Skip to content

Make delivery "placement" (install vs export) data-driven in the target manifest #37

Description

@adilei

Background

Follow-up from #28 (review comment). #28 externalized the target architecture registry so the choice grid is now fully data-driven (TARGETS.map(...)). This issue tracks the remaining follow-up and is not a regression in #28.

Problem

There's a second axis — placement (install-in-place vs export/download) — that's still inferred from architecture identity in the renderer rather than declared in the manifest. This is the same "one target, many edits" smell that #20 was about, just on the delivery dimension:

  • src/Library.tsx:496 — default useState<SkillArchitecture>("scout")
  • src/Library.tsx:966architecture === "cowork" ? "export" : "install"
  • src/Library.tsx:1143-1161 — "Added to Scout" / "Add to Scout" copy + the Scout-only Download button, gated on architecture === "scout"

Adding a new target (e.g. "Copilot Studio (skill, export-only)") today still requires touching these renderer branches.

Proposed approach

Lift placement into the existing target manifest as capabilities rather than identities:

{ id: "scout",  installTargetLabel: "Scout",
  targets: [
    { kind: "skill",      placements: ["install", "export"] },
    { kind: "automation", placements: ["install"] },
  ] }
{ id: "cowork", installTargetLabel: "Microsoft 365 Copilot",
  targets: [
    { kind: "skill", placements: ["export"] },
  ] }

Then the renderer derives:

  • default = first enabled target
  • placement buttons = target.placements
  • copy = installTargetLabel

…so no architecture string literals remain in src/. Adding "Copilot Studio (skill, export-only)" becomes one manifest entry + one catalogue file, with no renderer edits.

Scope / boundary (where to stop)

Keep the same UI-safe boundary already enforced for catalogue text:

  • Config = data/capabilities — labels, enabled, kinds, placements, icon key.
  • Behavior stays in codeskill vs automation genuinely branch (different builder, plan schema, IPC, render target), so those remain typed primitives; the manifest just decides whether each is offered.
  • Don't let config turn into a UI DSL. For any genuinely bespoke per-architecture UX later, a component registry keyed by SkillArchitecture beats piling more fields into config.

References

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions