@agent-native/core 0.147.0 → 0.148.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/analytics/DEVELOPING.md +50 -3
- package/corpus/templates/analytics/actions/purge-first-party-analytics-postgres.ts +190 -0
- package/corpus/templates/analytics/app/i18n/index.ts +14 -29
- package/corpus/templates/analytics/app/i18n-data.ts +10 -10
- package/corpus/templates/analytics/app/pages/Settings.tsx +5 -21
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -3
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery-backfill.ts +197 -18
- package/corpus/templates/analytics/server/db/schema.ts +23 -0
- package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +3 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +1 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +113 -13
- package/corpus/templates/analytics/server/lib/first-party-analytics-purge.ts +140 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-volume.ts +207 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +40 -9
- package/corpus/templates/analytics/server/lib/gcloud.ts +148 -20
- package/corpus/templates/analytics/server/plugins/db.ts +42 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/assets/app/i18n/index.ts +14 -29
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/brain/app/i18n/index.ts +14 -29
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/chat/app/i18n/index.ts +14 -29
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -7
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +18 -13
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +87 -370
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +59 -101
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +136 -213
- package/corpus/templates/clips/app/i18n/en-US.ts +11 -8
- package/corpus/templates/clips/desktop/src/app.tsx +1 -1
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/content/app/i18n/index.ts +14 -29
- package/corpus/templates/crm/app/i18n/index.ts +14 -29
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/design/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/design/actions/import-code.ts +2 -43
- package/corpus/templates/design/app/i18n/index.ts +14 -29
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/dispatch/app/i18n-data.ts +1 -1
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/factory/AGENTS.md +40 -49
- package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +66 -0
- package/corpus/templates/factory/actions/evaluate-triage-item.ts +37 -0
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +25 -4
- package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +55 -0
- package/corpus/templates/factory/actions/ingest-github-observation.ts +21 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +118 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +24 -2
- package/corpus/templates/factory/actions/poll-github-sources.ts +60 -0
- package/corpus/templates/factory/actions/poll-sentry-errors.ts +39 -0
- package/corpus/templates/factory/actions/poll-slack-channel.ts +45 -1
- package/corpus/templates/factory/actions/run-factory-automation.ts +1 -1
- package/corpus/templates/factory/actions/save-factory-automation.ts +2 -2
- package/corpus/templates/factory/actions/start-builder-for-item.ts +51 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +685 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +6 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +25 -0
- package/corpus/templates/factory/app/routes/factory.tsx +95 -42
- package/corpus/templates/factory/server/db/schema.ts +37 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +5 -1
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +29 -0
- package/corpus/templates/factory/server/triage/audit.ts +79 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/forms/app/i18n/index.ts +14 -29
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/macros/app/i18n/index.ts +14 -29
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/mail/app/i18n/index.ts +14 -29
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +7 -7
- package/corpus/templates/plan/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +15 -15
- package/corpus/templates/slides/actions/import-code.ts +2 -43
- package/corpus/templates/slides/app/i18n/index.ts +14 -29
- package/corpus/templates/slides/server/routes/api/preview-images.get.ts +4 -1
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +1 -84
- package/corpus/templates/tasks/app/hooks/use-mobile.tsx +1 -21
- package/corpus/templates/tasks/app/i18n/index.ts +14 -29
- package/dist/agent/engine/ai-sdk-engine.js +2 -1
- package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
- package/dist/agent/engine/openai-compatible-endpoint.js +5 -1
- package/dist/agent/engine/provider-endpoint-validation.d.ts +9 -0
- package/dist/agent/engine/provider-endpoint-validation.js +26 -0
- package/dist/agent/engine/provider-env-vars.d.ts +1 -1
- package/dist/agent/engine/provider-env-vars.js +1 -1
- package/dist/agent/engine/registry.d.ts +8 -6
- package/dist/agent/engine/registry.js +37 -24
- package/dist/agent/tool-search.d.ts +1 -0
- package/dist/agent/tool-search.js +17 -1
- package/dist/automations/service.js +4 -10
- package/dist/brand-kit/brand-signals.d.ts +13 -0
- package/dist/brand-kit/brand-signals.js +15 -0
- package/dist/brand-kit/index.d.ts +2 -2
- package/dist/brand-kit/index.js +1 -1
- package/dist/cli/plan-blocks.d.ts +3 -18
- package/dist/cli/plan-blocks.js +2 -95
- package/dist/cli/plan-publish-store.d.ts +2 -61
- package/dist/cli/plan-publish-store.js +2 -127
- package/dist/cli/skills-content/connection.d.ts +1 -1
- package/dist/cli/skills-content/connection.js +1 -52
- package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-recap-skill.js +1 -553
- package/dist/client/agent-engine-key.d.ts +14 -4
- package/dist/client/agent-engine-key.js +51 -5
- package/dist/client/agent-provider-catalog.d.ts +20 -0
- package/dist/client/agent-provider-catalog.js +100 -0
- package/dist/client/blocks/index.d.ts +1 -0
- package/dist/client/blocks/index.js +1 -0
- package/dist/client/chat/run-recovery.js +4 -48
- package/dist/client/chat-first.js +4 -3
- package/dist/client/i18n.d.ts +14 -0
- package/dist/client/i18n.js +18 -0
- package/dist/client/settings/ProviderSetupForm.d.ts +21 -0
- package/dist/client/settings/ProviderSetupForm.js +145 -0
- package/dist/client/settings/SettingsPanel.js +52 -49
- package/dist/client/settings/index.d.ts +2 -0
- package/dist/client/settings/index.js +2 -0
- package/dist/coding-tools/run-code.d.ts +5 -0
- package/dist/coding-tools/run-code.js +196 -36
- package/dist/coding-tools/tool-orchestration.d.ts +10 -0
- package/dist/coding-tools/tool-orchestration.js +107 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/jobs/frontmatter.d.ts +9 -0
- package/dist/jobs/frontmatter.js +16 -0
- package/dist/jobs/scheduler.js +8 -8
- package/dist/jobs/tools.d.ts +1 -1
- package/dist/jobs/tools.js +2 -7
- package/dist/localization/default-messages.d.ts +20 -0
- package/dist/localization/default-messages.js +25 -5
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/agent-engines/test-agent-engine.js +34 -10
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/run-code-tools.d.ts +1 -1
- package/dist/server/agent-chat/run-code-tools.js +3 -1
- package/dist/server/agent-chat-plugin.js +6 -6
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.js +43 -12
- package/dist/server/agents-bundle.js +2 -1
- package/dist/server/auth.js +21 -5
- package/dist/server/credential-provider.js +1 -0
- package/dist/server/design-token-utils.d.ts +18 -0
- package/dist/server/design-token-utils.js +31 -0
- package/dist/server/onboarding-html.js +22 -2
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/chat/app/i18n/index.ts +14 -29
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/templates/default/app/i18n/index.ts +14 -29
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/dist/triggers/dispatcher.js +1 -8
- package/docs/content/environment-variables.mdx +39 -38
- package/package.json +4 -4
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/chat/app/i18n/index.ts +14 -29
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
- package/src/templates/default/app/i18n/index.ts +14 -29
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
- package/corpus/templates/plan/app/components/plan/wireframe/sanitize-html.ts +0 -343
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
name: frontend-design
|
|
3
3
|
description: >-
|
|
4
4
|
Sets the visual direction for a new or redesigned surface, with production
|
|
5
|
-
quality that avoids generic AI aesthetics. Use when building
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
quality that avoids generic AI aesthetics. Use when building, redesigning, or
|
|
6
|
+
cleaning up any user-facing UI, including screenshot-driven feedback, copy or
|
|
7
|
+
density reduction, settings, control placement, or a design pass ("make this
|
|
8
|
+
look good"). Do not load it only for purely mechanical wiring or formatting.
|
|
9
9
|
scope: dev
|
|
10
10
|
license: Complete terms in LICENSE.txt
|
|
11
11
|
source: https://github.com/anthropics/skills/blob/main/skills/frontend-design/SKILL.md
|
|
12
12
|
local-changes: >-
|
|
13
|
-
Description
|
|
14
|
-
|
|
13
|
+
Description deliberately widened on 2026-08-09 because the previous narrow
|
|
14
|
+
trigger excluded routine UI edits, including screenshot-driven cleanup, copy
|
|
15
|
+
and density changes, settings, and control placement. An upstream sync must
|
|
16
|
+
not re-narrow it. Verification remains deliberately rescoped; an upstream
|
|
17
|
+
sync must not restore screenshot-everything or broad browser-automation steps.
|
|
15
18
|
metadata:
|
|
16
19
|
internal: true
|
|
17
20
|
---
|
|
@@ -26,10 +29,12 @@ The user may ask for a component, page, full app, dashboard, marketing surface,
|
|
|
26
29
|
|
|
27
30
|
Before coding, decide:
|
|
28
31
|
|
|
29
|
-
- **Purpose**: What workflow does this surface make easier? What
|
|
32
|
+
- **Purpose**: What workflow does this surface make easier? What does the user
|
|
33
|
+
need to understand, decide, or do next?
|
|
30
34
|
- **Audience**: Who will use it repeatedly, and what should feel fast, calm, playful, premium, editorial, technical, or utilitarian?
|
|
31
35
|
- **Tone**: Choose a concrete aesthetic direction: refined minimal, dense operations console, editorial, playful, industrial, warm handmade, high-contrast data tool, etc.
|
|
32
|
-
- **Information hierarchy**: What must be visible
|
|
36
|
+
- **Information hierarchy**: What must be visible to orient and act, and what
|
|
37
|
+
can wait until context or intent makes it relevant?
|
|
33
38
|
- **Differentiation**: What makes this feel designed for this exact domain?
|
|
34
39
|
|
|
35
40
|
Then implement working code that is cohesive, accessible, responsive, and polished in small details: typography, spacing, copy, motion, empty states, loading states, focus states, and error states.
|
|
@@ -50,46 +55,80 @@ before selecting its accent family. Shared behavior and semantic token names
|
|
|
50
55
|
should stay consistent; palette, density, composition, type contrast, and
|
|
51
56
|
shape language should not be identical by default.
|
|
52
57
|
|
|
53
|
-
## Minimalism And Progressive Disclosure
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
- **
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
- **
|
|
92
|
-
|
|
58
|
+
## High-Signal Minimalism And Progressive Disclosure
|
|
59
|
+
|
|
60
|
+
Minimalism means fewer competing kinds of UI, not less useful information. Keep
|
|
61
|
+
surfaces dense and scannable: reduce redundant prose, decorative containers,
|
|
62
|
+
borders, badges, accent colors, and persistent controls before removing content
|
|
63
|
+
that helps the user orient, compare, decide, or recover. The reference class is
|
|
64
|
+
calm productivity software such as ChatGPT/Codex, Linear, and Vercel, not empty
|
|
65
|
+
whitespace.
|
|
66
|
+
|
|
67
|
+
### Product UX Philosophy
|
|
68
|
+
|
|
69
|
+
Apply these principles as binding decision rules:
|
|
70
|
+
|
|
71
|
+
- **Purpose over presence**: Every visible element must support orientation,
|
|
72
|
+
state comprehension, a decision, an action, or recovery. Before adding one,
|
|
73
|
+
name which; if it supports none or duplicates another element, remove or
|
|
74
|
+
defer it.
|
|
75
|
+
- **Clarity over cleverness**: Use plain language, familiar patterns, explicit
|
|
76
|
+
hierarchy, and visible state. Do not make decoration or invented terminology
|
|
77
|
+
carry meaning. Preserve the labels, hit targets, focus states, and recovery
|
|
78
|
+
paths required for accessible use.
|
|
79
|
+
- **Simple first, powerful on demand**: Keep the current task and state in the
|
|
80
|
+
default presentation. Put advanced, rare, diagnostic, and secondary work
|
|
81
|
+
behind contextual disclosure, menus, or Settings. Do not turn a discoverability
|
|
82
|
+
concern into permanent chrome, and do not hide information needed for the
|
|
83
|
+
current decision.
|
|
84
|
+
- **Hierarchy over chrome**: Use typography, spacing, alignment, and restrained
|
|
85
|
+
emphasis to organize information. Treat prose, controls, borders, cards,
|
|
86
|
+
badges, and accent colors as a competition budget: reduce competing kinds of
|
|
87
|
+
elements before reducing useful information. When a surface has one clear
|
|
88
|
+
next decision, give it dominant emphasis and move secondary actions out of
|
|
89
|
+
the default path. Do not wrap every section in a card or add borders for
|
|
90
|
+
grouping alone; use spacing, alignment, typography, or dividers first. A
|
|
91
|
+
container must communicate grouping, state, or interaction.
|
|
92
|
+
- **Coherence over novelty**: Reuse the product's primitives, interaction
|
|
93
|
+
patterns, and language. When given a screenshot or reference product, match
|
|
94
|
+
its underlying hierarchy, density, and behavior; do not copy decoration or
|
|
95
|
+
introduce a second visual language without a product reason.
|
|
96
|
+
- **Quiet continuity**: Feedback must be immediate, contextual, and honest.
|
|
97
|
+
Preserve the user's place and layout, make loading, empty, and error states
|
|
98
|
+
understandable, and use motion only to explain a change.
|
|
99
|
+
- **Respect repeated use**: Optimize for the hundredth use, not the first
|
|
100
|
+
impression. If a control repeats an explanation, occupies persistent space
|
|
101
|
+
for an occasional task, or turns routine work into ceremony, remove it or
|
|
102
|
+
move it to the contextual surface that owns it.
|
|
103
|
+
|
|
104
|
+
### Progressive Disclosure And Information Timing
|
|
105
|
+
|
|
106
|
+
Expose information and controls according to relevance, frequency, and
|
|
107
|
+
consequence. Before coding, inventory the content and actions and assign them to
|
|
108
|
+
the smallest useful visibility layer:
|
|
109
|
+
|
|
110
|
+
1. **Orient and act**: location, current state, and context needed for the next
|
|
111
|
+
meaningful choice.
|
|
112
|
+
2. **Support active work**: details and controls for the selected item or
|
|
113
|
+
current workflow.
|
|
114
|
+
3. **Available on demand**: advanced settings, diagnostics, credentials,
|
|
115
|
+
metadata, destructive actions, documentation, and rare tools.
|
|
116
|
+
|
|
117
|
+
Use a disclosure pattern that matches the task. Keep independent concerns easy
|
|
118
|
+
to scan inside an expanded area instead of dumping every form, explanation,
|
|
119
|
+
and secondary action into the first reveal. A collapsed row must retain its
|
|
120
|
+
label and essential state; remove explanatory subtext unless it changes the
|
|
121
|
+
next decision. For configuration with a known current state, show that state
|
|
122
|
+
first and expose editing contextually instead of defaulting to a full form.
|
|
123
|
+
|
|
124
|
+
Before shipping, verify collapsed, expanded, loading, empty, error, and
|
|
125
|
+
narrow-width states. The default state fails review when its first viewport
|
|
126
|
+
contains multiple unrelated forms, repeated explanatory copy, documentation
|
|
127
|
+
links, or controls for unrelated tasks. It also fails when useful information
|
|
128
|
+
has been replaced with empty whitespace or extra clicks solely to look minimal.
|
|
129
|
+
The default state passes when users can identify their location, current state,
|
|
130
|
+
current task, and relevant next choice without reading documentation, while
|
|
131
|
+
the useful information remains dense and scannable.
|
|
93
132
|
|
|
94
133
|
## Aesthetic Guidelines
|
|
95
134
|
|
|
@@ -166,26 +205,28 @@ passed this requirement yet.
|
|
|
166
205
|
|
|
167
206
|
### Product Surface Review
|
|
168
207
|
|
|
169
|
-
Before shipping a new app or a substantial redesign, review the
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
208
|
+
Before shipping a new app or a substantial redesign, review the surface as an
|
|
209
|
+
operator would use it repeatedly:
|
|
210
|
+
|
|
211
|
+
- Can users identify where they are, what state they are in, and what
|
|
212
|
+
meaningful choices or next steps are available?
|
|
213
|
+
- Remove competing or redundant elements, then place optional inputs, provider
|
|
214
|
+
choices, diagnostics, long explanations, and secondary actions where they
|
|
215
|
+
remain discoverable without crowding the current task.
|
|
216
|
+
- Match the composition to the workflow. Use a focused page or step flow when
|
|
217
|
+
the work is sequential; use an overview when comparing or monitoring several
|
|
218
|
+
things is genuinely the job. Preserve the user's progress in either case.
|
|
179
219
|
- Remove generic hero copy, feature tours, repeated helper text, nested cards,
|
|
180
220
|
status-chip soup, and decorative AI treatment before adding more styling.
|
|
181
|
-
- For review flows,
|
|
182
|
-
|
|
183
|
-
|
|
221
|
+
- For review flows, choose stacking, side-by-side comparison, or another
|
|
222
|
+
composition based on content length, scanability, and the user's comparison
|
|
223
|
+
task.
|
|
184
224
|
- Compare the result with sibling apps. Shared toolkit behavior should feel
|
|
185
225
|
consistent, but a repeated palette, hero composition, type pairing, and
|
|
186
226
|
radius language without a product reason is visual drift, not consistency.
|
|
187
|
-
- Check the result at the target desktop width and a
|
|
188
|
-
|
|
227
|
+
- Check the result with realistic content at the target desktop width and a
|
|
228
|
+
narrow width. If it feels like documentation instead of a tool, reduce noise
|
|
229
|
+
or clarify the hierarchy.
|
|
189
230
|
|
|
190
231
|
## shadcn/ui Design Rules
|
|
191
232
|
|
|
@@ -203,18 +244,24 @@ as an operator would use it repeatedly:
|
|
|
203
244
|
not show generic "Loading..." text for content loads; reserve `Spinner` for
|
|
204
245
|
brief mutations, uploads, and progress actions. Use the app's existing
|
|
205
246
|
loading primitive when it is a genuine design-system adapter. Empty states
|
|
206
|
-
should
|
|
247
|
+
should communicate the state and offer the appropriate next step or small set
|
|
248
|
+
of choices.
|
|
207
249
|
|
|
208
250
|
## Anti-Patterns
|
|
209
251
|
|
|
210
|
-
Avoid
|
|
252
|
+
Avoid patterns that add visual noise, obscure state, or compete with the user's
|
|
253
|
+
task without a clear product reason:
|
|
211
254
|
|
|
212
255
|
- Generic AI aesthetics: purple gradients, glassy cards everywhere, vague sparkle language, decorative blobs, and context-free hero sections.
|
|
213
256
|
- Custom reimplementations of shadcn primitives.
|
|
214
257
|
- Raw color overrides on shared components when semantic tokens or variants would work.
|
|
215
|
-
- New always-visible controls for rare actions
|
|
216
|
-
|
|
217
|
-
-
|
|
258
|
+
- New always-visible controls for rare actions when a contextual surface would
|
|
259
|
+
preserve discoverability and reduce noise.
|
|
260
|
+
- Full-width banners, persistent helper rows, decorative cards, or explanatory
|
|
261
|
+
chrome for status that could be communicated more clearly with less weight.
|
|
262
|
+
- Hiding essential meaning or operability behind progressive disclosure. Defer
|
|
263
|
+
complexity when it is contextual or infrequent, but preserve labels, focus,
|
|
264
|
+
hit targets, accessibility, and recovery paths.
|
|
218
265
|
- UI cards nested inside other cards.
|
|
219
266
|
- Text or icons that resize or shift fixed-format UI on hover/loading.
|
|
220
267
|
|
|
@@ -11,42 +11,38 @@ ladder.
|
|
|
11
11
|
|
|
12
12
|
## Core rules
|
|
13
13
|
|
|
14
|
-
- Keep app state in SQL via Drizzle
|
|
15
|
-
|
|
16
|
-
- Keep migrations additive and portable. These tables
|
|
17
|
-
`ownerEmail`/`orgId
|
|
18
|
-
|
|
19
|
-
- Resolve Slack through `server/connectors/credentials.ts
|
|
20
|
-
|
|
21
|
-
connector code, so a new direct `process.env.SLACK_BOT_TOKEN` read is a bug.
|
|
14
|
+
- Keep app state in SQL via Drizzle, scope reads/writes by org and member, and
|
|
15
|
+
use actions as the UI, agent, CLI, MCP, and A2A surface.
|
|
16
|
+
- Keep migrations additive and portable. These org-visible tables use explicit
|
|
17
|
+
`ownerEmail`/`orgId`, not `ownableColumns()`; add deliberate visibility data
|
|
18
|
+
before using `accessFilter`.
|
|
19
|
+
- Resolve Slack through `server/connectors/credentials.ts` with caller identity
|
|
20
|
+
supplied at the entrypoint; never read `SLACK_BOT_TOKEN` directly.
|
|
22
21
|
- A missing callback, partial thread, unreadable provider response, or missed
|
|
23
|
-
reconciliation is not success
|
|
22
|
+
reconciliation is not success; preserve typed failure or
|
|
24
23
|
`reconciliation_required` state.
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
manual. Auto-merge additionally requires a verified Factory Builder run.
|
|
37
|
-
- Reuse the existing ai-services GitHub read and Builder execution APIs. Do not
|
|
38
|
-
duplicate GitHub installation/webhook infrastructure in this template.
|
|
24
|
+
- Auth, identity, credentials/vault, migrations, payments, security, and
|
|
25
|
+
publishable `packages/*` changes are code-level guards requiring human review.
|
|
26
|
+
- Deduplicate by Factory item and rule/run identity, not provider comment ID.
|
|
27
|
+
- Use the generic Slack adapter: clear-bug automations add 👀 and tag
|
|
28
|
+
`@builderio`; GitHub/Sentry clear bugs use the Builder run API. Clips, Design,
|
|
29
|
+
and Content stay owner-managed outside autonomous dispatch and PR governance.
|
|
30
|
+
- PR governance requires verified BuilderIO membership, a clear bug, passing CI,
|
|
31
|
+
and handled review feedback; product/UX implications stay manual. Auto-merge
|
|
32
|
+
also requires a verified Factory Builder run.
|
|
33
|
+
- Reuse the ai-services GitHub read and Builder execution APIs; do not duplicate
|
|
34
|
+
GitHub installation/webhook infrastructure here.
|
|
39
35
|
- Do not add CRUD routes under `server/routes/api/`; actions are the domain
|
|
40
|
-
surface. Provider callbacks
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
the same action surface as manual edits.
|
|
36
|
+
surface. Provider callbacks must verify signatures.
|
|
37
|
+
- Graph edits create immutable blueprint versions. AI proposes with `source=ai`;
|
|
38
|
+
a person reviews and publishes through the same action surface.
|
|
44
39
|
|
|
45
40
|
## Application state
|
|
46
41
|
|
|
47
42
|
- `navigation.view`: `factory` when the workspace is open.
|
|
48
43
|
- `navigation.factoryId`: selected Factory id when present.
|
|
49
|
-
- `navigation.factoryTab`: `map` | `inbox` | `rules` | `automations` | `settings`.
|
|
44
|
+
- `navigation.factoryTab`: `map` | `inbox` | `rules` | `automations` | `audit` | `settings`.
|
|
45
|
+
- `navigation.factoryAuditRunId`: selected automation run in the audit view when present.
|
|
50
46
|
- `navigation.factoryNodeId` / `navigation.factoryEdgeId`: selected graph item.
|
|
51
47
|
- A selected graph node or edge is part of `navigation` context. Read
|
|
52
48
|
`view-screen` before answering why a route exists or changing the selected
|
|
@@ -65,37 +61,32 @@ ladder.
|
|
|
65
61
|
| `evaluate-triage-item` | Append a decision. |
|
|
66
62
|
| `record-triage-feedback` | Capture human correction for learning. |
|
|
67
63
|
| `approve-factory-item` | Explicitly authorize one bounded run. |
|
|
68
|
-
| `start-builder-for-item` | Govern clear-bug dispatch
|
|
69
|
-
| `govern-agent-native-pull-request` | Apply CI, review,
|
|
70
|
-
| `list-factory-automations` / `save-factory-automation` / `run-factory-automation` | Inspect
|
|
71
|
-
| `
|
|
64
|
+
| `start-builder-for-item` | Govern clear-bug dispatch through Slack or Builder API. |
|
|
65
|
+
| `govern-agent-native-pull-request` | Apply CI, review, author, product, and owner gates. |
|
|
66
|
+
| `list-factory-automations` / `save-factory-automation` / `run-factory-automation` | Inspect or edit org-owned prompts, schedules, and runs. |
|
|
67
|
+
| `list-factory-audit` | Inspect automation runs, evidence, decisions, and provider actions. |
|
|
68
|
+
| `get-factory-automation-health` | Inspect scheduler heartbeat and last error. |
|
|
72
69
|
| `suggest-factory-rules` | Mine feedback and fast approvals into proposals. |
|
|
73
70
|
| `reconcile-triage-run` | Persist callback/provider reconciliation. |
|
|
74
71
|
| `list-factories` / `get-factory-graph` | Inspect Factory definitions, graph versions, and live evidence metrics. |
|
|
75
72
|
| `save-factory-graph` | Create or version a complete visual graph; never starts provider work. |
|
|
76
73
|
| `list-factory-comments` / `add-factory-comment` | Read or attach comments to a canvas, node, or edge. |
|
|
77
74
|
|
|
78
|
-
Rules start in shadow mode; hard guards always apply.
|
|
79
|
-
|
|
80
|
-
idempotency key, and provider confirmation. The legacy observer
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
natural language design, explanations, and proposals; it must preserve a
|
|
85
|
-
complete graph and use `save-factory-graph` rather than describing an
|
|
86
|
-
unpersisted change. Rule or guard changes must go through the triage rule
|
|
87
|
-
actions, never through graph JSON.
|
|
75
|
+
Rules start in shadow mode; hard guards always apply. Organization automations
|
|
76
|
+
execute stored prompts, and every external mutation needs a durable run,
|
|
77
|
+
idempotency key, and provider confirmation. The legacy observer ends once org
|
|
78
|
+
automations are seeded. Use the visual editor for graph changes and agent chat
|
|
79
|
+
for proposals; persist complete graphs with `save-factory-graph`. Change rules
|
|
80
|
+
through triage rule actions, never graph JSON.
|
|
88
81
|
|
|
89
82
|
## Scheduler identity
|
|
90
83
|
|
|
91
|
-
`WORKSPACE_OWNER_EMAIL` is
|
|
92
|
-
|
|
93
|
-
enter request authorization or credential resolution.
|
|
84
|
+
`WORKSPACE_OWNER_EMAIL` is startup-only deployment-org and seed identity; never
|
|
85
|
+
use it for request authorization or credential resolution.
|
|
94
86
|
|
|
95
87
|
## Hosting
|
|
96
88
|
|
|
97
89
|
Production needs `DATABASE_URL`, `WORKSPACE_OWNER_EMAIL`, and
|
|
98
|
-
`FACTORY_PUBLIC_URL
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
external writes must remain auditable and fail closed when evidence is partial.
|
|
90
|
+
`FACTORY_PUBLIC_URL`; Builder execution also needs its service URL, project ID,
|
|
91
|
+
and workspace credentials. GitHub/Sentry use workspace credentials. Callbacks
|
|
92
|
+
and external writes stay auditable and fail closed on partial evidence.
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
workspaceMemberIdentityFromContext,
|
|
12
12
|
} from "../server/lib/require-workspace-member.js";
|
|
13
13
|
import { createAiServicesGitReadClient } from "../server/triage/ai-services-git.js";
|
|
14
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
14
15
|
import { createGitHubClient } from "../server/triage/github-client.js";
|
|
15
16
|
import {
|
|
16
17
|
metadataString,
|
|
@@ -140,6 +141,20 @@ export default defineAction({
|
|
|
140
141
|
prBabysitState: "closed-or-draft",
|
|
141
142
|
prBabysitLastCheckedAt: new Date().toISOString(),
|
|
142
143
|
});
|
|
144
|
+
await recordFactoryAudit(
|
|
145
|
+
context,
|
|
146
|
+
{ userEmail, orgId },
|
|
147
|
+
{
|
|
148
|
+
action: "babysit-agent-native-pull-request",
|
|
149
|
+
kind: "governance",
|
|
150
|
+
status: "skipped",
|
|
151
|
+
itemId,
|
|
152
|
+
source: "github",
|
|
153
|
+
sourceUrl: item.sourceUrl,
|
|
154
|
+
summary: "Skipped because the pull request is closed or a draft.",
|
|
155
|
+
details: { state: pullRequest.state, draft: pullRequest.draft },
|
|
156
|
+
},
|
|
157
|
+
);
|
|
143
158
|
return { ok: true, action: "skipped", reason: "PR is closed or draft." };
|
|
144
159
|
}
|
|
145
160
|
|
|
@@ -154,6 +169,20 @@ export default defineAction({
|
|
|
154
169
|
prBabysitOwnerArea: ownerOwnedArea,
|
|
155
170
|
prBabysitLastCheckedAt: new Date().toISOString(),
|
|
156
171
|
});
|
|
172
|
+
await recordFactoryAudit(
|
|
173
|
+
context,
|
|
174
|
+
{ userEmail, orgId },
|
|
175
|
+
{
|
|
176
|
+
action: "babysit-agent-native-pull-request",
|
|
177
|
+
kind: "governance",
|
|
178
|
+
status: "skipped",
|
|
179
|
+
itemId,
|
|
180
|
+
source: "github",
|
|
181
|
+
sourceUrl: item.sourceUrl,
|
|
182
|
+
summary: `${ownerOwnedArea} is owner-managed; no bot feedback was posted.`,
|
|
183
|
+
details: { ownerOwnedArea },
|
|
184
|
+
},
|
|
185
|
+
);
|
|
157
186
|
return {
|
|
158
187
|
ok: true,
|
|
159
188
|
action: "skipped",
|
|
@@ -205,6 +234,30 @@ export default defineAction({
|
|
|
205
234
|
mergeableState: pullRequest.mergeableState,
|
|
206
235
|
snapshot: signal,
|
|
207
236
|
});
|
|
237
|
+
await recordFactoryAudit(
|
|
238
|
+
context,
|
|
239
|
+
{ userEmail, orgId },
|
|
240
|
+
{
|
|
241
|
+
action: "babysit-agent-native-pull-request",
|
|
242
|
+
kind: "governance",
|
|
243
|
+
status: needsBabysit ? "success" : "skipped",
|
|
244
|
+
itemId,
|
|
245
|
+
source: "github",
|
|
246
|
+
sourceUrl: item.sourceUrl,
|
|
247
|
+
summary: needsBabysit
|
|
248
|
+
? "Review feedback, CI, or mergeability needs Builder attention."
|
|
249
|
+
: "The pull request is clean and needs no Builder feedback request.",
|
|
250
|
+
details: {
|
|
251
|
+
headSha: snapshot.headSha,
|
|
252
|
+
checks: snapshot.checks.length,
|
|
253
|
+
comments: snapshot.comments.length,
|
|
254
|
+
unresolvedReviewState,
|
|
255
|
+
mergeable: pullRequest.mergeable,
|
|
256
|
+
mergeableState: pullRequest.mergeableState,
|
|
257
|
+
reviewFeedbackClean: signal.isClean,
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
);
|
|
208
261
|
const now = new Date();
|
|
209
262
|
const nowIso = now.toISOString();
|
|
210
263
|
const metadata = parseTriageMetadata(item.metadataJson);
|
|
@@ -261,6 +314,19 @@ export default defineAction({
|
|
|
261
314
|
item.pullRequestNumber,
|
|
262
315
|
BUILDER_BOT_REQUEST,
|
|
263
316
|
);
|
|
317
|
+
await recordFactoryAudit(
|
|
318
|
+
context,
|
|
319
|
+
{ userEmail, orgId },
|
|
320
|
+
{
|
|
321
|
+
action: "babysit-agent-native-pull-request",
|
|
322
|
+
kind: "external_action",
|
|
323
|
+
itemId,
|
|
324
|
+
source: "github",
|
|
325
|
+
sourceUrl: comment.htmlUrl,
|
|
326
|
+
summary: "Posted the bounded feedback-fix request to builder-io-bot.",
|
|
327
|
+
details: { commentUrl: comment.htmlUrl, quietForMinutes: 0 },
|
|
328
|
+
},
|
|
329
|
+
);
|
|
264
330
|
await updateBabysitMetadata(itemId, orgId, {
|
|
265
331
|
prBabysitState: "active",
|
|
266
332
|
prBabysitFingerprint: fingerprint,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
requireWorkspaceMember,
|
|
16
16
|
workspaceMemberIdentityFromContext,
|
|
17
17
|
} from "../server/lib/require-workspace-member.js";
|
|
18
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
18
19
|
import {
|
|
19
20
|
normalizeTriagePolicyGuards,
|
|
20
21
|
triageGuardCodeSchema,
|
|
@@ -70,6 +71,20 @@ export default defineAction({
|
|
|
70
71
|
: `Observed failure taxonomy: ${failureTaxonomy.label} (${failureTaxonomy.code}; ${failureTaxonomy.regime}). `;
|
|
71
72
|
|
|
72
73
|
if (rules.length === 0) {
|
|
74
|
+
await recordFactoryAudit(
|
|
75
|
+
context,
|
|
76
|
+
{ userEmail, orgId },
|
|
77
|
+
{
|
|
78
|
+
action: "evaluate-triage-item",
|
|
79
|
+
kind: "decision",
|
|
80
|
+
status: "skipped",
|
|
81
|
+
itemId,
|
|
82
|
+
source: item.source,
|
|
83
|
+
sourceUrl: item.sourceUrl,
|
|
84
|
+
summary: "No enabled shadow rules were available for this item.",
|
|
85
|
+
details: { evaluated: 0 },
|
|
86
|
+
},
|
|
87
|
+
);
|
|
73
88
|
return {
|
|
74
89
|
ok: true,
|
|
75
90
|
itemId,
|
|
@@ -119,6 +134,28 @@ export default defineAction({
|
|
|
119
134
|
.where(and(eq(triageItems.id, itemId), eq(triageItems.orgId, orgId)));
|
|
120
135
|
});
|
|
121
136
|
|
|
137
|
+
for (const decision of decisions) {
|
|
138
|
+
await recordFactoryAudit(
|
|
139
|
+
context,
|
|
140
|
+
{ userEmail, orgId },
|
|
141
|
+
{
|
|
142
|
+
action: "evaluate-triage-item",
|
|
143
|
+
kind: "decision",
|
|
144
|
+
itemId,
|
|
145
|
+
source: item.source,
|
|
146
|
+
sourceUrl: item.sourceUrl,
|
|
147
|
+
summary: decision.reason,
|
|
148
|
+
details: {
|
|
149
|
+
decisionId: decision.id,
|
|
150
|
+
outcome: decision.outcome,
|
|
151
|
+
ruleId: decision.ruleId,
|
|
152
|
+
mode: decision.mode,
|
|
153
|
+
promptVersion: decision.promptVersion,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
122
159
|
return {
|
|
123
160
|
ok: true,
|
|
124
161
|
itemId,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
requireWorkspaceMember,
|
|
10
10
|
workspaceMemberIdentityFromContext,
|
|
11
11
|
} from "../server/lib/require-workspace-member.js";
|
|
12
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
12
13
|
import { createSlackReader } from "../server/triage/slack-client.js";
|
|
13
14
|
|
|
14
15
|
const MAX_THREAD_PAGES = 5;
|
|
@@ -71,6 +72,25 @@ export default defineAction({
|
|
|
71
72
|
cursor = result.next_cursor;
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
await recordFactoryAudit(
|
|
76
|
+
context,
|
|
77
|
+
{ userEmail, orgId },
|
|
78
|
+
{
|
|
79
|
+
action: "get-slack-feedback-context",
|
|
80
|
+
kind: "read",
|
|
81
|
+
itemId,
|
|
82
|
+
source: "slack",
|
|
83
|
+
sourceUrl: item.sourceUrl,
|
|
84
|
+
summary: `Read the Slack thread (${messages.length} message${messages.length === 1 ? "" : "s"}).`,
|
|
85
|
+
details: {
|
|
86
|
+
channelId: item.channelId,
|
|
87
|
+
threadTs: item.threadTs,
|
|
88
|
+
coverage: hasMore ? "partial" : "complete",
|
|
89
|
+
messageCount: messages.length,
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
74
94
|
return {
|
|
75
95
|
ok: true,
|
|
76
96
|
itemId,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
requireWorkspaceMember,
|
|
14
14
|
workspaceMemberIdentityFromContext,
|
|
15
15
|
} from "../server/lib/require-workspace-member.js";
|
|
16
|
+
import { recordFactoryAudit } from "../server/triage/audit.js";
|
|
16
17
|
|
|
17
18
|
export default defineAction({
|
|
18
19
|
description:
|
|
@@ -21,7 +22,7 @@ export default defineAction({
|
|
|
21
22
|
http: { method: "GET" },
|
|
22
23
|
readOnly: true,
|
|
23
24
|
run: async ({ itemId }, context) => {
|
|
24
|
-
const { orgId } = await requireWorkspaceMember(
|
|
25
|
+
const { userEmail, orgId } = await requireWorkspaceMember(
|
|
25
26
|
workspaceMemberIdentityFromContext(context),
|
|
26
27
|
);
|
|
27
28
|
const db = getDb();
|
|
@@ -55,6 +56,28 @@ export default defineAction({
|
|
|
55
56
|
.where(and(eq(triageRuns.itemId, itemId), eq(triageRuns.orgId, orgId)))
|
|
56
57
|
.orderBy(asc(triageRuns.startedAt));
|
|
57
58
|
|
|
59
|
+
const matchingFeedback = feedback.filter((entry) =>
|
|
60
|
+
decisions.some((decision) => decision.id === entry.decisionId),
|
|
61
|
+
);
|
|
62
|
+
await recordFactoryAudit(
|
|
63
|
+
context,
|
|
64
|
+
{ userEmail, orgId },
|
|
65
|
+
{
|
|
66
|
+
action: "get-triage-item",
|
|
67
|
+
kind: "read",
|
|
68
|
+
itemId,
|
|
69
|
+
source: item.source,
|
|
70
|
+
sourceUrl: item.sourceUrl,
|
|
71
|
+
summary: `Inspected ${item.title}`,
|
|
72
|
+
details: {
|
|
73
|
+
decisionCount: decisions.length,
|
|
74
|
+
feedbackCount: matchingFeedback.length,
|
|
75
|
+
runCount: runs.length,
|
|
76
|
+
coverage: item.coverage,
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
58
81
|
return {
|
|
59
82
|
...item,
|
|
60
83
|
decisions: decisions.map((decision) => ({
|
|
@@ -65,9 +88,7 @@ export default defineAction({
|
|
|
65
88
|
mode: decision.mode,
|
|
66
89
|
createdAt: decision.createdAt,
|
|
67
90
|
})),
|
|
68
|
-
feedback:
|
|
69
|
-
decisions.some((decision) => decision.id === entry.decisionId),
|
|
70
|
-
),
|
|
91
|
+
feedback: matchingFeedback,
|
|
71
92
|
runs,
|
|
72
93
|
};
|
|
73
94
|
},
|