Teach the post-0.86 host surface - #5
Merged
Merged
Conversation
The template stopped at Button/Card/Tooltip, which is why plugins
scaffolded from it hand-roll everything: augpool builds a dashboard from
148 raw h() calls, slack uses no host.ui at all, provider-usage styles
its own progress bars and positions popovers with getBoundingClientRect.
They were built the way this template taught them.
Demonstrate what the host gained in 0.86.0, as one page assembled from
independently deletable parts rather than a kitchen sink:
- Card containing a Popover (host-positioned), a Progress bar over a
real bounded ratio, and a Table that swaps to Empty when there is
nothing to show, with Kbd for the new-task hint.
- host.toast on the Clear action. The button stays enabled when the
buffer is empty on purpose, so the .error path is reachable.
- host.utils.formatRelativeTime for the "seen" column and host.utils.cn
for conditional classes.
- host.onThemeChange behind a useHostTheme hook, wired to the one thing
on the page that genuinely needs it.
Also:
- Declare min_kandev_version: "0.86.0" — verified as the first release
containing #2408 and #2410 with git merge-base --is-ancestor. Both the
manifest and README note the check is release-only, so a successful
sideload onto a git-built host proves nothing about the floor.
- Declare access: "public" on the example webhook. The field defaults to
public today and an open PR proposes inverting that to authenticated;
declaring it means the same thing under either default. The comment
explains when each value is right and points at actions: for the
browser-to-plugin case.
- README: use the host's React *and* the host's recharts — same
context/portal hazard for both.
- go.mod: declare cmd/plugin-pack as a tool. Packaging already failed
against current kandev ("missing go.sum entry" for jsonschema/v6);
the tool directive keeps its transitive sums from being tidied away.
|
| Filename | Overview |
|---|---|
| ui/bundle.js | Expands the native page to demonstrate recent-task state, host UI components, utilities, toasts, and a cleaned-up theme subscription; no supported concrete defect was established. |
| manifest.yaml | Adds the minimum host-version floor and explicitly preserves public access for the example webhook. |
| go.mod | Tracks the host plugin-pack command as a Go tool so its transitive dependencies survive module tidying. |
| README.md | Documents the expanded host surface, webhook security choices, minimum-version caveats, and shared React requirements. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
WS[task.created WebSocket event] --> R[recordTask]
R --> B[Bounded recent-task buffer]
B --> P[Plugin page]
P --> T[Recent tasks table or empty state]
P --> G[Progress indicator]
C[Clear button] --> B
C --> O[Host toast]
H[Host theme changes] --> U[useHostTheme]
U --> A[About popover readout]
Reviews (1): Last reviewed commit: "feat: teach the post-0.86 host surface" | Re-trigger Greptile
`make package` was already broken against current kandev before this branch: `go run github.com/kandev/kandev/cmd/plugin-pack` resolves plugin-pack's dependencies against the *plugin's* go.sum, and plugin-pack reaches much further into the backend than server/ does, so it died with "missing go.sum entry" for jsonschema/v6. The first attempt here declared plugin-pack as a `tool` to pull those sums in. That fixed packaging and broke CI's tidy gate: the tool directive expands the tidy graph to plugin-pack's whole tree (otel, gonum, protocompile, regexp2...), and ci.yml checks out kandev main unpinned — so the committed go.sum can only stay tidy for as long as kandev main's dependency set holds still. Wrong trade for a template. Run the tool from inside the sibling checkout instead, where its own go.sum already covers it. go.mod/go.sum go back to exactly main's contents, `go mod tidy` is a no-op again, and packaging works.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The template stopped at
Button/Card*/Tooltip*, which is why plugins scaffolded from it hand-roll everything:augpoolbuilds a dashboard from 148 rawh()calls,slackuses nohost.uiat all,provider-usagestyles its own progress bars and does popover positioning withgetBoundingClientRect. None of that is bad code — it is what this template taught.What the scaffold now demonstrates
One page in
ui/bundle.js, assembled from parts that can be deleted independently:AboutPopoverPopover*, host-positioned — nogetBoundingClientRectmath. HoldsKbd/KbdGroupfor kandev's real new-task binding.Progressover an honest bounded ratio (buffer fill), plushost.utils.cnfor a conditional class.RecentTasksTableTable*, withhost.utils.formatRelativeTimeon the "seen" column.EmptyStateEmpty*— what you see before the first delivery.host.toast.successandhost.toast.error.useHostThemehost.theme+host.onThemeChange, with the unsubscribe returned from the effect.Two deliberate choices worth reviewing:
.errorpath reachable, and.erroron an expected condition is exactly the case the host documents (console log with plugin attribution, no backend error report).useHostThemeis wired to the popover's theme readout rather than a canvas demo. Everyhost.uicomponent and CSS-variable class already follows the theme with no JS; putting the subscription somewhere its absence would be visible teaches the actual rule without adding a chart to a starter template. The comment says so explicitly.Manifest
min_kandev_version: "0.86.0"— verified as the first release containing #2408 and #2410 viagit merge-base --is-ancestor(both are inv0.86.0, neither inv0.85.0).access: "public"on the example webhook, with a comment covering when each value is right and pointing atactions:for the browser-to-plugin case.Verified
make vet/test/fmt/package-host, then installed into a running kandev (v0.87.1-27-g4705f1fd0): route renders, popover opens,Kbdrenders, the toast fires with the documented[plugins] toast.error from "kandev-plugin-template"console line, the theme readout updates live on a theme flip, and the publicpingwebhook answers an anonymous POST 200. The served bundle is byte-identical to the source. Also checked with a headless React render against the realPLUGIN_UIname list, feeding the WS handler the actualtask.createdpayload shape.Two things found while doing it
make packagefailed withmissing go.sum entryforjsonschema/v6, whichcmd/plugin-packnow pulls in transitively. Pre-existing, unrelated to these edits. Fixed with atooldirective sogo mod tidycan't drop those sums again.min_kandev_versionenforcement is release-only.checkMinKandevVersionno-ops unless the running build reports a clean release version, so a git-built host skips it entirely — a package declaring99.0.0installs fine. The floor is still correct and will bite on real releases, but the manifest and README now say not to read a successful dev-instance sideload as proof.🤖 Generated with Claude Code
Summary by cubic
Expands the template to demonstrate the post‑0.86 host UI surface and fixes packaging by running
cmd/plugin-packfrom the sibling kandev module. The old template used onlyButton/Card*/Tooltip*; the new page useshost.uiprimitives,host.toast,host.utils, live theme subscription, and the manifest enforcesmin_kandev_version: "0.86.0".ui/bundle.js: buffers the 5 most recenttask.createdevents, renders aTablethat swaps toEmpty, shows a real boundedProgress, and includes anAboutPopoverwithKbd. The Clear button stays enabled to exercisehost.toast.error; success useshost.toast.success.useHostTheme(host.theme+host.onThemeChange) and useshost.utils.formatRelativeTimeandhost.utils.cn.README.mdto requirehost.Reactand hostChart*wrappers instead of bundling React orrecharts.min_kandev_version: "0.86.0"and declareswebhooks.access: "public"inmanifest.yaml, with guidance on when to use each value../cmd/plugin-packfrom the siblingkandev/apps/backendmodule in the Makefile, avoiding missing transitive deps and go.sum drift.Rollout and migration
min_kandev_versionto match the APIs you keep, and always setwebhooks.accessexplicitly. Usehost.Reactandhost.ui.Chart*; do not bundle React orrecharts.Written for commit 4f31f8f. Summary will update on new commits.