@agent-native/core 0.84.30 → 0.84.34

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.
Files changed (65) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +24 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/client/session-replay.ts +5 -0
  5. package/corpus/core/src/client/use-action.ts +5 -1
  6. package/corpus/core/src/server/ssr-handler.ts +12 -0
  7. package/corpus/core/src/vite/action-types-plugin.ts +6 -2
  8. package/corpus/core/src/vite/client.ts +152 -17
  9. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +13 -1
  10. package/corpus/templates/analytics/changelog/2026-07-01-session-replays-keep-inlined-css-without-live-resource-loa.md +6 -0
  11. package/corpus/templates/design/AGENTS.md +18 -0
  12. package/corpus/templates/design/actions/apply-source-edit.ts +87 -0
  13. package/corpus/templates/design/actions/import-design-source.ts +158 -0
  14. package/corpus/templates/design/actions/list-source-files.ts +52 -0
  15. package/corpus/templates/design/actions/navigate.ts +4 -2
  16. package/corpus/templates/design/actions/preview-source-edit.ts +85 -0
  17. package/corpus/templates/design/actions/read-source-file.ts +55 -0
  18. package/corpus/templates/design/actions/resolve-selection-source.ts +101 -0
  19. package/corpus/templates/design/actions/view-screen.ts +43 -1
  20. package/corpus/templates/design/app/components/design/CodeWorkbenchHost.tsx +630 -0
  21. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +519 -0
  22. package/corpus/templates/design/app/hooks/use-navigation-state.ts +32 -6
  23. package/corpus/templates/design/app/i18n/zh-TW.ts +40 -0
  24. package/corpus/templates/design/app/i18n-data.ts +508 -0
  25. package/corpus/templates/design/app/pages/DesignEditor.tsx +171 -9
  26. package/corpus/templates/design/changelog/2026-07-01-design-can-import-figma-paste-fig-files-and-standalone-html.md +6 -0
  27. package/corpus/templates/design/changelog/2026-07-01-design-code-workspace.md +6 -0
  28. package/corpus/templates/design/package.json +3 -0
  29. package/corpus/templates/design/server/handlers/import-design-file.ts +168 -0
  30. package/corpus/templates/design/server/lib/figma-import/clipboard.ts +122 -0
  31. package/corpus/templates/design/server/lib/figma-import/decode.ts +455 -0
  32. package/corpus/templates/design/server/lib/figma-import/processor.ts +116 -0
  33. package/corpus/templates/design/server/lib/figma-import/render-html.ts +397 -0
  34. package/corpus/templates/design/server/lib/figma-import/types.ts +60 -0
  35. package/corpus/templates/design/server/lib/import-design-files.ts +314 -0
  36. package/corpus/templates/design/server/routes/api/import-design-file.post.ts +1 -0
  37. package/corpus/templates/design/server/source-workspace.ts +215 -0
  38. package/corpus/templates/design/shared/design-source-capabilities.ts +5 -5
  39. package/corpus/templates/design/shared/source-workspace.ts +149 -0
  40. package/dist/client/session-replay.d.ts +1 -0
  41. package/dist/client/session-replay.d.ts.map +1 -1
  42. package/dist/client/session-replay.js +2 -0
  43. package/dist/client/session-replay.js.map +1 -1
  44. package/dist/client/use-action.d.ts +5 -1
  45. package/dist/client/use-action.d.ts.map +1 -1
  46. package/dist/client/use-action.js.map +1 -1
  47. package/dist/collab/awareness.d.ts +2 -2
  48. package/dist/collab/awareness.d.ts.map +1 -1
  49. package/dist/collab/routes.d.ts +1 -1
  50. package/dist/notifications/routes.d.ts +3 -3
  51. package/dist/observability/routes.d.ts +3 -3
  52. package/dist/progress/routes.d.ts +1 -1
  53. package/dist/resources/handlers.d.ts +3 -3
  54. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  55. package/dist/server/ssr-handler.d.ts.map +1 -1
  56. package/dist/server/ssr-handler.js +7 -0
  57. package/dist/server/ssr-handler.js.map +1 -1
  58. package/dist/server/transcribe-voice.d.ts +1 -1
  59. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  60. package/dist/vite/action-types-plugin.js +6 -2
  61. package/dist/vite/action-types-plugin.js.map +1 -1
  62. package/dist/vite/client.d.ts.map +1 -1
  63. package/dist/vite/client.js +132 -11
  64. package/dist/vite/client.js.map +1 -1
  65. package/package.json +1 -1
@@ -0,0 +1,52 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+
4
+ import { resolveSourceWorkspace } from "../server/source-workspace.js";
5
+
6
+ export default defineAction({
7
+ description:
8
+ "List source files for a Design code workspace. In the current MVP this " +
9
+ "returns inline SQL-backed design_files by filename; future localhost and " +
10
+ "container source backends will use the same shape.",
11
+ schema: z.object({
12
+ designId: z.string().describe("Design project ID"),
13
+ }),
14
+ readOnly: true,
15
+ http: { method: "GET" },
16
+ run: async ({ designId }) => {
17
+ const workspace = await resolveSourceWorkspace(designId);
18
+ const readonly = !workspace.canEdit || workspace.sourceType !== "inline";
19
+ return {
20
+ designId,
21
+ backend: {
22
+ kind: "virtual-inline" as const,
23
+ workspaceUri: `designfs://${designId}/`,
24
+ designId,
25
+ capabilities: {
26
+ readFile: true,
27
+ writeFile: workspace.canEdit && workspace.sourceType === "inline",
28
+ diff: true,
29
+ },
30
+ },
31
+ sourceType: workspace.sourceType,
32
+ files: workspace.files.map((file) => ({
33
+ path: file.filename,
34
+ displayName: file.filename,
35
+ kind: "file" as const,
36
+ sourceType: workspace.sourceType,
37
+ fileId: file.id,
38
+ readonly,
39
+ reason: readonly
40
+ ? workspace.canEdit
41
+ ? "Only inline Design files are editable in this MVP."
42
+ : "You need editor access to change this file."
43
+ : undefined,
44
+ language:
45
+ file.fileType === "html" || file.fileType === "css"
46
+ ? file.fileType
47
+ : undefined,
48
+ updatedAt: file.updatedAt,
49
+ })),
50
+ };
51
+ },
52
+ });
@@ -18,7 +18,7 @@
18
18
  * --designId Design ID (for editor/present views)
19
19
  * --editorView Editor mode for designs: single or overview
20
20
  * --inspectorTab Inspector tab for designs: design or tweaks (extensions opens Tools for compatibility)
21
- * --leftPanel Left editor panel: file, agent, assets, tools, or tokens
21
+ * --leftPanel Left editor panel: file, agent, assets, import, tools, tokens, or code
22
22
  * --fileId Screen/file id to focus in the design editor
23
23
  * --filename Screen filename to focus in the design editor
24
24
  * --tool Design editor tool to activate
@@ -51,13 +51,15 @@ const designLeftPanelSchema = z.enum([
51
51
  "file",
52
52
  "agent",
53
53
  "assets",
54
+ "import",
54
55
  "tools",
55
56
  "tokens",
57
+ "code",
56
58
  ]);
57
59
 
58
60
  export default defineAction({
59
61
  description:
60
- "Navigate the UI to a specific view or path. Views: list, editor, design-systems, present, settings. Use --designId with editor/present views and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use leftPanel=file|agent|assets|tools|tokens to focus the Figma-style left rail. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
62
+ "Navigate the UI to a specific view or path. Views: list, editor, design-systems, present, settings. Use --designId with editor/present views and --designSystemId with design-systems. For designs, use editorView=overview to show the infinite screens canvas, or editorView=single with fileId/filename/screen to focus a screen. Use leftPanel=file|agent|assets|import|tools|tokens|code to focus the left rail, including Import and the wide Code workspace. Legacy inspectorTab=extensions opens Tools. Use tool to activate a design editor tool.",
61
63
  schema: z
62
64
  .object({
63
65
  view: z
@@ -0,0 +1,85 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+
4
+ import {
5
+ findSourceWorkspaceFile,
6
+ readLiveSourceFile,
7
+ resolveSourceWorkspace,
8
+ } from "../server/source-workspace.js";
9
+ import {
10
+ applySourceEdit,
11
+ previewSourceDiff,
12
+ } from "../shared/source-workspace.js";
13
+
14
+ const sourceEditSchema = z.discriminatedUnion("kind", [
15
+ z.object({
16
+ kind: z.literal("full-replace"),
17
+ content: z.string().describe("Complete replacement file content"),
18
+ }),
19
+ z.object({
20
+ kind: z.literal("exact-replace"),
21
+ search: z.string().min(1).describe("Unique exact text to replace"),
22
+ replace: z.string().describe("Replacement text"),
23
+ }),
24
+ ]);
25
+
26
+ export default defineAction({
27
+ description:
28
+ "Preview a source-file edit without saving it. Returns changed byte counts, " +
29
+ "line range, and compact before/after excerpts for Design code workspace diffs.",
30
+ schema: z
31
+ .object({
32
+ designId: z.string().describe("Design project ID"),
33
+ path: z
34
+ .string()
35
+ .optional()
36
+ .describe("Source path/filename, such as index.html"),
37
+ fileId: z.string().optional().describe("Design file ID"),
38
+ edit: sourceEditSchema,
39
+ expectedVersionHash: z
40
+ .string()
41
+ .optional()
42
+ .describe("Optional hash from read-source-file to detect stale edits"),
43
+ })
44
+ .refine((args) => args.path || args.fileId, {
45
+ message: "Provide either path or fileId.",
46
+ path: ["path"],
47
+ }),
48
+ readOnly: true,
49
+ run: async ({ designId, path, fileId, edit, expectedVersionHash }) => {
50
+ const workspace = await resolveSourceWorkspace(designId, {
51
+ includeContent: true,
52
+ });
53
+ const file = findSourceWorkspaceFile(workspace.files, { fileId, path });
54
+ const live = await readLiveSourceFile(file);
55
+ const stale =
56
+ expectedVersionHash !== undefined &&
57
+ expectedVersionHash !== live.versionHash;
58
+ if (stale) {
59
+ return {
60
+ designId,
61
+ path: file.filename,
62
+ fileId: file.id,
63
+ okToApply: false,
64
+ conflict: "stale-version",
65
+ currentVersionHash: live.versionHash,
66
+ message:
67
+ "Source file changed since it was read. Re-read before saving.",
68
+ };
69
+ }
70
+
71
+ const next = applySourceEdit(live.content, edit);
72
+ return {
73
+ designId,
74
+ path: file.filename,
75
+ fileId: file.id,
76
+ okToApply: workspace.canEdit && workspace.sourceType === "inline",
77
+ conflict:
78
+ workspace.sourceType === "inline" ? null : "unsupported-source-backend",
79
+ currentVersionHash: live.versionHash,
80
+ nextVersionHash: next.changed ? undefined : live.versionHash,
81
+ editsApplied: next.editsApplied,
82
+ diff: previewSourceDiff(live.content, next.content),
83
+ };
84
+ },
85
+ });
@@ -0,0 +1,55 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+
4
+ import {
5
+ findSourceWorkspaceFile,
6
+ readLiveSourceFile,
7
+ resolveSourceWorkspace,
8
+ } from "../server/source-workspace.js";
9
+
10
+ export default defineAction({
11
+ description:
12
+ "Read one Design source file. For inline designs this returns live " +
13
+ "design_files content with a version hash for safe follow-up writes.",
14
+ schema: z
15
+ .object({
16
+ designId: z.string().describe("Design project ID"),
17
+ path: z
18
+ .string()
19
+ .optional()
20
+ .describe("Source path/filename, such as index.html"),
21
+ fileId: z.string().optional().describe("Design file ID"),
22
+ })
23
+ .refine((args) => args.path || args.fileId, {
24
+ message: "Provide either path or fileId.",
25
+ path: ["path"],
26
+ }),
27
+ readOnly: true,
28
+ http: { method: "GET" },
29
+ run: async ({ designId, path, fileId }) => {
30
+ const workspace = await resolveSourceWorkspace(designId, {
31
+ includeContent: true,
32
+ });
33
+ const file = findSourceWorkspaceFile(workspace.files, { fileId, path });
34
+ const live = await readLiveSourceFile(file);
35
+ return {
36
+ designId,
37
+ path: file.filename,
38
+ displayName: file.filename,
39
+ fileId: file.id,
40
+ sourceType: workspace.sourceType,
41
+ backendKind: "virtual-inline",
42
+ readonly: !workspace.canEdit || workspace.sourceType !== "inline",
43
+ language: live.language,
44
+ content: live.content,
45
+ versionHash: live.versionHash,
46
+ updatedAt: file.updatedAt,
47
+ provenance: {
48
+ kind: "design-file",
49
+ designId,
50
+ fileId: file.id,
51
+ filename: file.filename,
52
+ },
53
+ };
54
+ },
55
+ });
@@ -0,0 +1,101 @@
1
+ import { defineAction } from "@agent-native/core";
2
+ import { z } from "zod";
3
+
4
+ import {
5
+ findSourceWorkspaceFile,
6
+ readLiveSourceFile,
7
+ resolveSourceWorkspace,
8
+ } from "../server/source-workspace.js";
9
+ import { buildCodeLayerProjection } from "../shared/code-layer.js";
10
+
11
+ function offsetToLineColumn(content: string, offset: number) {
12
+ let line = 1;
13
+ let column = 1;
14
+ for (let index = 0; index < offset; index += 1) {
15
+ if (content.charCodeAt(index) === 10) {
16
+ line += 1;
17
+ column = 1;
18
+ } else {
19
+ column += 1;
20
+ }
21
+ }
22
+ return { line, column };
23
+ }
24
+
25
+ export default defineAction({
26
+ description:
27
+ "Resolve a selected Design canvas node to the best source file location. " +
28
+ "Inline designs resolve to the containing design file and, when possible, " +
29
+ "a line/column/snippet from the code-layer projection.",
30
+ schema: z
31
+ .object({
32
+ designId: z.string().describe("Design project ID"),
33
+ path: z
34
+ .string()
35
+ .optional()
36
+ .describe("Source path/filename, such as index.html"),
37
+ fileId: z.string().optional().describe("Design file ID"),
38
+ nodeId: z
39
+ .string()
40
+ .optional()
41
+ .describe("data-agent-native-node-id or code-layer node id"),
42
+ selector: z.string().optional().describe("CSS selector fallback"),
43
+ })
44
+ .refine((args) => args.path || args.fileId, {
45
+ message: "Provide either path or fileId.",
46
+ path: ["path"],
47
+ }),
48
+ readOnly: true,
49
+ http: { method: "GET" },
50
+ run: async ({ designId, path, fileId, nodeId, selector }) => {
51
+ const workspace = await resolveSourceWorkspace(designId, {
52
+ includeContent: true,
53
+ });
54
+ const file = findSourceWorkspaceFile(workspace.files, { fileId, path });
55
+ const live = await readLiveSourceFile(file);
56
+ const projection = buildCodeLayerProjection(live.content, {
57
+ source: {
58
+ kind: "design-file",
59
+ designId,
60
+ fileId: file.id,
61
+ filename: file.filename,
62
+ },
63
+ });
64
+ const node =
65
+ projection.nodes.find(
66
+ (candidate) =>
67
+ candidate.id === nodeId ||
68
+ candidate.dataAttributes["data-agent-native-node-id"] === nodeId ||
69
+ candidate.dataAttributes["data-code-layer-id"] === nodeId,
70
+ ) ??
71
+ projection.nodes.find((candidate) =>
72
+ selector
73
+ ? candidate.selector === selector ||
74
+ candidate.path === selector ||
75
+ candidate.selectors.includes(selector)
76
+ : false,
77
+ );
78
+
79
+ const start = node?.source?.openStart ?? node?.source?.start;
80
+ const location =
81
+ typeof start === "number"
82
+ ? offsetToLineColumn(live.content, start)
83
+ : null;
84
+ const snippet =
85
+ node?.source && typeof node.source.start === "number"
86
+ ? live.content.slice(node.source.start, node.source.end).slice(0, 1200)
87
+ : undefined;
88
+
89
+ return {
90
+ designId,
91
+ sourceType: workspace.sourceType,
92
+ backendKind: "virtual-inline",
93
+ path: file.filename,
94
+ fileId: file.id,
95
+ line: location?.line ?? null,
96
+ column: location?.column ?? null,
97
+ snippet,
98
+ resolved: Boolean(node),
99
+ };
100
+ },
101
+ });
@@ -34,6 +34,20 @@ function stringArrayProp(value: unknown, key: string): string[] {
34
34
  : [];
35
35
  }
36
36
 
37
+ function boolProp(value: unknown, key: string): boolean | undefined {
38
+ if (!value || typeof value !== "object") return undefined;
39
+ const candidate = (value as Record<string, unknown>)[key];
40
+ return typeof candidate === "boolean" ? candidate : undefined;
41
+ }
42
+
43
+ function objectProp(value: unknown, key: string): Record<string, unknown> {
44
+ if (!value || typeof value !== "object") return {};
45
+ const candidate = (value as Record<string, unknown>)[key];
46
+ return candidate && typeof candidate === "object" && !Array.isArray(candidate)
47
+ ? (candidate as Record<string, unknown>)
48
+ : {};
49
+ }
50
+
37
51
  function resolveActiveScreen(
38
52
  files: Array<{
39
53
  id: string;
@@ -93,9 +107,36 @@ function resolveActiveScreen(
93
107
  return null;
94
108
  }
95
109
 
110
+ function resolveActiveCodeFile(
111
+ files: Array<{
112
+ id: string;
113
+ filename: string;
114
+ fileType: string | null;
115
+ updatedAt: string | null;
116
+ }>,
117
+ designSelection: unknown,
118
+ ) {
119
+ const codeWorkspace = objectProp(designSelection, "codeWorkspace");
120
+ if (Object.keys(codeWorkspace).length === 0) return null;
121
+ const fileId = stringProp(codeWorkspace, "activeFileId");
122
+ const path = stringProp(codeWorkspace, "activePath");
123
+ const file = files.find(
124
+ (candidate) => candidate.id === fileId || candidate.filename === path,
125
+ );
126
+ return {
127
+ open: boolProp(codeWorkspace, "open") ?? false,
128
+ backendKind: stringProp(codeWorkspace, "backendKind") ?? "virtual-inline",
129
+ path: path ?? file?.filename ?? null,
130
+ fileId: fileId ?? file?.id ?? null,
131
+ dirty: boolProp(codeWorkspace, "dirty") ?? false,
132
+ versionHash: stringProp(codeWorkspace, "versionHash") ?? null,
133
+ file: file ?? null,
134
+ };
135
+ }
136
+
96
137
  export default defineAction({
97
138
  description:
98
- "See what the user is currently looking at on screen. Returns the current navigation state including which design is open, which view they are on (list, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design or tweaks), active left rail panel (file, agent, assets, tools, or tokens), overview canvas state, plus any pending question overlay. Always call this first before taking any action.",
139
+ "See what the user is currently looking at on screen. Returns the current navigation state including which design is open, which view they are on (list, editor, design-systems, present, settings), active/focused design screen, selected element, active inspector tab (design or tweaks), active left rail panel (file, agent, assets, import, tools, tokens, or code), active code file metadata, overview canvas state, plus any pending question overlay. Always call this first before taking any action.",
99
140
  schema: z.object({}),
100
141
  http: false,
101
142
  run: async () => {
@@ -154,6 +195,7 @@ export default defineAction({
154
195
  title: (access.resource as { title?: unknown }).title ?? null,
155
196
  screens: files,
156
197
  activeScreen: resolveActiveScreen(files, navigation, designSelection),
198
+ activeCodeFile: resolveActiveCodeFile(files, designSelection),
157
199
  canvasFrames: parseCanvasFrameGeometryById(data.canvasFrames),
158
200
  };
159
201
  }