smart-commit-copilot-cli 0.1.6 → 0.1.8
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/CHANGELOG.md +42 -0
- package/README.md +46 -4
- package/docs/configuration.md +99 -7
- package/docs/contracts.md +68 -2
- package/docs/getting-started.md +4 -1
- package/docs/publish.md +1 -1
- package/docs/releases/0.1.7-draft.md +55 -0
- package/docs/releases/0.1.8-draft.md +80 -0
- package/docs/roadmap.md +1 -1
- package/docs/verification.md +1 -0
- package/examples/config/smart-commit.json +32 -5
- package/out/cliApp.js +53 -6
- package/out/cliApp.js.map +1 -1
- package/out/commands/bridge.js +189 -6
- package/out/commands/bridge.js.map +1 -1
- package/out/commands/pullRequest.js +176 -0
- package/out/commands/pullRequest.js.map +1 -0
- package/out/commitMessage/index.js +2 -1
- package/out/commitMessage/index.js.map +1 -1
- package/out/commitMessage/prompt.js +58 -10
- package/out/commitMessage/prompt.js.map +1 -1
- package/out/commitMessage/protocol.js +168 -16
- package/out/commitMessage/protocol.js.map +1 -1
- package/out/config/cliArgs.js +114 -0
- package/out/config/cliArgs.js.map +1 -1
- package/out/config/constants.js +10 -1
- package/out/config/constants.js.map +1 -1
- package/out/config/env.js +90 -0
- package/out/config/env.js.map +1 -1
- package/out/config/file.js +113 -0
- package/out/config/file.js.map +1 -1
- package/out/config/legacySmartCommit.js +118 -9
- package/out/config/legacySmartCommit.js.map +1 -1
- package/out/config/merge.js +18 -0
- package/out/config/merge.js.map +1 -1
- package/out/config/schema.js +79 -7
- package/out/config/schema.js.map +1 -1
- package/out/contracts.js +174 -7
- package/out/contracts.js.map +1 -1
- package/out/git.js +108 -2
- package/out/git.js.map +1 -1
- package/out/output.js +4 -0
- package/out/output.js.map +1 -1
- package/out/pullRequest/api.js +528 -0
- package/out/pullRequest/api.js.map +1 -0
- package/out/pullRequest/client.js +17 -0
- package/out/pullRequest/client.js.map +1 -0
- package/out/pullRequest/config.js +18 -0
- package/out/pullRequest/config.js.map +1 -0
- package/out/pullRequest/contentPrompt.js +116 -0
- package/out/pullRequest/contentPrompt.js.map +1 -0
- package/out/pullRequest/contentService.js +77 -0
- package/out/pullRequest/contentService.js.map +1 -0
- package/out/pullRequest/index.js +25 -0
- package/out/pullRequest/index.js.map +1 -0
- package/out/pullRequest/platform.js +101 -0
- package/out/pullRequest/platform.js.map +1 -0
- package/out/pullRequest/redact.js +15 -0
- package/out/pullRequest/redact.js.map +1 -0
- package/out/pullRequest/workflow.js +153 -0
- package/out/pullRequest/workflow.js.map +1 -0
- package/out/renderOutput.js +31 -1
- package/out/renderOutput.js.map +1 -1
- package/out/reporting/aggregate.js +1 -1
- package/out/reporting/aggregate.js.map +1 -1
- package/out/reporting/mockProvider.js +5 -1
- package/out/reporting/mockProvider.js.map +1 -1
- package/out/reporting/openaiProvider.js +5 -1
- package/out/reporting/openaiProvider.js.map +1 -1
- package/out/reporting/prompt.js +145 -20
- package/out/reporting/prompt.js.map +1 -1
- package/out/reporting/render.js +24 -22
- package/out/reporting/render.js.map +1 -1
- package/out/reporting/timeWindow.js +101 -36
- package/out/reporting/timeWindow.js.map +1 -1
- package/out/reporting/types.js +3 -0
- package/out/reporting/types.js.map +1 -1
- package/out/review/mockProvider.js +25 -1
- package/out/review/mockProvider.js.map +1 -1
- package/out/stagedChangeSummary/index.js +53 -0
- package/out/stagedChangeSummary/index.js.map +1 -0
- package/out/stagedChangeSummary/mockProvider.js +24 -0
- package/out/stagedChangeSummary/mockProvider.js.map +1 -0
- package/out/stagedChangeSummary/openaiProvider.js +19 -0
- package/out/stagedChangeSummary/openaiProvider.js.map +1 -0
- package/out/stagedChangeSummary/prompt.js +138 -0
- package/out/stagedChangeSummary/prompt.js.map +1 -0
- package/out/stagedChangeSummary/provider.js +3 -0
- package/out/stagedChangeSummary/provider.js.map +1 -0
- package/out/stagedChangeSummary/render.js +74 -0
- package/out/stagedChangeSummary/render.js.map +1 -0
- package/package.json +1 -1
- package/src/git-commit-message-skills/conventional/SKILL.md +3 -3
- package/src/git-commit-message-skills/gitmoji/SKILL.md +3 -3
- package/src/git-commit-message-skills/semantic/SKILL.md +3 -3
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.EXIT_CODE_RUNTIME_ERROR = exports.EXIT_CODE_CONFIG_ERROR = exports.EXIT_CODE_SUCCESS = void 0;
|
|
37
|
+
exports.runPullRequestCreateCommand = runPullRequestCreateCommand;
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
const config_1 = require("../config");
|
|
41
|
+
const contracts_1 = require("../contracts");
|
|
42
|
+
const git_1 = require("../git");
|
|
43
|
+
const output_1 = require("../output");
|
|
44
|
+
const pullRequest_1 = require("../pullRequest");
|
|
45
|
+
const redact_1 = require("../pullRequest/redact");
|
|
46
|
+
exports.EXIT_CODE_SUCCESS = 0;
|
|
47
|
+
exports.EXIT_CODE_CONFIG_ERROR = 3;
|
|
48
|
+
exports.EXIT_CODE_RUNTIME_ERROR = 4;
|
|
49
|
+
class PullRequestConfigError extends Error {
|
|
50
|
+
constructor(message) {
|
|
51
|
+
super(message);
|
|
52
|
+
this.name = "PullRequestConfigError";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function runPullRequestCreateCommand(argv, env = process.env) {
|
|
56
|
+
const dryRun = argv.includes("--dry-run");
|
|
57
|
+
const configArgv = argv.filter((token) => token !== "--dry-run");
|
|
58
|
+
const fallbackConfig = (0, output_1.redactCliConfig)((0, config_1.resolveCliConfig)({
|
|
59
|
+
argv: [],
|
|
60
|
+
env: {},
|
|
61
|
+
validate: false,
|
|
62
|
+
requireConnection: false
|
|
63
|
+
}).config);
|
|
64
|
+
let resolved;
|
|
65
|
+
try {
|
|
66
|
+
resolved = (0, config_1.resolveCliConfig)({
|
|
67
|
+
argv: configArgv,
|
|
68
|
+
env,
|
|
69
|
+
validate: true,
|
|
70
|
+
requireConnection: true
|
|
71
|
+
});
|
|
72
|
+
validatePullRequestCommandConfig(resolved.config);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return buildErrorResult("CONFIG_ERROR", error instanceof Error ? error.message : String(error), null, dryRun, fallbackConfig);
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
const repositoryPath = await resolveRepositoryPath(resolved.runtime.repositoryPath);
|
|
79
|
+
const result = await (0, pullRequest_1.createPullRequestFromCurrentBranch)({
|
|
80
|
+
repositoryPath,
|
|
81
|
+
config: resolved.config,
|
|
82
|
+
client: (0, pullRequest_1.createOpenAICompatiblePullRequestContentClient)(resolved.config),
|
|
83
|
+
dryRun
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
exitCode: exports.EXIT_CODE_SUCCESS,
|
|
87
|
+
payload: {
|
|
88
|
+
schemaVersion: contracts_1.SMART_COMMIT_CLI_SCHEMA_VERSION,
|
|
89
|
+
status: result.status,
|
|
90
|
+
command: "pull-request create",
|
|
91
|
+
repositoryPath,
|
|
92
|
+
platform: result.platform,
|
|
93
|
+
sourceBranch: result.sourceBranch,
|
|
94
|
+
targetBranch: result.targetBranch,
|
|
95
|
+
title: result.title,
|
|
96
|
+
url: result.url,
|
|
97
|
+
warnings: result.warnings,
|
|
98
|
+
dryRun,
|
|
99
|
+
config: (0, output_1.redactCliConfig)(resolved.config),
|
|
100
|
+
summary: buildSummary(result.status, result.url)
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const code = error instanceof PullRequestConfigError ? "CONFIG_ERROR" : "RUNTIME_ERROR";
|
|
106
|
+
const message = redactPullRequestError(resolved.config, error instanceof Error ? error.message : String(error));
|
|
107
|
+
return buildErrorResult(code, message, resolved, dryRun, (0, output_1.redactCliConfig)(resolved.config));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function redactPullRequestError(config, message) {
|
|
111
|
+
return (0, redact_1.redactSensitiveText)(message, [config.pullRequest.authToken]);
|
|
112
|
+
}
|
|
113
|
+
function validatePullRequestCommandConfig(config) {
|
|
114
|
+
(0, config_1.validateCliConfig)(config, { requireConnection: true });
|
|
115
|
+
if (!config.pullRequest.targetBranch.trim()) {
|
|
116
|
+
throw new PullRequestConfigError("--target-branch or pullRequest.targetBranch is required.");
|
|
117
|
+
}
|
|
118
|
+
if (!config.pullRequest.authToken.trim()) {
|
|
119
|
+
throw new PullRequestConfigError("--auth-token or SMART_COMMIT_PULL_REQUEST_AUTH_TOKEN is required.");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function buildErrorResult(code, message, resolved, dryRun, config) {
|
|
123
|
+
return {
|
|
124
|
+
exitCode: code === "CONFIG_ERROR" ? exports.EXIT_CODE_CONFIG_ERROR : exports.EXIT_CODE_RUNTIME_ERROR,
|
|
125
|
+
payload: {
|
|
126
|
+
schemaVersion: contracts_1.SMART_COMMIT_CLI_SCHEMA_VERSION,
|
|
127
|
+
status: "error",
|
|
128
|
+
command: "pull-request create",
|
|
129
|
+
repositoryPath: resolved?.runtime.repositoryPath ? path.resolve(resolved.runtime.repositoryPath) : null,
|
|
130
|
+
platform: null,
|
|
131
|
+
sourceBranch: null,
|
|
132
|
+
targetBranch: resolved?.config.pullRequest.targetBranch || null,
|
|
133
|
+
title: null,
|
|
134
|
+
url: null,
|
|
135
|
+
warnings: [],
|
|
136
|
+
dryRun,
|
|
137
|
+
config,
|
|
138
|
+
summary: message,
|
|
139
|
+
error: { code, message }
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function buildSummary(status, url) {
|
|
144
|
+
if (status === "created") {
|
|
145
|
+
return `Created pull request / merge request: ${url ?? "(no url returned)"}`;
|
|
146
|
+
}
|
|
147
|
+
if (status === "existing") {
|
|
148
|
+
return `Pull request / merge request already exists: ${url ?? "(no url returned)"}`;
|
|
149
|
+
}
|
|
150
|
+
if (status === "ready") {
|
|
151
|
+
return "Pull request / merge request content is ready; dry-run did not create it.";
|
|
152
|
+
}
|
|
153
|
+
return "Pull request / merge request creation failed.";
|
|
154
|
+
}
|
|
155
|
+
async function resolveRepositoryPath(repositoryPath) {
|
|
156
|
+
if (!repositoryPath) {
|
|
157
|
+
throw new PullRequestConfigError("--repo is required for pull-request create.");
|
|
158
|
+
}
|
|
159
|
+
const resolved = path.resolve(repositoryPath);
|
|
160
|
+
if (!fs.existsSync(resolved)) {
|
|
161
|
+
throw new PullRequestConfigError(`Repository path not found: ${repositoryPath}`);
|
|
162
|
+
}
|
|
163
|
+
if (!fs.statSync(resolved).isDirectory()) {
|
|
164
|
+
throw new PullRequestConfigError(`Repository path must be a directory: ${repositoryPath}`);
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
return await (0, git_1.resolveGitRepositoryRoot)(resolved);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
if (error instanceof git_1.GitExecutionError) {
|
|
171
|
+
throw new PullRequestConfigError(`Repository path is not inside a Git repository: ${repositoryPath}`);
|
|
172
|
+
}
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=pullRequest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pullRequest.js","sourceRoot":"","sources":["../../src/commands/pullRequest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,kEAkEC;AA/GD,4CAA8B;AAC9B,gDAAkC;AAClC,sCAA2E;AAC3E,4CAA+D;AAC/D,gCAAqE;AACrE,sCAA6D;AAC7D,gDAAoH;AACpH,kDAA4D;AAE/C,QAAA,iBAAiB,GAAG,CAAC,CAAC;AACtB,QAAA,sBAAsB,GAAG,CAAC,CAAC;AAC3B,QAAA,uBAAuB,GAAG,CAAC,CAAC;AA2BzC,MAAM,sBAAuB,SAAQ,KAAK;IACxC,YAAmB,OAAe;QAChC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAEM,KAAK,UAAU,2BAA2B,CAC/C,IAAuB,EACvB,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;IACjE,MAAM,cAAc,GAAG,IAAA,wBAAe,EACpC,IAAA,yBAAgB,EAAC;QACf,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,EAAE;QACP,QAAQ,EAAE,KAAK;QACf,iBAAiB,EAAE,KAAK;KACzB,CAAC,CAAC,MAAM,CACV,CAAC;IAEF,IAAI,QAA6C,CAAC;IAClD,IAAI,CAAC;QACH,QAAQ,GAAG,IAAA,yBAAgB,EAAC;YAC1B,IAAI,EAAE,UAAU;YAChB,GAAG;YACH,QAAQ,EAAE,IAAI;YACd,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QACH,gCAAgC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,gBAAgB,CAAC,cAAc,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;IAChI,CAAC;IAED,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,qBAAqB,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpF,MAAM,MAAM,GAAG,MAAM,IAAA,gDAAkC,EAAC;YACtD,cAAc;YACd,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,MAAM,EAAE,IAAA,4DAA8C,EAAC,QAAQ,CAAC,MAAM,CAAC;YACvE,MAAM;SACP,CAAC,CAAC;QAEH,OAAO;YACL,QAAQ,EAAE,yBAAiB;YAC3B,OAAO,EAAE;gBACP,aAAa,EAAE,2CAA+B;gBAC9C,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,qBAAqB;gBAC9B,cAAc;gBACd,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,MAAM;gBACN,MAAM,EAAE,IAAA,wBAAe,EAAC,QAAQ,CAAC,MAAM,CAAC;gBACxC,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;aACjD;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,KAAK,YAAY,sBAAsB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe,CAAC;QACxF,MAAM,OAAO,GAAG,sBAAsB,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAChH,OAAO,gBAAgB,CACrB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAA,wBAAe,EAAC,QAAQ,CAAC,MAAM,CAAC,CACjC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,MAAiB,EAAE,OAAe;IAChE,OAAO,IAAA,4BAAmB,EAAC,OAAO,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,gCAAgC,CAAC,MAAiB;IACzD,IAAA,0BAAiB,EAAC,MAAM,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,MAAM,IAAI,sBAAsB,CAAC,0DAA0D,CAAC,CAAC;IAC/F,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,sBAAsB,CAAC,mEAAmE,CAAC,CAAC;IACxG,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,IAAsC,EACtC,OAAe,EACf,QAAoD,EACpD,MAAe,EACf,MAAuB;IAEvB,OAAO;QACL,QAAQ,EAAE,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,8BAAsB,CAAC,CAAC,CAAC,+BAAuB;QACpF,OAAO,EAAE;YACP,aAAa,EAAE,2CAA+B;YAC9C,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,qBAAqB;YAC9B,cAAc,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI;YACvG,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;YAClB,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,YAAY,IAAI,IAAI;YAC/D,KAAK,EAAE,IAAI;YACX,GAAG,EAAE,IAAI;YACT,QAAQ,EAAE,EAAE;YACZ,MAAM;YACN,MAAM;YACN,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE;SACzB;KACF,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,MAAyC,EAAE,GAAkB;IACjF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,yCAAyC,GAAG,IAAI,mBAAmB,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO,gDAAgD,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACtF,CAAC;IACD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,OAAO,2EAA2E,CAAC;IACrF,CAAC;IACD,OAAO,+CAA+C,CAAC;AACzD,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,cAAkC;IACrE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,sBAAsB,CAAC,6CAA6C,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,sBAAsB,CAAC,8BAA8B,cAAc,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,sBAAsB,CAAC,wCAAwC,cAAc,EAAE,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,IAAA,8BAAwB,EAAC,QAAQ,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,uBAAiB,EAAE,CAAC;YACvC,MAAM,IAAI,sBAAsB,CAAC,mDAAmD,cAAc,EAAE,CAAC,CAAC;QACxG,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -74,6 +74,7 @@ function buildGenerationInput(input, userDraft) {
|
|
|
74
74
|
diff: input.diff,
|
|
75
75
|
changedFiles: input.changedFiles,
|
|
76
76
|
language: input.config.commitMessage.language,
|
|
77
|
+
structure: input.config.commitMessage.structure,
|
|
77
78
|
protocol: input.config.commitMessage.validation.protocol,
|
|
78
79
|
...(userDraft ? { userDraft } : {})
|
|
79
80
|
};
|
|
@@ -107,7 +108,7 @@ function tryValidateGeneratedCommitMessage(rawCommitMessage, config, branchName)
|
|
|
107
108
|
return {
|
|
108
109
|
ok: true,
|
|
109
110
|
message: (0, protocol_1.validateAndFinalizeCommitMessage)({
|
|
110
|
-
rawCommitMessage
|
|
111
|
+
rawCommitMessage,
|
|
111
112
|
config,
|
|
112
113
|
branchName
|
|
113
114
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commitMessage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAkBA,oDA+CC;AAhED,kEAA6E;AAC7E,iDAAiE;AACjE,qDAA+E;AAG/E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commitMessage/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,11 +4,12 @@ exports.buildCommitMessageMessages = buildCommitMessageMessages;
|
|
|
4
4
|
exports.buildCommitMessageRepairMessages = buildCommitMessageRepairMessages;
|
|
5
5
|
function buildCommitMessageMessages(input, options = {}) {
|
|
6
6
|
const protocolLabel = formatCommitMessageProtocolLabel(input.protocol);
|
|
7
|
+
const structure = input.structure ?? "subjectOnly";
|
|
7
8
|
return [
|
|
8
9
|
{
|
|
9
10
|
role: "system",
|
|
10
11
|
content: [
|
|
11
|
-
|
|
12
|
+
buildCommitMessageSystemIntro(structure),
|
|
12
13
|
"You must obey the requested commit message language.",
|
|
13
14
|
protocolLabel === null
|
|
14
15
|
? "No built-in commit-message protocol is enforced."
|
|
@@ -24,8 +25,9 @@ function buildCommitMessageMessages(input, options = {}) {
|
|
|
24
25
|
`Repository: ${input.repositoryPath}`,
|
|
25
26
|
`Branch: ${input.branchName ?? "(unknown)"}`,
|
|
26
27
|
`Language: ${input.language}`,
|
|
28
|
+
`Commit message structure: ${structure}`,
|
|
27
29
|
`Commit message protocol: ${protocolLabel ?? "none"}`,
|
|
28
|
-
...(buildCommitMessageOutputRules(input.protocol)),
|
|
30
|
+
...(buildCommitMessageOutputRules(input.protocol, structure)),
|
|
29
31
|
`Changed files (${input.changedFiles.length}):`,
|
|
30
32
|
...input.changedFiles.map((file) => `- ${file}`),
|
|
31
33
|
"",
|
|
@@ -44,15 +46,16 @@ function buildCommitMessageMessages(input, options = {}) {
|
|
|
44
46
|
}
|
|
45
47
|
function buildCommitMessageRepairMessages(input, options = {}) {
|
|
46
48
|
const protocolLabel = formatCommitMessageProtocolLabel(input.generationInput.protocol);
|
|
49
|
+
const structure = input.generationInput.structure ?? "subjectOnly";
|
|
47
50
|
return [
|
|
48
51
|
{
|
|
49
52
|
role: "system",
|
|
50
53
|
content: [
|
|
51
|
-
|
|
54
|
+
buildCommitMessageRepairSystemIntro(structure),
|
|
52
55
|
"You must obey the requested commit message language.",
|
|
53
56
|
protocolLabel === null
|
|
54
57
|
? "No built-in commit-message protocol is enforced."
|
|
55
|
-
: `You must repair
|
|
58
|
+
: `You must repair the subject into valid ${protocolLabel} format.`,
|
|
56
59
|
"Return plain text only.",
|
|
57
60
|
"Do not return explanations or JSON.",
|
|
58
61
|
...(options.promptAugmentation?.length ? ["", ...options.promptAugmentation] : [])
|
|
@@ -64,8 +67,9 @@ function buildCommitMessageRepairMessages(input, options = {}) {
|
|
|
64
67
|
`Repository: ${input.generationInput.repositoryPath}`,
|
|
65
68
|
`Branch: ${input.generationInput.branchName ?? "(unknown)"}`,
|
|
66
69
|
`Language: ${input.generationInput.language}`,
|
|
70
|
+
`Commit message structure: ${structure}`,
|
|
67
71
|
`Commit message protocol: ${protocolLabel ?? "none"}`,
|
|
68
|
-
...(buildCommitMessageOutputRules(input.generationInput.protocol)),
|
|
72
|
+
...(buildCommitMessageOutputRules(input.generationInput.protocol, structure)),
|
|
69
73
|
"",
|
|
70
74
|
"Invalid previous response:",
|
|
71
75
|
input.invalidResponse,
|
|
@@ -76,17 +80,18 @@ function buildCommitMessageRepairMessages(input, options = {}) {
|
|
|
76
80
|
}
|
|
77
81
|
];
|
|
78
82
|
}
|
|
79
|
-
function buildCommitMessageOutputRules(protocol) {
|
|
83
|
+
function buildCommitMessageOutputRules(protocol, structure) {
|
|
84
|
+
const structureRules = buildCommitMessageStructureRules(structure);
|
|
80
85
|
if (protocol === "gitmoji") {
|
|
81
|
-
return ["
|
|
86
|
+
return [...structureRules, "Protocol rule: the subject must be a single-line Gitmoji subject."];
|
|
82
87
|
}
|
|
83
88
|
if (protocol === "semantic") {
|
|
84
|
-
return ["
|
|
89
|
+
return [...structureRules, "Protocol rule: the subject must be a single-line Semantic Commits subject."];
|
|
85
90
|
}
|
|
86
91
|
if (protocol === "conventional") {
|
|
87
|
-
return ["
|
|
92
|
+
return [...structureRules, "Protocol rule: the subject must be a single-line Conventional Commits subject."];
|
|
88
93
|
}
|
|
89
|
-
return ["
|
|
94
|
+
return [...structureRules, "Protocol rule: no built-in subject protocol is enforced."];
|
|
90
95
|
}
|
|
91
96
|
function formatCommitMessageProtocolLabel(protocol) {
|
|
92
97
|
if (protocol === "gitmoji") {
|
|
@@ -100,4 +105,47 @@ function formatCommitMessageProtocolLabel(protocol) {
|
|
|
100
105
|
}
|
|
101
106
|
return null;
|
|
102
107
|
}
|
|
108
|
+
function buildCommitMessageSystemIntro(structure) {
|
|
109
|
+
if (structure === "subjectOnly") {
|
|
110
|
+
return "You generate a single-line git commit message.";
|
|
111
|
+
}
|
|
112
|
+
if (structure === "subjectBody") {
|
|
113
|
+
return "You generate a git commit message with a subject and optional body.";
|
|
114
|
+
}
|
|
115
|
+
return "You generate a git commit message with a subject, optional body, and optional footer.";
|
|
116
|
+
}
|
|
117
|
+
function buildCommitMessageRepairSystemIntro(structure) {
|
|
118
|
+
if (structure === "subjectOnly") {
|
|
119
|
+
return "You are repairing an invalid single-line git commit message.";
|
|
120
|
+
}
|
|
121
|
+
if (structure === "subjectBody") {
|
|
122
|
+
return "You are repairing an invalid git commit message with a subject and optional body.";
|
|
123
|
+
}
|
|
124
|
+
return "You are repairing an invalid git commit message with a subject, optional body, and optional footer.";
|
|
125
|
+
}
|
|
126
|
+
function buildCommitMessageStructureRules(structure) {
|
|
127
|
+
if (structure === "subjectOnly") {
|
|
128
|
+
return [
|
|
129
|
+
"Output rule: return exactly one git commit subject line only.",
|
|
130
|
+
"If the staged diff is ambiguous, choose the single best subject and return only that one line."
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
if (structure === "subjectBody") {
|
|
134
|
+
return [
|
|
135
|
+
"Output rule: return a git commit message with this maximum structure: subject plus optional body.",
|
|
136
|
+
"The subject must be the first line.",
|
|
137
|
+
"Body is optional; if the staged diff is simple, return only the subject.",
|
|
138
|
+
"If you include a body, separate it from the subject with one blank line.",
|
|
139
|
+
"Do not include footer or trailer lines."
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
return [
|
|
143
|
+
"Output rule: return a git commit message with this maximum structure: subject plus optional body plus optional footer.",
|
|
144
|
+
"The subject must be the first line.",
|
|
145
|
+
"Body and footer are optional; if the staged diff is simple, return only the subject.",
|
|
146
|
+
"If you include body or footer content, separate each section with one blank line.",
|
|
147
|
+
"Include footer/trailer lines only when there is explicit evidence for them, such as breaking changes, issue references, co-authors, or sign-offs.",
|
|
148
|
+
"Footer/trailer lines must use Git trailer or Conventional Commits footer style, such as `Refs: #123`, `Signed-off-by: Name <email>`, or `BREAKING CHANGE: description`."
|
|
149
|
+
];
|
|
150
|
+
}
|
|
103
151
|
//# sourceMappingURL=prompt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/commitMessage/prompt.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/commitMessage/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CommitMessageFlowError = void 0;
|
|
4
4
|
exports.normalizeCommitMessage = normalizeCommitMessage;
|
|
5
|
+
exports.normalizeCommitMessageForStructure = normalizeCommitMessageForStructure;
|
|
5
6
|
exports.ensureTicketIdFromBranchIfMissing = ensureTicketIdFromBranchIfMissing;
|
|
6
7
|
exports.validateAndFinalizeCommitMessage = validateAndFinalizeCommitMessage;
|
|
7
8
|
exports.validateLanguageText = validateLanguageText;
|
|
@@ -22,6 +23,7 @@ const conventionalTypes = new Set([
|
|
|
22
23
|
]);
|
|
23
24
|
const typedCommitSubjectPattern = /^([a-z]+)(\([^)]+\))?(!)?: (.+)$/;
|
|
24
25
|
const gitmojiSubjectPattern = /^\S+\s+(.+)$/u;
|
|
26
|
+
const footerLinePattern = /^(?:BREAKING CHANGE|[A-Za-z0-9-]+):\s+\S.*$/;
|
|
25
27
|
const cjkPattern = /[\u3400-\u9fff]/;
|
|
26
28
|
const japaneseKanaPattern = /[\u3040-\u30FF\u31F0-\u31FF\uFF66-\uFF9D]/;
|
|
27
29
|
const japanesePattern = /[\u3040-\u30FF\u31F0-\u31FF\u3400-\u9fff\uFF66-\uFF9D]/;
|
|
@@ -39,7 +41,12 @@ const ticketLikeIdPatterns = [
|
|
|
39
41
|
const leadingTicketLikeIdPattern = /^(?:[A-Z][A-Z0-9]+-\d+|#\d+|(?:task|bugfix|bug|issue|story|feature|hotfix|ticket)-\d+)\s+/i;
|
|
40
42
|
const branchTicketLikeIdPattern = /[A-Za-z][A-Za-z0-9]+-\d+/g;
|
|
41
43
|
const outputLanguageDefinitions = {
|
|
42
|
-
zh: {
|
|
44
|
+
"zh-cn": {
|
|
45
|
+
validationMode: "script",
|
|
46
|
+
requiredPattern: cjkPattern,
|
|
47
|
+
requiredDescription: "Chinese text"
|
|
48
|
+
},
|
|
49
|
+
"zh-tw": {
|
|
43
50
|
validationMode: "script",
|
|
44
51
|
requiredPattern: cjkPattern,
|
|
45
52
|
requiredDescription: "Chinese text"
|
|
@@ -111,36 +118,54 @@ function normalizeCommitMessage(raw) {
|
|
|
111
118
|
.split("\n")[0]
|
|
112
119
|
.trim();
|
|
113
120
|
}
|
|
121
|
+
function normalizeCommitMessageForStructure(raw, structure) {
|
|
122
|
+
const sections = parseCommitMessageSections(raw);
|
|
123
|
+
return structure === "subjectOnly" ? sections.subject : sections.normalized;
|
|
124
|
+
}
|
|
114
125
|
function ensureTicketIdFromBranchIfMissing(commitMessage, branchName) {
|
|
115
126
|
const subject = normalizeCommitMessage(commitMessage);
|
|
116
127
|
if (!subject || !branchName?.trim()) {
|
|
117
|
-
return
|
|
128
|
+
return normalizeCommitMessageForStructure(commitMessage, "subjectBodyFooter");
|
|
118
129
|
}
|
|
119
130
|
if (containsTicketLikeId(subject)) {
|
|
120
|
-
return
|
|
131
|
+
return normalizeCommitMessageForStructure(commitMessage, "subjectBodyFooter");
|
|
121
132
|
}
|
|
122
133
|
const ticket = extractTicketLikeIdFromBranch(branchName);
|
|
123
134
|
if (!ticket) {
|
|
124
|
-
return
|
|
135
|
+
return normalizeCommitMessageForStructure(commitMessage, "subjectBodyFooter");
|
|
125
136
|
}
|
|
137
|
+
let updatedSubject;
|
|
126
138
|
const typedMatch = subject.match(typedCommitSubjectPattern);
|
|
127
139
|
if (typedMatch) {
|
|
128
140
|
const type = typedMatch[1] ?? "";
|
|
129
141
|
const scope = typedMatch[2] ?? "";
|
|
130
142
|
const breaking = typedMatch[3] ?? "";
|
|
131
143
|
const summary = (typedMatch[4] ?? "").trim();
|
|
132
|
-
|
|
144
|
+
updatedSubject = `${type}${scope}${breaking}: ${ticket} ${summary}`;
|
|
133
145
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
else {
|
|
147
|
+
const gitmojiMatch = subject.match(gitmojiSubjectPattern);
|
|
148
|
+
if (gitmojiMatch) {
|
|
149
|
+
const emoji = subject.split(/\s+/u)[0] ?? "";
|
|
150
|
+
const summary = gitmojiMatch[1]?.trim() ?? "";
|
|
151
|
+
updatedSubject = `${emoji} ${ticket} ${summary}`.trim();
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
updatedSubject = `${ticket} ${subject}`;
|
|
155
|
+
}
|
|
139
156
|
}
|
|
140
|
-
return
|
|
157
|
+
return replaceCommitMessageSubject(commitMessage, updatedSubject);
|
|
141
158
|
}
|
|
142
159
|
function validateAndFinalizeCommitMessage(input) {
|
|
143
|
-
|
|
160
|
+
const structure = input.config.commitMessage.structure;
|
|
161
|
+
const structureIssues = validateCommitMessageStructure(input.rawCommitMessage, structure);
|
|
162
|
+
if (structureIssues.length > 0) {
|
|
163
|
+
if (structureIssues.includes("response must not be empty")) {
|
|
164
|
+
throw new CommitMessageFlowError("COMMIT_MESSAGE_REQUIRED", "Commit message must not be empty.");
|
|
165
|
+
}
|
|
166
|
+
throw new CommitMessageFlowError("COMMIT_MESSAGE_INVALID", `Commit message validation failed: ${structureIssues.join("; ")}`);
|
|
167
|
+
}
|
|
168
|
+
let commitMessage = normalizeCommitMessageForStructure(input.rawCommitMessage, structure);
|
|
144
169
|
if (!commitMessage) {
|
|
145
170
|
throw new CommitMessageFlowError("COMMIT_MESSAGE_REQUIRED", "Commit message must not be empty.");
|
|
146
171
|
}
|
|
@@ -149,16 +174,17 @@ function validateAndFinalizeCommitMessage(input) {
|
|
|
149
174
|
}
|
|
150
175
|
const issues = [];
|
|
151
176
|
const protocol = input.config.commitMessage.validation.protocol;
|
|
177
|
+
const subject = normalizeCommitMessage(commitMessage);
|
|
152
178
|
if (protocol !== "none") {
|
|
153
|
-
issues.push(...validateCommitMessageProtocol(
|
|
179
|
+
issues.push(...validateCommitMessageProtocol(subject, input.config.commitMessage.language, protocol));
|
|
154
180
|
}
|
|
155
|
-
if (input.config.commitMessage.validation.requireTicketIdInMessage && !containsTicketLikeId(
|
|
181
|
+
if (input.config.commitMessage.validation.requireTicketIdInMessage && !containsTicketLikeId(subject)) {
|
|
156
182
|
issues.push("commit message must contain a ticket-like ID");
|
|
157
183
|
}
|
|
158
184
|
if (input.config.commitMessage.validation.pattern) {
|
|
159
185
|
const regex = new RegExp(input.config.commitMessage.validation.pattern);
|
|
160
|
-
if (!regex.test(
|
|
161
|
-
issues.push("commit message does not match the configured validation pattern");
|
|
186
|
+
if (!regex.test(subject)) {
|
|
187
|
+
issues.push("commit message subject does not match the configured validation pattern");
|
|
162
188
|
}
|
|
163
189
|
}
|
|
164
190
|
if (issues.length > 0) {
|
|
@@ -196,6 +222,34 @@ function containsTicketLikeId(raw) {
|
|
|
196
222
|
const subject = normalizeCommitMessage(raw);
|
|
197
223
|
return subject.length > 0 && ticketLikeIdPatterns.some((pattern) => pattern.test(subject));
|
|
198
224
|
}
|
|
225
|
+
function validateCommitMessageStructure(raw, structure) {
|
|
226
|
+
const issues = [];
|
|
227
|
+
const trimmed = raw.trim();
|
|
228
|
+
if (!trimmed) {
|
|
229
|
+
return ["response must not be empty"];
|
|
230
|
+
}
|
|
231
|
+
if (trimmed.includes("```")) {
|
|
232
|
+
issues.push("response must not use markdown code fences");
|
|
233
|
+
}
|
|
234
|
+
const sections = parseCommitMessageSections(raw);
|
|
235
|
+
issues.push(...sections.issues);
|
|
236
|
+
if (!sections.subject) {
|
|
237
|
+
issues.push("response must contain a non-empty subject after normalization");
|
|
238
|
+
}
|
|
239
|
+
if (structure === "subjectOnly") {
|
|
240
|
+
const nonEmptyLines = trimmed
|
|
241
|
+
.split(/\r?\n/)
|
|
242
|
+
.map((line) => line.trim())
|
|
243
|
+
.filter((line) => line.length > 0);
|
|
244
|
+
if (nonEmptyLines.length !== 1) {
|
|
245
|
+
issues.push("response must contain exactly one non-empty line");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (structure === "subjectBody" && sections.hasFooter) {
|
|
249
|
+
issues.push("response must not include a footer when commitMessage.structure is subjectBody");
|
|
250
|
+
}
|
|
251
|
+
return issues;
|
|
252
|
+
}
|
|
199
253
|
function validateCommitMessageProtocol(commitMessage, language, protocol) {
|
|
200
254
|
if (protocol === "gitmoji") {
|
|
201
255
|
return validateGitmojiSubject(commitMessage, language);
|
|
@@ -237,4 +291,102 @@ function validateGitmojiSubject(subject, language) {
|
|
|
237
291
|
const summaryWithoutLeadingTicket = summary.replace(leadingTicketLikeIdPattern, "").trim() || summary;
|
|
238
292
|
return validateLanguageText(summaryWithoutLeadingTicket, language, "summary");
|
|
239
293
|
}
|
|
294
|
+
function parseCommitMessageSections(raw) {
|
|
295
|
+
const trimmed = raw.trim();
|
|
296
|
+
if (!trimmed) {
|
|
297
|
+
return {
|
|
298
|
+
subject: "",
|
|
299
|
+
body: "",
|
|
300
|
+
footer: "",
|
|
301
|
+
hasFooter: false,
|
|
302
|
+
normalized: "",
|
|
303
|
+
issues: []
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
const lines = trimmed.split(/\r?\n/).map((line) => line.trimEnd());
|
|
307
|
+
const subjectIndex = lines.findIndex((line) => line.trim().length > 0);
|
|
308
|
+
if (subjectIndex === -1) {
|
|
309
|
+
return {
|
|
310
|
+
subject: "",
|
|
311
|
+
body: "",
|
|
312
|
+
footer: "",
|
|
313
|
+
hasFooter: false,
|
|
314
|
+
normalized: "",
|
|
315
|
+
issues: []
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
const subject = normalizeCommitMessage(lines[subjectIndex] ?? "");
|
|
319
|
+
const linesAfterSubject = lines.slice(subjectIndex + 1);
|
|
320
|
+
const hasContentAfterSubject = linesAfterSubject.some((line) => line.trim().length > 0);
|
|
321
|
+
const issues = [];
|
|
322
|
+
if (!hasContentAfterSubject) {
|
|
323
|
+
return {
|
|
324
|
+
subject,
|
|
325
|
+
body: "",
|
|
326
|
+
footer: "",
|
|
327
|
+
hasFooter: false,
|
|
328
|
+
normalized: subject,
|
|
329
|
+
issues
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
if ((linesAfterSubject[0] ?? "").trim().length > 0) {
|
|
333
|
+
issues.push("body or footer must be separated from the subject by a blank line");
|
|
334
|
+
}
|
|
335
|
+
const contentLines = trimBlankLines(linesAfterSubject);
|
|
336
|
+
const paragraphs = splitParagraphs(contentLines);
|
|
337
|
+
const footerParagraph = paragraphs.length > 0 && isFooterParagraph(paragraphs[paragraphs.length - 1] ?? [])
|
|
338
|
+
? paragraphs[paragraphs.length - 1]
|
|
339
|
+
: undefined;
|
|
340
|
+
const bodyParagraphs = footerParagraph ? paragraphs.slice(0, -1) : paragraphs;
|
|
341
|
+
const body = bodyParagraphs
|
|
342
|
+
.map((paragraph) => paragraph.join("\n").trim())
|
|
343
|
+
.filter(Boolean)
|
|
344
|
+
.join("\n\n");
|
|
345
|
+
const footer = footerParagraph ? footerParagraph.join("\n").trim() : "";
|
|
346
|
+
const normalized = [subject, body, footer].filter((section) => section.length > 0).join("\n\n");
|
|
347
|
+
return {
|
|
348
|
+
subject,
|
|
349
|
+
body,
|
|
350
|
+
footer,
|
|
351
|
+
hasFooter: footer.length > 0,
|
|
352
|
+
normalized,
|
|
353
|
+
issues
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
function replaceCommitMessageSubject(raw, subject) {
|
|
357
|
+
const sections = parseCommitMessageSections(raw);
|
|
358
|
+
return [subject, sections.body, sections.footer].filter((section) => section.length > 0).join("\n\n");
|
|
359
|
+
}
|
|
360
|
+
function trimBlankLines(lines) {
|
|
361
|
+
let start = 0;
|
|
362
|
+
let end = lines.length;
|
|
363
|
+
while (start < end && lines[start]?.trim().length === 0) {
|
|
364
|
+
start += 1;
|
|
365
|
+
}
|
|
366
|
+
while (end > start && lines[end - 1]?.trim().length === 0) {
|
|
367
|
+
end -= 1;
|
|
368
|
+
}
|
|
369
|
+
return lines.slice(start, end);
|
|
370
|
+
}
|
|
371
|
+
function splitParagraphs(lines) {
|
|
372
|
+
const paragraphs = [];
|
|
373
|
+
let current = [];
|
|
374
|
+
for (const line of lines) {
|
|
375
|
+
if (line.trim().length === 0) {
|
|
376
|
+
if (current.length > 0) {
|
|
377
|
+
paragraphs.push(current);
|
|
378
|
+
current = [];
|
|
379
|
+
}
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
current.push(line);
|
|
383
|
+
}
|
|
384
|
+
if (current.length > 0) {
|
|
385
|
+
paragraphs.push(current);
|
|
386
|
+
}
|
|
387
|
+
return paragraphs;
|
|
388
|
+
}
|
|
389
|
+
function isFooterParagraph(lines) {
|
|
390
|
+
return lines.length > 0 && lines.every((line) => footerLinePattern.test(line.trim()));
|
|
391
|
+
}
|
|
240
392
|
//# sourceMappingURL=protocol.js.map
|