zapdev 0.4.0 → 0.5.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 +7 -0
  2. package/dist/index.js +67 -19
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -39,9 +39,14 @@ zapdev commit
39
39
  | Flag | Description |
40
40
  | --- | --- |
41
41
  | `-m, --model <model>` | Override the Ollama model |
42
+ | `-t, --type <type>` | Force the Conventional Commits type (`feat`, `fix`, `chore`, …) |
42
43
  | `-p, --push` | Push after committing without asking |
43
44
  | `-y, --yes` | Skip prompts and commit directly |
44
45
 
46
+ ```bash
47
+ zapdev commit -t feat # force the type; the model still writes scope + description
48
+ ```
49
+
45
50
  Without a TTY (piped / CI), it commits automatically and only pushes when `--push` is set.
46
51
 
47
52
  ### `zapdev cleanup`
@@ -88,3 +93,5 @@ bun run build # bundle to dist/
88
93
  - `src/index.ts` — CLI entry (Citty); registers subcommands, defaults to `commit`.
89
94
  - `src/commands/` — one file per command.
90
95
  - `src/lib/` — pure logic (`config`, `commit-message`, `branches`, unit-tested) and side effects (`git`, `ollama`); shared helpers (`errors`).
96
+ - `src/prompts/` — LLM prompts as `.md` files, imported as text (`with { type: "text" }`) and inlined into the bundle at build time.
97
+ - `src/types/` — shared type declarations (one file per domain) and ambient module declarations.
package/dist/index.js CHANGED
@@ -2553,6 +2553,41 @@ async function cleanupRepo(repo, options, interactive) {
2553
2553
  return false;
2554
2554
  }
2555
2555
 
2556
+ // src/types/commit.ts
2557
+ var COMMIT_TYPES = [
2558
+ "feat",
2559
+ "fix",
2560
+ "chore",
2561
+ "docs",
2562
+ "style",
2563
+ "refactor",
2564
+ "perf",
2565
+ "test",
2566
+ "build",
2567
+ "ci",
2568
+ "revert"
2569
+ ];
2570
+
2571
+ // src/lib/commit-message.ts
2572
+ function normalizeCommitType(input) {
2573
+ const normalized = input.trim().toLowerCase();
2574
+ return COMMIT_TYPES.includes(normalized) ? normalized : null;
2575
+ }
2576
+ function applyCommitType(systemPrompt, type) {
2577
+ return `${systemPrompt}
2578
+
2579
+ The type MUST be exactly "${type}".`;
2580
+ }
2581
+ var MAX_DIFF_CHARS = 12000;
2582
+ function truncateDiff(diff, max = MAX_DIFF_CHARS) {
2583
+ return diff.length > max ? diff.slice(0, max) : diff;
2584
+ }
2585
+ function sanitizeCommitMessage(raw) {
2586
+ const firstLine = raw.split(`
2587
+ `, 1)[0] ?? "";
2588
+ return firstLine.replace(/[`"]/g, "").trim();
2589
+ }
2590
+
2556
2591
  // src/lib/config.ts
2557
2592
  var DEFAULT_OLLAMA_URL = "http://localhost:11434";
2558
2593
  var DEFAULT_MODEL = "deepseek-v4-flash:cloud";
@@ -3520,35 +3555,37 @@ class Ollama2 extends Ollama$1 {
3520
3555
  }
3521
3556
  var index = new Ollama2;
3522
3557
 
3523
- // src/lib/commit-message.ts
3524
- var COMMIT_SYSTEM_PROMPT = [
3525
- "Generate ONE commit message in Conventional Commits format.",
3526
- 'A single line: "type(scope): description", imperative, English, \u226472 chars.',
3527
- "Reply ONLY with the message, no backticks, no quotes, no explanation."
3528
- ].join(`
3529
- `);
3530
- var MAX_DIFF_CHARS = 12000;
3531
- function truncateDiff(diff, max = MAX_DIFF_CHARS) {
3532
- return diff.length > max ? diff.slice(0, max) : diff;
3533
- }
3534
- function sanitizeCommitMessage(raw) {
3535
- const firstLine = raw.split(`
3536
- `, 1)[0] ?? "";
3537
- return firstLine.replace(/[`"]/g, "").trim();
3538
- }
3558
+ // src/prompts/commit-message.md
3559
+ var commit_message_default = `You are zapdev, a CLI tool that creates commits quickly and reliably.
3560
+
3561
+ Generate ONE commit message in Conventional Commits format.
3562
+ A single line: imperative, English, \u226472 chars.
3563
+
3564
+ Strictly follow this format:
3565
+
3566
+ \`\`\`text
3567
+ type(scope): description
3568
+ \`\`\`
3569
+
3570
+ Reply ONLY with the message, no backticks, no quotes, no explanation.
3571
+ `;
3572
+
3573
+ // src/prompts/index.ts
3574
+ var COMMIT_SYSTEM_PROMPT = commit_message_default.trim();
3539
3575
 
3540
3576
  // src/lib/ollama.ts
3541
3577
  var REQUEST_TIMEOUT_MS = 25000;
3542
3578
  var fetchWithTimeout = Object.assign((input, init) => fetch(input, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) }), { preconnect: fetch.preconnect });
3543
- async function generateCommitMessage(diff, config) {
3579
+ async function generateCommitMessage(diff, config, type) {
3544
3580
  const client = new Ollama2({ host: config.ollamaUrl, fetch: fetchWithTimeout });
3581
+ const systemPrompt = type ? applyCommitType(COMMIT_SYSTEM_PROMPT, type) : COMMIT_SYSTEM_PROMPT;
3545
3582
  const response = await client.chat({
3546
3583
  model: config.model,
3547
3584
  stream: false,
3548
3585
  keep_alive: "30m",
3549
3586
  options: { temperature: 0.2 },
3550
3587
  messages: [
3551
- { role: "system", content: COMMIT_SYSTEM_PROMPT },
3588
+ { role: "system", content: systemPrompt },
3552
3589
  { role: "user", content: truncateDiff(diff) }
3553
3590
  ]
3554
3591
  });
@@ -3567,6 +3604,11 @@ var commitCommand = defineCommand({
3567
3604
  alias: "m",
3568
3605
  description: "Override the Ollama model (defaults to $OLLAMA_MODEL)."
3569
3606
  },
3607
+ type: {
3608
+ type: "string",
3609
+ alias: "t",
3610
+ description: `Force the Conventional Commits type (${COMMIT_TYPES.join(", ")}).`
3611
+ },
3570
3612
  push: {
3571
3613
  type: "boolean",
3572
3614
  alias: "p",
@@ -3581,6 +3623,12 @@ var commitCommand = defineCommand({
3581
3623
  async run({ args }) {
3582
3624
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
3583
3625
  const config = resolveConfig(process.env, args.model ? { model: args.model } : {});
3626
+ const type = args.type ? normalizeCommitType(args.type) : undefined;
3627
+ if (type === null) {
3628
+ log.error(`Invalid type "${args.type}". Valid types: ${COMMIT_TYPES.join(", ")}.`);
3629
+ process.exitCode = 1;
3630
+ return;
3631
+ }
3584
3632
  if (interactive)
3585
3633
  intro("zapdev commit");
3586
3634
  await stageAll();
@@ -3595,7 +3643,7 @@ var commitCommand = defineCommand({
3595
3643
  loader?.start("Generating commit message\u2026");
3596
3644
  let message;
3597
3645
  try {
3598
- message = await generateCommitMessage(diff, config);
3646
+ message = await generateCommitMessage(diff, config, type);
3599
3647
  } catch (error) {
3600
3648
  loader?.error("Generation failed");
3601
3649
  log.error(`Generation failed (machine unreachable?): ${errorMessage(error)}`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "zapdev",
3
- "version": "0.4.0",
4
- "description": "Fast, precise git chores from your terminal.",
3
+ "version": "0.5.0",
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": {
7
7
  "zapdev": "./dist/index.js"