gityo 1.0.11 → 1.0.12

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 +44 -5
  2. package/dist/index.js +65 -29
  3. package/package.json +7 -6
package/README.md CHANGED
@@ -46,13 +46,14 @@ If you already staged files before running `gityo`, only those are used for the
46
46
  gityo
47
47
  gityo --generate
48
48
  gityo --model fast --generate
49
- gityo --message "fix login redirect bug"
49
+ gityo --style concise --generate
50
+ gityo --input "fix login redirect bug"
50
51
  gityo --yolo
51
52
  ```
52
53
 
53
54
  ## AI setup
54
55
 
55
- A configured model is required — gityo won't run without one, and the API key must be resolvable from your environment even when you pass `--message`. Models live in a `models` map in your config file. Each key is a name you can pick with `--model`; the `default` key is used when you don't pass `--model`:
56
+ A configured model is required — gityo won't run without one, and the API key must be resolvable from your environment even when you pass `--input`. Models live in a `models` map in your config file. Each key is a name you can pick with `--model`; the `default` key is used when you don't pass `--model`:
56
57
 
57
58
  ```json
58
59
  {
@@ -68,7 +69,8 @@ A configured model is required — gityo won't run without one, and the API key
68
69
  "apiKeyEnv": "OPENAI_API_KEY",
69
70
  "model": "gpt-5-mini"
70
71
  }
71
- }
72
+ },
73
+ "style": "concise"
72
74
  }
73
75
  ```
74
76
 
@@ -101,6 +103,7 @@ Then use:
101
103
  ```bash
102
104
  gityo --generate
103
105
  gityo --model fast --generate
106
+ gityo --style concise --generate
104
107
  ```
105
108
 
106
109
  Providers are the official Vercel AI SDK packages: `@ai-sdk/openai`, `@ai-sdk/openai-compatible`, `@ai-sdk/anthropic`, `@ai-sdk/google`, `@ai-sdk/xai`, `@ai-sdk/azure`, `@ai-sdk/amazon-bedrock`, `@ai-sdk/groq`, `@ai-sdk/mistral`, `@ai-sdk/deepseek`, `@ai-sdk/togetherai`, `@ai-sdk/fireworks`, `@ai-sdk/perplexity`, `@ai-sdk/cohere`, `@ai-sdk/cerebras`, `@ai-sdk/luma`, `@ai-sdk/fal`, `@ai-sdk/deepinfra`, `@ai-sdk/google-vertex`, `@openrouter/ai-sdk-provider`, plus `ai-sdk-ollama`, `ollama-ai-provider-v2`, `workers-ai-provider`, `zhipu-ai-provider`, `sambanova-ai-provider`, `vercel-minimax-ai-provider`, `@aihubmix/ai-sdk-provider`, `ai-gateway-provider`, `@friendliai/ai-provider`, `@helicone/ai-sdk-provider`, and `ai-sdk-provider-opencode-sdk`.
@@ -116,7 +119,7 @@ gityo config
116
119
  Config is edited by hand in a JSON file. Project config goes in:
117
120
 
118
121
  ```text
119
- .gityo.config.json
122
+ .gityo.json
120
123
  ```
121
124
 
122
125
  Global config goes in:
@@ -151,6 +154,13 @@ Example:
151
154
  "model": "gpt-5-nano"
152
155
  }
153
156
  },
157
+ "style": "concise",
158
+ "styles": {
159
+ "team": "Use conventional commits. Keep the subject under 72 characters.",
160
+ "release": {
161
+ "path": ".gityo/release-style.md"
162
+ }
163
+ },
154
164
  "autoAcceptMessage": false,
155
165
  "postCommand": "push",
156
166
  "autoRunPostCommand": false,
@@ -160,6 +170,35 @@ Example:
160
170
  }
161
171
  ```
162
172
 
173
+ ### Commit message styles
174
+
175
+ Styles control the base commit-message convention sent to the model. Built-in
176
+ styles are `default`, `concise`, `explanatory`, `plain`, and `gitmoji`.
177
+
178
+ - `default` uses conventional commits and adds a body only for substantial,
179
+ multi-part changes that benefit from more context.
180
+ - `concise` uses conventional commits and adds a body only when it is essential.
181
+ - `explanatory` uses conventional commits and encourages a useful explanatory
182
+ body.
183
+ - `plain` produces a short, non-conventional imperative subject line.
184
+ - `gitmoji` prefixes a conventional subject with a relevant gitmoji.
185
+
186
+ Choose a default with `style`, or select one for a command with `--style`:
187
+
188
+ ```bash
189
+ gityo --style team --generate
190
+ ```
191
+
192
+ Custom `styles` extend the built-ins. A custom style with the same name replaces
193
+ the built-in style. A style can be inline text or an object with a `path` to a
194
+ prompt file. File paths are passed to Node's `path.resolve()`, so relative paths
195
+ resolve from the directory where you run `gityo`.
196
+
197
+ Style selection priority is `--style`, then config `style`, then `default`.
198
+
199
+ `instructions` uses the same format. Set it to a string or `{ "path": "..." }`
200
+ to load additional instructions from a file.
201
+
163
202
  ### Large changes
164
203
 
165
204
  When the diff is small, it is sent to the model as-is. When it is too large for one request, gityo minimizes it first:
@@ -186,5 +225,5 @@ Keep the subject line under 72 characters.
186
225
  Priority is simple:
187
226
 
188
227
  - `.gityo.md` for repo-specific instructions
189
- - `.gityo.config.json` for project config
228
+ - `.gityo.json` for project config
190
229
  - `~/.config/gityo.json` for your defaults
package/dist/index.js CHANGED
@@ -1710,7 +1710,7 @@ function useColor() {
1710
1710
  if (process$1.env.FORCE_COLOR || process$1.env.CLICOLOR_FORCE !== void 0) return true;
1711
1711
  }
1712
1712
  new Command();
1713
- var version$4 = "1.0.11";
1713
+ var version$4 = "1.0.12";
1714
1714
  Object.freeze({ status: "aborted" });
1715
1715
  function $constructor$3(name$16, initializer$6, params) {
1716
1716
  function init$1(inst, def) {
@@ -175933,29 +175933,34 @@ const modelSchema = object$4({
175933
175933
  apiUrl: url$3().optional(),
175934
175934
  options: record$3(string$6(), unknown$3()).optional()
175935
175935
  });
175936
+ const instructionSchema = union$4([string$6().min(1), object$4({ path: string$6().min(1) })]);
175936
175937
  const configSchema = object$4({
175937
175938
  $schema: url$3(),
175938
175939
  models: record$3(string$6().min(1), modelSchema),
175939
- autoAcceptMessage: boolean$5(),
175940
- instructions: string$6().min(1),
175940
+ instructions: instructionSchema,
175941
+ style: string$6().min(1),
175942
+ styles: record$3(string$6().min(1), instructionSchema),
175941
175943
  maxDiffTokens: number$5().int().min(1e3),
175942
175944
  perFileCap: number$5().int().min(50),
175943
- postCommand: _enum$4(["push", "push-and-pull"]).nullable(),
175944
- autoRunPostCommand: boolean$5()
175945
+ autoAcceptMessage: boolean$5(),
175946
+ autoRunPostCommand: boolean$5(),
175947
+ postCommand: _enum$4(["push", "push-and-pull"]).nullable()
175945
175948
  }).partial();
175946
175949
  function resolveConfig(input) {
175947
175950
  const parsed = configSchema.parse(input);
175948
175951
  return {
175949
175952
  models: parsed.models,
175953
+ style: parsed.style,
175954
+ styles: parsed.styles,
175950
175955
  instructions: parsed.instructions,
175951
- autoAcceptCommitMessage: parsed.autoAcceptMessage ?? false,
175952
175956
  maxDiffTokens: parsed.maxDiffTokens,
175953
175957
  perFileCap: parsed.perFileCap,
175954
- postCommand: parsed.postCommand === void 0 ? "push" : parsed.postCommand,
175955
- autoRunPostCommand: parsed.autoRunPostCommand ?? false
175958
+ autoAcceptCommitMessage: parsed.autoAcceptMessage ?? false,
175959
+ autoRunPostCommand: parsed.autoRunPostCommand ?? false,
175960
+ postCommand: parsed.postCommand === void 0 ? "push" : parsed.postCommand
175956
175961
  };
175957
175962
  }
175958
- const PROJECT_CONFIG_FILE_NAME = ".gityo.config.json";
175963
+ const PROJECT_CONFIG_FILE_NAME = ".gityo.json";
175959
175964
  const GLOBAL_CONFIG_FILE_PATH = path.join(os.homedir(), ".config", "gityo.json");
175960
175965
  async function loadConfig(cwd = process.cwd()) {
175961
175966
  const [globalConfig$3, projectConfig, projectInstructions] = await Promise.all([
@@ -181257,7 +181262,6 @@ function hardSplit(text$1, maxTokens) {
181257
181262
  if (current.length > 0) chunks.push(current);
181258
181263
  return chunks;
181259
181264
  }
181260
- var system_prompt_default = "You are a strict Git commit message generator. ONLY output the commit message, nothing else.\n\nREQUIRED FORMAT:\n- First line: <type>(<scope>): <subject> (max 50 characters)\n- Types: feat, fix, docs, style, refactor, perf, test, chore, ci\n- Subject: imperative mood, lowercase, no period\n- If body needed: blank line + detailed explanation (wrapped at 72 chars)\n\nSTRICT RULES:\n1. MUST use conventional commits format: type(scope): subject\n2. Subject line MUST be under 50 characters\n3. Subject MUST be in imperative mood (e.g., \"add\", \"fix\", \"update\")\n4. Subject MUST be lowercase\n5. Subject MUST NOT end with a period\n6. MUST provide clear context about WHAT changed and WHY\n7. MUST be specific about affected functions, components, or modules\n8. MUST NOT use vague terms like \"Update\", \"Fix stuff\", \"Changes\"\n9. If including a body, MUST have exactly one blank line between subject and body\n10. Body lines MUST wrap at 72 characters\n\nOUTPUT INSTRUCTION:\nReturn ONLY the commit message. No explanations, no extra text, no markdown formatting.\n\nEXAMPLE:\nfeat(llm): add support for streaming responses\n\nImplement streaming response handling for commit message\ngeneration to improve user experience with large diffs.\nAdds new stream event handlers and updates the API contract.\n\nAnalyze the diff and generate a message following ALL rules above.";
181261
181265
  const summarizePrompt = `You summarize parts of a large git diff for a commit message generator.
181262
181266
  Describe WHAT changed, in which files or modules, and any observable intent.
181263
181267
  Be factual and terse. Do NOT write a commit message. Maximum 120 words.`;
@@ -181268,8 +181272,8 @@ async function ask(languageModel, system, messages) {
181268
181272
  messages
181269
181273
  })).text.trim();
181270
181274
  }
181271
- async function generateCommitMessage(languageModel, instructions, diff) {
181272
- return ask(languageModel, system_prompt_default, [{
181275
+ async function generateCommitMessage(languageModel, style, instructions, diff) {
181276
+ return ask(languageModel, style, [{
181273
181277
  role: "user",
181274
181278
  content: `Changes:\n${diff}`
181275
181279
  }, {
@@ -181286,8 +181290,8 @@ async function summarizeChanges(languageModel, toc, chunk$1) {
181286
181290
  content: "Summarize these changes."
181287
181291
  }]);
181288
181292
  }
181289
- async function generateCommitMessageFromSummaries(languageModel, instructions, toc, summaries) {
181290
- return ask(languageModel, system_prompt_default, [{
181293
+ async function generateCommitMessageFromSummaries(llm, style, instructions, toc, summaries) {
181294
+ return ask(llm, style, [{
181291
181295
  role: "user",
181292
181296
  content: `All changed files:\n${toc}\n\nSummaries of all changes:\n${summaries.map((summary, index$2) => `Part ${index$2 + 1}:\n${summary}`).join("\n\n")}`
181293
181297
  }, {
@@ -181315,6 +181319,28 @@ function resolveLanguageModel(modelConfig) {
181315
181319
  ...modelConfig.options
181316
181320
  }).languageModel(modelConfig.model);
181317
181321
  }
181322
+ const BUILTIN_STYLES = {
181323
+ default: "You are a strict Git commit message generator. ONLY output the commit message, nothing else.\n\nREQUIRED FORMAT:\n\n- First line: <type>(<scope>): <subject> (max 50 characters)\n- Types: feat, fix, docs, style, refactor, perf, test, chore, ci\n- Subject: imperative mood, lowercase, no period\n- Optional body: blank line + concise explanation (wrapped at 72 chars)\n\nSTRICT RULES:\n\n- MUST use conventional commits format: type(scope): subject\n- Subject line MUST be under 50 characters\n- Subject MUST be in imperative mood (e.g., \"add\", \"fix\", \"update\")\n- Subject MUST be lowercase\n- Subject MUST NOT end with a period\n- MUST provide clear context about WHAT changed\n- MUST be specific about affected functions, components, or modules\n- MUST NOT use vague terms like \"Update\", \"Fix stuff\", \"Changes\"\n- Do NOT include a body for a small or focused change\n- Include a body only when the diff contains several substantial related changes and explaining them adds useful context\n- When a body is warranted, explain WHY when the rationale or impact is not obvious; do not force or invent a reason\n- If including a body, MUST have exactly one blank line between subject and body\n- Body lines MUST wrap at 72 characters\n\nOUTPUT INSTRUCTION:\nReturn ONLY the commit message. No explanations, no extra text, no markdown formatting.\n\nEXAMPLE:\nfeat(llm): add streaming responses\n\nAnalyze the diff and generate a message following ALL rules above.\n",
181324
+ concise: "You are a strict Git commit message generator. ONLY output the commit message, nothing else.\n\nREQUIRED FORMAT:\n- First line: <type>(<scope>): <subject> (max 50 characters)\n- Types: feat, fix, docs, style, refactor, perf, test, chore, ci\n- Subject: imperative mood, lowercase, no period\n- Exceptional body: blank line + minimal explanation (wrapped at 72 chars)\n\nSTRICT RULES:\n- MUST use conventional commits format: type(scope): subject\n- Subject line MUST be under 50 characters\n- Subject MUST be in imperative mood (e.g., \"add\", \"fix\", \"update\")\n- Subject MUST be lowercase\n- Subject MUST NOT end with a period\n- MUST provide clear context about the most important change\n- MUST be specific about affected functions, components, or modules\n- MUST NOT use vague terms like \"Update\", \"Fix stuff\", \"Changes\"\n- MUST prefer a subject line with no body\n- Include a body only when absolutely necessary to communicate critical context that cannot be expressed in the subject\n- If including a body, keep it as short as possible and explain WHY only when that rationale or impact is essential and supported by the diff\n- If including a body, MUST have exactly one blank line between subject and body\n- Body lines MUST wrap at 72 characters\n\nOUTPUT INSTRUCTION:\nReturn ONLY the commit message. No explanations, no extra text, no markdown formatting.\n\nEXAMPLE:\nfix(config): preserve provider settings\n\nAnalyze the diff and generate a message following ALL rules above.\n",
181325
+ explanatory: "You are a strict Git commit message generator. ONLY output the commit message, nothing else.\n\nREQUIRED FORMAT:\n- First line: <type>(<scope>): <subject> (max 72 characters)\n- Types: feat, fix, docs, style, refactor, perf, test, chore, ci\n- Subject: imperative mood, lowercase, no period\n- Encouraged body: blank line + concise explanation (wrapped at 72 chars)\n\nSTRICT RULES:\n- MUST use conventional commits format: type(scope): subject\n- Subject line MUST be under 72 characters\n- Subject MUST be in imperative mood (e.g., \"add\", \"fix\", \"update\")\n- Subject MUST be lowercase\n- Subject MUST NOT end with a period\n- MUST provide clear context about WHAT changed\n- MUST be specific about affected functions, components, or modules\n- MUST NOT use vague terms like \"Update\", \"Fix stuff\", \"Changes\"\n- Include a body whenever it adds meaningful context beyond the subject\n- Use the body to explain WHY the change was made or its impact when supported by the diff; do not force or invent a reason\n- Omit the body only when it would merely repeat the subject\n- If including a body, MUST have exactly one blank line between subject and body\n- Body lines MUST wrap at 72 characters\n\nOUTPUT INSTRUCTION:\nReturn ONLY the commit message. No explanations, no extra text, no markdown formatting.\n\nEXAMPLE:\nfix(config): preserve custom provider settings\n\nReload stored provider options before applying command-line overrides to\nprevent unrelated settings from being discarded.\n\nAnalyze the diff and generate a message following ALL rules above.\n",
181326
+ plain: "You are a strict Git commit message generator. ONLY output the commit message, nothing else.\n\nREQUIRED FORMAT:\n- Only line: <subject> (max 72 characters)\n- Subject: imperative mood, lowercase, no punctuation\n- No prefix, scope, emoji, or body\n\nSTRICT RULES:\n- MUST output exactly one plain subject line\n- Complete line MUST be under 72 characters\n- Subject MUST start with an imperative verb (e.g., \"add\", \"fix\", \"update\")\n- Subject MUST be lowercase\n- Subject MUST NOT end with punctuation\n- MUST provide clear context about the most important change\n- MUST be specific about affected functions, components, or modules\n- MUST NOT use vague terms like \"Update\", \"Fix stuff\", \"Changes\"\n- MUST NOT use conventional commit types, scopes, prefixes, or emoji\n- MUST NOT include a body\n\nOUTPUT INSTRUCTION:\nReturn ONLY the commit message. No explanations, no extra text, no markdown formatting.\n\nEXAMPLE:\npreserve custom provider settings\n\nAnalyze the diff and generate a message following ALL rules above.\n",
181327
+ gitmoji: "You are a strict Git commit message generator. ONLY output the commit message, nothing else.\n\nREQUIRED FORMAT:\n- Only line: <gitmoji> <type>(<scope>): <subject> (max 72 characters)\n- Types: feat, fix, docs, style, refactor, perf, test, chore, ci\n- Subject: imperative mood, lowercase, no period\n- No body\n\nSTRICT RULES:\n- MUST use gitmoji conventional commits format: <gitmoji> type(scope): subject\n- MUST choose exactly one gitmoji that best represents the change\n- Use relevant gitmoji such as ✨ for features, 🐛 for fixes, 📝 for documentation, ♻️ for refactoring, ✅ for tests, or 🔧 for configuration\n- Complete line MUST be under 72 characters\n- Subject MUST be in imperative mood (e.g., \"add\", \"fix\", \"update\")\n- Subject MUST be lowercase\n- Subject MUST NOT end with a period\n- MUST provide clear context about the most important change\n- MUST be specific about affected functions, components, or modules\n- MUST NOT use vague terms like \"Update\", \"Fix stuff\", \"Changes\"\n- MUST NOT include a body\n\nOUTPUT INSTRUCTION:\nReturn ONLY the commit message. No explanations, no extra text, no markdown formatting.\n\nEXAMPLE:\n✨ feat(cli): add interactive style selection\n\nAnalyze the diff and generate a message following ALL rules above.\n"
181328
+ };
181329
+ function getStyleKeys(styles$2) {
181330
+ return Object.keys({
181331
+ ...BUILTIN_STYLES,
181332
+ ...styles$2
181333
+ });
181334
+ }
181335
+ async function resolveStyle(styleKey, styles$2) {
181336
+ const style = styles$2?.[styleKey] ?? BUILTIN_STYLES[styleKey];
181337
+ if (!style) return;
181338
+ return resolveInstructionContent(style);
181339
+ }
181340
+ async function resolveInstructionContent(instruction) {
181341
+ if (typeof instruction === "string") return instruction;
181342
+ return readFile(path.resolve(instruction.path), "utf8");
181343
+ }
181318
181344
  const isUpKey = (key$1, keybindings = []) => key$1.name === "up" || keybindings.includes("vim") && key$1.name === "k" || keybindings.includes("emacs") && key$1.ctrl && key$1.name === "p";
181319
181345
  const isDownKey = (key$1, keybindings = []) => key$1.name === "down" || keybindings.includes("vim") && key$1.name === "j" || keybindings.includes("emacs") && key$1.ctrl && key$1.name === "n";
181320
181346
  const isSpaceKey = (key$1) => key$1.name === "space";
@@ -198117,7 +198143,11 @@ async function runWithLoading(label, task) {
198117
198143
  let index$2 = 0;
198118
198144
  const interval = setInterval(() => {
198119
198145
  readline.cursorTo(process.stdout, 0);
198120
- process.stdout.write(`${source_default.cyan(frames[index$2])} ${source_default.cyan(label)} ${source_default.reset.dim("...")}`);
198146
+ process.stdout.write([
198147
+ source_default.cyan(frames[index$2]) + " ",
198148
+ source_default.cyan(label),
198149
+ source_default.reset.dim("...")
198150
+ ].join(""));
198121
198151
  index$2 = (index$2 + 1) % frames.length;
198122
198152
  }, 80);
198123
198153
  try {
@@ -198143,10 +198173,17 @@ async function mainController(options = {}) {
198143
198173
  throw new Error(hint);
198144
198174
  }
198145
198175
  const languageModel = resolveLanguageModel(modelConfig);
198176
+ const styleKey = options.style ?? config$4.style ?? "default";
198177
+ const style = await resolveStyle(styleKey, config$4.styles);
198178
+ if (!style) {
198179
+ const availableStyles = getStyleKeys(config$4.styles).join(", ");
198180
+ throw new Error(`Style '${styleKey}' is not configured. Available styles: ${availableStyles}.`);
198181
+ }
198182
+ const instructions = config$4.instructions ? await resolveInstructionContent(config$4.instructions) : null;
198146
198183
  const forceLLMGenerate = options.generate || options.yolo;
198147
198184
  const forceExecPostCommand = options.post || options.yolo;
198148
- let finalCommitMessage = options.message?.trim() ?? "";
198149
- if (typeof options.message === "string" && finalCommitMessage.length === 0) throw new Error("Provided commit message cannot be empty.");
198185
+ let finalCommitMessage = options.input?.trim() ?? "";
198186
+ if (typeof options.input === "string" && finalCommitMessage.length === 0) throw new Error("Provided commit message input cannot be empty.");
198150
198187
  const files = await getChangedFiles(git);
198151
198188
  if (files.length === 0) return console.log("No changed files found.");
198152
198189
  const { diff, hasStaged } = await getCommitDiff(git);
@@ -198168,11 +198205,12 @@ async function mainController(options = {}) {
198168
198205
  finalCommitMessage = (await runWithLoading("Generating commit message", () => generateMessage({
198169
198206
  git,
198170
198207
  languageModel,
198171
- instructions: config$4.instructions ?? null,
198208
+ style,
198209
+ instructions,
198172
198210
  diff,
198173
198211
  files,
198174
- maxDiffTokens: config$4.maxDiffTokens ?? DEFAULT_MAX_DIFF_TOKENS,
198175
- perFileCap: config$4.perFileCap ?? DEFAULT_PER_FILE_CAP
198212
+ perFileCap: config$4.perFileCap ?? DEFAULT_PER_FILE_CAP,
198213
+ maxDiffTokens: config$4.maxDiffTokens ?? DEFAULT_MAX_DIFF_TOKENS
198176
198214
  }))).trim();
198177
198215
  if (finalCommitMessage.length === 0) throw new Error("The selected model returned an empty commit message.");
198178
198216
  console.log(source_default.cyan.dim(finalCommitMessage));
@@ -198194,15 +198232,13 @@ async function mainController(options = {}) {
198194
198232
  if (config$4.postCommand === "push-and-pull") await liveGit.pull();
198195
198233
  }
198196
198234
  async function generateMessage(options) {
198197
- const { git, languageModel, instructions, diff } = options;
198198
- if (estimateTokens(diff) <= options.maxDiffTokens) return generateCommitMessage(languageModel, instructions, diff);
198199
- console.log(source_default.yellow("• Large diff detected, minimizing"));
198235
+ const { git, languageModel, style, instructions, diff } = options;
198236
+ if (estimateTokens(diff) <= options.maxDiffTokens) return generateCommitMessage(languageModel, style, instructions, diff);
198200
198237
  const { toc, body } = await minimizeDiff(git, {
198201
198238
  perFileCap: options.perFileCap,
198202
198239
  allFiles: options.files
198203
198240
  });
198204
- if (estimateTokens(toc) + estimateTokens(body) <= options.maxDiffTokens) return generateCommitMessage(languageModel, instructions, `${toc}\n\n${body}`);
198205
- console.log(source_default.yellow("• Diff still too large, summarizing in parts"));
198241
+ if (estimateTokens(toc) + estimateTokens(body) <= options.maxDiffTokens) return generateCommitMessage(languageModel, style, instructions, `${toc}\n\n${body}`);
198206
198242
  let effectiveToc = toc;
198207
198243
  let chunkBudget = options.maxDiffTokens - estimateTokens(effectiveToc) - PROMPT_RESERVE_TOKENS;
198208
198244
  if (chunkBudget < MIN_CHUNK_BUDGET_TOKENS) {
@@ -198219,7 +198255,7 @@ async function generateMessage(options) {
198219
198255
  }
198220
198256
  }
198221
198257
  await Promise.all(Array.from({ length: Math.min(MAP_CONCURRENCY, chunks.length) }, worker));
198222
- return generateCommitMessageFromSummaries(languageModel, instructions, effectiveToc, summaries);
198258
+ return generateCommitMessageFromSummaries(languageModel, style, instructions, effectiveToc, summaries);
198223
198259
  }
198224
198260
  var AppUserCanceledError = class extends Error {};
198225
198261
  function handleError(fn$1) {
@@ -198231,9 +198267,9 @@ function handleError(fn$1) {
198231
198267
  }
198232
198268
  });
198233
198269
  }
198234
- const app = new Command().name("gityo").version(`v${version$4}`, "-v, --version", "Show the current version.").description("Stage changes, generate or enter a commit message, create a commit, and run a post-commit git command.").option("-g, --generate", "Generate a commit message and commit without asking.").option("-m, --message <message>", "Use the provided message as the commit message.").option("-p, --post", "Run the post-commit git command without asking.").option("--model <model>", "Model key from config to use (defaults to \"default\").").option("-y, --yolo", "Skip all questions, and generate message, commit, run post command. [Will fail if no model available]").action((options) => {
198235
- if (options.generate && options.message) {
198236
- console.error("Cannot use --generate and --message together.");
198270
+ const app = new Command().name("gityo").description("Stage changes, generate or enter a commit message, create a commit, and run a post-commit git command.").option("-i, --input <input>", "Use the provided input as the commit message.").option("-s, --style <style>", "Commit message style key to use (defaults to \"default\").").option("-m, --model <model>", "Model key from config to use (defaults to \"default\").").option("-g, --generate", "Generate a commit message and commit without asking.").option("-p, --post", "Run the post-commit git command without asking.").option("-y, --yolo", "Skip all questions, and generate message, commit, run post command. [Will fail if no model available]").version(`v${version$4}`, "-v, --version", "Show the current version.").action((options) => {
198271
+ if (options.generate && options.input) {
198272
+ console.error("Cannot use --generate and --input together.");
198237
198273
  process.exit(1);
198238
198274
  }
198239
198275
  handleError(() => mainController(options));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gityo",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/NazmusSayad/gityo.git"
@@ -8,12 +8,13 @@
8
8
  "sideEffects": false,
9
9
  "type": "module",
10
10
  "scripts": {
11
- "lint": "tsc --noEmit && eslint .",
12
- "fix": "tsc --noEmit && eslint . --fix",
13
- "start": "tsx --watch ./src/index.ts",
11
+ "typecheck": "tsc --noEmit",
12
+ "typecheck:watch": "tsc --noEmit --watch",
13
+ "lint": "eslint .",
14
+ "lint:fix": "eslint . --fix",
14
15
  "build": "tsdown --config ./tsdown.config.ts",
15
- "dev": "concurrently --names \"R,T\" --prefix-colors \"blue.dim,magenta.dim\" \"tsdown --config ./tsdown.config.ts --watch\" \"tsc --noEmit --watch\"",
16
- "dev:tsc": "tsc --noEmit --watch",
16
+ "dev": "tsdown --config ./tsdown.config.ts --watch",
17
+ "start": "node --watch ./dist/index.js",
17
18
  "json": "tsx ./src/json.ts"
18
19
  },
19
20
  "bin": {