Conversation
gloryfromca
left a comment
There was a problem hiding this comment.
No blockers; suggestions only, and they are marked inline.
I reviewed github/main...3d7014c73be1, the surrounding skills component, store, live source, CSS, callers, and relevant history. I also checked backward compatibility, test strength (the drawer query was narrowed rather than weakened), AGENTS.md constraints, CONTEXT-MAP.md architecture boundaries, and domain terminology. The implementation is otherwise consistent with the existing guarded drawer removal path.
Verification:
npm test --prefix ui-web: passed, 103 files and 1,681 tests. happy-dom emitted abort/connection diagnostics from iframe fetch fixtures, but the command exited 0.npm run type-check --prefix ui-web: passed.npm run gen:check --prefix ui-web: passed.git diff --check github/main...HEAD: passed.
One keyboard-path suggestion is inline; it does not block this change.
3d7014c to
061c2b9
Compare
gloryfromca
left a comment
There was a problem hiding this comment.
No blockers; suggestions only, and they are marked inline.
The branch was rebased onto current main; git range-diff confirms the PR patch is unchanged from 3d7014c73be1. I rechecked the full diff plus the affected component, store/live-source callers, history, compatibility, test changes, and repository architecture/rules. There are no new findings. The existing Enter-key propagation follow-up remains nonblocking and is still recorded inline.
Verification on this revision:
npm test --prefix ui-web: passed, 103 files and 1,681 tests. happy-dom again emitted its iframe teardown network diagnostics, but the command exited 0.npm run type-check --prefix ui-web: passed.npm run gen:check --prefix ui-web: passed.git diff --check github/main...HEAD: passed.
Removing an installed hub skill was reachable only from the detail drawer, and the card gave no sign it opened one: the use button was the only thing on it that looked like an action, so a reader who wanted a skill gone concluded the page could not do it and went to the CLI -- where the argument is the hub slug, not the name the card shows. The card's footer now carries the same armed remove the drawer does, gated on the same predicate: a builtin has no bundle to delete, so only a hub install offers it. `ArmRemove` gains an `inline` flag that drops the top margin meant for a drawer section; it already stopped propagation, which is what keeps the press off the card's own open-the-drawer handler. One existing drawer test now scopes its query to the drawer. It searched the whole document for the uninstall label, which was unambiguous while the card had none and matches two once the card has one. Co-authored-by: Claude (claude-opus-5) <noreply@anthropic.com>
Enter on the remove button reached the card's own handler first. Keydown bubbles, and the click that stops propagation is synthesised after it, so the drawer opened before the button could act on the press. That is worse than a stray navigation because the control is deliberately two presses: the first arms it, the second removes. With the first press navigating away there was no second press to make, so the action the card exists to offer could not be completed from the keyboard at all -- while the mouse path, which this card was added for, worked throughout. The card's handler now answers only for the card. A press that started on something inside it belongs to that thing, which already knows what to do with it. Co-authored-by: Claude (claude-opus-5) <noreply@anthropic.com>
061c2b9 to
fd27fe3
Compare
gloryfromca
left a comment
There was a problem hiding this comment.
No blockers; this can merge as far as I am concerned.
The new target/currentTarget guard fixes the keyboard event-ordering issue without changing direct card activation, and the regression test covers the failing path through removal. I reviewed the revision delta and full PR diff, affected component/store callers, relevant history, backward compatibility, test strength, AGENTS.md/CONTEXT-MAP.md constraints, and architecture boundaries. I found no new issues. My prior thread is resolved.
Verification:
npm ci --prefix ui-web: completed; npm warned that local Node 23 is outside Vitest's declared engine range.npm test --prefix ui-web: passed, 106 files and 1,732 tests. happy-dom emitted its existing iframe teardown network diagnostics, but the command exited 0.npm run type-check --prefix ui-web: passed.npm run gen:check --prefix ui-web: passed, 172 methods match.git diff --check github/main...HEAD: passed.
|
Not a blocker -- the card's remove and the drawer's remove do not guard the same way, and the card's can fire twice. The comment on the new button says it uses the same guard as the drawer:
That is half of it. The drawer's guard is Measured on
The control is the point: this is not how Why non-blocking: I could not show harm from the duplicate. The second call is If you want it closed, the smallest thing that matches the drawer is to give the card the same Checked and NOT worth raising, recorded so nobody re-derives them: the three withdrawal mutations all bite (drop the |
|
No blockers; suggestions only, and they are marked inline. The measurement from @0xKT changes my standing stance from clean to nonblocking. The observation holds: The existing note fully captures the follow-up; I have no additional finding. Focused verification on the unchanged head: |
Summary
Removing an installed skill was reachable only by opening the detail drawer, and
the card gave no sign it opened one. The card is a
role="button"that opens thedrawer on click, but the only thing on it that looks like an action is the use
button, so a reader who wants a skill gone reads the card as "use only" and goes
to the CLI -- where
raven skill removetakes the hub slug(
kbarbel640-del_skills_ai-ppt-generator), not the name the card shows(
ai-ppt-generator), and answers a bare "No installed Hub bundle found" for thename it does show.
The card's footer now carries the same armed remove the drawer already has,
gated on the same predicate, so the capability the page already had is visible
where the reader looks for it.
The predicate is
hub, which is not the same as "the source column sayshub". It is set from a
.skillhub.jsonmarker written beside the skill atinstall time, and
skillhub.removeneeds the id that marker holds. A bundleinstalled before the marker existed reads
hub: falseand offers no button --the same answer the drawer gives it today, unchanged by this.
Checked and deliberately not changed.
ArmRemovekeeps its two-click arm rather than growing a confirm dialog: theWKWebView shell has no JS-panel delegate, which is why the arm exists.
stopPropagation, so the press does not reach it; verified in a browser ratherthan reasoned about, and pinned by a test.
different readers and neither is redundant.
Type
Verification
Gates, each run as its own target and its exit code read directly:
Baseline,
npx vitest run --no-file-parallelismin a detached worktree atupstream/main(5b7566b), run the same way:Failing ids diffed rather than counted: 0 introduced. Neither side has a
failure to reconcile; the three extra tests are this branch's own.
Mutation-checked, each reverted afterwards with a clean
git status:ArmRemovefailsoffers removal on the installed card itselfandkeeps the drawer shut when the remove on the card is pressed,and nothing else.
c.hubguard withtruefailsoffers no removal for a builtin, and nothing else.Verified in a browser against a live gateway, not only in tests. With
amap-weather(hub, marker present),resume-master(hub, no marker) and twobuiltins installed: the button appears on the first and on neither of the others;
the first press relabels to the confirm and does not open the drawer; the second
removes the skill. The rail went from five rows to four and
<workspace>/skills/amap-weatheris gone from disk.CI, and what is red
Three jobs are red and none of them is this branch's.
mainfails the samethree at
5b7566b4, which is this branch's merge base, in run34744930015:The sets are identical.
page checksalso reproduces locally at that sha, in adetached worktree built from an untouched tree, with the same message:
Nine jobs pass, including every one this change could plausibly reach:
TUI checks,ui rpc contract,pre-commit diff,python lint,commit messages,repository files,bridge checks,kernel wheel smokeandpull request title.Risk
User-visible and the point of the change: an installed skill whose bundle can be
deleted now shows a remove control on its card. Destructive, so it is the armed
control the drawer already uses -- one press to arm, a second within four
seconds to fire, and the arm lapses on its own.
No behaviour outside the card: no RPC, no schema, no dependency, no change to
what
skillhub.removedoes or to which skills qualify.ArmRemovegains anoptional
inlineflag that drops a top margin meant for a drawer section; itsone existing caller passes nothing and renders as before.
One existing drawer test now scopes its query to the drawer. It searched the
whole document for the uninstall label, which was unambiguous while the card had
none and matches two once the card has one. The assertion it makes is unchanged.
Rollback is reverting the commit; nothing here is stateful or migrated.
Related Issues
N/A