@agent-native/core 0.84.21 → 0.84.23
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 +16 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/model-config.ts +1 -1
- package/corpus/core/src/cli/skills.ts +17 -3
- package/corpus/core/src/client/AssistantChat.tsx +27 -4
- package/corpus/core/src/client/guided-questions.tsx +11 -6
- package/corpus/core/src/client/tool-display.ts +8 -0
- package/corpus/core/src/file-upload/builder.ts +7 -2
- package/corpus/core/src/notifications/channels.ts +235 -38
- package/corpus/core/src/notifications/index.ts +1 -0
- package/corpus/core/src/notifications/registry.ts +13 -1
- package/corpus/core/src/server/analytics.ts +32 -6
- package/corpus/core/src/server/ssr-handler.ts +31 -12
- package/corpus/core/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/analytics/AGENTS.md +21 -0
- package/corpus/templates/analytics/README.md +35 -0
- package/corpus/templates/analytics/actions/delete-analytics-alert-rule.ts +23 -0
- package/corpus/templates/analytics/actions/list-analytics-alert-rules.ts +20 -0
- package/corpus/templates/analytics/actions/run-analytics-alerts.ts +23 -0
- package/corpus/templates/analytics/actions/save-analytics-alert-rule.ts +69 -0
- package/corpus/templates/analytics/changelog/2026-07-01-analytics-can-alert-when-first-party-events-spike.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-01-session-replays-play-back-in-production-instead-of-showing.md +6 -0
- package/corpus/templates/analytics/netlify.toml +3 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +126 -0
- package/corpus/templates/analytics/server/db/schema.ts +55 -0
- package/corpus/templates/analytics/server/handlers/session-replay.ts +5 -2
- package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +74 -0
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +803 -0
- package/corpus/templates/analytics/server/lib/session-replay.ts +10 -3
- package/corpus/templates/analytics/server/plugins/analytics-alert-jobs.ts +54 -0
- package/corpus/templates/analytics/server/plugins/db.ts +100 -0
- package/corpus/templates/analytics/server/routes/api/analytics-alerts/run.post.ts +60 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/assets/README.md +30 -8
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/brain/README.md +20 -552
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/calendar/README.md +22 -28
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/chat/README.md +32 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/clips/.agents/skills/recording/SKILL.md +30 -1
- package/corpus/templates/clips/README.md +37 -0
- package/corpus/templates/clips/actions/finalize-recording.ts +84 -4
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +256 -0
- package/corpus/templates/clips/actions/reprocess-recording.ts +160 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +18 -7
- package/corpus/templates/clips/app/components/library/recording-card.tsx +42 -5
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +41 -1
- package/corpus/templates/clips/changelog/2026-07-01-move-to-folder-now-opens-folder-choices-directly-instead-of.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-01-shared-clips-now-start-playing-and-scrub-instantly-instead-o.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
- package/corpus/templates/clips/server/lib/video-remux.ts +222 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +37 -0
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/content/AGENTS.md +7 -3
- package/corpus/templates/content/README.md +22 -34
- package/corpus/templates/content/actions/list-trashed-content-databases.ts +4 -0
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +58 -6
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +257 -24
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +41 -15
- package/corpus/templates/content/app/i18n/zh-TW.ts +25 -7
- package/corpus/templates/content/app/i18n-data.ts +278 -40
- package/corpus/templates/content/changelog/2026-06-30-database-once-again-creates-an-inline-database-in-the-curren.md +6 -0
- package/corpus/templates/content/shared/api.ts +1 -0
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +75 -19
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/design/AGENTS.md +7 -6
- package/corpus/templates/design/README.md +33 -0
- package/corpus/templates/design/actions/delete-file.ts +86 -10
- package/corpus/templates/design/actions/get-design-snapshot.ts +13 -0
- package/corpus/templates/design/actions/present-design-variants.ts +11 -13
- package/corpus/templates/design/app/hooks/use-question-flow.ts +2 -2
- package/corpus/templates/design/app/pages/DesignEditor.tsx +13 -3
- package/corpus/templates/design/changelog/2026-07-01-design-chat-no-longer-shows-an-empty-state-selection-chip-in-the-composer.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/dispatch/README.md +34 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/forms/README.md +34 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/macros/README.md +28 -0
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/mail/README.md +35 -0
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/plan/README.md +30 -118
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/slides/README.md +34 -0
- package/corpus/templates/videos/.agents/skills/frontend-design/SKILL.md +2 -0
- package/corpus/templates/videos/README.md +22 -201
- package/dist/agent/model-config.js +1 -1
- package/dist/agent/model-config.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +17 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +28 -4
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/guided-questions.d.ts.map +1 -1
- package/dist/client/guided-questions.js +10 -6
- package/dist/client/guided-questions.js.map +1 -1
- package/dist/client/tool-display.d.ts.map +1 -1
- package/dist/client/tool-display.js +8 -0
- package/dist/client/tool-display.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/builder.d.ts.map +1 -1
- package/dist/file-upload/builder.js +6 -2
- package/dist/file-upload/builder.js.map +1 -1
- package/dist/notifications/channels.d.ts +10 -0
- package/dist/notifications/channels.d.ts.map +1 -1
- package/dist/notifications/channels.js +172 -20
- package/dist/notifications/channels.js.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +1 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/registry.d.ts +5 -0
- package/dist/notifications/registry.d.ts.map +1 -1
- package/dist/notifications/registry.js +4 -1
- package/dist/notifications/registry.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/analytics.d.ts +16 -0
- package/dist/server/analytics.d.ts.map +1 -1
- package/dist/server/analytics.js +30 -7
- package/dist/server/analytics.js.map +1 -1
- package/dist/server/ssr-handler.d.ts.map +1 -1
- package/dist/server/ssr-handler.js +28 -12
- package/dist/server/ssr-handler.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
- package/package.json +1 -1
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +2 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +2 -0
|
@@ -18,22 +18,62 @@ Every generated design uses:
|
|
|
18
18
|
- **Google Fonts** — for distinctive typography (never Inter/Roboto/Arial)
|
|
19
19
|
- **CSS Custom Properties** — for theming and tweaks panel integration
|
|
20
20
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
## Why the workflow exists — it is the anti-slop engine
|
|
22
|
+
|
|
23
|
+
Generic output ("AI slop") is a *workflow* failure, not a lack of talent. When one
|
|
24
|
+
prompt has to set the taste, explore the options, and emit final code all at once,
|
|
25
|
+
the safest answer is the statistical average of the training data: Inter, an
|
|
26
|
+
indigo→violet gradient, a centered hero, three rounded icon cards. Design beats
|
|
27
|
+
this by splitting those jobs across the tools — use them in order, don't collapse
|
|
28
|
+
them:
|
|
29
|
+
|
|
30
|
+
1. **Direction** — `show-design-questions` (or a stated thesis) sets taste on purpose.
|
|
31
|
+
2. **Exploration** — `present-design-variants` compares genuinely different directions
|
|
32
|
+
before committing to one. **This step kills sameness; never skip it for open-ended work.**
|
|
33
|
+
3. **Spec** — a linked design system and the `:root` token block capture the chosen look as reusable rules.
|
|
34
|
+
4. **Code** — `generate-design` / `edit-design` execute a decision already made instead of guessing.
|
|
35
|
+
|
|
36
|
+
Jumping straight to code is how you get slop. Let the phases (below) do the work.
|
|
37
|
+
|
|
38
|
+
## Aesthetic quality bar — beat distributional convergence
|
|
39
|
+
|
|
40
|
+
You sample toward the "on-distribution" center by default; refuse it. **Every
|
|
41
|
+
"don't" here carries a "do"** — a banned default plus where to go instead —
|
|
42
|
+
because banning Inter alone just makes you reach for Roboto next. Use a banned
|
|
43
|
+
item only if the user explicitly asks.
|
|
44
|
+
|
|
45
|
+
- **Fonts.** Don't: Inter, Roboto, Arial, Open Sans, system-ui. Do: a distinctive
|
|
46
|
+
Google Font pairing matched to the chosen aesthetic (see the table) — editorial
|
|
47
|
+
serif, grotesk display + mono, or one variable font pushed across weight extremes.
|
|
48
|
+
- **Color.** Don't: the indigo/violet slop palette (`#6366F1`, `#8B5CF6`,
|
|
49
|
+
`#A855F7`), a purple gradient on white, or everything in default grays. Do:
|
|
50
|
+
anchor on one non-default family — clay/ochre/terracotta, ink/bone/mustard,
|
|
51
|
+
charcoal/lime, oxblood/cream, navy/copper, warm paper (`#FBF7F0`) over pure
|
|
52
|
+
white — with one decisive accent used sparingly for hierarchy, not decoration.
|
|
53
|
+
- **Layout.** Don't: centered hero + one CTA + a row of three icon cards,
|
|
54
|
+
rounded-everything, `0.1`-opacity drop shadows, blanket glassmorphism, or the
|
|
55
|
+
badge-above-headline cliché. Do: asymmetric 60/40 or 70/30 splits, uneven
|
|
56
|
+
visual weight, one clear focal point, and flat confident surfaces.
|
|
57
|
+
- **Background.** Don't: a single flat fill. Do: layered gradients, a geometric
|
|
58
|
+
pattern, grain, or a contextual texture that matches the theme.
|
|
59
|
+
- **Copy & voice.** Don't: lorem ipsum or buzzword filler ("empower", "seamless",
|
|
60
|
+
"leverage", "revolutionize", "in today's fast-paced world"). Do: realistic
|
|
61
|
+
domain content in a specific voice — copy is design material.
|
|
62
|
+
|
|
63
|
+
**Second-order convergence is real.** Even your "creative" picks converge (Space
|
|
64
|
+
Grotesk everywhere; teal accent + blinking dot + left accent bars). Vary
|
|
65
|
+
deliberately across generations so two designs never share a fingerprint.
|
|
66
|
+
|
|
67
|
+
**Principles to quote back while building:** color creates hierarchy, not
|
|
68
|
+
decoration · density over decoration · earn every animation · commit to one point
|
|
69
|
+
of view. **Match code to the vision** — maximalist themes want elaborate motion
|
|
70
|
+
and effects; minimal themes want restraint and precise spacing. Elegance is
|
|
71
|
+
executing one vision fully.
|
|
72
|
+
|
|
73
|
+
**References beat adjectives, but only with a reason.** "Linear: the quiet
|
|
74
|
+
confidence of its spacing" or "Stripe: dense but never crowded" points somewhere
|
|
75
|
+
specific; "Linear" alone collapses back to the average, and replying to your own
|
|
76
|
+
output with "make it cleaner / more premium" means you're negotiating with vibes.
|
|
37
77
|
|
|
38
78
|
## Prompt the design in four layers
|
|
39
79
|
|
|
@@ -70,6 +110,23 @@ Pick a preset by `projectType`:
|
|
|
70
110
|
`:root` CSS variable. Never hardcode `text-white` / `bg-black` / hex literals
|
|
71
111
|
in the markup — that's what keeps brand + multi-screen consistency automatic.
|
|
72
112
|
|
|
113
|
+
## Building on existing code, screens, or a design system
|
|
114
|
+
|
|
115
|
+
When a design system, tokens, current screens, or a connected codebase already
|
|
116
|
+
exist, the slop risk flips: the failure is ignoring the brand and reverting to
|
|
117
|
+
defaults. The banned-defaults list above still applies, plus:
|
|
118
|
+
|
|
119
|
+
- **Inspect before inventing.** Read the linked design system, the current
|
|
120
|
+
`:root` tokens, and existing screens (or the connected localhost/repo) first.
|
|
121
|
+
Derive the type scale, palette, radius, density, and component language from
|
|
122
|
+
what is actually there — don't restate a generic direction.
|
|
123
|
+
- **Treat every reversion as a missing spec entry.** If output drifts to a
|
|
124
|
+
default (Inter, pill buttons, a stock radius) despite the brand, don't just
|
|
125
|
+
re-prompt — pin the explicit value into `:root` so it can't drift again.
|
|
126
|
+
- **Consistency is not sameness.** Tokens alone make every screen "the same in
|
|
127
|
+
your colors". Keep structure and layout genuinely varied per screen while the
|
|
128
|
+
palette, type, and components stay on-brand.
|
|
129
|
+
|
|
73
130
|
## Generation Workflow — the canonical 4-phase flow
|
|
74
131
|
|
|
75
132
|
This flow mirrors Claude Design's UX: ask → show variants → user picks → refine. Don't skip phases for new designs.
|
|
@@ -502,9 +559,8 @@ regeneration is slow, expensive, and regresses unrelated parts.
|
|
|
502
559
|
|
|
503
560
|
## What NOT to Do
|
|
504
561
|
|
|
505
|
-
-
|
|
506
|
-
|
|
507
|
-
blinking-dot + three-column-hero cliché — see the Aesthetic Quality Bar.
|
|
562
|
+
- For aesthetics (fonts, palette, layout, backgrounds, copy), see the Aesthetic
|
|
563
|
+
quality bar above — every banned default there is out unless the user asks.
|
|
508
564
|
- Never link prototype screens with real/relative URLs — use Alpine state,
|
|
509
565
|
`data-screen`, or `#` anchors (see Multi-screen prototypes & navigation).
|
|
510
566
|
- Never hardcode colors — always reference CSS custom properties (no raw
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -222,12 +222,13 @@ patterns live in `.agents/skills/`.
|
|
|
222
222
|
and open the editor in overview mode.
|
|
223
223
|
- For human-in-the-loop UI exploration, create a design shell, call
|
|
224
224
|
`present-design-variants` with 2-5 concise directions (three by default),
|
|
225
|
-
wait for the user to pick one in chat, delete
|
|
226
|
-
|
|
227
|
-
screen's `fileId`, then call `edit-design`
|
|
228
|
-
follow-up refinement. Use `mode: "replace-file"`
|
|
229
|
-
representative placeholder into the full chosen direction.
|
|
230
|
-
`generate-design` after
|
|
225
|
+
wait for the user to pick one in chat, delete each other generated variant
|
|
226
|
+
screen with `delete-file` at most once, call `get-design-snapshot` exactly
|
|
227
|
+
once with the selected screen's `fileId`, then call `edit-design` exactly once
|
|
228
|
+
on that same `fileId` for follow-up refinement. Use `mode: "replace-file"`
|
|
229
|
+
when expanding the representative placeholder into the full chosen direction.
|
|
230
|
+
Do not repeat delete/snapshot cycles, and do not call `generate-design` after
|
|
231
|
+
a variant pick.
|
|
231
232
|
- If inline chat choice buttons are unavailable, the user can tell you the
|
|
232
233
|
preferred screen name. Do not show a separate variant picker or ask them to
|
|
233
234
|
paste a copyable handoff summary.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Design
|
|
2
|
+
|
|
3
|
+
An agent-native HTML prototyping studio — describe a screen and get a working
|
|
4
|
+
Alpine/Tailwind prototype you can refine, tweak, and export. An open-source,
|
|
5
|
+
self-hostable alternative to v0 and Lovable-style prototyping tools.
|
|
6
|
+
|
|
7
|
+
**Live app: [design.agent-native.com](https://design.agent-native.com)**
|
|
8
|
+
|
|
9
|
+
Instead of a layered drawing canvas, the agent generates complete self-contained
|
|
10
|
+
HTML prototypes, renders them in an iframe, and lets you refine the result with
|
|
11
|
+
prompts and visual tweak controls.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Generate complete, working HTML prototypes from a prompt.
|
|
16
|
+
- Compare multiple design directions, then keep refining the strongest one.
|
|
17
|
+
- Visual tweak controls for common copy, layout, color, and spacing changes.
|
|
18
|
+
- Save and reuse design-system preferences to stay on-brand.
|
|
19
|
+
- Import existing HTML or reference material as context.
|
|
20
|
+
- Export real files: HTML, ZIP, or PDF.
|
|
21
|
+
|
|
22
|
+
## Develop locally
|
|
23
|
+
|
|
24
|
+
Scaffold your own copy and run it:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx @agent-native/core@latest create my-design --standalone --template design
|
|
28
|
+
cd my-design
|
|
29
|
+
pnpm install
|
|
30
|
+
pnpm dev
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Full docs: [agent-native.com/docs/template-design](https://agent-native.com/docs/template-design).
|
|
@@ -5,9 +5,72 @@ import { z } from "zod";
|
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
7
|
|
|
8
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
9
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function parseDesignData(value: unknown): Record<string, unknown> {
|
|
13
|
+
if (typeof value !== "string" || !value.trim()) return {};
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(value);
|
|
16
|
+
return isRecord(parsed) ? parsed : {};
|
|
17
|
+
} catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function pruneKeyedRecord(
|
|
23
|
+
value: unknown,
|
|
24
|
+
fileId: string,
|
|
25
|
+
): Record<string, unknown> | undefined {
|
|
26
|
+
if (!isRecord(value)) return undefined;
|
|
27
|
+
const next = { ...value };
|
|
28
|
+
delete next[fileId];
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function variantScreenMatchesFile(screen: unknown, fileId: string): boolean {
|
|
33
|
+
if (typeof screen === "string") return screen === fileId;
|
|
34
|
+
return isRecord(screen) && screen.id === fileId;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function pruneDesignVariantSets(
|
|
38
|
+
value: unknown,
|
|
39
|
+
fileId: string,
|
|
40
|
+
): Record<string, unknown> | undefined {
|
|
41
|
+
if (!isRecord(value)) return undefined;
|
|
42
|
+
const next: Record<string, unknown> = {};
|
|
43
|
+
for (const [key, rawSet] of Object.entries(value)) {
|
|
44
|
+
if (!isRecord(rawSet) || !Array.isArray(rawSet.screens)) {
|
|
45
|
+
next[key] = rawSet;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const screens = rawSet.screens.filter(
|
|
49
|
+
(screen) => !variantScreenMatchesFile(screen, fileId),
|
|
50
|
+
);
|
|
51
|
+
if (screens.length <= 1) continue;
|
|
52
|
+
next[key] = { ...rawSet, screens };
|
|
53
|
+
}
|
|
54
|
+
return next;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function pruneDeletedFileMetadata(
|
|
58
|
+
data: Record<string, unknown>,
|
|
59
|
+
fileId: string,
|
|
60
|
+
): Record<string, unknown> {
|
|
61
|
+
return {
|
|
62
|
+
...data,
|
|
63
|
+
canvasFrames: pruneKeyedRecord(data.canvasFrames, fileId) ?? {},
|
|
64
|
+
screenMetadata: pruneKeyedRecord(data.screenMetadata, fileId) ?? {},
|
|
65
|
+
localhostScreens: pruneKeyedRecord(data.localhostScreens, fileId) ?? {},
|
|
66
|
+
designVariantSets:
|
|
67
|
+
pruneDesignVariantSets(data.designVariantSets, fileId) ?? {},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
8
71
|
export default defineAction({
|
|
9
72
|
description:
|
|
10
|
-
"Delete a file from a design project. Validates ownership via the parent design's access.",
|
|
73
|
+
"Delete a file from a design project. Idempotent: if the file is already gone, returns deleted=false so cleanup retries can continue. Validates ownership via the parent design's access when the file exists.",
|
|
11
74
|
schema: z.object({
|
|
12
75
|
id: z.string().describe("File ID to delete"),
|
|
13
76
|
}),
|
|
@@ -33,21 +96,34 @@ export default defineAction({
|
|
|
33
96
|
)
|
|
34
97
|
.limit(1);
|
|
35
98
|
|
|
36
|
-
if (!file) {
|
|
37
|
-
throw new Error(`File not found: ${id}`);
|
|
38
|
-
}
|
|
99
|
+
if (!file) return { id, deleted: false, alreadyMissing: true };
|
|
39
100
|
|
|
40
101
|
await assertAccess("design", file.designId, "editor");
|
|
41
102
|
|
|
42
103
|
const now = new Date().toISOString();
|
|
43
104
|
|
|
44
|
-
await db.
|
|
105
|
+
await db.transaction(async (tx) => {
|
|
106
|
+
const [currentDesign] = await tx
|
|
107
|
+
.select({ data: schema.designs.data })
|
|
108
|
+
.from(schema.designs)
|
|
109
|
+
.where(eq(schema.designs.id, file.designId))
|
|
110
|
+
.limit(1);
|
|
111
|
+
const nextData = pruneDeletedFileMetadata(
|
|
112
|
+
parseDesignData(currentDesign?.data),
|
|
113
|
+
id,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
await tx.delete(schema.designFiles).where(eq(schema.designFiles.id, id));
|
|
45
117
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
118
|
+
// Update the parent design's board metadata and updatedAt timestamp.
|
|
119
|
+
await tx
|
|
120
|
+
.update(schema.designs)
|
|
121
|
+
.set({
|
|
122
|
+
data: JSON.stringify({ ...nextData, updatedAt: now }),
|
|
123
|
+
updatedAt: now,
|
|
124
|
+
})
|
|
125
|
+
.where(eq(schema.designs.id, file.designId));
|
|
126
|
+
});
|
|
51
127
|
|
|
52
128
|
return { id, deleted: true };
|
|
53
129
|
},
|
|
@@ -87,6 +87,7 @@ export default defineAction({
|
|
|
87
87
|
err.statusCode = 409;
|
|
88
88
|
throw err;
|
|
89
89
|
}
|
|
90
|
+
const boundedFile = requestedFileId || requestedFilename ? files[0] : null;
|
|
90
91
|
|
|
91
92
|
return {
|
|
92
93
|
designId,
|
|
@@ -108,6 +109,18 @@ export default defineAction({
|
|
|
108
109
|
appliedTweaks: snapshot.appliedTweaks,
|
|
109
110
|
resolvedCssVars: snapshot.resolvedCssVars,
|
|
110
111
|
deepLink: designDeepLink(designId),
|
|
112
|
+
...(boundedFile
|
|
113
|
+
? {
|
|
114
|
+
editTarget: {
|
|
115
|
+
designId,
|
|
116
|
+
fileId: boundedFile.id,
|
|
117
|
+
filename: boundedFile.filename,
|
|
118
|
+
},
|
|
119
|
+
nextRequiredAction:
|
|
120
|
+
`Call edit-design exactly once with designId ${designId} and fileId ${boundedFile.id} (${boundedFile.filename}). ` +
|
|
121
|
+
"Do not call delete-file or get-design-snapshot again unless edit-design fails with a concrete missing context error.",
|
|
122
|
+
}
|
|
123
|
+
: {}),
|
|
111
124
|
};
|
|
112
125
|
},
|
|
113
126
|
link: ({ result }) => {
|
|
@@ -40,20 +40,18 @@ const FALLBACK_INSTRUCTIONS =
|
|
|
40
40
|
"The generated directions have been saved as normal screens on the Design " +
|
|
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
|
-
"delete
|
|
44
|
-
"the kept screen, then call edit-design on that same fileId in a bounded pass. " +
|
|
43
|
+
"delete each other variant screen at most once, call get-design-snapshot with fileId for " +
|
|
44
|
+
"the kept screen once, then call edit-design on that same fileId in a bounded pass. " +
|
|
45
45
|
'Use mode "replace-file" when expanding the representative placeholder. ' +
|
|
46
46
|
"Do not call generate-design after a variant pick.";
|
|
47
47
|
|
|
48
48
|
const VARIANT_PICK_SUBMIT_MESSAGE =
|
|
49
|
-
"Use this design direction.
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"do not create index.html, and do not resend a huge payload. Stop after the " +
|
|
56
|
-
"first successful edit-design save.";
|
|
49
|
+
"Use this design direction. Keep the selected screen, clean up each other " +
|
|
50
|
+
"variant screen at most once, read only the kept screen, then update that " +
|
|
51
|
+
"same screen in one bounded pass. If a cleanup action reports a screen was " +
|
|
52
|
+
"already missing, continue. Use the exact file ids and tool instructions in " +
|
|
53
|
+
"the selected answer below. Do not repeat cleanup/read cycles, do not create " +
|
|
54
|
+
"a new index.html, and stop after the first successful screen update.";
|
|
57
55
|
|
|
58
56
|
const variantSchema = z.object({
|
|
59
57
|
id: z.string().min(1).describe("Stable variant id, e.g. 'minimal-focus'"),
|
|
@@ -609,8 +607,8 @@ export default defineAction({
|
|
|
609
607
|
label: screen.label || optionName(index),
|
|
610
608
|
value:
|
|
611
609
|
`Keep "${screen.label}" (${screen.filename}, file id ${screen.id}) ` +
|
|
612
|
-
`from variant set ${variantSetId}. Delete
|
|
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.`,
|
|
610
|
+
`from variant set ${variantSetId}. Delete each other variant screen at most once: ${otherScreens}. If delete-file says a screen is already missing, continue. ` +
|
|
611
|
+
`Then call get-design-snapshot exactly once 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 repeat delete/snapshot cycles, do not create index.html, and do not resend a huge payload. Stop after the first successful edit-design save.`,
|
|
614
612
|
};
|
|
615
613
|
}),
|
|
616
614
|
},
|
|
@@ -628,7 +626,7 @@ export default defineAction({
|
|
|
628
626
|
embed: true,
|
|
629
627
|
fallbackInstructions: FALLBACK_INSTRUCTIONS,
|
|
630
628
|
nextRequiredAction:
|
|
631
|
-
'Wait for the user to pick a screen in chat. Then delete
|
|
629
|
+
'Wait for the user to pick a screen in chat. Then delete each unchosen variant screen with delete-file at most once, call get-design-snapshot exactly once 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 repeat delete/snapshot cycles. Do not call generate-design after a variant pick. Stop after the first successful edit-design save.',
|
|
632
630
|
};
|
|
633
631
|
},
|
|
634
632
|
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
|
|
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 each unchosen variant screen at most once, call get-design-snapshot exactly once with fileId for the kept screen, then call edit-design exactly once on that same fileId in a bounded pass. Use mode "replace-file" when expanding the representative placeholder into the full chosen direction. Do not repeat delete/snapshot cycles. 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
|
|
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 each unchosen variant screen at most once, call get-design-snapshot exactly once with fileId for the kept screen, then call edit-design exactly once on that same fileId in a bounded pass. Use mode "replace-file" when expanding the representative placeholder into the full chosen direction. Do not repeat delete/snapshot cycles. 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)
|
|
@@ -360,6 +360,16 @@ export function isScreenRootElementInfo(info: ElementInfo | null | undefined) {
|
|
|
360
360
|
return tagName === "BODY" || tagName === "HTML";
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
export function shouldMirrorSelectedElementToAgentChat(
|
|
364
|
+
info: ElementInfo | null | undefined,
|
|
365
|
+
): info is ElementInfo {
|
|
366
|
+
if (!info || isScreenRootElementInfo(info)) return false;
|
|
367
|
+
const text = info.textContent?.replace(/\s+/g, " ").trim();
|
|
368
|
+
if (!text) return true;
|
|
369
|
+
const labelText = text.replace(/^[^A-Za-z0-9]+/, "").toLowerCase();
|
|
370
|
+
return !labelText.startsWith("nothing here yet");
|
|
371
|
+
}
|
|
372
|
+
|
|
363
373
|
export function shouldIgnoreOverviewLayerCreationEcho(args: {
|
|
364
374
|
pendingLayerId: string | null | undefined;
|
|
365
375
|
pendingScreenId: string | null | undefined;
|
|
@@ -1573,7 +1583,7 @@ function designVariantGenerationDirectives(
|
|
|
1573
1583
|
...designSystemGenerationDirectives(designSystemId),
|
|
1574
1584
|
"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.",
|
|
1575
1585
|
"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.",
|
|
1576
|
-
'Wait for the user\'s chat pick, delete
|
|
1586
|
+
'Wait for the user\'s chat pick, delete each unchosen variant screen at most once, call `get-design-snapshot` exactly once with `fileId` for the kept screen, then call `edit-design` exactly once on that same `fileId` in a bounded pass. Use `mode: "replace-file"` when expanding the representative placeholder into the full chosen direction. Do not repeat delete/snapshot cycles. Do not call `generate-design` after a variant pick. Stop after the first successful `edit-design` save.',
|
|
1577
1587
|
];
|
|
1578
1588
|
}
|
|
1579
1589
|
|
|
@@ -1584,7 +1594,7 @@ function designGenerationDirectives(
|
|
|
1584
1594
|
return [
|
|
1585
1595
|
`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.`,
|
|
1586
1596
|
...designSystemGenerationDirectives(designSystemId),
|
|
1587
|
-
'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
|
|
1597
|
+
'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 each unchosen variant screen at most once, call `get-design-snapshot` exactly once with `fileId` for the kept screen, then call `edit-design` exactly once on that same `fileId` in a bounded pass. Use `mode: "replace-file"` when expanding the representative placeholder into the full chosen direction. Do not repeat delete/snapshot cycles. Do not call `generate-design` after a variant pick. Stop after the first successful `edit-design` save. Otherwise generate one polished first direction.',
|
|
1588
1598
|
"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.",
|
|
1589
1599
|
"After generate-design succeeds, stop and summarize what was created.",
|
|
1590
1600
|
];
|
|
@@ -9162,7 +9172,7 @@ export default function DesignEditor() {
|
|
|
9162
9172
|
|
|
9163
9173
|
useEffect(() => {
|
|
9164
9174
|
const key = "design:selected-element";
|
|
9165
|
-
if (!id || !selectedElement) {
|
|
9175
|
+
if (!id || !shouldMirrorSelectedElementToAgentChat(selectedElement)) {
|
|
9166
9176
|
removeAgentChatContextItem(key);
|
|
9167
9177
|
return;
|
|
9168
9178
|
}
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Dispatch
|
|
2
|
+
|
|
3
|
+
The agent-native workspace control plane — a central Slack/Telegram inbox, a
|
|
4
|
+
secrets vault, scheduled jobs, approvals, and an orchestrator agent that delegates
|
|
5
|
+
work to the right specialist app over A2A.
|
|
6
|
+
|
|
7
|
+
**Live app: [dispatch.agent-native.com](https://dispatch.agent-native.com)**
|
|
8
|
+
|
|
9
|
+
Where other templates are domain apps (Mail, Calendar, Analytics, Brain),
|
|
10
|
+
Dispatch is the app you run _alongside_ them to coordinate everything. It routes
|
|
11
|
+
messages, holds shared credentials, runs cross-app jobs, and gates sensitive
|
|
12
|
+
actions behind approvals.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- Central inbox for Slack DMs, Telegram, email, and A2A requests from other agents.
|
|
17
|
+
- Orchestrator agent that triages and delegates domain work over A2A.
|
|
18
|
+
- Secrets vault with per-app grants and an audit trail.
|
|
19
|
+
- Workspace resources: shared skills, guardrails, agent profiles, and MCP servers.
|
|
20
|
+
- Cross-app scheduled/recurring jobs.
|
|
21
|
+
- Approval queue for destructive or external actions.
|
|
22
|
+
|
|
23
|
+
## Develop locally
|
|
24
|
+
|
|
25
|
+
Scaffold your own copy and run it:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @agent-native/core@latest create my-dispatch --standalone --template dispatch
|
|
29
|
+
cd my-dispatch
|
|
30
|
+
pnpm install
|
|
31
|
+
pnpm dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Full docs: [agent-native.com/docs/template-dispatch](https://agent-native.com/docs/template-dispatch).
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Forms
|
|
2
|
+
|
|
3
|
+
An open-source, agent-native alternative to Typeform and Google Forms. Describe
|
|
4
|
+
the form you want, refine it in the visual editor, and publish a public form that
|
|
5
|
+
stores submissions in your own SQL database.
|
|
6
|
+
|
|
7
|
+
**Live app: [forms.agent-native.com](https://forms.agent-native.com)**
|
|
8
|
+
|
|
9
|
+
Build forms conversationally or by hand — the agent updates the schema and the
|
|
10
|
+
preview updates from SQL-backed state. Route new submissions wherever you need
|
|
11
|
+
them.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Build and edit forms conversationally, with a live preview.
|
|
16
|
+
- Visual builder for labels, validation, options, and field order.
|
|
17
|
+
- Shipped field types: text, email, number, long text, select, multi-select,
|
|
18
|
+
checkbox, radio, date, rating, and scale.
|
|
19
|
+
- Submissions stored in SQL with a per-response detail view and dashboard.
|
|
20
|
+
- Route submissions to webhooks, Slack, Discord, or Google Sheets.
|
|
21
|
+
- Publish public form URLs with a thank-you message.
|
|
22
|
+
|
|
23
|
+
## Develop locally
|
|
24
|
+
|
|
25
|
+
Scaffold your own copy and run it:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @agent-native/core@latest create my-forms --standalone --template forms
|
|
29
|
+
cd my-forms
|
|
30
|
+
pnpm install
|
|
31
|
+
pnpm dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Full docs: [agent-native.com/docs/template-forms](https://agent-native.com/docs/template-forms).
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Macros
|
|
2
|
+
|
|
3
|
+
An agent-native, voice-driven calorie and macro tracker — an open-source take on
|
|
4
|
+
MyFitnessPal-style logging. Speak or type what you ate and the agent logs the
|
|
5
|
+
food, estimates calories and macros, and keeps your daily stats up to date.
|
|
6
|
+
|
|
7
|
+
> **Internal/experimental template.** Macros is not shown in the public template
|
|
8
|
+
> pickers. It exists as a reference app and demo.
|
|
9
|
+
|
|
10
|
+
**Live app: [macros.agent-native.com](https://macros.agent-native.com)**
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Log foods and meals by voice or text through the agent.
|
|
15
|
+
- Automatic calorie and macro estimation.
|
|
16
|
+
- Voice corrections and quick edits.
|
|
17
|
+
- Daily and historical stats.
|
|
18
|
+
|
|
19
|
+
## Develop locally
|
|
20
|
+
|
|
21
|
+
Scaffold your own copy and run it:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @agent-native/core@latest create my-macros --standalone --template macros
|
|
25
|
+
cd my-macros
|
|
26
|
+
pnpm install
|
|
27
|
+
pnpm dev
|
|
28
|
+
```
|
|
@@ -53,6 +53,8 @@ Default to Apple/Linear-level restraint: make the primary workflow obvious, then
|
|
|
53
53
|
- **Visual assets**: Websites, games, and object-focused pages need real or generated media when images help users understand the subject.
|
|
54
54
|
- **Responsive fit**: Text must not overflow buttons, cards, tabs, sidebars, or fixed-format tools. Use stable dimensions for boards, grids, toolbars, and counters.
|
|
55
55
|
|
|
56
|
+
**Beat convergence, not just defaults.** You sample toward the "on-distribution" center, so naming what to avoid is not enough: every "don't" needs a "do", or you converge on the next safe option (ban Inter and you reach for Roboto; ban purple gradients and you reach for Space Grotesk + a teal accent on every screen). Commit to one named direction, pair any reference with the reason it fits ("Linear: the quiet confidence of its spacing" — a bare "Linear" collapses back to the average), and match implementation effort to the vision: maximalist wants elaborate motion and effects, minimal wants restraint and precise spacing. When building on an existing app, inspect its tokens/type/components first and treat any drift back to a default as a missing token to pin, not something to re-prompt.
|
|
57
|
+
|
|
56
58
|
## Agent-Native UI Rules
|
|
57
59
|
|
|
58
60
|
- Agent-native apps use React, Vite, Tailwind CSS, shadcn/ui, and `@tabler/icons-react`.
|