Add symbolic status prefixes to CLI output messages
This commit is contained in:
parent
e5085d50ed
commit
3580df2ba6
38
src/cli.ts
38
src/cli.ts
|
|
@ -92,7 +92,7 @@ program
|
||||||
if (!branch && opts.print) {
|
if (!branch && opts.print) {
|
||||||
branch = branchFromPrompt(opts.print)
|
branch = branchFromPrompt(opts.print)
|
||||||
} else if (!branch) {
|
} else if (!branch) {
|
||||||
console.error("Branch name or prompt is required.")
|
console.error("✖ Branch name or prompt is required.")
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
} else if (branch.includes(" ")) {
|
} else if (branch.includes(" ")) {
|
||||||
// If the "branch" contains spaces, it's actually a prompt — derive the branch name
|
// If the "branch" contains spaces, it's actually a prompt — derive the branch name
|
||||||
|
|
@ -104,7 +104,7 @@ program
|
||||||
|
|
||||||
const existing = await state.getSession(root, branch)
|
const existing = await state.getSession(root, branch)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
console.error(`Session "${branch}" already exists. Use "sandlot open ${branch}" to re-enter it.`)
|
console.error(`✖ Session "${branch}" already exists. Use "sandlot open ${branch}" to re-enter it.`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,7 +166,7 @@ program
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sessions.length === 0) {
|
if (sessions.length === 0) {
|
||||||
console.log("No active sessions.")
|
console.log("◆ No active sessions.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ program
|
||||||
const session = await state.getSession(root, branch)
|
const session = await state.getSession(root, branch)
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
console.error(`No session found for branch "${branch}".`)
|
console.error(`✖ No session found for branch "${branch}".`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,19 +233,19 @@ const closeAction = async (branch: string) => {
|
||||||
const worktreeAbs = session?.worktree ?? join(homedir(), '.sandlot', basename(root), branch)
|
const worktreeAbs = session?.worktree ?? join(homedir(), '.sandlot', basename(root), branch)
|
||||||
|
|
||||||
await git.removeWorktree(worktreeAbs, root)
|
await git.removeWorktree(worktreeAbs, root)
|
||||||
.catch((e) => console.warn(`Failed to remove worktree: ${e.message}`))
|
.catch((e) => console.warn(`⚠ Failed to remove worktree: ${e.message}`))
|
||||||
|
|
||||||
await unlink(join(root, '.sandlot', branch))
|
await unlink(join(root, '.sandlot', branch))
|
||||||
.catch(() => {}) // symlink may not exist
|
.catch(() => {}) // symlink may not exist
|
||||||
|
|
||||||
await git.deleteLocalBranch(branch, root)
|
await git.deleteLocalBranch(branch, root)
|
||||||
.catch((e) => console.warn(`Failed to delete branch ${branch}: ${e.message}`))
|
.catch((e) => console.warn(`⚠ Failed to delete branch ${branch}: ${e.message}`))
|
||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
await state.removeSession(root, branch)
|
await state.removeSession(root, branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Closed session ${branch}`)
|
console.log(`✔ Closed session ${branch}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── sandlot merge <branch> ──────────────────────────────────────────
|
// ── sandlot merge <branch> ──────────────────────────────────────────
|
||||||
|
|
@ -260,13 +260,13 @@ program
|
||||||
const conflicts = await git.merge(branch, root)
|
const conflicts = await git.merge(branch, root)
|
||||||
|
|
||||||
if (conflicts.length === 0) {
|
if (conflicts.length === 0) {
|
||||||
console.log(`Merged ${branch} into current branch`)
|
console.log(`✔ Merged ${branch} into current branch`)
|
||||||
await closeAction(branch)
|
await closeAction(branch)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve conflicts with Claude
|
// Resolve conflicts with Claude
|
||||||
console.log(`Merge conflicts in ${conflicts.length} file(s). Resolving with Claude...`)
|
console.log(`◆ Merge conflicts in ${conflicts.length} file(s). Resolving with Claude...`)
|
||||||
const spin = spinner("Starting container")
|
const spin = spinner("Starting container")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -327,7 +327,7 @@ program
|
||||||
const root = await git.repoRoot()
|
const root = await git.repoRoot()
|
||||||
const session = await state.getSession(root, branch)
|
const session = await state.getSession(root, branch)
|
||||||
if (!session) {
|
if (!session) {
|
||||||
console.error(`No session found for branch "${branch}".`)
|
console.error(`✖ No session found for branch "${branch}".`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,14 +345,14 @@ program
|
||||||
const root = await git.repoRoot()
|
const root = await git.repoRoot()
|
||||||
const session = await state.getSession(root, branch)
|
const session = await state.getSession(root, branch)
|
||||||
if (!session) {
|
if (!session) {
|
||||||
console.error(`No session found for branch "${branch}".`)
|
console.error(`✖ No session found for branch "${branch}".`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for uncommitted changes (staged + unstaged)
|
// Check for uncommitted changes (staged + unstaged)
|
||||||
const status = await $`git -C ${session.worktree} status --porcelain`.nothrow().quiet()
|
const status = await $`git -C ${session.worktree} status --porcelain`.nothrow().quiet()
|
||||||
if (status.exitCode !== 0) {
|
if (status.exitCode !== 0) {
|
||||||
console.error("git status failed")
|
console.error("✖ git status failed")
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -372,7 +372,7 @@ program
|
||||||
const main = await git.mainBranch(root)
|
const main = await git.mainBranch(root)
|
||||||
const result = await $`git -C ${session.worktree} diff --color=always ${main}...${branch}`.nothrow().quiet()
|
const result = await $`git -C ${session.worktree} diff --color=always ${main}...${branch}`.nothrow().quiet()
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
console.error("git diff failed")
|
console.error("✖ git diff failed")
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
diff = result.text()
|
diff = result.text()
|
||||||
|
|
@ -400,13 +400,13 @@ program
|
||||||
const root = await git.repoRoot()
|
const root = await git.repoRoot()
|
||||||
const session = await state.getSession(root, branch)
|
const session = await state.getSession(root, branch)
|
||||||
if (!session) {
|
if (!session) {
|
||||||
console.error(`No session found for branch "${branch}".`)
|
console.error(`✖ No session found for branch "${branch}".`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await $`git -C ${session.worktree} log main..HEAD`.nothrow()
|
const result = await $`git -C ${session.worktree} log main..HEAD`.nothrow()
|
||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
console.error("git log failed")
|
console.error("✖ git log failed")
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -421,7 +421,7 @@ program
|
||||||
const root = await git.repoRoot()
|
const root = await git.repoRoot()
|
||||||
const session = await state.getSession(root, branch)
|
const session = await state.getSession(root, branch)
|
||||||
if (!session) {
|
if (!session) {
|
||||||
console.error(`No session found for branch "${branch}".`)
|
console.error(`✖ No session found for branch "${branch}".`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -461,7 +461,7 @@ vmCmd
|
||||||
.description("Stop the VM")
|
.description("Stop the VM")
|
||||||
.action(async () => {
|
.action(async () => {
|
||||||
await vm.stop()
|
await vm.stop()
|
||||||
console.log("VM stopped")
|
console.log("✔ VM stopped")
|
||||||
})
|
})
|
||||||
|
|
||||||
vmCmd
|
vmCmd
|
||||||
|
|
@ -469,10 +469,10 @@ vmCmd
|
||||||
.description("Stop and delete the VM")
|
.description("Stop and delete the VM")
|
||||||
.action(async () => {
|
.action(async () => {
|
||||||
await vm.destroy()
|
await vm.destroy()
|
||||||
console.log("VM destroyed")
|
console.log("✔ VM destroyed")
|
||||||
})
|
})
|
||||||
|
|
||||||
program.parseAsync().catch((err) => {
|
program.parseAsync().catch((err) => {
|
||||||
console.error(err.message ?? err)
|
console.error(`✖ ${err.message ?? err}`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ function containerPath(hostPath: string): string {
|
||||||
|
|
||||||
function requireContainer(): void {
|
function requireContainer(): void {
|
||||||
if (!Bun.which("container")) {
|
if (!Bun.which("container")) {
|
||||||
console.error('Apple Container is not installed. Install it with: brew install container')
|
console.error('✖ Apple Container is not installed. Install it with: brew install container')
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user