git-coco 0.22.7 → 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.
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.mjs +87 -12
- package/dist/index.js +87 -12
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.esm.mjs
CHANGED
|
@@ -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.
|
|
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
|
-
//
|
|
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
|
|
@@ -11140,10 +11207,7 @@ for (var i = 0; i < 256; i++) {
|
|
|
11140
11207
|
simpleEscapeMap[i] = simpleEscapeSequence(i);
|
|
11141
11208
|
}
|
|
11142
11209
|
|
|
11143
|
-
|
|
11144
|
-
// const MAX_TOKENS_PER_SUMMARY = 4096
|
|
11145
|
-
const MAX_TOKENS_PER_SUMMARY = 12288;
|
|
11146
|
-
async function fileChangeParser({ changes, commit, options: { tokenizer, git, llm: model, logger }, }) {
|
|
11210
|
+
async function fileChangeParser({ changes, commit, options: { tokenizer, git, llm: model, logger, maxTokens }, }) {
|
|
11147
11211
|
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 10000, chunkOverlap: 250 });
|
|
11148
11212
|
const summarizationChain = loadSummarizationChain(model, {
|
|
11149
11213
|
type: 'map_reduce',
|
|
@@ -11161,7 +11225,7 @@ async function fileChangeParser({ changes, commit, options: { tokenizer, git, ll
|
|
|
11161
11225
|
logger.startTimer();
|
|
11162
11226
|
const summary = await summarizeDiffs(diffs, {
|
|
11163
11227
|
tokenizer,
|
|
11164
|
-
maxTokens:
|
|
11228
|
+
maxTokens: maxTokens || 4096,
|
|
11165
11229
|
textSplitter,
|
|
11166
11230
|
chain: summarizationChain,
|
|
11167
11231
|
logger,
|
|
@@ -11464,7 +11528,7 @@ const handler$3 = async (argv, logger) => {
|
|
|
11464
11528
|
return await fileChangeParser({
|
|
11465
11529
|
changes,
|
|
11466
11530
|
commit: '--staged',
|
|
11467
|
-
options: { tokenizer, git, llm, logger },
|
|
11531
|
+
options: { tokenizer, git, llm, logger, maxTokens: config.service.tokenLimit },
|
|
11468
11532
|
});
|
|
11469
11533
|
}
|
|
11470
11534
|
const commitMsg = await generateAndReviewLoop({
|
|
@@ -11498,12 +11562,23 @@ const handler$3 = async (argv, logger) => {
|
|
|
11498
11562
|
const schema = USE_CONVENTIONAL_COMMITS
|
|
11499
11563
|
? ConventionalCommitMessageResponseSchema
|
|
11500
11564
|
: CommitMessageResponseSchema;
|
|
11501
|
-
const formatInstructions = `You must
|
|
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:
|
|
11502
11568
|
${schema.description}
|
|
11569
|
+
|
|
11570
|
+
EXAMPLE (follow this exact structure):
|
|
11503
11571
|
{
|
|
11504
|
-
"title": "
|
|
11505
|
-
"body": "
|
|
11506
|
-
}
|
|
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`;
|
|
11507
11582
|
// Use conventional commit prompt if enabled
|
|
11508
11583
|
const promptTemplate = USE_CONVENTIONAL_COMMITS ? CONVENTIONAL_COMMIT_PROMPT : COMMIT_PROMPT;
|
|
11509
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.
|
|
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
|
-
//
|
|
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
|
|
@@ -11162,10 +11229,7 @@ for (var i = 0; i < 256; i++) {
|
|
|
11162
11229
|
simpleEscapeMap[i] = simpleEscapeSequence(i);
|
|
11163
11230
|
}
|
|
11164
11231
|
|
|
11165
|
-
|
|
11166
|
-
// const MAX_TOKENS_PER_SUMMARY = 4096
|
|
11167
|
-
const MAX_TOKENS_PER_SUMMARY = 12288;
|
|
11168
|
-
async function fileChangeParser({ changes, commit, options: { tokenizer, git, llm: model, logger }, }) {
|
|
11232
|
+
async function fileChangeParser({ changes, commit, options: { tokenizer, git, llm: model, logger, maxTokens }, }) {
|
|
11169
11233
|
const textSplitter = new RecursiveCharacterTextSplitter({ chunkSize: 10000, chunkOverlap: 250 });
|
|
11170
11234
|
const summarizationChain = loadSummarizationChain(model, {
|
|
11171
11235
|
type: 'map_reduce',
|
|
@@ -11183,7 +11247,7 @@ async function fileChangeParser({ changes, commit, options: { tokenizer, git, ll
|
|
|
11183
11247
|
logger.startTimer();
|
|
11184
11248
|
const summary = await summarizeDiffs(diffs, {
|
|
11185
11249
|
tokenizer,
|
|
11186
|
-
maxTokens:
|
|
11250
|
+
maxTokens: maxTokens || 4096,
|
|
11187
11251
|
textSplitter,
|
|
11188
11252
|
chain: summarizationChain,
|
|
11189
11253
|
logger,
|
|
@@ -11486,7 +11550,7 @@ const handler$3 = async (argv, logger) => {
|
|
|
11486
11550
|
return await fileChangeParser({
|
|
11487
11551
|
changes,
|
|
11488
11552
|
commit: '--staged',
|
|
11489
|
-
options: { tokenizer, git, llm, logger },
|
|
11553
|
+
options: { tokenizer, git, llm, logger, maxTokens: config.service.tokenLimit },
|
|
11490
11554
|
});
|
|
11491
11555
|
}
|
|
11492
11556
|
const commitMsg = await generateAndReviewLoop({
|
|
@@ -11520,12 +11584,23 @@ const handler$3 = async (argv, logger) => {
|
|
|
11520
11584
|
const schema = USE_CONVENTIONAL_COMMITS
|
|
11521
11585
|
? ConventionalCommitMessageResponseSchema
|
|
11522
11586
|
: CommitMessageResponseSchema;
|
|
11523
|
-
const formatInstructions = `You must
|
|
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:
|
|
11524
11590
|
${schema.description}
|
|
11591
|
+
|
|
11592
|
+
EXAMPLE (follow this exact structure):
|
|
11525
11593
|
{
|
|
11526
|
-
"title": "
|
|
11527
|
-
"body": "
|
|
11528
|
-
}
|
|
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`;
|
|
11529
11604
|
// Use conventional commit prompt if enabled
|
|
11530
11605
|
const promptTemplate = USE_CONVENTIONAL_COMMITS ? CONVENTIONAL_COMMIT_PROMPT : COMMIT_PROMPT;
|
|
11531
11606
|
const prompt = getPrompt({
|