@glrs-dev/cli 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +14 -15
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-6RHN2EDH.js +93 -0
- package/dist/chunk-DEODG2LC.js +55 -0
- package/dist/chunk-FSAGM22T.js +17 -0
- package/dist/chunk-GQBZREK5.js +136 -0
- package/dist/chunk-HWMRY35D.js +139 -0
- package/dist/chunk-LMRDQ4GW.js +129 -0
- package/dist/chunk-NLPX2KOF.js +149 -0
- package/dist/chunk-P7PRH4I3.js +177 -0
- package/dist/chunk-VCN7RNLU.js +60 -0
- package/dist/chunk-VJFNIKQJ.js +120 -0
- package/dist/chunk-W37UX3U2.js +35 -0
- package/dist/chunk-YBCA3IP6.js +25 -0
- package/dist/chunk-YGNDPKIW.js +99 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +89 -36
- package/dist/commands/cleanup.d.ts +19 -0
- package/dist/commands/cleanup.js +11 -0
- package/dist/commands/create.d.ts +17 -0
- package/dist/commands/create.js +12 -0
- package/dist/commands/delete.d.ts +17 -0
- package/dist/commands/delete.js +12 -0
- package/dist/commands/go.d.ts +4 -0
- package/dist/commands/go.js +11 -0
- package/dist/commands/list.d.ts +15 -0
- package/dist/commands/list.js +12 -0
- package/dist/commands/switch.d.ts +11 -0
- package/dist/commands/switch.js +12 -0
- package/dist/commands/types.d.ts +10 -0
- package/dist/commands/types.js +0 -0
- package/dist/index.d.ts +16 -19
- package/dist/index.js +4 -1
- package/dist/lib/config.d.ts +14 -0
- package/dist/lib/config.js +14 -0
- package/dist/lib/fmt.d.ts +12 -0
- package/dist/lib/fmt.js +25 -0
- package/dist/lib/git.d.ts +26 -0
- package/dist/lib/git.js +25 -0
- package/dist/lib/registry.d.ts +14 -0
- package/dist/lib/registry.js +13 -0
- package/dist/lib/select.d.ts +21 -0
- package/dist/lib/select.js +10 -0
- package/dist/lib/worktree.d.ts +35 -0
- package/dist/lib/worktree.js +17 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/agents-md-writer.md +89 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/architecture-advisor.md +46 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/build.md +93 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/code-searcher.md +54 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/docs-maintainer.md +128 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/gap-analyzer.md +44 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/lib-reader.md +39 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-builder.md +107 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/pilot-planner.md +153 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/plan-reviewer.md +49 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/plan.md +144 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/prime.md +374 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/qa-reviewer.md +68 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/qa-thorough.md +63 -0
- package/dist/vendor/harness-opencode/dist/agents/prompts/research.md +138 -0
- package/dist/vendor/harness-opencode/dist/agents/shared/index.ts +26 -0
- package/dist/vendor/harness-opencode/dist/agents/shared/workflow-mechanics.md +32 -0
- package/dist/vendor/harness-opencode/dist/bin/memory-mcp-launcher.sh +145 -0
- package/dist/vendor/harness-opencode/dist/bin/plan-check.sh +255 -0
- package/dist/vendor/harness-opencode/dist/chunk-BDFZGIY7.js +703 -0
- package/dist/vendor/harness-opencode/dist/chunk-UDB4NQ2R.js +205 -0
- package/dist/vendor/harness-opencode/dist/chunk-V3KJY6CN.js +731 -0
- package/dist/vendor/harness-opencode/dist/cli.d.ts +1 -0
- package/dist/vendor/harness-opencode/dist/cli.js +5096 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/autopilot.md +96 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/costs.md +94 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/fresh.md +382 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/init-deep.md +196 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/research.md +27 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/review.md +96 -0
- package/dist/vendor/harness-opencode/dist/commands/prompts/ship.md +104 -0
- package/dist/vendor/harness-opencode/dist/index.d.ts +21 -0
- package/dist/vendor/harness-opencode/dist/index.js +2092 -0
- package/dist/vendor/harness-opencode/dist/install-GDCZ7VFK.js +9 -0
- package/dist/vendor/harness-opencode/dist/skills/agent-estimation/SKILL.md +159 -0
- package/dist/vendor/harness-opencode/dist/skills/paths.ts +18 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/SKILL.md +49 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/dag-shape.md +47 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/decomposition.md +36 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/first-principles.md +29 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/milestones.md +57 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/self-review.md +46 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/task-context.md +47 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/touches-scope.md +47 -0
- package/dist/vendor/harness-opencode/dist/skills/pilot-planning/rules/verify-design.md +53 -0
- package/dist/vendor/harness-opencode/dist/skills/research/SKILL.md +350 -0
- package/dist/vendor/harness-opencode/dist/skills/research-auto/SKILL.md +283 -0
- package/dist/vendor/harness-opencode/dist/skills/research-local/SKILL.md +268 -0
- package/dist/vendor/harness-opencode/dist/skills/research-web/SKILL.md +119 -0
- package/dist/vendor/harness-opencode/dist/skills/review-plan/SKILL.md +32 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/AGENTS.md +946 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/README.md +60 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/SKILL.md +89 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/AGENTS.md +2975 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/README.md +123 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/SKILL.md +137 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +142 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/vendor/harness-opencode/dist/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/dist/vendor/harness-opencode/dist/skills/web-design-guidelines/SKILL.md +39 -0
- package/dist/vendor/harness-opencode/package.json +11 -0
- package/package.json +20 -15
- package/LICENSE +0 -21
- package/dist/chunk-TU23AE2F.js +0 -69
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
worktreePath
|
|
3
|
+
} from "./chunk-W37UX3U2.js";
|
|
4
|
+
import {
|
|
5
|
+
multiSelect
|
|
6
|
+
} from "./chunk-P7PRH4I3.js";
|
|
7
|
+
import {
|
|
8
|
+
gitIn,
|
|
9
|
+
gitInSafe,
|
|
10
|
+
gitRoot,
|
|
11
|
+
listWorktrees
|
|
12
|
+
} from "./chunk-LMRDQ4GW.js";
|
|
13
|
+
import {
|
|
14
|
+
loadRegistry,
|
|
15
|
+
unregisterWorktree
|
|
16
|
+
} from "./chunk-VCN7RNLU.js";
|
|
17
|
+
import {
|
|
18
|
+
bold,
|
|
19
|
+
dim,
|
|
20
|
+
ok,
|
|
21
|
+
red,
|
|
22
|
+
warn
|
|
23
|
+
} from "./chunk-YBCA3IP6.js";
|
|
24
|
+
|
|
25
|
+
// src/commands/delete.ts
|
|
26
|
+
import * as readline from "readline";
|
|
27
|
+
import { command, positional, flag, optional, string } from "cmd-ts";
|
|
28
|
+
var del = command({
|
|
29
|
+
name: "delete",
|
|
30
|
+
aliases: ["rm"],
|
|
31
|
+
description: "Remove worktrees and their branches",
|
|
32
|
+
args: {
|
|
33
|
+
name: positional({
|
|
34
|
+
type: optional(string),
|
|
35
|
+
displayName: "name",
|
|
36
|
+
description: "Worktree name. Omit for interactive multi-select."
|
|
37
|
+
}),
|
|
38
|
+
force: flag({
|
|
39
|
+
long: "force",
|
|
40
|
+
short: "f",
|
|
41
|
+
description: "Remove even if there are uncommitted changes"
|
|
42
|
+
})
|
|
43
|
+
},
|
|
44
|
+
handler: async ({ name, force }) => {
|
|
45
|
+
if (!name) {
|
|
46
|
+
await interactiveDelete();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const registry = loadRegistry();
|
|
50
|
+
const match = registry.find((e) => e.branch === name);
|
|
51
|
+
if (match) {
|
|
52
|
+
removeWorktree(match.repoPath, match.wtPath, match.branch, force);
|
|
53
|
+
unregisterWorktree(match.wtPath);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
let wtPath;
|
|
57
|
+
try {
|
|
58
|
+
wtPath = worktreePath(name);
|
|
59
|
+
} catch {
|
|
60
|
+
throw new Error(`Worktree '${name}' not found`);
|
|
61
|
+
}
|
|
62
|
+
const entries = listWorktrees();
|
|
63
|
+
const entry = entries.find((e) => e.path === wtPath);
|
|
64
|
+
if (!entry) {
|
|
65
|
+
throw new Error(`Worktree '${name}' not found at ${wtPath}`);
|
|
66
|
+
}
|
|
67
|
+
removeWorktree(gitRoot(), wtPath, name, force);
|
|
68
|
+
unregisterWorktree(wtPath);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
function removeWorktree(repoPath, wtPath, branch, force) {
|
|
72
|
+
if (force) {
|
|
73
|
+
gitIn(repoPath, "worktree", "remove", "--force", wtPath);
|
|
74
|
+
} else {
|
|
75
|
+
try {
|
|
76
|
+
gitIn(repoPath, "worktree", "remove", wtPath);
|
|
77
|
+
} catch {
|
|
78
|
+
throw new Error(
|
|
79
|
+
"Worktree has uncommitted changes. Use --force to override."
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
gitInSafe(repoPath, "branch", "-d", branch);
|
|
84
|
+
ok(`deleted worktree ${bold(branch)}`);
|
|
85
|
+
}
|
|
86
|
+
async function interactiveDelete() {
|
|
87
|
+
const entries = loadRegistry();
|
|
88
|
+
if (entries.length === 0) {
|
|
89
|
+
warn("no worktrees registered");
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const byRepo = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
const list = byRepo.get(entry.repo) ?? [];
|
|
95
|
+
list.push(entry);
|
|
96
|
+
byRepo.set(entry.repo, list);
|
|
97
|
+
}
|
|
98
|
+
const groups = [];
|
|
99
|
+
for (const [repo, repoEntries] of byRepo) {
|
|
100
|
+
groups.push({
|
|
101
|
+
title: repo,
|
|
102
|
+
choices: repoEntries.map((e) => ({
|
|
103
|
+
label: e.branch,
|
|
104
|
+
value: e,
|
|
105
|
+
hint: e.wtPath
|
|
106
|
+
}))
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
const selected = await multiSelect({
|
|
110
|
+
message: "Select worktrees to delete",
|
|
111
|
+
groups
|
|
112
|
+
});
|
|
113
|
+
if (selected.length === 0) return;
|
|
114
|
+
console.log();
|
|
115
|
+
for (const entry of selected) {
|
|
116
|
+
console.log(` ${red("\u2715")} ${entry.branch} ${dim(entry.wtPath)}`);
|
|
117
|
+
}
|
|
118
|
+
console.log();
|
|
119
|
+
const confirmed = await confirm(
|
|
120
|
+
`Delete ${selected.length} worktree(s)? [y/N] `
|
|
121
|
+
);
|
|
122
|
+
if (!confirmed) return;
|
|
123
|
+
for (const entry of selected) {
|
|
124
|
+
try {
|
|
125
|
+
gitIn(entry.repoPath, "worktree", "remove", entry.wtPath);
|
|
126
|
+
gitInSafe(entry.repoPath, "branch", "-d", entry.branch);
|
|
127
|
+
unregisterWorktree(entry.wtPath);
|
|
128
|
+
ok(`deleted ${entry.branch}`);
|
|
129
|
+
} catch {
|
|
130
|
+
warn(`failed to delete ${entry.branch} \u2014 may have uncommitted changes`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function confirm(prompt) {
|
|
135
|
+
const rl = readline.createInterface({
|
|
136
|
+
input: process.stdin,
|
|
137
|
+
output: process.stdout
|
|
138
|
+
});
|
|
139
|
+
return new Promise((resolve) => {
|
|
140
|
+
rl.question(prompt, (answer) => {
|
|
141
|
+
rl.close();
|
|
142
|
+
resolve(/^[Yy]$/.test(answer.trim()));
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export {
|
|
148
|
+
del
|
|
149
|
+
};
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import {
|
|
2
|
+
bold,
|
|
3
|
+
cyan,
|
|
4
|
+
dim,
|
|
5
|
+
green
|
|
6
|
+
} from "./chunk-YBCA3IP6.js";
|
|
7
|
+
|
|
8
|
+
// src/lib/select.ts
|
|
9
|
+
function flatten(groups) {
|
|
10
|
+
const items = [];
|
|
11
|
+
for (const group of groups) {
|
|
12
|
+
items.push({ type: "header", label: group.title });
|
|
13
|
+
for (const choice of group.choices) {
|
|
14
|
+
items.push({
|
|
15
|
+
type: "choice",
|
|
16
|
+
label: choice.label,
|
|
17
|
+
hint: choice.hint,
|
|
18
|
+
value: choice.value
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return items;
|
|
23
|
+
}
|
|
24
|
+
function selectableIndices(items) {
|
|
25
|
+
return items.reduce((acc, item, i) => {
|
|
26
|
+
if (item.type === "choice") acc.push(i);
|
|
27
|
+
return acc;
|
|
28
|
+
}, []);
|
|
29
|
+
}
|
|
30
|
+
function select(opts) {
|
|
31
|
+
const items = flatten(opts.groups);
|
|
32
|
+
const selectable = selectableIndices(items);
|
|
33
|
+
if (selectable.length === 0) return Promise.resolve(null);
|
|
34
|
+
let cursor = 0;
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
const { stdin, stdout } = process;
|
|
37
|
+
if (!stdin.isTTY) {
|
|
38
|
+
resolve(null);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
stdin.setRawMode(true);
|
|
42
|
+
stdin.resume();
|
|
43
|
+
stdin.setEncoding("utf8");
|
|
44
|
+
stdout.write("\x1B[?25l");
|
|
45
|
+
let lineCount = 0;
|
|
46
|
+
function render() {
|
|
47
|
+
let out = "";
|
|
48
|
+
if (lineCount > 0) out += `\x1B[${lineCount}A`;
|
|
49
|
+
const lines = [];
|
|
50
|
+
lines.push(`${cyan("?")} ${bold(opts.message)}`);
|
|
51
|
+
lines.push("");
|
|
52
|
+
for (let i = 0; i < items.length; i++) {
|
|
53
|
+
const item = items[i];
|
|
54
|
+
if (item.type === "header") {
|
|
55
|
+
lines.push(` ${bold(item.label)}`);
|
|
56
|
+
} else {
|
|
57
|
+
const active = selectable[cursor] === i;
|
|
58
|
+
const prefix = active ? cyan("> ") : " ";
|
|
59
|
+
const label = active ? item.label : dim(item.label);
|
|
60
|
+
const hint = item.hint ? ` ${dim(item.hint)}` : "";
|
|
61
|
+
lines.push(`${prefix}${label}${hint}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
out += lines.map((l) => `\x1B[2K${l}`).join("\n") + "\n";
|
|
65
|
+
stdout.write(out);
|
|
66
|
+
lineCount = lines.length;
|
|
67
|
+
}
|
|
68
|
+
function cleanup() {
|
|
69
|
+
stdin.removeListener("data", onKey);
|
|
70
|
+
stdin.setRawMode(false);
|
|
71
|
+
stdin.pause();
|
|
72
|
+
stdout.write("\x1B[?25h");
|
|
73
|
+
}
|
|
74
|
+
function onKey(data) {
|
|
75
|
+
if (data === "") {
|
|
76
|
+
cleanup();
|
|
77
|
+
process.exit(130);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (data === "\r" || data === "\n") {
|
|
81
|
+
cleanup();
|
|
82
|
+
resolve(items[selectable[cursor]].value);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (data === "\x1B[A" || data === "k") {
|
|
86
|
+
cursor = Math.max(0, cursor - 1);
|
|
87
|
+
render();
|
|
88
|
+
} else if (data === "\x1B[B" || data === "j") {
|
|
89
|
+
cursor = Math.min(selectable.length - 1, cursor + 1);
|
|
90
|
+
render();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
stdin.on("data", onKey);
|
|
94
|
+
render();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function multiSelect(opts) {
|
|
98
|
+
const items = flatten(opts.groups);
|
|
99
|
+
const selectable = selectableIndices(items);
|
|
100
|
+
if (selectable.length === 0) return Promise.resolve([]);
|
|
101
|
+
let cursor = 0;
|
|
102
|
+
const selected = /* @__PURE__ */ new Set();
|
|
103
|
+
return new Promise((resolve) => {
|
|
104
|
+
const { stdin, stdout } = process;
|
|
105
|
+
if (!stdin.isTTY) {
|
|
106
|
+
resolve([]);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
stdin.setRawMode(true);
|
|
110
|
+
stdin.resume();
|
|
111
|
+
stdin.setEncoding("utf8");
|
|
112
|
+
stdout.write("\x1B[?25l");
|
|
113
|
+
let lineCount = 0;
|
|
114
|
+
function render() {
|
|
115
|
+
let out = "";
|
|
116
|
+
if (lineCount > 0) out += `\x1B[${lineCount}A`;
|
|
117
|
+
const lines = [];
|
|
118
|
+
lines.push(
|
|
119
|
+
`${cyan("?")} ${bold(opts.message)} ${dim("(space = toggle, enter = confirm)")}`
|
|
120
|
+
);
|
|
121
|
+
lines.push("");
|
|
122
|
+
for (let i = 0; i < items.length; i++) {
|
|
123
|
+
const item = items[i];
|
|
124
|
+
if (item.type === "header") {
|
|
125
|
+
lines.push(` ${bold(item.label)}`);
|
|
126
|
+
} else {
|
|
127
|
+
const idx = selectable.indexOf(i);
|
|
128
|
+
const active = cursor === idx;
|
|
129
|
+
const checked = selected.has(idx);
|
|
130
|
+
const box = checked ? green("[x]") : dim("[ ]");
|
|
131
|
+
const prefix = active ? cyan("> ") : " ";
|
|
132
|
+
const hint = item.hint ? ` ${dim(item.hint)}` : "";
|
|
133
|
+
lines.push(`${prefix}${box} ${item.label}${hint}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
out += lines.map((l) => `\x1B[2K${l}`).join("\n") + "\n";
|
|
137
|
+
stdout.write(out);
|
|
138
|
+
lineCount = lines.length;
|
|
139
|
+
}
|
|
140
|
+
function cleanup() {
|
|
141
|
+
stdin.removeListener("data", onKey);
|
|
142
|
+
stdin.setRawMode(false);
|
|
143
|
+
stdin.pause();
|
|
144
|
+
stdout.write("\x1B[?25h");
|
|
145
|
+
}
|
|
146
|
+
function onKey(data) {
|
|
147
|
+
if (data === "") {
|
|
148
|
+
cleanup();
|
|
149
|
+
process.exit(130);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (data === "\r" || data === "\n") {
|
|
153
|
+
cleanup();
|
|
154
|
+
resolve([...selected].map((idx) => items[selectable[idx]].value));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (data === " ") {
|
|
158
|
+
if (selected.has(cursor)) selected.delete(cursor);
|
|
159
|
+
else selected.add(cursor);
|
|
160
|
+
render();
|
|
161
|
+
} else if (data === "\x1B[A" || data === "k") {
|
|
162
|
+
cursor = Math.max(0, cursor - 1);
|
|
163
|
+
render();
|
|
164
|
+
} else if (data === "\x1B[B" || data === "j") {
|
|
165
|
+
cursor = Math.min(selectable.length - 1, cursor + 1);
|
|
166
|
+
render();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
stdin.on("data", onKey);
|
|
170
|
+
render();
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
select,
|
|
176
|
+
multiSelect
|
|
177
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// src/lib/registry.ts
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as os from "os";
|
|
4
|
+
var REGISTRY_DIR = path.join(os.homedir(), ".glorious");
|
|
5
|
+
var REGISTRY_FILE = path.join(REGISTRY_DIR, "worktrees.json");
|
|
6
|
+
function ensureDir() {
|
|
7
|
+
Bun.mkdir(REGISTRY_DIR, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
function existsSync(filePath) {
|
|
10
|
+
return Bun.file(filePath).existsSync();
|
|
11
|
+
}
|
|
12
|
+
function readTextSync(filePath) {
|
|
13
|
+
try {
|
|
14
|
+
return Bun.file(filePath).textSync();
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function writeTextSync(filePath, content) {
|
|
20
|
+
Bun.file(filePath).writer().write(content);
|
|
21
|
+
}
|
|
22
|
+
function loadRegistry() {
|
|
23
|
+
if (!existsSync(REGISTRY_FILE)) return [];
|
|
24
|
+
try {
|
|
25
|
+
const raw = readTextSync(REGISTRY_FILE);
|
|
26
|
+
if (!raw) return [];
|
|
27
|
+
const entries = JSON.parse(raw);
|
|
28
|
+
const valid = entries.filter((e) => existsSync(e.wtPath));
|
|
29
|
+
if (valid.length !== entries.length) {
|
|
30
|
+
saveRegistry(valid);
|
|
31
|
+
}
|
|
32
|
+
return valid;
|
|
33
|
+
} catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function saveRegistry(entries) {
|
|
38
|
+
ensureDir();
|
|
39
|
+
writeTextSync(REGISTRY_FILE, JSON.stringify(entries, null, 2) + "\n");
|
|
40
|
+
}
|
|
41
|
+
function registerWorktree(entry) {
|
|
42
|
+
const entries = loadRegistry();
|
|
43
|
+
const filtered = entries.filter((e) => e.wtPath !== entry.wtPath);
|
|
44
|
+
filtered.push(entry);
|
|
45
|
+
saveRegistry(filtered);
|
|
46
|
+
}
|
|
47
|
+
function unregisterWorktree(wtPath) {
|
|
48
|
+
const entries = loadRegistry();
|
|
49
|
+
const filtered = entries.filter((e) => e.wtPath !== wtPath);
|
|
50
|
+
if (filtered.length !== entries.length) {
|
|
51
|
+
saveRegistry(filtered);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
loadRegistry,
|
|
57
|
+
saveRegistry,
|
|
58
|
+
registerWorktree,
|
|
59
|
+
unregisterWorktree
|
|
60
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
repoName,
|
|
3
|
+
worktreePath
|
|
4
|
+
} from "./chunk-W37UX3U2.js";
|
|
5
|
+
import {
|
|
6
|
+
defaultBranchIn,
|
|
7
|
+
gitIn,
|
|
8
|
+
gitInSafe,
|
|
9
|
+
gitRoot
|
|
10
|
+
} from "./chunk-LMRDQ4GW.js";
|
|
11
|
+
import {
|
|
12
|
+
registerWorktree
|
|
13
|
+
} from "./chunk-VCN7RNLU.js";
|
|
14
|
+
import {
|
|
15
|
+
bold,
|
|
16
|
+
info,
|
|
17
|
+
ok,
|
|
18
|
+
warn
|
|
19
|
+
} from "./chunk-YBCA3IP6.js";
|
|
20
|
+
|
|
21
|
+
// src/lib/worktree.ts
|
|
22
|
+
import * as path from "path";
|
|
23
|
+
function existsSync(filePath) {
|
|
24
|
+
return Bun.file(filePath).existsSync();
|
|
25
|
+
}
|
|
26
|
+
function mkdirSync(dirPath, opts) {
|
|
27
|
+
Bun.mkdir(dirPath, opts);
|
|
28
|
+
}
|
|
29
|
+
function autoName(now = /* @__PURE__ */ new Date(), suffix = randomSuffix()) {
|
|
30
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
31
|
+
const yy = now.getFullYear().toString().slice(2);
|
|
32
|
+
const mm = pad(now.getMonth() + 1);
|
|
33
|
+
const dd = pad(now.getDate());
|
|
34
|
+
const hh = pad(now.getHours());
|
|
35
|
+
const mi = pad(now.getMinutes());
|
|
36
|
+
const ss = pad(now.getSeconds());
|
|
37
|
+
return `wt-${yy}${mm}${dd}-${hh}${mi}${ss}-${suffix}`;
|
|
38
|
+
}
|
|
39
|
+
function randomSuffix() {
|
|
40
|
+
return Math.random().toString(36).slice(2, 5).padEnd(3, "0");
|
|
41
|
+
}
|
|
42
|
+
function assertPrimaryClone(srcRepo) {
|
|
43
|
+
const commonDir = gitInSafe(srcRepo, "rev-parse", "--git-common-dir");
|
|
44
|
+
if (!commonDir) return;
|
|
45
|
+
if (!path.isAbsolute(commonDir)) return;
|
|
46
|
+
const primary = path.dirname(commonDir);
|
|
47
|
+
if (path.resolve(primary) === path.resolve(srcRepo)) return;
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Refusing to create a nested worktree.
|
|
50
|
+
'${srcRepo}' is itself a worktree of '${primary}'.
|
|
51
|
+
Create worktrees from the primary clone, or pass a repo name:
|
|
52
|
+
glrs wt new <repo>`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function createWorktree(opts = {}) {
|
|
56
|
+
const srcRepo = opts.repoPath ?? gitRoot();
|
|
57
|
+
assertPrimaryClone(srcRepo);
|
|
58
|
+
const repo = opts.repo ?? path.basename(srcRepo);
|
|
59
|
+
const name = opts.name ?? autoName();
|
|
60
|
+
const wtPath = worktreePath(name, repo);
|
|
61
|
+
if (existsSync(wtPath)) {
|
|
62
|
+
throw new Error(`Worktree already exists: ${wtPath}`);
|
|
63
|
+
}
|
|
64
|
+
mkdirSync(path.dirname(wtPath), { recursive: true });
|
|
65
|
+
const base = opts.from ?? defaultBranchIn(srcRepo);
|
|
66
|
+
info(`fetching origin/${base}...`);
|
|
67
|
+
gitIn(srcRepo, "fetch", "origin", base, "--quiet");
|
|
68
|
+
const branchExists = gitInSafe(srcRepo, "show-ref", "--verify", `refs/heads/${name}`) !== null;
|
|
69
|
+
if (branchExists) {
|
|
70
|
+
warn(`branch ${bold(name)} already exists, resetting to origin/${base}`);
|
|
71
|
+
gitIn(srcRepo, "branch", "-D", name);
|
|
72
|
+
}
|
|
73
|
+
info(`creating worktree ${bold(name)} from origin/${base}...`);
|
|
74
|
+
gitIn(
|
|
75
|
+
srcRepo,
|
|
76
|
+
"worktree",
|
|
77
|
+
"add",
|
|
78
|
+
"-b",
|
|
79
|
+
name,
|
|
80
|
+
wtPath,
|
|
81
|
+
`origin/${base}`,
|
|
82
|
+
"--quiet"
|
|
83
|
+
);
|
|
84
|
+
try {
|
|
85
|
+
gitIn(wtPath, "branch", "--set-upstream-to", `origin/${base}`, name);
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
registerWorktree({
|
|
89
|
+
repo,
|
|
90
|
+
repoPath: srcRepo,
|
|
91
|
+
wtPath,
|
|
92
|
+
branch: name,
|
|
93
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
94
|
+
});
|
|
95
|
+
ok(`worktree created at ${bold(wtPath)}`);
|
|
96
|
+
return { wtPath, name, base };
|
|
97
|
+
}
|
|
98
|
+
function ensureWorktree(name, from) {
|
|
99
|
+
const repo = repoName();
|
|
100
|
+
const wtPath = worktreePath(name, repo);
|
|
101
|
+
if (existsSync(wtPath)) {
|
|
102
|
+
info(`worktree already exists at ${bold(wtPath)}, reusing...`);
|
|
103
|
+
registerWorktree({
|
|
104
|
+
repo,
|
|
105
|
+
repoPath: gitRoot(),
|
|
106
|
+
wtPath,
|
|
107
|
+
branch: name,
|
|
108
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
109
|
+
});
|
|
110
|
+
return wtPath;
|
|
111
|
+
}
|
|
112
|
+
return createWorktree({ name, from }).wtPath;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export {
|
|
116
|
+
autoName,
|
|
117
|
+
assertPrimaryClone,
|
|
118
|
+
createWorktree,
|
|
119
|
+
ensureWorktree
|
|
120
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
gitRoot
|
|
3
|
+
} from "./chunk-LMRDQ4GW.js";
|
|
4
|
+
|
|
5
|
+
// src/lib/config.ts
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import * as os from "os";
|
|
8
|
+
var PROTECTED_BRANCHES = /* @__PURE__ */ new Set([
|
|
9
|
+
"main",
|
|
10
|
+
"master",
|
|
11
|
+
"next",
|
|
12
|
+
"prerelease"
|
|
13
|
+
]);
|
|
14
|
+
function isProtected(branch) {
|
|
15
|
+
return PROTECTED_BRANCHES.has(branch);
|
|
16
|
+
}
|
|
17
|
+
function repoName() {
|
|
18
|
+
return path.basename(gitRoot());
|
|
19
|
+
}
|
|
20
|
+
function worktreesRoot(repo) {
|
|
21
|
+
const override = process.env.GLORIOUS_DIR;
|
|
22
|
+
if (override) return path.resolve(override, repo);
|
|
23
|
+
return path.join(os.homedir(), ".glorious", "worktrees", repo);
|
|
24
|
+
}
|
|
25
|
+
function worktreePath(name, repo) {
|
|
26
|
+
const repoKey = repo ?? repoName();
|
|
27
|
+
return path.join(worktreesRoot(repoKey), name);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
isProtected,
|
|
32
|
+
repoName,
|
|
33
|
+
worktreesRoot,
|
|
34
|
+
worktreePath
|
|
35
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/lib/fmt.ts
|
|
2
|
+
var isTTY = process.stdout.isTTY;
|
|
3
|
+
var bold = (s) => isTTY ? `\x1B[1m${s}\x1B[0m` : s;
|
|
4
|
+
var dim = (s) => isTTY ? `\x1B[2m${s}\x1B[0m` : s;
|
|
5
|
+
var red = (s) => isTTY ? `\x1B[31m${s}\x1B[0m` : s;
|
|
6
|
+
var green = (s) => isTTY ? `\x1B[32m${s}\x1B[0m` : s;
|
|
7
|
+
var yellow = (s) => isTTY ? `\x1B[33m${s}\x1B[0m` : s;
|
|
8
|
+
var cyan = (s) => isTTY ? `\x1B[36m${s}\x1B[0m` : s;
|
|
9
|
+
var ok = (msg) => console.log(`${green("\u2713")} ${msg}`);
|
|
10
|
+
var okErr = (msg) => console.error(`${green("\u2713")} ${msg}`);
|
|
11
|
+
var info = (msg) => console.log(`${cyan("\u25B8")} ${msg}`);
|
|
12
|
+
var warn = (msg) => console.error(`${yellow("warning:")} ${msg}`);
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
bold,
|
|
16
|
+
dim,
|
|
17
|
+
red,
|
|
18
|
+
green,
|
|
19
|
+
yellow,
|
|
20
|
+
cyan,
|
|
21
|
+
ok,
|
|
22
|
+
okErr,
|
|
23
|
+
info,
|
|
24
|
+
warn
|
|
25
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import { dirname, resolve as pathResolve } from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
function resolveVendoredHarness(binKey) {
|
|
6
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const vendorPkgJson = pathResolve(here, "vendor", "harness-opencode", "package.json");
|
|
8
|
+
let pkgJsonPath;
|
|
9
|
+
try {
|
|
10
|
+
readFileSync(vendorPkgJson, "utf8");
|
|
11
|
+
pkgJsonPath = vendorPkgJson;
|
|
12
|
+
} catch {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`[@glrs-dev/cli] Vendored harness-opencode not found at ${vendorPkgJson}.
|
|
15
|
+
This means the cli package was built incorrectly or the tarball is incomplete.
|
|
16
|
+
Report at https://github.com/iceglober/glrs/issues.`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
20
|
+
const bin = pkgJson.bin;
|
|
21
|
+
let relative;
|
|
22
|
+
if (typeof bin === "string") {
|
|
23
|
+
relative = bin;
|
|
24
|
+
} else if (bin && typeof bin === "object" && typeof bin[binKey] === "string") {
|
|
25
|
+
relative = bin[binKey];
|
|
26
|
+
} else {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`[@glrs-dev/cli] Vendored harness-opencode has no bin entry for '${binKey}'. This shouldn't happen \u2014 report at https://github.com/iceglober/glrs/issues.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const binPath = pathResolve(dirname(pkgJsonPath), relative);
|
|
32
|
+
return { executable: "bun", preArgs: [binPath] };
|
|
33
|
+
}
|
|
34
|
+
function resolveSubcommand(sub) {
|
|
35
|
+
switch (sub) {
|
|
36
|
+
case "oc":
|
|
37
|
+
return resolveVendoredHarness("harness-opencode");
|
|
38
|
+
case "wt":
|
|
39
|
+
throw new Error("Worktree commands should be handled natively");
|
|
40
|
+
default: {
|
|
41
|
+
const exhaustive = sub;
|
|
42
|
+
throw new Error(`Unknown subcommand: ${exhaustive}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
var SUBCOMMANDS = ["oc", "wt"];
|
|
47
|
+
var HELP_TEXT = `glrs \u2014 unified CLI for the @glrs-dev ecosystem
|
|
48
|
+
|
|
49
|
+
USAGE
|
|
50
|
+
glrs <subcommand> [args...]
|
|
51
|
+
|
|
52
|
+
SUBCOMMANDS
|
|
53
|
+
oc OpenCode agent harness (install, pilot, etc.)
|
|
54
|
+
wt Worktree management (create, list, switch, delete, cleanup)
|
|
55
|
+
|
|
56
|
+
Run 'glrs <subcommand> --help' for per-command help.
|
|
57
|
+
|
|
58
|
+
EXAMPLES
|
|
59
|
+
glrs oc install
|
|
60
|
+
glrs wt new
|
|
61
|
+
glrs wt list
|
|
62
|
+
glrs wt switch
|
|
63
|
+
|
|
64
|
+
REQUIREMENTS
|
|
65
|
+
Bun >= 1.2.0 on PATH (install: https://bun.sh)
|
|
66
|
+
|
|
67
|
+
DOCS https://glrs.dev
|
|
68
|
+
ISSUES https://github.com/iceglober/glrs/issues
|
|
69
|
+
`;
|
|
70
|
+
var WORKTREE_HELP_TEXT = `glrs wt \u2014 worktree management
|
|
71
|
+
|
|
72
|
+
USAGE
|
|
73
|
+
glrs wt <command> [args...]
|
|
74
|
+
|
|
75
|
+
COMMANDS
|
|
76
|
+
new Create a new worktree (auto-named from origin/default)
|
|
77
|
+
list, ls List all worktrees across repos
|
|
78
|
+
switch, sw Interactively select and switch to a worktree
|
|
79
|
+
delete, rm Remove worktrees (interactive or by name)
|
|
80
|
+
cleanup Delete merged/stale worktrees
|
|
81
|
+
|
|
82
|
+
EXAMPLES
|
|
83
|
+
glrs wt new # Create worktree in current repo
|
|
84
|
+
glrs wt new myrepo # Create worktree for named repo
|
|
85
|
+
glrs wt list # Show all worktrees
|
|
86
|
+
glrs wt list -i # Interactive picker
|
|
87
|
+
glrs wt switch # Interactive switcher
|
|
88
|
+
glrs wt delete my-branch # Delete specific worktree
|
|
89
|
+
glrs wt cleanup # Clean up merged worktrees
|
|
90
|
+
|
|
91
|
+
Worktrees are stored in ~/.glorious/worktrees/<repo>/<name>/
|
|
92
|
+
`;
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
resolveSubcommand,
|
|
96
|
+
SUBCOMMANDS,
|
|
97
|
+
HELP_TEXT,
|
|
98
|
+
WORKTREE_HELP_TEXT
|
|
99
|
+
};
|
package/dist/cli.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|