ti-agent
v0.1.8
Published
Effect v4 native AI coding agent CLI
Maintainers
Readme
ti-agent
Minimal ti CLI and interactive composer.
Install
ti-agent publishes the ti binary.
The npm package is the Node-runtime install path and requires Node.js 20 or
newer. Use the GitHub Release binaries when the target machine should not need
Node, Bun, Deno, or pnpm.
One-command install:
curl -fsSL https://raw.githubusercontent.com/agustif/ti/main/install.sh | shnpm install -g ti-agent
ti --version
ti authRun without installing globally:
pnpm dlx ti-agent auth
npx ti-agent auth
bunx ti-agent authPin an install-script version with TI_VERSION:
curl -fsSL https://raw.githubusercontent.com/agustif/ti/main/install.sh | TI_VERSION=0.1.8 shCommands
ti
ti login chatgpt
ti logout chatgpt
ti auth
ti models chatgpt
ti chat [--provider <openai|chatgpt>] [--session <id>] [--model <model>] <prompt>
ti resume --last
ti tool <read|write|edit|apply_patch|bash|py|code> '<json-args>'
ti --versionRuntime bundles
The portable runtime probe builds through Rslib:
pnpm --filter ti-agent runtime:buildThat single build emits:
dist/runtime/node/runtime-probe.js
dist/runtime/llrt/runtime-probe.js
dist/runtime/quickjs-ng/runtime-probe.jsDurable logs
ti keeps the terminal quiet by default. Enable durable Effect JSON logs only when
debugging stream/provider behavior:
TI_LOG=1 ti
TI_LOG_DIR=/tmp/ti-logs ti
TI_LOG_PATH=/tmp/ti.jsonl ti chat --provider chatgpt "hello"TI_LOG=1writes.ti/logs/ti-<timestamp>-<pid>.jsonl.TI_LOG_DIRchooses a log directory;TI_LOG_PATHchooses the exact JSONL file.TI_LOG_LEVELdefaults toDebugwhen logging is enabled.TI_LOG_STREAM_TEXT=1adds short content/reasoning previews. Without it, logs stay metadata-only.- Stream logs use the current OpenTelemetry GenAI semantic attribute names such as
gen_ai.operation.name,gen_ai.provider.name,gen_ai.request.model,gen_ai.response.finish_reasons, and token usage when the provider returns it. These GenAI conventions are still marked Development by OpenTelemetry. - Provider diagnostics are hidden from the UI but logged when durable logging is enabled, including raw SSE event types so reasoning-summary wiring can be verified live.
Interactive commands
Inside ti:
/help— show commands and shortcuts/version— show theti-agentpackage version, binary, runtime, and entrypoint/status— show version, repo, model, auth, session, and shortcuts/tools— list built-in tools/read <path>— preview a file and persist the full output to the session/bash <command>— run a shell command/py <code>— run Python throughuv,python3, orpython/tool <name> <json>— run any built-in tool with JSON args/session— show the current session id/quitorctrl-c— exit
Interactive shortcuts:
Enter— submit prompt or commandUp/Down— browse prompt historyCtrl-L— clear screenCtrl-T/Ctrl-O— show latest tool detailsCtrl-D— toggle debug overlayEsc— request interrupt for the active runCtrl-C— exit
Code Mode
Code Mode is an optional harness over the existing tool registry. It gives the
model one code tool whose JavaScript function can call current tools through
codemode.*:
ti tool code '{"code":"async () => codemode.read({ path: \"package.json\" })"}'
ti tool code '{"code":"async () => { const pkg = await codemode.readJson({ path: \"package.json\" }); return pkg.name; }"}'
TI_TOOL_MODE=code tiThe output is always parseable pretty JSON produced through Effect's formatter surface. Large values are truncated into a valid JSON envelope instead of returning a broken partial JSON string.
Tool calls preserve the raw tool result in the trace. When a tool returns JSON
text, parse it explicitly with codemode.readJson(args),
codemode.json.read(args), codemode.json.tool(name, args), or
codemode.json.parse(text). Automatic double-parsing is avoided so plain text
tool output and audit traces stay faithful to what the tool returned.
The current executor runs in the current JavaScript runtime. It is useful for local orchestration and runtime-host experiments, but it is not a sandbox or security boundary.
Runtime Policy
- Optional diagram or media renderers are not part of the default CLI. If they return, they should live in a small plugin/skill area rather than in core.
- The interactive agent has no default max model-round or tool-call cap.
Configure
TI_MAX_MODEL_ROUNDSorTI_MAX_TOOL_CALLSonly for a specific orchestrator/subagent policy. Values must be base-10 whole numbers; leave them unset for unbounded runs. TI_REPEATED_TOOL_BATCH_LIMITcontrols the repeated-batch doom-loop guard. Leave it unset for the runtime default, set it to0to disable it, or use a base-10 whole number to override the limit.
OpenAI WebSocket Transport
OpenAI can also use the experimental Responses WebSocket transport:
TI_OPENAI_TRANSPORT=responses-websocket tiThe default remains HTTP SSE. WebSocket mode requires a runtime whose
globalThis.WebSocket supports handshake headers; Node 25+ works in local
testing, while QuickJS/LLRT support depends on the selected host.
Notes
chatuses the configured provider layer and stores turns in the active session when session persistence is enabled.login/logout/auth/modelsare currently wired for ChatGPT auth and model discovery.- Live chat requires
OPENAI_API_KEY. - The default
ti-core-toolsplugin contributesread,write,edit,apply_patch,bash,py,code, andpreload_cli_tool. TI_TUI_SESSION_DIRcan override the interactive session storage directory.TI_TUI_SESSION_IDremains an internalresumehandoff variable while the current interactive boot path still snapshots env at startup.
