git-coco 0.22.5 → 0.22.7

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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  import * as yargs from 'yargs';
2
3
  import { Arguments } from 'yargs';
3
4
  import { OllamaInput } from '@langchain/community/llms/ollama';
@@ -5,7 +5,7 @@ import yargs from 'yargs';
5
5
  import chalk from 'chalk';
6
6
  import * as fs from 'fs';
7
7
  import fs__default, { promises, existsSync, readFileSync } from 'fs';
8
- import { confirm, editor, select, password, input } from '@inquirer/prompts';
8
+ import { confirm, editor, select, input, password } from '@inquirer/prompts';
9
9
  import * as ini from 'ini';
10
10
  import * as os from 'os';
11
11
  import os__default from 'os';
@@ -47,7 +47,7 @@ import { pathToFileURL } from 'url';
47
47
  /**
48
48
  * Current build version from package.json
49
49
  */
50
- const BUILD_VERSION = "0.22.5";
50
+ const BUILD_VERSION = "0.22.7";
51
51
 
52
52
  const isInteractive = (config) => {
53
53
  return config?.mode === 'interactive' || !!config?.interactive;
@@ -231,7 +231,7 @@ function validateRequired(value, paramName, functionName) {
231
231
  function validateNonEmptyString(value, paramName, functionName) {
232
232
  validateRequired(value, paramName, functionName);
233
233
  if (typeof value !== 'string' || value.trim() === '') {
234
- throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Parameter '${paramName}' must be a non-empty string`, { paramName, functionName, value, type: typeof value });
234
+ throw new LangChainValidationError(`${`${functionName}: ` }Parameter '${paramName}' must be a non-empty string`, { paramName, functionName, value, type: typeof value });
235
235
  }
236
236
  }
237
237
  /**
@@ -240,7 +240,7 @@ function validateNonEmptyString(value, paramName, functionName) {
240
240
  function validateNonEmptyArray(value, paramName, functionName) {
241
241
  validateRequired(value, paramName, functionName);
242
242
  if (!Array.isArray(value) || value.length === 0) {
243
- throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Parameter '${paramName}' must be a non-empty array`, { paramName, functionName, value, isArray: Array.isArray(value), length: Array.isArray(value) ? value.length : undefined });
243
+ throw new LangChainValidationError(`${`${functionName}: ` }Parameter '${paramName}' must be a non-empty array`, { paramName, functionName, value, isArray: Array.isArray(value), length: Array.isArray(value) ? value.length : undefined });
244
244
  }
245
245
  }
246
246
  /**
@@ -2627,9 +2627,8 @@ const errorMap = (issue, _ctx) => {
2627
2627
  }
2628
2628
  return { message };
2629
2629
  };
2630
- var defaultErrorMap = errorMap;
2631
2630
 
2632
- let overrideErrorMap = defaultErrorMap;
2631
+ let overrideErrorMap = errorMap;
2633
2632
  function getErrorMap() {
2634
2633
  return overrideErrorMap;
2635
2634
  }
@@ -2672,7 +2671,7 @@ function addIssueToContext(ctx, issueData) {
2672
2671
  ctx.common.contextualErrorMap, // contextual error map is first priority
2673
2672
  ctx.schemaErrorMap, // then schema-bound map if available
2674
2673
  overrideMap, // then global override map
2675
- overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map
2674
+ overrideMap === errorMap ? undefined : errorMap, // then global default map
2676
2675
  ].filter((x) => !!x),
2677
2676
  });
2678
2677
  ctx.common.issues.push(issue);
@@ -5988,9 +5987,6 @@ ZodReadonly.create = (type, params) => {
5988
5987
  ...processCreateParams(params),
5989
5988
  });
5990
5989
  };
5991
- ({
5992
- object: ZodObject.lazycreate,
5993
- });
5994
5990
  var ZodFirstPartyTypeKind;
5995
5991
  (function (ZodFirstPartyTypeKind) {
5996
5992
  ZodFirstPartyTypeKind["ZodString"] = "ZodString";
@@ -6034,7 +6030,6 @@ const stringType = ZodString.create;
6034
6030
  ZodNever.create;
6035
6031
  const arrayType = ZodArray.create;
6036
6032
  const objectType = ZodObject.create;
6037
- ZodObject.strictCreate;
6038
6033
  const unionType = ZodUnion.create;
6039
6034
  ZodIntersection.create;
6040
6035
  ZodTuple.create;
@@ -7721,7 +7716,7 @@ const handler$4 = async (argv, logger) => {
7721
7716
  logger.verbose(`Generating commit log since the last tag`, { color: 'yellow' });
7722
7717
  // This function returns string[], needs to be adapted or replaced
7723
7718
  // For now, this path will have limited details.
7724
- const commitMessages = await getChangesSinceLastTag({ git, logger });
7719
+ const commitMessages = await getChangesSinceLastTag({ git});
7725
7720
  commits = commitMessages.map(msg => ({ message: msg }));
7726
7721
  }
7727
7722
  else if (config.range && config.range.includes(':')) {
@@ -7966,31 +7961,64 @@ async function executeChainWithSchema(schema, llm, prompt, variables, options =
7966
7961
  */
7967
7962
  function formatCommitMessage(result, options = {}) {
7968
7963
  const { append, ticketId, appendTicket } = options;
7969
- // If it's a string, check if it contains a JSON object
7964
+ // Helper function to construct the final message with appends
7965
+ const constructMessage = (title, body) => {
7966
+ const appendedText = append ? `\n\n${append}` : '';
7967
+ const ticketFooter = appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
7968
+ return `${title}\n\n${body}${appendedText}${ticketFooter}`;
7969
+ };
7970
+ // If it's a string, check if it contains a JSON object (including markdown code blocks)
7970
7971
  if (typeof result === 'string') {
7971
- try {
7972
- // Try to parse as JSON to see if it's a stringified object
7973
- const parsed = JSON.parse(result);
7974
- if (parsed && typeof parsed === 'object' && parsed.title && parsed.body) {
7975
- // It's a stringified JSON object, format it properly
7976
- const appendedText = append ? `\n\n${append}` : '';
7977
- const ticketFooter = appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
7978
- return `${parsed.title}\n\n${parsed.body}${appendedText}${ticketFooter}`;
7972
+ // Early return if string clearly doesn't contain JSON-like content
7973
+ if (!result.includes('{') && !result.includes('"title"')) {
7974
+ return result;
7975
+ }
7976
+ // Handle multiple markdown code block formats
7977
+ const codeBlockPatterns = [
7978
+ /```(?:json)?\s*(\{[\s\S]*?\})\s*```/, // Standard markdown blocks
7979
+ /`(\{[\s\S]*?\})`/, // Inline code blocks
7980
+ /^\s*(\{[\s\S]*\})\s*$/ // Raw JSON without blocks
7981
+ ];
7982
+ let jsonString = result;
7983
+ // Try each pattern to extract JSON
7984
+ for (const pattern of codeBlockPatterns) {
7985
+ const match = result.match(pattern);
7986
+ if (match && match[1]) {
7987
+ jsonString = match[1].trim();
7988
+ break;
7979
7989
  }
7980
7990
  }
7981
- catch {
7982
- // Not valid JSON, treat as regular string
7991
+ // Only attempt JSON parsing if we found potential JSON content
7992
+ if (jsonString !== result || jsonString.startsWith('{')) {
7993
+ try {
7994
+ // Try to parse as JSON to see if it's a stringified object
7995
+ const parsed = JSON.parse(jsonString);
7996
+ if (parsed &&
7997
+ typeof parsed === 'object' &&
7998
+ typeof parsed.title === 'string' &&
7999
+ typeof parsed.body === 'string' &&
8000
+ parsed.title.length > 0 &&
8001
+ parsed.body.length > 0) {
8002
+ // It's a valid stringified JSON object, format it properly
8003
+ return constructMessage(parsed.title, parsed.body);
8004
+ }
8005
+ }
8006
+ catch {
8007
+ // Not valid JSON, continue to fallback
8008
+ }
7983
8009
  }
8010
+ // If no JSON found and it's already formatted, return as-is
7984
8011
  return result;
7985
8012
  }
7986
8013
  // If it's already an object with title and body, format it
7987
- if (typeof result === 'object' && result !== null && 'title' in result && 'body' in result) {
8014
+ if (typeof result === 'object' && result !== null &&
8015
+ 'title' in result && 'body' in result) {
7988
8016
  const commitMsgObj = result;
7989
- const appendedText = append ? `\n\n${append}` : '';
7990
- const ticketFooter = appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
7991
- return `${commitMsgObj.title}\n\n${commitMsgObj.body}${appendedText}${ticketFooter}`;
8017
+ if (typeof commitMsgObj.title === 'string' && typeof commitMsgObj.body === 'string') {
8018
+ return constructMessage(commitMsgObj.title, commitMsgObj.body);
8019
+ }
7992
8020
  }
7993
- // Fallback - convert to string
8021
+ // Fallback - convert to string and return as-is
7994
8022
  return String(result);
7995
8023
  }
7996
8024
 
@@ -11579,11 +11607,13 @@ ${schema.description}
11579
11607
  });
11580
11608
  },
11581
11609
  });
11582
- // Construct the full commit message
11583
- const appendedText = argv.append ? `\n\n${argv.append}` : '';
11610
+ // Construct the full commit message using the utility function
11584
11611
  const ticketId = extractTicketIdFromBranchName(branchName);
11585
- const ticketFooter = argv.appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
11586
- const fullMessage = `${commitMsg.title}\n\n${commitMsg.body}${appendedText}${ticketFooter}`;
11612
+ const fullMessage = formatCommitMessage(commitMsg, {
11613
+ append: argv.append,
11614
+ ticketId: ticketId || undefined,
11615
+ appendTicket: argv.appendTicket,
11616
+ });
11587
11617
  // If commitlint validation is needed and not skipped, validate the message
11588
11618
  if ((USE_CONVENTIONAL_COMMITS || hasCommitLintConfig) && !shouldSkipCommitlintValidation) {
11589
11619
  const { validateCommitMessage, CommitlintValidationError } = await Promise.resolve().then(function () { return commitlintValidator; });
@@ -11666,13 +11696,8 @@ ${schema.description}
11666
11696
  logger.verbose(`Retrying commit message generation (attempt ${attempt}): ${error.message}`, { color: 'yellow' });
11667
11697
  },
11668
11698
  });
11669
- // Ensure we always return a properly formatted commit message string
11670
- const ticketId = extractTicketIdFromBranchName(branchName);
11671
- return formatCommitMessage(result, {
11672
- append: argv.append,
11673
- ticketId: ticketId || undefined,
11674
- appendTicket: argv.appendTicket,
11675
- });
11699
+ // Return the result which is already a properly formatted commit message string
11700
+ return result;
11676
11701
  },
11677
11702
  noResult: async () => {
11678
11703
  await noResult$2({ git, logger });
@@ -12855,9 +12880,7 @@ var review = {
12855
12880
  command,
12856
12881
  desc: 'Perform a code review on your changes',
12857
12882
  builder,
12858
- handler: commandExecutor(handler),
12859
- options,
12860
- };
12883
+ handler: commandExecutor(handler)};
12861
12884
 
12862
12885
  var types = /*#__PURE__*/Object.freeze({
12863
12886
  __proto__: null
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var readline__namespace = /*#__PURE__*/_interopNamespaceDefault(readline);
69
69
  /**
70
70
  * Current build version from package.json
71
71
  */
72
- const BUILD_VERSION = "0.22.5";
72
+ const BUILD_VERSION = "0.22.7";
73
73
 
74
74
  const isInteractive = (config) => {
75
75
  return config?.mode === 'interactive' || !!config?.interactive;
@@ -253,7 +253,7 @@ function validateRequired(value, paramName, functionName) {
253
253
  function validateNonEmptyString(value, paramName, functionName) {
254
254
  validateRequired(value, paramName, functionName);
255
255
  if (typeof value !== 'string' || value.trim() === '') {
256
- throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Parameter '${paramName}' must be a non-empty string`, { paramName, functionName, value, type: typeof value });
256
+ throw new LangChainValidationError(`${`${functionName}: ` }Parameter '${paramName}' must be a non-empty string`, { paramName, functionName, value, type: typeof value });
257
257
  }
258
258
  }
259
259
  /**
@@ -262,7 +262,7 @@ function validateNonEmptyString(value, paramName, functionName) {
262
262
  function validateNonEmptyArray(value, paramName, functionName) {
263
263
  validateRequired(value, paramName, functionName);
264
264
  if (!Array.isArray(value) || value.length === 0) {
265
- throw new LangChainValidationError(`${functionName ? `${functionName}: ` : ''}Parameter '${paramName}' must be a non-empty array`, { paramName, functionName, value, isArray: Array.isArray(value), length: Array.isArray(value) ? value.length : undefined });
265
+ throw new LangChainValidationError(`${`${functionName}: ` }Parameter '${paramName}' must be a non-empty array`, { paramName, functionName, value, isArray: Array.isArray(value), length: Array.isArray(value) ? value.length : undefined });
266
266
  }
267
267
  }
268
268
  /**
@@ -2649,9 +2649,8 @@ const errorMap = (issue, _ctx) => {
2649
2649
  }
2650
2650
  return { message };
2651
2651
  };
2652
- var defaultErrorMap = errorMap;
2653
2652
 
2654
- let overrideErrorMap = defaultErrorMap;
2653
+ let overrideErrorMap = errorMap;
2655
2654
  function getErrorMap() {
2656
2655
  return overrideErrorMap;
2657
2656
  }
@@ -2694,7 +2693,7 @@ function addIssueToContext(ctx, issueData) {
2694
2693
  ctx.common.contextualErrorMap, // contextual error map is first priority
2695
2694
  ctx.schemaErrorMap, // then schema-bound map if available
2696
2695
  overrideMap, // then global override map
2697
- overrideMap === defaultErrorMap ? undefined : defaultErrorMap, // then global default map
2696
+ overrideMap === errorMap ? undefined : errorMap, // then global default map
2698
2697
  ].filter((x) => !!x),
2699
2698
  });
2700
2699
  ctx.common.issues.push(issue);
@@ -6010,9 +6009,6 @@ ZodReadonly.create = (type, params) => {
6010
6009
  ...processCreateParams(params),
6011
6010
  });
6012
6011
  };
6013
- ({
6014
- object: ZodObject.lazycreate,
6015
- });
6016
6012
  var ZodFirstPartyTypeKind;
6017
6013
  (function (ZodFirstPartyTypeKind) {
6018
6014
  ZodFirstPartyTypeKind["ZodString"] = "ZodString";
@@ -6056,7 +6052,6 @@ const stringType = ZodString.create;
6056
6052
  ZodNever.create;
6057
6053
  const arrayType = ZodArray.create;
6058
6054
  const objectType = ZodObject.create;
6059
- ZodObject.strictCreate;
6060
6055
  const unionType = ZodUnion.create;
6061
6056
  ZodIntersection.create;
6062
6057
  ZodTuple.create;
@@ -7743,7 +7738,7 @@ const handler$4 = async (argv, logger) => {
7743
7738
  logger.verbose(`Generating commit log since the last tag`, { color: 'yellow' });
7744
7739
  // This function returns string[], needs to be adapted or replaced
7745
7740
  // For now, this path will have limited details.
7746
- const commitMessages = await getChangesSinceLastTag({ git, logger });
7741
+ const commitMessages = await getChangesSinceLastTag({ git});
7747
7742
  commits = commitMessages.map(msg => ({ message: msg }));
7748
7743
  }
7749
7744
  else if (config.range && config.range.includes(':')) {
@@ -7988,31 +7983,64 @@ async function executeChainWithSchema(schema, llm, prompt, variables, options =
7988
7983
  */
7989
7984
  function formatCommitMessage(result, options = {}) {
7990
7985
  const { append, ticketId, appendTicket } = options;
7991
- // If it's a string, check if it contains a JSON object
7986
+ // Helper function to construct the final message with appends
7987
+ const constructMessage = (title, body) => {
7988
+ const appendedText = append ? `\n\n${append}` : '';
7989
+ const ticketFooter = appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
7990
+ return `${title}\n\n${body}${appendedText}${ticketFooter}`;
7991
+ };
7992
+ // If it's a string, check if it contains a JSON object (including markdown code blocks)
7992
7993
  if (typeof result === 'string') {
7993
- try {
7994
- // Try to parse as JSON to see if it's a stringified object
7995
- const parsed = JSON.parse(result);
7996
- if (parsed && typeof parsed === 'object' && parsed.title && parsed.body) {
7997
- // It's a stringified JSON object, format it properly
7998
- const appendedText = append ? `\n\n${append}` : '';
7999
- const ticketFooter = appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
8000
- return `${parsed.title}\n\n${parsed.body}${appendedText}${ticketFooter}`;
7994
+ // Early return if string clearly doesn't contain JSON-like content
7995
+ if (!result.includes('{') && !result.includes('"title"')) {
7996
+ return result;
7997
+ }
7998
+ // Handle multiple markdown code block formats
7999
+ const codeBlockPatterns = [
8000
+ /```(?:json)?\s*(\{[\s\S]*?\})\s*```/, // Standard markdown blocks
8001
+ /`(\{[\s\S]*?\})`/, // Inline code blocks
8002
+ /^\s*(\{[\s\S]*\})\s*$/ // Raw JSON without blocks
8003
+ ];
8004
+ let jsonString = result;
8005
+ // Try each pattern to extract JSON
8006
+ for (const pattern of codeBlockPatterns) {
8007
+ const match = result.match(pattern);
8008
+ if (match && match[1]) {
8009
+ jsonString = match[1].trim();
8010
+ break;
8001
8011
  }
8002
8012
  }
8003
- catch {
8004
- // Not valid JSON, treat as regular string
8013
+ // Only attempt JSON parsing if we found potential JSON content
8014
+ if (jsonString !== result || jsonString.startsWith('{')) {
8015
+ try {
8016
+ // Try to parse as JSON to see if it's a stringified object
8017
+ const parsed = JSON.parse(jsonString);
8018
+ if (parsed &&
8019
+ typeof parsed === 'object' &&
8020
+ typeof parsed.title === 'string' &&
8021
+ typeof parsed.body === 'string' &&
8022
+ parsed.title.length > 0 &&
8023
+ parsed.body.length > 0) {
8024
+ // It's a valid stringified JSON object, format it properly
8025
+ return constructMessage(parsed.title, parsed.body);
8026
+ }
8027
+ }
8028
+ catch {
8029
+ // Not valid JSON, continue to fallback
8030
+ }
8005
8031
  }
8032
+ // If no JSON found and it's already formatted, return as-is
8006
8033
  return result;
8007
8034
  }
8008
8035
  // If it's already an object with title and body, format it
8009
- if (typeof result === 'object' && result !== null && 'title' in result && 'body' in result) {
8036
+ if (typeof result === 'object' && result !== null &&
8037
+ 'title' in result && 'body' in result) {
8010
8038
  const commitMsgObj = result;
8011
- const appendedText = append ? `\n\n${append}` : '';
8012
- const ticketFooter = appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
8013
- return `${commitMsgObj.title}\n\n${commitMsgObj.body}${appendedText}${ticketFooter}`;
8039
+ if (typeof commitMsgObj.title === 'string' && typeof commitMsgObj.body === 'string') {
8040
+ return constructMessage(commitMsgObj.title, commitMsgObj.body);
8041
+ }
8014
8042
  }
8015
- // Fallback - convert to string
8043
+ // Fallback - convert to string and return as-is
8016
8044
  return String(result);
8017
8045
  }
8018
8046
 
@@ -11601,11 +11629,13 @@ ${schema.description}
11601
11629
  });
11602
11630
  },
11603
11631
  });
11604
- // Construct the full commit message
11605
- const appendedText = argv.append ? `\n\n${argv.append}` : '';
11632
+ // Construct the full commit message using the utility function
11606
11633
  const ticketId = extractTicketIdFromBranchName(branchName);
11607
- const ticketFooter = argv.appendTicket && ticketId ? `\n\nPart of **${ticketId}**` : '';
11608
- const fullMessage = `${commitMsg.title}\n\n${commitMsg.body}${appendedText}${ticketFooter}`;
11634
+ const fullMessage = formatCommitMessage(commitMsg, {
11635
+ append: argv.append,
11636
+ ticketId: ticketId || undefined,
11637
+ appendTicket: argv.appendTicket,
11638
+ });
11609
11639
  // If commitlint validation is needed and not skipped, validate the message
11610
11640
  if ((USE_CONVENTIONAL_COMMITS || hasCommitLintConfig) && !shouldSkipCommitlintValidation) {
11611
11641
  const { validateCommitMessage, CommitlintValidationError } = await Promise.resolve().then(function () { return commitlintValidator; });
@@ -11688,13 +11718,8 @@ ${schema.description}
11688
11718
  logger.verbose(`Retrying commit message generation (attempt ${attempt}): ${error.message}`, { color: 'yellow' });
11689
11719
  },
11690
11720
  });
11691
- // Ensure we always return a properly formatted commit message string
11692
- const ticketId = extractTicketIdFromBranchName(branchName);
11693
- return formatCommitMessage(result, {
11694
- append: argv.append,
11695
- ticketId: ticketId || undefined,
11696
- appendTicket: argv.appendTicket,
11697
- });
11721
+ // Return the result which is already a properly formatted commit message string
11722
+ return result;
11698
11723
  },
11699
11724
  noResult: async () => {
11700
11725
  await noResult$2({ git, logger });
@@ -12877,9 +12902,7 @@ var review = {
12877
12902
  command,
12878
12903
  desc: 'Perform a code review on your changes',
12879
12904
  builder,
12880
- handler: commandExecutor(handler),
12881
- options,
12882
- };
12905
+ handler: commandExecutor(handler)};
12883
12906
 
12884
12907
  var types = /*#__PURE__*/Object.freeze({
12885
12908
  __proto__: null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-coco",
3
- "version": "0.22.5",
3
+ "version": "0.22.7",
4
4
  "description": "zero-effort git commits with coco.",
5
5
  "author": "gfargo <ghfargo@gmail.com>",
6
6
  "license": "MIT",
@@ -60,7 +60,7 @@
60
60
  "eslint": "^8.54.0",
61
61
  "jest": "^30.0.5",
62
62
  "release-it": "^19.0.4",
63
- "rollup": "^3.26.1",
63
+ "rollup": "^4.50.0",
64
64
  "rollup-plugin-dts": "^6.1.0",
65
65
  "rollup-plugin-executable": "^1.6.3",
66
66
  "rollup-plugin-peer-deps-external": "^2.2.4",