zapdev 0.7.1 → 0.9.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.
Files changed (3) hide show
  1. package/README.md +13 -0
  2. package/dist/cli.js +69 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -43,6 +43,8 @@ zapdev commit
43
43
  zapdev commit -t feat # force the type; the model still writes scope + description
44
44
  ```
45
45
 
46
+ Pushing is optimistic — no preliminary fetch, so the common case stays a single round-trip. If the push is rejected because the branch is behind its upstream, zapdev automatically runs `git pull --rebase` and retries the push once — no prompt, in every mode. A rebase conflict stops before pushing so you can resolve it, then re-run.
47
+
46
48
  Without a TTY (piped / CI), it commits automatically and only pushes when `--push` is set.
47
49
 
48
50
  ### `zapdev reset`
@@ -65,6 +67,17 @@ zapdev reset -t dev # switch each repo to `dev` (or principal if absent
65
67
 
66
68
  Deletion is permanent: branches via `git branch -D` (force), worktrees via `git worktree remove --force`. Worktrees are removed first so the branches they held become deletable. Without a TTY, pass `--yes` — otherwise the destructive step is refused. `node_modules` is never scanned.
67
69
 
70
+ ## Shell aliases
71
+
72
+ `--yes` skips every prompt, which is exactly what you want behind a short alias. Two that pay off daily — add them to `~/.zshrc` or `~/.bashrc`:
73
+
74
+ ```bash
75
+ alias commit="zapdev commit --yes" # stage → generate message → commit, no prompts
76
+ alias git-reset="zapdev reset --yes --principal --pull" # switch each repo to its principal branch, wipe the rest, then pull
77
+ ```
78
+
79
+ `commit` collapses the whole stage → message → commit flow into one word. `git-reset` brings a workspace back to a clean principal state in one shot — point it at a parent directory to reset every child repo at once.
80
+
68
81
  ## Configuration
69
82
 
70
83
  | Variable | Default | Description |
package/dist/cli.js CHANGED
@@ -1718,7 +1718,7 @@ function _getBuiltinFlags(long, short, userNames, userAliases) {
1718
1718
  // package.json
1719
1719
  var package_default = {
1720
1720
  name: "zapdev",
1721
- version: "0.7.1",
1721
+ version: "0.9.0",
1722
1722
  description: "Fast, performant and lightweight git chores and dev tools using your terminal and your own local LLM.",
1723
1723
  type: "module",
1724
1724
  bin: {
@@ -2222,6 +2222,16 @@ async function push() {
2222
2222
  async function pushSetUpstream(branch) {
2223
2223
  await git(["push", "-u", "origin", branch]);
2224
2224
  }
2225
+ async function pullRebase() {
2226
+ await git(["pull", "--rebase"]);
2227
+ }
2228
+ async function fetchRemote() {
2229
+ await git(["fetch"]);
2230
+ }
2231
+ async function behindCount() {
2232
+ const out = await tryGit(["rev-list", "--count", `HEAD..${UPSTREAM_REF}`]);
2233
+ return out === null ? 0 : Number(out.trim()) || 0;
2234
+ }
2225
2235
  async function findRepos(path) {
2226
2236
  if (await isGitRepo(path)) return [path];
2227
2237
  const entries = await readdir(path, { withFileTypes: true }).catch(() => null);
@@ -2467,16 +2477,8 @@ var commitCommand = defineCommand({
2467
2477
  shouldPush = answer;
2468
2478
  }
2469
2479
  if (shouldPush) {
2470
- const pushLoader = interactive ? spinner() : void 0;
2471
- pushLoader?.start("Pushing");
2472
- try {
2473
- const [upstream, branch] = await Promise.all([hasUpstream(), currentBranch()]);
2474
- if (upstream) await push();
2475
- else await pushSetUpstream(branch);
2476
- pushLoader?.stop("\u2713 Pushed");
2477
- } catch (error) {
2478
- pushLoader?.error("Push failed");
2479
- log.error(`Push failed: ${errorMessage(error)}`);
2480
+ const pushed = await pushOptimistic(interactive);
2481
+ if (!pushed) {
2480
2482
  process.exitCode = 1;
2481
2483
  return;
2482
2484
  }
@@ -2484,6 +2486,62 @@ var commitCommand = defineCommand({
2484
2486
  if (interactive) outro("Done.");
2485
2487
  }
2486
2488
  });
2489
+ async function rebaseOnUpstream(interactive) {
2490
+ const loader = interactive ? spinner() : void 0;
2491
+ loader?.start("Pulling --rebase");
2492
+ try {
2493
+ await pullRebase();
2494
+ loader?.stop("\u2713 Rebased on upstream");
2495
+ return true;
2496
+ } catch (error) {
2497
+ loader?.error("Rebase failed");
2498
+ log.error(`Rebase failed (resolve conflicts, then push): ${errorMessage(error)}`);
2499
+ return false;
2500
+ }
2501
+ }
2502
+ async function pushOptimistic(interactive) {
2503
+ const [upstream, branch] = await Promise.all([hasUpstream(), currentBranch()]);
2504
+ const doPush = () => upstream ? push() : pushSetUpstream(branch);
2505
+ const first = await tryPush(interactive, doPush);
2506
+ if (first.ok) return true;
2507
+ if (upstream && await isBehind(interactive)) {
2508
+ if (!await rebaseOnUpstream(interactive)) return false;
2509
+ const retry = await tryPush(interactive, doPush);
2510
+ if (retry.ok) return true;
2511
+ log.error(`Push failed: ${errorMessage(retry.error)}`);
2512
+ return false;
2513
+ }
2514
+ log.error(`Push failed: ${errorMessage(first.error)}`);
2515
+ return false;
2516
+ }
2517
+ async function tryPush(interactive, doPush) {
2518
+ const loader = interactive ? spinner() : void 0;
2519
+ loader?.start("Pushing");
2520
+ try {
2521
+ await doPush();
2522
+ loader?.stop("\u2713 Pushed");
2523
+ return { ok: true };
2524
+ } catch (error) {
2525
+ loader?.error("Push failed");
2526
+ return { ok: false, error };
2527
+ }
2528
+ }
2529
+ async function isBehind(interactive) {
2530
+ const loader = interactive ? spinner() : void 0;
2531
+ loader?.start("Checking upstream");
2532
+ try {
2533
+ await fetchRemote();
2534
+ const behind = await behindCount();
2535
+ loader?.stop(
2536
+ behind > 0 ? `Behind upstream by ${behind} commit${behind > 1 ? "s" : ""}` : "Up to date with upstream"
2537
+ );
2538
+ return behind > 0;
2539
+ } catch (error) {
2540
+ loader?.error("Could not check upstream");
2541
+ log.warn(`Could not check upstream: ${errorMessage(error)}`);
2542
+ return false;
2543
+ }
2544
+ }
2487
2545
 
2488
2546
  // src/commands/reset.ts
2489
2547
  var CANCEL = /* @__PURE__ */ Symbol("cancel");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zapdev",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "description": "Fast, performant and lightweight git chores and dev tools using your terminal and your own local LLM.",
5
5
  "type": "module",
6
6
  "bin": {