git-coco 0.32.0 → 0.34.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/README.md +35 -1
- package/dist/index.d.ts +129 -14
- package/dist/index.esm.mjs +8686 -1655
- package/dist/index.js +8702 -1670
- package/package.json +21 -8
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
[](https://github.com/gfargo/coco/tree/main)
|
|
11
11
|
[](https://discord.gg/KGu9nE9Ejx)
|
|
12
12
|
|
|
13
|
-
An AI-powered git assistant that generates meaningful commit messages, creates changelogs, and streamlines your development workflow.
|
|
13
|
+
An AI-powered git assistant that generates meaningful commit messages, creates changelogs, explores repository history, and streamlines your development workflow.
|
|
14
14
|
|
|
15
15
|
**✨ Key Features:**
|
|
16
16
|
|
|
@@ -18,6 +18,7 @@ An AI-powered git assistant that generates meaningful commit messages, creates c
|
|
|
18
18
|
- 📋 **Conventional Commits** - Full support with automatic validation and formatting
|
|
19
19
|
- 🔧 **Commitlint Integration** - Seamless integration with your existing commitlint configuration
|
|
20
20
|
- 🏠 **Local AI Support** - Run completely offline with Ollama (no API costs, full privacy)
|
|
21
|
+
- 🖥️ **Coco UI Git Workstation** - Seven top-level views (history, status, diff, compose, branches, tags, stash) reachable via `g`-prefixed chords, with an interactive command palette (`:`) and global search (`/`)
|
|
21
22
|
- 📦 **Package Manager Friendly** - Works with npm, yarn, and pnpm
|
|
22
23
|
- 👥 **Team Ready** - Shared configurations and enterprise deployment
|
|
23
24
|
|
|
@@ -44,6 +45,8 @@ coco -i
|
|
|
44
45
|
- **`coco changelog`** - Create changelogs from commit history
|
|
45
46
|
- **`coco recap`** - Summarize recent changes and activity
|
|
46
47
|
- **`coco review`** - AI-powered code review of your changes
|
|
48
|
+
- **`coco log`** - Explore commit history with graph, filters, JSON output, and commit details
|
|
49
|
+
- **`coco ui`** - Open the full-screen Git workstation TUI
|
|
47
50
|
- **`coco init`** - Interactive setup wizard
|
|
48
51
|
|
|
49
52
|
## Usage Examples
|
|
@@ -85,8 +88,32 @@ coco recap --yesterday
|
|
|
85
88
|
|
|
86
89
|
# Code review before committing
|
|
87
90
|
coco review
|
|
91
|
+
|
|
92
|
+
# Explore commit history
|
|
93
|
+
coco ui
|
|
94
|
+
coco ui --view status
|
|
95
|
+
coco log --limit 20
|
|
96
|
+
coco log -i
|
|
97
|
+
coco log --view full --limit 20
|
|
98
|
+
coco log --all --limit 20
|
|
99
|
+
coco log --author "Grace Hopper" --path src
|
|
100
|
+
coco log --commit HEAD
|
|
101
|
+
coco log --format json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Navigating the TUI
|
|
105
|
+
|
|
106
|
+
`coco ui` and `coco log -i` share a chord-driven navigation model. Press `g` and then a second key to jump anywhere; `<` (or `Esc`) pops the navigation stack back.
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
g h history g c compose < back
|
|
110
|
+
g s status g b branches Esc back / close modal
|
|
111
|
+
g d diff g t tags ? help overlay
|
|
112
|
+
g z stash : command palette
|
|
88
113
|
```
|
|
89
114
|
|
|
115
|
+
The command palette (`:`) is an interactive launcher with fuzzy filter and recently-used at the top — every keybinding and workflow action is reachable from there. `/` searches the active view (history, branches, tags, or stash). See the [Coco UI](https://github.com/gfargo/coco/wiki/Coco-UI) wiki page for the full keymap.
|
|
116
|
+
|
|
90
117
|
## Configuration
|
|
91
118
|
|
|
92
119
|
Configure `coco` for your workflow with the interactive setup wizard:
|
|
@@ -109,6 +136,11 @@ coco init --scope project
|
|
|
109
136
|
{
|
|
110
137
|
"mode": "interactive",
|
|
111
138
|
"conventionalCommits": true,
|
|
139
|
+
"logTui": {
|
|
140
|
+
"theme": {
|
|
141
|
+
"preset": "catppuccin"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
112
144
|
"service": {
|
|
113
145
|
"provider": "openai",
|
|
114
146
|
"model": "gpt-4o"
|
|
@@ -126,6 +158,8 @@ For comprehensive guides, advanced usage, and detailed configuration options, vi
|
|
|
126
158
|
- **[Getting Started](https://github.com/gfargo/coco/wiki/Getting-Started)** - Complete beginner's guide from installation to first commit
|
|
127
159
|
- **[Command Reference](https://github.com/gfargo/coco/wiki/Command-Reference)** - Detailed command options and examples
|
|
128
160
|
- **[Configuration Overview](https://github.com/gfargo/coco/wiki/Config-Overview)** - All configuration options and setup methods
|
|
161
|
+
- **[Coco UI](https://github.com/gfargo/coco/wiki/Coco-UI)** - GitKraken-style terminal workstation guide
|
|
162
|
+
- **[Interactive Log TUI](https://github.com/gfargo/coco/wiki/Interactive-Log-TUI)** - History-focused `coco log -i` guide
|
|
129
163
|
- **[Team Collaboration](https://github.com/gfargo/coco/wiki/Team-Collaboration)** - Enterprise deployment and team adoption strategies
|
|
130
164
|
|
|
131
165
|
**Advanced Resources:**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,49 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as yargs from 'yargs';
|
|
3
3
|
import { Arguments } from 'yargs';
|
|
4
|
-
import { OllamaInput, ChatOllama } from '@langchain/ollama';
|
|
5
|
-
import { BaseLLMParams } from '@langchain/core/language_models/llms';
|
|
6
4
|
import * as _langchain_openai from '@langchain/openai';
|
|
7
|
-
import { TiktokenModel,
|
|
5
|
+
import { TiktokenModel, ChatOpenAI } from '@langchain/openai';
|
|
8
6
|
import { SimpleGit } from 'simple-git';
|
|
9
7
|
import { ChatAnthropic } from '@langchain/anthropic';
|
|
8
|
+
import { ChatOllama } from '@langchain/ollama';
|
|
10
9
|
import { Color } from 'chalk';
|
|
11
10
|
import { TiktokenModel as TiktokenModel$1 } from 'tiktoken';
|
|
12
11
|
|
|
12
|
+
type LogInkBorderStyle = 'round' | 'single' | 'classic';
|
|
13
|
+
type LogInkThemePreset = 'default' | 'monochrome' | 'catppuccin' | 'gruvbox';
|
|
14
|
+
type LogInkThemeColors = {
|
|
15
|
+
accent?: string;
|
|
16
|
+
border?: string;
|
|
17
|
+
danger?: string;
|
|
18
|
+
focusBorder?: string;
|
|
19
|
+
gitAdded?: string;
|
|
20
|
+
gitDeleted?: string;
|
|
21
|
+
gitModified?: string;
|
|
22
|
+
info?: string;
|
|
23
|
+
muted?: string;
|
|
24
|
+
selection?: string;
|
|
25
|
+
success?: string;
|
|
26
|
+
warning?: string;
|
|
27
|
+
};
|
|
28
|
+
type LogInkThemeConfig = {
|
|
29
|
+
ascii?: boolean;
|
|
30
|
+
borderStyle?: LogInkBorderStyle;
|
|
31
|
+
colors?: LogInkThemeColors;
|
|
32
|
+
preset?: LogInkThemePreset;
|
|
33
|
+
};
|
|
34
|
+
|
|
13
35
|
type LLMProvider = 'openai' | 'ollama' | 'anthropic';
|
|
36
|
+
type DynamicModelTask = 'summarize' | 'commit' | 'changelog' | 'review' | 'recap' | 'repair' | 'largeDiff';
|
|
37
|
+
type DynamicModelPreference = 'cost' | 'balanced' | 'quality';
|
|
14
38
|
type OpenAIModel = TiktokenModel | 'gpt-4o-mini' | 'gpt-4o' | 'gpt-4.1' | 'gpt-4.1-mini' | 'gpt-4.1-nano';
|
|
15
39
|
type AnthropicModel = 'claude-sonnet-4-0' | 'claude-3-7-sonnet-latest' | 'claude-3-5-haiku-latest' | 'claude-3-5-sonnet-latest' | 'claude-3-5-sonnet-20241022' | 'claude-3-5-sonnet-20240620' | 'claude-3-opus-20240229' | 'claude-3-sonnet-20240229' | 'claude-3-haiku-20240307';
|
|
16
40
|
type OllamaModel = 'deepseek-r1:1.5b' | 'deepseek-r1:8b' | 'deepseek-r1:32b' | 'codegemma:2b' | 'codegemma:7b-code' | 'codegemma' | 'codellama:13b' | 'codellama:34b' | 'codellama:70b' | 'codellama:7b' | 'codellama:instruct' | 'codellama:latest' | 'codellama' | 'gemma:2b' | 'gemma:7b' | 'gemma:latest' | 'gemma' | 'llama2:13b' | 'llama2:70b' | 'llama2:chat' | 'llama2:latest' | 'llama2:text' | 'llama2' | 'llama3:70b-text' | 'llama3:70b' | 'llama3:latest' | 'llama3:text' | 'llama3.1:70b' | 'llama3.1:8b' | 'llama3.1:latest' | 'llama3.2' | 'llama3.2:latest' | 'llama3.2:1b' | 'llama3.2:3b' | 'llama3' | 'llava-llama3:latest' | 'dolphin-llama3:latest' | 'dolphin-llama3:8b' | 'dolphin-llama3:70b' | 'mistral:7b' | 'mistral:latest' | 'mistral:text' | 'mistral' | 'phi3:14b' | 'phi3:3.8b' | 'phi3:instruct' | 'phi3:medium-128k' | 'phi3:medium-4k' | 'phi3:medium' | 'phi3' | 'qwen2:0.5b' | 'qwen2:1.5b' | 'qwen2:72b-text' | 'qwen2:72b' | 'qwen2' | 'qwen2.5-coder:latest' | 'qwen2.5-coder:0.5b' | 'qwen2.5-coder:1.5b' | 'qwen2.5-coder:3b' | 'qwen2.5-coder:7b' | 'qwen2.5-coder:14b' | 'qwen2.5-coder:32b';
|
|
17
41
|
type LLMModel = OpenAIModel | OllamaModel | AnthropicModel;
|
|
42
|
+
type ConfiguredLLMModel = LLMModel | 'dynamic';
|
|
43
|
+
type DynamicModelProfile = Partial<Record<DynamicModelTask, LLMModel>>;
|
|
18
44
|
type BaseLLMService = {
|
|
19
45
|
provider: LLMProvider;
|
|
20
|
-
model:
|
|
46
|
+
model: ConfiguredLLMModel;
|
|
21
47
|
/**
|
|
22
48
|
* The maximum number of tokens per request.
|
|
23
49
|
*
|
|
@@ -63,6 +89,16 @@ type BaseLLMService = {
|
|
|
63
89
|
* @default 3
|
|
64
90
|
*/
|
|
65
91
|
maxParsingAttempts?: number;
|
|
92
|
+
/**
|
|
93
|
+
* Optional task-to-model overrides used when model is set to "dynamic".
|
|
94
|
+
*/
|
|
95
|
+
dynamicModels?: DynamicModelProfile;
|
|
96
|
+
/**
|
|
97
|
+
* Default dynamic routing preference when model is set to "dynamic".
|
|
98
|
+
*
|
|
99
|
+
* @default 'balanced'
|
|
100
|
+
*/
|
|
101
|
+
dynamicModelPreference?: DynamicModelPreference;
|
|
66
102
|
};
|
|
67
103
|
type Authentication = {
|
|
68
104
|
type: 'None';
|
|
@@ -80,11 +116,16 @@ type Authentication = {
|
|
|
80
116
|
apiKey: string;
|
|
81
117
|
};
|
|
82
118
|
};
|
|
83
|
-
|
|
84
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Provider-specific extra options forwarded to the underlying LangChain client.
|
|
121
|
+
* Decoupled from upstream input types so schema generation stays stable across
|
|
122
|
+
* langchain releases.
|
|
123
|
+
*/
|
|
124
|
+
type OpenAIFields = Record<string, unknown>;
|
|
125
|
+
type OllamaFields = Record<string, unknown>;
|
|
85
126
|
type OpenAILLMService = BaseLLMService & {
|
|
86
127
|
provider: 'openai';
|
|
87
|
-
model: OpenAIModel;
|
|
128
|
+
model: OpenAIModel | 'dynamic';
|
|
88
129
|
/**
|
|
89
130
|
* Custom base URL for OpenAI-compatible APIs (e.g., OpenRouter, Azure OpenAI).
|
|
90
131
|
* If not specified, uses the default OpenAI API endpoint.
|
|
@@ -97,13 +138,13 @@ type OpenAILLMService = BaseLLMService & {
|
|
|
97
138
|
};
|
|
98
139
|
type OllamaLLMService = BaseLLMService & {
|
|
99
140
|
provider: 'ollama';
|
|
100
|
-
model: OllamaModel;
|
|
141
|
+
model: OllamaModel | 'dynamic';
|
|
101
142
|
endpoint: string;
|
|
102
143
|
fields?: OllamaFields;
|
|
103
144
|
};
|
|
104
145
|
type AnthropicLLMService = BaseLLMService & {
|
|
105
146
|
provider: 'anthropic';
|
|
106
|
-
model: AnthropicModel;
|
|
147
|
+
model: AnthropicModel | 'dynamic';
|
|
107
148
|
fields?: {
|
|
108
149
|
temperature?: number;
|
|
109
150
|
maxTokens?: number;
|
|
@@ -189,6 +230,15 @@ type BaseConfig = {
|
|
|
189
230
|
* @example { "model": "o4-mini", "approval-mode": "auto-edit" }
|
|
190
231
|
*/
|
|
191
232
|
autoFixToolOptions?: Record<string, string>;
|
|
233
|
+
/**
|
|
234
|
+
* Interactive log TUI settings.
|
|
235
|
+
*/
|
|
236
|
+
logTui?: {
|
|
237
|
+
/**
|
|
238
|
+
* Theme settings for `coco log -i`.
|
|
239
|
+
*/
|
|
240
|
+
theme?: LogInkThemeConfig;
|
|
241
|
+
};
|
|
192
242
|
};
|
|
193
243
|
type ConfigWithServiceObject = BaseConfig & Partial<BaseCommandOptions> & {
|
|
194
244
|
service: LLMService;
|
|
@@ -216,7 +266,7 @@ interface ChangelogOptions extends BaseCommandOptions {
|
|
|
216
266
|
}
|
|
217
267
|
type ChangelogArgv = Arguments<ChangelogOptions>;
|
|
218
268
|
|
|
219
|
-
declare const _default$
|
|
269
|
+
declare const _default$5: {
|
|
220
270
|
command: string;
|
|
221
271
|
desc: string;
|
|
222
272
|
builder: (yargs: yargs.Argv) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
@@ -233,10 +283,13 @@ interface CommitOptions extends BaseCommandOptions {
|
|
|
233
283
|
conventional: boolean;
|
|
234
284
|
includeBranchName: boolean;
|
|
235
285
|
noVerify: boolean;
|
|
286
|
+
split?: boolean;
|
|
287
|
+
plan?: boolean;
|
|
288
|
+
apply?: boolean;
|
|
236
289
|
}
|
|
237
290
|
type CommitArgv = Arguments<CommitOptions>;
|
|
238
291
|
|
|
239
|
-
declare const _default$
|
|
292
|
+
declare const _default$4: {
|
|
240
293
|
command: string;
|
|
241
294
|
desc: string;
|
|
242
295
|
builder: (yargs: yargs.Argv) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
@@ -246,13 +299,14 @@ declare const _default$2: {
|
|
|
246
299
|
|
|
247
300
|
type InstallationScope = 'global' | 'project';
|
|
248
301
|
|
|
249
|
-
declare const _default$
|
|
302
|
+
declare const _default$3: {
|
|
250
303
|
command: string;
|
|
251
304
|
desc: string;
|
|
252
305
|
builder: (yargs: yargs.Argv) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
253
306
|
handler: (argv: {
|
|
254
307
|
[x: string]: unknown;
|
|
255
308
|
scope?: InstallationScope | undefined;
|
|
309
|
+
dryRun?: boolean | undefined;
|
|
256
310
|
interactive: boolean;
|
|
257
311
|
verbose: boolean;
|
|
258
312
|
version: boolean;
|
|
@@ -262,6 +316,7 @@ declare const _default$1: {
|
|
|
262
316
|
} | Promise<{
|
|
263
317
|
[x: string]: unknown;
|
|
264
318
|
scope?: InstallationScope | undefined;
|
|
319
|
+
dryRun?: boolean | undefined;
|
|
265
320
|
interactive: boolean;
|
|
266
321
|
verbose: boolean;
|
|
267
322
|
version: boolean;
|
|
@@ -272,6 +327,32 @@ declare const _default$1: {
|
|
|
272
327
|
options: Record<string, yargs.Options>;
|
|
273
328
|
};
|
|
274
329
|
|
|
330
|
+
type LogFormat = 'table' | 'json';
|
|
331
|
+
type LogView = 'compact' | 'graph' | 'full';
|
|
332
|
+
interface LogOptions extends BaseCommandOptions {
|
|
333
|
+
all?: boolean;
|
|
334
|
+
author?: string;
|
|
335
|
+
branch?: string;
|
|
336
|
+
commit?: string;
|
|
337
|
+
format?: LogFormat;
|
|
338
|
+
limit?: number;
|
|
339
|
+
merges?: boolean;
|
|
340
|
+
noMerges?: boolean;
|
|
341
|
+
path?: string | string[];
|
|
342
|
+
since?: string;
|
|
343
|
+
until?: string;
|
|
344
|
+
view?: LogView;
|
|
345
|
+
}
|
|
346
|
+
type LogArgv = Arguments<LogOptions>;
|
|
347
|
+
|
|
348
|
+
declare const _default$2: {
|
|
349
|
+
command: string;
|
|
350
|
+
desc: string;
|
|
351
|
+
builder: (yargs: yargs.Argv) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
352
|
+
handler: (argv: LogArgv) => Promise<void>;
|
|
353
|
+
options: Record<string, yargs.Options>;
|
|
354
|
+
};
|
|
355
|
+
|
|
275
356
|
interface RecapOptions extends BaseCommandOptions {
|
|
276
357
|
yesterday?: boolean;
|
|
277
358
|
'last-week'?: boolean;
|
|
@@ -282,7 +363,7 @@ interface RecapOptions extends BaseCommandOptions {
|
|
|
282
363
|
}
|
|
283
364
|
type RecapArgv = Arguments<RecapOptions>;
|
|
284
365
|
|
|
285
|
-
declare const _default: {
|
|
366
|
+
declare const _default$1: {
|
|
286
367
|
command: string;
|
|
287
368
|
desc: string;
|
|
288
369
|
builder: (yargs: yargs.Argv) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
@@ -290,6 +371,25 @@ declare const _default: {
|
|
|
290
371
|
options: Record<string, yargs.Options>;
|
|
291
372
|
};
|
|
292
373
|
|
|
374
|
+
type UiView = 'history' | 'status' | 'diff';
|
|
375
|
+
interface UiOptions extends BaseCommandOptions {
|
|
376
|
+
all?: boolean;
|
|
377
|
+
branch?: string;
|
|
378
|
+
limit?: number;
|
|
379
|
+
path?: string | string[];
|
|
380
|
+
theme?: LogInkThemePreset;
|
|
381
|
+
view?: UiView;
|
|
382
|
+
}
|
|
383
|
+
type UiArgv = Arguments<UiOptions>;
|
|
384
|
+
|
|
385
|
+
declare const _default: {
|
|
386
|
+
command: string;
|
|
387
|
+
desc: string;
|
|
388
|
+
builder: (yargs: yargs.Argv) => yargs.Argv<yargs.Omit<{}, string> & yargs.InferredOptionTypes<Record<string, yargs.Options>>>;
|
|
389
|
+
handler: (argv: UiArgv) => Promise<void>;
|
|
390
|
+
options: Record<string, yargs.Options>;
|
|
391
|
+
};
|
|
392
|
+
|
|
293
393
|
/**
|
|
294
394
|
* Creates and configures an LLM instance based on the provider and configuration.
|
|
295
395
|
*
|
|
@@ -336,6 +436,20 @@ type TokenCounter = Awaited<ReturnType<typeof getTokenCounter>>;
|
|
|
336
436
|
*/
|
|
337
437
|
declare const getTokenCounter: (modelName: TiktokenModel$1) => Promise<(text: string) => number>;
|
|
338
438
|
|
|
439
|
+
type LlmCallMetadata = {
|
|
440
|
+
task: string;
|
|
441
|
+
command?: string;
|
|
442
|
+
provider?: string;
|
|
443
|
+
model?: string;
|
|
444
|
+
retryAttempt?: number;
|
|
445
|
+
parserType?: string;
|
|
446
|
+
variableKeys?: string[];
|
|
447
|
+
promptTokens?: number;
|
|
448
|
+
elapsedMs?: number;
|
|
449
|
+
inputDocuments?: number;
|
|
450
|
+
inputChunks?: number;
|
|
451
|
+
};
|
|
452
|
+
|
|
339
453
|
type FileChangeStatus = 'modified' | 'renamed' | 'added' | 'deleted' | 'untracked' | 'unknown';
|
|
340
454
|
interface FileChange {
|
|
341
455
|
summary: string;
|
|
@@ -389,6 +503,7 @@ interface BaseParserOptions {
|
|
|
389
503
|
* @default 6
|
|
390
504
|
*/
|
|
391
505
|
maxConcurrent?: number;
|
|
506
|
+
metadata?: Partial<LlmCallMetadata>;
|
|
392
507
|
}
|
|
393
508
|
interface BaseParserInput {
|
|
394
509
|
options: BaseParserOptions;
|
|
@@ -424,5 +539,5 @@ declare namespace types_d {
|
|
|
424
539
|
export type { types_d_BaseParserInput as BaseParserInput, types_d_BaseParserOptions as BaseParserOptions, types_d_CommandHandler as CommandHandler, types_d_CommitLogParserInput as CommitLogParserInput, types_d_ConfirmMessage as ConfirmMessage, types_d_ConfirmMessageCallback as ConfirmMessageCallback, types_d_DiffNode as DiffNode, types_d_DirectoryDiff as DirectoryDiff, types_d_FileChange as FileChange, types_d_FileChangeParserInput as FileChangeParserInput, types_d_FileChangeStatus as FileChangeStatus, types_d_FileDiff as FileDiff, types_d_GetChangesResult as GetChangesResult };
|
|
425
540
|
}
|
|
426
541
|
|
|
427
|
-
export { _default$
|
|
542
|
+
export { _default$5 as changelog, _default$4 as commit, _default$3 as init, _default$2 as log, _default$1 as recap, types_d as types, _default as ui };
|
|
428
543
|
export type { Config$1 as Config };
|