* chore: unify product name display to OpenDesign repo-wide Rename the user-facing product name from "Open Design" to "OpenDesign" across documentation, web/desktop UI strings, i18n locales, prompts, plugin/skill/design-system content, changelogs, and specs, matching the landing-page rename already in flight. Deliberately excluded so installed-app identity stays untouched: - packages/release PRODUCT_NAME and everything derived from it (app bundle names, installer/registry identity, updater feeds) - tools/pack, tools/release, apps/packaged, landing page (PR #6983) - mocks/ recorded traces and LICENSE - test fixtures and comments that encode real on-disk install paths (Open Design.app, Program Files\Open Design, AppData paths) Validated with pnpm guard, pnpm typecheck, and targeted web/desktop/host test runs over the renamed strings. * fix(web): keep two-letter author monogram for CamelCase brand names authorInitials split words on whitespace only, so the renamed single-token author name "OpenDesign" produced a one-letter monogram. Treat lower-to-upper CamelCase boundaries as word breaks so the avatar fallback stays "OD". * fix(release): restore spaced Windows source artifact names in win.ps1 tools/pack still derives builder outputs from the unchanged PRODUCT_NAME ("Open Design"), so the asset script must look for the spaced filenames. Matches the mac/mac-intel/linux asset scripts, which were already kept on the original names. --------- Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com>
15 KiB
Plugin authoring flow plan
Parent: spec.md · Related: plugin-driven-flow-plan.md · plugins-implementation.md
Purpose
Make "create my own plugin" a first-class product flow instead of a disconnected future tab. A user should be able to start from the Plugins area, land on the Home prompt with an authoring query already prepared, run an agent task that produces an OpenDesign plugin folder, inspect that folder as project output, and add it to My plugins with one click.
This plan is intentionally focused on the authoring loop. Marketplace publishing, enterprise private catalogs, and team review policies stay out of scope.
Requirements
- R1. Plugins tab exposes a create entry that starts a guided plugin authoring task instead of only offering import options.
- R2. The create entry navigates to Home, focuses
HomeHero's textarea, and pre-fills a prompt grounded in the OpenDesign plugin spec. - R3. The task should create a real plugin folder containing at minimum
SKILL.mdandopen-design.json, with optional examples/assets when the user asks for them. - R4. Project output must support selecting or viewing the generated plugin folder as a folder, not only as flat single files.
- R5. A generated plugin folder can be installed into the user plugin registry and then appears in
My pluginsand Home@search. - R6. Home's intent rail exposes a "Create plugin" chip that reuses the same authoring handoff, prompt contract, and
od-plugin-authoringscenario as the Plugins entry.
Scope boundaries
- No marketplace publishing in this pass. Installing to
My pluginsis enough. - No enterprise/team catalog permissions in this pass.
- No new plugin spec dialect. The generated folder must validate against the existing OpenDesign plugin shape in
docs/plugins-spec.mdanddocs/schemas/open-design.plugin.v1.json. - No requirement to build a full visual plugin IDE. The first version is an agent-guided task plus a one-click install action.
Deferred to follow-up work
- Marketplace publishing and team review workflows belong after local authoring and
My pluginsinstall are reliable.
Current code context
apps/web/src/components/PluginsView.tsxalready owns the Plugins tab,Create / Importbutton, import modal,My pluginstab, and refresh-after-install behavior.apps/web/src/components/HomeView.tsxowns prompt state, plugin apply lifecycle, andHomeHerofocus viainputRef.apps/web/src/components/HomeHero.tsxrenders the textarea,@picker, and intent rail.apps/web/src/components/home-hero/chips.tsdefines the declarativecreate-pluginrail chip;HomeViewdispatches it through the same authoring handoff used by the Plugins entry.apps/web/src/components/EntryShell.tsxowns view switching and the Home submit path that creates a project withpendingPromptandautoSendFirstMessage.apps/web/src/state/projects.tsalready exposesinstallPluginSource,uploadPluginFolder, anduploadPluginZipfor user plugin installation.apps/daemon/src/routes/plugins/index.tsregisters/api/plugins/install,/api/plugins/upload-folder,/api/plugins/upload-zip,/api/applied-plugins/export, and the project-relative/api/projects/:id/plugins/install-folderroute. The route handlers are composed fromapps/daemon/src/server.ts.apps/daemon/src/plugins/scaffold.ts,apps/daemon/src/plugins/export.ts, andapps/daemon/src/plugins/validate.tsalready encode scaffold/export/validate behavior that the authoring flow should reuse.
Key decisions
- The product entry is "Create plugin", not "Create from template" alone. Template scaffolding is one possible implementation detail, but the user intent is to describe a workflow and let the agent produce a plugin.
- Plugins tab and the Home rail are now equivalent supported entries: both prepare the same editable Home prompt and bind the same authoring scenario.
- Use the shipped dedicated bundled scenario
od-plugin-authoring. Theod-new-generationfallback remains only a compatibility bridge when an older registry does not contain the authoring scenario. - The generated plugin folder should live inside the project work directory so it can be inspected, edited, and installed without forcing a browser folder upload.
- One-click "Add to My plugins" should install from a daemon-visible project output path through the same local install path used by
/api/plugins/install, then refresh web plugin state.
High-level flow
This illustrates the intended approach and is directional guidance for review, not implementation specification.
sequenceDiagram
participant Plugins as Plugins tab
participant Home as Home prompt
participant Daemon as Daemon/project run
participant Files as Project files
participant Registry as User plugin registry
Plugins->>Home: Navigate home with plugin-authoring prefill
Home->>Home: Focus textarea and show editable prompt
Home->>Daemon: Submit project with authoring prompt and scenario
Daemon->>Files: Agent writes generated-plugin/
Files->>Plugins: Surface folder with Add to My plugins action
Plugins->>Daemon: Install generated-plugin/ as local user plugin
Daemon->>Registry: Register InstalledPluginRecord(sourceKind=user/local)
Registry->>Home: listPlugins includes new plugin for @ search
Proposed implementation units
-
U1. Home prefill and focus contract
Goal: Add a reusable way to navigate to Home with a prefilled prompt and focus the textarea.
Files:
- Modify:
apps/web/src/router.ts - Modify:
apps/web/src/components/EntryShell.tsx - Modify:
apps/web/src/components/HomeView.tsx - Test:
apps/web/tests/router-marketplace.test.ts - Test:
apps/web/tests/components/HomeHero.plugin-picker.test.tsxor a newapps/web/tests/components/HomeView.prefill.test.tsx
Approach:
- Prefer a small route/session handoff rather than global singleton state. The handoff should carry
{ prompt, focus: true, source: 'plugin-authoring' }. HomeViewshould consume the handoff once, setprompt, and call the existing textarea ref focus path.- Keep the prompt user-editable before submit.
Test scenarios:
- Happy path: navigating from Plugins with an authoring handoff renders Home, fills the textarea, and focuses it.
- Edge case: refreshing Home after the handoff does not repeatedly overwrite a user's edited prompt.
- Integration: submitting the prefilled prompt still creates a project through the existing
PluginLoopSubmitpath.
- Modify:
-
U2. Plugins create entry
Goal: Turn the Plugins tab
Create / Importsurface into two clear actions: guided create and import.Files:
- Modify:
apps/web/src/components/PluginsView.tsx - Modify:
apps/web/src/styles/home/plugins-view.css - Test:
apps/web/tests/components/PluginsView.test.tsx
Approach:
- Keep GitHub/zip/folder import in the existing modal.
- Add a primary
Create pluginaction that uses U1 to navigate to Home with a spec-grounded authoring prompt. - Keep "Create from template" in the import modal only if it launches the same authoring path or explicitly remains marked as coming soon.
Test scenarios:
- Happy path: clicking
Create plugintriggers Home navigation with the expected prefill payload. - Regression: GitHub/zip/folder import still installs and lands in
My plugins. - Accessibility: the create action has a clear button label and does not masquerade as a disabled tab.
- Modify:
-
U3. Plugin authoring scenario
Goal: Give the agent a purpose-built plugin authoring context that asks for the right files and validation behavior.
Files:
- Create:
plugins/_official/scenarios/od-plugin-authoring/open-design.json - Create:
plugins/_official/scenarios/od-plugin-authoring/SKILL.md - Modify:
apps/web/src/components/home-hero/chips.ts - Test:
apps/daemon/tests/plugins-bundled-scenarios-roster.test.ts - Test:
apps/daemon/tests/plugins-local-skill.test.ts
Approach:
- The scenario should instruct the agent to output a folder such as
generated-plugin/withSKILL.md,open-design.json, and optionalexamples/orassets/. - The prompt should cite the OpenDesign plugin spec and require validation-ready output, not a prose-only explanation.
- If the scenario includes GenUI, it should present checklist/progress and final "Add to My plugins" affordance, but the install action itself should call a daemon API rather than relying on copy/paste.
Test scenarios:
- Happy path: bundled scenario appears in plugin list and can be applied.
- Integration: applying the scenario injects its local
SKILL.mdbody into the run snapshot. - Regression: regular
od-new-generationand migration scenarios are unaffected.
- Create:
-
U4. Generated folder visibility in project output
Goal: Let users inspect and select a generated plugin folder from the project workspace.
Files:
- Modify:
apps/web/src/components/DesignFilesPanel.tsx - Modify:
apps/web/src/components/FileWorkspace.tsx - Modify:
apps/web/src/components/FileOpsSummary.tsxif folder outputs are surfaced from tool/file ops - Modify: daemon project file listing endpoints in
apps/daemon/src/server.tsif they currently flatten directories too aggressively - Test:
apps/web/tests/components/FileWorkspace.test.tsx - Test: daemon project file listing tests near the existing project/file tests
Approach:
- Preserve relative paths so
generated-plugin/open-design.jsonandgenerated-plugin/SKILL.mdremain visibly grouped. - A minimal v1 can show a folder row in
DesignFilesPaneland expand to its files; it does not need a full IDE tree. - The folder row should expose the install action only when it contains a plugin marker file.
Test scenarios:
- Happy path: a project with
generated-plugin/open-design.jsonandgenerated-plugin/SKILL.mdrenders a folder group. - Edge case: nested files remain selectable without losing their relative path.
- Error path: malformed or partial plugin folders do not show a misleading install success action.
- Modify:
-
U5. Install generated folder as My plugin
Goal: Add a one-click action that installs a daemon-visible generated folder into the user plugin registry.
Files:
- Modify:
apps/web/src/state/projects.ts - Modify:
apps/web/src/components/DesignFilesPanel.tsxor the GenUI surface that owns the final action - Modify:
apps/daemon/src/server.ts - Reuse:
apps/daemon/src/plugins/installer.ts - Reuse:
apps/daemon/src/plugins/validate.ts - Test:
apps/web/tests/state/projects.test.ts - Test:
apps/web/tests/components/FileWorkspace.test.tsx - Test:
apps/daemon/tests/plugins-installer.test.ts - Test:
apps/daemon/tests/plugins-validate.test.ts
Approach:
- Add a web helper such as
installGeneratedPluginFolder(projectId, relativePath)rather than forcing a browser upload. - The daemon endpoint should resolve the folder under the project work directory, validate traversal safety, validate plugin shape, install through the existing installer, and return a
PluginInstallOutcome-compatible response. - On success, web should refresh
listPlugins(), switch/openMy plugins, and make the plugin available to Home@search.
Test scenarios:
- Happy path: project output folder installs and appears as a user/local plugin.
- Error path: invalid folder returns diagnostics and does not mutate installed plugins.
- Security:
../traversal or absolute paths outside the project root are rejected. - Integration: after install,
GET /api/pluginsincludes the new record with non-bundledsource kind.
- Modify:
-
U6. Home rail create-plugin chip parity
Goal: Let the Home rail entry use the same authoring flow without duplicating behavior.
Files:
- Modify:
apps/web/src/components/home-hero/chips.ts - Modify:
apps/web/src/components/HomeView.tsx - Modify:
apps/web/src/components/HomeHero.tsx - Test:
apps/web/tests/components/HomeHero.rail.test.tsx
Approach:
- Add a
create-pluginchip action that invokes the U1 prefill/focus contract. - Keep the payload shape identical so Plugins tab and rail remain interchangeable entrypoints.
Test scenarios:
- Happy path: clicking the chip fills the same prompt as Plugins tab create.
- Regression: existing Prototype/Image/Figma/Template chips continue dispatching their current actions. Folder linking is owned by the composer Tools → Import path, not the Home rail.
- Modify:
Prompt contract
The authoring prompt should be stable enough for tests and user trust. A first version can be:
Create an OpenDesign plugin for: <user goal>.
Follow docs/plugins-spec.md and produce a folder named generated-plugin with:
- SKILL.md describing the agent behavior and workflow
- open-design.json with valid metadata, mode, task kind, inputs, and any pipeline/context references
- optional examples/ and assets/ when useful
When finished, summarize the files created and whether the folder is ready to add to My plugins.
Implementation can enrich this with the current locale and UI-provided goal, but the required output folder and marker files should stay stable.
Risks
- Generated output is prose-only: Use a dedicated authoring scenario and prompt contract that explicitly requires files.
- Folder paths become unsafe: Resolve generated-folder installs relative to the project root only; reject traversal and absolute external paths.
- Validation errors feel like failure: Return validation diagnostics in the UI so users can ask the agent to fix the plugin instead of starting over.
- Duplicate plugins: Installer should use existing plugin id/version collision behavior and surface clear messages before overwriting or upgrading.
- Two entrypoints diverge: Plugins tab and Home rail must share the same prefill payload and prompt contract.
Verification plan
- Web component coverage for Plugins create entry, Home prefill/focus, and rail parity.
- Web state coverage for installing a generated project folder.
- Daemon tests for project-root path resolution, validation failure, and successful install.
- The daemon-backed Playwright smoke in
e2e/ui/real-daemon-run.test.tscovers Home rail → Create plugin → boundod-plugin-authoringrun → generatedgenerated-plugin/files → action cards in chat and Design Files. Keep the remaining install-to-Home-@assertion covered at the web state/API layers until the browser smoke is extended.
Open questions
- Resolved: generated output defaults to
generated-plugin/for predictable UI detection; final install still uses the manifest id. - Resolved: "Add to My plugins" is exposed both on the assistant action card and in
DesignFilesPanel, backed by the same project-relative install handler. - Should the daemon expose a scaffold API now, or should the authoring scenario ask the agent to create files directly? Direct file creation is simpler for v1; scaffold API becomes useful for template-first creation.