@snelusha/noto 1.0.0-beta.3 → 1.0.0-beta.4
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.js +176 -58
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as p6 from "@clack/prompts";
|
|
3
|
+
import color6 from "picocolors";
|
|
4
4
|
|
|
5
5
|
// src/utils/parser.ts
|
|
6
6
|
import arg from "arg";
|
|
@@ -47,7 +47,8 @@ var StorageSchema = z2.object({
|
|
|
47
47
|
llm: z2.object({
|
|
48
48
|
apiKey: z2.string().optional(),
|
|
49
49
|
model: AvailableModelsSchema.optional()
|
|
50
|
-
}).optional()
|
|
50
|
+
}).optional(),
|
|
51
|
+
lastGeneratedMessage: z2.string().optional()
|
|
51
52
|
});
|
|
52
53
|
var StorageManager = class {
|
|
53
54
|
static storagePath = resolve(
|
|
@@ -94,19 +95,25 @@ var StorageManager = class {
|
|
|
94
95
|
}
|
|
95
96
|
};
|
|
96
97
|
|
|
98
|
+
// src/utils/process.ts
|
|
99
|
+
var exit = async (code) => {
|
|
100
|
+
await new Promise((resolve2) => setTimeout(resolve2, 1));
|
|
101
|
+
console.log();
|
|
102
|
+
process.exit(code);
|
|
103
|
+
};
|
|
104
|
+
|
|
97
105
|
// src/middleware/auth.ts
|
|
98
|
-
var withAuth = (fn) => {
|
|
99
|
-
return async (
|
|
106
|
+
var withAuth = (fn, options = {}) => {
|
|
107
|
+
return async (opts) => {
|
|
100
108
|
const storage = await StorageManager.get();
|
|
101
|
-
if (!storage.llm?.apiKey) {
|
|
109
|
+
if (!storage.llm?.apiKey && !options.silent) {
|
|
102
110
|
p.log.error(
|
|
103
111
|
dedent`${color.red("noto api key is missing.")}
|
|
104
112
|
${color.dim(`run ${color.cyan("`noto config key`")} to set it up.`)}`
|
|
105
113
|
);
|
|
106
|
-
|
|
107
|
-
process.exit(1);
|
|
114
|
+
return await exit(1);
|
|
108
115
|
}
|
|
109
|
-
return fn(
|
|
116
|
+
return fn(opts);
|
|
110
117
|
};
|
|
111
118
|
};
|
|
112
119
|
|
|
@@ -140,28 +147,27 @@ var commit = async (message) => {
|
|
|
140
147
|
};
|
|
141
148
|
|
|
142
149
|
// src/middleware/git.ts
|
|
143
|
-
var withRepository = (fn) => {
|
|
144
|
-
return async (
|
|
150
|
+
var withRepository = (fn, options = {}) => {
|
|
151
|
+
return async (opts) => {
|
|
145
152
|
const isRepo = await isGitRepository();
|
|
146
|
-
if (!isRepo) {
|
|
153
|
+
if (!isRepo && !options.silent) {
|
|
147
154
|
p2.log.error(
|
|
148
155
|
dedent2`${color2.red("no git repository found in cwd.")}
|
|
149
156
|
${color2.dim(`run ${color2.cyan("`git init`")} to initialize a new repository.`)}`
|
|
150
157
|
);
|
|
151
|
-
|
|
152
|
-
process.exit(1);
|
|
158
|
+
return await exit(1);
|
|
153
159
|
}
|
|
160
|
+
opts.isRepo = isRepo;
|
|
154
161
|
const diff = await getStagedDiff();
|
|
155
|
-
if (!diff) {
|
|
162
|
+
if (!diff && !options.silent) {
|
|
156
163
|
p2.log.error(
|
|
157
164
|
dedent2`${color2.red("no staged changes found.")}
|
|
158
165
|
${color2.dim(`run ${color2.cyan("`git add <file>`")} or ${color2.cyan("`git add .`")} to stage changes.`)}`
|
|
159
166
|
);
|
|
160
|
-
|
|
161
|
-
process.exit(1);
|
|
167
|
+
return await exit(1);
|
|
162
168
|
}
|
|
163
|
-
|
|
164
|
-
return fn(
|
|
169
|
+
opts.diff = diff;
|
|
170
|
+
return fn(opts);
|
|
165
171
|
};
|
|
166
172
|
};
|
|
167
173
|
|
|
@@ -265,6 +271,12 @@ var command = {
|
|
|
265
271
|
flag: "--apply",
|
|
266
272
|
alias: "-a",
|
|
267
273
|
description: "commit the generated message directly"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
type: Boolean,
|
|
277
|
+
flag: "--edit",
|
|
278
|
+
alias: "-e",
|
|
279
|
+
description: "edit the generated commit message"
|
|
268
280
|
}
|
|
269
281
|
],
|
|
270
282
|
execute: withAuth(
|
|
@@ -272,9 +284,27 @@ var command = {
|
|
|
272
284
|
const spin = p3.spinner();
|
|
273
285
|
try {
|
|
274
286
|
const { diff } = options;
|
|
287
|
+
const isEditMode = options["--edit"];
|
|
275
288
|
spin.start("generating commit message");
|
|
276
|
-
|
|
277
|
-
spin.stop(color3.green(message));
|
|
289
|
+
let message = await generateCommitMessage(diff);
|
|
290
|
+
spin.stop(isEditMode ? color3.white(message) : color3.green(message));
|
|
291
|
+
if (isEditMode) {
|
|
292
|
+
const editedMessage = await p3.text({
|
|
293
|
+
message: "edit the generated commit message",
|
|
294
|
+
initialValue: message,
|
|
295
|
+
placeholder: message
|
|
296
|
+
});
|
|
297
|
+
if (p3.isCancel(editedMessage)) {
|
|
298
|
+
p3.log.error(color3.red("nothing changed!"));
|
|
299
|
+
return await exit(1);
|
|
300
|
+
}
|
|
301
|
+
message = editedMessage;
|
|
302
|
+
p3.log.step(color3.green(message));
|
|
303
|
+
}
|
|
304
|
+
await StorageManager.update((current) => ({
|
|
305
|
+
...current,
|
|
306
|
+
lastGeneratedMessage: message
|
|
307
|
+
}));
|
|
278
308
|
if (options["--copy"]) {
|
|
279
309
|
clipboard.writeSync(message);
|
|
280
310
|
p3.log.step(color3.dim("copied commit message to clipboard"));
|
|
@@ -287,44 +317,135 @@ var command = {
|
|
|
287
317
|
p3.log.error(color3.red("failed to commit changes"));
|
|
288
318
|
}
|
|
289
319
|
}
|
|
320
|
+
process.stdout.write("\n");
|
|
290
321
|
} catch {
|
|
291
322
|
spin.stop(color3.red("failed to generate commit message"), 1);
|
|
292
|
-
|
|
293
|
-
} finally {
|
|
294
|
-
process.stdout.write("\n");
|
|
323
|
+
return await exit(1);
|
|
295
324
|
}
|
|
296
325
|
})
|
|
297
326
|
)
|
|
298
327
|
};
|
|
299
328
|
var noto_default = command;
|
|
300
329
|
|
|
301
|
-
// src/commands/
|
|
330
|
+
// src/commands/prev.ts
|
|
302
331
|
import * as p4 from "@clack/prompts";
|
|
303
332
|
import color4 from "picocolors";
|
|
333
|
+
import dedent4 from "dedent";
|
|
334
|
+
import clipboard2 from "clipboardy";
|
|
335
|
+
var command2 = {
|
|
336
|
+
name: "prev",
|
|
337
|
+
description: "access the last generated commit message",
|
|
338
|
+
usage: "noto prev [options]",
|
|
339
|
+
options: [
|
|
340
|
+
{
|
|
341
|
+
type: Boolean,
|
|
342
|
+
flag: "--copy",
|
|
343
|
+
alias: "-c",
|
|
344
|
+
description: "copy the last generated commit message to clipboard"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
type: Boolean,
|
|
348
|
+
flag: "--apply",
|
|
349
|
+
alias: "-a",
|
|
350
|
+
description: "commit the last generated message directly"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
type: Boolean,
|
|
354
|
+
flag: "--edit",
|
|
355
|
+
alias: "-e",
|
|
356
|
+
description: "edit the last generated commit message"
|
|
357
|
+
}
|
|
358
|
+
],
|
|
359
|
+
execute: withAuth(
|
|
360
|
+
withRepository(
|
|
361
|
+
async (options) => {
|
|
362
|
+
let lastGeneratedMessage = (await StorageManager.get()).lastGeneratedMessage;
|
|
363
|
+
if (!lastGeneratedMessage) {
|
|
364
|
+
p4.log.error(color4.red("no previous commit message found"));
|
|
365
|
+
return await exit(1);
|
|
366
|
+
}
|
|
367
|
+
const isEditMode = options["--edit"];
|
|
368
|
+
p4.log.step(
|
|
369
|
+
isEditMode ? color4.white(lastGeneratedMessage) : color4.green(lastGeneratedMessage)
|
|
370
|
+
);
|
|
371
|
+
if (options["--edit"]) {
|
|
372
|
+
const editedMessage = await p4.text({
|
|
373
|
+
message: "edit the last generated commit message",
|
|
374
|
+
initialValue: lastGeneratedMessage,
|
|
375
|
+
placeholder: lastGeneratedMessage
|
|
376
|
+
});
|
|
377
|
+
if (p4.isCancel(editedMessage)) {
|
|
378
|
+
p4.log.error(color4.red("nothing changed!"));
|
|
379
|
+
return await exit(1);
|
|
380
|
+
}
|
|
381
|
+
lastGeneratedMessage = editedMessage;
|
|
382
|
+
await StorageManager.update((current) => ({
|
|
383
|
+
...current,
|
|
384
|
+
lastGeneratedMessage: editedMessage
|
|
385
|
+
}));
|
|
386
|
+
p4.log.step(color4.green(lastGeneratedMessage));
|
|
387
|
+
}
|
|
388
|
+
if (options["--copy"]) {
|
|
389
|
+
clipboard2.writeSync(lastGeneratedMessage);
|
|
390
|
+
p4.log.step(
|
|
391
|
+
color4.dim("copied last generated commit message to clipboard")
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
if (options["--apply"]) {
|
|
395
|
+
if (!options.isRepo) {
|
|
396
|
+
p4.log.error(
|
|
397
|
+
dedent4`${color4.red("no git repository found in cwd.")}
|
|
398
|
+
${color4.dim(`run ${color4.cyan("`git init`")} to initialize a new repository.`)}`
|
|
399
|
+
);
|
|
400
|
+
return await exit(1);
|
|
401
|
+
}
|
|
402
|
+
if (!options.diff) {
|
|
403
|
+
p4.log.error(
|
|
404
|
+
dedent4`${color4.red("no staged changes found.")}
|
|
405
|
+
${color4.dim(`run ${color4.cyan("`git add <file>`")} or ${color4.cyan("`git add .`")} to stage changes.`)}`
|
|
406
|
+
);
|
|
407
|
+
return await exit(1);
|
|
408
|
+
}
|
|
409
|
+
const success = await commit(lastGeneratedMessage);
|
|
410
|
+
if (success) {
|
|
411
|
+
p4.log.step(color4.dim("commit successful"));
|
|
412
|
+
} else {
|
|
413
|
+
p4.log.error(color4.red("failed to commit changes"));
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
console.log();
|
|
417
|
+
},
|
|
418
|
+
{ silent: true }
|
|
419
|
+
)
|
|
420
|
+
)
|
|
421
|
+
};
|
|
422
|
+
var prev_default = command2;
|
|
423
|
+
|
|
424
|
+
// src/commands/config.ts
|
|
425
|
+
import * as p5 from "@clack/prompts";
|
|
426
|
+
import color5 from "picocolors";
|
|
304
427
|
var key = {
|
|
305
428
|
name: "key",
|
|
306
429
|
description: "configure api key",
|
|
307
430
|
usage: "noto config key [options]",
|
|
308
431
|
execute: async (options) => {
|
|
309
432
|
if ((await StorageManager.get()).llm?.apiKey) {
|
|
310
|
-
const confirm2 = await
|
|
433
|
+
const confirm2 = await p5.confirm({
|
|
311
434
|
message: "noto api key already configured, do you want to update it?"
|
|
312
435
|
});
|
|
313
|
-
if (
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
process.exit(1);
|
|
436
|
+
if (p5.isCancel(confirm2) || !confirm2) {
|
|
437
|
+
p5.log.error(color5.red("nothing changed!"));
|
|
438
|
+
return await exit(1);
|
|
317
439
|
}
|
|
318
440
|
}
|
|
319
441
|
let apiKey = options._[0];
|
|
320
442
|
if (!apiKey) {
|
|
321
|
-
const result = await
|
|
443
|
+
const result = await p5.text({
|
|
322
444
|
message: "enter your noto api key"
|
|
323
445
|
});
|
|
324
|
-
if (
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
process.exit(1);
|
|
446
|
+
if (p5.isCancel(result)) {
|
|
447
|
+
p5.log.error(color5.red("nothing changed!"));
|
|
448
|
+
return await exit(1);
|
|
328
449
|
}
|
|
329
450
|
apiKey = result;
|
|
330
451
|
}
|
|
@@ -335,7 +456,7 @@ var key = {
|
|
|
335
456
|
apiKey
|
|
336
457
|
}
|
|
337
458
|
}));
|
|
338
|
-
|
|
459
|
+
p5.log.success(color5.green("noto api key configured!"));
|
|
339
460
|
console.log();
|
|
340
461
|
}
|
|
341
462
|
};
|
|
@@ -344,7 +465,7 @@ var model = {
|
|
|
344
465
|
description: "configure model",
|
|
345
466
|
usage: "noto config model [options]",
|
|
346
467
|
execute: async (options) => {
|
|
347
|
-
const model2 = await
|
|
468
|
+
const model2 = await p5.select({
|
|
348
469
|
message: "select a model",
|
|
349
470
|
initialValue: (await StorageManager.get()).llm?.model,
|
|
350
471
|
options: Object.keys(models).map((model3) => ({
|
|
@@ -352,10 +473,9 @@ var model = {
|
|
|
352
473
|
value: model3
|
|
353
474
|
}))
|
|
354
475
|
});
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
process.exit();
|
|
476
|
+
if (p5.isCancel(model2)) {
|
|
477
|
+
p5.log.error(color5.red("nothing changed!"));
|
|
478
|
+
return await exit(1);
|
|
359
479
|
}
|
|
360
480
|
await StorageManager.update((current) => ({
|
|
361
481
|
...current,
|
|
@@ -364,48 +484,46 @@ var model = {
|
|
|
364
484
|
model: model2
|
|
365
485
|
}
|
|
366
486
|
}));
|
|
367
|
-
|
|
487
|
+
p5.log.success(color5.green("model configured!"));
|
|
368
488
|
console.log();
|
|
369
489
|
}
|
|
370
490
|
};
|
|
371
491
|
var subCommands = [key, model];
|
|
372
|
-
var
|
|
492
|
+
var command3 = {
|
|
373
493
|
name: "config",
|
|
374
494
|
description: "configure noto",
|
|
375
495
|
usage: "noto config [subcommand]",
|
|
376
496
|
execute: async (options) => {
|
|
377
|
-
const
|
|
497
|
+
const command4 = await p5.select({
|
|
378
498
|
message: "Select a subcommand",
|
|
379
499
|
options: subCommands.map((cmd2) => ({
|
|
380
500
|
label: cmd2.description,
|
|
381
501
|
value: cmd2.name
|
|
382
502
|
}))
|
|
383
503
|
});
|
|
384
|
-
if (
|
|
385
|
-
|
|
386
|
-
process.exit(1);
|
|
504
|
+
if (p5.isCancel(command4)) {
|
|
505
|
+
return await exit(1);
|
|
387
506
|
}
|
|
388
|
-
const cmd = getCommand(
|
|
507
|
+
const cmd = getCommand(command4, subCommands);
|
|
389
508
|
if (!cmd) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
process.exit(1);
|
|
509
|
+
p5.log.error(color5.red("unknown config command"));
|
|
510
|
+
return await exit(1);
|
|
393
511
|
}
|
|
394
512
|
options._ = options._.slice(1);
|
|
395
513
|
cmd.execute(options);
|
|
396
514
|
},
|
|
397
515
|
subCommands
|
|
398
516
|
};
|
|
399
|
-
var config_default =
|
|
517
|
+
var config_default = command3;
|
|
400
518
|
|
|
401
519
|
// src/commands/index.ts
|
|
402
|
-
var commands = [noto_default, config_default];
|
|
520
|
+
var commands = [noto_default, prev_default, config_default];
|
|
403
521
|
var getCommand = (name, cmds = commands) => {
|
|
404
522
|
return cmds.find((cmd) => cmd.name === name);
|
|
405
523
|
};
|
|
406
524
|
|
|
407
525
|
// package.json
|
|
408
|
-
var version = "1.0.0-beta.
|
|
526
|
+
var version = "1.0.0-beta.4";
|
|
409
527
|
|
|
410
528
|
// src/index.ts
|
|
411
529
|
var globalSpec = {
|
|
@@ -416,11 +534,11 @@ var globalSpec = {
|
|
|
416
534
|
};
|
|
417
535
|
function main() {
|
|
418
536
|
const args = process.argv.slice(2);
|
|
419
|
-
const { command:
|
|
537
|
+
const { command: command4, options: globalOptions } = parse(globalSpec, args);
|
|
420
538
|
console.log();
|
|
421
|
-
|
|
422
|
-
if (globalOptions["--version"]) return
|
|
423
|
-
const cmd = getCommand(
|
|
539
|
+
p6.intro(`${color6.bgCyan(color6.black(" @snelusha/noto "))}`);
|
|
540
|
+
if (globalOptions["--version"]) return p6.outro(version);
|
|
541
|
+
const cmd = getCommand(command4) ?? getCommand("noto");
|
|
424
542
|
if (!cmd) return getCommand("noto")?.execute(globalOptions);
|
|
425
543
|
let commandArgs = args;
|
|
426
544
|
let selectedCommand = cmd;
|