wizz-method 2.13.0 → 2.14.0
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.
- package/THIRD-PARTY-NOTICES.md +2 -0
- package/package.json +10 -3
- package/skills-registry.yaml +28 -23
- package/src/bmm-skills/1-analysis/research/wizz-domain-research/customize.toml +4 -3
- package/src/bmm-skills/1-analysis/research/wizz-market-research/customize.toml +4 -3
- package/src/bmm-skills/1-analysis/research/wizz-technical-research/customize.toml +3 -1
- package/src/bmm-skills/1-analysis/wizz-agent-analyst/customize.toml +3 -1
- package/src/bmm-skills/1-analysis/wizz-agent-tech-writer/customize.toml +4 -3
- package/src/bmm-skills/1-analysis/wizz-document-project/customize.toml +4 -3
- package/src/bmm-skills/1-analysis/wizz-prfaq/customize.toml +4 -3
- package/src/bmm-skills/1-analysis/wizz-product-brief/customize.toml +5 -6
- package/src/bmm-skills/2-plan-workflows/wizz-agent-pm/customize.toml +3 -1
- package/src/bmm-skills/2-plan-workflows/wizz-agent-ux-designer/customize.toml +3 -1
- package/src/bmm-skills/2-plan-workflows/wizz-create-prd/customize.toml +4 -3
- package/src/bmm-skills/2-plan-workflows/wizz-edit-prd/customize.toml +4 -3
- package/src/bmm-skills/2-plan-workflows/wizz-prd/customize.toml +5 -6
- package/src/bmm-skills/2-plan-workflows/wizz-ux/customize.toml +4 -3
- package/src/bmm-skills/2-plan-workflows/wizz-validate-prd/customize.toml +4 -3
- package/src/bmm-skills/3-solutioning/wizz-agent-architect/customize.toml +3 -1
- package/src/bmm-skills/3-solutioning/wizz-architecture/customize.toml +5 -6
- package/src/bmm-skills/3-solutioning/wizz-check-implementation-readiness/customize.toml +4 -3
- package/src/bmm-skills/3-solutioning/wizz-create-architecture/customize.toml +4 -3
- package/src/bmm-skills/3-solutioning/wizz-create-epics-and-stories/customize.toml +4 -3
- package/src/bmm-skills/3-solutioning/wizz-generate-project-context/steps/step-03-complete.md +7 -0
- package/src/bmm-skills/4-implementation/wizz-agent-dev/customize.toml +3 -1
- package/src/bmm-skills/4-implementation/wizz-checkpoint-preview/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-code-review/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-code-review/steps/step-03-triage.md +23 -14
- package/src/bmm-skills/4-implementation/wizz-code-review/steps/step-04-present.md +2 -2
- package/src/bmm-skills/4-implementation/wizz-correct-course/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-create-story/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-dev-story/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-investigate/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-qa-generate-e2e-tests/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-quick-dev/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-quick-dev/spec-template.md +6 -0
- package/src/bmm-skills/4-implementation/wizz-quick-dev/step-04-review.md +27 -16
- package/src/bmm-skills/4-implementation/wizz-quick-dev/step-oneshot.md +27 -6
- package/src/bmm-skills/4-implementation/wizz-retrospective/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-sprint-planning/customize.toml +4 -3
- package/src/bmm-skills/4-implementation/wizz-sprint-status/customize.toml +4 -3
- package/src/core-skills/wizz-brainstorming/customize.toml +5 -6
- package/src/core-skills/wizz-brainstorming/scripts/brain.py +19 -0
- package/src/core-skills/wizz-brainstorming/scripts/tests/test_brain.py +33 -0
- package/src/core-skills/wizz-forge-idea/scripts/resolve_personas.py +3 -1
- package/src/core-skills/wizz-forge-idea/scripts/tests/test_resolve_personas.py +21 -0
- package/src/core-skills/wizz-help/SKILL.md +5 -3
- package/src/core-skills/wizz-party-mode/customize.toml +5 -4
- package/src/core-skills/wizz-party-mode/scripts/resolve_party.py +3 -1
- package/src/core-skills/wizz-party-mode/scripts/tests/test_resolve_party.py +21 -0
- package/src/core-skills/wizz-spec/customize.toml +4 -5
- package/src/modules/wizz/_shared/model-ladder.md +4 -4
- package/src/modules/wizz/subagents/opencode/wizz-exec-review.md +2 -2
- package/src/modules/wizz/subagents/opencode/wizz-exec-standard.md +2 -2
- package/src/modules/wizz/subagents/opencode/wizz-exec-strong.md +2 -2
- package/src/modules/wizz/subagents/spec.yaml +3 -3
- package/src/scripts/resolve_config.py +8 -0
- package/src/scripts/resolve_customization.py +24 -3
- package/src/scripts/tests/test_resolve_config.py +42 -0
- package/src/scripts/tests/test_resolve_customization.py +45 -0
- package/src/skills-lib/ctc-align/SKILL.md +1 -1
- package/src/skills-lib/wizz-agent-browser/SKILL.md +5 -0
- package/src/skills-lib/wizz-huashu-design/scripts/html2pptx.js +902 -1061
- package/src/skills-lib/wizz-humanizer/README.md +134 -71
- package/src/skills-lib/wizz-humanizer/SKILL.md +51 -37
- package/src/skills-lib/wizz-humanizer/references/ai-writing-patterns.md +208 -190
- package/tools/installer/core/doctor.js +31 -1
- package/tools/installer/core/installer.js +32 -0
- package/tools/installer/core/project-instructions.js +199 -0
- package/src/bmm-skills/3-solutioning/wizz-architecture/scripts/__pycache__/lint_spine.cpython-313.pyc +0 -0
- package/src/bmm-skills/3-solutioning/wizz-architecture/scripts/tests/__pycache__/test_lint_spine.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/__pycache__/sprint_status.cpython-313.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-sprint-planning/scripts/__pycache__/sprint_plan.cpython-313.pyc +0 -0
- package/src/bmm-skills/4-implementation/wizz-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-advanced-elicitation/scripts/__pycache__/pick_methods.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-advanced-elicitation/scripts/tests/__pycache__/test_pick_methods.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-brainstorming/scripts/__pycache__/brain.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-brainstorming/scripts/tests/__pycache__/test_brain.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-brainstorming/scripts/tests/__pycache__/test_brain.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-customize/scripts/__pycache__/list_customizable_skills.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-customize/scripts/tests/__pycache__/test_list_customizable_skills.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-forge-idea/scripts/__pycache__/resolve_personas.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-forge-idea/scripts/__pycache__/resolve_personas.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-forge-idea/scripts/tests/__pycache__/test_resolve_personas.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-forge-idea/scripts/tests/__pycache__/test_resolve_personas.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-party-mode/scripts/__pycache__/resolve_party.cpython-313.pyc +0 -0
- package/src/core-skills/wizz-party-mode/scripts/__pycache__/resolve_party.cpython-314.pyc +0 -0
- package/src/core-skills/wizz-party-mode/scripts/tests/__pycache__/test_resolve_party.cpython-313-pytest-9.1.1.pyc +0 -0
- package/src/core-skills/wizz-party-mode/scripts/tests/__pycache__/test_resolve_party.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/resolve_customization.cpython-314.pyc +0 -0
- package/src/skills-lib/wizz-huashu-design/package-lock.json +0 -846
- package/src/skills-lib/wizz-humanizer/WARP.md +0 -53
- package/src/skills-lib/wizz-humanizer/references/full-example.md +0 -72
- package/src/skills-lib/wizz-humanizer/references/personality-and-soul.md +0 -36
- package/src/skills-lib/wizz-react-components/package-lock.json +0 -231
- package/src/skills-lib/wizz-supabase-postgres-best-practices/CLAUDE.md +0 -68
- package/src/skills-lib/wizz-ui-ux-pro-max/scripts/__pycache__/core.cpython-314.pyc +0 -0
- package/src/skills-lib/wizz-ui-ux-pro-max/scripts/__pycache__/design_system.cpython-314.pyc +0 -0
|
@@ -20,11 +20,10 @@ activation_steps_append = []
|
|
|
20
20
|
# Persistent facts the workflow keeps in mind for the whole run.
|
|
21
21
|
# Each entry is either a literal sentence, a skill prefixed with `skill:`,
|
|
22
22
|
# or a `file:`-prefixed path/glob whose contents are loaded as facts.
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
]
|
|
23
|
+
# Empty of project-context by default: repo-wide context belongs in CLAUDE.md/AGENTS.md
|
|
24
|
+
# (the Wizz block imports project-context.md there once per session). Add
|
|
25
|
+
# `file:{project-root}/**/project-context.md` here only to load it on every activation.
|
|
26
|
+
persistent_facts = []
|
|
28
27
|
|
|
29
28
|
# Executed when the workflow completes. Scalar or array of instructions.
|
|
30
29
|
on_complete = ""
|
|
@@ -4,7 +4,7 @@ The names `wizz-exec-mechanical`/`wizz-exec-standard`/`wizz-exec-strong`/`wizz-e
|
|
|
4
4
|
|
|
5
5
|
## The recommended session (the boss)
|
|
6
6
|
|
|
7
|
-
The recommended session model is the Standard tier (Sonnet
|
|
7
|
+
The recommended session model is the Standard tier (Sonnet / gpt-5.6-terra / claude-sonnet-5-5 / gemini-3.5-flash). The boss does common work itself — commands, questions, implementation with a spec — dispatches subagents for isolation or parallel work, arbitrates conflict between executor and reviewer, and takes architecture/product decisions WITH the user.
|
|
8
8
|
|
|
9
9
|
A session running above Standard (Opus, Fable, Mythos...) absorbs every tier at or below its own model: an Opus session does Strong work itself, and dispatches `wizz-exec-ultra` only after that attempt returns `ESCALAR` per the escalation signals below. A session on the Ultra model (Fable) absorbs Ultra too: it takes strong's `ESCALAR` itself and never dispatches `wizz-exec-ultra`. Review is the exception — it's NEVER absorbed: it always runs on `wizz-exec-review`, pinned to the Strong tier, so in a Fable session review moves off the boss and onto Opus.
|
|
10
10
|
|
|
@@ -15,10 +15,10 @@ How to know who the boss is in Claude Code: the system prompt states the session
|
|
|
15
15
|
| Tier | Subagent | Use | Claude Code | Codex | OpenCode | Gemini CLI |
|
|
16
16
|
|---|---|---|---|---|---|---|
|
|
17
17
|
| Mechanical | `wizz-exec-mechanical` | scanning, rename, repetitive diff, 100% specified change | haiku (maxTurns 50, no effort field) | gpt-5.6-luna, effort low | anthropic/claude-haiku-4-5 | gemini-3.1-flash-lite (max_turns 50, no effort field) |
|
|
18
|
-
| Standard | `wizz-exec-standard` | small/medium defined feature, bug with known cause, tests | sonnet, effort medium (maxTurns 80) | gpt-5.6-terra, effort medium | anthropic/claude-sonnet-5 | gemini-3.5-flash (max_turns 80) |
|
|
19
|
-
| Strong | `wizz-exec-strong` | bug with unclear cause after one investigation cycle, refactor spanning modules, schema/auth/payment changes, local technical decision | opus, effort high (maxTurns 120) | gpt-5.6-sol, effort high | anthropic/claude-opus-5 | gemini-3.1-pro-preview (max_turns 120) |
|
|
18
|
+
| Standard | `wizz-exec-standard` | small/medium defined feature, bug with known cause, tests | sonnet, effort medium (maxTurns 80) | gpt-5.6-terra, effort medium | anthropic/claude-sonnet-5-5 | gemini-3.5-flash (max_turns 80) |
|
|
19
|
+
| Strong | `wizz-exec-strong` | bug with unclear cause after one investigation cycle, refactor spanning modules, schema/auth/payment changes, local technical decision | opus, effort high (maxTurns 120) | gpt-5.6-sol, effort high | anthropic/claude-opus-5-5 | gemini-3.1-pro-preview (max_turns 120) |
|
|
20
20
|
| Ultra | `wizz-exec-ultra` | ultra-hard work the Strong tier returned `ESCALAR` on, plus its findings | fable, effort xhigh (maxTurns 150) | gpt-6-astra, effort xhigh | anthropic/claude-fable-5-1 | no ultra tier on this platform |
|
|
21
|
-
| Review | `wizz-exec-review` | review of a diff produced by any tier; pinned to Strong, never inherits the session | opus, effort high (maxTurns 60) | gpt-5.6-sol, effort high | anthropic/claude-opus-5 | gemini-3.1-pro-preview (max_turns 60) |
|
|
21
|
+
| Review | `wizz-exec-review` | review of a diff produced by any tier; pinned to Strong, never inherits the session | opus, effort high (maxTurns 60) | gpt-5.6-sol, effort high | anthropic/claude-opus-5-5 | gemini-3.1-pro-preview (max_turns 60) |
|
|
22
22
|
|
|
23
23
|
OpenCode gets the model only: its per-agent effort field isn't documented, and it has no per-agent turn cap field either. Claude Code and Gemini CLI enforce turn caps natively (`maxTurns` / `max_turns`); Codex and OpenCode have no per-agent turn cap field, so briefs to them should always carry `max_calls`.
|
|
24
24
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
|
|
3
3
|
description: >-
|
|
4
|
-
Wizz Method reviewer pinned to the Strong tier (anthropic/claude-opus-5), never to the session's model. Receives a diff or an executor's result and reviews correctness, security, regressions, and scope adherence. Doesn't implement: returns a verdict and a list of issues with file:line.
|
|
4
|
+
Wizz Method reviewer pinned to the Strong tier (anthropic/claude-opus-5-5), never to the session's model. Receives a diff or an executor's result and reviews correctness, security, regressions, and scope adherence. Doesn't implement: returns a verdict and a list of issues with file:line.
|
|
5
5
|
mode: subagent
|
|
6
|
-
model: anthropic/claude-opus-5
|
|
6
|
+
model: anthropic/claude-opus-5-5
|
|
7
7
|
permission:
|
|
8
8
|
edit: deny
|
|
9
9
|
---
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
|
|
3
3
|
description: >-
|
|
4
|
-
Standard Wizz Method executor for day-to-day implementation. Well-defined small/medium features, bug fixes with a known cause, multi-file edits, tests. Same tier as the recommended session model: dispatch it for isolation or parallel work (1 per file/module, up to 4 at once), not to escalate. Model on this platform: anthropic/claude-sonnet-5.
|
|
4
|
+
Standard Wizz Method executor for day-to-day implementation. Well-defined small/medium features, bug fixes with a known cause, multi-file edits, tests. Same tier as the recommended session model: dispatch it for isolation or parallel work (1 per file/module, up to 4 at once), not to escalate. Model on this platform: anthropic/claude-sonnet-5-5.
|
|
5
5
|
mode: subagent
|
|
6
|
-
model: anthropic/claude-sonnet-5
|
|
6
|
+
model: anthropic/claude-sonnet-5-5
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
You are an implementation executor for the Wizz Method. You receive a brief with a goal and context, and you implement it.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
# Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
|
|
3
3
|
description: >-
|
|
4
|
-
Strong Wizz Method executor for hard work. Bugs with no known cause after one investigation cycle, cross-module refactors, schema/auth/payment changes, local technical decisions. The session dispatches it when the work is too hard for the session's own tier. If the work turns out to be ultra hard, it returns ESCALAR with its findings; it never dispatches anything itself. Model on this platform: anthropic/claude-opus-5.
|
|
4
|
+
Strong Wizz Method executor for hard work. Bugs with no known cause after one investigation cycle, cross-module refactors, schema/auth/payment changes, local technical decisions. The session dispatches it when the work is too hard for the session's own tier. If the work turns out to be ultra hard, it returns ESCALAR with its findings; it never dispatches anything itself. Model on this platform: anthropic/claude-opus-5-5.
|
|
5
5
|
mode: subagent
|
|
6
|
-
model: anthropic/claude-opus-5
|
|
6
|
+
model: anthropic/claude-opus-5-5
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
You are a senior executor for the Wizz Method. You receive a brief with a goal and context for hard work, where the root cause or the path forward isn't clear yet.
|
|
@@ -165,10 +165,10 @@ models:
|
|
|
165
165
|
review: gemini-3.1-pro-preview
|
|
166
166
|
opencode:
|
|
167
167
|
mechanical: anthropic/claude-haiku-4-5
|
|
168
|
-
standard: anthropic/claude-sonnet-5
|
|
169
|
-
strong: anthropic/claude-opus-5
|
|
168
|
+
standard: anthropic/claude-sonnet-5-5
|
|
169
|
+
strong: anthropic/claude-opus-5-5
|
|
170
170
|
ultra: anthropic/claude-fable-5-1
|
|
171
|
-
review: anthropic/claude-opus-5
|
|
171
|
+
review: anthropic/claude-opus-5-5
|
|
172
172
|
codex:
|
|
173
173
|
mechanical: gpt-5.6-luna
|
|
174
174
|
standard: gpt-5.6-terra
|
|
@@ -169,6 +169,14 @@ def main():
|
|
|
169
169
|
else:
|
|
170
170
|
output = merged
|
|
171
171
|
|
|
172
|
+
write_json_stdout(output)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def write_json_stdout(output):
|
|
176
|
+
"""Write JSON as UTF-8 so Windows cp1252 stdout can carry emoji icons."""
|
|
177
|
+
reconfigure = getattr(sys.stdout, "reconfigure", None)
|
|
178
|
+
if reconfigure is not None:
|
|
179
|
+
reconfigure(encoding="utf-8")
|
|
172
180
|
sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False) + "\n")
|
|
173
181
|
|
|
174
182
|
|
|
@@ -15,6 +15,7 @@ Requires Python 3.11+ (uses stdlib `tomllib`). No `uv`, no `pip install`,
|
|
|
15
15
|
no virtualenv — plain `python3` is sufficient.
|
|
16
16
|
|
|
17
17
|
python3 resolve_customization.py --skill /abs/path/to/skill-dir
|
|
18
|
+
python3 resolve_customization.py --skill ... --project-root /abs/project
|
|
18
19
|
python3 resolve_customization.py --skill ... --key agent
|
|
19
20
|
python3 resolve_customization.py --skill ... --key agent.menu
|
|
20
21
|
|
|
@@ -86,13 +87,22 @@ _SHARED_DIR_NAME = "_shared"
|
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
def find_project_root(start: Path):
|
|
90
|
+
"""Nearest ancestor holding `_wizz/`, falling back to the nearest holding `.git`.
|
|
91
|
+
|
|
92
|
+
`_wizz/` outranks `.git` at every depth: a submodule or nested repo carries
|
|
93
|
+
`.git` without being the Wizz project, so treating the two as equal stops the
|
|
94
|
+
walk short of the root that owns `_wizz/custom/` (BMAD 6.12, #2802).
|
|
95
|
+
"""
|
|
96
|
+
git_root = None
|
|
89
97
|
current = start.resolve()
|
|
90
98
|
while True:
|
|
91
|
-
if (current / "_wizz").
|
|
99
|
+
if (current / "_wizz").is_dir():
|
|
92
100
|
return current
|
|
101
|
+
if git_root is None and (current / ".git").exists():
|
|
102
|
+
git_root = current
|
|
93
103
|
parent = current.parent
|
|
94
104
|
if parent == current:
|
|
95
|
-
return
|
|
105
|
+
return git_root
|
|
96
106
|
current = parent
|
|
97
107
|
|
|
98
108
|
|
|
@@ -388,6 +398,11 @@ def main():
|
|
|
388
398
|
"--skill", "-s", required=True,
|
|
389
399
|
help="Absolute path to the skill directory (must contain customize.toml)",
|
|
390
400
|
)
|
|
401
|
+
parser.add_argument(
|
|
402
|
+
"--project-root", "-p",
|
|
403
|
+
help="Absolute path to the project root (contains _wizz/). When omitted, "
|
|
404
|
+
"the root is inferred by walking up from the skill directory, then cwd.",
|
|
405
|
+
)
|
|
391
406
|
parser.add_argument(
|
|
392
407
|
"--key", "-k", action="append", default=[],
|
|
393
408
|
help="Dotted field path to resolve (repeatable). Omit for full dump.",
|
|
@@ -403,7 +418,13 @@ def main():
|
|
|
403
418
|
# for standalone skills invoked directly). Using cwd first is unsafe when
|
|
404
419
|
# an ancestor of cwd happens to have a stray _wizz/ from another project.
|
|
405
420
|
# Resolved BEFORE the base layer: the `_shared/` include fallback needs it.
|
|
406
|
-
|
|
421
|
+
# An explicit --project-root wins and skips the inference entirely: a
|
|
422
|
+
# skill installed under ~ walks up to ~, and a stray ~/_wizz there would
|
|
423
|
+
# hide the real project's overrides without any error (BMAD 6.12, #2802).
|
|
424
|
+
if args.project_root:
|
|
425
|
+
project_root = Path(args.project_root).resolve()
|
|
426
|
+
else:
|
|
427
|
+
project_root = find_project_root(skill_dir) or find_project_root(Path.cwd())
|
|
407
428
|
|
|
408
429
|
defaults = resolve_includes(
|
|
409
430
|
load_toml(defaults_path, required=True), defaults_path.parent, project_root, skill_name
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import tempfile
|
|
6
|
+
import unittest
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
SCRIPT = Path(__file__).resolve().parents[1] / "resolve_config.py"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ResolveConfigStdoutTests(unittest.TestCase):
|
|
14
|
+
def test_writes_emoji_json_when_stdout_encoding_is_cp1252(self):
|
|
15
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
16
|
+
root = Path(temp_dir)
|
|
17
|
+
(root / "_wizz").mkdir(parents=True)
|
|
18
|
+
(root / "_wizz" / "config.toml").write_text(
|
|
19
|
+
'[agents]\nname = "Analyst"\nicon = "📊"\n',
|
|
20
|
+
encoding="utf-8",
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
env = os.environ.copy()
|
|
24
|
+
env["PYTHONIOENCODING"] = "cp1252"
|
|
25
|
+
result = subprocess.run(
|
|
26
|
+
[sys.executable, str(SCRIPT), "--project-root", str(root)],
|
|
27
|
+
stdout=subprocess.PIPE,
|
|
28
|
+
stderr=subprocess.PIPE,
|
|
29
|
+
env=env,
|
|
30
|
+
check=False,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
stderr = result.stderr.decode("utf-8", errors="replace")
|
|
34
|
+
self.assertEqual(result.returncode, 0, msg=stderr)
|
|
35
|
+
|
|
36
|
+
output = result.stdout.decode("utf-8")
|
|
37
|
+
self.assertIn("📊", output)
|
|
38
|
+
self.assertEqual(json.loads(output)["agents"]["icon"], "📊")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
unittest.main()
|
|
@@ -46,5 +46,50 @@ class ResolveCustomizationStdoutTests(unittest.TestCase):
|
|
|
46
46
|
self.assertEqual(resolved["agent"]["icon"], "🧭")
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class ResolveCustomizationProjectRootTests(unittest.TestCase):
|
|
50
|
+
"""--project-root explícito e `_wizz/` acima de `.git` (BMAD 6.12, #2802)."""
|
|
51
|
+
|
|
52
|
+
def _skill(self, parent: Path) -> Path:
|
|
53
|
+
skill_dir = parent / "demo-skill"
|
|
54
|
+
skill_dir.mkdir(parents=True)
|
|
55
|
+
(skill_dir / "customize.toml").write_text('[workflow]\nmode = "base"\n', encoding="utf-8")
|
|
56
|
+
return skill_dir
|
|
57
|
+
|
|
58
|
+
def _override(self, root: Path) -> None:
|
|
59
|
+
custom = root / "_wizz" / "custom"
|
|
60
|
+
custom.mkdir(parents=True)
|
|
61
|
+
(custom / "demo-skill.toml").write_text('[workflow]\nmode = "team"\n', encoding="utf-8")
|
|
62
|
+
|
|
63
|
+
def _run(self, *args, cwd=None):
|
|
64
|
+
result = subprocess.run(
|
|
65
|
+
[sys.executable, str(SCRIPT), *args, "--key", "workflow"],
|
|
66
|
+
capture_output=True, text=True, cwd=cwd, check=False,
|
|
67
|
+
)
|
|
68
|
+
self.assertEqual(result.returncode, 0, msg=result.stderr)
|
|
69
|
+
return json.loads(result.stdout)["workflow"]
|
|
70
|
+
|
|
71
|
+
def test_explicit_project_root_wins_over_inference(self):
|
|
72
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
73
|
+
project = Path(tmp) / "project"
|
|
74
|
+
self._override(project)
|
|
75
|
+
# Skill fora do projeto: a inferência nunca chegaria em project/.
|
|
76
|
+
skill_dir = self._skill(Path(tmp) / "elsewhere")
|
|
77
|
+
self.assertEqual(self._run("--skill", str(skill_dir), cwd=tmp)["mode"], "base")
|
|
78
|
+
self.assertEqual(
|
|
79
|
+
self._run("--skill", str(skill_dir), "--project-root", str(project), cwd=tmp)["mode"],
|
|
80
|
+
"team",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def test_wizz_folder_outranks_nested_git(self):
|
|
84
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
85
|
+
project = Path(tmp) / "project"
|
|
86
|
+
self._override(project)
|
|
87
|
+
# Submódulo/repo aninhado: tem .git mas não é o projeto Wizz.
|
|
88
|
+
nested = project / "vendor" / "sub"
|
|
89
|
+
(nested / ".git").mkdir(parents=True)
|
|
90
|
+
skill_dir = self._skill(nested / "skills")
|
|
91
|
+
self.assertEqual(self._run("--skill", str(skill_dir), cwd=tmp)["mode"], "team")
|
|
92
|
+
|
|
93
|
+
|
|
49
94
|
if __name__ == "__main__":
|
|
50
95
|
unittest.main()
|
|
@@ -20,7 +20,7 @@ exact text and only looks for where each word is: precision within tens of ms.
|
|
|
20
20
|
|
|
21
21
|
mkdir -p tools/ctc-align && cd tools/ctc-align
|
|
22
22
|
uv venv --python 3.12 .venv
|
|
23
|
-
uv pip install --python .venv/bin/python "git+https://github.com/MahmoudAshraf97/ctc-forced-aligner.git"
|
|
23
|
+
uv pip install --python .venv/bin/python "git+https://github.com/MahmoudAshraf97/ctc-forced-aligner.git@64293cc6d711e57666c4a8b098e9fd93b381fd88"
|
|
24
24
|
|
|
25
25
|
Copy this skill's `scripts/align.py` to `tools/ctc-align/align.py`.
|
|
26
26
|
Runs on CPU (Mac ARM ok, no CUDA needed). First use downloads the MMS model (~1GB).
|
|
@@ -119,6 +119,9 @@ agent-browser open http://localhost:3000
|
|
|
119
119
|
| `-i` | Snapshot: interactive elements only |
|
|
120
120
|
| `-c` | Snapshot: compact output |
|
|
121
121
|
| `-d <n>` | Snapshot: limit tree depth |
|
|
122
|
+
| `--delta` | Snapshot: full state once, then only what changed (fewer tokens) |
|
|
123
|
+
| `--if-changed` | Screenshot: skip when the page did not change |
|
|
124
|
+
| `--no-webmcp` | Turn off WebMCP page tools (on by default since 0.36) |
|
|
122
125
|
|
|
123
126
|
## Debugging
|
|
124
127
|
|
|
@@ -137,3 +140,5 @@ agent-browser eval "document.title" # Run JS
|
|
|
137
140
|
3. **Wait when needed** - Use `wait <ms>` or `wait <selector>` after actions that trigger loading
|
|
138
141
|
4. **Sessions for auth** - Use named sessions to persist login state
|
|
139
142
|
5. **Headed for debugging** - Use `--headed` when things aren't working as expected
|
|
143
|
+
6. **Repeat checks cheaply** - `snapshot -i --delta` and `screenshot --if-changed` in a verify loop
|
|
144
|
+
7. **WebMCP off on third-party sites** - Since 0.36 a page can announce its own tools into your context. Launch with `--no-webmcp` unless the site is the project's own app; never invoke a page tool the user did not ask for
|