@agent-native/core 0.165.4 → 0.167.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/secrets/SKILL.md +5 -1
- package/corpus/templates/analytics/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +93 -56
- package/corpus/templates/analytics/app/i18n-data.ts +23 -20
- package/corpus/templates/analytics/app/pages/Settings.tsx +0 -1
- package/corpus/templates/analytics/app/pages/adhoc/explorer/index.tsx +0 -1
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +2 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -1
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +0 -32
- package/corpus/templates/analytics/server/lib/session-replay.ts +1 -5
- package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/assets/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/assets/actions/navigate.ts +2 -2
- package/corpus/templates/assets/actions/save-generated-image.ts +0 -5
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -262
- package/corpus/templates/assets/app/routes/library.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.tsx +0 -3
- package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/brain/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/brain/actions/ask-brain.ts +0 -1
- package/corpus/templates/brain/actions/navigate.ts +2 -2
- package/corpus/templates/brain/app/routes/sources.tsx +0 -4
- package/corpus/templates/brain/server/lib/capture-sanitization.ts +0 -11
- package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/calendar/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +0 -20
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +0 -1
- package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/chat/actions/navigate.ts +2 -2
- package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/clips/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/clips/CHANGELOG.md +1 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +16 -4
- package/corpus/templates/clips/actions/navigate.ts +2 -2
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +0 -1
- package/corpus/templates/clips/app/components/library/space-dialogs.tsx +0 -1
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +0 -1
- package/corpus/templates/clips/app/components/player/clips-share-trigger.tsx +17 -0
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +3 -3
- package/corpus/templates/clips/app/components/player/video-player.tsx +2 -2
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +0 -1
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +0 -1
- package/corpus/templates/clips/app/global.css +31 -0
- package/corpus/templates/clips/app/hooks/use-playback-position.ts +0 -2
- package/corpus/templates/clips/app/lib/download-release-channel.ts +10 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +1 -3
- package/corpus/templates/clips/app/routes/download.tsx +67 -44
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +7 -12
- package/corpus/templates/clips/app/routes/record.tsx +6 -6
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +26 -29
- package/corpus/templates/clips/changelog/2026-08-20-clip-viewer-share-actions.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-20-preparing-recording-countdown-overlay.md +1 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +0 -13
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +0 -1
- package/corpus/templates/clips/chrome-extension/src/popup.ts +0 -20
- package/corpus/templates/clips/desktop/src/app.tsx +6 -18
- package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +0 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +0 -8
- package/corpus/templates/content/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/content/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/content/actions/_database-source-utils.ts +0 -3
- package/corpus/templates/content/actions/attach-content-database-source.ts +1 -4
- package/corpus/templates/content/actions/navigate.ts +2 -2
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +1 -1
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +0 -6
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +0 -580
- package/corpus/templates/content/app/components/editor/database/FormView.tsx +2 -2
- package/corpus/templates/content/app/components/editor/database/filter-sort.ts +1 -1
- package/corpus/templates/content/app/components/editor/database/settings.tsx +0 -23
- package/corpus/templates/content/app/components/editor/database/sidebar.tsx +0 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +8 -304
- package/corpus/templates/content/app/hooks/use-documents.ts +0 -1
- package/corpus/templates/content/shared/api.ts +0 -1
- package/corpus/templates/content/shared/builder-mdx.ts +0 -1
- package/corpus/templates/content/shared/nfm.ts +1 -7
- package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/crm/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/crm/actions/merge-crm-records.ts +0 -4
- package/corpus/templates/crm/app/components/crm/record/RecordLists.tsx +0 -1
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +0 -1
- package/corpus/templates/crm/server/crm/salesforce-adapter.ts +0 -1
- package/corpus/templates/crm/server/db/crm-store.ts +1 -1
- package/corpus/templates/design/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/design/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1 -14
- package/corpus/templates/design/AGENTS.md +2 -1
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +1 -5
- package/corpus/templates/design/actions/generate-design.ts +0 -1
- package/corpus/templates/design/actions/generate-screens.ts +5 -2
- package/corpus/templates/design/actions/go-to-main-component.ts +2 -2
- package/corpus/templates/design/actions/list-design-systems.ts +10 -0
- package/corpus/templates/design/actions/navigate.ts +2 -2
- package/corpus/templates/design/actions/open-component-source.ts +4 -4
- package/corpus/templates/design/actions/present-design-variants.ts +1 -2
- package/corpus/templates/design/actions/run-design-audit.ts +0 -22
- package/corpus/templates/design/actions/show-design-questions.ts +5 -2
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +19 -8
- package/corpus/templates/design/app/components/design/EditPanel.tsx +11 -183
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +21 -4
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +1 -5
- package/corpus/templates/design/app/components/design/bridge/codegen.ts +1 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +10 -19
- package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +1 -1
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +13 -3
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +38 -32
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +1 -4
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +0 -4
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +15 -6
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +2 -2
- package/corpus/templates/design/app/components/visual-editor/NodeRewriteProposal.tsx +0 -1
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +1 -1
- package/corpus/templates/design/app/i18n-data.ts +122 -0
- package/corpus/templates/design/app/lib/clipboard-content-lineage.ts +11 -1
- package/corpus/templates/design/app/pages/DesignEditor.tsx +50 -254
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +163 -8
- package/corpus/templates/design/app/pages/Index.tsx +17 -0
- package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +44 -32
- package/corpus/templates/design/app/pages/design-editor/canvas-primitives.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +49 -3
- package/corpus/templates/design/app/pages/design-editor/clone-idrefs.ts +31 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +28 -0
- package/corpus/templates/design/app/pages/design-editor/commands/add-auto-layout.ts +3 -3
- package/corpus/templates/design/app/pages/design-editor/commands/align-selection.ts +44 -14
- package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +16 -5
- package/corpus/templates/design/app/pages/design-editor/commands/change-selected-z-index.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/frame-selection.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/group-selection.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/nudge-selection.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/paste-selection.ts +142 -17
- package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +1 -0
- package/corpus/templates/design/app/pages/design-editor/commands/ungroup-selection.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +1 -0
- package/corpus/templates/design/app/pages/design-editor/cross-screen-text-color.ts +25 -9
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +1 -0
- package/corpus/templates/design/app/pages/design-editor/measure-child-rects.ts +83 -0
- package/corpus/templates/design/app/pages/design-editor/paste-placement.ts +66 -0
- package/corpus/templates/design/server/routes/[...page].get.ts +0 -1
- package/corpus/templates/design/shared/code-layer.ts +120 -70
- package/corpus/templates/design/shared/design-surface-index.ts +0 -1
- package/corpus/templates/design/shared/pen-path.ts +0 -4
- package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/dispatch/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/dispatch/app/routes/integrations.tsx +0 -109
- package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/factory/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/factory/actions/navigate.ts +2 -2
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +0 -13
- package/corpus/templates/factory/app/routes/factory.tsx +0 -1
- package/corpus/templates/factory/server/factory-graph/store.ts +0 -1
- package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/forms/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/macros/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -1
- package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/mail/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/mail/app/components/email/EmailList.tsx +0 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/mail/shared/markdown.ts +3 -0
- package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/plan/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/slides/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/slides/actions/add-slide.ts +0 -1
- package/corpus/templates/slides/actions/list-decks.ts +1 -1
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +1 -4
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +0 -1
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -6
- package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +5 -1
- package/corpus/templates/tasks/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/corpus/templates/tasks/app/components/layout/Layout.tsx +0 -1
- package/corpus/templates/tasks/app/hooks/use-visible-task-fields.ts +1 -4
- package/corpus/templates/tasks/server/custom-fields/store.ts +1 -6
- package/corpus/templates/tasks/shared/list-screen-snapshot.ts +2 -2
- package/dist/agent/engine/registry.js +27 -14
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/production-agent.d.ts +19 -6
- package/dist/agent/production-agent.js +57 -16
- package/dist/agent/types.d.ts +3 -0
- package/dist/client/EnvironmentBadge.d.ts +1 -0
- package/dist/client/EnvironmentBadge.js +7 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.js +248 -0
- package/dist/deploy/build.js +12 -1
- package/dist/index.d.ts +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +2 -2
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/server/agent-chat/plugin-options.d.ts +3 -2
- package/dist/server/agent-chat-plugin.js +5 -2
- package/dist/server/index.d.ts +1 -1
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
- package/dist/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/dist/templates/chat/actions/navigate.ts +2 -2
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +5 -1
- package/dist/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
- package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/dist/vite/agent-native-config-loader.d.ts +1 -0
- package/dist/vite/agent-native-config-loader.js +3 -3
- package/dist/vite/agents-bundle-plugin.d.ts +1 -1
- package/dist/vite/agents-bundle-plugin.js +13 -1
- package/dist/vite/client.js +14 -14
- package/docs/content/agent-native-config.mdx +62 -11
- package/docs/content/agent-surfaces.mdx +6 -0
- package/docs/content/environment-variables.mdx +5 -2
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +5 -1
- package/src/templates/chat/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/src/templates/chat/actions/navigate.ts +2 -2
- package/src/templates/default/.agents/skills/secrets/SKILL.md +5 -1
- package/src/templates/default/.agents/skills/workspace-conventions/SKILL.md +4 -1
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +5 -1
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +5 -1
- package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export interface FreeformGeometry {
|
|
2
|
+
container: { width: number; height: number } | null;
|
|
3
|
+
children: Record<
|
|
4
|
+
string,
|
|
5
|
+
{ x: number; y: number; width: number; height: number }
|
|
6
|
+
>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const NOTHING_MEASURED: FreeformGeometry = { container: null, children: {} };
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Container-relative geometry for a node and its direct children, read from
|
|
13
|
+
* whichever preview iframe actually holds the node — the board and each screen
|
|
14
|
+
* have their own document, so a single global iframe lookup finds the wrong one.
|
|
15
|
+
*/
|
|
16
|
+
export function measureFreeformGeometry(nodeId: string): FreeformGeometry {
|
|
17
|
+
if (typeof document === "undefined") return NOTHING_MEASURED;
|
|
18
|
+
const selector = `[data-agent-native-node-id="${CSS.escape(nodeId)}"]`;
|
|
19
|
+
const iframes = Array.from(
|
|
20
|
+
document.querySelectorAll<HTMLIFrameElement>(
|
|
21
|
+
"iframe[data-design-preview-iframe],iframe[data-screen-iframe-id]",
|
|
22
|
+
),
|
|
23
|
+
);
|
|
24
|
+
for (const iframe of iframes) {
|
|
25
|
+
let container: HTMLElement | null = null;
|
|
26
|
+
try {
|
|
27
|
+
container =
|
|
28
|
+
iframe.contentDocument?.querySelector<HTMLElement>(selector) ?? null;
|
|
29
|
+
} catch {
|
|
30
|
+
// Cross-origin preview surfaces are not measurable; try the next one.
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!container) continue;
|
|
34
|
+
const view = container.ownerDocument.defaultView;
|
|
35
|
+
const origin = container.getBoundingClientRect();
|
|
36
|
+
// Absolute offsets resolve against the padding box, but a client rect is
|
|
37
|
+
// the border box, so a bordered container shifts every child it pins.
|
|
38
|
+
const borders = view?.getComputedStyle(container);
|
|
39
|
+
// Client rects are viewport-relative, so a scrolled container reports its
|
|
40
|
+
// children where they currently sit, not where the content box holds them.
|
|
41
|
+
const originLeft =
|
|
42
|
+
origin.left + edgeWidth(borders?.borderLeftWidth) - container.scrollLeft;
|
|
43
|
+
const originTop =
|
|
44
|
+
origin.top + edgeWidth(borders?.borderTopWidth) - container.scrollTop;
|
|
45
|
+
const rects: Record<
|
|
46
|
+
string,
|
|
47
|
+
{ x: number; y: number; width: number; height: number }
|
|
48
|
+
> = {};
|
|
49
|
+
for (const child of Array.from(container.children)) {
|
|
50
|
+
const childId = child.getAttribute("data-agent-native-node-id");
|
|
51
|
+
if (!childId) continue;
|
|
52
|
+
const rect = child.getBoundingClientRect();
|
|
53
|
+
rects[childId] = {
|
|
54
|
+
x: rect.left - originLeft,
|
|
55
|
+
y: rect.top - originTop,
|
|
56
|
+
width: rect.width,
|
|
57
|
+
height: rect.height,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Own box, in the same box-sizing terms as a width/height declaration on
|
|
61
|
+
// this element, so writing it back reproduces the rendered size.
|
|
62
|
+
const own = borders
|
|
63
|
+
? {
|
|
64
|
+
width: Number.parseFloat(borders.width),
|
|
65
|
+
height: Number.parseFloat(borders.height),
|
|
66
|
+
}
|
|
67
|
+
: null;
|
|
68
|
+
return {
|
|
69
|
+
container:
|
|
70
|
+
own && Number.isFinite(own.width) && Number.isFinite(own.height)
|
|
71
|
+
? own
|
|
72
|
+
: null,
|
|
73
|
+
children: rects,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return NOTHING_MEASURED;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function edgeWidth(value: string | undefined): number {
|
|
80
|
+
const parsed = Number.parseFloat(value ?? "");
|
|
81
|
+
// A missing or non-length border computes to no edge; both mean zero inset.
|
|
82
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
83
|
+
}
|
|
@@ -131,3 +131,69 @@ export function resolvePastePlacementForSelection(args: {
|
|
|
131
131
|
if (!node) return null;
|
|
132
132
|
return resolvePastePlacement(pasteTargetFromCodeLayerNode(node));
|
|
133
133
|
}
|
|
134
|
+
|
|
135
|
+
export interface PasteSourceAnchor {
|
|
136
|
+
fileId: string;
|
|
137
|
+
/**
|
|
138
|
+
* null when the entries do not share one resolvable parent. Never an empty
|
|
139
|
+
* array — a caller must not read "unresolved" as "insert at the root here",
|
|
140
|
+
* because the stored left/top are relative to a parent that is not there.
|
|
141
|
+
*/
|
|
142
|
+
parentSelectors: string[] | null;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A copied layer's left/top are parent-relative, so a paste that lands
|
|
147
|
+
* anywhere else reads them in the wrong coordinate space. Null means the
|
|
148
|
+
* source is unknown — never "the document root".
|
|
149
|
+
*/
|
|
150
|
+
export function resolvePasteSourceAnchor(args: {
|
|
151
|
+
entries: ReadonlyArray<{ rootNodeId?: string; sourceFileId: string }>;
|
|
152
|
+
getContent: (fileId: string) => string | undefined;
|
|
153
|
+
}): PasteSourceAnchor | null {
|
|
154
|
+
const first = args.entries[0];
|
|
155
|
+
if (!first) return null;
|
|
156
|
+
if (args.entries.some((entry) => entry.sourceFileId !== first.sourceFileId)) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
const content = args.getContent(first.sourceFileId);
|
|
160
|
+
if (!content) return null;
|
|
161
|
+
const projection = buildCodeLayerProjection(content);
|
|
162
|
+
const unresolved: PasteSourceAnchor = {
|
|
163
|
+
fileId: first.sourceFileId,
|
|
164
|
+
parentSelectors: null,
|
|
165
|
+
};
|
|
166
|
+
const parentIds = args.entries.map((entry) => {
|
|
167
|
+
const node = entry.rootNodeId
|
|
168
|
+
? projection.nodes.find(
|
|
169
|
+
(candidate) =>
|
|
170
|
+
candidate.dataAttributes["data-agent-native-node-id"] ===
|
|
171
|
+
entry.rootNodeId || candidate.id === entry.rootNodeId,
|
|
172
|
+
)
|
|
173
|
+
: undefined;
|
|
174
|
+
return node?.parentId ?? null;
|
|
175
|
+
});
|
|
176
|
+
const [sharedParentId] = parentIds;
|
|
177
|
+
// Layers copied out of different parents have no common coordinate space, so
|
|
178
|
+
// forcing them into the first one's parent moves the rest.
|
|
179
|
+
if (!sharedParentId || parentIds.some((id) => id !== sharedParentId)) {
|
|
180
|
+
return unresolved;
|
|
181
|
+
}
|
|
182
|
+
const parent = projection.nodes.find(
|
|
183
|
+
(candidate) => candidate.id === sharedParentId,
|
|
184
|
+
);
|
|
185
|
+
if (!parent) return unresolved;
|
|
186
|
+
const parentNodeId = parent.dataAttributes["data-agent-native-node-id"];
|
|
187
|
+
const parentSelectors = [
|
|
188
|
+
// A node-id selector is unique by construction; the projection's
|
|
189
|
+
// class/path aliases can match several siblings, and
|
|
190
|
+
// insertClonedHtmlLayers fails closed on that ambiguity.
|
|
191
|
+
parentNodeId
|
|
192
|
+
? `[data-agent-native-node-id="${parentNodeId.replace(/["\\]/g, "\\$&")}"]`
|
|
193
|
+
: null,
|
|
194
|
+
parent.selector,
|
|
195
|
+
...parent.selectors,
|
|
196
|
+
].filter((selector): selector is string => Boolean(selector));
|
|
197
|
+
if (parentSelectors.length === 0) return unresolved;
|
|
198
|
+
return { fileId: first.sourceFileId, parentSelectors };
|
|
199
|
+
}
|
|
@@ -498,6 +498,17 @@ export interface AutoLayoutEditIntent {
|
|
|
498
498
|
enabled: boolean;
|
|
499
499
|
direction?: "row" | "column";
|
|
500
500
|
gap?: string;
|
|
501
|
+
/**
|
|
502
|
+
* Measured child geometry, container-relative, keyed by stable node id.
|
|
503
|
+
* Supplied when disabling so children keep their rendered positions and
|
|
504
|
+
* become freely draggable; without it they re-stack in block flow.
|
|
505
|
+
*/
|
|
506
|
+
childRects?: Record<
|
|
507
|
+
string,
|
|
508
|
+
{ x: number; y: number; width: number; height: number }
|
|
509
|
+
>;
|
|
510
|
+
/** Rendered size of the container, so it cannot collapse once flow empties. */
|
|
511
|
+
containerRect?: { width: number; height: number };
|
|
501
512
|
}
|
|
502
513
|
|
|
503
514
|
/**
|
|
@@ -950,17 +961,6 @@ function cssIdent(value: string): string | null {
|
|
|
950
961
|
return null;
|
|
951
962
|
}
|
|
952
963
|
|
|
953
|
-
function unquoteHtmlAttributeValue(value: string): string {
|
|
954
|
-
const trimmed = value.trim();
|
|
955
|
-
if (
|
|
956
|
-
(trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
957
|
-
(trimmed.startsWith("'") && trimmed.endsWith("'"))
|
|
958
|
-
) {
|
|
959
|
-
return trimmed.slice(1, -1);
|
|
960
|
-
}
|
|
961
|
-
return trimmed;
|
|
962
|
-
}
|
|
963
|
-
|
|
964
964
|
function escapeHtmlAttribute(value: string): string {
|
|
965
965
|
return value
|
|
966
966
|
.replace(/&/g, "&")
|
|
@@ -1777,18 +1777,6 @@ function utilityToStyleProperty(
|
|
|
1777
1777
|
return null;
|
|
1778
1778
|
}
|
|
1779
1779
|
|
|
1780
|
-
function classStyleToken(token: string): StyleToken | null {
|
|
1781
|
-
const { utility } = parseClassToken(token);
|
|
1782
|
-
const mapped = utilityToStyleProperty(utility);
|
|
1783
|
-
if (!mapped) return null;
|
|
1784
|
-
const { property, confidence } = mapped;
|
|
1785
|
-
// The legacy value field preserves the original full token (including prefix)
|
|
1786
|
-
// for backward compatibility. The responsive path uses `breakpointValues`.
|
|
1787
|
-
const value =
|
|
1788
|
-
property === "display" ? (utility === "hidden" ? "none" : utility) : token;
|
|
1789
|
-
return { property, value, token, source: "class", confidence };
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
1780
|
function layoutFor(
|
|
1793
1781
|
element: ParsedElement,
|
|
1794
1782
|
parent: ParsedElement | undefined,
|
|
@@ -3385,43 +3373,6 @@ const FLEX_ITEM_STRIP_PROPS = [
|
|
|
3385
3373
|
"order",
|
|
3386
3374
|
] as const;
|
|
3387
3375
|
|
|
3388
|
-
/**
|
|
3389
|
-
* Apply display:flex + direction + gap to a raw open-tag string and return it.
|
|
3390
|
-
* Only touches the style attribute.
|
|
3391
|
-
*/
|
|
3392
|
-
function addAutoLayoutStyleToOpenTag(
|
|
3393
|
-
openTag: string,
|
|
3394
|
-
element: ParsedElement,
|
|
3395
|
-
html: string,
|
|
3396
|
-
direction: "row" | "column",
|
|
3397
|
-
gap: string,
|
|
3398
|
-
): string {
|
|
3399
|
-
const currentStyle = attributeValue(element, "style");
|
|
3400
|
-
let declarations = parseStyleDeclarations(currentStyle);
|
|
3401
|
-
const setOrReplace = (prop: string, val: string) => {
|
|
3402
|
-
const existing = declarations.find((d) => d.property === prop);
|
|
3403
|
-
if (existing) {
|
|
3404
|
-
existing.value = val;
|
|
3405
|
-
} else {
|
|
3406
|
-
declarations.push({ property: prop, value: val });
|
|
3407
|
-
}
|
|
3408
|
-
};
|
|
3409
|
-
setOrReplace("display", "flex");
|
|
3410
|
-
setOrReplace("flex-direction", direction);
|
|
3411
|
-
setOrReplace("gap", gap);
|
|
3412
|
-
const nextStyle = serializeStyleDeclarations(declarations);
|
|
3413
|
-
// We work on a scratch copy relative to element boundaries
|
|
3414
|
-
const attr = getAttribute(element, "style");
|
|
3415
|
-
if (attr) {
|
|
3416
|
-
return `${openTag.slice(0, attr.start - element.start)}${attr.name}="${escapeHtmlAttribute(nextStyle)}"${openTag.slice(attr.end - element.start)}`;
|
|
3417
|
-
}
|
|
3418
|
-
// Insert before closing >
|
|
3419
|
-
const closeChar = openTag.endsWith("/>")
|
|
3420
|
-
? openTag.length - 2
|
|
3421
|
-
: openTag.length - 1;
|
|
3422
|
-
return `${openTag.slice(0, closeChar)} style="${escapeHtmlAttribute(nextStyle)}"${openTag.slice(closeChar)}`;
|
|
3423
|
-
}
|
|
3424
|
-
|
|
3425
3376
|
/**
|
|
3426
3377
|
* Strip absolute-positioning properties from a child's inline style, applying
|
|
3427
3378
|
* the edit directly to the html string at the child element's source spans.
|
|
@@ -3889,6 +3840,13 @@ function applyUnwrap(
|
|
|
3889
3840
|
/**
|
|
3890
3841
|
* CONVERT: toggle auto-layout (display:flex) on an existing container.
|
|
3891
3842
|
*/
|
|
3843
|
+
/** Whether an existing min-width/min-height already preserves `extent` px. */
|
|
3844
|
+
function holdsOpen(value: string, extent: number): boolean {
|
|
3845
|
+
const trimmed = value.trim();
|
|
3846
|
+
if (!/^[\d.]+px$/i.test(trimmed)) return !/^0[a-z%]*$/i.test(trimmed);
|
|
3847
|
+
return Number.parseFloat(trimmed) >= extent;
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3892
3850
|
function applyAutoLayout(
|
|
3893
3851
|
html: string,
|
|
3894
3852
|
build: ProjectionBuild,
|
|
@@ -3907,21 +3865,113 @@ function applyAutoLayout(
|
|
|
3907
3865
|
if (!element) return "conflict";
|
|
3908
3866
|
|
|
3909
3867
|
if (!enabled) {
|
|
3910
|
-
|
|
3868
|
+
const childRects = intent.childRects;
|
|
3869
|
+
const hasRects = !!childRects && Object.keys(childRects).length > 0;
|
|
3911
3870
|
const currentStyle = attributeValue(element, "style");
|
|
3912
|
-
|
|
3913
|
-
const
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3871
|
+
const declarations = parseStyleDeclarations(currentStyle);
|
|
3872
|
+
const setOnContainer = (property: string, value: string) => {
|
|
3873
|
+
const existing = declarations.find((d) => d.property === property);
|
|
3874
|
+
if (existing) existing.value = value;
|
|
3875
|
+
else declarations.push({ property, value });
|
|
3876
|
+
};
|
|
3877
|
+
setOnContainer("display", "block");
|
|
3878
|
+
if (hasRects) {
|
|
3879
|
+
// Absolute children resolve against the nearest positioned ancestor, so
|
|
3880
|
+
// a static container would let them escape to the page.
|
|
3881
|
+
const position = declarations.find((d) => d.property === "position");
|
|
3882
|
+
if (!position || position.value === "static") {
|
|
3883
|
+
setOnContainer("position", "relative");
|
|
3884
|
+
}
|
|
3885
|
+
// With every child absolute the content box is empty, so a hug-sized
|
|
3886
|
+
// container collapses and overflow:hidden then hides what we just pinned.
|
|
3887
|
+
const rect = intent.containerRect;
|
|
3888
|
+
if (rect) {
|
|
3889
|
+
for (const [property, value] of [
|
|
3890
|
+
["min-width", rect.width],
|
|
3891
|
+
["min-height", rect.height],
|
|
3892
|
+
] as const) {
|
|
3893
|
+
const existing = declarations.find((d) => d.property === property);
|
|
3894
|
+
// `min-height: 0` is the standard flex idiom and holds nothing open.
|
|
3895
|
+
// Only a px minimum at least as large as the measured extent does.
|
|
3896
|
+
if (existing && !holdsOpen(existing.value, value)) {
|
|
3897
|
+
existing.value = `${Math.round(value)}px`;
|
|
3898
|
+
} else if (!existing) {
|
|
3899
|
+
declarations.push({ property, value: `${Math.round(value)}px` });
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
}
|
|
3904
|
+
let result = replaceOrInsertAttribute(
|
|
3905
|
+
html,
|
|
3906
|
+
element,
|
|
3907
|
+
"style",
|
|
3908
|
+
serializeStyleDeclarations(declarations),
|
|
3909
|
+
);
|
|
3910
|
+
if (!hasRects) {
|
|
3911
|
+
return {
|
|
3912
|
+
content: result,
|
|
3913
|
+
capability: { kind: "style", properties: ["display"], confidence: 0.9 },
|
|
3914
|
+
};
|
|
3915
|
+
}
|
|
3916
|
+
|
|
3917
|
+
const updatedElements = parseHtmlElements(result);
|
|
3918
|
+
const targetAttr = attributeValue(element, "data-agent-native-node-id");
|
|
3919
|
+
const updatedTarget =
|
|
3920
|
+
(targetAttr
|
|
3921
|
+
? updatedElements.find(
|
|
3922
|
+
(fe) =>
|
|
3923
|
+
attributeValue(fe, "data-agent-native-node-id") === targetAttr,
|
|
3924
|
+
)
|
|
3925
|
+
: undefined) ??
|
|
3926
|
+
updatedElements.find((fe) => fe.start === element.start);
|
|
3927
|
+
if (updatedTarget) {
|
|
3928
|
+
// Reverse order keeps earlier offsets valid as each write shifts the rest.
|
|
3929
|
+
for (const childIndex of [...updatedTarget.childIndexes].reverse()) {
|
|
3930
|
+
const child = updatedElements[childIndex];
|
|
3931
|
+
if (!child) continue;
|
|
3932
|
+
const childId = attributeValue(child, "data-agent-native-node-id");
|
|
3933
|
+
const rect = childId ? childRects[childId] : undefined;
|
|
3934
|
+
if (!rect) continue;
|
|
3935
|
+
const childDecls = parseStyleDeclarations(
|
|
3936
|
+
attributeValue(child, "style"),
|
|
3937
|
+
);
|
|
3938
|
+
const setOnChild = (property: string, value: string) => {
|
|
3939
|
+
const existing = childDecls.find((d) => d.property === property);
|
|
3940
|
+
if (existing) existing.value = value;
|
|
3941
|
+
else childDecls.push({ property, value });
|
|
3942
|
+
};
|
|
3943
|
+
// The measured rect is a border box placed by its margin edge, so a
|
|
3944
|
+
// content-box child would grow by its padding and a margin would shift
|
|
3945
|
+
// it off the position we just measured.
|
|
3946
|
+
setOnChild("box-sizing", "border-box");
|
|
3947
|
+
setOnChild("margin", "0");
|
|
3948
|
+
setOnChild("position", "absolute");
|
|
3949
|
+
setOnChild("left", `${Math.round(rect.x)}px`);
|
|
3950
|
+
setOnChild("top", `${Math.round(rect.y)}px`);
|
|
3951
|
+
setOnChild("width", `${Math.round(rect.width)}px`);
|
|
3952
|
+
setOnChild("height", `${Math.round(rect.height)}px`);
|
|
3953
|
+
result = replaceOrInsertAttribute(
|
|
3954
|
+
result,
|
|
3955
|
+
child,
|
|
3956
|
+
"style",
|
|
3957
|
+
serializeStyleDeclarations(childDecls),
|
|
3958
|
+
);
|
|
3959
|
+
}
|
|
3918
3960
|
}
|
|
3919
|
-
const nextStyle = serializeStyleDeclarations(declarations);
|
|
3920
3961
|
return {
|
|
3921
|
-
content:
|
|
3962
|
+
content: result,
|
|
3922
3963
|
capability: {
|
|
3923
3964
|
kind: "style",
|
|
3924
|
-
properties: [
|
|
3965
|
+
properties: [
|
|
3966
|
+
"display",
|
|
3967
|
+
"position",
|
|
3968
|
+
"min-width",
|
|
3969
|
+
"min-height",
|
|
3970
|
+
"left",
|
|
3971
|
+
"top",
|
|
3972
|
+
"width",
|
|
3973
|
+
"height",
|
|
3974
|
+
],
|
|
3925
3975
|
confidence: 0.9,
|
|
3926
3976
|
},
|
|
3927
3977
|
};
|
|
@@ -38,7 +38,11 @@ connection exists:
|
|
|
38
38
|
register a `kind: "oauth"` entry so the shared UI renders Connect and the
|
|
39
39
|
runtime owns status, refresh, and reauthorization.
|
|
40
40
|
- **Deploy- or app-level configuration** - use deployment/runtime
|
|
41
|
-
configuration, not a per-user secret row.
|
|
41
|
+
configuration, not a per-user secret row. For a non-secret public setting
|
|
42
|
+
already represented by `AgentNativeConfig`, put the default in
|
|
43
|
+
`agent-native.config.ts` and use its `AGENT_NATIVE_CONFIG_<PATH>` alias only
|
|
44
|
+
for a deployment override. Never put a credential or provider key in that
|
|
45
|
+
public namespace.
|
|
42
46
|
- **Account, customer, manager, or other non-secret identifier** - store it as
|
|
43
47
|
scoped connection metadata or app data, not as a masked secret field.
|
|
44
48
|
|
|
@@ -55,7 +55,10 @@ Preview before `--apply`, commit `agent-native.ejections.json`, and never edit
|
|
|
55
55
|
ZIPs, screenshots, thumbnails, session replay chunks) in configured file/blob
|
|
56
56
|
storage and persist only URLs, ids, or handles.
|
|
57
57
|
- Store shared runtime configuration in the workspace root `.env`; use
|
|
58
|
-
`apps/<app>/.env` only for app-specific overrides.
|
|
58
|
+
`apps/<app>/.env` only for app-specific overrides. For public app behavior,
|
|
59
|
+
prefer the default in `agent-native.config.ts` and use the deterministic
|
|
60
|
+
`AGENT_NATIVE_CONFIG_<UPPER_SNAKE_PATH>` alias only when a non-secret value
|
|
61
|
+
needs a deployment override. Never hardcode API keys,
|
|
59
62
|
tokens, webhook URLs, signing secrets, private Builder/internal data, customer
|
|
60
63
|
data, or credential-looking literals in source, docs, prompts, fixtures,
|
|
61
64
|
application state, action responses, or generated app content. Use
|
|
@@ -68,7 +68,6 @@ import {
|
|
|
68
68
|
IconChartBar,
|
|
69
69
|
IconCheck,
|
|
70
70
|
IconChevronDown,
|
|
71
|
-
IconCircleDashed,
|
|
72
71
|
IconClock,
|
|
73
72
|
IconDatabase,
|
|
74
73
|
IconEdit,
|
|
@@ -473,13 +472,6 @@ function statusLabel(t: Translate, status: WorkspaceConnectionStatus): string {
|
|
|
473
472
|
return t(`integrations.status.${status}`);
|
|
474
473
|
}
|
|
475
474
|
|
|
476
|
-
function readinessLabel(
|
|
477
|
-
t: Translate,
|
|
478
|
-
status: WorkspaceConnectionProviderReadinessStatus,
|
|
479
|
-
): string {
|
|
480
|
-
return t(`integrations.readiness.${status}`);
|
|
481
|
-
}
|
|
482
|
-
|
|
483
475
|
function scopeLabel(
|
|
484
476
|
t: Translate,
|
|
485
477
|
scope: WorkspaceConnectionCredentialRef["scope"],
|
|
@@ -742,32 +734,6 @@ function nextAllowedApps(
|
|
|
742
734
|
return current.filter((id) => id !== appId);
|
|
743
735
|
}
|
|
744
736
|
|
|
745
|
-
function summarizeGrant(
|
|
746
|
-
connection: WorkspaceConnection,
|
|
747
|
-
grantApps: GrantApp[],
|
|
748
|
-
grants: WorkspaceConnectionsResponse["grants"],
|
|
749
|
-
t: Translate,
|
|
750
|
-
) {
|
|
751
|
-
if (connection.allowedApps.length === 0) return t("integrations.allApps");
|
|
752
|
-
const grantedAppIds = Array.from(
|
|
753
|
-
new Set([
|
|
754
|
-
...connection.allowedApps,
|
|
755
|
-
...grants
|
|
756
|
-
.filter((grant) => grant.connectionId === connection.id)
|
|
757
|
-
.map((grant) => grant.appId)
|
|
758
|
-
.filter((appId) => appId !== "*"),
|
|
759
|
-
]),
|
|
760
|
-
);
|
|
761
|
-
const labels = grantedAppIds
|
|
762
|
-
.map((appId) => grantApps.find((app) => app.id === appId)?.label ?? appId)
|
|
763
|
-
.slice(0, 3);
|
|
764
|
-
const suffix =
|
|
765
|
-
grantedAppIds.length > labels.length
|
|
766
|
-
? ` +${grantedAppIds.length - labels.length}`
|
|
767
|
-
: "";
|
|
768
|
-
return `${labels.join(", ")}${suffix}`;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
737
|
function summarizeUserAccess(
|
|
772
738
|
connection: WorkspaceConnection,
|
|
773
739
|
t: Translate,
|
|
@@ -800,21 +766,6 @@ function summarizeUserAccess(
|
|
|
800
766
|
return `${labels.join(", ")}${suffix}`;
|
|
801
767
|
}
|
|
802
768
|
|
|
803
|
-
function summarizeAppList(
|
|
804
|
-
appIds: string[],
|
|
805
|
-
grantApps: GrantApp[],
|
|
806
|
-
t: Translate,
|
|
807
|
-
): string {
|
|
808
|
-
const labels = appIds
|
|
809
|
-
.map((appId) => grantApps.find((app) => app.id === appId)?.label ?? appId)
|
|
810
|
-
.slice(0, 3);
|
|
811
|
-
const suffix =
|
|
812
|
-
appIds.length > labels.length ? ` +${appIds.length - labels.length}` : "";
|
|
813
|
-
return labels.length > 0
|
|
814
|
-
? `${labels.join(", ")}${suffix}`
|
|
815
|
-
: t("integrations.noApps");
|
|
816
|
-
}
|
|
817
|
-
|
|
818
769
|
function startWorkspaceProviderOAuth(provider: WorkspaceConnectionProvider) {
|
|
819
770
|
const returnPath = `${window.location.pathname}${window.location.search}`;
|
|
820
771
|
if (provider.id === "slack") {
|
|
@@ -3516,66 +3467,6 @@ export default function WorkspaceIntegrationsRoute() {
|
|
|
3516
3467
|
);
|
|
3517
3468
|
}
|
|
3518
3469
|
|
|
3519
|
-
function IntegrationOnboarding() {
|
|
3520
|
-
const t = useT();
|
|
3521
|
-
const steps: Array<{
|
|
3522
|
-
icon: IconComponent;
|
|
3523
|
-
title: string;
|
|
3524
|
-
detail: string;
|
|
3525
|
-
}> = [
|
|
3526
|
-
{
|
|
3527
|
-
icon: IconPlugConnected,
|
|
3528
|
-
title: t("integrations.onboardingConnectTitle"),
|
|
3529
|
-
detail: t("integrations.onboardingConnectDetail"),
|
|
3530
|
-
},
|
|
3531
|
-
{
|
|
3532
|
-
icon: IconShieldCheck,
|
|
3533
|
-
title: t("integrations.onboardingGrantTitle"),
|
|
3534
|
-
detail: t("integrations.onboardingGrantDetail"),
|
|
3535
|
-
},
|
|
3536
|
-
{
|
|
3537
|
-
icon: IconDatabase,
|
|
3538
|
-
title: t("integrations.onboardingLocalTitle"),
|
|
3539
|
-
detail: t("integrations.onboardingLocalDetail"),
|
|
3540
|
-
},
|
|
3541
|
-
];
|
|
3542
|
-
|
|
3543
|
-
return (
|
|
3544
|
-
<section className="rounded-lg bg-muted/30 px-4 py-3">
|
|
3545
|
-
<div className="dispatch-onboarding-grid grid gap-3">
|
|
3546
|
-
<div>
|
|
3547
|
-
<h2 className="text-sm font-semibold text-foreground">
|
|
3548
|
-
{t("integrations.onboardingTitle")}
|
|
3549
|
-
</h2>
|
|
3550
|
-
<p className="mt-1 text-sm leading-5 text-muted-foreground">
|
|
3551
|
-
{t("integrations.onboardingDescription")}
|
|
3552
|
-
</p>
|
|
3553
|
-
</div>
|
|
3554
|
-
<div className="dispatch-onboarding-steps-grid grid gap-2">
|
|
3555
|
-
{steps.map((step) => {
|
|
3556
|
-
const Icon = step.icon;
|
|
3557
|
-
return (
|
|
3558
|
-
<div key={step.title} className="flex min-w-0 gap-2">
|
|
3559
|
-
<div className="mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-md bg-muted/50">
|
|
3560
|
-
<Icon size={14} className="text-muted-foreground" />
|
|
3561
|
-
</div>
|
|
3562
|
-
<div className="min-w-0">
|
|
3563
|
-
<div className="text-xs font-medium text-foreground">
|
|
3564
|
-
{step.title}
|
|
3565
|
-
</div>
|
|
3566
|
-
<div className="mt-0.5 text-xs leading-5 text-muted-foreground">
|
|
3567
|
-
{step.detail}
|
|
3568
|
-
</div>
|
|
3569
|
-
</div>
|
|
3570
|
-
</div>
|
|
3571
|
-
);
|
|
3572
|
-
})}
|
|
3573
|
-
</div>
|
|
3574
|
-
</div>
|
|
3575
|
-
</section>
|
|
3576
|
-
);
|
|
3577
|
-
}
|
|
3578
|
-
|
|
3579
3470
|
function SummaryCard({
|
|
3580
3471
|
icon: Icon,
|
|
3581
3472
|
label,
|
|
@@ -38,7 +38,11 @@ connection exists:
|
|
|
38
38
|
register a `kind: "oauth"` entry so the shared UI renders Connect and the
|
|
39
39
|
runtime owns status, refresh, and reauthorization.
|
|
40
40
|
- **Deploy- or app-level configuration** - use deployment/runtime
|
|
41
|
-
configuration, not a per-user secret row.
|
|
41
|
+
configuration, not a per-user secret row. For a non-secret public setting
|
|
42
|
+
already represented by `AgentNativeConfig`, put the default in
|
|
43
|
+
`agent-native.config.ts` and use its `AGENT_NATIVE_CONFIG_<PATH>` alias only
|
|
44
|
+
for a deployment override. Never put a credential or provider key in that
|
|
45
|
+
public namespace.
|
|
42
46
|
- **Account, customer, manager, or other non-secret identifier** - store it as
|
|
43
47
|
scoped connection metadata or app data, not as a masked secret field.
|
|
44
48
|
|
|
@@ -55,7 +55,10 @@ Preview before `--apply`, commit `agent-native.ejections.json`, and never edit
|
|
|
55
55
|
ZIPs, screenshots, thumbnails, session replay chunks) in configured file/blob
|
|
56
56
|
storage and persist only URLs, ids, or handles.
|
|
57
57
|
- Store shared runtime configuration in the workspace root `.env`; use
|
|
58
|
-
`apps/<app>/.env` only for app-specific overrides.
|
|
58
|
+
`apps/<app>/.env` only for app-specific overrides. For public app behavior,
|
|
59
|
+
prefer the default in `agent-native.config.ts` and use the deterministic
|
|
60
|
+
`AGENT_NATIVE_CONFIG_<UPPER_SNAKE_PATH>` alias only when a non-secret value
|
|
61
|
+
needs a deployment override. Never hardcode API keys,
|
|
59
62
|
tokens, webhook URLs, signing secrets, private Builder/internal data, customer
|
|
60
63
|
data, or credential-looking literals in source, docs, prompts, fixtures,
|
|
61
64
|
application state, action responses, or generated app content. Use
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { defineAction } from "@agent-native/core/action";
|
|
17
|
-
import {
|
|
17
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
18
18
|
import { z } from "zod";
|
|
19
19
|
|
|
20
20
|
export default defineAction({
|
|
@@ -35,7 +35,7 @@ export default defineAction({
|
|
|
35
35
|
if (args.path) nav.path = args.path;
|
|
36
36
|
if (args.threadId) nav.threadId = args.threadId;
|
|
37
37
|
nav._writeId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
38
|
-
await
|
|
38
|
+
await writeAppStateForCurrentTab("navigate", nav);
|
|
39
39
|
return `Navigating to ${args.view || args.path}`;
|
|
40
40
|
},
|
|
41
41
|
});
|
|
@@ -695,19 +695,6 @@ function formatAuditLabel(value: string): string {
|
|
|
695
695
|
.replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
696
696
|
}
|
|
697
697
|
|
|
698
|
-
function formatAuditValue(value: unknown): string {
|
|
699
|
-
if (value === null || value === undefined) return "-";
|
|
700
|
-
if (typeof value === "string") return value;
|
|
701
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
702
|
-
return String(value);
|
|
703
|
-
}
|
|
704
|
-
try {
|
|
705
|
-
return JSON.stringify(value);
|
|
706
|
-
} catch {
|
|
707
|
-
return "unreadable";
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
|
|
711
698
|
function truncateAuditText(value: string, maxLength: number): string {
|
|
712
699
|
return value.length > maxLength ? `${value.slice(0, maxLength - 1)}…` : value;
|
|
713
700
|
}
|
|
@@ -24,7 +24,6 @@ import { FactoryAgentsView } from "@/components/factory/FactoryAgentsView";
|
|
|
24
24
|
import { FactoryAuditView } from "@/components/factory/FactoryAuditView";
|
|
25
25
|
import {
|
|
26
26
|
FactoryCanvas,
|
|
27
|
-
type FactoryCanvasEdge,
|
|
28
27
|
type FactoryCanvasGraph,
|
|
29
28
|
type FactoryCanvasNode,
|
|
30
29
|
} from "@/components/factory/FactoryCanvas";
|