guild-cli 0.4.0__tar.gz → 0.4.2__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.4.2/.claude/skills/guild/SKILL.md +146 -0
- guild_cli-0.4.2/.claude/skills/guild/scripts/overview.sh +76 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/CHANGELOG.md +52 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/CLAUDE.md +11 -5
- {guild_cli-0.4.0 → guild_cli-0.4.2}/PKG-INFO +3 -2
- {guild_cli-0.4.0 → guild_cli-0.4.2}/README.md +2 -1
- {guild_cli-0.4.0 → guild_cli-0.4.2}/docs/skill-sources.md +14 -2
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/overview.py +155 -18
- guild_cli-0.4.2/guild/cli/_repo.py +235 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/skills/__init__.py +6 -3
- {guild_cli-0.4.0 → guild_cli-0.4.2}/pyproject.toml +1 -1
- guild_cli-0.4.2/tests/test_cli_overview.py +286 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/uv.lock +1 -1
- guild_cli-0.4.0/guild/cli/_repo.py +0 -116
- guild_cli-0.4.0/tests/test_cli_overview.py +0 -148
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/agent-config/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/cicd/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/onboard/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/onboard/scripts/onboard.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/run-tests/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/spec-to-plan/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/teach/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/teach/scripts/teach.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/think/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/think/scripts/think.sh +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/version-bump/SKILL.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.claude/skills.local.yaml.example +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.devague/frames/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.devague/plans/guildmaster-ships-teach-and-onboard-two-agent-firs.json +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.flake8 +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.github/workflows/publish.yml +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.github/workflows/tests.yml +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.gitignore +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/.markdownlint-cli2.yaml +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/LICENSE +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/culture.yaml +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/docs/cutover.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/docs/plans/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/docs/specs/2026-05-24-guildmaster-ships-teach-and-onboard-two-agent-firs.md +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/__init__.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/__main__.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/__init__.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/__init__.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/_broadcast.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/explain.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/learn.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/onboard.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/show.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/teach.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_commands/whoami.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_errors.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/cli/_output.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/skills/identity.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/skills/ledger.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/skills/render.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/guild/skills/sources.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/__init__.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_broadcast_post.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli_explain.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli_learn.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli_onboard.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli_show.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli_teach.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_cli_whoami.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_skills_convention.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_skills_identity.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_skills_ledger.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_skills_render.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_skills_sources.py +0 -0
- {guild_cli-0.4.0 → guild_cli-0.4.2}/tests/test_version_fallback.py +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: guild
|
|
3
|
+
description: >
|
|
4
|
+
Run guildmaster's skills-supplier overview and narrate it. Run `guild
|
|
5
|
+
overview` (via scripts/overview.sh) for the deterministic evidence pack — the
|
|
6
|
+
canonical skill set + versions/origins, the docs/skill-sources.md ledger, and
|
|
7
|
+
skills-scoped drift signals — then narrate three separated layers: observed
|
|
8
|
+
facts, inferred relationships, and suggestions (each naming the command that
|
|
9
|
+
enacts it). Use when an operator asks "what skills do we supply", "who
|
|
10
|
+
consumes what", "is anything drifting", or "what should I teach next".
|
|
11
|
+
Skills-scoped and reflect-only — it surfaces and interprets supplier-side
|
|
12
|
+
skill/version signals; it does NOT narrate the agent relationship graph or
|
|
13
|
+
judge alignment (that stays with steward's org-overview / steward doctor).
|
|
14
|
+
The skills-scoped excerpt of steward's `org-overview` narration contract
|
|
15
|
+
(cite-don't-import, issue #12).
|
|
16
|
+
type: command
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# guild — narrate guildmaster's own supplier surfaces
|
|
20
|
+
|
|
21
|
+
guildmaster is the mesh's skills **supplier**, and it owns the *inventory*
|
|
22
|
+
surfaces ([issue #12](https://github.com/agentculture/guildmaster/issues/12)).
|
|
23
|
+
The per-agent half (`guild show`) is backed by the vendored `agent-config`
|
|
24
|
+
skill. **This skill is the supplier half: the affordance for `guild overview`.**
|
|
25
|
+
It houses the scripts that run guildmaster's own read-only CLI surfaces and the
|
|
26
|
+
contract for narrating them — `overview` is the one script today.
|
|
27
|
+
|
|
28
|
+
Unlike the vendored skills, this one is **guildmaster's own** (origin =
|
|
29
|
+
`guildmaster`, not cited from steward): `guild overview` is a pure-Python,
|
|
30
|
+
read-only CLI verb, and `scripts/overview.sh` is the thin deterministic wrapper
|
|
31
|
+
that invokes it. The script picks how to call `guild` (installed console
|
|
32
|
+
script → `uv run` → `python -m guild`) and delegates; it interprets nothing.
|
|
33
|
+
|
|
34
|
+
**The load-bearing split** (this is the skills-scoped excerpt of steward's
|
|
35
|
+
`org-overview` narration contract — issue #12, cite-don't-import):
|
|
36
|
+
|
|
37
|
+
- **The CLI (`guild overview`) emits only deterministic facts** — the canonical
|
|
38
|
+
skill set, the ledger view, and neutral drift signals. No LLM, no
|
|
39
|
+
interpretation, mutates nothing.
|
|
40
|
+
- **This skill is where the agent interprets** — turning those facts into
|
|
41
|
+
inferred relationships and suggestions. **Never present an inference as a
|
|
42
|
+
fact**, and keep the layers in separate sections.
|
|
43
|
+
|
|
44
|
+
## What `overview` answers
|
|
45
|
+
|
|
46
|
+
A skills-scoped evidence pack — **not** `steward overview`'s ecosystem
|
|
47
|
+
relationship graph (issue #12: inventory → guildmaster; judgment → steward):
|
|
48
|
+
|
|
49
|
+
1. **Canonical skill set + versions** — every skill guildmaster supplies, its
|
|
50
|
+
origin (`guildmaster`, or a sibling it only re-broadcasts), and the current
|
|
51
|
+
canonical version, plus per-skill consumers.
|
|
52
|
+
2. **Ledger view** — who-consumes-which-skill, read from `docs/skill-sources.md`.
|
|
53
|
+
3. **Drift signals** — canonical skills no one consumes, canonical skills the
|
|
54
|
+
ledger doesn't track yet, and per-agent kit gaps. These feed `teach` /
|
|
55
|
+
`onboard`.
|
|
56
|
+
|
|
57
|
+
**Pre-cutover** the guildmaster ledger is still a consumer-side view with no
|
|
58
|
+
"Downstream" column, so the supplier ledger is empty and drift is inactive; the
|
|
59
|
+
verb reports the canonical set and says so plainly (see `docs/cutover.md`).
|
|
60
|
+
|
|
61
|
+
**`--scope mesh`** is the ledger-free alternative: it surveys every agent in the
|
|
62
|
+
workspace (`<workspace>/*/culture.yaml`) live off the filesystem and reports, per
|
|
63
|
+
agent, each canonical skill as **current** / **stale** (the agent's copy differs
|
|
64
|
+
from guildmaster's by content fingerprint) / **missing**, plus any non-canonical
|
|
65
|
+
"extra" skills. Use it to answer "what's missing or stale, and where" *today*,
|
|
66
|
+
without waiting for the cutover. Still skills-scoped — no relationship graph.
|
|
67
|
+
|
|
68
|
+
## When to use
|
|
69
|
+
|
|
70
|
+
- An operator asks "what skills do we supply" / "what's the canonical set".
|
|
71
|
+
- "Who has skill `<x>`?" / "who consumes what?" / "is anything drifting?"
|
|
72
|
+
- "What should I `teach` next?" — overview's gaps are the input to `teach`.
|
|
73
|
+
- Before `guild teach` / `guild onboard`, to see uncovered skills and kit gaps.
|
|
74
|
+
|
|
75
|
+
## How to run
|
|
76
|
+
|
|
77
|
+
One script. Pick the scope (or just run `guild overview`, which this wraps):
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Whole mesh — the canonical set + ledger + drift across all agents (default)
|
|
81
|
+
.claude/skills/guild/scripts/overview.sh
|
|
82
|
+
|
|
83
|
+
# One agent — that agent's kit + gaps (first positional → --scope self)
|
|
84
|
+
.claude/skills/guild/scripts/overview.sh daria
|
|
85
|
+
|
|
86
|
+
# Mesh survey — every agent's skills + missing/stale, live off the filesystem
|
|
87
|
+
.claude/skills/guild/scripts/overview.sh --scope mesh
|
|
88
|
+
|
|
89
|
+
# Machine-readable evidence for precise reasoning
|
|
90
|
+
.claude/skills/guild/scripts/overview.sh --json
|
|
91
|
+
.claude/skills/guild/scripts/overview.sh --scope mesh --json
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The script prints the CLI's markdown by default: the canonical-skill table, a
|
|
95
|
+
ledger section, and a drift section. The exact per-skill consumer and gap lists
|
|
96
|
+
live in `--json`.
|
|
97
|
+
|
|
98
|
+
## Narrate three layers — never blur them
|
|
99
|
+
|
|
100
|
+
`guild overview` emits only deterministic facts; this skill is where you
|
|
101
|
+
interpret them. Keep the three layers in separate sections, and never present
|
|
102
|
+
an inference as a fact:
|
|
103
|
+
|
|
104
|
+
1. **Observed facts.** Summarize the canonical set + versions/origins and the
|
|
105
|
+
ledger view in your own words — lead with what the counts reveal (the
|
|
106
|
+
canonical set, who's behind, who's unregistered). State only what the CLI
|
|
107
|
+
reported; don't reproduce the raw signal lists verbatim (read `--json` only
|
|
108
|
+
when you need an exact list to act on). Pre-cutover, say so plainly: the
|
|
109
|
+
ledger has no downstream column yet, so consumers are empty and drift is
|
|
110
|
+
inactive.
|
|
111
|
+
2. **Inferred relationships** (mark clearly as inferred). Connect facts no
|
|
112
|
+
single ledger row states outright — e.g. two consumers vendored from the
|
|
113
|
+
same upstream skill *both* lag a canonical bump (a shared exposure), or a
|
|
114
|
+
skill only `guildmaster` carries is a single point of supply.
|
|
115
|
+
3. **Suggestions** (kept separate from facts, and *named, not run*). Seed these
|
|
116
|
+
from the skills-scoped drift signals — for each, name the concrete next step
|
|
117
|
+
and the command that enacts it, then stop.
|
|
118
|
+
|
|
119
|
+
### Signal → suggestion (skills-scoped only)
|
|
120
|
+
|
|
121
|
+
These are the **skill/version** signals `guild overview` emits — guildmaster's
|
|
122
|
+
supplier lane:
|
|
123
|
+
|
|
124
|
+
| Drift signal (from `guild overview`) | Reading | Named follow-up — name it, do NOT auto-run |
|
|
125
|
+
|--------------------------------------|---------|--------------------------------------------|
|
|
126
|
+
| `unledgered_skills` | a canonical skill the ledger doesn't track (no owner row) | Fix the ledger: add it to `docs/skill-sources.md` |
|
|
127
|
+
| `uncovered_skills` | a canonical skill no agent consumes (orphan) | Confirm intentional, then `teach` it, or retire it |
|
|
128
|
+
| `agent_gaps` (per-agent missing skill) | a consumer behind / missing a skill | `guild teach --skill <name> --to <agent>` to close the gap |
|
|
129
|
+
| agent not registered in the ledger | a sibling not yet onboarded | `guild onboard --agent <owner/repo>` |
|
|
130
|
+
| consumer behind the canonical pin (post-cutover) | a team on an outdated procedure | Re-vendor: `guild teach` / `onboard` to the current pin |
|
|
131
|
+
|
|
132
|
+
### Out of scope — steward's lane
|
|
133
|
+
|
|
134
|
+
The **relationship** signals — `overlap`, `over-connected-agent`,
|
|
135
|
+
`isolated-repo` — and the typed agent relationship graph are **not** narrated
|
|
136
|
+
here. Those belong to steward's `org-overview` / `steward overview`. guildmaster
|
|
137
|
+
narrates skills/version drift, not the ecosystem graph or alignment judgment.
|
|
138
|
+
|
|
139
|
+
### Reflect-only
|
|
140
|
+
|
|
141
|
+
This skill **sees, reflects, and suggests — it does not act.** For every
|
|
142
|
+
suggestion, name the concrete next step and the command that enacts it, then
|
|
143
|
+
stop. Editing the ledger, filing an issue, or running `teach` / `onboard` is a
|
|
144
|
+
separate, explicit step the operator chooses. The skill writes nothing to disk
|
|
145
|
+
and mutates no repo — output is the chat conversation only. Read-only: no
|
|
146
|
+
`--apply`, no mutation, no network/LLM call.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
# overview — assemble the `guild overview` skills-supplier evidence pack for
|
|
4
|
+
# narration.
|
|
5
|
+
#
|
|
6
|
+
# The guildmaster agent runs this, then narrates the supplier view (the
|
|
7
|
+
# canonical skill set + versions/origins, the docs/skill-sources.md ledger, and
|
|
8
|
+
# the drift signals that feed `teach` / `onboard`). See SKILL.md.
|
|
9
|
+
# Deterministic glue only: resolve guildmaster's repo root, run from there,
|
|
10
|
+
# resolve how to invoke guild, pick the scope, and delegate to `guild overview`.
|
|
11
|
+
# No interpretation.
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
# overview.sh # whole ledger across the mesh (--scope all)
|
|
15
|
+
# overview.sh <agent> # one agent's kit + gaps (--scope self)
|
|
16
|
+
# overview.sh --scope mesh # live filesystem survey of every agent
|
|
17
|
+
# overview.sh --json # all, JSON evidence
|
|
18
|
+
# overview.sh <agent> --json # one agent, JSON evidence
|
|
19
|
+
#
|
|
20
|
+
# Contract: the FIRST argument, if it does not start with '-', is the agent
|
|
21
|
+
# (self scope). All remaining arguments pass through to `guild overview`.
|
|
22
|
+
#
|
|
23
|
+
# Exit codes:
|
|
24
|
+
# 0 success (delegates to `guild overview`; its exit code propagates)
|
|
25
|
+
# 1 environment error (no way to invoke guild)
|
|
26
|
+
|
|
27
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
28
|
+
|
|
29
|
+
# Resolve guildmaster's repo root and run from there, so `guild overview` always
|
|
30
|
+
# reports guildmaster's canonical set regardless of the caller's working
|
|
31
|
+
# directory (the CLI reads its repo from cwd). Prefer git (robust); fall back to
|
|
32
|
+
# climbing out of the fixed .claude/skills/<name>/scripts/ layout when git is
|
|
33
|
+
# unavailable.
|
|
34
|
+
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || true)"
|
|
35
|
+
if [ -z "$REPO_ROOT" ]; then
|
|
36
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
|
|
37
|
+
fi
|
|
38
|
+
cd "$REPO_ROOT"
|
|
39
|
+
|
|
40
|
+
# Resolve how to invoke guild: installed console script, then uv, then module.
|
|
41
|
+
if command -v guild >/dev/null 2>&1; then
|
|
42
|
+
GUILD=(guild)
|
|
43
|
+
elif [ -f "$REPO_ROOT/pyproject.toml" ] && command -v uv >/dev/null 2>&1; then
|
|
44
|
+
GUILD=(uv run --project "$REPO_ROOT" guild)
|
|
45
|
+
elif command -v python3 >/dev/null 2>&1; then
|
|
46
|
+
GUILD=(python3 -m guild)
|
|
47
|
+
else
|
|
48
|
+
echo "overview: cannot invoke guild (need 'guild', 'uv', or 'python3' on PATH)" >&2
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Honor an explicit --scope passed through (advanced use); otherwise pick one.
|
|
53
|
+
has_scope=false
|
|
54
|
+
for arg in "$@"; do
|
|
55
|
+
case "$arg" in
|
|
56
|
+
--scope | --scope=*)
|
|
57
|
+
has_scope=true
|
|
58
|
+
break
|
|
59
|
+
;;
|
|
60
|
+
esac
|
|
61
|
+
done
|
|
62
|
+
|
|
63
|
+
overview_args=()
|
|
64
|
+
if [ "$#" -gt 0 ] && [[ "$1" != -* ]]; then
|
|
65
|
+
# First arg is an agent → one-agent (self) scope.
|
|
66
|
+
agent="$1"
|
|
67
|
+
shift
|
|
68
|
+
$has_scope || overview_args+=(--scope self)
|
|
69
|
+
overview_args+=("$agent")
|
|
70
|
+
else
|
|
71
|
+
# No leading agent → whole-ledger (all) view.
|
|
72
|
+
$has_scope || overview_args+=(--scope all)
|
|
73
|
+
fi
|
|
74
|
+
overview_args+=("$@")
|
|
75
|
+
|
|
76
|
+
exec "${GUILD[@]}" overview "${overview_args[@]}"
|
|
@@ -5,6 +5,58 @@ 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.4.2] - 2026-05-24
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`guild overview --scope mesh`** — a live filesystem survey of the whole
|
|
13
|
+
workspace, the answer to "what skills does every agent have, and what's
|
|
14
|
+
missing or stale, and where" without waiting for the cutover. Discovers every
|
|
15
|
+
agent (`<workspace>/*/culture.yaml`, via the new `discover_agents` helper) and
|
|
16
|
+
reports, per agent, each canonical skill as **current** / **stale** (the
|
|
17
|
+
agent's copy differs from guildmaster's by content fingerprint —
|
|
18
|
+
`skill_fingerprint`) / **missing**, plus any non-canonical "extra" skills.
|
|
19
|
+
Markdown + `--json`; `--workspace-root DIR` overrides the surveyed root
|
|
20
|
+
(default: the parent of this repo). Read-only, inventory only — no
|
|
21
|
+
dependency/relationship graph (that stays steward's lane). The existing
|
|
22
|
+
ledger-based `--scope all` / `--scope self` are unchanged.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Mesh-survey robustness (Qodo review on #15): `discover_agents` and
|
|
29
|
+
`iter_skills` now skip non-UTF-8 / unreadable `culture.yaml` and `SKILL.md`
|
|
30
|
+
(one bad file in a surveyed repo no longer crashes the run), and
|
|
31
|
+
`skill_fingerprint` skips symlinks (never follows links outside the skill dir;
|
|
32
|
+
keeps the digest deterministic).
|
|
33
|
+
|
|
34
|
+
## [0.4.1] - 2026-05-24
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- **`guild` skill** — the backing affordance + narration skill for `guild
|
|
39
|
+
overview`, the supplier-overview half of the inventory split (sibling to the
|
|
40
|
+
vendored `agent-config` skill that backs `guild show`). `scripts/overview.sh`
|
|
41
|
+
is a deterministic wrapper that resolves how to invoke `guild` (installed →
|
|
42
|
+
`uv` → `python -m guild`) and delegates to `guild overview`; `SKILL.md` is the
|
|
43
|
+
**skills-scoped excerpt of steward's `org-overview` narration contract**
|
|
44
|
+
([#12](https://github.com/agentculture/guildmaster/issues/12),
|
|
45
|
+
cite-don't-import): narrate three separated layers — observed facts, inferred
|
|
46
|
+
relationships, suggestions (each naming its enacting `teach` / `onboard` /
|
|
47
|
+
ledger command), reflect-only. Skills/version scope only — does NOT narrate
|
|
48
|
+
steward's relationship-graph signals (`overlap` / `over-connected-agent` /
|
|
49
|
+
`isolated-repo`). Recorded in `docs/skill-sources.md` as guildmaster-origin
|
|
50
|
+
(not vendored).
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- `SELF_SKILLS` now includes `guild` — guildmaster's own affordance skill is
|
|
55
|
+
excluded from the canonical kit it supplies to siblings (like `teach` /
|
|
56
|
+
`onboard`), since it wraps the `guild` binary and is meaningless elsewhere.
|
|
57
|
+
|
|
58
|
+
### Fixed
|
|
59
|
+
|
|
8
60
|
## [0.4.0] - 2026-05-24
|
|
9
61
|
|
|
10
62
|
### Added
|
|
@@ -113,11 +113,17 @@ owns the mesh's *inventory* surfaces per
|
|
|
113
113
|
**inventory → guildmaster; judgment ("how do agents relate / are they aligned?")
|
|
114
114
|
→ steward.** Neither verb clones `steward overview`'s relationship graph.
|
|
115
115
|
|
|
116
|
-
- `guild overview [--scope all|self <agent
|
|
117
|
-
skill set + versions/origins, the `docs/skill-sources.md` ledger,
|
|
118
|
-
signals (uncovered skills, per-agent kit gaps). Pure-Python,
|
|
119
|
-
`--apply`**. Pre-cutover the ledger has no downstream column,
|
|
120
|
-
inactive and the verb says so (reads
|
|
116
|
+
- `guild overview [--scope all|self <agent>|mesh]` — the supplier view:
|
|
117
|
+
canonical skill set + versions/origins, the `docs/skill-sources.md` ledger,
|
|
118
|
+
and drift signals (uncovered skills, per-agent kit gaps). Pure-Python,
|
|
119
|
+
read-only, **no `--apply`**. Pre-cutover the ledger has no downstream column,
|
|
120
|
+
so `--scope all`/`self` drift is inactive and the verb says so (reads
|
|
121
|
+
whichever ledger is authoritative). `--scope mesh` is the ledger-free
|
|
122
|
+
alternative: it surveys every agent in the workspace
|
|
123
|
+
(`<workspace>/*/culture.yaml`) live off the filesystem and reports, per agent,
|
|
124
|
+
each canonical skill as current / **stale** (content fingerprint differs from
|
|
125
|
+
guildmaster's copy) / **missing** — answering "what's missing or stale, and
|
|
126
|
+
where" today. Still inventory only — no relationship graph.
|
|
121
127
|
- `guild show <path-or-suffix>` — one agent's full config: detected prompt file
|
|
122
128
|
(`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`), parallel `culture.yaml`, and the
|
|
123
129
|
`.claude/skills` index. Thin wrapper that shells out to the vendored
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guild-cli
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
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
|
|
@@ -104,12 +104,13 @@ read-only — no `--apply`, no mutation, no drift verdict (judgment stays with
|
|
|
104
104
|
|
|
105
105
|
| Verb | What it does |
|
|
106
106
|
|------|--------------|
|
|
107
|
-
| `guild overview [--scope all\|self <agent
|
|
107
|
+
| `guild overview [--scope all\|self <agent>\|mesh]` | The supplier view: the canonical skill set + versions/origins, the `docs/skill-sources.md` ledger, and drift signals (uncovered skills, per-agent kit gaps). Feeds `teach` / `onboard`. `--scope mesh` instead surveys every agent's vendored skills live off the filesystem and flags what's **missing**/**stale** per agent. |
|
|
108
108
|
| `guild show <path-or-suffix>` | One agent's full config in one view — its detected prompt file (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`), its parallel `culture.yaml`, and its `.claude/skills` index. |
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
111
|
uv run guild overview # whole ledger + canonical set
|
|
112
112
|
uv run guild overview --scope self daria # one agent's kit + gaps
|
|
113
|
+
uv run guild overview --scope mesh # live survey: every agent's skills + missing/stale
|
|
113
114
|
uv run guild show ../culture # config by path
|
|
114
115
|
uv run guild show daria # config by registered suffix
|
|
115
116
|
uv run guild show ../culture --json # structured config object
|
|
@@ -86,12 +86,13 @@ read-only — no `--apply`, no mutation, no drift verdict (judgment stays with
|
|
|
86
86
|
|
|
87
87
|
| Verb | What it does |
|
|
88
88
|
|------|--------------|
|
|
89
|
-
| `guild overview [--scope all\|self <agent
|
|
89
|
+
| `guild overview [--scope all\|self <agent>\|mesh]` | The supplier view: the canonical skill set + versions/origins, the `docs/skill-sources.md` ledger, and drift signals (uncovered skills, per-agent kit gaps). Feeds `teach` / `onboard`. `--scope mesh` instead surveys every agent's vendored skills live off the filesystem and flags what's **missing**/**stale** per agent. |
|
|
90
90
|
| `guild show <path-or-suffix>` | One agent's full config in one view — its detected prompt file (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`), its parallel `culture.yaml`, and its `.claude/skills` index. |
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
93
|
uv run guild overview # whole ledger + canonical set
|
|
94
94
|
uv run guild overview --scope self daria # one agent's kit + gaps
|
|
95
|
+
uv run guild overview --scope mesh # live survey: every agent's skills + missing/stale
|
|
95
96
|
uv run guild show ../culture # config by path
|
|
96
97
|
uv run guild show daria # config by registered suffix
|
|
97
98
|
uv run guild show ../culture --json # structured config object
|
|
@@ -7,8 +7,8 @@ but it onboards as a consumer first, vendoring the canonical skill set like ever
|
|
|
7
7
|
other sibling before taking over the upstream ledger, the
|
|
8
8
|
`announce-skill-update` broadcast, and skill-version tracking. Until that
|
|
9
9
|
ownership transfers, `steward` holds the live supplier ledger
|
|
10
|
-
(`../steward/docs/skill-sources.md`) and this file records
|
|
11
|
-
itself
|
|
10
|
+
(`../steward/docs/skill-sources.md`) and this file records the skills guildmaster
|
|
11
|
+
vendors plus the few it originates itself.
|
|
12
12
|
|
|
13
13
|
Everything here follows **cite, don't import**: each skill is *copied* into
|
|
14
14
|
`.claude/skills/<name>/`, not symlinked or installed as a cross-repo dependency.
|
|
@@ -67,6 +67,18 @@ and harmless on `claude-code`. This is the only divergence from upstream.
|
|
|
67
67
|
| `spec-to-plan` | `devague` (`agentculture/devague`, `../devague/.claude/skills/spec-to-plan/`) | 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`. |
|
|
68
68
|
| `assign-to-workforce` | `devague` (`agentculture/devague`, `../devague/.claude/skills/assign-to-workforce/`) | 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 the gate-3 `agex pr open`). |
|
|
69
69
|
|
|
70
|
+
## guildmaster-origin skills (origin = `guildmaster`)
|
|
71
|
+
|
|
72
|
+
These are guildmaster's **own** skills — not vendored from anyone, so there is
|
|
73
|
+
no upstream to re-sync from. They are the affordance + narration layer for
|
|
74
|
+
guildmaster's own CLI surfaces: the CLI verb is the implementation, and the
|
|
75
|
+
skill is how the resident agent knows when to reach for it and how to narrate
|
|
76
|
+
the result.
|
|
77
|
+
|
|
78
|
+
| Skill | Origin | Notes |
|
|
79
|
+
|-------|--------|-------|
|
|
80
|
+
| `guild` | `guildmaster` (this repo) | Houses guildmaster's own read-only supplier surfaces. Today: `scripts/overview.sh`, the wrapper backing the pure-Python `guild overview` verb ([#12](https://github.com/agentculture/guildmaster/issues/12)) — the skills-supplier half of the inventory split, sibling to the vendored `agent-config` skill that backs `guild show`. Its `SKILL.md` is the skills-scoped excerpt of steward's `org-overview` narration contract (three layers: facts / inferred / suggestions; reflect-only). Surfaces skills/version drift that feeds `teach` / `onboard`; does NOT narrate steward's relationship graph or judge alignment. |
|
|
81
|
+
|
|
70
82
|
## Vendoring policy
|
|
71
83
|
|
|
72
84
|
- **Cite, don't import.** Skills are copied into this repo, not symlinked or
|
|
@@ -13,23 +13,33 @@ surfaces three things, **skills-scoped only** — it does not reproduce
|
|
|
13
13
|
canonical skills the ledger doesn't track yet. These feed ``teach`` /
|
|
14
14
|
``onboard``.
|
|
15
15
|
|
|
16
|
+
``--scope mesh`` is the live alternative to the ledger: instead of reading
|
|
17
|
+
``docs/skill-sources.md``, it surveys every agent in the workspace
|
|
18
|
+
(``<workspace>/*/culture.yaml``) straight off the filesystem and reports, per
|
|
19
|
+
agent, which canonical skills are present / **stale** (the agent's copy differs
|
|
20
|
+
from guildmaster's canonical copy by content fingerprint) / **missing**. This
|
|
21
|
+
answers "what's missing or stale, and where" without waiting for the cutover —
|
|
22
|
+
still skills-scoped, still no dependency/relationship graph.
|
|
23
|
+
|
|
16
24
|
Read-only: no ``--apply``, no mutation, no network/LLM call. Pre-cutover the
|
|
17
25
|
guildmaster ledger is still a consumer-side view with no "Downstream" column, so
|
|
18
|
-
the supplier ledger is empty;
|
|
19
|
-
canonical set (see ``docs/cutover.md``)
|
|
26
|
+
the supplier ledger is empty; ``--scope all``/``self`` say so plainly and still
|
|
27
|
+
report the canonical set (see ``docs/cutover.md``), while ``--scope mesh`` does
|
|
28
|
+
not depend on the ledger at all.
|
|
20
29
|
"""
|
|
21
30
|
|
|
22
31
|
from __future__ import annotations
|
|
23
32
|
|
|
24
33
|
import argparse
|
|
25
34
|
import json
|
|
35
|
+
from pathlib import Path
|
|
26
36
|
|
|
27
37
|
from guild import __version__
|
|
28
38
|
from guild.cli._commands import _broadcast
|
|
29
39
|
from guild.cli._errors import EXIT_USER_ERROR, GuildError
|
|
30
40
|
from guild.cli._output import emit_result
|
|
31
|
-
from guild.cli._repo import repo_root
|
|
32
|
-
from guild.skills import INBOUND_ORIGINS
|
|
41
|
+
from guild.cli._repo import discover_agents, iter_skills, repo_root, skill_fingerprint
|
|
42
|
+
from guild.skills import INBOUND_ORIGINS, SELF_SKILLS
|
|
33
43
|
from guild.skills import ledger as _ledger
|
|
34
44
|
|
|
35
45
|
LEDGER_PATH = "docs/skill-sources.md"
|
|
@@ -38,24 +48,37 @@ LEDGER_PATH = "docs/skill-sources.md"
|
|
|
38
48
|
def register(sub: argparse._SubParsersAction) -> None:
|
|
39
49
|
parser = sub.add_parser(
|
|
40
50
|
"overview",
|
|
41
|
-
help="Skills-supplier overview: canonical set + ledger + drift
|
|
51
|
+
help="Skills-supplier overview: canonical set + ledger + drift, or a live mesh survey.",
|
|
42
52
|
description=(
|
|
43
53
|
"Report guildmaster's canonical skill set + versions, the "
|
|
44
|
-
"upstream/downstream ledger, and drift signals
|
|
45
|
-
"
|
|
46
|
-
"
|
|
54
|
+
"upstream/downstream ledger, and drift signals (--scope all/self, "
|
|
55
|
+
"from the ledger); or survey every agent's vendored skills live from "
|
|
56
|
+
"the filesystem and flag what's missing or stale per agent (--scope "
|
|
57
|
+
"mesh). Skills-scoped and read-only — no --apply, no mutation, no "
|
|
58
|
+
"dependency/relationship graph (that is steward's lane). For one "
|
|
59
|
+
"agent's full config, use `guild show <agent>`."
|
|
47
60
|
),
|
|
48
61
|
)
|
|
49
62
|
parser.add_argument(
|
|
50
63
|
"--scope",
|
|
51
|
-
choices=("all", "self"),
|
|
64
|
+
choices=("all", "self", "mesh"),
|
|
52
65
|
default="all",
|
|
53
|
-
help=
|
|
66
|
+
help=(
|
|
67
|
+
"all = whole ledger across the mesh (default); self = one agent's "
|
|
68
|
+
"kit + drift (from the ledger); mesh = live filesystem survey of "
|
|
69
|
+
"every agent's skills + missing/stale signals."
|
|
70
|
+
),
|
|
54
71
|
)
|
|
55
72
|
parser.add_argument(
|
|
56
73
|
"agent",
|
|
57
74
|
nargs="?",
|
|
58
|
-
help="Agent name — required with --scope self
|
|
75
|
+
help="Agent name — required with --scope self; ignored with --scope all/mesh.",
|
|
76
|
+
)
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
"--workspace-root",
|
|
79
|
+
type=Path,
|
|
80
|
+
default=None,
|
|
81
|
+
help="Workspace dir to survey for --scope mesh (default: the parent of this repo).",
|
|
59
82
|
)
|
|
60
83
|
parser.add_argument(
|
|
61
84
|
"--json",
|
|
@@ -146,6 +169,57 @@ def _build_self(root, agent: str) -> dict:
|
|
|
146
169
|
}
|
|
147
170
|
|
|
148
171
|
|
|
172
|
+
def _build_mesh(root, workspace_root) -> dict:
|
|
173
|
+
"""Live filesystem survey of every agent's vendored skills + drift.
|
|
174
|
+
|
|
175
|
+
Canonical reference is guildmaster's own supplied set (its ``.claude/skills``
|
|
176
|
+
minus ``SELF_SKILLS``); an agent's copy is **stale** when its content
|
|
177
|
+
fingerprint differs from guildmaster's, **missing** when absent. Inventory
|
|
178
|
+
only — no dependency/relationship graph (that judgment is steward's lane).
|
|
179
|
+
"""
|
|
180
|
+
canonical = [s for s in iter_skills(root) if s.name not in SELF_SKILLS]
|
|
181
|
+
canonical_fp = {s.name: skill_fingerprint(s.path) for s in canonical}
|
|
182
|
+
canonical_names = [s.name for s in canonical]
|
|
183
|
+
|
|
184
|
+
agents_view: list[dict] = []
|
|
185
|
+
for agent in discover_agents(workspace_root):
|
|
186
|
+
by_name = {s.name: s for s in iter_skills(agent.repo_path)}
|
|
187
|
+
per_skill: list[dict] = []
|
|
188
|
+
missing: list[str] = []
|
|
189
|
+
stale: list[str] = []
|
|
190
|
+
for name in canonical_names:
|
|
191
|
+
skill = by_name.get(name)
|
|
192
|
+
if skill is None:
|
|
193
|
+
missing.append(name)
|
|
194
|
+
per_skill.append({"skill": name, "status": "missing", "fingerprint": ""})
|
|
195
|
+
continue
|
|
196
|
+
fingerprint = skill_fingerprint(skill.path)
|
|
197
|
+
status = "current" if fingerprint == canonical_fp[name] else "stale"
|
|
198
|
+
if status == "stale":
|
|
199
|
+
stale.append(name)
|
|
200
|
+
per_skill.append({"skill": name, "status": status, "fingerprint": fingerprint})
|
|
201
|
+
agents_view.append(
|
|
202
|
+
{
|
|
203
|
+
"suffix": agent.suffix,
|
|
204
|
+
"backend": agent.backend,
|
|
205
|
+
"repo": agent.repo_name,
|
|
206
|
+
"skills": sorted(by_name),
|
|
207
|
+
"missing": missing,
|
|
208
|
+
"stale": stale,
|
|
209
|
+
"extra": sorted(n for n in by_name if n not in canonical_fp),
|
|
210
|
+
"per_skill": per_skill,
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
"scope": "mesh",
|
|
216
|
+
"version": __version__,
|
|
217
|
+
"workspace_root": str(workspace_root),
|
|
218
|
+
"canonical_skills": [{"name": n, "fingerprint": canonical_fp[n]} for n in canonical_names],
|
|
219
|
+
"agents": agents_view,
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
|
|
149
223
|
def _names_or(names, empty: str = "none") -> str:
|
|
150
224
|
"""Backtick-join *names*, or *empty* when there are none."""
|
|
151
225
|
return ", ".join(f"`{n}`" for n in names) or empty
|
|
@@ -247,9 +321,74 @@ def _render_self(data: dict) -> str:
|
|
|
247
321
|
return "\n".join(lines)
|
|
248
322
|
|
|
249
323
|
|
|
324
|
+
def _count_or_dash(names) -> str:
|
|
325
|
+
"""The count of *names*, or an em dash when there are none."""
|
|
326
|
+
return str(len(names)) if names else "—"
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def _render_mesh(data: dict) -> str:
|
|
330
|
+
agents = data["agents"]
|
|
331
|
+
canonical = data["canonical_skills"]
|
|
332
|
+
lines = [
|
|
333
|
+
"# guild overview — mesh skill inventory (scope: mesh)",
|
|
334
|
+
"",
|
|
335
|
+
f"guild {data['version']} · workspace: `{data['workspace_root']}` · "
|
|
336
|
+
f"{len(agents)} agent(s) · canonical set: {len(canonical)} skill(s)",
|
|
337
|
+
"",
|
|
338
|
+
]
|
|
339
|
+
if not agents:
|
|
340
|
+
lines += [
|
|
341
|
+
"No agents found — no `*/culture.yaml` under the workspace root. Pass "
|
|
342
|
+
"`--workspace-root DIR` to point at the directory holding the sibling repos.",
|
|
343
|
+
]
|
|
344
|
+
return "\n".join(lines)
|
|
345
|
+
|
|
346
|
+
lines += [
|
|
347
|
+
"## Agents",
|
|
348
|
+
"",
|
|
349
|
+
"| Agent | Backend | Repo | Skills | Missing | Stale |",
|
|
350
|
+
"|-------|---------|------|--------|---------|-------|",
|
|
351
|
+
]
|
|
352
|
+
for a in agents:
|
|
353
|
+
lines.append(
|
|
354
|
+
f"| `{a['suffix']}` | {a['backend'] or '—'} | `{a['repo']}` | "
|
|
355
|
+
f"{len(a['skills'])} | {_count_or_dash(a['missing'])} | "
|
|
356
|
+
f"{_count_or_dash(a['stale'])} |"
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
drifting = [a for a in agents if a["missing"] or a["stale"]]
|
|
360
|
+
lines += ["", "## Missing & stale detail", ""]
|
|
361
|
+
if not drifting:
|
|
362
|
+
lines.append("Every agent's vendored copies match guildmaster's canonical set.")
|
|
363
|
+
else:
|
|
364
|
+
for a in drifting:
|
|
365
|
+
parts = []
|
|
366
|
+
if a["stale"]:
|
|
367
|
+
parts.append("stale " + _names_or(a["stale"]))
|
|
368
|
+
if a["missing"]:
|
|
369
|
+
parts.append("missing " + _names_or(a["missing"]))
|
|
370
|
+
lines.append(f"- `{a['suffix']}` (`{a['repo']}`): " + "; ".join(parts))
|
|
371
|
+
|
|
372
|
+
lines += [
|
|
373
|
+
"",
|
|
374
|
+
"_Canonical = guildmaster's supplied set (its skills minus its own operator "
|
|
375
|
+
"verbs). \"Stale\" = the agent's copy differs from guildmaster's by content "
|
|
376
|
+
'fingerprint; "missing" = the agent lacks a canonical skill. Inventory only — '
|
|
377
|
+
"the dependency/relationship graph is steward's lane._",
|
|
378
|
+
]
|
|
379
|
+
return "\n".join(lines)
|
|
380
|
+
|
|
381
|
+
|
|
250
382
|
def _handle(args: argparse.Namespace) -> int:
|
|
251
383
|
root = repo_root()
|
|
252
384
|
|
|
385
|
+
if args.scope != "self" and args.agent:
|
|
386
|
+
raise GuildError(
|
|
387
|
+
code=EXIT_USER_ERROR,
|
|
388
|
+
message="an agent name is only valid with --scope self",
|
|
389
|
+
remediation="drop the agent, or use `--scope self <agent>`",
|
|
390
|
+
)
|
|
391
|
+
|
|
253
392
|
if args.scope == "self":
|
|
254
393
|
if not args.agent:
|
|
255
394
|
raise GuildError(
|
|
@@ -259,13 +398,11 @@ def _handle(args: argparse.Namespace) -> int:
|
|
|
259
398
|
)
|
|
260
399
|
data = _build_self(root, args.agent)
|
|
261
400
|
rendered = _render_self(data)
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
remediation="drop the agent, or use `--scope self <agent>`",
|
|
268
|
-
)
|
|
401
|
+
elif args.scope == "mesh":
|
|
402
|
+
workspace_root = (args.workspace_root or root.parent).expanduser().resolve()
|
|
403
|
+
data = _build_mesh(root, workspace_root)
|
|
404
|
+
rendered = _render_mesh(data)
|
|
405
|
+
else: # all
|
|
269
406
|
data = _build_all(root)
|
|
270
407
|
rendered = _render_all(data)
|
|
271
408
|
|