@pugi/cli 0.1.0-beta.3 → 0.1.0-beta.30
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/THIRD_PARTY_NOTICES.md +40 -0
- package/assets/pugi-mascot.ansi +15 -40
- package/bin/run.js +33 -1
- package/dist/commands/jobs-watch.js +201 -0
- package/dist/commands/jobs.js +15 -0
- package/dist/core/agent-progress/cleanup.js +134 -0
- package/dist/core/agent-progress/schema.js +144 -0
- package/dist/core/agent-progress/writer.js +101 -0
- package/dist/core/artifact-chain/dispatcher.js +148 -0
- package/dist/core/artifact-chain/exporter.js +164 -0
- package/dist/core/artifact-chain/state.js +243 -0
- package/dist/core/artifact-chain/steps.js +169 -0
- package/dist/core/auth/env-provider.js +238 -0
- package/dist/core/auto-update/channels.js +122 -0
- package/dist/core/auto-update/checker.js +241 -0
- package/dist/core/auto-update/state.js +235 -0
- package/dist/core/bare-mode/index.js +107 -0
- package/dist/core/checkpoint/resumer.js +149 -0
- package/dist/core/checkpoint/rewinder.js +291 -0
- package/dist/core/compact/auto-trigger.js +96 -0
- package/dist/core/compact/buffer-rewriter.js +115 -0
- package/dist/core/compact/summarizer.js +208 -0
- package/dist/core/compact/token-counter.js +108 -0
- package/dist/core/consensus/diff-capture.js +73 -0
- package/dist/core/context/index.js +7 -0
- package/dist/core/context/markdown-traverse.js +255 -0
- package/dist/core/cost/rate-card.js +129 -0
- package/dist/core/cost/tracker.js +221 -0
- package/dist/core/denial-tracking/index.js +8 -0
- package/dist/core/denial-tracking/state.js +264 -0
- package/dist/core/diagnostics/probe-runner.js +93 -0
- package/dist/core/diagnostics/probes/api.js +46 -0
- package/dist/core/diagnostics/probes/auth.js +86 -0
- package/dist/core/diagnostics/probes/bare-mode.js +42 -0
- package/dist/core/diagnostics/probes/cli-version.js +127 -0
- package/dist/core/diagnostics/probes/config.js +72 -0
- package/dist/core/diagnostics/probes/denial-tracking.js +57 -0
- package/dist/core/diagnostics/probes/disk.js +81 -0
- package/dist/core/diagnostics/probes/git.js +65 -0
- package/dist/core/diagnostics/probes/mcp.js +75 -0
- package/dist/core/diagnostics/probes/node.js +59 -0
- package/dist/core/diagnostics/probes/pnpm.js +36 -0
- package/dist/core/diagnostics/probes/pugi-md.js +89 -0
- package/dist/core/diagnostics/probes/session.js +74 -0
- package/dist/core/diagnostics/probes/status-snapshot.js +442 -0
- package/dist/core/diagnostics/probes/workspace.js +63 -0
- package/dist/core/diagnostics/types.js +70 -0
- package/dist/core/dispatch/cache-cleanup.js +197 -0
- package/dist/core/dispatch/cache-handoff.js +295 -0
- package/dist/core/edits/dispatch.js +218 -2
- package/dist/core/edits/journal.js +199 -0
- package/dist/core/edits/layer-d-ast.js +557 -14
- package/dist/core/edits/verify-hook.js +273 -0
- package/dist/core/edits/worktree.js +111 -18
- package/dist/core/engine/anvil-client.js +115 -5
- package/dist/core/engine/budgets.js +89 -0
- package/dist/core/engine/context-prefix.js +155 -0
- package/dist/core/engine/intent.js +260 -0
- package/dist/core/engine/native-pugi.js +852 -210
- package/dist/core/engine/prompts.js +89 -6
- package/dist/core/engine/strip-internal-fields.js +124 -0
- package/dist/core/engine/tool-bridge.js +972 -33
- package/dist/core/feedback/queue.js +177 -0
- package/dist/core/feedback/submitter.js +145 -0
- package/dist/core/file-cache.js +113 -1
- package/dist/core/hooks/events.js +44 -0
- package/dist/core/hooks/index.js +15 -0
- package/dist/core/hooks/registry.js +213 -0
- package/dist/core/hooks/runner.js +236 -0
- package/dist/core/init/scaffold.js +195 -0
- package/dist/core/lsp/cache.js +105 -0
- package/dist/core/lsp/client.js +174 -29
- package/dist/core/lsp/language-detect.js +66 -0
- package/dist/core/lsp/post-edit-diagnostics.js +171 -0
- package/dist/core/mcp/client.js +75 -6
- package/dist/core/mcp/http-server.js +553 -0
- package/dist/core/mcp/permission.js +190 -0
- package/dist/core/mcp/registry.js +24 -2
- package/dist/core/mcp/server-tools.js +219 -0
- package/dist/core/mcp/server.js +397 -0
- package/dist/core/memory/dual-write.js +416 -0
- package/dist/core/memory/dual-write.spec.js +297 -0
- package/dist/core/memory/phase1-kinds.js +20 -0
- package/dist/core/memory-sync/queue.js +158 -0
- package/dist/core/memory-sync/queue.spec.js +105 -0
- package/dist/core/onboarding/marker.js +111 -0
- package/dist/core/onboarding/telemetry-state.js +108 -0
- package/dist/core/output-style/presets.js +176 -0
- package/dist/core/output-style/state.js +185 -0
- package/dist/core/permissions/gate.js +187 -0
- package/dist/core/permissions/index.js +18 -0
- package/dist/core/permissions/mode.js +102 -0
- package/dist/core/permissions/state.js +215 -0
- package/dist/core/permissions/tool-class.js +93 -0
- package/dist/core/prd-check/parser.js +215 -0
- package/dist/core/prd-check/reporter.js +127 -0
- package/dist/core/prd-check/verifiers.js +223 -0
- package/dist/core/pugi-md/context-injector.js +76 -0
- package/dist/core/pugi-md/walk-up.js +207 -0
- package/dist/core/release-notes/parser.js +241 -0
- package/dist/core/release-notes/state.js +116 -0
- package/dist/core/repl/codebase-survey.js +308 -0
- package/dist/core/repl/history.js +11 -1
- package/dist/core/repl/init-interview.js +457 -0
- package/dist/core/repl/model-pricing.js +135 -0
- package/dist/core/repl/onboarding-state.js +297 -0
- package/dist/core/repl/session.js +1486 -30
- package/dist/core/repl/slash-commands.js +345 -9
- package/dist/core/repl/store/session-store.js +31 -2
- package/dist/core/repl/workspace-context.js +22 -0
- package/dist/core/repo-map/build.js +125 -0
- package/dist/core/repo-map/cache.js +185 -0
- package/dist/core/repo-map/extractor.js +254 -0
- package/dist/core/repo-map/formatter.js +145 -0
- package/dist/core/repo-map/scanner.js +211 -0
- package/dist/core/retry-budget/budget.js +284 -0
- package/dist/core/retry-budget/index.js +5 -0
- package/dist/core/session.js +44 -0
- package/dist/core/settings.js +80 -0
- package/dist/core/share/formatter.js +271 -0
- package/dist/core/share/redactor.js +221 -0
- package/dist/core/share/uploader.js +267 -0
- package/dist/core/skills/defaults.js +457 -0
- package/dist/core/subagents/dispatcher-real.js +600 -0
- package/dist/core/subagents/dispatcher.js +113 -24
- package/dist/core/subagents/index.js +18 -5
- package/dist/core/subagents/isolation-matrix.js +213 -0
- package/dist/core/subagents/spawn.js +19 -4
- package/dist/core/telemetry/emitter.js +229 -0
- package/dist/core/telemetry/queue.js +251 -0
- package/dist/core/theme/context.js +91 -0
- package/dist/core/theme/presets.js +228 -0
- package/dist/core/theme/state.js +181 -0
- package/dist/core/todos/invariant.js +10 -0
- package/dist/core/todos/state.js +177 -0
- package/dist/core/transport/version-interceptor.js +166 -0
- package/dist/core/vim/keymap.js +288 -0
- package/dist/core/vim/state.js +92 -0
- package/dist/index.js +28 -0
- package/dist/runtime/bootstrap.js +190 -0
- package/dist/runtime/cli.js +2595 -278
- package/dist/runtime/commands/chain.js +489 -0
- package/dist/runtime/commands/compact.js +297 -0
- package/dist/runtime/commands/cost.js +199 -0
- package/dist/runtime/commands/delegate.js +312 -0
- package/dist/runtime/commands/dispatch.js +126 -0
- package/dist/runtime/commands/doctor.js +390 -0
- package/dist/runtime/commands/feedback.js +184 -0
- package/dist/runtime/commands/hooks.js +184 -0
- package/dist/runtime/commands/lsp.js +212 -28
- package/dist/runtime/commands/mcp.js +824 -0
- package/dist/runtime/commands/memory.js +508 -0
- package/dist/runtime/commands/memory.spec.js +174 -0
- package/dist/runtime/commands/model.js +237 -0
- package/dist/runtime/commands/onboarding.js +275 -0
- package/dist/runtime/commands/patch.js +17 -0
- package/dist/runtime/commands/permissions.js +87 -0
- package/dist/runtime/commands/plan.js +143 -0
- package/dist/runtime/commands/prd-check.js +235 -0
- package/dist/runtime/commands/release-notes.js +229 -0
- package/dist/runtime/commands/repo-map.js +95 -0
- package/dist/runtime/commands/report.js +299 -0
- package/dist/runtime/commands/resume.js +118 -0
- package/dist/runtime/commands/review-consensus.js +17 -2
- package/dist/runtime/commands/rewind.js +333 -0
- package/dist/runtime/commands/roster.js +117 -0
- package/dist/runtime/commands/sessions.js +163 -0
- package/dist/runtime/commands/share.js +316 -0
- package/dist/runtime/commands/status.js +178 -0
- package/dist/runtime/commands/stickers.js +82 -0
- package/dist/runtime/commands/style.js +194 -0
- package/dist/runtime/commands/theme.js +196 -0
- package/dist/runtime/commands/update.js +289 -0
- package/dist/runtime/commands/vim.js +140 -0
- package/dist/runtime/commands/worktree.js +50 -6
- package/dist/runtime/headless.js +543 -0
- package/dist/runtime/load-hooks-or-exit.js +71 -0
- package/dist/runtime/plan-decompose.js +531 -0
- package/dist/runtime/version.js +65 -0
- package/dist/tools/agent-tool.js +229 -0
- package/dist/tools/apply-patch.js +281 -39
- package/dist/tools/ask-user-question.js +213 -0
- package/dist/tools/ask-user.js +115 -0
- package/dist/tools/file-tools.js +85 -14
- package/dist/tools/mcp-tool.js +260 -0
- package/dist/tools/multi-edit.js +361 -0
- package/dist/tools/registry.js +30 -2
- package/dist/tools/skill-tool.js +96 -0
- package/dist/tools/tasks.js +208 -0
- package/dist/tools/todo-write.js +184 -0
- package/dist/tools/web-fetch.js +147 -2
- package/dist/tools/web-search.js +458 -0
- package/dist/tui/agent-progress-card.js +111 -0
- package/dist/tui/agent-tree.js +10 -0
- package/dist/tui/ask-modal.js +2 -2
- package/dist/tui/ask-user-question-prompt.js +192 -0
- package/dist/tui/compact-banner.js +81 -0
- package/dist/tui/conversation-pane.js +82 -8
- package/dist/tui/cost-table.js +111 -0
- package/dist/tui/doctor-table.js +46 -0
- package/dist/tui/feedback-prompt.js +156 -0
- package/dist/tui/input-box.js +46 -2
- package/dist/tui/markdown-render.js +4 -4
- package/dist/tui/onboarding-wizard.js +240 -0
- package/dist/tui/repl-render.js +293 -35
- package/dist/tui/repl-splash.js +2 -2
- package/dist/tui/repl.js +45 -13
- package/dist/tui/splash.js +1 -1
- package/dist/tui/status-bar.js +94 -16
- package/dist/tui/status-table.js +7 -0
- package/dist/tui/stickers-art.js +136 -0
- package/dist/tui/style-table.js +28 -0
- package/dist/tui/theme-table.js +29 -0
- package/dist/tui/tool-stream-pane.js +7 -0
- package/dist/tui/update-banner.js +20 -2
- package/dist/tui/vim-input.js +267 -0
- package/docs/examples/codegraph.mcp.json +10 -0
- package/package.json +9 -6
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Leak L26 (2026-05-27) — `pugi vim` top-level command + REPL slash
|
|
3
|
+
* companion.
|
|
4
|
+
*
|
|
5
|
+
* Operator surface:
|
|
6
|
+
*
|
|
7
|
+
* pugi vim Show current vim-mode state.
|
|
8
|
+
* pugi vim on Enable + persist (~/.pugi/config.json).
|
|
9
|
+
* pugi vim off Disable + persist (default).
|
|
10
|
+
* /vim Toggle from inside the REPL.
|
|
11
|
+
* /vim on Enable from inside the REPL.
|
|
12
|
+
* /vim off Disable from inside the REPL.
|
|
13
|
+
*
|
|
14
|
+
* The same runner backs both surfaces so the slash + the shell verb
|
|
15
|
+
* stay single-sourced — operators trained on one read the same
|
|
16
|
+
* payload + banner on the other.
|
|
17
|
+
*
|
|
18
|
+
* Exit codes:
|
|
19
|
+
* 0 — show / enable / disable / toggle happy path
|
|
20
|
+
* 2 — unknown subcommand (e.g. `pugi vim chaos`)
|
|
21
|
+
*
|
|
22
|
+
* NOTE: there are NO `--persist` flag and no workspace tier. Vim mode
|
|
23
|
+
* is a single user-level preference, matching the leak research note
|
|
24
|
+
* that operators expect modal editing to be a body-memory trait, not
|
|
25
|
+
* a per-repo concern (see `core/vim/state.ts` header).
|
|
26
|
+
*/
|
|
27
|
+
import { resolveVimMode, setVimMode } from '../../core/vim/state.js';
|
|
28
|
+
/**
|
|
29
|
+
* Banner shown on enable so the operator can see the binding cheat
|
|
30
|
+
* sheet without reaching for `/help`. Echoed by both surfaces.
|
|
31
|
+
*/
|
|
32
|
+
export const VIM_ENABLED_BANNER = 'Vim mode on. Esc=normal, i=insert, :w=submit, :q=cancel.';
|
|
33
|
+
/**
|
|
34
|
+
* Entry point. Parses `args`, flips persistence as needed, emits the
|
|
35
|
+
* payload + text via `ctx.writeOutput`, and returns the exit code.
|
|
36
|
+
*/
|
|
37
|
+
export async function runVimCommand(args, ctx) {
|
|
38
|
+
// Validate args before reading state so a bad call never has a
|
|
39
|
+
// side-effect.
|
|
40
|
+
if (args.length > 1) {
|
|
41
|
+
const payload = {
|
|
42
|
+
command: 'vim',
|
|
43
|
+
status: 'invalid_args',
|
|
44
|
+
active: resolveVimMode({ env: ctx.env }),
|
|
45
|
+
message: `pugi vim takes at most one argument (on / off / toggle). Got: ${args.join(' ')}`,
|
|
46
|
+
attemptedArg: args.join(' '),
|
|
47
|
+
};
|
|
48
|
+
ctx.writeOutput(payload, payload.message);
|
|
49
|
+
return 2;
|
|
50
|
+
}
|
|
51
|
+
const current = resolveVimMode({ env: ctx.env });
|
|
52
|
+
const verb = args[0]?.toLowerCase() ?? '';
|
|
53
|
+
// No args → toggle (slash convention from the leak research). The
|
|
54
|
+
// CLI shell surface ALSO toggles on bare invocation so the two
|
|
55
|
+
// surfaces converge; if the operator wants the read-only show they
|
|
56
|
+
// can pipe through `pugi vim --json` or query the config directly.
|
|
57
|
+
// We surface the change as a `show` status when nothing flipped so
|
|
58
|
+
// scripts can distinguish read from write.
|
|
59
|
+
if (verb === '') {
|
|
60
|
+
const next = !current;
|
|
61
|
+
setVimMode(next, { env: ctx.env });
|
|
62
|
+
const status = next ? 'enabled' : 'disabled';
|
|
63
|
+
const message = next ? VIM_ENABLED_BANNER : 'Vim mode off.';
|
|
64
|
+
const payload = {
|
|
65
|
+
command: 'vim',
|
|
66
|
+
status,
|
|
67
|
+
active: next,
|
|
68
|
+
previous: current,
|
|
69
|
+
message,
|
|
70
|
+
};
|
|
71
|
+
ctx.writeOutput(payload, payload.message);
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
if (verb === 'on' || verb === 'enable' || verb === 'true') {
|
|
75
|
+
if (current) {
|
|
76
|
+
const payload = {
|
|
77
|
+
command: 'vim',
|
|
78
|
+
status: 'unchanged',
|
|
79
|
+
active: true,
|
|
80
|
+
previous: true,
|
|
81
|
+
message: 'Vim mode already on.',
|
|
82
|
+
};
|
|
83
|
+
ctx.writeOutput(payload, payload.message);
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
setVimMode(true, { env: ctx.env });
|
|
87
|
+
const payload = {
|
|
88
|
+
command: 'vim',
|
|
89
|
+
status: 'enabled',
|
|
90
|
+
active: true,
|
|
91
|
+
previous: current,
|
|
92
|
+
message: VIM_ENABLED_BANNER,
|
|
93
|
+
};
|
|
94
|
+
ctx.writeOutput(payload, payload.message);
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
if (verb === 'off' || verb === 'disable' || verb === 'false') {
|
|
98
|
+
if (!current) {
|
|
99
|
+
const payload = {
|
|
100
|
+
command: 'vim',
|
|
101
|
+
status: 'unchanged',
|
|
102
|
+
active: false,
|
|
103
|
+
previous: false,
|
|
104
|
+
message: 'Vim mode already off.',
|
|
105
|
+
};
|
|
106
|
+
ctx.writeOutput(payload, payload.message);
|
|
107
|
+
return 0;
|
|
108
|
+
}
|
|
109
|
+
setVimMode(false, { env: ctx.env });
|
|
110
|
+
const payload = {
|
|
111
|
+
command: 'vim',
|
|
112
|
+
status: 'disabled',
|
|
113
|
+
active: false,
|
|
114
|
+
previous: current,
|
|
115
|
+
message: 'Vim mode off.',
|
|
116
|
+
};
|
|
117
|
+
ctx.writeOutput(payload, payload.message);
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
if (verb === 'status' || verb === 'show') {
|
|
121
|
+
const payload = {
|
|
122
|
+
command: 'vim',
|
|
123
|
+
status: 'show',
|
|
124
|
+
active: current,
|
|
125
|
+
message: current ? 'Vim mode is on.' : 'Vim mode is off.',
|
|
126
|
+
};
|
|
127
|
+
ctx.writeOutput(payload, payload.message);
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
const payload = {
|
|
131
|
+
command: 'vim',
|
|
132
|
+
status: 'invalid_args',
|
|
133
|
+
active: current,
|
|
134
|
+
message: `Unknown vim subcommand "${verb}". Try one of: on, off, status.`,
|
|
135
|
+
attemptedArg: verb,
|
|
136
|
+
};
|
|
137
|
+
ctx.writeOutput(payload, payload.message);
|
|
138
|
+
return 2;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=vim.js.map
|
|
@@ -16,9 +16,21 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Brand voice: ASCII only, no emoji, no banned words.
|
|
18
18
|
*/
|
|
19
|
-
import { resolve } from 'node:path';
|
|
20
19
|
import { spawnSync } from 'node:child_process';
|
|
20
|
+
import { resolve, sep } from 'node:path';
|
|
21
21
|
import { createWorktree, dropWorktree, promoteWorktree } from '../../core/edits/worktree.js';
|
|
22
|
+
/**
|
|
23
|
+
* R1 fix (2026-05-26, PR #413 r1, P2 #10): operator-facing path
|
|
24
|
+
* validation. The core `promoteWorktree` / `dropWorktree` primitives
|
|
25
|
+
* already gate their inputs, but mirroring the check at the CLI surface
|
|
26
|
+
* gives the operator a clean error message before we even attempt the
|
|
27
|
+
* git invocation (which would otherwise leak `git rev-parse HEAD` stderr).
|
|
28
|
+
*/
|
|
29
|
+
function isUnderScratchRoot(cwd, candidate) {
|
|
30
|
+
const scratchRoot = resolve(cwd, '.pugi', 'worktrees');
|
|
31
|
+
const abs = resolve(cwd, candidate);
|
|
32
|
+
return abs.startsWith(scratchRoot + sep) && abs !== scratchRoot;
|
|
33
|
+
}
|
|
22
34
|
export async function runWorktreeCommand(args, opts) {
|
|
23
35
|
const [op, ...rest] = args;
|
|
24
36
|
if (!op)
|
|
@@ -56,6 +68,19 @@ export async function runWorktreeCommand(args, opts) {
|
|
|
56
68
|
exitCode: 2,
|
|
57
69
|
};
|
|
58
70
|
}
|
|
71
|
+
if (!isUnderScratchRoot(opts.cwd, worktreePath)) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
text: opts.json
|
|
75
|
+
? JSON.stringify({
|
|
76
|
+
ok: false,
|
|
77
|
+
reason: 'invalid_worktree_path',
|
|
78
|
+
detail: `worktree path must live under <cwd>/.pugi/worktrees/`,
|
|
79
|
+
}, null, 2)
|
|
80
|
+
: `promote failed: invalid_worktree_path: ${worktreePath} is not under .pugi/worktrees/`,
|
|
81
|
+
exitCode: 3,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
59
84
|
// Resolve the worktree path's base SHA from its own git HEAD so
|
|
60
85
|
// the operator never has to remember it after `worktree create`.
|
|
61
86
|
const abs = resolve(opts.cwd, worktreePath);
|
|
@@ -68,21 +93,27 @@ export async function runWorktreeCommand(args, opts) {
|
|
|
68
93
|
};
|
|
69
94
|
}
|
|
70
95
|
const baseSha = head.stdout.trim();
|
|
71
|
-
const result = promoteWorktree({
|
|
96
|
+
const result = promoteWorktree({
|
|
97
|
+
cwd: opts.cwd,
|
|
98
|
+
worktreePath: abs,
|
|
99
|
+
baseSha,
|
|
100
|
+
...(opts.dryRun ? { dryRun: true } : {}),
|
|
101
|
+
});
|
|
72
102
|
if (!result.ok) {
|
|
73
103
|
return {
|
|
74
104
|
ok: false,
|
|
75
105
|
text: opts.json
|
|
76
106
|
? JSON.stringify(result, null, 2)
|
|
77
107
|
: `promote failed: ${result.reason}: ${result.detail}`,
|
|
78
|
-
exitCode: 1,
|
|
108
|
+
exitCode: result.reason === 'protected_file_in_worktree' ? 3 : 1,
|
|
79
109
|
};
|
|
80
110
|
}
|
|
111
|
+
const prefix = opts.dryRun ? 'dry-run: would promote' : 'promoted';
|
|
81
112
|
return {
|
|
82
113
|
ok: true,
|
|
83
114
|
text: opts.json
|
|
84
|
-
? JSON.stringify({ filesChanged: result.value.filesChanged }, null, 2)
|
|
85
|
-
:
|
|
115
|
+
? JSON.stringify({ filesChanged: result.value.filesChanged, dryRun: opts.dryRun ?? false }, null, 2)
|
|
116
|
+
: `${prefix} ${result.value.filesChanged} files from ${abs}`,
|
|
86
117
|
exitCode: 0,
|
|
87
118
|
};
|
|
88
119
|
}
|
|
@@ -95,6 +126,19 @@ export async function runWorktreeCommand(args, opts) {
|
|
|
95
126
|
exitCode: 2,
|
|
96
127
|
};
|
|
97
128
|
}
|
|
129
|
+
if (!isUnderScratchRoot(opts.cwd, worktreePath)) {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
text: opts.json
|
|
133
|
+
? JSON.stringify({
|
|
134
|
+
ok: false,
|
|
135
|
+
reason: 'invalid_worktree_path',
|
|
136
|
+
detail: `worktree path must live under <cwd>/.pugi/worktrees/`,
|
|
137
|
+
}, null, 2)
|
|
138
|
+
: `drop failed: invalid_worktree_path: ${worktreePath} is not under .pugi/worktrees/`,
|
|
139
|
+
exitCode: 3,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
98
142
|
const abs = resolve(opts.cwd, worktreePath);
|
|
99
143
|
const result = dropWorktree(abs, opts.cwd);
|
|
100
144
|
if (!result.ok) {
|
|
@@ -103,7 +147,7 @@ export async function runWorktreeCommand(args, opts) {
|
|
|
103
147
|
text: opts.json
|
|
104
148
|
? JSON.stringify(result, null, 2)
|
|
105
149
|
: `drop failed: ${result.reason}: ${result.detail}`,
|
|
106
|
-
exitCode: 1,
|
|
150
|
+
exitCode: result.reason === 'invalid_worktree_path' ? 3 : 1,
|
|
107
151
|
};
|
|
108
152
|
}
|
|
109
153
|
return {
|