zapdev 1.16.0 → 1.17.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 +2 -2
- package/dist/cli.js +30 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,9 +143,9 @@ 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`, only repositories with local changes are pulled,
|
|
146
|
+
With `--pull`, only repositories with local changes are pulled, in parallel. With `--staged`, only repositories with a staged diff are pulled. All pulls must finish successfully before preparation and message generation start in parallel. 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 flow before staging, after all in-flight pulls finish; no rebase, merge commit, or automatic stash is performed. Successful pulls remain applied.
|
|
147
147
|
|
|
148
|
-
In a terminal, commit, pull, and push output is streamed into Clack task logs;
|
|
148
|
+
In a terminal, commit, pull, and push output is streamed into Clack task logs; parallel pulls share one log grouped by repository. Silent commits and pushes 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
|
|
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.17.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: {
|
|
@@ -2583,10 +2583,10 @@ var COMMIT_TYPES = [
|
|
|
2583
2583
|
|
|
2584
2584
|
// src/commands/git-task.ts
|
|
2585
2585
|
import { styleText as styleText3 } from "node:util";
|
|
2586
|
-
async function runGitTask(label, operation, successMessage, run) {
|
|
2586
|
+
async function runGitTask(label, operation, successMessage, run, group) {
|
|
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;
|
|
2589
|
+
const loader = interactive && !group ? spinner({ withGuide: false }) : void 0;
|
|
2590
2590
|
const startLoading = () => {
|
|
2591
2591
|
if (!loader) return;
|
|
2592
2592
|
const wasRaw = Boolean(process.stdin.isRaw);
|
|
@@ -2594,7 +2594,7 @@ async function runGitTask(label, operation, successMessage, run) {
|
|
|
2594
2594
|
process.stdin.setRawMode?.(wasRaw);
|
|
2595
2595
|
process.stdin.pause();
|
|
2596
2596
|
};
|
|
2597
|
-
let task;
|
|
2597
|
+
let task = group;
|
|
2598
2598
|
const onOutput = (chunk, stream) => {
|
|
2599
2599
|
if (!interactive) {
|
|
2600
2600
|
process[stream].write(chunk);
|
|
@@ -2626,6 +2626,7 @@ async function runGitTask(label, operation, successMessage, run) {
|
|
|
2626
2626
|
} catch (error) {
|
|
2627
2627
|
loader?.clear();
|
|
2628
2628
|
const message = `${label}: ${operation} failed${error instanceof GitOutputError ? "" : `: ${errorMessage(error)}`}`;
|
|
2629
|
+
group?.message(message);
|
|
2629
2630
|
if (task) task.error(message);
|
|
2630
2631
|
else if (!(error instanceof GitOutputError && error.hookFailureReported)) log.error(message);
|
|
2631
2632
|
return false;
|
|
@@ -2700,26 +2701,35 @@ var commitCommand = defineCommand({
|
|
|
2700
2701
|
if (interactive) outro("Nothing to do.");
|
|
2701
2702
|
return;
|
|
2702
2703
|
}
|
|
2704
|
+
const loader = interactive ? spinner() : void 0;
|
|
2703
2705
|
if (args.pull) {
|
|
2704
|
-
|
|
2706
|
+
loader?.start("Pulling repositories in parallel");
|
|
2707
|
+
let pullLog;
|
|
2708
|
+
const pulls = await Promise.allSettled(repos.map(async (repo) => {
|
|
2705
2709
|
const label = basename(repo);
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
log.warn(`${label}: no configured upstream remote. Skipping pull.`);
|
|
2712
|
-
continue;
|
|
2713
|
-
}
|
|
2714
|
-
} catch (error) {
|
|
2715
|
-
reportGitFailure(`${label}: pull failed`, error);
|
|
2716
|
-
process.exitCode = 1;
|
|
2717
|
-
return;
|
|
2710
|
+
const hasChanges = args.staged ? Boolean((await getStagedDiff(repo)).trim()) : (await getRepoStatus(repo)).hasChanges;
|
|
2711
|
+
if (!hasChanges) return true;
|
|
2712
|
+
const branch = await currentBranch(repo);
|
|
2713
|
+
if (!await getUpstreamRemote(repo, branch)) {
|
|
2714
|
+
return `${label}: no configured upstream remote. Skipping pull.`;
|
|
2718
2715
|
}
|
|
2719
|
-
if (
|
|
2720
|
-
|
|
2721
|
-
|
|
2716
|
+
if (interactive) {
|
|
2717
|
+
loader?.clear();
|
|
2718
|
+
pullLog ??= taskLog({ title: "Pulling repositories in parallel", limit: 10, retainLog: true });
|
|
2722
2719
|
}
|
|
2720
|
+
return runGitTask(label, "pull", `${label}: pulled`, (onHook, onOutput) => git(["pull", "--ff-only", "--no-rebase", "--no-autostash"], repo, onHook, onOutput), pullLog?.group(label));
|
|
2721
|
+
}));
|
|
2722
|
+
loader?.clear();
|
|
2723
|
+
const failed = pulls.some((result) => result.status === "rejected" || result.value === false);
|
|
2724
|
+
if (failed) pullLog?.error("Pulling failed");
|
|
2725
|
+
else pullLog?.success("Repositories pulled", { showLog: true });
|
|
2726
|
+
for (const [index, result] of pulls.entries()) {
|
|
2727
|
+
if (result.status === "rejected") reportGitFailure(`${basename(repos[index])}: pull failed`, result.reason);
|
|
2728
|
+
else if (typeof result.value === "string") log.warn(result.value);
|
|
2729
|
+
}
|
|
2730
|
+
if (failed) {
|
|
2731
|
+
process.exitCode = 1;
|
|
2732
|
+
return;
|
|
2723
2733
|
}
|
|
2724
2734
|
}
|
|
2725
2735
|
let scan;
|
|
@@ -2731,7 +2741,6 @@ var commitCommand = defineCommand({
|
|
|
2731
2741
|
return;
|
|
2732
2742
|
}
|
|
2733
2743
|
if (!scan) log.info("Gitleaks not found, skipping secret scan.");
|
|
2734
|
-
const loader = interactive ? spinner() : void 0;
|
|
2735
2744
|
loader?.start("Preparing repositories and generating commit messages in parallel");
|
|
2736
2745
|
const repositories = repos.map((repo) => ({ repo, label: basename(repo), pendingLabel: basename(repo) }));
|
|
2737
2746
|
const results = await Promise.allSettled(repositories.map(async (repository) => {
|