@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.
Files changed (2) hide show
  1. package/dist/index.js +176 -58
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
- import * as p5 from "@clack/prompts";
3
- import color5 from "picocolors";
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 (options) => {
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
- console.log();
107
- process.exit(1);
114
+ return await exit(1);
108
115
  }
109
- return fn(options);
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 (options) => {
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
- console.log();
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
- console.log();
161
- process.exit(1);
167
+ return await exit(1);
162
168
  }
163
- options.diff = diff;
164
- return fn(options);
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
- const message = await generateCommitMessage(diff);
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
- process.exit(1);
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/config.ts
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 p4.confirm({
433
+ const confirm2 = await p5.confirm({
311
434
  message: "noto api key already configured, do you want to update it?"
312
435
  });
313
- if (p4.isCancel(confirm2) || !confirm2) {
314
- p4.log.error(color4.red("nothing changed!"));
315
- console.log();
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 p4.text({
443
+ const result = await p5.text({
322
444
  message: "enter your noto api key"
323
445
  });
324
- if (p4.isCancel(result)) {
325
- p4.log.error(color4.red("nothing changed!"));
326
- console.log();
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
- p4.log.success(color4.green("noto api key configured!"));
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 p4.select({
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 (p4.isCancel(model2)) {
356
- p4.log.error(color4.red("nothing changed!"));
357
- console.log();
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
- p4.log.success(color4.green("model configured!"));
487
+ p5.log.success(color5.green("model configured!"));
368
488
  console.log();
369
489
  }
370
490
  };
371
491
  var subCommands = [key, model];
372
- var command2 = {
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 command3 = await p4.select({
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 (p4.isCancel(command3)) {
385
- console.log();
386
- process.exit(1);
504
+ if (p5.isCancel(command4)) {
505
+ return await exit(1);
387
506
  }
388
- const cmd = getCommand(command3, subCommands);
507
+ const cmd = getCommand(command4, subCommands);
389
508
  if (!cmd) {
390
- p4.log.error(color4.red("unknown config command"));
391
- console.log();
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 = command2;
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.3";
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: command3, options: globalOptions } = parse(globalSpec, args);
537
+ const { command: command4, options: globalOptions } = parse(globalSpec, args);
420
538
  console.log();
421
- p5.intro(`${color5.bgCyan(color5.black(" @snelusha/noto "))}`);
422
- if (globalOptions["--version"]) return p5.outro(version);
423
- const cmd = getCommand(command3) ?? getCommand("noto");
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snelusha/noto",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.4",
4
4
  "description": "Generate clean commit messages in a snap! ✨",
5
5
  "license": "MIT",
6
6
  "type": "module",