Skip to content

Host scripts

Part of the board lives outside the container: the skills the agent has installed, its credentials, the transcript of the session. The host helpers and persistent worker handle that on the machine where the agent runs and push the result into the board through the artisan commands. They ship with the package:

php artisan vendor:publish --tag=griglia-scripts   # → scripts/ in your project
Script What it does Command it feeds
sync-skills.py reads the skill folders of Claude Code, Codex CLI and Gemini CLI (plus the built-ins listed in builtin-skills.json) and tags each skill with the agents that can invoke it griglia:skills-import
sync-context.py writes the enabled context blocks back to CLAUDE.md / AGENTS.md, keeps the originals, --check tells you if they are in sync, --import loads a hand-written file griglia:context
claude-tokens.py sums the tokens of the session spent on a task (--todo=ID --args prints them ready for griglia:check --done) griglia:check
agent-status.py reads the agent's OAuth credentials and sends only percentages of the plan windows griglia:agent-status-import
griglia-agent-worker.py polls assigned work and launches Codex, Claude Code or a custom CLI; the systemd template keeps it alive griglia:check

All host scripts need python3 and reach Artisan through a transport, chosen by GRIGLIA_TRANSPORT: docker (docker exec <container> php artisan, container from GRIGLIA_CONTAINER, default laravel-dev-app), local (php artisan from the project root, with GRIGLIA_PHP naming the executable when it is not simply php) or — the default — auto, which uses the container when it is running and PHP on this machine otherwise. A host without Docker therefore runs the whole toolchain with no configuration at all; pin the choice where the probe is overhead or two setups coexist:

GRIGLIA_TRANSPORT=local
GRIGLIA_PHP=/usr/bin/php8.4

Details and everything else that changes outside a container are in Run Griglia without Docker. The synchronization helpers provide print/check modes; the worker instead needs access to the selected transport and to the agent CLI it launches. It reads the same variables and accepts per-instance overrides — see Persistent workers.

Where they think they are

The synchronization scripts need the project root (instruction files and transcript folders). They read it from GRIGLIA_PROJECT_ROOT when set; otherwise they derive it from their own position — the parent of the scripts/ folder, or the folder containing vendor/ when you run it straight from vendor/alle80/griglia/scripts/. So both of these work:

python3 scripts/sync-skills.py                              # published copy
python3 vendor/alle80/griglia/scripts/sync-skills.py        # straight from the package
GRIGLIA_PROJECT_ROOT=/srv/app python3 scripts/sync-skills.py  # anywhere else

Typical cron on the host:

* * * * * cd /srv/app && python3 scripts/sync-context.py >/dev/null 2>&1
*/5 * * * * cd /srv/app && python3 scripts/agent-status.py >/dev/null 2>&1

See also

Griglia v0.95.0