Metadata-Version: 2.4
Name: tack-agent
Version: 1.0.3
Summary: Self-evolving coding agent. Small, sharp, gets things done. Yours.
Author: egmaminta
License: MIT
Project-URL: Repository, https://github.com/egmaminta/tack
Project-URL: Issues, https://github.com/egmaminta/tack/issues
Project-URL: Changelog, https://github.com/egmaminta/tack/blob/main/docs/CHANGELOG.md
Project-URL: Documentation, https://github.com/egmaminta/tack/tree/main/docs
Keywords: agent,ai,anthropic,cli,coding-agent,llm,ollama,openai
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: any-llm-sdk[all]>=0.1.0
Requires-Dist: python-dotenv>=1.0
Requires-Dist: ddgs>=7.0
Requires-Dist: rich>=13.0
Requires-Dist: prompt-toolkit>=3.0
Requires-Dist: youtube-transcript-api>=1.2.4
Requires-Dist: pyyaml>=6.0
Requires-Dist: croniter>=6.2.2
Requires-Dist: fastmcp>=3.0
Requires-Dist: discord.py>=2.3
Provides-Extra: docling
Requires-Dist: docling>=2.85; extra == "docling"
Provides-Extra: tavily
Requires-Dist: tavily-python>=0.5; extra == "tavily"
Provides-Extra: ollama
Requires-Dist: ollama>=0.6.0; extra == "ollama"
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == "test"
Dynamic: license-file

# Tack

Self-evolving coding agent. ~14k lines of Python. Local-first. Provider-agnostic.

## Install

```bash
pip install tack-agent
```

The distribution is `tack-agent` because `tack` was already taken on
PyPI. The importable package and the CLI command stay `tack`.

From source:

```bash
git clone https://github.com/egmaminta/tack && cd tack
uv sync
```

MCP servers and the Discord connector ship with the base install. The
only optional extra is the heavy document parser:

```bash
pip install 'tack-agent[docling]'  # PDF/DOCX/PPTX in ReadDoc
```

## Quickstart

Point Tack at any provider that speaks OpenAI's chat-completions API.

```bash
ollama pull qwen2.5-coder:7b
tack
```

That's it. First run prompts you with three questions to seed the
identity files (`~/.tack/soul.md`, `<project>/.tack/user.md`,
`<project>/.tack/agents.md`). Skip with `--no-bootstrap`.

## Configure

`config.yaml` in the project root, or `~/.tack/config.yaml` for global.
Minimal:

```yaml
provider: ollama
model: qwen2.5-coder:7b
```

That's the entire required config. Defaults handle the rest.

For paid providers, add `api_key:` (or set `LLM_API_KEY`). For
non-default endpoints, add `api_base:`. Everything else (identity,
memory, cron, connectors, sandbox, dreaming) is opt-in and documented
in the docs below.

Env vars override YAML: `LLM_PROVIDER`, `LLM_MODEL`, `LLM_API_KEY`,
`LLM_API_BASE`, `DISCORD_BOT_TOKEN`.

## CLI

```
tack                          REPL
tack --session bug-auth       resume a named session
tack --provider ollama        override provider
tack --model qwen2.5:7b       override model
tack --thinking high          reasoning effort: none|low|medium|high|xhigh|auto
tack --verbose                show reasoning + telemetry
tack --trace                  write state transitions to ~/.tack/trace/
tack --no-sandbox             run Bash on host instead of Docker
tack --no-mcp                 disable MCP servers
tack --no-bootstrap           skip first-run identity dialogue
tack --daemon                 headless: cron + heartbeat, no stdin
```

## Slash commands

```
/help       /config     /thinking [level]   /verbose
/compact    /reset      /session {list|load|new|rename}
/skills     /soul       /user               /agents
/mcp        /listen     /copy               /exit
```

## Tools

40 built-in:

| Group | Tools |
|---|---|
| Core | Bash, Read, Write, Edit, MultiEdit, LS, Grep, Glob, ReadImage, ReadDoc |
| Sub-agent | Agent, ReadSidechain, Compact |
| Todo + Tasks | TodoRead, TodoWrite, TaskCreate, TaskUpdate, TaskList, TaskGet, TaskNext |
| Web | WebSearch, WebFetch |
| Identity | SoulEdit, UserEdit, AgentsEdit |
| Skills | SkillCreate, SkillDelete, SkillList |
| Memory | MemorySearch |
| Cron | CronCreate, CronList, CronDelete, CronEnable, CronDisable |
| Heartbeat | HeartbeatEdit |
| Discord | DiscordChannelCreate, DiscordChannelList |
| Dream | DreamRun, DreamRead |
| Email | EmailSend |

MCP tools merge in as `mcp__<server>__<tool>`.

Mutating tools (`Bash`, `Write`, `Edit`, identity edits, skill
mutations, every cron and heartbeat change, `DiscordChannelCreate`,
`DreamRun`, `EmailSend`) require approval. `approval_policy: auto`
cannot auto-approve identity, skill, cron, heartbeat, dream, or
email sends.

Profiles: `full` (40), `core` (28, no Web), `minimal` (11).

## Layout

```
tack/
  __init__.py           boot + dispatch (REPL or daemon)
  config.py             layered config: defaults < yaml < env < CLI
  agent/                loop, prompt, session, identity, memory, cron, daemon
  tools/                built-in tools + dispatcher
  connectors/           connector protocol + Discord
  mcp/                  MCP client + manager
  ui/                   abstract UIBridge, RichBridge (REPL), SilentBridge (daemon)

~/.tack/
  sessions/<hash>/      per-workdir session transcripts
  memory.db             SQLite FTS5 cross-session index
  soul.md               global persona
  cron/<id>.json        scheduled jobs
  logs/daemon.log       daemon output

<project>/.tack/
  user.md               per-project profile
  agents.md             per-project rules
```

## Docs

| | |
|---|---|
| [HOW-TO-SOUL.md](docs/HOW-TO-SOUL.md) | Identity files, agent self-edits, git integration |
| [HOW-TO-SKILLS.md](docs/HOW-TO-SKILLS.md) | Built-in skills, enable/disable, write your own |
| [HOW-TO-MEMORY.md](docs/HOW-TO-MEMORY.md) | SQLite FTS5 cross-session recall |
| [HOW-TO-CRON.md](docs/HOW-TO-CRON.md) | Cron expressions, daemon mode, failure handling |
| [HOW-TO-DISCORD.md](docs/HOW-TO-DISCORD.md) | Bot setup, allowlist, security model |
| [HOW-TO-DREAM.md](docs/HOW-TO-DREAM.md) | Nightly memory consolidation |
| [HOW-TO-EMAIL.md](docs/HOW-TO-EMAIL.md) | SMTP+TLS, allowlist, approval gate |
| [HOW-TO-MCP.md](docs/HOW-TO-MCP.md) | Connect any MCP server |
| [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Top failure modes, 5-minute fixes |
| [CHANGELOG.md](docs/CHANGELOG.md) | Per-release notes, newest first |

## Status

- **Version 1.0.0.** [GitHub releases](https://github.com/egmaminta/tack/releases).
- **Python 3.12+**, no cloud services required for core function.
- **CI: Linux, macOS, Windows.** `uv run pytest tests/ -q` runs the
  suite locally.
- **MIT license.** See [LICENSE](LICENSE).
