Skip to content

Refresh plugin template to match host + add care-plugin-builder skill#11

Open
bodhish wants to merge 20 commits into
mainfrom
feat/plugin-authoring-skill
Open

Refresh plugin template to match host + add care-plugin-builder skill#11
bodhish wants to merge 20 commits into
mainfrom
feat/plugin-authoring-skill

Conversation

@bodhish

@bodhish bodhish commented Jun 21, 2026

Copy link
Copy Markdown
Member

What & why

The care_hello_fe plugin template had drifted out of sync with the host (care_fe), including two runtime-breaking bugs. This PR re-aligns the template to the current host contract and adds a care-plugin-builder Claude Code skill that encodes how to build CARE features as plugins.

Grounded in how the real, shipping plugins (e.g. care_analytics_fe) and the host actually work — plugins are self-contained federated remotes that duck-type their manifest, reach host services via window globals, and vendor their own request layer.

Template fixes

  • Breaking: PatientInfoCardQuickActions slot props corrected to { encounter: EncounterRead; className? } (was { encounter: {id}, patientId, facilityId }).
  • Breaking: federation.shared now includes @tanstack/react-query + raviger (both were imported but not shared → "Should have a queue" hook-order crash at runtime).
  • Vendored src/types/pluginManifest.ts — a trimmed mirror of the host PluginManifest, so const manifest: PluginManifest turns shape drift into a compile error (this is what silently broke before).
  • Vendored src/lib/requests.tsquery/mutate/request reading window.CARE_API_URL + the JWT from localStorage.
  • federation.name → slug care_hello_fe; build target es2022; deps aligned to host ranges (raviger ^5.3.0, @originjs/vite-plugin-federation ^1.3.7, etc.); window globals declared in vite-env.d.ts.
  • Example authenticated query (src/pages/CurrentUser.tsx) exercising the vendored request layer end-to-end.
  • README rewritten for the two-mode workflow (in-tree apps/ dev → standalone remoteEntry.js), window globals, clone-component, REACT_ENABLED_APPS, and shared-dep parity.

New skill: .claude/skills/care-plugin-builder/

SKILL.md + 5 references (manifest contract with all 17 slots, recipes, data-and-auth, integration-and-deploy, advanced-extension-points). Treats care_fe/src/pluginTypes.ts as the source of truth and carries a verify-step + silent-failure gotchas.

Verification

  • npx tsc -b clean; npm run build emits dist/assets/remoteEntry.js with all 5 host singletons federated.
  • eslint → 0 errors, 0 warnings on changed files.
  • Live in-browser smoke test (in-tree apps/ render) deferred — static gates cover its failure mode.

Design docs

docs/superpowers/{specs,plans}/ contain the design spec and implementation plan (can be dropped if undesired in the template repo).

Follow-ups (separate)

  • Host should publish @ohcnetwork/care-plugin-types so plugins stop re-vendoring host types.
  • localPluginDevSupport() should discover symlinked apps/ dirs (currently isDirectory() filters them out).

🤖 Generated with Claude Code

bodhish and others added 20 commits June 21, 2026 14:22
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… as PluginManifest

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Set shared singletons (raviger, react-i18next, @tanstack/react-query,
lucide-react) and the federation plugin to the host's (care_fe) declared
ranges so the plugin loads against the same versions the host provides.

@originjs/vite-plugin-federation: ^1.4.1 -> ^1.3.7 is an intentional
downgrade to anchor to the host's build, even though care_analytics_fe
runs ^1.4.0. Do not "fix" this back to a higher range.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…API_URL

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The vendored ExtractRouteParams in src/lib/requests.ts copies the host's
`infer _Start` pattern, but the plugin's eslint config lacked the matching
no-unused-vars ignore-pattern that care_fe uses, so `npx eslint src` failed
with '_Start is defined but never used'. Add argsIgnorePattern/
varsIgnorePattern/caughtErrorsIgnorePattern '^_' to mirror the host
(care_fe/eslint.config.mjs), fixing the root cause.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…contract

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address code-quality review of the care-plugin-builder skill (Tasks 10-12):
- Replace the hardcoded /Users/... absolute path to the host pluginTypes.ts
  in manifest-contract.md with a portable repo-relative reference.
- Replace brittle "§2"/"§4" cross-references in SKILL.md with section-name
  references that survive section reordering.
- Swap Unicode "->" arrows in the gotchas list for ASCII to avoid
  rendering/accessibility issues on critical semantic lines.

The other reviewed concerns referenced files that do not exist in this repo
(.ai/skills/form.skill.md, .github/skills/questionnaire-json.skill.md,
form.knowledge.md) and content (LOINC codes, slug-length rules, questionnaire
type-mapping tables) that this skill does not contain; they do not apply.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Validate the care-plugin-builder skill (plan Task 16). Cross-link the
authoritative host local-dev doc (care-apps-local-dev.md) from the
integration-and-deploy reference. This commit records the required
context for the validation so it is reproducible.

Skill under validation
  .claude/skills/care-plugin-builder/SKILL.md
  + references/ (manifest-contract, recipes, data-and-auth,
    integration-and-deploy, advanced-extension-points).md

Part B locations (plan Tasks 13-15, validated here)
  .claude/skills/care-plugin-builder/references/data-and-auth.md          (Task 13)
  .claude/skills/care-plugin-builder/references/integration-and-deploy.md (Task 14)
  .claude/skills/care-plugin-builder/references/advanced-extension-points.md (Task 15)

Evaluation criteria (writing-skills validation) + result
  1. Frontmatter well-formed (name + description only): PASS.
  2. Description has concrete trigger phrases ("Use when building a
     feature for CARE ... as a plugin"): PASS.
  3. Every references/*.md linked from SKILL.md (5 links, 5 files,
     1:1): PASS.
  4. No broken intra-skill links (references/ + SKILL.md §x cross-refs):
     PASS.
  5. Every cited host path exists in the care_fe checkout
     (/Users/bodhishthomas/code/care_fe): PASS.

Host behavior references verified against /Users/bodhishthomas/code/care_fe
  src/pluginTypes.ts ........... PluginManifest, PluginEncounterTabProps,
                                 PluginOrganizationTab, PluginDeviceManifest,
                                 PluginOverride
  src/index.tsx ................ window.CARE_API_URL / AuthUserContext / __CORE_ENV__
  src/common/constants.tsx ..... LocalStorageKeys.accessToken = "care_access_token"
  vite.config.mts .............. localPluginDevSupport / getLocalPluginDefinitions /
                                 rewriteLocalPluginImports / /local-plugins/
  src/Utils/plugConfig.ts ...... mergePlugConfigs
  src/lib/override/{index,types,bridge}.ts ... register / OverrideCondition /
                                 window.__careOverrides
  src/pages/Encounters/EncounterShow.tsx ..... ENCOUNTER_TAB__ label convention
  src/pages/Organization/components/OrganizationLayout.tsx
  src/hooks/useCareApps.tsx
  scripts/clone-component.ts
  docs/care-apps-{local-dev,architecture-note,override-architecture}.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The README still claimed the skill was "in progress and not yet bundled"
even though SKILL.md and all five references are committed under
.claude/skills/care-plugin-builder/. The stale note made the skill
undiscoverable from the repo's primary doc surface (reviewers/tools that
skip dotfile dirs concluded no skill file existed). Point the README at
the actual location instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…st types

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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