@snelusha/noto 1.1.8 → 1.2.1
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/README.md +3 -9
- package/dist/index.js +97 -42
- package/package.json +5 -6
package/README.md
CHANGED
|
@@ -98,16 +98,10 @@ noto --type # or simply noto -t
|
|
|
98
98
|
noto --type chore # or simply noto -t chore
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
Combine all flags to specify the commit type, and apply the generated commit message in one go:
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
noto --
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Combine all flags to specify the commit type, open the interactive editor, and apply the generated commit message in one go:
|
|
108
|
-
|
|
109
|
-
```bash
|
|
110
|
-
noto --edit --type feat --apply # or simply: noto -e -t feat -a
|
|
104
|
+
noto --type feat --apply # or simply: noto -t feat -a
|
|
111
105
|
```
|
|
112
106
|
|
|
113
107
|
This command will generate a commit message for a "feat" commit, let you refine it interactively, and then apply it directly to your current commit.
|
|
@@ -160,7 +154,7 @@ noto branch delete --force # simply: noto branch delete -f
|
|
|
160
154
|
|
|
161
155
|
## Pro Tips
|
|
162
156
|
|
|
163
|
-
- 🚀 Get fast commits on the fly with `noto -
|
|
157
|
+
- 🚀 Get fast commits on the fly with `noto -a` to streamline your workflow!
|
|
164
158
|
|
|
165
159
|
## Contributing
|
|
166
160
|
|
package/dist/index.js
CHANGED
|
@@ -65,7 +65,8 @@ var AvailableModelsSchema = z.enum([
|
|
|
65
65
|
"gemini-2.0-flash-001",
|
|
66
66
|
"gemini-2.0-flash-exp",
|
|
67
67
|
"gemini-2.0-flash-lite-preview-02-05",
|
|
68
|
-
"gemini-2.5-pro-exp-03-25"
|
|
68
|
+
"gemini-2.5-pro-exp-03-25",
|
|
69
|
+
"gemini-2.5-flash-preview-04-17"
|
|
69
70
|
]);
|
|
70
71
|
|
|
71
72
|
// src/utils/storage.ts
|
|
@@ -296,7 +297,8 @@ var models = {
|
|
|
296
297
|
"gemini-2.0-flash-lite-preview-02-05": google(
|
|
297
298
|
"gemini-2.0-flash-lite-preview-02-05"
|
|
298
299
|
),
|
|
299
|
-
"gemini-2.5-pro-exp-03-25": google("gemini-2.5-pro-exp-03-25")
|
|
300
|
+
"gemini-2.5-pro-exp-03-25": google("gemini-2.5-pro-exp-03-25"),
|
|
301
|
+
"gemini-2.5-flash-preview-04-17": google("gemini-2.5-flash-preview-04-17")
|
|
300
302
|
};
|
|
301
303
|
var availableModels = Object.keys(models);
|
|
302
304
|
var getModel = async () => {
|
|
@@ -321,7 +323,7 @@ var getModel = async () => {
|
|
|
321
323
|
};
|
|
322
324
|
|
|
323
325
|
// src/ai/index.ts
|
|
324
|
-
var generateCommitMessage = async (diff, type) => {
|
|
326
|
+
var generateCommitMessage = async (diff, type, context) => {
|
|
325
327
|
const model2 = await getModel();
|
|
326
328
|
const { object } = await generateObject({
|
|
327
329
|
model: model2,
|
|
@@ -332,27 +334,65 @@ var generateCommitMessage = async (diff, type) => {
|
|
|
332
334
|
{
|
|
333
335
|
role: "system",
|
|
334
336
|
content: dedent3`
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
337
|
+
## Persona
|
|
338
|
+
You are a highly specialized AI assistant engineered for generating precise, standards-compliant Git commit messages. Your function is to serve as an automated tool ensuring consistency and clarity in version control history, adhering strictly to predefined formatting rules optimized for software development workflows.
|
|
339
|
+
|
|
340
|
+
## Core Objective
|
|
341
|
+
Your objective is to meticulously analyze provided code changes (diffs) and synthesize a Git commit message that strictly conforms to the specified output requirements. The focus is on accuracy, conciseness, and unwavering adherence to the format.
|
|
342
|
+
|
|
343
|
+
## Input Specification
|
|
344
|
+
The input provided by the user will be structured as follows:
|
|
345
|
+
|
|
346
|
+
1. **Optional Type Override:** A line indicating the desired commit type, formatted as:
|
|
347
|
+
\`USER_SPECIFIED_TYPE: <value>\`
|
|
348
|
+
* The \`<value>\` will either be one of the valid types (\`chore\`, \`feat\`, \`fix\`, \`docs\`, \`refactor\`, \`perf\`, \`test\) or the special keyword \`[none]\` if the user does not wish to force a specific type.
|
|
349
|
+
2. **Optional User Context:** A section providing supplementary information about the changes, formatted as:
|
|
350
|
+
\`USER_PROVIDED_CONTEXT:\`
|
|
351
|
+
\`{context_placeholder or [none]}\`
|
|
352
|
+
* This context (e.g., issue details, goal description) is optional. If provided, use it to better understand the *purpose* and *intent* behind the code changes. If not provided, the value will be \`[none]\`.
|
|
353
|
+
3. **Diff Content:** The raw diff output, typically generated by \`git diff --staged\`, encapsulated within triple backticks.
|
|
354
|
+
|
|
355
|
+
**You must parse the \`USER_SPECIFIED_TYPE:\` and \`USER_PROVIDED_CONTEXT:\` inputs before analyzing the diff.**
|
|
349
356
|
|
|
350
|
-
|
|
357
|
+
## Output Specification & Constraints (Mandatory Adherence)
|
|
358
|
+
Adherence to the following specifications is mandatory and non-negotiable. Any deviation constitutes an incorrect output.
|
|
359
|
+
|
|
360
|
+
1. **Commit Message Format:**
|
|
361
|
+
* The output MUST strictly follow the single-line format: \`<type>: <description>\`
|
|
362
|
+
* A single colon (\`:\`) followed by a single space MUST separate the \`<type>\` and \`<description>\`.
|
|
363
|
+
* Scopes within the type (e.g., \`feat(api):\`) are explicitly disallowed.
|
|
364
|
+
* Message bodies and footers are explicitly disallowed. The output MUST be exactly one line.
|
|
365
|
+
|
|
366
|
+
2. **Type (\`<type>\`) - Determination Logic:**
|
|
367
|
+
* **Priority 1: User-Specified Type:** Check the value provided on the \`USER_SPECIFIED_TYPE:\` line. If this value is exactly one of \`chore\`, \`feat\`, \`fix\`, \`docs\`, \`refactor\`, \`perf\`, \`test\`, then you **MUST** use this user-specified type.
|
|
368
|
+
* **Priority 2: Diff & Context Analysis (Default Behavior):** If the value on the \`USER_SPECIFIED_TYPE:\` line is \`[none]\` or invalid, you **MUST** select the \`<type>\` exclusively from the predefined vocabulary (\`chore\`, \`feat\`, \`fix\`, \`docs\`, \`refactor\`, \`perf\`, \`test\`). Base your selection on your analysis of the diff, **informed by the \`USER_PROVIDED_CONTEXT\`** if available, to accurately reflect the primary semantic purpose of the changes.
|
|
369
|
+
|
|
370
|
+
3. **Description (\`<description>\`):**
|
|
371
|
+
* **Tense:** MUST employ the imperative, present tense (e.g.,\`add\`, \`fix\`, \`update\`, \`implement\`, \`refactor\`, \`remove\`).
|
|
372
|
+
* **Content:** Must succinctly convey the core semantic change introduced by the diff.
|
|
373
|
+
* **Leverage Context:** If \`USER_PROVIDED_CONTEXT\` is available and not \`[none]\`, use it to **refine the description**, ensuring it reflects the *intent* and *purpose* behind the changes, while still accurately summarizing *what* was changed in the diff.
|
|
374
|
+
* **Focus:** Prioritize the most significant aspects of the change.
|
|
375
|
+
* **File Name Reference:** Inclusion of file names should be exceptional, reserved only for renaming operations or when essential for disambiguating the change's primary focus.
|
|
376
|
+
* **Case Sensitivity:** The entire output string, encompassing both \`<type>\` and \`<description>\`, MUST be rendered in lowercase.
|
|
377
|
+
* **Punctuation:** The description MUST NOT conclude with any terminal punctuation (e.g., no period/full stop).
|
|
378
|
+
* **Length Constraint:** The total character count of the generated commit message line MUST NOT exceed 72 characters. **The description must be concise enough to fit within this limit alongside the chosen type.**`
|
|
351
379
|
},
|
|
352
380
|
{
|
|
353
381
|
role: "user",
|
|
354
|
-
content: dedent3`
|
|
355
|
-
|
|
382
|
+
content: dedent3`
|
|
383
|
+
\`\`\`text
|
|
384
|
+
USER_SPECIFIED_TYPE: ${type ?? "[none]"}
|
|
385
|
+
|
|
386
|
+
USER_PROVIDED_CONTEXT:
|
|
387
|
+
${context ?? "[none]"}
|
|
388
|
+
\`\`\`
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
\`\`\`diff
|
|
393
|
+
${diff}
|
|
394
|
+
\`\`\`
|
|
395
|
+
`
|
|
356
396
|
}
|
|
357
397
|
]
|
|
358
398
|
});
|
|
@@ -384,6 +424,12 @@ var command = {
|
|
|
384
424
|
alias: "-t",
|
|
385
425
|
description: "generate commit message based on type"
|
|
386
426
|
},
|
|
427
|
+
{
|
|
428
|
+
type: String,
|
|
429
|
+
flag: "--message",
|
|
430
|
+
alias: "-m",
|
|
431
|
+
description: "provide context for the commit message"
|
|
432
|
+
},
|
|
387
433
|
{
|
|
388
434
|
type: Boolean,
|
|
389
435
|
flag: "--copy",
|
|
@@ -401,12 +447,6 @@ var command = {
|
|
|
401
447
|
flag: "--push",
|
|
402
448
|
alias: "-p",
|
|
403
449
|
description: "commit and push the changes"
|
|
404
|
-
},
|
|
405
|
-
{
|
|
406
|
-
type: Boolean,
|
|
407
|
-
flag: "--edit",
|
|
408
|
-
alias: "-e",
|
|
409
|
-
description: "edit the generated commit message"
|
|
410
450
|
}
|
|
411
451
|
],
|
|
412
452
|
execute: withAuth(
|
|
@@ -414,7 +454,6 @@ var command = {
|
|
|
414
454
|
const spin = p3.spinner();
|
|
415
455
|
try {
|
|
416
456
|
const { diff } = options;
|
|
417
|
-
const isEditMode = options["--edit"];
|
|
418
457
|
const type = options["--type"];
|
|
419
458
|
if (typeof type === "string" && !availableTypes.includes(type) || typeof type === "boolean") {
|
|
420
459
|
const type2 = await p3.select({
|
|
@@ -429,27 +468,43 @@ var command = {
|
|
|
429
468
|
} else if (typeof type === "string") {
|
|
430
469
|
options.type = type;
|
|
431
470
|
}
|
|
471
|
+
const context = options["--message"];
|
|
472
|
+
if (typeof context === "string") {
|
|
473
|
+
options.context = context;
|
|
474
|
+
} else if (typeof context === "boolean") {
|
|
475
|
+
const context2 = await p3.text({
|
|
476
|
+
message: "provide context for the commit message",
|
|
477
|
+
placeholder: "describe the changes"
|
|
478
|
+
});
|
|
479
|
+
if (p3.isCancel(context2)) {
|
|
480
|
+
p3.log.error(color3.red("nothing changed!"));
|
|
481
|
+
return await exit(1);
|
|
482
|
+
}
|
|
483
|
+
options.context = context2;
|
|
484
|
+
}
|
|
432
485
|
spin.start("generating commit message");
|
|
433
486
|
let message = null;
|
|
434
487
|
if (!await isFirstCommit()) {
|
|
435
|
-
message = await generateCommitMessage(
|
|
488
|
+
message = await generateCommitMessage(
|
|
489
|
+
diff,
|
|
490
|
+
options.type,
|
|
491
|
+
options.context
|
|
492
|
+
);
|
|
436
493
|
} else {
|
|
437
494
|
message = INIT_COMMIT_MESSAGE;
|
|
438
495
|
}
|
|
439
|
-
spin.stop(
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
return await exit(1);
|
|
449
|
-
}
|
|
450
|
-
message = editedMessage;
|
|
451
|
-
p3.log.step(color3.green(message));
|
|
496
|
+
spin.stop(color3.white(message));
|
|
497
|
+
const editedMessage = await p3.text({
|
|
498
|
+
message: "edit the generated commit message",
|
|
499
|
+
initialValue: message,
|
|
500
|
+
placeholder: message
|
|
501
|
+
});
|
|
502
|
+
if (p3.isCancel(editedMessage)) {
|
|
503
|
+
p3.log.error(color3.red("nothing changed!"));
|
|
504
|
+
return await exit(1);
|
|
452
505
|
}
|
|
506
|
+
message = editedMessage;
|
|
507
|
+
p3.log.step(color3.green(message));
|
|
453
508
|
await StorageManager.update((current2) => ({
|
|
454
509
|
...current2,
|
|
455
510
|
lastGeneratedMessage: message
|
|
@@ -1002,7 +1057,7 @@ var listCommand = () => {
|
|
|
1002
1057
|
};
|
|
1003
1058
|
|
|
1004
1059
|
// package.json
|
|
1005
|
-
var version = "1.1
|
|
1060
|
+
var version = "1.2.1";
|
|
1006
1061
|
|
|
1007
1062
|
// src/index.ts
|
|
1008
1063
|
var globalSpec = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snelusha/noto",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Generate clean commit messages in a snap! ✨",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsup --clean",
|
|
29
|
-
"dev": "tsup --clean --watch",
|
|
30
29
|
"test": "tsup --clean && vitest",
|
|
31
30
|
"clean": "git clean -xdf .cache .turbo node_modules"
|
|
32
31
|
},
|
|
@@ -42,18 +41,18 @@
|
|
|
42
41
|
"cli"
|
|
43
42
|
],
|
|
44
43
|
"devDependencies": {
|
|
45
|
-
"@types/node": "^22.15.
|
|
44
|
+
"@types/node": "^22.15.3",
|
|
46
45
|
"tsup": "^8.4.0",
|
|
47
46
|
"typescript": "^5.8.3",
|
|
48
47
|
"vitest": "^3.1.2"
|
|
49
48
|
},
|
|
50
49
|
"dependencies": {
|
|
51
|
-
"@ai-sdk/google": "^1.2.
|
|
50
|
+
"@ai-sdk/google": "^1.2.14",
|
|
52
51
|
"@clack/prompts": "^0.10.1",
|
|
53
|
-
"ai": "^4.3.
|
|
52
|
+
"ai": "^4.3.13",
|
|
54
53
|
"arg": "^5.0.2",
|
|
55
54
|
"clipboardy": "^4.0.0",
|
|
56
|
-
"dedent": "^1.
|
|
55
|
+
"dedent": "^1.6.0",
|
|
57
56
|
"picocolors": "^1.1.1",
|
|
58
57
|
"simple-git": "^3.27.0",
|
|
59
58
|
"tinyexec": "^0.3.2",
|