guild-cli 0.8.4__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- guild_cli-0.9.0/.claude/skills/outsource/SKILL.md +104 -0
- guild_cli-0.9.0/.claude/skills/outsource/prompts/explore.md +20 -0
- guild_cli-0.9.0/.claude/skills/outsource/prompts/review.md +27 -0
- guild_cli-0.9.0/.claude/skills/outsource/prompts/write.md +13 -0
- guild_cli-0.9.0/.claude/skills/outsource/scripts/outsource.sh +259 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.markdownlint-cli2.yaml +6 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/CHANGELOG.md +53 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/PKG-INFO +1 -1
- {guild_cli-0.8.4 → guild_cli-0.9.0}/docs/skill-sources.md +47 -11
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/skills/__init__.py +4 -2
- {guild_cli-0.8.4 → guild_cli-0.9.0}/pyproject.toml +1 -1
- {guild_cli-0.8.4 → guild_cli-0.9.0}/uv.lock +1 -1
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/agent-config/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/cicd/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/guild/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/guild/scripts/configure-repo.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/guild/scripts/create.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/guild/scripts/overview.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/onboard/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/onboard/scripts/onboard.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/teach/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/teach/scripts/teach.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/think/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/think/scripts/think.sh +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills.local.yaml.example +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.devague/frames/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.devague/plans/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.flake8 +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.github/workflows/publish.yml +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.github/workflows/tests.yml +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/.gitignore +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/CLAUDE.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/LICENSE +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/README.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/culture.yaml +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/docs/cutover.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/docs/plans/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/docs/specs/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/__init__.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/__main__.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/__init__.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/__init__.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/_broadcast.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/_provision_template.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/create.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/explain.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/learn.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/onboard.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/overview.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/show.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/teach.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_commands/whoami.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_errors.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_output.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/cli/_repo.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/scaffold/__init__.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/scaffold/instantiate.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/skills/identity.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/skills/ledger.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/skills/render.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/guild/skills/sources.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/sonar-project.properties +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/__init__.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_broadcast_post.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_create.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_explain.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_learn.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_onboard.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_overview.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_show.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_teach.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_cli_whoami.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_scaffold_instantiate.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_skills_convention.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_skills_identity.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_skills_ledger.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_skills_render.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_skills_sources.py +0 -0
- {guild_cli-0.8.4 → guild_cli-0.9.0}/tests/test_version_fallback.py +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: outsource
|
|
3
|
+
type: command
|
|
4
|
+
description: >
|
|
5
|
+
Hand a scoped repo task to convertible — a *different* engine/model than you
|
|
6
|
+
(e.g. a local vLLM Qwen) — and fold its answer back. The point isn't a stronger
|
|
7
|
+
model; it's a different mind, and diversity helps: `outsource review` gets an
|
|
8
|
+
independent second opinion on a diff, `outsource explore` gets a fresh read of
|
|
9
|
+
an area, `outsource write` delegates a small implementation. Use when the user
|
|
10
|
+
says "outsource this", "get a second opinion", "have convertible review/explore/
|
|
11
|
+
write", "ask the other model", or when you want a diverse perspective rather
|
|
12
|
+
than just doing it yourself. Read-only verbs (explore/review) run isolated in a
|
|
13
|
+
throwaway git worktree and cannot touch the working tree.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# outsource — use convertible as a different mind
|
|
17
|
+
|
|
18
|
+
`outsource` drives the **`convertible`** CLI so a Claude agent can hand a scoped
|
|
19
|
+
task to a *different* engine (default: a local vLLM `Qwen3.6-27B` on
|
|
20
|
+
`:8001`). Convertible's model is **not** assumed to be stronger than you — its
|
|
21
|
+
value is **diversity**. A second, independent mind catches things the author's
|
|
22
|
+
mind glides past, which is why **review** is the headline verb.
|
|
23
|
+
|
|
24
|
+
This skill is the operator: a portable wrapper that resolves the CLI and turns
|
|
25
|
+
each verb into a `convertible drive`, then prints the drive's result summary.
|
|
26
|
+
|
|
27
|
+
## How to run
|
|
28
|
+
|
|
29
|
+
The entry point is `scripts/outsource.sh`. Invoke it from the repo you want
|
|
30
|
+
convertible to work on:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bash .claude/skills/outsource/scripts/outsource.sh <verb> "<text>" [options]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
It resolves the CLI portably — an installed `convertible` on `PATH` (the normal
|
|
37
|
+
case), falling back to `uv run convertible` when inside the convertible checkout,
|
|
38
|
+
else an install hint.
|
|
39
|
+
|
|
40
|
+
### Verbs
|
|
41
|
+
|
|
42
|
+
| Verb | What it does | Side effects |
|
|
43
|
+
|------|--------------|--------------|
|
|
44
|
+
| `explore "<question or area>"` | Read-only investigation of the repo; the model reads and reports findings. | **None** — runs in a throwaway worktree at HEAD. |
|
|
45
|
+
| `review "<what to focus on>" [--base main]` | A diverse second opinion on the **committed** diff (`<base>...HEAD`). | **None** — throwaway worktree; reviews committed changes only. |
|
|
46
|
+
| `write "<task>" [--pr]` | Implement a change. Commits to a drive branch by default; `--pr` pushes + opens a PR. | In-place: a `convertible/<id>` drive branch (or a PR). |
|
|
47
|
+
|
|
48
|
+
### Options
|
|
49
|
+
|
|
50
|
+
| Option | Meaning |
|
|
51
|
+
|--------|---------|
|
|
52
|
+
| `--repo PATH` | Target repo (default: `.`). |
|
|
53
|
+
| `--base BRANCH` | Base for the `review` diff (default: `main`). |
|
|
54
|
+
| `--engine NAME` | Engine wheel (default: `$CONVERTIBLE_ENGINE` or `vllm-openai`). |
|
|
55
|
+
| `--model NAME` | Model (default: `$CONVERTIBLE_MODEL` or `mmangkad/Qwen3.6-27B-NVFP4`). |
|
|
56
|
+
| `--base-url URL` | OpenAI base URL (default: `$CONVERTIBLE_BASE_URL` or `http://localhost:8001/v1`). |
|
|
57
|
+
| `--max-steps N` | Loop step budget (default: 20). |
|
|
58
|
+
| `--allow-dirty` | (`write`) allow running on a dirty tree. |
|
|
59
|
+
| `--pr` | (`write`) push + open a PR instead of a local drive branch. |
|
|
60
|
+
|
|
61
|
+
The result printed to stdout is the drive's `TaskResult.summary` (plus
|
|
62
|
+
`changed_files` / drive branch for `write`), parsed from `convertible drive
|
|
63
|
+
--json`. Per-step progress streams to stderr while it runs.
|
|
64
|
+
|
|
65
|
+
## When to reach for which verb
|
|
66
|
+
|
|
67
|
+
- **review** — the standing use. You wrote (or an agent wrote) a change and you
|
|
68
|
+
want a candid, independent pass over the *committed* diff before you trust it.
|
|
69
|
+
Treat the output as a second opinion to weigh, not a verdict.
|
|
70
|
+
- **explore** — you want a fresh, unbiased read of an unfamiliar area ("how does
|
|
71
|
+
X work here?") without anchoring on your own assumptions.
|
|
72
|
+
- **write** — a small, well-scoped implementation you're happy to delegate. The
|
|
73
|
+
result lands on a drive branch you can inspect, merge, or discard.
|
|
74
|
+
|
|
75
|
+
## Hard rules (do not violate)
|
|
76
|
+
|
|
77
|
+
- **explore and review are read-only.** They run in a throwaway `git worktree`
|
|
78
|
+
at HEAD, so a stray write can't reach your working tree or branch; the prompts
|
|
79
|
+
also tell the model not to modify anything. Don't route a change-making task
|
|
80
|
+
through them — use `write`.
|
|
81
|
+
- **`write` refuses a dirty tree** unless you pass `--allow-dirty`. This guards
|
|
82
|
+
the dirty-tree hazard: `convertible drive --no-pr` commits *uncommitted* edits
|
|
83
|
+
onto the drive branch and leaves you there. Commit or stash first.
|
|
84
|
+
- **Outsourced output is a second opinion, not authority.** The engine may be a
|
|
85
|
+
smaller/different model; weigh its findings, verify its claims, and own the
|
|
86
|
+
decision yourself.
|
|
87
|
+
|
|
88
|
+
## Honest limits
|
|
89
|
+
|
|
90
|
+
- Read-only is enforced by **worktree isolation + prompt constraint**, not a
|
|
91
|
+
sandbox — the loop always exposes `write_file`/`run_command`, so the model can
|
|
92
|
+
still run arbitrary *read-only* commands.
|
|
93
|
+
- `review` covers **committed** changes only (`<base>...HEAD`). To review
|
|
94
|
+
uncommitted work, commit it first.
|
|
95
|
+
- The default engine is whatever single model is running locally; a multi-model
|
|
96
|
+
fleet (different model per verb) is separate infrastructure.
|
|
97
|
+
|
|
98
|
+
## Provenance
|
|
99
|
+
|
|
100
|
+
This is a **first-party convertible** skill — `agentculture/convertible` is its
|
|
101
|
+
origin. guildmaster **re-broadcasts** it to the mesh (the same inbound pattern as
|
|
102
|
+
the devague-origin workflow skills), tracking it in `docs/skill-sources.md`. The
|
|
103
|
+
`cite, don't import` policy holds: downstream repos copy it, they don't symlink
|
|
104
|
+
or depend on it.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
You are a second, independent mind brought in for a fresh read of this repository.
|
|
2
|
+
You are NOT the original author — your value is a different perspective, not authority.
|
|
3
|
+
|
|
4
|
+
Investigate the following and report what you find:
|
|
5
|
+
|
|
6
|
+
$ARGUMENTS
|
|
7
|
+
|
|
8
|
+
Rules:
|
|
9
|
+
- This is READ-ONLY. Use read_file, list_dir, and read-only run_command only
|
|
10
|
+
(e.g. `git log`, `git grep`, `ls`, `rg`). Do NOT create, modify, or delete any
|
|
11
|
+
file, and do NOT run any command that changes state.
|
|
12
|
+
- Be concrete: cite file paths and line numbers; quote the key code you rely on.
|
|
13
|
+
- Surface what's surprising, risky, or unclear — not just a tidy summary.
|
|
14
|
+
- You have a limited step budget. Read efficiently and call finish with your
|
|
15
|
+
report well before you run out — a focused finding beats endless reading.
|
|
16
|
+
|
|
17
|
+
When you are done, call finish with a structured findings report:
|
|
18
|
+
1. What it is / how it works (with file:line references).
|
|
19
|
+
2. Notable details, edge cases, or surprises.
|
|
20
|
+
3. Open questions or risks worth a closer look.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
You are an independent reviewer — a different mind from whoever wrote this change.
|
|
2
|
+
Your job is a candid second opinion, not a rubber stamp.
|
|
3
|
+
|
|
4
|
+
Focus the review on:
|
|
5
|
+
|
|
6
|
+
$ARGUMENTS
|
|
7
|
+
|
|
8
|
+
The change under review is the committed diff on this branch versus its base
|
|
9
|
+
(`$BASE`). Start by running, read-only:
|
|
10
|
+
|
|
11
|
+
git diff $BASE...HEAD --stat
|
|
12
|
+
git diff $BASE...HEAD
|
|
13
|
+
|
|
14
|
+
then read the touched files for the context you need.
|
|
15
|
+
|
|
16
|
+
Rules:
|
|
17
|
+
- READ-ONLY. Do NOT modify, create, or delete any file. Only read and run
|
|
18
|
+
read-only commands.
|
|
19
|
+
- Be terse and prioritized — lead with what actually matters. Don't pad.
|
|
20
|
+
- Call out real problems; if it's genuinely fine, say so and say why.
|
|
21
|
+
- You have a limited step budget. Read the diff efficiently and call finish with
|
|
22
|
+
your review well before you run out of steps.
|
|
23
|
+
|
|
24
|
+
When you are done, call finish with a structured review:
|
|
25
|
+
1. Correctness risks / likely bugs (with file:line).
|
|
26
|
+
2. Design, clarity, or maintainability concerns.
|
|
27
|
+
3. Concrete, actionable suggestions (ranked; most important first).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Implement the following task in this repository:
|
|
2
|
+
|
|
3
|
+
$ARGUMENTS
|
|
4
|
+
|
|
5
|
+
Rules:
|
|
6
|
+
- Make the SMALLEST change that correctly satisfies the task.
|
|
7
|
+
- Follow the repository's existing patterns, style, and conventions — read the
|
|
8
|
+
neighbouring files first so your change reads like the surrounding code.
|
|
9
|
+
- You may read, create, modify files, and run commands as needed.
|
|
10
|
+
- Don't widen the scope: do exactly what was asked, nothing more.
|
|
11
|
+
|
|
12
|
+
When you are done, call finish with a short summary of exactly what you changed
|
|
13
|
+
and why.
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# outsource — hand a scoped repo task to convertible (a different engine/mind).
|
|
4
|
+
#
|
|
5
|
+
# Convertible's engine is not necessarily stronger than the calling agent; it is
|
|
6
|
+
# a *different* mind, and diversity helps — which is why `review` is the headline
|
|
7
|
+
# verb. Three verbs drive `convertible drive` and print the result:
|
|
8
|
+
#
|
|
9
|
+
# outsource explore "<question or area>" read-only investigation -> findings
|
|
10
|
+
# outsource review "<what to focus on>" diverse second-opinion on the diff
|
|
11
|
+
# outsource write "<task>" [--pr] implement a change
|
|
12
|
+
#
|
|
13
|
+
# explore/review run in a throwaway `git worktree` at HEAD, so they can never
|
|
14
|
+
# touch your working tree or branch (any stray write is discarded). write runs
|
|
15
|
+
# in-place and lands a drive branch (or a PR with --pr).
|
|
16
|
+
#
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
20
|
+
PROMPTS_DIR="$SKILL_DIR/prompts"
|
|
21
|
+
|
|
22
|
+
# ── resolve the convertible CLI (installed, then local-dev fallback) ─────────
|
|
23
|
+
CONVERTIBLE=()
|
|
24
|
+
resolve_convertible() {
|
|
25
|
+
if command -v convertible >/dev/null 2>&1; then
|
|
26
|
+
CONVERTIBLE=(convertible) # installed tool — the normal case
|
|
27
|
+
return 0
|
|
28
|
+
fi
|
|
29
|
+
# Local-dev fallback: inside the convertible checkout, run via uv.
|
|
30
|
+
local dir="$PWD"
|
|
31
|
+
while [[ -n "$dir" ]] && [[ "$dir" != "/" ]]; do
|
|
32
|
+
if [[ -f "$dir/pyproject.toml" ]] \
|
|
33
|
+
&& grep -q '^name = "convertible-cli"' "$dir/pyproject.toml" 2>/dev/null; then
|
|
34
|
+
if command -v uv >/dev/null 2>&1; then
|
|
35
|
+
CONVERTIBLE=(uv run convertible)
|
|
36
|
+
return 0
|
|
37
|
+
fi
|
|
38
|
+
break
|
|
39
|
+
fi
|
|
40
|
+
dir=$(dirname "$dir")
|
|
41
|
+
done
|
|
42
|
+
cat >&2 <<'EOF'
|
|
43
|
+
error: convertible CLI not found.
|
|
44
|
+
hint: install it with `uv tool install convertible-cli` (or `pipx install convertible-cli`),
|
|
45
|
+
or run from inside the convertible checkout with `uv` available.
|
|
46
|
+
https://github.com/agentculture/convertible
|
|
47
|
+
EOF
|
|
48
|
+
return 1
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
usage() {
|
|
52
|
+
cat <<'EOF'
|
|
53
|
+
outsource — hand a scoped repo task to convertible (a different engine/mind).
|
|
54
|
+
|
|
55
|
+
Usage:
|
|
56
|
+
outsource explore "<question or area>" Read-only investigation -> findings (no side effects)
|
|
57
|
+
outsource review "<what to focus on>" Diverse second-opinion on the committed diff (no side effects)
|
|
58
|
+
outsource write "<task>" [--pr] Implement a change (drive branch, or PR with --pr)
|
|
59
|
+
|
|
60
|
+
Options:
|
|
61
|
+
--repo PATH Target repo (default: .)
|
|
62
|
+
--base BRANCH Base for `review` diff (default: main)
|
|
63
|
+
--engine NAME Engine wheel (default: $CONVERTIBLE_ENGINE or vllm-openai)
|
|
64
|
+
--model NAME Model (default: $CONVERTIBLE_MODEL or mmangkad/Qwen3.6-27B-NVFP4)
|
|
65
|
+
--base-url URL OpenAI base URL (default: $CONVERTIBLE_BASE_URL or http://localhost:8001/v1)
|
|
66
|
+
--max-steps N Loop step budget (default: 20)
|
|
67
|
+
--timeout N Per-request timeout, seconds (default: $CONVERTIBLE_TIMEOUT or 300)
|
|
68
|
+
--allow-dirty (write) allow running on a dirty tree
|
|
69
|
+
--pr (write) push + open a PR instead of a local drive branch
|
|
70
|
+
|
|
71
|
+
explore/review run in a throwaway git worktree at HEAD — they cannot touch your
|
|
72
|
+
working tree or branch. review compares <base>...HEAD (committed changes only).
|
|
73
|
+
EOF
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# ── parse the verb ──────────────────────────────────────────────────────────
|
|
77
|
+
VERB="${1:-}"
|
|
78
|
+
case "$VERB" in
|
|
79
|
+
explore | review | write) shift ;;
|
|
80
|
+
-h | --help) usage; exit 0 ;;
|
|
81
|
+
"") usage >&2; exit 2 ;;
|
|
82
|
+
*)
|
|
83
|
+
echo "error: unknown verb '$VERB' (expected explore|review|write)" >&2
|
|
84
|
+
echo "hint: run 'outsource --help'" >&2
|
|
85
|
+
exit 2
|
|
86
|
+
;;
|
|
87
|
+
esac
|
|
88
|
+
|
|
89
|
+
# Required external tools — fail fast with a clear message, not an opaque
|
|
90
|
+
# mid-run error, if the environment is missing one.
|
|
91
|
+
require_tools() {
|
|
92
|
+
local missing=() t
|
|
93
|
+
for t in python3 git grep mktemp; do
|
|
94
|
+
command -v "$t" >/dev/null 2>&1 || missing+=("$t")
|
|
95
|
+
done
|
|
96
|
+
if [[ ${#missing[@]} -gt 0 ]]; then
|
|
97
|
+
echo "error: missing required tool(s): ${missing[*]}" >&2
|
|
98
|
+
echo "hint: outsource needs python3, git, grep, and mktemp on PATH." >&2
|
|
99
|
+
exit 2
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# Guard a value-taking flag: a trailing flag with no value would otherwise
|
|
104
|
+
# dereference an unset $2 and abort under `set -u`.
|
|
105
|
+
need_value() { # $1 = remaining arg count ($#), $2 = flag name
|
|
106
|
+
[[ "$1" -ge 2 ]] || {
|
|
107
|
+
echo "error: $2 requires a value" >&2
|
|
108
|
+
echo "hint: run 'outsource --help'" >&2
|
|
109
|
+
exit 2
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
require_tools
|
|
114
|
+
|
|
115
|
+
# ── defaults + flag parsing ─────────────────────────────────────────────────
|
|
116
|
+
REPO="."
|
|
117
|
+
BASE="main"
|
|
118
|
+
ENGINE="${CONVERTIBLE_ENGINE:-vllm-openai}"
|
|
119
|
+
MODEL="${CONVERTIBLE_MODEL:-mmangkad/Qwen3.6-27B-NVFP4}"
|
|
120
|
+
BASE_URL="${CONVERTIBLE_BASE_URL:-http://localhost:8001/v1}"
|
|
121
|
+
MAX_STEPS=20
|
|
122
|
+
TIMEOUT="${CONVERTIBLE_TIMEOUT:-300}"
|
|
123
|
+
ALLOW_DIRTY=0
|
|
124
|
+
OPEN_PR=0
|
|
125
|
+
ARG=""
|
|
126
|
+
|
|
127
|
+
while [[ $# -gt 0 ]]; do
|
|
128
|
+
case "$1" in
|
|
129
|
+
--repo) need_value "$#" "$1"; REPO="$2"; shift 2 ;;
|
|
130
|
+
--base) need_value "$#" "$1"; BASE="$2"; shift 2 ;;
|
|
131
|
+
--engine) need_value "$#" "$1"; ENGINE="$2"; shift 2 ;;
|
|
132
|
+
--model) need_value "$#" "$1"; MODEL="$2"; shift 2 ;;
|
|
133
|
+
--base-url) need_value "$#" "$1"; BASE_URL="$2"; shift 2 ;;
|
|
134
|
+
--max-steps) need_value "$#" "$1"; MAX_STEPS="$2"; shift 2 ;;
|
|
135
|
+
--timeout) need_value "$#" "$1"; TIMEOUT="$2"; shift 2 ;;
|
|
136
|
+
--allow-dirty) ALLOW_DIRTY=1; shift ;;
|
|
137
|
+
--pr) OPEN_PR=1; shift ;;
|
|
138
|
+
-h | --help) usage; exit 0 ;;
|
|
139
|
+
--) shift; while [[ $# -gt 0 ]]; do ARG="${ARG:+$ARG }$1"; shift; done ;;
|
|
140
|
+
-*) echo "error: unknown option '$1'" >&2; echo "hint: run 'outsource --help'" >&2; exit 2 ;;
|
|
141
|
+
*) ARG="${ARG:+$ARG }$1"; shift ;;
|
|
142
|
+
esac
|
|
143
|
+
done
|
|
144
|
+
|
|
145
|
+
[[ -n "$ARG" ]] || { echo "error: $VERB needs a description argument" >&2; usage >&2; exit 2; }
|
|
146
|
+
[[ -d "$REPO" ]] || { echo "error: --repo is not a directory: $REPO" >&2; exit 2; }
|
|
147
|
+
REPO="$(cd "$REPO" && pwd)"
|
|
148
|
+
|
|
149
|
+
resolve_convertible || exit 2
|
|
150
|
+
|
|
151
|
+
# Per-request timeout is config (no drive flag); EngineConfig reads it from env.
|
|
152
|
+
# A local model can be slow on a growing context, so default generously.
|
|
153
|
+
export CONVERTIBLE_TIMEOUT="$TIMEOUT"
|
|
154
|
+
COMMON_FLAGS=(--engine "$ENGINE" --model "$MODEL" --base-url "$BASE_URL" --max-steps "$MAX_STEPS" --json)
|
|
155
|
+
|
|
156
|
+
# ── render an instruction from a prompt template ────────────────────────────
|
|
157
|
+
render_prompt() {
|
|
158
|
+
local file="$PROMPTS_DIR/$1.md"
|
|
159
|
+
[[ -f "$file" ]] || { echo "error: missing prompt template: $file" >&2; exit 2; }
|
|
160
|
+
ARG="$ARG" BASE="$BASE" python3 - "$file" <<'PY'
|
|
161
|
+
import os, sys
|
|
162
|
+
tpl = open(sys.argv[1], encoding="utf-8").read()
|
|
163
|
+
sys.stdout.write(tpl.replace("$ARGUMENTS", os.environ["ARG"]).replace("$BASE", os.environ["BASE"]))
|
|
164
|
+
PY
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
# ── print the TaskResult that convertible emitted as JSON on stdout ─────────
|
|
168
|
+
# Reads JSON on stdin; prints a human/agent-readable digest; exits non-zero if
|
|
169
|
+
# the drive failed.
|
|
170
|
+
print_result() {
|
|
171
|
+
# NOTE: must be `python3 -c`, not `python3 - <<HEREDOC`: a heredoc becomes
|
|
172
|
+
# python's stdin (the script source), which would shadow the piped JSON and
|
|
173
|
+
# leave sys.stdin.read() empty. The script body uses no single quotes.
|
|
174
|
+
python3 -c '
|
|
175
|
+
import sys, json
|
|
176
|
+
raw = sys.stdin.read().strip()
|
|
177
|
+
if not raw:
|
|
178
|
+
sys.stderr.write("error: convertible produced no result on stdout (see diagnostics above)\n")
|
|
179
|
+
sys.exit(2)
|
|
180
|
+
try:
|
|
181
|
+
d = json.loads(raw)
|
|
182
|
+
except Exception:
|
|
183
|
+
sys.stderr.write("error: could not parse convertible --json output:\n")
|
|
184
|
+
sys.stderr.write(raw[:2000] + "\n")
|
|
185
|
+
sys.exit(2)
|
|
186
|
+
print("status:", d.get("status"))
|
|
187
|
+
print()
|
|
188
|
+
print((d.get("summary") or "").rstrip())
|
|
189
|
+
cf = d.get("changed_files") or []
|
|
190
|
+
if cf:
|
|
191
|
+
print("\nchanged files:", ", ".join(cf))
|
|
192
|
+
if d.get("branch"):
|
|
193
|
+
print("drive branch:", d["branch"])
|
|
194
|
+
if d.get("artifacts_path"):
|
|
195
|
+
print("artifact:", d["artifacts_path"])
|
|
196
|
+
sys.exit(0 if d.get("status") == "ok" else 1)
|
|
197
|
+
'
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# ── read-only verbs: isolate the drive in a throwaway worktree at HEAD ──────
|
|
201
|
+
# Worktree state is module-global, not a function local: the EXIT trap fires
|
|
202
|
+
# *after* run_readonly returns, so under `set -u` a local would be unbound.
|
|
203
|
+
_WT=""
|
|
204
|
+
_DRIVE_BRANCH=""
|
|
205
|
+
|
|
206
|
+
_cleanup_worktree() {
|
|
207
|
+
[[ -n "$_WT" ]] || return 0
|
|
208
|
+
git -C "$REPO" worktree remove --force "$_WT" >/dev/null 2>&1 || true
|
|
209
|
+
rm -rf "$_WT" >/dev/null 2>&1 || true
|
|
210
|
+
# Only ever delete the ephemeral drive branch convertible names
|
|
211
|
+
# (convertible/<task_id>) — never an unrelated local branch, even if the
|
|
212
|
+
# JSON `branch` value were unexpected.
|
|
213
|
+
if [[ "$_DRIVE_BRANCH" == convertible/* ]]; then
|
|
214
|
+
git -C "$REPO" branch -D "$_DRIVE_BRANCH" >/dev/null 2>&1 || true
|
|
215
|
+
fi
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
run_readonly() {
|
|
219
|
+
local instruction="$1"
|
|
220
|
+
git -C "$REPO" rev-parse --is-inside-work-tree >/dev/null 2>&1 \
|
|
221
|
+
|| { echo "error: --repo is not a git repository: $REPO" >&2; exit 2; }
|
|
222
|
+
|
|
223
|
+
_WT="$(mktemp -d)"
|
|
224
|
+
trap _cleanup_worktree EXIT
|
|
225
|
+
git -C "$REPO" worktree add -q --detach "$_WT" HEAD
|
|
226
|
+
|
|
227
|
+
local out
|
|
228
|
+
out="$("${CONVERTIBLE[@]}" drive "$instruction" --repo "$_WT" --no-pr "${COMMON_FLAGS[@]}")" || true
|
|
229
|
+
_DRIVE_BRANCH="$(printf '%s' "$out" | python3 -c 'import sys, json
|
|
230
|
+
try:
|
|
231
|
+
print(json.load(sys.stdin).get("branch") or "")
|
|
232
|
+
except Exception:
|
|
233
|
+
print("")' 2>/dev/null || true)"
|
|
234
|
+
printf '%s' "$out" | print_result
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# ── write verb: in-place drive (drive branch, or PR with --pr) ──────────────
|
|
238
|
+
run_write() {
|
|
239
|
+
local instruction="$1"
|
|
240
|
+
if [[ "$ALLOW_DIRTY" -eq 0 ]] \
|
|
241
|
+
&& [[ -n "$(git -C "$REPO" status --porcelain 2>/dev/null)" ]]; then
|
|
242
|
+
echo "error: working tree is dirty — commit/stash first, or pass --allow-dirty" >&2
|
|
243
|
+
echo "hint: 'convertible drive --no-pr' commits uncommitted edits onto the drive branch" >&2
|
|
244
|
+
exit 2
|
|
245
|
+
fi
|
|
246
|
+
local out
|
|
247
|
+
if [[ "$OPEN_PR" -eq 1 ]]; then
|
|
248
|
+
out="$("${CONVERTIBLE[@]}" drive "$instruction" --repo "$REPO" "${COMMON_FLAGS[@]}")"
|
|
249
|
+
else
|
|
250
|
+
out="$("${CONVERTIBLE[@]}" drive "$instruction" --repo "$REPO" --no-pr "${COMMON_FLAGS[@]}")"
|
|
251
|
+
fi
|
|
252
|
+
printf '%s' "$out" | print_result
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
case "$VERB" in
|
|
256
|
+
explore) run_readonly "$(render_prompt explore)" ;;
|
|
257
|
+
review) run_readonly "$(render_prompt review)" ;;
|
|
258
|
+
write) run_write "$(render_prompt write)" ;;
|
|
259
|
+
esac
|
|
@@ -24,3 +24,9 @@ ignores:
|
|
|
24
24
|
# devague working state (frames/plans are committed as JSON; reviews are
|
|
25
25
|
# git-ignored) — not hand-authored prose.
|
|
26
26
|
- ".devague/**"
|
|
27
|
+
# Vendored skill prompt templates (e.g. outsource's explore/review/write) are
|
|
28
|
+
# raw LLM instruction text fed verbatim to a model, not hand-authored docs —
|
|
29
|
+
# they intentionally open with prose, not an H1 (MD041), and carry $PLACEHOLDER
|
|
30
|
+
# tokens. Linting them as markdown is a category error, and editing them to
|
|
31
|
+
# satisfy a linter would fork the cited-verbatim copy (cite-don't-import).
|
|
32
|
+
- ".claude/skills/**/prompts/**"
|
|
@@ -5,6 +5,59 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/). This project
|
|
6
6
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.9.0] - 2026-05-31
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Vendor the `outsource` skill** (`.claude/skills/outsource/`) — guildmaster
|
|
13
|
+
now runs the skill it will broadcast. `outsource` hands a scoped repo task to
|
|
14
|
+
[`convertible`](https://github.com/agentculture/convertible) — a *different*
|
|
15
|
+
engine/mind, not a stronger one — via three verbs: `explore` (read-only
|
|
16
|
+
investigation), `review` (a diverse second opinion on the committed diff, the
|
|
17
|
+
headline verb), and `write` (delegate a small implementation to a drive branch
|
|
18
|
+
or PR). `explore`/`review` run isolated in a throwaway `git worktree` at HEAD;
|
|
19
|
+
`write` refuses a dirty tree unless `--allow-dirty`.
|
|
20
|
+
- **Register `outsource`'s origin** in `guild.skills.INBOUND_ORIGINS`
|
|
21
|
+
(`agentculture/convertible`) so `guild teach` / `onboard` / `overview` attribute
|
|
22
|
+
it to convertible and frame it as *re-broadcast*, the same inbound pattern as
|
|
23
|
+
the devague workflow trio.
|
|
24
|
+
- **Ledger:** new "Inbound first-party skill (origin = `convertible`,
|
|
25
|
+
re-broadcast by `guildmaster`)" section in `docs/skill-sources.md` recording
|
|
26
|
+
`outsource`, its sole divergence (a reframed Provenance paragraph; upstream
|
|
27
|
+
already carries `type: command`), and its runtime dependency on the
|
|
28
|
+
`convertible` CLI. Downstream is empty by design — guildmaster is the first
|
|
29
|
+
holder outside convertible. Cross-links
|
|
30
|
+
[`culture-agent-template#8`](https://github.com/agentculture/culture-agent-template/issues/8),
|
|
31
|
+
which proposes adding `outsource` to the clone template.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
## [0.8.5] - 2026-05-31
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- **Register three new downstream consumers** in `docs/skill-sources.md`, each
|
|
42
|
+
provisioned via `guild create --apply` from `culture-agent-template`:
|
|
43
|
+
- `unsloth-cli` — agent + CLI that simplifies fine-tuning with Unsloth
|
|
44
|
+
(command `sloth`, import package `sloth`, dist `unsloth-cli`).
|
|
45
|
+
- `discord-bot-cli` — agent + CLI that gives an agent Discord access via a
|
|
46
|
+
bot (command `discord`; import package decoupled to `discord_bot_cli` so it
|
|
47
|
+
doesn't shadow the `discord.py` library; dist `discord-bot-cli`).
|
|
48
|
+
- `arxivist` — agent + CLI that fetches arXiv papers, maintains a knowledge
|
|
49
|
+
base, implements paper solutions, and benchmarks them against the papers'
|
|
50
|
+
claims (command = package = dist = `arxivist`).
|
|
51
|
+
|
|
52
|
+
Each is registered across all canonical supplied skills (`agent-config`,
|
|
53
|
+
`cicd`, `communicate`, `doc-test-alignment`, `pypi-maintainer`, `run-tests`,
|
|
54
|
+
`sonarclaude`, `version-bump`) and the inbound devague workflow skills
|
|
55
|
+
(`think`, `spec-to-plan`, `assign-to-workforce`).
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
8
61
|
## [0.8.4] - 2026-05-30
|
|
9
62
|
|
|
10
63
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guild-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: guildmaster — an agent and CLI that manages skills for the AgentCulture mesh.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/guildmaster
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/guildmaster/issues
|
|
@@ -32,14 +32,14 @@ current by `guild overview --scope mesh`.
|
|
|
32
32
|
|
|
33
33
|
| Skill | Upstream | Downstream copies (known) | Notes |
|
|
34
34
|
|-------|----------|---------------------------|-------|
|
|
35
|
-
| `agent-config` | `guildmaster` (`.claude/skills/agent-config/`) | `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Inventory variant backing `guild show` ([#12](https://github.com/agentculture/guildmaster/issues/12)); `show.sh` + `data/backend-fingerprints.yaml` vendored verbatim from steward, SKILL.md reframed from alignment-judgment to inventory + `type: command` added. **Forked from steward:** steward retains its own alignment-focused `agent-config` variant; the inventory variant is guildmaster's to supply. |
|
|
36
|
-
| `cicd` | `guildmaster` (`.claude/skills/cicd/`) — layered on `devex pr` (in `agentculture/devex`) | `afi-cli`, `devex` (adapted-thin delegate — owns `devex pr`; see [devex#53](https://github.com/agentculture/devex/pull/53)), `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi` (still named `pr-review`), `code-lens-cli`, `culture` (still named `pr-review`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `grant` (still named `pr-review`), `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Thin delegate to `devex pr` for lint / open / read / reply / delta, plus guildmaster's `status` (SonarCloud quality gate + hotspots + unresolved-thread tally) and `await` (composes `devex pr read --wait` with `status`, non-zero exit on Sonar ERROR / unresolved threads) extensions. **Inverted case:** devex, as the `devex pr` upstream, vendors the skill adapted-thin — a `workflow.sh`-only pure delegate ([devex#53](https://github.com/agentculture/devex/pull/53)). Renamed from `pr-review` in steward 0.7.0; downstream copies may keep the old name on their own cadence. |
|
|
37
|
-
| `communicate` | `guildmaster` (`.claude/skills/communicate/`) | `afi-cli`, `devex` (identifier-only — vendored steward 0.11.0; scripts current as of 0.18.0), `agtag`, `antoine`, `appsec`, `auntiepypi`, `code-lens-cli`, `culture` (still named `coordinate`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Cross-repo + mesh communication: file issues / hand off briefs to sibling-repo agents (auto-signed), comment on existing issues, fetch issues to inline state into briefs, and send live messages to Culture mesh channels (unsigned — nick is the speaker). Renamed from `coordinate` in steward 0.8.0; absorbed `gh-issues` (as `fetch-issues.sh`) in 0.9.1. Issue I/O backed by `agtag` (>=0.1) since steward 0.11.0 — signature resolves from local `culture.yaml` (override via `--as`). |
|
|
38
|
-
| `doc-test-alignment` | `guildmaster` (`.claude/skills/doc-test-alignment/`) | `devague`, `lecodeur`, `lepenseur`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Stub; real implementation TBD. `scripts/check.sh` exits not-yet-implemented today. |
|
|
39
|
-
| `pypi-maintainer` | `guildmaster` (`.claude/skills/pypi-maintainer/`) | `agtag`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Switches a PyPI package install between pypi / test-pypi / local. Generalised from the original culture-specific `change-package`. |
|
|
40
|
-
| `run-tests` | `guildmaster` (`.claude/skills/run-tests/`) | `agtag`, `antoine`, `appsec`, `code-lens-cli`, `culture`, `culture-sonar-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Coverage source resolves from `[tool.coverage.run]` in `pyproject.toml`, so the script is portable across siblings without modification. |
|
|
41
|
-
| `sonarclaude` | `guildmaster` (`.claude/skills/sonarclaude/`) | `antoine`, `appsec`, `code-lens-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | SonarCloud API client. Project key resolves from `$SONAR_PROJECT` or `--project KEY`. |
|
|
42
|
-
| `version-bump` | `guildmaster` (`.claude/skills/version-bump/`) | `afi-cli`, `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi`, `code-lens-cli`, `culture`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Pure Python, prepends a Keep-a-Changelog entry; no per-repo customization needed. |
|
|
35
|
+
| `agent-config` | `guildmaster` (`.claude/skills/agent-config/`) | `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Inventory variant backing `guild show` ([#12](https://github.com/agentculture/guildmaster/issues/12)); `show.sh` + `data/backend-fingerprints.yaml` vendored verbatim from steward, SKILL.md reframed from alignment-judgment to inventory + `type: command` added. **Forked from steward:** steward retains its own alignment-focused `agent-config` variant; the inventory variant is guildmaster's to supply. |
|
|
36
|
+
| `cicd` | `guildmaster` (`.claude/skills/cicd/`) — layered on `devex pr` (in `agentculture/devex`) | `afi-cli`, `devex` (adapted-thin delegate — owns `devex pr`; see [devex#53](https://github.com/agentculture/devex/pull/53)), `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi` (still named `pr-review`), `code-lens-cli`, `culture` (still named `pr-review`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `grant` (still named `pr-review`), `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Thin delegate to `devex pr` for lint / open / read / reply / delta, plus guildmaster's `status` (SonarCloud quality gate + hotspots + unresolved-thread tally) and `await` (composes `devex pr read --wait` with `status`, non-zero exit on Sonar ERROR / unresolved threads) extensions. **Inverted case:** devex, as the `devex pr` upstream, vendors the skill adapted-thin — a `workflow.sh`-only pure delegate ([devex#53](https://github.com/agentculture/devex/pull/53)). Renamed from `pr-review` in steward 0.7.0; downstream copies may keep the old name on their own cadence. |
|
|
37
|
+
| `communicate` | `guildmaster` (`.claude/skills/communicate/`) | `afi-cli`, `devex` (identifier-only — vendored steward 0.11.0; scripts current as of 0.18.0), `agtag`, `antoine`, `appsec`, `auntiepypi`, `code-lens-cli`, `culture` (still named `coordinate`), `devague`, `katvan`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Cross-repo + mesh communication: file issues / hand off briefs to sibling-repo agents (auto-signed), comment on existing issues, fetch issues to inline state into briefs, and send live messages to Culture mesh channels (unsigned — nick is the speaker). Renamed from `coordinate` in steward 0.8.0; absorbed `gh-issues` (as `fetch-issues.sh`) in 0.9.1. Issue I/O backed by `agtag` (>=0.1) since steward 0.11.0 — signature resolves from local `culture.yaml` (override via `--as`). |
|
|
38
|
+
| `doc-test-alignment` | `guildmaster` (`.claude/skills/doc-test-alignment/`) | `devague`, `lecodeur`, `lepenseur`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Stub; real implementation TBD. `scripts/check.sh` exits not-yet-implemented today. |
|
|
39
|
+
| `pypi-maintainer` | `guildmaster` (`.claude/skills/pypi-maintainer/`) | `agtag`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Switches a PyPI package install between pypi / test-pypi / local. Generalised from the original culture-specific `change-package`. |
|
|
40
|
+
| `run-tests` | `guildmaster` (`.claude/skills/run-tests/`) | `agtag`, `antoine`, `appsec`, `code-lens-cli`, `culture`, `culture-sonar-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Coverage source resolves from `[tool.coverage.run]` in `pyproject.toml`, so the script is portable across siblings without modification. |
|
|
41
|
+
| `sonarclaude` | `guildmaster` (`.claude/skills/sonarclaude/`) | `antoine`, `appsec`, `code-lens-cli`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | SonarCloud API client. Project key resolves from `$SONAR_PROJECT` or `--project KEY`. |
|
|
42
|
+
| `version-bump` | `guildmaster` (`.claude/skills/version-bump/`) | `afi-cli`, `agtag`, `antoine`, `appsec`, `auntiepypi`, `cfafi`, `code-lens-cli`, `culture`, `devague`, `lecodeur`, `lepenseur`, `seer-cli`, `grant`, `telek`, `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Pure Python, prepends a Keep-a-Changelog entry; no per-repo customization needed. |
|
|
43
43
|
|
|
44
44
|
> **How the downstream column is maintained.** The "Downstream copies (known)"
|
|
45
45
|
> entries are kept in sync with guildmaster's own drift detector:
|
|
@@ -86,14 +86,50 @@ harmless on `claude-code`. This is the only divergence from upstream.
|
|
|
86
86
|
|
|
87
87
|
| Skill | Origin | Downstream copies (known) | Notes |
|
|
88
88
|
|-------|--------|---------------------------|-------|
|
|
89
|
-
| `think` | `devague` (`agentculture/devague`, `../devague/.claude/skills/think/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Operator for the **idea→spec** leg (announcement frame → capture/classify claims → interrogate with honesty conditions → park open vagueness → `export` once the frame converges). Renamed from `devague` in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
|
|
90
|
-
| `spec-to-plan` | `devague` (`agentculture/devague`, `../devague/.claude/skills/spec-to-plan/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Operator for the **spec→plan** leg (`devague plan ...`): seed from a converged frame, cover every coverage target with acceptance-gated, acyclically-ordered tasks, park unknowns as risks, `export` once the plan converges. New in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
|
|
91
|
-
| `assign-to-workforce` | `devague` (`agentculture/devague`, `../devague/.claude/skills/assign-to-workforce/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli` | Operator for the **implementation** leg: reads `devague plan waves` (read-only) and fans out independent tasks to one agent per task per wave in isolated git worktrees, with main-agent TDD-gated merges. Three human gates: spec / split plan / final PR. The CLI stays non-orchestrating ([devague#20](https://github.com/agentculture/devague/issues/20)). New in devague 0.10.0. **Divergence:** `type: command` added. Runtime deps: `uv tool install devague`, `git worktree`, the vendored `cicd` skill (for gate-3 `devex pr open`). |
|
|
89
|
+
| `think` | `devague` (`agentculture/devague`, `../devague/.claude/skills/think/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Operator for the **idea→spec** leg (announcement frame → capture/classify claims → interrogate with honesty conditions → park open vagueness → `export` once the frame converges). Renamed from `devague` in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
|
|
90
|
+
| `spec-to-plan` | `devague` (`agentculture/devague`, `../devague/.claude/skills/spec-to-plan/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Operator for the **spec→plan** leg (`devague plan ...`): seed from a converged frame, cover every coverage target with acceptance-gated, acyclically-ordered tasks, park unknowns as risks, `export` once the plan converges. New in devague 0.4.0. **Divergence:** `type: command` added. Runtime dep: `uv tool install devague`. |
|
|
91
|
+
| `assign-to-workforce` | `devague` (`agentculture/devague`, `../devague/.claude/skills/assign-to-workforce/`) | — (broadcast pending), `agenda`, `dominion-breaker`, `convertible`, `jetson`, `reachy-mini-cli`, `jetson-ai-lab-cli`, `dgx-spark-cli`, `unsloth-cli`, `discord-bot-cli`, `arxivist` | Operator for the **implementation** leg: reads `devague plan waves` (read-only) and fans out independent tasks to one agent per task per wave in isolated git worktrees, with main-agent TDD-gated merges. Three human gates: spec / split plan / final PR. The CLI stays non-orchestrating ([devague#20](https://github.com/agentculture/devague/issues/20)). New in devague 0.10.0. **Divergence:** `type: command` added. Runtime deps: `uv tool install devague`, `git worktree`, the vendored `cicd` skill (for gate-3 `devex pr open`). |
|
|
92
92
|
|
|
93
93
|
Downstream is empty by design: these are still being introduced to the mesh.
|
|
94
94
|
`guild teach --new --skill <name> --to <repos>` frames them as *new* skills to
|
|
95
95
|
add fresh (not stale copies to resync).
|
|
96
96
|
|
|
97
|
+
## Inbound first-party skill (origin = `convertible`, re-broadcast by `guildmaster`)
|
|
98
|
+
|
|
99
|
+
`outsource` flows the **same opposite direction** as the devague trio above: a
|
|
100
|
+
sibling, [`convertible`](https://github.com/agentculture/convertible), is its
|
|
101
|
+
author/upstream; guildmaster pulls it from convertible and re-broadcasts it to
|
|
102
|
+
the mesh. `cite, don't import` still applies — re-sync, when it later changes
|
|
103
|
+
upstream, from `../convertible/.claude/skills/outsource/`.
|
|
104
|
+
|
|
105
|
+
Where the devague skills drive a deterministic CLI, `outsource` is a portable
|
|
106
|
+
wrapper (`scripts/outsource.sh`) that drives the **`convertible` CLI** so a
|
|
107
|
+
Claude agent can hand a scoped task to a *different* engine/mind (default: a
|
|
108
|
+
local vLLM `Qwen3.6-27B`) — `explore` (read-only investigation), `review` (a
|
|
109
|
+
diverse second opinion on the committed diff, the headline verb), and `write`
|
|
110
|
+
(delegate a small implementation to a drive branch / PR). `explore`/`review` run
|
|
111
|
+
isolated in a throwaway `git worktree` at HEAD; `write` refuses a dirty tree.
|
|
112
|
+
|
|
113
|
+
**Divergence from verbatim.** The upstream copy already carries `type: command`
|
|
114
|
+
(load-bearing on the culture backend), so no frontmatter change was needed. The
|
|
115
|
+
**only** edit is the SKILL.md *Provenance* paragraph: upstream says "the inverse
|
|
116
|
+
of the other skills … which convertible vendors *from* guildmaster" — true in
|
|
117
|
+
convertible's repo, misleading here — reframed to "guildmaster re-broadcasts it
|
|
118
|
+
… tracking it in `docs/skill-sources.md`." No script or prompt body is edited.
|
|
119
|
+
|
|
120
|
+
**Runtime dependency:** the `convertible` CLI on `PATH`
|
|
121
|
+
(`uv tool install convertible-cli`) plus a reachable engine (override the local
|
|
122
|
+
default via `--engine` / `--model` / `--base-url` or `CONVERTIBLE_*` env). Absent
|
|
123
|
+
the CLI, the wrapper exits with a clear install hint rather than crashing.
|
|
124
|
+
|
|
125
|
+
| Skill | Origin | Downstream copies (known) | Notes |
|
|
126
|
+
|-------|--------|---------------------------|-------|
|
|
127
|
+
| `outsource` | `convertible` (`agentculture/convertible`, `../convertible/.claude/skills/outsource/`) | — (broadcast pending; [`culture-agent-template#8`](https://github.com/agentculture/culture-agent-template/issues/8) proposes adding it to the clone template) | First-party convertible skill: hand a scoped task to a *different* engine/mind. Verbs `explore` / `review` / `write`. **Divergence:** Provenance paragraph reframed for re-broadcast (above); `type: command` already present upstream. Runtime dep: `uv tool install convertible-cli` + a reachable engine. |
|
|
128
|
+
|
|
129
|
+
Downstream is empty by design — guildmaster is the first holder outside
|
|
130
|
+
convertible. `guild teach --new --skill outsource --to <repos>` frames it as a
|
|
131
|
+
*new* skill when broadcasting.
|
|
132
|
+
|
|
97
133
|
## guildmaster-origin skills (origin = `guildmaster`)
|
|
98
134
|
|
|
99
135
|
These are guildmaster's **own** operator skills — not vendored from anyone and
|
|
@@ -15,12 +15,14 @@ from __future__ import annotations
|
|
|
15
15
|
|
|
16
16
|
# Skills whose origin is a *sibling* (not guildmaster): re-broadcasting them
|
|
17
17
|
# carries an origin-attribution block so consumers know guildmaster only
|
|
18
|
-
# re-broadcasts. Mirrors the "Inbound workflow skills"
|
|
19
|
-
# ``docs/skill-sources.md`` (the devague trio
|
|
18
|
+
# re-broadcasts. Mirrors the "Inbound workflow skills" + "Inbound first-party"
|
|
19
|
+
# sections of ``docs/skill-sources.md`` (the devague trio; convertible's
|
|
20
|
+
# ``outsource``).
|
|
20
21
|
INBOUND_ORIGINS: dict[str, str] = {
|
|
21
22
|
"think": "agentculture/devague",
|
|
22
23
|
"spec-to-plan": "agentculture/devague",
|
|
23
24
|
"assign-to-workforce": "agentculture/devague",
|
|
25
|
+
"outsource": "agentculture/convertible",
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
# guildmaster's own skills — present in ``.claude/skills/`` but NOT part of the
|
|
File without changes
|
{guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/agent-config/data/backend-fingerprints.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{guild_cli-0.8.4 → guild_cli-0.9.0}/.claude/skills/communicate/scripts/templates/skill-new-brief.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|