@adia-ai/adia-ui-factory 0.8.50 → 0.8.52
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/CHANGELOG.md +39 -0
- package/README.md +88 -3
- package/__init__.py +333 -0
- package/agents/app-planning-agent.md +4 -4
- package/agents/screen-composition-agent.md +1 -0
- package/agents/surface-qa-agent.md +4 -5
- package/agents/ui-architect.md +23 -36
- package/hermes-mcp.yaml +10 -0
- package/package.json +13 -2
- package/pi/ui-architect.extension.ts +458 -0
- package/plugin.yaml +4 -0
- package/prompts/app-audit.md +14 -0
- package/prompts/app-migration.md +15 -0
- package/prompts/app-planning.md +12 -0
- package/prompts/find-unused.md +23 -0
- package/prompts/gen-ui-wiring.md +11 -0
- package/prompts/project-scaffolding.md +13 -0
- package/prompts/surface-qa.md +20 -0
- package/scripts/adia-contract-check.mjs +30 -6
- package/scripts/adia-probe.mjs +54 -28
- package/scripts/build-result-lint +230 -0
- package/scripts/ui-architect-pi-selftest.mjs +111 -0
- package/scripts/verify-proof-lint +228 -0
- package/skills/pattern-catalog/SKILL.md +6 -1
- package/skills/pattern-catalog/references/pattern-index.md +172 -1
- package/skills/screen-composition/SKILL.md +5 -1
- package/skills/token-selection/references/a-alias-layer.md +3 -3
- package/skills/ui-architect/SKILL.md +119 -0
- package/skills/ui-architect/agents/openai.yaml +3 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adia-ui-kit-factory",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.52",
|
|
4
4
|
"description": "Author and verify apps built ON the adia-ui (@adia-ai) light-DOM web-component framework \u2014 orient, scaffold, compose, wire, verify, and migrate across SPA and SSR rendering modes. Wires the a2ui MCP for catalog retrieval, UI generation, and validation.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Kim",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adia-ui-kit-factory",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.52",
|
|
4
4
|
"description": "Author and verify apps built ON the adia-ui (@adia-ai) light-DOM web-component framework — orient, scaffold, compose, wire, verify, and migrate across SPA and SSR rendering modes. Wires the a2ui MCP for catalog retrieval, UI generation, and validation.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Kim",
|
package/.mcp.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog — adia-ui-kit-factory
|
|
2
2
|
|
|
3
|
+
## [0.8.52] — 2026-08-25
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **`ui-architect` portable skill + `BuildResult`/`VerifyProof` linters + repo-root Codex git-sourced marketplace (ADR-0091 C1/C2/C3/C4/C7, PR #1998).** `skills/ui-architect/SKILL.md` (with `agents/openai.yaml`, auto-derived via `codex-manifests.mjs`) authors one contract-grammar skill body every harness consumes as a thin adapter, backed by new `scripts/build-result-lint` and `scripts/verify-proof-lint` (record-lint family) plus `check:ui-architect-skill-portable` (85 → 88 gates in `npm run check`). `.agents/plugins/marketplace.json` (repo root) is the new git-install Codex channel — verified against OpenAI's own merged `codex-rs` marketplace-resolution source rather than assuming the Claude-side schema. `agents/ui-architect.md` slimmed to identity/tool-wall/dispatch-mechanics/failure-branches/stopping-predicate; the app-planning/screen-composition/surface-qa agent files already met the target shape.
|
|
7
|
+
- **`ui-architect` Pi extension (`pi/ui-architect.extension.ts`) + Hermes `delegate_task` `/ui-architect` command (ADR-0091 C5/C6, PR #2000).** Both harnesses verified live against their actual installed runtimes before building: Pi via the installed `@earendil-works/pi-coding-agent` v0.84.3's own subprocess-based subagent-dispatch pattern (live end-to-end run: dispatched all three isolated planning/composition/QA passes as real child `pi` processes, wrote a real file, took a real screenshot, returned a clean `VerifyProof`); Hermes via the installed Hermes Agent's own `PluginContext.register_command`/`delegate_tool.py` source, gated by the same portable-contract linters and live-verified via `hermes plugins doctor --ci`. Pi/Hermes native adapters framed as in-progress in the README rather than claiming unverified parity.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- **All agent seats pinned to `sonnet` + `xhigh` reasoning effort, replacing the prior fable/opus ceiling-ladder pins (PR #1999).** Operator's direct standing instruction, applied across `app-planning-agent`, `screen-composition-agent`, `surface-qa-agent`, `ui-architect`. See root `CHANGELOG.md` for the cross-plugin note.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **The new repo-root Codex marketplace manifest collided on `"name": "adia-plugins"` with the npm-sourced sibling, so `codex plugin marketplace add`/`codex plugin add` resolved ambiguously (PR #2002).** Renamed to `adia-ui-kit`, matching the existing Claude-side `adia-ui-kit`/`adia-plugins` split exactly; README + getting-started site page install references updated.
|
|
14
|
+
|
|
15
|
+
### Docs
|
|
16
|
+
- **README's install section hand-typed a stale "published v0.1.0" for `@adia-ai/adia-plugins`, now at v0.2.0 (PR #1996).** Dropped the hardcoded version number (it would only go stale again on the next Class-B cut) in favor of a pointer to the `adia-plugins` README, which carries its own current version and Non-Claude-harness detail.
|
|
17
|
+
|
|
18
|
+
### Maintenance
|
|
19
|
+
- **`.claude-plugin/plugin.json` version bump** — moves in lockstep with package.json (the `/plugin update` cache key).
|
|
20
|
+
- **`.codex-plugin/` touched in this release window** (1 file(s), e.g. `.codex-plugin/plugin.json`) — carried by the entries above.
|
|
21
|
+
|
|
22
|
+
## [0.8.51] — 2026-08-24
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Hermes + Pi external-distribution manifests (gh#1954) — `plugin.yaml` +
|
|
26
|
+
`__init__.py` + `hermes-mcp.yaml` (Hermes) and `prompts/*.md` + a `"pi"`
|
|
27
|
+
field in `package.json` (Pi), derived from `.claude-plugin/plugin.json` +
|
|
28
|
+
`skills/` + `commands/` + `.mcp.json` via `npm run
|
|
29
|
+
build:harness-manifests` (`check:harness-manifests-fresh` gates
|
|
30
|
+
freshness). Additive: the Claude Code plugin surface is unchanged.
|
|
31
|
+
**MCP caveat, not parity:** Hermes MCP is user-level config — merge the
|
|
32
|
+
generated `hermes-mcp.yaml` into `~/.hermes/config.yaml` by hand. Pi core
|
|
33
|
+
has no native MCP — the `adia-gen-ui` server only reaches Pi through the
|
|
34
|
+
third-party `pi-mcp-adapter` reading this plugin's `.mcp.json` unmodified.
|
|
35
|
+
See the README's "Non-Claude harnesses" section before promising Pi/Hermes
|
|
36
|
+
parity for this plugin's headline MCP-wiring feature.
|
|
37
|
+
|
|
38
|
+
### Maintenance
|
|
39
|
+
- **`.codex-plugin/` touched in this release window** (1 file(s), e.g. `.codex-plugin/plugin.json`) — carried by the entries above.
|
|
40
|
+
- **`scripts/` touched in this release window** (2 file(s), e.g. `scripts/adia-contract-check.mjs`) — carried by the entries above.
|
|
41
|
+
|
|
3
42
|
## [0.8.50] — 2026-08-23
|
|
4
43
|
|
|
5
44
|
### Maintenance
|
package/README.md
CHANGED
|
@@ -24,7 +24,9 @@ Sources the in-repo manifest at `.claude-plugin/marketplace.json` (repo
|
|
|
24
24
|
root — `claude plugin marketplace add` always expects the manifest there,
|
|
25
25
|
with or without `--sparse`; it does not resolve a subdirectory manifest).
|
|
26
26
|
The LIVE public install path (ADR-0045's npm-sourced manifest,
|
|
27
|
-
`@adia-ai/adia-plugins`,
|
|
27
|
+
`@adia-ai/adia-plugins`, live since v0.1.0 — gh#1160; see
|
|
28
|
+
`packages/plugins/adia-plugins/README.md` for its own current version, which
|
|
29
|
+
cuts on its own Class-B schedule independent of the framework lockstep):
|
|
28
30
|
|
|
29
31
|
```
|
|
30
32
|
/plugin marketplace add https://unpkg.com/@adia-ai/adia-plugins/marketplace.json
|
|
@@ -49,7 +51,7 @@ posture (ADR-0040) is about this plugin working standalone in any consumer
|
|
|
49
51
|
repo once installed some other way (no monorepo path assumptions in its own
|
|
50
52
|
scripts) — it does not add an npm-sourced marketplace entry.
|
|
51
53
|
|
|
52
|
-
## Skills (
|
|
54
|
+
## Skills (19 — `skills/` on disk is the roster; `check:plugin-count-claims` guards this header count)
|
|
53
55
|
|
|
54
56
|
| Skill | Species | Job |
|
|
55
57
|
|---|---|---|
|
|
@@ -61,6 +63,7 @@ scripts) — it does not add an npm-sourced marketplace entry.
|
|
|
61
63
|
| `screen-composition` | procedural | compose screens from the catalog; consumes the Domain Plan for PRD/spec input (§SpecToUi walked planning-side, gh#1207) |
|
|
62
64
|
| `shell-selection` | procedural | shell-family selection + per-shell contracts |
|
|
63
65
|
| `wave-coordination` | procedural | team-wave mechanics — parallel-branch integration, PR/conflict rules, shared-file ownership, wave sizing; preloaded by ui-architect |
|
|
66
|
+
| `ui-architect` | procedural | portable (runtime-neutral) whole-deliverable coordination workflow — gear selection, wave decomposition, generator-≠-reviewer separation, the four-lap cap, failure routing, the closing VerifyProof; the Claude-only dispatch mechanics live in `agents/ui-architect.md` + `wave-coordination` instead |
|
|
64
67
|
| `data-wiring` | knowledge | data/state patterns (signals, controllers, DataClient, hybrid) |
|
|
65
68
|
| `chart-selection` | knowledge | which component renders a chart/graph/sparkline/gauge/heatmap, and data/legend/theming wiring |
|
|
66
69
|
| `table-composition` | knowledge | `table-ui` usage — chrome, striping, sort/resize, inline-edit-grid, tree rows |
|
|
@@ -98,7 +101,7 @@ surface-qa-agent) · `component-model.md` · the `references/contracts/` twins.
|
|
|
98
101
|
|
|
99
102
|
## MCP
|
|
100
103
|
|
|
101
|
-
`adia-gen-ui` server pinned: `@adia-ai/mcp@0.8.
|
|
104
|
+
`adia-gen-ui` server pinned: `@adia-ai/mcp@0.8.52` (tool SoT:
|
|
102
105
|
`packages/gen-ui/mcp/TOOLS.md` — the `gen-ui` section; stability rule in
|
|
103
106
|
`references/contracts/`; pin lives in `.mcp.json` — `check:plugin-count-claims`
|
|
104
107
|
guards this README copy against it). The server is `adia-mcp gen-ui`,
|
|
@@ -108,6 +111,88 @@ before either ever published; the pin name and the `mcpServers` key flipped
|
|
|
108
111
|
in the P7 release commit per the 2026-08-14 config-key ruling — new entries
|
|
109
112
|
for the other subcommands use `adia-protocol` / `adia-factory`).
|
|
110
113
|
|
|
114
|
+
## Non-Claude harnesses
|
|
115
|
+
|
|
116
|
+
External install beyond Claude Code (AGENTS.md's own "Non-Claude harnesses"
|
|
117
|
+
section carries the shared degradation table this summarizes). **The MCP
|
|
118
|
+
story is the one place neither non-Claude harness matches Claude Code's
|
|
119
|
+
plug-and-play install** — read this section before promising Pi/Hermes
|
|
120
|
+
support for this plugin specifically, since its whole value proposition is
|
|
121
|
+
wiring the `adia-gen-ui` MCP server.
|
|
122
|
+
|
|
123
|
+
- **Codex** (gh#1888): `.codex-plugin/plugin.json` + per-skill
|
|
124
|
+
`agents/openai.yaml`, derived; `mcpServers` points at the same
|
|
125
|
+
`.mcp.json` Claude Code uses. No manifest key for hooks/commands/agents —
|
|
126
|
+
a command degrades to invoking its skill directly, and `ui-architect`'s
|
|
127
|
+
whole-deliverable coordination — gear selection, wave decomposition,
|
|
128
|
+
generator-≠-reviewer separation, the four-lap cap, failure routing, the
|
|
129
|
+
closing `VerifyProof` — ships as its own portable `ui-architect` skill
|
|
130
|
+
instead of a Claude subagent (ADR-0091): invoke it by name ("use the
|
|
131
|
+
`ui-architect` skill…"); it runs planning/composition/QA as isolated
|
|
132
|
+
dispatches where the installed Codex runtime supports that, or serially in
|
|
133
|
+
one context otherwise. Install via npm (see the `adia-plugins` package
|
|
134
|
+
README) or straight from Git, for anyone with repo access:
|
|
135
|
+
```
|
|
136
|
+
codex plugin marketplace add adiahealth/gen-ui-kit --ref main
|
|
137
|
+
codex plugin add adia-ui-kit-factory@adia-ui-kit
|
|
138
|
+
codex plugin add adia-ui-kit-forge@adia-ui-kit
|
|
139
|
+
```
|
|
140
|
+
Sourced from the repo-root `.agents/plugins/marketplace.json` — the
|
|
141
|
+
Codex-side sibling of this repo's own in-repo Claude channel
|
|
142
|
+
(`.claude-plugin/marketplace.json`), hand-authored the same way, never
|
|
143
|
+
generated (ADR-0091 D2/D3). Both plugins register under the manifest's own
|
|
144
|
+
name, `adia-ui-kit` — not the repo name, and a distinct marketplace name
|
|
145
|
+
from the npm-sourced channel above it (`adia-plugins`), mirroring the
|
|
146
|
+
existing Claude-side split exactly, kept deliberately parallel rather
|
|
147
|
+
than merged.
|
|
148
|
+
- **Hermes** (gh#1954): `plugin.yaml` + `__init__.py` at this package's
|
|
149
|
+
root — point Hermes's plugin loading at the installed
|
|
150
|
+
`node_modules/@adia-ai/adia-ui-factory` directory. **MCP is user-level
|
|
151
|
+
config in Hermes, not a plugin field** — merge the generated
|
|
152
|
+
`hermes-mcp.yaml` into your own `~/.hermes/config.yaml` by hand; there is
|
|
153
|
+
no automatic wiring. `__init__.py` registers the portable `ui-architect`
|
|
154
|
+
skill (ADR-0091) alongside every other skill, **and** a generated
|
|
155
|
+
`/ui-architect` command — verified against the installed Hermes Agent's
|
|
156
|
+
real `PluginContext.register_command` + `dispatch_tool` and
|
|
157
|
+
`tools/delegate_tool.py`'s `delegate_task(goal, context, role, …)` (not
|
|
158
|
+
assumed from documentation): each of planning, composition, and QA runs
|
|
159
|
+
as its own isolated `delegate_task` child (`role="leaf"`), gated by the
|
|
160
|
+
same `OrientationRecord`/`BuildResult`/`VerifyProof` linters every other
|
|
161
|
+
runtime calls, capped at four plan→build→QA laps per wave (LLD §C6, SPEC
|
|
162
|
+
REQ-012/013). Generated by `scripts/build/harness-manifests.mjs` — never
|
|
163
|
+
hand-edit `__init__.py`. Verified live via `hermes plugins doctor --ci`
|
|
164
|
+
(clean registration against the real `PluginContext`) plus a Python-level
|
|
165
|
+
selftest (`check:harness-manifests-selftest`) driving the actual
|
|
166
|
+
generated orchestration logic against a scripted `delegate_task` double
|
|
167
|
+
and the real linters; a live interactive `/ui-architect` dispatch was not
|
|
168
|
+
completed (sandboxed dev environment blocks mutating Hermes's global
|
|
169
|
+
plugin-enable state) — the mechanism itself is real and independently
|
|
170
|
+
verified, not simulated. No hooks/agents surface otherwise.
|
|
171
|
+
- **Pi** (gh#1954): discovered via the `pi-package` keyword and the `"pi"`
|
|
172
|
+
field in `package.json`; `prompts/*.md` gives every `/command` a genuine
|
|
173
|
+
Pi prompt template. **Pi core has no native MCP support at all** — the
|
|
174
|
+
`adia-gen-ui` server only reaches Pi through the third-party
|
|
175
|
+
[`pi-mcp-adapter`](https://pi.dev) package, which reads this plugin's
|
|
176
|
+
`.mcp.json` unmodified (same shape, no substitution needed). Install that
|
|
177
|
+
adapter first; without it, this plugin's headline feature — the a2ui MCP
|
|
178
|
+
wiring — silently does nothing on a stock Pi install. The portable
|
|
179
|
+
`ui-architect` skill (ADR-0091) is discoverable via the `"pi": {"skills":
|
|
180
|
+
[...]}` glob like every other skill, **and** `pi/ui-architect.extension.ts`
|
|
181
|
+
(`"pi": {"extensions": [...]}`) registers a real `/ui-architect` command:
|
|
182
|
+
verified against the installed `@earendil-works/pi-coding-agent` v0.84.3 —
|
|
183
|
+
its own shipped (if not core-builtin) `examples/extensions/subagent/`
|
|
184
|
+
proves the pattern this extension reuses — dispatching planning,
|
|
185
|
+
composition, and QA as isolated nested `pi --mode json -p --no-session`
|
|
186
|
+
child processes, each tool-walled to mirror this plugin's Claude seats
|
|
187
|
+
(`read,grep,find,ls,bash` for planning/QA; add `edit,write` only for
|
|
188
|
+
composition) and gated by the same three portable-contract linters
|
|
189
|
+
(LLD §C5, SPEC REQ-011). Live-verified end to end in this change's own
|
|
190
|
+
development — a real `pi -e ./pi/ui-architect.extension.ts` session ran
|
|
191
|
+
`/ui-architect` against a live model, dispatched all three isolated
|
|
192
|
+
passes, wrote a real file, took a real screenshot, and returned a clean
|
|
193
|
+
`VerifyProof` — not simulated against an unverified API. No hooks/agents
|
|
194
|
+
surface otherwise.
|
|
195
|
+
|
|
111
196
|
## Requirements
|
|
112
197
|
|
|
113
198
|
Python 3 (hook) + Node 22. Installs standalone in consumer repos (no monorepo
|
package/__init__.py
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"""adia-ui-kit-factory — generated by scripts/build/harness-manifests.mjs. Do not edit."""
|
|
2
|
+
import os
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
_HERE = os.path.dirname(os.path.abspath(__file__))
|
|
6
|
+
|
|
7
|
+
# --- ui-architect (ADR-0091 C6) --------------------------------------------
|
|
8
|
+
# Generated /ui-architect Hermes command, implementing the portable ui-architect
|
|
9
|
+
# workflow (skills/ui-architect/SKILL.md) through delegate_task. Never
|
|
10
|
+
# hand-edit this block — regenerate via scripts/build/harness-manifests.mjs.
|
|
11
|
+
# The skill body is read from disk at COMMAND-INVOCATION time, never copied
|
|
12
|
+
# into this file, so SKILL.md stays the single authored copy (SPEC REQ-001).
|
|
13
|
+
import json as _ui_architect_json
|
|
14
|
+
import re as _ui_architect_re
|
|
15
|
+
import subprocess as _ui_architect_subprocess
|
|
16
|
+
|
|
17
|
+
_UI_ARCHITECT_MAX_LAPS = 4
|
|
18
|
+
|
|
19
|
+
_UI_ARCHITECT_ORIENTATION_TEMPLATE = "\n".join([
|
|
20
|
+
"Rendering mode: SPA | SSR | hybrid — signal: <file/dep/marker or words>",
|
|
21
|
+
"Project shape: single-surface | rollup | shared-foundation — signal: <…>",
|
|
22
|
+
"Shell: admin | chat | editor | simple | embed | none — signal: <…>",
|
|
23
|
+
"Task: <task> — signal: <the request>",
|
|
24
|
+
"→ Route: <skill(s)>, per the task table",
|
|
25
|
+
"Verify target: <what the executor produces to call this done>",
|
|
26
|
+
"Open questions: <unresolved axes, each with its named fallback; blank if none>",
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
_UI_ARCHITECT_BUILD_TEMPLATE = "\n".join([
|
|
30
|
+
"BuildResult",
|
|
31
|
+
"surface: <screen/task identifier>",
|
|
32
|
+
"orientationRef: <the OrientationRecord this build executed>",
|
|
33
|
+
"filesChanged: <files written/edited, one per line or comma-list>",
|
|
34
|
+
"gatesRun: <builder self-checks and their pass/fail — adia-lint, validate_schema, check_anti_patterns, etc.>",
|
|
35
|
+
"evidence: <what was run/observed — probe output paths, screenshots, validator logs>",
|
|
36
|
+
"selfCheck: pass | fail | UNMEASURED — <reason> (NEVER a ship/hold verdict)",
|
|
37
|
+
'openIssues: <unresolved items, or "none">',
|
|
38
|
+
])
|
|
39
|
+
|
|
40
|
+
_UI_ARCHITECT_VERIFY_TEMPLATE = "\n".join([
|
|
41
|
+
"url: <the probed page>",
|
|
42
|
+
"consoleErrors: pass | fail | UNMEASURED — <each error verbatim; empty = pass; UNMEASURED carries the reason>",
|
|
43
|
+
"boundingBoxes: pass | fail — <selector: w×h per key element; any 0×0 = fail>",
|
|
44
|
+
"screenshot: <path> @ deviceScaleFactor 2",
|
|
45
|
+
'imageRead: <what the pixels actually show — REQUIRED prose, never "looks fine">',
|
|
46
|
+
"perf: <navigation timing>ms vs <budget>ms — ADVISORY, never gates | UNMEASURED — <reason>",
|
|
47
|
+
"a11y: pass | fail | UNMEASURED — region role/label · overlays · heading roles · keyboard path · AA contrast",
|
|
48
|
+
"structure: adia-lint clean on every written file | <findings>",
|
|
49
|
+
"verdict: ship | hold — <one line naming the blocker if hold>",
|
|
50
|
+
])
|
|
51
|
+
|
|
52
|
+
def _ui_architect_skill_body():
|
|
53
|
+
path = os.path.join(_HERE, "skills", "ui-architect", "SKILL.md")
|
|
54
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
55
|
+
raw = f.read()
|
|
56
|
+
m = _ui_architect_re.match(r"^---\n[\s\S]*?\n---\n?([\s\S]*)$", raw)
|
|
57
|
+
return (m.group(1) if m else raw).strip()
|
|
58
|
+
|
|
59
|
+
def _ui_architect_run_linter(linter_name, text):
|
|
60
|
+
linter_path = os.path.join(_HERE, "scripts", linter_name)
|
|
61
|
+
proc = _ui_architect_subprocess.run([linter_path, "-"], input=text, capture_output=True, text=True)
|
|
62
|
+
return proc.returncode == 0, (proc.stdout + proc.stderr).strip()
|
|
63
|
+
|
|
64
|
+
def _ui_architect_delegate(ctx, goal, context_text):
|
|
65
|
+
raw = ctx.dispatch_tool("delegate_task", {"goal": goal, "context": context_text, "role": "leaf"})
|
|
66
|
+
try:
|
|
67
|
+
data = _ui_architect_json.loads(raw)
|
|
68
|
+
except Exception:
|
|
69
|
+
return "", "error"
|
|
70
|
+
results = data.get("results") or []
|
|
71
|
+
if not results:
|
|
72
|
+
return "", "error"
|
|
73
|
+
return results[0].get("summary") or "", results[0].get("status") or "error"
|
|
74
|
+
|
|
75
|
+
def _ui_architect_parse_gear(text):
|
|
76
|
+
m = _ui_architect_re.search(r"^Gear:\s*([12])", text, _ui_architect_re.M | _ui_architect_re.I)
|
|
77
|
+
return 2 if m and m.group(1) == "2" else 1
|
|
78
|
+
|
|
79
|
+
def _ui_architect_parse_waves(text):
|
|
80
|
+
m = _ui_architect_re.search(r"^##\s*Waves\s*\n(.*?)(?:\n##|\n---|\Z)", text, _ui_architect_re.M | _ui_architect_re.S | _ui_architect_re.I)
|
|
81
|
+
if not m:
|
|
82
|
+
return ["the deliverable"]
|
|
83
|
+
waves = [_ui_architect_re.sub(r"^[-*]\s*", "", w).strip() for w in m.group(1).splitlines()]
|
|
84
|
+
waves = [w for w in waves if w]
|
|
85
|
+
return waves or ["the deliverable"]
|
|
86
|
+
|
|
87
|
+
def _ui_architect_parse_verdict(text):
|
|
88
|
+
m = _ui_architect_re.search(r"^verdict:\s*(ship|hold)\b", text, _ui_architect_re.M | _ui_architect_re.I)
|
|
89
|
+
return m.group(1).lower() if m else "unknown"
|
|
90
|
+
|
|
91
|
+
def _ui_architect_planning_prompt(skill_body):
|
|
92
|
+
parts = [
|
|
93
|
+
skill_body,
|
|
94
|
+
"---",
|
|
95
|
+
"You are running the PLANNING pass of the ui-architect workflow above, in an isolated context",
|
|
96
|
+
"(a separate delegate_task child with no memory of any other pass). Apply Gear selection to",
|
|
97
|
+
"the goal given to you.",
|
|
98
|
+
"",
|
|
99
|
+
"Your final answer MUST start with a line 'Gear: 1' or 'Gear: 2', followed by exactly one",
|
|
100
|
+
"app-planning OrientationRecord in EXACTLY this flat label: value line shape — no markdown",
|
|
101
|
+
"headings, no table, no extra prose around it:",
|
|
102
|
+
"",
|
|
103
|
+
_UI_ARCHITECT_ORIENTATION_TEMPLATE,
|
|
104
|
+
"",
|
|
105
|
+
"If Gear 2 (a PRD/multi-surface brief), also include a '## Waves' heading with one",
|
|
106
|
+
"'- <surface name>' line per surface — omit that heading entirely for Gear 1. Emit nothing else.",
|
|
107
|
+
]
|
|
108
|
+
return "\n".join(parts)
|
|
109
|
+
|
|
110
|
+
def _ui_architect_composition_prompt(skill_body):
|
|
111
|
+
parts = [
|
|
112
|
+
skill_body,
|
|
113
|
+
"---",
|
|
114
|
+
"You are running the COMPOSITION pass of the ui-architect workflow above, in an isolated",
|
|
115
|
+
"context, downstream of an OrientationRecord given to you as INPUT SIGNAL below — re-derive",
|
|
116
|
+
"from it, never adopt it uninspected. Build the surface it describes.",
|
|
117
|
+
"",
|
|
118
|
+
"Your final answer MUST be exactly one BuildResult record in EXACTLY this flat label: value",
|
|
119
|
+
"line shape — no markdown headings, no table, no extra prose around it — never a ship/hold",
|
|
120
|
+
"verdict, that field is VerifyProof-exclusive:",
|
|
121
|
+
"",
|
|
122
|
+
_UI_ARCHITECT_BUILD_TEMPLATE,
|
|
123
|
+
"",
|
|
124
|
+
"Emit nothing else.",
|
|
125
|
+
]
|
|
126
|
+
return "\n".join(parts)
|
|
127
|
+
|
|
128
|
+
def _ui_architect_qa_prompt(skill_body):
|
|
129
|
+
parts = [
|
|
130
|
+
skill_body,
|
|
131
|
+
"---",
|
|
132
|
+
"You are running the QA pass of the ui-architect workflow above, in an isolated context,",
|
|
133
|
+
"independent of and downstream from the BuildResult given to you as INPUT SIGNAL below. You",
|
|
134
|
+
"did not write this code — verify it fresh; never self-certify the builder's own report.",
|
|
135
|
+
"",
|
|
136
|
+
"Your final answer MUST be exactly one VerifyProof record in EXACTLY this flat label: value",
|
|
137
|
+
"line shape — no markdown headings, no table, no extra prose around it, carrying the",
|
|
138
|
+
"ship/hold verdict:",
|
|
139
|
+
"",
|
|
140
|
+
_UI_ARCHITECT_VERIFY_TEMPLATE,
|
|
141
|
+
"",
|
|
142
|
+
"Emit nothing else.",
|
|
143
|
+
]
|
|
144
|
+
return "\n".join(parts)
|
|
145
|
+
|
|
146
|
+
def _ui_architect_run_wave(ctx, skill_body, top_orientation, wave, max_laps, log):
|
|
147
|
+
findings = []
|
|
148
|
+
last_verify = ""
|
|
149
|
+
last_build = ""
|
|
150
|
+
lap = 0
|
|
151
|
+
while lap < max_laps:
|
|
152
|
+
lap += 1
|
|
153
|
+
log(" [%s] lap %d/%d — planning" % (wave, lap, max_laps))
|
|
154
|
+
if lap == 1:
|
|
155
|
+
plan_task = "Wave: %s\n\nTop-level OrientationRecord (INPUT SIGNAL):\n%s" % (wave, top_orientation)
|
|
156
|
+
else:
|
|
157
|
+
plan_task = "Wave: %s\n\nPrior VerifyProof findings to re-plan against (INPUT SIGNAL):\n%s" % (wave, last_verify)
|
|
158
|
+
plan_out, _plan_status = _ui_architect_delegate(ctx, plan_task, _ui_architect_planning_prompt(skill_body))
|
|
159
|
+
ok, lint_out = _ui_architect_run_linter("record-lint", plan_out)
|
|
160
|
+
if not ok:
|
|
161
|
+
findings.append("[%s] lap %d planning record-lint findings:\n%s" % (wave, lap, lint_out))
|
|
162
|
+
|
|
163
|
+
log(" [%s] lap %d — composition" % (wave, lap))
|
|
164
|
+
build_task = "Wave: %s\n\nOrientationRecord (INPUT SIGNAL):\n%s" % (wave, plan_out)
|
|
165
|
+
build_out, _build_status = _ui_architect_delegate(ctx, build_task, _ui_architect_composition_prompt(skill_body))
|
|
166
|
+
last_build = build_out
|
|
167
|
+
ok, lint_out = _ui_architect_run_linter("build-result-lint", build_out)
|
|
168
|
+
if not ok:
|
|
169
|
+
findings.append("[%s] lap %d build-result-lint findings:\n%s" % (wave, lap, lint_out))
|
|
170
|
+
|
|
171
|
+
log(" [%s] lap %d — QA" % (wave, lap))
|
|
172
|
+
verify_task = "Wave: %s\n\nBuildResult (INPUT SIGNAL):\n%s" % (wave, build_out)
|
|
173
|
+
verify_out, _verify_status = _ui_architect_delegate(ctx, verify_task, _ui_architect_qa_prompt(skill_body))
|
|
174
|
+
last_verify = verify_out
|
|
175
|
+
ok, lint_out = _ui_architect_run_linter("verify-proof-lint", verify_out)
|
|
176
|
+
if not ok:
|
|
177
|
+
findings.append("[%s] lap %d verify-proof-lint findings:\n%s" % (wave, lap, lint_out))
|
|
178
|
+
|
|
179
|
+
verdict = _ui_architect_parse_verdict(verify_out)
|
|
180
|
+
if max_laps == 1:
|
|
181
|
+
return {"wave": wave, "laps": lap, "verdict": verdict, "verifyProof": last_verify, "buildResult": last_build, "findings": findings}
|
|
182
|
+
if verdict == "ship":
|
|
183
|
+
return {"wave": wave, "laps": lap, "verdict": verdict, "verifyProof": last_verify, "buildResult": last_build, "findings": findings}
|
|
184
|
+
if lap >= max_laps:
|
|
185
|
+
findings.append("[%s] hit the %d-lap cap without a ship verdict — escalating, not re-running blind." % (wave, max_laps))
|
|
186
|
+
return {"wave": wave, "laps": lap, "verdict": "escalated", "verifyProof": last_verify, "buildResult": last_build, "findings": findings}
|
|
187
|
+
return {"wave": wave, "laps": max_laps, "verdict": "escalated", "verifyProof": last_verify, "buildResult": last_build, "findings": findings}
|
|
188
|
+
|
|
189
|
+
def _ui_architect_command(raw_args, ctx):
|
|
190
|
+
brief = (raw_args or "").strip()
|
|
191
|
+
lines_out = []
|
|
192
|
+
log = lambda line: lines_out.append(line)
|
|
193
|
+
if not brief:
|
|
194
|
+
return "ui-architect: no brief given. Usage: /ui-architect <brief, or a path to a PRD>"
|
|
195
|
+
if not hasattr(ctx, "dispatch_tool"):
|
|
196
|
+
return "ui-architect: no delegate_task-capable ctx available — cannot dispatch isolated passes."
|
|
197
|
+
skill_body = _ui_architect_skill_body()
|
|
198
|
+
log("ui-architect: dispatching an isolated PLANNING pass to size the brief (Gear selection)...")
|
|
199
|
+
initial_out, _status = _ui_architect_delegate(ctx, brief, _ui_architect_planning_prompt(skill_body))
|
|
200
|
+
ok, lint_out = _ui_architect_run_linter("record-lint", initial_out)
|
|
201
|
+
gear = _ui_architect_parse_gear(initial_out)
|
|
202
|
+
waves = _ui_architect_parse_waves(initial_out) if gear == 2 else ["the deliverable"]
|
|
203
|
+
max_laps = _UI_ARCHITECT_MAX_LAPS if gear == 2 else 1
|
|
204
|
+
log("ui-architect: GEAR %d — %d wave(s): %s" % (gear, len(waves), ", ".join(waves)))
|
|
205
|
+
if not ok:
|
|
206
|
+
log("ui-architect: initial OrientationRecord failed record-lint:\n%s" % lint_out)
|
|
207
|
+
outcomes = [_ui_architect_run_wave(ctx, skill_body, initial_out, wave, max_laps, log) for wave in waves]
|
|
208
|
+
shipped = sum(1 for o in outcomes if o["verdict"] == "ship")
|
|
209
|
+
escalated = [o for o in outcomes if o["verdict"] == "escalated"]
|
|
210
|
+
header = "ui-architect — GEAR %d — %d/%d wave(s) shipped" % (gear, shipped, len(outcomes))
|
|
211
|
+
if escalated:
|
|
212
|
+
header += ", %d escalated" % len(escalated)
|
|
213
|
+
lines_out.append(header)
|
|
214
|
+
lines_out.append("")
|
|
215
|
+
for o in outcomes:
|
|
216
|
+
lap_word = "lap" if o["laps"] == 1 else "laps"
|
|
217
|
+
lines_out.append("## %s — %s (%d %s)" % (o["wave"], o["verdict"], o["laps"], lap_word))
|
|
218
|
+
lines_out.append(o["verifyProof"] or "(no VerifyProof produced)")
|
|
219
|
+
if o["findings"]:
|
|
220
|
+
lines_out.append("Findings:")
|
|
221
|
+
for f in o["findings"]:
|
|
222
|
+
lines_out.append(" - %s" % f)
|
|
223
|
+
lines_out.append("")
|
|
224
|
+
return "\n".join(lines_out)
|
|
225
|
+
|
|
226
|
+
def _ui_architect_command_handler(_ctx_closure):
|
|
227
|
+
def _handler(raw_args):
|
|
228
|
+
return _ui_architect_command(raw_args, _ctx_closure)
|
|
229
|
+
return _handler
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def register(ctx):
|
|
233
|
+
ctx.register_skill(
|
|
234
|
+
name="app-audit",
|
|
235
|
+
path=Path(os.path.join(_HERE, "skills", "app-audit", "SKILL.md")),
|
|
236
|
+
description="Diagnose an EXISTING AdiaUI consumer codebase before touching it — recon, classify manifest/version/spec/capability drift, root-cause a DRIFT-caused wrong-output symptom via four-layer triage (skill/codebase/substrate/spec) instead of patching the surface. Use for \"audit this UI\", \"is this up to date\", \"what should we migrate\", \"doesn't match the reference\", \"looks unstyled/off-brand\", or a suspected-drifted @adia-ai/* consumer's version health check. Produces a ranked, evidence-cited report; hands CONFIRMED sweeps to a builder. NOT greenfield planning (app-planning) or confirmed migration (app-migration); NOT a live blank-screen/console-error check (surface-qa) or chart-specific render behavior (chart-selection); NOT a duplication review (project-scaffolding).",
|
|
237
|
+
)
|
|
238
|
+
ctx.register_skill(
|
|
239
|
+
name="app-migration",
|
|
240
|
+
path=Path(os.path.join(_HERE, "skills", "app-migration", "SKILL.md")),
|
|
241
|
+
description="Migrates a consumer adia-ui app. Use when asked to \"migrate to v0.X\", \"upgrade @adia-ai/web-components\", \"fix breaking changes\", \"sweep deprecated attributes\", port @agent-ui-kit/foreign code, or change SPA↔SSR mode — grep audit, mechanical sweep, verify gates. NOT for authoring the MIGRATION GUIDE or cutting releases (package-release, forge plugin).",
|
|
242
|
+
)
|
|
243
|
+
ctx.register_skill(
|
|
244
|
+
name="app-planning",
|
|
245
|
+
path=Path(os.path.join(_HERE, "skills", "app-planning", "SKILL.md")),
|
|
246
|
+
description="Cold-start router for adia-ui consumer-app work. Use when the user asks to \"build/start an adia-ui app\", \"add a surface\", \"orient in this repo\" — run FIRST, also on any task whose mode/shape/shell is undecided — classifies four axes on cited signals, emits an Orientation Record, routes onward. NOT for framework-monorepo internals (adia-ui-forge).",
|
|
247
|
+
)
|
|
248
|
+
ctx.register_skill(
|
|
249
|
+
name="chart-selection",
|
|
250
|
+
path=Path(os.path.join(_HERE, "skills", "chart-selection", "SKILL.md")),
|
|
251
|
+
description="Which adia-ui component renders a chart, graph, sparkline, gauge, or heatmap, and how to wire its data/legend/theming. Use for \"add a chart\", \"show a graph\", \"visualize this data\", \"add a sparkline/gauge/heatmap\", or \"wire a chart legend\". NOT for the surrounding screen (screen-composition), color tokens (token-selection), or data fetching (data-wiring).",
|
|
252
|
+
)
|
|
253
|
+
ctx.register_skill(
|
|
254
|
+
name="data-wiring",
|
|
255
|
+
path=Path(os.path.join(_HERE, "skills", "data-wiring", "SKILL.md")),
|
|
256
|
+
description="Data, state & hydration in an adia-ui app. Use for \"wire up the data\" / \"manage state\" / \"hydrate the island\": pattern choice (signals · shared app store · Service/Command · DataClient · property-API · data-*), hydration per mode (SPA/SSR/hybrid). NOT for host bootstrap/registration (host-wiring) or screen markup (screen-composition).",
|
|
257
|
+
)
|
|
258
|
+
ctx.register_skill(
|
|
259
|
+
name="domain-planning",
|
|
260
|
+
path=Path(os.path.join(_HERE, "skills", "domain-planning", "SKILL.md")),
|
|
261
|
+
description="Reasons through a PRD, spec, mockup, schema, or role/user-story BEFORE any UI is chosen — resolves intent, domain entities, roles, tasks, and decisions, then scores a semantic wireframe against the gate dimensions. Use when the input is spec-shaped (not a signed-off wireframe) and no Domain Plan exists yet for it. Preloaded by app-planning-agent; produces the Orientation Record's Domain Plan block. NOT for composing the UI itself (screen-composition) or classifying rendering mode/shape/shell (app-planning).",
|
|
262
|
+
)
|
|
263
|
+
ctx.register_skill(
|
|
264
|
+
name="find-unused",
|
|
265
|
+
path=Path(os.path.join(_HERE, "skills", "find-unused", "SKILL.md")),
|
|
266
|
+
description="Finds what a non-breaking @adia-ai upgrade shipped that this app never picked up — the opt-in layers nothing imports, the local workarounds a fixed bug made redundant, retired enum values still sitting in stored state, and the fixes that never reached MIGRATION.md. Use after \"we bumped and nothing broke\", \"what are we missing from 0.8.x\", \"are we actually using what we ship\", \"why is [scale]/[theme] doing nothing\", or when a PATCH span needs adoption rather than repair. NOT for breaking-change repair (app-migration); NOT for a first-time install (adia-scaffold); NOT for diagnosing a broken surface (app-audit).",
|
|
267
|
+
)
|
|
268
|
+
ctx.register_skill(
|
|
269
|
+
name="gen-ui-wiring",
|
|
270
|
+
path=Path(os.path.join(_HERE, "skills", "gen-ui-wiring", "SKILL.md")),
|
|
271
|
+
description="Authors a runtime generative-UI experience on the a2ui runtime — mounts a2ui-root/gen-root, wires generate_ui + data resolvers, grounds generation in a corpus (harvest chunks from our own pages, point retrieval at it). Use when END USERS generate UI at runtime. NOT for one-shot 'generate UI for X' screen asks (screen-composition), chat features (llm-wiring), or pipeline/MCP tool ops (adia-forge's a2ui-maintenance).",
|
|
272
|
+
)
|
|
273
|
+
ctx.register_skill(
|
|
274
|
+
name="host-wiring",
|
|
275
|
+
path=Path(os.path.join(_HERE, "skills", "host-wiring", "SKILL.md")),
|
|
276
|
+
description="Wires an adia-ui app's host — picks SPA/SSR/hybrid, then that mode's registration, CSS cascade, routing ownership. Use for \"wire the host\", \"set up index.html\", unstyled or non-upgrading elements, \"HTMLElement is not defined\" under Next/Nuxt/SvelteKit/Astro. NOT for screen UI (screen-composition), data/state (data-wiring), app layout (project-scaffolding).",
|
|
277
|
+
)
|
|
278
|
+
ctx.register_skill(
|
|
279
|
+
name="llm-wiring",
|
|
280
|
+
path=Path(os.path.join(_HERE, "skills", "llm-wiring", "SKILL.md")),
|
|
281
|
+
description="The @adia-ai/llm client contract — chat/streamChat streaming, StreamChunk, smart-proxy vs passthrough key security, chat-shell wiring. Use when adding a chat box or any LLM feature to an adia-ui app. NOT for runtime gen-UI (gen-ui-wiring), one-shot intent→screen composition (screen-composition), or @adia-ai/llm internals (adia-forge's llm-client-maintenance).",
|
|
282
|
+
)
|
|
283
|
+
ctx.register_skill(
|
|
284
|
+
name="pattern-catalog",
|
|
285
|
+
path=Path(os.path.join(_HERE, "skills", "pattern-catalog", "SKILL.md")),
|
|
286
|
+
description="Index of adia-ui's pre-assembled surfaces — hundreds of patterns and template screens (auth, registration, onboarding, settings, dashboards) — see references/pattern-index.md for the current count. Use BEFORE composing any screen from primitives, or when asked \"is there an existing pattern/template for X\", \"start from a pattern\", \"what patterns exist\". Answers and points at source — NOT for composing new UI (screen-composition), shell chrome (shell-selection), or authoring new patterns (primitive-authoring).",
|
|
287
|
+
)
|
|
288
|
+
ctx.register_skill(
|
|
289
|
+
name="project-scaffolding",
|
|
290
|
+
path=Path(os.path.join(_HERE, "skills", "project-scaffolding", "SKILL.md")),
|
|
291
|
+
description="Lays out an adia-ui app's on-disk structure — picks the project shape (single-surface / rollup / shared-foundation) and page form, scaffolds via scripts/adia-scaffold, gates on the structure rubric. Use for \"scaffold an app\", \"add a page/surface/component\" WHEN mode/shape are already decided, \"audit its structure\". If mode/shape/shell are still undecided, app-planning classifies first. NOT for the UI inside a screen (screen-composition) or host wiring (host-wiring).",
|
|
292
|
+
)
|
|
293
|
+
ctx.register_skill(
|
|
294
|
+
name="screen-composition",
|
|
295
|
+
path=Path(os.path.join(_HERE, "skills", "screen-composition", "SKILL.md")),
|
|
296
|
+
description="Composes adia-ui screens from light-DOM catalog primitives — discovers tags/props via the a2ui MCP, themes via --a-* tokens. Use when asked to build or 'generate UI for' a screen, page, form, dashboard, or nav pattern, or when a PRD/spec/mockup needs UI. NOT for shell chrome (shell-selection), host wiring (host-wiring), runtime gen-UI (gen-ui-wiring).",
|
|
297
|
+
)
|
|
298
|
+
ctx.register_skill(
|
|
299
|
+
name="shell-selection",
|
|
300
|
+
path=Path(os.path.join(_HERE, "skills", "shell-selection", "SKILL.md")),
|
|
301
|
+
description="Picks and composes an adia-ui page-chrome shell (@adia-ai/web-modules): admin (app frame), chat (LLM), editor (canvas+panes), simple (marketing/error), or embed. Use when asked to \"use a shell\", \"sidebar + topbar layout\", \"embed this surface\", or on shell markup debugging. NOT for screens inside it (screen-composition) or host/SSR wiring (host-wiring).",
|
|
302
|
+
)
|
|
303
|
+
ctx.register_skill(
|
|
304
|
+
name="surface-qa",
|
|
305
|
+
path=Path(os.path.join(_HERE, "skills", "surface-qa", "SKILL.md")),
|
|
306
|
+
description="Browser-QA gate for a CONSUMER app's adia-ui surfaces — renders headless with zero console/page errors, non-zero bounding boxes, and a screenshot actually read, plus AdiaUI a11y checks. Use when shipping a surface, on \"verify/QA this page\" or a page that renders blank/empty, or when \"tests pass\" is the only evidence. NOT for composing/fixing UI (screen-composition), structural lint (adia-lint hook), or the framework repo's own dogfood/ demo-page sweep (forge's demo-audit).",
|
|
307
|
+
)
|
|
308
|
+
ctx.register_skill(
|
|
309
|
+
name="table-composition",
|
|
310
|
+
path=Path(os.path.join(_HERE, "skills", "table-composition", "SKILL.md")),
|
|
311
|
+
description="Answers how to display/organize tabular data with table-ui: contained vs uncontained chrome, [raw] (consumer-owned body, a separate axis), opt-in striped rows, and resize/sort defaults that flip between JS .columns and declarative col-def forms, plus inline-edit-grid and tree/hierarchical-row patterns. Use for \"how do I show a table\", \"add sorting/filtering\", \"make this table striped\", \"columns aren't resizable\", \"card vs bare table\", \"editable/spreadsheet grid\", \"tree table / nested rows\", \"huge list of rows\". NOT for composing the surrounding screen (screen-composition), data wiring (data-wiring), OTHER non-table patterns (pattern-catalog), or 1000+-row virtualized lists (list-window-ui).",
|
|
312
|
+
)
|
|
313
|
+
ctx.register_skill(
|
|
314
|
+
name="token-selection",
|
|
315
|
+
path=Path(os.path.join(_HERE, "skills", "token-selection", "SKILL.md")),
|
|
316
|
+
description="Answers which color token/role an adia-ui surface should use — role grammar, pairing laws, state families, the --a-* alias layer. Use when asked \"which token for this background/text/hover/border\" or \"--a-* or --md-sys-color-*\". ANSWERS only. NOT for composing the screen (screen-composition) or designing/verifying palettes (framework-side).",
|
|
317
|
+
)
|
|
318
|
+
ctx.register_skill(
|
|
319
|
+
name="ui-architect",
|
|
320
|
+
path=Path(os.path.join(_HERE, "skills", "ui-architect", "SKILL.md")),
|
|
321
|
+
description="Whole-deliverable coordinator: runs the app-planning → screen-composition → surface-qa workflow for one entire multi-surface app or feature — gear selection, wave decomposition, generator-≠-reviewer separation, the four-lap plan/build/QA cap per wave, failure routing, and the closing VerifyProof. Portable across runtimes — permits native multi-agent delegation where the installed runtime provides it, and states the serial single-context fallback otherwise. Use on an end-to-end delivery ask: \"make an app that...\", \"coordinate everything in this PRD and open the PRs\", \"take this spec and ship the whole thing\". NOT for a lone classify/plan ask with nothing to deliver yet (app-planning keeps that territory entirely); NOT for one already-scoped screen (screen-composition); NOT for grading an existing surface (surface-qa).",
|
|
322
|
+
)
|
|
323
|
+
ctx.register_skill(
|
|
324
|
+
name="wave-coordination",
|
|
325
|
+
path=Path(os.path.join(_HERE, "skills", "wave-coordination", "SKILL.md")),
|
|
326
|
+
description="Team-pattern mechanics for a multi-screen build under ui-architect's GEAR 2 — who merges parallel screen-composition-agent branches and when, PR/branch mechanics, shared-file conflict rules for shared-foundation shapes, and how to size a wave. Use when planning or running a GEAR-2 dispatch: \"how do two parallel screen-composition-agent branches come back together\", \"who merges\", \"how big should a wave be\", \"what happens when two screens touch the same shared file\". NOT for picking a project's shape (project-scaffolding, which this skill's conflict rules build on) or composing one screen (screen-composition).",
|
|
327
|
+
)
|
|
328
|
+
ctx.register_command(
|
|
329
|
+
"ui-architect",
|
|
330
|
+
_ui_architect_command_handler(ctx),
|
|
331
|
+
description="Whole-deliverable coordinator: runs the app-planning → screen-composition → surface-qa workflow for one entire multi-surface app or feature — gear selection, wave decomposition, generator-≠-reviewer separation, the four-lap plan/build/QA cap per wave, failure routing, and the closing VerifyProof. Portable across runtimes — permits native multi-agent delegation where the installed runtime provides it, and states the serial single-context fallback otherwise. Use on an end-to-end delivery ask: \"make an app that...\", \"coordinate everything in this PRD and open the PRs\", \"take this spec and ship the whole thing\". NOT for a lone classify/plan ask with nothing to deliver yet (app-planning keeps that territory entirely); NOT for one already-scoped screen (screen-composition); NOT for grading an existing surface (surface-qa).",
|
|
332
|
+
args_hint="<brief, or a path to a PRD>",
|
|
333
|
+
)
|
|
@@ -12,10 +12,10 @@ skills:
|
|
|
12
12
|
- domain-planning
|
|
13
13
|
# Explicit pin (gh#618, tier corrected gh#1045): never `inherit` — the
|
|
14
14
|
# caller's tier would silently decide what model produces the Orientation
|
|
15
|
-
# Record.
|
|
16
|
-
#
|
|
17
|
-
model:
|
|
18
|
-
effort:
|
|
15
|
+
# Record. Operator's explicit standing instruction for this seat family:
|
|
16
|
+
# sonnet + xhigh.
|
|
17
|
+
model: sonnet
|
|
18
|
+
effort: xhigh
|
|
19
19
|
---
|
|
20
20
|
|
|
21
21
|
The app-planning-agent classifies before it plans — rendering mode, project
|
|
@@ -14,6 +14,7 @@ skills:
|
|
|
14
14
|
# non-preloadable shape; end-user runtime gen-UI is its own charter's
|
|
15
15
|
# territory, distinct from this seat's one-shot screen composition.
|
|
16
16
|
model: sonnet
|
|
17
|
+
effort: xhigh
|
|
17
18
|
---
|
|
18
19
|
|
|
19
20
|
The screen-composition-agent executes an Orientation Record (or a directly-scoped
|
|
@@ -10,11 +10,10 @@ tools: Read, Grep, Glob, Bash
|
|
|
10
10
|
skills:
|
|
11
11
|
- surface-qa
|
|
12
12
|
# Explicit pin (gh#618, tier corrected gh#1045): a review/critic seat's
|
|
13
|
-
# verdict must not depend on the caller's model tier — never `inherit
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
effort: high
|
|
13
|
+
# verdict must not depend on the caller's model tier — never `inherit`.
|
|
14
|
+
# Operator's explicit standing instruction for this seat family: sonnet + xhigh.
|
|
15
|
+
model: sonnet
|
|
16
|
+
effort: xhigh
|
|
18
17
|
---
|
|
19
18
|
|
|
20
19
|
The surface-qa-agent grades work it did not build — the reviewer seat that
|