@maxiaochao/pi-toolkit 0.5.1 → 0.5.3
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 +8 -0
- package/bin/pi-worktree +61 -10
- package/extensions/btw.ts +11 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 2026-09-15 - v0.5.3
|
|
2
|
+
|
|
3
|
+
- fix pi-worktree remove: worktrees with initialized submodules now remove via forced retry; dirty worktrees confirm the discard explicitly before removal; worktrees whose directory is already gone now prune their stale registration and clean up the branch
|
|
4
|
+
|
|
5
|
+
## 2026-09-11 - v0.5.2
|
|
6
|
+
|
|
7
|
+
- fix btw: side-session and summarize passed a nonexistent `modelRegistry` option to `createAgentSession`, so a fresh ModelRuntime was created that didn't know extension-registered providers (e.g. volcengine-plan) and prompting failed with "No API key found"; now the main session's ModelRuntime is reused via `modelRuntime`
|
|
8
|
+
|
|
1
9
|
## 2026-09-11 - v0.5.1
|
|
2
10
|
|
|
3
11
|
- fix pi-worktree: remove now cleans up the branch automatically — merged branches are deleted without prompting, unmerged ones confirm once (one prompt covers both worktree removal and branch deletion), so recreating the same name no longer silently reuses a stale branch
|
package/bin/pi-worktree
CHANGED
|
@@ -141,17 +141,68 @@ cmd_remove() {
|
|
|
141
141
|
require_repo
|
|
142
142
|
[[ $# -eq 1 ]] || die "usage: pi-worktree -r <name>"
|
|
143
143
|
local dir; dir="$(wt_dir "$1")"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
144
|
+
local branch registered rm_anyway=0 force=0
|
|
145
|
+
if [[ ! -d "$dir" ]]; then
|
|
146
|
+
# Directory already gone but possibly still registered (prunable), or a
|
|
147
|
+
# stale branch left behind by an earlier prune: clean the registration,
|
|
148
|
+
# then fall through to the branch cleanup.
|
|
149
|
+
local registered
|
|
150
|
+
registered=$(git worktree list --porcelain | awk -v p="$(pwd -P)/$dir" '
|
|
151
|
+
$0=="worktree "p {f=1; next}
|
|
152
|
+
f && /^branch / {print substr($0,8); exit}
|
|
153
|
+
f && /^detached/ {print "-"; exit}
|
|
154
|
+
f && /^$/ {exit}')
|
|
155
|
+
if [[ "$registered" == "-" ]]; then
|
|
156
|
+
git worktree prune
|
|
157
|
+
ok "pruned stale registration: $dir (directory already gone)"
|
|
158
|
+
return 0 # detached HEAD, nothing else to clean up
|
|
159
|
+
fi
|
|
160
|
+
if [[ -n "$registered" ]]; then
|
|
161
|
+
branch=${registered#refs/heads/}
|
|
162
|
+
elif git show-ref --verify --quiet "refs/heads/$1"; then
|
|
163
|
+
branch=$1 # registration already pruned; only the stale branch remains
|
|
164
|
+
else
|
|
165
|
+
die "worktree not found: $dir"
|
|
166
|
+
fi
|
|
167
|
+
if [[ -n "$registered" ]]; then
|
|
168
|
+
git worktree prune
|
|
169
|
+
ok "pruned stale registration: $dir (directory already gone)"
|
|
170
|
+
fi
|
|
171
|
+
else
|
|
172
|
+
# dirty worktree: removing discards modified/untracked files, which git
|
|
173
|
+
# refuses to do without --force — so confirm the loss explicitly
|
|
174
|
+
if ! git -C "$dir" diff --quiet 2>/dev/null \
|
|
175
|
+
|| ! git -C "$dir" diff --cached --quiet 2>/dev/null \
|
|
176
|
+
|| [[ -n "$(git -C "$dir" ls-files --others --exclude-standard)" ]]; then
|
|
177
|
+
warn "worktree contains modified/untracked files that will be discarded:"
|
|
178
|
+
git -C "$dir" status --short | head -10
|
|
179
|
+
read -rp "Discard and remove anyway? [y/N] " ans
|
|
180
|
+
[[ "$ans" =~ ^[Yy]$ ]] || die "aborted"
|
|
181
|
+
force=1
|
|
182
|
+
fi
|
|
183
|
+
branch=$(git -C "$dir" branch --show-current)
|
|
184
|
+
# refuse to remove if the branch is not merged into main
|
|
185
|
+
if [[ -n "$branch" ]] && ! git merge-base --is-ancestor "$branch" main 2>/dev/null; then
|
|
186
|
+
warn "branch '$branch' does not appear merged into 'main' (or no main branch exists)."
|
|
187
|
+
read -rp "Remove anyway? [y/N] " ans
|
|
188
|
+
[[ "$ans" =~ ^[Yy]$ ]] || die "aborted"
|
|
189
|
+
rm_anyway=1
|
|
190
|
+
fi
|
|
191
|
+
local out
|
|
192
|
+
if [[ "$force" == 1 ]]; then
|
|
193
|
+
git worktree remove --force "$dir" && ok "removed: $dir (discarded changes as confirmed)"
|
|
194
|
+
elif out=$(git worktree remove "$dir" 2>&1); then
|
|
195
|
+
ok "removed: $dir"
|
|
196
|
+
elif [[ "$out" == *"submodules cannot be moved or removed"* ]]; then
|
|
197
|
+
# git refuses to remove worktrees with initialized submodules unless
|
|
198
|
+
# --force is used (--force only overrides the submodule check here; the
|
|
199
|
+
# branch deletion below still asks before dropping unmerged commits)
|
|
200
|
+
git worktree remove --force "$dir" && ok "removed: $dir (contained submodules)"
|
|
201
|
+
else
|
|
202
|
+
printf '%s\n' "$out" >&2
|
|
203
|
+
die "failed to remove worktree: $dir"
|
|
204
|
+
fi
|
|
153
205
|
fi
|
|
154
|
-
git worktree remove "$dir" && ok "removed: $dir"
|
|
155
206
|
# The branch survives `git worktree remove`; recreating the same name would
|
|
156
207
|
# silently reuse this stale branch. Delete merged branches automatically.
|
|
157
208
|
if [[ -n "$branch" ]] && git show-ref --verify --quiet "refs/heads/$branch"; then
|
package/extensions/btw.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type ExtensionAPI,
|
|
10
10
|
type ExtensionCommandContext,
|
|
11
11
|
type ExtensionContext,
|
|
12
|
+
type ModelRuntime,
|
|
12
13
|
type ResourceLoader,
|
|
13
14
|
} from "@earendil-works/pi-coding-agent";
|
|
14
15
|
import { type AssistantMessage, type Message, type ThinkingLevel as AiThinkingLevel } from "@earendil-works/pi-ai";
|
|
@@ -633,7 +634,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
633
634
|
const { session } = await createAgentSession({
|
|
634
635
|
sessionManager: SessionManager.inMemory(),
|
|
635
636
|
model: ctx.model,
|
|
636
|
-
|
|
637
|
+
modelRuntime: getParentModelRuntime(ctx),
|
|
637
638
|
thinkingLevel: pi.getThinkingLevel() as SessionThinkingLevel,
|
|
638
639
|
tools: ["read", "bash", "edit", "write"],
|
|
639
640
|
resourceLoader: createBtwResourceLoader(ctx),
|
|
@@ -809,6 +810,14 @@ export default function (pi: ExtensionAPI) {
|
|
|
809
810
|
});
|
|
810
811
|
}
|
|
811
812
|
|
|
813
|
+
function getParentModelRuntime(ctx: ExtensionCommandContext | ExtensionContext): ModelRuntime {
|
|
814
|
+
// The ModelRegistry facade keeps its runtime in a JS property that is
|
|
815
|
+
// private at the type level. Reusing it is required: a fresh ModelRuntime
|
|
816
|
+
// would not know about extension-registered providers (e.g. volcengine-plan),
|
|
817
|
+
// causing "No API key found" even when auth.json has the credential.
|
|
818
|
+
return (ctx.modelRegistry as unknown as { runtime: ModelRuntime }).runtime;
|
|
819
|
+
}
|
|
820
|
+
|
|
812
821
|
async function summarizeThread(ctx: ExtensionContext, items: BtwDetails[]): Promise<string> {
|
|
813
822
|
const model = ctx.model;
|
|
814
823
|
if (!model) {
|
|
@@ -823,7 +832,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
823
832
|
const { session } = await createAgentSession({
|
|
824
833
|
sessionManager: SessionManager.inMemory(),
|
|
825
834
|
model,
|
|
826
|
-
|
|
835
|
+
modelRuntime: getParentModelRuntime(ctx),
|
|
827
836
|
thinkingLevel: "off",
|
|
828
837
|
tools: [],
|
|
829
838
|
resourceLoader: createBtwResourceLoader(ctx, [BTW_SUMMARY_PROMPT]),
|
package/package.json
CHANGED