agent-easy-framework 0.0.3__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.
- agent_easy_framework-0.0.3/.cursor/rules/skill-orchestrator-gate.mdc +51 -0
- agent_easy_framework-0.0.3/.cursor/skills/adoption-validation/SKILL.md +267 -0
- agent_easy_framework-0.0.3/.cursor/skills/code-smell-review/SKILL.md +201 -0
- agent_easy_framework-0.0.3/.cursor/skills/code-smell-review/examples.md +162 -0
- agent_easy_framework-0.0.3/.cursor/skills/onboarding-validation/SKILL.md +134 -0
- agent_easy_framework-0.0.3/.cursor/skills/skill-orchestrator/SKILL.md +334 -0
- agent_easy_framework-0.0.3/.cursor/skills/skill-orchestrator/pipelines.md +71 -0
- agent_easy_framework-0.0.3/.github/branch-protection.md +17 -0
- agent_easy_framework-0.0.3/.github/scripts/release_publish.sh +67 -0
- agent_easy_framework-0.0.3/.github/workflows/build-deploy.yml +67 -0
- agent_easy_framework-0.0.3/.github/workflows/ci.yml +123 -0
- agent_easy_framework-0.0.3/.gitignore +15 -0
- agent_easy_framework-0.0.3/.pre-commit-config.yaml +42 -0
- agent_easy_framework-0.0.3/GOLDEN_PATH.md +370 -0
- agent_easy_framework-0.0.3/LICENSE +21 -0
- agent_easy_framework-0.0.3/Makefile +83 -0
- agent_easy_framework-0.0.3/PKG-INFO +499 -0
- agent_easy_framework-0.0.3/README.md +461 -0
- agent_easy_framework-0.0.3/config/base.yaml +25 -0
- agent_easy_framework-0.0.3/config/profiles/local-http.yaml +10 -0
- agent_easy_framework-0.0.3/config/profiles/local.yaml +6 -0
- agent_easy_framework-0.0.3/config/profiles/prod.yaml +32 -0
- agent_easy_framework-0.0.3/examples/README.md +125 -0
- agent_easy_framework-0.0.3/examples/call_ping.py +43 -0
- agent_easy_framework-0.0.3/examples/call_ping_http.py +52 -0
- agent_easy_framework-0.0.3/examples/smoke_ops.sh +26 -0
- agent_easy_framework-0.0.3/proto/agent_server.proto +35 -0
- agent_easy_framework-0.0.3/pyproject.toml +85 -0
- agent_easy_framework-0.0.3/src/agent_server/__about__.py +3 -0
- agent_easy_framework-0.0.3/src/agent_server/__init__.py +13 -0
- agent_easy_framework-0.0.3/src/agent_server/__main__.py +8 -0
- agent_easy_framework-0.0.3/src/agent_server/auth/__init__.py +1 -0
- agent_easy_framework-0.0.3/src/agent_server/auth/base.py +67 -0
- agent_easy_framework-0.0.3/src/agent_server/auth/basic.py +95 -0
- agent_easy_framework-0.0.3/src/agent_server/auth/none.py +28 -0
- agent_easy_framework-0.0.3/src/agent_server/auth/oidc.py +114 -0
- agent_easy_framework-0.0.3/src/agent_server/bootstrap.py +32 -0
- agent_easy_framework-0.0.3/src/agent_server/checks/__init__.py +12 -0
- agent_easy_framework-0.0.3/src/agent_server/checks/invariants.py +324 -0
- agent_easy_framework-0.0.3/src/agent_server/cli.py +56 -0
- agent_easy_framework-0.0.3/src/agent_server/config/__init__.py +1 -0
- agent_easy_framework-0.0.3/src/agent_server/config/loader.py +102 -0
- agent_easy_framework-0.0.3/src/agent_server/config/schema.py +61 -0
- agent_easy_framework-0.0.3/src/agent_server/config/secrets/__init__.py +1 -0
- agent_easy_framework-0.0.3/src/agent_server/config/secrets/base.py +53 -0
- agent_easy_framework-0.0.3/src/agent_server/config/secrets/file_provider.py +46 -0
- agent_easy_framework-0.0.3/src/agent_server/core/__init__.py +1 -0
- agent_easy_framework-0.0.3/src/agent_server/core/context.py +54 -0
- agent_easy_framework-0.0.3/src/agent_server/core/registry.py +155 -0
- agent_easy_framework-0.0.3/src/agent_server/core/tools/__init__.py +12 -0
- agent_easy_framework-0.0.3/src/agent_server/core/tools/example.py +28 -0
- agent_easy_framework-0.0.3/src/agent_server/datasources/__init__.py +1 -0
- agent_easy_framework-0.0.3/src/agent_server/datasources/base.py +61 -0
- agent_easy_framework-0.0.3/src/agent_server/datasources/neo4j.py +72 -0
- agent_easy_framework-0.0.3/src/agent_server/datasources/postgres.py +76 -0
- agent_easy_framework-0.0.3/src/agent_server/docs/__init__.py +16 -0
- agent_easy_framework-0.0.3/src/agent_server/docs/server.py +176 -0
- agent_easy_framework-0.0.3/src/agent_server/ops/__init__.py +1 -0
- agent_easy_framework-0.0.3/src/agent_server/ops/app.py +59 -0
- agent_easy_framework-0.0.3/src/agent_server/ops/schemas.py +35 -0
- agent_easy_framework-0.0.3/src/agent_server/py.typed +0 -0
- agent_easy_framework-0.0.3/src/agent_server/runtime.py +39 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/__init__.py +55 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/dispatch.py +28 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/grpc/__init__.py +10 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/grpc/agent_server_pb2.py +45 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/grpc/agent_server_pb2_grpc.py +153 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/grpc/server.py +110 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/http.py +84 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/mcp_app.py +72 -0
- agent_easy_framework-0.0.3/src/agent_server/transports/stdio.py +27 -0
- agent_easy_framework-0.0.3/src/create_agent_server/__about__.py +7 -0
- agent_easy_framework-0.0.3/src/create_agent_server/__init__.py +17 -0
- agent_easy_framework-0.0.3/src/create_agent_server/add_tool.py +167 -0
- agent_easy_framework-0.0.3/src/create_agent_server/cli.py +205 -0
- agent_easy_framework-0.0.3/src/create_agent_server/generator.py +832 -0
- agent_easy_framework-0.0.3/src/create_agent_server/py.typed +0 -0
- agent_easy_framework-0.0.3/src/create_agent_server/template_paths.py +89 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/config/base.yaml +25 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/config/profiles/local-http.yaml +10 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/config/profiles/local.yaml +6 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/config/profiles/prod.yaml +32 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/examples/README.md +125 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/examples/call_ping.py +43 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/examples/call_ping_http.py +52 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/examples/smoke_ops.sh +26 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/gitignore +15 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/pre-commit-config.yaml +42 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/proto/agent_server.proto +35 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/tools/checks/run_checks.py +63 -0
- agent_easy_framework-0.0.3/src/create_agent_server/templates/tools/checks/validate_typing.py +74 -0
- agent_easy_framework-0.0.3/tests/integration/test_generate_and_boot.py +17 -0
- agent_easy_framework-0.0.3/tests/unit/test_add_tool.py +82 -0
- agent_easy_framework-0.0.3/tests/unit/test_auth.py +68 -0
- agent_easy_framework-0.0.3/tests/unit/test_checks.py +111 -0
- agent_easy_framework-0.0.3/tests/unit/test_cli.py +85 -0
- agent_easy_framework-0.0.3/tests/unit/test_datasources.py +186 -0
- agent_easy_framework-0.0.3/tests/unit/test_foundation.py +126 -0
- agent_easy_framework-0.0.3/tests/unit/test_generator.py +108 -0
- agent_easy_framework-0.0.3/tests/unit/test_transports.py +67 -0
- agent_easy_framework-0.0.3/tools/checks/run_checks.py +63 -0
- agent_easy_framework-0.0.3/tools/checks/validate_typing.py +74 -0
- agent_easy_framework-0.0.3/tools/sync_generator_templates.py +48 -0
- agent_easy_framework-0.0.3/tools/verify_generated.py +245 -0
- agent_easy_framework-0.0.3/uv.lock +1366 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >-
|
|
3
|
+
Mandatory completion gate — run skill-orchestrator after every code change
|
|
4
|
+
before marking a task done.
|
|
5
|
+
alwaysApply: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Skill orchestrator completion gate
|
|
9
|
+
|
|
10
|
+
After **any code change** in this repo, follow [skill-orchestrator](../skills/skill-orchestrator/SKILL.md) **before** telling the user the task is done.
|
|
11
|
+
|
|
12
|
+
## Required flow
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
implement → skill-orchestrator → close report (Ready to ship: YES) → then done
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Triggers
|
|
19
|
+
|
|
20
|
+
Run the orchestrator when you edit:
|
|
21
|
+
|
|
22
|
+
- `src/`, `tests/`, `tools/`
|
|
23
|
+
- `*.py`, generator, or templates under `create_agent_server/`
|
|
24
|
+
|
|
25
|
+
If there is no git diff yet, validate the files changed in the session.
|
|
26
|
+
|
|
27
|
+
## Blocks close
|
|
28
|
+
|
|
29
|
+
Do **not** mark the task complete while any of these fail:
|
|
30
|
+
|
|
31
|
+
- code-smell-review (must_fix > 0)
|
|
32
|
+
- onboarding-validation Judge (when onboarding surfaces changed)
|
|
33
|
+
- adoption-validation P0 escalations (when release/adoption pipeline)
|
|
34
|
+
- `make check` or `make test`
|
|
35
|
+
|
|
36
|
+
## Skip (rare)
|
|
37
|
+
|
|
38
|
+
Skip only when:
|
|
39
|
+
|
|
40
|
+
- **Question-only** or read-only work — no files changed
|
|
41
|
+
- User **explicitly** opts out for this task — note `SKIPPED` + reason in close report
|
|
42
|
+
|
|
43
|
+
## Minimum pipeline
|
|
44
|
+
|
|
45
|
+
Most code-only changes → **pipeline A**: smell review → `make check` → `make test`.
|
|
46
|
+
|
|
47
|
+
Docs/generator/examples → **pipeline B**. Pre-release → **pipeline C**. See [pipelines.md](../skills/skill-orchestrator/pipelines.md).
|
|
48
|
+
|
|
49
|
+
## Close report
|
|
50
|
+
|
|
51
|
+
Before saying done, produce the orchestrator close report from the skill with `Ready to ship: YES`.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: adoption-validation
|
|
3
|
+
description: >-
|
|
4
|
+
Docs-only multi-agent adoption test: a critical platform team with no prior
|
|
5
|
+
context tries to scaffold and run an MCP server using only published docs.
|
|
6
|
+
Use before releases, after README/CLI/generator changes, or when validating
|
|
7
|
+
whether real teams can adopt agent-easy. Findings that need fixes must
|
|
8
|
+
escalate through the onboarding-validation skill — never fix from adoption
|
|
9
|
+
reports alone.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Adoption Validation
|
|
13
|
+
|
|
14
|
+
Simulates a **skeptical platform team** adopting `agent-easy` for the first time. Sub-agents get **no conversation context** and **no source access** — only documented entry points. They must scaffold, configure, and invoke tools exactly as a PyPI user would.
|
|
15
|
+
|
|
16
|
+
If they find problems, **do not patch the framework from this skill**. Escalate through [onboarding-validation](../onboarding-validation/SKILL.md) so each issue is proven `GENUINE_UX_CONFUSION`, not team error.
|
|
17
|
+
|
|
18
|
+
## When to Run
|
|
19
|
+
|
|
20
|
+
- Before PyPI release or major doc/CLI changes
|
|
21
|
+
- After changing README quickstart, `agent-easy mcp` flags, or generator output
|
|
22
|
+
- User asks to "test adoption", "can a team use this from docs", or "run the adoption team"
|
|
23
|
+
- After adoption FAIL — only **after** onboarding-validation confirms fixes
|
|
24
|
+
|
|
25
|
+
## Adoption bar
|
|
26
|
+
|
|
27
|
+
The team is **critical and time-poor**. They will bounce if:
|
|
28
|
+
|
|
29
|
+
- Quickstart fails on first copy-paste
|
|
30
|
+
- Docs contradict each other (README vs generated README vs CLI output)
|
|
31
|
+
- They must read `src/` to succeed
|
|
32
|
+
- Surfaces are confused (in-process vs MCP HTTP vs ops REST)
|
|
33
|
+
- Generate-time flags do not match default runtime profile without explanation
|
|
34
|
+
|
|
35
|
+
**Verdict scale:**
|
|
36
|
+
|
|
37
|
+
| Verdict | Meaning |
|
|
38
|
+
|---------|---------|
|
|
39
|
+
| **ADOPT** | Team would standardize on this from docs alone |
|
|
40
|
+
| **ADOPT_WITH_FRICTION** | Works but docs/process need polish (escalate items) |
|
|
41
|
+
| **REJECT** | Team would abandon or fork; block release until resolved |
|
|
42
|
+
|
|
43
|
+
## Roles (all docs-only)
|
|
44
|
+
|
|
45
|
+
| Agent | Persona | Must NOT |
|
|
46
|
+
|-------|---------|----------|
|
|
47
|
+
| **Platform engineer** | Owns the golden path; runs scaffold + setup | Read `src/`, `generator.py`, or prior chat |
|
|
48
|
+
| **Integrator** | Wires MCP clients; runs example flows | Modify framework source |
|
|
49
|
+
| **Adoption critic** | Staff engineer evaluating build vs buy | Soften findings; recommend architecture rewrites |
|
|
50
|
+
|
|
51
|
+
Each agent reports **PASS/FAIL**, exact commands, exact output, and **blockers** with severity (P0/P1/P2).
|
|
52
|
+
|
|
53
|
+
## Allowed documentation
|
|
54
|
+
|
|
55
|
+
Agents may read **only**:
|
|
56
|
+
|
|
57
|
+
| Doc | When |
|
|
58
|
+
|-----|------|
|
|
59
|
+
| `README.md` | Quickstart, flags, journey |
|
|
60
|
+
| `GOLDEN_PATH.md` | Only if README points there or a step fails |
|
|
61
|
+
| Generated `<project>/README.md` | After scaffold |
|
|
62
|
+
| Generated `<project>/examples/README.md` | After scaffold |
|
|
63
|
+
| CLI `--help` output | Flag discovery |
|
|
64
|
+
|
|
65
|
+
**Forbidden:** `src/`, `tests/`, `generator.py`, conversation history, onboarding-validation reports from prior turns (unless orchestrator passes a **minimal** judge verdict for re-test).
|
|
66
|
+
|
|
67
|
+
## Workflow
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Adoption team (parallel, docs-only, no context)
|
|
71
|
+
↓
|
|
72
|
+
Adoption lead synthesizes verdict + findings
|
|
73
|
+
↓
|
|
74
|
+
Any finding that implies a doc/CLI/generator fix?
|
|
75
|
+
NO → close with verdict
|
|
76
|
+
YES → onboarding-validation (Junior → Judge → [Product])
|
|
77
|
+
↓
|
|
78
|
+
Product implements only GENUINE_UX_CONFUSION items
|
|
79
|
+
↓
|
|
80
|
+
Re-run adoption-validation until ADOPT or ADOPT_WITH_FRICTION
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Never skip onboarding-validation for UX fixes suggested by the adoption team.**
|
|
84
|
+
|
|
85
|
+
## Phase 1 — Platform engineer
|
|
86
|
+
|
|
87
|
+
**Prompt pattern (spawn with `Task`, `subagent_type: shell` or `generalPurpose`):**
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
You are a platform engineer on a critical team adopting agent-easy for the first time.
|
|
91
|
+
You have NO prior context and must NOT read source code under src/ or tests/.
|
|
92
|
+
|
|
93
|
+
Read ONLY README.md "Quickstart (no clone)" (and GOLDEN_PATH.md only if README sends you there).
|
|
94
|
+
|
|
95
|
+
Goal: scaffold a minimal MCP server and reach `make example` success.
|
|
96
|
+
|
|
97
|
+
Rules:
|
|
98
|
+
- Use a fresh temp directory (mktemp)
|
|
99
|
+
- Primary command: uvx agent-easy mcp <name> (if not on PyPI, report BLOCKER and use
|
|
100
|
+
uv run agent-easy mcp <name> from repo root ONLY as pre-publish fallback — tag as INFRA)
|
|
101
|
+
- Follow CLI printed next steps, then generated project README
|
|
102
|
+
- Do NOT read src/
|
|
103
|
+
- Report PASS/FAIL, commands, output snippets, P0/P1/P2 blockers, time estimate
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Pass:** `make setup` + `make example` returns pong without source reads.
|
|
107
|
+
|
|
108
|
+
## Phase 2 — Integrator
|
|
109
|
+
|
|
110
|
+
**Input:** Path to generated project from Phase 1 (orchestrator provides).
|
|
111
|
+
|
|
112
|
+
**Prompt pattern:**
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
You are an integrator on the same critical adoption team. NO prior context. NO src/ reads.
|
|
116
|
+
|
|
117
|
+
Read ONLY the generated project's README.md and examples/README.md.
|
|
118
|
+
|
|
119
|
+
Goal: prove documented surfaces work:
|
|
120
|
+
1. In-process: make example (if not already done)
|
|
121
|
+
2. Ops REST: ./examples/smoke_ops.sh (if documented) — only while server running if docs say two terminals
|
|
122
|
+
3. MCP HTTP: make run-http + make example-http — ONLY if project was generated with http transport
|
|
123
|
+
|
|
124
|
+
If stdio-only project: confirm docs do NOT falsely advertise HTTP; note if team expected HTTP from parent README.
|
|
125
|
+
|
|
126
|
+
Report PASS/FAIL per surface, confusion points, P0/P1/P2 blockers.
|
|
127
|
+
Do NOT modify source files.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Pass:** Every surface **documented for that project shape** works or is correctly absent.
|
|
131
|
+
|
|
132
|
+
## Phase 3 — Adoption critic
|
|
133
|
+
|
|
134
|
+
**Input:** Platform + Integrator reports (orchestrator provides).
|
|
135
|
+
|
|
136
|
+
**Prompt pattern:**
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
You are a staff engineer deciding whether your org adopts agent-easy vs FastMCP or an internal template.
|
|
140
|
+
You have NO prior context. You may read README.md, GOLDEN_PATH.md, and the two sub-agent reports only.
|
|
141
|
+
|
|
142
|
+
Deliver:
|
|
143
|
+
- Verdict: ADOPT | ADOPT_WITH_FRICTION | REJECT
|
|
144
|
+
- Top 3 adoption risks (plain language)
|
|
145
|
+
- Each finding: severity P0/P1/P2, classification:
|
|
146
|
+
NEEDS_ONBOARDING_VALIDATION — might require doc/CLI/generator fix
|
|
147
|
+
USER_ERROR — team should have read the doc
|
|
148
|
+
OUT_OF_SCOPE — valid feedback but not this product's promise
|
|
149
|
+
- Explicit: would you approve this as your org's MCP standard today? yes/no and why
|
|
150
|
+
|
|
151
|
+
Do NOT recommend rewriting core architecture to compensate for doc gaps.
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Phase 4 — Adoption lead (orchestrator)
|
|
155
|
+
|
|
156
|
+
Synthesize the three reports:
|
|
157
|
+
|
|
158
|
+
```markdown
|
|
159
|
+
# Adoption Validation Report
|
|
160
|
+
|
|
161
|
+
## Verdict
|
|
162
|
+
ADOPT | ADOPT_WITH_FRICTION | REJECT
|
|
163
|
+
|
|
164
|
+
## Team summary
|
|
165
|
+
[2–3 sentences]
|
|
166
|
+
|
|
167
|
+
## Flow matrix
|
|
168
|
+
| Flow | Platform | Integrator | Notes |
|
|
169
|
+
|------|----------|------------|-------|
|
|
170
|
+
|
|
171
|
+
## Findings
|
|
172
|
+
| ID | Severity | Classification | Finding | Owner |
|
|
173
|
+
|----|----------|----------------|---------|-------|
|
|
174
|
+
|
|
175
|
+
## Escalation to onboarding-validation
|
|
176
|
+
[List only NEEDS_ONBOARDING_VALIDATION items — one line each]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Escalation gate (mandatory)
|
|
180
|
+
|
|
181
|
+
For each finding classified **NEEDS_ONBOARDING_VALIDATION**:
|
|
182
|
+
|
|
183
|
+
1. **Stop** — do not implement from the adoption report alone
|
|
184
|
+
2. **Run** [onboarding-validation](../onboarding-validation/SKILL.md):
|
|
185
|
+
- Junior reproduces the failure with docs only
|
|
186
|
+
- Judge classifies `GENUINE_UX_CONFUSION` vs `USER_ERROR`
|
|
187
|
+
- Product resolves only genuine items
|
|
188
|
+
3. **Re-run adoption-validation** after fixes
|
|
189
|
+
|
|
190
|
+
If Judge marks **USER_ERROR**, update the adoption report to **reject** that finding — the team was wrong, not the product.
|
|
191
|
+
|
|
192
|
+
If Judge marks **GENUINE_UX_CONFUSION**, Product implements, then onboarding-validation judge PASS, then adoption-validation re-run.
|
|
193
|
+
|
|
194
|
+
## Subagent dispatch
|
|
195
|
+
|
|
196
|
+
Use `Task` tool. **Do not pass conversation history** to sub-agents. Pass only:
|
|
197
|
+
|
|
198
|
+
- Allowed doc paths (absolute)
|
|
199
|
+
- Generated project path (after scaffold)
|
|
200
|
+
- Pre-publish note if `uvx` unavailable: `"PyPI not published; platform engineer may use uv run from <repo> as INFRA fallback"`
|
|
201
|
+
|
|
202
|
+
Suggested order:
|
|
203
|
+
|
|
204
|
+
1. Platform engineer — foreground
|
|
205
|
+
2. Integrator — after scaffold path known (foreground; background if long-running server)
|
|
206
|
+
3. Adoption critic — after 1+2 complete
|
|
207
|
+
4. Orchestrator writes report + escalation list
|
|
208
|
+
|
|
209
|
+
For HTTP flows, generate with:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
uvx agent-easy mcp adopt-http-test --transports stdio,http
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Run a **second** integrator pass on that project if parent README advertises HTTP.
|
|
216
|
+
|
|
217
|
+
## Scenarios to cover
|
|
218
|
+
|
|
219
|
+
| Scenario | Generate command | Proves |
|
|
220
|
+
|----------|------------------|--------|
|
|
221
|
+
| Default quickstart | `agent-easy mcp my-service` | README hero path |
|
|
222
|
+
| Production-shaped | `--datasources neo4j --transports stdio,http --auth oidc` | Flagship example + secrets note |
|
|
223
|
+
| HTTP integrator | `--transports stdio,http` | MCP HTTP + ops distinction |
|
|
224
|
+
|
|
225
|
+
Minimum release bar: **default quickstart** scenario reaches **ADOPT** or **ADOPT_WITH_FRICTION** with zero P0 NEEDS_ONBOARDING_VALIDATION items open.
|
|
226
|
+
|
|
227
|
+
## Quality gate after adoption PASS
|
|
228
|
+
|
|
229
|
+
When verdict is ADOPT or ADOPT_WITH_FRICTION and no open escalations:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
make sync-templates # if generator or templates changed during fix loop
|
|
233
|
+
make check
|
|
234
|
+
make test
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Relationship to onboarding-validation
|
|
238
|
+
|
|
239
|
+
| Skill | Question |
|
|
240
|
+
|-------|----------|
|
|
241
|
+
| **adoption-validation** | Would a **critical team** adopt this from docs? |
|
|
242
|
+
| **onboarding-validation** | Can a **junior** copy-paste each integration flow? |
|
|
243
|
+
|
|
244
|
+
Adoption is broader and stricter in tone. Onboarding is the **appeals court** for whether adoption findings deserve product changes.
|
|
245
|
+
|
|
246
|
+
## Related skills
|
|
247
|
+
|
|
248
|
+
- **[skill-orchestrator](../skill-orchestrator/SKILL.md)** — runs adoption last on release pipelines; manages escalation back to onboarding
|
|
249
|
+
|
|
250
|
+
## Anti-patterns
|
|
251
|
+
|
|
252
|
+
- Fixing docs/code directly from adoption critic without Judge confirmation
|
|
253
|
+
- Giving sub-agents repo context or prior chat ("we just changed the CLI…")
|
|
254
|
+
- Letting the team read `src/` when stuck — that hides doc gaps
|
|
255
|
+
- REJECT verdict → rewrite architecture instead of fixing docs/onboarding
|
|
256
|
+
- PASS adoption when `uvx` is documented but PyPI package is missing (tag INFRA P0, verdict at most ADOPT_WITH_FRICTION)
|
|
257
|
+
- Skipping integrator because platform engineer already ran `make example`
|
|
258
|
+
|
|
259
|
+
## Example orchestrator close
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Adoption verdict: ADOPT_WITH_FRICTION
|
|
263
|
+
Escalations: 1 (profile override unclear — NEEDS_ONBOARDING_VALIDATION)
|
|
264
|
+
→ Running onboarding-validation on item #1…
|
|
265
|
+
→ Judge: GENUINE_UX_CONFUSION → Product adds README note → onboarding PASS
|
|
266
|
+
→ Re-run adoption-validation → ADOPT
|
|
267
|
+
```
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-smell-review
|
|
3
|
+
description: >-
|
|
4
|
+
Sub-agent gate that reviews diff hunks for code smells, comment noise,
|
|
5
|
+
over-defensive fallbacks, and assertiveness gaps. Invoked by
|
|
6
|
+
skill-orchestrator after every code change — do not mark work complete
|
|
7
|
+
without orchestrator PASS. Also use when the user asks for a smell review
|
|
8
|
+
directly.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Code Smell Review
|
|
12
|
+
|
|
13
|
+
Structured sub-agent workflow: parent implements → **reviewer sub-agent** inspects **diff hunks only** → parent fixes → repeat until reviewer **PASS**.
|
|
14
|
+
|
|
15
|
+
The reviewer is isolated by design (fresh sub-agent, no conversation history). It reports findings; the parent applies fixes. **Do not mark work complete until the reviewer passes.**
|
|
16
|
+
|
|
17
|
+
## When to Run
|
|
18
|
+
|
|
19
|
+
Run via **[skill-orchestrator](../skill-orchestrator/SKILL.md)** after every code change (default path).
|
|
20
|
+
|
|
21
|
+
Standalone (orchestrator bypass only if user explicitly opts out):
|
|
22
|
+
|
|
23
|
+
- User asks to "review for smells", "check comments", or "run smell gate"
|
|
24
|
+
|
|
25
|
+
## Roles
|
|
26
|
+
|
|
27
|
+
| Agent | Role | Must NOT |
|
|
28
|
+
|-------|------|----------|
|
|
29
|
+
| **Parent** | Implement features, apply reviewer fixes | Skip the gate or dismiss findings without fixing |
|
|
30
|
+
| **Smell reviewer** | Inspect diff hunks, return PASS/FAIL + findings | Edit files, see conversation history, rationalize parent choices |
|
|
31
|
+
|
|
32
|
+
## Workflow
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Parent implements → Smell reviewer (diff hunks) → [Parent fixes if FAIL] → repeat until PASS
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 1. Resolve diff scope
|
|
39
|
+
|
|
40
|
+
Use **diff hunks only** — added/changed/removed lines in the current change set:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git diff HEAD # unstaged + staged vs last commit
|
|
44
|
+
git diff --cached # staged only (if relevant)
|
|
45
|
+
git diff origin/main...HEAD # branch vs base, when preparing a PR
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Pass the reviewer **only the diff output** (or equivalent patch). Do not include conversation rationale, task description, or "why I did this" unless a finding requires one line of file context to identify a symbol.
|
|
49
|
+
|
|
50
|
+
### 2. Launch smell reviewer sub-agent
|
|
51
|
+
|
|
52
|
+
Use `Task` with `subagent_type: generalPurpose`. Prompt must state:
|
|
53
|
+
|
|
54
|
+
- **Read-only** — do not modify files
|
|
55
|
+
- **Input** — the diff hunks only
|
|
56
|
+
- **No bias** — do not assume the change is correct; flag real issues
|
|
57
|
+
- **Output** — structured PASS/FAIL report (template below)
|
|
58
|
+
|
|
59
|
+
Suggested model: mid-tier / fast reviewer model when available.
|
|
60
|
+
|
|
61
|
+
### 3. Parent fixes findings
|
|
62
|
+
|
|
63
|
+
For each `FAIL` finding classified **actionable**:
|
|
64
|
+
|
|
65
|
+
- Fix in a separate pass (rename, delete comment, flatten nesting, remove fallback, etc.)
|
|
66
|
+
- Re-run the reviewer on the **updated diff**
|
|
67
|
+
- Repeat until **PASS**
|
|
68
|
+
|
|
69
|
+
Skip only findings explicitly marked `false_positive` with one-line justification in the reviewer report. Do not bulk-ignore categories.
|
|
70
|
+
|
|
71
|
+
### 4. Close the task
|
|
72
|
+
|
|
73
|
+
After reviewer **PASS**, proceed with tests/lint as usual. The smell gate is a prerequisite to "done", not a substitute for `make check`.
|
|
74
|
+
|
|
75
|
+
## Smell checklist
|
|
76
|
+
|
|
77
|
+
Review **every added/changed hunk** for:
|
|
78
|
+
|
|
79
|
+
### Comments
|
|
80
|
+
|
|
81
|
+
- **Delete**: comments that narrate **what** the next lines do (`# increment counter`, `# return result`)
|
|
82
|
+
- **Delete**: change narration (`# added for ticket X`, `# as requested`, `# TODO: clean up later` with no concrete constraint)
|
|
83
|
+
- **Delete**: section-header comments (`# --- Setup ---`, `# ===== Helpers =====`)
|
|
84
|
+
- **Delete**: comments restating obvious control flow (`# if user exists`, `# loop through items`)
|
|
85
|
+
- **Keep**: non-obvious **why** — hidden constraints, subtle invariants, required workarounds, external API quirks
|
|
86
|
+
- **Keep**: public API docstrings on exported surfaces; inline noise is the primary target
|
|
87
|
+
|
|
88
|
+
**Test:** If deleting the comment loses no information a reader couldn't get from names and structure, flag it.
|
|
89
|
+
|
|
90
|
+
### Naming
|
|
91
|
+
|
|
92
|
+
- Flag identifiers that **require** a comment to understand (`data2`, `temp`, `handle_stuff`)
|
|
93
|
+
- Prefer rename over comment
|
|
94
|
+
|
|
95
|
+
### Complexity
|
|
96
|
+
|
|
97
|
+
- Deep nesting (3+ levels): ternaries, if/else chains, nested switches
|
|
98
|
+
- Functions doing too much (long blocks, multiple unrelated responsibilities)
|
|
99
|
+
- God objects / modules accumulating unrelated helpers
|
|
100
|
+
|
|
101
|
+
### Duplication
|
|
102
|
+
|
|
103
|
+
- Copy-paste with slight variation that should unify
|
|
104
|
+
- Inline logic that duplicates an existing utility in the codebase (note the existing symbol if visible from the hunk's imports/calls)
|
|
105
|
+
|
|
106
|
+
### Over-defensive code
|
|
107
|
+
|
|
108
|
+
- Redundant null/empty checks when types or callers already guarantee the value
|
|
109
|
+
- Excessive try/except that swallows errors or hides bugs
|
|
110
|
+
- Checks-before-use (existence probes) when operating and handling failure is clearer
|
|
111
|
+
|
|
112
|
+
### Assertive over fallbacks
|
|
113
|
+
|
|
114
|
+
- **Flag**: silent fallbacks when a required resource, config, path, or dependency is missing (`get(..., default)`, `or ""`, `if x else fallback_value`, broad except + continue)
|
|
115
|
+
- **Prefer**: assert preconditions, raise explicit errors, fail fast with clear messages
|
|
116
|
+
- **Exception**: user-facing optional features with documented defaults — still flag if the fallback hides misconfiguration
|
|
117
|
+
|
|
118
|
+
### AI slop patterns
|
|
119
|
+
|
|
120
|
+
- One-off helpers used once
|
|
121
|
+
- Unnecessary abstraction layers (wrapper classes, indirection with no second use)
|
|
122
|
+
- Verbose error strings that repeat the function name and obvious context
|
|
123
|
+
- Defensive comments apologizing for the code
|
|
124
|
+
|
|
125
|
+
## Reviewer output template
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
# Code Smell Review
|
|
129
|
+
|
|
130
|
+
**Verdict:** PASS | FAIL
|
|
131
|
+
**Diff scope:** [command used, e.g. git diff HEAD]
|
|
132
|
+
**Hunks reviewed:** N
|
|
133
|
+
|
|
134
|
+
## Findings
|
|
135
|
+
|
|
136
|
+
| # | Severity | Category | Location | Issue | Suggested fix |
|
|
137
|
+
|---|----------|----------|----------|-------|---------------|
|
|
138
|
+
| 1 | must_fix | comments | path:line | narrates obvious loop | delete comment |
|
|
139
|
+
| 2 | must_fix | fallbacks | path:line | `or "default"` hides missing config | raise ValueError with key name |
|
|
140
|
+
|
|
141
|
+
## Summary
|
|
142
|
+
|
|
143
|
+
- must_fix: N
|
|
144
|
+
- suggestion: N
|
|
145
|
+
- false_positive: N (with justification)
|
|
146
|
+
|
|
147
|
+
## Pass criteria
|
|
148
|
+
|
|
149
|
+
PASS only when **must_fix = 0** for the current diff.
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Severity:**
|
|
153
|
+
|
|
154
|
+
| Level | Meaning |
|
|
155
|
+
|-------|---------|
|
|
156
|
+
| `must_fix` | Blocks PASS — parent must fix and re-run |
|
|
157
|
+
| `suggestion` | Does not block PASS; parent may fix or defer explicitly |
|
|
158
|
+
| `false_positive` | Reviewer self-correction with justification |
|
|
159
|
+
|
|
160
|
+
Default: comment noise, fallbacks, and assertiveness gaps are **`must_fix`**, not suggestions.
|
|
161
|
+
|
|
162
|
+
## Subagent dispatch
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
Task(subagent_type: generalPurpose, readonly via prompt)
|
|
166
|
+
|
|
167
|
+
Prompt:
|
|
168
|
+
You are the smell reviewer. Read-only. Do not edit files.
|
|
169
|
+
|
|
170
|
+
Input: the git diff below (hunks only). No conversation context.
|
|
171
|
+
|
|
172
|
+
Apply the checklist in code-smell-review skill:
|
|
173
|
+
- comment noise (what/change/section headers bad; why/docstrings ok)
|
|
174
|
+
- naming, complexity, duplication, over-defensive code
|
|
175
|
+
- assertive over fallbacks (no silent defaults for required things)
|
|
176
|
+
- AI slop patterns
|
|
177
|
+
|
|
178
|
+
Return the structured PASS/FAIL report. Be strict on must_fix items.
|
|
179
|
+
Do not praise the code. Do not explain your process.
|
|
180
|
+
|
|
181
|
+
<DIFF>
|
|
182
|
+
...
|
|
183
|
+
</DIFF>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Re-run after each fix pass with the fresh diff until PASS.
|
|
187
|
+
|
|
188
|
+
## Anti-patterns
|
|
189
|
+
|
|
190
|
+
- Parent skipping the gate because "the change is small"
|
|
191
|
+
- Feeding the reviewer full files instead of diff hunks
|
|
192
|
+
- Including conversation history in the reviewer prompt ( biases toward PASS)
|
|
193
|
+
- Marking work done on FAIL with "user can fix later"
|
|
194
|
+
- Replacing a fallback with an empty string instead of raising
|
|
195
|
+
- Adding comments to explain bad names instead of renaming
|
|
196
|
+
|
|
197
|
+
## Related skills
|
|
198
|
+
|
|
199
|
+
- **[skill-orchestrator](../skill-orchestrator/SKILL.md)** — runs this skill in the correct pipeline order before close
|
|
200
|
+
- **ce-simplify-code** — broader simplification (reuse, efficiency); run smell review first or after, not as a substitute
|
|
201
|
+
- **ce-code-review** — full PR review with security/correctness personas; smell gate is a pre-merge hygiene check on agent-written diffs
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Code Smell Review — Examples
|
|
2
|
+
|
|
3
|
+
Calibration examples for the smell reviewer. **Flag the bad; leave the good alone.**
|
|
4
|
+
|
|
5
|
+
## Comments
|
|
6
|
+
|
|
7
|
+
### Bad — narrates what
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
# Get the user from the database
|
|
11
|
+
user = db.get_user(user_id)
|
|
12
|
+
|
|
13
|
+
# Return early if not found
|
|
14
|
+
if user is None:
|
|
15
|
+
return None
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Fix:** Delete both comments. Names and structure are enough.
|
|
19
|
+
|
|
20
|
+
### Bad — change narration
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
# Added per review feedback — validate port range
|
|
24
|
+
if not 1 <= port <= 65535:
|
|
25
|
+
raise ValueError(f"port out of range: {port}")
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Fix:** Delete the comment. The raise message is sufficient.
|
|
29
|
+
|
|
30
|
+
### Bad — section header
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
# --- HTTP transport setup ---
|
|
34
|
+
|
|
35
|
+
def bind_http_server(host: str, port: int) -> None:
|
|
36
|
+
...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Fix:** Delete the header. Use a function name or module structure instead.
|
|
40
|
+
|
|
41
|
+
### Good — non-obvious why
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
# MCP streamable HTTP requires session id before tool calls (spec 2025-03).
|
|
45
|
+
await client.initialize()
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Keep:** Documents an external constraint not visible from code alone.
|
|
49
|
+
|
|
50
|
+
### Good — public docstring
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
def add_tool(package: str, name: str, *, overwrite: bool = False) -> Path:
|
|
54
|
+
"""Register a new tool module and wire it into the package registry."""
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Keep:** Public API surface; not inline noise.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Assertive over fallbacks
|
|
62
|
+
|
|
63
|
+
### Bad — silent default hides misconfiguration
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
def load_profile(name: str) -> dict:
|
|
67
|
+
path = os.environ.get("AGENT_EASY_PROFILE") or "local"
|
|
68
|
+
...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Fix:** Require explicit config or raise:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
def load_profile(name: str) -> dict:
|
|
75
|
+
path = os.environ["AGENT_EASY_PROFILE"] # or explicit arg with no env fallback
|
|
76
|
+
...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Bad — swallow and continue
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
try:
|
|
83
|
+
registry.register(tool)
|
|
84
|
+
except Exception:
|
|
85
|
+
pass # tool might already exist
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Fix:** Catch the specific exception or check registration state; re-raise or raise a clear error.
|
|
89
|
+
|
|
90
|
+
### OK — documented optional with explicit default
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
def create_server(*, port: int = 8000) -> Server:
|
|
94
|
+
"""Start HTTP MCP on ``port`` (default 8000 for local dev)."""
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Keep:** Default is part of the public contract, not a hidden fallback for missing config.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Complexity & naming
|
|
102
|
+
|
|
103
|
+
### Bad — name forces comment
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
def process(data: list[dict]) -> list[dict]:
|
|
107
|
+
# Filter active items and map to ids
|
|
108
|
+
return [x["id"] for x in data if x.get("active")]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Fix:** Rename and delete comment:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
def active_item_ids(items: list[dict]) -> list[str]:
|
|
115
|
+
return [item["id"] for item in items if item["active"]]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
(Also flags defensive `.get("active")` if `active` is required — use direct access or validate upstream.)
|
|
119
|
+
|
|
120
|
+
### Bad — deep nesting
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
result = (
|
|
124
|
+
fetch_a()
|
|
125
|
+
if cond_a
|
|
126
|
+
else fetch_b()
|
|
127
|
+
if cond_b
|
|
128
|
+
else fetch_c()
|
|
129
|
+
)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Fix:** Early returns or if/elif chain with named intermediate values.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## AI slop
|
|
137
|
+
|
|
138
|
+
### Bad — unnecessary helper
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
def _normalize_name(name: str) -> str:
|
|
142
|
+
return name.strip().lower()
|
|
143
|
+
|
|
144
|
+
def register(name: str) -> None:
|
|
145
|
+
register_impl(_normalize_name(name))
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Fix:** Inline if used once, or move to a shared util if the pattern repeats elsewhere.
|
|
149
|
+
|
|
150
|
+
### Bad — verbose error
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
raise ValueError(
|
|
154
|
+
"register_tool failed because the tool name parameter was invalid or empty"
|
|
155
|
+
)
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Fix:**
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
raise ValueError(f"tool name must be non-empty, got {name!r}")
|
|
162
|
+
```
|