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
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ ANTHROPIC_API_KEY=
GEMINI_API_KEY=

# Optional overrides (also settable via config file / CLI flags)
# THERR_AGENT_PROVIDER=anthropic # anthropic | gemini
# THERR_AGENT_MODEL=claude-opus-4-8
# TINY_CODE_PROVIDER=anthropic # anthropic | gemini
# TINY_CODE_MODEL=claude-opus-4-8
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Project Instructions for therr-agent
# Project Instructions for tiny-code

This file is loaded into the agent's system prompt when it runs in this repo.

Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# therr-agent
# tiny-code

A small, extensible CLI coding agent. Interactive terminal REPL, interchangeable
**Anthropic** and **Gemini** models, and just the core features you actually use:
read/write/edit files, run shell commands, search code, and a custom
commands/skills system. No business logic baked in.

> Status: early (v0.x). The package/binary name (`@therr/agent` / `therr-agent`)
> is a working name and may change before the first npm publish.
> Status: early (v0.x). Published as `@therr/tiny-code`; the binary is
> `tiny-code`. Names may change before the first npm publish.

## Install

```bash
npm install -g @therr/agent
npm install -g @therr/tiny-code
```

Or run from source:
Expand All @@ -34,9 +34,9 @@ export GEMINI_API_KEY=...
## Usage

```bash
therr-agent # start the REPL (uses an available key)
therr-agent --provider gemini # force a provider
therr-agent --model claude-opus-4-8
tiny-code # start the REPL (uses an available key)
tiny-code --provider gemini # force a provider
tiny-code --model claude-opus-4-8
```

In the REPL: type a request, watch it work. Mutating actions (writes, edits,
Expand All @@ -55,7 +55,7 @@ conventions there.
## Custom commands (skills)

Drop markdown files with YAML frontmatter into `./.agent/commands/` (per project)
or `~/.config/therr-agent/commands/` (global):
or `~/.config/tiny-code/commands/` (global):

```markdown
---
Expand All @@ -73,8 +73,8 @@ after the command (appended if the placeholder is absent).

## Configuration

Optional `therr-agent.config.json` in the project root (or
`~/.config/therr-agent/config.json`). Precedence: defaults < config file < env <
Optional `tiny-code.config.json` in the project root (or
`~/.config/tiny-code/config.json`). Precedence: defaults < config file < env <
CLI flags.

```json
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@therr/agent",
"name": "@therr/tiny-code",
"version": "0.1.0",
"description": "A small, extensible CLI coding agent with interchangeable Anthropic and Gemini models.",
"type": "module",
"bin": {
"therr-agent": "dist/cli.js"
"tiny-code": "dist/cli.js"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import type { CliOverrides, Provider } from './config/load.js';
const require = createRequire(import.meta.url);
const pkg = require('../package.json') as { version: string };

const USAGE = `therr-agent — a small, extensible CLI coding agent
const USAGE = `tiny-code — a small, extensible CLI coding agent

Usage:
therr-agent [options]
tiny-code [options]

Options:
--provider <name> anthropic | gemini (default: inferred from API keys)
Expand Down
16 changes: 8 additions & 8 deletions src/config/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ function readFileConfig(path: string): FileConfig {
*/
export function loadConfig(overrides: CliOverrides = {}, cwd: string = process.cwd()): ResolvedConfig {
const home = homedir();
const homeConfig = readFileConfig(join(home, '.config', 'therr-agent', 'config.json'));
const homeConfig = readFileConfig(join(home, '.config', 'tiny-code', 'config.json'));
const projectConfig = overrides.configPath
? readFileConfig(overrides.configPath)
: readFileConfig(join(cwd, 'therr-agent.config.json'));
: readFileConfig(join(cwd, 'tiny-code.config.json'));
const file: FileConfig = { ...homeConfig, ...projectConfig };

const env = process.env;
Expand All @@ -85,22 +85,22 @@ export function loadConfig(overrides: CliOverrides = {}, cwd: string = process.c

const provider: Provider =
overrides.provider ??
(env.THERR_AGENT_PROVIDER as Provider | undefined) ??
(env.TINY_CODE_PROVIDER as Provider | undefined) ??
file.provider ??
(anthropicApiKey ? 'anthropic' : geminiApiKey ? 'gemini' : 'anthropic');

const model =
overrides.model ?? env.THERR_AGENT_MODEL ?? file.model ?? DEFAULT_MODELS[provider];
overrides.model ?? env.TINY_CODE_MODEL ?? file.model ?? DEFAULT_MODELS[provider];

const maxTokens = env.THERR_AGENT_MAX_TOKENS
? Number(env.THERR_AGENT_MAX_TOKENS)
const maxTokens = env.TINY_CODE_MAX_TOKENS
? Number(env.TINY_CODE_MAX_TOKENS)
: (file.maxTokens ?? 16_000);

const effort = (env.THERR_AGENT_EFFORT as Effort | undefined) ?? file.effort ?? 'high';
const effort = (env.TINY_CODE_EFFORT as Effort | undefined) ?? file.effort ?? 'high';

const defaultCommandDirs = [
join(cwd, '.agent', 'commands'),
join(home, '.config', 'therr-agent', 'commands'),
join(home, '.config', 'tiny-code', 'commands'),
];

return {
Expand Down
2 changes: 1 addition & 1 deletion src/repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export async function startRepl(overrides: CliOverrides): Promise<void> {
});

console.log(
pc.bold('therr-agent') + pc.dim(` · ${provider.name}:${provider.model} · ${cwd}`),
pc.bold('tiny-code') + pc.dim(` · ${provider.name}:${provider.model} · ${cwd}`),
);
if (projectContext.trim().length > 0) {
console.log(pc.dim('Loaded project context.'));
Expand Down
2 changes: 1 addition & 1 deletion tests/commands/loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { loadCommands, renderCommand } from '../../src/commands/loader.js';
let root: string;

beforeEach(async () => {
root = await mkdtemp(join(tmpdir(), 'therr-cmd-'));
root = await mkdtemp(join(tmpdir(), 'tiny-code-cmd-'));
});

afterEach(async () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/config/context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { loadProjectContext } from '../../src/config/context.js';
let root: string;

beforeEach(async () => {
root = await mkdtemp(join(tmpdir(), 'therr-ctx-'));
root = await mkdtemp(join(tmpdir(), 'tiny-code-ctx-'));
});

afterEach(async () => {
Expand Down
18 changes: 9 additions & 9 deletions tests/config/load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ import { loadConfig } from '../../src/config/load.js';
const ENV_KEYS = [
'ANTHROPIC_API_KEY',
'GEMINI_API_KEY',
'THERR_AGENT_PROVIDER',
'THERR_AGENT_MODEL',
'THERR_AGENT_MAX_TOKENS',
'THERR_AGENT_EFFORT',
'TINY_CODE_PROVIDER',
'TINY_CODE_MODEL',
'TINY_CODE_MAX_TOKENS',
'TINY_CODE_EFFORT',
'HOME',
];

let cwd: string;
let saved: Record<string, string | undefined>;

beforeEach(async () => {
cwd = await mkdtemp(join(tmpdir(), 'therr-cfg-'));
cwd = await mkdtemp(join(tmpdir(), 'tiny-code-cfg-'));
saved = {};
for (const k of ENV_KEYS) {
saved[k] = process.env[k];
delete process.env[k];
}
// Isolate from any real ~/.config/therr-agent/config.json
// Isolate from any real ~/.config/tiny-code/config.json
process.env.HOME = cwd;
});

Expand Down Expand Up @@ -61,7 +61,7 @@ describe('loadConfig', () => {

it('reads a project config file', async () => {
await writeFile(
join(cwd, 'therr-agent.config.json'),
join(cwd, 'tiny-code.config.json'),
JSON.stringify({
provider: 'anthropic',
maxTokens: 8000,
Expand All @@ -78,10 +78,10 @@ describe('loadConfig', () => {

it('lets env override the config file model', async () => {
await writeFile(
join(cwd, 'therr-agent.config.json'),
join(cwd, 'tiny-code.config.json'),
JSON.stringify({ provider: 'anthropic', model: 'from-file' }),
);
process.env.THERR_AGENT_MODEL = 'from-env';
process.env.TINY_CODE_MODEL = 'from-env';
const cfg = loadConfig({}, cwd);
expect(cfg.model).toBe('from-env');
});
Expand Down
2 changes: 1 addition & 1 deletion tests/tools/fileTools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { grepTool } from '../../src/tools/grep.js';
let cwd: string;

beforeEach(async () => {
cwd = await mkdtemp(join(tmpdir(), 'therr-agent-'));
cwd = await mkdtemp(join(tmpdir(), 'tiny-code-'));
});

afterEach(async () => {
Expand Down
Loading