mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* fix(plugins): make Publish repo actually create the author's repo (#2332) QA repro from 0.8.0 preview: clicking "Publish repo" on a generated plugin's `DesignFilesPanel` card ran the agent down a path that produced an Open Design registry-submission URL but never created the author's GitHub repo. After the action finished, `gh repo view nuomi/cat` still returned 404 and `git ls-remote https://github.com/nuomi/cat.git HEAD` failed with "Repository not found". Root cause is the action prompt at `apps/web/src/components/design-files/pluginFolderActions.ts:11-12`: publish: 'Use the supported `od plugin publish` or repository-publish flow after confirming the manifest.' That sentence let the agent pick the legacy registry-link CLI (`od plugin publish --to open-design`), which mirrors the path the "Open Design PR" button takes and emits an issue URL instead of creating a public repo. The button label said "Publish repo" but the behavior collapsed onto the registry-submission flow. This PR rewrites the `publish` prompt in the same shape PR #2182 used for `contribute` — a numbered gh + git sequence that drives the real action end-to-end: 1. Pre-flight `gh --version` / `gh auth status`. Invalid / expired tokens are treated the same as not-logged-in (the bug-report agent kept going past an "invalid token" warning). 2. Read manifest, capture `name`, `version`, `description`, `plugin.repo`. Fall back to `https://github.com/<gh-login>/<name>` when `plugin.repo` is missing and write it back into the manifest. 3. `gh repo view <owner>/<name>` to decide create-vs-update. 4a. Repo does not exist → `git init` + commit + tag + `gh repo create <owner>/<name> --public --source . --push`. 4b. Repo exists → reuse the remote, `git add -A` + `git commit -m "Update: <name> v<version>"` (skip if working tree is clean), `git tag v<version>` (skip if already published), `git push`. 5. Verify with `gh repo view <owner>/<name> --json url,nameWithOwner`. 6. Hand off the resolved `https://github.com/<owner>/<name>` URL to chat. End the turn. Hard constraints encoded in the prompt: * Do NOT call `od plugin publish --to open-design` (or any `--to <catalog>` variant). That is the registry-submission flow. * Do NOT call `AskUserQuestion` — fire-and-forget, same as the `contribute` flow's stall fix. * Do NOT auto-install gh/git. Detect-and-instruct only. * Do NOT force-push or overwrite a published tag. * Do NOT retry a failed step. Report and stop. Refactor: pulled `publish` out of the shared `ACTION_TITLES`/ `ACTION_NOTES` template into its own `buildPublishPrompt(folderPath)` function (mirrors `buildContributePrompt` from PR #2182). `install` keeps the simple shared template — that action stays inferrable from the manifest and doesn't need the same blast radius. Tests: * `apps/web/tests/components/pluginFolderActions.test.ts` — extends the existing contract suite with seven new `publish` assertions: targets `plugin.repo` not the registry catalog, drives the full gh + git command list, handles both new-repo and existing-repo branches, explicit ban on the registry-submission CLI, hard-bans on AskUserQuestion / auto-install / force-push / retry, "invalid token" treated as STOP, `${folderPath}` interpolation guard, ends by handing the repo URL back to chat. Validation: * `pnpm --filter @open-design/web exec vitest run tests/components/pluginFolderActions.test.ts` → 16/16 passed (was 9/9 before this PR; +7 new publish-flow assertions, the old generic "mentions od plugin publish" assertion replaced with the precise contract above) (Local `pnpm --filter @open-design/web typecheck` fails on `tests/runtime/exports.test.ts` because `packages/host/dist/testing` isn't built in this checkout — pre-existing breakage from `2c128e0e refactor desktop host bridge` on main, unrelated to this prompt change. CI runs a fresh install and was green on the four previous prompt-only PRs that touched the same module.) Closes #2332. * fix(plugins): don't assume standalone jq when reading the manifest QA repro from the Open Design PR button (transcript shared with the PR #2363 thread): the agent reached step 2 of the contribute prompt, ran `jq '{name,title,description,version}' generated-plugin/open-design.json`, got `zsh:1: command not found: jq`, and stopped per the prompt's "stop on first hard failure" rule. No fork, no branch, no PR. jq is not part of the OD agent runtime baseline — default macOS and Windows shells don't ship it. The agent reached for it first because "jq" is the default JSON tool in claude/codex's shell training distribution, not because the prompt asked for it. The prompt just said "Load and capture", which the agent interpreted as "shell out to the most common JSON parser". Updates both step-2 instructions (contribute + publish prompts) to: - List portable manifest-read alternatives in priority order: the built-in Read tool (always available); `cat` + manual JSON parsing; `node -e 'JSON.parse(...)'` as the shell-only fallback. - Add an explicit "Do not assume the standalone `jq` binary is installed" guard with the macOS / Windows shell rationale. - Disambiguate the standalone `jq` CLI from `gh ... --jq`. The gh flag uses an embedded library and is fine — without the disambiguation the agent reads the ban literally and stops using `gh api user --jq .login` at step 3. Tests: * `apps/web/tests/components/pluginFolderActions.test.ts` — two new contract assertions: - publish prompt: warns against assuming standalone jq is installed; lists cat and node -e as alternatives. Closes the regression on its own surface. - shared block: both contribute and publish prompts disambiguate standalone jq from `gh ... --jq`. One assertion guards both flows so a future prose edit can't drop the carve-out on one side. Validation: * `pnpm --filter @open-design/web exec vitest run tests/components/pluginFolderActions.test.ts` → 18/18 passed (was 16/16 on the previous PR #2363 commit; +2 new jq-guidance assertions) Continues PR #2363. Same source-of-bug shape as the registry-submission fallback issue this PR was opened to fix: agent picks a tool the prompt didn't actually ask for because the prompt was loose. |
||
|---|---|---|
| .. | ||
| Theater | ||
| AgentIcon.test.tsx | ||
| App.connectors.test.tsx | ||
| App.mediaProviders.test.tsx | ||
| assistant-message-tool-status.test.tsx | ||
| assistant-message-unfinished-todos.test.tsx | ||
| AssistantMessage.test.ts | ||
| AssistantMessage.test.tsx | ||
| auto-open-file.test.ts | ||
| BoardComposerPopover.pod-chip-hover.test.tsx | ||
| BoardComposerPopover.pod-remove.test.tsx | ||
| chat-feedback.test.tsx | ||
| chat-scroll-preservation.test.tsx | ||
| ChatComposer.context-pickers.test.tsx | ||
| ChatComposer.infinite-render.test.tsx | ||
| ChatComposer.search.test.tsx | ||
| ChatPane.resume-conversation.test.tsx | ||
| ChatPane.streaming.test.tsx | ||
| CommentTargetOverlay.hover-class.test.tsx | ||
| ConnectorsBrowser.test.tsx | ||
| ContinueInCliButton.test.tsx | ||
| conversation-timestamps.test.tsx | ||
| CustomSelect.test.tsx | ||
| DesignFilesPanel.test.tsx | ||
| DesignsTab.select-mode.test.tsx | ||
| DesignsTab.test.ts | ||
| DesignSystemFlow.test.tsx | ||
| DesignSystemsTab.test.tsx | ||
| EntryView.test.ts | ||
| examples-tab-filter-counts.test.tsx | ||
| examples-tab-preview-dispatch.test.tsx | ||
| examples-tab-retry.test.tsx | ||
| ExamplesTab.test.tsx | ||
| file-viewer-markdown-copy.test.tsx | ||
| file-viewer-render-mode.test.ts | ||
| FileOpsSummary.test.tsx | ||
| FileViewer.manual-edit-history.test.tsx | ||
| FileViewer.manual-edit.test.tsx | ||
| FileViewer.test.tsx | ||
| FileWorkspace.design-system.test.tsx | ||
| FileWorkspace.test.tsx | ||
| GenUISurfaceRenderer.diff-review.test.tsx | ||
| GenUISurfaceRenderer.schema-form.test.tsx | ||
| GenUISurfaceRenderer.test.tsx | ||
| HomeHero.plugin-picker.test.tsx | ||
| HomeHero.rail.test.tsx | ||
| HomeView.context-picker.test.tsx | ||
| HomeView.media-options.test.tsx | ||
| HomeView.plugin-i18n.test.tsx | ||
| HomeView.prefill.test.tsx | ||
| InlinePluginsRail.test.tsx | ||
| ManualEditPanel.test.tsx | ||
| MarketplaceView.test.tsx | ||
| McpClientSection.oauth.test.tsx | ||
| McpJsonHelper.test.tsx | ||
| MemorySection.test.tsx | ||
| modelOptions.test.tsx | ||
| NewAutomationModal.context-picker.test.tsx | ||
| NewProjectModal.test.tsx | ||
| NewProjectPanel.media.test.tsx | ||
| NewProjectPanel.test.ts | ||
| NewProjectPanel.test.tsx | ||
| pet-task-center.test.ts | ||
| PetOverlay.test.tsx | ||
| PluginDetailsModal.dispatch.test.tsx | ||
| pluginFolderActions.test.ts | ||
| PluginInputsForm.test.tsx | ||
| plugins-home-facets.test.ts | ||
| plugins-home-html-surface.test.tsx | ||
| plugins-home-preview.test.ts | ||
| plugins-home-section.test.tsx | ||
| plugins-home-visualScore.test.ts | ||
| PluginShareMenu.test.tsx | ||
| PluginsSection.test.tsx | ||
| PluginsView.test.tsx | ||
| preview-modal-error-state.test.tsx | ||
| preview-modal-fullscreen.test.tsx | ||
| preview-modal-unavailable-state.test.tsx | ||
| PreviewDrawOverlay.test.tsx | ||
| PreviewModal.test.tsx | ||
| PrivacyConsentModal.test.tsx | ||
| PrivacySection.test.tsx | ||
| ProjectView.api-empty-response.test.tsx | ||
| ProjectView.deleteConversation.test.tsx | ||
| ProjectView.pendingPrompt.test.tsx | ||
| ProjectView.projectInstructions.test.tsx | ||
| ProjectView.resume-conversation.test.tsx | ||
| ProjectView.run-cleanup.test.tsx | ||
| ProjectView.run-isolation.test.tsx | ||
| ProjectView.tabs-navigation.test.tsx | ||
| QuestionForm.test.tsx | ||
| QuickSwitcher.test.tsx | ||
| RoutinesSection.test.tsx | ||
| SettingsDialog.execution.test.tsx | ||
| SettingsDialog.media.test.tsx | ||
| SettingsDialog.orbit.test.tsx | ||
| SettingsDialog.test.ts | ||
| sketch-model.test.ts | ||
| SkillsSection.test.tsx | ||
| TasksView.history.test.tsx | ||
| TasksView.templates.test.tsx | ||
| Toast.test.tsx | ||
| TrustBadge.test.tsx | ||
| UpdaterPopup.test.tsx | ||
| use-everywhere-agent-guide.test.ts | ||
| WorkspaceTabsBar.test.tsx | ||