@aku11i/phantom 0.4.0 → 0.5.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.ja.md +42 -4
- package/README.md +42 -4
- package/dist/phantom.js +276 -117
- package/dist/phantom.js.map +4 -4
- package/package.json +4 -4
package/README.ja.md
CHANGED
|
@@ -24,6 +24,7 @@ Phantomは、Git worktreeの管理を劇的にシンプルにするCLIツール
|
|
|
24
24
|
- 🎯 **ブランチとWorktreeの同期** - 各worktreeに対応するブランチを自動作成
|
|
25
25
|
- 🐚 **インタラクティブシェル** - SSH風のworktreeナビゲーション体験
|
|
26
26
|
- ⚡ **ゼロ設定** - 賢明なデフォルト設定ですぐに使用可能
|
|
27
|
+
- 📦 **ゼロ依存** - 外部依存関係がなく軽量で高速
|
|
27
28
|
|
|
28
29
|
## 🤔 なぜPhantom?
|
|
29
30
|
|
|
@@ -55,6 +56,9 @@ npm install -g @aku11i/phantom
|
|
|
55
56
|
# 新しいworktreeを作成
|
|
56
57
|
phantom create feature-awesome
|
|
57
58
|
|
|
59
|
+
# 既存のブランチにアタッチ
|
|
60
|
+
phantom attach existing-branch
|
|
61
|
+
|
|
58
62
|
# worktreeにジャンプ
|
|
59
63
|
phantom shell feature-awesome
|
|
60
64
|
|
|
@@ -105,6 +109,9 @@ npm link
|
|
|
105
109
|
# 対応するブランチを持つ新しいworktreeを作成
|
|
106
110
|
phantom create <name>
|
|
107
111
|
|
|
112
|
+
# 既存のブランチにworktreeとしてアタッチ
|
|
113
|
+
phantom attach <branch-name>
|
|
114
|
+
|
|
108
115
|
# すべてのworktreeとその現在のステータスをリスト表示
|
|
109
116
|
phantom list
|
|
110
117
|
|
|
@@ -149,7 +156,7 @@ tmuxとPhantomを組み合わせることで、驚くほど効率的なワーク
|
|
|
149
156
|
|
|
150
157
|
```bash
|
|
151
158
|
# 新しいtmuxウィンドウを開いて、同時にworktreeを作成
|
|
152
|
-
tmux new-window 'phantom create new-feature
|
|
159
|
+
tmux new-window 'phantom create --shell new-feature'
|
|
153
160
|
```
|
|
154
161
|
|
|
155
162
|
このたった1行のコマンドで:
|
|
@@ -163,8 +170,11 @@ tmux new-window 'phantom create new-feature --shell'
|
|
|
163
170
|
|
|
164
171
|
```bash
|
|
165
172
|
# worktreeを作成してすぐにVS Codeで開く
|
|
166
|
-
phantom create feature
|
|
167
|
-
phantom exec feature
|
|
173
|
+
phantom create --exec "code ." new-feature
|
|
174
|
+
phantom create --exec "cursor ." new-feature # Cursorでも動作します!
|
|
175
|
+
|
|
176
|
+
# 既存のブランチにアタッチしてVS Codeで開く
|
|
177
|
+
phantom attach --exec "code ." feature/existing-branch
|
|
168
178
|
```
|
|
169
179
|
|
|
170
180
|
### 並行開発ワークフロー
|
|
@@ -184,6 +194,7 @@ phantom shell feature-awesome # 機能開発を続行
|
|
|
184
194
|
| 機能 | Git Worktree | Phantom |
|
|
185
195
|
|---------|--------------|---------|
|
|
186
196
|
| worktree + ブランチの作成 | `git worktree add -b feature ../project-feature` | `phantom create feature` |
|
|
197
|
+
| 既存のブランチにアタッチ | `git worktree add ../project-feature feature` | `phantom attach feature` |
|
|
187
198
|
| worktreeのリスト表示 | `git worktree list` | `phantom list` |
|
|
188
199
|
| worktreeへの移動 | `cd ../project-feature` | `phantom shell feature` |
|
|
189
200
|
| worktreeでコマンド実行 | `cd ../project-feature && npm test` | `phantom exec feature npm test` |
|
|
@@ -201,7 +212,7 @@ pnpm install
|
|
|
201
212
|
pnpm test
|
|
202
213
|
|
|
203
214
|
# 型チェック
|
|
204
|
-
pnpm
|
|
215
|
+
pnpm typecheck
|
|
205
216
|
|
|
206
217
|
# リンティング
|
|
207
218
|
pnpm lint
|
|
@@ -262,6 +273,33 @@ Phantomの新しいバージョンをリリースするには:
|
|
|
262
273
|
--target main
|
|
263
274
|
```
|
|
264
275
|
|
|
276
|
+
7. **リリースノートを分かりやすく更新**
|
|
277
|
+
- 自動生成されたリリースノートをレビュー
|
|
278
|
+
- 重要な詳細についてはPRの説明を確認
|
|
279
|
+
- リリースノートをよりユーザーフレンドリーに更新:
|
|
280
|
+
- 変更をカテゴリー別にグループ化(機能、バグ修正、改善)
|
|
281
|
+
- 新機能には使用例を追加
|
|
282
|
+
- 変更の影響を平易な言葉で説明
|
|
283
|
+
- セキュリティ修正と破壊的変更を強調
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# リリースノートを編集
|
|
287
|
+
gh release edit v<version> --notes "$(cat <<'EOF'
|
|
288
|
+
## 🚀 v<version> の新機能
|
|
289
|
+
|
|
290
|
+
### ✨ 新機能
|
|
291
|
+
- 使用例付きの機能説明
|
|
292
|
+
|
|
293
|
+
### 🐛 バグ修正
|
|
294
|
+
- 修正内容の明確な説明
|
|
295
|
+
|
|
296
|
+
### 🛠️ 改善
|
|
297
|
+
- パフォーマンス、セキュリティ、その他の改善
|
|
298
|
+
|
|
299
|
+
EOF
|
|
300
|
+
)"
|
|
301
|
+
```
|
|
302
|
+
|
|
265
303
|
ビルドプロセスは`prepublishOnly`スクリプトによって自動的に処理され、以下を行います:
|
|
266
304
|
- すべてのテストとチェックを実行
|
|
267
305
|
- esbuildを使用してTypeScriptソースをJavaScriptにビルド
|
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ Phantom is a CLI tool that dramatically simplifies Git worktree management. It's
|
|
|
24
24
|
- 🎯 **Branch-Worktree Sync** - Automatically creates matching branches for each worktree
|
|
25
25
|
- 🐚 **Interactive Shell** - SSH-like experience for worktree navigation
|
|
26
26
|
- ⚡ **Zero Configuration** - Works out of the box with sensible defaults
|
|
27
|
+
- 📦 **Zero Dependencies** - Lightweight and fast with no external dependencies
|
|
27
28
|
|
|
28
29
|
## 🤔 Why Phantom?
|
|
29
30
|
|
|
@@ -55,6 +56,9 @@ npm install -g @aku11i/phantom
|
|
|
55
56
|
# Create a new worktree
|
|
56
57
|
phantom create feature-awesome
|
|
57
58
|
|
|
59
|
+
# Attach to an existing branch
|
|
60
|
+
phantom attach existing-branch
|
|
61
|
+
|
|
58
62
|
# Jump into the worktree
|
|
59
63
|
phantom shell feature-awesome
|
|
60
64
|
|
|
@@ -105,6 +109,9 @@ npm link
|
|
|
105
109
|
# Create a new worktree with a matching branch
|
|
106
110
|
phantom create <name>
|
|
107
111
|
|
|
112
|
+
# Attach to an existing branch as a worktree
|
|
113
|
+
phantom attach <branch-name>
|
|
114
|
+
|
|
108
115
|
# List all worktrees with their current status
|
|
109
116
|
phantom list
|
|
110
117
|
|
|
@@ -149,7 +156,7 @@ Combine tmux with Phantom for an incredibly efficient workflow:
|
|
|
149
156
|
|
|
150
157
|
```bash
|
|
151
158
|
# Open a new tmux window and create a worktree in one command
|
|
152
|
-
tmux new-window 'phantom create new-feature
|
|
159
|
+
tmux new-window 'phantom create --shell new-feature'
|
|
153
160
|
```
|
|
154
161
|
|
|
155
162
|
This single line:
|
|
@@ -163,8 +170,11 @@ When developing multiple features in parallel, you can manage each feature in it
|
|
|
163
170
|
|
|
164
171
|
```bash
|
|
165
172
|
# Create a worktree and immediately open it in VS Code
|
|
166
|
-
phantom create feature
|
|
167
|
-
phantom exec feature
|
|
173
|
+
phantom create --exec "code ." new-feature
|
|
174
|
+
phantom create --exec "cursor ." new-feature # also works with cursor!!
|
|
175
|
+
|
|
176
|
+
# Attach to existing branch and open in VS Code
|
|
177
|
+
phantom attach --exec "code ." feature/existing-branch
|
|
168
178
|
```
|
|
169
179
|
|
|
170
180
|
### Parallel Development Workflow
|
|
@@ -184,6 +194,7 @@ phantom shell feature-awesome # Continue feature development
|
|
|
184
194
|
| Feature | Git Worktree | Phantom |
|
|
185
195
|
|---------|--------------|---------|
|
|
186
196
|
| Create worktree + branch | `git worktree add -b feature ../project-feature` | `phantom create feature` |
|
|
197
|
+
| Attach to existing branch | `git worktree add ../project-feature feature` | `phantom attach feature` |
|
|
187
198
|
| List worktrees | `git worktree list` | `phantom list` |
|
|
188
199
|
| Navigate to worktree | `cd ../project-feature` | `phantom shell feature` |
|
|
189
200
|
| Run command in worktree | `cd ../project-feature && npm test` | `phantom exec feature npm test` |
|
|
@@ -201,7 +212,7 @@ pnpm install
|
|
|
201
212
|
pnpm test
|
|
202
213
|
|
|
203
214
|
# Type checking
|
|
204
|
-
pnpm
|
|
215
|
+
pnpm typecheck
|
|
205
216
|
|
|
206
217
|
# Linting
|
|
207
218
|
pnpm lint
|
|
@@ -262,6 +273,33 @@ To release a new version of Phantom:
|
|
|
262
273
|
--target main
|
|
263
274
|
```
|
|
264
275
|
|
|
276
|
+
7. **Update release notes for clarity**
|
|
277
|
+
- Review the auto-generated release notes
|
|
278
|
+
- Check PR descriptions for important details
|
|
279
|
+
- Update the release notes to be more user-friendly:
|
|
280
|
+
- Group changes by category (Features, Bug Fixes, Improvements)
|
|
281
|
+
- Add usage examples for new features
|
|
282
|
+
- Explain the impact of changes in plain language
|
|
283
|
+
- Highlight security fixes and breaking changes
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
# Edit the release notes
|
|
287
|
+
gh release edit v<version> --notes "$(cat <<'EOF'
|
|
288
|
+
## 🚀 What's New in v<version>
|
|
289
|
+
|
|
290
|
+
### ✨ New Features
|
|
291
|
+
- Feature description with usage example
|
|
292
|
+
|
|
293
|
+
### 🐛 Bug Fixes
|
|
294
|
+
- Clear description of what was fixed
|
|
295
|
+
|
|
296
|
+
### 🛠️ Improvements
|
|
297
|
+
- Performance, security, or other improvements
|
|
298
|
+
|
|
299
|
+
EOF
|
|
300
|
+
)"
|
|
301
|
+
```
|
|
302
|
+
|
|
265
303
|
The build process is automatically handled by the `prepublishOnly` script, which:
|
|
266
304
|
- Runs all tests and checks
|
|
267
305
|
- Builds the TypeScript source to JavaScript using esbuild
|
package/dist/phantom.js
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
// src/bin/phantom.ts
|
|
4
4
|
import { argv, exit } from "node:process";
|
|
5
5
|
|
|
6
|
-
// src/cli/handlers/
|
|
6
|
+
// src/cli/handlers/attach.ts
|
|
7
7
|
import { parseArgs } from "node:util";
|
|
8
8
|
|
|
9
|
+
// src/core/git/libs/get-git-root.ts
|
|
10
|
+
import { dirname, resolve } from "node:path";
|
|
11
|
+
|
|
9
12
|
// src/core/git/executor.ts
|
|
10
13
|
import { execFile as execFileCallback } from "node:child_process";
|
|
11
14
|
import { promisify } from "node:util";
|
|
@@ -41,8 +44,15 @@ async function executeGitCommandInDirectory(directory, args2) {
|
|
|
41
44
|
|
|
42
45
|
// src/core/git/libs/get-git-root.ts
|
|
43
46
|
async function getGitRoot() {
|
|
44
|
-
const { stdout } = await executeGitCommand(["rev-parse", "--
|
|
45
|
-
|
|
47
|
+
const { stdout } = await executeGitCommand(["rev-parse", "--git-common-dir"]);
|
|
48
|
+
if (stdout.endsWith("/.git") || stdout === ".git") {
|
|
49
|
+
return resolve(process.cwd(), dirname(stdout));
|
|
50
|
+
}
|
|
51
|
+
const { stdout: toplevel } = await executeGitCommand([
|
|
52
|
+
"rev-parse",
|
|
53
|
+
"--show-toplevel"
|
|
54
|
+
]);
|
|
55
|
+
return toplevel;
|
|
46
56
|
}
|
|
47
57
|
|
|
48
58
|
// src/core/types/result.ts
|
|
@@ -82,6 +92,12 @@ var GitOperationError = class extends WorktreeError {
|
|
|
82
92
|
this.name = "GitOperationError";
|
|
83
93
|
}
|
|
84
94
|
};
|
|
95
|
+
var BranchNotFoundError = class extends WorktreeError {
|
|
96
|
+
constructor(branchName) {
|
|
97
|
+
super(`Branch '${branchName}' not found`);
|
|
98
|
+
this.name = "BranchNotFoundError";
|
|
99
|
+
}
|
|
100
|
+
};
|
|
85
101
|
|
|
86
102
|
// src/core/worktree/validate.ts
|
|
87
103
|
import fs from "node:fs/promises";
|
|
@@ -126,33 +142,17 @@ async function validateWorktreeDoesNotExist(gitRoot, name) {
|
|
|
126
142
|
};
|
|
127
143
|
}
|
|
128
144
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
await fs.access(phantomDir);
|
|
133
|
-
return true;
|
|
134
|
-
} catch {
|
|
135
|
-
return false;
|
|
145
|
+
function validateWorktreeName(name) {
|
|
146
|
+
if (!name || name.trim() === "") {
|
|
147
|
+
return err(new Error("Phantom name cannot be empty"));
|
|
136
148
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const phantomDir = getPhantomDirectory(gitRoot);
|
|
140
|
-
if (!await validatePhantomDirectoryExists(gitRoot)) {
|
|
141
|
-
return [];
|
|
149
|
+
if (name.includes("/")) {
|
|
150
|
+
return err(new Error("Phantom name cannot contain slashes"));
|
|
142
151
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const validWorktrees = [];
|
|
146
|
-
for (const entry of entries) {
|
|
147
|
-
const result = await validateWorktreeExists(gitRoot, entry);
|
|
148
|
-
if (result.exists) {
|
|
149
|
-
validWorktrees.push(entry);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return validWorktrees;
|
|
153
|
-
} catch {
|
|
154
|
-
return [];
|
|
152
|
+
if (name.startsWith(".")) {
|
|
153
|
+
return err(new Error("Phantom name cannot start with a dot"));
|
|
155
154
|
}
|
|
155
|
+
return ok(void 0);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// src/core/process/spawn.ts
|
|
@@ -191,24 +191,24 @@ var ProcessSpawnError = class extends ProcessError {
|
|
|
191
191
|
|
|
192
192
|
// src/core/process/spawn.ts
|
|
193
193
|
async function spawnProcess(config) {
|
|
194
|
-
return new Promise((
|
|
194
|
+
return new Promise((resolve2) => {
|
|
195
195
|
const { command: command2, args: args2 = [], options = {} } = config;
|
|
196
196
|
const childProcess = nodeSpawn(command2, args2, {
|
|
197
197
|
stdio: "inherit",
|
|
198
198
|
...options
|
|
199
199
|
});
|
|
200
200
|
childProcess.on("error", (error) => {
|
|
201
|
-
|
|
201
|
+
resolve2(err(new ProcessSpawnError(command2, error.message)));
|
|
202
202
|
});
|
|
203
203
|
childProcess.on("exit", (code, signal) => {
|
|
204
204
|
if (signal) {
|
|
205
|
-
|
|
205
|
+
resolve2(err(new ProcessSignalError(signal)));
|
|
206
206
|
} else {
|
|
207
207
|
const exitCode = code ?? 0;
|
|
208
208
|
if (exitCode === 0) {
|
|
209
|
-
|
|
209
|
+
resolve2(ok({ exitCode }));
|
|
210
210
|
} else {
|
|
211
|
-
|
|
211
|
+
resolve2(err(new ProcessExecutionError(command2, exitCode)));
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
});
|
|
@@ -255,43 +255,68 @@ async function shellInWorktree(gitRoot, worktreeName) {
|
|
|
255
255
|
});
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
// src/core/worktree/
|
|
259
|
-
import
|
|
258
|
+
// src/core/worktree/attach.ts
|
|
259
|
+
import { existsSync } from "node:fs";
|
|
260
260
|
|
|
261
|
-
// src/core/git/libs/
|
|
262
|
-
async function
|
|
263
|
-
|
|
264
|
-
|
|
261
|
+
// src/core/git/libs/attach-worktree.ts
|
|
262
|
+
async function attachWorktree(gitRoot, worktreePath, branchName) {
|
|
263
|
+
try {
|
|
264
|
+
await executeGitCommand(["worktree", "add", worktreePath, branchName], {
|
|
265
|
+
cwd: gitRoot
|
|
266
|
+
});
|
|
267
|
+
return ok(void 0);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
return err(
|
|
270
|
+
error instanceof Error ? error : new Error(`Failed to attach worktree: ${String(error)}`)
|
|
271
|
+
);
|
|
272
|
+
}
|
|
265
273
|
}
|
|
266
274
|
|
|
267
|
-
// src/core/
|
|
268
|
-
async function
|
|
269
|
-
const { branch = name, commitish = "HEAD" } = options;
|
|
270
|
-
const worktreesPath = getPhantomDirectory(gitRoot);
|
|
271
|
-
const worktreePath = getWorktreePath(gitRoot, name);
|
|
275
|
+
// src/core/git/libs/branch-exists.ts
|
|
276
|
+
async function branchExists(gitRoot, branchName) {
|
|
272
277
|
try {
|
|
273
|
-
await
|
|
274
|
-
|
|
275
|
-
|
|
278
|
+
await executeGitCommand(
|
|
279
|
+
["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`],
|
|
280
|
+
{ cwd: gitRoot }
|
|
281
|
+
);
|
|
282
|
+
return ok(true);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
285
|
+
const execError = error;
|
|
286
|
+
if (execError.code === 1) {
|
|
287
|
+
return ok(false);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return err(
|
|
291
|
+
new Error(
|
|
292
|
+
`Failed to check branch existence: ${error instanceof Error ? error.message : String(error)}`
|
|
293
|
+
)
|
|
294
|
+
);
|
|
276
295
|
}
|
|
277
|
-
|
|
278
|
-
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/core/worktree/attach.ts
|
|
299
|
+
async function attachWorktreeCore(gitRoot, name) {
|
|
300
|
+
const validation = validateWorktreeName(name);
|
|
301
|
+
if (isErr(validation)) {
|
|
302
|
+
return validation;
|
|
303
|
+
}
|
|
304
|
+
const worktreePath = getWorktreePath(gitRoot, name);
|
|
305
|
+
if (existsSync(worktreePath)) {
|
|
279
306
|
return err(new WorktreeAlreadyExistsError(name));
|
|
280
307
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
branch,
|
|
285
|
-
commitish
|
|
286
|
-
});
|
|
287
|
-
return ok({
|
|
288
|
-
message: `Created worktree '${name}' at ${worktreePath}`,
|
|
289
|
-
path: worktreePath
|
|
290
|
-
});
|
|
291
|
-
} catch (error) {
|
|
292
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
293
|
-
return err(new GitOperationError("worktree add", errorMessage));
|
|
308
|
+
const branchCheckResult = await branchExists(gitRoot, name);
|
|
309
|
+
if (isErr(branchCheckResult)) {
|
|
310
|
+
return err(branchCheckResult.error);
|
|
294
311
|
}
|
|
312
|
+
if (!branchCheckResult.value) {
|
|
313
|
+
return err(new BranchNotFoundError(name));
|
|
314
|
+
}
|
|
315
|
+
const attachResult = await attachWorktree(gitRoot, worktreePath, name);
|
|
316
|
+
if (isErr(attachResult)) {
|
|
317
|
+
return err(attachResult.error);
|
|
318
|
+
}
|
|
319
|
+
return ok(worktreePath);
|
|
295
320
|
}
|
|
296
321
|
|
|
297
322
|
// src/cli/output.ts
|
|
@@ -326,9 +351,116 @@ function exitWithError(message, exitCode = exitCodes.generalError) {
|
|
|
326
351
|
process.exit(exitCode);
|
|
327
352
|
}
|
|
328
353
|
|
|
354
|
+
// src/cli/handlers/attach.ts
|
|
355
|
+
async function attachHandler(args2) {
|
|
356
|
+
const { positionals, values } = parseArgs({
|
|
357
|
+
args: args2,
|
|
358
|
+
strict: true,
|
|
359
|
+
allowPositionals: true,
|
|
360
|
+
options: {
|
|
361
|
+
shell: {
|
|
362
|
+
type: "boolean",
|
|
363
|
+
short: "s"
|
|
364
|
+
},
|
|
365
|
+
exec: {
|
|
366
|
+
type: "string",
|
|
367
|
+
short: "e"
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
if (positionals.length === 0) {
|
|
372
|
+
exitWithError(
|
|
373
|
+
"Missing required argument: branch name",
|
|
374
|
+
exitCodes.validationError
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
const [branchName] = positionals;
|
|
378
|
+
if (values.shell && values.exec) {
|
|
379
|
+
exitWithError(
|
|
380
|
+
"Cannot use both --shell and --exec options",
|
|
381
|
+
exitCodes.validationError
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
const gitRoot = await getGitRoot();
|
|
385
|
+
const result = await attachWorktreeCore(gitRoot, branchName);
|
|
386
|
+
if (isErr(result)) {
|
|
387
|
+
const error = result.error;
|
|
388
|
+
if (error instanceof WorktreeAlreadyExistsError) {
|
|
389
|
+
exitWithError(error.message, exitCodes.validationError);
|
|
390
|
+
}
|
|
391
|
+
if (error instanceof BranchNotFoundError) {
|
|
392
|
+
exitWithError(error.message, exitCodes.notFound);
|
|
393
|
+
}
|
|
394
|
+
exitWithError(error.message, exitCodes.generalError);
|
|
395
|
+
}
|
|
396
|
+
const worktreePath = result.value;
|
|
397
|
+
output.log(`Attached phantom: ${branchName}`);
|
|
398
|
+
if (values.shell) {
|
|
399
|
+
const shellResult = await shellInWorktree(gitRoot, branchName);
|
|
400
|
+
if (isErr(shellResult)) {
|
|
401
|
+
exitWithError(shellResult.error.message, exitCodes.generalError);
|
|
402
|
+
}
|
|
403
|
+
} else if (values.exec) {
|
|
404
|
+
const execResult = await execInWorktree(
|
|
405
|
+
gitRoot,
|
|
406
|
+
branchName,
|
|
407
|
+
values.exec.split(" ")
|
|
408
|
+
);
|
|
409
|
+
if (isErr(execResult)) {
|
|
410
|
+
exitWithError(execResult.error.message, exitCodes.generalError);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// src/cli/handlers/create.ts
|
|
416
|
+
import { parseArgs as parseArgs2 } from "node:util";
|
|
417
|
+
|
|
418
|
+
// src/core/worktree/create.ts
|
|
419
|
+
import fs2 from "node:fs/promises";
|
|
420
|
+
|
|
421
|
+
// src/core/git/libs/add-worktree.ts
|
|
422
|
+
async function addWorktree(options) {
|
|
423
|
+
const { path, branch, commitish = "HEAD" } = options;
|
|
424
|
+
await executeGitCommand(["worktree", "add", path, "-b", branch, commitish]);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// src/core/worktree/create.ts
|
|
428
|
+
async function createWorktree(gitRoot, name, options = {}) {
|
|
429
|
+
const nameValidation = validateWorktreeName(name);
|
|
430
|
+
if (isErr(nameValidation)) {
|
|
431
|
+
return nameValidation;
|
|
432
|
+
}
|
|
433
|
+
const { branch = name, commitish = "HEAD" } = options;
|
|
434
|
+
const worktreesPath = getPhantomDirectory(gitRoot);
|
|
435
|
+
const worktreePath = getWorktreePath(gitRoot, name);
|
|
436
|
+
try {
|
|
437
|
+
await fs2.access(worktreesPath);
|
|
438
|
+
} catch {
|
|
439
|
+
await fs2.mkdir(worktreesPath, { recursive: true });
|
|
440
|
+
}
|
|
441
|
+
const validation = await validateWorktreeDoesNotExist(gitRoot, name);
|
|
442
|
+
if (validation.exists) {
|
|
443
|
+
return err(new WorktreeAlreadyExistsError(name));
|
|
444
|
+
}
|
|
445
|
+
try {
|
|
446
|
+
await addWorktree({
|
|
447
|
+
path: worktreePath,
|
|
448
|
+
branch,
|
|
449
|
+
commitish
|
|
450
|
+
});
|
|
451
|
+
return ok({
|
|
452
|
+
message: `Created worktree '${name}' at ${worktreePath}`,
|
|
453
|
+
path: worktreePath
|
|
454
|
+
});
|
|
455
|
+
} catch (error) {
|
|
456
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
457
|
+
return err(new GitOperationError("worktree add", errorMessage));
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
329
461
|
// src/cli/handlers/create.ts
|
|
330
462
|
async function createHandler(args2) {
|
|
331
|
-
const { values, positionals } =
|
|
463
|
+
const { values, positionals } = parseArgs2({
|
|
332
464
|
args: args2,
|
|
333
465
|
options: {
|
|
334
466
|
shell: {
|
|
@@ -408,7 +540,7 @@ Entering worktree '${worktreeName}' at ${result.value.path}`
|
|
|
408
540
|
}
|
|
409
541
|
|
|
410
542
|
// src/cli/handlers/delete.ts
|
|
411
|
-
import { parseArgs as
|
|
543
|
+
import { parseArgs as parseArgs3 } from "node:util";
|
|
412
544
|
|
|
413
545
|
// src/core/worktree/delete.ts
|
|
414
546
|
async function getWorktreeStatus(worktreePath) {
|
|
@@ -498,7 +630,7 @@ ${message}`;
|
|
|
498
630
|
|
|
499
631
|
// src/cli/handlers/delete.ts
|
|
500
632
|
async function deleteHandler(args2) {
|
|
501
|
-
const { values, positionals } =
|
|
633
|
+
const { values, positionals } = parseArgs3({
|
|
502
634
|
args: args2,
|
|
503
635
|
options: {
|
|
504
636
|
force: {
|
|
@@ -537,9 +669,9 @@ async function deleteHandler(args2) {
|
|
|
537
669
|
}
|
|
538
670
|
|
|
539
671
|
// src/cli/handlers/exec.ts
|
|
540
|
-
import { parseArgs as
|
|
672
|
+
import { parseArgs as parseArgs4 } from "node:util";
|
|
541
673
|
async function execHandler(args2) {
|
|
542
|
-
const { positionals } =
|
|
674
|
+
const { positionals } = parseArgs4({
|
|
543
675
|
args: args2,
|
|
544
676
|
options: {},
|
|
545
677
|
strict: true,
|
|
@@ -569,20 +701,48 @@ async function execHandler(args2) {
|
|
|
569
701
|
}
|
|
570
702
|
|
|
571
703
|
// src/cli/handlers/list.ts
|
|
572
|
-
import { parseArgs as
|
|
704
|
+
import { parseArgs as parseArgs5 } from "node:util";
|
|
573
705
|
|
|
574
|
-
// src/core/
|
|
575
|
-
async function
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
706
|
+
// src/core/git/libs/list-worktrees.ts
|
|
707
|
+
async function listWorktrees(gitRoot) {
|
|
708
|
+
const { stdout } = await executeGitCommand([
|
|
709
|
+
"worktree",
|
|
710
|
+
"list",
|
|
711
|
+
"--porcelain"
|
|
712
|
+
]);
|
|
713
|
+
const worktrees = [];
|
|
714
|
+
let currentWorktree = {};
|
|
715
|
+
const lines = stdout.split("\n").filter((line) => line.length > 0);
|
|
716
|
+
for (const line of lines) {
|
|
717
|
+
if (line.startsWith("worktree ")) {
|
|
718
|
+
if (currentWorktree.path) {
|
|
719
|
+
worktrees.push(currentWorktree);
|
|
720
|
+
}
|
|
721
|
+
currentWorktree = {
|
|
722
|
+
path: line.substring("worktree ".length),
|
|
723
|
+
isLocked: false,
|
|
724
|
+
isPrunable: false
|
|
725
|
+
};
|
|
726
|
+
} else if (line.startsWith("HEAD ")) {
|
|
727
|
+
currentWorktree.head = line.substring("HEAD ".length);
|
|
728
|
+
} else if (line.startsWith("branch ")) {
|
|
729
|
+
const fullBranch = line.substring("branch ".length);
|
|
730
|
+
currentWorktree.branch = fullBranch.startsWith("refs/heads/") ? fullBranch.substring("refs/heads/".length) : fullBranch;
|
|
731
|
+
} else if (line === "detached") {
|
|
732
|
+
currentWorktree.branch = "(detached HEAD)";
|
|
733
|
+
} else if (line === "locked") {
|
|
734
|
+
currentWorktree.isLocked = true;
|
|
735
|
+
} else if (line === "prunable") {
|
|
736
|
+
currentWorktree.isPrunable = true;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (currentWorktree.path) {
|
|
740
|
+
worktrees.push(currentWorktree);
|
|
584
741
|
}
|
|
742
|
+
return worktrees;
|
|
585
743
|
}
|
|
744
|
+
|
|
745
|
+
// src/core/worktree/list.ts
|
|
586
746
|
async function getWorktreeStatus2(worktreePath) {
|
|
587
747
|
try {
|
|
588
748
|
const { stdout } = await executeGitCommandInDirectory(worktreePath, [
|
|
@@ -594,36 +754,30 @@ async function getWorktreeStatus2(worktreePath) {
|
|
|
594
754
|
return true;
|
|
595
755
|
}
|
|
596
756
|
}
|
|
597
|
-
async function
|
|
598
|
-
const worktreePath = getWorktreePath(gitRoot, name);
|
|
599
|
-
const [branch, isClean] = await Promise.all([
|
|
600
|
-
getWorktreeBranch(worktreePath),
|
|
601
|
-
getWorktreeStatus2(worktreePath)
|
|
602
|
-
]);
|
|
603
|
-
return {
|
|
604
|
-
name,
|
|
605
|
-
path: worktreePath,
|
|
606
|
-
branch,
|
|
607
|
-
isClean
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
async function listWorktrees(gitRoot) {
|
|
611
|
-
if (!await validatePhantomDirectoryExists(gitRoot)) {
|
|
612
|
-
return ok({
|
|
613
|
-
worktrees: [],
|
|
614
|
-
message: "No worktrees found (worktrees directory doesn't exist)"
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
const worktreeNames = await listValidWorktrees(gitRoot);
|
|
618
|
-
if (worktreeNames.length === 0) {
|
|
619
|
-
return ok({
|
|
620
|
-
worktrees: [],
|
|
621
|
-
message: "No worktrees found"
|
|
622
|
-
});
|
|
623
|
-
}
|
|
757
|
+
async function listWorktrees2(gitRoot) {
|
|
624
758
|
try {
|
|
759
|
+
const gitWorktrees = await listWorktrees(gitRoot);
|
|
760
|
+
const phantomDir = getPhantomDirectory(gitRoot);
|
|
761
|
+
const phantomWorktrees = gitWorktrees.filter(
|
|
762
|
+
(worktree) => worktree.path.startsWith(phantomDir)
|
|
763
|
+
);
|
|
764
|
+
if (phantomWorktrees.length === 0) {
|
|
765
|
+
return ok({
|
|
766
|
+
worktrees: [],
|
|
767
|
+
message: "No worktrees found"
|
|
768
|
+
});
|
|
769
|
+
}
|
|
625
770
|
const worktrees = await Promise.all(
|
|
626
|
-
|
|
771
|
+
phantomWorktrees.map(async (gitWorktree) => {
|
|
772
|
+
const name = gitWorktree.path.substring(phantomDir.length + 1);
|
|
773
|
+
const isClean = await getWorktreeStatus2(gitWorktree.path);
|
|
774
|
+
return {
|
|
775
|
+
name,
|
|
776
|
+
path: gitWorktree.path,
|
|
777
|
+
branch: gitWorktree.branch || "(detached HEAD)",
|
|
778
|
+
isClean
|
|
779
|
+
};
|
|
780
|
+
})
|
|
627
781
|
);
|
|
628
782
|
return ok({
|
|
629
783
|
worktrees
|
|
@@ -636,7 +790,7 @@ async function listWorktrees(gitRoot) {
|
|
|
636
790
|
|
|
637
791
|
// src/cli/handlers/list.ts
|
|
638
792
|
async function listHandler(args2 = []) {
|
|
639
|
-
|
|
793
|
+
parseArgs5({
|
|
640
794
|
args: args2,
|
|
641
795
|
options: {},
|
|
642
796
|
strict: true,
|
|
@@ -644,7 +798,7 @@ async function listHandler(args2 = []) {
|
|
|
644
798
|
});
|
|
645
799
|
try {
|
|
646
800
|
const gitRoot = await getGitRoot();
|
|
647
|
-
const result = await
|
|
801
|
+
const result = await listWorktrees2(gitRoot);
|
|
648
802
|
if (isErr(result)) {
|
|
649
803
|
exitWithError("Failed to list worktrees", exitCodes.generalError);
|
|
650
804
|
}
|
|
@@ -670,9 +824,9 @@ async function listHandler(args2 = []) {
|
|
|
670
824
|
}
|
|
671
825
|
|
|
672
826
|
// src/cli/handlers/shell.ts
|
|
673
|
-
import { parseArgs as
|
|
827
|
+
import { parseArgs as parseArgs6 } from "node:util";
|
|
674
828
|
async function shellHandler(args2) {
|
|
675
|
-
const { positionals } =
|
|
829
|
+
const { positionals } = parseArgs6({
|
|
676
830
|
args: args2,
|
|
677
831
|
options: {},
|
|
678
832
|
strict: true,
|
|
@@ -711,13 +865,13 @@ async function shellHandler(args2) {
|
|
|
711
865
|
}
|
|
712
866
|
|
|
713
867
|
// src/cli/handlers/version.ts
|
|
714
|
-
import { parseArgs as
|
|
868
|
+
import { parseArgs as parseArgs7 } from "node:util";
|
|
715
869
|
|
|
716
870
|
// package.json
|
|
717
871
|
var package_default = {
|
|
718
872
|
name: "@aku11i/phantom",
|
|
719
873
|
packageManager: "pnpm@10.8.1",
|
|
720
|
-
version: "0.
|
|
874
|
+
version: "0.5.0",
|
|
721
875
|
description: "A powerful CLI tool for managing Git worktrees for parallel development",
|
|
722
876
|
keywords: [
|
|
723
877
|
"git",
|
|
@@ -746,12 +900,12 @@ var package_default = {
|
|
|
746
900
|
start: "node ./src/bin/phantom.ts",
|
|
747
901
|
phantom: "node ./src/bin/phantom.ts",
|
|
748
902
|
build: "node build.ts",
|
|
749
|
-
|
|
903
|
+
typecheck: "tsgo --noEmit",
|
|
750
904
|
test: "node --test --experimental-strip-types --experimental-test-module-mocks src/**/*.test.ts",
|
|
751
905
|
lint: "biome check .",
|
|
752
906
|
fix: "biome check --write .",
|
|
753
|
-
ready: "pnpm fix && pnpm
|
|
754
|
-
"ready:check": "pnpm lint && pnpm
|
|
907
|
+
ready: "pnpm fix && pnpm typecheck && pnpm test",
|
|
908
|
+
"ready:check": "pnpm lint && pnpm typecheck && pnpm test",
|
|
755
909
|
prepublishOnly: "pnpm ready:check && pnpm build"
|
|
756
910
|
},
|
|
757
911
|
engines: {
|
|
@@ -778,7 +932,7 @@ function getVersion() {
|
|
|
778
932
|
|
|
779
933
|
// src/cli/handlers/version.ts
|
|
780
934
|
function versionHandler(args2 = []) {
|
|
781
|
-
|
|
935
|
+
parseArgs7({
|
|
782
936
|
args: args2,
|
|
783
937
|
options: {},
|
|
784
938
|
strict: true,
|
|
@@ -790,7 +944,7 @@ function versionHandler(args2 = []) {
|
|
|
790
944
|
}
|
|
791
945
|
|
|
792
946
|
// src/cli/handlers/where.ts
|
|
793
|
-
import { parseArgs as
|
|
947
|
+
import { parseArgs as parseArgs8 } from "node:util";
|
|
794
948
|
|
|
795
949
|
// src/core/worktree/where.ts
|
|
796
950
|
async function whereWorktree(gitRoot, name) {
|
|
@@ -805,7 +959,7 @@ async function whereWorktree(gitRoot, name) {
|
|
|
805
959
|
|
|
806
960
|
// src/cli/handlers/where.ts
|
|
807
961
|
async function whereHandler(args2) {
|
|
808
|
-
const { positionals } =
|
|
962
|
+
const { positionals } = parseArgs8({
|
|
809
963
|
args: args2,
|
|
810
964
|
options: {},
|
|
811
965
|
strict: true,
|
|
@@ -838,6 +992,11 @@ var commands = [
|
|
|
838
992
|
description: "Create a new worktree [--shell | --exec <command>]",
|
|
839
993
|
handler: createHandler
|
|
840
994
|
},
|
|
995
|
+
{
|
|
996
|
+
name: "attach",
|
|
997
|
+
description: "Attach to an existing branch [--shell | --exec <command>]",
|
|
998
|
+
handler: attachHandler
|
|
999
|
+
},
|
|
841
1000
|
{
|
|
842
1001
|
name: "list",
|
|
843
1002
|
description: "List all worktrees",
|
package/dist/phantom.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/bin/phantom.ts", "../src/cli/handlers/
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport { argv, exit } from \"node:process\";\nimport { createHandler } from \"../cli/handlers/create.ts\";\nimport { deleteHandler } from \"../cli/handlers/delete.ts\";\nimport { execHandler } from \"../cli/handlers/exec.ts\";\nimport { listHandler } from \"../cli/handlers/list.ts\";\nimport { shellHandler } from \"../cli/handlers/shell.ts\";\nimport { versionHandler } from \"../cli/handlers/version.ts\";\nimport { whereHandler } from \"../cli/handlers/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: \"create\",\n description: \"Create a new worktree [--shell | --exec <command>]\",\n handler: createHandler,\n },\n {\n name: \"list\",\n description: \"List all worktrees\",\n handler: listHandler,\n },\n {\n name: \"where\",\n description: \"Output the path of a specific worktree\",\n handler: whereHandler,\n },\n {\n name: \"delete\",\n description: \"Delete a worktree (use --force for uncommitted changes)\",\n handler: deleteHandler,\n },\n {\n name: \"exec\",\n description: \"Execute a command in a worktree directory\",\n handler: execHandler,\n },\n {\n name: \"shell\",\n description: \"Open interactive shell in a worktree directory\",\n handler: shellHandler,\n },\n {\n name: \"version\",\n description: \"Display phantom version\",\n handler: versionHandler,\n },\n];\n\nfunction printHelp(commands: Command[]) {\n console.log(\"Usage: phantom <command> [options]\\n\");\n console.log(\"Commands:\");\n for (const cmd of commands) {\n console.log(` ${cmd.name.padEnd(12)} ${cmd.description}`);\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\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n versionHandler();\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 { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { execInWorktree } from \"../../core/process/exec.ts\";\nimport { shellInWorktree } from \"../../core/process/shell.ts\";\nimport { isErr, isOk } from \"../../core/types/result.ts\";\nimport { createWorktree as createWorktreeCore } from \"../../core/worktree/create.ts\";\nimport { WorktreeAlreadyExistsError } from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError, exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function createHandler(args: string[]): Promise<void> {\n const { values, positionals } = parseArgs({\n args,\n options: {\n shell: {\n type: \"boolean\",\n short: \"s\",\n },\n exec: {\n type: \"string\",\n short: \"x\",\n },\n },\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Please provide a name for the new worktree\",\n exitCodes.validationError,\n );\n }\n\n const worktreeName = positionals[0];\n const openShell = values.shell ?? false;\n const execCommand = values.exec;\n\n if (openShell && execCommand) {\n exitWithError(\n \"Cannot use --shell and --exec together\",\n exitCodes.validationError,\n );\n }\n\n try {\n const gitRoot = await getGitRoot();\n const result = await createWorktreeCore(gitRoot, worktreeName);\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeAlreadyExistsError\n ? exitCodes.validationError\n : exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n output.log(result.value.message);\n\n if (execCommand && isOk(result)) {\n output.log(\n `\\nExecuting command in worktree '${worktreeName}': ${execCommand}`,\n );\n\n const shell = process.env.SHELL || \"/bin/sh\";\n const execResult = await execInWorktree(gitRoot, worktreeName, [\n shell,\n \"-c\",\n execCommand,\n ]);\n\n if (isErr(execResult)) {\n output.error(execResult.error.message);\n const exitCode =\n \"exitCode\" in execResult.error\n ? (execResult.error.exitCode ?? exitCodes.generalError)\n : exitCodes.generalError;\n exitWithError(\"\", exitCode);\n }\n\n process.exit(execResult.value.exitCode ?? 0);\n }\n\n if (openShell && isOk(result)) {\n output.log(\n `\\nEntering worktree '${worktreeName}' at ${result.value.path}`,\n );\n output.log(\"Type 'exit' to return to your original directory\\n\");\n\n const shellResult = await shellInWorktree(gitRoot, worktreeName);\n\n if (isErr(shellResult)) {\n output.error(shellResult.error.message);\n const exitCode =\n \"exitCode\" in shellResult.error\n ? (shellResult.error.exitCode ?? exitCodes.generalError)\n : exitCodes.generalError;\n exitWithError(\"\", exitCode);\n }\n\n process.exit(shellResult.value.exitCode ?? 0);\n }\n\n exitWithSuccess();\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { execFile as execFileCallback } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFile = promisify(execFileCallback);\n\nexport interface GitExecutorOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface GitExecutorResult {\n stdout: string;\n stderr: string;\n}\n\n/**\n * Execute a git command with consistent error handling\n */\nexport async function executeGitCommand(\n args: string[],\n options: GitExecutorOptions = {},\n): Promise<GitExecutorResult> {\n try {\n const result = await execFile(\"git\", args, {\n cwd: options.cwd,\n env: options.env || process.env,\n encoding: \"utf8\",\n });\n\n return {\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n };\n } catch (error) {\n // Git commands often return non-zero exit codes for normal operations\n // (e.g., `git diff` returns 1 when there are differences)\n // So we need to handle errors carefully\n if (\n error &&\n typeof error === \"object\" &&\n \"stdout\" in error &&\n \"stderr\" in error\n ) {\n const execError = error as {\n stdout: string;\n stderr: string;\n code?: number;\n };\n\n // If we have stderr content, it's likely a real error\n if (execError.stderr?.trim()) {\n throw new Error(execError.stderr.trim());\n }\n\n // Otherwise, return the output even though the exit code was non-zero\n return {\n stdout: execError.stdout?.trim() || \"\",\n stderr: execError.stderr?.trim() || \"\",\n };\n }\n\n throw error;\n }\n}\n\n/**\n * Execute a git command in a specific directory\n */\nexport async function executeGitCommandInDirectory(\n directory: string,\n args: string[],\n): Promise<GitExecutorResult> {\n return executeGitCommand([\"-C\", directory, ...args], {});\n}\n", "import { executeGitCommand } from \"../executor.ts\";\n\nexport async function getGitRoot(): Promise<string> {\n const { stdout } = await executeGitCommand([\"rev-parse\", \"--show-toplevel\"]);\n return stdout;\n}\n", "/**\n * Represents a value that is either successful (Ok) or contains an error (Err).\n * This type is inspired by Rust's Result type and provides type-safe error handling.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value (defaults to Error)\n */\nexport type Result<T, E = Error> =\n | { ok: true; value: T }\n | { ok: false; error: E };\n\n/**\n * Creates a successful Result containing the given value.\n *\n * @template T - The type of the success value\n * @param value - The success value to wrap\n * @returns A Result in the Ok state containing the value\n *\n * @example\n * const result = ok(42);\n * // result: Result<number, never> = { ok: true, value: 42 }\n */\nexport const ok = <T>(value: T): Result<T, never> => ({\n ok: true,\n value,\n});\n\n/**\n * Creates a failed Result containing the given error.\n *\n * @template E - The type of the error value\n * @param error - The error value to wrap\n * @returns A Result in the Err state containing the error\n *\n * @example\n * const result = err(new Error(\"Something went wrong\"));\n * // result: Result<never, Error> = { ok: false, error: Error(...) }\n */\nexport const err = <E>(error: E): Result<never, E> => ({\n ok: false,\n error,\n});\n\n/**\n * Type guard that checks if a Result is in the Ok state.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value\n * @param result - The Result to check\n * @returns True if the Result is Ok, false otherwise\n *\n * @example\n * if (isOk(result)) {\n * console.log(result.value); // TypeScript knows result.value exists\n * }\n */\nexport const isOk = <T, E>(\n result: Result<T, E>,\n): result is { ok: true; value: T } => result.ok;\n\n/**\n * Type guard that checks if a Result is in the Err state.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value\n * @param result - The Result to check\n * @returns True if the Result is Err, false otherwise\n *\n * @example\n * if (isErr(result)) {\n * console.error(result.error); // TypeScript knows result.error exists\n * }\n */\nexport const isErr = <T, E>(\n result: Result<T, E>,\n): result is { ok: false; error: E } => !result.ok;\n", "export class WorktreeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WorktreeError\";\n }\n}\n\nexport class WorktreeNotFoundError extends WorktreeError {\n constructor(name: string) {\n super(`Worktree '${name}' not found`);\n this.name = \"WorktreeNotFoundError\";\n }\n}\n\nexport class WorktreeAlreadyExistsError extends WorktreeError {\n constructor(name: string) {\n super(`Worktree '${name}' already exists`);\n this.name = \"WorktreeAlreadyExistsError\";\n }\n}\n\nexport class InvalidWorktreeNameError extends WorktreeError {\n constructor(name: string) {\n super(`Invalid worktree name: '${name}'`);\n this.name = \"InvalidWorktreeNameError\";\n }\n}\n\nexport class GitOperationError extends WorktreeError {\n constructor(operation: string, details: string) {\n super(`Git ${operation} failed: ${details}`);\n this.name = \"GitOperationError\";\n }\n}\n", "import fs from \"node:fs/promises\";\nimport { getPhantomDirectory, getWorktreePath } from \"../paths.ts\";\n\nexport interface ValidationResult {\n exists: boolean;\n path?: string;\n message?: string;\n}\n\nexport async function validateWorktreeExists(\n gitRoot: string,\n name: string,\n): Promise<ValidationResult> {\n const worktreePath = getWorktreePath(gitRoot, name);\n\n try {\n await fs.access(worktreePath);\n return {\n exists: true,\n path: worktreePath,\n };\n } catch {\n return {\n exists: false,\n message: `Worktree '${name}' does not exist`,\n };\n }\n}\n\nexport async function validateWorktreeDoesNotExist(\n gitRoot: string,\n name: string,\n): Promise<ValidationResult> {\n const worktreePath = getWorktreePath(gitRoot, name);\n\n try {\n await fs.access(worktreePath);\n return {\n exists: true,\n message: `Worktree '${name}' already exists`,\n };\n } catch {\n return {\n exists: false,\n path: worktreePath,\n };\n }\n}\n\nexport async function validatePhantomDirectoryExists(\n gitRoot: string,\n): Promise<boolean> {\n const phantomDir = getPhantomDirectory(gitRoot);\n\n try {\n await fs.access(phantomDir);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function listValidWorktrees(gitRoot: string): Promise<string[]> {\n const phantomDir = getPhantomDirectory(gitRoot);\n\n if (!(await validatePhantomDirectoryExists(gitRoot))) {\n return [];\n }\n\n try {\n const entries = await fs.readdir(phantomDir);\n const validWorktrees: string[] = [];\n\n for (const entry of entries) {\n const result = await validateWorktreeExists(gitRoot, entry);\n if (result.exists) {\n validWorktrees.push(entry);\n }\n }\n\n return validWorktrees;\n } catch {\n return [];\n }\n}\n", "import { join } from \"node:path\";\n\nexport function getPhantomDirectory(gitRoot: string): string {\n return join(gitRoot, \".git\", \"phantom\", \"worktrees\");\n}\n\nexport function getWorktreePath(gitRoot: string, name: string): string {\n return join(getPhantomDirectory(gitRoot), name);\n}\n", "import {\n type ChildProcess,\n type SpawnOptions,\n spawn as nodeSpawn,\n} from \"node:child_process\";\nimport { type Result, err, ok } from \"../types/result.ts\";\nimport {\n type ProcessError,\n ProcessExecutionError,\n ProcessSignalError,\n ProcessSpawnError,\n} from \"./errors.ts\";\n\nexport interface SpawnSuccess {\n exitCode: number;\n}\n\nexport interface SpawnConfig {\n command: string;\n args?: string[];\n options?: SpawnOptions;\n}\n\nexport async function spawnProcess(\n config: SpawnConfig,\n): Promise<Result<SpawnSuccess, ProcessError>> {\n return new Promise((resolve) => {\n const { command, args = [], options = {} } = config;\n\n const childProcess: ChildProcess = nodeSpawn(command, args, {\n stdio: \"inherit\",\n ...options,\n });\n\n childProcess.on(\"error\", (error) => {\n resolve(err(new ProcessSpawnError(command, error.message)));\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve(err(new ProcessSignalError(signal)));\n } else {\n const exitCode = code ?? 0;\n if (exitCode === 0) {\n resolve(ok({ exitCode }));\n } else {\n resolve(err(new ProcessExecutionError(command, exitCode)));\n }\n }\n });\n });\n}\n", "export class ProcessError extends Error {\n public readonly exitCode?: number;\n\n constructor(message: string, exitCode?: number) {\n super(message);\n this.name = \"ProcessError\";\n this.exitCode = exitCode;\n }\n}\n\nexport class ProcessExecutionError extends ProcessError {\n constructor(command: string, exitCode: number) {\n super(`Command '${command}' failed with exit code ${exitCode}`, exitCode);\n this.name = \"ProcessExecutionError\";\n }\n}\n\nexport class ProcessSignalError extends ProcessError {\n constructor(signal: string) {\n const exitCode = 128 + (signal === \"SIGTERM\" ? 15 : 1);\n super(`Command terminated by signal: ${signal}`, exitCode);\n this.name = \"ProcessSignalError\";\n }\n}\n\nexport class ProcessSpawnError extends ProcessError {\n constructor(command: string, details: string) {\n super(`Error executing command '${command}': ${details}`);\n this.name = \"ProcessSpawnError\";\n }\n}\n", "import { type Result, err } from \"../types/result.ts\";\nimport { WorktreeNotFoundError } from \"../worktree/errors.ts\";\nimport { validateWorktreeExists } from \"../worktree/validate.ts\";\nimport type { ProcessError } from \"./errors.ts\";\nimport { type SpawnSuccess, spawnProcess } from \"./spawn.ts\";\n\nexport type ExecInWorktreeSuccess = SpawnSuccess;\n\nexport async function execInWorktree(\n gitRoot: string,\n worktreeName: string,\n command: string[],\n): Promise<\n Result<ExecInWorktreeSuccess, WorktreeNotFoundError | ProcessError>\n> {\n const validation = await validateWorktreeExists(gitRoot, worktreeName);\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(worktreeName));\n }\n\n const worktreePath = validation.path as string;\n const [cmd, ...args] = command;\n\n return spawnProcess({\n command: cmd,\n args,\n options: {\n cwd: worktreePath,\n },\n });\n}\n", "import { type Result, err } from \"../types/result.ts\";\nimport { WorktreeNotFoundError } from \"../worktree/errors.ts\";\nimport { validateWorktreeExists } from \"../worktree/validate.ts\";\nimport type { ProcessError } from \"./errors.ts\";\nimport { type SpawnSuccess, spawnProcess } from \"./spawn.ts\";\n\nexport type ShellInWorktreeSuccess = SpawnSuccess;\n\nexport async function shellInWorktree(\n gitRoot: string,\n worktreeName: string,\n): Promise<\n Result<ShellInWorktreeSuccess, WorktreeNotFoundError | ProcessError>\n> {\n const validation = await validateWorktreeExists(gitRoot, worktreeName);\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(worktreeName));\n }\n\n const worktreePath = validation.path as string;\n const shell = process.env.SHELL || \"/bin/sh\";\n\n return spawnProcess({\n command: shell,\n args: [],\n options: {\n cwd: worktreePath,\n env: {\n ...process.env,\n PHANTOM: \"1\",\n PHANTOM_NAME: worktreeName,\n PHANTOM_PATH: worktreePath,\n },\n },\n });\n}\n", "import fs from \"node:fs/promises\";\nimport { addWorktree } from \"../git/libs/add-worktree.ts\";\nimport { getPhantomDirectory, getWorktreePath } from \"../paths.ts\";\nimport { type Result, err, ok } from \"../types/result.ts\";\nimport { GitOperationError, WorktreeAlreadyExistsError } from \"./errors.ts\";\nimport { validateWorktreeDoesNotExist } from \"./validate.ts\";\n\nexport interface CreateWorktreeOptions {\n branch?: string;\n commitish?: string;\n}\n\nexport interface CreateWorktreeSuccess {\n message: string;\n path: string;\n}\n\nexport async function createWorktree(\n gitRoot: string,\n name: string,\n options: CreateWorktreeOptions = {},\n): Promise<\n Result<CreateWorktreeSuccess, WorktreeAlreadyExistsError | GitOperationError>\n> {\n const { branch = name, commitish = \"HEAD\" } = options;\n\n const worktreesPath = getPhantomDirectory(gitRoot);\n const worktreePath = getWorktreePath(gitRoot, name);\n\n try {\n await fs.access(worktreesPath);\n } catch {\n await fs.mkdir(worktreesPath, { recursive: true });\n }\n\n const validation = await validateWorktreeDoesNotExist(gitRoot, name);\n if (validation.exists) {\n return err(new WorktreeAlreadyExistsError(name));\n }\n\n try {\n await addWorktree({\n path: worktreePath,\n branch,\n commitish,\n });\n\n return ok({\n message: `Created worktree '${name}' at ${worktreePath}`,\n path: worktreePath,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return err(new GitOperationError(\"worktree add\", errorMessage));\n }\n}\n", "import { executeGitCommand } from \"../executor.ts\";\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 executeGitCommand([\"worktree\", \"add\", path, \"-b\", branch, commitish]);\n}\n", "import type { ChildProcess } from \"node:child_process\";\n\nexport const output = {\n log: (message: string) => {\n console.log(message);\n },\n\n error: (message: string) => {\n console.error(message);\n },\n\n table: (data: unknown) => {\n console.table(data);\n },\n\n processOutput: (proc: ChildProcess) => {\n proc.stdout?.pipe(process.stdout);\n proc.stderr?.pipe(process.stderr);\n },\n};\n", "import { output } from \"./output.ts\";\n\nexport const exitCodes = {\n success: 0,\n generalError: 1,\n notFound: 2,\n validationError: 3,\n} as const;\n\nexport function handleError(\n error: unknown,\n exitCode: number = exitCodes.generalError,\n): never {\n if (error instanceof Error) {\n output.error(error.message);\n } else {\n output.error(String(error));\n }\n process.exit(exitCode);\n}\n\nexport function exitWithSuccess(): never {\n process.exit(exitCodes.success);\n}\n\nexport function exitWithError(\n message: string,\n exitCode: number = exitCodes.generalError,\n): never {\n output.error(message);\n process.exit(exitCode);\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { deleteWorktree as deleteWorktreeCore } from \"../../core/worktree/delete.ts\";\nimport {\n WorktreeError,\n WorktreeNotFoundError,\n} from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError, exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function deleteHandler(args: string[]): Promise<void> {\n const { values, positionals } = parseArgs({\n args,\n options: {\n force: {\n type: \"boolean\",\n short: \"f\",\n },\n },\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Please provide a worktree name to delete\",\n exitCodes.validationError,\n );\n }\n\n const worktreeName = positionals[0];\n const forceDelete = values.force ?? false;\n\n try {\n const gitRoot = await getGitRoot();\n const result = await deleteWorktreeCore(gitRoot, worktreeName, {\n force: forceDelete,\n });\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeNotFoundError\n ? exitCodes.validationError\n : result.error instanceof WorktreeError &&\n result.error.message.includes(\"uncommitted changes\")\n ? exitCodes.validationError\n : exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n output.log(result.value.message);\n exitWithSuccess();\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import {\n executeGitCommand,\n executeGitCommandInDirectory,\n} from \"../git/executor.ts\";\nimport { type Result, err, isOk, ok } from \"../types/result.ts\";\nimport {\n GitOperationError,\n WorktreeError,\n WorktreeNotFoundError,\n} from \"./errors.ts\";\nimport { validateWorktreeExists } from \"./validate.ts\";\n\nexport interface DeleteWorktreeOptions {\n force?: boolean;\n}\n\nexport interface DeleteWorktreeSuccess {\n message: string;\n hasUncommittedChanges?: boolean;\n changedFiles?: number;\n}\n\nexport interface WorktreeStatus {\n hasUncommittedChanges: boolean;\n changedFiles: number;\n}\n\nexport async function getWorktreeStatus(\n worktreePath: string,\n): Promise<WorktreeStatus> {\n try {\n const { stdout } = await executeGitCommandInDirectory(worktreePath, [\n \"status\",\n \"--porcelain\",\n ]);\n if (stdout) {\n return {\n hasUncommittedChanges: true,\n changedFiles: stdout.split(\"\\n\").length,\n };\n }\n } catch {\n // If git status fails, assume no changes\n }\n return {\n hasUncommittedChanges: false,\n changedFiles: 0,\n };\n}\n\nexport async function removeWorktree(\n gitRoot: string,\n worktreePath: string,\n force = false,\n): Promise<void> {\n try {\n await executeGitCommand([\"worktree\", \"remove\", worktreePath], {\n cwd: gitRoot,\n });\n } catch (error) {\n // Always try force removal if the regular removal fails\n try {\n await executeGitCommand([\"worktree\", \"remove\", \"--force\", worktreePath], {\n cwd: gitRoot,\n });\n } catch {\n throw new Error(\"Failed to remove worktree\");\n }\n }\n}\n\nexport async function deleteBranch(\n gitRoot: string,\n branchName: string,\n): Promise<Result<boolean, GitOperationError>> {\n try {\n await executeGitCommand([\"branch\", \"-D\", branchName], { cwd: gitRoot });\n return ok(true);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return err(new GitOperationError(\"branch delete\", errorMessage));\n }\n}\n\nexport async function deleteWorktree(\n gitRoot: string,\n name: string,\n options: DeleteWorktreeOptions = {},\n): Promise<\n Result<\n DeleteWorktreeSuccess,\n WorktreeNotFoundError | WorktreeError | GitOperationError\n >\n> {\n const { force = false } = options;\n\n const validation = await validateWorktreeExists(gitRoot, name);\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(name));\n }\n\n const worktreePath = validation.path as string;\n\n const status = await getWorktreeStatus(worktreePath);\n\n if (status.hasUncommittedChanges && !force) {\n return err(\n new WorktreeError(\n `Worktree '${name}' has uncommitted changes (${status.changedFiles} files). Use --force to delete anyway.`,\n ),\n );\n }\n\n try {\n await removeWorktree(gitRoot, worktreePath, force);\n\n const branchName = name;\n const branchResult = await deleteBranch(gitRoot, branchName);\n\n let message: string;\n if (isOk(branchResult)) {\n message = `Deleted worktree '${name}' and its branch '${branchName}'`;\n } else {\n message = `Deleted worktree '${name}'`;\n message += `\\nNote: Branch '${branchName}' could not be deleted: ${branchResult.error.message}`;\n }\n\n if (status.hasUncommittedChanges) {\n message = `Warning: Worktree '${name}' had uncommitted changes (${status.changedFiles} files)\\n${message}`;\n }\n\n return ok({\n message,\n hasUncommittedChanges: status.hasUncommittedChanges,\n changedFiles: status.hasUncommittedChanges\n ? status.changedFiles\n : undefined,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return err(new GitOperationError(\"worktree remove\", errorMessage));\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { execInWorktree as execInWorktreeCore } from \"../../core/process/exec.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { WorktreeNotFoundError } from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\n\nexport async function execHandler(args: string[]): Promise<void> {\n const { positionals } = parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length < 2) {\n exitWithError(\n \"Usage: phantom exec <worktree-name> <command> [args...]\",\n exitCodes.validationError,\n );\n }\n\n const [worktreeName, ...commandArgs] = positionals;\n\n try {\n const gitRoot = await getGitRoot();\n const result = await execInWorktreeCore(gitRoot, worktreeName, commandArgs);\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeNotFoundError\n ? exitCodes.notFound\n : result.error.exitCode || exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n process.exit(result.value.exitCode);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { listWorktrees as listWorktreesCore } from \"../../core/worktree/list.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function listHandler(args: string[] = []): Promise<void> {\n parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: false,\n });\n try {\n const gitRoot = await getGitRoot();\n const result = await listWorktreesCore(gitRoot);\n\n if (isErr(result)) {\n exitWithError(\"Failed to list worktrees\", exitCodes.generalError);\n }\n\n const { worktrees, message } = result.value;\n\n if (worktrees.length === 0) {\n output.log(message || \"No worktrees found.\");\n process.exit(exitCodes.success);\n }\n\n const maxNameLength = Math.max(...worktrees.map((wt) => wt.name.length));\n\n for (const worktree of worktrees) {\n const paddedName = worktree.name.padEnd(maxNameLength + 2);\n const branchInfo = worktree.branch ? `(${worktree.branch})` : \"\";\n const status = !worktree.isClean ? \" [dirty]\" : \"\";\n\n output.log(`${paddedName} ${branchInfo}${status}`);\n }\n\n process.exit(exitCodes.success);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { executeGitCommandInDirectory } from \"../git/executor.ts\";\nimport { getWorktreePath } from \"../paths.ts\";\nimport { type Result, ok } from \"../types/result.ts\";\nimport {\n listValidWorktrees,\n validatePhantomDirectoryExists,\n} from \"./validate.ts\";\n\nexport interface WorktreeInfo {\n name: string;\n path: string;\n branch: string;\n isClean: boolean;\n}\n\nexport interface ListWorktreesSuccess {\n worktrees: WorktreeInfo[];\n message?: string;\n}\n\nexport async function getWorktreeBranch(worktreePath: string): Promise<string> {\n try {\n const { stdout } = await executeGitCommandInDirectory(worktreePath, [\n \"branch\",\n \"--show-current\",\n ]);\n return stdout || \"(detached HEAD)\";\n } catch {\n return \"unknown\";\n }\n}\n\nexport async function getWorktreeStatus(\n worktreePath: string,\n): Promise<boolean> {\n try {\n const { stdout } = await executeGitCommandInDirectory(worktreePath, [\n \"status\",\n \"--porcelain\",\n ]);\n return !stdout; // Clean if no output\n } catch {\n // If git status fails, assume clean\n return true;\n }\n}\n\nexport async function getWorktreeInfo(\n gitRoot: string,\n name: string,\n): Promise<WorktreeInfo> {\n const worktreePath = getWorktreePath(gitRoot, name);\n\n const [branch, isClean] = await Promise.all([\n getWorktreeBranch(worktreePath),\n getWorktreeStatus(worktreePath),\n ]);\n\n return {\n name,\n path: worktreePath,\n branch,\n isClean,\n };\n}\n\nexport async function listWorktrees(\n gitRoot: string,\n): Promise<Result<ListWorktreesSuccess, never>> {\n if (!(await validatePhantomDirectoryExists(gitRoot))) {\n return ok({\n worktrees: [],\n message: \"No worktrees found (worktrees directory doesn't exist)\",\n });\n }\n\n const worktreeNames = await listValidWorktrees(gitRoot);\n\n if (worktreeNames.length === 0) {\n return ok({\n worktrees: [],\n message: \"No worktrees found\",\n });\n }\n\n try {\n const worktrees = await Promise.all(\n worktreeNames.map((name) => getWorktreeInfo(gitRoot, name)),\n );\n\n return ok({\n worktrees,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to list worktrees: ${errorMessage}`);\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { shellInWorktree as shellInWorktreeCore } from \"../../core/process/shell.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { WorktreeNotFoundError } from \"../../core/worktree/errors.ts\";\nimport { validateWorktreeExists } from \"../../core/worktree/validate.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function shellHandler(args: string[]): Promise<void> {\n const { positionals } = parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Usage: phantom shell <worktree-name>\",\n exitCodes.validationError,\n );\n }\n\n const worktreeName = positionals[0];\n\n try {\n const gitRoot = await getGitRoot();\n\n // Get worktree path for display\n const validation = await validateWorktreeExists(gitRoot, worktreeName);\n if (!validation.exists) {\n exitWithError(\n validation.message || `Worktree '${worktreeName}' not found`,\n exitCodes.generalError,\n );\n }\n\n output.log(`Entering worktree '${worktreeName}' at ${validation.path}`);\n output.log(\"Type 'exit' to return to your original directory\\n\");\n\n const result = await shellInWorktreeCore(gitRoot, worktreeName);\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeNotFoundError\n ? exitCodes.notFound\n : result.error.exitCode || exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n process.exit(result.value.exitCode);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getVersion } from \"../../core/version.ts\";\nimport { exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport function versionHandler(args: string[] = []): void {\n parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: false,\n });\n const version = getVersion();\n output.log(`Phantom v${version}`);\n exitWithSuccess();\n}\n", "{\n \"name\": \"@aku11i/phantom\",\n \"packageManager\": \"pnpm@10.8.1\",\n \"version\": \"0.4.0\",\n \"description\": \"A powerful CLI tool for managing Git worktrees for parallel development\",\n \"keywords\": [\n \"git\",\n \"worktree\",\n \"cli\",\n \"phantom\",\n \"workspace\",\n \"development\",\n \"parallel\"\n ],\n \"homepage\": \"https://github.com/aku11i/phantom#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/aku11i/phantom/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/aku11i/phantom.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"aku11i\",\n \"type\": \"module\",\n \"bin\": {\n \"phantom\": \"./dist/phantom.js\"\n },\n \"scripts\": {\n \"start\": \"node ./src/bin/phantom.ts\",\n \"phantom\": \"node ./src/bin/phantom.ts\",\n \"build\": \"node build.ts\",\n \"type-check\": \"tsgo --noEmit\",\n \"test\": \"node --test --experimental-strip-types --experimental-test-module-mocks src/**/*.test.ts\",\n \"lint\": \"biome check .\",\n \"fix\": \"biome check --write .\",\n \"ready\": \"pnpm fix && pnpm type-check && pnpm test\",\n \"ready:check\": \"pnpm lint && pnpm type-check && pnpm test\",\n \"prepublishOnly\": \"pnpm ready:check && pnpm build\"\n },\n \"engines\": {\n \"node\": \">=22.0.0\"\n },\n \"files\": [\n \"dist/\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.9.4\",\n \"@types/node\": \"^22.15.29\",\n \"@typescript/native-preview\": \"7.0.0-dev.20250602.1\",\n \"esbuild\": \"^0.25.5\",\n \"typescript\": \"^5.8.3\"\n }\n}\n", "import packageJson from \"../../package.json\" with { type: \"json\" };\n\nexport function getVersion(): string {\n return packageJson.version;\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { whereWorktree as whereWorktreeCore } from \"../../core/worktree/where.ts\";\nimport { exitCodes, exitWithError, exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function whereHandler(args: string[]): Promise<void> {\n const { positionals } = parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\"Please provide a worktree name\", exitCodes.validationError);\n }\n\n const worktreeName = positionals[0];\n\n try {\n const gitRoot = await getGitRoot();\n const result = await whereWorktreeCore(gitRoot, worktreeName);\n\n if (isErr(result)) {\n exitWithError(result.error.message, exitCodes.notFound);\n }\n\n output.log(result.value.path);\n exitWithSuccess();\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { type Result, err, ok } from \"../types/result.ts\";\nimport { WorktreeNotFoundError } from \"./errors.ts\";\nimport { validateWorktreeExists } from \"./validate.ts\";\n\nexport interface WhereWorktreeSuccess {\n path: string;\n}\n\nexport async function whereWorktree(\n gitRoot: string,\n name: string,\n): Promise<Result<WhereWorktreeSuccess, WorktreeNotFoundError>> {\n const validation = await validateWorktreeExists(gitRoot, name);\n\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(name));\n }\n\n return ok({\n path: validation.path as string,\n });\n}\n"],
|
|
5
|
-
"mappings": ";;;AAEA,SAAS,MAAM,YAAY;;;ACF3B,SAAS,iBAAiB;;;ACA1B,SAAS,YAAY,wBAAwB;AAC7C,SAAS,iBAAiB;AAE1B,IAAM,WAAW,UAAU,gBAAgB;AAe3C,eAAsB,kBACpBA,OACA,UAA8B,CAAC,GACH;AAC5B,MAAI;AACF,UAAM,SAAS,MAAM,SAAS,OAAOA,OAAM;AAAA,MACzC,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ,OAAO,QAAQ;AAAA,MAC5B,UAAU;AAAA,IACZ,CAAC;AAED,WAAO;AAAA,MACL,QAAQ,OAAO,OAAO,KAAK;AAAA,MAC3B,QAAQ,OAAO,OAAO,KAAK;AAAA,IAC7B;AAAA,EACF,SAAS,OAAO;AAId,QACE,SACA,OAAO,UAAU,YACjB,YAAY,SACZ,YAAY,OACZ;AACA,YAAM,YAAY;AAOlB,UAAI,UAAU,QAAQ,KAAK,GAAG;AAC5B,cAAM,IAAI,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACzC;AAGA,aAAO;AAAA,QACL,QAAQ,UAAU,QAAQ,KAAK,KAAK;AAAA,QACpC,QAAQ,UAAU,QAAQ,KAAK,KAAK;AAAA,MACtC;AAAA,IACF;AAEA,UAAM;AAAA,EACR;AACF;AAKA,eAAsB,6BACpB,WACAA,OAC4B;AAC5B,SAAO,kBAAkB,CAAC,MAAM,WAAW,GAAGA,KAAI,GAAG,CAAC,CAAC;AACzD;;;ACvEA,eAAsB,aAA8B;AAClD,QAAM,EAAE,OAAO,IAAI,MAAM,kBAAkB,CAAC,aAAa,iBAAiB,CAAC;AAC3E,SAAO;AACT;;;ACiBO,IAAM,KAAK,CAAI,WAAgC;AAAA,EACpD,IAAI;AAAA,EACJ;AACF;AAaO,IAAM,MAAM,CAAI,WAAgC;AAAA,EACrD,IAAI;AAAA,EACJ;AACF;AAeO,IAAM,OAAO,CAClB,WACqC,OAAO;AAevC,IAAM,QAAQ,CACnB,WACsC,CAAC,OAAO;;;AC3EzC,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,wBAAN,cAAoC,cAAc;AAAA,EACvD,YAAY,MAAc;AACxB,UAAM,aAAa,IAAI,aAAa;AACpC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,6BAAN,cAAyC,cAAc;AAAA,EAC5D,YAAY,MAAc;AACxB,UAAM,aAAa,IAAI,kBAAkB;AACzC,SAAK,OAAO;AAAA,EACd;AACF;AASO,IAAM,oBAAN,cAAgC,cAAc;AAAA,EACnD,YAAY,WAAmB,SAAiB;AAC9C,UAAM,OAAO,SAAS,YAAY,OAAO,EAAE;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;;;ACjCA,OAAO,QAAQ;;;ACAf,SAAS,YAAY;AAEd,SAAS,oBAAoB,SAAyB;AAC3D,SAAO,KAAK,SAAS,QAAQ,WAAW,WAAW;AACrD;AAEO,SAAS,gBAAgB,SAAiB,MAAsB;AACrE,SAAO,KAAK,oBAAoB,OAAO,GAAG,IAAI;AAChD;;;ADCA,eAAsB,uBACpB,SACA,MAC2B;AAC3B,QAAM,eAAe,gBAAgB,SAAS,IAAI;AAElD,MAAI;AACF,UAAM,GAAG,OAAO,YAAY;AAC5B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,aAAa,IAAI;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,eAAsB,6BACpB,SACA,MAC2B;AAC3B,QAAM,eAAe,gBAAgB,SAAS,IAAI;AAElD,MAAI;AACF,UAAM,GAAG,OAAO,YAAY;AAC5B,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,aAAa,IAAI;AAAA,IAC5B;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,eAAsB,+BACpB,SACkB;AAClB,QAAM,aAAa,oBAAoB,OAAO;AAE9C,MAAI;AACF,UAAM,GAAG,OAAO,UAAU;AAC1B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,mBAAmB,SAAoC;AAC3E,QAAM,aAAa,oBAAoB,OAAO;AAE9C,MAAI,CAAE,MAAM,+BAA+B,OAAO,GAAI;AACpD,WAAO,CAAC;AAAA,EACV;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,GAAG,QAAQ,UAAU;AAC3C,UAAM,iBAA2B,CAAC;AAElC,eAAW,SAAS,SAAS;AAC3B,YAAM,SAAS,MAAM,uBAAuB,SAAS,KAAK;AAC1D,UAAI,OAAO,QAAQ;AACjB,uBAAe,KAAK,KAAK;AAAA,MAC3B;AAAA,IACF;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;AEpFA;AAAA,EAGE,SAAS;AAAA,OACJ;;;ACJA,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtB;AAAA,EAEhB,YAAY,SAAiB,UAAmB;AAC9C,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,WAAW;AAAA,EAClB;AACF;AAEO,IAAM,wBAAN,cAAoC,aAAa;AAAA,EACtD,YAAYC,UAAiB,UAAkB;AAC7C,UAAM,YAAYA,QAAO,2BAA2B,QAAQ,IAAI,QAAQ;AACxE,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,qBAAN,cAAiC,aAAa;AAAA,EACnD,YAAY,QAAgB;AAC1B,UAAM,WAAW,OAAO,WAAW,YAAY,KAAK;AACpD,UAAM,iCAAiC,MAAM,IAAI,QAAQ;AACzD,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,aAAa;AAAA,EAClD,YAAYA,UAAiB,SAAiB;AAC5C,UAAM,4BAA4BA,QAAO,MAAM,OAAO,EAAE;AACxD,SAAK,OAAO;AAAA,EACd;AACF;;;ADPA,eAAsB,aACpB,QAC6C;AAC7C,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,EAAE,SAAAC,UAAS,MAAAC,QAAO,CAAC,GAAG,UAAU,CAAC,EAAE,IAAI;AAE7C,UAAM,eAA6B,UAAUD,UAASC,OAAM;AAAA,MAC1D,OAAO;AAAA,MACP,GAAG;AAAA,IACL,CAAC;AAED,iBAAa,GAAG,SAAS,CAAC,UAAU;AAClC,cAAQ,IAAI,IAAI,kBAAkBD,UAAS,MAAM,OAAO,CAAC,CAAC;AAAA,IAC5D,CAAC;AAED,iBAAa,GAAG,QAAQ,CAAC,MAAM,WAAW;AACxC,UAAI,QAAQ;AACV,gBAAQ,IAAI,IAAI,mBAAmB,MAAM,CAAC,CAAC;AAAA,MAC7C,OAAO;AACL,cAAM,WAAW,QAAQ;AACzB,YAAI,aAAa,GAAG;AAClB,kBAAQ,GAAG,EAAE,SAAS,CAAC,CAAC;AAAA,QAC1B,OAAO;AACL,kBAAQ,IAAI,IAAI,sBAAsBA,UAAS,QAAQ,CAAC,CAAC;AAAA,QAC3D;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;;;AE3CA,eAAsB,eACpB,SACA,cACAE,UAGA;AACA,QAAM,aAAa,MAAM,uBAAuB,SAAS,YAAY;AACrE,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO,IAAI,IAAI,sBAAsB,YAAY,CAAC;AAAA,EACpD;AAEA,QAAM,eAAe,WAAW;AAChC,QAAM,CAAC,KAAK,GAAGC,KAAI,IAAID;AAEvB,SAAO,aAAa;AAAA,IAClB,SAAS;AAAA,IACT,MAAAC;AAAA,IACA,SAAS;AAAA,MACP,KAAK;AAAA,IACP;AAAA,EACF,CAAC;AACH;;;ACtBA,eAAsB,gBACpB,SACA,cAGA;AACA,QAAM,aAAa,MAAM,uBAAuB,SAAS,YAAY;AACrE,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO,IAAI,IAAI,sBAAsB,YAAY,CAAC;AAAA,EACpD;AAEA,QAAM,eAAe,WAAW;AAChC,QAAM,QAAQ,QAAQ,IAAI,SAAS;AAEnC,SAAO,aAAa;AAAA,IAClB,SAAS;AAAA,IACT,MAAM,CAAC;AAAA,IACP,SAAS;AAAA,MACP,KAAK;AAAA,MACL,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,SAAS;AAAA,QACT,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACnCA,OAAOC,SAAQ;;;ACQf,eAAsB,YAAY,SAA4C;AAC5E,QAAM,EAAE,MAAM,QAAQ,YAAY,OAAO,IAAI;AAE7C,QAAM,kBAAkB,CAAC,YAAY,OAAO,MAAM,MAAM,QAAQ,SAAS,CAAC;AAC5E;;;ADKA,eAAsB,eACpB,SACA,MACA,UAAiC,CAAC,GAGlC;AACA,QAAM,EAAE,SAAS,MAAM,YAAY,OAAO,IAAI;AAE9C,QAAM,gBAAgB,oBAAoB,OAAO;AACjD,QAAM,eAAe,gBAAgB,SAAS,IAAI;AAElD,MAAI;AACF,UAAMC,IAAG,OAAO,aAAa;AAAA,EAC/B,QAAQ;AACN,UAAMA,IAAG,MAAM,eAAe,EAAE,WAAW,KAAK,CAAC;AAAA,EACnD;AAEA,QAAM,aAAa,MAAM,6BAA6B,SAAS,IAAI;AACnE,MAAI,WAAW,QAAQ;AACrB,WAAO,IAAI,IAAI,2BAA2B,IAAI,CAAC;AAAA,EACjD;AAEA,MAAI;AACF,UAAM,YAAY;AAAA,MAChB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,CAAC;AAED,WAAO,GAAG;AAAA,MACR,SAAS,qBAAqB,IAAI,QAAQ,YAAY;AAAA,MACtD,MAAM;AAAA,IACR,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,WAAO,IAAI,IAAI,kBAAkB,gBAAgB,YAAY,CAAC;AAAA,EAChE;AACF;;;AErDO,IAAM,SAAS;AAAA,EACpB,KAAK,CAAC,YAAoB;AACxB,YAAQ,IAAI,OAAO;AAAA,EACrB;AAAA,EAEA,OAAO,CAAC,YAAoB;AAC1B,YAAQ,MAAM,OAAO;AAAA,EACvB;AAAA,EAEA,OAAO,CAAC,SAAkB;AACxB,YAAQ,MAAM,IAAI;AAAA,EACpB;AAAA,EAEA,eAAe,CAAC,SAAuB;AACrC,SAAK,QAAQ,KAAK,QAAQ,MAAM;AAChC,SAAK,QAAQ,KAAK,QAAQ,MAAM;AAAA,EAClC;AACF;;;ACjBO,IAAM,YAAY;AAAA,EACvB,SAAS;AAAA,EACT,cAAc;AAAA,EACd,UAAU;AAAA,EACV,iBAAiB;AACnB;AAcO,SAAS,kBAAyB;AACvC,UAAQ,KAAK,UAAU,OAAO;AAChC;AAEO,SAAS,cACd,SACA,WAAmB,UAAU,cACtB;AACP,SAAO,MAAM,OAAO;AACpB,UAAQ,KAAK,QAAQ;AACvB;;;AdrBA,eAAsB,cAAcC,OAA+B;AACjE,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU;AAAA,IACxC,MAAAA;AAAA,IACA,SAAS;AAAA,MACP,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,YAAY,WAAW,GAAG;AAC5B;AAAA,MACE;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,eAAe,YAAY,CAAC;AAClC,QAAM,YAAY,OAAO,SAAS;AAClC,QAAM,cAAc,OAAO;AAE3B,MAAI,aAAa,aAAa;AAC5B;AAAA,MACE;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,SAAS,MAAM,eAAmB,SAAS,YAAY;AAE7D,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,WACJ,OAAO,iBAAiB,6BACpB,UAAU,kBACV,UAAU;AAChB,oBAAc,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9C;AAEA,WAAO,IAAI,OAAO,MAAM,OAAO;AAE/B,QAAI,eAAe,KAAK,MAAM,GAAG;AAC/B,aAAO;AAAA,QACL;AAAA,iCAAoC,YAAY,MAAM,WAAW;AAAA,MACnE;AAEA,YAAM,QAAQ,QAAQ,IAAI,SAAS;AACnC,YAAM,aAAa,MAAM,eAAe,SAAS,cAAc;AAAA,QAC7D;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,UAAI,MAAM,UAAU,GAAG;AACrB,eAAO,MAAM,WAAW,MAAM,OAAO;AACrC,cAAM,WACJ,cAAc,WAAW,QACpB,WAAW,MAAM,YAAY,UAAU,eACxC,UAAU;AAChB,sBAAc,IAAI,QAAQ;AAAA,MAC5B;AAEA,cAAQ,KAAK,WAAW,MAAM,YAAY,CAAC;AAAA,IAC7C;AAEA,QAAI,aAAa,KAAK,MAAM,GAAG;AAC7B,aAAO;AAAA,QACL;AAAA,qBAAwB,YAAY,QAAQ,OAAO,MAAM,IAAI;AAAA,MAC/D;AACA,aAAO,IAAI,oDAAoD;AAE/D,YAAM,cAAc,MAAM,gBAAgB,SAAS,YAAY;AAE/D,UAAI,MAAM,WAAW,GAAG;AACtB,eAAO,MAAM,YAAY,MAAM,OAAO;AACtC,cAAM,WACJ,cAAc,YAAY,QACrB,YAAY,MAAM,YAAY,UAAU,eACzC,UAAU;AAChB,sBAAc,IAAI,QAAQ;AAAA,MAC5B;AAEA,cAAQ,KAAK,YAAY,MAAM,YAAY,CAAC;AAAA,IAC9C;AAEA,oBAAgB;AAAA,EAClB,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;Ae9GA,SAAS,aAAAC,kBAAiB;;;AC2B1B,eAAsB,kBACpB,cACyB;AACzB,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,6BAA6B,cAAc;AAAA,MAClE;AAAA,MACA;AAAA,IACF,CAAC;AACD,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,uBAAuB;AAAA,QACvB,cAAc,OAAO,MAAM,IAAI,EAAE;AAAA,MACnC;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AAAA,IACL,uBAAuB;AAAA,IACvB,cAAc;AAAA,EAChB;AACF;AAEA,eAAsB,eACpB,SACA,cACA,QAAQ,OACO;AACf,MAAI;AACF,UAAM,kBAAkB,CAAC,YAAY,UAAU,YAAY,GAAG;AAAA,MAC5D,KAAK;AAAA,IACP,CAAC;AAAA,EACH,SAAS,OAAO;AAEd,QAAI;AACF,YAAM,kBAAkB,CAAC,YAAY,UAAU,WAAW,YAAY,GAAG;AAAA,QACvE,KAAK;AAAA,MACP,CAAC;AAAA,IACH,QAAQ;AACN,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAAA,EACF;AACF;AAEA,eAAsB,aACpB,SACA,YAC6C;AAC7C,MAAI;AACF,UAAM,kBAAkB,CAAC,UAAU,MAAM,UAAU,GAAG,EAAE,KAAK,QAAQ,CAAC;AACtE,WAAO,GAAG,IAAI;AAAA,EAChB,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,WAAO,IAAI,IAAI,kBAAkB,iBAAiB,YAAY,CAAC;AAAA,EACjE;AACF;AAEA,eAAsB,eACpB,SACA,MACA,UAAiC,CAAC,GAMlC;AACA,QAAM,EAAE,QAAQ,MAAM,IAAI;AAE1B,QAAM,aAAa,MAAM,uBAAuB,SAAS,IAAI;AAC7D,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO,IAAI,IAAI,sBAAsB,IAAI,CAAC;AAAA,EAC5C;AAEA,QAAM,eAAe,WAAW;AAEhC,QAAM,SAAS,MAAM,kBAAkB,YAAY;AAEnD,MAAI,OAAO,yBAAyB,CAAC,OAAO;AAC1C,WAAO;AAAA,MACL,IAAI;AAAA,QACF,aAAa,IAAI,8BAA8B,OAAO,YAAY;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAM,eAAe,SAAS,cAAc,KAAK;AAEjD,UAAM,aAAa;AACnB,UAAM,eAAe,MAAM,aAAa,SAAS,UAAU;AAE3D,QAAI;AACJ,QAAI,KAAK,YAAY,GAAG;AACtB,gBAAU,qBAAqB,IAAI,qBAAqB,UAAU;AAAA,IACpE,OAAO;AACL,gBAAU,qBAAqB,IAAI;AACnC,iBAAW;AAAA,gBAAmB,UAAU,2BAA2B,aAAa,MAAM,OAAO;AAAA,IAC/F;AAEA,QAAI,OAAO,uBAAuB;AAChC,gBAAU,sBAAsB,IAAI,8BAA8B,OAAO,YAAY;AAAA,EAAY,OAAO;AAAA,IAC1G;AAEA,WAAO,GAAG;AAAA,MACR;AAAA,MACA,uBAAuB,OAAO;AAAA,MAC9B,cAAc,OAAO,wBACjB,OAAO,eACP;AAAA,IACN,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,WAAO,IAAI,IAAI,kBAAkB,mBAAmB,YAAY,CAAC;AAAA,EACnE;AACF;;;ADnIA,eAAsB,cAAcC,OAA+B;AACjE,QAAM,EAAE,QAAQ,YAAY,IAAIC,WAAU;AAAA,IACxC,MAAAD;AAAA,IACA,SAAS;AAAA,MACP,OAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,YAAY,WAAW,GAAG;AAC5B;AAAA,MACE;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,eAAe,YAAY,CAAC;AAClC,QAAM,cAAc,OAAO,SAAS;AAEpC,MAAI;AACF,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,SAAS,MAAM,eAAmB,SAAS,cAAc;AAAA,MAC7D,OAAO;AAAA,IACT,CAAC;AAED,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,WACJ,OAAO,iBAAiB,wBACpB,UAAU,kBACV,OAAO,iBAAiB,iBACtB,OAAO,MAAM,QAAQ,SAAS,qBAAqB,IACnD,UAAU,kBACV,UAAU;AAClB,oBAAc,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9C;AAEA,WAAO,IAAI,OAAO,MAAM,OAAO;AAC/B,oBAAgB;AAAA,EAClB,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;AE3DA,SAAS,aAAAE,kBAAiB;AAO1B,eAAsB,YAAYC,OAA+B;AAC/D,QAAM,EAAE,YAAY,IAAIC,WAAU;AAAA,IAChC,MAAAD;AAAA,IACA,SAAS,CAAC;AAAA,IACV,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,YAAY,SAAS,GAAG;AAC1B;AAAA,MACE;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,CAAC,cAAc,GAAG,WAAW,IAAI;AAEvC,MAAI;AACF,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,SAAS,MAAM,eAAmB,SAAS,cAAc,WAAW;AAE1E,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,WACJ,OAAO,iBAAiB,wBACpB,UAAU,WACV,OAAO,MAAM,YAAY,UAAU;AACzC,oBAAc,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9C;AAEA,YAAQ,KAAK,OAAO,MAAM,QAAQ;AAAA,EACpC,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;AC3CA,SAAS,aAAAE,kBAAiB;;;ACoB1B,eAAsB,kBAAkB,cAAuC;AAC7E,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,6BAA6B,cAAc;AAAA,MAClE;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,UAAU;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAsBC,mBACpB,cACkB;AAClB,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAM,6BAA6B,cAAc;AAAA,MAClE;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,CAAC;AAAA,EACV,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBACpB,SACA,MACuB;AACvB,QAAM,eAAe,gBAAgB,SAAS,IAAI;AAElD,QAAM,CAAC,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,IAC1C,kBAAkB,YAAY;AAAA,IAC9BA,mBAAkB,YAAY;AAAA,EAChC,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,cACpB,SAC8C;AAC9C,MAAI,CAAE,MAAM,+BAA+B,OAAO,GAAI;AACpD,WAAO,GAAG;AAAA,MACR,WAAW,CAAC;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,QAAM,gBAAgB,MAAM,mBAAmB,OAAO;AAEtD,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO,GAAG;AAAA,MACR,WAAW,CAAC;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI;AACF,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,cAAc,IAAI,CAAC,SAAS,gBAAgB,SAAS,IAAI,CAAC;AAAA,IAC5D;AAEA,WAAO,GAAG;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,UAAM,IAAI,MAAM,6BAA6B,YAAY,EAAE;AAAA,EAC7D;AACF;;;AD1FA,eAAsB,YAAYC,QAAiB,CAAC,GAAkB;AACpE,EAAAC,WAAU;AAAA,IACR,MAAAD;AAAA,IACA,SAAS,CAAC;AAAA,IACV,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AACD,MAAI;AACF,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,SAAS,MAAM,cAAkB,OAAO;AAE9C,QAAI,MAAM,MAAM,GAAG;AACjB,oBAAc,4BAA4B,UAAU,YAAY;AAAA,IAClE;AAEA,UAAM,EAAE,WAAW,QAAQ,IAAI,OAAO;AAEtC,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,IAAI,WAAW,qBAAqB;AAC3C,cAAQ,KAAK,UAAU,OAAO;AAAA,IAChC;AAEA,UAAM,gBAAgB,KAAK,IAAI,GAAG,UAAU,IAAI,CAAC,OAAO,GAAG,KAAK,MAAM,CAAC;AAEvE,eAAW,YAAY,WAAW;AAChC,YAAM,aAAa,SAAS,KAAK,OAAO,gBAAgB,CAAC;AACzD,YAAM,aAAa,SAAS,SAAS,IAAI,SAAS,MAAM,MAAM;AAC9D,YAAM,SAAS,CAAC,SAAS,UAAU,aAAa;AAEhD,aAAO,IAAI,GAAG,UAAU,IAAI,UAAU,GAAG,MAAM,EAAE;AAAA,IACnD;AAEA,YAAQ,KAAK,UAAU,OAAO;AAAA,EAChC,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;AE9CA,SAAS,aAAAE,kBAAiB;AAS1B,eAAsB,aAAaC,OAA+B;AAChE,QAAM,EAAE,YAAY,IAAIC,WAAU;AAAA,IAChC,MAAAD;AAAA,IACA,SAAS,CAAC;AAAA,IACV,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,YAAY,WAAW,GAAG;AAC5B;AAAA,MACE;AAAA,MACA,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,QAAM,eAAe,YAAY,CAAC;AAElC,MAAI;AACF,UAAM,UAAU,MAAM,WAAW;AAGjC,UAAM,aAAa,MAAM,uBAAuB,SAAS,YAAY;AACrE,QAAI,CAAC,WAAW,QAAQ;AACtB;AAAA,QACE,WAAW,WAAW,aAAa,YAAY;AAAA,QAC/C,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,IAAI,sBAAsB,YAAY,QAAQ,WAAW,IAAI,EAAE;AACtE,WAAO,IAAI,oDAAoD;AAE/D,UAAM,SAAS,MAAM,gBAAoB,SAAS,YAAY;AAE9D,QAAI,MAAM,MAAM,GAAG;AACjB,YAAM,WACJ,OAAO,iBAAiB,wBACpB,UAAU,WACV,OAAO,MAAM,YAAY,UAAU;AACzC,oBAAc,OAAO,MAAM,SAAS,QAAQ;AAAA,IAC9C;AAEA,YAAQ,KAAK,OAAO,MAAM,QAAQ;AAAA,EACpC,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;AC1DA,SAAS,aAAAE,kBAAiB;;;ACA1B;AAAA,EACE,MAAQ;AAAA,EACR,gBAAkB;AAAA,EAClB,SAAW;AAAA,EACX,aAAe;AAAA,EACf,UAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,UAAY;AAAA,EACZ,MAAQ;AAAA,IACN,KAAO;AAAA,EACT;AAAA,EACA,YAAc;AAAA,IACZ,MAAQ;AAAA,IACR,KAAO;AAAA,EACT;AAAA,EACA,SAAW;AAAA,EACX,QAAU;AAAA,EACV,MAAQ;AAAA,EACR,KAAO;AAAA,IACL,SAAW;AAAA,EACb;AAAA,EACA,SAAW;AAAA,IACT,OAAS;AAAA,IACT,SAAW;AAAA,IACX,OAAS;AAAA,IACT,cAAc;AAAA,IACd,MAAQ;AAAA,IACR,MAAQ;AAAA,IACR,KAAO;AAAA,IACP,OAAS;AAAA,IACT,eAAe;AAAA,IACf,gBAAkB;AAAA,EACpB;AAAA,EACA,SAAW;AAAA,IACT,MAAQ;AAAA,EACV;AAAA,EACA,OAAS;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,iBAAmB;AAAA,IACjB,kBAAkB;AAAA,IAClB,eAAe;AAAA,IACf,8BAA8B;AAAA,IAC9B,SAAW;AAAA,IACX,YAAc;AAAA,EAChB;AACF;;;ACrDO,SAAS,aAAqB;AACnC,SAAO,gBAAY;AACrB;;;AFCO,SAAS,eAAeC,QAAiB,CAAC,GAAS;AACxD,EAAAC,WAAU;AAAA,IACR,MAAAD;AAAA,IACA,SAAS,CAAC;AAAA,IACV,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AACD,QAAM,UAAU,WAAW;AAC3B,SAAO,IAAI,YAAY,OAAO,EAAE;AAChC,kBAAgB;AAClB;;;AGfA,SAAS,aAAAE,kBAAiB;;;ACQ1B,eAAsB,cACpB,SACA,MAC8D;AAC9D,QAAM,aAAa,MAAM,uBAAuB,SAAS,IAAI;AAE7D,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO,IAAI,IAAI,sBAAsB,IAAI,CAAC;AAAA,EAC5C;AAEA,SAAO,GAAG;AAAA,IACR,MAAM,WAAW;AAAA,EACnB,CAAC;AACH;;;ADdA,eAAsB,aAAaC,OAA+B;AAChE,QAAM,EAAE,YAAY,IAAIC,WAAU;AAAA,IAChC,MAAAD;AAAA,IACA,SAAS,CAAC;AAAA,IACV,QAAQ;AAAA,IACR,kBAAkB;AAAA,EACpB,CAAC;AAED,MAAI,YAAY,WAAW,GAAG;AAC5B,kBAAc,kCAAkC,UAAU,eAAe;AAAA,EAC3E;AAEA,QAAM,eAAe,YAAY,CAAC;AAElC,MAAI;AACF,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,SAAS,MAAM,cAAkB,SAAS,YAAY;AAE5D,QAAI,MAAM,MAAM,GAAG;AACjB,oBAAc,OAAO,MAAM,SAAS,UAAU,QAAQ;AAAA,IACxD;AAEA,WAAO,IAAI,OAAO,MAAM,IAAI;AAC5B,oBAAgB;AAAA,EAClB,SAAS,OAAO;AACd;AAAA,MACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AACF;;;AzBnBA,IAAM,WAAsB;AAAA,EAC1B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AACF;AAEA,SAAS,UAAUE,WAAqB;AACtC,UAAQ,IAAI,sCAAsC;AAClD,UAAQ,IAAI,WAAW;AACvB,aAAW,OAAOA,WAAU;AAC1B,YAAQ,IAAI,KAAK,IAAI,KAAK,OAAO,EAAE,CAAC,IAAI,IAAI,WAAW,EAAE;AAAA,EAC3D;AACF;AAEA,SAAS,YACPC,OACAD,WACsD;AACtD,MAAIC,MAAK,WAAW,GAAG;AACrB,WAAO,EAAE,SAAS,MAAM,eAAe,CAAC,EAAE;AAAA,EAC5C;AAEA,QAAM,CAAC,SAAS,GAAG,IAAI,IAAIA;AAC3B,QAAMC,WAAUF,UAAS,KAAK,CAAC,QAAQ,IAAI,SAAS,OAAO;AAE3D,MAAI,CAACE,UAAS;AACZ,WAAO,EAAE,SAAS,MAAM,eAAeD,MAAK;AAAA,EAC9C;AAEA,MAAIC,SAAQ,eAAe,KAAK,SAAS,GAAG;AAC1C,UAAM,EAAE,SAAS,YAAY,eAAAC,eAAc,IAAI;AAAA,MAC7C;AAAA,MACAD,SAAQ;AAAA,IACV;AACA,QAAI,YAAY;AACd,aAAO,EAAE,SAAS,YAAY,eAAAC,eAAc;AAAA,IAC9C;AAAA,EACF;AAEA,SAAO,EAAE,SAAAD,UAAS,eAAe,KAAK;AACxC;AAEA,IAAM,OAAO,KAAK,MAAM,CAAC;AAEzB,IAAI,KAAK,WAAW,KAAK,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,MAAM,UAAU;AACjE,YAAU,QAAQ;AAClB,OAAK,CAAC;AACR;AAEA,IAAI,KAAK,CAAC,MAAM,eAAe,KAAK,CAAC,MAAM,MAAM;AAC/C,iBAAe;AACf,OAAK,CAAC;AACR;AAEA,IAAM,EAAE,SAAS,cAAc,IAAI,YAAY,MAAM,QAAQ;AAE7D,IAAI,CAAC,WAAW,CAAC,QAAQ,SAAS;AAChC,UAAQ,MAAM,2BAA2B,KAAK,KAAK,GAAG,CAAC;AAAA,CAAK;AAC5D,YAAU,QAAQ;AAClB,OAAK,CAAC;AACR;AAEA,IAAI;AACF,QAAM,QAAQ,QAAQ,aAAa;AACrC,SAAS,OAAO;AACd,UAAQ;AAAA,IACN;AAAA,IACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EACvD;AACA,OAAK,CAAC;AACR;",
|
|
6
|
-
"names": ["args", "command", "command", "args", "command", "args", "fs", "fs", "args", "parseArgs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "parseArgs", "getWorktreeStatus", "args", "parseArgs", "parseArgs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "commands", "args", "command", "remainingArgs"]
|
|
3
|
+
"sources": ["../src/bin/phantom.ts", "../src/cli/handlers/attach.ts", "../src/core/git/libs/get-git-root.ts", "../src/core/git/executor.ts", "../src/core/types/result.ts", "../src/core/worktree/errors.ts", "../src/core/worktree/validate.ts", "../src/core/paths.ts", "../src/core/process/spawn.ts", "../src/core/process/errors.ts", "../src/core/process/exec.ts", "../src/core/process/shell.ts", "../src/core/worktree/attach.ts", "../src/core/git/libs/attach-worktree.ts", "../src/core/git/libs/branch-exists.ts", "../src/cli/output.ts", "../src/cli/errors.ts", "../src/cli/handlers/create.ts", "../src/core/worktree/create.ts", "../src/core/git/libs/add-worktree.ts", "../src/cli/handlers/delete.ts", "../src/core/worktree/delete.ts", "../src/cli/handlers/exec.ts", "../src/cli/handlers/list.ts", "../src/core/git/libs/list-worktrees.ts", "../src/core/worktree/list.ts", "../src/cli/handlers/shell.ts", "../src/cli/handlers/version.ts", "../package.json", "../src/core/version.ts", "../src/cli/handlers/where.ts", "../src/core/worktree/where.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport { argv, exit } from \"node:process\";\nimport { attachHandler } from \"../cli/handlers/attach.ts\";\nimport { createHandler } from \"../cli/handlers/create.ts\";\nimport { deleteHandler } from \"../cli/handlers/delete.ts\";\nimport { execHandler } from \"../cli/handlers/exec.ts\";\nimport { listHandler } from \"../cli/handlers/list.ts\";\nimport { shellHandler } from \"../cli/handlers/shell.ts\";\nimport { versionHandler } from \"../cli/handlers/version.ts\";\nimport { whereHandler } from \"../cli/handlers/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: \"create\",\n description: \"Create a new worktree [--shell | --exec <command>]\",\n handler: createHandler,\n },\n {\n name: \"attach\",\n description: \"Attach to an existing branch [--shell | --exec <command>]\",\n handler: attachHandler,\n },\n {\n name: \"list\",\n description: \"List all worktrees\",\n handler: listHandler,\n },\n {\n name: \"where\",\n description: \"Output the path of a specific worktree\",\n handler: whereHandler,\n },\n {\n name: \"delete\",\n description: \"Delete a worktree (use --force for uncommitted changes)\",\n handler: deleteHandler,\n },\n {\n name: \"exec\",\n description: \"Execute a command in a worktree directory\",\n handler: execHandler,\n },\n {\n name: \"shell\",\n description: \"Open interactive shell in a worktree directory\",\n handler: shellHandler,\n },\n {\n name: \"version\",\n description: \"Display phantom version\",\n handler: versionHandler,\n },\n];\n\nfunction printHelp(commands: Command[]) {\n console.log(\"Usage: phantom <command> [options]\\n\");\n console.log(\"Commands:\");\n for (const cmd of commands) {\n console.log(` ${cmd.name.padEnd(12)} ${cmd.description}`);\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\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n versionHandler();\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 { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { execInWorktree } from \"../../core/process/exec.ts\";\nimport { shellInWorktree } from \"../../core/process/shell.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { attachWorktreeCore } from \"../../core/worktree/attach.ts\";\nimport {\n BranchNotFoundError,\n WorktreeAlreadyExistsError,\n} from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function attachHandler(args: string[]): Promise<void> {\n const { positionals, values } = parseArgs({\n args,\n strict: true,\n allowPositionals: true,\n options: {\n shell: {\n type: \"boolean\",\n short: \"s\",\n },\n exec: {\n type: \"string\",\n short: \"e\",\n },\n },\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Missing required argument: branch name\",\n exitCodes.validationError,\n );\n }\n\n const [branchName] = positionals;\n\n if (values.shell && values.exec) {\n exitWithError(\n \"Cannot use both --shell and --exec options\",\n exitCodes.validationError,\n );\n }\n\n const gitRoot = await getGitRoot();\n const result = await attachWorktreeCore(gitRoot, branchName);\n\n if (isErr(result)) {\n const error = result.error;\n if (error instanceof WorktreeAlreadyExistsError) {\n exitWithError(error.message, exitCodes.validationError);\n }\n if (error instanceof BranchNotFoundError) {\n exitWithError(error.message, exitCodes.notFound);\n }\n exitWithError(error.message, exitCodes.generalError);\n }\n\n const worktreePath = result.value;\n output.log(`Attached phantom: ${branchName}`);\n\n if (values.shell) {\n const shellResult = await shellInWorktree(gitRoot, branchName);\n if (isErr(shellResult)) {\n exitWithError(shellResult.error.message, exitCodes.generalError);\n }\n } else if (values.exec) {\n const execResult = await execInWorktree(\n gitRoot,\n branchName,\n values.exec.split(\" \"),\n );\n if (isErr(execResult)) {\n exitWithError(execResult.error.message, exitCodes.generalError);\n }\n }\n}\n", "import { dirname, resolve } from \"node:path\";\nimport { executeGitCommand } from \"../executor.ts\";\n\nexport async function getGitRoot(): Promise<string> {\n const { stdout } = await executeGitCommand([\"rev-parse\", \"--git-common-dir\"]);\n\n if (stdout.endsWith(\"/.git\") || stdout === \".git\") {\n return resolve(process.cwd(), dirname(stdout));\n }\n\n const { stdout: toplevel } = await executeGitCommand([\n \"rev-parse\",\n \"--show-toplevel\",\n ]);\n return toplevel;\n}\n", "import { execFile as execFileCallback } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFile = promisify(execFileCallback);\n\nexport interface GitExecutorOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface GitExecutorResult {\n stdout: string;\n stderr: string;\n}\n\n/**\n * Execute a git command with consistent error handling\n */\nexport async function executeGitCommand(\n args: string[],\n options: GitExecutorOptions = {},\n): Promise<GitExecutorResult> {\n try {\n const result = await execFile(\"git\", args, {\n cwd: options.cwd,\n env: options.env || process.env,\n encoding: \"utf8\",\n });\n\n return {\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n };\n } catch (error) {\n // Git commands often return non-zero exit codes for normal operations\n // (e.g., `git diff` returns 1 when there are differences)\n // So we need to handle errors carefully\n if (\n error &&\n typeof error === \"object\" &&\n \"stdout\" in error &&\n \"stderr\" in error\n ) {\n const execError = error as {\n stdout: string;\n stderr: string;\n code?: number;\n };\n\n // If we have stderr content, it's likely a real error\n if (execError.stderr?.trim()) {\n throw new Error(execError.stderr.trim());\n }\n\n // Otherwise, return the output even though the exit code was non-zero\n return {\n stdout: execError.stdout?.trim() || \"\",\n stderr: execError.stderr?.trim() || \"\",\n };\n }\n\n throw error;\n }\n}\n\n/**\n * Execute a git command in a specific directory\n */\nexport async function executeGitCommandInDirectory(\n directory: string,\n args: string[],\n): Promise<GitExecutorResult> {\n return executeGitCommand([\"-C\", directory, ...args], {});\n}\n", "/**\n * Represents a value that is either successful (Ok) or contains an error (Err).\n * This type is inspired by Rust's Result type and provides type-safe error handling.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value (defaults to Error)\n */\nexport type Result<T, E = Error> =\n | { ok: true; value: T }\n | { ok: false; error: E };\n\n/**\n * Creates a successful Result containing the given value.\n *\n * @template T - The type of the success value\n * @param value - The success value to wrap\n * @returns A Result in the Ok state containing the value\n *\n * @example\n * const result = ok(42);\n * // result: Result<number, never> = { ok: true, value: 42 }\n */\nexport const ok = <T>(value: T): Result<T, never> => ({\n ok: true,\n value,\n});\n\n/**\n * Creates a failed Result containing the given error.\n *\n * @template E - The type of the error value\n * @param error - The error value to wrap\n * @returns A Result in the Err state containing the error\n *\n * @example\n * const result = err(new Error(\"Something went wrong\"));\n * // result: Result<never, Error> = { ok: false, error: Error(...) }\n */\nexport const err = <E>(error: E): Result<never, E> => ({\n ok: false,\n error,\n});\n\n/**\n * Type guard that checks if a Result is in the Ok state.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value\n * @param result - The Result to check\n * @returns True if the Result is Ok, false otherwise\n *\n * @example\n * if (isOk(result)) {\n * console.log(result.value); // TypeScript knows result.value exists\n * }\n */\nexport const isOk = <T, E>(\n result: Result<T, E>,\n): result is { ok: true; value: T } => result.ok;\n\n/**\n * Type guard that checks if a Result is in the Err state.\n *\n * @template T - The type of the success value\n * @template E - The type of the error value\n * @param result - The Result to check\n * @returns True if the Result is Err, false otherwise\n *\n * @example\n * if (isErr(result)) {\n * console.error(result.error); // TypeScript knows result.error exists\n * }\n */\nexport const isErr = <T, E>(\n result: Result<T, E>,\n): result is { ok: false; error: E } => !result.ok;\n", "export class WorktreeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"WorktreeError\";\n }\n}\n\nexport class WorktreeNotFoundError extends WorktreeError {\n constructor(name: string) {\n super(`Worktree '${name}' not found`);\n this.name = \"WorktreeNotFoundError\";\n }\n}\n\nexport class WorktreeAlreadyExistsError extends WorktreeError {\n constructor(name: string) {\n super(`Worktree '${name}' already exists`);\n this.name = \"WorktreeAlreadyExistsError\";\n }\n}\n\nexport class InvalidWorktreeNameError extends WorktreeError {\n constructor(name: string) {\n super(`Invalid worktree name: '${name}'`);\n this.name = \"InvalidWorktreeNameError\";\n }\n}\n\nexport class GitOperationError extends WorktreeError {\n constructor(operation: string, details: string) {\n super(`Git ${operation} failed: ${details}`);\n this.name = \"GitOperationError\";\n }\n}\n\nexport class BranchNotFoundError extends WorktreeError {\n constructor(branchName: string) {\n super(`Branch '${branchName}' not found`);\n this.name = \"BranchNotFoundError\";\n }\n}\n", "import fs from \"node:fs/promises\";\nimport { getPhantomDirectory, getWorktreePath } from \"../paths.ts\";\nimport { type Result, err, ok } from \"../types/result.ts\";\n\nexport interface ValidationResult {\n exists: boolean;\n path?: string;\n message?: string;\n}\n\nexport async function validateWorktreeExists(\n gitRoot: string,\n name: string,\n): Promise<ValidationResult> {\n const worktreePath = getWorktreePath(gitRoot, name);\n\n try {\n await fs.access(worktreePath);\n return {\n exists: true,\n path: worktreePath,\n };\n } catch {\n return {\n exists: false,\n message: `Worktree '${name}' does not exist`,\n };\n }\n}\n\nexport async function validateWorktreeDoesNotExist(\n gitRoot: string,\n name: string,\n): Promise<ValidationResult> {\n const worktreePath = getWorktreePath(gitRoot, name);\n\n try {\n await fs.access(worktreePath);\n return {\n exists: true,\n message: `Worktree '${name}' already exists`,\n };\n } catch {\n return {\n exists: false,\n path: worktreePath,\n };\n }\n}\n\nexport async function validatePhantomDirectoryExists(\n gitRoot: string,\n): Promise<boolean> {\n const phantomDir = getPhantomDirectory(gitRoot);\n\n try {\n await fs.access(phantomDir);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function validateWorktreeName(name: string): Result<void, Error> {\n if (!name || name.trim() === \"\") {\n return err(new Error(\"Phantom name cannot be empty\"));\n }\n\n if (name.includes(\"/\")) {\n return err(new Error(\"Phantom name cannot contain slashes\"));\n }\n\n if (name.startsWith(\".\")) {\n return err(new Error(\"Phantom name cannot start with a dot\"));\n }\n\n return ok(undefined);\n}\n", "import { join } from \"node:path\";\n\nexport function getPhantomDirectory(gitRoot: string): string {\n return join(gitRoot, \".git\", \"phantom\", \"worktrees\");\n}\n\nexport function getWorktreePath(gitRoot: string, name: string): string {\n return join(getPhantomDirectory(gitRoot), name);\n}\n", "import {\n type ChildProcess,\n type SpawnOptions,\n spawn as nodeSpawn,\n} from \"node:child_process\";\nimport { type Result, err, ok } from \"../types/result.ts\";\nimport {\n type ProcessError,\n ProcessExecutionError,\n ProcessSignalError,\n ProcessSpawnError,\n} from \"./errors.ts\";\n\nexport interface SpawnSuccess {\n exitCode: number;\n}\n\nexport interface SpawnConfig {\n command: string;\n args?: string[];\n options?: SpawnOptions;\n}\n\nexport async function spawnProcess(\n config: SpawnConfig,\n): Promise<Result<SpawnSuccess, ProcessError>> {\n return new Promise((resolve) => {\n const { command, args = [], options = {} } = config;\n\n const childProcess: ChildProcess = nodeSpawn(command, args, {\n stdio: \"inherit\",\n ...options,\n });\n\n childProcess.on(\"error\", (error) => {\n resolve(err(new ProcessSpawnError(command, error.message)));\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve(err(new ProcessSignalError(signal)));\n } else {\n const exitCode = code ?? 0;\n if (exitCode === 0) {\n resolve(ok({ exitCode }));\n } else {\n resolve(err(new ProcessExecutionError(command, exitCode)));\n }\n }\n });\n });\n}\n", "export class ProcessError extends Error {\n public readonly exitCode?: number;\n\n constructor(message: string, exitCode?: number) {\n super(message);\n this.name = \"ProcessError\";\n this.exitCode = exitCode;\n }\n}\n\nexport class ProcessExecutionError extends ProcessError {\n constructor(command: string, exitCode: number) {\n super(`Command '${command}' failed with exit code ${exitCode}`, exitCode);\n this.name = \"ProcessExecutionError\";\n }\n}\n\nexport class ProcessSignalError extends ProcessError {\n constructor(signal: string) {\n const exitCode = 128 + (signal === \"SIGTERM\" ? 15 : 1);\n super(`Command terminated by signal: ${signal}`, exitCode);\n this.name = \"ProcessSignalError\";\n }\n}\n\nexport class ProcessSpawnError extends ProcessError {\n constructor(command: string, details: string) {\n super(`Error executing command '${command}': ${details}`);\n this.name = \"ProcessSpawnError\";\n }\n}\n", "import { type Result, err } from \"../types/result.ts\";\nimport { WorktreeNotFoundError } from \"../worktree/errors.ts\";\nimport { validateWorktreeExists } from \"../worktree/validate.ts\";\nimport type { ProcessError } from \"./errors.ts\";\nimport { type SpawnSuccess, spawnProcess } from \"./spawn.ts\";\n\nexport type ExecInWorktreeSuccess = SpawnSuccess;\n\nexport async function execInWorktree(\n gitRoot: string,\n worktreeName: string,\n command: string[],\n): Promise<\n Result<ExecInWorktreeSuccess, WorktreeNotFoundError | ProcessError>\n> {\n const validation = await validateWorktreeExists(gitRoot, worktreeName);\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(worktreeName));\n }\n\n const worktreePath = validation.path as string;\n const [cmd, ...args] = command;\n\n return spawnProcess({\n command: cmd,\n args,\n options: {\n cwd: worktreePath,\n },\n });\n}\n", "import { type Result, err } from \"../types/result.ts\";\nimport { WorktreeNotFoundError } from \"../worktree/errors.ts\";\nimport { validateWorktreeExists } from \"../worktree/validate.ts\";\nimport type { ProcessError } from \"./errors.ts\";\nimport { type SpawnSuccess, spawnProcess } from \"./spawn.ts\";\n\nexport type ShellInWorktreeSuccess = SpawnSuccess;\n\nexport async function shellInWorktree(\n gitRoot: string,\n worktreeName: string,\n): Promise<\n Result<ShellInWorktreeSuccess, WorktreeNotFoundError | ProcessError>\n> {\n const validation = await validateWorktreeExists(gitRoot, worktreeName);\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(worktreeName));\n }\n\n const worktreePath = validation.path as string;\n const shell = process.env.SHELL || \"/bin/sh\";\n\n return spawnProcess({\n command: shell,\n args: [],\n options: {\n cwd: worktreePath,\n env: {\n ...process.env,\n PHANTOM: \"1\",\n PHANTOM_NAME: worktreeName,\n PHANTOM_PATH: worktreePath,\n },\n },\n });\n}\n", "import { existsSync } from \"node:fs\";\nimport { attachWorktree } from \"../git/libs/attach-worktree.ts\";\nimport { branchExists } from \"../git/libs/branch-exists.ts\";\nimport { getWorktreePath } from \"../paths.ts\";\nimport type { Result } from \"../types/result.ts\";\nimport { err, isErr, ok } from \"../types/result.ts\";\nimport { BranchNotFoundError, WorktreeAlreadyExistsError } from \"./errors.ts\";\nimport { validateWorktreeName } from \"./validate.ts\";\n\nexport async function attachWorktreeCore(\n gitRoot: string,\n name: string,\n): Promise<Result<string, Error>> {\n const validation = validateWorktreeName(name);\n if (isErr(validation)) {\n return validation;\n }\n\n const worktreePath = getWorktreePath(gitRoot, name);\n if (existsSync(worktreePath)) {\n return err(new WorktreeAlreadyExistsError(name));\n }\n\n const branchCheckResult = await branchExists(gitRoot, name);\n if (isErr(branchCheckResult)) {\n return err(branchCheckResult.error);\n }\n\n if (!branchCheckResult.value) {\n return err(new BranchNotFoundError(name));\n }\n\n const attachResult = await attachWorktree(gitRoot, worktreePath, name);\n if (isErr(attachResult)) {\n return err(attachResult.error);\n }\n\n return ok(worktreePath);\n}\n", "import type { Result } from \"../../types/result.ts\";\nimport { err, ok } from \"../../types/result.ts\";\nimport { executeGitCommand } from \"../executor.ts\";\n\nexport async function attachWorktree(\n gitRoot: string,\n worktreePath: string,\n branchName: string,\n): Promise<Result<void, Error>> {\n try {\n await executeGitCommand([\"worktree\", \"add\", worktreePath, branchName], {\n cwd: gitRoot,\n });\n return ok(undefined);\n } catch (error) {\n return err(\n error instanceof Error\n ? error\n : new Error(`Failed to attach worktree: ${String(error)}`),\n );\n }\n}\n", "import type { Result } from \"../../types/result.ts\";\nimport { err, isErr, ok } from \"../../types/result.ts\";\nimport { executeGitCommand } from \"../executor.ts\";\n\nexport async function branchExists(\n gitRoot: string,\n branchName: string,\n): Promise<Result<boolean, Error>> {\n try {\n await executeGitCommand(\n [\"show-ref\", \"--verify\", \"--quiet\", `refs/heads/${branchName}`],\n { cwd: gitRoot },\n );\n return ok(true);\n } catch (error) {\n if (error && typeof error === \"object\" && \"code\" in error) {\n const execError = error as { code?: number; message?: string };\n if (execError.code === 1) {\n return ok(false);\n }\n }\n return err(\n new Error(\n `Failed to check branch existence: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n }\n}\n", "import type { ChildProcess } from \"node:child_process\";\n\nexport const output = {\n log: (message: string) => {\n console.log(message);\n },\n\n error: (message: string) => {\n console.error(message);\n },\n\n table: (data: unknown) => {\n console.table(data);\n },\n\n processOutput: (proc: ChildProcess) => {\n proc.stdout?.pipe(process.stdout);\n proc.stderr?.pipe(process.stderr);\n },\n};\n", "import { output } from \"./output.ts\";\n\nexport const exitCodes = {\n success: 0,\n generalError: 1,\n notFound: 2,\n validationError: 3,\n} as const;\n\nexport function handleError(\n error: unknown,\n exitCode: number = exitCodes.generalError,\n): never {\n if (error instanceof Error) {\n output.error(error.message);\n } else {\n output.error(String(error));\n }\n process.exit(exitCode);\n}\n\nexport function exitWithSuccess(): never {\n process.exit(exitCodes.success);\n}\n\nexport function exitWithError(\n message: string,\n exitCode: number = exitCodes.generalError,\n): never {\n output.error(message);\n process.exit(exitCode);\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { execInWorktree } from \"../../core/process/exec.ts\";\nimport { shellInWorktree } from \"../../core/process/shell.ts\";\nimport { isErr, isOk } from \"../../core/types/result.ts\";\nimport { createWorktree as createWorktreeCore } from \"../../core/worktree/create.ts\";\nimport { WorktreeAlreadyExistsError } from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError, exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function createHandler(args: string[]): Promise<void> {\n const { values, positionals } = parseArgs({\n args,\n options: {\n shell: {\n type: \"boolean\",\n short: \"s\",\n },\n exec: {\n type: \"string\",\n short: \"x\",\n },\n },\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Please provide a name for the new worktree\",\n exitCodes.validationError,\n );\n }\n\n const worktreeName = positionals[0];\n const openShell = values.shell ?? false;\n const execCommand = values.exec;\n\n if (openShell && execCommand) {\n exitWithError(\n \"Cannot use --shell and --exec together\",\n exitCodes.validationError,\n );\n }\n\n try {\n const gitRoot = await getGitRoot();\n const result = await createWorktreeCore(gitRoot, worktreeName);\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeAlreadyExistsError\n ? exitCodes.validationError\n : exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n output.log(result.value.message);\n\n if (execCommand && isOk(result)) {\n output.log(\n `\\nExecuting command in worktree '${worktreeName}': ${execCommand}`,\n );\n\n const shell = process.env.SHELL || \"/bin/sh\";\n const execResult = await execInWorktree(gitRoot, worktreeName, [\n shell,\n \"-c\",\n execCommand,\n ]);\n\n if (isErr(execResult)) {\n output.error(execResult.error.message);\n const exitCode =\n \"exitCode\" in execResult.error\n ? (execResult.error.exitCode ?? exitCodes.generalError)\n : exitCodes.generalError;\n exitWithError(\"\", exitCode);\n }\n\n process.exit(execResult.value.exitCode ?? 0);\n }\n\n if (openShell && isOk(result)) {\n output.log(\n `\\nEntering worktree '${worktreeName}' at ${result.value.path}`,\n );\n output.log(\"Type 'exit' to return to your original directory\\n\");\n\n const shellResult = await shellInWorktree(gitRoot, worktreeName);\n\n if (isErr(shellResult)) {\n output.error(shellResult.error.message);\n const exitCode =\n \"exitCode\" in shellResult.error\n ? (shellResult.error.exitCode ?? exitCodes.generalError)\n : exitCodes.generalError;\n exitWithError(\"\", exitCode);\n }\n\n process.exit(shellResult.value.exitCode ?? 0);\n }\n\n exitWithSuccess();\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import fs from \"node:fs/promises\";\nimport { addWorktree } from \"../git/libs/add-worktree.ts\";\nimport { getPhantomDirectory, getWorktreePath } from \"../paths.ts\";\nimport { type Result, err, isErr, ok } from \"../types/result.ts\";\nimport { GitOperationError, WorktreeAlreadyExistsError } from \"./errors.ts\";\nimport {\n validateWorktreeDoesNotExist,\n validateWorktreeName,\n} from \"./validate.ts\";\n\nexport interface CreateWorktreeOptions {\n branch?: string;\n commitish?: string;\n}\n\nexport interface CreateWorktreeSuccess {\n message: string;\n path: string;\n}\n\nexport async function createWorktree(\n gitRoot: string,\n name: string,\n options: CreateWorktreeOptions = {},\n): Promise<\n Result<CreateWorktreeSuccess, WorktreeAlreadyExistsError | GitOperationError>\n> {\n const nameValidation = validateWorktreeName(name);\n if (isErr(nameValidation)) {\n return nameValidation;\n }\n\n const { branch = name, commitish = \"HEAD\" } = options;\n\n const worktreesPath = getPhantomDirectory(gitRoot);\n const worktreePath = getWorktreePath(gitRoot, name);\n\n try {\n await fs.access(worktreesPath);\n } catch {\n await fs.mkdir(worktreesPath, { recursive: true });\n }\n\n const validation = await validateWorktreeDoesNotExist(gitRoot, name);\n if (validation.exists) {\n return err(new WorktreeAlreadyExistsError(name));\n }\n\n try {\n await addWorktree({\n path: worktreePath,\n branch,\n commitish,\n });\n\n return ok({\n message: `Created worktree '${name}' at ${worktreePath}`,\n path: worktreePath,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return err(new GitOperationError(\"worktree add\", errorMessage));\n }\n}\n", "import { executeGitCommand } from \"../executor.ts\";\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 executeGitCommand([\"worktree\", \"add\", path, \"-b\", branch, commitish]);\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { deleteWorktree as deleteWorktreeCore } from \"../../core/worktree/delete.ts\";\nimport {\n WorktreeError,\n WorktreeNotFoundError,\n} from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError, exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function deleteHandler(args: string[]): Promise<void> {\n const { values, positionals } = parseArgs({\n args,\n options: {\n force: {\n type: \"boolean\",\n short: \"f\",\n },\n },\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Please provide a worktree name to delete\",\n exitCodes.validationError,\n );\n }\n\n const worktreeName = positionals[0];\n const forceDelete = values.force ?? false;\n\n try {\n const gitRoot = await getGitRoot();\n const result = await deleteWorktreeCore(gitRoot, worktreeName, {\n force: forceDelete,\n });\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeNotFoundError\n ? exitCodes.validationError\n : result.error instanceof WorktreeError &&\n result.error.message.includes(\"uncommitted changes\")\n ? exitCodes.validationError\n : exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n output.log(result.value.message);\n exitWithSuccess();\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import {\n executeGitCommand,\n executeGitCommandInDirectory,\n} from \"../git/executor.ts\";\nimport { type Result, err, isOk, ok } from \"../types/result.ts\";\nimport {\n GitOperationError,\n WorktreeError,\n WorktreeNotFoundError,\n} from \"./errors.ts\";\nimport { validateWorktreeExists } from \"./validate.ts\";\n\nexport interface DeleteWorktreeOptions {\n force?: boolean;\n}\n\nexport interface DeleteWorktreeSuccess {\n message: string;\n hasUncommittedChanges?: boolean;\n changedFiles?: number;\n}\n\nexport interface WorktreeStatus {\n hasUncommittedChanges: boolean;\n changedFiles: number;\n}\n\nexport async function getWorktreeStatus(\n worktreePath: string,\n): Promise<WorktreeStatus> {\n try {\n const { stdout } = await executeGitCommandInDirectory(worktreePath, [\n \"status\",\n \"--porcelain\",\n ]);\n if (stdout) {\n return {\n hasUncommittedChanges: true,\n changedFiles: stdout.split(\"\\n\").length,\n };\n }\n } catch {\n // If git status fails, assume no changes\n }\n return {\n hasUncommittedChanges: false,\n changedFiles: 0,\n };\n}\n\nexport async function removeWorktree(\n gitRoot: string,\n worktreePath: string,\n force = false,\n): Promise<void> {\n try {\n await executeGitCommand([\"worktree\", \"remove\", worktreePath], {\n cwd: gitRoot,\n });\n } catch (error) {\n // Always try force removal if the regular removal fails\n try {\n await executeGitCommand([\"worktree\", \"remove\", \"--force\", worktreePath], {\n cwd: gitRoot,\n });\n } catch {\n throw new Error(\"Failed to remove worktree\");\n }\n }\n}\n\nexport async function deleteBranch(\n gitRoot: string,\n branchName: string,\n): Promise<Result<boolean, GitOperationError>> {\n try {\n await executeGitCommand([\"branch\", \"-D\", branchName], { cwd: gitRoot });\n return ok(true);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return err(new GitOperationError(\"branch delete\", errorMessage));\n }\n}\n\nexport async function deleteWorktree(\n gitRoot: string,\n name: string,\n options: DeleteWorktreeOptions = {},\n): Promise<\n Result<\n DeleteWorktreeSuccess,\n WorktreeNotFoundError | WorktreeError | GitOperationError\n >\n> {\n const { force = false } = options;\n\n const validation = await validateWorktreeExists(gitRoot, name);\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(name));\n }\n\n const worktreePath = validation.path as string;\n\n const status = await getWorktreeStatus(worktreePath);\n\n if (status.hasUncommittedChanges && !force) {\n return err(\n new WorktreeError(\n `Worktree '${name}' has uncommitted changes (${status.changedFiles} files). Use --force to delete anyway.`,\n ),\n );\n }\n\n try {\n await removeWorktree(gitRoot, worktreePath, force);\n\n const branchName = name;\n const branchResult = await deleteBranch(gitRoot, branchName);\n\n let message: string;\n if (isOk(branchResult)) {\n message = `Deleted worktree '${name}' and its branch '${branchName}'`;\n } else {\n message = `Deleted worktree '${name}'`;\n message += `\\nNote: Branch '${branchName}' could not be deleted: ${branchResult.error.message}`;\n }\n\n if (status.hasUncommittedChanges) {\n message = `Warning: Worktree '${name}' had uncommitted changes (${status.changedFiles} files)\\n${message}`;\n }\n\n return ok({\n message,\n hasUncommittedChanges: status.hasUncommittedChanges,\n changedFiles: status.hasUncommittedChanges\n ? status.changedFiles\n : undefined,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return err(new GitOperationError(\"worktree remove\", errorMessage));\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { execInWorktree as execInWorktreeCore } from \"../../core/process/exec.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { WorktreeNotFoundError } from \"../../core/worktree/errors.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\n\nexport async function execHandler(args: string[]): Promise<void> {\n const { positionals } = parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length < 2) {\n exitWithError(\n \"Usage: phantom exec <worktree-name> <command> [args...]\",\n exitCodes.validationError,\n );\n }\n\n const [worktreeName, ...commandArgs] = positionals;\n\n try {\n const gitRoot = await getGitRoot();\n const result = await execInWorktreeCore(gitRoot, worktreeName, commandArgs);\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeNotFoundError\n ? exitCodes.notFound\n : result.error.exitCode || exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n process.exit(result.value.exitCode);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { listWorktrees as listWorktreesCore } from \"../../core/worktree/list.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function listHandler(args: string[] = []): Promise<void> {\n parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: false,\n });\n try {\n const gitRoot = await getGitRoot();\n const result = await listWorktreesCore(gitRoot);\n\n if (isErr(result)) {\n exitWithError(\"Failed to list worktrees\", exitCodes.generalError);\n }\n\n const { worktrees, message } = result.value;\n\n if (worktrees.length === 0) {\n output.log(message || \"No worktrees found.\");\n process.exit(exitCodes.success);\n }\n\n const maxNameLength = Math.max(...worktrees.map((wt) => wt.name.length));\n\n for (const worktree of worktrees) {\n const paddedName = worktree.name.padEnd(maxNameLength + 2);\n const branchInfo = worktree.branch ? `(${worktree.branch})` : \"\";\n const status = !worktree.isClean ? \" [dirty]\" : \"\";\n\n output.log(`${paddedName} ${branchInfo}${status}`);\n }\n\n process.exit(exitCodes.success);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { executeGitCommand } from \"../executor.ts\";\n\nexport interface GitWorktree {\n path: string;\n branch: string;\n head: string;\n isLocked: boolean;\n isPrunable: boolean;\n}\n\nexport async function listWorktrees(gitRoot: string): Promise<GitWorktree[]> {\n const { stdout } = await executeGitCommand([\n \"worktree\",\n \"list\",\n \"--porcelain\",\n ]);\n\n const worktrees: GitWorktree[] = [];\n let currentWorktree: Partial<GitWorktree> = {};\n\n const lines = stdout.split(\"\\n\").filter((line) => line.length > 0);\n\n for (const line of lines) {\n if (line.startsWith(\"worktree \")) {\n if (currentWorktree.path) {\n worktrees.push(currentWorktree as GitWorktree);\n }\n currentWorktree = {\n path: line.substring(\"worktree \".length),\n isLocked: false,\n isPrunable: false,\n };\n } else if (line.startsWith(\"HEAD \")) {\n currentWorktree.head = line.substring(\"HEAD \".length);\n } else if (line.startsWith(\"branch \")) {\n const fullBranch = line.substring(\"branch \".length);\n currentWorktree.branch = fullBranch.startsWith(\"refs/heads/\")\n ? fullBranch.substring(\"refs/heads/\".length)\n : fullBranch;\n } else if (line === \"detached\") {\n currentWorktree.branch = \"(detached HEAD)\";\n } else if (line === \"locked\") {\n currentWorktree.isLocked = true;\n } else if (line === \"prunable\") {\n currentWorktree.isPrunable = true;\n }\n }\n\n if (currentWorktree.path) {\n worktrees.push(currentWorktree as GitWorktree);\n }\n\n return worktrees;\n}\n", "import { executeGitCommandInDirectory } from \"../git/executor.ts\";\nimport { listWorktrees as gitListWorktrees } from \"../git/libs/list-worktrees.ts\";\nimport { getPhantomDirectory, getWorktreePath } from \"../paths.ts\";\nimport { type Result, ok } from \"../types/result.ts\";\n\nexport interface WorktreeInfo {\n name: string;\n path: string;\n branch: string;\n isClean: boolean;\n}\n\nexport interface ListWorktreesSuccess {\n worktrees: WorktreeInfo[];\n message?: string;\n}\n\nexport async function getWorktreeBranch(worktreePath: string): Promise<string> {\n try {\n const { stdout } = await executeGitCommandInDirectory(worktreePath, [\n \"branch\",\n \"--show-current\",\n ]);\n return stdout || \"(detached HEAD)\";\n } catch {\n return \"unknown\";\n }\n}\n\nexport async function getWorktreeStatus(\n worktreePath: string,\n): Promise<boolean> {\n try {\n const { stdout } = await executeGitCommandInDirectory(worktreePath, [\n \"status\",\n \"--porcelain\",\n ]);\n return !stdout; // Clean if no output\n } catch {\n // If git status fails, assume clean\n return true;\n }\n}\n\nexport async function getWorktreeInfo(\n gitRoot: string,\n name: string,\n): Promise<WorktreeInfo> {\n const worktreePath = getWorktreePath(gitRoot, name);\n\n const [branch, isClean] = await Promise.all([\n getWorktreeBranch(worktreePath),\n getWorktreeStatus(worktreePath),\n ]);\n\n return {\n name,\n path: worktreePath,\n branch,\n isClean,\n };\n}\n\nexport async function listWorktrees(\n gitRoot: string,\n): Promise<Result<ListWorktreesSuccess, never>> {\n try {\n const gitWorktrees = await gitListWorktrees(gitRoot);\n const phantomDir = getPhantomDirectory(gitRoot);\n\n const phantomWorktrees = gitWorktrees.filter((worktree) =>\n worktree.path.startsWith(phantomDir),\n );\n\n if (phantomWorktrees.length === 0) {\n return ok({\n worktrees: [],\n message: \"No worktrees found\",\n });\n }\n\n const worktrees = await Promise.all(\n phantomWorktrees.map(async (gitWorktree) => {\n const name = gitWorktree.path.substring(phantomDir.length + 1);\n const isClean = await getWorktreeStatus(gitWorktree.path);\n\n return {\n name,\n path: gitWorktree.path,\n branch: gitWorktree.branch || \"(detached HEAD)\",\n isClean,\n };\n }),\n );\n\n return ok({\n worktrees,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to list worktrees: ${errorMessage}`);\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { shellInWorktree as shellInWorktreeCore } from \"../../core/process/shell.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { WorktreeNotFoundError } from \"../../core/worktree/errors.ts\";\nimport { validateWorktreeExists } from \"../../core/worktree/validate.ts\";\nimport { exitCodes, exitWithError } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function shellHandler(args: string[]): Promise<void> {\n const { positionals } = parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\n \"Usage: phantom shell <worktree-name>\",\n exitCodes.validationError,\n );\n }\n\n const worktreeName = positionals[0];\n\n try {\n const gitRoot = await getGitRoot();\n\n // Get worktree path for display\n const validation = await validateWorktreeExists(gitRoot, worktreeName);\n if (!validation.exists) {\n exitWithError(\n validation.message || `Worktree '${worktreeName}' not found`,\n exitCodes.generalError,\n );\n }\n\n output.log(`Entering worktree '${worktreeName}' at ${validation.path}`);\n output.log(\"Type 'exit' to return to your original directory\\n\");\n\n const result = await shellInWorktreeCore(gitRoot, worktreeName);\n\n if (isErr(result)) {\n const exitCode =\n result.error instanceof WorktreeNotFoundError\n ? exitCodes.notFound\n : result.error.exitCode || exitCodes.generalError;\n exitWithError(result.error.message, exitCode);\n }\n\n process.exit(result.value.exitCode);\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { parseArgs } from \"node:util\";\nimport { getVersion } from \"../../core/version.ts\";\nimport { exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport function versionHandler(args: string[] = []): void {\n parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: false,\n });\n const version = getVersion();\n output.log(`Phantom v${version}`);\n exitWithSuccess();\n}\n", "{\n \"name\": \"@aku11i/phantom\",\n \"packageManager\": \"pnpm@10.8.1\",\n \"version\": \"0.5.0\",\n \"description\": \"A powerful CLI tool for managing Git worktrees for parallel development\",\n \"keywords\": [\n \"git\",\n \"worktree\",\n \"cli\",\n \"phantom\",\n \"workspace\",\n \"development\",\n \"parallel\"\n ],\n \"homepage\": \"https://github.com/aku11i/phantom#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/aku11i/phantom/issues\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/aku11i/phantom.git\"\n },\n \"license\": \"MIT\",\n \"author\": \"aku11i\",\n \"type\": \"module\",\n \"bin\": {\n \"phantom\": \"./dist/phantom.js\"\n },\n \"scripts\": {\n \"start\": \"node ./src/bin/phantom.ts\",\n \"phantom\": \"node ./src/bin/phantom.ts\",\n \"build\": \"node build.ts\",\n \"typecheck\": \"tsgo --noEmit\",\n \"test\": \"node --test --experimental-strip-types --experimental-test-module-mocks src/**/*.test.ts\",\n \"lint\": \"biome check .\",\n \"fix\": \"biome check --write .\",\n \"ready\": \"pnpm fix && pnpm typecheck && pnpm test\",\n \"ready:check\": \"pnpm lint && pnpm typecheck && pnpm test\",\n \"prepublishOnly\": \"pnpm ready:check && pnpm build\"\n },\n \"engines\": {\n \"node\": \">=22.0.0\"\n },\n \"files\": [\n \"dist/\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.9.4\",\n \"@types/node\": \"^22.15.29\",\n \"@typescript/native-preview\": \"7.0.0-dev.20250602.1\",\n \"esbuild\": \"^0.25.5\",\n \"typescript\": \"^5.8.3\"\n }\n}\n", "import packageJson from \"../../package.json\" with { type: \"json\" };\n\nexport function getVersion(): string {\n return packageJson.version;\n}\n", "import { parseArgs } from \"node:util\";\nimport { getGitRoot } from \"../../core/git/libs/get-git-root.ts\";\nimport { isErr } from \"../../core/types/result.ts\";\nimport { whereWorktree as whereWorktreeCore } from \"../../core/worktree/where.ts\";\nimport { exitCodes, exitWithError, exitWithSuccess } from \"../errors.ts\";\nimport { output } from \"../output.ts\";\n\nexport async function whereHandler(args: string[]): Promise<void> {\n const { positionals } = parseArgs({\n args,\n options: {},\n strict: true,\n allowPositionals: true,\n });\n\n if (positionals.length === 0) {\n exitWithError(\"Please provide a worktree name\", exitCodes.validationError);\n }\n\n const worktreeName = positionals[0];\n\n try {\n const gitRoot = await getGitRoot();\n const result = await whereWorktreeCore(gitRoot, worktreeName);\n\n if (isErr(result)) {\n exitWithError(result.error.message, exitCodes.notFound);\n }\n\n output.log(result.value.path);\n exitWithSuccess();\n } catch (error) {\n exitWithError(\n error instanceof Error ? error.message : String(error),\n exitCodes.generalError,\n );\n }\n}\n", "import { type Result, err, ok } from \"../types/result.ts\";\nimport { WorktreeNotFoundError } from \"./errors.ts\";\nimport { validateWorktreeExists } from \"./validate.ts\";\n\nexport interface WhereWorktreeSuccess {\n path: string;\n}\n\nexport async function whereWorktree(\n gitRoot: string,\n name: string,\n): Promise<Result<WhereWorktreeSuccess, WorktreeNotFoundError>> {\n const validation = await validateWorktreeExists(gitRoot, name);\n\n if (!validation.exists) {\n return err(new WorktreeNotFoundError(name));\n }\n\n return ok({\n path: validation.path as string,\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["args", "command", "resolve", "command", "args", "command", "args", "args", "parseArgs", "fs", "fs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "parseArgs", "getWorktreeStatus", "listWorktrees", "getWorktreeStatus", "args", "parseArgs", "listWorktrees", "parseArgs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "parseArgs", "args", "parseArgs", "commands", "args", "command", "remainingArgs"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aku11i/phantom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A powerful CLI tool for managing Git worktrees for parallel development",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"git",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"start": "node ./src/bin/phantom.ts",
|
|
45
45
|
"phantom": "node ./src/bin/phantom.ts",
|
|
46
46
|
"build": "node build.ts",
|
|
47
|
-
"
|
|
47
|
+
"typecheck": "tsgo --noEmit",
|
|
48
48
|
"test": "node --test --experimental-strip-types --experimental-test-module-mocks src/**/*.test.ts",
|
|
49
49
|
"lint": "biome check .",
|
|
50
50
|
"fix": "biome check --write .",
|
|
51
|
-
"ready": "pnpm fix && pnpm
|
|
52
|
-
"ready:check": "pnpm lint && pnpm
|
|
51
|
+
"ready": "pnpm fix && pnpm typecheck && pnpm test",
|
|
52
|
+
"ready:check": "pnpm lint && pnpm typecheck && pnpm test"
|
|
53
53
|
}
|
|
54
54
|
}
|