@event4u/agent-config 1.14.0 → 1.15.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/.agent-src/commands/agent-handoff.md +1 -1
- package/.agent-src/commands/bug-fix.md +2 -2
- package/.agent-src/commands/chat-history-checkpoint.md +2 -2
- package/.agent-src/commands/chat-history-clear.md +1 -1
- package/.agent-src/commands/chat-history-resume.md +2 -2
- package/.agent-src/commands/chat-history.md +2 -2
- package/.agent-src/commands/check-current-md.md +43 -32
- package/.agent-src/commands/commit-in-chunks.md +43 -23
- package/.agent-src/commands/compress.md +34 -2
- package/.agent-src/commands/feature-roadmap.md +2 -2
- package/.agent-src/commands/fix-portability.md +2 -2
- package/.agent-src/commands/onboard.md +14 -5
- package/.agent-src/commands/optimize-augmentignore.md +9 -0
- package/.agent-src/commands/refine-ticket.md +9 -7
- package/.agent-src/commands/review-changes.md +35 -8
- package/.agent-src/commands/roadmap-create.md +13 -2
- package/.agent-src/commands/roadmap-execute.md +9 -7
- package/.agent-src/commands/set-cost-profile.md +8 -0
- package/.agent-src/commands/sync-agent-settings.md +9 -0
- package/.agent-src/commands/tests-execute.md +2 -3
- package/.agent-src/rules/artifact-engagement-recording.md +1 -1
- package/.agent-src/rules/augment-portability.md +56 -37
- package/.agent-src/rules/chat-history-cadence.md +109 -0
- package/.agent-src/rules/chat-history-ownership.md +123 -0
- package/.agent-src/rules/chat-history-visibility.md +96 -0
- package/.agent-src/rules/cli-output-handling.md +1 -1
- package/.agent-src/rules/command-suggestion.md +3 -2
- package/.agent-src/rules/commit-policy.md +44 -34
- package/.agent-src/rules/direct-answers.md +1 -1
- package/.agent-src/rules/language-and-tone.md +19 -15
- package/.agent-src/rules/non-destructive-by-default.md +18 -18
- package/.agent-src/rules/roadmap-progress-sync.md +133 -74
- package/.agent-src/rules/role-mode-adherence.md +1 -1
- package/.agent-src/rules/size-enforcement.md +2 -1
- package/.agent-src/rules/user-interaction.md +28 -4
- package/.agent-src/scripts/update_roadmap_progress.py +56 -4
- package/.agent-src/skills/blade-ui/SKILL.md +29 -10
- package/.agent-src/skills/command-writing/SKILL.md +15 -4
- package/.agent-src/skills/existing-ui-audit/SKILL.md +24 -9
- package/.agent-src/skills/fe-design/SKILL.md +20 -15
- package/.agent-src/skills/file-editor/SKILL.md +9 -0
- package/.agent-src/skills/livewire/SKILL.md +26 -7
- package/.agent-src/skills/refine-ticket/SKILL.md +30 -24
- package/.agent-src/skills/roadmap-management/SKILL.md +22 -16
- package/.agent-src/skills/skill-writing/SKILL.md +3 -3
- package/.agent-src/skills/upstream-contribute/SKILL.md +2 -2
- package/.agent-src/templates/agent-settings.md +1 -1
- package/.agent-src/templates/roadmaps.md +9 -8
- package/.agent-src/templates/scripts/memory_lookup.py +1 -1
- package/.agent-src/templates/scripts/work_engine/__init__.py +2 -2
- package/.agent-src/templates/scripts/work_engine/cli.py +64 -461
- package/.agent-src/templates/scripts/work_engine/cli_args.py +116 -0
- package/.agent-src/templates/scripts/work_engine/delivery_state.py +3 -3
- package/.agent-src/templates/scripts/work_engine/directives/backend/__init__.py +1 -1
- package/.agent-src/templates/scripts/work_engine/directives/backend/implement.py +1 -1
- package/.agent-src/templates/scripts/work_engine/directives/backend/memory.py +1 -1
- package/.agent-src/templates/scripts/work_engine/directives/backend/plan.py +1 -1
- package/.agent-src/templates/scripts/work_engine/directives/backend/report.py +1 -1
- package/.agent-src/templates/scripts/work_engine/dispatcher.py +1 -1
- package/.agent-src/templates/scripts/work_engine/emitters.py +43 -0
- package/.agent-src/templates/scripts/work_engine/errors.py +19 -0
- package/.agent-src/templates/scripts/work_engine/hook_bootstrap.py +76 -0
- package/.agent-src/templates/scripts/work_engine/input_builders.py +163 -0
- package/.agent-src/templates/scripts/work_engine/migration/v0_to_v1.py +34 -2
- package/.agent-src/templates/scripts/work_engine/persona_policy.py +1 -1
- package/.agent-src/templates/scripts/work_engine/resolvers/prompt.py +1 -1
- package/.agent-src/templates/scripts/work_engine/state_io.py +202 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/AGENTS.md +6 -4
- package/CHANGELOG.md +83 -8
- package/README.md +24 -23
- package/docs/MIGRATION.md +122 -0
- package/docs/architecture.md +83 -34
- package/docs/contracts/STABILITY.md +95 -0
- package/docs/contracts/adr-chat-history-split.md +132 -0
- package/docs/contracts/adr-command-suggestion.md +146 -0
- package/docs/contracts/adr-implement-ticket-runtime.md +122 -0
- package/docs/contracts/adr-product-ui-track.md +384 -0
- package/docs/contracts/adr-prompt-driven-execution.md +187 -0
- package/docs/contracts/agent-memory-contract.md +149 -0
- package/docs/contracts/artifact-engagement-flow.md +262 -0
- package/docs/contracts/command-clusters.md +126 -0
- package/docs/contracts/command-suggestion-flow.md +148 -0
- package/docs/contracts/implement-ticket-flow.md +628 -0
- package/docs/contracts/linear-ai-rules-inclusion.md +143 -0
- package/docs/contracts/linear-ai-three-layers.md +131 -0
- package/docs/contracts/rule-interactions.md +107 -0
- package/docs/contracts/rule-interactions.yml +142 -0
- package/docs/contracts/ui-stack-extension.md +236 -0
- package/docs/contracts/ui-track-flow.md +338 -0
- package/docs/getting-started.md +2 -2
- package/docs/installation.md +42 -6
- package/docs/migrations/commands-1.15.0.md +112 -0
- package/docs/ui-track-mental-model.md +121 -0
- package/package.json +1 -1
- package/scripts/build_linear_digest.py +4 -4
- package/scripts/check_portability.py +2 -0
- package/scripts/check_public_links.py +185 -0
- package/scripts/check_references.py +1 -0
- package/scripts/lint_no_new_atomic_commands.py +179 -0
- package/scripts/lint_rule_interactions.py +149 -0
- package/scripts/memory_lookup.py +1 -1
- package/scripts/release.py +297 -64
- package/scripts/skill_linter.py +14 -0
- package/scripts/update_counts.py +10 -0
- package/.agent-src/rules/chat-history.md +0 -200
|
@@ -18,6 +18,7 @@ EXACTLY ONE LINE NAMES THE RECOMMENDED NUMBER. NO INLINE TAG. NO SECOND PROSE NU
|
|
|
18
18
|
THE OPTION BLOCK STAYS NEUTRAL. THE RECOMMENDATION LINE IS THE ONLY SOURCE OF TRUTH.
|
|
19
19
|
DRIFT BETWEEN OPTION-BLOCK AND PROSE IS STRUCTURALLY IMPOSSIBLE WHEN THE TAG DOES NOT EXIST.
|
|
20
20
|
MISSING RECOMMENDATION = RULE VIOLATION, NOT A SLIP.
|
|
21
|
+
POSITION-AGNOSTIC. END-OF-TURN MENUS COUNT. NEXT-STEP LISTS COUNT. NO EXCEPTIONS.
|
|
21
22
|
```
|
|
22
23
|
|
|
23
24
|
The agent has read the code, the contracts, the trade-offs. Refusing
|
|
@@ -25,6 +26,16 @@ to take a position dumps that work back on the user. Take the
|
|
|
25
26
|
position; be wrong out loud if needed. "Egal, was bevorzugst Du?" /
|
|
26
27
|
"no preference" is NEVER acceptable.
|
|
27
28
|
|
|
29
|
+
**Position-agnostic — closes the most common slip:** End-of-turn
|
|
30
|
+
"Wie weiter?" / "What next?" / "How to proceed?" / "How should we
|
|
31
|
+
continue?" blocks with numbered options are **numbered-options
|
|
32
|
+
blocks**. Same Iron Law applies — exactly one `Empfehlung: N` /
|
|
33
|
+
`Recommendation: N` line, every time. There is no "these are just
|
|
34
|
+
follow-up suggestions" exception, no "the user knows better here"
|
|
35
|
+
exception, no "I genuinely don't have a preference" exception. If
|
|
36
|
+
the agent prints `1. … 2. … 3. …` anywhere in the reply, the
|
|
37
|
+
recommendation line is mandatory.
|
|
38
|
+
|
|
28
39
|
**Format — non-negotiable:**
|
|
29
40
|
|
|
30
41
|
- Options block stays NEUTRAL — no `(recommended)`, no `(rec)`, no `←`, no bold, no checkmark.
|
|
@@ -58,16 +69,28 @@ SKIPPING IT IS A RULE VIOLATION, NOT A SLIP.
|
|
|
58
69
|
```
|
|
59
70
|
|
|
60
71
|
Before emitting any reply that contains numbered options, scan the
|
|
61
|
-
drafted
|
|
72
|
+
**entire drafted reply** — top to bottom, including end-of-turn
|
|
73
|
+
"Wie weiter?" / "What next?" continuation menus, follow-up
|
|
74
|
+
suggestion blocks, and any list of `1. … 2. … 3. …` regardless of
|
|
75
|
+
its position or framing:
|
|
62
76
|
|
|
63
77
|
1. Count occurrences of `(recommended)` / `(rec)` / `(empfohlen)` inline next to a numbered option → MUST be **zero**. Found one → rewrite, drop the tag.
|
|
64
|
-
2. Count
|
|
65
|
-
3.
|
|
78
|
+
2. Count `1\.\s` / `2\.\s` / `3\.\s` patterns inside blockquotes or top-level prose → if **any** numbered-option block exists anywhere in the reply, the recommendation line is mandatory.
|
|
79
|
+
3. Count distinct `Recommendation:\s*N` / `Empfehlung:\s*N` lines (case-insensitive) → MUST be **exactly one per options block**. Zero → add one. Two or more distinct numbers → rewrite, pick one.
|
|
80
|
+
4. The number on the recommendation line MUST exist in the option block it follows.
|
|
81
|
+
5. If the reply has multiple options blocks (e.g. a clarification block AND an end-of-turn menu), each block gets its own `Recommendation: N` line directly underneath.
|
|
66
82
|
|
|
67
83
|
Mechanical backstop: `python3 scripts/check_reply_consistency.py --stdin < draft.md`
|
|
68
84
|
(non-zero exit on any rule above). Self-scan is the primary gate; the
|
|
69
85
|
script is the deterministic safety net for ambiguous cases.
|
|
70
86
|
|
|
87
|
+
### Common failure modes — known, named, no excuses
|
|
88
|
+
|
|
89
|
+
- **End-of-turn menu skipped.** Reply answers the question fine, then ends with `> 1. Foo > 2. Bar > 3. Stop` and no `Empfehlung:`. Iron Law 1 was violated — these are numbered options, position is irrelevant.
|
|
90
|
+
- **"Genuinely no preference" hedge.** Pick anyway. The agent has more context than the user on the trade-off; refusing to pick dumps the work back. Pick the safest option, name the flip-condition.
|
|
91
|
+
- **"User knows the project better" hedge.** Same failure mode, different costume. The user asked for an opinion by virtue of accepting the options block; deliver it.
|
|
92
|
+
- **Multi-block reply with one recommendation.** Two options blocks but only one `Empfehlung:` line — the second block is unguarded. Rule 5 above closes this.
|
|
93
|
+
|
|
71
94
|
## Numbered Options — Always
|
|
72
95
|
|
|
73
96
|
When asking the user a question with predefined choices, **always
|
|
@@ -87,9 +110,10 @@ just a number (e.g., `1`) instead of typing a sentence.
|
|
|
87
110
|
### Rules
|
|
88
111
|
|
|
89
112
|
- **Every question with choices** must use numbered options — no exceptions.
|
|
113
|
+
- **Every numbered list with `1. … 2. … 3. …`** is a numbered-options block, regardless of position. End-of-turn "Wie weiter?" / "What next?" / "How to proceed?" menus, mid-reply continuation prompts, and clarification blocks all count.
|
|
90
114
|
- **Keep options short** — one line each, with a brief explanation after the dash.
|
|
91
115
|
- **Always include a "skip" or "no change" option** when applicable.
|
|
92
|
-
- **Always state a recommendation** — Iron Law 1 above.
|
|
116
|
+
- **Always state a recommendation** — Iron Law 1 above. Per options block, every time, position-agnostic.
|
|
93
117
|
- **Use the user's language** for the question and options.
|
|
94
118
|
- **Accept both** the number and a natural language answer (e.g., "1" or "the first one").
|
|
95
119
|
|
|
@@ -16,6 +16,13 @@ Checkbox states:
|
|
|
16
16
|
Percentage = done / (done + open). Deferred and cancelled do not count towards
|
|
17
17
|
"open" (they are explicit decisions).
|
|
18
18
|
|
|
19
|
+
Roadmap visibility is binary:
|
|
20
|
+
|
|
21
|
+
- No `status:` frontmatter (or `status: ready`) → executable, listed.
|
|
22
|
+
- `status: draft` → hidden from the dashboard entirely (not counted,
|
|
23
|
+
not listed). Drafts become visible the moment the frontmatter flag
|
|
24
|
+
is removed or flipped to `ready`.
|
|
25
|
+
|
|
19
26
|
Invocation (from project root):
|
|
20
27
|
python3 .augment/scripts/update_roadmap_progress.py # rewrite
|
|
21
28
|
python3 .augment/scripts/update_roadmap_progress.py --check # CI: exit 1 if stale
|
|
@@ -56,6 +63,13 @@ EXCLUDE_NAMES = {"template.md", "README.md", "progress.md", "roadmaps-progress.m
|
|
|
56
63
|
EXCLUDE_PREFIXES = ("open-questions",)
|
|
57
64
|
EXCLUDE_DIRS = {"archive", "skipped"}
|
|
58
65
|
|
|
66
|
+
# Frontmatter — minimal YAML block at the top of a roadmap. Used to hide
|
|
67
|
+
# drafts (`status: draft`) from the dashboard. Anything else (no
|
|
68
|
+
# frontmatter, `status: ready`, unknown values) counts as a normal
|
|
69
|
+
# executable roadmap.
|
|
70
|
+
FRONTMATTER_RE = re.compile(r"\A---\n(.*?)\n---\s*\n", re.DOTALL)
|
|
71
|
+
DRAFT_VALUES = frozenset({"draft"})
|
|
72
|
+
|
|
59
73
|
|
|
60
74
|
@dataclass
|
|
61
75
|
class PhaseStats:
|
|
@@ -130,6 +144,37 @@ class RoadmapStats:
|
|
|
130
144
|
return round(self.done * 100 / self.total_active) if self.total_active else 0
|
|
131
145
|
|
|
132
146
|
|
|
147
|
+
def parse_frontmatter(text: str) -> dict[str, str]:
|
|
148
|
+
"""Parse a leading YAML frontmatter block. String scalars only.
|
|
149
|
+
|
|
150
|
+
Returns an empty dict if no frontmatter is present. Handles quoted and
|
|
151
|
+
unquoted values; ignores blank lines and comments. Nested keys, lists,
|
|
152
|
+
and multiline scalars are out of scope — the dashboard only needs flat
|
|
153
|
+
string flags (`status`, `mode`).
|
|
154
|
+
"""
|
|
155
|
+
m = FRONTMATTER_RE.match(text)
|
|
156
|
+
if not m:
|
|
157
|
+
return {}
|
|
158
|
+
fm: dict[str, str] = {}
|
|
159
|
+
for line in m.group(1).splitlines():
|
|
160
|
+
stripped = line.strip()
|
|
161
|
+
if not stripped or stripped.startswith("#") or ":" not in line:
|
|
162
|
+
continue
|
|
163
|
+
key, _, value = line.partition(":")
|
|
164
|
+
fm[key.strip()] = value.strip().strip('"').strip("'")
|
|
165
|
+
return fm
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def is_draft(fm: dict[str, str]) -> bool:
|
|
169
|
+
"""Return True when frontmatter declares the roadmap as draft.
|
|
170
|
+
|
|
171
|
+
`status: draft` is the single supported way to hide a roadmap from
|
|
172
|
+
the dashboard. Everything else (no frontmatter, `status: ready`,
|
|
173
|
+
unknown values) counts as an executable roadmap.
|
|
174
|
+
"""
|
|
175
|
+
return fm.get("status", "").lower() in DRAFT_VALUES
|
|
176
|
+
|
|
177
|
+
|
|
133
178
|
def is_roadmap_candidate(path: Path) -> bool:
|
|
134
179
|
if path.name in EXCLUDE_NAMES:
|
|
135
180
|
return False
|
|
@@ -180,10 +225,14 @@ def bar(pct: int, width: int = 10) -> str:
|
|
|
180
225
|
|
|
181
226
|
|
|
182
227
|
def collect(roadmap_root: Path) -> list[RoadmapStats]:
|
|
228
|
+
"""Collect executable roadmaps. Drafts are excluded."""
|
|
183
229
|
results: list[RoadmapStats] = []
|
|
184
230
|
for path in sorted(roadmap_root.rglob("*.md")):
|
|
185
231
|
if not path.is_file() or not is_roadmap_candidate(path):
|
|
186
232
|
continue
|
|
233
|
+
text = path.read_text(encoding="utf-8")
|
|
234
|
+
if is_draft(parse_frontmatter(text)):
|
|
235
|
+
continue
|
|
187
236
|
stats = parse_roadmap(path, roadmap_root)
|
|
188
237
|
if stats:
|
|
189
238
|
results.append(stats)
|
|
@@ -205,14 +254,17 @@ def render(roadmaps: list[RoadmapStats]) -> str:
|
|
|
205
254
|
overall_pct = round(total_done * 100 / total_active) if total_active else 0
|
|
206
255
|
lines: list[str] = []
|
|
207
256
|
lines.append("# Roadmap Progress\n")
|
|
257
|
+
header_meta = (
|
|
258
|
+
f"> {len(roadmaps)} open roadmap"
|
|
259
|
+
f"{'s' if len(roadmaps) != 1 else ''}"
|
|
260
|
+
" · [roadmaps/](roadmaps/) · [archive/](roadmaps/archive/) · "
|
|
261
|
+
"[skipped/](roadmaps/skipped/)\n"
|
|
262
|
+
)
|
|
208
263
|
lines.append(
|
|
209
264
|
"> Auto-generated by `.augment/scripts/update_roadmap_progress.py`. "
|
|
210
265
|
"Do not edit — regenerated on every roadmap-create, -execute, or "
|
|
211
266
|
"completion change (last-modified timestamp lives in git history).\n>\n"
|
|
212
|
-
|
|
213
|
-
f"{'s' if len(roadmaps) != 1 else ''} · "
|
|
214
|
-
"[roadmaps/](roadmaps/) · [archive/](roadmaps/archive/) · "
|
|
215
|
-
"[skipped/](roadmaps/skipped/)\n"
|
|
267
|
+
+ header_meta
|
|
216
268
|
)
|
|
217
269
|
lines.append("## Overall\n")
|
|
218
270
|
lines.append(f"**{total_done} / {total_active} steps done · {overall_pct}%**\n")
|
|
@@ -8,7 +8,11 @@ source: package
|
|
|
8
8
|
|
|
9
9
|
## Positioning — dispatched, not standalone
|
|
10
10
|
|
|
11
|
-
`blade-ui` is the **apply-step executor** for the Blade stack.
|
|
11
|
+
`blade-ui` is the **apply-step executor** for the Blade stack. It is
|
|
12
|
+
invoked by [`directives/ui/apply.py`](../../templates/scripts/work_engine/directives/ui/apply.py)
|
|
13
|
+
once the design brief is locked, and revisited by `review.py` /
|
|
14
|
+
`polish.py` during the design-review loop. It does **not** own the
|
|
15
|
+
flow, does **not** drive the audit, and does **not** lock the design.
|
|
12
16
|
|
|
13
17
|
| Concern | Owner |
|
|
14
18
|
|---|---|
|
|
@@ -27,7 +31,7 @@ Cite this skill when:
|
|
|
27
31
|
Do NOT use when:
|
|
28
32
|
|
|
29
33
|
- API-only endpoints (use `api-endpoint` skill)
|
|
30
|
-
- Livewire components (use `livewire` skill — composes Blade views internally)
|
|
34
|
+
- Livewire components (use `livewire` skill — it composes Blade views internally)
|
|
31
35
|
- Flux UI components (use `flux` skill)
|
|
32
36
|
- Driving the full UI flow yourself — that is the `directives/ui/` orchestrator
|
|
33
37
|
|
|
@@ -39,11 +43,11 @@ Do NOT use when:
|
|
|
39
43
|
2. Inspect existing UI patterns — layouts, partials, component naming, CSS conventions.
|
|
40
44
|
3. Check form handling style — old input, validation errors, session flashes, reusable field partials.
|
|
41
45
|
4. Inspect neighboring templates — match indentation, directives, slot usage, classes.
|
|
42
|
-
5. Determine data flow — controller/view model vs. template.
|
|
46
|
+
5. Determine data flow — what belongs in controller/view model vs. template.
|
|
43
47
|
|
|
44
48
|
### Step 1: Create the template
|
|
45
49
|
|
|
46
|
-
1. Use project's existing layout system.
|
|
50
|
+
1. Use the project's existing layout system.
|
|
47
51
|
2. Keep template presentation-focused — no business logic, no DB queries.
|
|
48
52
|
3. Extract repeated sections into partials or components.
|
|
49
53
|
|
|
@@ -72,12 +76,27 @@ Do NOT use when:
|
|
|
72
76
|
|
|
73
77
|
### Review pass — a11y findings + preview envelope
|
|
74
78
|
|
|
75
|
-
When dispatched by `directives/ui/review.py` (test slot)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
When this skill is dispatched by `directives/ui/review.py` (test slot)
|
|
80
|
+
or `directives/ui/polish.py` (verify slot) — i.e. a review/polish run,
|
|
81
|
+
not the initial apply — it also emits:
|
|
82
|
+
|
|
83
|
+
- `state.ui_review.a11y` — `{violations: [{rule, selector, severity}, ...],
|
|
84
|
+
severity_floor?, accepted_violations?}`. Use the same `(rule, selector)`
|
|
85
|
+
shape as `state.ui_audit.a11y_baseline` so the engine's de-dup matches
|
|
86
|
+
pre-existing entries on replay. Omit the envelope on apply passes; the
|
|
87
|
+
engine's `_apply_a11y_gate` only fires when a baseline is present.
|
|
88
|
+
- `state.ui_review.preview` — `{render_ok: bool, screenshot_path?,
|
|
89
|
+
dom_dump_path?, error?, skipped?}`. `render_ok: false` with `error`
|
|
90
|
+
populated triggers the `preview_render_failed` halt; `render_ok: true`
|
|
91
|
+
with `screenshot_path` threads the screenshot into the delivery
|
|
92
|
+
report's `artifacts` list. Browser tooling (Playwright/Cypress/…) is
|
|
93
|
+
a consumer-project dependency — this package does not ship one.
|
|
94
|
+
|
|
95
|
+
Polish dispatch: when the dispatcher skips `review` because a previous
|
|
96
|
+
review pass already returned `SUCCESS`, this skill MUST itself
|
|
97
|
+
synthesise the updated `state.ui_review.findings` (including any
|
|
98
|
+
remaining `a11y_violation` entries) so the engine's gate sees the
|
|
99
|
+
current state on the next polish round.
|
|
81
100
|
|
|
82
101
|
## Gotcha
|
|
83
102
|
|
|
@@ -67,7 +67,7 @@ suggestion: # required (road-to-context-aware-command-suggesti
|
|
|
67
67
|
---
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Or, when opting out:
|
|
71
71
|
|
|
72
72
|
```yaml
|
|
73
73
|
suggestion:
|
|
@@ -75,10 +75,21 @@ suggestion:
|
|
|
75
75
|
rationale: "one-line reason this command must be invoked deliberately"
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
Suggestion-block rules (linter-enforced):
|
|
79
|
+
|
|
80
|
+
* `eligible` is **required** and must be `true` or `false`.
|
|
81
|
+
* `eligible: true` → both `trigger_description` and `trigger_context` must be
|
|
82
|
+
non-empty (≥ 10 chars each); the linter rejects empty or overly generic
|
|
83
|
+
patterns. The suggestion layer never auto-executes; the user always picks.
|
|
84
|
+
* `eligible: false` → `rationale` must be non-empty. Use the opt-out for
|
|
85
|
+
intentional-only invocations (settings mutations, destructive actions,
|
|
86
|
+
package-internal tools, niche maintenance).
|
|
87
|
+
* Optional `confidence_floor` (0.0–1.0) and `cooldown` (e.g. `10m`)
|
|
88
|
+
override the global settings per command.
|
|
89
|
+
|
|
90
|
+
Eligibility decisions are tracked in
|
|
81
91
|
[`agents/contexts/command-suggestion-eligibility.md`](../../../agents/contexts/command-suggestion-eligibility.md).
|
|
92
|
+
Add or revise entries there before changing a command's `suggestion` block.
|
|
82
93
|
|
|
83
94
|
When iterating on the description, delegate to the
|
|
84
95
|
[`description-assist`](../description-assist/SKILL.md) skill — approval-gated,
|
|
@@ -128,19 +128,31 @@ Record the user's pick in `state.ui_audit.greenfield_decision` (`scaffold` | `ba
|
|
|
128
128
|
|
|
129
129
|
### 8. (Optional) Capture an a11y baseline
|
|
130
130
|
|
|
131
|
-
R4 visual-review-loop contract reads `state.ui_audit.a11y_baseline`
|
|
131
|
+
The R4 visual-review-loop contract reads `state.ui_audit.a11y_baseline`
|
|
132
|
+
when present; the review gate then filters incoming
|
|
133
|
+
`state.ui_review.a11y.violations` against it so pre-existing
|
|
134
|
+
violations stay informational and only NEW or CHANGED entries block
|
|
135
|
+
the polish loop. Without a baseline the gate sees every violation as
|
|
136
|
+
actionable — fine for greenfield, noisy for legacy surfaces.
|
|
132
137
|
|
|
133
|
-
Capture baseline when:
|
|
138
|
+
Capture the baseline when:
|
|
134
139
|
|
|
135
|
-
-
|
|
136
|
-
|
|
140
|
+
- The audit covers components with known a11y debt the project does
|
|
141
|
+
not intend to fix in this run (legacy templates, third-party
|
|
142
|
+
embeds, vendor widgets).
|
|
143
|
+
- The user says "don't block on existing a11y issues" or similar.
|
|
137
144
|
|
|
138
|
-
Skip baseline (omit key, leave `state.ui_audit.a11y_baseline`
|
|
145
|
+
Skip the baseline (omit the key, leave `state.ui_audit.a11y_baseline`
|
|
146
|
+
unset) when:
|
|
139
147
|
|
|
140
|
-
-
|
|
141
|
-
|
|
148
|
+
- The surface is greenfield — the review gate should treat every
|
|
149
|
+
violation as new.
|
|
150
|
+
- The project's a11y posture is "zero known violations" and any
|
|
151
|
+
finding is by definition actionable.
|
|
142
152
|
|
|
143
|
-
Shape (each entry
|
|
153
|
+
Shape (each entry must carry at least `rule` + `selector`; severity
|
|
154
|
+
is optional but recommended so the review gate's severity-floor
|
|
155
|
+
filter behaves the same on replay):
|
|
144
156
|
|
|
145
157
|
```
|
|
146
158
|
state.ui_audit.a11y_baseline = [
|
|
@@ -150,7 +162,10 @@ state.ui_audit.a11y_baseline = [
|
|
|
150
162
|
]
|
|
151
163
|
```
|
|
152
164
|
|
|
153
|
-
Producer parity: review skill that writes
|
|
165
|
+
Producer parity: the review skill that writes
|
|
166
|
+
`state.ui_review.a11y.violations` MUST use the same `(rule, selector)`
|
|
167
|
+
shape, otherwise the engine's de-dup will miss matches and pre-existing
|
|
168
|
+
violations will surface as new findings on every run.
|
|
154
169
|
|
|
155
170
|
### 9. Validate and write findings
|
|
156
171
|
|
|
@@ -8,7 +8,9 @@ source: package
|
|
|
8
8
|
|
|
9
9
|
## Positioning — reference, not executor
|
|
10
10
|
|
|
11
|
-
`fe-design` is a **universal reference skill**, not an executor.
|
|
11
|
+
`fe-design` is a **universal reference skill**, not an executor. It carries
|
|
12
|
+
stack-agnostic heuristics that the UI directive set cites; it does **not**
|
|
13
|
+
own the flow.
|
|
12
14
|
|
|
13
15
|
| Concern | Owner |
|
|
14
16
|
|---|---|
|
|
@@ -35,7 +37,10 @@ Do NOT use this skill to:
|
|
|
35
37
|
|
|
36
38
|
## How the directive set cites this skill
|
|
37
39
|
|
|
38
|
-
`directives/ui/design.py` produces the design brief (layout, components,
|
|
40
|
+
`directives/ui/design.py` produces the design brief (layout, components,
|
|
41
|
+
states, microcopy, a11y). The brief picks heuristics from this reference
|
|
42
|
+
when the audit doesn't already pin a project pattern. Stack-specific
|
|
43
|
+
choices come from the dispatched implementation skill, not from here.
|
|
39
44
|
|
|
40
45
|
## Component Architecture
|
|
41
46
|
|
|
@@ -53,7 +58,8 @@ Page layout
|
|
|
53
58
|
└── Footer (static)
|
|
54
59
|
```
|
|
55
60
|
|
|
56
|
-
|
|
61
|
+
The stack-specific mapping (Blade partial vs. Livewire component vs.
|
|
62
|
+
React island vs. Vue SFC) is the apply-step's concern, not this skill's.
|
|
57
63
|
|
|
58
64
|
### When to use what (kind, not framework)
|
|
59
65
|
|
|
@@ -69,7 +75,7 @@ Stack-specific mapping (Blade partial vs. Livewire component vs. React island vs
|
|
|
69
75
|
|
|
70
76
|
- **One stateful component per concern** — don't build mega-components.
|
|
71
77
|
- **Compose with reusable UI components** for shared shells, headers, fields.
|
|
72
|
-
- **Use the project's library primitives first** — never rebuild what the design system provides (audit findings tell you which).
|
|
78
|
+
- **Use the project's library primitives first** — never rebuild what the design system already provides (audit findings tell you which).
|
|
73
79
|
- **Extract when used 3+ times** — DRY applies to UI too.
|
|
74
80
|
|
|
75
81
|
## Form Design
|
|
@@ -194,20 +200,20 @@ Step indicator (1 — 2 — 3)
|
|
|
194
200
|
|
|
195
201
|
When `directives/ui/design.py` (or any caller) cites this skill:
|
|
196
202
|
|
|
197
|
-
1. **Confirm audit ran first** — `state.ui_audit` from [`existing-ui-audit`](../existing-ui-audit/SKILL.md) is mandatory. Stop and request audit if missing.
|
|
198
|
-
2. **Pick smallest matching section** — Component Architecture, Form Design, Table Design, Responsive Strategy, Accessibility, or UX Principles. Cite by H2/H3 heading, never paste whole skill.
|
|
199
|
-
3. **Defer to audit findings** — when audit pins a project pattern (token, primitive, layout convention), use it.
|
|
200
|
-
4. **Defer to stack apply skill** — Blade vs. Livewire vs. Flux vs. React-shadcn choices come from dispatched implementation skill, never from this reference.
|
|
201
|
-
5. **Surface conflicts** — if heuristic here contradicts an audit finding or stack convention, name both and let caller decide; do not silently pick.
|
|
203
|
+
1. **Confirm the audit ran first** — `state.ui_audit` from [`existing-ui-audit`](../existing-ui-audit/SKILL.md) is mandatory. Stop and request the audit if missing.
|
|
204
|
+
2. **Pick the smallest matching section** — Component Architecture, Form Design, Table Design, Responsive Strategy, Accessibility, or UX Principles. Cite by H2/H3 heading, never paste the whole skill.
|
|
205
|
+
3. **Defer to audit findings** — when the audit pins a project pattern (token, primitive, layout convention), use it. The heuristics here are fallbacks for gaps, not overrides.
|
|
206
|
+
4. **Defer to the stack apply skill** — Blade vs. Livewire vs. Flux vs. React-shadcn choices come from the dispatched implementation skill, never from this reference.
|
|
207
|
+
5. **Surface conflicts** — if a heuristic here contradicts an audit finding or stack convention, name both and let the caller decide; do not silently pick.
|
|
202
208
|
|
|
203
209
|
## Output format
|
|
204
210
|
|
|
205
211
|
When this skill's content is folded into a design brief or review:
|
|
206
212
|
|
|
207
|
-
1. Quote cited heuristic verbatim, with H2/H3 heading and one-line "why this applies" tie-back to request.
|
|
208
|
-
2. Map each heuristic to a concrete artifact in brief (component, form section, table column, breakpoint rule, a11y check, UX state).
|
|
209
|
-
3. Keep stack-agnostic — never name Blade/Livewire/Flux/React primitives in cited prose; apply step adds those.
|
|
210
|
-
4. Mark anything overridden by audit findings as `[audit override]` and link to audit entry.
|
|
213
|
+
1. Quote the cited heuristic verbatim, with the H2/H3 heading and a one-line "why this applies" tie-back to the request.
|
|
214
|
+
2. Map each heuristic to a concrete artifact in the brief (component, form section, table column, breakpoint rule, a11y check, UX state).
|
|
215
|
+
3. Keep stack-agnostic — never name Blade/Livewire/Flux/React primitives in the cited prose; the apply step adds those.
|
|
216
|
+
4. Mark anything overridden by audit findings as `[audit override]` and link to the audit entry.
|
|
211
217
|
|
|
212
218
|
## Related
|
|
213
219
|
|
|
@@ -222,7 +228,7 @@ When this skill's content is folded into a design brief or review:
|
|
|
222
228
|
|
|
223
229
|
## Gotcha
|
|
224
230
|
|
|
225
|
-
- Don't design components without running `existing-ui-audit` first — audit's component/token inventory is canonical for "what already exists in this project". Reinventing is the #1 failure mode.
|
|
231
|
+
- Don't design components without running `existing-ui-audit` first — the audit's component/token inventory is the canonical source for "what already exists in this project". Reinventing is the #1 failure mode.
|
|
226
232
|
- Heuristics in this reference apply across stacks; do not promote them to project rules without checking the audit.
|
|
227
233
|
- Mobile-first is not optional — every layout must work on 320px width.
|
|
228
234
|
|
|
@@ -232,4 +238,3 @@ When this skill's content is folded into a design brief or review:
|
|
|
232
238
|
- Do NOT use fixed pixel widths for responsive layouts.
|
|
233
239
|
- Do NOT ignore accessibility requirements.
|
|
234
240
|
- Do NOT use this skill as an executor — it is a reference cited by `directives/ui/design.py`.
|
|
235
|
-
|
|
@@ -8,6 +8,8 @@ execution:
|
|
|
8
8
|
allowed_tools: []
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
<!-- cloud_safe: noop -->
|
|
12
|
+
|
|
11
13
|
# file-editor
|
|
12
14
|
|
|
13
15
|
## When to use
|
|
@@ -127,3 +129,10 @@ code app/Models/User.php
|
|
|
127
129
|
- Do NOT prompt the user about IDE settings during normal work — suggest `/onboard` (for first-run) or editing `.agent-settings.yml` directly.
|
|
128
130
|
- Do NOT open files that were only read, not edited.
|
|
129
131
|
- Do NOT open more than 10 files at once — summarize instead.
|
|
132
|
+
|
|
133
|
+
## Cloud Behavior
|
|
134
|
+
|
|
135
|
+
On cloud surfaces (Claude.ai Web, Skills API) this skill is **fully inert** —
|
|
136
|
+
there is no local IDE to open files in, no `.agent-settings.yml` to read, and
|
|
137
|
+
no shell handler available. The cloud agent simply finishes its edits and
|
|
138
|
+
reports back; file-opening is a local-agent concern.
|
|
@@ -8,7 +8,11 @@ source: package
|
|
|
8
8
|
|
|
9
9
|
## Positioning — dispatched, not standalone
|
|
10
10
|
|
|
11
|
-
`livewire` is the **apply-step executor** for the Livewire stack.
|
|
11
|
+
`livewire` is the **apply-step executor** for the Livewire stack. It is
|
|
12
|
+
invoked by [`directives/ui/apply.py`](../../templates/scripts/work_engine/directives/ui/apply.py)
|
|
13
|
+
once the design brief is locked, and revisited by `review.py` /
|
|
14
|
+
`polish.py` during the design-review loop. It does **not** own the
|
|
15
|
+
flow, does **not** drive the audit, and does **not** lock the design.
|
|
12
16
|
|
|
13
17
|
| Concern | Owner |
|
|
14
18
|
|---|---|
|
|
@@ -77,12 +81,27 @@ Do NOT use when:
|
|
|
77
81
|
|
|
78
82
|
### Review pass — a11y findings + preview envelope
|
|
79
83
|
|
|
80
|
-
When dispatched by `directives/ui/review.py` (test slot)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
When this skill is dispatched by `directives/ui/review.py` (test slot)
|
|
85
|
+
or `directives/ui/polish.py` (verify slot) — i.e. a review/polish run,
|
|
86
|
+
not the initial apply — it also emits:
|
|
87
|
+
|
|
88
|
+
- `state.ui_review.a11y` — `{violations: [{rule, selector, severity}, ...],
|
|
89
|
+
severity_floor?, accepted_violations?}`. Use the same `(rule, selector)`
|
|
90
|
+
shape as `state.ui_audit.a11y_baseline` so the engine's de-dup matches
|
|
91
|
+
pre-existing entries on replay. Omit the envelope on apply passes; the
|
|
92
|
+
engine's `_apply_a11y_gate` only fires when a baseline is present.
|
|
93
|
+
- `state.ui_review.preview` — `{render_ok: bool, screenshot_path?,
|
|
94
|
+
dom_dump_path?, error?, skipped?}`. `render_ok: false` with `error`
|
|
95
|
+
populated triggers the `preview_render_failed` halt; `render_ok: true`
|
|
96
|
+
with `screenshot_path` threads the screenshot into the delivery
|
|
97
|
+
report's `artifacts` list. Browser tooling (Playwright/Cypress/…) is
|
|
98
|
+
a consumer-project dependency — this package does not ship one.
|
|
99
|
+
|
|
100
|
+
Polish dispatch: when the dispatcher skips `review` because a previous
|
|
101
|
+
review pass already returned `SUCCESS`, this skill MUST itself
|
|
102
|
+
synthesise the updated `state.ui_review.findings` (including any
|
|
103
|
+
remaining `a11y_violation` entries) so the engine's gate sees the
|
|
104
|
+
current state on the next polish round.
|
|
86
105
|
|
|
87
106
|
## Gotcha
|
|
88
107
|
|
|
@@ -47,19 +47,24 @@ execution:
|
|
|
47
47
|
|
|
48
48
|
## Language strategy
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
The refined output's prose language is picked once, up front, and
|
|
51
|
+
applied to every section (refined description, risks, persona voices,
|
|
52
|
+
orchestration notes, close-prompt). Fallback order — first hit wins:
|
|
52
53
|
|
|
53
|
-
1. **User-message language.**
|
|
54
|
-
|
|
54
|
+
1. **User-message language.** If the latest user message is in
|
|
55
|
+
German, the entire output is German; if English, English; etc.
|
|
56
|
+
This honours the global `language-and-tone` iron law.
|
|
55
57
|
2. **Ticket body language.** When the user's message is ambiguous
|
|
56
|
-
(one-word `/refine-ticket PROJ-123`), mirror the language the
|
|
57
|
-
is written in
|
|
58
|
-
3. **`.agent-settings.yml` default
|
|
59
|
-
|
|
58
|
+
(one-word `/refine-ticket PROJ-123`), mirror the language the
|
|
59
|
+
ticket is written in — detected from the summary + description.
|
|
60
|
+
3. **`.agent-settings.yml` default.** If both are silent or unclear,
|
|
61
|
+
fall back to the project default in `.agent-settings.yml`
|
|
62
|
+
(`personal.language` or equivalent). If that is also missing,
|
|
63
|
+
default to English.
|
|
60
64
|
|
|
61
|
-
Quoted identifiers (keys, paths,
|
|
62
|
-
prose mirrors the
|
|
65
|
+
Quoted identifiers (ticket keys, file paths, command names, code
|
|
66
|
+
snippets) stay in their native form. Only the prose mirrors the
|
|
67
|
+
selected language.
|
|
63
68
|
|
|
64
69
|
## Inputs (four equivalent paths)
|
|
65
70
|
|
|
@@ -88,8 +93,8 @@ Delegate to `jira-ticket` §1-3:
|
|
|
88
93
|
If pasted text: skip API, parse markdown, extract title + AC
|
|
89
94
|
bullets + body.
|
|
90
95
|
|
|
91
|
-
**Auto-fetch parent (Phase F4).** Before detection, check the
|
|
92
|
-
type and fold parent context in:
|
|
96
|
+
**Auto-fetch parent (Phase F4).** Before detection, check the
|
|
97
|
+
issue type and fold parent context in:
|
|
93
98
|
|
|
94
99
|
```python
|
|
95
100
|
from scripts.refine_ticket_detect import (
|
|
@@ -105,18 +110,19 @@ if issuetype_needs_parent(ticket["issuetype"]):
|
|
|
105
110
|
```
|
|
106
111
|
|
|
107
112
|
Rules:
|
|
108
|
-
- Applies to `Story` and `Sub-task` (and Linear / Shortcut
|
|
109
|
-
`Task` / `Bug` / `Epic` skip the auto-fetch unless a
|
|
110
|
-
|
|
113
|
+
- Applies to `Story` and `Sub-task` (and their Linear / Shortcut
|
|
114
|
+
equivalents). `Task` / `Bug` / `Epic` skip the auto-fetch unless a
|
|
115
|
+
`parent` link field is already populated — in that case the agent
|
|
116
|
+
folds explicitly without the issuetype guard.
|
|
111
117
|
- `fold_parent_context()` is idempotent; folding twice with the same
|
|
112
118
|
parent does not duplicate the block.
|
|
113
|
-
-
|
|
114
|
-
to orchestration notes:
|
|
119
|
+
- When the parent fetch fails (404, permission, network), skip the
|
|
120
|
+
fold and append a line to orchestration notes:
|
|
115
121
|
*"Parent `<key>` not reachable — AC may lack upstream context."*
|
|
116
122
|
|
|
117
|
-
Parent AC lines surfaced this way must be cited verbatim in the
|
|
118
|
-
output's *Open questions* section so the user sees which
|
|
119
|
-
come from the parent.
|
|
123
|
+
Parent AC lines surfaced this way must be cited verbatim in the
|
|
124
|
+
refined output's *Open questions* section so the user sees which
|
|
125
|
+
constraints come from the parent.
|
|
120
126
|
|
|
121
127
|
### 2. Inspect ticket + detect orchestration triggers
|
|
122
128
|
|
|
@@ -246,8 +252,8 @@ so the user can grab it verbatim.
|
|
|
246
252
|
|
|
247
253
|
## Close-prompt (mandatory final step)
|
|
248
254
|
|
|
249
|
-
**Probe write access first (Phase F6).**
|
|
250
|
-
|
|
255
|
+
**Probe write access first (Phase F6).** Before rendering, do a
|
|
256
|
+
cheap upfront check:
|
|
251
257
|
|
|
252
258
|
```python
|
|
253
259
|
from scripts.refine_ticket_detect import render_close_prompt
|
|
@@ -271,8 +277,8 @@ Behaviour:
|
|
|
271
277
|
| Probe failed (`None`) | Full three-option prompt; skill degrades to copy-paste on selection (v1 fallback) |
|
|
272
278
|
|
|
273
279
|
Per user interaction rules, accept number or free text. `editmeta`
|
|
274
|
-
is cheap and cacheable; cache per Jira project key for
|
|
275
|
-
re-probe on project change.
|
|
280
|
+
is cheap and cacheable; cache the result per Jira project key for
|
|
281
|
+
the session, re-probe on project change.
|
|
276
282
|
|
|
277
283
|
## Output format
|
|
278
284
|
|