zapdev 1.14.0 → 1.16.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/README.md +4 -4
- package/dist/cli.js +26 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -114,7 +114,7 @@ Stages all changes, scans them with Gitleaks when installed, generates Conventio
|
|
|
114
114
|
- **Unified review:** generates messages in parallel, then presents every message with its repository name and branch. Repositories with pending changes are shown in bold when terminal styling is enabled.
|
|
115
115
|
- **Actions:** commit all, commit only a named repository, edit a named repository's message, or cancel. Editing returns to the review menu.
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
Only repositories successfully committed during the current run are offered for push or pushed with `--push`. Unselected or cancelled changes remain staged; failed or unselected commit drafts are not pushed. The branch is chosen before committing, never when pushing. Push confirmation is asked once, only for repositories with a configured upstream remote; it is omitted when none have one.
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
120
|
zapdev commit
|
|
@@ -127,7 +127,7 @@ zapdev commit
|
|
|
127
127
|
| `--effort <effort>` | Override the reasoning effort |
|
|
128
128
|
| `-t, --type <type>` | Force an exact lowercase Conventional Commit type (`feat`, `fix`, `chore`, etc.) |
|
|
129
129
|
| `-p, --push` | Skip push confirmation and push the current branch |
|
|
130
|
-
| `--pull` | Pull fast-forward updates in repositories with
|
|
130
|
+
| `--pull` | Pull fast-forward updates only in repositories with changes to commit and an upstream remote |
|
|
131
131
|
| `-s, --staged` | Commit only changes that are already staged |
|
|
132
132
|
| `-y, --yes` | Skip commit review; still confirm push unless `--push` is set |
|
|
133
133
|
|
|
@@ -143,13 +143,13 @@ Before contacting the LLM endpoint, zapdev runs `gitleaks git --staged --verbose
|
|
|
143
143
|
|
|
144
144
|
Preparation and commit failures are reported per repository while the others continue. A push failure stops all remaining sends. Any failure produces a nonzero exit code.
|
|
145
145
|
|
|
146
|
-
With `--pull`, repositories are pulled one at a time before any staging, secret scan, or message generation. Git uses each current branch's configured upstream. Repositories without a configured upstream remote are skipped with a warning, even if they have a single remote. Divergent history, a missing upstream branch, or conflicting local changes stop the entire flow before staging; no rebase, merge commit, or automatic stash is performed. Earlier successful pulls remain applied.
|
|
146
|
+
With `--pull`, only repositories with local changes are pulled, one at a time before any staging, secret scan, or message generation. With `--staged`, only repositories with a staged diff are pulled. Git uses each current branch's configured upstream. Repositories without a configured upstream remote are skipped with a warning, even if they have a single remote. Divergent history, a missing upstream branch, or conflicting local changes stop the entire flow before staging; no rebase, merge commit, or automatic stash is performed. Earlier successful pulls remain applied.
|
|
147
147
|
|
|
148
148
|
In a terminal, commit, pull, and push output is streamed into Clack task logs; silent commands create no output block. Git keeps terminal input, but stdout/stderr are pipes: hooks requiring a TTY on those streams are not supported. Git controls hook stdin; hooks can read from `/dev/tty`, although prompts written there appear outside the blocks. `--yes` skips commit review, not native prompts. Without a terminal, stdout/stderr are streamed directly. Each hook has a 60-second deadline, including time spent answering prompts; override it with `ZD_HOOK_TIMEOUT=120 zapdev commit`.
|
|
149
149
|
|
|
150
150
|
Immediately before each selected commit, zapdev asks for a local branch only when the current name exactly matches `main`, `master`, `principal`, `dev`, or `development`, including with `--yes`. The first prompt starts empty; subsequent prompts reuse the previous input across repositories. Press Enter to accept the prefilled name; an empty or cleared input keeps the current branch and leaves the next prompt empty. A different name switches to the existing local branch or creates it from HEAD, without forcing or discarding pending changes. Other branches and repositories with nothing to commit never trigger this prompt. Cancelling stops the remaining commits and all pushes; earlier commits remain local.
|
|
151
151
|
|
|
152
|
-
Pushes always target a remote branch with the current local branch's name, with no destination input. They use only the current branch's configured upstream remote and run `git push <remote> HEAD:refs/heads/<current-branch>`. Repositories without a configured upstream remote are skipped with a warning, even if they have a single remote. Pushes run directly, without a preliminary fetch or history comparison; Git handles up-to-date branches and rejects non-fast-forward updates.
|
|
152
|
+
Pushes always target a remote branch with the current local branch's name, with no destination input. They use only the current branch's configured upstream remote and run `git push <remote> HEAD:refs/heads/<current-branch>`. Repositories without a configured upstream remote are skipped with a warning, even if they have a single remote. Pushes run directly, without a preliminary fetch or history comparison; Git handles up-to-date branches and rejects non-fast-forward updates. No rebase, merge, retry, or force-push.
|
|
153
153
|
|
|
154
154
|
Without a TTY, zapdev commits prepared repositories on nonprotected branches automatically; protected-branch commits are refused and changes remain staged. `--push` can publish without a TTY; without it, commits stay local. Repositories without new changes do not trigger an LLM call, branch prompt, or new commit.
|
|
155
155
|
|
package/dist/cli.js
CHANGED
|
@@ -1854,7 +1854,7 @@ function _getBuiltinFlags(long, short, userNames, userAliases) {
|
|
|
1854
1854
|
// package.json
|
|
1855
1855
|
var package_default = {
|
|
1856
1856
|
name: "zapdev",
|
|
1857
|
-
version: "1.
|
|
1857
|
+
version: "1.16.0",
|
|
1858
1858
|
description: "Fast, performant and lightweight git chores and dev tools using your terminal and an OpenAI-compatible LLM endpoint.",
|
|
1859
1859
|
type: "module",
|
|
1860
1860
|
bin: {
|
|
@@ -2586,30 +2586,45 @@ import { styleText as styleText3 } from "node:util";
|
|
|
2586
2586
|
async function runGitTask(label, operation, successMessage, run) {
|
|
2587
2587
|
const title = `${label}: ${operation}`;
|
|
2588
2588
|
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
2589
|
+
const loader = interactive ? spinner({ withGuide: false }) : void 0;
|
|
2590
|
+
const startLoading = () => {
|
|
2591
|
+
if (!loader) return;
|
|
2592
|
+
const wasRaw = Boolean(process.stdin.isRaw);
|
|
2593
|
+
loader.start(title);
|
|
2594
|
+
process.stdin.setRawMode?.(wasRaw);
|
|
2595
|
+
process.stdin.pause();
|
|
2596
|
+
};
|
|
2589
2597
|
let task;
|
|
2590
2598
|
const onOutput = (chunk, stream) => {
|
|
2591
2599
|
if (!interactive) {
|
|
2592
2600
|
process[stream].write(chunk);
|
|
2593
2601
|
return;
|
|
2594
2602
|
}
|
|
2595
|
-
task
|
|
2603
|
+
if (!task) loader?.clear();
|
|
2604
|
+
task ??= taskLog({ title: `${title}: running\u2026`, limit: 10, retainLog: true });
|
|
2596
2605
|
task.message(chunk, { raw: true });
|
|
2597
2606
|
};
|
|
2598
2607
|
const onHook = (event) => {
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2608
|
+
loader?.clear();
|
|
2609
|
+
if (event.phase === "start" || event.exitCode !== 0) {
|
|
2610
|
+
const hook = `${label}: ${event.name}`;
|
|
2611
|
+
const message = event.phase === "start" ? `${hook}: running\u2026` : `${hook}: failed (exit ${event.exitCode})`;
|
|
2612
|
+
if (task) task.message(message);
|
|
2613
|
+
else if (event.phase === "start") log.step(styleText3("bold", message));
|
|
2614
|
+
else log.error(message);
|
|
2615
|
+
}
|
|
2616
|
+
if (event.phase === "exit" && !task) startLoading();
|
|
2605
2617
|
};
|
|
2606
|
-
log.info(title);
|
|
2618
|
+
if (!interactive) log.info(title);
|
|
2619
|
+
startLoading();
|
|
2607
2620
|
try {
|
|
2608
2621
|
await run(onHook, onOutput);
|
|
2622
|
+
loader?.clear();
|
|
2609
2623
|
if (task) task.success(successMessage, { showLog: true });
|
|
2610
2624
|
else log.success(successMessage);
|
|
2611
2625
|
return true;
|
|
2612
2626
|
} catch (error) {
|
|
2627
|
+
loader?.clear();
|
|
2613
2628
|
const message = `${label}: ${operation} failed${error instanceof GitOutputError ? "" : `: ${errorMessage(error)}`}`;
|
|
2614
2629
|
if (task) task.error(message);
|
|
2615
2630
|
else if (!(error instanceof GitOutputError && error.hookFailureReported)) log.error(message);
|
|
@@ -2689,6 +2704,8 @@ var commitCommand = defineCommand({
|
|
|
2689
2704
|
for (const repo of repos) {
|
|
2690
2705
|
const label = basename(repo);
|
|
2691
2706
|
try {
|
|
2707
|
+
const hasChanges = args.staged ? Boolean((await getStagedDiff(repo)).trim()) : (await getRepoStatus(repo)).hasChanges;
|
|
2708
|
+
if (!hasChanges) continue;
|
|
2692
2709
|
const branch = await currentBranch(repo);
|
|
2693
2710
|
if (!await getUpstreamRemote(repo, branch)) {
|
|
2694
2711
|
log.warn(`${label}: no configured upstream remote. Skipping pull.`);
|
|
@@ -2733,7 +2750,6 @@ var commitCommand = defineCommand({
|
|
|
2733
2750
|
}));
|
|
2734
2751
|
loader?.stop("Repositories prepared");
|
|
2735
2752
|
const drafts = [];
|
|
2736
|
-
const unchanged = [];
|
|
2737
2753
|
for (const [index, result] of results.entries()) {
|
|
2738
2754
|
if (result.status === "rejected") {
|
|
2739
2755
|
log.error(`${repositories[index].pendingLabel}: ${errorMessage(result.reason)}`);
|
|
@@ -2742,7 +2758,6 @@ var commitCommand = defineCommand({
|
|
|
2742
2758
|
drafts.push(result.value);
|
|
2743
2759
|
} else {
|
|
2744
2760
|
log.info(`${repositories[index].pendingLabel}: nothing to commit.`);
|
|
2745
|
-
unchanged.push(repositories[index]);
|
|
2746
2761
|
}
|
|
2747
2762
|
}
|
|
2748
2763
|
const selected = drafts.length ? await reviewMessages(drafts, interactive && !args.yes) : [];
|
|
@@ -2783,7 +2798,6 @@ var commitCommand = defineCommand({
|
|
|
2783
2798
|
process.exitCode = 1;
|
|
2784
2799
|
}
|
|
2785
2800
|
}
|
|
2786
|
-
toSend.push(...unchanged);
|
|
2787
2801
|
if (toSend.length === 0) return;
|
|
2788
2802
|
if (!interactive && !args.push) return;
|
|
2789
2803
|
const destinations = [];
|