Skip to content

hjun1052/tali

Repository files navigation

Tali

Release CI License: MIT

One command instead of a fragile wall of setup instructions.

Tali is an AI-friendly command manifest runner. It gives coding agents a safe, auditable way to hand work to a human:

tali 03

Instead of pasting this into terminal:

cd app
npm install
cp .env.example .env
npm run db:migrate
npm run deploy

an agent writes a Tali manifest, registers it, and tells the user to run one short command. Tali shows the plan, asks for approval, collects inputs and secrets, executes the steps, masks sensitive output, and stores complete logs for repair.

Tali is intentionally boring in the best way: it is a runtime, not a planner. The agent decides what should happen. Tali runs the manifest predictably.

Install

macOS and Linux:

curl -fsSL https://github.com/hjun1052/tali/releases/latest/download/install.sh | sh

Windows PowerShell:

irm https://github.com/hjun1052/tali/releases/latest/download/install.ps1 | iex

The installer verifies checksums, runs tali self-test, and installs the bundled tali-agent skill into detected agent skill directories when possible.

Useful installer options:

TALI_VERSION=0.1.5 curl -fsSL https://github.com/hjun1052/tali/releases/latest/download/install.sh | sh
TALI_INSTALL_DIR="$HOME/.local/bin" curl -fsSL https://github.com/hjun1052/tali/releases/latest/download/install.sh | sh
TALI_INSTALL_SKILL=0 curl -fsSL https://github.com/hjun1052/tali/releases/latest/download/install.sh | sh
TALI_SKILL_DIRS="$HOME/.codex/skills:$HOME/.agents/skills" curl -fsSL https://github.com/hjun1052/tali/releases/latest/download/install.sh | sh

Update later with:

tali update

What It Feels Like

$ tali 03
Manifest: nextjs-blog
Plan:
1. Shell: npm install
2. Write file: .env
3. Shell: npm run dev
Inputs required:
- project_name
- database_url [secret]
Okay to proceed? [y/N] y
Project name [my-app]:
Database URL:
Running step 1/3: Install dependencies
...
Run succeeded.
Logs saved to:
/Users/you/Library/Application Support/tali/runs/run-20260615071629-g42VzkQr

If something fails:

Run failed.
Failed step: 3 / 3
Step name: Start dev server
Exit code: 1
Logs saved to:
...
For AI repair, share:
tali logs latest

Why Agents Need This

Coding agents are getting good at planning local changes, but the handoff to a human is still clumsy. The usual pattern is a long checklist of commands, manual edits, copied secrets, and "if this fails, try..." notes.

Tali turns that into a small contract:

  • The agent writes exactly what should happen.
  • The user sees the plan before it runs.
  • Secrets are prompted at runtime and masked everywhere.
  • Every run gets structured logs, stdout, stderr, live events, and a manifest copy.
  • A failed run can be inspected by an agent and repaired with a new manifest.

That makes Tali useful for setup scripts, local dev bootstraps, one-off deploys, project migrations, test runs, environment creation, and anything else where "please run these 12 commands" would normally appear in chat.

Quick Start For Agents

Create a manifest:

version = 1
name = "nextjs-blog"
description = "Install dependencies, write .env, and start dev."

[[inputs]]
name = "database_url"
prompt = "Database URL"
secret = true
required = true

[[inputs]]
name = "project_name"
prompt = "Project name"
required = true
default = "my-app"

[[steps]]
name = "Install dependencies"
type = "shell"
cmd = "npm install"

[[steps]]
name = "Write env file"
type = "write_file"
path = ".env"
content = """
DATABASE_URL={{database_url}}
PROJECT_NAME={{project_name}}
"""

[[steps]]
name = "Start dev server"
type = "shell"
cmd = "npm run dev"

Register it:

tali add setup.toml --json

Tell the user only:

tali 03

Watch progress while the user runs it:

tali logs follow latest

If it fails, collect repair context:

tali logs latest --for-ai

Manifest Steps

Tali supports five MVP step types.

Shell

[[steps]]
name = "Deploy"
type = "shell"
cmd = "npm run deploy"
cwd = "."

[steps.env]
OPENAI_API_KEY = "{{openai_key}}"

Shell commands run through sh -lc on macOS/Linux and PowerShell on Windows (pwsh when available, then powershell). Tali streams stdout/stderr to the user and stores masked logs.

Write File

[[steps]]
name = "Write env"
type = "write_file"
path = ".env"
content = "OPENAI_API_KEY={{openai_key}}"
overwrite = true
create_dirs = true

Before overwriting a file, Tali stores a lightweight backup under the run directory so future rollback support has the data it needs.

Mkdir

[[steps]]
name = "Create config directory"
type = "mkdir"
path = "config"

Copy

[[steps]]
name = "Copy env template"
type = "copy"
from = ".env.example"
to = ".env"
overwrite = false

Replace In File

Use replace_in_file when a project already has placeholders and Tali should fill only those positions:

[[steps]]
name = "Fill API key"
type = "replace_in_file"
path = ".env"
expected_matches = 1

[steps.replacements]
"__OPENAI_API_KEY__" = "{{openai_key}}"

Given this existing file:

OPENAI_API_KEY=__OPENAI_API_KEY__

Tali prompts for openai_key, replaces the placeholder, stores a backup, and logs only the number of replacements. It does not log the rendered file content.

Fields:

  • path: required file path
  • replacements: required table of placeholder = replacement
  • require_match: optional bool, default true
  • expected_matches: optional total replacement count

Conditions

Steps can be conditional with when:

[[steps]]
name = "Install macOS tools"
type = "shell"
cmd = "brew bundle"
when = "os_is('macos') && file_exists('Brewfile')"

Supported helpers:

  • os_is("macos" | "linux" | "windows")
  • file_exists("path")
  • dir_exists("path")
  • env_exists("NAME")
  • input_exists("name")
  • input_equals("name", "value")

Use not, &&, ||, and parentheses for boolean logic.

Commands

tali add <path>
tali add <path> --json
tali list
tali run <id-or-name>
tali <id-or-name>
tali inspect <id-or-name>
tali run <id-or-name> --dry-run
tali run <id-or-name> --yes
tali run <id-or-name> --no-update-check
tali run <id-or-name> --input key=value
tali run <id-or-name> --input-env secret_name=ENV_VAR
tali logs latest
tali logs latest --json
tali logs latest --for-ai
tali logs follow latest
tali logs <run-id>
tali cleanup --dry-run
tali cleanup --older-than 30d
tali cleanup --older-than 30d --yes
tali skill install <skill-dir>
tali skill install <skill-dir> --no-overwrite
tali update --check
tali update
tali doctor
tali self-test
tali completions zsh

Cleanup

Tali keeps full run logs because they are valuable for repair. Over time, that can take space. Use cleanup when old runs are no longer useful:

tali cleanup --dry-run

Preview output:

Cleanup preview:
Runs older than 30d: 12
Cache entries older than 30d: 38
Estimated space to free: 84.0 MB

Nothing deleted. Run with:
tali cleanup --older-than 30d --yes

Cleanup is conservative:

  • tali cleanup previews by default.
  • --yes is required to delete.
  • runs/ and cache/ are eligible.
  • manifests/ and secrets/ are never deleted by cleanup.
  • A currently running run is skipped.
  • If the latest run is deleted, logs/latest is moved to the newest remaining run.

Supported ages: 60s, 15m, 12h, 30d.

Project Manifests

Global manifests are temporary or semi-temporary handoffs created by agents. Project manifests can be private local conveniences or explicit shared project assets:

project/
└─ .tali/
   ├─ setup.toml
   ├─ build.toml
   ├─ deploy.toml
   └─ share/
      └─ ci.toml

Run them by name:

tali setup
tali build
tali deploy

Private project manifests live directly under .tali/. Because those files can contain local paths or workflow details, Tali checks after a project-local run whether .tali/ is ignored by git. If it is not ignored, interactive runs ask before adding this recommended block:

# Tali private manifests and runtime files
.tali/
!.tali/share/
!.tali/share/*.toml

Runs with --yes or non-interactive stdin never modify .gitignore automatically; they print the suggested block instead. If you want a manifest to be committed and shared, put it under .tali/share/<name>.toml. tali <name> resolves .tali/<name>.toml first, then .tali/share/<name>.toml, then global manifests.

Updates

Check manually:

tali update --check

Update in place:

tali update

After tali run, tali doctor, and tali self-test, Tali may perform a passive update check at most once every 24 hours. Network failures are ignored and never change the command result. Disable passive checks with:

tali run setup --no-update-check
TALI_NO_UPDATE_CHECK=1 tali run setup

Storage

Tali uses platform-correct app data directories:

  • macOS: ~/Library/Application Support/tali/
  • Linux: $XDG_DATA_HOME/tali/ or ~/.local/share/tali/
  • Windows: %APPDATA%\tali\

Layout:

tali/
├─ manifests/
├─ runs/
├─ logs/
├─ cache/
└─ secrets/

Each run stores:

runs/<run-id>/
├─ run.json
├─ events.jsonl
├─ stdout.log
├─ stderr.log
├─ manifest.toml
└─ backups/

Security Model

Tali is not a sandbox and does not try to prove shell commands are safe.

It does provide practical guardrails:

  • The plan is shown before execution.
  • Approval is required unless --yes is passed.
  • --yes approves the manifest run, not repository policy changes such as editing .gitignore.
  • Secret inputs use hidden prompts.
  • Secret values are masked in commands, env values, stdout, stderr, live events, and JSON logs.
  • File operations cannot escape the working directory by default.
  • allow_outside_cwd = true is required for file writes/copies/replacements/mkdir outside the working directory.
  • Persistent encrypted secrets are not implemented yet; secrets/ exists for future use.

Tali does not guess where secrets should go. The manifest author must decide where to interpolate them.

Development

cargo test
cargo run -- doctor
cargo run -- self-test

Rust version is 1.85. Maintainer release tags match the Cargo version, for example v0.1.5.

Release checks:

./scripts/release-check.sh

Status

Tali is early, practical infrastructure for AI-assisted development workflows. The core loop is already here: manifest, approval, execution, live logs, repair logs, agent skill installation, update, and cleanup.

If you build with coding agents and are tired of turning chat instructions into terminal chores, Tali is for you.

About

AI-friendly command manifest runner

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors