@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.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +11 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/durable-background.ts +30 -0
- package/corpus/core/src/agent/production-agent.ts +34 -6
- package/corpus/core/src/agent/run-manager.ts +45 -2
- package/corpus/core/src/chat-threads/store.ts +2 -0
- package/corpus/core/src/cli/skills.ts +10 -6
- package/corpus/core/src/client/AssistantChat.tsx +40 -9
- package/corpus/core/src/client/agent-chat-adapter.ts +23 -2
- package/corpus/core/src/client/chat/run-recovery.tsx +52 -44
- package/corpus/core/src/client/chat/tool-call-display.tsx +7 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +1 -0
- package/corpus/core/src/shared/streaming-text-smoothing.ts +10 -5
- package/corpus/templates/clips/app/components/library/recording-card.tsx +14 -4
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +10 -12
- package/corpus/templates/clips/app/hooks/use-library.ts +7 -4
- package/corpus/templates/clips/app/lib/recording-status.ts +32 -0
- package/corpus/templates/clips/changelog/2026-07-01-dictation-keeps-listening-through-natural-pauses-and-gives-c.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-redoing-a-paused-desktop-recording-no-longer-leaves-the-recording-controls-disabled.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-stalled-clip-uploads-now-update-in-the-library-and-surface-as-failed.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +36 -18
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +99 -27
- package/corpus/templates/clips/desktop/src/overlays/flow-bar.tsx +4 -43
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +3 -0
- package/corpus/templates/clips/desktop/src/styles.css +5 -48
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +4 -5
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +15 -6
- package/corpus/templates/design/AGENTS.md +8 -4
- package/corpus/templates/design/actions/create-design.ts +1 -0
- package/corpus/templates/design/actions/duplicate-design.ts +3 -1
- package/corpus/templates/design/actions/edit-design.ts +43 -13
- package/corpus/templates/design/actions/generate-design.ts +5 -1
- package/corpus/templates/design/actions/present-design-variants.ts +17 -12
- package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
- package/corpus/templates/design/app/pages/DesignEditor.tsx +2 -2
- package/corpus/templates/design/changelog/2026-07-01-org-members-can-see-design-projects-created-in-their-workspace.md +6 -0
- package/corpus/templates/design/server/plugins/db.ts +9 -0
- package/dist/agent/durable-background.d.ts +3 -0
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +19 -0
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts +1 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +29 -6
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-manager.d.ts.map +1 -1
- package/dist/agent/run-manager.js +40 -2
- package/dist/agent/run-manager.js.map +1 -1
- package/dist/chat-threads/store.d.ts +1 -0
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +2 -0
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +10 -6
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +10 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +26 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +21 -2
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/chat/run-recovery.d.ts.map +1 -1
- package/dist/client/chat/run-recovery.js +15 -10
- package/dist/client/chat/run-recovery.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +1 -0
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +3 -2
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/collab/routes.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +1 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/shared/streaming-text-smoothing.d.ts.map +1 -1
- package/dist/shared/streaming-text-smoothing.js +8 -5
- package/dist/shared/streaming-text-smoothing.js.map +1 -1
- 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.
|
|
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
|
|
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
|
|
3739
|
-
|
|
3740
|
-
|
|
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
|
-
//
|
|
1214
|
-
//
|
|
1215
|
-
|
|
1216
|
-
let
|
|
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
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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:
|
|
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
|
|
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
|
|
68
|
-
|
|
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`,
|
|
226
|
-
`
|
|
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.
|
|
@@ -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
|
|
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.
|
|
143
|
-
"
|
|
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
|
-
.
|
|
150
|
-
.describe(
|
|
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
|
|
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 ({
|
|
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
|
-
|
|
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(
|
|
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,
|
|
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
|
|
50
|
-
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
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
|
-
"
|
|
425
|
-
"
|
|
426
|
-
"
|
|
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
|
|
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})
|
|
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
|
-
|
|
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
|
-
?
|
|
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
|
-
?
|
|
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
|
-
|
|
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
|
-
|
|
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
|
];
|
|
@@ -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
|