@agent-native/core 0.145.8 → 0.146.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/analytics/actions/compose-dashboard.ts +2 -27
- package/corpus/templates/analytics/actions/get-sql-dashboard.ts +18 -3
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +75 -24
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +16 -24
- package/corpus/templates/analytics/actions/rename-dashboard.ts +2 -24
- package/corpus/templates/analytics/actions/reorder-dashboard-panels.ts +2 -24
- package/corpus/templates/analytics/actions/restore-dashboard-revision.ts +2 -25
- package/corpus/templates/analytics/actions/update-dashboard.ts +4 -32
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +1 -40
- package/corpus/templates/analytics/changelog/2026-08-07-analytics-migrations-now-use-bounded-pressure-aware-backgrou.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-language-selection-now-lives-in-settings-instead-of-the-comm.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-07-template-activity-charts-now-show-only-core-agent-native-app.md +6 -0
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +110 -0
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +450 -0
- package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +2 -2
- package/corpus/templates/analytics/server/lib/analytics-rollup-lock.ts +4 -5
- package/corpus/templates/analytics/server/lib/dashboard-collab-sync.ts +77 -0
- package/corpus/templates/analytics/server/lib/demo-dashboards.ts +2 -23
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +10 -4
- package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +4 -11
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +2 -5
- package/corpus/templates/analytics/server/plugins/db.ts +42 -0
- package/corpus/templates/analytics/server/routes/api/analytics-bigquery/backfill.post.ts +55 -0
- package/corpus/templates/analytics/server/routes/api/dashboard-agent-context.json.get.ts +18 -4
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/brain/server/lib/connectors.ts +38 -14
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/clips/app/components/player/video-player.tsx +1 -1
- package/corpus/templates/clips/changelog/2026-08-07-fixed-trimmed-clips-durations-so-the-main-player-display-mat.md +6 -0
- package/corpus/templates/clips/chrome-extension/STORE_DRAFT.md +1 -1
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/dispatch/changelog/2026-08-07-language-selection-now-lives-in-settings-instead-of-the-disp.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +59 -22
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +10 -1
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +10 -3
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/corpus/templates/slides/actions/generate-image-api.ts +123 -0
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -2
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +13 -0
- package/corpus/templates/slides/app/components/editor/GeneratingSlidePreview.tsx +5 -0
- package/corpus/templates/slides/app/components/editor/ImageGenPanel.tsx +1 -1
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +5 -0
- package/corpus/templates/slides/app/components/presentation/PresenterView.tsx +5 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +3 -0
- package/corpus/templates/slides/app/pages/Presentation.tsx +3 -0
- package/corpus/templates/slides/app/pages/SharedPresentation.tsx +5 -0
- package/corpus/templates/slides/app/routes/slide.tsx +10 -5
- package/corpus/templates/slides/changelog/2026-08-07-deleting-a-deck-no-longer-freezes-the-slides-browser.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-07-slide-previews-and-present-now-keep-deck-colors-consistent.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-07-slides-verify-generated-images-are-persisted-on-the-target-s.md +6 -0
- package/corpus/templates/slides/server/db/schema.ts +1 -0
- package/corpus/templates/slides/server/handlers/share.ts +51 -3
- package/corpus/templates/slides/server/lib/slide-image-insertion.ts +141 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/slides/server/plugins/db.ts +5 -0
- package/corpus/templates/slides/shared/api.ts +2 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/dist/cli/code-agent-executor.js +8 -3
- package/dist/client/AgentPanel.d.ts +10 -4
- package/dist/client/AgentPanel.js +29 -82
- package/dist/client/ConnectBuilderCard.d.ts +7 -7
- package/dist/client/ConnectBuilderCard.js +45 -20
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/config.d.ts +9 -2
- package/dist/config.js +38 -2
- package/dist/db/client.d.ts +13 -1
- package/dist/db/client.js +76 -2
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/migrations.js +22 -4
- package/dist/deploy/build.d.ts +1 -0
- package/dist/deploy/build.js +32 -23
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/scripts/docs/search.js +3 -2
- package/dist/server/agent-chat/prompt-resources.js +4 -3
- package/dist/server/agents-bundle.d.ts +20 -3
- package/dist/server/agents-bundle.js +57 -30
- package/dist/server/better-auth-instance.js +2 -2
- package/dist/server/builder-browser.d.ts +34 -0
- package/dist/server/builder-browser.js +179 -0
- package/dist/server/core-routes-plugin.d.ts +5 -0
- package/dist/server/core-routes-plugin.js +24 -8
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/shared/cache-control.d.ts +2 -2
- package/dist/shared/cache-control.js +2 -2
- package/dist/shared/runtime-config.js +1 -1
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/dist/vite/agent-native-config-loader.d.ts +10 -0
- package/dist/vite/agent-native-config-loader.js +56 -0
- package/dist/vite/agents-bundle-plugin.d.ts +5 -1
- package/dist/vite/agents-bundle-plugin.js +29 -6
- package/dist/vite/client.d.ts +4 -2
- package/dist/vite/client.js +17 -50
- package/dist/vite/index.d.ts +2 -2
- package/dist/vite/index.js +1 -1
- package/docs/content/agent-native-config.mdx +43 -17
- package/docs/content/drop-in-agent.mdx +3 -3
- package/docs/content/environment-variables.mdx +1 -1
- package/docs/content/getting-started-actions.mdx +1 -2
- package/docs/content/getting-started-pages.mdx +1 -2
- package/docs/content/getting-started.mdx +0 -4
- package/docs/content/what-is-agent-native.mdx +4 -4
- package/package.json +1 -1
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +41 -11
- package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +21 -2
- package/docs/content/getting-started-database.mdx +0 -173
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Turn visible project context, a proven thread, skill, or workflow into a
|
|
5
5
|
runnable Agent-Native app with simple buttons, visible agent steps, preview,
|
|
6
6
|
and deployment handoff. Use when a user invokes `/turn-into-app` or asks to
|
|
7
|
-
make a workflow into an app.
|
|
7
|
+
make a workflow into an app, including from Claude or ChatGPT on the web.
|
|
8
8
|
user-invocable: true
|
|
9
9
|
scope: both
|
|
10
10
|
metadata:
|
|
@@ -13,9 +13,36 @@ metadata:
|
|
|
13
13
|
|
|
14
14
|
# Turn Into App
|
|
15
15
|
|
|
16
|
+
## Host execution boundary
|
|
17
|
+
|
|
18
|
+
The build location depends on the host. Treat this as a hard routing rule:
|
|
19
|
+
|
|
20
|
+
- In Claude Web, ChatGPT Web, or a Claude/ChatGPT Project on the web, you are
|
|
21
|
+
the source analyst and handoff orchestrator. You must not build the app in
|
|
22
|
+
the host sandbox. Do not run `npm`, `pnpm`, `npx`, `agent-native create`, or
|
|
23
|
+
`add-app`; do not edit files, create artifacts, or start a local dev server.
|
|
24
|
+
After writing the bounded source brief, call the connected Dispatch action
|
|
25
|
+
`start-workspace-app-creation`. Pass the brief and repeatable workflow in
|
|
26
|
+
`prompt`, plus the inferred `appId`, `description`, `template`, and selected
|
|
27
|
+
`resourceIds` when available. This is the Builder handoff.
|
|
28
|
+
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
|
+
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
34
|
+
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
35
|
+
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
36
|
+
local build or claim that the app exists.
|
|
37
|
+
- In Claude Code, Codex Code, or another local code-agent runtime with a target
|
|
38
|
+
workspace, follow the local implementation steps below. The local agent may
|
|
39
|
+
scaffold, edit, run, and verify the app there.
|
|
40
|
+
|
|
16
41
|
## Default behavior
|
|
17
42
|
|
|
18
|
-
|
|
43
|
+
For a local code-agent runtime this is an end-to-end build skill, not a request
|
|
44
|
+
for an app proposal. For an online host, the end-to-end result is a verified
|
|
45
|
+
Builder handoff and the resulting workspace app, not code written in the host.
|
|
19
46
|
|
|
20
47
|
- With no argument, choose the source in this order: visible project context,
|
|
21
48
|
then the current thread. A fresh Claude or ChatGPT Project is a valid source
|
|
@@ -47,9 +74,12 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
47
74
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
48
75
|
attachment and treat that artifact as imported source material.
|
|
49
76
|
|
|
50
|
-
|
|
51
|
-
buttons and agent handoffs, start its dev
|
|
52
|
-
continue through build/deployment handoff. Do
|
|
77
|
+
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
78
|
+
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
79
|
+
server, verify the main path, and continue through build/deployment handoff. Do
|
|
80
|
+
not stop at a plan. For online hosts, call Dispatch first after the source brief,
|
|
81
|
+
then report the returned Builder branch/path and verify the workspace app through
|
|
82
|
+
Dispatch when it becomes available.
|
|
53
83
|
|
|
54
84
|
## Fresh project context mode
|
|
55
85
|
|
|
@@ -190,12 +220,12 @@ Do not use `create` for an existing workspace; it scaffolds a new standalone
|
|
|
190
220
|
workspace rather than adding an app to the current one.
|
|
191
221
|
|
|
192
222
|
When the source came from a fresh external Project and the target is a Builder
|
|
193
|
-
workspace,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
223
|
+
workspace, the online host path is mandatory: after writing the source brief,
|
|
224
|
+
call `start-workspace-app-creation` with a concise prompt, the inferred app id,
|
|
225
|
+
and the brief's repeatable workflow. Pass selected workspace resource IDs when
|
|
226
|
+
they are available, rather than pasting entire knowledge files. Continue from
|
|
227
|
+
the returned workspace path or Builder branch handoff and report the actual
|
|
228
|
+
verification result. Do not run the local scaffold commands in this host mode.
|
|
199
229
|
|
|
200
230
|
Use a first-party template only when it materially fits the workflow. Keep the
|
|
201
231
|
new app independent from the source thread's working tree unless the user
|
|
@@ -50,14 +50,33 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
61
|
+
|
|
62
|
+
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
63
|
+
orchestrator, not the build environment. After forming the source brief, call
|
|
64
|
+
the Dispatch `start-workspace-app-creation` action so Builder creates the app
|
|
65
|
+
in the connected workspace. Do not use the host's code interpreter, shell,
|
|
66
|
+
artifact editor, `create_workspace_app`, or local `pnpm`/`npm` commands. If the
|
|
67
|
+
handoff action is unavailable, stop and ask the user to authenticate Dispatch;
|
|
68
|
+
do not fall back to a local sandbox build. Claude Code and Codex Code are the
|
|
69
|
+
local-agent exception and may follow the implementation steps in the main
|
|
70
|
+
skill.
|
|
53
71
|
|
|
54
72
|
In a new Project chat, say:
|
|
55
73
|
|
|
56
74
|
```text
|
|
57
75
|
Turn this project into an app. Use the visible Project instructions,
|
|
58
76
|
knowledge files, and any selected successful runs as the source. Create the
|
|
59
|
-
app in the connected Agent-Native workspace
|
|
60
|
-
and report the real path and
|
|
77
|
+
app in the connected Agent-Native workspace through Dispatch and Builder, keep
|
|
78
|
+
the source brief bounded, and report the real Builder branch/path and
|
|
79
|
+
verification result. Do not build it in this chat's sandbox.
|
|
61
80
|
```
|
|
62
81
|
|
|
63
82
|
If the host does not show the Project instructions or files to the model, stop
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Turn visible project context, a proven thread, skill, or workflow into a
|
|
5
5
|
runnable Agent-Native app with simple buttons, visible agent steps, preview,
|
|
6
6
|
and deployment handoff. Use when a user invokes `/turn-into-app` or asks to
|
|
7
|
-
make a workflow into an app.
|
|
7
|
+
make a workflow into an app, including from Claude or ChatGPT on the web.
|
|
8
8
|
user-invocable: true
|
|
9
9
|
scope: both
|
|
10
10
|
metadata:
|
|
@@ -13,9 +13,36 @@ metadata:
|
|
|
13
13
|
|
|
14
14
|
# Turn Into App
|
|
15
15
|
|
|
16
|
+
## Host execution boundary
|
|
17
|
+
|
|
18
|
+
The build location depends on the host. Treat this as a hard routing rule:
|
|
19
|
+
|
|
20
|
+
- In Claude Web, ChatGPT Web, or a Claude/ChatGPT Project on the web, you are
|
|
21
|
+
the source analyst and handoff orchestrator. You must not build the app in
|
|
22
|
+
the host sandbox. Do not run `npm`, `pnpm`, `npx`, `agent-native create`, or
|
|
23
|
+
`add-app`; do not edit files, create artifacts, or start a local dev server.
|
|
24
|
+
After writing the bounded source brief, call the connected Dispatch action
|
|
25
|
+
`start-workspace-app-creation`. Pass the brief and repeatable workflow in
|
|
26
|
+
`prompt`, plus the inferred `appId`, `description`, `template`, and selected
|
|
27
|
+
`resourceIds` when available. This is the Builder handoff.
|
|
28
|
+
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
|
+
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
34
|
+
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
35
|
+
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
36
|
+
local build or claim that the app exists.
|
|
37
|
+
- In Claude Code, Codex Code, or another local code-agent runtime with a target
|
|
38
|
+
workspace, follow the local implementation steps below. The local agent may
|
|
39
|
+
scaffold, edit, run, and verify the app there.
|
|
40
|
+
|
|
16
41
|
## Default behavior
|
|
17
42
|
|
|
18
|
-
|
|
43
|
+
For a local code-agent runtime this is an end-to-end build skill, not a request
|
|
44
|
+
for an app proposal. For an online host, the end-to-end result is a verified
|
|
45
|
+
Builder handoff and the resulting workspace app, not code written in the host.
|
|
19
46
|
|
|
20
47
|
- With no argument, choose the source in this order: visible project context,
|
|
21
48
|
then the current thread. A fresh Claude or ChatGPT Project is a valid source
|
|
@@ -47,9 +74,12 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
47
74
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
48
75
|
attachment and treat that artifact as imported source material.
|
|
49
76
|
|
|
50
|
-
|
|
51
|
-
buttons and agent handoffs, start its dev
|
|
52
|
-
continue through build/deployment handoff. Do
|
|
77
|
+
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
78
|
+
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
79
|
+
server, verify the main path, and continue through build/deployment handoff. Do
|
|
80
|
+
not stop at a plan. For online hosts, call Dispatch first after the source brief,
|
|
81
|
+
then report the returned Builder branch/path and verify the workspace app through
|
|
82
|
+
Dispatch when it becomes available.
|
|
53
83
|
|
|
54
84
|
## Fresh project context mode
|
|
55
85
|
|
|
@@ -190,12 +220,12 @@ Do not use `create` for an existing workspace; it scaffolds a new standalone
|
|
|
190
220
|
workspace rather than adding an app to the current one.
|
|
191
221
|
|
|
192
222
|
When the source came from a fresh external Project and the target is a Builder
|
|
193
|
-
workspace,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
223
|
+
workspace, the online host path is mandatory: after writing the source brief,
|
|
224
|
+
call `start-workspace-app-creation` with a concise prompt, the inferred app id,
|
|
225
|
+
and the brief's repeatable workflow. Pass selected workspace resource IDs when
|
|
226
|
+
they are available, rather than pasting entire knowledge files. Continue from
|
|
227
|
+
the returned workspace path or Builder branch handoff and report the actual
|
|
228
|
+
verification result. Do not run the local scaffold commands in this host mode.
|
|
199
229
|
|
|
200
230
|
Use a first-party template only when it materially fits the workflow. Keep the
|
|
201
231
|
new app independent from the source thread's working tree unless the user
|
|
@@ -50,14 +50,33 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
61
|
+
|
|
62
|
+
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
63
|
+
orchestrator, not the build environment. After forming the source brief, call
|
|
64
|
+
the Dispatch `start-workspace-app-creation` action so Builder creates the app
|
|
65
|
+
in the connected workspace. Do not use the host's code interpreter, shell,
|
|
66
|
+
artifact editor, `create_workspace_app`, or local `pnpm`/`npm` commands. If the
|
|
67
|
+
handoff action is unavailable, stop and ask the user to authenticate Dispatch;
|
|
68
|
+
do not fall back to a local sandbox build. Claude Code and Codex Code are the
|
|
69
|
+
local-agent exception and may follow the implementation steps in the main
|
|
70
|
+
skill.
|
|
53
71
|
|
|
54
72
|
In a new Project chat, say:
|
|
55
73
|
|
|
56
74
|
```text
|
|
57
75
|
Turn this project into an app. Use the visible Project instructions,
|
|
58
76
|
knowledge files, and any selected successful runs as the source. Create the
|
|
59
|
-
app in the connected Agent-Native workspace
|
|
60
|
-
and report the real path and
|
|
77
|
+
app in the connected Agent-Native workspace through Dispatch and Builder, keep
|
|
78
|
+
the source brief bounded, and report the real Builder branch/path and
|
|
79
|
+
verification result. Do not build it in this chat's sandbox.
|
|
61
80
|
```
|
|
62
81
|
|
|
63
82
|
If the host does not show the Project instructions or files to the model, stop
|
|
@@ -53,6 +53,14 @@ Call the action with the destination so Assets can ground the generation:
|
|
|
53
53
|
generate-image-api { prompt, deckId, slideId, slideContent }
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
For direct insertion, add `insertIntoSlide: true`. This requires both IDs and
|
|
57
|
+
only returns `inserted: true` after Slides writes the transformed HTML through
|
|
58
|
+
`update-slide` and re-reads it through `get-deck` to find the image source.
|
|
59
|
+
Never say the image was added based on `url`, `previewUrl`, or a completed
|
|
60
|
+
Assets reply alone. For preview-only variations, leave `insertIntoSlide` false;
|
|
61
|
+
after choosing one, use `update-slide` and verify the persisted source with
|
|
62
|
+
`get-deck` before claiming insertion.
|
|
63
|
+
|
|
56
64
|
Do **not** reach for the generic `call-agent` tool to ask Assets for an image.
|
|
57
65
|
It talks to the same app, so it looks equivalent, but it skips the slide
|
|
58
66
|
grounding, the completed-vs-failed task handling, and the ready-to-render
|
|
@@ -65,7 +73,8 @@ generation settings, and provenance. Include the active design system's
|
|
|
65
73
|
image-style guidance in the prompt context, but do not ask Assets to invent a
|
|
66
74
|
competing brand direction.
|
|
67
75
|
|
|
68
|
-
|
|
76
|
+
Use the returned `previewUrl` for previews. Do not drop it into slide HTML
|
|
77
|
+
without the verified insertion workflow above.
|
|
69
78
|
|
|
70
79
|
## Showing the result in chat
|
|
71
80
|
|
|
@@ -34,8 +34,13 @@ legacy image action directly:
|
|
|
34
34
|
image syntax (``), not a plain link (`[Variation 1](url)`)
|
|
35
35
|
— the chat renders `![]()` as an actual image but `[]()` as a bare link.
|
|
36
36
|
4. Preserve the returned `assetId`, `runId`, `previewUrl`, and `downloadUrl`.
|
|
37
|
-
5.
|
|
38
|
-
|
|
37
|
+
5. For direct insertion, call `generate-image-api` with `insertIntoSlide: true`,
|
|
38
|
+
`deckId`, and `slideId`. Only say the image was added when it returns
|
|
39
|
+
`inserted: true`; a preview URL is not proof of a slide write.
|
|
40
|
+
6. For preview-only variations, place the chosen URL with `update-slide`, then
|
|
41
|
+
re-read that slide with `get-deck` and confirm the persisted HTML contains
|
|
42
|
+
the image source before reporting success.
|
|
43
|
+
7. For feedback, refine the same asset rather than starting an unrelated run.
|
|
39
44
|
|
|
40
45
|
### Context to pass
|
|
41
46
|
|
|
@@ -72,4 +77,6 @@ pnpm action search-images --q "Acme logo transparent" --count 5
|
|
|
72
77
|
- Use `.fmd-img-placeholder` divs in slides before real images are generated
|
|
73
78
|
- Use one canonical provider action per conceptual search; do not loop legacy
|
|
74
79
|
provider scripts or manually guess provider URLs
|
|
75
|
-
-
|
|
80
|
+
- Never claim image insertion from a generation response alone; require the
|
|
81
|
+
verified `inserted: true` response, or an `update-slide` plus `get-deck`
|
|
82
|
+
verification for preview-only placement
|
|
@@ -4,7 +4,7 @@ description: >-
|
|
|
4
4
|
Turn visible project context, a proven thread, skill, or workflow into a
|
|
5
5
|
runnable Agent-Native app with simple buttons, visible agent steps, preview,
|
|
6
6
|
and deployment handoff. Use when a user invokes `/turn-into-app` or asks to
|
|
7
|
-
make a workflow into an app.
|
|
7
|
+
make a workflow into an app, including from Claude or ChatGPT on the web.
|
|
8
8
|
user-invocable: true
|
|
9
9
|
scope: both
|
|
10
10
|
metadata:
|
|
@@ -13,9 +13,36 @@ metadata:
|
|
|
13
13
|
|
|
14
14
|
# Turn Into App
|
|
15
15
|
|
|
16
|
+
## Host execution boundary
|
|
17
|
+
|
|
18
|
+
The build location depends on the host. Treat this as a hard routing rule:
|
|
19
|
+
|
|
20
|
+
- In Claude Web, ChatGPT Web, or a Claude/ChatGPT Project on the web, you are
|
|
21
|
+
the source analyst and handoff orchestrator. You must not build the app in
|
|
22
|
+
the host sandbox. Do not run `npm`, `pnpm`, `npx`, `agent-native create`, or
|
|
23
|
+
`add-app`; do not edit files, create artifacts, or start a local dev server.
|
|
24
|
+
After writing the bounded source brief, call the connected Dispatch action
|
|
25
|
+
`start-workspace-app-creation`. Pass the brief and repeatable workflow in
|
|
26
|
+
`prompt`, plus the inferred `appId`, `description`, `template`, and selected
|
|
27
|
+
`resourceIds` when available. This is the Builder handoff.
|
|
28
|
+
- Do not substitute the generic `create_workspace_app` MCP tool in an online
|
|
29
|
+
host. That tool is a local workspace scaffolder, not the Builder handoff.
|
|
30
|
+
- Connect the Agent-Native Dispatch MCP connector only. Dispatch uses the
|
|
31
|
+
authenticated Builder Projects API to reuse or provision the workspace
|
|
32
|
+
project before starting the Builder Cloud Agent; a separate Builder CMS MCP
|
|
33
|
+
connection is not required for this workflow.
|
|
34
|
+
- If `start-workspace-app-creation` is not available or Dispatch is not
|
|
35
|
+
authenticated, stop with the connector setup needed. Do not fall back to a
|
|
36
|
+
local build or claim that the app exists.
|
|
37
|
+
- In Claude Code, Codex Code, or another local code-agent runtime with a target
|
|
38
|
+
workspace, follow the local implementation steps below. The local agent may
|
|
39
|
+
scaffold, edit, run, and verify the app there.
|
|
40
|
+
|
|
16
41
|
## Default behavior
|
|
17
42
|
|
|
18
|
-
|
|
43
|
+
For a local code-agent runtime this is an end-to-end build skill, not a request
|
|
44
|
+
for an app proposal. For an online host, the end-to-end result is a verified
|
|
45
|
+
Builder handoff and the resulting workspace app, not code written in the host.
|
|
19
46
|
|
|
20
47
|
- With no argument, choose the source in this order: visible project context,
|
|
21
48
|
then the current thread. A fresh Claude or ChatGPT Project is a valid source
|
|
@@ -47,9 +74,12 @@ private web access, invent an importer, add fake OAuth, or scrape a logged-in
|
|
|
47
74
|
page. If the needed context is not visible, ask for an export, transcript, or
|
|
48
75
|
attachment and treat that artifact as imported source material.
|
|
49
76
|
|
|
50
|
-
|
|
51
|
-
buttons and agent handoffs, start its dev
|
|
52
|
-
continue through build/deployment handoff. Do
|
|
77
|
+
For local code-agent runtimes, deliver a fresh app in a new directory,
|
|
78
|
+
implement the repeatable workflow with buttons and agent handoffs, start its dev
|
|
79
|
+
server, verify the main path, and continue through build/deployment handoff. Do
|
|
80
|
+
not stop at a plan. For online hosts, call Dispatch first after the source brief,
|
|
81
|
+
then report the returned Builder branch/path and verify the workspace app through
|
|
82
|
+
Dispatch when it becomes available.
|
|
53
83
|
|
|
54
84
|
## Fresh project context mode
|
|
55
85
|
|
|
@@ -190,12 +220,12 @@ Do not use `create` for an existing workspace; it scaffolds a new standalone
|
|
|
190
220
|
workspace rather than adding an app to the current one.
|
|
191
221
|
|
|
192
222
|
When the source came from a fresh external Project and the target is a Builder
|
|
193
|
-
workspace,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
223
|
+
workspace, the online host path is mandatory: after writing the source brief,
|
|
224
|
+
call `start-workspace-app-creation` with a concise prompt, the inferred app id,
|
|
225
|
+
and the brief's repeatable workflow. Pass selected workspace resource IDs when
|
|
226
|
+
they are available, rather than pasting entire knowledge files. Continue from
|
|
227
|
+
the returned workspace path or Builder branch handoff and report the actual
|
|
228
|
+
verification result. Do not run the local scaffold commands in this host mode.
|
|
199
229
|
|
|
200
230
|
Use a first-party template only when it materially fits the workflow. Keep the
|
|
201
231
|
new app independent from the source thread's working tree unless the user
|
|
@@ -50,14 +50,33 @@ skills. For a ChatGPT Project or any host that exposes only the MCP connector,
|
|
|
50
50
|
also place the skill instructions or this reference in the Project
|
|
51
51
|
instructions/knowledge files. Then add and authenticate the Dispatch MCP
|
|
52
52
|
connector from the packaged `adapters/chatgpt-mcp/connector.json`.
|
|
53
|
+
This single connector is enough: Dispatch provisions or reuses the Builder
|
|
54
|
+
project through the Builder Projects API, so do not ask the user to add a
|
|
55
|
+
separate Builder CMS MCP for app creation.
|
|
56
|
+
Builder's separate Fusion MCP is available as a custom remote connector at
|
|
57
|
+
`https://mcp.builder.io/mcp/fusion` for direct Builder work. It can run an
|
|
58
|
+
existing project, but it cannot provision the repo-backed Agent-Native
|
|
59
|
+
workspace project, so it is optional and not a replacement for the Dispatch
|
|
60
|
+
handoff in this skill. Do not add Builder's CMS MCP for this workflow.
|
|
61
|
+
|
|
62
|
+
For Claude Web, ChatGPT Web, and their web Projects, the host is an
|
|
63
|
+
orchestrator, not the build environment. After forming the source brief, call
|
|
64
|
+
the Dispatch `start-workspace-app-creation` action so Builder creates the app
|
|
65
|
+
in the connected workspace. Do not use the host's code interpreter, shell,
|
|
66
|
+
artifact editor, `create_workspace_app`, or local `pnpm`/`npm` commands. If the
|
|
67
|
+
handoff action is unavailable, stop and ask the user to authenticate Dispatch;
|
|
68
|
+
do not fall back to a local sandbox build. Claude Code and Codex Code are the
|
|
69
|
+
local-agent exception and may follow the implementation steps in the main
|
|
70
|
+
skill.
|
|
53
71
|
|
|
54
72
|
In a new Project chat, say:
|
|
55
73
|
|
|
56
74
|
```text
|
|
57
75
|
Turn this project into an app. Use the visible Project instructions,
|
|
58
76
|
knowledge files, and any selected successful runs as the source. Create the
|
|
59
|
-
app in the connected Agent-Native workspace
|
|
60
|
-
and report the real path and
|
|
77
|
+
app in the connected Agent-Native workspace through Dispatch and Builder, keep
|
|
78
|
+
the source brief bounded, and report the real Builder branch/path and
|
|
79
|
+
verification result. Do not build it in this chat's sandbox.
|
|
61
80
|
```
|
|
62
81
|
|
|
63
82
|
If the host does not show the Project instructions or files to the model, stop
|
|
@@ -8,16 +8,31 @@ import {
|
|
|
8
8
|
extractAssetUrl,
|
|
9
9
|
imagePreviewMarkdown,
|
|
10
10
|
} from "../server/lib/assets-image-delegation.js";
|
|
11
|
+
import {
|
|
12
|
+
insertImageIntoSlideHtml,
|
|
13
|
+
slideHtmlContainsImageSource,
|
|
14
|
+
} from "../server/lib/slide-image-insertion.js";
|
|
11
15
|
import {
|
|
12
16
|
DEFAULT_STYLE_REFERENCE_URLS,
|
|
13
17
|
normalizeReferenceUrls,
|
|
14
18
|
} from "../shared/api.js";
|
|
19
|
+
import getDeckAction from "./get-deck.js";
|
|
20
|
+
import updateSlideAction from "./update-slide.js";
|
|
15
21
|
|
|
16
22
|
interface ReferenceImage {
|
|
17
23
|
data: string; // base64
|
|
18
24
|
mimeType: string;
|
|
19
25
|
}
|
|
20
26
|
|
|
27
|
+
interface DeckSlide {
|
|
28
|
+
id?: string;
|
|
29
|
+
content?: unknown;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface DeckWithSlides {
|
|
33
|
+
slides?: DeckSlide[];
|
|
34
|
+
}
|
|
35
|
+
|
|
21
36
|
async function urlToReferenceImage(
|
|
22
37
|
url: string,
|
|
23
38
|
): Promise<ReferenceImage | null> {
|
|
@@ -33,6 +48,83 @@ async function urlToReferenceImage(
|
|
|
33
48
|
}
|
|
34
49
|
}
|
|
35
50
|
|
|
51
|
+
function parseGeneratedImageUrl(url: string | undefined): string {
|
|
52
|
+
if (!url) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
"Image generation did not return a parseable image URL for insertion",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const parsed = new URL(url);
|
|
59
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
60
|
+
throw new Error("unsupported protocol");
|
|
61
|
+
}
|
|
62
|
+
return parsed.toString();
|
|
63
|
+
} catch {
|
|
64
|
+
throw new Error(
|
|
65
|
+
"Image generation did not return a parseable image URL for insertion",
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function insertGeneratedImage({
|
|
71
|
+
deckId,
|
|
72
|
+
slideId,
|
|
73
|
+
prompt,
|
|
74
|
+
url,
|
|
75
|
+
}: {
|
|
76
|
+
deckId: string | undefined;
|
|
77
|
+
slideId: string | undefined;
|
|
78
|
+
prompt: string;
|
|
79
|
+
url: string | undefined;
|
|
80
|
+
}): Promise<{ inserted: true; url: string }> {
|
|
81
|
+
if (!deckId || !slideId) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
"deckId and slideId are required when insertIntoSlide is true",
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const imageUrl = parseGeneratedImageUrl(url);
|
|
88
|
+
const deck = (await getDeckAction.run({ id: deckId })) as DeckWithSlides;
|
|
89
|
+
const slide = deck.slides?.find((candidate) => candidate.id === slideId);
|
|
90
|
+
if (!slide || typeof slide.content !== "string") {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Slide ${slideId} was not found in deck ${deckId} for image insertion`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const fullContent = insertImageIntoSlideHtml(slide.content, imageUrl, {
|
|
97
|
+
alt: prompt,
|
|
98
|
+
});
|
|
99
|
+
const update = await updateSlideAction.run({
|
|
100
|
+
deckId,
|
|
101
|
+
slideId,
|
|
102
|
+
fullContent,
|
|
103
|
+
preserveSource: true,
|
|
104
|
+
});
|
|
105
|
+
if (!update.ok || !("applied" in update) || !update.applied) {
|
|
106
|
+
throw new Error(`Image insertion was not applied to slide ${slideId}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const verifiedDeck = (await getDeckAction.run({
|
|
110
|
+
id: deckId,
|
|
111
|
+
})) as DeckWithSlides;
|
|
112
|
+
const verifiedSlide = verifiedDeck.slides?.find(
|
|
113
|
+
(candidate) => candidate.id === slideId,
|
|
114
|
+
);
|
|
115
|
+
if (
|
|
116
|
+
!verifiedSlide ||
|
|
117
|
+
typeof verifiedSlide.content !== "string" ||
|
|
118
|
+
!slideHtmlContainsImageSource(verifiedSlide.content, imageUrl)
|
|
119
|
+
) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Image insertion could not be verified on slide ${slideId}`,
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return { inserted: true, url: imageUrl };
|
|
126
|
+
}
|
|
127
|
+
|
|
36
128
|
export default defineAction({
|
|
37
129
|
description:
|
|
38
130
|
"Generate a slide image. Delegates to the Assets app over A2A so generations use the brand library, presets, and audit log; falls back to a local Gemini/OpenAI key only when Assets is unreachable. Show the returned `url` to the user as an inline markdown image () so it renders in chat, never as a bare link.",
|
|
@@ -46,6 +138,13 @@ export default defineAction({
|
|
|
46
138
|
),
|
|
47
139
|
deckId: z.string().optional().describe("Deck the image is destined for"),
|
|
48
140
|
slideId: z.string().optional().describe("Slide the image is destined for"),
|
|
141
|
+
insertIntoSlide: z
|
|
142
|
+
.boolean()
|
|
143
|
+
.optional()
|
|
144
|
+
.default(false)
|
|
145
|
+
.describe(
|
|
146
|
+
"Insert the generated image into deckId/slideId and verify it persisted",
|
|
147
|
+
),
|
|
49
148
|
slideContent: z
|
|
50
149
|
.string()
|
|
51
150
|
.optional()
|
|
@@ -60,6 +159,11 @@ export default defineAction({
|
|
|
60
159
|
if (!prompt?.trim()) {
|
|
61
160
|
throw new Error("Prompt is required");
|
|
62
161
|
}
|
|
162
|
+
if (args.insertIntoSlide && (!args.deckId || !args.slideId)) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
"deckId and slideId are required when insertIntoSlide is true",
|
|
165
|
+
);
|
|
166
|
+
}
|
|
63
167
|
|
|
64
168
|
const delegation = await delegateImageGenerationToAssets({
|
|
65
169
|
prompt,
|
|
@@ -73,6 +177,14 @@ export default defineAction({
|
|
|
73
177
|
const url = extractAssetUrl(delegation.reply, {
|
|
74
178
|
baseUrl: delegation.target,
|
|
75
179
|
});
|
|
180
|
+
const insertion = args.insertIntoSlide
|
|
181
|
+
? await insertGeneratedImage({
|
|
182
|
+
deckId: args.deckId,
|
|
183
|
+
slideId: args.slideId,
|
|
184
|
+
prompt,
|
|
185
|
+
url: url ?? undefined,
|
|
186
|
+
})
|
|
187
|
+
: {};
|
|
76
188
|
return {
|
|
77
189
|
source: "assets-a2a" as const,
|
|
78
190
|
prompt,
|
|
@@ -80,6 +192,7 @@ export default defineAction({
|
|
|
80
192
|
// rather than guessing at URLs it did not return.
|
|
81
193
|
reply: delegation.reply,
|
|
82
194
|
...(url ? { url, showToUser: imagePreviewMarkdown(prompt, url) } : {}),
|
|
195
|
+
...insertion,
|
|
83
196
|
};
|
|
84
197
|
}
|
|
85
198
|
|
|
@@ -128,6 +241,15 @@ export default defineAction({
|
|
|
128
241
|
);
|
|
129
242
|
}
|
|
130
243
|
|
|
244
|
+
const insertion = args.insertIntoSlide
|
|
245
|
+
? await insertGeneratedImage({
|
|
246
|
+
deckId: args.deckId,
|
|
247
|
+
slideId: args.slideId,
|
|
248
|
+
prompt,
|
|
249
|
+
url: uploaded.url,
|
|
250
|
+
})
|
|
251
|
+
: {};
|
|
252
|
+
|
|
131
253
|
return {
|
|
132
254
|
source: "slides-fallback" as const,
|
|
133
255
|
fallbackReason: delegation.reason,
|
|
@@ -135,6 +257,7 @@ export default defineAction({
|
|
|
135
257
|
url: uploaded.url,
|
|
136
258
|
model: result.model,
|
|
137
259
|
prompt,
|
|
260
|
+
...insertion,
|
|
138
261
|
};
|
|
139
262
|
},
|
|
140
263
|
});
|
|
@@ -59,6 +59,7 @@ export default function DeckCard({
|
|
|
59
59
|
const [contextOpen, setContextOpen] = useState(false);
|
|
60
60
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
61
61
|
const pendingRenameRef = useRef(false);
|
|
62
|
+
const pendingDeleteRef = useRef(false);
|
|
62
63
|
const pendingWorkspaceDefaultRef = useRef(false);
|
|
63
64
|
|
|
64
65
|
useEffect(() => {
|
|
@@ -227,6 +228,11 @@ export default function DeckCard({
|
|
|
227
228
|
pendingWorkspaceDefaultRef.current = false;
|
|
228
229
|
onSetWorkspaceDefault?.(deck.id, !isWorkspaceDefault);
|
|
229
230
|
}
|
|
231
|
+
if (pendingDeleteRef.current) {
|
|
232
|
+
e.preventDefault();
|
|
233
|
+
pendingDeleteRef.current = false;
|
|
234
|
+
setTimeout(() => onDelete(deck.id), 0);
|
|
235
|
+
}
|
|
230
236
|
}}
|
|
231
237
|
>
|
|
232
238
|
<DropdownMenuItem
|
|
@@ -268,8 +274,10 @@ export default function DeckCard({
|
|
|
268
274
|
)}
|
|
269
275
|
<DropdownMenuSeparator />
|
|
270
276
|
<DropdownMenuItem
|
|
271
|
-
onSelect={() => {
|
|
272
|
-
|
|
277
|
+
onSelect={(event) => {
|
|
278
|
+
event.preventDefault();
|
|
279
|
+
pendingDeleteRef.current = true;
|
|
280
|
+
setMenuOpen(false);
|
|
273
281
|
}}
|
|
274
282
|
className="text-red-400 focus:text-red-400"
|
|
275
283
|
>
|