@agent-native/core 0.86.0 → 0.86.1

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 (183) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +9 -0
  3. package/corpus/core/package.json +2 -1
  4. package/corpus/core/src/client/AgentPanel.tsx +10 -0
  5. package/corpus/core/src/client/AssistantChat.tsx +91 -27
  6. package/corpus/core/src/client/ErrorBoundary.tsx +67 -12
  7. package/corpus/core/src/client/ErrorReportActions.tsx +69 -0
  8. package/corpus/core/src/client/FeedbackButton.tsx +8 -4
  9. package/corpus/core/src/client/db-admin/DbAdminPage.tsx +41 -13
  10. package/corpus/core/src/client/db-admin/SqlEditor.tsx +10 -3
  11. package/corpus/core/src/client/db-admin/TableEditor.tsx +12 -5
  12. package/corpus/core/src/client/db-admin/useAgentSync.ts +10 -3
  13. package/corpus/core/src/client/db-admin/useDbAdmin.ts +65 -16
  14. package/corpus/core/src/client/error-reporting.ts +100 -0
  15. package/corpus/core/src/client/index.ts +11 -0
  16. package/corpus/core/src/client/org/RequireActiveOrg.tsx +12 -0
  17. package/corpus/core/src/client/visual-style-controls.tsx +615 -2
  18. package/corpus/core/src/db-admin/index.ts +26 -0
  19. package/corpus/core/src/db-admin/operations.ts +87 -49
  20. package/corpus/core/src/localization/default-messages.ts +4 -0
  21. package/corpus/core/src/server/builder-design-systems.ts +328 -9
  22. package/corpus/core/src/server/index.ts +15 -0
  23. package/corpus/core/src/templates/default/app/root.tsx +47 -0
  24. package/corpus/templates/analytics/AGENTS.md +6 -4
  25. package/corpus/templates/analytics/actions/delete-db-admin-connection.ts +19 -0
  26. package/corpus/templates/analytics/actions/list-db-admin-connections.ts +18 -0
  27. package/corpus/templates/analytics/actions/navigate.ts +17 -3
  28. package/corpus/templates/analytics/actions/save-db-admin-connection.ts +33 -0
  29. package/corpus/templates/analytics/actions/view-screen.ts +11 -3
  30. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +11 -2
  31. package/corpus/templates/analytics/app/i18n/zh-TW.ts +23 -2
  32. package/corpus/templates/analytics/app/i18n-data.ts +230 -20
  33. package/corpus/templates/analytics/app/pages/Agents.tsx +398 -4
  34. package/corpus/templates/analytics/changelog/2026-07-03-connect-other-app-databases-from-analytics.md +6 -0
  35. package/corpus/templates/analytics/server/db/schema.ts +27 -0
  36. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +458 -0
  37. package/corpus/templates/analytics/server/plugins/db.ts +35 -0
  38. package/corpus/templates/analytics/server/routes/[base]/_agent-native/analytics-db-admin/[...path].ts +1 -0
  39. package/corpus/templates/analytics/server/routes/_agent-native/analytics-db-admin/[...path].ts +160 -0
  40. package/corpus/templates/content/app/root.tsx +9 -0
  41. package/corpus/templates/content/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  42. package/corpus/templates/design/AGENTS.md +13 -7
  43. package/corpus/templates/design/actions/get-design-system.ts +21 -0
  44. package/corpus/templates/design/actions/index-design-system-with-builder.ts +14 -37
  45. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +3 -3
  46. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +70 -9
  47. package/corpus/templates/design/app/components/design/code-workbench/editor/EditorTabs.tsx +11 -2
  48. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +1 -1
  49. package/corpus/templates/design/app/components/design/code-workbench/editor/StatusBar.tsx +1 -1
  50. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +8 -2
  51. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +7 -3
  52. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +48 -0
  53. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +6 -0
  54. package/corpus/templates/design/app/i18n/zh-TW.ts +15 -14
  55. package/corpus/templates/design/app/i18n-data.ts +154 -142
  56. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +32 -14
  57. package/corpus/templates/design/changelog/2026-07-03-design-system-setup-now-indexes-figma-code-and-design-md-sou.md +6 -0
  58. package/corpus/templates/design/changelog/2026-07-03-the-code-editor-is-easier-to-use-with-top-sidebar-tabs-clear.md +6 -0
  59. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +16 -106
  60. package/corpus/templates/mail/app/root.tsx +60 -1
  61. package/corpus/templates/mail/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  62. package/corpus/templates/plan/app/i18n/ar-SA.ts +3 -0
  63. package/corpus/templates/plan/app/i18n/de-DE.ts +4 -0
  64. package/corpus/templates/plan/app/i18n/en-US.ts +4 -0
  65. package/corpus/templates/plan/app/i18n/es-ES.ts +4 -0
  66. package/corpus/templates/plan/app/i18n/fr-FR.ts +4 -0
  67. package/corpus/templates/plan/app/i18n/hi-IN.ts +3 -0
  68. package/corpus/templates/plan/app/i18n/ja-JP.ts +4 -0
  69. package/corpus/templates/plan/app/i18n/ko-KR.ts +4 -0
  70. package/corpus/templates/plan/app/i18n/pt-BR.ts +4 -0
  71. package/corpus/templates/plan/app/i18n/zh-CN.ts +3 -0
  72. package/corpus/templates/plan/app/i18n/zh-TW.ts +3 -0
  73. package/corpus/templates/plan/app/pages/PlansPage.tsx +74 -3
  74. package/corpus/templates/plan/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  75. package/corpus/templates/slides/AGENTS.md +7 -3
  76. package/corpus/templates/slides/actions/get-design-system.ts +21 -0
  77. package/corpus/templates/slides/actions/import-file.ts +15 -7
  78. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +14 -37
  79. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +32 -8
  80. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +2 -2
  81. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +2 -4
  82. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +163 -154
  83. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +19 -15
  84. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +56 -6
  85. package/corpus/templates/slides/app/components/layout/Layout.tsx +6 -1
  86. package/corpus/templates/slides/app/i18n/ar-SA.ts +8 -7
  87. package/corpus/templates/slides/app/i18n/de-DE.ts +7 -8
  88. package/corpus/templates/slides/app/i18n/en-US.ts +8 -7
  89. package/corpus/templates/slides/app/i18n/es-ES.ts +7 -8
  90. package/corpus/templates/slides/app/i18n/fr-FR.ts +7 -8
  91. package/corpus/templates/slides/app/i18n/hi-IN.ts +8 -7
  92. package/corpus/templates/slides/app/i18n/ja-JP.ts +7 -8
  93. package/corpus/templates/slides/app/i18n/ko-KR.ts +7 -7
  94. package/corpus/templates/slides/app/i18n/pt-BR.ts +7 -8
  95. package/corpus/templates/slides/app/i18n/zh-CN.ts +8 -7
  96. package/corpus/templates/slides/app/i18n/zh-TW.ts +8 -7
  97. package/corpus/templates/slides/app/lib/canvas-zoom.ts +16 -1
  98. package/corpus/templates/slides/app/pages/DeckEditor.tsx +3 -3
  99. package/corpus/templates/slides/changelog/2026-07-03-design-system-setup-now-indexes-figma-code-and-design-md-sou.md +6 -0
  100. package/corpus/templates/slides/changelog/2026-07-03-slide-editing-now-keeps-thumbnails-speaker-notes-styling-and.md +6 -0
  101. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +16 -104
  102. package/dist/client/AgentPanel.d.ts.map +1 -1
  103. package/dist/client/AgentPanel.js +2 -1
  104. package/dist/client/AgentPanel.js.map +1 -1
  105. package/dist/client/AssistantChat.d.ts.map +1 -1
  106. package/dist/client/AssistantChat.js +77 -25
  107. package/dist/client/AssistantChat.js.map +1 -1
  108. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  109. package/dist/client/ErrorBoundary.js +37 -2
  110. package/dist/client/ErrorBoundary.js.map +1 -1
  111. package/dist/client/ErrorReportActions.d.ts +13 -0
  112. package/dist/client/ErrorReportActions.d.ts.map +1 -0
  113. package/dist/client/ErrorReportActions.js +14 -0
  114. package/dist/client/ErrorReportActions.js.map +1 -0
  115. package/dist/client/FeedbackButton.d.ts +3 -1
  116. package/dist/client/FeedbackButton.d.ts.map +1 -1
  117. package/dist/client/FeedbackButton.js +6 -5
  118. package/dist/client/FeedbackButton.js.map +1 -1
  119. package/dist/client/db-admin/DbAdminPage.d.ts +9 -1
  120. package/dist/client/db-admin/DbAdminPage.d.ts.map +1 -1
  121. package/dist/client/db-admin/DbAdminPage.js +17 -13
  122. package/dist/client/db-admin/DbAdminPage.js.map +1 -1
  123. package/dist/client/db-admin/SqlEditor.d.ts +3 -1
  124. package/dist/client/db-admin/SqlEditor.d.ts.map +1 -1
  125. package/dist/client/db-admin/SqlEditor.js +3 -3
  126. package/dist/client/db-admin/SqlEditor.js.map +1 -1
  127. package/dist/client/db-admin/TableEditor.d.ts +3 -1
  128. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  129. package/dist/client/db-admin/TableEditor.js +6 -6
  130. package/dist/client/db-admin/TableEditor.js.map +1 -1
  131. package/dist/client/db-admin/useAgentSync.d.ts +3 -2
  132. package/dist/client/db-admin/useAgentSync.d.ts.map +1 -1
  133. package/dist/client/db-admin/useAgentSync.js +8 -4
  134. package/dist/client/db-admin/useAgentSync.js.map +1 -1
  135. package/dist/client/db-admin/useDbAdmin.d.ts +11 -7
  136. package/dist/client/db-admin/useDbAdmin.d.ts.map +1 -1
  137. package/dist/client/db-admin/useDbAdmin.js +45 -20
  138. package/dist/client/db-admin/useDbAdmin.js.map +1 -1
  139. package/dist/client/error-reporting.d.ts +19 -0
  140. package/dist/client/error-reporting.d.ts.map +1 -0
  141. package/dist/client/error-reporting.js +71 -0
  142. package/dist/client/error-reporting.js.map +1 -0
  143. package/dist/client/index.d.ts +3 -1
  144. package/dist/client/index.d.ts.map +1 -1
  145. package/dist/client/index.js +3 -1
  146. package/dist/client/index.js.map +1 -1
  147. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -1
  148. package/dist/client/org/RequireActiveOrg.js +2 -1
  149. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  150. package/dist/client/visual-style-controls.d.ts +11 -0
  151. package/dist/client/visual-style-controls.d.ts.map +1 -1
  152. package/dist/client/visual-style-controls.js +350 -1
  153. package/dist/client/visual-style-controls.js.map +1 -1
  154. package/dist/collab/routes.d.ts +1 -1
  155. package/dist/collab/struct-routes.d.ts +1 -1
  156. package/dist/db-admin/index.d.ts +3 -0
  157. package/dist/db-admin/index.d.ts.map +1 -0
  158. package/dist/db-admin/index.js +2 -0
  159. package/dist/db-admin/index.js.map +1 -0
  160. package/dist/db-admin/operations.d.ts +26 -5
  161. package/dist/db-admin/operations.d.ts.map +1 -1
  162. package/dist/db-admin/operations.js +66 -55
  163. package/dist/db-admin/operations.js.map +1 -1
  164. package/dist/localization/default-messages.d.ts +3 -0
  165. package/dist/localization/default-messages.d.ts.map +1 -1
  166. package/dist/localization/default-messages.js +3 -0
  167. package/dist/localization/default-messages.js.map +1 -1
  168. package/dist/notifications/routes.d.ts +1 -1
  169. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  170. package/dist/resources/handlers.d.ts +1 -1
  171. package/dist/secrets/routes.d.ts +9 -9
  172. package/dist/server/builder-design-systems.d.ts +61 -0
  173. package/dist/server/builder-design-systems.d.ts.map +1 -1
  174. package/dist/server/builder-design-systems.js +219 -14
  175. package/dist/server/builder-design-systems.js.map +1 -1
  176. package/dist/server/index.d.ts +1 -1
  177. package/dist/server/index.d.ts.map +1 -1
  178. package/dist/server/index.js +1 -1
  179. package/dist/server/index.js.map +1 -1
  180. package/dist/server/transcribe-voice.d.ts +1 -1
  181. package/dist/templates/default/app/root.tsx +47 -0
  182. package/package.json +2 -1
  183. package/src/templates/default/app/root.tsx +47 -0
@@ -92,13 +92,19 @@ patterns live in `.agents/skills/`.
92
92
  `inspectorTab: "extensions"` after installing it.
93
93
  - Follow linked design-system tokens and `customInstructions` whenever present;
94
94
  explicit user instructions in the current turn still win.
95
- - When a user wants tokens from design.md, CSS, theme/tokens JSON, Tailwind
96
- config, local files, or the current design, call `import-design-tokens` and
97
- preserve its `tokens`, `filesAnalyzed`, and provenance in your answer. Manual
98
- `apply-design-token-edit` / one-by-one token entry is the fallback for a small
99
- one-off token, not the primary import workflow. For Figma variables/styles or
100
- raw `.fig` files, keep using Builder-backed design-system indexing instead of
101
- local `.fig` parsing.
95
+ - For reusable design-system setup from Figma, connected code/GitHub, local
96
+ code/design files, or optional `design.md`, use Builder-backed DSI indexing
97
+ through `index-design-system-with-builder` or `import-file --format fig`.
98
+ Pass readable `design.md` content as `designMd`, use the returned local design
99
+ system id in Design flows, and call `get-design-system` before generation to
100
+ hydrate Builder docs/tokens when available. Do not create a duplicate local
101
+ design system from raw Figma/code sources.
102
+ - When a user wants one-off tokens from design.md, CSS, theme/tokens JSON,
103
+ Tailwind config, local files, or the current design, call
104
+ `import-design-tokens` and preserve its `tokens`, `filesAnalyzed`, and
105
+ provenance in your answer. Manual `apply-design-token-edit` / one-by-one
106
+ token entry is the fallback for a small one-off token, not the primary import
107
+ workflow.
102
108
  - Persist useful work early: create/update the design and files as soon as a
103
109
  coherent candidate exists, then iterate.
104
110
  - For non-trivial new design prompts, ask before generating: create/open the
@@ -1,4 +1,8 @@
1
1
  import { defineAction } from "@agent-native/core";
2
+ import {
3
+ hydrateBuilderDesignSystemReference,
4
+ parseBuilderDesignSystemProxyReference,
5
+ } from "@agent-native/core/server";
2
6
  import { resolveAccess } from "@agent-native/core/sharing";
3
7
  import { z } from "zod";
4
8
 
@@ -19,6 +23,22 @@ export default defineAction({
19
23
  }
20
24
 
21
25
  const row = access.resource;
26
+ const builderReference = parseBuilderDesignSystemProxyReference(row.data);
27
+ const builder = builderReference
28
+ ? await hydrateBuilderDesignSystemReference(builderReference).catch(
29
+ (error) => ({
30
+ ...builderReference,
31
+ docs: [],
32
+ tokenValues: {},
33
+ docCount: 0,
34
+ warning:
35
+ error instanceof Error
36
+ ? error.message
37
+ : "Builder design-system docs could not be loaded.",
38
+ }),
39
+ )
40
+ : null;
41
+
22
42
  return {
23
43
  id: row.id,
24
44
  title: row.title,
@@ -30,6 +50,7 @@ export default defineAction({
30
50
  visibility: row.visibility,
31
51
  createdAt: row.createdAt,
32
52
  updatedAt: row.updatedAt,
53
+ builder,
33
54
  };
34
55
  },
35
56
  });
@@ -1,7 +1,7 @@
1
1
  import { defineAction } from "@agent-native/core";
2
2
  import {
3
+ buildBuilderDesignSystemIndexFiles,
3
4
  startBuilderDesignSystemIndex,
4
- type BuilderDesignSystemIndexFile,
5
5
  } from "@agent-native/core/server";
6
6
  import {
7
7
  getRequestOrgId,
@@ -11,50 +11,17 @@ import { z } from "zod";
11
11
 
12
12
  import { upsertBuilderProxyDesignSystem } from "../server/lib/builder-design-system-proxy.js";
13
13
 
14
- const MAX_CODE_FILES = 50;
15
- const MAX_TOTAL_CODE_BYTES = 2 * 1024 * 1024;
16
-
17
14
  const codeFileSchema = z.object({
18
15
  filename: z.string().trim().min(1).describe("File name or relative path"),
19
16
  content: z.string().describe("Raw text content of the code/design file"),
20
17
  mimeType: z.string().trim().optional().describe("Optional MIME type"),
21
18
  });
22
19
 
23
- function mimeTypeForFilename(filename: string, explicit?: string): string {
24
- if (explicit?.trim()) return explicit.trim();
25
- const lower = filename.toLowerCase();
26
- if (lower.endsWith(".css")) return "text/css";
27
- if (lower.endsWith(".json")) return "application/json";
28
- if (lower.endsWith(".md") || lower.endsWith(".mdx")) return "text/markdown";
29
- if (lower.endsWith(".html")) return "text/html";
30
- if (lower.endsWith(".svg")) return "image/svg+xml";
31
- return "text/plain";
32
- }
33
-
34
- function makeFiles(
35
- codeFiles: Array<z.infer<typeof codeFileSchema>> | undefined,
36
- ): BuilderDesignSystemIndexFile[] {
37
- const encoder = new TextEncoder();
38
- const files: BuilderDesignSystemIndexFile[] = [];
39
- let totalBytes = 0;
40
- for (const file of (codeFiles ?? []).slice(0, MAX_CODE_FILES)) {
41
- const data = encoder.encode(file.content);
42
- if (totalBytes + data.byteLength > MAX_TOTAL_CODE_BYTES) break;
43
- totalBytes += data.byteLength;
44
- files.push({
45
- name: file.filename.replace(/^\/+/, "") || "code.txt",
46
- data,
47
- mimeType: mimeTypeForFilename(file.filename, file.mimeType),
48
- });
49
- }
50
- return files;
51
- }
52
-
53
20
  export default defineAction({
54
21
  description:
55
- "Start Builder design-system indexing from a GitHub repository and/or code files. " +
22
+ "Start Builder DSI design-system indexing from connected code, a GitHub repository, code/design files, and optional design.md guidance. " +
56
23
  "Use this instead of local import-code/import-github when the user wants a reusable brand kit or design system. " +
57
- "Requires Builder.io to be connected; Builder owns the indexed design-system docs, generated guidance, and job state.",
24
+ "Requires Builder.io to be connected; Builder owns the indexed design-system docs, generated guidance, token/component extraction, and job state.",
58
25
  schema: z.object({
59
26
  projectName: z
60
27
  .string()
@@ -76,6 +43,12 @@ export default defineAction({
76
43
  .array(codeFileSchema)
77
44
  .optional()
78
45
  .describe("Optional inlined code/design files to upload to Builder"),
46
+ designMd: z
47
+ .string()
48
+ .optional()
49
+ .describe(
50
+ "Optional design.md guidance to upload to Builder DSI alongside Figma/code sources",
51
+ ),
79
52
  }),
80
53
  run: async ({
81
54
  projectName,
@@ -83,8 +56,12 @@ export default defineAction({
83
56
  githubRepoUrl,
84
57
  connectedProjectId,
85
58
  codeFiles,
59
+ designMd,
86
60
  }) => {
87
- const files = makeFiles(codeFiles);
61
+ const files = buildBuilderDesignSystemIndexFiles({
62
+ codeFiles,
63
+ designMd,
64
+ });
88
65
  const result = await startBuilderDesignSystemIndex({
89
66
  projectName,
90
67
  description,
@@ -19,7 +19,6 @@ import {
19
19
  readCodeWorkbenchTheme,
20
20
  type CodeWorkbenchTheme,
21
21
  } from "../code-workbench-theme";
22
- import { ActivityBar } from "./ActivityBar";
23
22
  import {
24
23
  createCoreCommands,
25
24
  dispatchKeybinding,
@@ -372,7 +371,6 @@ function CodeWorkbenchInner({
372
371
  style={theme.values as CSSProperties}
373
372
  >
374
373
  <div className="flex min-h-0 flex-1">
375
- <ActivityBar />
376
374
  {state.sidebarVisible ? (
377
375
  <>
378
376
  <div
@@ -396,7 +394,9 @@ function CodeWorkbenchInner({
396
394
  ) : null}
397
395
  <div className="flex min-h-0 min-w-0 flex-1 flex-col bg-[var(--workbench-editor-bg)]">
398
396
  <EditorTabs />
399
- {activeTabUri && activePath ? <Breadcrumbs /> : null}
397
+ {activeTabUri && activePath && activePath.includes("/") ? (
398
+ <Breadcrumbs />
399
+ ) : null}
400
400
  <div className="relative min-h-0 flex-1">
401
401
  <MonacoHost
402
402
  editorRef={editorRef}
@@ -1,8 +1,16 @@
1
+ import { IconFiles, IconSearch } from "@tabler/icons-react";
2
+
3
+ import {
4
+ Tooltip,
5
+ TooltipContent,
6
+ TooltipTrigger,
7
+ } from "@/components/ui/tooltip";
1
8
  import { cn } from "@/lib/utils";
2
9
 
10
+ import { formatKeybinding } from "./commands";
3
11
  import { ExplorerView } from "./explorer/ExplorerView";
4
12
  import { SearchView } from "./search/SearchView";
5
- import { useWorkbench } from "./store";
13
+ import { useWorkbench, type SideView } from "./store";
6
14
 
7
15
  export interface SideBarProps {
8
16
  designId: string;
@@ -14,13 +22,30 @@ export interface SideBarProps {
14
22
  ) => void;
15
23
  }
16
24
 
17
- const VIEW_LABELS: Record<"explorer" | "search", string> = {
18
- explorer: "Explorer" /* i18n-ignore */,
19
- search: "Search" /* i18n-ignore */,
20
- };
25
+ interface SideBarTab {
26
+ view: SideView;
27
+ icon: typeof IconFiles;
28
+ label: string;
29
+ keybinding: string;
30
+ }
31
+
32
+ const VIEW_TABS: SideBarTab[] = [
33
+ {
34
+ view: "explorer",
35
+ icon: IconFiles,
36
+ label: "Explorer" /* i18n-ignore */,
37
+ keybinding: "$mod+shift+e",
38
+ },
39
+ {
40
+ view: "search",
41
+ icon: IconSearch,
42
+ label: "Search" /* i18n-ignore */,
43
+ keybinding: "$mod+shift+f",
44
+ },
45
+ ];
21
46
 
22
47
  /**
23
- * Sidebar shell: 35px uppercase header + the active view. Both the explorer
48
+ * Sidebar shell: top view tabs + the active view. Both the explorer
24
49
  * and search views stay mounted (hidden via CSS) so search query/results and
25
50
  * explorer scroll/expansion state survive switching between them.
26
51
  */
@@ -30,13 +55,49 @@ export function SideBar({
30
55
  explorerFocusToken,
31
56
  onRequestLocalWriteConsent,
32
57
  }: SideBarProps) {
33
- const { state } = useWorkbench();
58
+ const { state, api } = useWorkbench();
34
59
  const view = state.sideView;
35
60
 
36
61
  return (
37
62
  <div className="flex min-h-0 flex-1 flex-col">
38
- <div className="flex h-[35px] shrink-0 items-center px-3 text-[11px] font-semibold uppercase tracking-wide text-[var(--workbench-muted-fg)]">
39
- {VIEW_LABELS[view]}
63
+ <div
64
+ role="tablist"
65
+ aria-label="Code sidebar views" /* i18n-ignore */
66
+ className="flex h-10 shrink-0 items-center gap-1 border-b border-[var(--workbench-border)] px-2"
67
+ >
68
+ {VIEW_TABS.map((item) => {
69
+ const Icon = item.icon;
70
+ const active = view === item.view;
71
+ return (
72
+ <Tooltip key={item.view}>
73
+ <TooltipTrigger asChild>
74
+ <button
75
+ type="button"
76
+ role="tab"
77
+ aria-selected={active}
78
+ aria-label={item.label}
79
+ className={cn(
80
+ "relative flex size-8 cursor-pointer items-center justify-center rounded-[5px] text-[var(--workbench-muted-fg)] outline-none transition-colors",
81
+ "hover:bg-[var(--workbench-hover-bg)] hover:text-[var(--workbench-fg)] focus-visible:ring-1 focus-visible:ring-[var(--workbench-accent)]",
82
+ active &&
83
+ "bg-[var(--workbench-list-active-bg,var(--workbench-active-bg))] text-[var(--workbench-accent)]",
84
+ )}
85
+ onClick={() => {
86
+ if (!active) api.setSideView(item.view);
87
+ }}
88
+ >
89
+ {active ? (
90
+ <span className="absolute inset-x-1 bottom-0 h-[2px] rounded-full bg-[var(--workbench-accent)]" />
91
+ ) : null}
92
+ <Icon className="size-[18px]" />
93
+ </button>
94
+ </TooltipTrigger>
95
+ <TooltipContent side="bottom">
96
+ {item.label} {formatKeybinding(item.keybinding)}
97
+ </TooltipContent>
98
+ </Tooltip>
99
+ );
100
+ })}
40
101
  </div>
41
102
  <div className={cn("min-h-0 flex-1", view !== "explorer" && "hidden")}>
42
103
  <ExplorerView
@@ -19,11 +19,16 @@ import {
19
19
  ContextMenuSeparator,
20
20
  ContextMenuTrigger,
21
21
  } from "@/components/ui/context-menu";
22
+ import { prettyScreenName } from "@/lib/screen-names";
22
23
  import { cn } from "@/lib/utils";
23
24
 
24
25
  import { FileIcon } from "../explorer/file-icons";
25
26
  import { useWorkbench, type EditorTab } from "../store";
26
- import { baseName, parseWorkbenchUri } from "../workspace/types";
27
+ import {
28
+ baseName,
29
+ parseWorkbenchUri,
30
+ providerKindFromKey,
31
+ } from "../workspace/types";
27
32
  import { isTabReorderNoop, resolveTabDropIndex } from "./tab-drag";
28
33
 
29
34
  interface PendingClose {
@@ -267,7 +272,11 @@ function EditorTabRow({
267
272
  const [hovered, setHovered] = useState(false);
268
273
  const meta = state.buffers[tab.uri];
269
274
  const dirty = meta?.dirty ?? false;
270
- const name = baseName(tab.path);
275
+ const fileName = baseName(tab.path);
276
+ const name =
277
+ providerKindFromKey(tab.providerKey) === "inline"
278
+ ? prettyScreenName(fileName)
279
+ : fileName;
271
280
 
272
281
  return (
273
282
  <ContextMenu>
@@ -69,7 +69,7 @@ export function MonacoHost({
69
69
  fontFamily: MONACO_FONT_FAMILY,
70
70
  fontSize: 12,
71
71
  lineHeight: 20,
72
- minimap: { enabled: true, scale: 0.75, showSlider: "mouseover" },
72
+ minimap: { enabled: false },
73
73
  bracketPairColorization: { enabled: true },
74
74
  guides: { bracketPairs: true, indentation: true },
75
75
  lineNumbers: "on",
@@ -161,7 +161,7 @@ export function StatusBar({ editorRef, onGoToLine }: StatusBarProps) {
161
161
  onClick={() => activeUri && void api.reloadBuffer(activeUri)}
162
162
  className="flex cursor-pointer items-center gap-1 rounded-[3px] px-1.5 text-[var(--workbench-warning)] hover:bg-[var(--workbench-list-hover-bg)]"
163
163
  >
164
- {"File changed externallyclick to reload" /* i18n-ignore */}
164
+ {"File changed elsewherereload latest" /* i18n-ignore */}
165
165
  </button>
166
166
  ) : null}
167
167
  </div>
@@ -1,9 +1,11 @@
1
1
  import { useActionQuery } from "@agent-native/core/client";
2
2
  import { useCallback, useEffect, useMemo, useState } from "react";
3
3
 
4
+ import { prettyScreenName } from "@/lib/screen-names";
5
+
4
6
  import { useWorkbench } from "../store";
5
7
  import { buildFileTree } from "../workspace/tree";
6
- import type { WorkspaceFileEntry } from "../workspace/types";
8
+ import { baseName, type WorkspaceFileEntry } from "../workspace/types";
7
9
  import { FileTree } from "./FileTree";
8
10
 
9
11
  export interface ExplorerViewProps {
@@ -40,7 +42,11 @@ export function ExplorerView({
40
42
  return files.map((file) => ({
41
43
  path: String(file.path ?? ""),
42
44
  displayName:
43
- typeof file.displayName === "string" ? file.displayName : undefined,
45
+ typeof file.path === "string"
46
+ ? prettyScreenName(baseName(file.path))
47
+ : typeof file.displayName === "string"
48
+ ? file.displayName
49
+ : undefined,
44
50
  fileId: typeof file.fileId === "string" ? file.fileId : undefined,
45
51
  readonly: Boolean(file.readonly),
46
52
  }));
@@ -34,7 +34,11 @@ import { cn } from "@/lib/utils";
34
34
 
35
35
  import { useWorkbench } from "../store";
36
36
  import { flattenVisibleTree, type TreeNode } from "../workspace/tree";
37
- import { workbenchUri, type WorkspaceCapabilities } from "../workspace/types";
37
+ import {
38
+ baseName,
39
+ workbenchUri,
40
+ type WorkspaceCapabilities,
41
+ } from "../workspace/types";
38
42
  import { FileIcon, FolderIcon } from "./file-icons";
39
43
 
40
44
  interface PendingNewFile {
@@ -118,7 +122,7 @@ export function FileTree({
118
122
 
119
123
  const startRename = useCallback((node: TreeNode) => {
120
124
  setRenamingPath(node.path);
121
- setRenameDraft(node.name);
125
+ setRenameDraft(baseName(node.path));
122
126
  }, []);
123
127
 
124
128
  const handleWriteError = useCallback(
@@ -145,7 +149,7 @@ export function FileTree({
145
149
  async (node: TreeNode) => {
146
150
  const nextName = renameDraft.trim();
147
151
  setRenamingPath(null);
148
- if (!nextName || nextName === node.name) return;
152
+ if (!nextName || nextName === baseName(node.path)) return;
149
153
  const parentPath = node.path.split("/").slice(0, -1).join("/");
150
154
  const nextPath = parentPath ? `${parentPath}/${nextName}` : nextName;
151
155
  try {
@@ -591,6 +591,34 @@ export function WorkbenchProvider({
591
591
  },
592
592
  });
593
593
  } catch (error) {
594
+ if (error instanceof WorkspaceStaleVersionError) {
595
+ try {
596
+ const latest = await provider.readFile(path);
597
+ if (latest.content === content) {
598
+ rememberVersionHash(uri, latest.versionHash);
599
+ modelRegistry.markSaved(uri, altVersionId);
600
+ dispatch({
601
+ type: "PATCH_BUFFER",
602
+ uri,
603
+ patch: {
604
+ saving: false,
605
+ dirty: modelRegistry.isDirty(uri),
606
+ conflict: false,
607
+ readonly: latest.readonly ?? meta.readonly,
608
+ language: latest.language ?? meta.language,
609
+ fileId: latest.fileId ?? meta.fileId,
610
+ savedVersionHash:
611
+ latest.versionHash ?? meta.savedVersionHash,
612
+ lastSavedAt: Date.now(),
613
+ },
614
+ });
615
+ return;
616
+ }
617
+ } catch {
618
+ // Keep the original stale-version error; the user can reload
619
+ // latest from the status bar without losing this buffer first.
620
+ }
621
+ }
594
622
  dispatch({
595
623
  type: "PATCH_BUFFER",
596
624
  uri,
@@ -619,6 +647,26 @@ export function WorkbenchProvider({
619
647
  if (read.versionHash && read.versionHash === meta.savedVersionHash) {
620
648
  return;
621
649
  }
650
+ const entry = modelRegistry.get(uri);
651
+ if (entry && !entry.model.isDisposed()) {
652
+ if (entry.model.getValue() === read.content) {
653
+ rememberVersionHash(uri, read.versionHash);
654
+ modelRegistry.markSaved(uri, entry.model.getAlternativeVersionId());
655
+ dispatch({
656
+ type: "PATCH_BUFFER",
657
+ uri,
658
+ patch: {
659
+ savedVersionHash: read.versionHash ?? meta.savedVersionHash,
660
+ dirty: false,
661
+ conflict: false,
662
+ readonly: read.readonly ?? meta.readonly,
663
+ language: read.language ?? meta.language,
664
+ fileId: read.fileId ?? meta.fileId,
665
+ },
666
+ });
667
+ return;
668
+ }
669
+ }
622
670
  // Stale echo: a poll that resolved out of order carries a hash this
623
671
  // client already loaded or saved. Never apply it over newer content.
624
672
  if (
@@ -174,6 +174,12 @@ export function isDesignHotkeyEditableTarget(target: EventTarget | null) {
174
174
  ) {
175
175
  return true;
176
176
  }
177
+ if (
178
+ editable instanceof HTMLElement &&
179
+ editable.getAttribute("role") === "textbox"
180
+ ) {
181
+ return true;
182
+ }
177
183
  const tagName = editable.tagName.toLowerCase();
178
184
  return tagName === "input" || tagName === "textarea" || tagName === "select";
179
185
  }
@@ -746,20 +746,20 @@ const messages = {
746
746
  continue: "繼續生成",
747
747
  title: "設定您的設計系統",
748
748
  description:
749
- "提供來源的任意組合。您提供的脈絡越多,擷取的設計系統就越準確。",
750
- figmaParsingTitle: "正在解析您的 Figma 檔案...",
751
- figmaParsingDescription: "解碼檔案並擷取品牌權杖",
752
- uploadFig: "上傳.fig 檔案",
753
- figmaSaveLocalCopy: "Figma中:檔案->儲存本機副本",
749
+ "透過 Builder DSI 連接 Figma、程式碼和選用的 design.md 指引。脈絡越多,代理得到的系統越準確。",
750
+ figmaParsingTitle: "正在啟動 Builder DSI 索引...",
751
+ figmaParsingDescription: "Builder 會擷取權杖、元件、資產和使用指引",
752
+ uploadFig: "連接 Figma .fig 檔案",
753
+ figmaSaveLocalCopy: "上傳 Figma 本機副本:File -> Save local copy",
754
754
  websiteUrl: "網站 URL",
755
755
  add: "新增",
756
756
  githubRepository: "GitHub 儲存庫",
757
757
  privateRepoPrefix: "私人倉庫需要一個細粒度的權杖,另存為",
758
758
  privateRepoSuffix: "具有內容讀取權限。",
759
- localCodeFiles: "本機程式碼檔案",
760
- dropCodeFiles: "將 CSS、Tailwind 設定、主題檔案拖放到此處,或點選瀏覽",
759
+ localCodeFiles: "連接程式碼檔案",
760
+ dropCodeFiles: "將 CSS、Tailwind 設定、主題檔案或 design.md 拖放到此處",
761
761
  codeFilePatterns:
762
- "檔案型別: .css、.scss、tailwind.config.*、theme.*、tokens.*、package.json",
762
+ "檔案型別: .css、.scss、tailwind.config.*、theme.*、tokens.*、design.md、package.json",
763
763
  documents: "檔案和簡報",
764
764
  documentsHelp: "PPTX、DOCX、PDF、XLSX - 品牌指南、推介材料、風格檔案",
765
765
  visualReferences: "螢幕截圖和視覺參考",
@@ -800,21 +800,22 @@ const messages = {
800
800
  },
801
801
  sections: {
802
802
  figma: {
803
- title: " Figma 檔案開始",
803
+ title: "連接 Figma",
804
804
  description:
805
- "上傳.fig,我們會將品牌(顏色、字型比例、簽名漸變和品牌特徵簡介)深入擷取到即用型設計系統中。",
805
+ "上傳 .fig,Builder DSI 會將權杖、元件、資產和品牌指引索引成可重用的設計系統。",
806
806
  },
807
807
  company: {
808
808
  title: "公司/品牌",
809
809
  description: "名稱、描述和網站",
810
810
  },
811
811
  code: {
812
- title: "程式碼",
813
- description: "GitHub 儲存庫或本機檔案 - 設計權杖的最強信號",
812
+ title: "連接程式碼",
813
+ description:
814
+ "GitHub 儲存庫、本機程式碼檔案或 design.md 會交給 Builder DSI 索引。",
814
815
  },
815
816
  designFiles: {
816
- title: "設計檔案",
817
- description: "Figma 檔案、檔案、螢幕截圖、品牌資產",
817
+ title: "參考檔案",
818
+ description: "文件、截圖和品牌資產會補充 Builder DSI 的索引脈絡",
818
819
  },
819
820
  importExisting: {
820
821
  title: "從現有的匯入",