git-coco 0.22.8 → 0.22.9

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.
@@ -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.8";
50
+ const BUILD_VERSION = "0.22.9";
51
51
 
52
52
  const isInteractive = (config) => {
53
53
  return config?.mode === 'interactive' || !!config?.interactive;
@@ -7212,6 +7212,8 @@ const CONVENTIONAL_TEMPLATE = `Generate a commit message that strictly adheres t
7212
7212
  - Scope should be a noun in parentheses (e.g., (parser), (ui), (config))
7213
7213
  - Omit scope if the change is broad or affects multiple areas
7214
7214
 
7215
+ CRITICAL: You must respond with ONLY valid JSON. All string values must be properly quoted.
7216
+
7215
7217
  Based on the following diff summary, generate a conventional commit message that follows these rules exactly:
7216
7218
 
7217
7219
  """"""
@@ -7955,6 +7957,55 @@ async function executeChainWithSchema(schema, llm, prompt, variables, options =
7955
7957
  }
7956
7958
  }
7957
7959
 
7960
+ /**
7961
+ * Utility to repair common JSON formatting issues that LLMs make
7962
+ * Specifically handles cases where string values are not properly quoted
7963
+ */
7964
+ function repairJson(jsonString) {
7965
+ // Remove any markdown code block wrapping
7966
+ let cleaned = jsonString.replace(/```(?:json)?\s*([\s\S]*?)\s*```/g, '$1').trim();
7967
+ // Remove inline code block wrapping
7968
+ cleaned = cleaned.replace(/^`(.*)`$/, '$1').trim();
7969
+ // If it doesn't look like JSON, return as-is
7970
+ if (!cleaned.startsWith('{') || !cleaned.endsWith('}')) {
7971
+ return jsonString;
7972
+ }
7973
+ try {
7974
+ // First try parsing as-is
7975
+ JSON.parse(cleaned);
7976
+ return cleaned;
7977
+ }
7978
+ catch {
7979
+ // Try to repair common issues
7980
+ let repaired = cleaned;
7981
+ // Fix unquoted string values in title and body fields
7982
+ // Pattern: "title": unquoted_value, -> "title": "unquoted_value",
7983
+ repaired = repaired.replace(/"(title|body)":\s*([^",\{\}\[\]]+?)(?=\s*[,\}])/g, (match, field, value) => {
7984
+ // Clean up the value (remove leading/trailing whitespace)
7985
+ const cleanValue = value.trim();
7986
+ // If it's already quoted or looks like a number/boolean, leave it
7987
+ if (cleanValue.startsWith('"') || /^(true|false|\d+)$/.test(cleanValue)) {
7988
+ return match;
7989
+ }
7990
+ // Quote the value
7991
+ return `"${field}": "${cleanValue}"`;
7992
+ });
7993
+ // Fix missing quotes around field names (though this should be rare)
7994
+ repaired = repaired.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
7995
+ // Remove trailing commas before closing braces
7996
+ repaired = repaired.replace(/,(\s*[}\]])/g, '$1');
7997
+ try {
7998
+ // Test if the repair worked
7999
+ JSON.parse(repaired);
8000
+ return repaired;
8001
+ }
8002
+ catch {
8003
+ // If repair failed, return original
8004
+ return jsonString;
8005
+ }
8006
+ }
8007
+ }
8008
+
7958
8009
  /**
7959
8010
  * Utility function to ensure commit messages are properly formatted as strings
7960
8011
  * rather than JSON objects, whether they come as parsed objects or stringified JSON
@@ -8004,7 +8055,23 @@ function formatCommitMessage(result, options = {}) {
8004
8055
  }
8005
8056
  }
8006
8057
  catch {
8007
- // Not valid JSON, continue to fallback
8058
+ // Try to repair the JSON and parse again
8059
+ try {
8060
+ const repairedJson = repairJson(jsonString);
8061
+ const parsed = JSON.parse(repairedJson);
8062
+ if (parsed &&
8063
+ typeof parsed === 'object' &&
8064
+ typeof parsed.title === 'string' &&
8065
+ typeof parsed.body === 'string' &&
8066
+ parsed.title.length > 0 &&
8067
+ parsed.body.length > 0) {
8068
+ // Successfully repaired and parsed JSON
8069
+ return constructMessage(parsed.title, parsed.body);
8070
+ }
8071
+ }
8072
+ catch {
8073
+ // Repair failed, continue to fallback
8074
+ }
8008
8075
  }
8009
8076
  }
8010
8077
  // If no JSON found and it's already formatted, return as-is
@@ -11495,12 +11562,23 @@ const handler$3 = async (argv, logger) => {
11495
11562
  const schema = USE_CONVENTIONAL_COMMITS
11496
11563
  ? ConventionalCommitMessageResponseSchema
11497
11564
  : CommitMessageResponseSchema;
11498
- const formatInstructions = `You must always return a valid JSON object. Do not return any additional text. The JSON object you return should match the following schema:
11565
+ const formatInstructions = `CRITICAL: You must return ONLY a valid JSON object with no additional text, explanations, or markdown formatting.
11566
+
11567
+ REQUIRED JSON FORMAT:
11499
11568
  ${schema.description}
11569
+
11570
+ EXAMPLE (follow this exact structure):
11500
11571
  {
11501
- "title": "The commit title",
11502
- "body": "The commit body"
11503
- }`;
11572
+ "title": "feat(auth): add user authentication system",
11573
+ "body": "Implement JWT-based authentication with login and logout functionality. Includes password hashing and session management."
11574
+ }
11575
+
11576
+ IMPORTANT RULES:
11577
+ - ALL string values MUST be enclosed in double quotes
11578
+ - NO trailing commas
11579
+ - NO comments or additional text outside the JSON
11580
+ - The "title" and "body" values must be properly quoted strings
11581
+ - Return ONLY the JSON object, nothing else`;
11504
11582
  // Use conventional commit prompt if enabled
11505
11583
  const promptTemplate = USE_CONVENTIONAL_COMMITS ? CONVENTIONAL_COMMIT_PROMPT : COMMIT_PROMPT;
11506
11584
  const prompt = getPrompt({
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.8";
72
+ const BUILD_VERSION = "0.22.9";
73
73
 
74
74
  const isInteractive = (config) => {
75
75
  return config?.mode === 'interactive' || !!config?.interactive;
@@ -7234,6 +7234,8 @@ const CONVENTIONAL_TEMPLATE = `Generate a commit message that strictly adheres t
7234
7234
  - Scope should be a noun in parentheses (e.g., (parser), (ui), (config))
7235
7235
  - Omit scope if the change is broad or affects multiple areas
7236
7236
 
7237
+ CRITICAL: You must respond with ONLY valid JSON. All string values must be properly quoted.
7238
+
7237
7239
  Based on the following diff summary, generate a conventional commit message that follows these rules exactly:
7238
7240
 
7239
7241
  """"""
@@ -7977,6 +7979,55 @@ async function executeChainWithSchema(schema, llm, prompt, variables, options =
7977
7979
  }
7978
7980
  }
7979
7981
 
7982
+ /**
7983
+ * Utility to repair common JSON formatting issues that LLMs make
7984
+ * Specifically handles cases where string values are not properly quoted
7985
+ */
7986
+ function repairJson(jsonString) {
7987
+ // Remove any markdown code block wrapping
7988
+ let cleaned = jsonString.replace(/```(?:json)?\s*([\s\S]*?)\s*```/g, '$1').trim();
7989
+ // Remove inline code block wrapping
7990
+ cleaned = cleaned.replace(/^`(.*)`$/, '$1').trim();
7991
+ // If it doesn't look like JSON, return as-is
7992
+ if (!cleaned.startsWith('{') || !cleaned.endsWith('}')) {
7993
+ return jsonString;
7994
+ }
7995
+ try {
7996
+ // First try parsing as-is
7997
+ JSON.parse(cleaned);
7998
+ return cleaned;
7999
+ }
8000
+ catch {
8001
+ // Try to repair common issues
8002
+ let repaired = cleaned;
8003
+ // Fix unquoted string values in title and body fields
8004
+ // Pattern: "title": unquoted_value, -> "title": "unquoted_value",
8005
+ repaired = repaired.replace(/"(title|body)":\s*([^",\{\}\[\]]+?)(?=\s*[,\}])/g, (match, field, value) => {
8006
+ // Clean up the value (remove leading/trailing whitespace)
8007
+ const cleanValue = value.trim();
8008
+ // If it's already quoted or looks like a number/boolean, leave it
8009
+ if (cleanValue.startsWith('"') || /^(true|false|\d+)$/.test(cleanValue)) {
8010
+ return match;
8011
+ }
8012
+ // Quote the value
8013
+ return `"${field}": "${cleanValue}"`;
8014
+ });
8015
+ // Fix missing quotes around field names (though this should be rare)
8016
+ repaired = repaired.replace(/([{,]\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*:/g, '$1"$2":');
8017
+ // Remove trailing commas before closing braces
8018
+ repaired = repaired.replace(/,(\s*[}\]])/g, '$1');
8019
+ try {
8020
+ // Test if the repair worked
8021
+ JSON.parse(repaired);
8022
+ return repaired;
8023
+ }
8024
+ catch {
8025
+ // If repair failed, return original
8026
+ return jsonString;
8027
+ }
8028
+ }
8029
+ }
8030
+
7980
8031
  /**
7981
8032
  * Utility function to ensure commit messages are properly formatted as strings
7982
8033
  * rather than JSON objects, whether they come as parsed objects or stringified JSON
@@ -8026,7 +8077,23 @@ function formatCommitMessage(result, options = {}) {
8026
8077
  }
8027
8078
  }
8028
8079
  catch {
8029
- // Not valid JSON, continue to fallback
8080
+ // Try to repair the JSON and parse again
8081
+ try {
8082
+ const repairedJson = repairJson(jsonString);
8083
+ const parsed = JSON.parse(repairedJson);
8084
+ if (parsed &&
8085
+ typeof parsed === 'object' &&
8086
+ typeof parsed.title === 'string' &&
8087
+ typeof parsed.body === 'string' &&
8088
+ parsed.title.length > 0 &&
8089
+ parsed.body.length > 0) {
8090
+ // Successfully repaired and parsed JSON
8091
+ return constructMessage(parsed.title, parsed.body);
8092
+ }
8093
+ }
8094
+ catch {
8095
+ // Repair failed, continue to fallback
8096
+ }
8030
8097
  }
8031
8098
  }
8032
8099
  // If no JSON found and it's already formatted, return as-is
@@ -11517,12 +11584,23 @@ const handler$3 = async (argv, logger) => {
11517
11584
  const schema = USE_CONVENTIONAL_COMMITS
11518
11585
  ? ConventionalCommitMessageResponseSchema
11519
11586
  : CommitMessageResponseSchema;
11520
- const formatInstructions = `You must always return a valid JSON object. Do not return any additional text. The JSON object you return should match the following schema:
11587
+ const formatInstructions = `CRITICAL: You must return ONLY a valid JSON object with no additional text, explanations, or markdown formatting.
11588
+
11589
+ REQUIRED JSON FORMAT:
11521
11590
  ${schema.description}
11591
+
11592
+ EXAMPLE (follow this exact structure):
11522
11593
  {
11523
- "title": "The commit title",
11524
- "body": "The commit body"
11525
- }`;
11594
+ "title": "feat(auth): add user authentication system",
11595
+ "body": "Implement JWT-based authentication with login and logout functionality. Includes password hashing and session management."
11596
+ }
11597
+
11598
+ IMPORTANT RULES:
11599
+ - ALL string values MUST be enclosed in double quotes
11600
+ - NO trailing commas
11601
+ - NO comments or additional text outside the JSON
11602
+ - The "title" and "body" values must be properly quoted strings
11603
+ - Return ONLY the JSON object, nothing else`;
11526
11604
  // Use conventional commit prompt if enabled
11527
11605
  const promptTemplate = USE_CONVENTIONAL_COMMITS ? CONVENTIONAL_COMMIT_PROMPT : COMMIT_PROMPT;
11528
11606
  const prompt = getPrompt({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-coco",
3
- "version": "0.22.8",
3
+ "version": "0.22.9",
4
4
  "description": "zero-effort git commits with coco.",
5
5
  "author": "gfargo <ghfargo@gmail.com>",
6
6
  "license": "MIT",