Skip to content

Teach the post-0.86 host surface - #5

Merged
jcfs merged 2 commits into
mainfrom
feature/modernize-template-host-surface
Aug 13, 2026
Merged

Teach the post-0.86 host surface#5
jcfs merged 2 commits into
mainfrom
feature/modernize-template-host-surface

Conversation

@jcfs

@jcfs jcfs commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

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 does popover positioning with getBoundingClientRect. 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:

Part Shows
AboutPopover Popover*, host-positioned — no getBoundingClientRect math. Holds Kbd/KbdGroup for kandev's real new-task binding.
Progress block Progress over an honest bounded ratio (buffer fill), plus host.utils.cn for a conditional class.
RecentTasksTable Table*, with host.utils.formatRelativeTime on the "seen" column.
EmptyState Empty* — what you see before the first delivery.
Clear button host.toast.success and host.toast.error.
useHostTheme host.theme + host.onThemeChange, with the unsubscribe returned from the effect.

Two deliberate choices worth reviewing:

  • The Clear button stays enabled when the buffer is empty. That is what makes the .error path reachable, and .error on an expected condition is exactly the case the host documents (console log with plugin attribution, no backend error report).
  • useHostTheme is wired to the popover's theme readout rather than a canvas demo. Every host.ui component 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 via git merge-base --is-ancestor (both are in v0.86.0, neither in v0.85.0).
  • access: "public" on the example webhook, with a comment covering when each value is right and pointing at actions: 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, Kbd renders, 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 public ping webhook answers an anonymous POST 200. The served bundle is byte-identical to the source. Also checked with a headless React render against the real PLUGIN_UI name list, feeding the WS handler the actual task.created payload shape.

Two things found while doing it

  • Packaging was already broken against current kandev. make package failed with missing go.sum entry for jsonschema/v6, which cmd/plugin-pack now pulls in transitively. Pre-existing, unrelated to these edits. Fixed with a tool directive so go mod tidy can't drop those sums again.
  • min_kandev_version enforcement is release-only. checkMinKandevVersion no-ops unless the running build reports a clean release version, so a git-built host skips it entirely — a package declaring 99.0.0 installs 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-pack from the sibling kandev module. The old template used only Button/Card*/Tooltip*; the new page uses host.ui primitives, host.toast, host.utils, live theme subscription, and the manifest enforces min_kandev_version: "0.86.0".

  • Adds a single page in ui/bundle.js: buffers the 5 most recent task.created events, renders a Table that swaps to Empty, shows a real bounded Progress, and includes an AboutPopover with Kbd. The Clear button stays enabled to exercise host.toast.error; success uses host.toast.success.
  • Introduces useHostTheme (host.theme + host.onThemeChange) and uses host.utils.formatRelativeTime and host.utils.cn.
  • Updates README.md to require host.React and host Chart* wrappers instead of bundling React or recharts.
  • Sets min_kandev_version: "0.86.0" and declares webhooks.access: "public" in manifest.yaml, with guidance on when to use each value.
  • Fixes packaging by invoking ./cmd/plugin-pack from the sibling kandev/apps/backend module in the Makefile, avoiding missing transitive deps and go.sum drift.

Rollout and migration

  • No app behavior change. Installing the template now fails on release hosts older than 0.86; dev git builds bypass the gate.
  • When using this scaffold, set min_kandev_version to match the APIs you keep, and always set webhooks.access explicitly. Use host.React and host.ui.Chart*; do not bundle React or recharts.

Written for commit 4f31f8f. Summary will update on new commits.

Review in cubic

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.
@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown

Greptile Summary

The PR expands the plugin scaffold to demonstrate the post-0.86 host UI, utility, toast, theme, and webhook-access surfaces, while repairing packaging dependency retention.

  • Replaces the task counter with a bounded recent-task table, progress indicator, empty state, popover, keyboard hint, toasts, and live theme readout.
  • Declares a 0.86.0 minimum host version and explicit public access for the example webhook.
  • Adds the plugin-pack tool dependency so go mod tidy retains packaging checksums.
  • Documents host component usage, webhook access choices, minimum-version behavior, and development constraints.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code failure established.

The new UI state handling, manifest declarations, and packaging dependency retention are internally consistent, and no reachable blocking or independently actionable non-blocking defect remains.

Important Files Changed

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]
Loading

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.
@jcfs
jcfs merged commit c107c22 into main Aug 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant