@agent-native/core 0.84.12 → 0.84.14

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.
Files changed (112) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +19 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/durable-background.ts +42 -5
  5. package/corpus/core/src/agent/production-agent.ts +72 -10
  6. package/corpus/core/src/agent/run-manager.ts +84 -4
  7. package/corpus/core/src/agent/run-store.ts +55 -11
  8. package/corpus/core/src/chat-threads/store.ts +2 -0
  9. package/corpus/core/src/cli/skills.ts +10 -6
  10. package/corpus/core/src/client/AssistantChat.tsx +40 -9
  11. package/corpus/core/src/client/agent-chat-adapter.ts +44 -5
  12. package/corpus/core/src/client/blocks/library/diagram.tsx +3 -3
  13. package/corpus/core/src/client/chat/message-components.tsx +17 -0
  14. package/corpus/core/src/client/chat/run-recovery.tsx +52 -44
  15. package/corpus/core/src/client/chat/tool-call-display.tsx +7 -2
  16. package/corpus/core/src/observability/traces.ts +17 -3
  17. package/corpus/core/src/server/agent-chat-plugin.ts +12 -1
  18. package/corpus/core/src/shared/streaming-text-smoothing.ts +10 -5
  19. package/corpus/core/src/styles/blocks.css +44 -1
  20. package/corpus/templates/clips/app/components/library/recording-card.tsx +14 -4
  21. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +10 -12
  22. package/corpus/templates/clips/app/hooks/use-library.ts +7 -4
  23. package/corpus/templates/clips/app/lib/recording-status.ts +32 -0
  24. package/corpus/templates/clips/changelog/2026-07-01-chrome-extension-recordings-stream-uploads-while-recording.md +6 -0
  25. package/corpus/templates/clips/changelog/2026-07-01-dictation-keeps-listening-through-natural-pauses-and-gives-c.md +6 -0
  26. package/corpus/templates/clips/changelog/2026-07-01-redoing-a-paused-desktop-recording-no-longer-leaves-the-recording-controls-disabled.md +6 -0
  27. package/corpus/templates/clips/changelog/2026-07-01-stalled-clip-uploads-now-update-in-the-library-and-surface-as-failed.md +6 -0
  28. package/corpus/templates/clips/chrome-extension/src/background.ts +8 -0
  29. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +61 -16
  30. package/corpus/templates/clips/desktop/src/lib/recorder.ts +36 -18
  31. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +99 -27
  32. package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +4 -43
  33. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +3 -0
  34. package/corpus/templates/clips/desktop/src/styles.css +5 -48
  35. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +4 -5
  36. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +15 -6
  37. package/corpus/templates/design/AGENTS.md +8 -4
  38. package/corpus/templates/design/actions/create-design.ts +1 -0
  39. package/corpus/templates/design/actions/duplicate-design.ts +3 -1
  40. package/corpus/templates/design/actions/edit-design.ts +43 -13
  41. package/corpus/templates/design/actions/generate-design.ts +5 -1
  42. package/corpus/templates/design/actions/present-design-variants.ts +17 -12
  43. package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
  44. package/corpus/templates/design/app/pages/DesignEditor.tsx +2 -2
  45. package/corpus/templates/design/changelog/2026-07-01-org-members-can-see-design-projects-created-in-their-workspace.md +6 -0
  46. package/corpus/templates/design/server/plugins/db.ts +9 -0
  47. package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +44 -1
  48. package/corpus/templates/plan/changelog/2026-07-01-visual-plan-and-recap-diagram-labels-now-wrap-inside-their-b.md +6 -0
  49. package/dist/agent/durable-background.d.ts +3 -0
  50. package/dist/agent/durable-background.d.ts.map +1 -1
  51. package/dist/agent/durable-background.js +33 -3
  52. package/dist/agent/durable-background.js.map +1 -1
  53. package/dist/agent/production-agent.d.ts +1 -0
  54. package/dist/agent/production-agent.d.ts.map +1 -1
  55. package/dist/agent/production-agent.js +55 -9
  56. package/dist/agent/production-agent.js.map +1 -1
  57. package/dist/agent/run-manager.d.ts +2 -0
  58. package/dist/agent/run-manager.d.ts.map +1 -1
  59. package/dist/agent/run-manager.js +68 -5
  60. package/dist/agent/run-manager.js.map +1 -1
  61. package/dist/agent/run-store.d.ts +9 -0
  62. package/dist/agent/run-store.d.ts.map +1 -1
  63. package/dist/agent/run-store.js +47 -11
  64. package/dist/agent/run-store.js.map +1 -1
  65. package/dist/chat-threads/store.d.ts +1 -0
  66. package/dist/chat-threads/store.d.ts.map +1 -1
  67. package/dist/chat-threads/store.js +2 -0
  68. package/dist/chat-threads/store.js.map +1 -1
  69. package/dist/cli/skills.d.ts.map +1 -1
  70. package/dist/cli/skills.js +10 -6
  71. package/dist/cli/skills.js.map +1 -1
  72. package/dist/client/AssistantChat.d.ts +10 -0
  73. package/dist/client/AssistantChat.d.ts.map +1 -1
  74. package/dist/client/AssistantChat.js +26 -8
  75. package/dist/client/AssistantChat.js.map +1 -1
  76. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  77. package/dist/client/agent-chat-adapter.js +40 -5
  78. package/dist/client/agent-chat-adapter.js.map +1 -1
  79. package/dist/client/blocks/library/diagram.js +3 -3
  80. package/dist/client/blocks/library/diagram.js.map +1 -1
  81. package/dist/client/chat/message-components.d.ts +3 -1
  82. package/dist/client/chat/message-components.d.ts.map +1 -1
  83. package/dist/client/chat/message-components.js +16 -2
  84. package/dist/client/chat/message-components.js.map +1 -1
  85. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  86. package/dist/client/chat/run-recovery.js +15 -10
  87. package/dist/client/chat/run-recovery.js.map +1 -1
  88. package/dist/client/chat/tool-call-display.d.ts +1 -0
  89. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  90. package/dist/client/chat/tool-call-display.js +3 -2
  91. package/dist/client/chat/tool-call-display.js.map +1 -1
  92. package/dist/collab/awareness.d.ts +2 -2
  93. package/dist/collab/awareness.d.ts.map +1 -1
  94. package/dist/collab/routes.d.ts +1 -1
  95. package/dist/notifications/routes.d.ts +3 -3
  96. package/dist/observability/routes.d.ts +6 -6
  97. package/dist/observability/traces.d.ts +5 -0
  98. package/dist/observability/traces.d.ts.map +1 -1
  99. package/dist/observability/traces.js +9 -3
  100. package/dist/observability/traces.js.map +1 -1
  101. package/dist/resources/handlers.d.ts +2 -2
  102. package/dist/server/agent-chat-plugin.d.ts +2 -1
  103. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  104. package/dist/server/agent-chat-plugin.js +8 -3
  105. package/dist/server/agent-chat-plugin.js.map +1 -1
  106. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  107. package/dist/server/transcribe-voice.d.ts +1 -1
  108. package/dist/shared/streaming-text-smoothing.d.ts.map +1 -1
  109. package/dist/shared/streaming-text-smoothing.js +8 -5
  110. package/dist/shared/streaming-text-smoothing.js.map +1 -1
  111. package/dist/styles/blocks.css +44 -1
  112. package/package.json +1 -1
@@ -119,14 +119,21 @@ Each `content` is a complete, self-contained document (Alpine.js + Tailwind via
119
119
 
120
120
  Wait for the user's pick before refining. Once they choose, keep the selected
121
121
  screen, delete the unchosen variant screens with `delete-file`, and continue
122
- from the kept screen. If inline chat choice buttons are unavailable in the host,
123
- ask the user to tell you the preferred screen name. Do not ask them to paste HTML
124
- or a generated handoff summary; the variants are already real screens on the
125
- board.
122
+ from the kept screen by calling `get-design-snapshot` with the selected
123
+ screen's `fileId`, then calling `edit-design` on that same `fileId`. Use
124
+ `mode: "replace-file"` when expanding the representative placeholder into the
125
+ full chosen direction. Do not call `generate-design` after a variant pick. If
126
+ inline chat choice buttons are unavailable in the host, ask the user to tell you
127
+ the preferred screen name. Do not ask them to paste HTML or a generated handoff
128
+ summary; the variants are already real screens on the board.
126
129
 
127
130
  ### Phase 3 — Save with `generate-design` (when not using variants)
128
131
 
129
- Skip variants and call `generate-design` directly for: refinements to an already-picked design, multi-screen additions to an existing design, or one-shot prompts where the direction is unambiguous.
132
+ Skip variants and call `generate-design` directly for: a brand-new first
133
+ renderable file, multi-screen additions to an existing design, or one-shot
134
+ prompts where the direction is unambiguous. For refinements to an already-picked
135
+ design or selected screen, use `get-design-snapshot` followed by `edit-design`
136
+ instead.
130
137
 
131
138
  ```bash
132
139
  pnpm action generate-design \
@@ -476,7 +483,9 @@ regeneration is slow, expensive, and regresses unrelated parts.
476
483
  Each `search` must match the file **exactly and uniquely** — include enough
477
484
  surrounding context to be unambiguous. Wrapping an element in a new div is
478
485
  just a search/replace whose `replace` adds the wrapper around the original.
479
- 3. **Reserve `generate-design` for** net-new files or large structural rewrites.
486
+ 3. **Reserve `generate-design` for** net-new files. For large structural
487
+ rewrites of an existing selected file, call `edit-design` with
488
+ `mode: "replace-file"` and the exact `fileId` from `get-design-snapshot`.
480
489
  Never resend files you aren't changing.
481
490
  4. **Treat `:root` as the global spec.** For theme-wide restyles, edit the
482
491
  tokens in `:root` rather than touching every element.
@@ -64,8 +64,9 @@ patterns live in `.agents/skills/`.
64
64
  URLs, which would navigate the preview iframe to the app itself.
65
65
  - To refine an existing design, make the smallest change: read it with
66
66
  `get-design-snapshot`, then use `edit-design` (search/replace). Reserve
67
- `generate-design` for new files or large structural rewrites; never resend
68
- files you aren't changing.
67
+ `generate-design` for new files. For broad rewrites of an existing selected
68
+ file, use `edit-design` with `mode: "replace-file"` and the exact `fileId`;
69
+ never resend files you aren't changing.
69
70
  - When the user asks to add tweak controls, preserve existing useful tweaks,
70
71
  add or update the requested `tweaks` definitions, and make sure each control
71
72
  is backed by a CSS custom property the rendered file actually uses. If source
@@ -222,8 +223,11 @@ patterns live in `.agents/skills/`.
222
223
  - For human-in-the-loop UI exploration, create a design shell, call
223
224
  `present-design-variants` with 2-5 concise directions (three by default),
224
225
  wait for the user to pick one in chat, delete the other generated variant
225
- screens with `delete-file`, then use `get-design-snapshot` and
226
- `generate-design` or `edit-design` for follow-up refinements.
226
+ screens with `delete-file`, call `get-design-snapshot` with the selected
227
+ screen's `fileId`, then call `edit-design` on that same `fileId` for
228
+ follow-up refinement. Use `mode: "replace-file"` when expanding the
229
+ representative placeholder into the full chosen direction. Do not call
230
+ `generate-design` after a variant pick.
227
231
  - If inline chat choice buttons are unavailable, the user can tell you the
228
232
  preferred screen name. Do not show a separate variant picker or ask them to
229
233
  paste a copyable handoff summary.
@@ -85,6 +85,7 @@ export default defineAction({
85
85
  data: "{}",
86
86
  ownerEmail,
87
87
  orgId,
88
+ visibility: orgId ? "org" : "private",
88
89
  createdAt: now,
89
90
  updatedAt: now,
90
91
  });
@@ -63,6 +63,7 @@ export default defineAction({
63
63
  }
64
64
 
65
65
  // Copy the design with remapped canvasFrames
66
+ const orgId = getRequestOrgId() || null;
66
67
  await db.insert(schema.designs).values({
67
68
  id: newId,
68
69
  title: newTitle,
@@ -75,7 +76,8 @@ export default defineAction({
75
76
  if (!e) throw new Error("no authenticated user");
76
77
  return e;
77
78
  })(),
78
- orgId: getRequestOrgId() || null,
79
+ orgId,
80
+ visibility: orgId ? "org" : "private",
79
81
  createdAt: now,
80
82
  updatedAt: now,
81
83
  });
@@ -139,20 +139,31 @@ export default defineAction({
139
139
  "`replace` adds the wrapper around the original text. For broad copy-only " +
140
140
  'changes such as translating all visible text, use `mode: "replace-file"` ' +
141
141
  "with `replacementContent`: the complete updated file content copied from " +
142
- "the snapshot with only the requested copy changed. Use `generate-design` " +
143
- "instead only for brand-new files or large structural rewrites.",
142
+ "the snapshot with only the requested copy changed. After a variant pick " +
143
+ "or any other selected-screen follow-up, pass the exact `fileId` from " +
144
+ '`get-design-snapshot` and use `mode: "replace-file"` when replacing ' +
145
+ "the representative placeholder with the full chosen direction. Use " +
146
+ "`generate-design` instead only for brand-new files.",
144
147
  schema: z
145
148
  .object({
146
149
  designId: z.string().describe("Design project ID"),
150
+ fileId: z
151
+ .string()
152
+ .optional()
153
+ .describe(
154
+ "Optional exact design file ID to edit. Use this after a variant pick or selected-screen snapshot; when provided, it wins over filename.",
155
+ ),
147
156
  filename: z
148
157
  .string()
149
- .default("index.html")
150
- .describe("File to edit (e.g. 'index.html')"),
158
+ .optional()
159
+ .describe(
160
+ "File to edit (e.g. 'index.html'). Defaults to index.html only when fileId is omitted.",
161
+ ),
151
162
  mode: z
152
163
  .enum(["search-replace", "replace-file"])
153
164
  .optional()
154
165
  .describe(
155
- "Defaults to search-replace. Use replace-file for broad copy-only edits like translating the whole page after reading get-design-snapshot.",
166
+ "Defaults to search-replace. Use replace-file for selected variant expansion or broad copy-only edits after reading get-design-snapshot.",
156
167
  ),
157
168
  edits: editBlocksSchema
158
169
  .optional()
@@ -164,7 +175,7 @@ export default defineAction({
164
175
  .min(1)
165
176
  .optional()
166
177
  .describe(
167
- "Complete updated file content. Use only with mode=replace-file for broad copy-only changes; preserve all HTML structure, CSS, scripts, and tweaks from get-design-snapshot.",
178
+ "Complete updated file content. Use only with mode=replace-file for selected variant expansion or broad copy-only changes; preserve all HTML structure, CSS, scripts, and tweaks from get-design-snapshot.",
168
179
  ),
169
180
  })
170
181
  .superRefine((value, ctx) => {
@@ -201,16 +212,31 @@ export default defineAction({
201
212
  });
202
213
  }
203
214
  }),
204
- run: async ({ designId, filename, edits, mode, replacementContent }) => {
215
+ run: async ({
216
+ designId,
217
+ fileId,
218
+ filename,
219
+ edits,
220
+ mode,
221
+ replacementContent,
222
+ }) => {
205
223
  await assertAccess("design", designId, "editor");
206
224
 
207
225
  const db = getDb();
208
226
  const now = new Date().toISOString();
227
+ const requestedFileId = fileId?.trim();
228
+ const targetFilename = requestedFileId
229
+ ? undefined
230
+ : filename?.trim() || "index.html";
231
+ const targetCondition = requestedFileId
232
+ ? eq(schema.designFiles.id, requestedFileId)
233
+ : eq(schema.designFiles.filename, targetFilename!);
209
234
 
210
- // Resolve the target file (access-scoped) by design + filename.
235
+ // Resolve the target file (access-scoped) by design + fileId or filename.
211
236
  const [file] = await db
212
237
  .select({
213
238
  id: schema.designFiles.id,
239
+ filename: schema.designFiles.filename,
214
240
  content: schema.designFiles.content,
215
241
  })
216
242
  .from(schema.designFiles)
@@ -221,14 +247,18 @@ export default defineAction({
221
247
  .where(
222
248
  and(
223
249
  eq(schema.designFiles.designId, designId),
224
- eq(schema.designFiles.filename, filename),
250
+ targetCondition,
225
251
  accessFilter(schema.designs, schema.designShares),
226
252
  ),
227
253
  )
228
254
  .limit(1);
229
255
 
230
256
  if (!file) {
231
- throw new Error(`File "${filename}" not found in design ${designId}`);
257
+ throw new Error(
258
+ requestedFileId
259
+ ? `File id "${requestedFileId}" not found in design ${designId}`
260
+ : `File "${targetFilename}" not found in design ${designId}`,
261
+ );
232
262
  }
233
263
 
234
264
  // Prefer live collab content so we edit in-flight changes, not a stale
@@ -265,13 +295,13 @@ export default defineAction({
265
295
  selection: firstSearch
266
296
  ? `[data-edit-target="${firstSearch.slice(0, 40)}"]`
267
297
  : null,
268
- editingFile: filename,
298
+ editingFile: file.filename,
269
299
  designId,
270
300
  });
271
301
  } else {
272
302
  agentUpdateSelection(file.id, {
273
303
  selection: null,
274
- editingFile: filename,
304
+ editingFile: file.filename,
275
305
  designId,
276
306
  });
277
307
  }
@@ -301,7 +331,7 @@ export default defineAction({
301
331
 
302
332
  return {
303
333
  designId,
304
- filename,
334
+ filename: file.filename,
305
335
  fileId: file.id,
306
336
  mode: resolvedMode,
307
337
  editsApplied: applied,
@@ -81,7 +81,8 @@ const generateDesignAgentParameters = {
81
81
  type: "string",
82
82
  description:
83
83
  "JSON array of files to save. Pass one compact, complete, renderable index.html first, e.g. " +
84
- '[{"filename":"index.html","fileType":"html","content":"<!doctype html>..."}].',
84
+ '[{"filename":"index.html","fileType":"html","content":"<!doctype html>..."}]. ' +
85
+ "Do not use generate-design to replace a selected variant screen after a variant pick; snapshot that fileId and use edit-design instead.",
85
86
  },
86
87
  designSystemId: {
87
88
  type: ["string", "null"],
@@ -117,6 +118,9 @@ const generateDesignAction = defineAction({
117
118
  "version then refine individual files with `edit-design` (search/replace) rather " +
118
119
  "than resending a big multi-file payload — a single oversized payload can get cut " +
119
120
  "off mid-stream and stall the turn. " +
121
+ "Do not use this action to replace a selected variant screen after a " +
122
+ "variant pick; call `get-design-snapshot` for the selected `fileId` and " +
123
+ "`edit-design` that same `fileId` instead. " +
120
124
  "Do not report a design as ready until this action succeeds. " +
121
125
  "When adding multiple screens or states, pass canvasFrames with filenames " +
122
126
  "and x/y/width/height so the new screens appear placed on the overview canvas.",
@@ -41,16 +41,19 @@ const FALLBACK_INSTRUCTIONS =
41
41
  "overview board. The chat shows one button per screen. Ask the user to pick " +
42
42
  "a screen by name if the inline buttons are not available; after they pick, " +
43
43
  "delete the other variant screens, call get-design-snapshot with fileId for " +
44
- "the kept screen, and continue from that one file in a bounded pass.";
44
+ "the kept screen, then call edit-design on that same fileId in a bounded pass. " +
45
+ 'Use mode "replace-file" when expanding the representative placeholder. ' +
46
+ "Do not call generate-design after a variant pick.";
45
47
 
46
48
  const VARIANT_PICK_SUBMIT_MESSAGE =
47
49
  "Use this design direction. Delete the other variant screens, call " +
48
50
  "get-design-snapshot with the selected option's fileId (or filename if " +
49
- "needed) for the kept file, then continue from that current HTML in a " +
50
- "bounded single-file pass. Prefer edit-design for refinements; if " +
51
- "generate-design is needed, update only the kept file compactly. Do not " +
52
- "generate a full multi-screen rewrite or resend a huge payload. Stop after " +
53
- "the first successful save.";
51
+ "needed) for the kept file, then call edit-design with that same fileId in " +
52
+ 'a bounded single-file pass. Use mode "replace-file" when replacing the ' +
53
+ "representative placeholder with the full chosen direction, or search/replace " +
54
+ "for smaller refinements. Do not call generate-design after a variant pick, " +
55
+ "do not create index.html, and do not resend a huge payload. Stop after the " +
56
+ "first successful edit-design save.";
54
57
 
55
58
  const variantSchema = z.object({
56
59
  id: z.string().min(1).describe("Stable variant id, e.g. 'minimal-focus'"),
@@ -421,9 +424,11 @@ export default defineAction({
421
424
  "exploration before follow-up refinement. After the user's choice, keep " +
422
425
  "the chosen screen, delete the other generated variant screens, and " +
423
426
  "call get-design-snapshot with fileId for the kept screen before " +
424
- "continuing from that single file in a bounded pass. Prefer edit-design " +
425
- "for refinements; if generate-design is needed, update only the kept file " +
426
- "compactly and stop after the first successful save. For complex apps, " +
427
+ "calling edit-design on that same fileId in a bounded pass. Use " +
428
+ '`mode: "replace-file"` when expanding the representative placeholder ' +
429
+ "into the full chosen direction. Do not call generate-design after a " +
430
+ "variant pick. Stop after the first successful edit-design save. For " +
431
+ "complex apps, " +
427
432
  "make each variant a " +
428
433
  "compact representative screen; pass concise labels/descriptions/features " +
429
434
  "and omit content when full HTML would be too large. Design will render " +
@@ -577,7 +582,7 @@ export default defineAction({
577
582
  await writeAppStateForCurrentTab("guided-questions", {
578
583
  title: prompt ?? "Pick a direction",
579
584
  description:
580
- "All options are on the board. Choose one to keep; I will delete the others, read only the kept screen, and continue from that single file in a bounded pass.",
585
+ "All options are on the board. Choose one to keep; I will delete the others, read only the kept screen, and edit that same file in a bounded pass.",
581
586
  submitLabel: "Use selected direction",
582
587
  submitMessage: VARIANT_PICK_SUBMIT_MESSAGE,
583
588
  skipLabel: "Show another set",
@@ -605,7 +610,7 @@ export default defineAction({
605
610
  value:
606
611
  `Keep "${screen.label}" (${screen.filename}, file id ${screen.id}) ` +
607
612
  `from variant set ${variantSetId}. Delete the other variant screens: ${otherScreens}. ` +
608
- `Then call get-design-snapshot with designId ${designId} and fileId ${screen.id} (filename ${screen.filename}) and continue from that current HTML in a bounded single-file pass. Prefer edit-design for refinements; if generate-design is needed, update only this kept file compactly. Do not generate a full multi-screen rewrite or resend a huge payload. Stop after the first successful save.`,
613
+ `Then call get-design-snapshot with designId ${designId} and fileId ${screen.id} (filename ${screen.filename}), then call edit-design with fileId ${screen.id} on that same kept file in a bounded single-file pass. Use mode "replace-file" when replacing the representative placeholder with the full chosen direction, or search/replace for smaller refinements. Do not call generate-design after this variant pick, do not create index.html, and do not resend a huge payload. Stop after the first successful edit-design save.`,
609
614
  };
610
615
  }),
611
616
  },
@@ -623,7 +628,7 @@ export default defineAction({
623
628
  embed: true,
624
629
  fallbackInstructions: FALLBACK_INSTRUCTIONS,
625
630
  nextRequiredAction:
626
- "Wait for the user to pick a screen in chat. Then delete the unchosen variant screens with delete-file, call get-design-snapshot with fileId for the chosen screen, and continue from that single file in a bounded pass. Prefer edit-design; if generate-design is needed, update only the kept file compactly and stop after the first successful save.",
631
+ 'Wait for the user to pick a screen in chat. Then delete the unchosen variant screens with delete-file, call get-design-snapshot with fileId for the chosen screen, and call edit-design with that same fileId in a bounded pass. Use mode "replace-file" when expanding the placeholder into the full chosen direction. Do not call generate-design after a variant pick. Stop after the first successful edit-design save.',
627
632
  };
628
633
  },
629
634
  link: ({ result }) => {
@@ -41,7 +41,7 @@ export function useQuestionFlow(
41
41
  formattedAnswers,
42
42
  "",
43
43
  designId
44
- ? "Now continue the design. Honor any answer about variations: if the user asked to explore options, call present-design-variants with 2-5 concise directions using label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens - wait for their chat pick, delete the unchosen variant screens, call get-design-snapshot with fileId for the kept screen, then continue from that single file in a bounded pass. Prefer edit-design; if generate-design is needed, update only the kept file compactly and stop after the first successful save. Otherwise call generate-design with one complete, renderable index.html first. Do not ask another question unless a required decision is still genuinely missing."
44
+ ? 'Now continue the design. Honor any answer about variations: if the user asked to explore options, call present-design-variants with 2-5 concise directions using label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens - wait for their chat pick, delete the unchosen variant screens, call get-design-snapshot with fileId for the kept screen, then call edit-design on that same fileId in a bounded pass. Use mode "replace-file" when expanding the representative placeholder into the full chosen direction. Do not call generate-design after a variant pick. Stop after the first successful edit-design save. Otherwise call generate-design with one complete, renderable index.html first. Do not ask another question unless a required decision is still genuinely missing.'
45
45
  : "Now continue the design. Honor any answer about variations: use variants only if requested; otherwise generate one polished direction.",
46
46
  ]
47
47
  .filter(Boolean)
@@ -79,7 +79,7 @@ export function useQuestionFlow(
79
79
  formattedAnswers,
80
80
  "",
81
81
  designId
82
- ? "Now continue the design. Honor any answer about variations: if the user asked to explore options, call present-design-variants with 2-5 concise directions using label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens - wait for their chat pick, delete the unchosen variant screens, call get-design-snapshot with fileId for the kept screen, then continue from that single file in a bounded pass. Prefer edit-design; if generate-design is needed, update only the kept file compactly and stop after the first successful save. Otherwise call generate-design with one complete, renderable index.html first. Do not ask another question unless a required decision is still genuinely missing."
82
+ ? 'Now continue the design. Honor any answer about variations: if the user asked to explore options, call present-design-variants with 2-5 concise directions using label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens - wait for their chat pick, delete the unchosen variant screens, call get-design-snapshot with fileId for the kept screen, then call edit-design on that same fileId in a bounded pass. Use mode "replace-file" when expanding the representative placeholder into the full chosen direction. Do not call generate-design after a variant pick. Stop after the first successful edit-design save. Otherwise call generate-design with one complete, renderable index.html first. Do not ask another question unless a required decision is still genuinely missing.'
83
83
  : "Now continue the design. Honor any answer about variations: use variants only if requested; otherwise generate one polished direction.",
84
84
  ]
85
85
  .filter(Boolean)
@@ -1445,7 +1445,7 @@ function designVariantGenerationDirectives(
1445
1445
  ...designSystemGenerationDirectives(designSystemId),
1446
1446
  "The user's prompt already asks to explore multiple directions, so DO NOT call `show-design-questions` first and DO NOT call `generate-design` first.",
1447
1447
  "Call `present-design-variants` with 2-5 concise directions (3 when unspecified). Prefer label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens.",
1448
- "Wait for the user's chat pick, delete the unchosen variant screens, call `get-design-snapshot` with `fileId` for the kept screen, then continue from that single file in a bounded pass. Prefer `edit-design`; if `generate-design` is needed, update only the kept file compactly and stop after the first successful save.",
1448
+ 'Wait for the user\'s chat pick, delete the unchosen variant screens, call `get-design-snapshot` with `fileId` for the kept screen, then call `edit-design` on that same `fileId` in a bounded pass. Use `mode: "replace-file"` when expanding the representative placeholder into the full chosen direction. Do not call `generate-design` after a variant pick. Stop after the first successful `edit-design` save.',
1449
1449
  ];
1450
1450
  }
1451
1451
 
@@ -1456,7 +1456,7 @@ function designGenerationDirectives(
1456
1456
  return [
1457
1457
  `Use the \`generate-design --designId="${designId}"\` action with exactly one complete, renderable \`index.html\` file first. The design already exists - DO NOT call create-design.`,
1458
1458
  ...designSystemGenerationDirectives(designSystemId),
1459
- "If the user asked to explore variations, call `present-design-variants` with 2-5 concise directions. Prefer label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens. Wait for their chat pick, delete the unchosen variant screens, call `get-design-snapshot` with `fileId` for the kept screen, then continue from that single file in a bounded pass. Prefer `edit-design`; if `generate-design` is needed, update only the kept file compactly and stop after the first successful save. Otherwise generate one polished first direction.",
1459
+ 'If the user asked to explore variations, call `present-design-variants` with 2-5 concise directions. Prefer label, description, accentColor, and feature bullets; omit large content HTML when needed because the action can render compact representative screens. Wait for their chat pick, delete the unchosen variant screens, call `get-design-snapshot` with `fileId` for the kept screen, then call `edit-design` on that same `fileId` in a bounded pass. Use `mode: "replace-file"` when expanding the representative placeholder into the full chosen direction. Do not call `generate-design` after a variant pick. Stop after the first successful `edit-design` save. Otherwise generate one polished first direction.',
1460
1460
  "Keep the first pass bounded enough to finish quickly: one self-contained Alpine.js + Tailwind CDN HTML document, polished but concise. Add 3-6 tweaks only when they naturally fit the design.",
1461
1461
  "After generate-design succeeds, stop and summarize what was created.",
1462
1462
  ];
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-01
4
+ ---
5
+
6
+ Org members can see Design projects created in their workspace.
@@ -260,6 +260,15 @@ ALTER TABLE motion_timeline ADD COLUMN IF NOT EXISTS org_id TEXT;
260
260
  ALTER TABLE motion_timeline ADD COLUMN IF NOT EXISTS visibility TEXT NOT NULL DEFAULT 'private';
261
261
  CREATE INDEX IF NOT EXISTS motion_timeline_owner_org_updated_idx ON motion_timeline (owner_email, org_id, updated_at)`,
262
262
  },
263
+ // v18: intentionally no-op. New org-scoped designs now default to
264
+ // org-visible at creation time, but existing private org rows may have
265
+ // been intentionally private. There is no durable marker that separates
266
+ // old default-private rows from explicit private rows, so do not widen
267
+ // historical access in a migration.
268
+ {
269
+ version: 18,
270
+ sql: {},
271
+ },
263
272
  ],
264
273
  { table: "design_migrations" },
265
274
  );
@@ -405,8 +405,37 @@
405
405
  color: var(--wf-ink) !important;
406
406
  }
407
407
 
408
- .plan-diagram-frame :is(.diagram-node, .diagram-box, .diagram-card) {
408
+ .plan-diagram-frame
409
+ :is(
410
+ .diagram-panel,
411
+ .diagram-card,
412
+ .diagram-node,
413
+ .diagram-box,
414
+ [class*="card"],
415
+ [class*="panel"],
416
+ [class*="box"]
417
+ ) {
409
418
  max-width: 100%;
419
+ overflow-wrap: anywhere !important;
420
+ word-break: break-word;
421
+ white-space: normal !important;
422
+ }
423
+
424
+ .plan-diagram-frame
425
+ :is(
426
+ .diagram-panel,
427
+ .diagram-card,
428
+ .diagram-node,
429
+ .diagram-box,
430
+ [class*="card"],
431
+ [class*="panel"],
432
+ [class*="box"]
433
+ )
434
+ :is(h1, h2, h3, p, small, strong, span, li) {
435
+ max-width: 100%;
436
+ overflow-wrap: anywhere !important;
437
+ word-break: break-word;
438
+ white-space: normal !important;
410
439
  }
411
440
 
412
441
  /* Base padding so primitive text never touches the box edge, even when an author
@@ -472,6 +501,7 @@
472
501
  display: inline-flex;
473
502
  align-items: center;
474
503
  justify-content: center;
504
+ flex-wrap: wrap;
475
505
  /* A pill hugs its label. `fit-content` is a definite cross size, so a flex
476
506
  * column with the default `align-items: stretch` no longer blows the pill out
477
507
  * to full width (the number chips and short status labels stay pill-shaped).
@@ -484,6 +514,19 @@
484
514
  padding: 3px 11px;
485
515
  color: var(--wf-ink);
486
516
  background: var(--wf-paper);
517
+ overflow-wrap: anywhere !important;
518
+ text-align: center;
519
+ white-space: normal !important;
520
+ word-break: break-word;
521
+ }
522
+
523
+ .plan-diagram-frame
524
+ :is(.diagram-pill, [class*="pill"], [class*="badge"], [class*="chip"])
525
+ > * {
526
+ min-width: 0;
527
+ max-width: 100%;
528
+ overflow-wrap: anywhere !important;
529
+ white-space: normal !important;
487
530
  }
488
531
 
489
532
  .plan-diagram-frame :is(.diagram-accent, .diagram-pill.accent) {
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-01
4
+ ---
5
+
6
+ Visual plan and recap diagram labels now wrap inside their boxes instead of spilling outside.
@@ -101,6 +101,9 @@ export declare function isHostedRuntimeForDurableBackground(): boolean;
101
101
  * additional signals — the latter an operator escape hatch. Off by default.
102
102
  */
103
103
  export declare function isInBackgroundFunctionRuntime(): boolean;
104
+ export declare function backgroundRunMarkerExpectsBackgroundRuntime(marker: unknown): boolean;
105
+ export declare function shouldUseBackgroundFunctionTimeoutForWorker(marker: unknown): boolean;
106
+ export declare function backgroundRuntimeDiagnosticDetail(marker: unknown): string;
104
107
  /**
105
108
  * The single gate. True when the env flag is explicitly enabled, or a workspace
106
109
  * app opted in and has a per-app background-function target, AND the runtime is
@@ -1 +1 @@
1
- {"version":3,"file":"durable-background.d.ts","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2CACE,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,gDAA0D,CAAC;AAsB1G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAY/D;AAED;;;GAGG;AACH,eAAO,MAAM,iCAAiC,kCACb,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAsB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD;AAwCD;;;;;;;GAOG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAWV;AAED,uDAAuD;AACvD,MAAM,MAAM,qBAAqB,GAC7B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAahE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,qBAAqB,CAiDvB"}
1
+ {"version":3,"file":"durable-background.d.ts","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2CACE,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,gDAA0D,CAAC;AAiC1G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAQ/D;AAED;;;GAGG;AACH,eAAO,MAAM,iCAAiC,kCACb,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAsB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,OAAO,GACd,OAAO,CAOT;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,OAAO,GACd,OAAO,CAKT;AAED,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAQzE;AAwCD;;;;;;;GAOG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAWV;AAED,uDAAuD;AACvD,MAAM,MAAM,qBAAqB,GAC7B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAahE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,qBAAqB,CAiDvB"}
@@ -87,6 +87,19 @@ function resolveWorkspaceBackgroundFunctionUrlPath() {
87
87
  return null;
88
88
  return `/.netlify/functions/${candidate}-agent-background`;
89
89
  }
90
+ function isNetlifyHostedRuntimeForDispatch() {
91
+ if (process.env.NETLIFY_LOCAL === "true")
92
+ return false;
93
+ if (process.env.NETLIFY === "false")
94
+ return false;
95
+ if (process.env.NETLIFY && process.env.NETLIFY !== "false")
96
+ return true;
97
+ // Netlify sets AWS Lambda runtime env on deployed Functions, but the build-time
98
+ // NETLIFY flag is not always present in the runtime isolate. Treat Lambda as
99
+ // Netlify here unless Netlify was explicitly disabled above; non-Netlify AWS
100
+ // falls back inline if the /.netlify/functions dispatch fast-fails.
101
+ return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);
102
+ }
90
103
  /**
91
104
  * Resolve the path the foreground POST should self-dispatch the chat background
92
105
  * worker to.
@@ -119,9 +132,7 @@ function resolveWorkspaceBackgroundFunctionUrlPath() {
119
132
  * to shadow because `/.netlify/*` is already excluded from the `server` catch-all.
120
133
  */
121
134
  export function resolveAgentChatProcessRunDispatchPath() {
122
- if (process.env.NETLIFY &&
123
- process.env.NETLIFY !== "false" &&
124
- process.env.NETLIFY_LOCAL !== "true") {
135
+ if (isNetlifyHostedRuntimeForDispatch()) {
125
136
  return (resolveWorkspaceBackgroundFunctionUrlPath() ??
126
137
  AGENT_BACKGROUND_FUNCTION_URL_PATH);
127
138
  }
@@ -205,6 +216,25 @@ export function isInBackgroundFunctionRuntime() {
205
216
  }
206
217
  return false;
207
218
  }
219
+ export function backgroundRunMarkerExpectsBackgroundRuntime(marker) {
220
+ return (typeof marker === "object" &&
221
+ marker !== null &&
222
+ marker
223
+ .backgroundFunctionRuntimeExpected === true);
224
+ }
225
+ export function shouldUseBackgroundFunctionTimeoutForWorker(marker) {
226
+ return (isInBackgroundFunctionRuntime() ||
227
+ backgroundRunMarkerExpectsBackgroundRuntime(marker));
228
+ }
229
+ export function backgroundRuntimeDiagnosticDetail(marker) {
230
+ return [
231
+ `markerExpected=${backgroundRunMarkerExpectsBackgroundRuntime(marker)}`,
232
+ `runtimeDetected=${isInBackgroundFunctionRuntime()}`,
233
+ `globalMarker=${globalThis.__AGENT_NATIVE_BACKGROUND_RUNTIME__ === true}`,
234
+ `lambdaNameEndsBackground=${typeof process.env.AWS_LAMBDA_FUNCTION_NAME === "string" && process.env.AWS_LAMBDA_FUNCTION_NAME.toLowerCase().endsWith("-background")}`,
235
+ `forceEnv=${typeof process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME === "string" && process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME.trim().length > 0}`,
236
+ ].join(" ");
237
+ }
208
238
  function isFlagEnabled() {
209
239
  // Read the literal key (not `process.env[CONST]`) so guard:no-env-credentials
210
240
  // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this