@johnowennixon/diffdash 1.11.0 → 1.12.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 CHANGED
@@ -1,3 +1,5 @@
1
+ ![Demonstration](asciinema/diffdash-demo.gif)
2
+
1
3
  # DiffDash
2
4
 
3
5
  ![npm version](https://img.shields.io/npm/v/@johnowennixon/diffdash.svg)
@@ -7,21 +9,17 @@
7
9
 
8
10
  A command-line tool to generate Git commit messages using AI.
9
11
 
10
- ## Demonstration
11
-
12
- ![Demonstration](asciinema/diffdash-demo.gif)
13
-
14
12
  ## Features
15
13
 
16
14
  * Generate Git commit messages in **natural English**
17
- * Add a footer to the generated commit messages
18
15
  * Add a prefix or suffix to the summary line
16
+ * Add a footer to the generated commit messages
19
17
  * Select from a choice of LLM models
20
18
  * Compare messages generated from all configured models
21
19
  * Disable or auto-approve various stages
22
20
  * Option to output just the commit message for use in scripts
23
21
  * Configuration using standard API provider environment variables
24
- * Uses the Vercel AI SDK (version 5)
22
+ * Uses the Vercel AI SDK (version 6)
25
23
  * Uses structured JSON with compatible models
26
24
  * Substantially written using AI coding (Claude Code, Roo Code, and Amp)
27
25
 
@@ -37,8 +35,8 @@ Currently, for this application, the best LLM model is **gpt-4.1-mini** from Ope
37
35
  It is set as the default model.
38
36
  I can only presume they have done a ton of training on diffs.
39
37
 
40
- I am now testing the GPT-5 models and **gpt-5-mini-minimal** (GPT-5 Mini with reasoning disabled) is behaving much the same.
41
- It will probably become the default model soon.
38
+ I have tested the GPT-5 models and **gpt-5-mini-minimal** (GPT-5 Mini with reasoning disabled) is behaving much the same.
39
+ It will become the default model if gpt-4.1-mini is deprecated.
42
40
 
43
41
  ## API Keys
44
42
 
@@ -98,7 +96,7 @@ diffdash --no-verify
98
96
  diffdash --add-prefix "[FIX]"
99
97
 
100
98
  # Add a suffix to the commit message summary line
101
- diffdash --add-suffix "(closes #123)"
99
+ diffdash --add-suffix "(closes #DEV-1234)"
102
100
 
103
101
  # Display commit messages generated by all models
104
102
  diffdash --llm-compare
@@ -158,6 +156,8 @@ There is a rudimentary check for secrets in diffs before submitting to the LLM.
158
156
 
159
157
  ## Development
160
158
 
159
+ You will need to install [bun](https://bun.com/docs/pm/cli/install).
160
+
161
161
  To install on your laptop:
162
162
 
163
163
  ```bash
@@ -166,10 +166,10 @@ git clone https://github.com/johnowennixon/diffdash.git
166
166
  cd diffdash
167
167
 
168
168
  # Install dependencies
169
- pnpm install
169
+ bun install
170
170
 
171
171
  # Build the project
172
- pnpm run build
172
+ bun run build
173
173
 
174
174
  # Make binaries executable
175
175
  npm link
@@ -179,13 +179,13 @@ To rebuild after editing:
179
179
 
180
180
  ```bash
181
181
  # Lint the code
182
- pnpm run lint
182
+ bun run lint
183
183
 
184
184
  # Fix formatting issues (if required)
185
- pnpm run fix
185
+ bun run fix
186
186
 
187
187
  # Build the project
188
- pnpm run build
188
+ bun run build
189
189
  ```
190
190
 
191
191
  ## License
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johnowennixon/diffdash",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "A command-line tool to generate Git commit messages using AI",
5
5
  "license": "0BSD",
6
6
  "author": "John Owen Nixon",
@@ -23,12 +23,12 @@
23
23
  "build:chmod": "echo 'Changing bin files to be executable' && chmodx --package",
24
24
  "build:clean": "echo 'Removing dist' && rimraf dist",
25
25
  "build:shebang": "echo 'Fixing the shebangs' && add-shebangs --node --exclude 'dist/**/lib_*.js' 'dist/**/*.js'",
26
- "build:tsc": "echo 'Transpiling TypeScript to dist (using tsc)' && tsc --erasableSyntaxOnly --libReplacement false",
26
+ "build:tsc": "echo 'Transpiling TypeScript to dist (using tsc)' && tsc",
27
27
  "build:tsgo": "echo 'Transpiling TypeScript to dist (using tsgo)' && tsgo || (rimraf dist && false)",
28
28
  "fix": "run-s -ls fix:biome fix:markdownlint",
29
29
  "fix:biome": "echo 'Fixing with Biome' && biome check --write",
30
30
  "fix:docbot": "echo 'Fixing with DocBot' && docbot --prune --generate",
31
- "fix:markdownlint": "echo 'Fixing with markdownlint' && markdownlint-cli2 '**/*.md' --fix",
31
+ "fix:markdownlint": "echo 'Fixing with Markdownlint' && markdownlint-cli2 '**/*.md' --fix",
32
32
  "fix:oxlint": "echo 'Fixing with Oxlint' && oxlint --fix",
33
33
  "lint": "run-s -ls lint:biome lint:oxlint lint:tsgolint lint:knip lint:markdownlint",
34
34
  "lint:biome": "echo 'Linting with Biome' && biome check",
@@ -36,39 +36,39 @@
36
36
  "lint:knip": "echo 'Linting with Knip' && knip",
37
37
  "lint:markdownlint": "echo 'Linting with Markdownlint' && markdownlint-cli2 '**/*.md'",
38
38
  "lint:oxlint": "echo 'Linting with Oxlint' && oxlint",
39
- "lint:tsc": "echo 'Linting with tsc' && tsc --noEmit --erasableSyntaxOnly --libReplacement false",
39
+ "lint:tsc": "echo 'Linting with tsc' && tsc --noEmit",
40
40
  "lint:tsgo": "echo 'Linting with tsgo' && tsgo --noEmit",
41
41
  "lint:tsgolint": "echo 'Linting with tsgolint' && candide-tsgolint",
42
42
  "test": "run-s -ls lint build"
43
43
  },
44
44
  "dependencies": {
45
- "@ai-sdk/anthropic": "2.0.53",
46
- "@ai-sdk/deepseek": "1.0.31",
47
- "@ai-sdk/google": "2.0.44",
48
- "@ai-sdk/openai": "2.0.77",
49
- "@inquirer/prompts": "8.0.2",
50
- "@openrouter/ai-sdk-provider": "1.2.3",
51
- "ai": "5.0.102",
45
+ "@ai-sdk/anthropic": "3.0.8",
46
+ "@ai-sdk/deepseek": "2.0.4",
47
+ "@ai-sdk/google": "3.0.5",
48
+ "@ai-sdk/openai": "3.0.21",
49
+ "@inquirer/prompts": "8.2.0",
50
+ "@openrouter/ai-sdk-provider": "2.1.1",
51
+ "ai": "6.0.17",
52
52
  "ansis": "4.2.0",
53
53
  "argparse": "2.0.1",
54
54
  "cli-table3": "0.6.5",
55
55
  "json5": "2.2.3",
56
56
  "magic-regexp": "0.10.0",
57
57
  "simple-git": "3.30.0",
58
- "zod": "4.1.13"
58
+ "zod": "4.3.6"
59
59
  },
60
60
  "devDependencies": {
61
- "@biomejs/biome": "2.3.8",
62
- "@candide/tsgolint": "1.4.0",
61
+ "@biomejs/biome": "2.3.13",
62
+ "@candide/tsgolint": "1.5.0",
63
63
  "@johnowennixon/add-shebangs": "1.1.0",
64
64
  "@johnowennixon/chmodx": "2.1.0",
65
65
  "@types/argparse": "2.0.17",
66
- "@types/node": "24.10.1",
67
- "@typescript/native-preview": "7.0.0-dev.20251022.1",
68
- "knip": "5.71.0",
69
- "markdownlint-cli2": "0.19.1",
66
+ "@types/node": "25.0.3",
67
+ "@typescript/native-preview": "7.0.0-dev.20260103.1",
68
+ "knip": "5.82.1",
69
+ "markdownlint-cli2": "0.20.0",
70
70
  "npm-run-all2": "8.0.4",
71
- "oxlint": "1.31.0",
71
+ "oxlint": "1.42.0",
72
72
  "rimraf": "6.1.2",
73
73
  "typescript": "5.9.3"
74
74
  }
@@ -1,5 +1,14 @@
1
1
  import { EMPTY } from "./lib_char_empty.js";
2
2
  import { COLON, DASH, SPACE } from "./lib_char_punctuation.js";
3
+ export const DATETIME_WEEKDAYS = {
4
+ SUNDAY: 0,
5
+ MONDAY: 1,
6
+ TUESDAY: 2,
7
+ WEDNESDAY: 3,
8
+ THURSDAY: 4,
9
+ FRIDAY: 5,
10
+ SATURDAY: 6,
11
+ };
3
12
  export function datetime_now() {
4
13
  return new Date();
5
14
  }
@@ -8,6 +17,11 @@ export function datetime_now_minus_days(days) {
8
17
  date.setDate(date.getDate() - days);
9
18
  return date;
10
19
  }
20
+ export function datetime_now_plus_days(days) {
21
+ const date = datetime_now();
22
+ date.setDate(date.getDate() + days);
23
+ return date;
24
+ }
11
25
  export function datetime_parse(s) {
12
26
  return new Date(s);
13
27
  }
@@ -4,8 +4,8 @@ const model_name_default = "gpt-4.1-mini";
4
4
  const model_name_options = [
5
5
  "claude-3.5-haiku", // fallback
6
6
  "deepseek-chat",
7
- "gemini-2.0-flash",
8
7
  "gemini-2.5-flash",
8
+ "gemini-3-flash-preview-low",
9
9
  "gpt-4.1-mini", // the best
10
10
  "gpt-4.1-nano",
11
11
  "gpt-5-mini",
@@ -13,7 +13,6 @@ const model_name_options = [
13
13
  "gpt-5-nano",
14
14
  "gpt-5-nano-minimal",
15
15
  "grok-code-fast-1",
16
- "llama-4-maverick@groq",
17
16
  ];
18
17
  export const diffdash_llm_model_details = llm_model_get_details({ llm_model_names: model_name_options });
19
18
  export const diffdash_llm_model_choices = llm_model_get_choices({ llm_model_details: diffdash_llm_model_details });
@@ -5,6 +5,8 @@ import { createOpenAI } from "@ai-sdk/openai";
5
5
  import { createOpenRouter } from "@openrouter/ai-sdk-provider";
6
6
  import { abort_with_error } from "./lib_abort.js";
7
7
  import { env_get } from "./lib_env.js";
8
+ // Disable AI SDK warning logs temporarily
9
+ globalThis.AI_SDK_LOG_WARNINGS = false;
8
10
  export function llm_api_get_api_key_env(llm_api_code) {
9
11
  switch (llm_api_code) {
10
12
  case "anthropic":
@@ -1,4 +1,4 @@
1
- import { generateObject, generateText, stepCountIs } from "ai";
1
+ import { generateText, Output, stepCountIs } from "ai";
2
2
  import { debug_channels, debug_inspect_when } from "./lib_debug.js";
3
3
  import { Duration } from "./lib_duration.js";
4
4
  import { env_get_empty, env_get_substitute } from "./lib_env.js";
@@ -93,8 +93,7 @@ export async function llm_chat_generate_object({ llm_config, user_prompt, system
93
93
  model: ai_sdk_language_model,
94
94
  system: system_prompt,
95
95
  prompt: user_prompt,
96
- output: "object",
97
- schema,
96
+ output: Output.object({ schema }),
98
97
  maxOutputTokens: max_output_tokens_env ?? max_output_tokens,
99
98
  temperature,
100
99
  providerOptions: provider_options,
@@ -102,8 +101,8 @@ export async function llm_chat_generate_object({ llm_config, user_prompt, system
102
101
  };
103
102
  debug_inspect_when(debug_channels.llm_inputs, llm_inputs, `LLM inputs object (for ${llm_model_name})`);
104
103
  // This is liable to throw an error
105
- const llm_outputs = await generateObject(llm_inputs);
104
+ const llm_outputs = await generateText(llm_inputs);
106
105
  debug_inspect_when(debug_channels.llm_outputs, llm_outputs, `LLM outputs object (for ${llm_model_name})`);
107
- const { object: generated_object, usage: total_usage, providerMetadata: provider_metadata } = llm_outputs;
106
+ const { output: generated_object, usage: total_usage, providerMetadata: provider_metadata } = llm_outputs;
108
107
  return { generated_object, total_usage, provider_metadata };
109
108
  }
@@ -1,10 +1,10 @@
1
1
  import { DOLLAR } from "./lib_char_punctuation.js";
2
2
  import { stdio_write_stdout_linefeed } from "./lib_stdio_write.js";
3
3
  import { tell_info, tell_warning } from "./lib_tell.js";
4
- import { TuiTable } from "./lib_tui_table.js";
4
+ import { LEFT, RIGHT, TuiTable } from "./lib_tui_table.js";
5
5
  export function llm_list_models({ llm_model_details }) {
6
6
  const headings = ["NAME", "API", "CONTEXT", "INPUT", "OUTPUT", "REASONING"];
7
- const alignments = ["left", "left", "right", "right", "right", "left"];
7
+ const alignments = [LEFT, LEFT, RIGHT, RIGHT, RIGHT, LEFT];
8
8
  const table = new TuiTable({ headings, alignments, compact: true });
9
9
  for (const detail of llm_model_details) {
10
10
  const { llm_model_name, llm_api_code, context_window, cents_input, cents_output, default_reasoning } = detail;
@@ -184,19 +184,6 @@ export const LLM_MODEL_DETAILS = [
184
184
  recommended_temperature: undefined,
185
185
  provider_options: provider_options_openrouter({ only: "mistral" }),
186
186
  },
187
- {
188
- llm_model_name: "gemini-2.0-flash",
189
- llm_model_code: "gemini-2.0-flash",
190
- llm_api_code: "google",
191
- context_window: 1_048_576,
192
- max_output_tokens: 8192,
193
- cents_input: 10,
194
- cents_output: 40,
195
- default_reasoning: false,
196
- has_structured_json: true,
197
- recommended_temperature: undefined,
198
- provider_options: undefined,
199
- },
200
187
  {
201
188
  llm_model_name: "gemini-2.5-flash",
202
189
  llm_model_code: "gemini-2.5-flash",
@@ -223,6 +210,32 @@ export const LLM_MODEL_DETAILS = [
223
210
  recommended_temperature: undefined,
224
211
  provider_options: undefined,
225
212
  },
213
+ {
214
+ llm_model_name: "gemini-3-flash-preview-high",
215
+ llm_model_code: "gemini-3-flash-preview",
216
+ llm_api_code: "google",
217
+ context_window: 1_048_576,
218
+ max_output_tokens: 65_536,
219
+ cents_input: 50,
220
+ cents_output: 300,
221
+ default_reasoning: true,
222
+ has_structured_json: true,
223
+ recommended_temperature: undefined,
224
+ provider_options: provider_options_google({ thinking_level: "high" }),
225
+ },
226
+ {
227
+ llm_model_name: "gemini-3-flash-preview-low",
228
+ llm_model_code: "gemini-3-flash-preview",
229
+ llm_api_code: "google",
230
+ context_window: 1_048_576,
231
+ max_output_tokens: 65_536,
232
+ cents_input: 50,
233
+ cents_output: 300,
234
+ default_reasoning: true,
235
+ has_structured_json: true,
236
+ recommended_temperature: undefined,
237
+ provider_options: provider_options_google({ thinking_level: "low" }),
238
+ },
226
239
  {
227
240
  llm_model_name: "gemini-3-pro-preview-high",
228
241
  llm_model_code: "gemini-3-pro-preview",
@@ -250,37 +263,11 @@ export const LLM_MODEL_DETAILS = [
250
263
  provider_options: provider_options_google({ thinking_level: "low" }),
251
264
  },
252
265
  {
253
- llm_model_name: "glm-4.5@z-ai",
254
- llm_model_code: "z-ai/glm-4.5",
266
+ llm_model_name: "glm-4.7@z-ai",
267
+ llm_model_code: "z-ai/glm-4.7",
255
268
  llm_api_code: "openrouter",
256
- context_window: 128_000,
257
- max_output_tokens: 96_000,
258
- cents_input: 60,
259
- cents_output: 220,
260
- default_reasoning: true,
261
- has_structured_json: false,
262
- recommended_temperature: undefined,
263
- provider_options: provider_options_openrouter({ only: "z-ai" }),
264
- },
265
- {
266
- llm_model_name: "glm-4.5-air@z-ai",
267
- llm_model_code: "z-ai/glm-4.5-air",
268
- llm_api_code: "openrouter",
269
- context_window: 128_000,
270
- max_output_tokens: 96_000,
271
- cents_input: 20,
272
- cents_output: 110,
273
- default_reasoning: true,
274
- has_structured_json: false,
275
- recommended_temperature: undefined,
276
- provider_options: provider_options_openrouter({ only: "z-ai" }),
277
- },
278
- {
279
- llm_model_name: "glm-4.6@z-ai",
280
- llm_model_code: "z-ai/glm-4.6",
281
- llm_api_code: "openrouter",
282
- context_window: 128_000,
283
- max_output_tokens: 96_000,
269
+ context_window: 200_000,
270
+ max_output_tokens: 131_072,
284
271
  cents_input: 60,
285
272
  cents_output: 220,
286
273
  default_reasoning: true,
@@ -626,6 +613,19 @@ export const LLM_MODEL_DETAILS = [
626
613
  recommended_temperature: undefined,
627
614
  provider_options: undefined,
628
615
  },
616
+ {
617
+ llm_model_name: "minimax-m2.1",
618
+ llm_model_code: "minimax/minimax-m2.1",
619
+ llm_api_code: "openrouter",
620
+ context_window: 204_800,
621
+ max_output_tokens: 131_072,
622
+ cents_input: 30,
623
+ cents_output: 120,
624
+ default_reasoning: false,
625
+ has_structured_json: false,
626
+ recommended_temperature: undefined,
627
+ provider_options: provider_options_openrouter({ only: "minimax" }),
628
+ },
629
629
  {
630
630
  llm_model_name: "mistral-medium-3.1",
631
631
  llm_model_code: "mistralai/mistral-medium-3.1",
@@ -26,19 +26,20 @@ export function llm_results_summary(all_results) {
26
26
  const { default_reasoning } = llm_model_detail;
27
27
  const { outputs } = result;
28
28
  const { total_usage, provider_metadata } = outputs;
29
+ const { reasoningTokens: reasoning_tokens } = total_usage.outputTokenDetails;
29
30
  const openrouter_provider = provider_metadata?.["openrouter"]?.["provider"];
30
31
  const tui_model = tui_justify_left(max_length_model, llm_model_name);
31
32
  const tui_seconds = tui_number_plain({ num: seconds, justify_left: 3 });
32
33
  const tui_input = tui_number_plain({ num: total_usage.inputTokens, justify_left: 5 });
33
34
  const tui_output = tui_number_plain({ num: total_usage.outputTokens, justify_left: 5 });
34
- const tui_reasoning = tui_number_plain({ num: total_usage.reasoningTokens, justify_left: 5, none: QUESTION });
35
+ const tui_reasoning = tui_number_plain({ num: reasoning_tokens, justify_left: 5, none: QUESTION });
35
36
  const tui_provider = tui_none_blank(openrouter_provider);
36
37
  const segments = [];
37
38
  segments.push(tui_model);
38
39
  segments.push(`seconds=${tui_seconds}`);
39
40
  segments.push(`input=${tui_input}`);
40
41
  segments.push(`output=${tui_output}`);
41
- if (default_reasoning || total_usage.reasoningTokens !== undefined) {
42
+ if (default_reasoning || reasoning_tokens !== undefined) {
42
43
  segments.push(`reasoning=${tui_reasoning}`);
43
44
  }
44
45
  if (openrouter_provider) {
@@ -1,6 +1,9 @@
1
1
  import cli_table3 from "cli-table3";
2
2
  import { abort_with_error } from "./lib_abort.js";
3
3
  import { ansi_bold } from "./lib_ansi.js";
4
+ export const LEFT = "left";
5
+ export const CENTER = "center";
6
+ export const RIGHT = "right";
4
7
  export class TuiTable {
5
8
  table;
6
9
  columns_total;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@johnowennixon/diffdash",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "A command-line tool to generate Git commit messages using AI",
5
5
  "license": "0BSD",
6
6
  "author": "John Owen Nixon",
@@ -18,48 +18,17 @@
18
18
  "bin": {
19
19
  "diffdash": "dist/src/diffdash.js"
20
20
  },
21
- "dependencies": {
22
- "@ai-sdk/anthropic": "2.0.53",
23
- "@ai-sdk/deepseek": "1.0.31",
24
- "@ai-sdk/google": "2.0.44",
25
- "@ai-sdk/openai": "2.0.77",
26
- "@inquirer/prompts": "8.0.2",
27
- "@openrouter/ai-sdk-provider": "1.2.3",
28
- "ai": "5.0.102",
29
- "ansis": "4.2.0",
30
- "argparse": "2.0.1",
31
- "cli-table3": "0.6.5",
32
- "json5": "2.2.3",
33
- "magic-regexp": "0.10.0",
34
- "simple-git": "3.30.0",
35
- "zod": "4.1.13"
36
- },
37
- "devDependencies": {
38
- "@biomejs/biome": "2.3.8",
39
- "@candide/tsgolint": "1.4.0",
40
- "@johnowennixon/add-shebangs": "1.1.0",
41
- "@johnowennixon/chmodx": "2.1.0",
42
- "@types/argparse": "2.0.17",
43
- "@types/node": "24.10.1",
44
- "@typescript/native-preview": "7.0.0-dev.20251022.1",
45
- "knip": "5.71.0",
46
- "markdownlint-cli2": "0.19.1",
47
- "npm-run-all2": "8.0.4",
48
- "oxlint": "1.31.0",
49
- "rimraf": "6.1.2",
50
- "typescript": "5.9.3"
51
- },
52
21
  "scripts": {
53
22
  "build": "run-s -ls build:clean build:tsc build:shebang build:chmod",
54
23
  "build:chmod": "echo 'Changing bin files to be executable' && chmodx --package",
55
24
  "build:clean": "echo 'Removing dist' && rimraf dist",
56
25
  "build:shebang": "echo 'Fixing the shebangs' && add-shebangs --node --exclude 'dist/**/lib_*.js' 'dist/**/*.js'",
57
- "build:tsc": "echo 'Transpiling TypeScript to dist (using tsc)' && tsc --erasableSyntaxOnly --libReplacement false",
26
+ "build:tsc": "echo 'Transpiling TypeScript to dist (using tsc)' && tsc",
58
27
  "build:tsgo": "echo 'Transpiling TypeScript to dist (using tsgo)' && tsgo || (rimraf dist && false)",
59
28
  "fix": "run-s -ls fix:biome fix:markdownlint",
60
29
  "fix:biome": "echo 'Fixing with Biome' && biome check --write",
61
30
  "fix:docbot": "echo 'Fixing with DocBot' && docbot --prune --generate",
62
- "fix:markdownlint": "echo 'Fixing with markdownlint' && markdownlint-cli2 '**/*.md' --fix",
31
+ "fix:markdownlint": "echo 'Fixing with Markdownlint' && markdownlint-cli2 '**/*.md' --fix",
63
32
  "fix:oxlint": "echo 'Fixing with Oxlint' && oxlint --fix",
64
33
  "lint": "run-s -ls lint:biome lint:oxlint lint:tsgolint lint:knip lint:markdownlint",
65
34
  "lint:biome": "echo 'Linting with Biome' && biome check",
@@ -67,9 +36,40 @@
67
36
  "lint:knip": "echo 'Linting with Knip' && knip",
68
37
  "lint:markdownlint": "echo 'Linting with Markdownlint' && markdownlint-cli2 '**/*.md'",
69
38
  "lint:oxlint": "echo 'Linting with Oxlint' && oxlint",
70
- "lint:tsc": "echo 'Linting with tsc' && tsc --noEmit --erasableSyntaxOnly --libReplacement false",
39
+ "lint:tsc": "echo 'Linting with tsc' && tsc --noEmit",
71
40
  "lint:tsgo": "echo 'Linting with tsgo' && tsgo --noEmit",
72
41
  "lint:tsgolint": "echo 'Linting with tsgolint' && candide-tsgolint",
73
42
  "test": "run-s -ls lint build"
43
+ },
44
+ "dependencies": {
45
+ "@ai-sdk/anthropic": "3.0.8",
46
+ "@ai-sdk/deepseek": "2.0.4",
47
+ "@ai-sdk/google": "3.0.5",
48
+ "@ai-sdk/openai": "3.0.21",
49
+ "@inquirer/prompts": "8.2.0",
50
+ "@openrouter/ai-sdk-provider": "2.1.1",
51
+ "ai": "6.0.17",
52
+ "ansis": "4.2.0",
53
+ "argparse": "2.0.1",
54
+ "cli-table3": "0.6.5",
55
+ "json5": "2.2.3",
56
+ "magic-regexp": "0.10.0",
57
+ "simple-git": "3.30.0",
58
+ "zod": "4.3.6"
59
+ },
60
+ "devDependencies": {
61
+ "@biomejs/biome": "2.3.13",
62
+ "@candide/tsgolint": "1.5.0",
63
+ "@johnowennixon/add-shebangs": "1.1.0",
64
+ "@johnowennixon/chmodx": "2.1.0",
65
+ "@types/argparse": "2.0.17",
66
+ "@types/node": "25.0.3",
67
+ "@typescript/native-preview": "7.0.0-dev.20260103.1",
68
+ "knip": "5.82.1",
69
+ "markdownlint-cli2": "0.20.0",
70
+ "npm-run-all2": "8.0.4",
71
+ "oxlint": "1.42.0",
72
+ "rimraf": "6.1.2",
73
+ "typescript": "5.9.3"
74
74
  }
75
- }
75
+ }