Commit Graph
21 Commits
Author SHA1 Message Date
Michael Sitarzewski 83452ee559 Merge commit 'refs/b3/956' into integ/installer-batch3
# Conflicts:
#	.github/workflows/check-tools.yml
2026-09-30 21:20:46 -05:00
Michael Sitarzewski 057243b089 Merge commit 'refs/b3/958' into integ/installer-batch3
# Conflicts:
#	.github/workflows/check-tools.yml
2026-09-30 21:20:45 -05:00
hotragn bdb3143fcd fix(cli): an unknown option exits 1; convert.sh --help shows every option
Both scripts handled an unknown option with `error ...; usage`, and usage()
always ended in `exit 0`:

  $ ./scripts/convert.sh --tol codex; echo $?
  [ERR] Unknown option: --tol
  ...usage...
  0

so a mistyped flag in CI or a wrapper script read as success. usage() now
takes a status. --help still prints to stdout and exits 0; an unknown
option prints the usage text to stderr and exits 1, the same as a bad
--tool or --division value already does.

convert.sh --help also printed a hard-coded `sed -n '3,28p'`. The option
notes live on lines 33-34, so --parallel and --jobs never appeared, and
--out was only in the synopsis. It now uses USAGE-START/END sentinels, as
install.sh has for a while, and the option list covers --tool and --out.

test-cli-usage.sh checks both scripts: an unknown option exits non-zero
with its name and the usage on stderr and nothing on stdout, --help exits 0
without printing the sentinels, and convert.sh --help describes --tool,
--out, --parallel and --jobs. It fails on main at the first check and runs
in check-tools.yml.
2026-09-30 05:02:50 -04:00
hotragn ec4ff9fed4 fix(install): one failing tool no longer stops the tools after it
A sequential install called install_tool bare under set -e, so the first
tool that returned 1 exited the whole script. With copilot, cursor, qwen,
codex and hermes detected and no integrations/cursor:

  [1/5] copilot   [OK]
  [2/5] cursor    [ERR] integrations/cursor missing. Run convert.sh first.
  (exit 1)

qwen, codex and hermes were never attempted, and nothing said so. The same
happens for any ensure_converted failure or an OpenClaw registration error.

Each tool now runs in a subshell with errexit on. It is not
`install_tool "$t" || failed+=(...)`: bash ignores errexit for everything on
the left of ||, subshells included, so a failing cp inside a tool would carry
on as if it had worked. Instead the parent turns errexit off for that one
command, and the subshell turns it back on for itself.

A failed tool is recorded and the loop moves on. The done box reads
"Installed 2 of 3 tool(s)" instead of "Done!", and the run ends with
"Failed: cursor — see the [ERR] line under each above" and exit 1. A clean
install is unchanged. Nothing in install_* sets globals the parent reads
afterwards, and the SKIPPED_LOG cleanup trap does not fire in a ( )
subshell, so running tools in a subshell loses nothing.

Parallel mode is untouched; its log replay on failure is item 1 of #917.

test-install-continue-after-failure.sh builds a fixture repo with
gemini-cli and qwen output and no cursor output, installs all three, and
checks that qwen still installs, cursor's error is shown, the summary names
cursor, and the exit is non-zero. It also checks that a clean run still
exits 0. It fails on main at "qwen ... was never installed" and runs in
check-tools.yml.
2026-09-30 04:49:05 -04:00
hotragn 3d80c07945 fix(markdown): seven agents' templates break out of their code blocks
Markdown has no nesting at equal fence length. Inside a ```markdown
template, a ```bash line is text, and the example's bare ``` closes the
template. Seven agents nest example blocks inside a template that way, so on
GitHub the rest of each template renders as headings and prose, and in three
of them the last block then runs open to the end of the file:

  design-ux-architect          code from line 414 to EOF
  ats-validator-architect      code from line 307 to EOF
  master-plan-architect        code from line 102 to EOF
  technical-writer, incident-response-commander, developer-advocate,
  workflow-architect           templates end early, rest renders as markdown

The fix for each is the one CommonMark intends: fence the outer template
with four backticks so the three-backtick examples stay inside it. Nine outer
blocks change; no content does.

Nothing caught this because lib.sh's fence_closes_p accepted "```python" as
a closing fence. CommonMark allows only whitespace after a closing run, and
GitHub renders by that rule. With the old rule the linter and the OpenClaw
split read those seven files one way and GitHub another, so each agreed with
itself and all three disagreed with what users see. fence_closes_p now
requires a bare run, and the OpenClaw split invariant in
test-convert-outputs.sh uses the same rule.

lint-agents.sh gets two errors, each with the file line number:

  - a fence line inside an open block that is long enough to close it but
    carries an info string -- the only way that happens is an attempted
    nest, and the message says how to fix it
  - a block that is still open at the end of the file

The body loop now reads the file from the line after the frontmatter
instead of from $body, which drops every "---" line and so cannot give a
line number. It also keeps a last line with no trailing newline; two agents
end on a closing fence with none, and without that they read as unclosed.

The whole roster lints with 0 errors after the fix; on main the same check
reports 18 errors across the seven files.
scripts/test-lint-fences.sh covers both errors, the suggested fix, tilde
fences, and fence_closes_p directly, and runs in check-tools.yml.
2026-09-30 04:37:58 -04:00
Rudy Celekli 3acce92df2 fix(convert): refuse symlinked tool output directories 2026-09-29 12:59:47 -04:00
Michael SitarzewskiandClaude Opus 5.5 3963190e14 ci: run the parallel-failure and unclosed-frontmatter tests from #901 and #904
Both tests shipped with their fixes but no workflow invoked them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 11:09:26 -05:00
Michael Sitarzewski d2089289b8 Merge branch 'rudy-906' into integ/rudy-series
# Conflicts:
#	.github/workflows/check-tools.yml
2026-09-29 10:25:02 -05:00
Michael Sitarzewski cb156e0b15 Merge branch 'rudy-902' into integ/rudy-series
# Conflicts:
#	.github/workflows/check-tools.yml
2026-09-29 10:25:02 -05:00
Michael Sitarzewski 6671f71765 Merge branch 'rudy-900' into integ/rudy-series
# Conflicts:
#	.github/workflows/check-tools.yml
2026-09-29 10:25:01 -05:00
Michael Sitarzewski 747ad1576d Merge branch 'rudy-899' into integ/rudy-series 2026-09-29 10:24:41 -05:00
Rudy Celekli 9445c9cbee fix(installer): avoid SIGPIPE when checking selected agents 2026-09-28 01:19:06 -04:00
Rudy Celekli 4e2d91d687 fix(installer): protect unrelated Hermes destinations 2026-09-28 01:05:47 -04:00
Rudy Celekli 070640f34c fix(installer): guard shared paths for detected tools 2026-09-28 00:56:56 -04:00
Rudy Celekli 25d6c10b92 fix(installer): stop after failed automatic conversion 2026-09-28 00:49:42 -04:00
Rudy Celekli fda3beeaba fix(convert): refuse duplicate agent slugs before writing 2026-09-28 00:32:16 -04:00
Michael SitarzewskiandClaude Fable 5.1 449e0c71b1 test(convert): manifest v2 — one line per agent, platform-neutral hashes, advisory drift on PRs (#844)
See the PR for the why/what/proof. Contributors no longer touch scripts/convert-outputs.sha256; drift is advisory on pull requests and strict on main.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 18:59:03 -05:00
Michael SitarzewskiandClaude Fable 5.1 04eadbd3e5 test(convert): regression eval for generated outputs + app contracts; fix two get_field bugs it found (#829)
Adds scripts/test-convert-outputs.sh, the output half of the regression eval
(the install half landed in #828), and wires it plus the previously
un-wired test-agent-selection.sh (#779) into CI.

Why an eval at all: every converter bug so far passed lint and the existing
tests while the installed product was broken. #778 shipped a double-wrapped
description that was valid YAML, so a wrapper check passed; #817 dropped a
whole tool from --parallel and every remaining tool looked fine. Those are
invariant violations, not syntax errors.

Layer A (no history needed), for every agent x every converted tool:
  round-trip   parsed(generated).description == source description
  strict-parse every generated frontmatter / TOML / YAML parses with a real
               parser (kimi/vibe carry only an identifier: id == slug and the
               prose file exists; aider/windsurf: "## Name" + description line)
  count        every tool emits exactly one output per roster agent
  source       every SOURCE frontmatter strict-parses and carries no leaked
               quote — the desktop app reads sources with js-yaml (#473)
Layer B: scripts/convert-outputs.sha256, one aggregate hash per tool plus
divisions.json / tools.json / runbooks.json. A flipped line means outputs or a
contract changed; --update regenerates deliberately so review sees the blast
radius. Date-stable (no generated file embeds a date).

The expected side is derived by an INDEPENDENT strict parse of each source,
never by lib.sh's get_field: the generator uses get_field, so an expected
value derived the same way would move with a get_field bug and hide it —
which is exactly how #778 stayed invisible. That independence found two
shipping defects on the first green run:

- get_field returned only the first line of a multi-line plain scalar.
  Three healthcare agents write their description as an indented
  continuation; every generated output for them shipped it truncated
  mid-sentence while the app showed the whole thing. get_field now folds
  continuation lines the way YAML does (newline -> single space).
- get_field stripped only "field: " (one space). The same three files use
  column-aligned frontmatter (name:        X), so their generated names
  carried leading whitespace in every tool's output. Plain-scalar padding
  is now trimmed.

After both fixes get_field agrees with PyYAML on name and description for
all 273 sources. Acceptance: re-introducing #778's double-wrap, a dropped
tool, a divisions.json change, and an unquoted source each fail the eval
(the double-wrap via Layer A round-trip, not only the manifest).

Refs #778 #817 #473 #810 #826 #828 #779

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 07:58:13 -05:00
hari 3464daa3c6 fix(convert): quote YAML frontmatter values (#778)
Signed-off-by: Mr-Neutr0n <harikp2002@gmail.com>
2026-08-26 08:49:51 -05:00
Pip, Agent PipandMichael Sitarzewski 6e45066041 fix(hermes): expose Agency tool parameters (#717)
Co-authored-by: Michael Sitarzewski <michael@sitarzewski.com>
2026-07-15 09:55:50 -05:00
Michael SitarzewskiandClaude Opus 4.8 d4067cc48a ci: add check-tools.yml to enforce the tool contract (#607)
Mirrors check-divisions.yml. Runs scripts/check-tools.sh on every PR and on
push to main (no path filter) so any change to ALL_TOOLS in install.sh, the
converter set in convert.sh, or tools.json that breaks consistency fails the
build — same CI protection divisions.json already has.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 16:30:35 -05:00