@agent-native/core 0.182.1 → 0.182.2-nightly-20260917210345
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/clips/app/root.tsx +59 -10
- package/corpus/templates/clips/changelog/2026-09-17-desktop-popover-closes-when-clicking-away.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-17-self-hosted-extension-sign-in.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +45 -25
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +43 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +55 -6
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +54 -22
- package/corpus/templates/design/actions/apply-visual-edit.ts +1 -0
- package/corpus/templates/design/actions/create-design-from-template.ts +50 -35
- package/corpus/templates/design/actions/create-design-version.ts +21 -0
- package/corpus/templates/design/actions/create-file.ts +35 -33
- package/corpus/templates/design/actions/delete-design.ts +29 -28
- package/corpus/templates/design/actions/delete-file.ts +154 -23
- package/corpus/templates/design/actions/generate-design.ts +28 -16
- package/corpus/templates/design/actions/get-component-details.ts +187 -33
- package/corpus/templates/design/actions/get-design-version.ts +9 -1
- package/corpus/templates/design/actions/go-to-main-component.ts +37 -35
- package/corpus/templates/design/actions/index-components.ts +241 -126
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +12 -9
- package/corpus/templates/design/actions/present-design-variants.ts +68 -72
- package/corpus/templates/design/actions/rename-component.ts +294 -0
- package/corpus/templates/design/actions/rename-screen.ts +10 -10
- package/corpus/templates/design/actions/update-file.ts +327 -330
- package/corpus/templates/design/actions/update-screen-source.ts +2 -43
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +8 -1
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +55 -33
- package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +4 -2
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +5 -1
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +57 -9
- package/corpus/templates/design/app/components/design/types.ts +1 -0
- package/corpus/templates/design/app/hooks/use-design-versions.ts +3 -2
- package/corpus/templates/design/app/i18n-breakpoints.ts +0 -110
- package/corpus/templates/design/app/i18n-data.ts +0 -10
- package/corpus/templates/design/app/pages/DesignEditor.tsx +250 -107
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +2 -0
- package/corpus/templates/design/app/pages/design-editor/commands/delete-files.ts +69 -47
- package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +8 -1
- package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +107 -2
- package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +26 -1
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +63 -2
- package/corpus/templates/design/app/pages/design-editor/nudge-intent.ts +74 -22
- package/corpus/templates/design/app/pages/design-editor/source-publication.ts +14 -2
- package/corpus/templates/design/changelog/2026-09-16-design-components-retain-linked-identities-when-edited-and-d.md +6 -0
- package/corpus/templates/design/changelog/2026-09-17-screen-deletion-is-immediate-and-undoable-with-history-that-.md +6 -0
- package/corpus/templates/design/e2e/fixtures/design-component-react/index.html +98 -0
- package/corpus/templates/design/e2e/fixtures/design-component-react/inline-component.html +65 -0
- package/corpus/templates/design/server/lib/design-data-mutation.ts +9 -5
- package/corpus/templates/design/server/lib/design-snapshot.ts +28 -16
- package/corpus/templates/design/server/lib/design-versions.ts +208 -130
- package/corpus/templates/design/server/lib/fusion-screens.ts +46 -20
- package/corpus/templates/design/server/lib/import-design-files.ts +5 -1
- package/corpus/templates/design/server/lib/localhost-connection.ts +54 -0
- package/corpus/templates/design/server/source-workspace.ts +412 -356
- package/corpus/templates/design/shared/component-library.ts +36 -6
- package/corpus/templates/design/shared/component-model.ts +8 -2
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/chat/agentkit-protocol.js +148 -34
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/package.json +4 -4
- package/corpus/templates/design/app/components/design/editor/PendingScreenDeletionDialog.tsx +0 -66
|
@@ -102,9 +102,21 @@ export function resolveSourceBaseForPublication(args: {
|
|
|
102
102
|
persistedContent?: string | null;
|
|
103
103
|
beforeContent: string;
|
|
104
104
|
}): string {
|
|
105
|
+
const pendingContent = args.pending?.content;
|
|
106
|
+
const migrationSource = args.pending?.identityMigrationSourceContent;
|
|
107
|
+
// Identity repair is a real full-document save. Keep its raw CAS base while
|
|
108
|
+
// that save is still in flight, but switch to the canonical pending bytes as
|
|
109
|
+
// soon as the collab or persisted mirror has acknowledged them.
|
|
110
|
+
if (
|
|
111
|
+
pendingContent !== undefined &&
|
|
112
|
+
migrationSource !== undefined &&
|
|
113
|
+
args.collabContent !== pendingContent &&
|
|
114
|
+
args.persistedContent !== pendingContent
|
|
115
|
+
) {
|
|
116
|
+
return migrationSource;
|
|
117
|
+
}
|
|
105
118
|
const raw =
|
|
106
|
-
|
|
107
|
-
args.pending?.content ??
|
|
119
|
+
pendingContent ??
|
|
108
120
|
args.collabContent ??
|
|
109
121
|
args.persistedContent ??
|
|
110
122
|
args.beforeContent;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>Design component React fixture</title>
|
|
6
|
+
<style>
|
|
7
|
+
body {
|
|
8
|
+
margin: 0;
|
|
9
|
+
min-height: 700px;
|
|
10
|
+
background: #111827;
|
|
11
|
+
color: white;
|
|
12
|
+
font: 16px system-ui;
|
|
13
|
+
}
|
|
14
|
+
main {
|
|
15
|
+
padding: 40px;
|
|
16
|
+
}
|
|
17
|
+
.card {
|
|
18
|
+
display: grid;
|
|
19
|
+
gap: 8px;
|
|
20
|
+
width: 260px;
|
|
21
|
+
padding: 20px;
|
|
22
|
+
border-radius: 14px;
|
|
23
|
+
background: #1f2937;
|
|
24
|
+
}
|
|
25
|
+
.card button {
|
|
26
|
+
padding: 10px 14px;
|
|
27
|
+
border: 0;
|
|
28
|
+
border-radius: 8px;
|
|
29
|
+
background: #6366f1;
|
|
30
|
+
color: white;
|
|
31
|
+
}
|
|
32
|
+
[data-agent-native-component-ref] {
|
|
33
|
+
outline: 1px dashed #f59e0b;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
36
|
+
</head>
|
|
37
|
+
<body>
|
|
38
|
+
<main
|
|
39
|
+
data-agent-native-node-id="react-screen"
|
|
40
|
+
data-agent-native-layer-name="React Component Screen"
|
|
41
|
+
data-agent-native-source-kind="react"
|
|
42
|
+
data-agent-native-source-path="src/App.tsx"
|
|
43
|
+
data-agent-native-source-file="src/App.tsx"
|
|
44
|
+
data-agent-native-source-line="1"
|
|
45
|
+
data-agent-native-source-column="1"
|
|
46
|
+
>
|
|
47
|
+
<div
|
|
48
|
+
data-agent-native-node-id="promotion-target"
|
|
49
|
+
data-agent-native-layer-name="Promotion target"
|
|
50
|
+
>
|
|
51
|
+
Promote me
|
|
52
|
+
</div>
|
|
53
|
+
<section
|
|
54
|
+
class="card"
|
|
55
|
+
data-agent-native-node-id="card-main"
|
|
56
|
+
data-agent-native-layer-name="Card Main"
|
|
57
|
+
data-agent-native-component="ReusableCard"
|
|
58
|
+
data-agent-native-component-id="cmp-reusable-card"
|
|
59
|
+
data-agent-native-source-file="src/App.tsx"
|
|
60
|
+
data-agent-native-source-line="3"
|
|
61
|
+
data-agent-native-source-column="1"
|
|
62
|
+
data-source-framework="react"
|
|
63
|
+
data-source-file="src/App.tsx"
|
|
64
|
+
data-source-line="3"
|
|
65
|
+
data-source-column="1"
|
|
66
|
+
data-component-name="ReusableCard"
|
|
67
|
+
>
|
|
68
|
+
<strong data-agent-native-node-id="card-title">Canonical card</strong>
|
|
69
|
+
<button
|
|
70
|
+
data-agent-native-node-id="card-button"
|
|
71
|
+
data-agent-native-prop-label="Open"
|
|
72
|
+
>
|
|
73
|
+
Open
|
|
74
|
+
</button>
|
|
75
|
+
</section>
|
|
76
|
+
<section
|
|
77
|
+
class="card"
|
|
78
|
+
data-agent-native-node-id="card-instance"
|
|
79
|
+
data-agent-native-layer-name="Card Instance"
|
|
80
|
+
data-agent-native-component="ReusableCard"
|
|
81
|
+
data-agent-native-component-ref="cmp-reusable-card"
|
|
82
|
+
data-agent-native-component-overrides="%7B%22card-title%22%3A%7B%22textContent%22%3A%22Instance%20override%22%7D%7D"
|
|
83
|
+
>
|
|
84
|
+
<strong
|
|
85
|
+
data-agent-native-node-id="card-instance-title"
|
|
86
|
+
data-agent-native-component-source-node-id="card-title"
|
|
87
|
+
>Instance override</strong
|
|
88
|
+
>
|
|
89
|
+
<button
|
|
90
|
+
data-agent-native-node-id="card-instance-button"
|
|
91
|
+
data-agent-native-component-source-node-id="card-button"
|
|
92
|
+
>
|
|
93
|
+
Open
|
|
94
|
+
</button>
|
|
95
|
+
</section>
|
|
96
|
+
</main>
|
|
97
|
+
</body>
|
|
98
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<title>Inline component fixture</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body style="margin: 0; position: relative; min-height: 900px">
|
|
8
|
+
<aside
|
|
9
|
+
data-agent-native-node-id="legacy-copy"
|
|
10
|
+
data-agent-native-layer-name="Legacy same-name copy"
|
|
11
|
+
data-agent-native-component="ReusableCard"
|
|
12
|
+
style="
|
|
13
|
+
position: absolute;
|
|
14
|
+
left: 40px;
|
|
15
|
+
top: 40px;
|
|
16
|
+
width: 180px;
|
|
17
|
+
height: 80px;
|
|
18
|
+
background: #ddd;
|
|
19
|
+
"
|
|
20
|
+
>
|
|
21
|
+
Legacy
|
|
22
|
+
</aside>
|
|
23
|
+
<section
|
|
24
|
+
data-agent-native-node-id="card-main"
|
|
25
|
+
data-agent-native-layer-name="Card Main"
|
|
26
|
+
style="
|
|
27
|
+
position: absolute;
|
|
28
|
+
left: 300px;
|
|
29
|
+
top: 40px;
|
|
30
|
+
width: 420px;
|
|
31
|
+
height: 360px;
|
|
32
|
+
padding: 20px;
|
|
33
|
+
background: #1f2937;
|
|
34
|
+
color: white;
|
|
35
|
+
"
|
|
36
|
+
>
|
|
37
|
+
<div
|
|
38
|
+
data-agent-native-node-id="card-body"
|
|
39
|
+
data-agent-native-layer-name="Card Body"
|
|
40
|
+
style="display: grid; gap: 8px"
|
|
41
|
+
>
|
|
42
|
+
<strong data-agent-native-node-id="card-title"
|
|
43
|
+
><span data-agent-native-node-id="card-title-text"
|
|
44
|
+
>Canonical card</span
|
|
45
|
+
></strong
|
|
46
|
+
>
|
|
47
|
+
<button
|
|
48
|
+
data-agent-native-node-id="card-button"
|
|
49
|
+
data-agent-native-layer-name="Card Action"
|
|
50
|
+
data-agent-native-prop-label="Open"
|
|
51
|
+
style="width: 120px; padding: 10px; background: #6366f1; color: white"
|
|
52
|
+
>
|
|
53
|
+
Open
|
|
54
|
+
</button>
|
|
55
|
+
</div>
|
|
56
|
+
<div
|
|
57
|
+
data-agent-native-node-id="card-slot"
|
|
58
|
+
data-agent-native-layer-name="Card Slot"
|
|
59
|
+
style="min-height: 70px; padding: 10px; background: #374151"
|
|
60
|
+
>
|
|
61
|
+
Reparent target
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
</body>
|
|
65
|
+
</html>
|
|
@@ -2,6 +2,10 @@ import { assertAccess } from "@agent-native/core/sharing";
|
|
|
2
2
|
import { and, eq, isNull, sql } from "drizzle-orm";
|
|
3
3
|
|
|
4
4
|
import { getDb, schema } from "../db/index.js";
|
|
5
|
+
import {
|
|
6
|
+
designSourceMutationLockKey,
|
|
7
|
+
lockDesignFilesTable,
|
|
8
|
+
} from "../source-workspace.js";
|
|
5
9
|
|
|
6
10
|
const DEFAULT_MAX_ATTEMPTS = 8;
|
|
7
11
|
const CONFLICT_BACKOFF_MS = 8;
|
|
@@ -199,11 +203,10 @@ async function mutateDesignDataUnlocked({
|
|
|
199
203
|
// Keep the design-data CAS and HTML rewrites in one transaction.
|
|
200
204
|
// ponytail: reuse the existing design-file lock; split by design only
|
|
201
205
|
// if breakpoint edits become a measurable multi-tenant bottleneck.
|
|
202
|
-
await (
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
).execute(sql`LOCK TABLE design_files IN SHARE ROW EXCLUSIVE MODE`);
|
|
206
|
+
await tx.execute(
|
|
207
|
+
sql`SELECT pg_advisory_xact_lock(hashtextextended(${designSourceMutationLockKey(designId)}, 0::bigint))`,
|
|
208
|
+
);
|
|
209
|
+
await lockDesignFilesTable(tx);
|
|
207
210
|
}
|
|
208
211
|
|
|
209
212
|
const [currentRow] = await tx
|
|
@@ -233,6 +236,7 @@ async function mutateDesignDataUnlocked({
|
|
|
233
236
|
})
|
|
234
237
|
.from(schema.designFiles)
|
|
235
238
|
.where(eq(schema.designFiles.designId, designId))
|
|
239
|
+
.for("update")
|
|
236
240
|
: [];
|
|
237
241
|
const revisionConditions = [
|
|
238
242
|
eq(schema.designs.id, designId),
|
|
@@ -43,6 +43,13 @@ export interface DesignSnapshot {
|
|
|
43
43
|
resolvedCssVars: Record<string, string>;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
export interface BuildDesignSnapshotOptions {
|
|
47
|
+
/** Read the persisted SQL rows even when a live collaboration document exists. */
|
|
48
|
+
preferStoredFileContent?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type SnapshotDatabase = Pick<ReturnType<typeof getDb>, "select">;
|
|
52
|
+
|
|
46
53
|
function parseDesignData(data?: string | null): Record<string, unknown> {
|
|
47
54
|
if (!data) return {};
|
|
48
55
|
try {
|
|
@@ -62,8 +69,10 @@ function parseDesignData(data?: string | null): Record<string, unknown> {
|
|
|
62
69
|
export async function buildDesignSnapshot(
|
|
63
70
|
designId: string,
|
|
64
71
|
designData?: string | null,
|
|
72
|
+
options: BuildDesignSnapshotOptions = {},
|
|
73
|
+
database?: SnapshotDatabase,
|
|
65
74
|
): Promise<DesignSnapshot> {
|
|
66
|
-
const db = getDb();
|
|
75
|
+
const db = database ?? getDb();
|
|
67
76
|
|
|
68
77
|
const rows = await db
|
|
69
78
|
.select()
|
|
@@ -76,23 +85,26 @@ export async function buildDesignSnapshot(
|
|
|
76
85
|
let source: "collab" | "stored" = "stored";
|
|
77
86
|
// Prefer live collab text when an editing session exists for this file so
|
|
78
87
|
// an external agent sees in-flight edits, not the last persisted snapshot.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
if (!options.preferStoredFileContent) {
|
|
89
|
+
try {
|
|
90
|
+
if (await hasCollabState(f.id)) {
|
|
91
|
+
const live = await getText(f.id, "content");
|
|
92
|
+
if (
|
|
93
|
+
typeof live === "string" &&
|
|
94
|
+
shouldUseLiveFileContent({
|
|
95
|
+
liveContent: live,
|
|
96
|
+
storedContent: f.content,
|
|
97
|
+
fileType: f.fileType,
|
|
98
|
+
})
|
|
99
|
+
) {
|
|
100
|
+
content = live;
|
|
101
|
+
source = "collab";
|
|
102
|
+
}
|
|
92
103
|
}
|
|
104
|
+
} catch {
|
|
105
|
+
// coercion-ok: live collaboration is optional; stored content remains explicitly tagged.
|
|
106
|
+
// Collab read is best-effort; fall back to stored content.
|
|
93
107
|
}
|
|
94
|
-
} catch {
|
|
95
|
-
// Collab read is best-effort; fall back to stored content.
|
|
96
108
|
}
|
|
97
109
|
files.push({
|
|
98
110
|
id: f.id,
|