git-coco 0.8.2 → 0.8.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.esm.mjs +427 -107
- package/dist/index.js +427 -107
- package/package.json +8 -6
package/dist/index.esm.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import os__default from 'os';
|
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import path__default from 'path';
|
|
12
12
|
import * as ini from 'ini';
|
|
13
|
+
import Ajv from 'ajv';
|
|
13
14
|
import ora from 'ora';
|
|
14
15
|
import now from 'performance-now';
|
|
15
16
|
import prettyMilliseconds from 'pretty-ms';
|
|
@@ -318,6 +319,318 @@ function loadIgnore(config) {
|
|
|
318
319
|
return config;
|
|
319
320
|
}
|
|
320
321
|
|
|
322
|
+
// this file is auto-generated by the 'build:schema' script
|
|
323
|
+
const SCHEMA_PUBLIC_URL = "http://git-co.co/schema.json";
|
|
324
|
+
const schema = {
|
|
325
|
+
"$id": "http://git-co.co/schema.json",
|
|
326
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
327
|
+
"type": "object",
|
|
328
|
+
"properties": {
|
|
329
|
+
"service": {
|
|
330
|
+
"description": "The LLM provider to use",
|
|
331
|
+
"default": "openai",
|
|
332
|
+
"enum": [
|
|
333
|
+
"openai",
|
|
334
|
+
"ollama"
|
|
335
|
+
]
|
|
336
|
+
},
|
|
337
|
+
"model": {
|
|
338
|
+
"type": "string",
|
|
339
|
+
"description": "The LLM model to use",
|
|
340
|
+
"default": "gpt-4o",
|
|
341
|
+
"oneOf": [
|
|
342
|
+
{
|
|
343
|
+
"if": {
|
|
344
|
+
"$ref": "#/definitions/is-openai"
|
|
345
|
+
},
|
|
346
|
+
"then": {
|
|
347
|
+
"enum": [
|
|
348
|
+
"gpt-3.5-turbo",
|
|
349
|
+
"gpt-3.5-turbo-16k",
|
|
350
|
+
"gpt-4",
|
|
351
|
+
"gpt-4-32k",
|
|
352
|
+
"gpt-4-turbo",
|
|
353
|
+
"gpt-4-turbo-preview",
|
|
354
|
+
"gpt-4o",
|
|
355
|
+
"gpt-4o-2024-05-13"
|
|
356
|
+
]
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"if": {
|
|
361
|
+
"$ref": "#/definitions/is-ollama"
|
|
362
|
+
},
|
|
363
|
+
"then": {
|
|
364
|
+
"enum": [
|
|
365
|
+
"orca-mini",
|
|
366
|
+
"orca-mini:13b",
|
|
367
|
+
"orca2",
|
|
368
|
+
"aya:8b",
|
|
369
|
+
"aya:35b",
|
|
370
|
+
"mistral",
|
|
371
|
+
"codegemma",
|
|
372
|
+
"codegemma:7b-code",
|
|
373
|
+
"codellama",
|
|
374
|
+
"llama2",
|
|
375
|
+
"llama2-uncensored",
|
|
376
|
+
"llama2:13b",
|
|
377
|
+
"llama2:70b",
|
|
378
|
+
"llama3",
|
|
379
|
+
"llama3:70b",
|
|
380
|
+
"phi3",
|
|
381
|
+
"phi3:mini",
|
|
382
|
+
"phi3:medium",
|
|
383
|
+
"qwen2",
|
|
384
|
+
"qwen2:1.5b",
|
|
385
|
+
"qwen2:0.5b"
|
|
386
|
+
]
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
]
|
|
390
|
+
},
|
|
391
|
+
"tokenLimit": {
|
|
392
|
+
"type": "number",
|
|
393
|
+
"description": "Maximum number of tokens for the commit message",
|
|
394
|
+
"default": 500
|
|
395
|
+
},
|
|
396
|
+
"verbose": {
|
|
397
|
+
"type": "boolean",
|
|
398
|
+
"description": "Verbose output",
|
|
399
|
+
"default": false
|
|
400
|
+
},
|
|
401
|
+
"prompt": {
|
|
402
|
+
"type": "string",
|
|
403
|
+
"description": "Prompt for the LLM service",
|
|
404
|
+
"default": "What are the changes in this commit?"
|
|
405
|
+
},
|
|
406
|
+
"temperature": {
|
|
407
|
+
"type": "number",
|
|
408
|
+
"description": "Controls randomness in GPT-3 output. Lower values yield focused output; higher values offer diversity",
|
|
409
|
+
"default": 0.4
|
|
410
|
+
},
|
|
411
|
+
"mode": {
|
|
412
|
+
"type": "string",
|
|
413
|
+
"description": "Preferred output method for generated commit messages",
|
|
414
|
+
"enum": [
|
|
415
|
+
"stdout",
|
|
416
|
+
"interactive"
|
|
417
|
+
],
|
|
418
|
+
"default": "stdout"
|
|
419
|
+
},
|
|
420
|
+
"summarizePrompt": {
|
|
421
|
+
"type": "string",
|
|
422
|
+
"description": "GPT-3 prompt for summarizing large files",
|
|
423
|
+
"default": "Summarize the changes in this large file:"
|
|
424
|
+
},
|
|
425
|
+
"ignoredFiles": {
|
|
426
|
+
"type": "array",
|
|
427
|
+
"description": "Paths of files to be excluded when generating commit messages",
|
|
428
|
+
"items": {
|
|
429
|
+
"type": "string"
|
|
430
|
+
},
|
|
431
|
+
"default": [
|
|
432
|
+
"package-lock.json"
|
|
433
|
+
]
|
|
434
|
+
},
|
|
435
|
+
"ignoredExtensions": {
|
|
436
|
+
"type": "array",
|
|
437
|
+
"description": "File extensions to be excluded when generating commit messages",
|
|
438
|
+
"items": {
|
|
439
|
+
"type": "string"
|
|
440
|
+
},
|
|
441
|
+
"default": [
|
|
442
|
+
".map",
|
|
443
|
+
".lock"
|
|
444
|
+
]
|
|
445
|
+
},
|
|
446
|
+
"defaultBranch": {
|
|
447
|
+
"type": "string",
|
|
448
|
+
"description": "Default branch for the repository",
|
|
449
|
+
"default": "main"
|
|
450
|
+
}
|
|
451
|
+
},
|
|
452
|
+
"required": [
|
|
453
|
+
"service",
|
|
454
|
+
"model"
|
|
455
|
+
],
|
|
456
|
+
"allOf": [
|
|
457
|
+
{
|
|
458
|
+
"if": {
|
|
459
|
+
"properties": {
|
|
460
|
+
"service": {
|
|
461
|
+
"const": "openai"
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
"then": {
|
|
466
|
+
"properties": {
|
|
467
|
+
"model": {
|
|
468
|
+
"enum": [
|
|
469
|
+
"gpt-3.5-turbo",
|
|
470
|
+
"gpt-3.5-turbo-16k",
|
|
471
|
+
"gpt-4",
|
|
472
|
+
"gpt-4-32k",
|
|
473
|
+
"gpt-4-turbo",
|
|
474
|
+
"gpt-4-turbo-preview",
|
|
475
|
+
"gpt-4o",
|
|
476
|
+
"gpt-4o-2024-05-13"
|
|
477
|
+
]
|
|
478
|
+
},
|
|
479
|
+
"openAIApiKey": {
|
|
480
|
+
"type": "string",
|
|
481
|
+
"description": "Your OpenAI API key",
|
|
482
|
+
"default": null
|
|
483
|
+
},
|
|
484
|
+
"endpoint": false
|
|
485
|
+
},
|
|
486
|
+
"required": [
|
|
487
|
+
"openAIApiKey"
|
|
488
|
+
],
|
|
489
|
+
"not": {
|
|
490
|
+
"required": [
|
|
491
|
+
"endpoint"
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
"if": {
|
|
498
|
+
"properties": {
|
|
499
|
+
"service": {
|
|
500
|
+
"const": "ollama"
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
"then": {
|
|
505
|
+
"properties": {
|
|
506
|
+
"model": {
|
|
507
|
+
"enum": [
|
|
508
|
+
"orca-mini",
|
|
509
|
+
"orca-mini:13b",
|
|
510
|
+
"orca2",
|
|
511
|
+
"aya:8b",
|
|
512
|
+
"aya:35b",
|
|
513
|
+
"mistral",
|
|
514
|
+
"codegemma",
|
|
515
|
+
"codegemma:7b-code",
|
|
516
|
+
"codellama",
|
|
517
|
+
"llama2",
|
|
518
|
+
"llama2-uncensored",
|
|
519
|
+
"llama2:13b",
|
|
520
|
+
"llama2:70b",
|
|
521
|
+
"llama3",
|
|
522
|
+
"llama3:70b",
|
|
523
|
+
"phi3",
|
|
524
|
+
"phi3:mini",
|
|
525
|
+
"phi3:medium",
|
|
526
|
+
"qwen2",
|
|
527
|
+
"qwen2:1.5b",
|
|
528
|
+
"qwen2:0.5b"
|
|
529
|
+
]
|
|
530
|
+
},
|
|
531
|
+
"openAIApiKey": false,
|
|
532
|
+
"endpoint": {
|
|
533
|
+
"type": "string",
|
|
534
|
+
"description": "The endpoint to use for the LLM service"
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
"not": {
|
|
538
|
+
"required": [
|
|
539
|
+
"openAIApiKey"
|
|
540
|
+
]
|
|
541
|
+
},
|
|
542
|
+
"required": [
|
|
543
|
+
"endpoint"
|
|
544
|
+
]
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
],
|
|
548
|
+
"definitions": {
|
|
549
|
+
"is-openai": {
|
|
550
|
+
"properties": {
|
|
551
|
+
"service": {
|
|
552
|
+
"enum": [
|
|
553
|
+
"openai"
|
|
554
|
+
]
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
"required": [
|
|
558
|
+
"service"
|
|
559
|
+
]
|
|
560
|
+
},
|
|
561
|
+
"is-ollama": {
|
|
562
|
+
"properties": {
|
|
563
|
+
"service": {
|
|
564
|
+
"enum": [
|
|
565
|
+
"ollama"
|
|
566
|
+
]
|
|
567
|
+
}
|
|
568
|
+
},
|
|
569
|
+
"required": [
|
|
570
|
+
"service"
|
|
571
|
+
]
|
|
572
|
+
},
|
|
573
|
+
"ollama-requires-endpoint": {
|
|
574
|
+
"anyOf": [
|
|
575
|
+
{
|
|
576
|
+
"not": {
|
|
577
|
+
"$ref": "#/definitions/is-openai"
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"required": [
|
|
582
|
+
"endpoint"
|
|
583
|
+
]
|
|
584
|
+
}
|
|
585
|
+
]
|
|
586
|
+
},
|
|
587
|
+
"openai-models": {
|
|
588
|
+
"enum": [
|
|
589
|
+
"gpt-3.5-turbo",
|
|
590
|
+
"gpt-3.5-turbo-16k",
|
|
591
|
+
"gpt-4",
|
|
592
|
+
"gpt-4-32k",
|
|
593
|
+
"gpt-4-turbo",
|
|
594
|
+
"gpt-4-turbo-preview",
|
|
595
|
+
"gpt-4o",
|
|
596
|
+
"gpt-4o-2024-05-13"
|
|
597
|
+
]
|
|
598
|
+
},
|
|
599
|
+
"ollama-models": {
|
|
600
|
+
"enum": [
|
|
601
|
+
"orca-mini",
|
|
602
|
+
"orca-mini:13b",
|
|
603
|
+
"orca2",
|
|
604
|
+
"aya:8b",
|
|
605
|
+
"aya:35b",
|
|
606
|
+
"mistral",
|
|
607
|
+
"codegemma",
|
|
608
|
+
"codegemma:7b-code",
|
|
609
|
+
"codellama",
|
|
610
|
+
"llama2",
|
|
611
|
+
"llama2-uncensored",
|
|
612
|
+
"llama2:13b",
|
|
613
|
+
"llama2:70b",
|
|
614
|
+
"llama3",
|
|
615
|
+
"llama3:70b",
|
|
616
|
+
"phi3",
|
|
617
|
+
"phi3:mini",
|
|
618
|
+
"phi3:medium",
|
|
619
|
+
"qwen2",
|
|
620
|
+
"qwen2:1.5b",
|
|
621
|
+
"qwen2:0.5b"
|
|
622
|
+
]
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
const ajv = new Ajv({
|
|
628
|
+
allErrors: true,
|
|
629
|
+
verbose: true,
|
|
630
|
+
strictTypes: false,
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
const validate = ajv.compile(schema);
|
|
321
634
|
/**
|
|
322
635
|
* Load project config
|
|
323
636
|
*
|
|
@@ -325,11 +638,13 @@ function loadIgnore(config) {
|
|
|
325
638
|
* @returns {Config} Updated config
|
|
326
639
|
**/
|
|
327
640
|
function loadProjectJsonConfig(config) {
|
|
328
|
-
// TODO: Add validation based of JSON schema?
|
|
329
|
-
// @see https://github.com/acornejo/jjv
|
|
330
641
|
if (fs.existsSync('.coco.config.json')) {
|
|
331
642
|
const projectConfig = JSON.parse(fs.readFileSync('.coco.config.json', 'utf-8'));
|
|
332
643
|
config = { ...config, ...projectConfig };
|
|
644
|
+
const isProjectConfigValid = validate(config);
|
|
645
|
+
if (!isProjectConfigValid) {
|
|
646
|
+
throw new Error('Invalid project config', { cause: validate.errors });
|
|
647
|
+
}
|
|
333
648
|
}
|
|
334
649
|
return config;
|
|
335
650
|
}
|
|
@@ -338,7 +653,7 @@ const appendToProjectJsonConfig = (filePath, config) => {
|
|
|
338
653
|
fs.writeFileSync(filePath, '{}');
|
|
339
654
|
}
|
|
340
655
|
fs.writeFileSync(filePath, JSON.stringify({
|
|
341
|
-
$schema:
|
|
656
|
+
$schema: SCHEMA_PUBLIC_URL,
|
|
342
657
|
...config,
|
|
343
658
|
}, null, 2));
|
|
344
659
|
};
|
|
@@ -359,6 +674,106 @@ function loadXDGConfig(config) {
|
|
|
359
674
|
return config;
|
|
360
675
|
}
|
|
361
676
|
|
|
677
|
+
const DEFAULT_OLLAMA_LLM_SERVICE = {
|
|
678
|
+
provider: 'ollama',
|
|
679
|
+
model: 'codellama',
|
|
680
|
+
endpoint: 'http://localhost:11434',
|
|
681
|
+
maxConcurrent: 1,
|
|
682
|
+
tokenLimit: 1024,
|
|
683
|
+
};
|
|
684
|
+
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
685
|
+
provider: 'openai',
|
|
686
|
+
model: 'gpt-4',
|
|
687
|
+
authentication: {
|
|
688
|
+
type: 'APIKey',
|
|
689
|
+
credentials: {
|
|
690
|
+
apiKey: '',
|
|
691
|
+
},
|
|
692
|
+
},
|
|
693
|
+
tokenLimit: 1024,
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Retrieves the provider and model from the given configuration object.
|
|
698
|
+
* @param config The configuration object.
|
|
699
|
+
* @returns An object containing the provider and model.
|
|
700
|
+
* @throws Error if the configuration is invalid or missing required properties.
|
|
701
|
+
*/
|
|
702
|
+
function getModelAndProviderFromConfig(config) {
|
|
703
|
+
if (!config.service) {
|
|
704
|
+
throw new Error('Invalid service: undefined');
|
|
705
|
+
}
|
|
706
|
+
let result;
|
|
707
|
+
switch (typeof config.service) {
|
|
708
|
+
case 'string':
|
|
709
|
+
result = getDefaultServiceConfigFromAlias(config.service, config?.model);
|
|
710
|
+
break;
|
|
711
|
+
case 'object':
|
|
712
|
+
default:
|
|
713
|
+
result = config.service;
|
|
714
|
+
break;
|
|
715
|
+
}
|
|
716
|
+
const { provider, model } = result;
|
|
717
|
+
if (!model || !provider) {
|
|
718
|
+
throw new Error(`Invalid service: ${config.service}`);
|
|
719
|
+
}
|
|
720
|
+
return { provider, model };
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
723
|
+
* Retrieve appropriate API key based on selected model
|
|
724
|
+
* @param service
|
|
725
|
+
* @param options
|
|
726
|
+
* @returns API Key
|
|
727
|
+
*/
|
|
728
|
+
function getApiKeyForModel(config) {
|
|
729
|
+
const { provider } = getModelAndProviderFromConfig(config);
|
|
730
|
+
switch (provider) {
|
|
731
|
+
case 'openai':
|
|
732
|
+
return config.openAIApiKey || getDefaultServiceApiKey(config);
|
|
733
|
+
default:
|
|
734
|
+
return getDefaultServiceApiKey(config);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Retrieves the default service API key from the given configuration.
|
|
739
|
+
* @param config The configuration object.
|
|
740
|
+
* @returns The default service API key.
|
|
741
|
+
*/
|
|
742
|
+
function getDefaultServiceApiKey(config) {
|
|
743
|
+
const service = config.service;
|
|
744
|
+
if (service.authentication.type === 'APIKey') {
|
|
745
|
+
return service.authentication.credentials?.apiKey;
|
|
746
|
+
}
|
|
747
|
+
else if (service.authentication.type === 'OAuth') {
|
|
748
|
+
return service.authentication.credentials?.token;
|
|
749
|
+
}
|
|
750
|
+
return '';
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Retrieves the default service configuration based on the provided alias and optional model.
|
|
754
|
+
* @param alias - The alias of the service.
|
|
755
|
+
* @param model - The optional model to be used.
|
|
756
|
+
* @returns The default service configuration.
|
|
757
|
+
* @throws Error if the alias is invalid or undefined.
|
|
758
|
+
*/
|
|
759
|
+
function getDefaultServiceConfigFromAlias(alias, model) {
|
|
760
|
+
if (!alias) {
|
|
761
|
+
throw new Error('Invalid alias: undefined');
|
|
762
|
+
}
|
|
763
|
+
switch (alias) {
|
|
764
|
+
case 'openai':
|
|
765
|
+
return {
|
|
766
|
+
...DEFAULT_OPENAI_LLM_SERVICE,
|
|
767
|
+
model: model || DEFAULT_OPENAI_LLM_SERVICE.model,
|
|
768
|
+
};
|
|
769
|
+
case 'ollama':
|
|
770
|
+
return {
|
|
771
|
+
...DEFAULT_OLLAMA_LLM_SERVICE,
|
|
772
|
+
model: model || DEFAULT_OLLAMA_LLM_SERVICE.model,
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
362
777
|
/**
|
|
363
778
|
* Load application config
|
|
364
779
|
*
|
|
@@ -379,6 +794,11 @@ function loadXDGConfig(config) {
|
|
|
379
794
|
function loadConfig(argv = {}) {
|
|
380
795
|
// Default config
|
|
381
796
|
let config = DEFAULT_CONFIG;
|
|
797
|
+
const { model } = getDefaultServiceConfigFromAlias(config.service, config.model);
|
|
798
|
+
config = {
|
|
799
|
+
model: model,
|
|
800
|
+
...config,
|
|
801
|
+
};
|
|
382
802
|
config = loadGitignore(config);
|
|
383
803
|
config = loadIgnore(config);
|
|
384
804
|
config = loadXDGConfig(config);
|
|
@@ -823,106 +1243,6 @@ const COMMIT_PROMPT = new PromptTemplate({
|
|
|
823
1243
|
inputVariables: inputVariables$1,
|
|
824
1244
|
});
|
|
825
1245
|
|
|
826
|
-
const DEFAULT_OLLAMA_LLM_SERVICE = {
|
|
827
|
-
provider: 'ollama',
|
|
828
|
-
model: 'codellama',
|
|
829
|
-
endpoint: 'http://localhost:11434',
|
|
830
|
-
maxConcurrent: 1,
|
|
831
|
-
tokenLimit: 1024,
|
|
832
|
-
};
|
|
833
|
-
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
834
|
-
provider: 'openai',
|
|
835
|
-
model: 'gpt-4',
|
|
836
|
-
authentication: {
|
|
837
|
-
type: 'APIKey',
|
|
838
|
-
credentials: {
|
|
839
|
-
apiKey: '',
|
|
840
|
-
},
|
|
841
|
-
},
|
|
842
|
-
tokenLimit: 1024,
|
|
843
|
-
};
|
|
844
|
-
|
|
845
|
-
/**
|
|
846
|
-
* Retrieves the provider and model from the given configuration object.
|
|
847
|
-
* @param config The configuration object.
|
|
848
|
-
* @returns An object containing the provider and model.
|
|
849
|
-
* @throws Error if the configuration is invalid or missing required properties.
|
|
850
|
-
*/
|
|
851
|
-
function getModelAndProviderFromConfig(config) {
|
|
852
|
-
if (!config.service) {
|
|
853
|
-
throw new Error('Invalid service: undefined');
|
|
854
|
-
}
|
|
855
|
-
let result;
|
|
856
|
-
switch (typeof config.service) {
|
|
857
|
-
case 'string':
|
|
858
|
-
result = getDefaultServiceConfigFromAlias(config.service, config?.model);
|
|
859
|
-
break;
|
|
860
|
-
case 'object':
|
|
861
|
-
default:
|
|
862
|
-
result = config.service;
|
|
863
|
-
break;
|
|
864
|
-
}
|
|
865
|
-
const { provider, model } = result;
|
|
866
|
-
if (!model || !provider) {
|
|
867
|
-
throw new Error(`Invalid service: ${config.service}`);
|
|
868
|
-
}
|
|
869
|
-
return { provider, model };
|
|
870
|
-
}
|
|
871
|
-
/**
|
|
872
|
-
* Retrieve appropriate API key based on selected model
|
|
873
|
-
* @param service
|
|
874
|
-
* @param options
|
|
875
|
-
* @returns API Key
|
|
876
|
-
*/
|
|
877
|
-
function getApiKeyForModel(config) {
|
|
878
|
-
const { provider } = getModelAndProviderFromConfig(config);
|
|
879
|
-
switch (provider) {
|
|
880
|
-
case 'openai':
|
|
881
|
-
return config.openAIApiKey || getDefaultServiceApiKey(config);
|
|
882
|
-
default:
|
|
883
|
-
return getDefaultServiceApiKey(config);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Retrieves the default service API key from the given configuration.
|
|
888
|
-
* @param config The configuration object.
|
|
889
|
-
* @returns The default service API key.
|
|
890
|
-
*/
|
|
891
|
-
function getDefaultServiceApiKey(config) {
|
|
892
|
-
const service = config.service;
|
|
893
|
-
if (service.authentication.type === 'APIKey') {
|
|
894
|
-
return service.authentication.credentials?.apiKey;
|
|
895
|
-
}
|
|
896
|
-
else if (service.authentication.type === 'OAuth') {
|
|
897
|
-
return service.authentication.credentials?.token;
|
|
898
|
-
}
|
|
899
|
-
return '';
|
|
900
|
-
}
|
|
901
|
-
/**
|
|
902
|
-
* Retrieves the default service configuration based on the provided alias and optional model.
|
|
903
|
-
* @param alias - The alias of the service.
|
|
904
|
-
* @param model - The optional model to be used.
|
|
905
|
-
* @returns The default service configuration.
|
|
906
|
-
* @throws Error if the alias is invalid or undefined.
|
|
907
|
-
*/
|
|
908
|
-
function getDefaultServiceConfigFromAlias(alias, model) {
|
|
909
|
-
if (!alias) {
|
|
910
|
-
throw new Error('Invalid alias: undefined');
|
|
911
|
-
}
|
|
912
|
-
switch (alias) {
|
|
913
|
-
case 'openai':
|
|
914
|
-
return {
|
|
915
|
-
...DEFAULT_OPENAI_LLM_SERVICE,
|
|
916
|
-
model: model || DEFAULT_OPENAI_LLM_SERVICE.model,
|
|
917
|
-
};
|
|
918
|
-
case 'ollama':
|
|
919
|
-
return {
|
|
920
|
-
...DEFAULT_OLLAMA_LLM_SERVICE,
|
|
921
|
-
model: model || DEFAULT_OLLAMA_LLM_SERVICE.model,
|
|
922
|
-
};
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
|
|
926
1246
|
/**
|
|
927
1247
|
* Get LLM Model Based on Configuration
|
|
928
1248
|
*
|
|
@@ -1499,7 +1819,7 @@ const builder$2 = (yargs) => {
|
|
|
1499
1819
|
|
|
1500
1820
|
var commit = {
|
|
1501
1821
|
command: 'commit',
|
|
1502
|
-
desc: '
|
|
1822
|
+
desc: 'Write a commit message summarizing the staged changes.',
|
|
1503
1823
|
builder: builder$2,
|
|
1504
1824
|
handler: commandExecutor(handler$2),
|
|
1505
1825
|
options: options$2,
|
|
@@ -2049,17 +2369,17 @@ y.command([commit.command, '$0'], commit.desc,
|
|
|
2049
2369
|
// TODO: fix type on builder
|
|
2050
2370
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2051
2371
|
// @ts-ignore
|
|
2052
|
-
commit.builder, commit.handler);
|
|
2372
|
+
commit.builder, commit.handler).options(commit.options);
|
|
2053
2373
|
y.command(changelog.command, changelog.desc,
|
|
2054
2374
|
// TODO: fix type on builder
|
|
2055
2375
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2056
2376
|
// @ts-ignore
|
|
2057
|
-
changelog.builder, changelog.handler);
|
|
2377
|
+
changelog.builder, changelog.handler).options(changelog.options);
|
|
2058
2378
|
y.command(init.command, init.desc,
|
|
2059
2379
|
// TODO: fix type on builder
|
|
2060
2380
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2061
2381
|
// @ts-ignore
|
|
2062
|
-
init.builder, init.handler);
|
|
2382
|
+
init.builder, init.handler).options(init.options);
|
|
2063
2383
|
y.parse(process.argv.slice(2));
|
|
2064
2384
|
|
|
2065
2385
|
export { changelog, commit, init, types };
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ var chalk = require('chalk');
|
|
|
9
9
|
var os = require('os');
|
|
10
10
|
var path = require('path');
|
|
11
11
|
var ini = require('ini');
|
|
12
|
+
var Ajv = require('ajv');
|
|
12
13
|
var ora = require('ora');
|
|
13
14
|
var now = require('performance-now');
|
|
14
15
|
var prettyMilliseconds = require('pretty-ms');
|
|
@@ -339,6 +340,318 @@ function loadIgnore(config) {
|
|
|
339
340
|
return config;
|
|
340
341
|
}
|
|
341
342
|
|
|
343
|
+
// this file is auto-generated by the 'build:schema' script
|
|
344
|
+
const SCHEMA_PUBLIC_URL = "http://git-co.co/schema.json";
|
|
345
|
+
const schema = {
|
|
346
|
+
"$id": "http://git-co.co/schema.json",
|
|
347
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
348
|
+
"type": "object",
|
|
349
|
+
"properties": {
|
|
350
|
+
"service": {
|
|
351
|
+
"description": "The LLM provider to use",
|
|
352
|
+
"default": "openai",
|
|
353
|
+
"enum": [
|
|
354
|
+
"openai",
|
|
355
|
+
"ollama"
|
|
356
|
+
]
|
|
357
|
+
},
|
|
358
|
+
"model": {
|
|
359
|
+
"type": "string",
|
|
360
|
+
"description": "The LLM model to use",
|
|
361
|
+
"default": "gpt-4o",
|
|
362
|
+
"oneOf": [
|
|
363
|
+
{
|
|
364
|
+
"if": {
|
|
365
|
+
"$ref": "#/definitions/is-openai"
|
|
366
|
+
},
|
|
367
|
+
"then": {
|
|
368
|
+
"enum": [
|
|
369
|
+
"gpt-3.5-turbo",
|
|
370
|
+
"gpt-3.5-turbo-16k",
|
|
371
|
+
"gpt-4",
|
|
372
|
+
"gpt-4-32k",
|
|
373
|
+
"gpt-4-turbo",
|
|
374
|
+
"gpt-4-turbo-preview",
|
|
375
|
+
"gpt-4o",
|
|
376
|
+
"gpt-4o-2024-05-13"
|
|
377
|
+
]
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"if": {
|
|
382
|
+
"$ref": "#/definitions/is-ollama"
|
|
383
|
+
},
|
|
384
|
+
"then": {
|
|
385
|
+
"enum": [
|
|
386
|
+
"orca-mini",
|
|
387
|
+
"orca-mini:13b",
|
|
388
|
+
"orca2",
|
|
389
|
+
"aya:8b",
|
|
390
|
+
"aya:35b",
|
|
391
|
+
"mistral",
|
|
392
|
+
"codegemma",
|
|
393
|
+
"codegemma:7b-code",
|
|
394
|
+
"codellama",
|
|
395
|
+
"llama2",
|
|
396
|
+
"llama2-uncensored",
|
|
397
|
+
"llama2:13b",
|
|
398
|
+
"llama2:70b",
|
|
399
|
+
"llama3",
|
|
400
|
+
"llama3:70b",
|
|
401
|
+
"phi3",
|
|
402
|
+
"phi3:mini",
|
|
403
|
+
"phi3:medium",
|
|
404
|
+
"qwen2",
|
|
405
|
+
"qwen2:1.5b",
|
|
406
|
+
"qwen2:0.5b"
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
},
|
|
412
|
+
"tokenLimit": {
|
|
413
|
+
"type": "number",
|
|
414
|
+
"description": "Maximum number of tokens for the commit message",
|
|
415
|
+
"default": 500
|
|
416
|
+
},
|
|
417
|
+
"verbose": {
|
|
418
|
+
"type": "boolean",
|
|
419
|
+
"description": "Verbose output",
|
|
420
|
+
"default": false
|
|
421
|
+
},
|
|
422
|
+
"prompt": {
|
|
423
|
+
"type": "string",
|
|
424
|
+
"description": "Prompt for the LLM service",
|
|
425
|
+
"default": "What are the changes in this commit?"
|
|
426
|
+
},
|
|
427
|
+
"temperature": {
|
|
428
|
+
"type": "number",
|
|
429
|
+
"description": "Controls randomness in GPT-3 output. Lower values yield focused output; higher values offer diversity",
|
|
430
|
+
"default": 0.4
|
|
431
|
+
},
|
|
432
|
+
"mode": {
|
|
433
|
+
"type": "string",
|
|
434
|
+
"description": "Preferred output method for generated commit messages",
|
|
435
|
+
"enum": [
|
|
436
|
+
"stdout",
|
|
437
|
+
"interactive"
|
|
438
|
+
],
|
|
439
|
+
"default": "stdout"
|
|
440
|
+
},
|
|
441
|
+
"summarizePrompt": {
|
|
442
|
+
"type": "string",
|
|
443
|
+
"description": "GPT-3 prompt for summarizing large files",
|
|
444
|
+
"default": "Summarize the changes in this large file:"
|
|
445
|
+
},
|
|
446
|
+
"ignoredFiles": {
|
|
447
|
+
"type": "array",
|
|
448
|
+
"description": "Paths of files to be excluded when generating commit messages",
|
|
449
|
+
"items": {
|
|
450
|
+
"type": "string"
|
|
451
|
+
},
|
|
452
|
+
"default": [
|
|
453
|
+
"package-lock.json"
|
|
454
|
+
]
|
|
455
|
+
},
|
|
456
|
+
"ignoredExtensions": {
|
|
457
|
+
"type": "array",
|
|
458
|
+
"description": "File extensions to be excluded when generating commit messages",
|
|
459
|
+
"items": {
|
|
460
|
+
"type": "string"
|
|
461
|
+
},
|
|
462
|
+
"default": [
|
|
463
|
+
".map",
|
|
464
|
+
".lock"
|
|
465
|
+
]
|
|
466
|
+
},
|
|
467
|
+
"defaultBranch": {
|
|
468
|
+
"type": "string",
|
|
469
|
+
"description": "Default branch for the repository",
|
|
470
|
+
"default": "main"
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
"required": [
|
|
474
|
+
"service",
|
|
475
|
+
"model"
|
|
476
|
+
],
|
|
477
|
+
"allOf": [
|
|
478
|
+
{
|
|
479
|
+
"if": {
|
|
480
|
+
"properties": {
|
|
481
|
+
"service": {
|
|
482
|
+
"const": "openai"
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
},
|
|
486
|
+
"then": {
|
|
487
|
+
"properties": {
|
|
488
|
+
"model": {
|
|
489
|
+
"enum": [
|
|
490
|
+
"gpt-3.5-turbo",
|
|
491
|
+
"gpt-3.5-turbo-16k",
|
|
492
|
+
"gpt-4",
|
|
493
|
+
"gpt-4-32k",
|
|
494
|
+
"gpt-4-turbo",
|
|
495
|
+
"gpt-4-turbo-preview",
|
|
496
|
+
"gpt-4o",
|
|
497
|
+
"gpt-4o-2024-05-13"
|
|
498
|
+
]
|
|
499
|
+
},
|
|
500
|
+
"openAIApiKey": {
|
|
501
|
+
"type": "string",
|
|
502
|
+
"description": "Your OpenAI API key",
|
|
503
|
+
"default": null
|
|
504
|
+
},
|
|
505
|
+
"endpoint": false
|
|
506
|
+
},
|
|
507
|
+
"required": [
|
|
508
|
+
"openAIApiKey"
|
|
509
|
+
],
|
|
510
|
+
"not": {
|
|
511
|
+
"required": [
|
|
512
|
+
"endpoint"
|
|
513
|
+
]
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
"if": {
|
|
519
|
+
"properties": {
|
|
520
|
+
"service": {
|
|
521
|
+
"const": "ollama"
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
},
|
|
525
|
+
"then": {
|
|
526
|
+
"properties": {
|
|
527
|
+
"model": {
|
|
528
|
+
"enum": [
|
|
529
|
+
"orca-mini",
|
|
530
|
+
"orca-mini:13b",
|
|
531
|
+
"orca2",
|
|
532
|
+
"aya:8b",
|
|
533
|
+
"aya:35b",
|
|
534
|
+
"mistral",
|
|
535
|
+
"codegemma",
|
|
536
|
+
"codegemma:7b-code",
|
|
537
|
+
"codellama",
|
|
538
|
+
"llama2",
|
|
539
|
+
"llama2-uncensored",
|
|
540
|
+
"llama2:13b",
|
|
541
|
+
"llama2:70b",
|
|
542
|
+
"llama3",
|
|
543
|
+
"llama3:70b",
|
|
544
|
+
"phi3",
|
|
545
|
+
"phi3:mini",
|
|
546
|
+
"phi3:medium",
|
|
547
|
+
"qwen2",
|
|
548
|
+
"qwen2:1.5b",
|
|
549
|
+
"qwen2:0.5b"
|
|
550
|
+
]
|
|
551
|
+
},
|
|
552
|
+
"openAIApiKey": false,
|
|
553
|
+
"endpoint": {
|
|
554
|
+
"type": "string",
|
|
555
|
+
"description": "The endpoint to use for the LLM service"
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
"not": {
|
|
559
|
+
"required": [
|
|
560
|
+
"openAIApiKey"
|
|
561
|
+
]
|
|
562
|
+
},
|
|
563
|
+
"required": [
|
|
564
|
+
"endpoint"
|
|
565
|
+
]
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
],
|
|
569
|
+
"definitions": {
|
|
570
|
+
"is-openai": {
|
|
571
|
+
"properties": {
|
|
572
|
+
"service": {
|
|
573
|
+
"enum": [
|
|
574
|
+
"openai"
|
|
575
|
+
]
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
"required": [
|
|
579
|
+
"service"
|
|
580
|
+
]
|
|
581
|
+
},
|
|
582
|
+
"is-ollama": {
|
|
583
|
+
"properties": {
|
|
584
|
+
"service": {
|
|
585
|
+
"enum": [
|
|
586
|
+
"ollama"
|
|
587
|
+
]
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
"required": [
|
|
591
|
+
"service"
|
|
592
|
+
]
|
|
593
|
+
},
|
|
594
|
+
"ollama-requires-endpoint": {
|
|
595
|
+
"anyOf": [
|
|
596
|
+
{
|
|
597
|
+
"not": {
|
|
598
|
+
"$ref": "#/definitions/is-openai"
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"required": [
|
|
603
|
+
"endpoint"
|
|
604
|
+
]
|
|
605
|
+
}
|
|
606
|
+
]
|
|
607
|
+
},
|
|
608
|
+
"openai-models": {
|
|
609
|
+
"enum": [
|
|
610
|
+
"gpt-3.5-turbo",
|
|
611
|
+
"gpt-3.5-turbo-16k",
|
|
612
|
+
"gpt-4",
|
|
613
|
+
"gpt-4-32k",
|
|
614
|
+
"gpt-4-turbo",
|
|
615
|
+
"gpt-4-turbo-preview",
|
|
616
|
+
"gpt-4o",
|
|
617
|
+
"gpt-4o-2024-05-13"
|
|
618
|
+
]
|
|
619
|
+
},
|
|
620
|
+
"ollama-models": {
|
|
621
|
+
"enum": [
|
|
622
|
+
"orca-mini",
|
|
623
|
+
"orca-mini:13b",
|
|
624
|
+
"orca2",
|
|
625
|
+
"aya:8b",
|
|
626
|
+
"aya:35b",
|
|
627
|
+
"mistral",
|
|
628
|
+
"codegemma",
|
|
629
|
+
"codegemma:7b-code",
|
|
630
|
+
"codellama",
|
|
631
|
+
"llama2",
|
|
632
|
+
"llama2-uncensored",
|
|
633
|
+
"llama2:13b",
|
|
634
|
+
"llama2:70b",
|
|
635
|
+
"llama3",
|
|
636
|
+
"llama3:70b",
|
|
637
|
+
"phi3",
|
|
638
|
+
"phi3:mini",
|
|
639
|
+
"phi3:medium",
|
|
640
|
+
"qwen2",
|
|
641
|
+
"qwen2:1.5b",
|
|
642
|
+
"qwen2:0.5b"
|
|
643
|
+
]
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
const ajv = new Ajv({
|
|
649
|
+
allErrors: true,
|
|
650
|
+
verbose: true,
|
|
651
|
+
strictTypes: false,
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
const validate = ajv.compile(schema);
|
|
342
655
|
/**
|
|
343
656
|
* Load project config
|
|
344
657
|
*
|
|
@@ -346,11 +659,13 @@ function loadIgnore(config) {
|
|
|
346
659
|
* @returns {Config} Updated config
|
|
347
660
|
**/
|
|
348
661
|
function loadProjectJsonConfig(config) {
|
|
349
|
-
// TODO: Add validation based of JSON schema?
|
|
350
|
-
// @see https://github.com/acornejo/jjv
|
|
351
662
|
if (fs__namespace.existsSync('.coco.config.json')) {
|
|
352
663
|
const projectConfig = JSON.parse(fs__namespace.readFileSync('.coco.config.json', 'utf-8'));
|
|
353
664
|
config = { ...config, ...projectConfig };
|
|
665
|
+
const isProjectConfigValid = validate(config);
|
|
666
|
+
if (!isProjectConfigValid) {
|
|
667
|
+
throw new Error('Invalid project config', { cause: validate.errors });
|
|
668
|
+
}
|
|
354
669
|
}
|
|
355
670
|
return config;
|
|
356
671
|
}
|
|
@@ -359,7 +674,7 @@ const appendToProjectJsonConfig = (filePath, config) => {
|
|
|
359
674
|
fs__namespace.writeFileSync(filePath, '{}');
|
|
360
675
|
}
|
|
361
676
|
fs__namespace.writeFileSync(filePath, JSON.stringify({
|
|
362
|
-
$schema:
|
|
677
|
+
$schema: SCHEMA_PUBLIC_URL,
|
|
363
678
|
...config,
|
|
364
679
|
}, null, 2));
|
|
365
680
|
};
|
|
@@ -380,6 +695,106 @@ function loadXDGConfig(config) {
|
|
|
380
695
|
return config;
|
|
381
696
|
}
|
|
382
697
|
|
|
698
|
+
const DEFAULT_OLLAMA_LLM_SERVICE = {
|
|
699
|
+
provider: 'ollama',
|
|
700
|
+
model: 'codellama',
|
|
701
|
+
endpoint: 'http://localhost:11434',
|
|
702
|
+
maxConcurrent: 1,
|
|
703
|
+
tokenLimit: 1024,
|
|
704
|
+
};
|
|
705
|
+
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
706
|
+
provider: 'openai',
|
|
707
|
+
model: 'gpt-4',
|
|
708
|
+
authentication: {
|
|
709
|
+
type: 'APIKey',
|
|
710
|
+
credentials: {
|
|
711
|
+
apiKey: '',
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
tokenLimit: 1024,
|
|
715
|
+
};
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Retrieves the provider and model from the given configuration object.
|
|
719
|
+
* @param config The configuration object.
|
|
720
|
+
* @returns An object containing the provider and model.
|
|
721
|
+
* @throws Error if the configuration is invalid or missing required properties.
|
|
722
|
+
*/
|
|
723
|
+
function getModelAndProviderFromConfig(config) {
|
|
724
|
+
if (!config.service) {
|
|
725
|
+
throw new Error('Invalid service: undefined');
|
|
726
|
+
}
|
|
727
|
+
let result;
|
|
728
|
+
switch (typeof config.service) {
|
|
729
|
+
case 'string':
|
|
730
|
+
result = getDefaultServiceConfigFromAlias(config.service, config?.model);
|
|
731
|
+
break;
|
|
732
|
+
case 'object':
|
|
733
|
+
default:
|
|
734
|
+
result = config.service;
|
|
735
|
+
break;
|
|
736
|
+
}
|
|
737
|
+
const { provider, model } = result;
|
|
738
|
+
if (!model || !provider) {
|
|
739
|
+
throw new Error(`Invalid service: ${config.service}`);
|
|
740
|
+
}
|
|
741
|
+
return { provider, model };
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Retrieve appropriate API key based on selected model
|
|
745
|
+
* @param service
|
|
746
|
+
* @param options
|
|
747
|
+
* @returns API Key
|
|
748
|
+
*/
|
|
749
|
+
function getApiKeyForModel(config) {
|
|
750
|
+
const { provider } = getModelAndProviderFromConfig(config);
|
|
751
|
+
switch (provider) {
|
|
752
|
+
case 'openai':
|
|
753
|
+
return config.openAIApiKey || getDefaultServiceApiKey(config);
|
|
754
|
+
default:
|
|
755
|
+
return getDefaultServiceApiKey(config);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Retrieves the default service API key from the given configuration.
|
|
760
|
+
* @param config The configuration object.
|
|
761
|
+
* @returns The default service API key.
|
|
762
|
+
*/
|
|
763
|
+
function getDefaultServiceApiKey(config) {
|
|
764
|
+
const service = config.service;
|
|
765
|
+
if (service.authentication.type === 'APIKey') {
|
|
766
|
+
return service.authentication.credentials?.apiKey;
|
|
767
|
+
}
|
|
768
|
+
else if (service.authentication.type === 'OAuth') {
|
|
769
|
+
return service.authentication.credentials?.token;
|
|
770
|
+
}
|
|
771
|
+
return '';
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Retrieves the default service configuration based on the provided alias and optional model.
|
|
775
|
+
* @param alias - The alias of the service.
|
|
776
|
+
* @param model - The optional model to be used.
|
|
777
|
+
* @returns The default service configuration.
|
|
778
|
+
* @throws Error if the alias is invalid or undefined.
|
|
779
|
+
*/
|
|
780
|
+
function getDefaultServiceConfigFromAlias(alias, model) {
|
|
781
|
+
if (!alias) {
|
|
782
|
+
throw new Error('Invalid alias: undefined');
|
|
783
|
+
}
|
|
784
|
+
switch (alias) {
|
|
785
|
+
case 'openai':
|
|
786
|
+
return {
|
|
787
|
+
...DEFAULT_OPENAI_LLM_SERVICE,
|
|
788
|
+
model: model || DEFAULT_OPENAI_LLM_SERVICE.model,
|
|
789
|
+
};
|
|
790
|
+
case 'ollama':
|
|
791
|
+
return {
|
|
792
|
+
...DEFAULT_OLLAMA_LLM_SERVICE,
|
|
793
|
+
model: model || DEFAULT_OLLAMA_LLM_SERVICE.model,
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
383
798
|
/**
|
|
384
799
|
* Load application config
|
|
385
800
|
*
|
|
@@ -400,6 +815,11 @@ function loadXDGConfig(config) {
|
|
|
400
815
|
function loadConfig(argv = {}) {
|
|
401
816
|
// Default config
|
|
402
817
|
let config = DEFAULT_CONFIG;
|
|
818
|
+
const { model } = getDefaultServiceConfigFromAlias(config.service, config.model);
|
|
819
|
+
config = {
|
|
820
|
+
model: model,
|
|
821
|
+
...config,
|
|
822
|
+
};
|
|
403
823
|
config = loadGitignore(config);
|
|
404
824
|
config = loadIgnore(config);
|
|
405
825
|
config = loadXDGConfig(config);
|
|
@@ -844,106 +1264,6 @@ const COMMIT_PROMPT = new prompts.PromptTemplate({
|
|
|
844
1264
|
inputVariables: inputVariables$1,
|
|
845
1265
|
});
|
|
846
1266
|
|
|
847
|
-
const DEFAULT_OLLAMA_LLM_SERVICE = {
|
|
848
|
-
provider: 'ollama',
|
|
849
|
-
model: 'codellama',
|
|
850
|
-
endpoint: 'http://localhost:11434',
|
|
851
|
-
maxConcurrent: 1,
|
|
852
|
-
tokenLimit: 1024,
|
|
853
|
-
};
|
|
854
|
-
const DEFAULT_OPENAI_LLM_SERVICE = {
|
|
855
|
-
provider: 'openai',
|
|
856
|
-
model: 'gpt-4',
|
|
857
|
-
authentication: {
|
|
858
|
-
type: 'APIKey',
|
|
859
|
-
credentials: {
|
|
860
|
-
apiKey: '',
|
|
861
|
-
},
|
|
862
|
-
},
|
|
863
|
-
tokenLimit: 1024,
|
|
864
|
-
};
|
|
865
|
-
|
|
866
|
-
/**
|
|
867
|
-
* Retrieves the provider and model from the given configuration object.
|
|
868
|
-
* @param config The configuration object.
|
|
869
|
-
* @returns An object containing the provider and model.
|
|
870
|
-
* @throws Error if the configuration is invalid or missing required properties.
|
|
871
|
-
*/
|
|
872
|
-
function getModelAndProviderFromConfig(config) {
|
|
873
|
-
if (!config.service) {
|
|
874
|
-
throw new Error('Invalid service: undefined');
|
|
875
|
-
}
|
|
876
|
-
let result;
|
|
877
|
-
switch (typeof config.service) {
|
|
878
|
-
case 'string':
|
|
879
|
-
result = getDefaultServiceConfigFromAlias(config.service, config?.model);
|
|
880
|
-
break;
|
|
881
|
-
case 'object':
|
|
882
|
-
default:
|
|
883
|
-
result = config.service;
|
|
884
|
-
break;
|
|
885
|
-
}
|
|
886
|
-
const { provider, model } = result;
|
|
887
|
-
if (!model || !provider) {
|
|
888
|
-
throw new Error(`Invalid service: ${config.service}`);
|
|
889
|
-
}
|
|
890
|
-
return { provider, model };
|
|
891
|
-
}
|
|
892
|
-
/**
|
|
893
|
-
* Retrieve appropriate API key based on selected model
|
|
894
|
-
* @param service
|
|
895
|
-
* @param options
|
|
896
|
-
* @returns API Key
|
|
897
|
-
*/
|
|
898
|
-
function getApiKeyForModel(config) {
|
|
899
|
-
const { provider } = getModelAndProviderFromConfig(config);
|
|
900
|
-
switch (provider) {
|
|
901
|
-
case 'openai':
|
|
902
|
-
return config.openAIApiKey || getDefaultServiceApiKey(config);
|
|
903
|
-
default:
|
|
904
|
-
return getDefaultServiceApiKey(config);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
/**
|
|
908
|
-
* Retrieves the default service API key from the given configuration.
|
|
909
|
-
* @param config The configuration object.
|
|
910
|
-
* @returns The default service API key.
|
|
911
|
-
*/
|
|
912
|
-
function getDefaultServiceApiKey(config) {
|
|
913
|
-
const service = config.service;
|
|
914
|
-
if (service.authentication.type === 'APIKey') {
|
|
915
|
-
return service.authentication.credentials?.apiKey;
|
|
916
|
-
}
|
|
917
|
-
else if (service.authentication.type === 'OAuth') {
|
|
918
|
-
return service.authentication.credentials?.token;
|
|
919
|
-
}
|
|
920
|
-
return '';
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* Retrieves the default service configuration based on the provided alias and optional model.
|
|
924
|
-
* @param alias - The alias of the service.
|
|
925
|
-
* @param model - The optional model to be used.
|
|
926
|
-
* @returns The default service configuration.
|
|
927
|
-
* @throws Error if the alias is invalid or undefined.
|
|
928
|
-
*/
|
|
929
|
-
function getDefaultServiceConfigFromAlias(alias, model) {
|
|
930
|
-
if (!alias) {
|
|
931
|
-
throw new Error('Invalid alias: undefined');
|
|
932
|
-
}
|
|
933
|
-
switch (alias) {
|
|
934
|
-
case 'openai':
|
|
935
|
-
return {
|
|
936
|
-
...DEFAULT_OPENAI_LLM_SERVICE,
|
|
937
|
-
model: model || DEFAULT_OPENAI_LLM_SERVICE.model,
|
|
938
|
-
};
|
|
939
|
-
case 'ollama':
|
|
940
|
-
return {
|
|
941
|
-
...DEFAULT_OLLAMA_LLM_SERVICE,
|
|
942
|
-
model: model || DEFAULT_OLLAMA_LLM_SERVICE.model,
|
|
943
|
-
};
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
|
|
947
1267
|
/**
|
|
948
1268
|
* Get LLM Model Based on Configuration
|
|
949
1269
|
*
|
|
@@ -1520,7 +1840,7 @@ const builder$2 = (yargs) => {
|
|
|
1520
1840
|
|
|
1521
1841
|
var commit = {
|
|
1522
1842
|
command: 'commit',
|
|
1523
|
-
desc: '
|
|
1843
|
+
desc: 'Write a commit message summarizing the staged changes.',
|
|
1524
1844
|
builder: builder$2,
|
|
1525
1845
|
handler: commandExecutor(handler$2),
|
|
1526
1846
|
options: options$2,
|
|
@@ -2070,17 +2390,17 @@ y.command([commit.command, '$0'], commit.desc,
|
|
|
2070
2390
|
// TODO: fix type on builder
|
|
2071
2391
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2072
2392
|
// @ts-ignore
|
|
2073
|
-
commit.builder, commit.handler);
|
|
2393
|
+
commit.builder, commit.handler).options(commit.options);
|
|
2074
2394
|
y.command(changelog.command, changelog.desc,
|
|
2075
2395
|
// TODO: fix type on builder
|
|
2076
2396
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2077
2397
|
// @ts-ignore
|
|
2078
|
-
changelog.builder, changelog.handler);
|
|
2398
|
+
changelog.builder, changelog.handler).options(changelog.options);
|
|
2079
2399
|
y.command(init.command, init.desc,
|
|
2080
2400
|
// TODO: fix type on builder
|
|
2081
2401
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
2082
2402
|
// @ts-ignore
|
|
2083
|
-
init.builder, init.handler);
|
|
2403
|
+
init.builder, init.handler).options(init.options);
|
|
2084
2404
|
y.parse(process.argv.slice(2));
|
|
2085
2405
|
|
|
2086
2406
|
exports.changelog = changelog;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-coco",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"description": "zero-effort git commits with coco.",
|
|
5
5
|
"author": "gfargo <ghfargo@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"start": "npm run dev",
|
|
27
27
|
"dev": "tsx watch src/index.ts",
|
|
28
28
|
"build": "rollup -c",
|
|
29
|
-
"build:schema": "node bin/generateSchema.
|
|
29
|
+
"build:schema": "node bin/generateSchema.mjs",
|
|
30
30
|
"build:watch": "rollup -c -w",
|
|
31
31
|
"clean": "rimraf dist && rimraf coverage",
|
|
32
32
|
"lint": "eslint src",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"coco:esm": "node dist/index.esm.mjs"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@rollup/plugin-commonjs": "^
|
|
46
|
+
"@rollup/plugin-commonjs": "^26.0.1",
|
|
47
47
|
"@rollup/plugin-eslint": "^9.0.5",
|
|
48
48
|
"@rollup/plugin-json": "^6.0.0",
|
|
49
49
|
"@rollup/plugin-node-resolve": "^15.1.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@typescript-eslint/parser": "^7.13.1",
|
|
61
61
|
"eslint": "^8.54.0",
|
|
62
62
|
"eslint-formatter-pretty": "^6.0.0",
|
|
63
|
-
"jest": "^29.
|
|
63
|
+
"jest": "^29.7.0",
|
|
64
64
|
"jest-mock": "^29.5.0",
|
|
65
65
|
"release-it": "^17.0.0",
|
|
66
66
|
"rimraf": "^5.0.1",
|
|
@@ -82,16 +82,18 @@
|
|
|
82
82
|
"dependencies": {
|
|
83
83
|
"@inquirer/prompts": "3.3.0",
|
|
84
84
|
"@jridgewell/sourcemap-codec": "^1.4.15",
|
|
85
|
+
"ajv": "^8.16.0",
|
|
86
|
+
"ajv-formats": "^3.0.1",
|
|
85
87
|
"chalk": "4.1.2",
|
|
86
88
|
"diff": "5.2.0",
|
|
87
89
|
"ini": "4.1.1",
|
|
88
90
|
"langchain": "0.0.196",
|
|
89
|
-
"minimatch": "9.0.
|
|
91
|
+
"minimatch": "9.0.4",
|
|
90
92
|
"ora": "5.4.1",
|
|
91
93
|
"p-queue": "5.0.0",
|
|
92
94
|
"performance-now": "2.1.0",
|
|
93
95
|
"pretty-ms": "7.0.1",
|
|
94
|
-
"simple-git": "3.
|
|
96
|
+
"simple-git": "3.25.0",
|
|
95
97
|
"tiktoken": "^1.0.15",
|
|
96
98
|
"yargs": "17.7.2"
|
|
97
99
|
}
|