Skip to content

Releases: ypxing/coding-crew

fix: don't trust a partial dev-commands.json cache as fully discovered

Choose a tag to compare

@github-actions github-actions released this 15 Sep 07:40

Fixed

  • Command discovery (discover-commands.sh) no longer trusts a partial .coding-crew/dev-commands.json as fully discovered. It used to skip re-running discovery the moment the cache file existed at all, regardless of which of the six fields (test/lint/typecheck/install/env/credential_target) it actually contained. That let a partial write — e.g. ensure-deps.sh's own install_mode/docker_service fields landing first because an earlier sprint's model dispatch failed (expired credentials, a timeout) before ever writing the six discovery fields — permanently starve every later sprint of full discovery, since the file "already existed." The skip now requires all six fields to be present (any value, including JSON null, which still means "checked, confirmed no such command") before trusting the cache; a cache missing even one field falls through and re-runs discovery.

feat: prune skills dropped from a --skills list

Choose a tag to compare

@github-actions github-actions released this 14 Sep 00:22

Fixed

  • install.sh now re-execs into a newer bash instead of dying with declare: -A: invalid option on macOS. Apple's stock /bin/bash is 3.2 (frozen there since the GPLv2→GPLv3
    switch) and install.sh's own #!/bin/bash shebang is resolved by the kernel from that
    hardcoded path, not from $PATH — so a newer Homebrew bash already on a user's PATH was
    never picked up just by running the script (which is what bootstrap.sh's exec "$INSTALL"
    does). The registry-read cache needs declare -A (bash ≥ 4). The script now detects bash < 4,
    hops to a findable newer bash (Homebrew's common install locations, or PATH), and exits with
    brew install bash guidance if none exists.

Added

  • install.sh claude --skills a,b,c now treats that list as the full desired skill set: a
    name present in a prior --skills install but missing from this one is uninstalled, instead
    of being silently left on disk forever. write_manifest()'s merge only adds/updates keys, so
    without this a shrunk --skills list had no way to actually drop anything. The new
    prune_skills_not_in() shells out to uninstall.sh --skill — the existing single writer of
    skill removal — rather than duplicating that logic, then deletes the pruned key from
    manifest.json so the merge doesn't resurrect it.

chore: remove caveman and improve-codebase-architecture skills

Choose a tag to compare

@github-actions github-actions released this 13 Sep 13:56

Removed

  • The caveman and improve-codebase-architecture skills are gone, along with their
    registry.json entries, install.sh/bootstrap.sh/unbootstrap.sh/uninstall.sh examples,
    doc references, and structural tests. Both were third-party skills (JuliusBrussee/crew-caveman,
    mattpocock/skills) this repo no longer maintains as part of its distribution.

fix: clear stale sidecar report.json before each dispatch

Choose a tag to compare

@github-actions github-actions released this 11 Sep 13:47

Fixed

  • runWorker/runReview/runTriage now delete each dispatch's .report.json sidecar
    before writing that round's prompt, instead of leaving a prior round's (or a prior resumed
    sprint's) sidecar sitting at the same fixed path.
    waitForSidecarReport in dispatch.mjs
    treats existsSync as "found" the instant the herdr wait settles, so a stale sidecar from an
    earlier dispatch to the same slug was read back as this round's verdict whenever the coder's,
    reviewer's, or triage agent's turn died before writing a fresh one — a false verdict rather
    than the intended pane-scrape fallback.

feat: extend the sidecar-first herdr dispatch policy to review and triage

Choose a tag to compare

@github-actions github-actions released this 11 Sep 12:43

Changed

  • The <slug>.report.json sidecar-first dispatch policy (already used for the crew-coder
    worker) now also covers the reviewer and triage agents.
    dispatchViaHerdr checks each
    role's report file before scraping the pane at all: the review and triage prompts now name
    a reportPath and instruct the agent to write its verdict there as its last action, falling
    back to the same fenced-json-in-prose reply only if that file never lands.
    parseReviewReport/parseTriageReport accept the parsed sidecar and prefer it over the
    captured text entirely, same policy parseWorkerReport already had. Closes the same class of
    herdr read-capture failure (empty/garbled pane render) for review and triage that the worker
    fix already closed — a genuine verdict no longer depends on a terminal scrape succeeding.

fix: report render line count and echo-found status on herdr empty-reply failures

Choose a tag to compare

@github-actions github-actions released this 11 Sep 11:19

Changed

  • A herdr DISPATCH-FAIL outEmpty=true line now reports the captured render's line count and
    whether the echoed prompt was found anywhere in it (lines=N echoFound=yes|no).
    Previously
    the log's only diagnostic was the last 400 characters of the render — which is always just
    Claude's bottom status-bar chrome whether the reply capture failed or succeeded, so it couldn't
    distinguish "the read's --lines window (or the pane's alt-screen buffer) never captured the
    echoed prompt at all" from "the echo is there but extractHerdrReply's end-marker pattern
    didn't match." echoFound is computed by herdrEchoFound, sharing herdrIsEchoLine with
    extractHerdrReply itself rather than reimplementing the echo check.

feat: unify review/triage verdict reporting on a shared JSON contract

Choose a tag to compare

@github-actions github-actions released this 11 Sep 09:11

Changed

  • The reviewer and triage agents now report their verdict as a fenced json block
    ({"branch", "slug", "verdict", "detail", "findings"} / {"fixable", "category", "detail"})
    instead of column-0 ## Branch:/AC:/Review:/FINDING: and FIXABLE:/CATEGORY:/DETAIL:
    lines, mirroring the structured-result contract crew-coder already used.
    The old shape had
    three independent hand-rolled parsers of the same aggregate review report file — a Node regex
    gating the merge, an awk in crew-summary.sh's rollup, and a second awk in
    promote-findings.sh's remind — and they drifted apart on how much whitespace a
    herdr-captured review header could carry before a line no longer matched. A genuinely
    successful, all-met retry review could land indented and without the ## after an earlier
    not_run stub in the same file and still be silently dropped from the summary and the findings
    count, even though the merge/AC gate (whose regex already tolerated leading whitespace) had
    parsed and acted on the real verdict correctly. JSON's whitespace-between-tokens-is-insignificant
    grammar closes the whole class rather than one more anchor at a time — crew-summary.sh and
    promote-findings.sh now both read the aggregate file through one shared parser
    (orchestrator/review-rollup.mjs, over report.mjs's new parseReviewAggregate) instead of
    reimplementing it twice. report.mjs's parseReviewReport/parseTriageReport prefer the json
    block and fall back to the old markdown shape, so an un-migrated reviewer/triage agent still
    works. mark-not-run's stub now emits the same json shape (verdict: "not_run").

fix: notify the triggering herdr pane even when a sprint fails before it starts

Choose a tag to compare

@github-actions github-actions released this 11 Sep 05:01

Added

  • Under HERDR_ENV=1, crew-afk now pushes the sprint's outcome into the triggering pane
    ($HERDR_PANE_ID) once the run finishes, stalls, or errors,
    instead of leaving that pane to
    poll on a long interval for the same information — see notifyTriggeringPane's doc comment.

Fixed

  • That nudge only fired once a sprint had actually been initialized, so a preflight or
    feature-slug resolution failure — the fastest way a run can end — left the triggering pane
    with nothing to stop polling for.
    main()'s run is now wrapped in a single try/finally
    from before preflight onward, so every exit path, including one that never got as far as
    creating a Sprint, still reaches the notify call.

fix: fail fast on a herdr pane blocked mid-turn, log last-seen agent_status on empty replies

Choose a tag to compare

@github-actions github-actions released this 11 Sep 02:57

Fixed

  • A dialog appearing mid-turn on a herdr pane (after --wait settled on a stale idle/done
    match) polled uselessly until the dispatch's whole deadline expired before reporting an
    unexplained empty reply.
    Unlike idle/done, a blocked agent_status never resolves on its
    own — it stays blocked until a dialog is answered — so dispatchViaHerdr now fails immediately
    on that status (from both the direct check and from inside waitForHerdrIdle's own polling)
    with the pane's actual dialog text, the same way it already does for a dialog that's there
    before the prompt is even sent.
  • A DISPATCH-FAIL outEmpty=true log line gave no way to tell a genuinely empty reply from
    one that simply ran out of deadline while the pane was still busy.
    The line now includes the
    last-seen agent_status alongside the rendered tail.

fix: check agent_status directly before giving up on a busy herdr pane that never errors on read

Choose a tag to compare

@github-actions github-actions released this 11 Sep 02:49

Fixed

  • A herdr dispatch could still report an empty reply even after v1.29.79's agent_not_idle
    fix, when the pane was busy in a way that never made agent read itself error.
    The same
    --wait "does not track turns" gap could leave a read succeeding with code 0 while only
    catching the pane's live status footer (tool-call counters, a running timer) — indistinguishable
    from a genuinely blank reply, and the fixed-delay backoff that follows only covers a few
    seconds of flush lag, not minutes of real work. dispatchViaHerdr now checks agent_status
    directly once that backoff is exhausted: if the pane is still actively busy, it polls until
    idle/done (bounded by the dispatch's own deadline) and reads again, instead of giving up while
    the coder is still working.