refactor(cli): centralize worktree ls path resolution
What I changed:\n- Refactored worktree path handling in worktree ls into focused helpers: resolvePaseoHomePath, resolvePaseoWorktreesDir, and isAgentInManagedWorktree.\n- Switched worktree name extraction to node:path basename for clearer intent and path handling.\n- Added a focused regression test (20-worktree-ls-paths.test.ts) covering explicit PASEO_HOME and fallback home resolution behavior.\n\nReasoning:\n- The prior implementation repeated path derivation inline inside the agent loop, mixed decision logic with mapping, and relied on string concatenation for filesystem boundaries.\n- Extracting this logic reduces cognitive load, keeps policy in one place, and makes behavior directly testable without daemon dependencies.\n\nVerification:\n- npx tsx packages/cli/tests/20-worktree-ls-paths.test.ts\n- npx tsx packages/cli/tests/14-worktree.test.ts\n- npm run typecheck (all workspaces)\n\nNotes for next agent:\n- Similar inline PASEO_HOME/path derivation still exists in other CLI commands; these helpers can be reused to continue consistency work.\n- No behavior change intended for command output or error semantics; this was a structural-only refactor aligned with refactor-skill constraints.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import type { Command } from 'commander'
|
||||
import { homedir } from 'node:os'
|
||||
import { basename, join, sep } from 'node:path'
|
||||
import { connectToDaemon, getDaemonHost } from '../../utils/client.js'
|
||||
import type { CommandOptions, ListResult, OutputSchema, CommandError } from '../../output/index.js'
|
||||
|
||||
@@ -21,9 +23,20 @@ function shortenPath(path: string): string {
|
||||
|
||||
/** Extract worktree name from path */
|
||||
function extractWorktreeName(path: string): string {
|
||||
// ~/.paseo/worktrees/<repo>/<name> -> name
|
||||
const parts = path.split('/')
|
||||
return parts[parts.length - 1] ?? path
|
||||
return basename(path)
|
||||
}
|
||||
|
||||
export function resolvePaseoHomePath(): string {
|
||||
return process.env.PASEO_HOME ?? join(homedir(), '.paseo')
|
||||
}
|
||||
|
||||
export function resolvePaseoWorktreesDir(): string {
|
||||
return join(resolvePaseoHomePath(), 'worktrees')
|
||||
}
|
||||
|
||||
function isAgentInManagedWorktree(agentCwd: string): boolean {
|
||||
const worktreesDir = resolvePaseoWorktreesDir()
|
||||
return agentCwd === worktreesDir || agentCwd.startsWith(worktreesDir + sep)
|
||||
}
|
||||
|
||||
/** Schema for worktree ls output */
|
||||
@@ -81,10 +94,7 @@ export async function runLsCommand(
|
||||
// Build a map of worktree paths to agent IDs
|
||||
const worktreeAgentMap = new Map<string, string>()
|
||||
for (const agent of agents) {
|
||||
// Check if agent cwd is under ~/.paseo/worktrees/
|
||||
const paseoHome = process.env.PASEO_HOME ?? (process.env.HOME + '/.paseo')
|
||||
const worktreesDir = paseoHome + '/worktrees/'
|
||||
if (agent.cwd.startsWith(worktreesDir)) {
|
||||
if (isAgentInManagedWorktree(agent.cwd)) {
|
||||
worktreeAgentMap.set(agent.cwd, agent.id.slice(0, 7))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env npx tsx
|
||||
|
||||
import assert from 'node:assert'
|
||||
import { homedir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { resolvePaseoHomePath, resolvePaseoWorktreesDir } from '../src/commands/worktree/ls.js'
|
||||
|
||||
console.log('=== Worktree LS Path Helper Tests ===\n')
|
||||
|
||||
const originalPaseoHome = process.env.PASEO_HOME
|
||||
|
||||
try {
|
||||
{
|
||||
console.log('Test 1: resolves explicit PASEO_HOME when set')
|
||||
process.env.PASEO_HOME = '/tmp/paseo-explicit-home'
|
||||
|
||||
assert.strictEqual(resolvePaseoHomePath(), '/tmp/paseo-explicit-home')
|
||||
assert.strictEqual(resolvePaseoWorktreesDir(), '/tmp/paseo-explicit-home/worktrees')
|
||||
console.log('\u2713 explicit PASEO_HOME is respected\n')
|
||||
}
|
||||
|
||||
{
|
||||
console.log('Test 2: falls back to homedir/.paseo when PASEO_HOME is unset')
|
||||
delete process.env.PASEO_HOME
|
||||
|
||||
assert.strictEqual(resolvePaseoHomePath(), join(homedir(), '.paseo'))
|
||||
assert.strictEqual(resolvePaseoWorktreesDir(), join(homedir(), '.paseo', 'worktrees'))
|
||||
console.log('\u2713 fallback home path is derived from os.homedir()\n')
|
||||
}
|
||||
} finally {
|
||||
if (originalPaseoHome === undefined) {
|
||||
delete process.env.PASEO_HOME
|
||||
} else {
|
||||
process.env.PASEO_HOME = originalPaseoHome
|
||||
}
|
||||
}
|
||||
|
||||
console.log('=== All worktree ls path helper tests passed ===')
|
||||
Reference in New Issue
Block a user