Skip to content

Wrappers

wrappers

Shell wrapper generation for agent CLI commands.

Produces per-provider bash functions (claude(), codex(), vibe(), etc.) that set git identity, handle session resume, and support both interactive and headless (--terok-timeout) modes.

The shell itself lives in the Jinja template resources/templates/agent-wrappers.sh.j2; this module only prepares the per-provider data the template renders. Keeping the shell in a template — rather than assembling it from Python string fragments — lets the wrapper logic be read as shell, with the vendor-specific blocks visible inline.

INITIAL_PROMPT_PATH = '/home/dev/.terok/initial-prompt.txt' module-attribute

Container path of the per-task initial prompt the TUI/CLI writes at launch.

INITIAL_PROMPT_CONSUMED_PATH = '/home/dev/.terok/initial-prompt.consumed.txt' module-attribute

Where the prompt file is moved after an agent picks it up (one-shot semantics).

INSTRUCTIONS_PATH = '/home/dev/.terok/instructions.md' module-attribute

Container path of the resolved terok per-task system instructions.

CONTAINER_WORKSPACE = '/workspace' module-attribute

Container path the host-side repo is bind-mounted at (see container/env.py).

generate_all_wrappers(has_agents)

Render terok-executor.sh: a shell wrapper function for every provider.

The output file contains a shell function per provider (claude(), codex(), vibe(), …), each with correct git env vars, timeout support, and session-resume logic, plus the two shared helper functions they call. This lets interactive CLI users invoke any agent regardless of which provider was configured as default.

Parameters:

Name Type Description Default
has_agents bool

Whether an agents.json was written — adds Claude's --agents flag to the claude() wrapper.

required
Source code in src/terok_executor/provider/wrappers.py
def generate_all_wrappers(has_agents: bool) -> str:
    """Render ``terok-executor.sh``: a shell wrapper function for every provider.

    The output file contains a shell function per provider (``claude()``,
    ``codex()``, ``vibe()``, …), each with correct git env vars, timeout
    support, and session-resume logic, plus the two shared helper functions
    they call.  This lets interactive CLI users invoke any agent regardless of
    which provider was configured as default.

    Args:
        has_agents: Whether an ``agents.json`` was written — adds Claude's
            ``--agents`` flag to the ``claude()`` wrapper.
    """
    providers = [_wrapper_context(p) for p in AGENT_PROVIDERS.values()]
    return _env().from_string(_template_source()).render(providers=providers, has_agents=has_agents)

generate_agent_wrapper(provider, has_agents=False)

Render a single provider's wrapper function, without the shared helpers.

Used to inspect one provider's wrapper in isolation; the full file (with the _terok_resume_or_fresh / _terok_trust_workspace_for_vibe helpers) is produced by generate_all_wrappers.

Source code in src/terok_executor/provider/wrappers.py
def generate_agent_wrapper(provider: AgentProvider, has_agents: bool = False) -> str:
    """Render a single provider's wrapper function, without the shared helpers.

    Used to inspect one provider's wrapper in isolation; the full file (with
    the ``_terok_resume_or_fresh`` / ``_terok_trust_workspace_for_vibe``
    helpers) is produced by
    [`generate_all_wrappers`][terok_executor.provider.wrappers.generate_all_wrappers].
    """
    ctx = _wrapper_context(provider)
    # Jinja resolves macros dynamically, so the template module's macro
    # attributes (claude_wrapper / generic_wrapper) are not statically known.
    macros: Any = _env().from_string(_template_source()).module
    if ctx["is_claude"]:
        return str(macros.claude_wrapper(ctx, has_agents))
    return str(macros.generic_wrapper(ctx))