devague 0.12.0__tar.gz → 0.13.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.
- devague-0.13.0/.claude/skills/agent-config/SKILL.md +82 -0
- devague-0.13.0/.claude/skills/agent-config/data/backend-fingerprints.yaml +30 -0
- devague-0.13.0/.claude/skills/agent-config/scripts/show.sh +136 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/assign-to-workforce/SKILL.md +6 -5
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/cicd/SKILL.md +37 -8
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/cicd/scripts/portability-lint.sh +2 -2
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/SKILL.md +4 -4
- devague-0.13.0/.claude/skills/communicate/scripts/templates/skill-new-brief.md +85 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +13 -13
- devague-0.13.0/.claude/skills/pypi-maintainer/SKILL.md +75 -0
- devague-0.13.0/.claude/skills/pypi-maintainer/scripts/switch-source.sh +102 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/spec-to-plan/SKILL.md +5 -4
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/think/SKILL.md +5 -3
- {devague-0.12.0 → devague-0.13.0}/CHANGELOG.md +15 -0
- {devague-0.12.0 → devague-0.13.0}/CLAUDE.md +19 -4
- {devague-0.12.0 → devague-0.13.0}/PKG-INFO +1 -1
- devague-0.13.0/docs/skill-sources.md +74 -0
- {devague-0.12.0 → devague-0.13.0}/docs/skills.md +1 -1
- {devague-0.12.0 → devague-0.13.0}/pyproject.toml +1 -1
- {devague-0.12.0 → devague-0.13.0}/uv.lock +1 -1
- devague-0.12.0/docs/skill-sources.md +0 -55
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/run-tests/SKILL.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/run-tests/scripts/test.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/sonarclaude/SKILL.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/think/scripts/think.sh +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/version-bump/SKILL.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/.claude/skills.local.yaml.example +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/current_plan +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/frames/devague-0-6-0-ships-the-human-review-loop-devague.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/frames/devague-now-ships-a-documented-spec-contract-every.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/frames/devague-turns-a-converged-plan-into-parallel-simpl.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/plans/devague-0-6-0-ships-the-human-review-loop-devague.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/plans/devague-now-ships-a-documented-spec-contract-every.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/.devague/plans/devague-turns-a-converged-plan-into-parallel-simpl.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/.flake8 +0 -0
- {devague-0.12.0 → devague-0.13.0}/.github/workflows/publish.yml +0 -0
- {devague-0.12.0 → devague-0.13.0}/.github/workflows/security-checks.yml +0 -0
- {devague-0.12.0 → devague-0.13.0}/.github/workflows/tests.yml +0 -0
- {devague-0.12.0 → devague-0.13.0}/.gitignore +0 -0
- {devague-0.12.0 → devague-0.13.0}/.markdownlint-cli2.yaml +0 -0
- {devague-0.12.0 → devague-0.13.0}/.pre-commit-config.yaml +0 -0
- {devague-0.12.0 → devague-0.13.0}/LICENSE +0 -0
- {devague-0.12.0 → devague-0.13.0}/README.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/culture.yaml +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/__init__.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/__main__.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/__init__.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/__init__.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/capture.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/confirm.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/converge.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/explain.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/export.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/interrogate.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/learn.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/list_frames.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/new.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/park.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/plan.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/question.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/reject.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/review.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/show.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_commands/status.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_errors.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_frames.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_output.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_paths.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_plans.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/cli/_status.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/convergence.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/frame.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/plan.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/plan_convergence.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/plan_store.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/questions_io.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/render/__init__.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/render/frame_md.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/render/plan_md.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/render/review_md.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/render/spec_md.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/devague/store.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/assign-to-workforce-worked-example.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/examples/contract-example.json +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/llm-guidance.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/plans/2026-05-23-devague-0-6-0-ships-the-human-review-loop-devague.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/plans/2026-05-23-devague-now-ships-a-documented-spec-contract-every.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/plans/2026-05-23-devague-turns-a-converged-plan-into-parallel-simpl.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/reviews/spec-contract-frame-review.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/spec-contract.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/specs/2026-05-23-devague-0-6-0-ships-the-human-review-loop-devague.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/specs/2026-05-23-devague-now-ships-a-documented-spec-contract-every.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/specs/2026-05-23-devague-turns-a-converged-plan-into-parallel-simpl.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/superpowers/plans/2026-05-22-specifix-onboarding.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/superpowers/plans/2026-05-23-devague-rename.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/superpowers/plans/2026-05-23-devague-working-backwards-engine.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/superpowers/specs/2026-05-22-specifix-onboarding-design.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/superpowers/specs/2026-05-23-devague-spec-to-plan-design.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/docs/superpowers/specs/2026-05-23-devague-working-backwards-design.md +0 -0
- {devague-0.12.0 → devague-0.13.0}/sonar-project.properties +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/__init__.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_affordances.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_chassis.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_converge_export.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_errors.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_learn.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_moves.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_output.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_paths.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_plan.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_question.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_review.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_cli_status.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_contract.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_convergence.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_frame.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_offline.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_package.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_plan.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_plan_convergence.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_plan_store.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_render.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_render_plan.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_review_loop_integration.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_review_loop_invariants.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_spec_to_plan_skill.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_store.py +0 -0
- {devague-0.12.0 → devague-0.13.0}/tests/test_think_skill.py +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agent-config
|
|
3
|
+
description: >
|
|
4
|
+
Show a Culture agent's full configuration in one read-only view: its
|
|
5
|
+
system-prompt file (CLAUDE.md / AGENTS.md / GEMINI.md), the parallel
|
|
6
|
+
culture.yaml, and the agent's local .claude/skills index. Use when an
|
|
7
|
+
operator says "show agent <name>", "what does <agent> look like", or before
|
|
8
|
+
teaching/onboarding an agent and you need to see its current kit + config.
|
|
9
|
+
Backs the `guild show` verb. Vendored from steward (cite-don't-import);
|
|
10
|
+
inventory only — it reports, it does not judge alignment or drift.
|
|
11
|
+
type: command
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# agent-config — surface a Culture agent's config in one view
|
|
15
|
+
|
|
16
|
+
guildmaster is the mesh's skills supplier and owns the **inventory** surfaces:
|
|
17
|
+
"what kit + config does this agent have?" This skill answers exactly that for a
|
|
18
|
+
single agent, showing the three artifacts that together define it:
|
|
19
|
+
|
|
20
|
+
1. **System-prompt file** (`CLAUDE.md` / `AGENTS.md` / `GEMINI.md`) — the
|
|
21
|
+
prompt-side guidance for the agent's backend. The script detects which file
|
|
22
|
+
is present from a backend-fingerprint registry.
|
|
23
|
+
2. **`culture.yaml`** — the runtime-side config (`agents:` list with `suffix`,
|
|
24
|
+
`backend`, `model`, `system_prompt`, `channels`, `tags`, `acp_command`,
|
|
25
|
+
`extras`). Lives parallel to the prompt file at the project root.
|
|
26
|
+
3. **`.claude/skills/*/SKILL.md`** — the per-project skills the agent can
|
|
27
|
+
invoke, one line each (name + truncated description).
|
|
28
|
+
|
|
29
|
+
This is the **inventory half** of the steward → guildmaster split
|
|
30
|
+
([issue #12](https://github.com/agentculture/guildmaster/issues/12)): it reports
|
|
31
|
+
the config, it does **not** interpret drift or judge alignment. The relationship
|
|
32
|
+
graph and the "is this agent aligned?" judgment stay with `steward overview` /
|
|
33
|
+
`steward doctor`.
|
|
34
|
+
|
|
35
|
+
## When to use
|
|
36
|
+
|
|
37
|
+
- Before `guild teach` / `guild onboard` — see an agent's current kit + config.
|
|
38
|
+
- When an operator asks "show me agent `<name>`" or "what does `<agent>` run".
|
|
39
|
+
- Read it, don't guess — before answering a question about what an agent does.
|
|
40
|
+
|
|
41
|
+
## How to run
|
|
42
|
+
|
|
43
|
+
One script, two ways to call it (or just run `guild show`, which wraps it):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Path mode — point at any directory with a prompt file + culture.yaml
|
|
47
|
+
.claude/skills/agent-config/scripts/show.sh ../culture
|
|
48
|
+
|
|
49
|
+
# Suffix mode — resolve a registered agent suffix via the Culture server's
|
|
50
|
+
# manifest (location set by culture_server_yaml in skills.local.yaml)
|
|
51
|
+
.claude/skills/agent-config/scripts/show.sh daria
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Output is three sections: the detected system-prompt file, `culture.yaml` (or
|
|
55
|
+
`(missing)`), and a one-line summary per local skill (name + description,
|
|
56
|
+
truncated to 120 chars).
|
|
57
|
+
|
|
58
|
+
## What to look at in `culture.yaml`
|
|
59
|
+
|
|
60
|
+
| Field | Why it matters |
|
|
61
|
+
|-------|----------------|
|
|
62
|
+
| `suffix` | Identifies the agent on the mesh. |
|
|
63
|
+
| `backend` | One of `claude` / `codex` / `copilot` / `acp`. The all-backends rule means a feature in one must land in all four. |
|
|
64
|
+
| `model` | Drift here changes behavior silently. |
|
|
65
|
+
| `system_prompt` | Should not contradict the prompt file. |
|
|
66
|
+
| `channels` | Where the agent listens. |
|
|
67
|
+
| `tags`, `extras`, `acp_command` | Backend-specific. |
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
|
|
71
|
+
- **Read-only.** The script never edits agent files. It reports; it does not
|
|
72
|
+
flag or fix drift — that judgment is steward's lane.
|
|
73
|
+
- **Backend-aware.** Prompt-file detection comes from
|
|
74
|
+
`data/backend-fingerprints.yaml` (the `prompt:` mapping), falling back to the
|
|
75
|
+
built-in `(CLAUDE.md AGENTS.md GEMINI.md)` list if the registry is absent.
|
|
76
|
+
- **Per-machine config.** Suffix mode reads `culture_server_yaml` from
|
|
77
|
+
`.claude/skills.local.yaml` (git-ignored), falling back to
|
|
78
|
+
`.claude/skills.local.yaml.example`.
|
|
79
|
+
- **Vendored from steward** (`agent-config`). guildmaster owns this copy and may
|
|
80
|
+
diverge; re-sync from steward's canonical copy when it changes. Divergences:
|
|
81
|
+
the SKILL.md is reframed for guildmaster's inventory role and adds
|
|
82
|
+
`type: command` for the culture backend's skill loader.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Canonical backend fingerprint registry. Vendored from steward's agent-config
|
|
2
|
+
# skill (cite-don't-import); guildmaster owns this copy. Read by the agent-config
|
|
3
|
+
# show.sh (bash), which `guild show` shells out to. Upstream steward also reads
|
|
4
|
+
# it from a Python detector; guildmaster has no parallel detector, so only the
|
|
5
|
+
# `backends:` prompt mapping below is load-bearing here. Keep that mapping in
|
|
6
|
+
# sync with upstream when re-syncing.
|
|
7
|
+
#
|
|
8
|
+
# `prompt` — the backend's system-prompt filename at the repo root.
|
|
9
|
+
# `steering` — files/dirs distinctive enough to attribute to this backend.
|
|
10
|
+
# `shared_steering` — files/dirs that belong to NO specific backend. A repo
|
|
11
|
+
# declared as any backend may have these without triggering a
|
|
12
|
+
# mismatch. `.agents` is a generic Culture agent-config
|
|
13
|
+
# convention. `.claude/settings.json` and
|
|
14
|
+
# `.claude/settings.local.json` are generic Claude Code
|
|
15
|
+
# (editor/CLI) workspace config files — they appear in any
|
|
16
|
+
# repo that uses Claude Code as the development tool,
|
|
17
|
+
# regardless of the agent backend, so they must never be used
|
|
18
|
+
# to infer the backend or flag a mismatch. The claude backend
|
|
19
|
+
# is identified solely by its `CLAUDE.md` prompt file.
|
|
20
|
+
# `.github/copilot-instructions.md` is generic GitHub Copilot
|
|
21
|
+
# editor/IDE config — any repo may have it regardless of the
|
|
22
|
+
# declared agent backend, so it must not trigger a mismatch.
|
|
23
|
+
backends:
|
|
24
|
+
claude: { prompt: CLAUDE.md, steering: [] }
|
|
25
|
+
codex: { prompt: AGENTS.md, steering: [".codex"] }
|
|
26
|
+
acp: { prompt: AGENTS.md, steering: [".kiro"] }
|
|
27
|
+
copilot: { prompt: AGENTS.md, steering: [] }
|
|
28
|
+
gemini: { prompt: GEMINI.md, steering: [".gemini"] }
|
|
29
|
+
shared_steering: [".agents", ".claude/settings.json", ".claude/settings.local.json", ".github/copilot-instructions.md"]
|
|
30
|
+
prompt_fallback: AGENTS.md
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
# Show a Culture agent's full configuration in one view:
|
|
4
|
+
# the detected system-prompt file (CLAUDE.md / AGENTS.md / GEMINI.md), the
|
|
5
|
+
# parallel culture.yaml, and the .claude/skills/ index.
|
|
6
|
+
#
|
|
7
|
+
# Usage: show.sh <path-or-agent-suffix>
|
|
8
|
+
#
|
|
9
|
+
# Path mode: show.sh ../culture
|
|
10
|
+
# Suffix mode: show.sh daria (resolved via culture_server_yaml in skills.local.yaml)
|
|
11
|
+
#
|
|
12
|
+
# Exit codes:
|
|
13
|
+
# 0 success
|
|
14
|
+
# 1 environment error (missing manifest, missing PyYAML for suffix mode)
|
|
15
|
+
# 2 user error (no target given, unknown suffix, target path doesn't exist)
|
|
16
|
+
|
|
17
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
18
|
+
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
19
|
+
REPO_ROOT="$(cd "$SKILL_DIR/../../.." && pwd)"
|
|
20
|
+
|
|
21
|
+
CFG="$REPO_ROOT/.claude/skills.local.yaml"
|
|
22
|
+
[ -f "$CFG" ] || CFG="$REPO_ROOT/.claude/skills.local.yaml.example"
|
|
23
|
+
|
|
24
|
+
# Read a top-level YAML scalar from CFG. Schema is intentionally tiny:
|
|
25
|
+
# key: value (with optional surrounding quotes / trailing comment)
|
|
26
|
+
# No PyYAML dependency.
|
|
27
|
+
read_cfg() {
|
|
28
|
+
awk -v key="$1" '
|
|
29
|
+
$0 ~ ("^" key ":[[:space:]]*") {
|
|
30
|
+
sub("^" key ":[[:space:]]*", "")
|
|
31
|
+
sub(/[[:space:]]*#.*$/, "")
|
|
32
|
+
sub(/^[[:space:]]+/, ""); sub(/[[:space:]]+$/, "")
|
|
33
|
+
sub(/^["\047]/, ""); sub(/["\047]$/, "")
|
|
34
|
+
print
|
|
35
|
+
exit
|
|
36
|
+
}
|
|
37
|
+
' "$CFG"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
target="${1:-}"
|
|
41
|
+
if [ -z "$target" ]; then
|
|
42
|
+
echo "Usage: $(basename "$0") <path-or-agent-suffix>" >&2
|
|
43
|
+
exit 2
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
if [ -d "$target" ]; then
|
|
47
|
+
DIR="$target"
|
|
48
|
+
else
|
|
49
|
+
SERVER_YAML_RAW="$(read_cfg culture_server_yaml)"
|
|
50
|
+
SERVER_YAML="${SERVER_YAML_RAW/#\~/$HOME}"
|
|
51
|
+
if [ ! -f "$SERVER_YAML" ]; then
|
|
52
|
+
echo "no server manifest at $SERVER_YAML — set culture_server_yaml in $CFG" >&2
|
|
53
|
+
echo "or pass an explicit path instead of suffix '$target'" >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
# Suffix mode parses Culture's server manifest, whose schema is dictated by
|
|
57
|
+
# Culture (not by us) and includes nested mappings — too rich for awk.
|
|
58
|
+
# We use python+PyYAML here, with a friendly install hint if it's missing.
|
|
59
|
+
if ! python3 -c 'import yaml' 2>/dev/null; then
|
|
60
|
+
echo "suffix mode needs Python + PyYAML to parse $SERVER_YAML" >&2
|
|
61
|
+
echo " install: pip install --user pyyaml (or: uv pip install pyyaml)" >&2
|
|
62
|
+
echo " or pass an explicit path instead of suffix '$target'" >&2
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
# Use a dedicated exit code (2) for "unknown suffix" so the steward CLI
|
|
66
|
+
# wrapper can distinguish user errors (typo'd suffix) from env errors
|
|
67
|
+
# (missing manifest / PyYAML).
|
|
68
|
+
if ! DIR=$(python3 - "$SERVER_YAML" "$target" <<'PY'
|
|
69
|
+
import sys, yaml, pathlib
|
|
70
|
+
manifest_path, suffix = sys.argv[1], sys.argv[2]
|
|
71
|
+
m = yaml.safe_load(pathlib.Path(manifest_path).read_text()) or {}
|
|
72
|
+
agents = m.get('agents', {})
|
|
73
|
+
entry = agents.get(suffix)
|
|
74
|
+
if entry is None:
|
|
75
|
+
print(f"no agent registered with suffix {suffix!r} in {manifest_path}", file=sys.stderr)
|
|
76
|
+
sys.exit(2)
|
|
77
|
+
print(entry['directory'] if isinstance(entry, dict) else entry)
|
|
78
|
+
PY
|
|
79
|
+
); then
|
|
80
|
+
exit 2
|
|
81
|
+
fi
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
DIR="${DIR/#\~/$HOME}"
|
|
85
|
+
|
|
86
|
+
# Recognized prompt filenames come from the shared registry (single source
|
|
87
|
+
# of truth with the Python detector). Fall back to the built-in list if the
|
|
88
|
+
# registry isn't present (e.g. skill vendored without the data file).
|
|
89
|
+
REGISTRY="$SKILL_DIR/data/backend-fingerprints.yaml"
|
|
90
|
+
prompt_files=()
|
|
91
|
+
if [ -f "$REGISTRY" ]; then
|
|
92
|
+
while IFS= read -r pf; do
|
|
93
|
+
[ -n "$pf" ] && prompt_files+=("$pf")
|
|
94
|
+
done < <(grep -oE 'prompt:[[:space:]]*[^,}[:space:]]+' "$REGISTRY" | awk '{print $NF}' | sort -u)
|
|
95
|
+
fi
|
|
96
|
+
[ ${#prompt_files[@]} -eq 0 ] && prompt_files=(CLAUDE.md AGENTS.md GEMINI.md)
|
|
97
|
+
|
|
98
|
+
shown=0
|
|
99
|
+
for pf in "${prompt_files[@]}"; do
|
|
100
|
+
if [ -f "$DIR/$pf" ]; then
|
|
101
|
+
echo "=== $DIR/$pf ==="
|
|
102
|
+
cat "$DIR/$pf"
|
|
103
|
+
echo
|
|
104
|
+
shown=1
|
|
105
|
+
fi
|
|
106
|
+
done
|
|
107
|
+
if [ "$shown" -eq 0 ]; then
|
|
108
|
+
echo "=== $DIR (system prompt) ==="
|
|
109
|
+
echo "(no recognized prompt file: ${prompt_files[*]})"
|
|
110
|
+
echo
|
|
111
|
+
fi
|
|
112
|
+
echo "=== $DIR/culture.yaml ==="
|
|
113
|
+
if [ -f "$DIR/culture.yaml" ]; then cat "$DIR/culture.yaml"; else echo "(missing)"; fi
|
|
114
|
+
echo
|
|
115
|
+
echo "=== $DIR/.claude/skills/ ==="
|
|
116
|
+
found=0
|
|
117
|
+
for s in "$DIR"/.claude/skills/*/SKILL.md; do
|
|
118
|
+
[ -f "$s" ] || continue
|
|
119
|
+
found=1
|
|
120
|
+
name=$(awk '/^name:/{print $2; exit}' "$s")
|
|
121
|
+
desc=$(awk '
|
|
122
|
+
/^description:/ {
|
|
123
|
+
sub(/^description:[[:space:]]*/, "")
|
|
124
|
+
buf = $0
|
|
125
|
+
flag = 1
|
|
126
|
+
next
|
|
127
|
+
}
|
|
128
|
+
flag && /^[a-z_-]+:/ { flag = 0 }
|
|
129
|
+
flag { buf = buf " " $0 }
|
|
130
|
+
END { gsub(/^[[:space:]]+|[[:space:]]+$/, "", buf); print buf }
|
|
131
|
+
' "$s")
|
|
132
|
+
printf " %-30s %s\n" "$name" "${desc:0:120}"
|
|
133
|
+
done
|
|
134
|
+
if [ "$found" -eq 0 ]; then
|
|
135
|
+
echo " (no skills)"
|
|
136
|
+
fi
|
|
@@ -10,8 +10,9 @@ description: >
|
|
|
10
10
|
performs the fan-out. Use when the user says "assign to workforce",
|
|
11
11
|
"fan out the plan", "parallel subagents", or after /spec-to-plan exports a
|
|
12
12
|
plan. Authored and maintained in agentculture/devague (origin = devague);
|
|
13
|
-
|
|
14
|
-
mesh — it is NOT vendored from
|
|
13
|
+
guildmaster pulls this skill from here and broadcasts it to the AgentCulture
|
|
14
|
+
mesh — it is NOT vendored from guildmaster like the other skills here.
|
|
15
|
+
type: command
|
|
15
16
|
---
|
|
16
17
|
|
|
17
18
|
# assign-to-workforce — fan out a converged plan's waves to parallel agents
|
|
@@ -235,7 +236,7 @@ This is a **first-party** skill — its origin is `agentculture/devague`, where
|
|
|
235
236
|
the devague agent maintains it alongside the tools it operates (dogfooding),
|
|
236
237
|
next to its siblings `/think` and `/spec-to-plan`. It is the *third* skill in
|
|
237
238
|
that outbound family, covering the implementation leg after a plan converges.
|
|
238
|
-
The flow runs the *opposite* direction of the vendored
|
|
239
|
-
pulls this **from** devague and broadcasts it to the rest of the
|
|
240
|
-
mesh. The `cite, don't import` policy still holds: downstream repos copy it,
|
|
239
|
+
The flow runs the *opposite* direction of the vendored guildmaster skills:
|
|
240
|
+
guildmaster pulls this **from** devague and broadcasts it to the rest of the
|
|
241
|
+
AgentCulture mesh. The `cite, don't import` policy still holds: downstream repos copy it,
|
|
241
242
|
they don't symlink or depend on it. See `docs/skill-sources.md`.
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cicd
|
|
3
3
|
description: >
|
|
4
|
-
|
|
5
|
-
read / reply / delta to agex; adds two
|
|
4
|
+
guildmaster's CI/CD lane, layered on `agex pr`. Delegates lint / open /
|
|
5
|
+
read / reply / delta to agex; adds two extensions — `status`
|
|
6
6
|
(SonarCloud quality gate + hotspots + unresolved-thread tally) and
|
|
7
7
|
`await` (read --wait + status with non-zero exit on Sonar ERROR or
|
|
8
|
-
unresolved threads). Use when: creating PRs in
|
|
8
|
+
unresolved threads). Use when: creating PRs in guildmaster, handling
|
|
9
9
|
review feedback, polling CI status, or the user says "create PR",
|
|
10
10
|
"review comments", "address feedback", "resolve threads". Renamed
|
|
11
11
|
from `pr-review` in steward 0.7.0; rebased on agex in 0.12.0.
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
# CI/CD —
|
|
14
|
+
# CI/CD — guildmaster edition
|
|
15
15
|
|
|
16
16
|
`agex pr` (in `agentculture/agex-cli`) is the upstream for the
|
|
17
17
|
five core PR-lifecycle verbs — `lint`, `open`, `read`, `reply`,
|
|
@@ -25,14 +25,43 @@ What's left in this skill is **the steward-specific gating layer**:
|
|
|
25
25
|
Sonar `ERROR` / unresolved threads. The single command to run after
|
|
26
26
|
pushing a fix when you want "wake me when this PR is triage-able."
|
|
27
27
|
|
|
28
|
-
Those two are the steward unique surface today.
|
|
29
|
-
|
|
30
|
-
([agex-cli#41](https://github.com/agentculture/agex-cli/issues/41)
|
|
31
|
-
|
|
28
|
+
Those two are the steward unique surface today. The `await` combo verb
|
|
29
|
+
landed natively in agex
|
|
30
|
+
([agex-cli#41](https://github.com/agentculture/agex-cli/issues/41), now
|
|
31
|
+
closed); the gate extras that aren't yet native — SonarCloud hotspots,
|
|
32
|
+
deploy-preview URL, an explicit resolved/unresolved thread tally — are
|
|
33
|
+
tracked upstream in
|
|
34
|
+
[agex-cli#52](https://github.com/agentculture/agex-cli/issues/52) and
|
|
35
|
+
migrate out of this skill once they land.
|
|
32
36
|
|
|
33
37
|
The workflow is encapsulated in `scripts/workflow.sh` — follow that
|
|
34
38
|
(or call `agex pr` directly).
|
|
35
39
|
|
|
40
|
+
## The agex-cli inversion (upstream-as-consumer)
|
|
41
|
+
|
|
42
|
+
One consumer is special: **agex-cli itself**, the repo that owns `agex pr`.
|
|
43
|
+
Vendoring this skill there verbatim would re-vendor bash that just wraps the
|
|
44
|
+
Python agex-cli already ships, so agex-cli vendors it **adapted-thin**
|
|
45
|
+
([agex-cli#53](https://github.com/agentculture/agex-cli/pull/53)):
|
|
46
|
+
`workflow.sh` is the only script and it forwards
|
|
47
|
+
`lint | open | read | reply | delta | await` straight to the native
|
|
48
|
+
`agex pr <verb>` — including the native `agex pr await` combo verb (agex-cli
|
|
49
|
+
0.21.0). The steward `status` / `await` shell extensions and the vendored
|
|
50
|
+
helpers (`pr-reply.sh`, `_resolve-nick.sh`, `portability-lint.sh`) are all
|
|
51
|
+
redundant there, each superseded by a native verb. For that one consumer the
|
|
52
|
+
skill collapses to a **pure delegate**.
|
|
53
|
+
|
|
54
|
+
The only gate bits not yet native are SonarCloud **hotspots**, the
|
|
55
|
+
**deploy-preview URL**, and an explicit **resolved/unresolved thread tally** —
|
|
56
|
+
tracked upstream in
|
|
57
|
+
[agex-cli#52](https://github.com/agentculture/agex-cli/issues/52). Once those
|
|
58
|
+
land, steward retires `pr-status.sh` too and `workflow.sh status/await`
|
|
59
|
+
delegates to native `agex pr` everywhere.
|
|
60
|
+
|
|
61
|
+
**For broadcasts:** a skill-update brief to agex-cli should expect this thin
|
|
62
|
+
`workflow.sh`-only shape, not steward's five-file layout. (Ref:
|
|
63
|
+
[steward#53](https://github.com/agentculture/steward/issues/53).)
|
|
64
|
+
|
|
36
65
|
## Prerequisites
|
|
37
66
|
|
|
38
67
|
Hard requirements: `agex` (>=0.1), `gh` (GitHub CLI), `jq`, `bash`,
|
|
@@ -22,7 +22,7 @@ esac
|
|
|
22
22
|
|
|
23
23
|
# ----- Check 1: hard-coded /home/<user>/... paths -----
|
|
24
24
|
# devague-divergence: drop GNU-only `xargs -r` (fails on BSD/macOS); `$files`
|
|
25
|
-
# is already guarded non-empty above. Upstream to
|
|
25
|
+
# is already guarded non-empty above. Upstream to guildmaster; remove on re-vendor.
|
|
26
26
|
hits1=$(echo "$files" | xargs grep -nE '/home/[a-z][a-z0-9_-]+/' 2>/dev/null || true)
|
|
27
27
|
|
|
28
28
|
# ----- Check 2: per-user dotfile *config* refs in committed docs/configs -----
|
|
@@ -32,7 +32,7 @@ hits1=$(echo "$files" | xargs grep -nE '/home/[a-z][a-z0-9_-]+/' 2>/dev/null ||
|
|
|
32
32
|
md_yaml=$(echo "$files" | grep -E '\.(md|ya?ml|toml|json|jsonc)$' || true)
|
|
33
33
|
if [ -n "$md_yaml" ]; then
|
|
34
34
|
# devague-divergence: drop GNU-only `xargs -r` (see Check 1); `$md_yaml`
|
|
35
|
-
# is guarded non-empty by the `if` above. Upstream to
|
|
35
|
+
# is guarded non-empty by the `if` above. Upstream to guildmaster.
|
|
36
36
|
hits2=$(echo "$md_yaml" | xargs grep -nE '~/\.[A-Za-z]' 2>/dev/null \
|
|
37
37
|
| grep -vE '~/\.claude/skills/[^[:space:]"]+/scripts/' \
|
|
38
38
|
| grep -vE '~/\.culture/' \
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: communicate
|
|
3
3
|
description: >
|
|
4
|
-
Cross-repo + mesh communication from
|
|
4
|
+
Cross-repo + mesh communication from guildmaster: file tracked GitHub issues
|
|
5
5
|
on sibling repos, fetch issues from sibling repos to inline current state
|
|
6
6
|
into briefs, and send live messages to Culture mesh channels. Use when
|
|
7
|
-
the next step lives outside
|
|
7
|
+
the next step lives outside guildmaster (a brief for a sibling-repo agent, a
|
|
8
8
|
status ping for a Culture channel, or pulling an issue body + comments
|
|
9
|
-
into context). Issue posts auto-sign with `-
|
|
10
|
-
messages are unsigned (the IRC nick is the speaker). Not for in-
|
|
9
|
+
into context). Issue posts auto-sign with `- guildmaster (Claude)`; mesh
|
|
10
|
+
messages are unsigned (the IRC nick is the speaker). Not for in-guildmaster
|
|
11
11
|
issues — use `gh issue create` or the `cicd` skill for those. Renamed
|
|
12
12
|
from `coordinate` in steward 0.8.0; absorbed `gh-issues` in 0.9.1.
|
|
13
13
|
Issue I/O is backed by `agtag` (>=0.1) starting in 0.11.0.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD041 -->
|
|
2
|
+
<!-- This file is the NEW-SKILL template rendered by announce-skill-update -->
|
|
3
|
+
<!-- when --new is passed. It posts as an issue body where GitHub supplies -->
|
|
4
|
+
<!-- the title, so there's no H1 here on purpose. Placeholders use the -->
|
|
5
|
+
<!-- `{{NAME}}` syntax; {{ORIGIN_BLOCK}} is empty unless --origin is given. -->
|
|
6
|
+
|
|
7
|
+
## A new skill is available to vendor
|
|
8
|
+
|
|
9
|
+
`{{SKILL}}` is a **new** skill in the AgentCulture mesh. Your repo does
|
|
10
|
+
not have it yet — this brief tells you how to **add it fresh** (there is no
|
|
11
|
+
older vendored copy to replace). If you maintain a `docs/skill-sources.md`
|
|
12
|
+
provenance ledger, add a row for it; if not, just drop it into
|
|
13
|
+
`.claude/skills/`.
|
|
14
|
+
|
|
15
|
+
{{ORIGIN_BLOCK}}
|
|
16
|
+
|
|
17
|
+
Relevant guildmaster CHANGELOG entries (where guildmaster picked the skill up):
|
|
18
|
+
|
|
19
|
+
{{CHANGELOG_BLOCK}}
|
|
20
|
+
|
|
21
|
+
## Cite locations (source of truth)
|
|
22
|
+
|
|
23
|
+
- Local sibling checkout (preferred when available):
|
|
24
|
+
`../guildmaster/.claude/skills/{{SKILL}}/`
|
|
25
|
+
- Remote, if the workspace doesn't include a local guildmaster checkout:
|
|
26
|
+
<https://github.com/agentculture/guildmaster/tree/main/.claude/skills/{{SKILL}}>
|
|
27
|
+
|
|
28
|
+
guildmaster re-broadcasts this skill to the mesh, so its copy is the citation
|
|
29
|
+
point even when the skill originates in another sibling (see origin note
|
|
30
|
+
above, if present). The directory ships a `SKILL.md` and a `scripts/`
|
|
31
|
+
directory per the AgentCulture skills-portability rule (each skill is
|
|
32
|
+
self-contained; nothing reaches across skill boundaries at runtime).
|
|
33
|
+
|
|
34
|
+
## What's in the upstream now
|
|
35
|
+
|
|
36
|
+
`{{SKILL}}/scripts/` ({{UPSTREAM_SCRIPT_COUNT}} files):
|
|
37
|
+
|
|
38
|
+
{{UPSTREAM_SCRIPT_LIST}}
|
|
39
|
+
|
|
40
|
+
{{DELTA_BLOCK}}
|
|
41
|
+
|
|
42
|
+
{{NOTE_BLOCK}}
|
|
43
|
+
|
|
44
|
+
## What to do
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 0. Branch.
|
|
48
|
+
git checkout -b skill/{{SKILL}}-add
|
|
49
|
+
|
|
50
|
+
# 1. Add the skill fresh from upstream (no existing copy to remove).
|
|
51
|
+
cp -R ../guildmaster/.claude/skills/{{SKILL}} .claude/skills/
|
|
52
|
+
chmod +x .claude/skills/{{SKILL}}/scripts/*.sh 2>/dev/null || true
|
|
53
|
+
|
|
54
|
+
# 2. If you keep docs/skill-sources.md, add a row pointing at
|
|
55
|
+
# ../guildmaster/.claude/skills/{{SKILL}}/ (record any local divergence).
|
|
56
|
+
|
|
57
|
+
# 3. Bump version per project convention (CI version-check enforces in
|
|
58
|
+
# AgentCulture siblings); add a CHANGELOG entry.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Acceptance criteria
|
|
62
|
+
|
|
63
|
+
- `.claude/skills/{{SKILL}}/SKILL.md` is present with frontmatter
|
|
64
|
+
`name: {{SKILL}}`. **On the culture/agex backend, also add
|
|
65
|
+
`type: command`** — `core.skill_loader` requires all of `name`,
|
|
66
|
+
`description`, and `type:`, and a SKILL.md lacking `type:` is silently
|
|
67
|
+
skipped by `backends/claude_code/probe.py`.
|
|
68
|
+
- `.claude/skills/{{SKILL}}/scripts/` contains the
|
|
69
|
+
{{UPSTREAM_SCRIPT_COUNT}} files listed above (and only those, unless your
|
|
70
|
+
repo intentionally adds extras — record divergence in the SKILL.md
|
|
71
|
+
frontmatter `description` per the AgentCulture vendoring policy).
|
|
72
|
+
- All scripts are executable (`chmod +x`).
|
|
73
|
+
- If you keep a `docs/skill-sources.md`, it lists `{{SKILL}}` with the
|
|
74
|
+
upstream `../guildmaster/.claude/skills/{{SKILL}}/`.
|
|
75
|
+
- `CHANGELOG.md` has a new version entry describing the addition; the
|
|
76
|
+
version is bumped per project convention; CI's `version-check` job is green.
|
|
77
|
+
|
|
78
|
+
## References
|
|
79
|
+
|
|
80
|
+
- guildmaster CHANGELOG (release-by-release deltas):
|
|
81
|
+
<https://github.com/agentculture/guildmaster/blob/main/CHANGELOG.md>
|
|
82
|
+
- `{{SKILL}}` SKILL.md:
|
|
83
|
+
<https://github.com/agentculture/guildmaster/blob/main/.claude/skills/{{SKILL}}/SKILL.md>
|
|
84
|
+
- AgentCulture skills-portability rule (each vendor owns and may adapt its
|
|
85
|
+
copy): the `communicate` SKILL.md "Conventions in use" section.
|
{devague-0.12.0 → devague-0.13.0}/.claude/skills/communicate/scripts/templates/skill-update-brief.md
RENAMED
|
@@ -7,17 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
Your repo's `.claude/skills/{{SKILL}}/` (or its older vendored
|
|
9
9
|
name — see your `docs/skill-sources.md` if you keep a provenance
|
|
10
|
-
ledger) is a vendored copy of the
|
|
11
|
-
moved on. Relevant CHANGELOG entries from
|
|
10
|
+
ledger) is a vendored copy of the guildmaster skill that has since
|
|
11
|
+
moved on. Relevant CHANGELOG entries from guildmaster:
|
|
12
12
|
|
|
13
13
|
{{CHANGELOG_BLOCK}}
|
|
14
14
|
|
|
15
15
|
## Cite locations (source of truth)
|
|
16
16
|
|
|
17
17
|
- Local sibling checkout (preferred when available):
|
|
18
|
-
`../
|
|
19
|
-
- Remote, if the workspace doesn't include a local
|
|
20
|
-
<https://github.com/agentculture/
|
|
18
|
+
`../guildmaster/.claude/skills/{{SKILL}}/`
|
|
19
|
+
- Remote, if the workspace doesn't include a local guildmaster checkout:
|
|
20
|
+
<https://github.com/agentculture/guildmaster/tree/main/.claude/skills/{{SKILL}}>
|
|
21
21
|
|
|
22
22
|
The directory ships with a `SKILL.md` and a `scripts/` directory
|
|
23
23
|
per the AgentCulture skills-portability rule (each skill is
|
|
@@ -44,14 +44,14 @@ git checkout -b skill/{{SKILL}}-resync
|
|
|
44
44
|
# If your old vendored name differs (e.g. pr-review → cicd),
|
|
45
45
|
# `git rm` the old dir first.
|
|
46
46
|
git rm -r .claude/skills/<old-name-if-different> # skip if name is already {{SKILL}}
|
|
47
|
-
cp -R ../
|
|
47
|
+
cp -R ../guildmaster/.claude/skills/{{SKILL}} .claude/skills/
|
|
48
48
|
chmod +x .claude/skills/{{SKILL}}/scripts/*.sh 2>/dev/null || true
|
|
49
49
|
|
|
50
50
|
# 2. Adapt identifiers per the existing "identifier-only adapted"
|
|
51
51
|
# pattern in your docs/skill-sources.md (if you keep one):
|
|
52
|
-
# - SKILL.md prose framing: replace "
|
|
52
|
+
# - SKILL.md prose framing: replace "guildmaster" with your repo
|
|
53
53
|
# name where it identifies the consumer (NOT where it cites
|
|
54
|
-
#
|
|
54
|
+
# guildmaster as the upstream).
|
|
55
55
|
# - For any script that hard-codes a signature literal, change it
|
|
56
56
|
# to `- <your-repo> (Claude)`. (The communicate skill no longer
|
|
57
57
|
# hard-codes one — agtag resolves the nick from your local
|
|
@@ -80,9 +80,9 @@ grep -rn '<old-name-if-different>' .claude docs CLAUDE.md README.md 2>/dev/null
|
|
|
80
80
|
AgentCulture vendoring policy).
|
|
81
81
|
- All scripts are executable (`chmod +x`).
|
|
82
82
|
- If the skill hard-codes a signature literal anywhere, your
|
|
83
|
-
vendored copy uses your repo's signature, not `-
|
|
83
|
+
vendored copy uses your repo's signature, not `- guildmaster (Claude)`.
|
|
84
84
|
- If you keep a `docs/skill-sources.md`, it lists `{{SKILL}}` with
|
|
85
|
-
the upstream `../
|
|
85
|
+
the upstream `../guildmaster/.claude/skills/{{SKILL}}/`; no row
|
|
86
86
|
remains for the old vendored name.
|
|
87
87
|
- `grep -rn '<old-name-if-different>' .claude docs CLAUDE.md README.md`
|
|
88
88
|
returns zero hits, or only historical mentions in CHANGELOG.
|
|
@@ -92,10 +92,10 @@ grep -rn '<old-name-if-different>' .claude docs CLAUDE.md README.md 2>/dev/null
|
|
|
92
92
|
|
|
93
93
|
## References
|
|
94
94
|
|
|
95
|
-
-
|
|
96
|
-
<https://github.com/agentculture/
|
|
95
|
+
- guildmaster CHANGELOG (release-by-release deltas):
|
|
96
|
+
<https://github.com/agentculture/guildmaster/blob/main/CHANGELOG.md>
|
|
97
97
|
- `{{SKILL}}` SKILL.md:
|
|
98
|
-
<https://github.com/agentculture/
|
|
98
|
+
<https://github.com/agentculture/guildmaster/blob/main/.claude/skills/{{SKILL}}/SKILL.md>
|
|
99
99
|
- AgentCulture skills-portability rule (why each vendor adapts
|
|
100
100
|
signature literals locally): the `communicate` SKILL.md
|
|
101
101
|
"Per-channel signature rules" + "Conventions in use" sections.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pypi-maintainer
|
|
3
|
+
description: >
|
|
4
|
+
Switch a PyPI package install between the production index, TestPyPI
|
|
5
|
+
pre-release builds, and a local editable checkout. Use when an agent
|
|
6
|
+
maintains a package and needs to verify a TestPyPI dev build before
|
|
7
|
+
promoting to production, or when the user says "install from
|
|
8
|
+
test-pypi", "switch to local", "change package source", or
|
|
9
|
+
"install from pypi".
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# PyPI Maintainer
|
|
13
|
+
|
|
14
|
+
Switch the install source for a package the agent maintains. Three sources
|
|
15
|
+
are supported: production PyPI, TestPyPI (pre-release / dev builds), and a
|
|
16
|
+
local editable checkout. The same script works for any package an
|
|
17
|
+
AgentCulture sibling publishes — pass the package name as the first
|
|
18
|
+
argument.
|
|
19
|
+
|
|
20
|
+
## When to use
|
|
21
|
+
|
|
22
|
+
- Verifying a PR's TestPyPI dev build before merging.
|
|
23
|
+
- Reproducing a user-reported bug against the published version.
|
|
24
|
+
- Hot-patching against a local checkout while a fix is in flight.
|
|
25
|
+
- Restoring the production install after local-mode debugging.
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Production PyPI
|
|
31
|
+
bash .claude/skills/pypi-maintainer/scripts/switch-source.sh <package> pypi
|
|
32
|
+
|
|
33
|
+
# TestPyPI (pre-release dev builds)
|
|
34
|
+
bash .claude/skills/pypi-maintainer/scripts/switch-source.sh <package> test-pypi
|
|
35
|
+
|
|
36
|
+
# TestPyPI, pinned to a specific dev version
|
|
37
|
+
bash .claude/skills/pypi-maintainer/scripts/switch-source.sh <package> test-pypi --version 0.4.0.dev42
|
|
38
|
+
|
|
39
|
+
# Local editable checkout (defaults to current directory)
|
|
40
|
+
bash .claude/skills/pypi-maintainer/scripts/switch-source.sh <package> local
|
|
41
|
+
|
|
42
|
+
# Local editable from an explicit path
|
|
43
|
+
bash .claude/skills/pypi-maintainer/scripts/switch-source.sh <package> local --path ../<package>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Prerequisites
|
|
47
|
+
|
|
48
|
+
The script requires the following tools on `PATH`:
|
|
49
|
+
|
|
50
|
+
- `bash`
|
|
51
|
+
- `uv` — the script delegates to `uv tool install` and `uv tool list`
|
|
52
|
+
(or `uv pip install` for `local`).
|
|
53
|
+
|
|
54
|
+
## Why TestPyPI needs special flags
|
|
55
|
+
|
|
56
|
+
When a package is published to **both** PyPI and TestPyPI, `uv tool install`
|
|
57
|
+
finds the production version on PyPI first and never looks at TestPyPI.
|
|
58
|
+
The script passes `--index-strategy unsafe-best-match` so uv compares the
|
|
59
|
+
two index sets and picks the highest version, plus `--prerelease=allow`
|
|
60
|
+
because TestPyPI builds carry dev suffixes (e.g. `0.4.0.dev42`).
|
|
61
|
+
|
|
62
|
+
## After running
|
|
63
|
+
|
|
64
|
+
The script prints the resolved version once install completes — cross-check
|
|
65
|
+
that against the expected version (PR run number, local `pyproject.toml`)
|
|
66
|
+
before continuing.
|
|
67
|
+
|
|
68
|
+
## Arguments
|
|
69
|
+
|
|
70
|
+
| Position / flag | Meaning |
|
|
71
|
+
|-----------------|---------|
|
|
72
|
+
| `<package>` (required) | The PyPI distribution name, e.g. `steward-cli`, `culture`, `daria-cli`. |
|
|
73
|
+
| `<source>` (required) | One of `pypi`, `test-pypi`, `local`. |
|
|
74
|
+
| `--version VERSION` | Pin to a specific version (TestPyPI builds typically need this). |
|
|
75
|
+
| `--path PATH` | Local-source-only: path to the editable checkout (default: cwd). |
|