Skip to content

Provision default OpenWork Marketplace#2086

Open
benjaminshafii wants to merge 11 commits into
devfrom
improved-onboarding-cloud-2
Open

Provision default OpenWork Marketplace#2086
benjaminshafii wants to merge 11 commits into
devfrom
improved-onboarding-cloud-2

Conversation

@benjaminshafii
Copy link
Copy Markdown
Member

@benjaminshafii benjaminshafii commented Jun 3, 2026

Summary

  • lazily provision a default OpenWork Marketplace per org with built-in OpenWork extension entries
  • render cloud-provided built-ins in desktop Marketplace as Built-in without install/remove actions
  • update Den/landing onboarding copy and add an end-to-end eval doc

Validation

  • pnpm --filter @openwork-ee/den-api build
  • pnpm --filter @openwork/app typecheck
  • pnpm --filter @openwork-ee/landing build
  • pnpm --filter @openwork-ee/den-web build
  • pnpm --filter @openwork/app exec bun test ./tests/den-extension-projection.test.ts

Daytona Evidence

Clean replacement video, verified with no Authorize folder native picker windows present before each screenshot:

Note: chat send remains blocked in this Daytona sandbox by OpenCode request failed / missing opencode runtime wiring. Marketplace sync, built-in display, plugin import, My Extensions state, and workspace file materialization are validated.

Founder Journey E2E Recording

Final Daytona recording for the Den-to-desktop Marketplace journey. Verified no native Authorize folder picker before screenshots.

Caveat: in Daytona, Den Web form submit/deep-link handoff is affected by proxy origin behavior, so the recording uses the validated direct Den API token to bridge from visible Den sign-in to desktop connected state. The desktop Marketplace sync, built-in rendering, live plugin install state, My Extensions state, and materialized workspace file are validated end-to-end.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview, Comment Jun 4, 2026 5:55am
openwork-den Ready Ready Preview, Comment Jun 4, 2026 5:55am
openwork-den-worker-proxy Ready Ready Preview, Comment Jun 4, 2026 5:55am
openwork-landing Ready Ready Preview, Comment, Open in v0 Jun 4, 2026 5:55am

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="ee/apps/den-api/src/routes/org/plugin-system/store.ts">

<violation number="1" location="ee/apps/den-api/src/routes/org/plugin-system/store.ts:1682">
P2: Lazy provisioning is racy: concurrent `listMarketplaces` calls can create duplicate default marketplace/plugins due to non-atomic check-then-insert and no unique org+name constraint.</violation>

<violation number="2" location="ee/apps/den-api/src/routes/org/plugin-system/store.ts:1694">
P1: Provisioning selects built-ins by `PluginTable.name`, which can hijack same-named custom plugins into the system marketplace and access policy.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

.from(PluginTable)
.where(and(
eq(PluginTable.organizationId, organizationId),
eq(PluginTable.name, manifest.name),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Provisioning selects built-ins by PluginTable.name, which can hijack same-named custom plugins into the system marketplace and access policy.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ee/apps/den-api/src/routes/org/plugin-system/store.ts, line 1694:

<comment>Provisioning selects built-ins by `PluginTable.name`, which can hijack same-named custom plugins into the system marketplace and access policy.</comment>

<file context>
@@ -1522,6 +1652,163 @@ export async function listMarketplaces(input: { context: PluginArchActorContext;
+      .from(PluginTable)
+      .where(and(
+        eq(PluginTable.organizationId, organizationId),
+        eq(PluginTable.name, manifest.name),
+        isNull(PluginTable.deletedAt),
+      ))
</file context>

status: "active" as const,
updatedAt: now,
}
await db.insert(MarketplaceTable).values(marketplaceRow)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Lazy provisioning is racy: concurrent listMarketplaces calls can create duplicate default marketplace/plugins due to non-atomic check-then-insert and no unique org+name constraint.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ee/apps/den-api/src/routes/org/plugin-system/store.ts, line 1682:

<comment>Lazy provisioning is racy: concurrent `listMarketplaces` calls can create duplicate default marketplace/plugins due to non-atomic check-then-insert and no unique org+name constraint.</comment>

<file context>
@@ -1522,6 +1652,163 @@ export async function listMarketplaces(input: { context: PluginArchActorContext;
+      status: "active" as const,
+      updatedAt: now,
+    }
+    await db.insert(MarketplaceTable).values(marketplaceRow)
+    marketplace = marketplaceRow
+  }
</file context>

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="ee/apps/den-web/app/(den)/_providers/den-flow-provider.tsx">

<violation number="1" location="ee/apps/den-web/app/(den)/_providers/den-flow-provider.tsx:182">
P1: `sessionHydrated` is initialized to `true`, so auth-gated routing can execute before async session refresh completes, causing premature redirects for valid sessions.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

return token;
});
const [sessionHydrated, setSessionHydrated] = useState(false);
const [sessionHydrated, setSessionHydrated] = useState(true);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: sessionHydrated is initialized to true, so auth-gated routing can execute before async session refresh completes, causing premature redirects for valid sessions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At ee/apps/den-web/app/(den)/_providers/den-flow-provider.tsx, line 182:

<comment>`sessionHydrated` is initialized to `true`, so auth-gated routing can execute before async session refresh completes, causing premature redirects for valid sessions.</comment>

<file context>
@@ -179,7 +179,7 @@ export function DenFlowProvider({ children }: { children: ReactNode }) {
     return token;
   });
-  const [sessionHydrated, setSessionHydrated] = useState(false);
+  const [sessionHydrated, setSessionHydrated] = useState(true);
   const [desktopAuthRequested, setDesktopAuthRequested] = useState(false);
   const [desktopAuthScheme, setDesktopAuthScheme] = useState("openwork");
</file context>
Suggested change
const [sessionHydrated, setSessionHydrated] = useState(true);
const [sessionHydrated, setSessionHydrated] = useState(false);

@benjaminshafii
Copy link
Copy Markdown
Member Author

Update after latest docs commit (ad8dcf930):

Fresh founder-flow artifact URL while the Daytona artifact sandbox is running:

Added to evals/default-openwork-marketplace-onboarding-flow.md:

  • 8-star experience target: one continuous Den-to-desktop journey, clear Marketplace/plugin explanation, no auth bridge, immediate desktop connected/synced success state, built-ins grouped as ready first-party capabilities, live plugin install visible in My Extensions and composer/tooling, and a successful chat/task using the imported plugin.
  • Future full server-owned extensions direction: versioned extension packages, signing/trust, runtime boundaries, desktop extension host, admin policy/rollout/rollback, observability, offline behavior, and migration from desktop-owned built-ins to Den-managed first-party packages.

Current caveats remain unchanged:

  • Daytona Den Web form submit/deep-link handoff required a validated direct Den API token bridge because of proxy/origin behavior.
  • Chat send remains blocked by missing/opencode runtime wiring in the sandbox.
  • Marketplace sync, built-in rendering, live plugin install state, My Extensions state, and materialized workspace files are validated.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".opencode/skills/daytona-flow-validator/SKILL.md">

<violation number="1" location=".opencode/skills/daytona-flow-validator/SKILL.md:157">
P2: The "fail fast" screenshot command does not actually stop on picker detection because `;` allows execution to continue after a failed grep check.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

if a picker is present:

```bash
daytona exec "$SANDBOX" -- 'bash -lc '\''DISPLAY=:99 wmctrl -l | tee /tmp/windows-before-shot.txt; ! grep -q "Authorize folder" /tmp/windows-before-shot.txt; DISPLAY=:99 .devcontainer/capture-daytona-screenshot.sh --output /daytona-artifacts/screenshots/<flow>/<step>.png'\'''
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The "fail fast" screenshot command does not actually stop on picker detection because ; allows execution to continue after a failed grep check.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .opencode/skills/daytona-flow-validator/SKILL.md, line 157:

<comment>The "fail fast" screenshot command does not actually stop on picker detection because `;` allows execution to continue after a failed grep check.</comment>

<file context>
@@ -144,6 +150,18 @@ new screenshot, inspect the new image, and only then share it. If bad evidence
+if a picker is present:
+
+```bash
+daytona exec "$SANDBOX" -- 'bash -lc '\''DISPLAY=:99 wmctrl -l | tee /tmp/windows-before-shot.txt; ! grep -q "Authorize folder" /tmp/windows-before-shot.txt; DISPLAY=:99 .devcontainer/capture-daytona-screenshot.sh --output /daytona-artifacts/screenshots/<flow>/<step>.png'\'''
+```
+
</file context>
Suggested change
daytona exec "$SANDBOX" -- 'bash -lc '\''DISPLAY=:99 wmctrl -l | tee /tmp/windows-before-shot.txt; ! grep -q "Authorize folder" /tmp/windows-before-shot.txt; DISPLAY=:99 .devcontainer/capture-daytona-screenshot.sh --output /daytona-artifacts/screenshots/<flow>/<step>.png'\'''
daytona exec "$SANDBOX" -- 'bash -lc '\''DISPLAY=:99 wmctrl -l | tee /tmp/windows-before-shot.txt && ! grep -q "Authorize folder" /tmp/windows-before-shot.txt && DISPLAY=:99 .devcontainer/capture-daytona-screenshot.sh --output /daytona-artifacts/screenshots/<flow>/<step>.png'\'''

@benjaminshafii
Copy link
Copy Markdown
Member Author

Latest validation update: the end-to-end Marketplace extension-use path now passes in Daytona. After Den onboarding and desktop Marketplace sync, I created and installed the live Marketplace Runtime Probe plugin from Anthropic-Compatible Plugins, verified its skill materialized under .opencode/skills/.../SKILL.md, and sent a desktop chat task in Marketplace Runtime Chat. The chat response included MARKETPLACE_RUNTIME_PROBE_OK, matching the imported skill's deterministic output. Recording: https://8090-7xhivksbzfwmpqc9.daytonaproxy01.net/recordings/marketplace-guided-onboarding-desktop.mp4

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="evals/den-marketplace-guided-onboarding-flow.md">

<violation number="1" location="evals/den-marketplace-guided-onboarding-flow.md:24">
P2: This guidance contradicts the repo eval convention and encourages less reliable interaction methods, which can make recordings/evals flakier.</violation>
</file>

<file name="evals/default-openwork-marketplace-onboarding-flow.md">

<violation number="1" location="evals/default-openwork-marketplace-onboarding-flow.md:33">
P2: The added instruction conflicts with existing eval conventions by preferring UID-based interactions for normal actions, which is less reliable on dynamic React screens.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

## Demo Standard

- The primary eval artifact must be a full human-visible recording, not a final-state clip.
- Drive Den Web through Chrome CDP and desktop through Electron CDP using `browser_snapshot`, `browser_click`, and `browser_fill` wherever possible.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This guidance contradicts the repo eval convention and encourages less reliable interaction methods, which can make recordings/evals flakier.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At evals/den-marketplace-guided-onboarding-flow.md, line 24:

<comment>This guidance contradicts the repo eval convention and encourages less reliable interaction methods, which can make recordings/evals flakier.</comment>

<file context>
@@ -18,6 +18,15 @@ marketplaces from the app.
+## Demo Standard
+
+- The primary eval artifact must be a full human-visible recording, not a final-state clip.
+- Drive Den Web through Chrome CDP and desktop through Electron CDP using `browser_snapshot`, `browser_click`, and `browser_fill` wherever possible.
+- Show the journey click by click: sign-up, org creation, onboarding, marketplace explanation, desktop handoff, desktop sign-in, Marketplace sync, plugin install, and chat response.
+- Use API calls only for setup that the product UI cannot perform yet, such as creating a deterministic test plugin. Immediately show the resulting plugin in the desktop UI.
</file context>

## Demo Standard

- The primary demo should be a full click-by-click recording through Chrome and Electron, not a recording of the final state after hidden setup.
- Use `browser_snapshot` UIDs with `browser_click` and `browser_fill` for normal user actions.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The added instruction conflicts with existing eval conventions by preferring UID-based interactions for normal actions, which is less reliable on dynamic React screens.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At evals/default-openwork-marketplace-onboarding-flow.md, line 33:

<comment>The added instruction conflicts with existing eval conventions by preferring UID-based interactions for normal actions, which is less reliable on dynamic React screens.</comment>

<file context>
@@ -27,6 +27,15 @@ Marketplace containing built-in OpenWork extension capabilities.
+## Demo Standard
+
+- The primary demo should be a full click-by-click recording through Chrome and Electron, not a recording of the final state after hidden setup.
+- Use `browser_snapshot` UIDs with `browser_click` and `browser_fill` for normal user actions.
+- Use `browser_eval`, direct APIs, localStorage writes, direct URLs, or filesystem checks only when the UI cannot perform the step yet.
+- When a shortcut is used, label it as setup or a product gap and return to a visible UI state before continuing the recording.
</file context>

@benjaminshafii
Copy link
Copy Markdown
Member Author

Fresh human-visible Daytona validation completed after runtime fix.\n\nEvidence:\n- Recording: https://8090-d4qz5adl3ytukpri.daytonaproxy01.net/recordings/marketplace-visible-end-to-end-demo.mp4\n- Den sign-up, org creation, guided onboarding, and default Marketplaces shown visibly.\n- Desktop visible folder path created workspace /workspace/visible-demo-workspace.\n- Desktop sign-in completed through the visible paste-link fallback, then org resources showed 2 Marketplaces.\n- Marketplace built-ins rendered as Built-in.\n- Live test plugin Visible Runtime Probe was created via Den API setup, appeared in desktop Marketplace, and installed visibly.\n- Installed skill materialized at /workspace/visible-demo-workspace/.opencode/skills/visible-runtime-probe-plugin/visible-runtime-probe-skill/SKILL.md.\n- Desktop chat runtime responded with VISIBLE_RUNTIME_PROBE_OK.\n\nFix included in this push:\n- 706f2bc fix: start local runtime during onboarding\n\nVerification run:\n- pnpm --filter @openwork/app typecheck: 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