Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
387 changes: 242 additions & 145 deletions .agents/skills/fleet-onboarding/SKILL.md

Large diffs are not rendered by default.

80 changes: 56 additions & 24 deletions .agents/skills/fleet-pane/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: fleet-pane
description: Put the fleet queue pane on the operator's thurbox screen and diagnose it when it is installed and drawing nothing, or drawing the wrong thing. Covers the install (a side effect of scripts/install-extension.sh), what verifies it, the layout.lua block that places it and that nothing here writes, the F-key that hides it, and removal. Use when asked to install, place, hide, remove or debug the TUI queue pane, when the pane is there and empty, or when it draws too much to read.
description: Put the fleet queue pane on the operator's thurbox screen and diagnose it when it is installed and drawing nothing, or drawing the wrong thing. Covers the install (a side effect of scripts/install-extension.sh), what verifies it, the layout.lua block that places it and the script that writes that block on the operator's word, the F-key that hides it, and removal. Use when asked to install, place, hide, remove or debug the TUI queue pane, when the pane is there and empty, or when it draws too much to read.
user-invocable: true
allowed-tools: Read, Bash, Glob, Grep
---
Expand All @@ -11,14 +11,19 @@ allowed-tools: Read, Bash, Glob, Grep
the view is and why it is built the way it is; this skill owns getting it onto a
screen and finding out why it is not on one.

> **Installing the pane and seeing the pane are two different things, and only
> one of them is fleet's.** `thurbox-cli plugin install` succeeding and
> `thurbox-cli plugin list` showing the pane are both true of a pane the
> operator cannot see. A thurbox pane names a *slot*; the ARRANGEMENT decides
> where that slot goes, and the arrangement is `layout.lua` — a file every pane
> on their screen shares, so **nothing in this repo writes it and neither do
> you**. A pane no arrangement places loads cleanly, declares its keys, appears
> in `plugin list`, and draws nothing.
> **Installing the pane and seeing the pane are two different things.**
> `thurbox-cli plugin install` succeeding and `thurbox-cli plugin list` showing
> the pane are both true of a pane the operator cannot see. A thurbox pane
> names a *slot*; the ARRANGEMENT decides where that slot goes, and the
> arrangement is `layout.lua` — a file every pane on their screen shares. A
> pane no arrangement places loads cleanly, declares its keys, appears in
> `plugin list`, and draws nothing.
>
> **`./scripts/place-pane.sh` writes that block, and only ever because the
> operator said to.** It is never a step that happens on the way to something
> else: ask, then run it. It refuses a layout it cannot recognise, backs the
> file up, re-reads its own edit with `lua`, and verifies with `plugin check`.
> §4 is the whole of it.

That is the failure with no symptom, and every message the operator has says it
should be working. Reach for §4 before anything else when a pane is "installed
Expand Down Expand Up @@ -175,7 +180,7 @@ whether anything draws it. `--json` adds `installed_from`, which is the useful
part: it names the checkout the pane was installed from, so a stale path here
and a moved clone are the same bug.

## 4. Placing it — the operator's edit, not yours
## 4. Placing it — the operator's call, and then the script's job

The block goes **inside the `columns` list** of `layout.lua`, beside the other
side columns:
Expand All @@ -186,18 +191,39 @@ if panels.shown("fleetqueue") and filled(ctx, "fleetqueue") then
end
```

Find the file rather than assuming `~/.config/thurbox/ui` — a dev build's
interface directory is elsewhere:
**Ask first — always.** A mistake in `layout.lua` takes the whole interface
down, not one column, and it is the operator's file: the bundled panes, their
arrangement and every other plugin they have all live in it. So the choice is
theirs, and it is a real one — right of the terminal (the recommended place: a
narrow readout beside the agent, session list still on the left), left of it,
or the block printed for them to add by hand.

On yes:

```bash
thurbox-cli plugin dir --text | head -1
./scripts/place-pane.sh --dry-run # the file, the anchor and the exact block
./scripts/place-pane.sh # right of the terminal
./scripts/place-pane.sh --left # between the session list and the terminal
./scripts/place-pane.sh --check # is it placed? changes nothing
```

**Print the block, say where it goes, and stop there on purpose.** A mistake in
`layout.lua` takes the whole interface down, not one column, and it is the
operator's file — the bundled panes, their arrangement and any other plugin they
have all live in it. This skill does not carry write tools for that reason. Say
plainly that you stopped, rather than offering to do it.
What makes that safe enough to run at all, and what its header argues in full:
it refuses a layout it does not recognise rather than guessing and says which
part it could not find, it is idempotent — a layout already carving the slot is
left exactly as the operator arranged it — it backs the file up to
`layout.lua.bak-<timestamp>` first, it re-reads its own edit with `lua` and
puts the backup back if the result no longer parses, and it finishes with
`thurbox-cli plugin check`. The slot it writes is read from
`interface/fleet_queue.lua`, never spelled in the script, so a rename cannot
half-land.

If they would rather do it themselves, print the block, name the file, and stop
there on purpose. Find it rather than assuming `~/.config/thurbox/ui` — a dev
build's interface directory is elsewhere:

```bash
thurbox-cli plugin dir --text | head -1
```

**Give the guard, not just the slot.** `plugin check` suggests a bare
`{ slot = "fleetqueue" }`, and that is enough to make the pane DRAW — which is
Expand Down Expand Up @@ -237,9 +263,11 @@ removes nothing. That one command takes back the file, its `plugins.toml` entry
and the lock together; `plugin list` names the path to pass while it is still
installed, and `scripts/install-extension.sh`'s header owns this.

Removing the pane leaves the `layout.lua` block behind. It is guarded by
`filled(ctx, "fleetqueue")`, so an orphaned block carves nothing and is
harmless — but it is the operator's line to delete, on the same terms as §4.
Removing the pane leaves the `layout.lua` block behind, and `place-pane.sh`
has no verb that takes it back out — a block it did not necessarily write is
not one it should delete. It is guarded by `filled(ctx, "fleetqueue")`, so an
orphaned block carves nothing and is harmless; deleting it is the operator's
line, on the same terms as §4.

Taking back the whole extension is a different verb —
`thurbox-cli extension deactivate` / `uninstall`, which the installer's closing
Expand All @@ -260,8 +288,8 @@ spells out in the column itself, so:

| What you see | What it means | What to do |
|---|---|---|
| no column; `plugin check` exits non-zero | installed, placed by nothing | §4 — print the block |
| column opens and never closes | placement block is missing `panels.shown` | §4 — add the guard |
| no column; `plugin check` exits non-zero | installed, placed by nothing | §4 — ask, then `./scripts/place-pane.sh` |
| column opens and never closes | placement block is missing `panels.shown` | §4 — the guard is missing from a hand-added block |
| `F3` opens Help, Theme or Settings | the chord collides with a kernel one | rebind in thurbox settings; `check.sh pane` refuses a kernel chord in the repo |
| `not trusted yet` | the `run` capability is declared, not granted | the operator grants it: settings (`Ctrl+,`) → `]` → `t`. You cannot do it for them |
| `no '<lead>' session` | no session by the name the pane probes | the extension has not been installed, or the lead was renamed — §2, and `extension.toml.in`'s RENAMING header |
Expand Down Expand Up @@ -299,7 +327,11 @@ the harness to reproduce a shape you are chasing.
## 8. The gate

`./scripts/check.sh pane` is what keeps this skill and the installer from
drifting apart from the pane. It holds one spelling of the slot name, the
drifting apart from the pane, and `./scripts/check.sh onboarding` covers the
writer: `scripts/onboarding-selftest.sh` §3 drives `place-pane.sh` against a
copy of a stock layout — placed right by default, left on `--left`, idempotent,
backed up, refused on an arrangement it cannot read, and still parsing as Lua
afterwards. It holds one spelling of the slot name, the
placement guard, the `plugin remove` path and the F-key across the pane, the
installer and the documents that print the block — this file among them — and it
refuses a binding on a chord the kernel owns. Read `check_pane` in
Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/update-fleet/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ than inferring the pane from the exit code** — §4.
## 4. Pane — the installed plugin is stale

`.agents/skills/fleet-pane/` owns the pane end to end: the install, the one
command that verifies it, the `layout.lua` block that places it and that nothing
here writes, the F-key, removal, and the symptom table for a pane that is
installed and drawing nothing. **Use that skill; do not restate its procedure
command that verifies it, the `layout.lua` block that places it and the script
that writes that block once the operator says so, the F-key, removal, and the
symptom table for a pane that is installed and drawing nothing. **Use that skill; do not restate its procedure
here.** §3 already re-ran the install, so what is left is its verification step
and, if that comes back unplaced, its placement section.

Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,27 @@ jobs:
sudo ln -sf /usr/bin/lua5.4 /usr/local/bin/lua
- run: ./scripts/check.sh pane

# Unfiltered, for the same reason the pane job is: what it covers spans four
# scripts, a fixture and the pane's own slot declaration, so a paths filter
# would have to list all of them to be correct. It is also the setup nobody
# re-runs — a regression here is invisible to every operator who is already
# set up, and total for the next one. Two seconds, offline, all stubs.
onboarding:
name: Onboarding
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
# place-pane.sh reads its own edit back with `lua` and restores the
# backup when the result no longer parses; without an interpreter that
# assertion silently skips. The apt dance is the pane job's — see there.
- name: Install lua
run: |
sudo rm -f /etc/apt/sources.list.d/google-chrome.list /etc/apt/sources.list.d/google-chrome.sources
sudo apt-get update -qq
sudo apt-get install -y --no-install-recommends lua5.4
sudo ln -sf /usr/bin/lua5.4 /usr/local/bin/lua
- run: ./scripts/check.sh onboarding

# Single required status check. Every job feeds this gate; a branch ruleset
# requires only "All Checks", so adding or removing jobs never needs a
# ruleset change — but a new job MUST be added to `needs:` below, or it can
Expand All @@ -208,6 +229,7 @@ jobs:
- reconcile
- skills
- pane
- onboarding
runs-on: ubuntu-latest
steps:
- name: Verify all checks passed
Expand Down
28 changes: 20 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,12 @@ names every path and the reason for each.
view of the queue, drawn in a thurbox column over the same records
`queue.sh list` reads. `scripts/install-extension.sh` installs it
with `thurbox-cli plugin install`; the file's own header owns the view.
**Placing it is a guarded block in the user's `layout.lua` and nothing here
writes it** — a pane no arrangement places loads, lists, and draws nothing.
**Placing it is a guarded block in the user's `layout.lua`, and
`./scripts/place-pane.sh` writes that block — only ever after the operator
was ASKED and said yes** — because a pane no arrangement places loads, lists,
and draws nothing. It refuses a layout it cannot recognise, backs the file up,
re-reads its own edit with `lua`, and verifies with `thurbox-cli plugin
check`; the fleet-pane skill's §4 owns the ask.
`./scripts/pane-selftest.sh` renders it offline — no thurbox, no queue, no
session; `check.sh pane` runs it.
`.agents/skills/fleet-pane/` is the driving surface for all of it: install,
Expand All @@ -91,14 +95,22 @@ names every path and the reason for each.
Everything outside that fence is the lead's judgement and nothing ever
overwrites it. Gitignored, like everything a run produces; the template is
the one tracked file there.
- `scripts/preflight.sh` — every dependency fleet needs, in one pass, in three
tiers (required / recommended / gate), each row carrying what breaks without
it and the command that installs it. It probes and prints; installing is the
operator's, which is what `--commands` is for. `scripts/discover-owners.sh`
is its counterpart for the one input the map needs: it reads the `gh`
session, the git config and the remotes of the clones already on the disk,
and prints owner candidates with the evidence for each. Both write nothing.
- `.agents/skills/<name>/SKILL.md` — agent skills, in one agent-agnostic tree.
`.claude/skills` is a **symlink** to it, so Claude Code and opencode (which
auto-discovers `.claude/skills`) both load the same copy. Never add a second
copy under `.claude/`, and do not mirror into `.opencode/skills` — that
registers the same skill twice. Five skills live there: `fleet-queue` (the
queue: intake, ordering, dispatch, and the two halves of completion),
`thurbox-session` (driving one worker session), `fleet-onboarding` (a fresh
clone to a working control plane),
clone to a working control plane: dependencies, owners, registry, extension,
the pane on screen, the loop up),
`fleet-pane` (getting the TUI queue pane onto a screen, and diagnosing one
that is installed and drawing nothing), and `update-fleet` (a working control
plane that is BEHIND origin, and the consequences of the sync that
Expand Down Expand Up @@ -248,14 +260,14 @@ CI only runs on pull requests, and routine control-plane changes go straight to
`main`. So gate locally before you push:

```bash
./scripts/check.sh # shellcheck, markdown, YAML, profiles, queue,
# reconciler, status, skills, pane
./scripts/check.sh # every check
./scripts/check.sh --fix # same, applying the fixes a check can apply
```

That one script is the whole gate. CI runs it, the prek hooks run it, and
`.no-mistakes.yaml` points its `lint` command at it, so a green local run and a
green pull request mean the same thing.
That one script is the whole gate, and its header names every check it runs. CI
runs it, the prek hooks run it, and `.no-mistakes.yaml` points its `lint`
command at it, so a green local run and a green pull request mean the same
thing.

Changes that open a pull request land by **squash merge** — the only merge
method the remote allows — so the pull request title becomes the commit on
Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ generated registry, and agent skills. Everything below follows from that.
One script is the whole gate:

```bash
./scripts/check.sh # shellcheck, markdown, YAML, profiles, queue, reconciler, status, skills, pane
./scripts/check.sh # every check
./scripts/check.sh --fix # the same, applying the fixes a check can apply
./scripts/check.sh shell # just one check
```
Expand All @@ -20,7 +20,8 @@ requests** while routine control-plane changes go straight to `main`, so the
local run is the one doing the work.

A missing tool fails the check rather than skipping it. The script's header
holds the full tool list and the full usage.
holds the full list of checks, the tools they need, and the full usage —
it is the one place that list lives.

### Pre-commit hooks

Expand Down
34 changes: 24 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,30 @@ Then open the clone in your agent CLI and run:
```

The [onboarding skill](.agents/skills/fleet-onboarding/SKILL.md) does the setup
rather than instructing you through it — prerequisites, your GitHub owners, the
repo map, the thurbox extension, the queue pane and the reconciler —
verifying each step and naming anything missing with its remedy
before it writes a thing.
Run it twice and it converges. It hands you a guarded block to add yourself:
the pane's slot in your thurbox `layout.lua`.

Requires `jq` and `thurbox-cli` **2.19.0 or newer**, plus the CLI for each forge
you work on: `gh` for GitHub, `glab` for GitLab, each authenticated. `gh` is not
optional even on a GitLab-only fleet — it is what builds the repo map.
rather than instructing you through it — seven steps: dependencies, this
checkout, your GitHub owners, the repo map, the thurbox extension, the queue
pane on screen, and the reconciler. It verifies each one and names anything
missing with its remedy before it writes a thing. Run it twice and it
converges.

Four of those steps ask you something, and only four. Whether to install the
dependencies that are missing; which of the owners it found on your machine the
map should cover; where the queue pane goes (a column on the right, by
default); and whether to bring the reconciler up. It reads your `gh` session,
your git config and the remotes of the clones you already have, so the owners
step is a list to confirm rather than one to type.

What it needs, and what it will tell you itself:

```bash
./scripts/preflight.sh # every dependency, in three tiers, with why
./scripts/preflight.sh --commands # exactly what to run for the ones missing
```

`git`, `gh` (authenticated), `jq`, `python3` with PyYAML and `thurbox-cli`
**2.19.0 or newer** are required; `quota-axi` and `glab` are recommended, and
each names what degrades without it. `gh` is not optional even on a GitLab-only
fleet — it is what builds the repo map.

That done, open the Mission Control session in thurbox and give it a goal.

Expand Down
5 changes: 3 additions & 2 deletions extension.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@
# So the stance holds unchanged: nothing in THIS FILE reaches
# outside the extension home. The pane is installed by a
# script, through thurbox's own front door for panes, and
# placing it stays the user's own edit — see
# `scripts/install-extension.sh`.
# placing it stays the user's own call — `scripts/place-pane.sh`
# writes that block only once they have been asked and said
# yes, and its header owns what keeps that safe.
# home / --home Omitted, so the home defaults to
# `<config>/extensions/fleet`. Do NOT "fix" the placeholder
# by installing with `--home <your clone>`: that would make
Expand Down
Loading