refactor: delegate fj work to the fj-worker subagent instead of forking #8

Merged
jerome merged 4 commits from refactor/forgejo-cli-delegation into main 2026-06-25 09:08:09 +03:00
Collaborator

Goal

Invert the forgejo-cli plugin from an auto-forking skill into a thin router
that splits Forgejo work two ways:

  • Reads (PR/issue body, comments, formal reviews, inline code comments) run
    a deterministic bundled script (scripts/fj_read.py) -- no model in the loop,
    so content comes back exactly as written (a body that is a spec stays verbatim).
  • Writes + the long tail delegate to the fj-worker subagent (Sonnet),
    which holds the full fj reference + footguns and runs one small,
    self-contained task at a time, taking any multi-line content via an absolute
    tmp-file path the caller writes.

Either way the main context stays lean and carries zero fj mechanics.

Why

The previous design used context: fork so any fj mention forked the whole
task into the worker. Two problems: the main context did no thinking of its own,
and routing a content read through an LLM risked summarising/truncating a body
that is actually a spec. The new model keeps the main context in control, makes
reads deterministic (a script, not a model), and reserves the worker for the
footgun-heavy writes and adaptive error recovery.

Steps

  • Move the canonical fj reference (commands, footguns, REST fallbacks,
    token scopes, subcommand surface) into the fj-worker agent, and add an
    operating contract: one small self-contained task per dispatch; large
    content arrives as an absolute tmp-file path to Read; results terse,
    but returned content (a body) verbatim.
  • Move the extras.md companion next to the agent
    (agents/references/extras.md) and retarget its cross-references at the
    agent reference, since the skill no longer owns it.
  • Shrink SKILL.md to a thin router: drop the context: fork + agent:
    frontmatter, trim the description to a pure trigger, and make the body the
    two-path contract (script the reads, delegate the writes; the tmp-file rule
    for bodies; what comes back).
  • Add scripts/fj_read.py -- a stdlib-only script that reads fj's stored
    token and hits the Forgejo REST API to dump a PR/issue verbatim (metadata,
    body, flat comments, and reviews + inline comments, which fj can't show)
    to a tmp file or stdout (--format json for machine output). Route reads
    through it in the skill router.

Notes

  • Reference lives only in the agent (agents/fj-worker.md +
    agents/references/extras.md); main context carries just the small router body
    when the skill triggers.
  • Reads are deterministic and free of a subagent round-trip: fj_read.py is more
    capable than fj for reads (reviews/inline comments are REST-only; it also
    sidesteps the broken fj pr status).
  • No automated test suite for this plugin repo. fj_read.py was verified live
    against this PR (#8): body verbatim, comments captured, JSON + --out + error
    paths (bad host, 404) all behave.
  • Follow-up (separate PR, out of scope): the taskpy suite still tells callers
    to "invoke the forgejo-cli skill ... for syntax" and references "the
    forgejo-cli skill's review subsection" -- those now resolve to the agent /
    fj_read.py, so the references want updating.

Depends on: none.

## Goal Invert the `forgejo-cli` plugin from an auto-forking skill into a **thin router** that splits Forgejo work two ways: - **Reads** (PR/issue body, comments, formal reviews, inline code comments) run a deterministic bundled script (`scripts/fj_read.py`) -- no model in the loop, so content comes back exactly as written (a body that is a spec stays verbatim). - **Writes + the long tail** delegate to the `fj-worker` subagent (Sonnet), which holds the full `fj` reference + footguns and runs one small, self-contained task at a time, taking any multi-line content via an absolute tmp-file path the caller writes. Either way the main context stays lean and carries zero `fj` mechanics. ## Why The previous design used `context: fork` so any `fj` mention forked the *whole* task into the worker. Two problems: the main context did no thinking of its own, and routing a content read through an LLM risked summarising/truncating a body that is actually a spec. The new model keeps the main context in control, makes reads deterministic (a script, not a model), and reserves the worker for the footgun-heavy writes and adaptive error recovery. ## Steps - [x] Move the canonical `fj` reference (commands, footguns, REST fallbacks, token scopes, subcommand surface) into the `fj-worker` agent, and add an operating contract: one small self-contained task per dispatch; large content arrives as an absolute tmp-file path to `Read`; results terse, but returned *content* (a body) verbatim. - [x] Move the `extras.md` companion next to the agent (`agents/references/extras.md`) and retarget its cross-references at the agent reference, since the skill no longer owns it. - [x] Shrink `SKILL.md` to a thin router: drop the `context: fork` + `agent:` frontmatter, trim the description to a pure trigger, and make the body the two-path contract (script the reads, delegate the writes; the tmp-file rule for bodies; what comes back). - [x] Add `scripts/fj_read.py` -- a stdlib-only script that reads `fj`'s stored token and hits the Forgejo REST API to dump a PR/issue verbatim (metadata, body, flat comments, and reviews + inline comments, which `fj` can't show) to a tmp file or stdout (`--format json` for machine output). Route reads through it in the skill router. ## Notes - Reference lives **only** in the agent (`agents/fj-worker.md` + `agents/references/extras.md`); main context carries just the small router body when the skill triggers. - Reads are deterministic and free of a subagent round-trip: `fj_read.py` is more capable than `fj` for reads (reviews/inline comments are REST-only; it also sidesteps the broken `fj pr status`). - No automated test suite for this plugin repo. `fj_read.py` was verified live against this PR (#8): body verbatim, comments captured, JSON + `--out` + error paths (bad host, 404) all behave. - Follow-up (separate PR, out of scope): the `taskpy` suite still tells callers to "invoke the `forgejo-cli` skill ... for syntax" and references "the forgejo-cli skill's review subsection" -- those now resolve to the agent / `fj_read.py`, so the references want updating. **Depends on:** none.
The worker now executes one small, self-contained fj operation per
dispatch from its own reference, reading large content (a PR/issue body)
from an absolute tmp-file path. Move the extras companion next to the
agent (agents/references/extras.md) since the skill no longer owns it.
refactor: make forgejo-cli a thin router that delegates to fj-worker
All checks were successful
gitleaks / gitleaks (pull_request) Successful in 3s
92849783ef
Drop context:fork and the auto-fork frontmatter; the skill body now
fits in the main context and instructs it to delegate each fj operation
to the fj-worker subagent as a small self-contained task, passing any
multi-line body through a tmp file. Main context no longer carries the
fj reference.
Author
Collaborator

2026-06-25 -- resolver pass on refactor/forgejo-cli-delegation at 9284978.

  • Steps done: all 3 (reference + operating contract into the agent; extras moved to agents/references/; SKILL.md shrunk to the delegation router, context:fork dropped).
  • Deferred: none (no automated test suite for this plugin repo; verification is manual -- delegate a real fj op through the worker and confirm the tmp-file body path works end to end).
  • The fj reference now lives only in agents/fj-worker.md + agents/references/extras.md; main context carries just the small router body when the skill triggers.
2026-06-25 -- resolver pass on refactor/forgejo-cli-delegation at 9284978. - Steps done: all 3 (reference + operating contract into the agent; extras moved to agents/references/; SKILL.md shrunk to the delegation router, context:fork dropped). - Deferred: none (no automated test suite for this plugin repo; verification is manual -- delegate a real fj op through the worker and confirm the tmp-file body path works end to end). - The fj reference now lives only in agents/fj-worker.md + agents/references/extras.md; main context carries just the small router body when the skill triggers.
Route reads (body, flat comments, formal reviews, inline comments)
through a stdlib-only script that hits the Forgejo REST API with fj's
stored token and emits the record verbatim to a tmp file -- no model in
the loop, so a body that is a spec comes back exactly as written, and
reviews/inline comments (which fj can't show) are included. The skill
router now scripts reads and delegates only writes + the long tail to
fj-worker; the worker keeps a verbatim-content safeguard for the
fallback case.
Merge remote-tracking branch 'origin/main' into refactor/forgejo-cli-delegation
All checks were successful
gitleaks / gitleaks (pull_request) Successful in 3s
1264e3f98c
Author
Collaborator

2026-06-25 -- second resolver pass on refactor/forgejo-cli-delegation at 1264e3f.

  • Added scripts/fj_read.py (Step 4): deterministic, stdlib-only REST dump of a PR/issue -- body + flat comments + reviews + inline comments, verbatim, to a tmp file or stdout (--format json). Reads no longer route through fj-worker.
  • SKILL.md router now splits the two paths (script the reads, delegate the writes); fj-worker keeps a verbatim-content safeguard for the fallback read.
  • Verified fj_read.py live against this PR: body verbatim, comments captured, JSON/--out/error paths (bad host, 404) all behave.
  • Caught the branch up to origin/main (PR #7's taskpy rename landed while this was in flight); clean merge, diff stays scoped to the 4 forgejo-cli files.
  • Follow-up (separate PR): taskpy-implement still points callers at "the forgejo-cli skill ... for syntax" / "review subsection" (SKILL.md:165,:315; worktree-and-branches.md:53,:280) -- those now resolve to the agent + fj_read.py.
2026-06-25 -- second resolver pass on refactor/forgejo-cli-delegation at 1264e3f. - Added scripts/fj_read.py (Step 4): deterministic, stdlib-only REST dump of a PR/issue -- body + flat comments + reviews + inline comments, verbatim, to a tmp file or stdout (--format json). Reads no longer route through fj-worker. - SKILL.md router now splits the two paths (script the reads, delegate the writes); fj-worker keeps a verbatim-content safeguard for the fallback read. - Verified fj_read.py live against this PR: body verbatim, comments captured, JSON/--out/error paths (bad host, 404) all behave. - Caught the branch up to origin/main (PR #7's taskpy rename landed while this was in flight); clean merge, diff stays scoped to the 4 forgejo-cli files. - Follow-up (separate PR): taskpy-implement still points callers at "the forgejo-cli skill ... for syntax" / "review subsection" (SKILL.md:165,:315; worktree-and-branches.md:53,:280) -- those now resolve to the agent + fj_read.py.
jerome approved these changes 2026-06-25 09:08:02 +03:00
jerome changed title from WIP: refactor: delegate fj work to the fj-worker subagent instead of forking to refactor: delegate fj work to the fj-worker subagent instead of forking 2026-06-25 09:08:04 +03:00
jerome merged commit c7093d7c35 into main 2026-06-25 09:08:09 +03:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
public/chiche-plugins!8
No description provided.