Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 2.0.2

### Added
- Added `--no-summary` flag to disable the token/model summary box at the end of output
- Updated config types in SDK to support `noSummary` option

## 2.0.1

### Fixed
Expand Down
1 change: 0 additions & 1 deletion codefetch.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export default {
gitignore: true,
tokenEncoder: "simple",
tokenLimiter: "truncated",
trackedModels: ["o3", "gemini-2.5-pro", "claude-sonnet-4", "claude-opus-4"],
dryRun: false,
disableLineNumbers: false,
defaultPromptFile: undefined,
Expand Down
58 changes: 0 additions & 58 deletions modeldb.json

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"license": "MIT",
"type": "module",
"scripts": {
"build": "pnpm -r build",
"build": "pnpm -C packages/sdk build && pnpm -C packages/cli build && pnpm -C packages/mcp build",
"test": "pnpm -r test",
"cli": "pnpm --filter codefetch run cli",
"lint": "pnpm -r lint",
Expand Down
9 changes: 7 additions & 2 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,14 @@ Create a `.codefetchrc` file for project-specific settings:
- `-h, --help` - Show help information
- `-v, --verbose` - Increase verbosity (use multiple times: -vvv)
- `--dry-run, -d` - Output to console instead of file
- `--stdout` - Print only the final output to stdout (equivalent to `--dry-run --no-summary --verbose 0`)
- `-o, --output` - Output filename (default: codefetch-output-[timestamp].md)
- `--output-path` - Output directory path
- `--max-tokens` - Maximum token limit
- `--token-encoder` - Token encoder model (cl100k, p50k, r50k, o200k)
- `--token-count-only, -c` - Only output token count
- `--disable-line-numbers` - Disable line numbers in code blocks
- `--no-summary` - Disable the token/model summary box at the end

### File Filtering

Expand All @@ -153,7 +155,7 @@ Create a `.codefetchrc` file for project-specific settings:
### Display Options

- `-t, --project-tree` - Show project tree (0=off, 1+=depth)
- `--tracked-models` - Show token counts for specific models
- `--tracked-models` - Label the token summary with specific models
- `--format` - Output format (markdown, json) (default: markdown)

### Advanced Options
Expand Down Expand Up @@ -209,8 +211,11 @@ codefetch -p improve --max-tokens 30000

### Track Multiple Models

You can tag the summary with the models you care about:

```bash
codefetch --tracked-models gpt-4,claude-3-opus,gpt-3.5-turbo
codefetch --tracked-models gpt-4o,claude-3.5-sonnet
codefetch --tracked-models gpt-4o,claude-3.5-sonnet --no-summary # hide summary box
```

### JSON Output Format
Expand Down
19 changes: 17 additions & 2 deletions packages/cli/src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ export function parseArgs(args: string[]) {
d: "dry-run",
p: "prompt",
c: "token-count-only",
s: "stdout",
},
boolean: [
"dry-run",
"disable-line-numbers",
"token-count-only",
"summary",
"stdout",
"no-cache",
"no-api",
"ignore-robots",
Expand Down Expand Up @@ -46,6 +49,7 @@ export function parseArgs(args: string[]) {
"max-depth",
"ignore-robots",
"ignore-cors",
"tracked-models",
],
});

Expand Down Expand Up @@ -145,6 +149,11 @@ export function parseArgs(args: string[]) {
outputFile = outputFile.replace(/^(\.\/)?codefetch\//, "");
}

const isStdout = Boolean(argv.stdout);

const verbose =
argv.verbose === undefined ? (isStdout ? 0 : 1) : Number(argv.verbose);

return {
...(outputFile && { outputFile }),
...(argv["output-path"] && { outputPath: resolve(argv["output-path"]) }),
Expand All @@ -168,12 +177,15 @@ export function parseArgs(args: string[]) {
...(argv["token-limiter"] && {
tokenLimiter: argv["token-limiter"] as TokenLimiter,
}),
...(argv["tracked-models"] && {
trackedModels: splitValues(argv["tracked-models"]),
}),
...(defaultPromptFile && { defaultPromptFile }),
...(Object.keys(templateVars).length > 0 && { templateVars }),
verbose: argv.verbose === undefined ? 1 : Number(argv.verbose),
verbose,
projectTree: treeDepth,

dryRun: Boolean(argv["dry-run"]),
dryRun: Boolean(argv["dry-run"] || isStdout),
disableLineNumbers: Boolean(argv["disable-line-numbers"]),
tokenCountOnly: Boolean(argv["token-count-only"]),
...(argv.format && { format: argv.format as "markdown" | "json" }),
Expand All @@ -191,5 +203,8 @@ export function parseArgs(args: string[]) {
...(argv["max-depth"] && { maxDepth: Number(argv["max-depth"]) }),
ignoreRobots: Boolean(argv["ignore-robots"]),
ignoreCors: Boolean(argv["ignore-cors"]),
// mri treats --no-summary as summary: false; stdout implies no summary
noSummary: argv.summary === false || isStdout,
stdout: isStdout,
};
}
31 changes: 22 additions & 9 deletions packages/cli/src/commands/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
DEFAULT_IGNORE_PATTERNS,
findProjectRoot,
countTokens,
fetchModels,
VALID_PROMPTS,
collectFilesAsTree,
FetchResultImpl,
Expand Down Expand Up @@ -104,7 +103,9 @@ export default async function defaultMain(rawArgs: Argv) {
); // 10 minutes

try {
logger.info(`Using format: ${config.format || "markdown"}`);
if (config.verbose > 0) {
logger.info(`Using format: ${config.format || "markdown"}`);
}
const { fetch } = await import("codefetch-sdk");

// Prepare web-specific options
Expand Down Expand Up @@ -178,11 +179,15 @@ export default async function defaultMain(rawArgs: Argv) {
verbose: config.verbose,
});

logger.info(`Using format: ${config.format || "markdown"}`);
if (config.verbose > 0) {
logger.info(`Using format: ${config.format || "markdown"}`);
}

if (config.format === "json") {
// Generate JSON format
logger.info("Generating JSON format...");
if (config.verbose > 0) {
logger.info("Generating JSON format...");
}
const {
root,
totalSize,
Expand All @@ -205,7 +210,9 @@ export default async function defaultMain(rawArgs: Argv) {
output = new FetchResultImpl(root, metadata);
} else {
// Generate markdown format (default)
logger.info("Generating markdown format...");
if (config.verbose > 0) {
logger.info("Generating markdown format...");
}
const markdown = await generateMarkdown(files, {
maxTokens: config.maxTokens ? Number(config.maxTokens) : null,
verbose: Number(config.verbose || 0),
Expand Down Expand Up @@ -271,13 +278,19 @@ export default async function defaultMain(rawArgs: Argv) {
}
}

if (config.trackedModels?.length) {
const { modelDb } = await fetchModels(config.trackedModels);
const modelInfo = formatModelInfo(config.trackedModels, modelDb);
if (!config.noSummary) {
let message = `Current Codebase: ${totalTokens.toLocaleString()} tokens`;

if (config.trackedModels?.length) {
const modelInfo = formatModelInfo(config.trackedModels);
if (modelInfo) {
message += `\n\n${modelInfo}`;
}
}

logger.box({
title: `Token Count Overview`,
message: `Current Codebase: ${totalTokens.toLocaleString()} tokens\n\nModel Token Limits:\n${modelInfo}`,
message,
style: {
padding: 0,
borderColor: "cyan",
Expand Down
23 changes: 5 additions & 18 deletions packages/cli/src/format-model-info.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import type { ModelDb } from "codefetch-sdk";
export function formatModelInfo(trackedModels: string[]): string {
if (trackedModels.length === 0) return "";

export function formatModelInfo(
trackedModels: string[],
modelDb: ModelDb
): string {
const rows = trackedModels.map((modelName) => {
const model = modelDb[modelName] || {};
const tokens = model.max_input_tokens
? model.max_input_tokens.toLocaleString()
: "Unknown";
return `│ ${modelName.padEnd(30)} │ ${tokens.padEnd(15)} │`;
});
const header = "Tracked models:";
const rows = trackedModels.map((modelName) => `- ${modelName}`);

const header = "│ Model Name │ Max Tokens │";
const separator = "├────────────────────────────────┼────────────────┤";
const topBorder = "┌────────────────────────────────┬────────────────┐";
const bottomBorder = "└────────────────────────────────┴────────────────┘";

return [topBorder, header, separator, ...rows, bottomBorder].join("\n");
return [header, ...rows].join("\n");
}
6 changes: 0 additions & 6 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ export { findProjectRoot } from "codefetch-sdk";
export * from "./args";
export * from "./config";
export { countTokens } from "codefetch-sdk";
export {
fetchModels,
getLocalModels,
type ModelInfo,
type ModelDb,
} from "codefetch-sdk";
export { processPromptTemplate, resolvePrompt } from "codefetch-sdk";
export * from "./help-prompt";
export { formatModelInfo } from "./format-model-info";
Expand Down
24 changes: 24 additions & 0 deletions packages/cli/test/unit/args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,37 @@ describe("parseArgs", () => {
expect(result.disableLineNumbers).toBe(true);
});

it("should parse tracked-models option into an array", () => {
const args = ["--tracked-models", "gpt-4o,claude-3.5-sonnet"];
const result = parseArgs(args);

expect(result.trackedModels).toEqual(["gpt-4o", "claude-3.5-sonnet"]);
});

it("should default disable-line-numbers to false when not specified", () => {
const args = ["-o", "output.md"];
const result = parseArgs(args);

expect(result.disableLineNumbers).toBe(false);
});

it("should parse no-summary flag", () => {
const args = ["--no-summary"];
const result = parseArgs(args);

expect(result.noSummary).toBe(true);
});

it("should treat --stdout as dry-run with no summary and verbose 0", () => {
const args = ["--stdout"];
const result = parseArgs(args);

expect(result.stdout).toBe(true);
expect(result.dryRun).toBe(true);
expect(result.noSummary).toBe(true);
expect(result.verbose).toBe(0);
});

it("should handle multiple options together", () => {
const args = [
"-o",
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/config-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface CodefetchConfig {
gitignore: boolean;
tokenLimiter: string;
tokenCountOnly: boolean;
noSummary?: boolean;
promptFile?: string;
prompt?: string;
templateVars: Record<string, string>;
Expand Down
4 changes: 3 additions & 1 deletion packages/sdk/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface CodefetchConfig {
dryRun?: boolean;
disableLineNumbers?: boolean;
tokenCountOnly?: boolean;
noSummary?: boolean;
defaultPromptFile: string;
defaultChat?: string;
templateVars?: Record<string, string>;
Expand All @@ -39,10 +40,11 @@ export const getDefaultConfig = (): CodefetchConfig => ({
gitignore: true,
tokenEncoder: "simple",
tokenLimiter: "truncated",
trackedModels: ["o3", "gemini-2.5-pro", "claude-sonnet-4", "claude-opus-4"],
trackedModels: [],
dryRun: false,
disableLineNumbers: false,
tokenCountOnly: false,
noSummary: false,
defaultPromptFile: "default.md",
defaultChat: "https://chat.com",
templateVars: {},
Expand Down
1 change: 0 additions & 1 deletion packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export * from "./template-parser";
export * from "./utils";
export * from "./utils/path";
export * from "./constants";
export * from "./model-db";
export * from "./default-ignore";
export * from "./fetch-result";
export * from "./fetch";
Expand Down
Loading
Loading