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.
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.mjs +1074 -0
- package/dist/index.esm.mjs.map +1 -0
- package/dist/index.js +1098 -0
- package/dist/lib/config/default.d.ts +7 -0
- package/dist/lib/config/index.d.ts +21 -0
- package/dist/lib/config/services/env.d.ts +8 -0
- package/dist/lib/config/services/git.d.ts +8 -0
- package/dist/lib/config/services/ignore.d.ts +15 -0
- package/dist/lib/config/services/project.d.ts +8 -0
- package/dist/lib/config/services/xdg.d.ts +8 -0
- package/dist/lib/config/services/yargs.d.ts +25 -0
- package/dist/lib/config/types.d.ts +63 -0
- package/dist/lib/langchain/chains/llm.d.ts +6 -0
- package/dist/lib/langchain/chains/summarize.d.ts +11 -0
- package/dist/lib/langchain/prompts/commitDefault.d.ts +3 -0
- package/dist/lib/langchain/prompts/summarize.d.ts +3 -0
- package/dist/lib/langchain/utils.d.ts +20 -0
- package/dist/lib/parsers/default/fileChangeParser.d.ts +2 -0
- package/dist/lib/parsers/default/utils/collectDiffs.d.ts +8 -0
- package/dist/lib/parsers/default/utils/createDiffTree.d.ts +12 -0
- package/dist/lib/parsers/default/utils/parseFileDiff.d.ts +4 -0
- package/dist/lib/parsers/default/utils/summarizeDiffs.d.ts +24 -0
- package/dist/lib/parsers/noResult.d.ts +8 -0
- package/dist/lib/types.d.ts +34 -0
- package/dist/lib/ui.d.ts +2 -0
- package/dist/lib/utils/getPathFromFilePath.d.ts +6 -0
- package/dist/lib/utils/getTokenizer.d.ts +9 -0
- package/dist/lib/utils/getTruncatedFilePath.d.ts +1 -0
- package/dist/lib/utils/git/constants.d.ts +1 -0
- package/dist/lib/utils/git/createCommit.d.ts +2 -0
- package/dist/lib/utils/git/getChanges.d.ts +43 -0
- package/dist/lib/utils/git/getStatus.d.ts +3 -0
- package/dist/lib/utils/git/getSummaryText.d.ts +2 -0
- package/dist/lib/utils/git/parsePatches.d.ts +18 -0
- package/dist/lib/utils/logger.d.ts +23 -0
- package/dist/lib/utils/readFile.d.ts +3 -0
- package/dist/lib/utils/removeUndefined.d.ts +9 -0
- package/dist/stats.html +5305 -0
- package/dist/types.d.ts +2 -0
- package/package.json +92 -0
|
@@ -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,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,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,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,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,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,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
|
+
}
|
package/dist/lib/ui.d.ts
ADDED
|
@@ -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,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,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
|
+
}
|