@agent-native/core 0.84.12 → 0.84.13

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 (83) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +11 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/agent/durable-background.ts +30 -0
  5. package/corpus/core/src/agent/production-agent.ts +34 -6
  6. package/corpus/core/src/agent/run-manager.ts +45 -2
  7. package/corpus/core/src/chat-threads/store.ts +2 -0
  8. package/corpus/core/src/cli/skills.ts +10 -6
  9. package/corpus/core/src/client/AssistantChat.tsx +40 -9
  10. package/corpus/core/src/client/agent-chat-adapter.ts +23 -2
  11. package/corpus/core/src/client/chat/run-recovery.tsx +52 -44
  12. package/corpus/core/src/client/chat/tool-call-display.tsx +7 -2
  13. package/corpus/core/src/server/agent-chat-plugin.ts +1 -0
  14. package/corpus/core/src/shared/streaming-text-smoothing.ts +10 -5
  15. package/corpus/templates/clips/app/components/library/recording-card.tsx +14 -4
  16. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +10 -12
  17. package/corpus/templates/clips/app/hooks/use-library.ts +7 -4
  18. package/corpus/templates/clips/app/lib/recording-status.ts +32 -0
  19. package/corpus/templates/clips/changelog/2026-07-01-dictation-keeps-listening-through-natural-pauses-and-gives-c.md +6 -0
  20. package/corpus/templates/clips/changelog/2026-07-01-redoing-a-paused-desktop-recording-no-longer-leaves-the-recording-controls-disabled.md +6 -0
  21. package/corpus/templates/clips/changelog/2026-07-01-stalled-clip-uploads-now-update-in-the-library-and-surface-as-failed.md +6 -0
  22. package/corpus/templates/clips/desktop/src/lib/recorder.ts +36 -18
  23. package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +99 -27
  24. package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +4 -43
  25. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +3 -0
  26. package/corpus/templates/clips/desktop/src/styles.css +5 -48
  27. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +4 -5
  28. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +15 -6
  29. package/corpus/templates/design/AGENTS.md +8 -4
  30. package/corpus/templates/design/actions/create-design.ts +1 -0
  31. package/corpus/templates/design/actions/duplicate-design.ts +3 -1
  32. package/corpus/templates/design/actions/edit-design.ts +43 -13
  33. package/corpus/templates/design/actions/generate-design.ts +5 -1
  34. package/corpus/templates/design/actions/present-design-variants.ts +17 -12
  35. package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
  36. package/corpus/templates/design/app/pages/DesignEditor.tsx +2 -2
  37. package/corpus/templates/design/changelog/2026-07-01-org-members-can-see-design-projects-created-in-their-workspace.md +6 -0
  38. package/corpus/templates/design/server/plugins/db.ts +9 -0
  39. package/dist/agent/durable-background.d.ts +3 -0
  40. package/dist/agent/durable-background.d.ts.map +1 -1
  41. package/dist/agent/durable-background.js +19 -0
  42. package/dist/agent/durable-background.js.map +1 -1
  43. package/dist/agent/production-agent.d.ts +1 -0
  44. package/dist/agent/production-agent.d.ts.map +1 -1
  45. package/dist/agent/production-agent.js +29 -6
  46. package/dist/agent/production-agent.js.map +1 -1
  47. package/dist/agent/run-manager.d.ts.map +1 -1
  48. package/dist/agent/run-manager.js +40 -2
  49. package/dist/agent/run-manager.js.map +1 -1
  50. package/dist/chat-threads/store.d.ts +1 -0
  51. package/dist/chat-threads/store.d.ts.map +1 -1
  52. package/dist/chat-threads/store.js +2 -0
  53. package/dist/chat-threads/store.js.map +1 -1
  54. package/dist/cli/skills.d.ts.map +1 -1
  55. package/dist/cli/skills.js +10 -6
  56. package/dist/cli/skills.js.map +1 -1
  57. package/dist/client/AssistantChat.d.ts +10 -0
  58. package/dist/client/AssistantChat.d.ts.map +1 -1
  59. package/dist/client/AssistantChat.js +26 -8
  60. package/dist/client/AssistantChat.js.map +1 -1
  61. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  62. package/dist/client/agent-chat-adapter.js +21 -2
  63. package/dist/client/agent-chat-adapter.js.map +1 -1
  64. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  65. package/dist/client/chat/run-recovery.js +15 -10
  66. package/dist/client/chat/run-recovery.js.map +1 -1
  67. package/dist/client/chat/tool-call-display.d.ts +1 -0
  68. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  69. package/dist/client/chat/tool-call-display.js +3 -2
  70. package/dist/client/chat/tool-call-display.js.map +1 -1
  71. package/dist/collab/routes.d.ts +2 -2
  72. package/dist/notifications/routes.d.ts +2 -2
  73. package/dist/observability/routes.d.ts +3 -3
  74. package/dist/progress/routes.d.ts +1 -1
  75. package/dist/resources/handlers.d.ts +1 -1
  76. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  77. package/dist/server/agent-chat-plugin.js +1 -1
  78. package/dist/server/agent-chat-plugin.js.map +1 -1
  79. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  80. package/dist/shared/streaming-text-smoothing.d.ts.map +1 -1
  81. package/dist/shared/streaming-text-smoothing.js +8 -5
  82. package/dist/shared/streaming-text-smoothing.js.map +1 -1
  83. package/package.json +1 -1
@@ -3663,57 +3663,18 @@ body[data-clips-route="recording-pill"] #root {
3663
3663
 
3664
3664
  /* Wispr Flow-style dictation pill: small capsule anchored to the bottom
3665
3665
  of its (transparent) overlay window. The window itself is positioned
3666
- bottom-center on the primary display by show_flow_bar in Rust. We
3667
- stack the live transcript above the pill in a column so the user sees
3668
- the words being recognized in real time. */
3666
+ bottom-center on the primary display by show_flow_bar in Rust. */
3669
3667
  .flow-bar-root {
3670
3668
  position: fixed;
3671
3669
  inset: var(--overlay-shadow-gutter);
3672
3670
  display: flex;
3673
- flex-direction: column;
3674
3671
  align-items: center;
3675
3672
  justify-content: flex-end;
3676
3673
  padding-bottom: 8px;
3677
- gap: 6px;
3678
3674
  background: transparent;
3679
3675
  pointer-events: none;
3680
3676
  }
3681
3677
 
3682
- /* Live partial-transcript chip floating above the pill. Same dark glass
3683
- look as the pill, smaller, only there when transcript is non-empty.
3684
- Caps width and clips from the left so the newest words stay visible
3685
- when a long sentence reaches the edge of the transparent window. */
3686
- .flow-bar-transcript {
3687
- max-width: 360px;
3688
- padding: 4px 10px;
3689
- border-radius: 12px;
3690
- background: rgba(18, 18, 20, 0.92);
3691
- backdrop-filter: blur(20px);
3692
- -webkit-backdrop-filter: blur(20px);
3693
- border: 1px solid rgba(255, 255, 255, 0.06);
3694
- color: rgba(255, 255, 255, 0.92);
3695
- font-size: 12px;
3696
- line-height: 1.35;
3697
- text-align: left;
3698
- white-space: nowrap;
3699
- overflow: hidden;
3700
- text-overflow: ellipsis;
3701
- /* RTL on the OUTER box so overflow clips from the visual left
3702
- (older text), keeping the newest characters pinned to the right.
3703
- `unicode-bidi: plaintext` on the inner <bdi> makes the actual
3704
- transcript text follow its own (LTR) direction — without it,
3705
- bidi reordering pushes the last few Latin characters past the
3706
- visible right edge and they get clipped a few chars short. */
3707
- direction: rtl;
3708
- pointer-events: none;
3709
- animation: flow-bar-in 100ms ease-out;
3710
- }
3711
-
3712
- .flow-bar-transcript > bdi {
3713
- unicode-bidi: plaintext;
3714
- direction: ltr;
3715
- }
3716
-
3717
3678
  .flow-bar {
3718
3679
  display: flex;
3719
3680
  align-items: center;
@@ -3729,17 +3690,13 @@ body[data-clips-route="recording-pill"] #root {
3729
3690
  /* Subtle fade-in so the pill doesn't hard-pop on appear. */
3730
3691
  animation: flow-bar-in 140ms ease-out;
3731
3692
  /* Fade out to opacity 0 when state goes idle (after Fn release).
3732
- Keeping the pill in the DOM means the transcript chip above
3733
- doesn't reflow when the pill "goes away" — important for the
3734
- linger UX where the chip stays put while the pill dissolves. */
3693
+ Keeping the pill in the DOM lets the waveform fade instead of pop. */
3735
3694
  transition: opacity 220ms ease-out;
3736
3695
  }
3737
3696
 
3738
- /* When the dictation engine reports idle (e.g. mid-linger after Fn
3739
- release on the browser path), fade the pill out without unmounting
3740
- it. The canvas keeps its last-frame so the user sees the waveform
3741
- smoothly fade rather than pop into nothing. Pointer-events go off
3742
- so the now-invisible chip can't catch clicks. */
3697
+ /* When the dictation engine reports idle, fade the pill out without
3698
+ unmounting it. Pointer-events go off so the invisible pill cannot
3699
+ catch clicks. */
3743
3700
  .flow-bar-idle {
3744
3701
  opacity: 0;
3745
3702
  pointer-events: none;
@@ -1210,11 +1210,10 @@ pub async fn show_flow_bar(app: AppHandle) -> Result<(), String> {
1210
1210
 
1211
1211
  let (mx, my, mw, mh) = tray_monitor_physical_rect(&app);
1212
1212
  let scale = overlay_scale_factor(&app);
1213
- // Wider + taller than the pill alone so the live transcript chip
1214
- // can stack above it. Height accommodates: bottom-anchored 32px pill
1215
- // + 6px gap + ~28px transcript chip + transparent window margin.
1216
- let content_w: u32 = (420.0 * scale).round() as u32;
1217
- let content_h: u32 = (120.0 * scale).round() as u32;
1213
+ // Compact Wispr-style pill window: just enough transparent canvas for
1214
+ // the bottom-centered waveform bar and its shadow gutter.
1215
+ let content_w: u32 = (160.0 * scale).round() as u32;
1216
+ let content_h: u32 = (56.0 * scale).round() as u32;
1218
1217
  let bottom_margin: i32 = (14.0 * scale).round() as i32;
1219
1218
  let gutter = overlay_shadow_gutter_physical(&app);
1220
1219
  let w: u32 = content_w + gutter * 2;
@@ -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
  );
@@ -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;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;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"}
@@ -205,6 +205,25 @@ export function isInBackgroundFunctionRuntime() {
205
205
  }
206
206
  return false;
207
207
  }
208
+ export function backgroundRunMarkerExpectsBackgroundRuntime(marker) {
209
+ return (typeof marker === "object" &&
210
+ marker !== null &&
211
+ marker
212
+ .backgroundFunctionRuntimeExpected === true);
213
+ }
214
+ export function shouldUseBackgroundFunctionTimeoutForWorker(marker) {
215
+ return (isInBackgroundFunctionRuntime() ||
216
+ backgroundRunMarkerExpectsBackgroundRuntime(marker));
217
+ }
218
+ export function backgroundRuntimeDiagnosticDetail(marker) {
219
+ return [
220
+ `markerExpected=${backgroundRunMarkerExpectsBackgroundRuntime(marker)}`,
221
+ `runtimeDetected=${isInBackgroundFunctionRuntime()}`,
222
+ `globalMarker=${globalThis.__AGENT_NATIVE_BACKGROUND_RUNTIME__ === true}`,
223
+ `lambdaNameEndsBackground=${typeof process.env.AWS_LAMBDA_FUNCTION_NAME === "string" && process.env.AWS_LAMBDA_FUNCTION_NAME.toLowerCase().endsWith("-background")}`,
224
+ `forceEnv=${typeof process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME === "string" && process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME.trim().length > 0}`,
225
+ ].join(" ");
226
+ }
208
227
  function isFlagEnabled() {
209
228
  // Read the literal key (not `process.env[CONST]`) so guard:no-env-credentials
210
229
  // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this