{"id":49103400,"url":"https://github.com/ywatanabe1989/scitex-agent-container","last_synced_at":"2026-04-28T03:07:37.265Z","repository":{"id":349744870,"uuid":"1203709829","full_name":"ywatanabe1989/scitex-agent-container","owner":"ywatanabe1989","description":"Declarative YAML-based agent lifecycle management for AI coding agents — start, stop, monitor with a single command","archived":false,"fork":false,"pushed_at":"2026-04-16T04:26:19.000Z","size":723,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-16T04:35:52.741Z","etag":null,"topics":["agent","claude-code","container","orchestration","scitex","yaml"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ywatanabe1989.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-07T09:48:19.000Z","updated_at":"2026-04-16T04:12:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ywatanabe1989/scitex-agent-container","commit_stats":null,"previous_names":["ywatanabe1989/scitex-agent-container"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ywatanabe1989/scitex-agent-container","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fscitex-agent-container","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fscitex-agent-container/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fscitex-agent-container/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fscitex-agent-container/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ywatanabe1989","download_url":"https://codeload.github.com/ywatanabe1989/scitex-agent-container/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fscitex-agent-container/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32071073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T21:26:33.338Z","status":"ssl_error","status_checked_at":"2026-04-20T21:26:22.081Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","claude-code","container","orchestration","scitex","yaml"],"created_at":"2026-04-21T00:12:29.409Z","updated_at":"2026-04-28T03:07:37.257Z","avatar_url":"https://github.com/ywatanabe1989.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- SciTeX Convention: Header (logo, tagline, badges) --\u003e\n# scitex-agent-container\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://scitex.ai\"\u003e\n    \u003cimg src=\"docs/scitex-logo-blue-cropped.png\" alt=\"SciTeX\" width=\"400\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cb\u003eDeclarative YAML-based AI agent lifecycle management\u003c/b\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://badge.fury.io/py/scitex-agent-container\"\u003e\u003cimg src=\"https://badge.fury.io/py/scitex-agent-container.svg\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://scitex-agent-container.readthedocs.io/\"\u003e\u003cimg src=\"https://readthedocs.org/projects/scitex-agent-container/badge/?version=latest\" alt=\"Documentation\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/ywatanabe1989/scitex-agent-container/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/ywatanabe1989/scitex-agent-container/actions/workflows/ci.yml/badge.svg\" alt=\"Tests\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.gnu.org/licenses/agpl-3.0\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-AGPL--3.0-blue.svg\" alt=\"License: AGPL-3.0\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ccode\u003epip install scitex-agent-container\u003c/code\u003e\n\u003c/p\u003e\n\n---\n\n\u003e **Interfaces:** Python ⭐⭐ · CLI ⭐⭐⭐ · MCP ⭐ · Skills ⭐⭐ · Hook — · HTTP —\n\n## Problem and Solution\n\n| # | Problem | Solution |\n|---|---------|----------|\n| 1 | **Fragile per-agent scripts** — launching Claude Code / Cursor / Aider means hand-rolling shell scripts for tmux, env vars, MCP configs, and auto-accept prompts, with no restart policy or health monitoring | **Declarative YAML manifest** — one file fully specifies runtime, model, MCP servers, env, health checks, and remote host; `sac start` brings the agent up in tmux/screen with auto-accept and a watchdog |\n| 2 | **No fleet story** — scaling from one agent to many across machines duplicates the same fragile scripts, with no SSH deploy, no presence, and no inter-agent comms | **Remote deploy + state inspection** — `sac` copies src files, installs the venv over SSH, and keeps a live view of every pane's state so the fleet behaves as one unit |\n\n## Problem\n\nManaging AI coding agents (Claude Code, Cursor, Aider) in production requires manual script-writing, environment setup, and process monitoring for each agent instance. Scaling from one agent to a fleet across multiple machines means duplicating fragile shell scripts with no health checks, restart policies, remote deployment, or inter-agent communication.\n\n## Solution\n\nscitex-agent-container provides declarative YAML definitions that fully specify an agent -- runtime, model, MCP servers, environment, health checks, remote host -- started with a single command:\n\n```\nYAML manifest + src_CLAUDE.md + src_mcp.json\n          |\n          v\nscitex-agent-container start\n          |\n          v\ntmux/screen session + auto-accept TUI prompts\n                     + remote SSH deploy\n                     + health monitor\n                     + restart policy\n```\n\n## Installation\n\nRequires Python \u003e= 3.10.\n\n```bash\npip install scitex-agent-container\n```\n\n## Templates\n\n`config/templates/` ships six minimal pattern templates — copy and adapt:\n\n| Template | Pattern | When to use |\n|---|---|---|\n| `local.yaml` | claude-code on local host | Default; shares operator's env (skills, MCP, venv) |\n| `docker.yaml` | claude-code in Docker | Local isolation; `mount_host_claude` opt-in |\n| `apptainer.yaml` | claude-code in Apptainer/Singularity | HPC compute nodes / locked-down hosts |\n| `ssh.yaml` | claude-code via SSH on remote host | Cross-machine fleet member |\n| `ssh-slurm.yaml` | SLURM-submitted job (with auto-resubmit) | Long-running compute on shared cluster |\n| `mcp.yaml` | claude-code with MCP server wiring | Agent that needs MCP tool access |\n\nConcrete real-world configs live in `config/examples/` (e.g. `newbie-docker.yaml`, `researcher-opus.yaml`). Both directories are validated by `tests/test_templates_v3_valid.py` — every shipped YAML must round-trip through `load_config`, and the SLURM template must additionally render a valid sbatch script.\n\nTo instantiate (dir-as-SSoT — agent name is derived from the parent directory):\n\n```bash\nmkdir -p ~/.scitex/orochi/agents/my-agent\ncp config/templates/local.yaml ~/.scitex/orochi/agents/my-agent/my-agent.yaml\nscitex-agent-container start my-agent\n```\n\n## Quickstart (v2 config)\n\n1. Create agent definition directory:\n\n```\nmy-agent/\n  my-agent.yaml     # Agent config\n  src_CLAUDE.md      # -\u003e deployed to {workdir}/CLAUDE.md\n  src_mcp.json       # -\u003e deployed to {workdir}/.mcp.json\n  src_env            # -\u003e deployed to {workdir}/.env  (mode 0600)\n```\n\nThe `src_*` family is a generic file-deploy pipeline: a sibling file named `src_X` next to the YAML is materialized into the workspace at agent start, with `${VAR}` and `${metadata.name}` interpolation. `src_env` is the dotenv variant — sourceable by anything the agent spawns (cron jobs, ssh-launched commands, fresh shells), not just the multiplexer session. See [`_skills/scitex-agent-container/06_env-injection-ports.md`](src/scitex_agent_container/_skills/scitex-agent-container/06_env-injection-ports.md) for the four distinct env-injection ports and when to use each.\n\n2. Write a YAML manifest:\n\n```yaml\napiVersion: scitex-agent-container/v2\nkind: Agent\nmetadata:\n  name: my-agent\n  labels:\n    role: worker\n    machine: local\nspec:\n  runtime: claude-code\n  model: sonnet\n  multiplexer: tmux       # tmux (default) or screen\n\n  claude:\n    flags:\n      - --dangerously-skip-permissions\n    # session: continue-or-new (default) | continue | new\n    # continue-or-new: pass --continue iff a prior session exists for the\n    #   workdir, else launch fresh. Preserves /compact history across\n    #   rolling restarts without risking a hard failure.\n    # continue: always pass --continue (fails if no prior session)\n    # new:      never pass --continue\n    session: continue-or-new\n\n  skills:\n    required:\n      - scitex\n\n  health:\n    enabled: true\n    interval: 60\n    method: multiplexer-alive\n\n  restart:\n    policy: on-failure\n    max_retries: 3\n```\n\nv2 auto-derives from `metadata.name`: workdir, session name, env vars (CLAUDE_AGENT_ID, CLAUDE_AGENT_ROLE, etc.), and pre-start hooks. Sibling `src_CLAUDE.md` and `src_mcp.json` files are deployed to the workspace with `${metadata.name}` and `${ENV_VAR}` interpolation.\n\n3. Start and monitor:\n\n```bash\nscitex-agent-container start my-agent.yaml\nscitex-agent-container inspect my-agent         # Live state detection\nscitex-agent-container status my-agent\nscitex-agent-container logs my-agent -n 100\nscitex-agent-container attach my-agent          # Ctrl-B D to detach (tmux)\n```\n\n## Remote SSH Deployment\n\nDeploy agents to remote machines:\n\n```yaml\nspec:\n  remote:\n    host: mba              # SSH hostname\n    user: ywatanabe\n    timeout: 180\n```\n\n```bash\nscitex-agent-container start remote-agent.yaml   # SSHs to remote, launches there\nscitex-agent-container stop remote-agent.yaml     # Accepts name or YAML path\nscitex-agent-container inspect my-remote-agent    # Live state from remote\n```\n\n## SLURM (single-agent)\n\nSubmit an agent as an `sbatch` job that holds the allocation, runs claude in tmux on the compute node, and auto-resubmits before walltime via a `SIGUSR1` trap:\n\n```yaml\nspec:\n  runtime: slurm\n  slurm:\n    partition: cascade\n    cpus_per_task: 4\n    mem: \"16G\"\n    time_limit: \"7-00:00:00\"\n    auto_resubmit: true\n    hooks:\n      pre_agent: ~/path/to/module-load.sh    # `module load Python/3.11.3` etc.\n```\n\n```bash\nsac start head-spartan/head-spartan.yaml   # submits sbatch on the local SLURM submission host\nsac attach head-spartan                    # srun --pty + tmux attach on the compute node\nsac stop head-spartan                      # scancel + clear state\n```\n\n## SLURM (multi-tenant — many agents on one allocation)\n\nRequires `pip install scitex-agent-container[slurm]` (pulls `scitex-hpc\u003e=0.6.1`).\n\nBook a reservation **once**, then launch many agents into the same allocation. Cuts queue wait from minutes per launch to one ssh round-trip per launch:\n\n```bash\n# Once: book a node for the day\nscitex-hpc reservations book dev-pool \\\n    --host spartan --partition cascade \\\n    --cpus 8 --mem 32G --time 7-0 \\\n    --tmux-server sac --persistent\n\n# All day: launch agents into it\nsac start dev-helper.yaml         # tmux session in dev-pool's allocation\nsac start doc-builder.yaml        # second tmux session, same allocation\nsac start test-runner.yaml        # third, same allocation\n\nsac attach dev-helper             # interactive on compute node\n\n# When done with the day's pool:\nscitex-hpc reservations release dev-pool\n```\n\nTenant agent YAML — note the new runtime kind and the `slurm.reservation` field:\n\n```yaml\nspec:\n  runtime: slurm-tenant\n  slurm:\n    reservation: dev-pool         # name of the existing scitex-hpc lease\n  claude:\n    flags: [--dangerously-skip-permissions]\n```\n\nThe reservation's hold body bootstraps a long-lived tmux server as PID 1 of the sbatch script (via `--tmux-server sac`), so tenant tmux sessions survive past their setup commands. Without it, `srun --overlap` step cgroups would terminate them within seconds.\n\n**Compatible with HPC policies banning persistent daemons** — every operation is bastion-initiated SSH, no `crontab @reboot`, no autossh, no tunnel. SLURM's documented `SIGUSR1` signal handles walltime auto-resubmit.\n\n## MCP Servers (src_mcp.json)\n\nMCP config lives alongside the YAML as `src_mcp.json` -- visible, editable, version-controlled:\n\n```json\n{\n  \"mcpServers\": {\n    \"scitex-orochi\": {\n      \"type\": \"stdio\",\n      \"command\": \"bun\",\n      \"args\": [\"run\", \"~/proj/scitex-orochi/ts/mcp_channel.ts\"],\n      \"env\": {\n        \"SCITEX_OROCHI_URL\": \"wss://scitex-orochi.com\",\n        \"SCITEX_OROCHI_AGENT\": \"${metadata.name}\",\n        \"SCITEX_OROCHI_TOKEN\": \"${SCITEX_OROCHI_TOKEN}\"\n      }\n    }\n  }\n}\n```\n\n`~` in args is expanded at deploy time. `${metadata.name}` interpolates from YAML. `${ENV_VAR}` resolves from the environment.\n\n## Auto-Accept TUI Prompts\n\nClaude Code shows confirmation prompts for dangerous flags. The auto-accept system handles them automatically using modular prompt handlers (`runtimes/prompts.py`):\n\n```python\n# Each handler: detect prompt text -\u003e send number key + Enter\nPromptHandler(name=\"bypass-permissions\",\n              detect=lambda c: \"2. Yes, I accept\" in c,\n              keys=[\"2\", \"Enter\"])\n```\n\nHandlers are order-agnostic, use numbered option text for reliability, and work with both tmux and screen. New prompts are added by appending to `PROMPT_HANDLERS`.\n\nDiagnostics logged to `~/.scitex/agent-container/logs/{name}/auto-accept.log`.\n\n## CLI Commands\n\n```bash\n# Lifecycle (accepts name or YAML path)\nscitex-agent-container start \u003cconfig.yaml\u003e\nscitex-agent-container stop \u003cname|yaml\u003e\nscitex-agent-container restart \u003cname|yaml\u003e\n\n# Inspection\nscitex-agent-container inspect \u003cname\u003e [--json]   # Live pane state detection\nscitex-agent-container status [name] [--json]   # Rich status dict (see below)\nscitex-agent-container list [--json] [--capability X] [--machine Y]\nscitex-agent-container logs \u003cname\u003e [-n LINES]\nscitex-agent-container health \u003cname\u003e [--json]\nscitex-agent-container attach \u003cname\u003e\n\n# Hook event ingestor (wired from Claude Code hooks, see below)\nscitex-agent-container hook-event \u003cpretool|posttool|prompt|stop|other\u003e\n\n# Pane actions (see \"Pane Actions\" below)\nscitex-agent-container actions run \u003cnonce-probe|compact\u003e \u003cagent\u003e [--json]\nscitex-agent-container actions query [--agent X] [--action Y] [--since 2h]\nscitex-agent-container actions stats [--agent X] [--since 7d]\nscitex-agent-container actions purge [--days N]\n\n# A2A protocol — standalone agent endpoint, no fleet deps\n# (echo handler by default; --handler claude_cli runs `claude --print`)\nscitex-agent-container a2a serve \u003cagent.yaml\u003e... [--port 8888] [--handler echo|claude_cli|exec]\n\n# Configuration\nscitex-agent-container validate \u003cconfig.yaml\u003e\nscitex-agent-container check \u003cconfig.yaml\u003e\n\n# Maintenance\nscitex-agent-container cleanup\n```\n\n## Rich Status (`status \u003cname\u003e --json`)\n\n`status \u003cname\u003e --json` returns a non-agentic snapshot of the agent suitable\nfor dashboards or fleet monitors. The payload merges the base registry\nentry with fields from `agent_meta.collect_rich()` and\n`event_log.summarize()`:\n\n| Field | Description |\n|---|---|\n| `pane_text` | Recent tmux `capture-pane` output, secrets redacted |\n| `pane_state` | Classified: `running` / `idle_prompt` / `y_n_prompt` / `auth_error` / `compose_pending_unsent` / `limit_reached` / `unknown` |\n| `stuck_prompt_text` | Last line when `pane_state` indicates a blocking prompt |\n| `claude_md` | Workspace `CLAUDE.md` contents (truncated) |\n| `mcp_json` | Workspace `.mcp.json` with token-like values redacted |\n| `recent_tools`, `recent_prompts` | Last N tool uses / user prompts from the hook ring-buffer |\n| `agent_calls`, `background_tasks` | Subagent launches and `Bash run_in_background=true` starts |\n| `tool_counts` | `{tool_name: count}` over the window |\n| `last_tool_at`, `last_tool_name` | ISO timestamp and name of the newest `pretool` event (any tool) -- functional heartbeat, distinguishes \"process alive\" from \"LLM actually producing tool calls\" |\n| `last_mcp_tool_at`, `last_mcp_tool_name` | Same, restricted to tools whose name starts with `mcp__` -- MCP sidecar health probe |\n| `last_action_at`, `last_action_name` | ISO timestamp and name of the most recent `PaneAction` attempt. `last_action_name` (renamed from `last_action`) avoids a column collision with orochi's hub schema. |\n| `last_action_outcome`, `last_action_elapsed_s` | Outcome (`success`, `precondition_fail`, `send_error`, `completion_timeout`, `skipped_by_policy`) and wall-clock duration of that attempt |\n| `action_counts` | `{action_name: count}` rollup from `action_store.summarize()` |\n| `p95_elapsed_s_by_action` | `{action_name: p95_seconds}` per-action latency headline |\n| `context_pct`, `current_tool`, `current_task`, `last_user_msg`, `model_transcript` | Derived from the active Claude Code transcript JSONL |\n| `quota_5h_used_pct`, `quota_7d_used_pct`, `quota_*_reset_at` | Claude usage (best-effort, cached) |\n| `metrics` | Host-level CPU / memory / load / disk (psutil) |\n\nEvery field is best-effort: failures leave the default value (`\"\"`,\n`0`, `[]`) rather than raising.\n\n```bash\nscitex-agent-container status my-agent --json | jq '.pane_state, .recent_tools[-3:]'\n```\n\n## Claude Code Hook Integration\n\n`hook-event` is the non-agentic counterpart to the status command: Claude\nCode invokes it on every tool call / prompt / stop, and the handler\nappends a compact JSON record to a per-agent ring-buffer at\n`$XDG_DATA_HOME/.scitex/agent-container/events/\u003cagent\u003e.jsonl` (capped at\n500 lines). `status --json` reads that buffer to populate\n`recent_tools`, `recent_prompts`, `agent_calls`, `background_tasks`, and\n`tool_counts`.\n\nWire it in the agent workspace's `.claude/settings.local.json`:\n\n```json\n{\n  \"hooks\": {\n    \"PreToolUse\":       [{\"matcher\": \"\", \"hooks\": [\n      {\"type\": \"command\", \"command\": \"scitex-agent-container hook-event pretool\"}\n    ]}],\n    \"PostToolUse\":      [{\"matcher\": \"\", \"hooks\": [\n      {\"type\": \"command\", \"command\": \"scitex-agent-container hook-event posttool\"}\n    ]}],\n    \"UserPromptSubmit\": [{\"matcher\": \"\", \"hooks\": [\n      {\"type\": \"command\", \"command\": \"scitex-agent-container hook-event prompt\"}\n    ]}],\n    \"Stop\":             [{\"matcher\": \"\", \"hooks\": [\n      {\"type\": \"command\", \"command\": \"scitex-agent-container hook-event stop\"}\n    ]}]\n  }\n}\n```\n\nAgent name resolution order: `--agent \u003cname\u003e` flag \u003e\n`SCITEX_OROCHI_AGENT` env var \u003e `CLAUDE_AGENT_ID` env var \u003e basename of\nthe current working directory. The handler swallows all errors so a\nbroken log can never block a tool call.\n\n## Pane Actions\n\nA typed, logged vocabulary for pane-mediated agent actions. Each\naction is a `PaneAction` subclass implementing four methods\n(`snapshot` / `precheck` / `send` / `is_complete`); the `run_action`\nengine classifies every attempt as `success`, `precondition_fail`,\n`send_error`, `completion_timeout`, or `skipped_by_policy`, and\nwrites it to a host-wide SQLite log at\n`~/.scitex/agent-container/actions.db` (`agent` is a column, not a\npath). Two concrete actions ship today:\n\n- `NonceProbeAction` -- sends `Repeat \u003cnonce\u003e` and confirms the model\n  echoes it back (true functional liveness, not just \"process alive\").\n- `CompactAction` -- sends `/compact` and confirms by watching\n  `context_pct` drop by at least `--min-drop-pct` (default 20).\n\n```bash\n# Run an attempt (non-zero exit on any non-SUCCESS / non-SKIPPED).\nscitex-agent-container actions run nonce-probe \u003cagent\u003e\nscitex-agent-container actions run compact \u003cagent\u003e \\\n    --min-drop-pct 30 --timeout 60 --json\n\n# Query / aggregate / purge the attempt log.\nscitex-agent-container actions query \\\n    --agent \u003cagent\u003e --action compact --since 2h --limit 20\nscitex-agent-container actions stats --agent \u003cagent\u003e --since 7d\nscitex-agent-container actions purge --days 14\n```\n\nThe latest attempt is folded into `status --json` via\n`agent_meta.collect_rich()` as `last_action_at` / `last_action_name` /\n`last_action_outcome` / `last_action_elapsed_s`, with rollups\n`action_counts` and `p95_elapsed_s_by_action`.\n\nReliable `send_keys` into a running pane needs an inter-key delay and\na settle window before `Enter`. Both are configurable via env vars\n(read once at import time by `runtimes/tmux.py` and `runtimes/screen.py`):\n\n| Env var | Default | Meaning |\n|---|---|---|\n| `SCITEX_AGENT_KEY_DELAY_S` | `0.1` | Delay between individual keys |\n| `SCITEX_AGENT_SUBMIT_SETTLE_S` | `0.3` | Settle after text, before `Enter` |\n| `SCITEX_AGENT_ACTION_RETENTION_DAYS` | `30` | Default `actions purge --days` horizon |\n\nA `send_text_and_submit(session, text)` helper wraps the \"type then\nsubmit\" pattern used by every action's `send`.\n\n## Zero Coupling to Downstream Orchestrators\n\nscitex-agent-container is a generic library. It knows nothing about\nscitex-orochi, the hub, or any particular dashboard. `status --json`\nemits a self-describing dict; downstream consumers (e.g. orochi's\n`heartbeat-push` command) wrap it -- calling `status --json`, reshaping\nthe payload, and POSTing to whatever endpoint they own. Keeping the\ntwo sides decoupled lets you swap the orchestrator, the transport, or\nthe schema without touching this package.\n\n## YAML Spec Reference\n\n| Section | Key Fields | Description |\n|---------|-----------|-------------|\n| `apiVersion` | `scitex-agent-container/v2`, `cld-agent/v1` | Config format version |\n| `metadata` | `name`, `labels` | Agent identity and labels |\n| `spec.runtime` | `claude-code`, `cursor`, `aider` | AI coding tool |\n| `spec.model` | `sonnet`, `opus[1m]` | Model selection |\n| `spec.multiplexer` | `tmux` (default), `screen` | Terminal multiplexer |\n| `spec.remote` | `host`, `user`, `timeout` | SSH remote deployment |\n| `spec.claude` | `flags[]`, `session`, `auto_accept` | Claude Code options. `session` values: `continue-or-new` (default, try `--continue` with graceful fallback), `continue` (strict resume), `new` (always fresh). Top-level `spec.session:` also accepted and takes precedence. |\n| `spec.health` | `enabled`, `interval`, `method` | Health monitoring |\n| `spec.restart` | `policy`, `max_retries`, `backoff` | Auto-restart |\n| `spec.skills` | `required[]`, `available[]` | Skill injection |\n| `spec.env` | key-value pairs | Environment variables |\n| `spec.venv` | path | Python virtualenv to activate |\n| `spec.hooks` | `pre_start`, `post_start`, `pre_stop`, `post_stop` | Lifecycle hooks |\n| `spec.container` | `runtime`, `image`, `volumes` | Docker/Apptainer |\n\n## Part of SciTeX\n\nscitex-agent-container is part of [**SciTeX**](https://scitex.ai), used as a generic agent lifecycle library by downstream orchestrators like [scitex-orochi](https://github.com/ywatanabe1989/scitex-orochi) for multi-machine fleet dispatch.\n\n\u003eFour Freedoms for Research\n\u003e\n\u003e0. The freedom to **run** your research anywhere -- your machine, your terms.\n\u003e1. The freedom to **study** how every step works -- from raw data to final manuscript.\n\u003e2. The freedom to **redistribute** your workflows, not just your papers.\n\u003e3. The freedom to **modify** any module and share improvements with the community.\n\u003e\n\u003eAGPL-3.0\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://scitex.ai\" target=\"_blank\"\u003e\u003cimg src=\"docs/scitex-icon-navy-inverted.png\" alt=\"SciTeX\" width=\"40\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c!-- EOF --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fywatanabe1989%2Fscitex-agent-container","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fywatanabe1989%2Fscitex-agent-container","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fywatanabe1989%2Fscitex-agent-container/lists"}