git-coco 0.1.0

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.esm.mjs +1074 -0
  5. package/dist/index.esm.mjs.map +1 -0
  6. package/dist/index.js +1098 -0
  7. package/dist/lib/config/default.d.ts +7 -0
  8. package/dist/lib/config/index.d.ts +21 -0
  9. package/dist/lib/config/services/env.d.ts +8 -0
  10. package/dist/lib/config/services/git.d.ts +8 -0
  11. package/dist/lib/config/services/ignore.d.ts +15 -0
  12. package/dist/lib/config/services/project.d.ts +8 -0
  13. package/dist/lib/config/services/xdg.d.ts +8 -0
  14. package/dist/lib/config/services/yargs.d.ts +25 -0
  15. package/dist/lib/config/types.d.ts +63 -0
  16. package/dist/lib/langchain/chains/llm.d.ts +6 -0
  17. package/dist/lib/langchain/chains/summarize.d.ts +11 -0
  18. package/dist/lib/langchain/prompts/commitDefault.d.ts +3 -0
  19. package/dist/lib/langchain/prompts/summarize.d.ts +3 -0
  20. package/dist/lib/langchain/utils.d.ts +20 -0
  21. package/dist/lib/parsers/default/fileChangeParser.d.ts +2 -0
  22. package/dist/lib/parsers/default/utils/collectDiffs.d.ts +8 -0
  23. package/dist/lib/parsers/default/utils/createDiffTree.d.ts +12 -0
  24. package/dist/lib/parsers/default/utils/parseFileDiff.d.ts +4 -0
  25. package/dist/lib/parsers/default/utils/summarizeDiffs.d.ts +24 -0
  26. package/dist/lib/parsers/noResult.d.ts +8 -0
  27. package/dist/lib/types.d.ts +34 -0
  28. package/dist/lib/ui.d.ts +2 -0
  29. package/dist/lib/utils/getPathFromFilePath.d.ts +6 -0
  30. package/dist/lib/utils/getTokenizer.d.ts +9 -0
  31. package/dist/lib/utils/getTruncatedFilePath.d.ts +1 -0
  32. package/dist/lib/utils/git/constants.d.ts +1 -0
  33. package/dist/lib/utils/git/createCommit.d.ts +2 -0
  34. package/dist/lib/utils/git/getChanges.d.ts +43 -0
  35. package/dist/lib/utils/git/getStatus.d.ts +3 -0
  36. package/dist/lib/utils/git/getSummaryText.d.ts +2 -0
  37. package/dist/lib/utils/git/parsePatches.d.ts +18 -0
  38. package/dist/lib/utils/logger.d.ts +23 -0
  39. package/dist/lib/utils/readFile.d.ts +3 -0
  40. package/dist/lib/utils/removeUndefined.d.ts +9 -0
  41. package/dist/stats.html +5305 -0
  42. package/dist/types.d.ts +2 -0
  43. package/package.json +92 -0
@@ -0,0 +1,7 @@
1
+ import { Config } from './types';
2
+ /**
3
+ * Default Config
4
+ *
5
+ * @type {Config}
6
+ */
7
+ export declare const DEFAULT_CONFIG: Config;
@@ -0,0 +1,21 @@
1
+ import { Config } from './types';
2
+ /**
3
+ * Load application config
4
+ *
5
+ * Merge config from multiple sources.
6
+ *
7
+ * \* Order of precedence:
8
+ * \* 1. Command line flags
9
+ * \* 2. Environment variables
10
+ * \* 3. Project config
11
+ * \* 4. Git config
12
+ * \* 5. XDG config
13
+ * \* 6. .gitignore
14
+ * \* 7. .ignore
15
+ * \* 8. Default config
16
+ *
17
+ * @returns {Config} application config
18
+ **/
19
+ export declare function loadConfig(): Config;
20
+ declare const config: Config;
21
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { Config } from '../types';
2
+ /**
3
+ * Load environment variables
4
+ *
5
+ * @param {Config} config
6
+ * @returns {Config} Updated config
7
+ **/
8
+ export declare function loadEnvConfig(config: Config): Config;
@@ -0,0 +1,8 @@
1
+ import { Config } from '../types';
2
+ /**
3
+ * Load git profile config (from ~/.gitconfig)
4
+ *
5
+ * @param {Config} config
6
+ * @returns {Config} Updated config
7
+ **/
8
+ export declare function loadGitConfig(config: Config): Config;
@@ -0,0 +1,15 @@
1
+ import { Config } from '../types';
2
+ /**
3
+ * Load .gitignore in project root
4
+ *
5
+ * @param {Config} config
6
+ * @returns
7
+ */
8
+ export declare function loadGitignore(config: Config): Config;
9
+ /**
10
+ * Load .ignore in project root
11
+ *
12
+ * @param {Config} config
13
+ * @returns
14
+ */
15
+ export declare function loadIgnore(config: Config): Config;
@@ -0,0 +1,8 @@
1
+ import { Config } from '../types';
2
+ /**
3
+ * Load project config
4
+ *
5
+ * @param {Config} config
6
+ * @returns {Config} Updated config
7
+ **/
8
+ export declare function loadProjectConfig(config: Config): Config;
@@ -0,0 +1,8 @@
1
+ import { Config } from '../types';
2
+ /**
3
+ * Load XDG config
4
+ *
5
+ * @param {Config} config
6
+ * @returns {Config} Updated config
7
+ */
8
+ export declare function loadXDGConfig(config: Config): Config;
@@ -0,0 +1,25 @@
1
+ import yargs from 'yargs';
2
+ import { Config } from '../types';
3
+ /**
4
+ * Command line options via yargs
5
+ */
6
+ export declare const options: Record<string, yargs.Options>;
7
+ /**
8
+ * Load command line flags via yargs
9
+ *
10
+ * @returns {Partial<Config>} Updated config
11
+ */
12
+ export declare const loadArgv: () => {
13
+ [x: string]: unknown;
14
+ _: (string | number)[];
15
+ $0: string;
16
+ };
17
+ /**
18
+ * Load command line flags
19
+ *
20
+ * Note: Arugments are parsed using yargs.
21
+ *
22
+ * @param {Config} config
23
+ * @returns {Config} Updated config
24
+ **/
25
+ export declare function loadCmdLineFlags(config: Config): Config;
@@ -0,0 +1,63 @@
1
+ export interface Config {
2
+ /**
3
+ * The OpenAI API key.
4
+ */
5
+ openAIApiKey: string;
6
+ /**
7
+ * The maximum number of tokens per request.
8
+ *
9
+ * @default 1024
10
+ */
11
+ tokenLimit?: number;
12
+ /**
13
+ * The prompt text used for generating results.
14
+ */
15
+ prompt?: string;
16
+ /**
17
+ * The temperature value controls the randomness of the generated output.
18
+ * Higher values (e.g., 0.8) make the output more random, while lower values (e.g., 0.2) make it more deterministic.
19
+ *
20
+ * @default 0.4
21
+ */
22
+ temperature?: number;
23
+ /**
24
+ * The output destination for the generated result.
25
+ * - 'stdout': Prints the result to the standard output. This is the default behavior.
26
+ * - 'interactive': Provides an interactive prompt for editing the result & committing the changes.
27
+ *
28
+ * @default 'stdout'
29
+ */
30
+ mode?: 'stdout' | 'interactive';
31
+ /**
32
+ * Enable verbose logging.
33
+ *
34
+ * @default false
35
+ */
36
+ verbose?: boolean;
37
+ /**
38
+ * Open the commit message in an editor for editing before proceeding.
39
+ *
40
+ * @default false
41
+ */
42
+ openInEditor?: boolean;
43
+ /**
44
+ * The prompt text used specifically for generating summaries of large files.
45
+ */
46
+ summarizePrompt?: string;
47
+ /**
48
+ * An array of file paths or patterns to be ignored during processing.
49
+ *
50
+ * Note: This is a list of patterns interpreted by the `minimatch` library.
51
+ * @see https://github.com/isaacs/minimatch
52
+ *
53
+ * @example ['package-lock.json', 'node_modules']
54
+ * @default ['package-lock.json', contents of .gitignore, contents of .ignore]
55
+ */
56
+ ignoredFiles?: string[];
57
+ /**
58
+ * An array of file extensions to be ignored during processing.
59
+ *
60
+ * @default ['.map', '.lock']
61
+ */
62
+ ignoredExtensions?: string[];
63
+ }
@@ -0,0 +1,6 @@
1
+ import { LLMChainInput } from 'langchain/chains';
2
+ type LLMInput = {
3
+ variables: Record<string, unknown>;
4
+ } & LLMChainInput;
5
+ export declare const llm: ({ llm, prompt, variables }: LLMInput) => Promise<any>;
6
+ export {};
@@ -0,0 +1,11 @@
1
+ import { MapReduceDocumentsChain, RefineDocumentsChain, StuffDocumentsChain } from 'langchain/chains';
2
+ import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
3
+ import { DocumentInput } from 'langchain/document';
4
+ export type SummarizeContext = {
5
+ textSplitter: RecursiveCharacterTextSplitter;
6
+ chain: StuffDocumentsChain | MapReduceDocumentsChain | RefineDocumentsChain;
7
+ options?: {
8
+ returnIntermediateSteps?: boolean;
9
+ };
10
+ };
11
+ export declare function summarize(documents: DocumentInput[], { chain, textSplitter, options }: SummarizeContext): Promise<string>;
@@ -0,0 +1,3 @@
1
+ import { PromptTemplate } from 'langchain/prompts';
2
+ export declare const inputVariables: string[];
3
+ export declare const COMMIT_PROMPT: PromptTemplate;
@@ -0,0 +1,3 @@
1
+ import { PromptTemplate } from 'langchain/prompts';
2
+ export declare const inputVariables: string[];
3
+ export declare const SUMMARIZE_PROMPT: PromptTemplate;
@@ -0,0 +1,20 @@
1
+ import { HuggingFaceInference } from 'langchain/llms/hf';
2
+ import { PromptTemplate } from 'langchain/prompts';
3
+ import { SummarizationChainParams } from 'langchain/chains';
4
+ import { BaseLLMParams } from 'langchain/llms/base';
5
+ import { AzureOpenAIInput, OpenAIInput, OpenAI } from 'langchain/llms/openai';
6
+ import { RecursiveCharacterTextSplitter, RecursiveCharacterTextSplitterParams } from 'langchain/text_splitter';
7
+ import { ConfigurationParameters } from 'openai';
8
+ export declare function getModel(fields?: (Partial<OpenAIInput> & Partial<AzureOpenAIInput> & BaseLLMParams & {
9
+ configuration?: ConfigurationParameters | undefined;
10
+ }) | undefined, configuration?: ConfigurationParameters | undefined): OpenAI | HuggingFaceInference;
11
+ export declare function getTextSplitter(options?: Partial<RecursiveCharacterTextSplitterParams>): RecursiveCharacterTextSplitter;
12
+ export declare function getChain(model: ReturnType<typeof getModel>, options?: SummarizationChainParams): import("langchain/chains").StuffDocumentsChain | import("langchain/chains").MapReduceDocumentsChain | import("langchain/chains").RefineDocumentsChain;
13
+ type CreatePromptInput = {
14
+ template?: string;
15
+ variables: string[];
16
+ fallback?: PromptTemplate;
17
+ };
18
+ export declare function getPrompt({ template, variables, fallback }: CreatePromptInput): PromptTemplate;
19
+ export declare function validatePromptTemplate(text: string, inputVariables: string[]): string | true;
20
+ export {};
@@ -0,0 +1,2 @@
1
+ import { BaseParser } from '../../types';
2
+ export declare const fileChangeParser: BaseParser;
@@ -0,0 +1,8 @@
1
+ import GPT3Tokenizer from 'gpt3-tokenizer';
2
+ import { DiffNode, FileChange } from '../../../types';
3
+ import { Logger } from '../../../utils/logger';
4
+ import { DiffTreeNode } from './createDiffTree';
5
+ /**
6
+ * Asynchronously collect diffs for a given node and its children.
7
+ */
8
+ export declare function collectDiffs(node: DiffTreeNode, getFileDiff: (change: FileChange) => Promise<string>, tokenizer: GPT3Tokenizer, logger?: Logger): Promise<DiffNode>;
@@ -0,0 +1,12 @@
1
+ import { FileChange } from '../../../types';
2
+ export declare class DiffTreeNode {
3
+ path: string[];
4
+ files: FileChange[];
5
+ children: Map<string, DiffTreeNode>;
6
+ constructor(path?: string[]);
7
+ addFile(file: FileChange): void;
8
+ addChild(part: string, node: DiffTreeNode): void;
9
+ getChild(part: string): DiffTreeNode | undefined;
10
+ getPath(): string;
11
+ }
12
+ export declare const createDiffTree: (changes: FileChange[]) => DiffTreeNode;
@@ -0,0 +1,4 @@
1
+ import { Repository, Tree, Index } from 'nodegit';
2
+ import { FileChange } from '../../../types';
3
+ import { Logger } from '../../../utils/logger';
4
+ export declare const parseFileDiff: (nodeFile: FileChange, repo: Repository, headTree: Tree, index: Index, logger: Logger) => Promise<string>;
@@ -0,0 +1,24 @@
1
+ import GPT3Tokenizer from 'gpt3-tokenizer';
2
+ import { DirectoryDiff, DiffNode } from '../../../types';
3
+ import { SummarizeContext } from '../../../langchain/chains/summarize';
4
+ /**
5
+ * Create groups from a given node info.
6
+ * @param {DiffNode} node - The node info to start grouping.
7
+ * @returns {DirectoryDiff[]} The groups created.
8
+ */
9
+ export declare function createDirectoryDiffs(node: DiffNode): DirectoryDiff[];
10
+ type SummarizeDirectoryDiffOptions = {
11
+ tokenizer: GPT3Tokenizer;
12
+ } & SummarizeContext;
13
+ /**
14
+ * Summarize a directory diff asynchronously.
15
+ */
16
+ export declare function summarizeDirectoryDiff(directory: DirectoryDiff, { chain, textSplitter, tokenizer }: SummarizeDirectoryDiffOptions): Promise<DirectoryDiff>;
17
+ declare const defaultOutputCallback: (group: DirectoryDiff) => string;
18
+ type SummarizeDiffsOptions = {
19
+ tokenizer: GPT3Tokenizer;
20
+ maxTokens: number;
21
+ handleOutput?: typeof defaultOutputCallback;
22
+ } & SummarizeContext;
23
+ export declare function summarizeDiffs(rootDiffNode: DiffNode, { tokenizer, maxTokens, textSplitter, chain, handleOutput, }: SummarizeDiffsOptions): Promise<string>;
24
+ export {};
@@ -0,0 +1,8 @@
1
+ import { Repository } from 'nodegit';
2
+ import { Logger } from '../utils/logger';
3
+ type NoResultInput = {
4
+ repo: Repository;
5
+ logger: Logger;
6
+ };
7
+ export declare const noResult: ({ repo, logger }: NoResultInput) => Promise<never>;
8
+ export {};
@@ -0,0 +1,34 @@
1
+ import GPT3Tokenizer from 'gpt3-tokenizer';
2
+ import { Repository } from 'nodegit';
3
+ import { getModel } from './langchain/utils';
4
+ export type FileChangeStatus = 'modified' | 'renamed' | 'added' | 'new file' | 'deleted' | 'untracked' | 'unknown';
5
+ export interface FileChange {
6
+ summary: string;
7
+ filepath: string;
8
+ oldFilepath?: string;
9
+ status: FileChangeStatus;
10
+ }
11
+ export interface FileDiff {
12
+ file: string;
13
+ diff: string;
14
+ summary: string;
15
+ tokenCount: number;
16
+ }
17
+ export interface DiffNode {
18
+ path: string;
19
+ diffs: FileDiff[];
20
+ children: DiffNode[];
21
+ }
22
+ export interface DirectoryDiff {
23
+ path: string;
24
+ diffs: FileDiff[];
25
+ summary?: string;
26
+ tokenCount: number;
27
+ }
28
+ export interface BaseParser {
29
+ (changes: FileChange[], options: {
30
+ tokenizer: GPT3Tokenizer;
31
+ model: ReturnType<typeof getModel>;
32
+ repo: Repository;
33
+ }): Promise<string>;
34
+ }
@@ -0,0 +1,2 @@
1
+ export declare const logCommit: (commit: string) => void;
2
+ export declare const logSuccess: () => void;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Extract the path from a file path string.
3
+ * @param {string} filePath - The full file path.
4
+ * @returns {string} The path portion of the file path.
5
+ */
6
+ export declare function getPathFromFilePath(filePath: string): string;
@@ -0,0 +1,9 @@
1
+ import GPT3NodeTokenizer from "gpt3-tokenizer";
2
+ /**
3
+ * Wrapper around GPT3NodeTokenizer to handle default export.
4
+ *
5
+ * @see https://github.com/botisan-ai/gpt3-tokenizer/issues/18
6
+ *
7
+ * @returns {GPT3NodeTokenizer} The GPT3NodeTokenizer instance.
8
+ */
9
+ export declare const getTokenizer: () => GPT3NodeTokenizer;
@@ -0,0 +1 @@
1
+ export declare function getTruncatedFilePath(filePath: string, maxLength?: number): string;
@@ -0,0 +1 @@
1
+ export declare const EMPTY_GIT_TREE_HASH = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
@@ -0,0 +1,2 @@
1
+ import * as nodegit from 'nodegit';
2
+ export declare function createCommit(commitMsg: string, repo: nodegit.Repository): Promise<nodegit.Oid | null>;
@@ -0,0 +1,43 @@
1
+ import { Repository } from 'nodegit';
2
+ import { FileChange } from '../../types';
3
+ export type GetChangesArgs = {
4
+ ignoreUnstaged?: boolean;
5
+ ignoreUntracked?: boolean;
6
+ ignoredFiles?: string[];
7
+ ignoredExtensions?: string[];
8
+ };
9
+ export type GetChangesResult = {
10
+ staged: FileChange[];
11
+ unstaged?: FileChange[];
12
+ untracked?: FileChange[];
13
+ };
14
+ /**
15
+ * The 'git status' for coco
16
+ *
17
+ * Get paths of changed files in the Git repository, excluding ignored files and extensions.
18
+ *
19
+ * @param {string[]} [options.ignoredFiles] - An optional array of file patterns to ignore.
20
+ * If not provided, it defaults to the `ignoredFiles` configuration value from the app's config.
21
+ * @param {string[]} [options.ignoredExtensions] - An optional array of file extensions to ignore.
22
+ * If not provided, it defaults to the `ignoredExtensions` configuration value from the app's config.
23
+ * @returns {Promise<GetChangesResult>} A Promise that resolves to an array of changed file paths.
24
+ *
25
+ * @example
26
+ * const changes = await getStagedChanges()
27
+ * console.log(changes)
28
+ * // {
29
+ * // staged: [
30
+ * // {
31
+ * // filepath: 'src/index.ts',
32
+ * // action: 'modified'
33
+ * // },
34
+ * // ],
35
+ * // unstaged: [
36
+ * // {
37
+ * // filepath: 'src/index.test.ts',
38
+ * // action: 'added'
39
+ * // }
40
+ * // ]
41
+ * // }
42
+ */
43
+ export declare function getChanges(repo: Repository, options?: GetChangesArgs): Promise<GetChangesResult>;
@@ -0,0 +1,3 @@
1
+ import { ConvenientPatch } from "nodegit";
2
+ import { FileChangeStatus } from "../../types";
3
+ export declare const getStatus: (patch: ConvenientPatch) => FileChangeStatus;
@@ -0,0 +1,2 @@
1
+ import { ConvenientPatch } from 'nodegit';
2
+ export declare const getSummaryText: (patch: ConvenientPatch) => string;
@@ -0,0 +1,18 @@
1
+ import { ConvenientPatch } from 'nodegit';
2
+ import { FileChange } from '../../types';
3
+ type ParsePatchesOptions = {
4
+ ignoredFiles?: string[];
5
+ ignoredExtensions?: string[];
6
+ };
7
+ /**
8
+ * Parse patches from a git diff.
9
+ *
10
+ * @param {ConvenientPatch[]} patches - An array of git patches.
11
+ * @param {string[]} [options.ignoredFiles] - An optional array of file patterns to ignore.
12
+ * If not provided, it defaults to the `ignoredFiles` configuration value from the app's config.
13
+ * @param {string[]} [options.ignoredExtensions] - An optional array of file extensions to ignore.
14
+ * If not provided, it defaults to the `ignoredExtensions` configuration value from the app's config.
15
+ * @returns {Promise<FileChange[]>} A Promise that resolves to an array of file changes.
16
+ **/
17
+ export declare const parsePatches: (patches: ConvenientPatch[], { ignoredFiles, ignoredExtensions, }: ParsePatchesOptions) => Promise<FileChange[]>;
18
+ export {};
@@ -0,0 +1,23 @@
1
+ import { type Color } from 'chalk';
2
+ export interface LoggerOptions {
3
+ color?: typeof Color;
4
+ }
5
+ export interface SpinnerOptions {
6
+ mode?: undefined | 'stop' | 'succeed' | 'warn' | 'fail';
7
+ color?: typeof Color;
8
+ }
9
+ export interface Config {
10
+ verbose?: boolean;
11
+ }
12
+ export declare class Logger {
13
+ private config;
14
+ private timerStart;
15
+ private spinner;
16
+ constructor(config: Config);
17
+ log(message: string, options?: LoggerOptions): Logger;
18
+ verbose(message: string, options?: LoggerOptions): Logger;
19
+ startTimer(): Logger;
20
+ stopTimer(message?: string, options?: LoggerOptions): Logger;
21
+ startSpinner(message: string, options?: Omit<SpinnerOptions, 'mode'>): Logger;
22
+ stopSpinner(message?: string | undefined, options?: SpinnerOptions): Logger;
23
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="node" />
2
+ import * as fs from 'fs';
3
+ export declare const readFile: typeof fs.readFile.__promisify__;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Returns a new object with all undefined keys removed
3
+ *
4
+ * @param obj Object to remove undefined keys from
5
+ * @returns
6
+ */
7
+ export declare function removeUndefined(obj: Record<string, unknown>): {
8
+ [k: string]: unknown;
9
+ };