- Plexer: always-active terminal multiplexing. NativePlexerController/ TmuxPlexerController share one interface, chosen by which env var is already set (TAI_PLEXER_SOCKET vs TMUX_PANE); NativePlexerBackend is the pty.fork()-based wrapper (raw mode, SIGWINCH resize forwarding, a Unix-socket control protocol, continuous session logging, a Ctrl+A prefix key distinct from tmux's own Ctrl+B). Auto-wraps new interactive shells via a .bashrc hook mirroring the existing command-not-found install pattern, gated on $TMUX/$TAI_PLEXER_ACTIVE/ a $HOME/.tai-no-plexer bypass. New plexer_send/read/type/status tools, env-gated on a detected controller. - tests/container.py + docker-compose.yml + tests/docker/Dockerfile: a disposable podman/docker image for the tests that must never touch a real machine (installing the plexer hook into a real ~/.bashrc, a live tmux session). Required suite (test_seal.py, test_tai.py, tests/plexer.py, tests/bashrc.py) gates the result; tests/rag.py runs as best-effort since its real-LLM dependency can't be satisfied inside a disposable container with no nested engine. - tests/bashrc.py: real end-to-end hook install + bash -i auto-wrap, anti-recursion, tmux-active skip, non-interactive skip, a live TmuxPlexerController test, and an install/uninstall round-trip. - tests/plexer.py: NativePlexerBackend under a real pty, plus a dedicated robustness pass (file permissions, >64KB payload framing, a malformed control request, a genuine self-deadlock fix in the write-to-child path). - tai_test.py: the shared async process-driving framework (pipe/pty transport, group-wide kill-and-reap, a StdinBridge for --interactive) both test files build on. - ChatClient last-resort backend: when there's no local opencode CLI but the sandbox box is already running, install opencode into it (official Node tarball, not apt -- apt's nodejs/npm pull in webpack/babel/jest as transitive deps) and route through it instead of giving up. Only reachable after the first retry round already failed everything else; never creates the box itself. TmuxPlexerController.status() fixed to use `list-panes` instead of `display-message -p`, which silently fell back to the default pane instead of erroring against a dead target. - Fix 4 pre-existing test_tai.py bugs surfaced by running it in a clean environment for the first time: two stale mock signatures (subprocess.run's stdout= kwarg, Chat.complete's deadline= kwarg), one $TMUX-dependent catalog assertion, one tty-dependent color assertion. - research/: a sourced research archive (Source Dossier/Citation Card/Conclusion tiers) backing the above design decisions, with its own audit.py consistency checker. - .gitignore: fix a blanket *.md rule that was about to silently drop the entire research/ archive from version control; add __pycache__/ and the one-off debug transcript this session started from. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.2 KiB
AGENTS.md
Conventions
- Use plain
importandfromstatements in Python files. - Use the
.pyextension for Python source and test files. - Keep source files at the repository top level.
- There are two kinds of test, in two different places, on purpose — see "Testing" below for the full split. In short: unit tests are top-level
test_*.py; integration tests aretests/<topic>.py(notest_prefix) built ontai_test.py.
Testing
Unit tests: test_tai.py, test_seal.py, at the repository top level, named test_*.py, unittest-based, import tai.py as a module directly, no subprocess, fast. python3 test_tai.py / python3 test_seal.py, or a single test via python3 -m unittest test_tai.SomeClass.test_method.
Integration tests: tests/<topic>.py (e.g. tests/rag.py), deliberately not named test_*.py and not at the top level, so the two kinds are never confused. These drive the real tai.py binary as a subprocess (one-shot or REPL) and check actual CLI behavior, using tai_test.py (the framework, at the repository root) as the one and only base to build on — never a one-off subprocess/asyncio harness per file. They must exercise a real LLM call through the real binary — never a mocked model or a database write standing in for what the agent would have done; the resulting flakiness from a free, rotating backend is accepted, not engineered away. Full conventions, that rule's full rationale, the required isolation rule (always a throwaway TAI_HOME), and why verification must check vault state rather than scrape CLI rendering, are in tests/README.md — read it before adding a new one. Run with python3 tests/<topic>.py (--filter, --interactive, --timeout all supported).
Agent Overview
tai: The main autonomous agent.devops: A bot that manages the DevPlace DevOps platform.
Agent Profiles
default: Default agent profile for general tasks.work: Work-focused agent profile.dev: Development-focused agent profile.
Bot Details
devops: A bot that automates DevPlace DevOps operations.- Manages workspaces, projects, and deployments.
- Handles user authentication and access control.
- Provides development tools and utilities.
- Integrates with OpenShift Dev Spaces.
Key Features
- Autonomous decision making
- Multi-profile support
- Background subagent orchestration
- Secure vault storage
- Container sandbox support
- Progress tracking
- Interactive REPL
- Command-line interface
Usage Examples
-
Start the main agent:
./tai.py -
Use a specific profile:
./tai.py --profile work -
Run a one-shot command:
./tai.py what is 2+3, use the shell -
Check agent status:
./tai.py --version -
Install the agent:
./tai.py --install
Development Guidelines
- Write clear, concise code
- Follow Python conventions
- Test thoroughly
- Use the agent for documentation
- Keep code maintainable
- Document decisions
- Version control changes
- Collaborate effectively
Research Rule
All external research conducted for this project (web searches, reading documentation to settle a design question, competitive/prior-art analysis) is archived under research/, maintained under the auspices of the Molodetz Institute — Research & Retrieval Division. The full specification — folder layout, the three required document types (Source Dossier, Source Citation Card, Conclusion Document), required metadata, and the quality bar — lives in research/README.md; research/INDEX.md is the living registry and statistics page. Read research/README.md in full before writing into this archive.
The binding rule, in short: a research task is not done until it is written into research/. Every source actually consulted gets its own document (Tier 1 if read and synthesized, Tier 2 if only seen in a result listing — never skipped, never inflated past what's actually known), every decision the research produced gets its own Conclusion document in that subject's conclusions/ folder, and research/INDEX.md gets updated in the same pass. Check research/INDEX.md for an existing subject before opening a new one.