History

Add workspace file browser and preview panel (#3087)

Julius Marminge committed 5 months agov0.0.28-nightly.20260615.565

Commit de8bdc11 parent 477795662 files · +2850 −9551Browse files

Unified · Split

62 files
  1. apps/server/src/server.test.ts +36 −0
  2. apps/server/src/workspace/Layers/WorkspaceEntries.test.ts +29 −0
  3. apps/server/src/workspace/Layers/WorkspaceEntries.ts +15 −0
  4. apps/server/src/workspace/Layers/WorkspaceFileSystem.test.ts +58 −0
  5. apps/server/src/workspace/Layers/WorkspaceFileSystem.ts +66 −1
  6. apps/server/src/workspace/Services/WorkspaceEntries.ts +9 −0
  7. apps/server/src/workspace/Services/WorkspaceFileSystem.ts +21 −2
  8. apps/server/src/ws.ts +31 −0
  9. apps/web/THIRD_PARTY_NOTICES.md +11 −0
  10. apps/web/package.json +1 −0
  11. apps/web/src/components/ChatMarkdown.browser.tsx +90 −2
  12. apps/web/src/components/ChatMarkdown.tsx +34 −26
  13. apps/web/src/components/ChatView.browser.tsx +368 −13
  14. apps/web/src/components/ChatView.tsx +174 −34
  15. apps/web/src/components/ComposerPromptEditor.tsx +1 −1
  16. apps/web/src/components/DiffWorkerPoolProvider.tsx +1 −0
  17. apps/web/src/components/NoActiveThreadState.tsx +2 −4
  18. apps/web/src/components/RightPanelTabs.tsx +150 −71
  19. apps/web/src/components/chat/ChangedFilesTree.tsx +2 −2
  20. apps/web/src/components/chat/ChatComposer.tsx +1 −1
  21. apps/web/src/components/chat/ChatHeader.tsx +11 −64
  22. apps/web/src/components/chat/ComposerCommandMenu.tsx +2 −2
  23. apps/web/src/components/chat/FileTagChip.tsx +3 −3
  24. apps/web/src/components/chat/MessagesTimeline.browser.tsx +2 −6
  25. apps/web/src/components/chat/PanelLayoutControls.tsx +114 −0
  26. apps/web/src/components/chat/PierreEntryIcon.tsx +95 −0
  27. apps/web/src/components/chat/VscodeEntryIcon.tsx +0 −37
  28. apps/web/src/components/files/FileBrowserPanel.tsx +128 −0
  29. apps/web/src/components/files/FilePreviewPanel.tsx +298 −0
  30. apps/web/src/components/files/fileContentRevision.test.ts +15 −0
  31. apps/web/src/components/files/fileContentRevision.ts +12 −0
  32. apps/web/src/components/files/filePath.test.ts +23 −0
  33. apps/web/src/components/files/filePath.ts +17 −0
  34. apps/web/src/components/files/fileSaveCoordinator.test.ts +87 −0
  35. apps/web/src/components/files/fileSaveCoordinator.ts +75 −0
  36. apps/web/src/components/files/projectFilesQueryState.test.ts +129 −0
  37. apps/web/src/components/files/projectFilesQueryState.ts +206 −0
  38. apps/web/src/components/preview/PreviewPanelShell.tsx +13 −4
  39. apps/web/src/environmentApi.ts +2 −0
  40. apps/web/src/environments/runtime/service.threadSubscriptions.test.ts +2 −0
  41. apps/web/src/index.css +43 −0
  42. apps/web/src/localApi.test.ts +2 −0
  43. apps/web/src/markdown-links.test.ts +9 −0
  44. apps/web/src/markdown-links.ts +15 −0
  45. apps/web/src/pierre-icons.test.ts +57 −0
  46. apps/web/src/pierre-icons.ts +117 −0
  47. apps/web/src/rightPanelStore.test.ts +48 −0
  48. apps/web/src/rightPanelStore.ts +52 −7
  49. apps/web/src/vscode-icons-language-associations.json +0 −481
  50. apps/web/src/vscode-icons-manifest.json +0 −8351
  51. apps/web/src/vscode-icons.test.ts +0 −52
  52. apps/web/src/vscode-icons.ts +0 −211
  53. apps/web/vite.config.ts +1 −0
  54. package.json +0 −1
  55. packages/client-runtime/src/wsRpcClient.ts +6 −0
  56. packages/contracts/src/ipc.ts +6 −0
  57. packages/contracts/src/project.ts +43 −1
  58. packages/contracts/src/rpc.ts +22 −0
  59. patches/@pierre%2Fdiffs@1.3.0-beta.4.patch +2 −2
  60. pnpm-lock.yaml +89 −17
  61. pnpm-workspace.yaml +4 −2
  62. scripts/sync-vscode-icons.mjs +0 −153
apps/server/src/server.test.ts+36−0
@@ -4357,6 +4357,42 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 4356 unmodified lines
43574357 }).pipe(Effect.provide(NodeHttpServer.layerTest)),
43584358 );
43594359
4360+ it.effect("routes websocket rpc projects.listEntries and projects.readFile", () =>
4361+ Effect.gen(function* () {
4362+ const fs = yield* FileSystem.FileSystem;
4363+ const path = yield* Path.Path;
4364+ const workspaceDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-ws-project-files-" });
4365+ yield* fs.makeDirectory(path.join(workspaceDir, "src"), { recursive: true });
4366+ yield* fs.writeFileString(
4367+ path.join(workspaceDir, "src", "index.ts"),
4368+ "export const answer = 42;\n",
4369+ );
4370+
4371+ yield* buildAppUnderTest();
4372+
4373+ const wsUrl = yield* getWsServerUrl("/ws");
4374+ const response = yield* Effect.scoped(
4375+ withWsRpcClient(wsUrl, (client) =>
4376+ Effect.all({
4377+ listing: client[WS_METHODS.projectsListEntries]({ cwd: workspaceDir }),
4378+ file: client[WS_METHODS.projectsReadFile]({
4379+ cwd: workspaceDir,
4380+ relativePath: "src/index.ts",
4381+ }),
4382+ }),
4383+ ),
4384+ );
4385+
4386+ assert.isTrue(response.listing.entries.some((entry) => entry.path === "src/index.ts"));
4387+ assert.deepEqual(response.file, {
4388+ relativePath: "src/index.ts",
4389+ contents: "export const answer = 42;\n",
4390+ byteLength: 26,
4391+ truncated: false,
4392+ });
4393+ }).pipe(Effect.provide(NodeHttpServer.layerTest)),
4394+ );
4395+
43604396 it.effect("routes websocket rpc projects.searchEntries excludes gitignored files", () =>
43614397 Effect.gen(function* () {
43624398 const fs = yield* FileSystem.FileSystem;
apps/server/src/workspace/Layers/WorkspaceEntries.test.ts+29−0
@@ -87,6 +87,35 @@ it.layer(TestLayer)("WorkspaceEntriesLive", (it) => { · 86 unmodified lines
8787 vi.restoreAllMocks();
8888 });
8989
90+ describe("list", () => {
91+ it.effect("returns the complete cached workspace index", () =>
92+ Effect.gen(function* () {
93+ const cwd = yield* makeTempDir();
94+ yield* writeTextFile(cwd, "src/components/Composer.tsx");
95+ yield* writeTextFile(cwd, "README.md");
96+ yield* writeTextFile(cwd, "node_modules/pkg/index.js");
97+
98+ const workspaceEntries = yield* WorkspaceEntries;
99+ const result = yield* workspaceEntries.list({ cwd });
100+
101+ expect(result.entries).toEqual(
102+ expect.arrayContaining([
103+ { path: "src", kind: "directory" },
104+ { path: "src/components", kind: "directory", parentPath: "src" },
105+ {
106+ path: "src/components/Composer.tsx",
107+ kind: "file",
108+ parentPath: "src/components",
109+ },
110+ { path: "README.md", kind: "file" },
111+ ]),
112+ );
113+ expect(result.entries.some((entry) => entry.path.startsWith("node_modules"))).toBe(false);
114+ expect(result.truncated).toBe(false);
115+ }),
116+ );
117+ });
118+
90119 describe("search", () => {
91120 it.effect("returns files and directories relative to cwd", () =>
92121 Effect.gen(function* () {
apps/server/src/workspace/Layers/WorkspaceEntries.ts+15−0
@@ -530,9 +530,24 @@ export const makeWorkspaceEntries = Effect.gen(function* () { · 529 unmodified lines
530530 },
531531 );
532532
533+ const list: WorkspaceEntriesShape["list"] = Effect.fn("WorkspaceEntries.list")(function* (input) {
534+ const normalizedCwd = yield* normalizeWorkspaceRoot(input.cwd);
535+ return yield* Cache.get(workspaceIndexCache, normalizedCwd).pipe(
536+ Effect.map((index) => ({
537+ entries: index.entries.map(({ path: entryPath, kind, parentPath }) => ({
538+ path: entryPath,
539+ kind,
540+ ...(parentPath ? { parentPath } : {}),
541+ })),
542+ truncated: index.truncated,
543+ })),
544+ );
545+ });
546+
533547 return {
534548 browse,
535549 invalidate,
550+ list,
536551 search,
537552 } satisfies WorkspaceEntriesShape;
538553 });
apps/server/src/workspace/Layers/WorkspaceFileSystem.test.ts+58−0
@@ -54,6 +54,64 @@ const writeTextFile = Effect.fn("writeTextFile")(function* ( · 53 unmodified lines
5454 });
5555
5656 it.layer(TestLayer)("WorkspaceFileSystemLive", (it) => {
57+ describe("readFile", () => {
58+ it.effect("reads UTF-8 files relative to the workspace root", () =>
59+ Effect.gen(function* () {
60+ const workspaceFileSystem = yield* WorkspaceFileSystem;
61+ const cwd = yield* makeTempDir;
62+ yield* writeTextFile(cwd, "src/index.ts", "export const answer = 42;\n");
63+
64+ const result = yield* workspaceFileSystem.readFile({
65+ cwd,
66+ relativePath: "src/index.ts",
67+ });
68+
69+ expect(result).toEqual({
70+ relativePath: "src/index.ts",
71+ contents: "export const answer = 42;\n",
72+ byteLength: 26,
73+ truncated: false,
74+ });
75+ }),
76+ );
77+
78+ it.effect("rejects reads outside the workspace root", () =>
79+ Effect.gen(function* () {
80+ const workspaceFileSystem = yield* WorkspaceFileSystem;
81+ const cwd = yield* makeTempDir;
82+
83+ const error = yield* workspaceFileSystem
84+ .readFile({ cwd, relativePath: "../escape.md" })
85+ .pipe(Effect.flip);
86+
87+ expect(error.message).toContain(
88+ "Workspace file path must be relative to the project root: ../escape.md",
89+ );
90+ }),
91+ );
92+
93+ it.effect("rejects symlinks that resolve outside the workspace root", () =>
94+ Effect.gen(function* () {
95+ const workspaceFileSystem = yield* WorkspaceFileSystem;
96+ const fileSystem = yield* FileSystem.FileSystem;
97+ const path = yield* Path.Path;
98+ const cwd = yield* makeTempDir;
99+ const outsideDir = yield* makeTempDir;
100+ yield* writeTextFile(outsideDir, "secret.txt", "outside\n");
101+ yield* fileSystem.symlink(
102+ path.join(outsideDir, "secret.txt"),
103+ path.join(cwd, "linked-secret.txt"),
104+ );
105+
106+ const error = yield* workspaceFileSystem
107+ .readFile({ cwd, relativePath: "linked-secret.txt" })
108+ .pipe(Effect.flip);
109+
110+ expect(error.message).toContain("resolves outside the project root");
111+ }),
112+ );
113+ });
114+
57115 describe("writeFile", () => {
58116 it.effect("writes files relative to the workspace root", () =>
59117 Effect.gen(function* () {
apps/server/src/workspace/Layers/WorkspaceFileSystem.ts+66−1
@@ -1,3 +1,6 @@
1+// @effect-diagnostics nodeBuiltinImport:off
2+import fsPromises from "node:fs/promises";
3+
14 import * as Effect from "effect/Effect";
25 import * as FileSystem from "effect/FileSystem";
36 import * as Layer from "effect/Layer";
@@ -11,12 +14,74 @@ import { · 7 unmodified lines
1114 import { WorkspaceEntries } from "../Services/WorkspaceEntries.ts";
1215 import { WorkspacePaths } from "../Services/WorkspacePaths.ts";
1316
17+const PROJECT_READ_FILE_MAX_BYTES = 1024 * 1024;
18+
1419 export const makeWorkspaceFileSystem = Effect.gen(function* () {
1520 const fileSystem = yield* FileSystem.FileSystem;
1621 const path = yield* Path.Path;
1722 const workspacePaths = yield* WorkspacePaths;
1823 const workspaceEntries = yield* WorkspaceEntries;
1924
25+ const readFile: WorkspaceFileSystemShape["readFile"] = Effect.fn("WorkspaceFileSystem.readFile")(
26+ function* (input) {
27+ const target = yield* workspacePaths.resolveRelativePathWithinRoot({
28+ workspaceRoot: input.cwd,
29+ relativePath: input.relativePath,
30+ });
31+
32+ const result = yield* Effect.tryPromise({
33+ try: async () => {
34+ const [realWorkspaceRoot, realTargetPath] = await Promise.all([
35+ fsPromises.realpath(input.cwd),
36+ fsPromises.realpath(target.absolutePath),
37+ ]);
38+ const relativeRealPath = path.relative(realWorkspaceRoot, realTargetPath);
39+ if (
40+ relativeRealPath.startsWith(`..${path.sep}`) ||
41+ relativeRealPath === ".." ||
42+ path.isAbsolute(relativeRealPath)
43+ ) {
44+ throw new Error("Workspace file path resolves outside the project root.");
45+ }
46+
47+ const handle = await fsPromises.open(realTargetPath, "r");
48+ try {
49+ const stat = await handle.stat();
50+ if (!stat.isFile()) {
51+ throw new Error("Workspace path is not a file.");
52+ }
53+ const bytesToRead = Math.min(stat.size, PROJECT_READ_FILE_MAX_BYTES);
54+ const buffer = Buffer.alloc(bytesToRead);
55+ const { bytesRead } = await handle.read(buffer, 0, bytesToRead, 0);
56+ const fileBytes = buffer.subarray(0, bytesRead);
57+ if (fileBytes.includes(0)) {
58+ throw new Error("Binary files cannot be previewed as text.");
59+ }
60+ const contents = new TextDecoder("utf-8").decode(fileBytes);
61+ return {
62+ relativePath: target.relativePath,
63+ contents,
64+ byteLength: stat.size,
65+ truncated: stat.size > PROJECT_READ_FILE_MAX_BYTES,
66+ };
67+ } finally {
68+ await handle.close();
69+ }
70+ },
71+ catch: (cause) =>
72+ new WorkspaceFileSystemError({
73+ cwd: input.cwd,
74+ relativePath: input.relativePath,
75+ operation: "workspaceFileSystem.readFile",
76+ detail: cause instanceof Error ? cause.message : String(cause),
77+ cause,
78+ }),
79+ });
80+
81+ return result;
82+ },
83+ );
84+
2085 const writeFile: WorkspaceFileSystemShape["writeFile"] = Effect.fn(
2186 "WorkspaceFileSystem.writeFile",
2287 )(function* (input) {
@@ -52,7 +117,7 @@ export const makeWorkspaceFileSystem = Effect.gen(function* () { · 29 unmodified lines
52117 yield* workspaceEntries.invalidate(input.cwd);
53118 return { relativePath: target.relativePath };
54119 });
55− return { writeFile } satisfies WorkspaceFileSystemShape;
120+ return { readFile, writeFile } satisfies WorkspaceFileSystemShape;
56121 });
57122
58123 export const WorkspaceFileSystemLive = Layer.effect(WorkspaceFileSystem, makeWorkspaceFileSystem);
apps/server/src/workspace/Services/WorkspaceEntries.ts+9−0
@@ -13,6 +13,8 @@ import type * as Effect from "effect/Effect"; · 12 unmodified lines
1313 import type {
1414 FilesystemBrowseInput,
1515 FilesystemBrowseResult,
16+ ProjectListEntriesInput,
17+ ProjectListEntriesResult,
1618 ProjectSearchEntriesInput,
1719 ProjectSearchEntriesResult,
1820 } from "@t3tools/contracts";
@@ -50,6 +52,13 @@ export interface WorkspaceEntriesShape { · 31 unmodified lines
5052 input: FilesystemBrowseInput,
5153 ) => Effect.Effect<FilesystemBrowseResult, WorkspaceEntriesBrowseError>;
5254
55+ /**
56+ * List the cached workspace index for a project root.
57+ */
58+ readonly list: (
59+ input: ProjectListEntriesInput,
60+ ) => Effect.Effect<ProjectListEntriesResult, WorkspaceEntriesError>;
61+
5362 /**
5463 * Search indexed workspace entries for files and directories matching the
5564 * provided query.
apps/server/src/workspace/Services/WorkspaceFileSystem.ts+21−2
@@ -10,7 +10,12 @@ import * as Schema from "effect/Schema"; · 9 unmodified lines
1010 import * as Context from "effect/Context";
1111 import type * as Effect from "effect/Effect";
1212
13−import type { ProjectWriteFileInput, ProjectWriteFileResult } from "@t3tools/contracts";
13+import type {
14+ ProjectReadFileInput,
15+ ProjectReadFileResult,
16+ ProjectWriteFileInput,
17+ ProjectWriteFileResult,
18+} from "@t3tools/contracts";
1419 import { WorkspacePathOutsideRootError } from "./WorkspacePaths.ts";
1520
1621 export class WorkspaceFileSystemError extends Schema.TaggedErrorClass<WorkspaceFileSystemError>()(
@@ -22,12 +27,26 @@ export class WorkspaceFileSystemError extends Schema.TaggedErrorClass<WorkspaceF · 5 unmodified lines
2227 detail: Schema.String,
2328 cause: Schema.optional(Schema.Defect()),
2429 },
25−) {}
30+) {
31+ override get message(): string {
32+ return this.detail;
33+ }
34+}
2635
2736 /**
2837 * WorkspaceFileSystemShape - Service API for workspace-relative file operations.
2938 */
3039 export interface WorkspaceFileSystemShape {
40+ /**
41+ * Read a UTF-8 text file relative to the workspace root.
42+ */
43+ readonly readFile: (
44+ input: ProjectReadFileInput,
45+ ) => Effect.Effect<
46+ ProjectReadFileResult,
47+ WorkspaceFileSystemError | WorkspacePathOutsideRootError
48+ >;
49+
3150 /**
3251 * Write a file relative to the workspace root.
3352 *
apps/server/src/ws.ts+31−0
@@ -34,6 +34,8 @@ import { · 33 unmodified lines
3434 OrchestrationGetSnapshotError,
3535 OrchestrationGetTurnDiffError,
3636 ORCHESTRATION_WS_METHODS,
37+ ProjectListEntriesError,
38+ ProjectReadFileError,
3739 ProjectSearchEntriesError,
3840 ProjectWriteFileError,
3941 RelayClientInstallFailedError,
@@ -160,6 +162,8 @@ const RPC_REQUIRED_SCOPE = new Map<string, AuthEnvironmentScope>([ · 120 unmodified lines
160162 [WS_METHODS.sourceControlLookupRepository, AuthOrchestrationReadScope],
161163 [WS_METHODS.sourceControlCloneRepository, AuthOrchestrationOperateScope],
162164 [WS_METHODS.sourceControlPublishRepository, AuthOrchestrationOperateScope],
165+ [WS_METHODS.projectsListEntries, AuthOrchestrationReadScope],
166+ [WS_METHODS.projectsReadFile, AuthOrchestrationReadScope],
163167 [WS_METHODS.projectsSearchEntries, AuthOrchestrationReadScope],
164168 [WS_METHODS.projectsWriteFile, AuthOrchestrationOperateScope],
165169 [WS_METHODS.shellOpenInEditor, AuthOrchestrationOperateScope],
@@ -1172,6 +1176,33 @@ const makeWsRpcLayer = (currentSession: AuthenticatedSession) => · 1006 unmodified lines
11721176 ),
11731177 { "rpc.aggregate": "workspace" },
11741178 ),
1179+ [WS_METHODS.projectsListEntries]: (input) =>
1180+ observeRpcEffect(
1181+ WS_METHODS.projectsListEntries,
1182+ workspaceEntries.list(input).pipe(
1183+ Effect.mapError(
1184+ (cause) =>
1185+ new ProjectListEntriesError({
1186+ message: `Failed to list workspace entries: ${cause.detail}`,
1187+ cause,
1188+ }),
1189+ ),
1190+ ),
1191+ { "rpc.aggregate": "workspace" },
1192+ ),
1193+ [WS_METHODS.projectsReadFile]: (input) =>
1194+ observeRpcEffect(
1195+ WS_METHODS.projectsReadFile,
1196+ workspaceFileSystem.readFile(input).pipe(
1197+ Effect.mapError((cause) => {
1198+ const message = isWorkspacePathOutsideRootError(cause)
1199+ ? "Workspace file path must stay within the project root."
1200+ : `Failed to read workspace file: ${cause.detail}`;
1201+ return new ProjectReadFileError({ message, cause });
1202+ }),
1203+ ),
1204+ { "rpc.aggregate": "workspace" },
1205+ ),
11751206 [WS_METHODS.projectsWriteFile]: (input) =>
11761207 observeRpcEffect(
11771208 WS_METHODS.projectsWriteFile,
apps/web/THIRD_PARTY_NOTICES.md+11−0
@@ -0,0 +1,11 @@
1+# Third-Party Notices
2+
3+## vscode-icons
4+
5+The custom file icon symbols in `src/pierre-icons.ts` are adapted from the
6+[`vscode-icons`](https://github.com/vscode-icons/vscode-icons) project.
7+
8+Copyright (c) 2016 Roberto Huertas
9+
10+Licensed under the MIT License. The full license text is available in the
11+upstream repository: <https://github.com/vscode-icons/vscode-icons/blob/master/LICENSE>.
apps/web/package.json+1−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 "@legendapp/list": "3.0.0-beta.44",
2828 "@lexical/react": "^0.41.0",
2929 "@pierre/diffs": "catalog:",
30+ "@pierre/trees": "1.0.0-beta.4",
3031 "@t3tools/client-runtime": "workspace:*",
3132 "@t3tools/contracts": "workspace:*",
3233 "@t3tools/shared": "workspace:*",
apps/web/src/components/ChatMarkdown.browser.tsx+90−2
@@ -50,6 +50,7 @@ vi.mock("../browser/openFileInPreview", async (importOriginal) => ({ · 49 unmodified lines
5050 import ChatMarkdown from "./ChatMarkdown";
5151 import { serializeTableElementToCsv, serializeTableElementToMarkdown } from "../markdown-clipboard";
5252 import { EnvironmentId, ThreadId } from "@t3tools/contracts";
53+import { selectThreadRightPanelState, useRightPanelStore } from "../rightPanelStore";
5354
5455 const threadRef = {
5556 environmentId: EnvironmentId.make("environment-test"),
@@ -63,6 +64,7 @@ describe("ChatMarkdown", () => { · 7 unmodified lines
6364 openUrlInPreviewMock.mockClear();
6465 contextMenuShowMock.mockReset();
6566 readLocalApiMock.mockClear();
67+ useRightPanelStore.setState({ byThreadKey: {} });
6668 localStorage.clear();
6769 document.body.innerHTML = "";
6870 });
@@ -248,6 +250,92 @@ describe("ChatMarkdown", () => { · 179 unmodified lines
248250 }
249251 });
250252
253+ it("opens code file links in the right-panel file preview", async () => {
254+ const screen = await render(
255+ <ChatMarkdown
256+ text="[ChatMarkdown.tsx](apps/web/src/components/ChatMarkdown.tsx#L978)"
257+ cwd="/repo/project"
258+ threadRef={threadRef}
259+ />,
260+ );
261+
262+ try {
263+ await page.getByRole("link", { name: "ChatMarkdown.tsx · L978" }).click();
264+
265+ await vi.waitFor(() => {
266+ expect(
267+ selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, threadRef),
268+ ).toMatchObject({
269+ isOpen: true,
270+ activeSurfaceId: "file:apps/web/src/components/ChatMarkdown.tsx",
271+ });
272+ expect(openInPreferredEditorMock).not.toHaveBeenCalled();
273+ expect(openFileInPreviewMock).not.toHaveBeenCalled();
274+ });
275+ } finally {
276+ await screen.unmount();
277+ }
278+ });
279+
280+ it("opens HTML and PDF file links in the integrated browser preview", async () => {
281+ const screen = await render(
282+ <ChatMarkdown
283+ text="[report.html](report.html) [report.pdf](report.pdf)"
284+ cwd="/repo/project"
285+ threadRef={threadRef}
286+ />,
287+ );
288+
289+ try {
290+ await page.getByRole("link", { name: "report.html" }).click();
291+ await page.getByRole("link", { name: "report.pdf" }).click();
292+
293+ await vi.waitFor(() => {
294+ expect(openFileInPreviewMock).toHaveBeenNthCalledWith(
295+ 1,
296+ threadRef,
297+ "/repo/project/report.html",
298+ );
299+ expect(openFileInPreviewMock).toHaveBeenNthCalledWith(
300+ 2,
301+ threadRef,
302+ "/repo/project/report.pdf",
303+ );
304+ expect(openInPreferredEditorMock).not.toHaveBeenCalled();
305+ });
306+ } finally {
307+ await screen.unmount();
308+ }
309+ });
310+
311+ it("keeps opening file links in the editor from the context menu", async () => {
312+ contextMenuShowMock.mockResolvedValue("open");
313+ const filePath = "/repo/project/src/index.ts";
314+ const screen = await render(
315+ <ChatMarkdown text="[index.ts](src/index.ts)" cwd="/repo/project" threadRef={threadRef} />,
316+ );
317+
318+ try {
319+ page
320+ .getByRole("link", { name: "index.ts" })
321+ .element()
322+ .dispatchEvent(
323+ new MouseEvent("contextmenu", {
324+ bubbles: true,
325+ cancelable: true,
326+ clientX: 4,
327+ clientY: 8,
328+ }),
329+ );
330+
331+ await vi.waitFor(() => {
332+ expect(openInPreferredEditorMock).toHaveBeenCalledWith(expect.anything(), filePath);
333+ });
334+ } finally {
335+ await screen.unmount();
336+ }
337+ });
338+
251339 it("keeps a favicon with the leading segment of a wrapping URL", async () => {
252340 const url = "https://github.com/pingdotgg/t3code/pull/3017/changes";
253341 const screen = await render(
@@ -429,7 +517,7 @@ describe("ChatMarkdown", () => { · 175 unmodified lines
429517
430518 // Language with a known icon: icon XOR text — never the redundant pair.
431519 const languageOnly = titles[0]!;
432− const hasIcon = languageOnly.querySelector("img") != null;
520+ const hasIcon = languageOnly.querySelector("svg[data-pierre-icon]") != null;
433521 const hasText = (languageOnly.textContent ?? "").includes("ts");
434522 expect(hasIcon || hasText).toBe(true);
435523 expect(hasIcon && hasText).toBe(false);
@@ -446,7 +534,7 @@ describe("ChatMarkdown", () => { · 10 unmodified lines
446534 expect(titles[1]!.textContent).toBe("src/main.ts");
447535
448536 // Unknown language: no icon attempt, text label.
449− expect(titles[2]!.querySelector("img")).toBeNull();
537+ expect(titles[2]!.querySelector("svg[data-pierre-icon]")).toBeNull();
450538 expect(titles[2]!.textContent).toBe("text");
451539 } finally {
452540 await screen.unmount();
apps/web/src/components/ChatMarkdown.tsx+34−26
@@ -33,12 +33,8 @@ import remarkBreaks from "remark-breaks"; · 32 unmodified lines
3333 import remarkGfm from "remark-gfm";
3434 import { renderSkillInlineMarkdownChildren } from "./chat/SkillInlineText";
3535 import { CHAT_FILE_TAG_CHIP_CLASS_NAME, FileTagChipContent } from "./chat/FileTagChip";
36−import { VscodeEntryIcon } from "./chat/VscodeEntryIcon";
37−import {
38− getVscodeIconUrlForEntry,
39− hasSpecificVscodeIconForFileName,
40− syntheticFileNameForLanguageId,
41−} from "../vscode-icons";
36+import { PierreEntryIcon } from "./chat/PierreEntryIcon";
37+import { hasSpecificPierreIconForFileName, syntheticFileNameForLanguageId } from "../pierre-icons";
4238 import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip";
4339 import { Button } from "./ui/button";
4440 import { Collapsible, CollapsiblePanel, CollapsibleTrigger } from "./ui/collapsible";
@@ -62,6 +58,7 @@ import { · 17 unmodified lines
6258 } from "../markdown-links";
6359 import { readLocalApi } from "../localApi";
6460 import { cn } from "../lib/utils";
61+import { useRightPanelStore } from "../rightPanelStore";
6562 import { isPreviewSupportedInRuntime } from "../previewStateStore";
6663 import {
6764 isBrowserPreviewFile,
@@ -443,22 +440,17 @@ function MarkdownCodeBlockTitleContent({ · 375 unmodified lines
443440 language: string;
444441 theme: "light" | "dark";
445442 }) {
446− const [failedIconUrl, setFailedIconUrl] = useState<string | null>(null);
447−
448443 if (fenceTitle) {
449444 return (
450445 <>
451− <VscodeEntryIcon pathValue={fenceTitle} kind="file" theme={theme} className="size-3.5" />
446+ <PierreEntryIcon pathValue={fenceTitle} kind="file" theme={theme} className="size-3.5" />
452447 <span className="truncate">{fenceTitle}</span>
453448 </>
454449 );
455450 }
456451
457452 const fileName = syntheticFileNameForLanguageId(language);
458− const iconUrl = hasSpecificVscodeIconForFileName(fileName, theme)
459− ? getVscodeIconUrlForEntry(fileName, "file", theme)
460− : null;
461− if (!iconUrl || failedIconUrl === iconUrl) {
453+ if (!hasSpecificPierreIconForFileName(fileName)) {
462454 return <span className="truncate">{language}</span>;
463455 }
464456 return (
@@ -468,15 +460,7 @@ function MarkdownCodeBlockTitleContent({ · 3 unmodified lines
468460 <span className="inline-flex shrink-0 rounded-sm" aria-label={`Language: ${language}`} />
469461 }
470462 >
471− <img
472− src={iconUrl}
473− alt=""
474− aria-hidden
475− className="size-3.5 shrink-0"
476− loading="lazy"
477− draggable={false}
478− onError={() => setFailedIconUrl(iconUrl)}
479− />
463+ <PierreEntryIcon pathValue={fileName} kind="file" theme={theme} className="size-3.5" />
480464 </TooltipTrigger>
481465 <TooltipPopup side="top">{language}</TooltipPopup>
482466 </Tooltip>
@@ -674,6 +658,7 @@ interface MarkdownFileLinkProps { · 191 unmodified lines
674658 targetPath: string;
675659 iconPath: string;
676660 displayPath: string;
661+ workspaceRelativePath: string | null;
677662 label: string;
678663 copyMarkdown: string;
679664 theme: "light" | "dark";
@@ -997,13 +982,14 @@ const MarkdownFileLink = memo(function MarkdownFileLink({ · 317 unmodified lines
997982 targetPath,
998983 iconPath,
999984 displayPath,
985+ workspaceRelativePath,
1000986 label,
1001987 copyMarkdown,
1002988 theme,
1003989 threadRef,
1004990 className,
1005991 }: MarkdownFileLinkProps) {
1006− const handleOpen = useCallback(() => {
992+ const handleOpenInEditor = useCallback(() => {
1007993 const api = readLocalApi();
1008994 if (!api) {
1009995 toastManager.add({
@@ -1024,6 +1010,14 @@ const MarkdownFileLink = memo(function MarkdownFileLink({ · 14 unmodified lines
10241010 });
10251011 }, [targetPath]);
10261012
1013+ const handleOpenInFilePreview = useCallback(() => {
1014+ if (!threadRef || !workspaceRelativePath) {
1015+ handleOpenInEditor();
1016+ return;
1017+ }
1018+ useRightPanelStore.getState().openFile(threadRef, workspaceRelativePath);
1019+ }, [handleOpenInEditor, threadRef, workspaceRelativePath]);
1020+
10271021 const handleOpenInBrowser = useCallback(() => {
10281022 if (!threadRef) return;
10291023 void openFileInPreview(threadRef, iconPath).catch((error) => {
@@ -1092,7 +1086,7 @@ const MarkdownFileLink = memo(function MarkdownFileLink({ · 62 unmodified lines
10921086 );
10931087
10941088 if (clicked === "open") {
1095− handleOpen();
1089+ handleOpenInEditor();
10961090 return;
10971091 }
10981092 if (clicked === "open-in-browser") {
@@ -1107,7 +1101,15 @@ const MarkdownFileLink = memo(function MarkdownFileLink({ · 8 unmodified lines
11071101 handleCopy(targetPath, "Full path");
11081102 }
11091103 },
1110− [displayPath, handleCopy, handleOpen, handleOpenInBrowser, iconPath, targetPath, threadRef],
1104+ [
1105+ displayPath,
1106+ handleCopy,
1107+ handleOpenInBrowser,
1108+ handleOpenInEditor,
1109+ iconPath,
1110+ targetPath,
1111+ threadRef,
1112+ ],
11111113 );
11121114
11131115 return (
@@ -1121,7 +1123,11 @@ const MarkdownFileLink = memo(function MarkdownFileLink({ · 7 unmodified lines
11211123 onClick={(event) => {
11221124 event.preventDefault();
11231125 event.stopPropagation();
1124− handleOpen();
1126+ if (threadRef && isPreviewSupportedInRuntime() && isBrowserPreviewFile(iconPath)) {
1127+ handleOpenInBrowser();
1128+ return;
1129+ }
1130+ handleOpenInFilePreview();
11251131 }}
11261132 onContextMenu={handleContextMenu}
11271133 >
@@ -1150,6 +1156,7 @@ function areMarkdownFileLinkPropsEqual( · 22 unmodified lines
11501156 previous.targetPath === next.targetPath &&
11511157 previous.iconPath === next.iconPath &&
11521158 previous.displayPath === next.displayPath &&
1159+ previous.workspaceRelativePath === next.workspaceRelativePath &&
11531160 previous.label === next.label &&
11541161 previous.copyMarkdown === next.copyMarkdown &&
11551162 previous.theme === next.theme &&
@@ -1274,6 +1281,7 @@ function ChatMarkdown({ · 118 unmodified lines
12741281 targetPath={fileLinkMeta.targetPath}
12751282 iconPath={fileLinkMeta.filePath}
12761283 displayPath={fileLinkMeta.displayPath}
1284+ workspaceRelativePath={fileLinkMeta.workspaceRelativePath}
12771285 label={labelParts.join(" · ")}
12781286 copyMarkdown={`[${fileLinkMeta.basename}](${normalizedHref})`}
12791287 theme={resolvedTheme}
apps/web/src/components/ChatView.browser.tsx+368−13
@@ -53,7 +53,7 @@ import { · 52 unmodified lines
5353 resetSavedEnvironmentRuntimeStoreForTests,
5454 useSavedEnvironmentRegistryStore,
5555 useSavedEnvironmentRuntimeStore,
56−} from "../environments/runtime";
56+} from "../environments/runtime/catalog";
5757 import {
5858 INLINE_TERMINAL_CONTEXT_PLACEHOLDER,
5959 removeInlineTerminalContextPlaceholder,
@@ -2110,6 +2110,360 @@ describe("ChatView timeline estimator parity (full app)", () => { · 2050 unmodified lines
21102110 }
21112111 });
21122112
2113+ it("keeps panel toggles fixed and can maximize the right panel", async () => {
2114+ const mounted = await mountChatView({
2115+ viewport: WIDE_FOOTER_VIEWPORT,
2116+ snapshot: createSnapshotForTargetUser({
2117+ targetMessageId: "msg-user-maximize-right-panel" as MessageId,
2118+ targetText: "maximize right panel",
2119+ }),
2120+ });
2121+
2122+ try {
2123+ const terminalToggle = await waitForElement(
2124+ () =>
2125+ document.querySelector<HTMLButtonElement>('button[aria-label="Toggle terminal drawer"]'),
2126+ "Unable to find terminal drawer toggle.",
2127+ );
2128+ const rightPanelToggle = await waitForElement(
2129+ () => document.querySelector<HTMLButtonElement>('button[aria-label="Toggle right panel"]'),
2130+ "Unable to find right panel toggle.",
2131+ );
2132+ const headerActions = await waitForElement(
2133+ () => document.querySelector<HTMLElement>("[data-chat-header-actions]"),
2134+ "Unable to find chat header actions.",
2135+ );
2136+ const chatHeader = await waitForElement(
2137+ () => document.querySelector<HTMLElement>("[data-chat-header]"),
2138+ "Unable to find chat header.",
2139+ );
2140+ const panelLayoutControls = await waitForElement(
2141+ () => document.querySelector<HTMLElement>("[data-panel-layout-controls]"),
2142+ "Unable to find panel layout controls.",
2143+ );
2144+ expect(chatHeader.getBoundingClientRect().height).toBe(52);
2145+ expect(panelLayoutControls.getBoundingClientRect().height).toBe(52);
2146+ expect(panelLayoutControls.getBoundingClientRect().top).toBe(
2147+ chatHeader.getBoundingClientRect().top,
2148+ );
2149+ const initialTerminalRect = terminalToggle.getBoundingClientRect();
2150+ const initialRightPanelRect = rightPanelToggle.getBoundingClientRect();
2151+ const initialControlRects = [initialTerminalRect, initialRightPanelRect];
2152+ expect(document.querySelector('button[aria-label="Maximize panel"]')).toBeNull();
2153+ expect(initialControlRects.every((rect) => rect.width === 28 && rect.height === 28)).toBe(
2154+ true,
2155+ );
2156+ expect(initialControlRects.every((rect) => rect.top === initialControlRects[0]?.top)).toBe(
2157+ true,
2158+ );
2159+ expect(initialRightPanelRect.left - initialTerminalRect.right).toBe(4);
2160+ expect(
2161+ initialTerminalRect.left -
2162+ (headerActions.lastElementChild?.getBoundingClientRect().right ?? Number.NaN),
2163+ ).toBe(4);
2164+
2165+ document.documentElement.classList.add("wco");
2166+ expect(panelLayoutControls.getBoundingClientRect().height).toBe(52);
2167+ expect(panelLayoutControls.getBoundingClientRect().top).toBe(
2168+ chatHeader.getBoundingClientRect().top,
2169+ );
2170+ document.documentElement.classList.remove("wco");
2171+
2172+ rightPanelToggle.click();
2173+
2174+ const maximizeButton = await waitForElement(
2175+ () => document.querySelector<HTMLButtonElement>('button[aria-label="Maximize panel"]'),
2176+ "Unable to find maximize panel button.",
2177+ );
2178+ const rightPanelTabbar = await waitForElement(
2179+ () => document.querySelector<HTMLElement>("[data-right-panel-tabbar]"),
2180+ "Unable to find right panel tab bar.",
2181+ );
2182+ const maximizeRect = maximizeButton.getBoundingClientRect();
2183+ const rightPanelTabbarRect = rightPanelTabbar.getBoundingClientRect();
2184+ expect(document.querySelector('button[aria-label="Add panel surface"]')).toBeNull();
2185+ expect(rightPanelTabbarRect.height).toBe(52);
2186+ expect(rightPanelTabbarRect.top).toBe(chatHeader.getBoundingClientRect().top);
2187+ expect(maximizeRect.width).toBe(28);
2188+ expect(maximizeRect.height).toBe(28);
2189+ expect(maximizeRect.top).toBe(initialTerminalRect.top);
2190+ expect(initialTerminalRect.left - maximizeRect.right).toBe(4);
2191+ expect(terminalToggle.getBoundingClientRect().left).toBeCloseTo(initialTerminalRect.left, 1);
2192+ expect(rightPanelToggle.getBoundingClientRect().left).toBeCloseTo(
2193+ initialRightPanelRect.left,
2194+ 1,
2195+ );
2196+
2197+ useRightPanelStore.getState().openFile(THREAD_REF, "components.json");
2198+ const fileTabIcon = await waitForElement(
2199+ () =>
2200+ document.querySelector<SVGElement>(
2201+ '[data-right-panel-tabbar] [data-pierre-icon][data-icon-token="json"]',
2202+ ),
2203+ "Unable to find the Pierre file icon in the file tab.",
2204+ );
2205+ expect(fileTabIcon.closest("button")?.textContent).toContain("components.json");
2206+
2207+ document.documentElement.classList.add("wco");
2208+ expect(rightPanelTabbar.getBoundingClientRect().height).toBe(
2209+ panelLayoutControls.getBoundingClientRect().height,
2210+ );
2211+ expect(rightPanelTabbar.getBoundingClientRect().top).toBe(
2212+ panelLayoutControls.getBoundingClientRect().top,
2213+ );
2214+ document.documentElement.classList.remove("wco");
2215+
2216+ maximizeButton.click();
2217+
2218+ await vi.waitFor(() => {
2219+ const chatColumn = document.querySelector<HTMLElement>(
2220+ '[data-chat-column-maximized-away="true"]',
2221+ );
2222+ const panel = document.querySelector<HTMLElement>(
2223+ '[data-preview-panel-mode="inline"][data-preview-panel-maximized="true"]',
2224+ );
2225+ expect(chatColumn?.getBoundingClientRect().width).toBe(0);
2226+ expect(panel?.getBoundingClientRect().width).toBeGreaterThan(1_000);
2227+ expect(
2228+ document.querySelector<HTMLButtonElement>('button[aria-label="Restore panel size"]'),
2229+ ).not.toBeNull();
2230+ expect(terminalToggle.getBoundingClientRect().left).toBeCloseTo(
2231+ initialTerminalRect.left,
2232+ 1,
2233+ );
2234+ expect(rightPanelToggle.getBoundingClientRect().left).toBeCloseTo(
2235+ initialRightPanelRect.left,
2236+ 1,
2237+ );
2238+ });
2239+ } finally {
2240+ await mounted.cleanup();
2241+ }
2242+ });
2243+
2244+ it("scrolls file tabs and preserves the workspace explorer across file previews", async () => {
2245+ const workspaceEntries = [
2246+ { path: "src", kind: "directory" as const },
2247+ { path: "src/index.ts", kind: "file" as const },
2248+ { path: "src/router.ts", kind: "file" as const },
2249+ { path: "src/store.ts", kind: "file" as const },
2250+ { path: "src/styles.css", kind: "file" as const },
2251+ { path: "src/large.ts", kind: "file" as const },
2252+ { path: "e2e", kind: "directory" as const },
2253+ { path: "e2e/test-results", kind: "directory" as const },
2254+ {
2255+ path: "e2e/test-results/playwright-integration-results",
2256+ kind: "directory" as const,
2257+ },
2258+ {
2259+ path: "e2e/test-results/playwright-integration-results/chromium-desktop-project",
2260+ kind: "directory" as const,
2261+ },
2262+ {
2263+ path: "e2e/test-results/playwright-integration-results/chromium-desktop-project/.last-run.json",
2264+ kind: "file" as const,
2265+ },
2266+ { path: "README.md", kind: "file" as const },
2267+ { path: "AGENTS.md", kind: "file" as const },
2268+ { path: "package.json", kind: "file" as const },
2269+ { path: "tsconfig.json", kind: "file" as const },
2270+ ];
2271+ const mounted = await mountChatView({
2272+ viewport: WIDE_FOOTER_VIEWPORT,
2273+ snapshot: createSnapshotForTargetUser({
2274+ targetMessageId: "msg-user-file-tabs-and-tree-state" as MessageId,
2275+ targetText: "keep file tabs readable and preserve tree state",
2276+ }),
2277+ resolveRpc: (body) => {
2278+ if (body._tag === WS_METHODS.projectsListEntries) {
2279+ return { entries: workspaceEntries, truncated: false };
2280+ }
2281+ if (body._tag === WS_METHODS.projectsReadFile) {
2282+ const relativePath =
2283+ typeof body.relativePath === "string" ? body.relativePath : "file.ts";
2284+ const contents =
2285+ relativePath === "src/large.ts"
2286+ ? Array.from(
2287+ { length: 5_000 },
2288+ (_, index) => `export const line${index + 1} = ${index + 1};`,
2289+ ).join("\n")
2290+ : `// ${relativePath}\n`;
2291+ return {
2292+ relativePath,
2293+ contents,
2294+ byteLength: new TextEncoder().encode(contents).byteLength,
2295+ truncated: false,
2296+ };
2297+ }
2298+ return undefined;
2299+ },
2300+ });
2301+
2302+ try {
2303+ useRightPanelStore.getState().open(THREAD_REF, "files");
2304+
2305+ const explorer = await waitForElement(
2306+ () => document.querySelector<HTMLElement>("[data-file-browser-panel]"),
2307+ "Unable to find the workspace file explorer.",
2308+ );
2309+
2310+ for (const entry of workspaceEntries) {
2311+ if (entry.kind === "file") {
2312+ useRightPanelStore.getState().openFile(THREAD_REF, entry.path);
2313+ }
2314+ }
2315+
2316+ const tabList = await waitForElement(
2317+ () => document.querySelector<HTMLElement>("[data-right-panel-tab-list]"),
2318+ "Unable to find the right panel tab list.",
2319+ );
2320+ const tabViewport = await waitForElement(
2321+ () => tabList.querySelector<HTMLElement>('[data-slot="scroll-area-viewport"]'),
2322+ "Unable to find the right panel tab viewport.",
2323+ );
2324+
2325+ await vi.waitFor(() => {
2326+ const fileTabs = Array.from(tabList.querySelectorAll<HTMLElement>("[data-active-tab]"));
2327+ expect(fileTabs.length).toBe(
2328+ workspaceEntries.filter((entry) => entry.kind === "file").length,
2329+ );
2330+ expect(tabViewport.scrollWidth).toBeGreaterThan(tabViewport.clientWidth);
2331+ expect(tabViewport.scrollLeft).toBeGreaterThan(0);
2332+ expect(tabList.querySelector('[data-slot="scroll-area-scrollbar"]')).toBeNull();
2333+ expect(
2334+ fileTabs.every((tab) => {
2335+ const width = tab.getBoundingClientRect().width;
2336+ return width >= 100 && width <= 176;
2337+ }),
2338+ ).toBe(true);
2339+ expect(document.querySelector<HTMLElement>("[data-file-browser-panel]")).toBe(explorer);
2340+ });
2341+
2342+ useRightPanelStore.getState().openFile(THREAD_REF, "src/index.ts");
2343+ await vi.waitFor(() => {
2344+ expect(document.querySelector<HTMLElement>("[data-file-browser-panel]")).toBe(explorer);
2345+ });
2346+
2347+ useRightPanelStore
2348+ .getState()
2349+ .openFile(
2350+ THREAD_REF,
2351+ "e2e/test-results/playwright-integration-results/chromium-desktop-project/.last-run.json",
2352+ );
2353+ await mounted.setContainerSize({ width: 800, height: WIDE_FOOTER_VIEWPORT.height });
2354+ const breadcrumbs = await waitForElement(
2355+ () => document.querySelector<HTMLElement>("[data-file-breadcrumbs]"),
2356+ "Unable to find the responsive file breadcrumbs.",
2357+ );
2358+ const breadcrumbViewport = await waitForElement(
2359+ () => breadcrumbs.querySelector<HTMLElement>('[data-slot="scroll-area-viewport"]'),
2360+ "Unable to find the file breadcrumb viewport.",
2361+ );
2362+ const currentCrumb = await waitForElement(
2363+ () =>
2364+ Array.from(
2365+ breadcrumbs.querySelectorAll<HTMLElement>("[data-current-file-crumb='true']"),
2366+ ).find((crumb) => crumb.textContent === ".last-run.json") ?? null,
2367+ "Unable to find the current file breadcrumb.",
2368+ );
2369+ const explorerToggle = await waitForElement(
2370+ () => document.querySelector<HTMLButtonElement>('button[aria-label="Hide file explorer"]'),
2371+ "Unable to find the file explorer toggle.",
2372+ );
2373+
2374+ await vi.waitFor(() => {
2375+ const viewportRect = breadcrumbViewport.getBoundingClientRect();
2376+ const currentCrumbRect = currentCrumb.getBoundingClientRect();
2377+ expect(breadcrumbViewport.scrollWidth).toBeGreaterThan(breadcrumbViewport.clientWidth);
2378+ expect(breadcrumbViewport.scrollLeft).toBeGreaterThan(0);
2379+ expect(breadcrumbs.querySelector('[data-slot="scroll-area-scrollbar"]')).toBeNull();
2380+ expect(currentCrumbRect.right).toBeLessThanOrEqual(viewportRect.right + 1);
2381+ expect(viewportRect.right).toBeLessThan(explorerToggle.getBoundingClientRect().left);
2382+ expect(explorerToggle.getAttribute("aria-pressed")).toBe("true");
2383+ expect(explorerToggle.getBoundingClientRect().width).toBe(28);
2384+ expect(explorerToggle.getBoundingClientRect().height).toBe(28);
2385+ });
2386+
2387+ const fileSearchButton = await waitForElement(
2388+ () =>
2389+ document.querySelector<HTMLButtonElement>('button[aria-label="Search workspace files"]'),
2390+ "Unable to find the workspace file search button.",
2391+ );
2392+ fileSearchButton.click();
2393+ const fileTree = await waitForElement(
2394+ () => document.querySelector<HTMLElement>("file-tree-container"),
2395+ "Unable to find the file tree host.",
2396+ );
2397+ const fileSearchInput = await waitForElement(
2398+ () =>
2399+ fileTree.shadowRoot?.querySelector<HTMLInputElement>("[data-file-tree-search-input]") ??
2400+ null,
2401+ "Unable to find the file tree search input.",
2402+ );
2403+ fileSearchInput.focus();
2404+ const searchKeyEvent = new KeyboardEvent("keydown", {
2405+ key: "r",
2406+ bubbles: true,
2407+ cancelable: true,
2408+ composed: true,
2409+ });
2410+ fileSearchInput.dispatchEvent(searchKeyEvent);
2411+ await waitForLayout();
2412+ expect(searchKeyEvent.defaultPrevented).toBe(false);
2413+ expect(fileTree.shadowRoot?.activeElement).toBe(fileSearchInput);
2414+ expect(useComposerDraftStore.getState().draftsByThreadKey[THREAD_KEY]?.prompt ?? "").toBe("");
2415+
2416+ useRightPanelStore.getState().openFile(THREAD_REF, "src/large.ts");
2417+ const codeVirtualizer = await waitForElement(
2418+ () => document.querySelector<HTMLElement>(".file-preview-virtualizer"),
2419+ "Unable to find the virtualized file preview.",
2420+ );
2421+ expect(codeVirtualizer.querySelector("diffs-container")).not.toBeNull();
2422+ expect(codeVirtualizer.classList.contains("overflow-auto")).toBe(true);
2423+ } finally {
2424+ await mounted.cleanup();
2425+ }
2426+ });
2427+
2428+ it("removes persisted file tabs when a draft workspace no longer exists", async () => {
2429+ const orphanedDraftId = DraftId.make("draft-orphaned-file-panel");
2430+ const orphanedThreadId = "thread-orphaned-file-panel" as ThreadId;
2431+ const orphanedThreadRef = scopeThreadRef(LOCAL_ENVIRONMENT_ID, orphanedThreadId);
2432+ useComposerDraftStore.getState().setProjectDraftThreadId(
2433+ {
2434+ environmentId: LOCAL_ENVIRONMENT_ID,
2435+ projectId: "project-deleted" as ProjectId,
2436+ },
2437+ orphanedDraftId,
2438+ { threadId: orphanedThreadId },
2439+ );
2440+ useRightPanelStore.getState().openFile(orphanedThreadRef, "conductor.json");
2441+
2442+ const mounted = await mountChatView({
2443+ viewport: WIDE_FOOTER_VIEWPORT,
2444+ snapshot: createSnapshotForTargetUser({
2445+ targetMessageId: "msg-user-orphaned-file-panel" as MessageId,
2446+ targetText: "orphaned persisted file panel",
2447+ }),
2448+ initialPath: `/draft/${orphanedDraftId}`,
2449+ });
2450+
2451+ try {
2452+ await vi.waitFor(() => {
2453+ expect(
2454+ selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, orphanedThreadRef),
2455+ ).toEqual({
2456+ isOpen: false,
2457+ activeSurfaceId: null,
2458+ surfaces: [],
2459+ });
2460+ expect(document.querySelector("[data-right-panel-tabbar]")).toBeNull();
2461+ });
2462+ } finally {
2463+ await mounted.cleanup();
2464+ }
2465+ });
2466+
21132467 it("keeps multiple terminal panel surfaces separate from the bottom drawer", async () => {
21142468 const mounted = await mountChatView({
21152469 viewport: WIDE_FOOTER_VIEWPORT,
@@ -2126,11 +2480,10 @@ describe("ChatView timeline estimator parity (full app)", () => { · 10 unmodified lines
21262480 );
21272481 rightPanelToggle.click();
21282482
2129− const addSurface = await waitForElement(
2130− () => document.querySelector<HTMLButtonElement>('button[aria-label="Add panel surface"]'),
2131− "Unable to find add panel surface button.",
2132− );
2133− expect(document.body.textContent).toContain("Open a surface");
2483+ await vi.waitFor(() => {
2484+ expect(document.body.textContent).toContain("Open a surface");
2485+ });
2486+ expect(document.querySelector('button[aria-label="Add panel surface"]')).toBeNull();
21342487 expect(
21352488 selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, THREAD_REF),
21362489 ).toEqual({
@@ -2140,16 +2493,14 @@ describe("ChatView timeline estimator parity (full app)", () => { · 3 unmodified lines
21402493 });
21412494 expect(wsRequests.some((request) => request._tag === WS_METHODS.terminalOpen)).toBe(false);
21422495
2143− addSurface.click();
2144−
2145− const terminalItem = await waitForElement(
2496+ const emptyStateTerminalButton = await waitForElement(
21462497 () =>
2147− Array.from(document.querySelectorAll<HTMLElement>('[role="menuitem"]')).find(
2148− (item) => item.textContent?.trim() === "Terminal",
2498+ Array.from(document.querySelectorAll<HTMLButtonElement>("button")).find((button) =>
2499+ button.textContent?.includes("Start a shell in this workspace."),
21492500 ) ?? null,
2150− "Unable to find Terminal panel menu item.",
2501+ "Unable to find the empty-state Terminal button.",
21512502 );
2152− terminalItem.click();
2503+ emptyStateTerminalButton.click();
21532504
21542505 await vi.waitFor(() => {
21552506 expect(
@@ -2159,6 +2510,10 @@ describe("ChatView timeline estimator parity (full app)", () => { · 3 unmodified lines
21592510 ).toEqual(["term-1"]);
21602511 });
21612512
2513+ const addSurface = await waitForElement(
2514+ () => document.querySelector<HTMLButtonElement>('button[aria-label="Add panel surface"]'),
2515+ "Unable to find add panel surface button beside the tabs.",
2516+ );
21622517 addSurface.click();
21632518 const secondTerminalItem = await waitForElement(
21642519 () =>
apps/web/src/components/ChatView.tsx+174−34
@@ -35,7 +35,7 @@ import { lazy, memo, Suspense, useCallback, useEffect, useMemo, useRef, useState · 34 unmodified lines
3535 import { useNavigate, useSearch } from "@tanstack/react-router";
3636 import { useShallow } from "zustand/react/shallow";
3737 import { useVcsStatus } from "~/lib/vcsStatusState";
38−import { usePrimaryEnvironmentId } from "../environments/primary";
38+import { usePrimaryEnvironmentId } from "../environments/primary/context";
3939 import { readEnvironmentApi } from "../environmentApi";
4040 import { resolveAssetUrl } from "../assets/assetUrls";
4141 import { isElectron } from "../env";
@@ -67,7 +67,7 @@ import { · 25 unmodified lines
6767 togglePendingUserInputOptionSelection,
6868 type PendingUserInputDraftAnswer,
6969 } from "../pendingUserInput";
70−import { selectProjectsAcrossEnvironments, useStore } from "../store";
70+import { selectEnvironmentState, selectProjectsAcrossEnvironments, useStore } from "../store";
7171 import { createProjectSelectorByRef, createThreadSelectorByRef } from "../storeSelectors";
7272 import { useUiStateStore } from "../uiStateStore";
7373 import {
@@ -111,6 +111,8 @@ const PreviewPanel = lazy(() => · 37 unmodified lines
111111 import("./preview/PreviewPanel").then((mod) => ({ default: mod.PreviewPanel })),
112112 );
113113 const DiffPanel = lazy(() => import("./DiffPanel"));
114+const FilePreviewPanel = lazy(() => import("./files/FilePreviewPanel"));
115+const EMPTY_PENDING_FILE_SURFACE_IDS: ReadonlySet<string> = new Set();
114116 import { BranchToolbar } from "./BranchToolbar";
115117 import { resolveShortcutCommand, shortcutLabelForCommand } from "../keybindings";
116118 import PlanSidebar from "./PlanSidebar";
@@ -137,10 +139,10 @@ import { · 20 unmodified lines
137139 selectProjectGroupingSettings,
138140 } from "../logicalProject";
139141 import {
140− reconnectSavedEnvironment,
141142 useSavedEnvironmentRegistryStore,
142143 useSavedEnvironmentRuntimeStore,
143−} from "../environments/runtime";
144+} from "../environments/runtime/catalog";
145+import { reconnectSavedEnvironment } from "../environments/runtime/service";
144146 import { buildDraftThreadRouteParams } from "../threadRoutes";
145147 import {
146148 type ComposerImageAttachment,
@@ -167,6 +169,7 @@ import { ExpandedImageDialog } from "./chat/ExpandedImageDialog"; · 20 unmodified lines
167169 import { PullRequestThreadDialog } from "./PullRequestThreadDialog";
168170 import { MessagesTimeline } from "./chat/MessagesTimeline";
169171 import { ChatHeader } from "./chat/ChatHeader";
172+import { PanelLayoutControls } from "./chat/PanelLayoutControls";
170173 import { type ExpandedImagePreview } from "./chat/ExpandedImagePreview";
171174 import { NoActiveThreadState } from "./NoActiveThreadState";
172175 import { resolveEffectiveEnvMode, resolveEnvironmentOptionLabel } from "./BranchToolbar.logic";
@@ -256,10 +259,12 @@ type EnvironmentUnavailableState = { · 83 unmodified lines
256259
257260 type ThreadPlanCatalogEntry = Pick<Thread, "id" | "proposedPlans">;
258261
259−function eventTargetElement(target: EventTarget | null): Element | null {
260− if (target instanceof Element) return target;
261− if (target instanceof Node) return target.parentElement;
262− return null;
262+function eventPathContainsSelector(event: Event, selector: string): boolean {
263+ const path = event.composedPath();
264+ if (path.length === 0 && event.target) {
265+ path.push(event.target);
266+ }
267+ return path.some((target) => target instanceof Element && target.closest(selector));
263268 }
264269
265270 function shouldTypeToFocusComposer(event: KeyboardEvent): boolean {
@@ -267,9 +272,8 @@ function shouldTypeToFocusComposer(event: KeyboardEvent): boolean { · 1 unmodified line
267272 if (event.metaKey || event.ctrlKey || event.altKey) return false;
268273 if (event.key.length !== 1) return false;
269274
270− const target = eventTargetElement(event.target);
271− if (target?.closest(TYPE_TO_FOCUS_EDITABLE_SELECTOR)) return false;
272− if (target?.closest(TYPE_TO_FOCUS_INTERACTIVE_SELECTOR)) return false;
275+ if (eventPathContainsSelector(event, TYPE_TO_FOCUS_EDITABLE_SELECTOR)) return false;
276+ if (eventPathContainsSelector(event, TYPE_TO_FOCUS_INTERACTIVE_SELECTOR)) return false;
273277 if (document.querySelector(TYPE_TO_FOCUS_FLOATING_LAYER_SELECTOR)) return false;
274278
275279 return true;
@@ -1055,7 +1059,7 @@ const PersistentThreadTerminalPanel = memo(function PersistentThreadTerminalPane · 779 unmodified lines
10551059 );
10561060 });
10571061
1058−export default function ChatView(props: ChatViewProps) {
1062+function ChatViewContent(props: ChatViewProps) {
10591063 const {
10601064 environmentId,
10611065 threadId,
@@ -1152,6 +1156,9 @@ export default function ChatView(props: ChatViewProps) { · 90 unmodified lines
11521156 >({});
11531157 const [isConnecting, _setIsConnecting] = useState(false);
11541158 const [isRevertingCheckpoint, setIsRevertingCheckpoint] = useState(false);
1159+ const [maximizedRightPanelThreadKey, setMaximizedRightPanelThreadKey] = useState<string | null>(
1160+ null,
1161+ );
11551162 const [respondingRequestIds, setRespondingRequestIds] = useState<ApprovalRequestId[]>([]);
11561163 const [respondingUserInputRequestIds, setRespondingUserInputRequestIds] = useState<
11571164 ApprovalRequestId[]
@@ -1324,6 +1331,9 @@ export default function ChatView(props: ChatViewProps) { · 166 unmodified lines
13241331 const planSidebarOpen = activeRightPanelKind === "plan";
13251332 const previewPanelOpen = activeRightPanelKind === "preview" && isPreviewSupportedInRuntime();
13261333 const rightPanelOpen = rightPanelState.isOpen;
1334+ const canMaximizeRightPanel = rightPanelOpen && !shouldUsePlanSidebarSheet;
1335+ const rightPanelMaximized =
1336+ canMaximizeRightPanel && maximizedRightPanelThreadKey === routeThreadKey;
13271337 const inlineRightPanelOwnsTitleBar = rightPanelOpen && !shouldUsePlanSidebarSheet;
13281338
13291339 useEffect(() => {
@@ -1358,11 +1368,58 @@ export default function ChatView(props: ChatViewProps) { · 28 unmodified lines
13581368 const activeProject = useStore(
13591369 useMemo(() => createProjectSelectorByRef(activeProjectRef), [activeProjectRef]),
13601370 );
1371+ const activeProjectKey = activeProject
1372+ ? `${activeProject.environmentId}:${activeProject.cwd}`
1373+ : null;
1374+ const [pendingFileSurfaceIdsByProject, setPendingFileSurfaceIdsByProject] = useState<
1375+ ReadonlyMap<string, ReadonlySet<string>>
1376+ >(() => new Map());
1377+ const pendingFileSurfaceIds = activeProjectKey
1378+ ? (pendingFileSurfaceIdsByProject.get(activeProjectKey) ?? EMPTY_PENDING_FILE_SURFACE_IDS)
1379+ : EMPTY_PENDING_FILE_SURFACE_IDS;
1380+ const handleFilePendingChange = useCallback(
1381+ (relativePath: string, pending: boolean) => {
1382+ if (!activeProjectKey) return;
1383+ setPendingFileSurfaceIdsByProject((currentByProject) => {
1384+ const current = currentByProject.get(activeProjectKey) ?? EMPTY_PENDING_FILE_SURFACE_IDS;
1385+ const surfaceId = `file:${relativePath}`;
1386+ if (current.has(surfaceId) === pending) return currentByProject;
1387+
1388+ const next = new Set(current);
1389+ if (pending) {
1390+ next.add(surfaceId);
1391+ } else {
1392+ next.delete(surfaceId);
1393+ }
1394+
1395+ const nextByProject = new Map(currentByProject);
1396+ if (next.size === 0) {
1397+ nextByProject.delete(activeProjectKey);
1398+ } else {
1399+ nextByProject.set(activeProjectKey, next);
1400+ }
1401+ return nextByProject;
1402+ });
1403+ },
1404+ [activeProjectKey],
1405+ );
1406+ const activeEnvironmentBootstrapComplete = useStore((state) =>
1407+ activeThread
1408+ ? selectEnvironmentState(state, activeThread.environmentId).bootstrapComplete
1409+ : false,
1410+ );
13611411 const configuredPreviewUrls = useMemo(
13621412 () => getConfiguredPreviewUrls(activeProject?.scripts),
13631413 [activeProject?.scripts],
13641414 );
13651415
1416+ useEffect(() => {
1417+ if (!activeThreadRef || !activeEnvironmentBootstrapComplete) return;
1418+ useRightPanelStore
1419+ .getState()
1420+ .reconcileFileSurfaces(activeThreadRef, activeProject !== undefined);
1421+ }, [activeEnvironmentBootstrapComplete, activeProject, activeThreadRef]);
1422+
13661423 useEffect(() => {
13671424 if (routeKind !== "server") {
13681425 return;
@@ -2209,6 +2266,8 @@ export default function ChatView(props: ChatViewProps) { · 840 unmodified lines
22092266 }),
22102267 [terminalUiState.terminalOpen],
22112268 );
2269+ const terminalToggleShortcutLabel = shortcutLabelForCommand(keybindings, "terminal.toggle");
2270+ const rightPanelToggleShortcutLabel = shortcutLabelForCommand(keybindings, "rightPanel.toggle");
22122271 const splitTerminalShortcutLabel = useMemo(
22132272 () => shortcutLabelForCommand(keybindings, "terminal.split", terminalShortcutLabelOptions),
22142273 [keybindings, terminalShortcutLabelOptions],
@@ -2257,6 +2316,14 @@ export default function ChatView(props: ChatViewProps) { · 42 unmodified lines
22572316 onDiffPanelOpen,
22582317 threadId,
22592318 ]);
2319+ const addFilesSurface = () => {
2320+ if (!activeThreadRef || !activeProject) return;
2321+ useRightPanelStore.getState().open(activeThreadRef, "files");
2322+ };
2323+ const openFileSurface = (relativePath: string) => {
2324+ if (!activeThreadRef || !activeProject) return;
2325+ useRightPanelStore.getState().openFile(activeThreadRef, relativePath);
2326+ };
22602327 // Right-panel arbitration:
22612328 // - The diff panel's openness is mirrored by the `?diff=1` URL search
22622329 // param so it deep-links cleanly. The store still records preview/plan
@@ -2979,12 +3046,14 @@ export default function ChatView(props: ChatViewProps) { · 716 unmodified lines
29793046 }, [activePlan?.turnId, activeThreadRef, planSidebarOpen, sidebarProposedPlan?.turnId]);
29803047 const closePlanSidebar = useCallback(() => {
29813048 if (!activeThreadRef) return;
3049+ setMaximizedRightPanelThreadKey(null);
29823050 useRightPanelStore.getState().close(activeThreadRef);
29833051 planSidebarDismissedForTurnRef.current =
29843052 activePlan?.turnId ?? sidebarProposedPlan?.turnId ?? "__dismissed__";
29853053 }, [activePlan?.turnId, activeThreadRef, sidebarProposedPlan?.turnId]);
29863054 const closePreviewPanel = useCallback(() => {
29873055 if (!activeThreadRef) return;
3056+ setMaximizedRightPanelThreadKey(null);
29883057 useRightPanelStore.getState().close(activeThreadRef);
29893058 }, [activeThreadRef]);
29903059 const activateRightPanelSurface = useCallback(
@@ -3018,8 +3087,17 @@ export default function ChatView(props: ChatViewProps) { · 27 unmodified lines
30183087 );
30193088 const toggleRightPanel = useCallback(() => {
30203089 if (!activeThreadRef) return;
3090+ if (rightPanelOpen) {
3091+ setMaximizedRightPanelThreadKey(null);
3092+ }
30213093 useRightPanelStore.getState().toggleVisibility(activeThreadRef);
3022− }, [activeThreadRef]);
3094+ }, [activeThreadRef, rightPanelOpen]);
3095+ const toggleRightPanelMaximized = () => {
3096+ if (!canMaximizeRightPanel) return;
3097+ setMaximizedRightPanelThreadKey((threadKey) =>
3098+ threadKey === routeThreadKey ? null : routeThreadKey,
3099+ );
3100+ };
30233101 const closeRightPanelSurface = useCallback(
30243102 (surface: RightPanelSurface) => {
30253103 if (!activeThreadRef) return;
@@ -4481,23 +4559,43 @@ export default function ChatView(props: ChatViewProps) { · 1455 unmodified lines
44814559 }
44824560
44834561 return (
4484− <div className="flex min-h-0 min-w-0 flex-1 overflow-hidden bg-background">
4562+ <div className="relative flex min-h-0 min-w-0 flex-1 overflow-hidden bg-background">
44854563 {isElectron && activeThreadRef ? (
44864564 <PreviewAutomationOwner threadRef={activeThreadRef} visible={previewPanelOpen} />
44874565 ) : null}
4488− <div className="flex min-h-0 min-w-0 flex-1 flex-col overflow-x-hidden">
4566+ <PanelLayoutControls
4567+ terminalAvailable={Boolean(activeProject)}
4568+ terminalOpen={Boolean(terminalUiState.terminalOpen)}
4569+ terminalShortcutLabel={terminalToggleShortcutLabel}
4570+ rightPanelAvailable={Boolean(activeProject)}
4571+ rightPanelOpen={rightPanelOpen}
4572+ rightPanelShortcutLabel={rightPanelToggleShortcutLabel}
4573+ rightPanelMaximized={rightPanelMaximized}
4574+ canMaximizeRightPanel={canMaximizeRightPanel}
4575+ onToggleTerminal={toggleTerminalVisibility}
4576+ onToggleRightPanel={toggleRightPanel}
4577+ onToggleRightPanelMaximized={toggleRightPanelMaximized}
4578+ />
4579+ <div
4580+ className={cn(
4581+ "flex min-h-0 min-w-0 flex-col overflow-hidden",
4582+ rightPanelMaximized ? "w-0 flex-none" : "flex-1",
4583+ )}
4584+ data-chat-column-maximized-away={rightPanelMaximized ? "true" : "false"}
4585+ >
44894586 {/* Top bar */}
44904587 <header
4588+ data-chat-header
44914589 className={cn(
44924590 "border-b border-border",
44934591 isElectron
44944592 ? cn(
4495− "drag-region flex h-[52px] items-center px-3 sm:px-5 wco:h-[env(titlebar-area-height)]",
4593+ "workspace-topbar drag-region px-3 sm:px-5",
44964594 reserveTitleBarControlInset &&
44974595 !inlineRightPanelOwnsTitleBar &&
4498− "wco:pr-[calc(100vw-env(titlebar-area-width)-env(titlebar-area-x)+1em)]",
4596+ "wco:pr-[var(--workspace-native-controls-inset)]",
44994597 )
4500− : "pb-2 pl-[calc(env(safe-area-inset-left)+0.75rem)] pr-[calc(env(safe-area-inset-right)+0.75rem)] pt-2 sm:pb-3 sm:pl-[calc(env(safe-area-inset-left)+1.25rem)] sm:pr-[calc(env(safe-area-inset-right)+1.25rem)] sm:pt-3",
4598+ : "workspace-topbar pl-[calc(env(safe-area-inset-left)+0.75rem)] pr-[calc(env(safe-area-inset-right)+0.75rem)] sm:pl-[calc(env(safe-area-inset-left)+1.25rem)] sm:pr-[calc(env(safe-area-inset-right)+1.25rem)]",
45014599 )}
45024600 >
45034601 <ChatHeader
@@ -4513,17 +4611,12 @@ export default function ChatView(props: ChatViewProps) { · 9 unmodified lines
45134611 }
45144612 keybindings={keybindings}
45154613 availableEditors={availableEditors}
4516− terminalAvailable={Boolean(activeProject)}
4517− terminalOpen={Boolean(terminalUiState.terminalOpen)}
4518− rightPanelAvailable={Boolean(activeProject)}
4519− rightPanelOpen={rightPanelOpen}
45204614 gitCwd={gitCwd}
45214615 onRunProjectScript={runProjectScript}
45224616 onAddProjectScript={saveProjectScript}
45234617 onUpdateProjectScript={updateProjectScript}
45244618 onDeleteProjectScript={deleteProjectScript}
4525− onToggleTerminal={toggleTerminalVisibility}
4526− onToggleRightPanel={toggleRightPanel}
4619+ rightPanelOpen={rightPanelOpen}
45274620 />
45284621 </header>
45294622
@@ -4730,8 +4823,10 @@ export default function ChatView(props: ChatViewProps) { · 200 unmodified lines
47304823 {!shouldUsePlanSidebarSheet && rightPanelOpen && activeThreadRef ? (
47314824 <RightPanelTabs
47324825 mode="inline"
4826+ maximized={rightPanelMaximized}
47334827 surfaces={rightPanelState.surfaces}
47344828 activeSurfaceId={activeRightPanelSurface?.id ?? null}
4829+ pendingSurfaceIds={pendingFileSurfaceIds}
47354830 previewSessions={activePreviewState.sessions}
47364831 terminalLabelsById={activeTerminalLabelsById}
47374832 onActivate={activateRightPanelSurface}
@@ -4739,8 +4834,10 @@ export default function ChatView(props: ChatViewProps) { · 1 unmodified line
47394834 onAddBrowser={createBrowserSurface}
47404835 onAddTerminal={addTerminalSurface}
47414836 onAddDiff={addDiffSurface}
4837+ onAddFiles={addFilesSurface}
47424838 browserAvailable={isPreviewSupportedInRuntime()}
47434839 diffAvailable={isServerThread && isGitRepo}
4840+ filesAvailable={Boolean(activeProject)}
47444841 >
47454842 {activeRightPanelSurface?.kind === "preview" ? (
47464843 <Suspense fallback={null}>
@@ -4771,11 +4868,27 @@ export default function ChatView(props: ChatViewProps) { · 24 unmodified lines
47714868 closeShortcutLabel={closeTerminalShortcutLabel ?? undefined}
47724869 />
47734870 ) : activeRightPanelSurface?.kind === "diff" ? (
4774− <DiffWorkerPoolProvider>
4775− <Suspense fallback={null}>
4776− <DiffPanel mode="embedded" />
4777− </Suspense>
4778− </DiffWorkerPoolProvider>
4871+ <Suspense fallback={null}>
4872+ <DiffPanel mode="embedded" />
4873+ </Suspense>
4874+ ) : (activeRightPanelSurface?.kind === "files" ||
4875+ activeRightPanelSurface?.kind === "file") &&
4876+ activeProject ? (
4877+ <Suspense fallback={null}>
4878+ <FilePreviewPanel
4879+ key={`${activeProject.environmentId}:${activeProject.cwd}`}
4880+ environmentId={activeProject.environmentId}
4881+ cwd={activeProject.cwd}
4882+ projectName={activeProject.name}
4883+ relativePath={
4884+ activeRightPanelSurface.kind === "file"
4885+ ? activeRightPanelSurface.relativePath
4886+ : null
4887+ }
4888+ onOpenFile={openFileSurface}
4889+ onPendingChange={handleFilePendingChange}
4890+ />
4891+ </Suspense>
47794892 ) : null}
47804893 </RightPanelTabs>
47814894 ) : null}
@@ -4786,6 +4899,7 @@ export default function ChatView(props: ChatViewProps) { · 4 unmodified lines
47864899 mode="sheet"
47874900 surfaces={rightPanelState.surfaces}
47884901 activeSurfaceId={activeRightPanelSurface?.id ?? null}
4902+ pendingSurfaceIds={pendingFileSurfaceIds}
47894903 previewSessions={activePreviewState.sessions}
47904904 terminalLabelsById={activeTerminalLabelsById}
47914905 onActivate={activateRightPanelSurface}
@@ -4793,8 +4907,10 @@ export default function ChatView(props: ChatViewProps) { · 1 unmodified line
47934907 onAddBrowser={createBrowserSurface}
47944908 onAddTerminal={addTerminalSurface}
47954909 onAddDiff={addDiffSurface}
4910+ onAddFiles={addFilesSurface}
47964911 browserAvailable={isPreviewSupportedInRuntime()}
47974912 diffAvailable={isServerThread && isGitRepo}
4913+ filesAvailable={Boolean(activeProject)}
47984914 >
47994915 {activeRightPanelSurface?.kind === "preview" ? (
48004916 <Suspense fallback={null}>
@@ -4825,11 +4941,9 @@ export default function ChatView(props: ChatViewProps) { · 24 unmodified lines
48254941 closeShortcutLabel={closeTerminalShortcutLabel ?? undefined}
48264942 />
48274943 ) : activeRightPanelSurface?.kind === "diff" ? (
4828− <DiffWorkerPoolProvider>
4829− <Suspense fallback={null}>
4830− <DiffPanel mode="embedded" />
4831− </Suspense>
4832− </DiffWorkerPoolProvider>
4944+ <Suspense fallback={null}>
4945+ <DiffPanel mode="embedded" />
4946+ </Suspense>
48334947 ) : activeRightPanelSurface?.kind === "plan" ? (
48344948 <PlanSidebar
48354949 activePlan={activePlan}
@@ -4843,6 +4957,24 @@ export default function ChatView(props: ChatViewProps) { · 7 unmodified lines
48434957 mode="embedded"
48444958 onClose={closePlanSidebar}
48454959 />
4960+ ) : (activeRightPanelSurface?.kind === "files" ||
4961+ activeRightPanelSurface?.kind === "file") &&
4962+ activeProject ? (
4963+ <Suspense fallback={null}>
4964+ <FilePreviewPanel
4965+ key={`${activeProject.environmentId}:${activeProject.cwd}`}
4966+ environmentId={activeProject.environmentId}
4967+ cwd={activeProject.cwd}
4968+ projectName={activeProject.name}
4969+ relativePath={
4970+ activeRightPanelSurface.kind === "file"
4971+ ? activeRightPanelSurface.relativePath
4972+ : null
4973+ }
4974+ onOpenFile={openFileSurface}
4975+ onPendingChange={handleFilePendingChange}
4976+ />
4977+ </Suspense>
48464978 ) : null}
48474979 </RightPanelTabs>
48484980 </RightPanelSheet>
@@ -4854,3 +4986,11 @@ export default function ChatView(props: ChatViewProps) { · 5 unmodified lines
48544986 </div>
48554987 );
48564988 }
4989+
4990+export default function ChatView(props: ChatViewProps) {
4991+ return (
4992+ <DiffWorkerPoolProvider>
4993+ <ChatViewContent {...props} />
4994+ </DiffWorkerPoolProvider>
4995+ );
4996+}
apps/web/src/components/ComposerPromptEditor.tsx+1−1
@@ -64,7 +64,7 @@ import { · 63 unmodified lines
6464 type TerminalContextDraft,
6565 } from "~/lib/terminalContext";
6666 import { cn } from "~/lib/utils";
67−import { basenameOfPath } from "~/vscode-icons";
67+import { basenameOfPath } from "~/pierre-icons";
6868 import {
6969 COMPOSER_INLINE_CHIP_ICON_CLASS_NAME,
7070 COMPOSER_INLINE_CHIP_LABEL_CLASS_NAME,
apps/web/src/components/DiffWorkerPoolProvider.tsx+1−0
@@ -47,6 +47,7 @@ export function DiffWorkerPoolProvider({ children }: { children?: ReactNode }) { · 46 unmodified lines
4747 highlighterOptions={{
4848 theme: diffThemeName,
4949 tokenizeMaxLineLength: 1_000,
50+ useTokenTransformer: true,
5051 }}
5152 >
5253 <DiffWorkerThemeSync themeName={diffThemeName} />
apps/web/src/components/NoActiveThreadState.tsx+2−4
@@ -10,13 +10,11 @@ export function NoActiveThreadState() { · 9 unmodified lines
1010 <header
1111 className={cn(
1212 "border-b border-border px-3 sm:px-5",
13− isElectron
14− ? "drag-region flex h-[52px] items-center wco:h-[env(titlebar-area-height)]"
15− : "py-2 sm:py-3",
13+ isElectron ? "workspace-topbar drag-region" : "workspace-topbar",
1614 )}
1715 >
1816 {isElectron ? (
19− <span className="text-xs text-muted-foreground/50 wco:pr-[calc(100vw-env(titlebar-area-width)-env(titlebar-area-x)+1em)]">
17+ <span className="text-xs text-muted-foreground/50 wco:pr-[var(--workspace-native-controls-inset)]">
2018 No active thread
2119 </span>
2220 ) : (
apps/web/src/components/RightPanelTabs.tsx+150−71
@@ -1,21 +1,26 @@
11 import type { PreviewSessionSnapshot } from "@t3tools/contracts";
22 import { getTerminalLabel } from "@t3tools/shared/terminalLabels";
3−import { ClipboardList, FileDiff, Globe2, Plus, TerminalSquare, X } from "lucide-react";
4−import { type ReactNode, useState } from "react";
3+import { ClipboardList, FileDiff, Files, Globe2, Plus, TerminalSquare, X } from "lucide-react";
4+import { type ReactNode, useEffect, useRef, useState } from "react";
55
66 import { isElectron } from "~/env";
77 import type { RightPanelSurface } from "~/rightPanelStore";
88 import { cn } from "~/lib/utils";
9−import { Menu, MenuItem, MenuPopup, MenuTrigger } from "~/components/ui/menu";
109 import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip";
10+import { Menu, MenuItem, MenuPopup, MenuTrigger } from "~/components/ui/menu";
11+import { ScrollArea } from "~/components/ui/scroll-area";
1112 import { faviconUrlForOrigin } from "~/lib/favicon";
13+import { useTheme } from "~/hooks/useTheme";
1214
1315 import { PreviewPanelShell, type PreviewPanelMode } from "./preview/PreviewPanelShell";
16+import { PierreEntryIcon } from "./chat/PierreEntryIcon";
1417
1518 interface RightPanelTabsProps {
1619 mode: PreviewPanelMode;
20+ maximized?: boolean;
1721 surfaces: readonly RightPanelSurface[];
1822 activeSurfaceId: string | null;
23+ pendingSurfaceIds: ReadonlySet<string>;
1924 previewSessions: Readonly<Record<string, PreviewSessionSnapshot>>;
2025 terminalLabelsById: ReadonlyMap<string, string>;
2126 onActivate: (surface: RightPanelSurface) => void;
@@ -23,8 +28,10 @@ interface RightPanelTabsProps { · 1 unmodified line
2328 onAddBrowser: () => void;
2429 onAddTerminal: () => void;
2530 onAddDiff: () => void;
31+ onAddFiles: () => void;
2632 browserAvailable: boolean;
2733 diffAvailable: boolean;
34+ filesAvailable: boolean;
2835 children: ReactNode;
2936 }
3037
@@ -32,8 +39,10 @@ function RightPanelEmptyState(props: { · 1 unmodified line
3239 onAddBrowser: () => void;
3340 onAddTerminal: () => void;
3441 onAddDiff: () => void;
42+ onAddFiles: () => void;
3543 browserAvailable: boolean;
3644 diffAvailable: boolean;
45+ filesAvailable: boolean;
3746 }) {
3847 const actions = [
3948 {
@@ -50,6 +59,13 @@ function RightPanelEmptyState(props: { · 10 unmodified lines
5059 available: true,
5160 onClick: props.onAddTerminal,
5261 },
62+ {
63+ label: "Files",
64+ description: "Browse and read workspace files.",
65+ icon: Files,
66+ available: props.filesAvailable,
67+ onClick: props.onAddFiles,
68+ },
5369 {
5470 label: "Diff",
5571 description: "Review changes in this thread.",
@@ -68,7 +84,7 @@ function RightPanelEmptyState(props: { · 12 unmodified lines
6884 Choose what to show in the right panel.
6985 </p>
7086 </div>
71− <div className="grid gap-2 sm:grid-cols-3">
87+ <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-4">
7288 {actions.map((action) => {
7389 const Icon = action.icon;
7490 return (
@@ -101,6 +117,10 @@ function surfaceTitle( · 26 unmodified lines
101117 switch (surface.kind) {
102118 case "diff":
103119 return "Diff";
120+ case "files":
121+ return "Files";
122+ case "file":
123+ return surface.relativePath.slice(surface.relativePath.lastIndexOf("/") + 1);
104124 case "terminal":
105125 return (
106126 terminalLabelsById.get(surface.activeTerminalId) ??
@@ -140,9 +160,11 @@ function PreviewFavicon({ url }: { url: string | null }) { · 33 unmodified lines
140160 function SurfaceIcon({
141161 surface,
142162 sessions,
163+ theme,
143164 }: {
144165 surface: RightPanelSurface;
145166 sessions: Readonly<Record<string, PreviewSessionSnapshot>>;
167+ theme: "light" | "dark";
146168 }) {
147169 switch (surface.kind) {
148170 case "preview": {
@@ -152,6 +174,17 @@ function SurfaceIcon({ · 3 unmodified lines
152174 }
153175 case "diff":
154176 return <FileDiff className="size-3.5 shrink-0" />;
177+ case "files":
178+ return <Files className="size-3.5 shrink-0" />;
179+ case "file":
180+ return (
181+ <PierreEntryIcon
182+ pathValue={surface.relativePath}
183+ kind="file"
184+ theme={theme}
185+ className="size-3.5"
186+ />
187+ );
155188 case "terminal":
156189 return <TerminalSquare className="size-3.5 shrink-0" />;
157190 case "plan":
@@ -161,80 +194,124 @@ function SurfaceIcon({ · 3 unmodified lines
161194
162195 export function RightPanelTabs(props: RightPanelTabsProps) {
163196 const ownsDesktopTitleBar = isElectron && props.mode === "inline";
197+ const { resolvedTheme } = useTheme();
198+ const tabListRef = useRef<HTMLDivElement>(null);
199+
200+ useEffect(() => {
201+ const activeTab = tabListRef.current?.querySelector<HTMLElement>("[data-active-tab='true']");
202+ activeTab?.scrollIntoView({ block: "nearest", inline: "nearest" });
203+ }, [props.activeSurfaceId]);
164204
165205 return (
166− <PreviewPanelShell mode={props.mode}>
206+ <PreviewPanelShell
207+ mode={props.mode}
208+ {...(props.maximized !== undefined ? { maximized: props.maximized } : {})}
209+ >
167210 <div
168211 className={cn(
169− "flex shrink-0 items-center px-2",
170− ownsDesktopTitleBar
171− ? "drag-region h-[52px] wco:h-[env(titlebar-area-height)] wco:pr-[calc(100vw-env(titlebar-area-width)-env(titlebar-area-x)+1em)]"
172− : "h-10",
212+ "px-2 pr-28",
213+ props.mode === "inline" ? "workspace-topbar" : "flex h-10 shrink-0 items-center",
214+ ownsDesktopTitleBar &&
215+ "drag-region wco:pr-[calc(var(--workspace-native-controls-inset)+6rem)]",
173216 )}
217+ data-right-panel-tabbar
174218 >
175− <div className="flex min-w-0 flex-1 items-center gap-1 overflow-x-auto">
176− {props.surfaces.map((surface) => {
177− const active = surface.id === props.activeSurfaceId;
178− const title = surfaceTitle(surface, props.previewSessions, props.terminalLabelsById);
179− return (
180− <div
181− key={surface.id}
182− className={cn(
183− "group flex h-7 min-w-0 max-w-52 items-center gap-1.5 rounded-md px-2 text-sm",
184− active
185− ? "bg-accent text-foreground"
186− : "text-muted-foreground hover:bg-accent/60 hover:text-foreground",
187− )}
188− >
189− <Tooltip>
190− <TooltipTrigger
191− render={
192− <button
193− type="button"
194− className="flex min-w-0 flex-1 items-center gap-1.5"
195− onClick={() => props.onActivate(surface)}
196− >
197− <SurfaceIcon surface={surface} sessions={props.previewSessions} />
198− <span className="truncate">{title}</span>
199− </button>
200− }
201− />
202− <TooltipPopup>{title}</TooltipPopup>
203− </Tooltip>
204− <button
205− type="button"
206− className="rounded p-0.5 opacity-0 hover:bg-muted group-hover:opacity-100 focus:opacity-100"
207− aria-label={`Close ${title}`}
208− onClick={() => props.onCloseSurface(surface)}
219+ <ScrollArea
220+ ref={tabListRef}
221+ hideScrollbars
222+ scrollFade
223+ className="min-w-0 flex-1 rounded-none"
224+ data-right-panel-tab-list
225+ >
226+ <div className="flex h-full w-max min-w-full items-center gap-1">
227+ {props.surfaces.map((surface) => {
228+ const active = surface.id === props.activeSurfaceId;
229+ const pending = props.pendingSurfaceIds.has(surface.id);
230+ const title = surfaceTitle(surface, props.previewSessions, props.terminalLabelsById);
231+ return (
232+ <div
233+ key={surface.id}
234+ data-active-tab={active}
235+ className={cn(
236+ "group flex h-7 min-w-25 max-w-44 shrink-0 items-center gap-1.5 rounded-md px-2 text-sm",
237+ active
238+ ? "bg-accent text-foreground"
239+ : "text-muted-foreground hover:bg-accent/60 hover:text-foreground",
240+ )}
209241 >
210− <X className="size-3" />
211− </button>
212− </div>
213− );
214− })}
215− </div>
216− <Menu>
217− <MenuTrigger
218− className="relative ml-1 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground"
219− aria-label="Add panel surface"
220− >
221− <Plus className="size-4" />
222− </MenuTrigger>
223− <MenuPopup align="start" side="bottom" sideOffset={6} className="min-w-44">
224− <MenuItem onClick={props.onAddBrowser} disabled={!props.browserAvailable}>
225− <Globe2 />
226− Browser
227− </MenuItem>
228− <MenuItem onClick={props.onAddTerminal}>
229− <TerminalSquare />
230− Terminal
231− </MenuItem>
232− <MenuItem onClick={props.onAddDiff} disabled={!props.diffAvailable}>
233− <FileDiff />
234− Diff
235− </MenuItem>
236− </MenuPopup>
237− </Menu>
242+ <Tooltip>
243+ <TooltipTrigger
244+ render={
245+ <button
246+ type="button"
247+ className="flex min-w-0 flex-1 items-center gap-1.5"
248+ onClick={() => props.onActivate(surface)}
249+ >
250+ <SurfaceIcon
251+ surface={surface}
252+ sessions={props.previewSessions}
253+ theme={resolvedTheme}
254+ />
255+ <span className="truncate">{title}</span>
256+ </button>
257+ }
258+ />
259+ <TooltipPopup>{title}</TooltipPopup>
260+ </Tooltip>
261+ <button
262+ type="button"
263+ className={cn(
264+ "relative flex size-4 shrink-0 items-center justify-center rounded hover:bg-muted focus:opacity-100",
265+ pending ? "opacity-100" : "opacity-0 group-hover:opacity-100",
266+ )}
267+ aria-label={`Close ${title}`}
268+ onClick={() => props.onCloseSurface(surface)}
269+ >
270+ {pending ? (
271+ <>
272+ <span
273+ className="size-2 rounded-full bg-current group-hover:hidden"
274+ aria-hidden
275+ />
276+ <X className="hidden size-3 group-hover:block" />
277+ </>
278+ ) : (
279+ <X className="size-3" />
280+ )}
281+ </button>
282+ </div>
283+ );
284+ })}
285+ {props.surfaces.length > 0 ? (
286+ <Menu>
287+ <MenuTrigger
288+ className="relative inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground"
289+ aria-label="Add panel surface"
290+ >
291+ <Plus className="size-4" />
292+ </MenuTrigger>
293+ <MenuPopup align="start" side="bottom" sideOffset={6} className="min-w-44">
294+ <MenuItem onClick={props.onAddBrowser} disabled={!props.browserAvailable}>
295+ <Globe2 />
296+ Browser
297+ </MenuItem>
298+ <MenuItem onClick={props.onAddTerminal}>
299+ <TerminalSquare />
300+ Terminal
301+ </MenuItem>
302+ <MenuItem onClick={props.onAddFiles} disabled={!props.filesAvailable}>
303+ <Files />
304+ Files
305+ </MenuItem>
306+ <MenuItem onClick={props.onAddDiff} disabled={!props.diffAvailable}>
307+ <FileDiff />
308+ Diff
309+ </MenuItem>
310+ </MenuPopup>
311+ </Menu>
312+ ) : null}
313+ </div>
314+ </ScrollArea>
238315 </div>
239316 <div className="flex min-h-0 flex-1 flex-col">
240317 {props.activeSurfaceId === null ? (
@@ -242,8 +319,10 @@ export function RightPanelTabs(props: RightPanelTabsProps) { · 1 unmodified line
242319 onAddBrowser={props.onAddBrowser}
243320 onAddTerminal={props.onAddTerminal}
244321 onAddDiff={props.onAddDiff}
322+ onAddFiles={props.onAddFiles}
245323 browserAvailable={props.browserAvailable}
246324 diffAvailable={props.diffAvailable}
325+ filesAvailable={props.filesAvailable}
247326 />
248327 ) : (
249328 props.children
apps/web/src/components/chat/ChangedFilesTree.tsx+2−2
@@ -9,7 +9,7 @@ import { · 8 unmodified lines
99 import { ChevronRightIcon, FolderIcon, FolderClosedIcon } from "lucide-react";
1010 import { cn } from "~/lib/utils";
1111 import { DiffStatLabel, hasNonZeroStat } from "./DiffStatLabel";
12−import { VscodeEntryIcon } from "./VscodeEntryIcon";
12+import { PierreEntryIcon } from "./PierreEntryIcon";
1313 import { Button } from "../ui/button";
1414
1515 const EMPTY_DIRECTORY_OVERRIDES: Record<string, boolean> = {};
@@ -177,7 +177,7 @@ export const ChangedFilesTree = memo(function ChangedFilesTree(props: { · 161 unmodified lines
177177 {hasDirectoryNodes || depth > 0 ? (
178178 <span aria-hidden="true" className="size-3.5 shrink-0" />
179179 ) : null}
180− <VscodeEntryIcon
180+ <PierreEntryIcon
181181 pathValue={node.path}
182182 kind="file"
183183 theme={resolvedTheme}
apps/web/src/components/chat/ChatComposer.tsx+1−1
@@ -79,7 +79,7 @@ import { · 78 unmodified lines
7979 } from "./composerProviderState";
8080 import { ContextWindowMeter } from "./ContextWindowMeter";
8181 import { buildExpandedImagePreview, type ExpandedImagePreview } from "./ExpandedImagePreview";
82−import { basenameOfPath } from "../../vscode-icons";
82+import { basenameOfPath } from "../../pierre-icons";
8383 import { cn, randomUUID } from "~/lib/utils";
8484 import { Separator } from "../ui/separator";
8585 import { Button } from "../ui/button";
apps/web/src/components/chat/ChatHeader.tsx+11−64
@@ -9,14 +9,12 @@ import { scopeThreadRef } from "@t3tools/client-runtime"; · 8 unmodified lines
99 import { memo } from "react";
1010 import GitActionsControl from "../GitActionsControl";
1111 import { type DraftId } from "~/composerDraftStore";
12−import { PanelBottomIcon, PanelRightIcon } from "lucide-react";
1312 import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
1413 import ProjectScriptsControl, { type NewProjectScriptInput } from "../ProjectScriptsControl";
15−import { Toggle } from "../ui/toggle";
1614 import { SidebarTrigger } from "../ui/sidebar";
1715 import { OpenInPicker } from "./OpenInPicker";
18−import { usePrimaryEnvironmentId } from "../../environments/primary";
19−import { shortcutLabelForCommand } from "../../keybindings";
16+import { usePrimaryEnvironmentId } from "../../environments/primary/context";
17+import { cn } from "~/lib/utils";
2018
2119 interface ChatHeaderProps {
2220 activeThreadEnvironmentId: EnvironmentId;
@@ -29,17 +27,12 @@ interface ChatHeaderProps { · 6 unmodified lines
2927 preferredScriptId: string | null;
3028 keybindings: ResolvedKeybindingsConfig;
3129 availableEditors: ReadonlyArray<EditorId>;
32− terminalAvailable: boolean;
33− terminalOpen: boolean;
34− rightPanelAvailable: boolean;
35− rightPanelOpen: boolean;
3630 gitCwd: string | null;
3731 onRunProjectScript: (script: ProjectScript) => void;
3832 onAddProjectScript: (input: NewProjectScriptInput) => Promise<void>;
3933 onUpdateProjectScript: (scriptId: string, input: NewProjectScriptInput) => Promise<void>;
4034 onDeleteProjectScript: (scriptId: string) => Promise<void>;
41− onToggleTerminal: () => void;
42− onToggleRightPanel: () => void;
35+ rightPanelOpen: boolean;
4336 }
4437
4538 export function shouldShowOpenInPicker(input: {
@@ -65,17 +58,12 @@ export const ChatHeader = memo(function ChatHeader({ · 19 unmodified lines
6558 preferredScriptId,
6659 keybindings,
6760 availableEditors,
68− terminalAvailable,
69− terminalOpen,
70− rightPanelAvailable,
71− rightPanelOpen,
7261 gitCwd,
7362 onRunProjectScript,
7463 onAddProjectScript,
7564 onUpdateProjectScript,
7665 onDeleteProjectScript,
77− onToggleTerminal,
78− onToggleRightPanel,
66+ rightPanelOpen,
7967 }: ChatHeaderProps) {
8068 const primaryEnvironmentId = usePrimaryEnvironmentId();
8169 const showOpenInPicker = shouldShowOpenInPicker({
@@ -83,9 +71,6 @@ export const ChatHeader = memo(function ChatHeader({ · 1 unmodified line
8371 activeThreadEnvironmentId,
8472 primaryEnvironmentId,
8573 });
86− const terminalShortcutLabel = shortcutLabelForCommand(keybindings, "terminal.toggle");
87− const rightPanelShortcutLabel = shortcutLabelForCommand(keybindings, "rightPanel.toggle");
88−
8974 return (
9075 <div className="@container/header-actions flex min-w-0 flex-1 flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
9176 <div className="flex min-w-0 flex-wrap items-center gap-2 overflow-hidden sm:flex-1 sm:flex-nowrap sm:gap-3">
@@ -104,7 +89,13 @@ export const ChatHeader = memo(function ChatHeader({ · 12 unmodified lines
10489 <TooltipPopup side="top">{activeThreadTitle}</TooltipPopup>
10590 </Tooltip>
10691 </div>
107− <div className="flex min-w-0 flex-wrap items-center justify-start gap-2 sm:shrink-0 sm:justify-end @3xl/header-actions:gap-3">
92+ <div
93+ data-chat-header-actions
94+ className={cn(
95+ "flex min-w-0 flex-wrap items-center justify-start gap-2 sm:shrink-0 sm:justify-end @3xl/header-actions:gap-3",
96+ rightPanelOpen ? "pr-0" : "pr-16",
97+ )}
98+ >
10899 {activeProjectScripts && (
109100 <ProjectScriptsControl
110101 scripts={activeProjectScripts}
@@ -130,50 +121,6 @@ export const ChatHeader = memo(function ChatHeader({ · 19 unmodified lines
130121 {...(draftId ? { draftId } : {})}
131122 />
132123 )}
133− <Tooltip>
134− <TooltipTrigger
135− render={
136− <Toggle
137− className="shrink-0"
138− pressed={terminalOpen}
139− onPressedChange={onToggleTerminal}
140− aria-label="Toggle terminal drawer"
141− variant="ghost"
142− size="xs"
143− disabled={!terminalAvailable}
144− >
145− <PanelBottomIcon className="size-3.5" />
146− </Toggle>
147− }
148− />
149− <TooltipPopup side="bottom">
150− {terminalAvailable
151− ? `Toggle terminal drawer${terminalShortcutLabel ? ` (${terminalShortcutLabel})` : ""}`
152− : "Terminal drawer is unavailable"}
153− </TooltipPopup>
154− </Tooltip>
155− <Tooltip>
156− <TooltipTrigger
157− render={
158− <Toggle
159− className="shrink-0"
160− pressed={rightPanelOpen}
161− onPressedChange={onToggleRightPanel}
162− aria-label="Toggle right panel"
163− variant="ghost"
164− size="xs"
165− disabled={!rightPanelAvailable}
166− >
167− <PanelRightIcon className="size-3.5" />
168− </Toggle>
169− }
170− />
171− <TooltipPopup side="bottom">
172− {rightPanelAvailable
173− ? `Toggle right panel${rightPanelShortcutLabel ? ` (${rightPanelShortcutLabel})` : ""}`
174− : "Right panel is unavailable"}
175− </TooltipPopup>
176− </Tooltip>
177124 </div>
178125 </div>
179126 );
apps/web/src/components/chat/ComposerCommandMenu.tsx+2−2
@@ -18,7 +18,7 @@ import { · 17 unmodified lines
1818 CommandList,
1919 CommandSeparator,
2020 } from "../ui/command";
21−import { VscodeEntryIcon } from "./VscodeEntryIcon";
21+import { PierreEntryIcon } from "./PierreEntryIcon";
2222
2323 export type ComposerCommandItem =
2424 | {
@@ -228,7 +228,7 @@ const ComposerCommandMenuItem = memo(function ComposerCommandMenuItem(props: { · 203 unmodified lines
228228 }}
229229 >
230230 {props.item.type === "path" ? (
231− <VscodeEntryIcon
231+ <PierreEntryIcon
232232 pathValue={props.item.path}
233233 kind={props.item.pathKind}
234234 theme={props.resolvedTheme}
apps/web/src/components/chat/FileTagChip.tsx+3−3
@@ -1,4 +1,4 @@
1−import { inferEntryKindFromPath } from "../../vscode-icons";
1+import { inferEntryKindFromPath } from "../../pierre-icons";
22 import {
33 CHAT_INLINE_CHIP_CLASS_NAME,
44 CHAT_INLINE_CHIP_LABEL_CLASS_NAME,
@@ -6,7 +6,7 @@ import { · 1 unmodified line
66 COMPOSER_INLINE_CHIP_ICON_CLASS_NAME,
77 COMPOSER_INLINE_CHIP_LABEL_CLASS_NAME,
88 } from "../composerInlineChip";
9−import { VscodeEntryIcon } from "./VscodeEntryIcon";
9+import { PierreEntryIcon } from "./PierreEntryIcon";
1010
1111 export const FILE_TAG_CHIP_CLASS_NAME = COMPOSER_INLINE_CHIP_CLASS_NAME;
1212 export const CHAT_FILE_TAG_CHIP_CLASS_NAME = CHAT_INLINE_CHIP_CLASS_NAME;
@@ -19,7 +19,7 @@ export function FileTagChipContent(props: { · 6 unmodified lines
1919 }) {
2020 return (
2121 <>
22− <VscodeEntryIcon
22+ <PierreEntryIcon
2323 pathValue={props.path}
2424 kind={inferEntryKindFromPath(props.path)}
2525 theme={props.theme}
apps/web/src/components/chat/MessagesTimeline.browser.tsx+2−6
@@ -7,8 +7,6 @@ import { page } from "vite-plus/test/browser"; · 6 unmodified lines
77 import { afterEach, describe, expect, it, vi } from "vite-plus/test";
88 import { render } from "vitest-browser-react";
99
10−import { getVscodeIconUrlForEntry } from "../../vscode-icons";
11−
1210 const scrollToEndSpy = vi.fn();
1311 const getStateSpy = vi.fn(() => ({ isAtEnd: true }));
1412
@@ -392,14 +390,12 @@ describe("MessagesTimeline", () => { · 377 unmodified lines
392390 const assistantFileLink = document.querySelector(
393391 '[data-message-role="assistant"] .chat-markdown-file-link',
394392 );
395− const icon = assistantFileLink?.querySelector("img");
393+ const icon = assistantFileLink?.querySelector("svg[data-pierre-icon]");
396394
397395 expect(assistantFileLink?.textContent).toContain("package.json");
398396 expect(assistantFileLink?.textContent).toContain("L25");
399397 expect(assistantFileLink?.getAttribute("href")).toBe("/repo/project/path/to/package.json:25");
400− expect(icon?.getAttribute("src")).toBe(
401− getVscodeIconUrlForEntry("/repo/project/path/to/package.json", "file", "dark"),
402− );
398+ expect(icon?.getAttribute("data-pierre-icon")).toBe("t3-file-icon-package-json");
403399 } finally {
404400 await screen.unmount();
405401 }
apps/web/src/components/chat/PanelLayoutControls.tsx+114−0
@@ -0,0 +1,114 @@
1+import { Maximize2Icon, Minimize2Icon, PanelBottomIcon, PanelRightIcon } from "lucide-react";
2+import { memo } from "react";
3+
4+import { cn } from "~/lib/utils";
5+
6+import { Toggle } from "../ui/toggle";
7+import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
8+
9+interface PanelLayoutControlsProps {
10+ terminalAvailable: boolean;
11+ terminalOpen: boolean;
12+ terminalShortcutLabel: string | null;
13+ rightPanelAvailable: boolean;
14+ rightPanelOpen: boolean;
15+ rightPanelShortcutLabel: string | null;
16+ rightPanelMaximized: boolean;
17+ canMaximizeRightPanel: boolean;
18+ onToggleTerminal: () => void;
19+ onToggleRightPanel: () => void;
20+ onToggleRightPanelMaximized: () => void;
21+}
22+
23+export const PanelLayoutControls = memo(function PanelLayoutControls({
24+ terminalAvailable,
25+ terminalOpen,
26+ terminalShortcutLabel,
27+ rightPanelAvailable,
28+ rightPanelOpen,
29+ rightPanelShortcutLabel,
30+ rightPanelMaximized,
31+ canMaximizeRightPanel,
32+ onToggleTerminal,
33+ onToggleRightPanel,
34+ onToggleRightPanelMaximized,
35+}: PanelLayoutControlsProps) {
36+ return (
37+ <div className={cn("workspace-titlebar-controls z-50 gap-1")} data-panel-layout-controls>
38+ {rightPanelOpen ? (
39+ <Tooltip>
40+ <TooltipTrigger
41+ render={
42+ <Toggle
43+ className="shrink-0"
44+ pressed={rightPanelMaximized}
45+ onPressedChange={onToggleRightPanelMaximized}
46+ aria-label={rightPanelMaximized ? "Restore panel size" : "Maximize panel"}
47+ variant="ghost"
48+ size="sm"
49+ disabled={!canMaximizeRightPanel}
50+ >
51+ {rightPanelMaximized ? (
52+ <Minimize2Icon className="size-3.5" />
53+ ) : (
54+ <Maximize2Icon className="size-3.5" />
55+ )}
56+ </Toggle>
57+ }
58+ />
59+ <TooltipPopup side="bottom">
60+ {canMaximizeRightPanel
61+ ? rightPanelMaximized
62+ ? "Restore panel size"
63+ : "Maximize panel"
64+ : "Panel maximization is unavailable at this width"}
65+ </TooltipPopup>
66+ </Tooltip>
67+ ) : null}
68+ <Tooltip>
69+ <TooltipTrigger
70+ render={
71+ <Toggle
72+ className="shrink-0"
73+ pressed={terminalOpen}
74+ onPressedChange={onToggleTerminal}
75+ aria-label="Toggle terminal drawer"
76+ variant="ghost"
77+ size="sm"
78+ disabled={!terminalAvailable}
79+ >
80+ <PanelBottomIcon className="size-3.5" />
81+ </Toggle>
82+ }
83+ />
84+ <TooltipPopup side="bottom">
85+ {terminalAvailable
86+ ? `Toggle terminal drawer${terminalShortcutLabel ? ` (${terminalShortcutLabel})` : ""}`
87+ : "Terminal drawer is unavailable"}
88+ </TooltipPopup>
89+ </Tooltip>
90+ <Tooltip>
91+ <TooltipTrigger
92+ render={
93+ <Toggle
94+ className="shrink-0"
95+ pressed={rightPanelOpen}
96+ onPressedChange={onToggleRightPanel}
97+ aria-label="Toggle right panel"
98+ variant="ghost"
99+ size="sm"
100+ disabled={!rightPanelAvailable}
101+ >
102+ <PanelRightIcon className="size-3.5" />
103+ </Toggle>
104+ }
105+ />
106+ <TooltipPopup side="bottom">
107+ {rightPanelAvailable
108+ ? `Toggle right panel${rightPanelShortcutLabel ? ` (${rightPanelShortcutLabel})` : ""}`
109+ : "Right panel is unavailable"}
110+ </TooltipPopup>
111+ </Tooltip>
112+ </div>
113+ );
114+});
apps/web/src/components/chat/PierreEntryIcon.tsx+95−0
@@ -0,0 +1,95 @@
1+import { FileIcon, FolderIcon } from "lucide-react";
2+import { memo, useInsertionEffect, useMemo } from "react";
3+
4+import { ensurePierreIconSprite, resolvePierreIconForEntry } from "../../pierre-icons";
5+import { cn } from "~/lib/utils";
6+
7+const ICON_COLORS: Record<string, readonly [light: string, dark: string]> = {
8+ astro: ["#a631be", "#d568ea"],
9+ babel: ["#d5a910", "#ffd452"],
10+ bash: ["#199f43", "#5ecc71"],
11+ biome: ["#1a85d4", "#69b1ff"],
12+ bootstrap: ["#693acf", "#9d6afb"],
13+ browserslist: ["#d5a910", "#ffd452"],
14+ bun: ["#594c5b", "#79697b"],
15+ c: ["#1a85d4", "#69b1ff"],
16+ claude: ["#d47628", "#ffa359"],
17+ cpp: ["#1a85d4", "#69b1ff"],
18+ css: ["#693acf", "#9d6afb"],
19+ database: ["#a631be", "#d568ea"],
20+ default: ["#84848a", "#adadb1"],
21+ docker: ["#1a85d4", "#69b1ff"],
22+ eslint: ["#693acf", "#9d6afb"],
23+ git: ["#ff8c5b", "#d5512f"],
24+ go: ["#1ca1c7", "#68cdf2"],
25+ graphql: ["#d32a61", "#ff678d"],
26+ html: ["#d47628", "#ffa359"],
27+ image: ["#d32a61", "#ff678d"],
28+ javascript: ["#d5a910", "#ffd452"],
29+ json: ["#d47628", "#ffa359"],
30+ markdown: ["#199f43", "#5ecc71"],
31+ mcp: ["#17a5af", "#64d1db"],
32+ nextjs: ["#84848a", "#adadb1"],
33+ npm: ["#d52c36", "#ff6762"],
34+ oxc: ["#1ca1c7", "#68cdf2"],
35+ postcss: ["#d52c36", "#ff6762"],
36+ prettier: ["#17a5af", "#64d1db"],
37+ python: ["#1a85d4", "#69b1ff"],
38+ react: ["#1ca1c7", "#68cdf2"],
39+ ruby: ["#d52c36", "#ff6762"],
40+ rust: ["#d47628", "#ffa359"],
41+ sass: ["#d32a61", "#ff678d"],
42+ stylelint: ["#84848a", "#adadb1"],
43+ svelte: ["#d52c36", "#ff6762"],
44+ svg: ["#d47628", "#ffa359"],
45+ svgo: ["#199f43", "#5ecc71"],
46+ swift: ["#d47628", "#ffa359"],
47+ table: ["#17a5af", "#64d1db"],
48+ tailwind: ["#1ca1c7", "#68cdf2"],
49+ terraform: ["#693acf", "#9d6afb"],
50+ text: ["#84848a", "#adadb1"],
51+ typescript: ["#1a85d4", "#69b1ff"],
52+ vite: ["#a631be", "#d568ea"],
53+ vscode: ["#1a85d4", "#69b1ff"],
54+ vue: ["#199f43", "#5ecc71"],
55+ wasm: ["#693acf", "#9d6afb"],
56+ webpack: ["#1a85d4", "#69b1ff"],
57+ yml: ["#d52c36", "#ff6762"],
58+ zig: ["#d47628", "#ffa359"],
59+ zip: ["#d47628", "#ffa359"],
60+};
61+
62+export const PierreEntryIcon = memo(function PierreEntryIcon(props: {
63+ pathValue: string;
64+ kind: "file" | "directory";
65+ theme: "light" | "dark";
66+ className?: string;
67+}) {
68+ useInsertionEffect(ensurePierreIconSprite, []);
69+ const icon = useMemo(
70+ () => resolvePierreIconForEntry(props.pathValue, props.kind),
71+ [props.kind, props.pathValue],
72+ );
73+
74+ if (!icon) {
75+ return props.kind === "directory" ? (
76+ <FolderIcon className={cn("size-4 text-muted-foreground/80", props.className)} />
77+ ) : (
78+ <FileIcon className={cn("size-4 text-muted-foreground/80", props.className)} />
79+ );
80+ }
81+
82+ const colors = ICON_COLORS[icon.token ?? "default"] ?? ICON_COLORS.default;
83+ return (
84+ <svg
85+ aria-hidden="true"
86+ data-pierre-icon={icon.name}
87+ data-icon-token={icon.token}
88+ className={cn("size-4 shrink-0", props.className)}
89+ style={{ color: colors?.[props.theme === "light" ? 0 : 1] }}
90+ viewBox="0 0 16 16"
91+ >
92+ <use href={`#${icon.name}`} />
93+ </svg>
94+ );
95+});
apps/web/src/components/chat/VscodeEntryIcon.tsx+0−37
@@ -1,37 +0,0 @@
1−import { memo, useMemo, useState } from "react";
2−import { getVscodeIconUrlForEntry } from "../../vscode-icons";
3−import { FileIcon, FolderIcon } from "lucide-react";
4−import { cn } from "~/lib/utils";
5−
6−export const VscodeEntryIcon = memo(function VscodeEntryIcon(props: {
7− pathValue: string;
8− kind: "file" | "directory";
9− theme: "light" | "dark";
10− className?: string;
11−}) {
12− const [failedIconUrl, setFailedIconUrl] = useState<string | null>(null);
13− const iconUrl = useMemo(
14− () => getVscodeIconUrlForEntry(props.pathValue, props.kind, props.theme),
15− [props.kind, props.pathValue, props.theme],
16− );
17− const failed = failedIconUrl === iconUrl;
18−
19− if (failed) {
20− return props.kind === "directory" ? (
21− <FolderIcon className={cn("size-4 text-muted-foreground/80", props.className)} />
22− ) : (
23− <FileIcon className={cn("size-4 text-muted-foreground/80", props.className)} />
24− );
25− }
26−
27− return (
28− <img
29− src={iconUrl}
30− alt=""
31− aria-hidden="true"
32− className={cn("size-4 shrink-0", props.className)}
33− loading="lazy"
34− onError={() => setFailedIconUrl(iconUrl)}
35− />
36− );
37−});
apps/web/src/components/files/FileBrowserPanel.tsx+128−0
@@ -0,0 +1,128 @@
1+import type { EnvironmentId, ProjectEntry } from "@t3tools/contracts";
2+import { FileTree, useFileTree } from "@pierre/trees/react";
3+import { RefreshCw, Search } from "lucide-react";
4+import { useEffect, useMemo, useRef } from "react";
5+
6+import { useTheme } from "~/hooks/useTheme";
7+import { cn } from "~/lib/utils";
8+import { T3_PIERRE_ICONS } from "~/pierre-icons";
9+
10+import { useProjectEntriesQuery } from "./projectFilesQueryState";
11+
12+interface FileBrowserPanelProps {
13+ environmentId: EnvironmentId;
14+ cwd: string;
15+ projectName: string;
16+ onOpenFile: (relativePath: string) => void;
17+}
18+
19+const TREE_UNSAFE_CSS = `
20+ :host {
21+ --trees-bg-override: transparent;
22+ --trees-selected-bg-override: color-mix(in srgb, currentColor 12%, transparent);
23+ --trees-hover-bg-override: color-mix(in srgb, currentColor 7%, transparent);
24+ --trees-border-color-override: color-mix(in srgb, currentColor 14%, transparent);
25+ --trees-font-family-override: var(--font-sans);
26+ --trees-font-size-override: 12px;
27+ }
28+ button[data-type='item'] { border-radius: 5px; }
29+`;
30+
31+function treePath(entry: ProjectEntry): string {
32+ return entry.kind === "directory" ? `${entry.path}/` : entry.path;
33+}
34+
35+export default function FileBrowserPanel({
36+ environmentId,
37+ cwd,
38+ projectName,
39+ onOpenFile,
40+}: FileBrowserPanelProps) {
41+ const { resolvedTheme } = useTheme();
42+ const entriesQuery = useProjectEntriesQuery(environmentId, cwd);
43+ const entries = entriesQuery.data?.entries ?? [];
44+ const entryKinds = useMemo(
45+ () => new Map(entries.map((entry) => [entry.path, entry.kind] as const)),
46+ [entries],
47+ );
48+ const entryKindsRef = useRef<ReadonlyMap<string, ProjectEntry["kind"]>>(entryKinds);
49+ const treePaths = useMemo(() => entries.map(treePath), [entries]);
50+ const previousTreePathsRef = useRef<readonly string[]>([]);
51+
52+ const { model } = useFileTree({
53+ density: "compact",
54+ fileTreeSearchMode: "hide-non-matches",
55+ flattenEmptyDirectories: true,
56+ initialExpansion: 1,
57+ icons: T3_PIERRE_ICONS,
58+ onSelectionChange: (selectedPaths) => {
59+ const selectedPath = selectedPaths.at(-1)?.replace(/\/$/, "");
60+ if (selectedPath && entryKindsRef.current.get(selectedPath) === "file") {
61+ onOpenFile(selectedPath);
62+ }
63+ },
64+ paths: [],
65+ search: true,
66+ unsafeCSS: TREE_UNSAFE_CSS,
67+ });
68+
69+ useEffect(() => {
70+ if (previousTreePathsRef.current === treePaths) return;
71+ entryKindsRef.current = entryKinds;
72+ previousTreePathsRef.current = treePaths;
73+ model.resetPaths(treePaths);
74+ }, [entryKinds, model, treePaths]);
75+
76+ const fileCount = useMemo(
77+ () => entries.reduce((count, entry) => count + (entry.kind === "file" ? 1 : 0), 0),
78+ [entries],
79+ );
80+
81+ return (
82+ <div
83+ className="flex min-h-0 flex-1 flex-col bg-background"
84+ data-file-browser-panel={`${environmentId}:${cwd}`}
85+ >
86+ <div className="flex h-9 shrink-0 items-center gap-2 border-b border-border/60 px-3">
87+ <div className="min-w-0 flex-1">
88+ <div className="truncate text-xs font-medium text-foreground">{projectName}</div>
89+ <div className="truncate text-[10px] leading-none text-muted-foreground">
90+ {entriesQuery.isPending && entriesQuery.data === null
91+ ? "Indexing…"
92+ : `${fileCount.toLocaleString()} files`}
93+ {entriesQuery.data?.truncated ? " · partial" : ""}
94+ </div>
95+ </div>
96+ <button
97+ type="button"
98+ className="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground"
99+ aria-label="Search workspace files"
100+ onClick={() => model.openSearch()}
101+ >
102+ <Search className="size-3.5" />
103+ </button>
104+ <button
105+ type="button"
106+ className="rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground"
107+ aria-label="Refresh workspace files"
108+ onClick={entriesQuery.refresh}
109+ >
110+ <RefreshCw className={cn("size-3.5", entriesQuery.isPending && "animate-spin")} />
111+ </button>
112+ </div>
113+ {entriesQuery.error && entriesQuery.data === null ? (
114+ <div className="p-4 text-xs leading-relaxed text-destructive">{entriesQuery.error}</div>
115+ ) : (
116+ <FileTree
117+ model={model}
118+ aria-label={`${projectName} files`}
119+ className="min-h-0 flex-1 overflow-hidden"
120+ style={{
121+ colorScheme: resolvedTheme,
122+ ["--trees-fg-override" as string]: "var(--foreground)",
123+ }}
124+ />
125+ )}
126+ </div>
127+ );
128+}
apps/web/src/components/files/FilePreviewPanel.tsx+298−0
@@ -0,0 +1,298 @@
1+import type { EnvironmentId } from "@t3tools/contracts";
2+import { Editor } from "@pierre/diffs/editor";
3+import { EditorProvider, File, Virtualizer } from "@pierre/diffs/react";
4+import { ChevronRight, FolderTree, LoaderCircle } from "lucide-react";
5+import { useEffect, useMemo, useRef, useState } from "react";
6+
7+import { ensureEnvironmentApi } from "~/environmentApi";
8+import { useTheme } from "~/hooks/useTheme";
9+import { resolveDiffThemeName } from "~/lib/diffRendering";
10+import { cn } from "~/lib/utils";
11+import { ScrollArea } from "~/components/ui/scroll-area";
12+import { Toggle } from "~/components/ui/toggle";
13+import { Tooltip, TooltipPopup, TooltipTrigger } from "~/components/ui/tooltip";
14+
15+import FileBrowserPanel from "./FileBrowserPanel";
16+import { projectFileCacheKey } from "./fileContentRevision";
17+import { fileBreadcrumbs } from "./filePath";
18+import { FileSaveCoordinator } from "./fileSaveCoordinator";
19+import {
20+ confirmProjectFileQueryData,
21+ setProjectFileQueryData,
22+ useProjectFileQuery,
23+} from "./projectFilesQueryState";
24+
25+interface FilePreviewPanelProps {
26+ environmentId: EnvironmentId;
27+ cwd: string;
28+ projectName: string;
29+ relativePath: string | null;
30+ onOpenFile: (relativePath: string) => void;
31+ onPendingChange: (relativePath: string, pending: boolean) => void;
32+}
33+
34+const FILE_EXPLORER_STORAGE_KEY = "t3code.fileExplorerOpen";
35+const FILE_SAVE_DEBOUNCE_MS = 500;
36+
37+interface EditableFileSurfaceProps {
38+ environmentId: EnvironmentId;
39+ cwd: string;
40+ relativePath: string;
41+ contents: string;
42+ resolvedTheme: "light" | "dark";
43+ onPendingChange: (relativePath: string, pending: boolean) => void;
44+}
45+
46+function EditableFileSurface({
47+ environmentId,
48+ cwd,
49+ relativePath,
50+ contents,
51+ resolvedTheme,
52+ onPendingChange,
53+}: EditableFileSurfaceProps) {
54+ const saveCoordinator = useMemo(
55+ () =>
56+ new FileSaveCoordinator({
57+ debounceMs: FILE_SAVE_DEBOUNCE_MS,
58+ onPendingChange: (pending) => onPendingChange(relativePath, pending),
59+ persist: async (nextContents) => {
60+ await ensureEnvironmentApi(environmentId).projects.writeFile({
61+ cwd,
62+ relativePath,
63+ contents: nextContents,
64+ });
65+ },
66+ onConfirmed: (confirmedContents) => {
67+ confirmProjectFileQueryData(environmentId, cwd, relativePath, confirmedContents);
68+ },
69+ }),
70+ [cwd, environmentId, onPendingChange, relativePath],
71+ );
72+ const editor = useMemo(
73+ () =>
74+ new Editor({
75+ onChange: (file) => {
76+ setProjectFileQueryData(environmentId, cwd, relativePath, file.contents);
77+ saveCoordinator.change(file.contents);
78+ },
79+ }),
80+ [cwd, environmentId, relativePath, saveCoordinator],
81+ );
82+
83+ useEffect(
84+ () => () => {
85+ editor.cleanUp();
86+ saveCoordinator.dispose();
87+ },
88+ [editor, saveCoordinator],
89+ );
90+
91+ return (
92+ <EditorProvider editor={editor}>
93+ <Virtualizer
94+ className="file-preview-virtualizer min-h-0 flex-1 overflow-auto"
95+ config={{
96+ overscrollSize: 600,
97+ intersectionObserverMargin: 1200,
98+ }}
99+ >
100+ <File
101+ file={{
102+ name: relativePath,
103+ contents,
104+ cacheKey: projectFileCacheKey(cwd, relativePath, contents),
105+ }}
106+ options={{
107+ disableFileHeader: true,
108+ overflow: "scroll",
109+ theme: resolveDiffThemeName(resolvedTheme),
110+ themeType: resolvedTheme,
111+ }}
112+ className="min-h-full"
113+ contentEditable
114+ />
115+ </Virtualizer>
116+ </EditorProvider>
117+ );
118+}
119+
120+function initialExplorerOpen(): boolean {
121+ try {
122+ return window.localStorage.getItem(FILE_EXPLORER_STORAGE_KEY) !== "false";
123+ } catch {
124+ return true;
125+ }
126+}
127+
128+export default function FilePreviewPanel({
129+ environmentId,
130+ cwd,
131+ projectName,
132+ relativePath,
133+ onOpenFile,
134+ onPendingChange,
135+}: FilePreviewPanelProps) {
136+ const { resolvedTheme } = useTheme();
137+ const file = useProjectFileQuery(environmentId, cwd, relativePath);
138+ const [explorerOpen, setExplorerOpen] = useState(initialExplorerOpen);
139+ const breadcrumbRef = useRef<HTMLDivElement>(null);
140+ const breadcrumbs = useMemo(
141+ () => (relativePath ? fileBreadcrumbs(projectName, relativePath) : []),
142+ [projectName, relativePath],
143+ );
144+
145+ useEffect(() => {
146+ const currentCrumb = breadcrumbRef.current?.querySelector<HTMLElement>(
147+ "[data-current-file-crumb='true']",
148+ );
149+ currentCrumb?.scrollIntoView({ block: "nearest", inline: "end" });
150+ }, [relativePath]);
151+
152+ const toggleExplorer = () => {
153+ setExplorerOpen((current) => {
154+ const next = !current;
155+ try {
156+ window.localStorage.setItem(FILE_EXPLORER_STORAGE_KEY, String(next));
157+ } catch {}
158+ return next;
159+ });
160+ };
161+
162+ return (
163+ <div className="flex min-h-0 flex-1 flex-col overflow-hidden bg-background">
164+ {relativePath ? (
165+ <div className="flex h-11 shrink-0 items-center gap-2 border-y border-border/60 px-3">
166+ <ScrollArea
167+ ref={breadcrumbRef}
168+ hideScrollbars
169+ scrollFade
170+ className="min-w-0 flex-1 rounded-none"
171+ data-file-breadcrumbs
172+ >
173+ <div className="flex h-full w-max min-w-full items-center text-xs">
174+ {breadcrumbs.map((crumb, index) => (
175+ <div
176+ key={crumb.path || "project"}
177+ className="flex min-w-0 shrink-0 items-center"
178+ data-current-file-crumb={crumb.kind === "file"}
179+ >
180+ {index > 0 ? (
181+ <ChevronRight className="mx-1 size-3.5 shrink-0 text-muted-foreground/60" />
182+ ) : null}
183+ <span
184+ className={cn(
185+ "max-w-40 truncate",
186+ crumb.kind === "file"
187+ ? "font-medium text-foreground"
188+ : "text-muted-foreground",
189+ )}
190+ title={crumb.path || projectName}
191+ >
192+ {crumb.label}
193+ </span>
194+ </div>
195+ ))}
196+ </div>
197+ </ScrollArea>
198+ <Tooltip>
199+ <TooltipTrigger
200+ render={
201+ <Toggle
202+ className="shrink-0"
203+ pressed={explorerOpen}
204+ onPressedChange={toggleExplorer}
205+ aria-label={explorerOpen ? "Hide file explorer" : "Show file explorer"}
206+ variant="ghost"
207+ size="sm"
208+ >
209+ <FolderTree className="size-3.5" />
210+ </Toggle>
211+ }
212+ />
213+ <TooltipPopup>
214+ {explorerOpen ? "Hide file explorer" : "Show file explorer"}
215+ </TooltipPopup>
216+ </Tooltip>
217+ </div>
218+ ) : null}
219+ {relativePath && file.data?.truncated ? (
220+ <div className="shrink-0 border-b border-amber-500/20 bg-amber-500/8 px-3 py-1.5 text-[11px] text-amber-700 dark:text-amber-300">
221+ Preview limited to the first 1 MB of a {file.data.byteLength.toLocaleString()} byte file.
222+ </div>
223+ ) : null}
224+ <div className="flex min-h-0 flex-1 overflow-hidden">
225+ <div
226+ className={cn(
227+ "min-w-0 flex-1 flex-col overflow-hidden",
228+ relativePath ? "flex" : "hidden",
229+ )}
230+ >
231+ {relativePath && file.error && file.data === null ? (
232+ <div className="flex min-h-0 flex-1 items-center justify-center px-6 text-center text-xs leading-relaxed text-destructive">
233+ {file.error}
234+ </div>
235+ ) : relativePath && file.data === null ? (
236+ <div className="flex min-h-0 flex-1 items-center justify-center text-muted-foreground">
237+ <LoaderCircle className="size-5 animate-spin" />
238+ </div>
239+ ) : relativePath && file.data ? (
240+ file.data.truncated ? (
241+ <Virtualizer
242+ key={`${relativePath}:${resolvedTheme}:${file.data.byteLength}`}
243+ className="file-preview-virtualizer min-h-0 flex-1 overflow-auto"
244+ config={{
245+ overscrollSize: 600,
246+ intersectionObserverMargin: 1200,
247+ }}
248+ >
249+ <File
250+ file={{
251+ name: relativePath,
252+ contents: file.data.contents,
253+ cacheKey: projectFileCacheKey(cwd, relativePath, file.data.contents),
254+ }}
255+ options={{
256+ disableFileHeader: true,
257+ overflow: "scroll",
258+ theme: resolveDiffThemeName(resolvedTheme),
259+ themeType: resolvedTheme,
260+ }}
261+ className="min-h-full"
262+ />
263+ </Virtualizer>
264+ ) : (
265+ <EditableFileSurface
266+ key={`${relativePath}:${resolvedTheme}`}
267+ environmentId={environmentId}
268+ cwd={cwd}
269+ relativePath={relativePath}
270+ contents={file.data.contents}
271+ resolvedTheme={resolvedTheme}
272+ onPendingChange={onPendingChange}
273+ />
274+ )
275+ ) : null}
276+ </div>
277+ {explorerOpen || relativePath === null ? (
278+ <aside
279+ className={cn(
280+ "flex min-h-0 shrink-0 bg-background",
281+ relativePath
282+ ? "w-[min(22rem,46%)] min-w-64 border-l border-border/60"
283+ : "min-w-0 flex-1",
284+ )}
285+ >
286+ <FileBrowserPanel
287+ key={`${environmentId}:${cwd}`}
288+ environmentId={environmentId}
289+ cwd={cwd}
290+ projectName={projectName}
291+ onOpenFile={onOpenFile}
292+ />
293+ </aside>
294+ ) : null}
295+ </div>
296+ </div>
297+ );
298+}
apps/web/src/components/files/fileContentRevision.test.ts+15−0
@@ -0,0 +1,15 @@
1+import { describe, expect, it } from "vite-plus/test";
2+
3+import { fileContentRevision, projectFileCacheKey } from "./fileContentRevision";
4+
5+describe("fileContentRevision", () => {
6+ it("changes for same-length edits", () => {
7+ expect(fileContentRevision("nodeVersion")).not.toBe(fileContentRevision("nodeVeasdrs"));
8+ });
9+
10+ it("keeps identical contents stable", () => {
11+ expect(projectFileCacheKey("/repo", "file.json", "contents")).toBe(
12+ projectFileCacheKey("/repo", "file.json", "contents"),
13+ );
14+ });
15+});
apps/web/src/components/files/fileContentRevision.ts+12−0
@@ -0,0 +1,12 @@
1+export function fileContentRevision(contents: string): string {
2+ let hash = 2_166_136_261;
3+ for (let index = 0; index < contents.length; index += 1) {
4+ hash ^= contents.charCodeAt(index);
5+ hash = Math.imul(hash, 16_777_619);
6+ }
7+ return `${contents.length}:${(hash >>> 0).toString(36)}`;
8+}
9+
10+export function projectFileCacheKey(cwd: string, relativePath: string, contents: string): string {
11+ return `${cwd}:${relativePath}:${fileContentRevision(contents)}`;
12+}
apps/web/src/components/files/filePath.test.ts+23−0
@@ -0,0 +1,23 @@
1+import { describe, expect, it } from "vite-plus/test";
2+
3+import { fileBreadcrumbs } from "./filePath";
4+
5+describe("fileBreadcrumbs", () => {
6+ it("builds project, directory, and file crumbs", () => {
7+ expect(fileBreadcrumbs("t3code", "apps/web/src/main.tsx")).toEqual([
8+ { label: "t3code", path: "", kind: "project" },
9+ { label: "apps", path: "apps", kind: "directory" },
10+ { label: "web", path: "apps/web", kind: "directory" },
11+ { label: "src", path: "apps/web/src", kind: "directory" },
12+ { label: "main.tsx", path: "apps/web/src/main.tsx", kind: "file" },
13+ ]);
14+ });
15+
16+ it("normalizes repeated separators", () => {
17+ expect(fileBreadcrumbs("workspace", "/src//index.ts").map((crumb) => crumb.label)).toEqual([
18+ "workspace",
19+ "src",
20+ "index.ts",
21+ ]);
22+ });
23+});
apps/web/src/components/files/filePath.ts+17−0
@@ -0,0 +1,17 @@
1+export interface FileBreadcrumb {
2+ label: string;
3+ path: string;
4+ kind: "project" | "directory" | "file";
5+}
6+
7+export function fileBreadcrumbs(projectName: string, relativePath: string): FileBreadcrumb[] {
8+ const parts = relativePath.split("/").filter(Boolean);
9+ return [
10+ { label: projectName, path: "", kind: "project" },
11+ ...parts.map((part, index) => ({
12+ label: part,
13+ path: parts.slice(0, index + 1).join("/"),
14+ kind: index === parts.length - 1 ? ("file" as const) : ("directory" as const),
15+ })),
16+ ];
17+}
apps/web/src/components/files/fileSaveCoordinator.test.ts+87−0
@@ -0,0 +1,87 @@
1+import { afterEach, describe, expect, it, vi } from "vite-plus/test";
2+
3+import { FileSaveCoordinator } from "./fileSaveCoordinator";
4+
5+function deferred() {
6+ let resolve!: () => void;
7+ const promise = new Promise<void>((resolvePromise) => {
8+ resolve = resolvePromise;
9+ });
10+ return { promise, resolve };
11+}
12+
13+describe("FileSaveCoordinator", () => {
14+ afterEach(() => {
15+ vi.useRealTimers();
16+ });
17+
18+ it("debounces edits and persists only the latest contents", async () => {
19+ vi.useFakeTimers();
20+ const persist = vi.fn<(contents: string) => Promise<void>>().mockResolvedValue(undefined);
21+ const onPendingChange = vi.fn();
22+ const onConfirmed = vi.fn();
23+ const coordinator = new FileSaveCoordinator({
24+ debounceMs: 500,
25+ persist,
26+ onPendingChange,
27+ onConfirmed,
28+ });
29+
30+ coordinator.change("first");
31+ await vi.advanceTimersByTimeAsync(300);
32+ coordinator.change("latest");
33+ await vi.advanceTimersByTimeAsync(499);
34+ expect(persist).not.toHaveBeenCalled();
35+
36+ await vi.advanceTimersByTimeAsync(1);
37+ expect(persist).toHaveBeenCalledOnce();
38+ expect(persist).toHaveBeenCalledWith("latest");
39+ expect(onConfirmed).toHaveBeenCalledWith("latest");
40+ expect(onPendingChange.mock.calls).toEqual([[true], [true], [false]]);
41+ });
42+
43+ it("keeps pending state until an edit made during a write is also saved", async () => {
44+ vi.useFakeTimers();
45+ const firstWrite = deferred();
46+ const persist = vi
47+ .fn<(contents: string) => Promise<void>>()
48+ .mockReturnValueOnce(firstWrite.promise)
49+ .mockResolvedValueOnce(undefined);
50+ const onPendingChange = vi.fn();
51+ const coordinator = new FileSaveCoordinator({
52+ debounceMs: 500,
53+ persist,
54+ onPendingChange,
55+ onConfirmed: vi.fn(),
56+ });
57+
58+ coordinator.change("first");
59+ await vi.advanceTimersByTimeAsync(500);
60+ coordinator.change("latest");
61+ await vi.advanceTimersByTimeAsync(500);
62+ expect(persist).toHaveBeenCalledTimes(1);
63+
64+ firstWrite.resolve();
65+ await vi.runAllTimersAsync();
66+ expect(persist).toHaveBeenCalledTimes(2);
67+ expect(persist).toHaveBeenLastCalledWith("latest");
68+ expect(onPendingChange.mock.calls.at(-1)).toEqual([false]);
69+ });
70+
71+ it("leaves the file pending when the latest write fails", async () => {
72+ vi.useFakeTimers();
73+ const onPendingChange = vi.fn();
74+ const coordinator = new FileSaveCoordinator({
75+ debounceMs: 500,
76+ persist: vi.fn().mockRejectedValue(new Error("write failed")),
77+ onPendingChange,
78+ onConfirmed: vi.fn(),
79+ });
80+
81+ coordinator.change("latest");
82+ await vi.advanceTimersByTimeAsync(500);
83+ await Promise.resolve();
84+ expect(onPendingChange).toHaveBeenCalledWith(true);
85+ expect(onPendingChange).not.toHaveBeenCalledWith(false);
86+ });
87+});
apps/web/src/components/files/fileSaveCoordinator.ts+75−0
@@ -0,0 +1,75 @@
1+export interface FileSaveCoordinatorOptions {
2+ readonly debounceMs: number;
3+ readonly persist: (contents: string) => Promise<void>;
4+ readonly onPendingChange: (pending: boolean) => void;
5+ readonly onConfirmed: (contents: string) => void;
6+}
7+
8+export class FileSaveCoordinator {
9+ private timer: ReturnType<typeof setTimeout> | null = null;
10+ private latestContents = "";
11+ private latestRevision = 0;
12+ private lastChangeAt = 0;
13+ private saving = false;
14+ private disposed = false;
15+
16+ constructor(private readonly options: FileSaveCoordinatorOptions) {}
17+
18+ change(contents: string): void {
19+ this.latestContents = contents;
20+ this.latestRevision += 1;
21+ this.lastChangeAt = Date.now();
22+ this.options.onPendingChange(true);
23+ this.schedule(this.options.debounceMs);
24+ }
25+
26+ dispose(): void {
27+ this.disposed = true;
28+ this.clearTimer();
29+ if (this.latestRevision > 0) void this.persistLatest();
30+ }
31+
32+ private schedule(delay: number): void {
33+ this.clearTimer();
34+ this.timer = setTimeout(() => {
35+ this.timer = null;
36+ void this.persistLatest();
37+ }, delay);
38+ }
39+
40+ private clearTimer(): void {
41+ if (this.timer === null) return;
42+ clearTimeout(this.timer);
43+ this.timer = null;
44+ }
45+
46+ private async persistLatest(): Promise<void> {
47+ if (this.saving || this.latestRevision === 0) return;
48+
49+ this.saving = true;
50+ const contents = this.latestContents;
51+ const revision = this.latestRevision;
52+ let succeeded = false;
53+ try {
54+ await this.options.persist(contents);
55+ succeeded = true;
56+ this.options.onConfirmed(contents);
57+ } catch {}
58+
59+ this.saving = false;
60+ if (revision === this.latestRevision) {
61+ if (succeeded) this.options.onPendingChange(false);
62+ return;
63+ }
64+
65+ const remainingDebounce = Math.max(
66+ 0,
67+ this.options.debounceMs - (Date.now() - this.lastChangeAt),
68+ );
69+ if (this.disposed) {
70+ void this.persistLatest();
71+ } else {
72+ this.schedule(remainingDebounce);
73+ }
74+ }
75+}
apps/web/src/components/files/projectFilesQueryState.test.ts+129−0
@@ -0,0 +1,129 @@
1+import type {
2+ EnvironmentApi,
3+ ProjectListEntriesResult,
4+ ProjectReadFileResult,
5+} from "@t3tools/contracts";
6+import { EnvironmentId } from "@t3tools/contracts";
7+import * as Option from "effect/Option";
8+import { AsyncResult, AtomRegistry } from "effect/unstable/reactivity";
9+import { afterEach, describe, expect, it, vi } from "vite-plus/test";
10+
11+import {
12+ __resetEnvironmentApiOverridesForTests,
13+ __setEnvironmentApiOverrideForTests,
14+} from "~/environmentApi";
15+import { appAtomRegistry } from "~/rpc/atomRegistry";
16+
17+import {
18+ __resetProjectFileQueryDataForTests,
19+ confirmProjectFileQueryData,
20+ getProjectEntriesQueryAtom,
21+ getProjectFileQueryAtom,
22+ resolveProjectFileQueryData,
23+ setProjectFileQueryData,
24+} from "./projectFilesQueryState";
25+
26+const environmentId = EnvironmentId.make("environment-project-files-query-test");
27+
28+function deferred<A>() {
29+ let resolve!: (value: A) => void;
30+ const promise = new Promise<A>((resolvePromise) => {
31+ resolve = resolvePromise;
32+ });
33+ return { promise, resolve };
34+}
35+
36+describe("project files queries", () => {
37+ afterEach(() => {
38+ __resetProjectFileQueryDataForTests();
39+ __resetEnvironmentApiOverridesForTests();
40+ vi.unstubAllGlobals();
41+ });
42+
43+ it("retains cached entries while explicitly revalidating", async () => {
44+ vi.stubGlobal("window", {});
45+ const first = {
46+ entries: [{ path: "README.md", kind: "file" }],
47+ truncated: false,
48+ } satisfies ProjectListEntriesResult;
49+ const second = {
50+ entries: [
51+ { path: "README.md", kind: "file" },
52+ { path: "src", kind: "directory" },
53+ ],
54+ truncated: false,
55+ } satisfies ProjectListEntriesResult;
56+ const revalidation = deferred<ProjectListEntriesResult>();
57+ const listEntries = vi
58+ .fn<EnvironmentApi["projects"]["listEntries"]>()
59+ .mockResolvedValueOnce(first)
60+ .mockReturnValueOnce(revalidation.promise);
61+ __setEnvironmentApiOverrideForTests(environmentId, {
62+ projects: { listEntries },
63+ } as unknown as EnvironmentApi);
64+ const registry = AtomRegistry.make();
65+ const atom = getProjectEntriesQueryAtom(environmentId, "/repo");
66+
67+ registry.get(atom);
68+ await vi.waitFor(() => {
69+ expect(Option.getOrNull(AsyncResult.value(registry.get(atom)))).toEqual(first);
70+ });
71+
72+ registry.refresh(atom);
73+ await vi.waitFor(() => expect(listEntries).toHaveBeenCalledTimes(2));
74+ const refreshing = registry.get(atom);
75+ expect(refreshing.waiting).toBe(true);
76+ expect(Option.getOrNull(AsyncResult.value(refreshing))).toEqual(first);
77+
78+ revalidation.resolve(second);
79+ await vi.waitFor(() => {
80+ expect(Option.getOrNull(AsyncResult.value(registry.get(atom)))).toEqual(second);
81+ });
82+ registry.dispose();
83+ });
84+
85+ it("keeps the latest optimistic draft when an older write finishes", async () => {
86+ vi.stubGlobal("window", {});
87+ const initial = {
88+ relativePath: "convex.json",
89+ contents: '{"nodeVersion":"20"}',
90+ byteLength: 20,
91+ truncated: false,
92+ } satisfies ProjectReadFileResult;
93+ const readFile = vi.fn<EnvironmentApi["projects"]["readFile"]>().mockResolvedValue(initial);
94+ __setEnvironmentApiOverrideForTests(environmentId, {
95+ projects: { readFile },
96+ } as unknown as EnvironmentApi);
97+ const atom = getProjectFileQueryAtom(environmentId, "/repo", "convex.json");
98+
99+ appAtomRegistry.get(atom);
100+ await vi.waitFor(() => {
101+ expect(Option.getOrNull(AsyncResult.value(appAtomRegistry.get(atom)))).toEqual(initial);
102+ });
103+
104+ setProjectFileQueryData(environmentId, "/repo", "convex.json", '{"nodeVersion":"220"}');
105+ setProjectFileQueryData(environmentId, "/repo", "convex.json", '{"nodeVersion":"22"}');
106+
107+ expect(
108+ confirmProjectFileQueryData(environmentId, "/repo", "convex.json", '{"nodeVersion":"220"}'),
109+ ).toBe(false);
110+
111+ expect(
112+ resolveProjectFileQueryData(
113+ environmentId,
114+ "/repo",
115+ "convex.json",
116+ Option.getOrNull(AsyncResult.value(appAtomRegistry.get(atom))),
117+ ),
118+ ).toEqual({
119+ relativePath: "convex.json",
120+ contents: '{"nodeVersion":"22"}',
121+ byteLength: 20,
122+ truncated: false,
123+ });
124+
125+ expect(
126+ confirmProjectFileQueryData(environmentId, "/repo", "convex.json", '{"nodeVersion":"22"}'),
127+ ).toBe(true);
128+ });
129+});
apps/web/src/components/files/projectFilesQueryState.ts+206−0
@@ -0,0 +1,206 @@
1+import { useAtomValue } from "@effect/atom-react";
2+import type {
3+ EnvironmentId,
4+ ProjectListEntriesResult,
5+ ProjectReadFileResult,
6+} from "@t3tools/contracts";
7+import * as Cause from "effect/Cause";
8+import * as Data from "effect/Data";
9+import * as Effect from "effect/Effect";
10+import * as Option from "effect/Option";
11+import { AsyncResult, Atom } from "effect/unstable/reactivity";
12+import { useCallback, useEffect } from "react";
13+
14+import { ensureEnvironmentApi } from "~/environmentApi";
15+import { appAtomRegistry } from "~/rpc/atomRegistry";
16+
17+const PROJECT_QUERY_STALE_TIME_MS = 30_000;
18+const PROJECT_QUERY_IDLE_TTL_MS = 5 * 60_000;
19+const EMPTY_PROJECT_FILE_PATH = "";
20+interface OptimisticProjectFile {
21+ readonly data: ProjectReadFileResult;
22+ readonly confirmed: boolean;
23+}
24+
25+const optimisticProjectFiles = new Map<string, OptimisticProjectFile>();
26+
27+class ProjectQueryError extends Data.TaggedError("ProjectQueryError")<{
28+ readonly message: string;
29+ readonly cause?: unknown;
30+}> {}
31+
32+function queryError(message: string, cause: unknown): ProjectQueryError {
33+ return new ProjectQueryError({ message, cause });
34+}
35+
36+function entriesKey(environmentId: EnvironmentId, cwd: string): string {
37+ return [environmentId, cwd].map(encodeURIComponent).join("|");
38+}
39+
40+function fileKey(environmentId: EnvironmentId, cwd: string, relativePath: string): string {
41+ return [environmentId, cwd, relativePath].map(encodeURIComponent).join("|");
42+}
43+
44+function keyParts(key: string): string[] {
45+ return key.split("|").map(decodeURIComponent);
46+}
47+
48+const projectEntriesQueryAtom = Atom.family((key: string) =>
49+ Atom.make(
50+ Effect.tryPromise({
51+ try: () => {
52+ const [environmentId, cwd] = keyParts(key) as [EnvironmentId, string];
53+ return ensureEnvironmentApi(environmentId).projects.listEntries({ cwd });
54+ },
55+ catch: (cause) => queryError("Could not load workspace files.", cause),
56+ }),
57+ ).pipe(
58+ Atom.swr({
59+ staleTime: PROJECT_QUERY_STALE_TIME_MS,
60+ revalidateOnMount: true,
61+ }),
62+ Atom.setIdleTTL(PROJECT_QUERY_IDLE_TTL_MS),
63+ Atom.withLabel(`projects:entries:${key}`),
64+ ),
65+);
66+
67+const projectFileQueryAtom = Atom.family((key: string) =>
68+ Atom.make(
69+ Effect.tryPromise({
70+ try: () => {
71+ const [environmentId, cwd, relativePath] = keyParts(key) as [EnvironmentId, string, string];
72+ if (relativePath === EMPTY_PROJECT_FILE_PATH) return Promise.resolve(null);
73+ return ensureEnvironmentApi(environmentId).projects.readFile({ cwd, relativePath });
74+ },
75+ catch: (cause) => queryError("Could not read workspace file.", cause),
76+ }),
77+ ).pipe(
78+ Atom.swr({
79+ staleTime: PROJECT_QUERY_STALE_TIME_MS,
80+ revalidateOnMount: true,
81+ }),
82+ Atom.setIdleTTL(PROJECT_QUERY_IDLE_TTL_MS),
83+ Atom.withLabel(`projects:file:${key}`),
84+ ),
85+);
86+
87+interface ProjectQueryState<A> {
88+ readonly data: A | null;
89+ readonly error: string | null;
90+ readonly isPending: boolean;
91+ readonly refresh: () => void;
92+}
93+
94+export function getProjectEntriesQueryAtom(environmentId: EnvironmentId, cwd: string) {
95+ return projectEntriesQueryAtom(entriesKey(environmentId, cwd));
96+}
97+
98+export function getProjectFileQueryAtom(
99+ environmentId: EnvironmentId,
100+ cwd: string,
101+ relativePath: string | null,
102+) {
103+ return projectFileQueryAtom(fileKey(environmentId, cwd, relativePath ?? EMPTY_PROJECT_FILE_PATH));
104+}
105+
106+export function setProjectFileQueryData(
107+ environmentId: EnvironmentId,
108+ cwd: string,
109+ relativePath: string,
110+ contents: string,
111+): void {
112+ const key = fileKey(environmentId, cwd, relativePath);
113+ optimisticProjectFiles.set(key, {
114+ confirmed: false,
115+ data: {
116+ relativePath,
117+ contents,
118+ byteLength: new TextEncoder().encode(contents).byteLength,
119+ truncated: false,
120+ },
121+ });
122+}
123+
124+export function confirmProjectFileQueryData(
125+ environmentId: EnvironmentId,
126+ cwd: string,
127+ relativePath: string,
128+ contents: string,
129+): boolean {
130+ const key = fileKey(environmentId, cwd, relativePath);
131+ const optimisticFile = optimisticProjectFiles.get(key);
132+ if (optimisticFile?.data.contents !== contents) return false;
133+
134+ optimisticProjectFiles.set(key, { ...optimisticFile, confirmed: true });
135+ appAtomRegistry.refresh(getProjectFileQueryAtom(environmentId, cwd, relativePath));
136+ return true;
137+}
138+
139+export function resolveProjectFileQueryData(
140+ environmentId: EnvironmentId,
141+ cwd: string,
142+ relativePath: string | null,
143+ data: ProjectReadFileResult | null,
144+): ProjectReadFileResult | null {
145+ if (relativePath === null) return data;
146+ return optimisticProjectFiles.get(fileKey(environmentId, cwd, relativePath))?.data ?? data;
147+}
148+
149+export function __resetProjectFileQueryDataForTests(): void {
150+ optimisticProjectFiles.clear();
151+}
152+
153+function errorMessage<A>(result: AsyncResult.AsyncResult<A, unknown>): string | null {
154+ if (result._tag !== "Failure") return null;
155+ const cause = Cause.squash(result.cause);
156+ return cause instanceof Error ? cause.message : "Workspace query failed.";
157+}
158+
159+export function useProjectEntriesQuery(
160+ environmentId: EnvironmentId,
161+ cwd: string,
162+): ProjectQueryState<ProjectListEntriesResult> {
163+ const atom = getProjectEntriesQueryAtom(environmentId, cwd);
164+ const result = useAtomValue(atom);
165+ const refresh = useCallback(() => appAtomRegistry.refresh(atom), [atom]);
166+ return {
167+ data: Option.getOrNull(AsyncResult.value(result)),
168+ error: errorMessage(result),
169+ isPending: result.waiting,
170+ refresh,
171+ };
172+}
173+
174+export function useProjectFileQuery(
175+ environmentId: EnvironmentId,
176+ cwd: string,
177+ relativePath: string | null,
178+): ProjectQueryState<ProjectReadFileResult> {
179+ const atom = getProjectFileQueryAtom(environmentId, cwd, relativePath);
180+ const result = useAtomValue(atom);
181+ const refresh = useCallback(() => appAtomRegistry.refresh(atom), [atom]);
182+ const data = Option.getOrNull(AsyncResult.value(result));
183+ const optimisticFile =
184+ relativePath === null
185+ ? undefined
186+ : optimisticProjectFiles.get(fileKey(environmentId, cwd, relativePath));
187+
188+ useEffect(() => {
189+ if (
190+ relativePath === null ||
191+ optimisticFile === undefined ||
192+ !optimisticFile.confirmed ||
193+ data?.contents !== optimisticFile.data.contents
194+ ) {
195+ return;
196+ }
197+ optimisticProjectFiles.delete(fileKey(environmentId, cwd, relativePath));
198+ }, [cwd, data?.contents, environmentId, optimisticFile, relativePath]);
199+
200+ return {
201+ data: optimisticFile?.data ?? data,
202+ error: errorMessage(result),
203+ isPending: result.waiting,
204+ refresh,
205+ };
206+}
apps/web/src/components/preview/PreviewPanelShell.tsx+13−4
@@ -21,7 +21,11 @@ const PREVIEW_PANEL_DEFAULT_WIDTH = 540; · 20 unmodified lines
2121 * via a drag handle on the left edge; width persists per browser. In
2222 * sheet/sidebar modes the parent owns the size.
2323 */
24−export function PreviewPanelShell(props: { mode: PreviewPanelMode; children: ReactNode }) {
24+export function PreviewPanelShell(props: {
25+ mode: PreviewPanelMode;
26+ maximized?: boolean;
27+ children: ReactNode;
28+}) {
2529 const useDragRegion = isElectron && props.mode !== "sheet" && props.mode !== "embedded";
2630 const isInline = props.mode === "inline";
2731 const maxWidth = useViewportClampedMaxWidth();
@@ -37,12 +41,17 @@ export function PreviewPanelShell(props: { mode: PreviewPanelMode; children: Rea · 9 unmodified lines
3741 <div
3842 className={cn(
3943 "relative flex h-full min-h-0 min-w-0 flex-col self-stretch bg-background",
40− isInline ? "shrink-0 border-l border-border" : "w-full",
44+ isInline
45+ ? props.maximized
46+ ? "flex-1 border-l border-border"
47+ : "shrink-0 border-l border-border"
48+ : "w-full",
4149 )}
42− style={isInline ? { width: `${width}px` } : undefined}
50+ style={isInline && !props.maximized ? { width: `${width}px` } : undefined}
4351 data-preview-panel-mode={props.mode}
52+ data-preview-panel-maximized={props.maximized ? "true" : "false"}
4453 >
45− {isInline ? <RightPanelResizeHandle handlers={handlers} /> : null}
54+ {isInline && !props.maximized ? <RightPanelResizeHandle handlers={handlers} /> : null}
4655 {useDragRegion ? <div className="electron-drag-region h-0 w-full" aria-hidden /> : null}
4756 {props.children}
4857 </div>
apps/web/src/environmentApi.ts+2−0
@@ -19,6 +19,8 @@ export function createEnvironmentApi(rpcClient: WsRpcClient): EnvironmentApi { · 18 unmodified lines
1919 onMetadata: (callback, options) => rpcClient.terminal.onMetadata(callback, options),
2020 },
2121 projects: {
22+ listEntries: rpcClient.projects.listEntries,
23+ readFile: rpcClient.projects.readFile,
2224 searchEntries: rpcClient.projects.searchEntries,
2325 writeFile: rpcClient.projects.writeFile,
2426 },
apps/web/src/environments/runtime/service.threadSubscriptions.test.ts+2−0
@@ -121,6 +121,8 @@ vi.mock("@t3tools/client-runtime", async (importOriginal) => { · 120 unmodified lines
121121 subscribePorts: vi.fn(() => () => undefined),
122122 },
123123 projects: {
124+ listEntries: vi.fn(),
125+ readFile: vi.fn(),
124126 searchEntries: vi.fn(),
125127 writeFile: vi.fn(),
126128 },
apps/web/src/index.css+43−0
@@ -4,6 +4,30 @@ · 3 unmodified lines
44 /* Window Controls Overlay: active when Electron exposes native titlebar control geometry. */
55 @custom-variant wco (&:is(.wco, .wco *));
66
7+:root {
8+ --workspace-topbar-height: 52px;
9+ --workspace-controls-top: 0px;
10+ --workspace-controls-right: calc(env(safe-area-inset-right) + 0.75rem);
11+ --workspace-native-controls-inset: 0px;
12+}
13+
14+@media (width >= 40rem) {
15+ :root {
16+ --workspace-controls-right: calc(env(safe-area-inset-right) + 1.25rem);
17+ }
18+}
19+
20+.wco {
21+ --workspace-topbar-height: env(titlebar-area-height, 52px);
22+ --workspace-controls-top: env(titlebar-area-y, 0px);
23+ --workspace-controls-right: calc(
24+ 100vw - env(titlebar-area-width, 100vw) - env(titlebar-area-x, 0px) + 1em
25+ );
26+ --workspace-native-controls-inset: calc(
27+ 100vw - env(titlebar-area-width, 100vw) - env(titlebar-area-x, 0px) + 1em
28+ );
29+}
30+
731 @theme inline {
832 --animate-skeleton: skeleton 2s -1s infinite linear;
933 --font-sans:
@@ -71,6 +95,25 @@ · 61 unmodified lines
7195 }
7296 }
7397
98+@layer components {
99+ .workspace-topbar {
100+ display: flex;
101+ height: var(--workspace-topbar-height);
102+ min-height: var(--workspace-topbar-height);
103+ flex-shrink: 0;
104+ align-items: center;
105+ }
106+
107+ .workspace-titlebar-controls {
108+ position: absolute;
109+ top: var(--workspace-controls-top);
110+ right: var(--workspace-controls-right);
111+ display: flex;
112+ height: var(--workspace-topbar-height);
113+ align-items: center;
114+ }
115+}
116+
74117 /* Safe-area inset utilities for surfaces that opt into edge-to-edge rendering.
75118 Insets resolve to 0 when the browser already constrains the layout viewport
76119 to the safe area. */
apps/web/src/localApi.test.ts+2−0
@@ -55,6 +55,8 @@ const rpcClientMock = { · 54 unmodified lines
5555 ),
5656 },
5757 projects: {
58+ listEntries: vi.fn(),
59+ readFile: vi.fn(),
5860 searchEntries: vi.fn(),
5961 writeFile: vi.fn(),
6062 },
apps/web/src/markdown-links.test.ts+9−0
@@ -83,6 +83,7 @@ describe("resolveMarkdownFileLinkTarget", () => { · 82 unmodified lines
8383 ),
8484 ).toMatchObject({
8585 displayPath: "t3code/apps/web/src/session-logic.ts:501",
86+ workspaceRelativePath: "apps/web/src/session-logic.ts",
8687 });
8788 });
8889
@@ -95,6 +96,14 @@ describe("resolveMarkdownFileLinkTarget", () => { · 6 unmodified lines
9596 ).toMatchObject({
9697 displayPath:
9798 "t3code/apps/web/src/components/chat/MessagesTimeline.virtualization.browser.tsx",
99+ workspaceRelativePath:
100+ "apps/web/src/components/chat/MessagesTimeline.virtualization.browser.tsx",
101+ });
102+ });
103+
104+ it("does not create a preview path for files outside the workspace", () => {
105+ expect(resolveMarkdownFileLinkMeta("/tmp/report.ts", "/repo/project")).toMatchObject({
106+ workspaceRelativePath: null,
98107 });
99108 });
100109
apps/web/src/markdown-links.ts+15−0
@@ -26,6 +26,7 @@ export interface MarkdownFileLinkMeta { · 25 unmodified lines
2626 filePath: string;
2727 targetPath: string;
2828 displayPath: string;
29+ workspaceRelativePath: string | null;
2930 basename: string;
3031 line?: number;
3132 column?: number;
@@ -174,6 +175,19 @@ function basenameOfPath(path: string): string { · 142 unmodified lines
174175 return separatorIndex >= 0 ? path.slice(separatorIndex + 1) : path;
175176 }
176177
178+function workspaceRelativePath(path: string, workspaceRoot: string | undefined): string | null {
179+ if (!workspaceRoot) return null;
180+ const normalizedPath = normalizeWindowsDrivePath(path.replaceAll("\\", "/"));
181+ const normalizedRoot = normalizeWindowsDrivePath(workspaceRoot.replaceAll("\\", "/")).replace(
182+ /\/+$/,
183+ "",
184+ );
185+ const pathForCompare = normalizedPath.toLowerCase();
186+ const rootForCompare = normalizedRoot.toLowerCase();
187+ if (!pathForCompare.startsWith(`${rootForCompare}/`)) return null;
188+ return normalizedPath.slice(normalizedRoot.length + 1);
189+}
190+
177191 export function resolveMarkdownFileLinkMeta(
178192 href: string | undefined,
179193 cwd?: string,
@@ -191,6 +205,7 @@ export function resolveMarkdownFileLinkMeta( · 11 unmodified lines
191205 filePath: path,
192206 targetPath,
193207 displayPath: formatWorkspaceRelativePath(targetPath, cwd),
208+ workspaceRelativePath: workspaceRelativePath(path, cwd),
194209 basename: basenameOfPath(path),
195210 ...(lineNumber !== undefined ? { line: lineNumber } : {}),
196211 ...(columnNumber !== undefined ? { column: columnNumber } : {}),
apps/web/src/pierre-icons.test.ts+57−0
@@ -0,0 +1,57 @@
1+import { assert, describe, it } from "vite-plus/test";
2+
3+import {
4+ hasSpecificPierreIconForFileName,
5+ resolvePierreIconForEntry,
6+ syntheticFileNameForLanguageId,
7+ T3_PIERRE_ICONS,
8+} from "./pierre-icons";
9+
10+describe("Pierre file icons", () => {
11+ it("uses Pierre exact filename and complete-set extension mappings", () => {
12+ assert.equal(resolvePierreIconForEntry("Dockerfile", "file")?.token, "docker");
13+ assert.equal(resolvePierreIconForEntry("src/Button.tsx", "file")?.token, "react");
14+ assert.equal(resolvePierreIconForEntry("vite.config.ts", "file")?.token, "vite");
15+ });
16+
17+ it("extends Pierre with T3-specific exact filename icons", () => {
18+ assert.equal(
19+ resolvePierreIconForEntry("package.json", "file")?.name,
20+ "t3-file-icon-package-json",
21+ );
22+ assert.equal(
23+ resolvePierreIconForEntry("config/tsconfig.json", "file")?.name,
24+ "t3-file-icon-tsconfig",
25+ );
26+ assert.equal(resolvePierreIconForEntry("AGENTS.md", "file")?.name, "t3-file-icon-agents");
27+ assert.equal(resolvePierreIconForEntry("CLAUDE.md", "file")?.name, "t3-file-icon-claude");
28+ assert.equal(resolvePierreIconForEntry("README.md", "file")?.name, "t3-file-icon-readme");
29+ assert.equal(resolvePierreIconForEntry("pnpm-lock.yaml", "file")?.name, "t3-file-icon-pnpm");
30+ assert.equal(
31+ resolvePierreIconForEntry("pnpm-workspace.yaml", "file")?.name,
32+ "t3-file-icon-pnpm",
33+ );
34+ });
35+
36+ it("ships every custom icon referenced by the extended resolver", () => {
37+ const customIconNames = new Set(Object.values(T3_PIERRE_ICONS.byFileName));
38+ for (const iconName of customIconNames) {
39+ assert.include(T3_PIERRE_ICONS.spriteSheet, `id="${iconName}"`);
40+ }
41+ });
42+
43+ it("uses the Pierre default icon for unknown file types", () => {
44+ assert.equal(resolvePierreIconForEntry("artifact.unknown-ext", "file")?.token, "default");
45+ assert.isFalse(hasSpecificPierreIconForFileName("artifact.unknown-ext"));
46+ });
47+
48+ it("leaves directory rendering to the shared folder fallback", () => {
49+ assert.isNull(resolvePierreIconForEntry("packages/client-runtime", "directory"));
50+ });
51+
52+ it("normalizes common markdown fence language aliases", () => {
53+ assert.equal(syntheticFileNameForLanguageId("typescript"), "file.ts");
54+ assert.equal(syntheticFileNameForLanguageId("shellscript"), "file.sh");
55+ assert.equal(syntheticFileNameForLanguageId("python"), "file.py");
56+ });
57+});
apps/web/src/pierre-icons.ts+117−0
@@ -0,0 +1,117 @@
1+import {
2+ createFileTreeIconResolver,
3+ getBuiltInSpriteSheet,
4+ type FileTreeIcons,
5+} from "@pierre/trees";
6+
7+export interface PierreIconResolution {
8+ name: string;
9+ token?: string;
10+}
11+
12+const PIERRE_ICON_SPRITE_ID = "t3code-pierre-file-icon-sprite";
13+
14+const T3_FILE_ICON_SPRITE = `
15+<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" aria-hidden="true">
16+ <symbol id="t3-file-icon-package-json" viewBox="0 0 32 32">
17+ <path d="M2 2H30V30H2" fill="#c12127" />
18+ <path d="M7.25 7.25h17.5v17.5h-3.5v-14H16v14H7.25" fill="#fff" />
19+ </symbol>
20+ <symbol id="t3-file-icon-tsconfig" viewBox="0 0 32 32">
21+ <path d="M23.827 8.243a4.424 4.424 0 0 1 2.223 1.281 5.853 5.853 0 0 1 .852 1.143c.011.045-1.534 1.083-2.471 1.662-.034.023-.169-.124-.322-.35a2.014 2.014 0 0 0-1.67-1c-1.077-.074-1.771.49-1.766 1.433a1.3 1.3 0 0 0 .153.666c.237.49.677.784 2.059 1.383 2.544 1.1 3.636 1.817 4.31 2.843a5.158 5.158 0 0 1 .416 4.333 4.764 4.764 0 0 1-3.932 2.815 10.9 10.9 0 0 1-2.708-.028 6.531 6.531 0 0 1-3.616-1.884 6.278 6.278 0 0 1-.926-1.371 2.655 2.655 0 0 1 .327-.208c.158-.09.756-.434 1.32-.761l1.024-.6.214.312a4.771 4.771 0 0 0 1.35 1.292 3.3 3.3 0 0 0 3.458-.175 1.545 1.545 0 0 0 .2-1.974c-.276-.4-.84-.727-2.443-1.422a8.8 8.8 0 0 1-3.349-2.055 4.687 4.687 0 0 1-.976-1.777 7.116 7.116 0 0 1-.062-2.268 4.332 4.332 0 0 1 3.644-3.374 9 9 0 0 1 2.71.01ZM15.484 9.726l.011 1.454h-4.63v13.148H7.6V11.183H2.97V9.755a13.986 13.986 0 0 1 .04-1.466c.017-.023 2.832-.034 6.245-.028l6.211.017Z" fill="#007acc" />
22+ <path d="m27.075 25.107.363-.361c1.68.055 1.706 0 1.78-.177l.462-1.124.034-.107-.038-.093c-.02-.049-.081-.2-1.13-1.2v-.526c1.211-1.166 1.185-1.226 1.116-1.4l-.46-1.136c-.069-.17-.1-.237-1.763-.191l-.364-.367a8.138 8.138 0 0 0-.057-1.657l-.047-.106-1.2-.525c-.177-.081-.239-.11-1.372 1.124l-.509-.008c-1.167-1.245-1.222-1.223-1.4-1.152l-1.115.452c-.175.071-.236.1-.169 1.79l-.36.359c-1.68-.055-1.7 0-1.778.177L18.606 20l-.036.108.038.094c.02.048.078.194 1.13 1.2v.525c-1.211 1.166-1.184 1.226-1.115 1.4l.459 1.137c.07.174.1.236 1.763.192l.363.377a8.169 8.169 0 0 0 .055 1.654l.047.107 1.208.528c.176.073.236.1 1.366-1.13l.509.006c1.168 1.247 1.228 1.223 1.4 1.154l1.113-.45c.176-.075.237-.102.169-1.795Zm-4.788-2.632a2 2 0 1 1 2.618 1.14 2.023 2.023 0 0 1-2.618-1.14Z" fill="#99b8c4" />
23+ </symbol>
24+ <symbol id="t3-file-icon-agents" viewBox="0 0 32 32">
25+ <path fill="currentColor" d="M27.2 16c0-6.19-5.01-11.2-11.2-11.2C9.81 4.8 4.8 9.81 4.8 16S9.81 27.2 16 27.2c6.19 0 11.2-5.01 11.2-11.2Zm-5.6 2.1a1.4 1.4 0 1 1 0 2.8h-4.2a1.4 1.4 0 1 1 0-2.8Zm-11.2-6.8c.622-.373 1.42-.208 1.84.361l.079.119 2.1 3.5.088.171c.15.351.15.748 0 1.1l-.088.171-2.1 3.5a1.4 1.4 0 0 1-2.4-1.44L11.59 16l-1.67-2.78-.067-.127c-.302-.642-.075-1.42.547-1.79ZM30 16c0 7.73-6.27 14-14 14S2 23.73 2 16 8.27 2 16 2s14 6.27 14 14Z" />
26+ </symbol>
27+ <symbol id="t3-file-icon-claude" viewBox="0 0 32 32">
28+ <path fill="#d97757" d="m7.5 20.61 5.5-3.08.1-.27-.1-.15h-.27l-.92-.06a234.2 234.2 0 0 1-8.51-.34l-.67-.14-.62-.82.06-.41.56-.38.8.07c3.08.2 6.15.4 9.21.72h.46l.06-.19-.16-.1-.12-.12-2.74-1.86c-2.04-1.3-3.55-2.43-5.38-3.68l-.43-.54-.18-1.18.76-.84 1.03.07.26.07c2.03 1.6 4.1 3.14 6.17 4.66l.43.36.17-.12.02-.09-.2-.32c-1.43-2.6-2.55-4.62-4-6.96l-.2-.72c-.08-.3-.13-.55-.13-.85l.87-1.18.49-.16 1.16.16.49.42c1.4 3.31 2.76 5.93 4.23 8.83l.29.97.1.3h.19v-.17c.65-3.42 0-6.57 1.22-9.53l.87-.57.68.33.56.8-.08.51c-.37 2.62-.92 5.22-1.4 7.82h.24l.29-.29a68.66 68.66 0 0 1 4.91-5.94l.64-.5h1.2l.89 1.32-.4 1.36a53.45 53.45 0 0 0-4.66 6.47l.09.13.22-.02c2.4-.57 4.84-.99 7.27-1.4l.97.45.1.46-.37.94c-3 .72-6 1.34-9 2.05l-.05.04.06.07c2.7.26 5.62.3 7.99.47l.92.61.55.75-.1.56-1.4.73c-2.93-.7-5.19-1.22-7.91-1.9h-.22v.13c2.18 2.12 4.6 4.27 6.54 6.07l.15.68-.38.53-.4-.06c-2.04-1.43-3.9-3.09-5.8-4.7h-.15v.2l.52.76c1.14 1.79 2.64 3.25 2.87 5.37l-.2.41-.7.25-.78-.14a73.16 73.16 0 0 1-4.58-7.04l-.17.09-.78 8.46-.37.43-.85.33-.71-.54-.38-.87a114 114 0 0 0 1.53-7.97l.2-.73-.01-.05-.16.02a76.67 76.67 0 0 1-6.23 7.88l-.48.2-.84-.44.08-.77.47-.69c2.07-2.57 3.54-4.66 5.54-7v-.19h-.07l-7.4 4.8-1.31.17-.57-.53.07-.87.27-.28 2.23-1.53Z" />
29+ </symbol>
30+ <symbol id="t3-file-icon-readme" viewBox="0 0 32 32">
31+ <rect x="2.5" y="7.955" width="27" height="16.091" fill="none" stroke="#b48a5a" />
32+ <path fill="#b48a5a" d="M5.909 20.636v-9.272h2.727l2.728 3.409 2.727-3.409h2.727v9.272h-2.727v-5.318l-2.727 3.409-2.728-3.409v5.318H5.91Zm17.046 0-4.091-4.5h2.727v-4.772h2.727v4.772h2.727l-4.09 4.5Z" />
33+ </symbol>
34+ <symbol id="t3-file-icon-pnpm" viewBox="0 0 32 32">
35+ <path fill="#f9ad00" d="M30 10.75h-8.749V2H30Zm-9.626 0h-8.75V2h8.75Zm-9.625 0H2V2h8.749ZM30 20.375h-8.749v-8.75H30Z" />
36+ <path fill="currentColor" d="M20.374 20.375h-8.75v-8.75h8.75Zm0 9.625h-8.75v-8.75h8.75ZM30 30h-8.749v-8.75H30Zm-19.251 0H2v-8.75h8.749Z" />
37+ </symbol>
38+</svg>`;
39+
40+export const T3_PIERRE_ICONS = {
41+ set: "complete",
42+ colored: true,
43+ spriteSheet: T3_FILE_ICON_SPRITE,
44+ byFileName: {
45+ "package.json": "t3-file-icon-package-json",
46+ "tsconfig.json": "t3-file-icon-tsconfig",
47+ "agents.md": "t3-file-icon-agents",
48+ "claude.md": "t3-file-icon-claude",
49+ "readme.md": "t3-file-icon-readme",
50+ "pnpm-lock.yaml": "t3-file-icon-pnpm",
51+ "pnpm-workspace.yaml": "t3-file-icon-pnpm",
52+ },
53+} satisfies FileTreeIcons;
54+
55+const completeIconResolver = createFileTreeIconResolver(T3_PIERRE_ICONS);
56+
57+const LANGUAGE_EXTENSION_ALIASES: Record<string, string> = {
58+ bash: "sh",
59+ csharp: "cs",
60+ dockerfile: "dockerfile",
61+ javascript: "js",
62+ jsx: "jsx",
63+ markdown: "md",
64+ mdx: "mdx",
65+ plaintext: "txt",
66+ python: "py",
67+ ruby: "rb",
68+ rust: "rs",
69+ shell: "sh",
70+ shellscript: "sh",
71+ swift: "swift",
72+ typescript: "ts",
73+ tsx: "tsx",
74+ yaml: "yml",
75+};
76+
77+export function basenameOfPath(pathValue: string): string {
78+ const slashIndex = pathValue.lastIndexOf("/");
79+ return slashIndex === -1 ? pathValue : pathValue.slice(slashIndex + 1);
80+}
81+
82+export function inferEntryKindFromPath(pathValue: string): "file" | "directory" {
83+ const base = basenameOfPath(pathValue);
84+ if (base.startsWith(".") && !base.slice(1).includes(".")) return "directory";
85+ return base.includes(".") ? "file" : "directory";
86+}
87+
88+export function syntheticFileNameForLanguageId(languageId: string): string {
89+ const normalized = languageId.toLowerCase();
90+ return `file.${LANGUAGE_EXTENSION_ALIASES[normalized] ?? normalized}`;
91+}
92+
93+export function resolvePierreIconForEntry(
94+ pathValue: string,
95+ kind: "file" | "directory",
96+): PierreIconResolution | null {
97+ if (kind === "directory") return null;
98+ return completeIconResolver.resolveIcon("file-tree-icon-file", pathValue);
99+}
100+
101+export function hasSpecificPierreIconForFileName(fileName: string): boolean {
102+ return resolvePierreIconForEntry(fileName, "file")?.token !== "default";
103+}
104+
105+export function ensurePierreIconSprite(): void {
106+ if (typeof document === "undefined" || document.getElementById(PIERRE_ICON_SPRITE_ID)) return;
107+ const container = document.createElement("div");
108+ container.id = PIERRE_ICON_SPRITE_ID;
109+ container.setAttribute("aria-hidden", "true");
110+ container.style.position = "absolute";
111+ container.style.width = "0";
112+ container.style.height = "0";
113+ container.style.overflow = "hidden";
114+ container.style.pointerEvents = "none";
115+ container.innerHTML = `${getBuiltInSpriteSheet("complete")}${T3_FILE_ICON_SPRITE}`;
116+ document.body.prepend(container);
117+}
apps/web/src/rightPanelStore.test.ts+48−0
@@ -88,6 +88,54 @@ describe("rightPanelStore", () => { · 87 unmodified lines
8888 ).toHaveLength(2);
8989 });
9090
91+ it("keeps files as a singleton surface", () => {
92+ useRightPanelStore.getState().open(refA, "files");
93+ useRightPanelStore.getState().open(refA, "files");
94+ expect(selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, refA)).toEqual({
95+ isOpen: true,
96+ activeSurfaceId: "files",
97+ surfaces: [{ id: "files", kind: "files" }],
98+ });
99+ });
100+
101+ it("replaces the standalone explorer with peer file surfaces", () => {
102+ useRightPanelStore.getState().open(refA, "files");
103+ useRightPanelStore.getState().openFile(refA, "src/index.ts");
104+ useRightPanelStore.getState().openFile(refA, "src/index.ts");
105+ useRightPanelStore.getState().openFile(refA, "README.md");
106+
107+ expect(selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, refA)).toEqual({
108+ isOpen: true,
109+ activeSurfaceId: "file:README.md",
110+ surfaces: [
111+ { id: "file:src/index.ts", kind: "file", relativePath: "src/index.ts" },
112+ { id: "file:README.md", kind: "file", relativePath: "README.md" },
113+ ],
114+ });
115+ });
116+
117+ it("removes persisted file surfaces when their workspace no longer exists", () => {
118+ useRightPanelStore.getState().openFile(refA, "src/index.ts");
119+ useRightPanelStore.getState().open(refA, "plan");
120+ useRightPanelStore.getState().openFile(refA, "README.md");
121+
122+ useRightPanelStore.getState().reconcileFileSurfaces(refA, false);
123+
124+ expect(selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, refA)).toEqual({
125+ isOpen: true,
126+ activeSurfaceId: "plan",
127+ surfaces: [{ id: "plan", kind: "plan" }],
128+ });
129+
130+ useRightPanelStore.getState().openFile(refB, "conductor.json");
131+ useRightPanelStore.getState().reconcileFileSurfaces(refB, false);
132+ expect(selectThreadRightPanelState(useRightPanelStore.getState().byThreadKey, refB)).toEqual({
133+ isOpen: false,
134+ activeSurfaceId: null,
135+ surfaces: [],
136+ });
137+ });
138+
91139 it("close hides the panel without clearing its selected surface", () => {
92140 useRightPanelStore.getState().open(refA, "plan");
93141 useRightPanelStore.getState().close(refA);
apps/web/src/rightPanelStore.ts+52−7
@@ -4,8 +4,8 @@ · 3 unmodified lines
44 * This is intentionally a shallow workspace model: it owns an ordered set of
55 * surface descriptors and the active surface, while each feature continues to
66 * own its durable resource state. Browser surfaces point at preview tab ids,
7− * terminal surfaces point at terminal session ids, and diff/plan remain
8− * singleton surfaces.
7+ * terminal surfaces point at terminal session ids, file surfaces point at
8+ * workspace paths, and diff/plan/files remain singleton surfaces.
99 */
1010 import { scopedThreadKey } from "@t3tools/client-runtime";
1111 import type { ScopedThreadRef } from "@t3tools/contracts";
@@ -14,7 +14,7 @@ import { createJSONStorage, persist } from "zustand/middleware"; · 2 unmodified lines
1414
1515 import { resolveStorage } from "./lib/storage";
1616
17−export const RIGHT_PANEL_KINDS = ["plan", "diff", "preview", "terminal"] as const;
17+export const RIGHT_PANEL_KINDS = ["plan", "diff", "files", "file", "preview", "terminal"] as const;
1818 export type RightPanelKind = (typeof RIGHT_PANEL_KINDS)[number];
1919
2020 export type RightPanelSurface =
@@ -29,10 +29,12 @@ export type RightPanelSurface = · 8 unmodified lines
2929 splitDirection?: "horizontal" | "vertical";
3030 }
3131 | { id: "diff"; kind: "diff" }
32+ | { id: "files"; kind: "files" }
33+ | { id: `file:${string}`; kind: "file"; relativePath: string }
3234 | { id: "plan"; kind: "plan" };
3335
3436 const RIGHT_PANEL_STORAGE_KEY = "t3code:right-panel-state:v2";
35−const RIGHT_PANEL_STORAGE_VERSION = 5;
37+const RIGHT_PANEL_STORAGE_VERSION = 6;
3638
3739 export interface ThreadRightPanelState {
3840 isOpen: boolean;
@@ -42,8 +44,9 @@ export interface ThreadRightPanelState { · 3 unmodified lines
4244
4345 interface RightPanelStoreState {
4446 byThreadKey: Record<string, ThreadRightPanelState>;
45− open: (ref: ScopedThreadRef, kind: Exclude<RightPanelKind, "terminal">) => void;
47+ open: (ref: ScopedThreadRef, kind: Exclude<RightPanelKind, "file" | "terminal">) => void;
4648 openBrowser: (ref: ScopedThreadRef, tabId: string | null) => void;
49+ openFile: (ref: ScopedThreadRef, relativePath: string) => void;
4750 openTerminal: (ref: ScopedThreadRef, terminalId: string) => void;
4851 splitTerminal: (
4952 ref: ScopedThreadRef,
@@ -56,10 +59,11 @@ interface RightPanelStoreState { · 6 unmodified lines
5659 activateSurface: (ref: ScopedThreadRef, surfaceId: string) => void;
5760 closeSurface: (ref: ScopedThreadRef, surfaceId: string) => void;
5861 reconcileBrowserSurfaces: (ref: ScopedThreadRef, tabIds: readonly string[]) => void;
62+ reconcileFileSurfaces: (ref: ScopedThreadRef, workspaceAvailable: boolean) => void;
5963 show: (ref: ScopedThreadRef) => void;
6064 close: (ref: ScopedThreadRef) => void;
6165 toggleVisibility: (ref: ScopedThreadRef) => void;
62− toggle: (ref: ScopedThreadRef, kind: Exclude<RightPanelKind, "terminal">) => void;
66+ toggle: (ref: ScopedThreadRef, kind: Exclude<RightPanelKind, "file" | "terminal">) => void;
6367 removeThread: (ref: ScopedThreadRef) => void;
6468 }
6569
@@ -70,11 +74,13 @@ const EMPTY_THREAD_STATE: ThreadRightPanelState = { · 4 unmodified lines
7074 };
7175
7276 const singletonSurface = (
73− kind: Exclude<RightPanelKind, "preview" | "terminal">,
77+ kind: Exclude<RightPanelKind, "file" | "preview" | "terminal">,
7478 ): RightPanelSurface => {
7579 switch (kind) {
7680 case "diff":
7781 return { id: "diff", kind };
82+ case "files":
83+ return { id: "files", kind };
7884 case "plan":
7985 return { id: "plan", kind };
8086 }
@@ -85,6 +91,12 @@ const browserSurface = (tabId: string | null): RightPanelSurface => · 4 unmodified lines
8591 ? { id: `browser:${tabId}`, kind: "preview", resourceId: tabId }
8692 : { id: "browser:new", kind: "preview", resourceId: null };
8793
94+const fileSurface = (relativePath: string): RightPanelSurface => ({
95+ id: `file:${relativePath}`,
96+ kind: "file",
97+ relativePath,
98+});
99+
88100 const terminalSurface = (terminalId: string): RightPanelSurface => ({
89101 id: `terminal:${terminalId}`,
90102 kind: "terminal",
@@ -213,6 +225,18 @@ export const useRightPanelStore = create<RightPanelStoreState>()( · 122 unmodified lines
213225 return upsertSurface({ ...current, surfaces: withoutPlaceholder }, surface);
214226 }),
215227 })),
228+ openFile: (ref, relativePath) =>
229+ set((state) => ({
230+ byThreadKey: updateThread(state.byThreadKey, scopedThreadKey(ref), (current) => {
231+ const withoutStandaloneExplorer = current.surfaces.filter(
232+ (surface) => surface.kind !== "files",
233+ );
234+ return upsertSurface(
235+ { ...current, surfaces: withoutStandaloneExplorer },
236+ fileSurface(relativePath),
237+ );
238+ }),
239+ })),
216240 openTerminal: (ref, terminalId) =>
217241 set((state) => ({
218242 byThreadKey: updateThread(state.byThreadKey, scopedThreadKey(ref), (current) =>
@@ -339,6 +363,27 @@ export const useRightPanelStore = create<RightPanelStoreState>()( · 120 unmodified lines
339363 };
340364 }),
341365 })),
366+ reconcileFileSurfaces: (ref, workspaceAvailable) =>
367+ set((state) => ({
368+ byThreadKey: updateThread(state.byThreadKey, scopedThreadKey(ref), (current) => {
369+ if (workspaceAvailable) return current;
370+ const surfaces = current.surfaces.filter(
371+ (surface) => surface.kind !== "files" && surface.kind !== "file",
372+ );
373+ if (surfaces.length === current.surfaces.length) return current;
374+ const activeStillExists = surfaces.some(
375+ (surface) => surface.id === current.activeSurfaceId,
376+ );
377+ return {
378+ ...current,
379+ isOpen: surfaces.length > 0 ? current.isOpen : false,
380+ surfaces,
381+ activeSurfaceId: activeStillExists
382+ ? current.activeSurfaceId
383+ : (surfaces.at(-1)?.id ?? null),
384+ };
385+ }),
386+ })),
342387 show: (ref) =>
343388 set((state) => ({
344389 byThreadKey: updateThread(state.byThreadKey, scopedThreadKey(ref), (current) =>
apps/web/src/vscode-icons-language-associations.json+0−481
@@ -1,481 +0,0 @@
1−{
2− "version": "12.17.0",
3− "source": "https://raw.githubusercontent.com/vscode-icons/vscode-icons/v12.17.0/src/iconsManifest/languages.ts",
4− "generatedAt": "2026-02-17T20:03:11.362Z",
5− "extensionToLanguageId": {
6− "as": "actionscript",
7− "ada": "ada",
8− "prw": "advpl",
9− "affect": "affectscript",
10− "agda": "agda",
11− "al": "al",
12− "alloy": "alloy",
13− "ansible": "ansible",
14− "g4": "antlr",
15− "any": "anyscript",
16− "htaccess": "apacheconf",
17− "cls": "apex",
18− "apib": "apiblueprint",
19− "apl": "apl",
20− "applescript": "applescript",
21− "adoc": "asciidoc",
22− "asp": "asp",
23− "asm": "arm",
24− "astro": "astro",
25− "ats": "ats",
26− "ahk": "ahk",
27− "au3": "autoit",
28− "am": "automake",
29− "avcs": "avro",
30− "azcli": "azcli",
31− "azure-pipelines.yml": "azure-pipelines",
32− "bal": "ballerina",
33− "bat": "bat",
34− "bats": "bats",
35− "bzl": "bazel",
36− "bf": "befunge",
37− "bicep": "bicep",
38− "bib": "bibtex",
39− "biml": "biml",
40− "bin": "code-text-binary",
41− "rast": "biome_syntax_tree",
42− "blade.php": "blade",
43− "blitzbasic": "blitzbasic",
44− "bolt": "bolt",
45− "bsq": "bosque",
46− "bru": "bruno",
47− "buf.yaml": "buf",
48− "lockb": "bun.lockb",
49− "c": "c",
50− "c3": "c3",
51− "cal": "c-al",
52− "cabal": "cabal",
53− "capnp": "capnp",
54− "casc": "casc",
55− "cddl": "cddl",
56− "ceylon": "ceylon",
57− "cfc": "cfc",
58− "cfm": "cfmhtml",
59− "circom": "circom",
60− "clojure": "clojure",
61− "clojurescript": "clojurescript",
62− "yml": "manifest-yaml",
63− "cmake": "cmake",
64− "cbl": "cobol",
65− "ql": "ql",
66− "coffee": "coffeescript",
67− "cfml": "cfml",
68− "confluence": "confluence",
69− "ckbk": "cookbook",
70− "instructions.md": "instructions",
71− "cpp": "cpp",
72− "cr": "crystal",
73− "cs": "csharp",
74− "css": "css",
75− "wxss": "css",
76− "acss": "css",
77− "mcss": "css",
78− "pcss": "css",
79− "postcss": "css",
80− "nss": "css",
81− "ccss": "css",
82− "less": "css",
83− "scss": "css",
84− "sass": "css",
85− "csv": "csv",
86− "feature": "cucumber",
87− "cu": "cuda",
88− "cypher": "cypher",
89− "pyx": "cython",
90− "dal": "dal",
91− "dart": "dart",
92− "dhall": "dhall",
93− "html": "django-html",
94− "diff": "diff",
95− "d": "d",
96− "hcl": "dockerbake",
97− "dtx": "doctex",
98− "env": "dotenv",
99− "dot": "dotjs",
100− "dox": "doxygen",
101− "drawio": "drawio",
102− "drl": "drools",
103− "dtd": "dtd",
104− "dust": "dustjs",
105− "dylan": "dylan",
106− "earthfile": "earthfile",
107− "edge": "edge",
108− "eex": "eex",
109− "es": "es",
110− "ex": "elixir",
111− "elm": "elm",
112− "erb": "erb",
113− "erl": "erlang",
114− "yaml": "esphome",
115− "xlsx": "excel",
116− "falcon": "falcon",
117− "fql": "fql",
118− "f": "fortran",
119− "ftl": "ftl",
120− "fs": "fsharp",
121− "fthtml": "fthtml",
122− "gspec": "galen",
123− "gml": "gml-gms",
124− "gcode": "gcode",
125− "gen": "genstat",
126− "git": "git-commit",
127− "gleam": "gleam",
128− "gjs": "glimmer-js",
129− "glsl": "glsl",
130− "glyphs": "glyphs",
131− "gp": "gnuplot",
132− "go": "go",
133− "mod": "go.mod",
134− "work": "go.work",
135− "api": "goctl",
136− "gd": "gdscript",
137− "gradle.kts": "gradle-kotlin-dsl",
138− "gr": "grain",
139− "gql": "graphql",
140− "gv": "dot",
141− "grit": "grit",
142− "groovy": "groovy",
143− "haml": "haml",
144− "hbs": "handlebars",
145− "prg": "harbour",
146− "hs": "haskell",
147− "haxe": "haxe",
148− "helm.tpl": "helm",
149− "hjson": "hjson",
150− "hlsl": "hlsl",
151− "hosts": "hosts",
152− "http": "http",
153− "aff": "hunspell.aff",
154− "hy": "hy",
155− "hypr": "hypr",
156− "icl": "icl",
157− "imba": "imba",
158− "4gl": "4GL",
159− "ini": "ini",
160− "ink": "ink",
161− "iss": "innosetup",
162− "io": "io",
163− "janet": "janet",
164− "java": "java",
165− "js": "javascript",
166− "mjs": "javascript",
167− "cjs": "javascript",
168− "es6": "javascript",
169− "jake": "javascript",
170− "jsm": "javascript",
171− "jsx": "javascript",
172− "njs": "javascript",
173− "pac": "javascript",
174− "sjs": "javascript",
175− "ssjs": "javascript",
176− "xsjs": "javascript",
177− "xsjslib": "javascript",
178− "jekyll": "jekyll",
179− "jenkins": "jenkins",
180− "jest-snap": "jest-snapshot",
181− "jinja": "jinja",
182− "json": "json",
183− "jsonc": "jsonc",
184− "jsonl": "jsonl",
185− "jsonnet": "jsonnet",
186− "json5": "json5",
187− "jl": "julia",
188− "id": "iodine",
189− "k": "k",
190− "kv": "kivy",
191− "ks": "kos",
192− "kt": "kotlin",
193− "kusto": "kusto",
194− "tex": "latex",
195− "lark": "lark",
196− "lat": "latino",
197− "lean": "lean4",
198− "flex": "lex",
199− "ly": "lilypond",
200− "lisp": "lisp",
201− "lhs": "literate haskell",
202− "log": "log",
203− "lol": "lolcode",
204− "lsl": "lsl",
205− "lua": "lua",
206− "m4": "m4",
207− "mk": "makefile",
208− "md": "markdown",
209− "markdown": "markdown",
210− "mdown": "markdown",
211− "mkd": "markdown",
212− "marko": "marko",
213− "mat": "matlab",
214− "ms": "maxscript",
215− "mdx": "mdx",
216− "mediawiki": "mediawiki",
217− "mel": "mel",
218− "mmd": "mermaid",
219− "metal": "metal",
220− "mcfunction": "bc-mcfunction",
221− "mjml": "mjml",
222− "pq": "powerquery",
223− "mojo": "mojo",
224− "ep": "mojolicious",
225− "mongo": "mongo",
226− "mson": "mson",
227− "mv": "mv",
228− "mvt": "mvt",
229− "ne": "nearley",
230− "nginx": "nginx",
231− "nim": "nim",
232− "nimble": "nimble",
233− "nix": "nix",
234− "nsi": "nsis",
235− "nunjucks": "nunjucks",
236− "nu": "nushell",
237− "m": "objective-c",
238− "mm": "objective-cpp",
239− "ml": "ocaml",
240− "o3": "ogone",
241− "w": "abl",
242− "things": "openhab",
243− "org": "org",
244− "pas": "pascal",
245− "pddl": "pddl",
246− "plan": "plan",
247− "happenings": "happenings",
248− "pl": "perl",
249− "pl6": "perl6",
250− "pgsql": "pgsql",
251− "php": "php",
252− "php4": "php",
253− "php5": "php",
254− "php7": "php",
255− "phtml": "php",
256− "phps": "php",
257− "phpt": "php",
258− "phar": "php",
259− "aw": "php",
260− "ctp": "php",
261− "inc": "php",
262− "php3": "php",
263− "php8": "php",
264− "module": "php",
265− "theme": "php",
266− "tpl": "php",
267− "pine": "pine",
268− "txt": "plaintext",
269− "dbgasm": "platformio-debug.disassembly",
270− "ddl": "plsql",
271− "po": "po",
272− "dib": "polyglot-notebook",
273− "polymer": "polymer",
274− "pony": "pony",
275− "ps": "postscript",
276− "ps1": "powershell",
277− "prisma": "prisma",
278− "pde": "pde",
279− "pro": "prolog",
280− "rules": "prometheus",
281− "properties": "java-properties",
282− "proto": "proto3",
283− "pug": "jade",
284− "pp": "puppet",
285− "purs": "purescript",
286− "arr": "pyret",
287− "pyscript": "pyscript",
288− "py": "python",
289− "pyi": "python",
290− "pyw": "python",
291− "pyc": "python",
292− "pyd": "python",
293− "pyo": "python",
294− "pxd": "python",
295− "pxi": "python",
296− "rpy": "python",
297− "cpy": "python",
298− "ipy": "python",
299− "pyowo": "pythowo",
300− "qvs": "qlik",
301− "qml": "qml",
302− "qs": "qsharp",
303− "r": "r",
304− "rkt": "racket",
305− "raku": "raku",
306− "cshtml": "razor",
307− "raml": "raml",
308− "re": "reason",
309− "red": "red",
310− "res": "rescript",
311− "rst": "restructuredtext",
312− "rex": "rexx",
313− "tag": "riot",
314− "ripple": "ripple",
315− "rmd": "rmd",
316− "rnc": "rnc",
317− "robot": "robot",
318− "rb": "ruby",
319− "rbw": "ruby",
320− "rake": "ruby",
321− "gemspec": "ruby",
322− "ru": "ruby",
323− "rjs": "ruby",
324− "rxml": "ruby",
325− "rsel": "ruby",
326− "builder": "ruby",
327− "jbuilder": "ruby",
328− "rabl": "ruby",
329− "prawn": "ruby",
330− "thor": "ruby",
331− "rs": "rust",
332− "sl": "s-lang",
333− "san": "san",
334− "sas": "SAS",
335− "sbt": "sbt",
336− "scad": "scad",
337− "scala": "scala",
338− "sce": "scilab",
339− "sdl": "sdl",
340− "code-search": "search-result",
341− "shader": "shaderlab",
342− "sh": "shellscript",
343− "bash": "shellscript",
344− "zsh": "shellscript",
345− "ksh": "shellscript",
346− "fish": "shellscript",
347− "slang": "slang",
348− "ice": "slice",
349− "slim": "slim",
350− "slint": "slint",
351− "sln": "sln",
352− "ss": "silverstripe",
353− "sn": "sino",
354− "eskip": "eskip",
355− "smk": "snakemake",
356− "code-snippets": "snippets",
357− "snort": "snort",
358− "sol": "solidity",
359− "rq": "sparql",
360− "sqf": "sqf",
361− "sql": "sql",
362− "nut": "squirrel",
363− "stan": "stan",
364− "bazel": "starlark",
365− "do": "stata",
366− "stencil": "stencil",
367− "html.stencil": "stencil-html",
368− "st.css": "stylable",
369− "styled": "source.css.styled",
370− "styl": "stylus",
371− "svelte": "svelte",
372− "svg": "svg",
373− "swagger": "Swagger",
374− "swift": "swift",
375− "swig": "swig",
376− "link": "systemd-conf",
377− "sv": "systemverilog",
378− "tt": "t4",
379− "teal": "teal",
380− "templ": "templ",
381− "tt3": "tt",
382− "tera": "tera",
383− "tf": "terraform",
384− "sty": "tex",
385− "textile": "textile",
386− "json-tmlanguage": "json-tmlanguage",
387− "yaml-tmlanguage": "yaml-tmlanguage",
388− "toit": "toit",
389− "toml": "toml",
390− "toon": "toon",
391− "ttcn3": "ttcn",
392− "tuc": "tuc",
393− "twig": "twig",
394− "ts": "typescript",
395− "mts": "typescript",
396− "cts": "typescript",
397− "tsx": "typescriptreact",
398− "typoscript": "typoscript",
399− "ua": "uiua",
400− "u": "unison",
401− "vb": "vb",
402− "wsf": "vbscript",
403− "vm": "velocity",
404− "vto": "vento",
405− "v": "verilog",
406− "vhdl": "vhdl",
407− "vim": "viml",
408− "vitest-snap": "vitest-snapshot",
409− "volt": "volt",
410− "vroom": "vroom",
411− "vue": "vue",
412− "vue2": "vue",
413− "vue3": "vue",
414− "vues": "vue",
415− "vuex": "vue",
416− "vuerc": "vue",
417− "vy": "vyper",
418− "wai": "wai",
419− "wasm": "wasm",
420− "wat": "wasm",
421− "wast": "wasm",
422− "wsm": "wasm",
423− "wast.js": "wasm",
424− "wit": "wasm",
425− "witx": "wasm",
426− "wy": "wenyan",
427− "wgsl": "wgsl",
428− "wt": "wikitext",
429− "wl": "wolfram",
430− "wurst": "wurstlang",
431− "xcompose": "xcompose",
432− "xmake.lua": "xmake",
433− "xml": "xml",
434− "xquery": "xquery",
435− "xsl": "xsl",
436− "bison": "yacc",
437− "yang": "yang",
438− "zig": "zig",
439− "zip": "zip"
440− },
441− "fileNameToLanguageId": {
442− "browserslist": "browserslist",
443− ".browserslistrc": "browserslist",
444− "caddyfile": "caddyfile",
445− "cmakelists.txt": "cmake",
446− "cmakecache.txt": "cmake-cache",
447− "docker-compose.yml": "dockercompose",
448− "docker-compose.yaml": "dockercompose",
449− "compose.yaml": "dockercompose",
450− "compose.yml": "dockercompose",
451− "dockerfile": "dockerfile",
452− "dockerfile.dev": "dockerfile",
453− "dockerfile.prod": "dockerfile",
454− "dockerfile.test": "dockerfile",
455− ".editorconfig": "editorconfig",
456− "justfile": "just",
457− "meson.build": "meson",
458− ".php-version": "php",
459− "artisan": "php",
460− "requirements.txt": "pip-requirements",
461− "requirements-dev.txt": "pip-requirements",
462− "requirements-test.txt": "pip-requirements",
463− "requirements-prod.txt": "pip-requirements",
464− "setup.py": "python",
465− "setup.cfg": "python",
466− ".python-version": "python",
467− "pipfile": "python",
468− "pipfile.lock": "python",
469− "robots.txt": "robots-txt",
470− "config.ru": "ruby",
471− ".bashrc": "shellscript",
472− ".zshrc": "shellscript",
473− ".profile": "shellscript",
474− ".bash_profile": "shellscript",
475− ".bash_aliases": "shellscript",
476− ".zprofile": "shellscript",
477− "tiltfile": "tiltfile",
478− ".vue-cli-rc": "vue",
479− "yarn.lock": "yarnlock"
480− }
481−}
apps/web/src/vscode-icons-manifest.json+0−8351
@@ -1,8351 +0,0 @@
1−{
2− "iconDefinitions": {
3− "_file": { "iconPath": "../../icons/default_file.svg" },
4− "_folder": { "iconPath": "../../icons/default_folder.svg" },
5− "_folder_open": { "iconPath": "../../icons/default_folder_opened.svg" },
6− "_root_folder": { "iconPath": "../../icons/default_root_folder.svg" },
7− "_root_folder_open": { "iconPath": "../../icons/default_root_folder_opened.svg" },
8− "_file_light": { "iconPath": "" },
9− "_folder_light": { "iconPath": "" },
10− "_folder_light_open": { "iconPath": "" },
11− "_root_folder_light": { "iconPath": "" },
12− "_root_folder_light_open": { "iconPath": "" },
13− "_fd_android": { "iconPath": "../../icons/folder_type_android.svg" },
14− "_fd_android_open": { "iconPath": "../../icons/folder_type_android_opened.svg" },
15− "_fd_angular": { "iconPath": "../../icons/folder_type_angular.svg" },
16− "_fd_angular_open": { "iconPath": "../../icons/folder_type_angular_opened.svg" },
17− "_fd_apache": { "iconPath": "../../icons/folder_type_apache.svg" },
18− "_fd_apache_open": { "iconPath": "../../icons/folder_type_apache_opened.svg" },
19− "_fd_api": { "iconPath": "../../icons/folder_type_api.svg" },
20− "_fd_api_open": { "iconPath": "../../icons/folder_type_api_opened.svg" },
21− "_fd_app": { "iconPath": "../../icons/folder_type_app.svg" },
22− "_fd_app_open": { "iconPath": "../../icons/folder_type_app_opened.svg" },
23− "_fd_arangodb": { "iconPath": "../../icons/folder_type_arangodb.svg" },
24− "_fd_arangodb_open": { "iconPath": "../../icons/folder_type_arangodb_opened.svg" },
25− "_fd_asset": { "iconPath": "../../icons/folder_type_asset.svg" },
26− "_fd_asset_open": { "iconPath": "../../icons/folder_type_asset_opened.svg" },
27− "_fd_astro": { "iconPath": "../../icons/folder_type_astro.svg" },
28− "_fd_astro_open": { "iconPath": "../../icons/folder_type_astro_opened.svg" },
29− "_fd_audio": { "iconPath": "../../icons/folder_type_audio.svg" },
30− "_fd_audio_open": { "iconPath": "../../icons/folder_type_audio_opened.svg" },
31− "_fd_aurelia": { "iconPath": "../../icons/folder_type_aurelia.svg" },
32− "_fd_aurelia_open": { "iconPath": "../../icons/folder_type_aurelia_opened.svg" },
33− "_fd_aws": { "iconPath": "../../icons/folder_type_aws.svg" },
34− "_fd_aws_open": { "iconPath": "../../icons/folder_type_aws_opened.svg" },
35− "_fd_azure": { "iconPath": "../../icons/folder_type_azure.svg" },
36− "_fd_azure_open": { "iconPath": "../../icons/folder_type_azure_opened.svg" },
37− "_fd_azurepipelines": { "iconPath": "../../icons/folder_type_azurepipelines.svg" },
38− "_fd_azurepipelines_open": { "iconPath": "../../icons/folder_type_azurepipelines_opened.svg" },
39− "_fd_binary": { "iconPath": "../../icons/folder_type_binary.svg" },
40− "_fd_binary_open": { "iconPath": "../../icons/folder_type_binary_opened.svg" },
41− "_fd_bloc": { "iconPath": "../../icons/folder_type_bloc.svg" },
42− "_fd_bloc_open": { "iconPath": "../../icons/folder_type_bloc_opened.svg" },
43− "_fd_blueprint": { "iconPath": "../../icons/folder_type_blueprint.svg" },
44− "_fd_blueprint_open": { "iconPath": "../../icons/folder_type_blueprint_opened.svg" },
45− "_fd_bot": { "iconPath": "../../icons/folder_type_bot.svg" },
46− "_fd_bot_open": { "iconPath": "../../icons/folder_type_bot_opened.svg" },
47− "_fd_bower": { "iconPath": "../../icons/folder_type_bower.svg" },
48− "_fd_bower_open": { "iconPath": "../../icons/folder_type_bower_opened.svg" },
49− "_fd_buildkite": { "iconPath": "../../icons/folder_type_buildkite.svg" },
50− "_fd_buildkite_open": { "iconPath": "../../icons/folder_type_buildkite_opened.svg" },
51− "_fd_cake": { "iconPath": "../../icons/folder_type_cake.svg" },
52− "_fd_cake_open": { "iconPath": "../../icons/folder_type_cake_opened.svg" },
53− "_fd_cargo": { "iconPath": "../../icons/folder_type_cargo.svg" },
54− "_fd_cargo_open": { "iconPath": "../../icons/folder_type_cargo_opened.svg" },
55− "_fd_certificate": { "iconPath": "../../icons/folder_type_certificate.svg" },
56− "_fd_certificate_open": { "iconPath": "../../icons/folder_type_certificate_opened.svg" },
57− "_fd_changesets": { "iconPath": "../../icons/folder_type_changesets.svg" },
58− "_fd_changesets_open": { "iconPath": "../../icons/folder_type_changesets_opened.svg" },
59− "_fd_chef": { "iconPath": "../../icons/folder_type_chef.svg" },
60− "_fd_chef_open": { "iconPath": "../../icons/folder_type_chef_opened.svg" },
61− "_fd_circleci": { "iconPath": "../../icons/folder_type_circleci.svg" },
62− "_fd_circleci_open": { "iconPath": "../../icons/folder_type_circleci_opened.svg" },
63− "_fd_claude": { "iconPath": "../../icons/folder_type_claude.svg" },
64− "_fd_claude_open": { "iconPath": "../../icons/folder_type_claude_opened.svg" },
65− "_fd_cli": { "iconPath": "../../icons/folder_type_cli.svg" },
66− "_fd_cli_open": { "iconPath": "../../icons/folder_type_cli_opened.svg" },
67− "_fd_client": { "iconPath": "../../icons/folder_type_client.svg" },
68− "_fd_client_open": { "iconPath": "../../icons/folder_type_client_opened.svg" },
69− "_fd_cloudflare": { "iconPath": "../../icons/folder_type_cloudflare.svg" },
70− "_fd_cloudflare_open": { "iconPath": "../../icons/folder_type_cloudflare_opened.svg" },
71− "_fd_cmake": { "iconPath": "../../icons/folder_type_cmake.svg" },
72− "_fd_cmake_open": { "iconPath": "../../icons/folder_type_cmake_opened.svg" },
73− "_fd_common": { "iconPath": "../../icons/folder_type_common.svg" },
74− "_fd_common_open": { "iconPath": "../../icons/folder_type_common_opened.svg" },
75− "_fd_component": { "iconPath": "../../icons/folder_type_component.svg" },
76− "_fd_component_open": { "iconPath": "../../icons/folder_type_component_opened.svg" },
77− "_fd_composer": { "iconPath": "../../icons/folder_type_composer.svg" },
78− "_fd_composer_open": { "iconPath": "../../icons/folder_type_composer_opened.svg" },
79− "_fd_config": { "iconPath": "../../icons/folder_type_config.svg" },
80− "_fd_config_open": { "iconPath": "../../icons/folder_type_config_opened.svg" },
81− "_fd_controller": { "iconPath": "../../icons/folder_type_controller.svg" },
82− "_fd_controller_open": { "iconPath": "../../icons/folder_type_controller_opened.svg" },
83− "_fd_coverage": { "iconPath": "../../icons/folder_type_coverage.svg" },
84− "_fd_coverage_open": { "iconPath": "../../icons/folder_type_coverage_opened.svg" },
85− "_fd_css": { "iconPath": "../../icons/folder_type_css.svg" },
86− "_fd_css_open": { "iconPath": "../../icons/folder_type_css_opened.svg" },
87− "_fd_cubit": { "iconPath": "../../icons/folder_type_cubit.svg" },
88− "_fd_cubit_open": { "iconPath": "../../icons/folder_type_cubit_opened.svg" },
89− "_fd_cursor": { "iconPath": "../../icons/folder_type_cursor.svg" },
90− "_fd_cursor_open": { "iconPath": "../../icons/folder_type_cursor_opened.svg" },
91− "_fd_light_cursor": { "iconPath": "../../icons/folder_type_light_cursor.svg" },
92− "_fd_light_cursor_open": { "iconPath": "../../icons/folder_type_light_cursor_opened.svg" },
93− "_fd_cypress": { "iconPath": "../../icons/folder_type_cypress.svg" },
94− "_fd_cypress_open": { "iconPath": "../../icons/folder_type_cypress_opened.svg" },
95− "_fd_light_cypress": { "iconPath": "../../icons/folder_type_light_cypress.svg" },
96− "_fd_light_cypress_open": { "iconPath": "../../icons/folder_type_light_cypress_opened.svg" },
97− "_fd_dapr": { "iconPath": "../../icons/folder_type_dapr.svg" },
98− "_fd_dapr_open": { "iconPath": "../../icons/folder_type_dapr_opened.svg" },
99− "_fd_dart": { "iconPath": "../../icons/folder_type_dart.svg" },
100− "_fd_dart_open": { "iconPath": "../../icons/folder_type_dart_opened.svg" },
101− "_fd_datadog": { "iconPath": "../../icons/folder_type_datadog.svg" },
102− "_fd_datadog_open": { "iconPath": "../../icons/folder_type_datadog_opened.svg" },
103− "_fd_db": { "iconPath": "../../icons/folder_type_db.svg" },
104− "_fd_db_open": { "iconPath": "../../icons/folder_type_db_opened.svg" },
105− "_fd_debian": { "iconPath": "../../icons/folder_type_debian.svg" },
106− "_fd_debian_open": { "iconPath": "../../icons/folder_type_debian_opened.svg" },
107− "_fd_dependabot": { "iconPath": "../../icons/folder_type_dependabot.svg" },
108− "_fd_dependabot_open": { "iconPath": "../../icons/folder_type_dependabot_opened.svg" },
109− "_fd_devcontainer": { "iconPath": "../../icons/folder_type_devcontainer.svg" },
110− "_fd_devcontainer_open": { "iconPath": "../../icons/folder_type_devcontainer_opened.svg" },
111− "_fd_dist": { "iconPath": "../../icons/folder_type_dist.svg" },
112− "_fd_dist_open": { "iconPath": "../../icons/folder_type_dist_opened.svg" },
113− "_fd_docker": { "iconPath": "../../icons/folder_type_docker.svg" },
114− "_fd_docker_open": { "iconPath": "../../icons/folder_type_docker_opened.svg" },
115− "_fd_docs": { "iconPath": "../../icons/folder_type_docs.svg" },
116− "_fd_docs_open": { "iconPath": "../../icons/folder_type_docs_opened.svg" },
117− "_fd_e2e": { "iconPath": "../../icons/folder_type_e2e.svg" },
118− "_fd_e2e_open": { "iconPath": "../../icons/folder_type_e2e_opened.svg" },
119− "_fd_elasticbeanstalk": { "iconPath": "../../icons/folder_type_elasticbeanstalk.svg" },
120− "_fd_elasticbeanstalk_open": {
121− "iconPath": "../../icons/folder_type_elasticbeanstalk_opened.svg"
122− },
123− "_fd_electron": { "iconPath": "../../icons/folder_type_electron.svg" },
124− "_fd_electron_open": { "iconPath": "../../icons/folder_type_electron_opened.svg" },
125− "_fd_light_electron": { "iconPath": "../../icons/folder_type_light_electron.svg" },
126− "_fd_light_electron_open": { "iconPath": "../../icons/folder_type_light_electron_opened.svg" },
127− "_fd_expo": { "iconPath": "../../icons/folder_type_expo.svg" },
128− "_fd_expo_open": { "iconPath": "../../icons/folder_type_expo_opened.svg" },
129− "_fd_light_expo": { "iconPath": "../../icons/folder_type_light_expo.svg" },
130− "_fd_light_expo_open": { "iconPath": "../../icons/folder_type_light_expo_opened.svg" },
131− "_fd_favicon": { "iconPath": "../../icons/folder_type_favicon.svg" },
132− "_fd_favicon_open": { "iconPath": "../../icons/folder_type_favicon_opened.svg" },
133− "_fd_flow": { "iconPath": "../../icons/folder_type_flow.svg" },
134− "_fd_flow_open": { "iconPath": "../../icons/folder_type_flow_opened.svg" },
135− "_fd_flutter": { "iconPath": "../../icons/folder_type_flutter.svg" },
136− "_fd_flutter_open": { "iconPath": "../../icons/folder_type_flutter_opened.svg" },
137− "_fd_fonts": { "iconPath": "../../icons/folder_type_fonts.svg" },
138− "_fd_fonts_open": { "iconPath": "../../icons/folder_type_fonts_opened.svg" },
139− "_fd_light_fonts": { "iconPath": "../../icons/folder_type_light_fonts.svg" },
140− "_fd_light_fonts_open": { "iconPath": "../../icons/folder_type_light_fonts_opened.svg" },
141− "_fd_frontcommerce": { "iconPath": "../../icons/folder_type_frontcommerce.svg" },
142− "_fd_frontcommerce_open": { "iconPath": "../../icons/folder_type_frontcommerce_opened.svg" },
143− "_fd_gcp": { "iconPath": "../../icons/folder_type_gcp.svg" },
144− "_fd_gcp_open": { "iconPath": "../../icons/folder_type_gcp_opened.svg" },
145− "_fd_gemini": { "iconPath": "../../icons/folder_type_gemini.svg" },
146− "_fd_gemini_open": { "iconPath": "../../icons/folder_type_gemini_opened.svg" },
147− "_fd_git": { "iconPath": "../../icons/folder_type_git.svg" },
148− "_fd_git_open": { "iconPath": "../../icons/folder_type_git_opened.svg" },
149− "_fd_github": { "iconPath": "../../icons/folder_type_github.svg" },
150− "_fd_github_open": { "iconPath": "../../icons/folder_type_github_opened.svg" },
151− "_fd_gitlab": { "iconPath": "../../icons/folder_type_gitlab.svg" },
152− "_fd_gitlab_open": { "iconPath": "../../icons/folder_type_gitlab_opened.svg" },
153− "_fd_godot": { "iconPath": "../../icons/folder_type_godot.svg" },
154− "_fd_godot_open": { "iconPath": "../../icons/folder_type_godot_opened.svg" },
155− "_fd_gradle": { "iconPath": "../../icons/folder_type_gradle.svg" },
156− "_fd_gradle_open": { "iconPath": "../../icons/folder_type_gradle_opened.svg" },
157− "_fd_light_gradle": { "iconPath": "../../icons/folder_type_light_gradle.svg" },
158− "_fd_light_gradle_open": { "iconPath": "../../icons/folder_type_light_gradle_opened.svg" },
159− "_fd_graphql": { "iconPath": "../../icons/folder_type_graphql.svg" },
160− "_fd_graphql_open": { "iconPath": "../../icons/folder_type_graphql_opened.svg" },
161− "_fd_grunt": { "iconPath": "../../icons/folder_type_grunt.svg" },
162− "_fd_grunt_open": { "iconPath": "../../icons/folder_type_grunt_opened.svg" },
163− "_fd_gulp": { "iconPath": "../../icons/folder_type_gulp.svg" },
164− "_fd_gulp_open": { "iconPath": "../../icons/folder_type_gulp_opened.svg" },
165− "_fd_haxelib": { "iconPath": "../../icons/folder_type_haxelib.svg" },
166− "_fd_haxelib_open": { "iconPath": "../../icons/folder_type_haxelib_opened.svg" },
167− "_fd_helper": { "iconPath": "../../icons/folder_type_helper.svg" },
168− "_fd_helper_open": { "iconPath": "../../icons/folder_type_helper_opened.svg" },
169− "_fd_histoire": { "iconPath": "../../icons/folder_type_histoire.svg" },
170− "_fd_histoire_open": { "iconPath": "../../icons/folder_type_histoire_opened.svg" },
171− "_fd_hook": { "iconPath": "../../icons/folder_type_hook.svg" },
172− "_fd_hook_open": { "iconPath": "../../icons/folder_type_hook_opened.svg" },
173− "_fd_husky": { "iconPath": "../../icons/folder_type_husky.svg" },
174− "_fd_husky_open": { "iconPath": "../../icons/folder_type_husky_opened.svg" },
175− "_fd_idea": { "iconPath": "../../icons/folder_type_idea.svg" },
176− "_fd_idea_open": { "iconPath": "../../icons/folder_type_idea_opened.svg" },
177− "_fd_images": { "iconPath": "../../icons/folder_type_images.svg" },
178− "_fd_images_open": { "iconPath": "../../icons/folder_type_images_opened.svg" },
179− "_fd_include": { "iconPath": "../../icons/folder_type_include.svg" },
180− "_fd_include_open": { "iconPath": "../../icons/folder_type_include_opened.svg" },
181− "_fd_interfaces": { "iconPath": "../../icons/folder_type_interfaces.svg" },
182− "_fd_interfaces_open": { "iconPath": "../../icons/folder_type_interfaces_opened.svg" },
183− "_fd_ios": { "iconPath": "../../icons/folder_type_ios.svg" },
184− "_fd_ios_open": { "iconPath": "../../icons/folder_type_ios_opened.svg" },
185− "_fd_js": { "iconPath": "../../icons/folder_type_js.svg" },
186− "_fd_js_open": { "iconPath": "../../icons/folder_type_js_opened.svg" },
187− "_fd_json": { "iconPath": "../../icons/folder_type_json.svg" },
188− "_fd_json_open": { "iconPath": "../../icons/folder_type_json_opened.svg" },
189− "_fd_junie": { "iconPath": "../../icons/folder_type_junie.svg" },
190− "_fd_junie_open": { "iconPath": "../../icons/folder_type_junie_opened.svg" },
191− "_fd_kotlin": { "iconPath": "../../icons/folder_type_kotlin.svg" },
192− "_fd_kotlin_open": { "iconPath": "../../icons/folder_type_kotlin_opened.svg" },
193− "_fd_kubernetes": { "iconPath": "../../icons/folder_type_kubernetes.svg" },
194− "_fd_kubernetes_open": { "iconPath": "../../icons/folder_type_kubernetes_opened.svg" },
195− "_fd_less": { "iconPath": "../../icons/folder_type_less.svg" },
196− "_fd_less_open": { "iconPath": "../../icons/folder_type_less_opened.svg" },
197− "_fd_library": { "iconPath": "../../icons/folder_type_library.svg" },
198− "_fd_library_open": { "iconPath": "../../icons/folder_type_library_opened.svg" },
199− "_fd_linux": { "iconPath": "../../icons/folder_type_linux.svg" },
200− "_fd_linux_open": { "iconPath": "../../icons/folder_type_linux_opened.svg" },
201− "_fd_locale": { "iconPath": "../../icons/folder_type_locale.svg" },
202− "_fd_locale_open": { "iconPath": "../../icons/folder_type_locale_opened.svg" },
203− "_fd_log": { "iconPath": "../../icons/folder_type_log.svg" },
204− "_fd_log_open": { "iconPath": "../../icons/folder_type_log_opened.svg" },
205− "_fd_macos": { "iconPath": "../../icons/folder_type_macos.svg" },
206− "_fd_macos_open": { "iconPath": "../../icons/folder_type_macos_opened.svg" },
207− "_fd_mariadb": { "iconPath": "../../icons/folder_type_mariadb.svg" },
208− "_fd_mariadb_open": { "iconPath": "../../icons/folder_type_mariadb_opened.svg" },
209− "_fd_maven": { "iconPath": "../../icons/folder_type_maven.svg" },
210− "_fd_maven_open": { "iconPath": "../../icons/folder_type_maven_opened.svg" },
211− "_fd_mediawiki": { "iconPath": "../../icons/folder_type_mediawiki.svg" },
212− "_fd_mediawiki_open": { "iconPath": "../../icons/folder_type_mediawiki_opened.svg" },
213− "_fd_memcached": { "iconPath": "../../icons/folder_type_memcached.svg" },
214− "_fd_memcached_open": { "iconPath": "../../icons/folder_type_memcached_opened.svg" },
215− "_fd_meteor": { "iconPath": "../../icons/folder_type_meteor.svg" },
216− "_fd_meteor_open": { "iconPath": "../../icons/folder_type_meteor_opened.svg" },
217− "_fd_light_meteor": { "iconPath": "../../icons/folder_type_light_meteor.svg" },
218− "_fd_light_meteor_open": { "iconPath": "../../icons/folder_type_light_meteor_opened.svg" },
219− "_fd_middleware": { "iconPath": "../../icons/folder_type_middleware.svg" },
220− "_fd_middleware_open": { "iconPath": "../../icons/folder_type_middleware_opened.svg" },
221− "_fd_minecraft": { "iconPath": "../../icons/folder_type_minecraft.svg" },
222− "_fd_minecraft_open": { "iconPath": "../../icons/folder_type_minecraft_opened.svg" },
223− "_fd_minikube": { "iconPath": "../../icons/folder_type_minikube.svg" },
224− "_fd_minikube_open": { "iconPath": "../../icons/folder_type_minikube_opened.svg" },
225− "_fd_mjml": { "iconPath": "../../icons/folder_type_mjml.svg" },
226− "_fd_mjml_open": { "iconPath": "../../icons/folder_type_mjml_opened.svg" },
227− "_fd_mock": { "iconPath": "../../icons/folder_type_mock.svg" },
228− "_fd_mock_open": { "iconPath": "../../icons/folder_type_mock_opened.svg" },
229− "_fd_model": { "iconPath": "../../icons/folder_type_model.svg" },
230− "_fd_model_open": { "iconPath": "../../icons/folder_type_model_opened.svg" },
231− "_fd_module": { "iconPath": "../../icons/folder_type_module.svg" },
232− "_fd_module_open": { "iconPath": "../../icons/folder_type_module_opened.svg" },
233− "_fd_mojo": { "iconPath": "../../icons/folder_type_mojo.svg" },
234− "_fd_mojo_open": { "iconPath": "../../icons/folder_type_mojo_opened.svg" },
235− "_fd_mongodb": { "iconPath": "../../icons/folder_type_mongodb.svg" },
236− "_fd_mongodb_open": { "iconPath": "../../icons/folder_type_mongodb_opened.svg" },
237− "_fd_mypy": { "iconPath": "../../icons/folder_type_mypy.svg" },
238− "_fd_mypy_open": { "iconPath": "../../icons/folder_type_mypy_opened.svg" },
239− "_fd_light_mypy": { "iconPath": "../../icons/folder_type_light_mypy.svg" },
240− "_fd_light_mypy_open": { "iconPath": "../../icons/folder_type_light_mypy_opened.svg" },
241− "_fd_mysql": { "iconPath": "../../icons/folder_type_mysql.svg" },
242− "_fd_mysql_open": { "iconPath": "../../icons/folder_type_mysql_opened.svg" },
243− "_fd_light_mysql": { "iconPath": "../../icons/folder_type_light_mysql.svg" },
244− "_fd_light_mysql_open": { "iconPath": "../../icons/folder_type_light_mysql_opened.svg" },
245− "_fd_netlify": { "iconPath": "../../icons/folder_type_netlify.svg" },
246− "_fd_netlify_open": { "iconPath": "../../icons/folder_type_netlify_opened.svg" },
247− "_fd_next": { "iconPath": "../../icons/folder_type_next.svg" },
248− "_fd_next_open": { "iconPath": "../../icons/folder_type_next_opened.svg" },
249− "_fd_nginx": { "iconPath": "../../icons/folder_type_nginx.svg" },
250− "_fd_nginx_open": { "iconPath": "../../icons/folder_type_nginx_opened.svg" },
251− "_fd_nix": { "iconPath": "../../icons/folder_type_nix.svg" },
252− "_fd_nix_open": { "iconPath": "../../icons/folder_type_nix_opened.svg" },
253− "_fd_node": { "iconPath": "../../icons/folder_type_node.svg" },
254− "_fd_node_open": { "iconPath": "../../icons/folder_type_node_opened.svg" },
255− "_fd_light_node": { "iconPath": "../../icons/folder_type_light_node.svg" },
256− "_fd_light_node_open": { "iconPath": "../../icons/folder_type_light_node_opened.svg" },
257− "_fd_notebooks": { "iconPath": "../../icons/folder_type_notebooks.svg" },
258− "_fd_notebooks_open": { "iconPath": "../../icons/folder_type_notebooks_opened.svg" },
259− "_fd_notification": { "iconPath": "../../icons/folder_type_notification.svg" },
260− "_fd_notification_open": { "iconPath": "../../icons/folder_type_notification_opened.svg" },
261− "_fd_nuget": { "iconPath": "../../icons/folder_type_nuget.svg" },
262− "_fd_nuget_open": { "iconPath": "../../icons/folder_type_nuget_opened.svg" },
263− "_fd_nuxt": { "iconPath": "../../icons/folder_type_nuxt.svg" },
264− "_fd_nuxt_open": { "iconPath": "../../icons/folder_type_nuxt_opened.svg" },
265− "_fd_package": { "iconPath": "../../icons/folder_type_package.svg" },
266− "_fd_package_open": { "iconPath": "../../icons/folder_type_package_opened.svg" },
267− "_fd_paket": { "iconPath": "../../icons/folder_type_paket.svg" },
268− "_fd_paket_open": { "iconPath": "../../icons/folder_type_paket_opened.svg" },
269− "_fd_php": { "iconPath": "../../icons/folder_type_php.svg" },
270− "_fd_php_open": { "iconPath": "../../icons/folder_type_php_opened.svg" },
271− "_fd_platformio": { "iconPath": "../../icons/folder_type_platformio.svg" },
272− "_fd_platformio_open": { "iconPath": "../../icons/folder_type_platformio_opened.svg" },
273− "_fd_plugin": { "iconPath": "../../icons/folder_type_plugin.svg" },
274− "_fd_plugin_open": { "iconPath": "../../icons/folder_type_plugin_opened.svg" },
275− "_fd_prisma": { "iconPath": "../../icons/folder_type_prisma.svg" },
276− "_fd_prisma_open": { "iconPath": "../../icons/folder_type_prisma_opened.svg" },
277− "_fd_private": { "iconPath": "../../icons/folder_type_private.svg" },
278− "_fd_private_open": { "iconPath": "../../icons/folder_type_private_opened.svg" },
279− "_fd_public": { "iconPath": "../../icons/folder_type_public.svg" },
280− "_fd_public_open": { "iconPath": "../../icons/folder_type_public_opened.svg" },
281− "_fd_pytest": { "iconPath": "../../icons/folder_type_pytest.svg" },
282− "_fd_pytest_open": { "iconPath": "../../icons/folder_type_pytest_opened.svg" },
283− "_fd_python": { "iconPath": "../../icons/folder_type_python.svg" },
284− "_fd_python_open": { "iconPath": "../../icons/folder_type_python_opened.svg" },
285− "_fd_ravendb": { "iconPath": "../../icons/folder_type_ravendb.svg" },
286− "_fd_ravendb_open": { "iconPath": "../../icons/folder_type_ravendb_opened.svg" },
287− "_fd_redis": { "iconPath": "../../icons/folder_type_redis.svg" },
288− "_fd_redis_open": { "iconPath": "../../icons/folder_type_redis_opened.svg" },
289− "_fd_redux": { "iconPath": "../../icons/folder_type_redux.svg" },
290− "_fd_redux_open": { "iconPath": "../../icons/folder_type_redux_opened.svg" },
291− "_fd_light_redux": { "iconPath": "../../icons/folder_type_light_redux.svg" },
292− "_fd_light_redux_open": { "iconPath": "../../icons/folder_type_light_redux_opened.svg" },
293− "_fd_route": { "iconPath": "../../icons/folder_type_route.svg" },
294− "_fd_route_open": { "iconPath": "../../icons/folder_type_route_opened.svg" },
295− "_fd_sass": { "iconPath": "../../icons/folder_type_sass.svg" },
296− "_fd_sass_open": { "iconPath": "../../icons/folder_type_sass_opened.svg" },
297− "_fd_light_sass": { "iconPath": "../../icons/folder_type_light_sass.svg" },
298− "_fd_light_sass_open": { "iconPath": "../../icons/folder_type_light_sass_opened.svg" },
299− "_fd_script": { "iconPath": "../../icons/folder_type_script.svg" },
300− "_fd_script_open": { "iconPath": "../../icons/folder_type_script_opened.svg" },
301− "_fd_seedkit": { "iconPath": "../../icons/folder_type_seedkit.svg" },
302− "_fd_seedkit_open": { "iconPath": "../../icons/folder_type_seedkit_opened.svg" },
303− "_fd_server": { "iconPath": "../../icons/folder_type_server.svg" },
304− "_fd_server_open": { "iconPath": "../../icons/folder_type_server_opened.svg" },
305− "_fd_services": { "iconPath": "../../icons/folder_type_services.svg" },
306− "_fd_services_open": { "iconPath": "../../icons/folder_type_services_opened.svg" },
307− "_fd_shared": { "iconPath": "../../icons/folder_type_shared.svg" },
308− "_fd_shared_open": { "iconPath": "../../icons/folder_type_shared_opened.svg" },
309− "_fd_snaplet": { "iconPath": "../../icons/folder_type_snaplet.svg" },
310− "_fd_snaplet_open": { "iconPath": "../../icons/folder_type_snaplet_opened.svg" },
311− "_fd_spin": { "iconPath": "../../icons/folder_type_spin.svg" },
312− "_fd_spin_open": { "iconPath": "../../icons/folder_type_spin_opened.svg" },
313− "_fd_src": { "iconPath": "../../icons/folder_type_src.svg" },
314− "_fd_src_open": { "iconPath": "../../icons/folder_type_src_opened.svg" },
315− "_fd_sso": { "iconPath": "../../icons/folder_type_sso.svg" },
316− "_fd_sso_open": { "iconPath": "../../icons/folder_type_sso_opened.svg" },
317− "_fd_story": { "iconPath": "../../icons/folder_type_story.svg" },
318− "_fd_story_open": { "iconPath": "../../icons/folder_type_story_opened.svg" },
319− "_fd_style": { "iconPath": "../../icons/folder_type_style.svg" },
320− "_fd_style_open": { "iconPath": "../../icons/folder_type_style_opened.svg" },
321− "_fd_supabase": { "iconPath": "../../icons/folder_type_supabase.svg" },
322− "_fd_supabase_open": { "iconPath": "../../icons/folder_type_supabase_opened.svg" },
323− "_fd_svelte": { "iconPath": "../../icons/folder_type_svelte.svg" },
324− "_fd_svelte_open": { "iconPath": "../../icons/folder_type_svelte_opened.svg" },
325− "_fd_tauri": { "iconPath": "../../icons/folder_type_tauri.svg" },
326− "_fd_tauri_open": { "iconPath": "../../icons/folder_type_tauri_opened.svg" },
327− "_fd_temp": { "iconPath": "../../icons/folder_type_temp.svg" },
328− "_fd_temp_open": { "iconPath": "../../icons/folder_type_temp_opened.svg" },
329− "_fd_template": { "iconPath": "../../icons/folder_type_template.svg" },
330− "_fd_template_open": { "iconPath": "../../icons/folder_type_template_opened.svg" },
331− "_fd_test": { "iconPath": "../../icons/folder_type_test.svg" },
332− "_fd_test_open": { "iconPath": "../../icons/folder_type_test_opened.svg" },
333− "_fd_theme": { "iconPath": "../../icons/folder_type_theme.svg" },
334− "_fd_theme_open": { "iconPath": "../../icons/folder_type_theme_opened.svg" },
335− "_fd_tools": { "iconPath": "../../icons/folder_type_tools.svg" },
336− "_fd_tools_open": { "iconPath": "../../icons/folder_type_tools_opened.svg" },
337− "_fd_travis": { "iconPath": "../../icons/folder_type_travis.svg" },
338− "_fd_travis_open": { "iconPath": "../../icons/folder_type_travis_opened.svg" },
339− "_fd_trunk": { "iconPath": "../../icons/folder_type_trunk.svg" },
340− "_fd_trunk_open": { "iconPath": "../../icons/folder_type_trunk_opened.svg" },
341− "_fd_turbo": { "iconPath": "../../icons/folder_type_turbo.svg" },
342− "_fd_turbo_open": { "iconPath": "../../icons/folder_type_turbo_opened.svg" },
343− "_fd_typescript": { "iconPath": "../../icons/folder_type_typescript.svg" },
344− "_fd_typescript_open": { "iconPath": "../../icons/folder_type_typescript_opened.svg" },
345− "_fd_typings": { "iconPath": "../../icons/folder_type_typings.svg" },
346− "_fd_typings_open": { "iconPath": "../../icons/folder_type_typings_opened.svg" },
347− "_fd_vagrant": { "iconPath": "../../icons/folder_type_vagrant.svg" },
348− "_fd_vagrant_open": { "iconPath": "../../icons/folder_type_vagrant_opened.svg" },
349− "_fd_vercel": { "iconPath": "../../icons/folder_type_vercel.svg" },
350− "_fd_vercel_open": { "iconPath": "../../icons/folder_type_vercel_opened.svg" },
351− "_fd_video": { "iconPath": "../../icons/folder_type_video.svg" },
352− "_fd_video_open": { "iconPath": "../../icons/folder_type_video_opened.svg" },
353− "_fd_view": { "iconPath": "../../icons/folder_type_view.svg" },
354− "_fd_view_open": { "iconPath": "../../icons/folder_type_view_opened.svg" },
355− "_fd_vitepress": { "iconPath": "../../icons/folder_type_vitepress.svg" },
356− "_fd_vitepress_open": { "iconPath": "../../icons/folder_type_vitepress_opened.svg" },
357− "_fd_vs": { "iconPath": "../../icons/folder_type_vs.svg" },
358− "_fd_vs_open": { "iconPath": "../../icons/folder_type_vs_opened.svg" },
359− "_fd_vscode": { "iconPath": "../../icons/folder_type_vscode.svg" },
360− "_fd_vscode_open": { "iconPath": "../../icons/folder_type_vscode_opened.svg" },
361− "_fd_vscode_test": { "iconPath": "../../icons/folder_type_vscode_test.svg" },
362− "_fd_vscode_test_open": { "iconPath": "../../icons/folder_type_vscode_test_opened.svg" },
363− "_fd_wasm": { "iconPath": "../../icons/folder_type_wasm.svg" },
364− "_fd_wasm_open": { "iconPath": "../../icons/folder_type_wasm_opened.svg" },
365− "_fd_webpack": { "iconPath": "../../icons/folder_type_webpack.svg" },
366− "_fd_webpack_open": { "iconPath": "../../icons/folder_type_webpack_opened.svg" },
367− "_fd_windows": { "iconPath": "../../icons/folder_type_windows.svg" },
368− "_fd_windows_open": { "iconPath": "../../icons/folder_type_windows_opened.svg" },
369− "_fd_windsurf": { "iconPath": "../../icons/folder_type_windsurf.svg" },
370− "_fd_windsurf_open": { "iconPath": "../../icons/folder_type_windsurf_opened.svg" },
371− "_fd_wit": { "iconPath": "../../icons/folder_type_wit.svg" },
372− "_fd_wit_open": { "iconPath": "../../icons/folder_type_wit_opened.svg" },
373− "_fd_www": { "iconPath": "../../icons/folder_type_www.svg" },
374− "_fd_www_open": { "iconPath": "../../icons/folder_type_www_opened.svg" },
375− "_fd_yarn": { "iconPath": "../../icons/folder_type_yarn.svg" },
376− "_fd_yarn_open": { "iconPath": "../../icons/folder_type_yarn_opened.svg" },
377− "_fd_zed": { "iconPath": "../../icons/folder_type_zed.svg" },
378− "_fd_zed_open": { "iconPath": "../../icons/folder_type_zed_opened.svg" },
379− "_fd_light_zed": { "iconPath": "../../icons/folder_type_light_zed.svg" },
380− "_fd_light_zed_open": { "iconPath": "../../icons/folder_type_light_zed_opened.svg" },
381− "_f_access": { "iconPath": "../../icons/file_type_access.svg" },
382− "_f_actionscript": { "iconPath": "../../icons/file_type_actionscript.svg" },
383− "_f_ada": { "iconPath": "../../icons/file_type_ada.svg" },
384− "_f_light_ada": { "iconPath": "../../icons/file_type_light_ada.svg" },
385− "_f_advpl": { "iconPath": "../../icons/file_type_advpl.svg" },
386− "_f_affectscript": { "iconPath": "../../icons/file_type_affectscript.svg" },
387− "_f_affinity": { "iconPath": "../../icons/file_type_affinity.svg" },
388− "_f_affinitydesigner": { "iconPath": "../../icons/file_type_affinitydesigner.svg" },
389− "_f_affinityphoto": { "iconPath": "../../icons/file_type_affinityphoto.svg" },
390− "_f_affinitypublisher": { "iconPath": "../../icons/file_type_affinitypublisher.svg" },
391− "_f_agda": { "iconPath": "../../icons/file_type_agda.svg" },
392− "_f_light_agda": { "iconPath": "../../icons/file_type_light_agda.svg" },
393− "_f_agents": { "iconPath": "../../icons/file_type_agents.svg" },
394− "_f_light_agents": { "iconPath": "../../icons/file_type_light_agents.svg" },
395− "_f_ai": { "iconPath": "../../icons/file_type_ai.svg" },
396− "_f_al": { "iconPath": "../../icons/file_type_al.svg" },
397− "_f_al_dal": { "iconPath": "../../icons/file_type_al_dal.svg" },
398− "_f_alchemy": { "iconPath": "../../icons/file_type_alchemy.svg" },
399− "_f_allcontributors": { "iconPath": "../../icons/file_type_allcontributors.svg" },
400− "_f_alloy": { "iconPath": "../../icons/file_type_alloy.svg" },
401− "_f_allure": { "iconPath": "../../icons/file_type_allure.svg" },
402− "_f_angular": { "iconPath": "../../icons/file_type_angular.svg" },
403− "_f_ansible": { "iconPath": "../../icons/file_type_ansible.svg" },
404− "_f_antlers_html": { "iconPath": "../../icons/file_type_antlers_html.svg" },
405− "_f_antlr": { "iconPath": "../../icons/file_type_antlr.svg" },
406− "_f_anyscript": { "iconPath": "../../icons/file_type_anyscript.svg" },
407− "_f_apache": { "iconPath": "../../icons/file_type_apache.svg" },
408− "_f_apex": { "iconPath": "../../icons/file_type_apex.svg" },
409− "_f_api_extractor": { "iconPath": "../../icons/file_type_api_extractor.svg" },
410− "_f_apib": { "iconPath": "../../icons/file_type_apib.svg" },
411− "_f_apl": { "iconPath": "../../icons/file_type_apl.svg" },
412− "_f_light_apl": { "iconPath": "../../icons/file_type_light_apl.svg" },
413− "_f_applescript": { "iconPath": "../../icons/file_type_applescript.svg" },
414− "_f_appscript": { "iconPath": "../../icons/file_type_appscript.svg" },
415− "_f_appsemble": { "iconPath": "../../icons/file_type_appsemble.svg" },
416− "_f_appveyor": { "iconPath": "../../icons/file_type_appveyor.svg" },
417− "_f_arduino": { "iconPath": "../../icons/file_type_arduino.svg" },
418− "_f_asciidoc": { "iconPath": "../../icons/file_type_asciidoc.svg" },
419− "_f_aseprite": { "iconPath": "../../icons/file_type_aseprite.svg" },
420− "_f_asp": { "iconPath": "../../icons/file_type_asp.svg" },
421− "_f_aspx": { "iconPath": "../../icons/file_type_aspx.svg" },
422− "_f_assembly": { "iconPath": "../../icons/file_type_assembly.svg" },
423− "_f_assembly_script": { "iconPath": "../../icons/file_type_assembly_script.svg" },
424− "_f_astro": { "iconPath": "../../icons/file_type_astro.svg" },
425− "_f_light_astro": { "iconPath": "../../icons/file_type_light_astro.svg" },
426− "_f_astroconfig": { "iconPath": "../../icons/file_type_astroconfig.svg" },
427− "_f_light_astroconfig": { "iconPath": "../../icons/file_type_light_astroconfig.svg" },
428− "_f_atom": { "iconPath": "../../icons/file_type_atom.svg" },
429− "_f_ats": { "iconPath": "../../icons/file_type_ats.svg" },
430− "_f_attw": { "iconPath": "../../icons/file_type_attw.svg" },
431− "_f_audio": { "iconPath": "../../icons/file_type_audio.svg" },
432− "_f_aurelia": { "iconPath": "../../icons/file_type_aurelia.svg" },
433− "_f_autohotkey": { "iconPath": "../../icons/file_type_autohotkey.svg" },
434− "_f_autoit": { "iconPath": "../../icons/file_type_autoit.svg" },
435− "_f_avif": { "iconPath": "../../icons/file_type_avif.svg" },
436− "_f_avro": { "iconPath": "../../icons/file_type_avro.svg" },
437− "_f_awk": { "iconPath": "../../icons/file_type_awk.svg" },
438− "_f_aws": { "iconPath": "../../icons/file_type_aws.svg" },
439− "_f_azure": { "iconPath": "../../icons/file_type_azure.svg" },
440− "_f_azurepipelines": { "iconPath": "../../icons/file_type_azurepipelines.svg" },
441− "_f_babel": { "iconPath": "../../icons/file_type_babel.svg" },
442− "_f_light_babel": { "iconPath": "../../icons/file_type_light_babel.svg" },
443− "_f_bak": { "iconPath": "../../icons/file_type_bak.svg" },
444− "_f_ballerina": { "iconPath": "../../icons/file_type_ballerina.svg" },
445− "_f_bat": { "iconPath": "../../icons/file_type_bat.svg" },
446− "_f_bats": { "iconPath": "../../icons/file_type_bats.svg" },
447− "_f_bazaar": { "iconPath": "../../icons/file_type_bazaar.svg" },
448− "_f_bazel": { "iconPath": "../../icons/file_type_bazel.svg" },
449− "_f_bazel_ignore": { "iconPath": "../../icons/file_type_bazel_ignore.svg" },
450− "_f_bazel_version": { "iconPath": "../../icons/file_type_bazel_version.svg" },
451− "_f_befunge": { "iconPath": "../../icons/file_type_befunge.svg" },
452− "_f_bicep": { "iconPath": "../../icons/file_type_bicep.svg" },
453− "_f_biml": { "iconPath": "../../icons/file_type_biml.svg" },
454− "_f_binary": { "iconPath": "../../icons/file_type_binary.svg" },
455− "_f_biome": { "iconPath": "../../icons/file_type_biome.svg" },
456− "_f_bitbucketpipeline": { "iconPath": "../../icons/file_type_bitbucketpipeline.svg" },
457− "_f_bithound": { "iconPath": "../../icons/file_type_bithound.svg" },
458− "_f_blade": { "iconPath": "../../icons/file_type_blade.svg" },
459− "_f_blender": { "iconPath": "../../icons/file_type_blender.svg" },
460− "_f_blitzbasic": { "iconPath": "../../icons/file_type_blitzbasic.svg" },
461− "_f_bolt": { "iconPath": "../../icons/file_type_bolt.svg" },
462− "_f_bosque": { "iconPath": "../../icons/file_type_bosque.svg" },
463− "_f_bower": { "iconPath": "../../icons/file_type_bower.svg" },
464− "_f_browserslist": { "iconPath": "../../icons/file_type_browserslist.svg" },
465− "_f_bruno": { "iconPath": "../../icons/file_type_bruno.svg" },
466− "_f_buckbuild": { "iconPath": "../../icons/file_type_buckbuild.svg" },
467− "_f_buf": { "iconPath": "../../icons/file_type_buf.svg" },
468− "_f_bun": { "iconPath": "../../icons/file_type_bun.svg" },
469− "_f_bundlemon": { "iconPath": "../../icons/file_type_bundlemon.svg" },
470− "_f_bundler": { "iconPath": "../../icons/file_type_bundler.svg" },
471− "_f_bunfig": { "iconPath": "../../icons/file_type_bunfig.svg" },
472− "_f_c": { "iconPath": "../../icons/file_type_c.svg" },
473− "_f_c3": { "iconPath": "../../icons/file_type_c3.svg" },
474− "_f_c_al": { "iconPath": "../../icons/file_type_c_al.svg" },
475− "_f_cabal": { "iconPath": "../../icons/file_type_cabal.svg" },
476− "_f_caddy": { "iconPath": "../../icons/file_type_caddy.svg" },
477− "_f_cake": { "iconPath": "../../icons/file_type_cake.svg" },
478− "_f_cakephp": { "iconPath": "../../icons/file_type_cakephp.svg" },
479− "_f_capacitor": { "iconPath": "../../icons/file_type_capacitor.svg" },
480− "_f_capnp": { "iconPath": "../../icons/file_type_capnp.svg" },
481− "_f_cargo": { "iconPath": "../../icons/file_type_cargo.svg" },
482− "_f_casc": { "iconPath": "../../icons/file_type_casc.svg" },
483− "_f_cddl": { "iconPath": "../../icons/file_type_cddl.svg" },
484− "_f_cert": { "iconPath": "../../icons/file_type_cert.svg" },
485− "_f_ceylon": { "iconPath": "../../icons/file_type_ceylon.svg" },
486− "_f_cf": { "iconPath": "../../icons/file_type_cf.svg" },
487− "_f_cfc": { "iconPath": "../../icons/file_type_cfc.svg" },
488− "_f_cfm": { "iconPath": "../../icons/file_type_cfm.svg" },
489− "_f_changie": { "iconPath": "../../icons/file_type_changie.svg" },
490− "_f_cheader": { "iconPath": "../../icons/file_type_cheader.svg" },
491− "_f_chef": { "iconPath": "../../icons/file_type_chef.svg" },
492− "_f_chef_cookbook": { "iconPath": "../../icons/file_type_chef_cookbook.svg" },
493− "_f_circleci": { "iconPath": "../../icons/file_type_circleci.svg" },
494− "_f_light_circleci": { "iconPath": "../../icons/file_type_light_circleci.svg" },
495− "_f_circom": { "iconPath": "../../icons/file_type_circom.svg" },
496− "_f_class": { "iconPath": "../../icons/file_type_class.svg" },
497− "_f_claude": { "iconPath": "../../icons/file_type_claude.svg" },
498− "_f_clojure": { "iconPath": "../../icons/file_type_clojure.svg" },
499− "_f_clojurescript": { "iconPath": "../../icons/file_type_clojurescript.svg" },
500− "_f_cloudflare": { "iconPath": "../../icons/file_type_cloudflare.svg" },
501− "_f_cloudfoundry": { "iconPath": "../../icons/file_type_cloudfoundry.svg" },
502− "_f_light_cloudfoundry": { "iconPath": "../../icons/file_type_light_cloudfoundry.svg" },
503− "_f_cmake": { "iconPath": "../../icons/file_type_cmake.svg" },
504− "_f_cobol": { "iconPath": "../../icons/file_type_cobol.svg" },
505− "_f_codacy": { "iconPath": "../../icons/file_type_codacy.svg" },
506− "_f_light_codacy": { "iconPath": "../../icons/file_type_light_codacy.svg" },
507− "_f_codeclimate": { "iconPath": "../../icons/file_type_codeclimate.svg" },
508− "_f_light_codeclimate": { "iconPath": "../../icons/file_type_light_codeclimate.svg" },
509− "_f_codecov": { "iconPath": "../../icons/file_type_codecov.svg" },
510− "_f_codekit": { "iconPath": "../../icons/file_type_codekit.svg" },
511− "_f_codemagic": { "iconPath": "../../icons/file_type_codemagic.svg" },
512− "_f_codeowners": { "iconPath": "../../icons/file_type_codeowners.svg" },
513− "_f_light_codeowners": { "iconPath": "../../icons/file_type_light_codeowners.svg" },
514− "_f_codeql": { "iconPath": "../../icons/file_type_codeql.svg" },
515− "_f_coderabbit": { "iconPath": "../../icons/file_type_coderabbit.svg" },
516− "_f_coffeelint": { "iconPath": "../../icons/file_type_coffeelint.svg" },
517− "_f_coffeescript": { "iconPath": "../../icons/file_type_coffeescript.svg" },
518− "_f_commitizen": { "iconPath": "../../icons/file_type_commitizen.svg" },
519− "_f_commitlint": { "iconPath": "../../icons/file_type_commitlint.svg" },
520− "_f_compass": { "iconPath": "../../icons/file_type_compass.svg" },
521− "_f_composer": { "iconPath": "../../icons/file_type_composer.svg" },
522− "_f_conan": { "iconPath": "../../icons/file_type_conan.svg" },
523− "_f_conda": { "iconPath": "../../icons/file_type_conda.svg" },
524− "_f_config": { "iconPath": "../../icons/file_type_config.svg" },
525− "_f_light_config": { "iconPath": "../../icons/file_type_light_config.svg" },
526− "_f_confluence": { "iconPath": "../../icons/file_type_confluence.svg" },
527− "_f_copilot": { "iconPath": "../../icons/file_type_copilot.svg" },
528− "_f_light_copilot": { "iconPath": "../../icons/file_type_light_copilot.svg" },
529− "_f_coverage": { "iconPath": "../../icons/file_type_coverage.svg" },
530− "_f_coveralls": { "iconPath": "../../icons/file_type_coveralls.svg" },
531− "_f_cpp": { "iconPath": "../../icons/file_type_cpp.svg" },
532− "_f_cppheader": { "iconPath": "../../icons/file_type_cppheader.svg" },
533− "_f_craco": { "iconPath": "../../icons/file_type_craco.svg" },
534− "_f_crowdin": { "iconPath": "../../icons/file_type_crowdin.svg" },
535− "_f_crystal": { "iconPath": "../../icons/file_type_crystal.svg" },
536− "_f_light_crystal": { "iconPath": "../../icons/file_type_light_crystal.svg" },
537− "_f_csharp": { "iconPath": "../../icons/file_type_csharp.svg" },
538− "_f_cspell": { "iconPath": "../../icons/file_type_cspell.svg" },
539− "_f_csproj": { "iconPath": "../../icons/file_type_csproj.svg" },
540− "_f_css": { "iconPath": "../../icons/file_type_css.svg" },
541− "_f_csscomb": { "iconPath": "../../icons/file_type_csscomb.svg" },
542− "_f_csslint": { "iconPath": "../../icons/file_type_csslint.svg" },
543− "_f_cssmap": { "iconPath": "../../icons/file_type_cssmap.svg" },
544− "_f_cucumber": { "iconPath": "../../icons/file_type_cucumber.svg" },
545− "_f_cuda": { "iconPath": "../../icons/file_type_cuda.svg" },
546− "_f_cursorrules": { "iconPath": "../../icons/file_type_cursorrules.svg" },
547− "_f_cvs": { "iconPath": "../../icons/file_type_cvs.svg" },
548− "_f_cypress": { "iconPath": "../../icons/file_type_cypress.svg" },
549− "_f_light_cypress": { "iconPath": "../../icons/file_type_light_cypress.svg" },
550− "_f_cypress_spec": { "iconPath": "../../icons/file_type_cypress_spec.svg" },
551− "_f_light_cypress_spec": { "iconPath": "../../icons/file_type_light_cypress_spec.svg" },
552− "_f_cython": { "iconPath": "../../icons/file_type_cython.svg" },
553− "_f_dal": { "iconPath": "../../icons/file_type_dal.svg" },
554− "_f_darcs": { "iconPath": "../../icons/file_type_darcs.svg" },
555− "_f_dartlang": { "iconPath": "../../icons/file_type_dartlang.svg" },
556− "_f_dartlang_generated": { "iconPath": "../../icons/file_type_dartlang_generated.svg" },
557− "_f_dartlang_ignore": { "iconPath": "../../icons/file_type_dartlang_ignore.svg" },
558− "_f_datadog": { "iconPath": "../../icons/file_type_datadog.svg" },
559− "_f_db": { "iconPath": "../../icons/file_type_db.svg" },
560− "_f_light_db": { "iconPath": "../../icons/file_type_light_db.svg" },
561− "_f_debian": { "iconPath": "../../icons/file_type_debian.svg" },
562− "_f_delphi": { "iconPath": "../../icons/file_type_delphi.svg" },
563− "_f_deno": { "iconPath": "../../icons/file_type_deno.svg" },
564− "_f_denoify": { "iconPath": "../../icons/file_type_denoify.svg" },
565− "_f_dependabot": { "iconPath": "../../icons/file_type_dependabot.svg" },
566− "_f_dependencies": { "iconPath": "../../icons/file_type_dependencies.svg" },
567− "_f_design_tokens": { "iconPath": "../../icons/file_type_design_tokens.svg" },
568− "_f_devcontainer": { "iconPath": "../../icons/file_type_devcontainer.svg" },
569− "_f_devvit": { "iconPath": "../../icons/file_type_devvit.svg" },
570− "_f_dhall": { "iconPath": "../../icons/file_type_dhall.svg" },
571− "_f_light_dhall": { "iconPath": "../../icons/file_type_light_dhall.svg" },
572− "_f_diff": { "iconPath": "../../icons/file_type_diff.svg" },
573− "_f_django": { "iconPath": "../../icons/file_type_django.svg" },
574− "_f_dlang": { "iconPath": "../../icons/file_type_dlang.svg" },
575− "_f_docker": { "iconPath": "../../icons/file_type_docker.svg" },
576− "_f_dockertest": { "iconPath": "../../icons/file_type_dockertest.svg" },
577− "_f_docpad": { "iconPath": "../../icons/file_type_docpad.svg" },
578− "_f_light_docpad": { "iconPath": "../../icons/file_type_light_docpad.svg" },
579− "_f_docusaurus": { "iconPath": "../../icons/file_type_docusaurus.svg" },
580− "_f_docz": { "iconPath": "../../icons/file_type_docz.svg" },
581− "_f_dojo": { "iconPath": "../../icons/file_type_dojo.svg" },
582− "_f_doppler": { "iconPath": "../../icons/file_type_doppler.svg" },
583− "_f_dotenv": { "iconPath": "../../icons/file_type_dotenv.svg" },
584− "_f_dotjs": { "iconPath": "../../icons/file_type_dotjs.svg" },
585− "_f_doxygen": { "iconPath": "../../icons/file_type_doxygen.svg" },
586− "_f_drawio": { "iconPath": "../../icons/file_type_drawio.svg" },
587− "_f_drone": { "iconPath": "../../icons/file_type_drone.svg" },
588− "_f_light_drone": { "iconPath": "../../icons/file_type_light_drone.svg" },
589− "_f_drools": { "iconPath": "../../icons/file_type_drools.svg" },
590− "_f_dtd": { "iconPath": "../../icons/file_type_dtd.svg" },
591− "_f_dune": { "iconPath": "../../icons/file_type_dune.svg" },
592− "_f_dustjs": { "iconPath": "../../icons/file_type_dustjs.svg" },
593− "_f_dvc": { "iconPath": "../../icons/file_type_dvc.svg" },
594− "_f_dylan": { "iconPath": "../../icons/file_type_dylan.svg" },
595− "_f_earthly": { "iconPath": "../../icons/file_type_earthly.svg" },
596− "_f_eas-metadata": { "iconPath": "../../icons/file_type_eas-metadata.svg" },
597− "_f_light_eas-metadata": { "iconPath": "../../icons/file_type_light_eas-metadata.svg" },
598− "_f_edge": { "iconPath": "../../icons/file_type_edge.svg" },
599− "_f_editorconfig": { "iconPath": "../../icons/file_type_editorconfig.svg" },
600− "_f_eex": { "iconPath": "../../icons/file_type_eex.svg" },
601− "_f_ejs": { "iconPath": "../../icons/file_type_ejs.svg" },
602− "_f_elastic": { "iconPath": "../../icons/file_type_elastic.svg" },
603− "_f_elasticbeanstalk": { "iconPath": "../../icons/file_type_elasticbeanstalk.svg" },
604− "_f_electron": { "iconPath": "../../icons/file_type_electron.svg" },
605− "_f_eleventy": { "iconPath": "../../icons/file_type_eleventy.svg" },
606− "_f_light_eleventy": { "iconPath": "../../icons/file_type_light_eleventy.svg" },
607− "_f_elixir": { "iconPath": "../../icons/file_type_elixir.svg" },
608− "_f_elm": { "iconPath": "../../icons/file_type_elm.svg" },
609− "_f_emacs": { "iconPath": "../../icons/file_type_emacs.svg" },
610− "_f_ember": { "iconPath": "../../icons/file_type_ember.svg" },
611− "_f_ensime": { "iconPath": "../../icons/file_type_ensime.svg" },
612− "_f_eps": { "iconPath": "../../icons/file_type_eps.svg" },
613− "_f_epub": { "iconPath": "../../icons/file_type_epub.svg" },
614− "_f_erb": { "iconPath": "../../icons/file_type_erb.svg" },
615− "_f_erlang": { "iconPath": "../../icons/file_type_erlang.svg" },
616− "_f_esbuild": { "iconPath": "../../icons/file_type_esbuild.svg" },
617− "_f_eslint": { "iconPath": "../../icons/file_type_eslint.svg" },
618− "_f_esphome": { "iconPath": "../../icons/file_type_esphome.svg" },
619− "_f_light_esphome": { "iconPath": "../../icons/file_type_light_esphome.svg" },
620− "_f_excalidraw": { "iconPath": "../../icons/file_type_excalidraw.svg" },
621− "_f_excel": { "iconPath": "../../icons/file_type_excel.svg" },
622− "_f_expo": { "iconPath": "../../icons/file_type_expo.svg" },
623− "_f_light_expo": { "iconPath": "../../icons/file_type_light_expo.svg" },
624− "_f_falcon": { "iconPath": "../../icons/file_type_falcon.svg" },
625− "_f_fantasticon": { "iconPath": "../../icons/file_type_fantasticon.svg" },
626− "_f_fastly": { "iconPath": "../../icons/file_type_fastly.svg" },
627− "_f_fauna": { "iconPath": "../../icons/file_type_fauna.svg" },
628− "_f_favicon": { "iconPath": "../../icons/file_type_favicon.svg" },
629− "_f_fbx": { "iconPath": "../../icons/file_type_fbx.svg" },
630− "_f_firebase": { "iconPath": "../../icons/file_type_firebase.svg" },
631− "_f_firebasehosting": { "iconPath": "../../icons/file_type_firebasehosting.svg" },
632− "_f_light_firebasehosting": { "iconPath": "../../icons/file_type_light_firebasehosting.svg" },
633− "_f_firebasestorage": { "iconPath": "../../icons/file_type_firebasestorage.svg" },
634− "_f_firestore": { "iconPath": "../../icons/file_type_firestore.svg" },
635− "_f_fitbit": { "iconPath": "../../icons/file_type_fitbit.svg" },
636− "_f_fla": { "iconPath": "../../icons/file_type_fla.svg" },
637− "_f_light_fla": { "iconPath": "../../icons/file_type_light_fla.svg" },
638− "_f_flareact": { "iconPath": "../../icons/file_type_flareact.svg" },
639− "_f_flash": { "iconPath": "../../icons/file_type_flash.svg" },
640− "_f_floobits": { "iconPath": "../../icons/file_type_floobits.svg" },
641− "_f_flow": { "iconPath": "../../icons/file_type_flow.svg" },
642− "_f_flutter": { "iconPath": "../../icons/file_type_flutter.svg" },
643− "_f_flutter_package": { "iconPath": "../../icons/file_type_flutter_package.svg" },
644− "_f_flyio": { "iconPath": "../../icons/file_type_flyio.svg" },
645− "_f_font": { "iconPath": "../../icons/file_type_font.svg" },
646− "_f_light_font": { "iconPath": "../../icons/file_type_light_font.svg" },
647− "_f_formkit": { "iconPath": "../../icons/file_type_formkit.svg" },
648− "_f_fortran": { "iconPath": "../../icons/file_type_fortran.svg" },
649− "_f_fossa": { "iconPath": "../../icons/file_type_fossa.svg" },
650− "_f_fossil": { "iconPath": "../../icons/file_type_fossil.svg" },
651− "_f_freemarker": { "iconPath": "../../icons/file_type_freemarker.svg" },
652− "_f_frontcommerce": { "iconPath": "../../icons/file_type_frontcommerce.svg" },
653− "_f_fsharp": { "iconPath": "../../icons/file_type_fsharp.svg" },
654− "_f_fsproj": { "iconPath": "../../icons/file_type_fsproj.svg" },
655− "_f_fthtml": { "iconPath": "../../icons/file_type_fthtml.svg" },
656− "_f_funding": { "iconPath": "../../icons/file_type_funding.svg" },
657− "_f_fusebox": { "iconPath": "../../icons/file_type_fusebox.svg" },
658− "_f_galen": { "iconPath": "../../icons/file_type_galen.svg" },
659− "_f_gamemaker": { "iconPath": "../../icons/file_type_gamemaker.svg" },
660− "_f_gamemaker2": { "iconPath": "../../icons/file_type_gamemaker2.svg" },
661− "_f_light_gamemaker2": { "iconPath": "../../icons/file_type_light_gamemaker2.svg" },
662− "_f_gamemaker81": { "iconPath": "../../icons/file_type_gamemaker81.svg" },
663− "_f_gatsby": { "iconPath": "../../icons/file_type_gatsby.svg" },
664− "_f_gcloud": { "iconPath": "../../icons/file_type_gcloud.svg" },
665− "_f_gcode": { "iconPath": "../../icons/file_type_gcode.svg" },
666− "_f_gdscript": { "iconPath": "../../icons/file_type_gdscript.svg" },
667− "_f_gduid": { "iconPath": "../../icons/file_type_gduid.svg" },
668− "_f_gemini": { "iconPath": "../../icons/file_type_gemini.svg" },
669− "_f_genstat": { "iconPath": "../../icons/file_type_genstat.svg" },
670− "_f_geojson": { "iconPath": "../../icons/file_type_geojson.svg" },
671− "_f_gimp": { "iconPath": "../../icons/file_type_gimp.svg" },
672− "_f_git": { "iconPath": "../../icons/file_type_git.svg" },
673− "_f_gitlab": { "iconPath": "../../icons/file_type_gitlab.svg" },
674− "_f_gitpod": { "iconPath": "../../icons/file_type_gitpod.svg" },
675− "_f_gleam": { "iconPath": "../../icons/file_type_gleam.svg" },
676− "_f_gleamconfig": { "iconPath": "../../icons/file_type_gleamconfig.svg" },
677− "_f_glide": { "iconPath": "../../icons/file_type_glide.svg" },
678− "_f_glimmer": { "iconPath": "../../icons/file_type_glimmer.svg" },
679− "_f_glitter": { "iconPath": "../../icons/file_type_glitter.svg" },
680− "_f_glsl": { "iconPath": "../../icons/file_type_glsl.svg" },
681− "_f_gltf": { "iconPath": "../../icons/file_type_gltf.svg" },
682− "_f_glyphs": { "iconPath": "../../icons/file_type_glyphs.svg" },
683− "_f_gnu": { "iconPath": "../../icons/file_type_gnu.svg" },
684− "_f_gnuplot": { "iconPath": "../../icons/file_type_gnuplot.svg" },
685− "_f_go": { "iconPath": "../../icons/file_type_go.svg" },
686− "_f_go_package": { "iconPath": "../../icons/file_type_go_package.svg" },
687− "_f_go_work": { "iconPath": "../../icons/file_type_go_work.svg" },
688− "_f_goctl": { "iconPath": "../../icons/file_type_goctl.svg" },
689− "_f_godot": { "iconPath": "../../icons/file_type_godot.svg" },
690− "_f_gpg": { "iconPath": "../../icons/file_type_gpg.svg" },
691− "_f_gradle": { "iconPath": "../../icons/file_type_gradle.svg" },
692− "_f_light_gradle": { "iconPath": "../../icons/file_type_light_gradle.svg" },
693− "_f_grain": { "iconPath": "../../icons/file_type_grain.svg" },
694− "_f_graphql": { "iconPath": "../../icons/file_type_graphql.svg" },
695− "_f_graphql_config": { "iconPath": "../../icons/file_type_graphql_config.svg" },
696− "_f_graphviz": { "iconPath": "../../icons/file_type_graphviz.svg" },
697− "_f_greenkeeper": { "iconPath": "../../icons/file_type_greenkeeper.svg" },
698− "_f_gridsome": { "iconPath": "../../icons/file_type_gridsome.svg" },
699− "_f_grit": { "iconPath": "../../icons/file_type_grit.svg" },
700− "_f_groovy": { "iconPath": "../../icons/file_type_groovy.svg" },
701− "_f_grunt": { "iconPath": "../../icons/file_type_grunt.svg" },
702− "_f_gulp": { "iconPath": "../../icons/file_type_gulp.svg" },
703− "_f_haml": { "iconPath": "../../icons/file_type_haml.svg" },
704− "_f_handlebars": { "iconPath": "../../icons/file_type_handlebars.svg" },
705− "_f_harbour": { "iconPath": "../../icons/file_type_harbour.svg" },
706− "_f_hardhat": { "iconPath": "../../icons/file_type_hardhat.svg" },
707− "_f_hashicorp": { "iconPath": "../../icons/file_type_hashicorp.svg" },
708− "_f_light_hashicorp": { "iconPath": "../../icons/file_type_light_hashicorp.svg" },
709− "_f_haskell": { "iconPath": "../../icons/file_type_haskell.svg" },
710− "_f_haxe": { "iconPath": "../../icons/file_type_haxe.svg" },
711− "_f_haxecheckstyle": { "iconPath": "../../icons/file_type_haxecheckstyle.svg" },
712− "_f_haxedevelop": { "iconPath": "../../icons/file_type_haxedevelop.svg" },
713− "_f_helix": { "iconPath": "../../icons/file_type_helix.svg" },
714− "_f_helm": { "iconPath": "../../icons/file_type_helm.svg" },
715− "_f_histoire": { "iconPath": "../../icons/file_type_histoire.svg" },
716− "_f_hjson": { "iconPath": "../../icons/file_type_hjson.svg" },
717− "_f_light_hjson": { "iconPath": "../../icons/file_type_light_hjson.svg" },
718− "_f_hlsl": { "iconPath": "../../icons/file_type_hlsl.svg" },
719− "_f_homeassistant": { "iconPath": "../../icons/file_type_homeassistant.svg" },
720− "_f_horusec": { "iconPath": "../../icons/file_type_horusec.svg" },
721− "_f_host": { "iconPath": "../../icons/file_type_host.svg" },
722− "_f_html": { "iconPath": "../../icons/file_type_html.svg" },
723− "_f_htmlhint": { "iconPath": "../../icons/file_type_htmlhint.svg" },
724− "_f_htmlvalidate": { "iconPath": "../../icons/file_type_htmlvalidate.svg" },
725− "_f_http": { "iconPath": "../../icons/file_type_http.svg" },
726− "_f_hugo": { "iconPath": "../../icons/file_type_hugo.svg" },
727− "_f_humanstxt": { "iconPath": "../../icons/file_type_humanstxt.svg" },
728− "_f_hunspell": { "iconPath": "../../icons/file_type_hunspell.svg" },
729− "_f_husky": { "iconPath": "../../icons/file_type_husky.svg" },
730− "_f_hy": { "iconPath": "../../icons/file_type_hy.svg" },
731− "_f_hygen": { "iconPath": "../../icons/file_type_hygen.svg" },
732− "_f_hypr": { "iconPath": "../../icons/file_type_hypr.svg" },
733− "_f_icl": { "iconPath": "../../icons/file_type_icl.svg" },
734− "_f_idris": { "iconPath": "../../icons/file_type_idris.svg" },
735− "_f_idrisbin": { "iconPath": "../../icons/file_type_idrisbin.svg" },
736− "_f_idrispkg": { "iconPath": "../../icons/file_type_idrispkg.svg" },
737− "_f_image": { "iconPath": "../../icons/file_type_image.svg" },
738− "_f_imba": { "iconPath": "../../icons/file_type_imba.svg" },
739− "_f_inc": { "iconPath": "../../icons/file_type_inc.svg" },
740− "_f_infopath": { "iconPath": "../../icons/file_type_infopath.svg" },
741− "_f_informix": { "iconPath": "../../icons/file_type_informix.svg" },
742− "_f_ini": { "iconPath": "../../icons/file_type_ini.svg" },
743− "_f_light_ini": { "iconPath": "../../icons/file_type_light_ini.svg" },
744− "_f_ink": { "iconPath": "../../icons/file_type_ink.svg" },
745− "_f_innosetup": { "iconPath": "../../icons/file_type_innosetup.svg" },
746− "_f_io": { "iconPath": "../../icons/file_type_io.svg" },
747− "_f_light_io": { "iconPath": "../../icons/file_type_light_io.svg" },
748− "_f_iodine": { "iconPath": "../../icons/file_type_iodine.svg" },
749− "_f_ionic": { "iconPath": "../../icons/file_type_ionic.svg" },
750− "_f_jake": { "iconPath": "../../icons/file_type_jake.svg" },
751− "_f_janet": { "iconPath": "../../icons/file_type_janet.svg" },
752− "_f_jar": { "iconPath": "../../icons/file_type_jar.svg" },
753− "_f_jasmine": { "iconPath": "../../icons/file_type_jasmine.svg" },
754− "_f_java": { "iconPath": "../../icons/file_type_java.svg" },
755− "_f_jbuilder": { "iconPath": "../../icons/file_type_jbuilder.svg" },
756− "_f_jekyll": { "iconPath": "../../icons/file_type_jekyll.svg" },
757− "_f_jenkins": { "iconPath": "../../icons/file_type_jenkins.svg" },
758− "_f_jest": { "iconPath": "../../icons/file_type_jest.svg" },
759− "_f_jest_snapshot": { "iconPath": "../../icons/file_type_jest_snapshot.svg" },
760− "_f_jetbrains": { "iconPath": "../../icons/file_type_jetbrains.svg" },
761− "_f_jinja": { "iconPath": "../../icons/file_type_jinja.svg" },
762− "_f_jpm": { "iconPath": "../../icons/file_type_jpm.svg" },
763− "_f_js": { "iconPath": "../../icons/file_type_js.svg" },
764− "_f_light_js": { "iconPath": "../../icons/file_type_light_js.svg" },
765− "_f_jsbeautify": { "iconPath": "../../icons/file_type_jsbeautify.svg" },
766− "_f_jsconfig": { "iconPath": "../../icons/file_type_jsconfig.svg" },
767− "_f_light_jsconfig": { "iconPath": "../../icons/file_type_light_jsconfig.svg" },
768− "_f_jscpd": { "iconPath": "../../icons/file_type_jscpd.svg" },
769− "_f_jshint": { "iconPath": "../../icons/file_type_jshint.svg" },
770− "_f_jsmap": { "iconPath": "../../icons/file_type_jsmap.svg" },
771− "_f_light_jsmap": { "iconPath": "../../icons/file_type_light_jsmap.svg" },
772− "_f_json": { "iconPath": "../../icons/file_type_json.svg" },
773− "_f_light_json": { "iconPath": "../../icons/file_type_light_json.svg" },
774− "_f_json5": { "iconPath": "../../icons/file_type_json5.svg" },
775− "_f_light_json5": { "iconPath": "../../icons/file_type_light_json5.svg" },
776− "_f_json_schema": { "iconPath": "../../icons/file_type_json_schema.svg" },
777− "_f_light_json_schema": { "iconPath": "../../icons/file_type_light_json_schema.svg" },
778− "_f_jsonld": { "iconPath": "../../icons/file_type_jsonld.svg" },
779− "_f_light_jsonld": { "iconPath": "../../icons/file_type_light_jsonld.svg" },
780− "_f_jsonnet": { "iconPath": "../../icons/file_type_jsonnet.svg" },
781− "_f_jsp": { "iconPath": "../../icons/file_type_jsp.svg" },
782− "_f_jsr": { "iconPath": "../../icons/file_type_jsr.svg" },
783− "_f_jss": { "iconPath": "../../icons/file_type_jss.svg" },
784− "_f_juice": { "iconPath": "../../icons/file_type_juice.svg" },
785− "_f_julia": { "iconPath": "../../icons/file_type_julia.svg" },
786− "_f_jupyter": { "iconPath": "../../icons/file_type_jupyter.svg" },
787− "_f_just": { "iconPath": "../../icons/file_type_just.svg" },
788− "_f_k": { "iconPath": "../../icons/file_type_k.svg" },
789− "_f_karma": { "iconPath": "../../icons/file_type_karma.svg" },
790− "_f_key": { "iconPath": "../../icons/file_type_key.svg" },
791− "_f_kitchenci": { "iconPath": "../../icons/file_type_kitchenci.svg" },
792− "_f_kite": { "iconPath": "../../icons/file_type_kite.svg" },
793− "_f_light_kite": { "iconPath": "../../icons/file_type_light_kite.svg" },
794− "_f_kivy": { "iconPath": "../../icons/file_type_kivy.svg" },
795− "_f_knip": { "iconPath": "../../icons/file_type_knip.svg" },
796− "_f_kos": { "iconPath": "../../icons/file_type_kos.svg" },
797− "_f_kotlin": { "iconPath": "../../icons/file_type_kotlin.svg" },
798− "_f_kusto": { "iconPath": "../../icons/file_type_kusto.svg" },
799− "_f_language_configuration": { "iconPath": "../../icons/file_type_language_configuration.svg" },
800− "_f_lark": { "iconPath": "../../icons/file_type_lark.svg" },
801− "_f_light_lark": { "iconPath": "../../icons/file_type_light_lark.svg" },
802− "_f_latino": { "iconPath": "../../icons/file_type_latino.svg" },
803− "_f_layout": { "iconPath": "../../icons/file_type_layout.svg" },
804− "_f_lean": { "iconPath": "../../icons/file_type_lean.svg" },
805− "_f_light_lean": { "iconPath": "../../icons/file_type_light_lean.svg" },
806− "_f_leanconfig": { "iconPath": "../../icons/file_type_leanconfig.svg" },
807− "_f_light_leanconfig": { "iconPath": "../../icons/file_type_light_leanconfig.svg" },
808− "_f_lefthook": { "iconPath": "../../icons/file_type_lefthook.svg" },
809− "_f_lerna": { "iconPath": "../../icons/file_type_lerna.svg" },
810− "_f_light_lerna": { "iconPath": "../../icons/file_type_light_lerna.svg" },
811− "_f_less": { "iconPath": "../../icons/file_type_less.svg" },
812− "_f_lex": { "iconPath": "../../icons/file_type_lex.svg" },
813− "_f_liara": { "iconPath": "../../icons/file_type_liara.svg" },
814− "_f_libreoffice_base": { "iconPath": "../../icons/file_type_libreoffice_base.svg" },
815− "_f_libreoffice_calc": { "iconPath": "../../icons/file_type_libreoffice_calc.svg" },
816− "_f_libreoffice_draw": { "iconPath": "../../icons/file_type_libreoffice_draw.svg" },
817− "_f_libreoffice_impress": { "iconPath": "../../icons/file_type_libreoffice_impress.svg" },
818− "_f_libreoffice_math": { "iconPath": "../../icons/file_type_libreoffice_math.svg" },
819− "_f_libreoffice_writer": { "iconPath": "../../icons/file_type_libreoffice_writer.svg" },
820− "_f_license": { "iconPath": "../../icons/file_type_license.svg" },
821− "_f_licensebat": { "iconPath": "../../icons/file_type_licensebat.svg" },
822− "_f_lighthouse": { "iconPath": "../../icons/file_type_lighthouse.svg" },
823− "_f_lilypond": { "iconPath": "../../icons/file_type_lilypond.svg" },
824− "_f_lime": { "iconPath": "../../icons/file_type_lime.svg" },
825− "_f_lintstagedrc": { "iconPath": "../../icons/file_type_lintstagedrc.svg" },
826− "_f_liquid": { "iconPath": "../../icons/file_type_liquid.svg" },
827− "_f_lisp": { "iconPath": "../../icons/file_type_lisp.svg" },
828− "_f_livescript": { "iconPath": "../../icons/file_type_livescript.svg" },
829− "_f_lnk": { "iconPath": "../../icons/file_type_lnk.svg" },
830− "_f_locale": { "iconPath": "../../icons/file_type_locale.svg" },
831− "_f_log": { "iconPath": "../../icons/file_type_log.svg" },
832− "_f_lolcode": { "iconPath": "../../icons/file_type_lolcode.svg" },
833− "_f_lsl": { "iconPath": "../../icons/file_type_lsl.svg" },
834− "_f_lua": { "iconPath": "../../icons/file_type_lua.svg" },
835− "_f_luau": { "iconPath": "../../icons/file_type_luau.svg" },
836− "_f_lync": { "iconPath": "../../icons/file_type_lync.svg" },
837− "_f_mailing": { "iconPath": "../../icons/file_type_mailing.svg" },
838− "_f_light_mailing": { "iconPath": "../../icons/file_type_light_mailing.svg" },
839− "_f_manifest": { "iconPath": "../../icons/file_type_manifest.svg" },
840− "_f_manifest_bak": { "iconPath": "../../icons/file_type_manifest_bak.svg" },
841− "_f_manifest_skip": { "iconPath": "../../icons/file_type_manifest_skip.svg" },
842− "_f_map": { "iconPath": "../../icons/file_type_map.svg" },
843− "_f_markdown": { "iconPath": "../../icons/file_type_markdown.svg" },
844− "_f_markdownlint": { "iconPath": "../../icons/file_type_markdownlint.svg" },
845− "_f_markdownlint_ignore": { "iconPath": "../../icons/file_type_markdownlint_ignore.svg" },
846− "_f_marko": { "iconPath": "../../icons/file_type_marko.svg" },
847− "_f_markojs": { "iconPath": "../../icons/file_type_markojs.svg" },
848− "_f_markuplint": { "iconPath": "../../icons/file_type_markuplint.svg" },
849− "_f_light_markuplint": { "iconPath": "../../icons/file_type_light_markuplint.svg" },
850− "_f_master-co": { "iconPath": "../../icons/file_type_master-co.svg" },
851− "_f_matlab": { "iconPath": "../../icons/file_type_matlab.svg" },
852− "_f_maven": { "iconPath": "../../icons/file_type_maven.svg" },
853− "_f_maxscript": { "iconPath": "../../icons/file_type_maxscript.svg" },
854− "_f_maya": { "iconPath": "../../icons/file_type_maya.svg" },
855− "_f_mcp": { "iconPath": "../../icons/file_type_mcp.svg" },
856− "_f_light_mcp": { "iconPath": "../../icons/file_type_light_mcp.svg" },
857− "_f_mdx": { "iconPath": "../../icons/file_type_mdx.svg" },
858− "_f_light_mdx": { "iconPath": "../../icons/file_type_light_mdx.svg" },
859− "_f_mdx-components": { "iconPath": "../../icons/file_type_mdx-components.svg" },
860− "_f_light_mdx-components": { "iconPath": "../../icons/file_type_light_mdx-components.svg" },
861− "_f_mdxlint": { "iconPath": "../../icons/file_type_mdxlint.svg" },
862− "_f_mediawiki": { "iconPath": "../../icons/file_type_mediawiki.svg" },
863− "_f_mercurial": { "iconPath": "../../icons/file_type_mercurial.svg" },
864− "_f_mermaid": { "iconPath": "../../icons/file_type_mermaid.svg" },
865− "_f_meson": { "iconPath": "../../icons/file_type_meson.svg" },
866− "_f_metal": { "iconPath": "../../icons/file_type_metal.svg" },
867− "_f_meteor": { "iconPath": "../../icons/file_type_meteor.svg" },
868− "_f_minecraft": { "iconPath": "../../icons/file_type_minecraft.svg" },
869− "_f_mivascript": { "iconPath": "../../icons/file_type_mivascript.svg" },
870− "_f_mjml": { "iconPath": "../../icons/file_type_mjml.svg" },
871− "_f_mlang": { "iconPath": "../../icons/file_type_mlang.svg" },
872− "_f_light_mlang": { "iconPath": "../../icons/file_type_light_mlang.svg" },
873− "_f_mocha": { "iconPath": "../../icons/file_type_mocha.svg" },
874− "_f_modernizr": { "iconPath": "../../icons/file_type_modernizr.svg" },
875− "_f_mojo": { "iconPath": "../../icons/file_type_mojo.svg" },
876− "_f_mojolicious": { "iconPath": "../../icons/file_type_mojolicious.svg" },
877− "_f_moleculer": { "iconPath": "../../icons/file_type_moleculer.svg" },
878− "_f_mondoo": { "iconPath": "../../icons/file_type_mondoo.svg" },
879− "_f_mongo": { "iconPath": "../../icons/file_type_mongo.svg" },
880− "_f_monotone": { "iconPath": "../../icons/file_type_monotone.svg" },
881− "_f_motif": { "iconPath": "../../icons/file_type_motif.svg" },
882− "_f_mson": { "iconPath": "../../icons/file_type_mson.svg" },
883− "_f_mustache": { "iconPath": "../../icons/file_type_mustache.svg" },
884− "_f_light_mustache": { "iconPath": "../../icons/file_type_light_mustache.svg" },
885− "_f_mvt": { "iconPath": "../../icons/file_type_mvt.svg" },
886− "_f_mvtcss": { "iconPath": "../../icons/file_type_mvtcss.svg" },
887− "_f_mvtjs": { "iconPath": "../../icons/file_type_mvtjs.svg" },
888− "_f_mypy": { "iconPath": "../../icons/file_type_mypy.svg" },
889− "_f_light_mypy": { "iconPath": "../../icons/file_type_light_mypy.svg" },
890− "_f_nanostaged": { "iconPath": "../../icons/file_type_nanostaged.svg" },
891− "_f_ndst": { "iconPath": "../../icons/file_type_ndst.svg" },
892− "_f_nearly": { "iconPath": "../../icons/file_type_nearly.svg" },
893− "_f_neo4j": { "iconPath": "../../icons/file_type_neo4j.svg" },
894− "_f_light_neo4j": { "iconPath": "../../icons/file_type_light_neo4j.svg" },
895− "_f_nestjs": { "iconPath": "../../icons/file_type_nestjs.svg" },
896− "_f_netlify": { "iconPath": "../../icons/file_type_netlify.svg" },
897− "_f_light_netlify": { "iconPath": "../../icons/file_type_light_netlify.svg" },
898− "_f_next": { "iconPath": "../../icons/file_type_next.svg" },
899− "_f_light_next": { "iconPath": "../../icons/file_type_light_next.svg" },
900− "_f_nextflow": { "iconPath": "../../icons/file_type_nextflow.svg" },
901− "_f_ng_tailwind": { "iconPath": "../../icons/file_type_ng_tailwind.svg" },
902− "_f_nginx": { "iconPath": "../../icons/file_type_nginx.svg" },
903− "_f_nim": { "iconPath": "../../icons/file_type_nim.svg" },
904− "_f_nimble": { "iconPath": "../../icons/file_type_nimble.svg" },
905− "_f_ninja": { "iconPath": "../../icons/file_type_ninja.svg" },
906− "_f_nix": { "iconPath": "../../icons/file_type_nix.svg" },
907− "_f_njsproj": { "iconPath": "../../icons/file_type_njsproj.svg" },
908− "_f_noc": { "iconPath": "../../icons/file_type_noc.svg" },
909− "_f_node": { "iconPath": "../../icons/file_type_node.svg" },
910− "_f_nodemon": { "iconPath": "../../icons/file_type_nodemon.svg" },
911− "_f_npm": { "iconPath": "../../icons/file_type_npm.svg" },
912− "_f_npmpackagejsonlint": { "iconPath": "../../icons/file_type_npmpackagejsonlint.svg" },
913− "_f_nsi": { "iconPath": "../../icons/file_type_nsi.svg" },
914− "_f_nsri": { "iconPath": "../../icons/file_type_nsri.svg" },
915− "_f_nsri-integrity": { "iconPath": "../../icons/file_type_nsri-integrity.svg" },
916− "_f_nuget": { "iconPath": "../../icons/file_type_nuget.svg" },
917− "_f_numpy": { "iconPath": "../../icons/file_type_numpy.svg" },
918− "_f_nunjucks": { "iconPath": "../../icons/file_type_nunjucks.svg" },
919− "_f_nushell": { "iconPath": "../../icons/file_type_nushell.svg" },
920− "_f_nuxt": { "iconPath": "../../icons/file_type_nuxt.svg" },
921− "_f_nx": { "iconPath": "../../icons/file_type_nx.svg" },
922− "_f_light_nx": { "iconPath": "../../icons/file_type_light_nx.svg" },
923− "_f_nyc": { "iconPath": "../../icons/file_type_nyc.svg" },
924− "_f_objectivec": { "iconPath": "../../icons/file_type_objectivec.svg" },
925− "_f_objectivecpp": { "iconPath": "../../icons/file_type_objectivecpp.svg" },
926− "_f_objidconfig": { "iconPath": "../../icons/file_type_objidconfig.svg" },
927− "_f_light_objidconfig": { "iconPath": "../../icons/file_type_light_objidconfig.svg" },
928− "_f_ocaml": { "iconPath": "../../icons/file_type_ocaml.svg" },
929− "_f_ocaml_intf": { "iconPath": "../../icons/file_type_ocaml_intf.svg" },
930− "_f_ogone": { "iconPath": "../../icons/file_type_ogone.svg" },
931− "_f_onenote": { "iconPath": "../../icons/file_type_onenote.svg" },
932− "_f_opam": { "iconPath": "../../icons/file_type_opam.svg" },
933− "_f_openHAB": { "iconPath": "../../icons/file_type_openHAB.svg" },
934− "_f_light_openHAB": { "iconPath": "../../icons/file_type_light_openHAB.svg" },
935− "_f_opencl": { "iconPath": "../../icons/file_type_opencl.svg" },
936− "_f_openscad": { "iconPath": "../../icons/file_type_openscad.svg" },
937− "_f_opentofu": { "iconPath": "../../icons/file_type_opentofu.svg" },
938− "_f_org": { "iconPath": "../../icons/file_type_org.svg" },
939− "_f_outlook": { "iconPath": "../../icons/file_type_outlook.svg" },
940− "_f_ovpn": { "iconPath": "../../icons/file_type_ovpn.svg" },
941− "_f_oxc": { "iconPath": "../../icons/file_type_oxc.svg" },
942− "_f_light_oxc": { "iconPath": "../../icons/file_type_light_oxc.svg" },
943− "_f_package": { "iconPath": "../../icons/file_type_package.svg" },
944− "_f_packship": { "iconPath": "../../icons/file_type_packship.svg" },
945− "_f_light_packship": { "iconPath": "../../icons/file_type_light_packship.svg" },
946− "_f_paket": { "iconPath": "../../icons/file_type_paket.svg" },
947− "_f_pandacss": { "iconPath": "../../icons/file_type_pandacss.svg" },
948− "_f_patch": { "iconPath": "../../icons/file_type_patch.svg" },
949− "_f_pcl": { "iconPath": "../../icons/file_type_pcl.svg" },
950− "_f_light_pcl": { "iconPath": "../../icons/file_type_light_pcl.svg" },
951− "_f_pddl": { "iconPath": "../../icons/file_type_pddl.svg" },
952− "_f_pddl_happenings": { "iconPath": "../../icons/file_type_pddl_happenings.svg" },
953− "_f_pddl_plan": { "iconPath": "../../icons/file_type_pddl_plan.svg" },
954− "_f_pdf": { "iconPath": "../../icons/file_type_pdf.svg" },
955− "_f_pdm": { "iconPath": "../../icons/file_type_pdm.svg" },
956− "_f_peeky": { "iconPath": "../../icons/file_type_peeky.svg" },
957− "_f_perl": { "iconPath": "../../icons/file_type_perl.svg" },
958− "_f_perl6": { "iconPath": "../../icons/file_type_perl6.svg" },
959− "_f_pgsql": { "iconPath": "../../icons/file_type_pgsql.svg" },
960− "_f_photoshop": { "iconPath": "../../icons/file_type_photoshop.svg" },
961− "_f_php": { "iconPath": "../../icons/file_type_php.svg" },
962− "_f_phpcsfixer": { "iconPath": "../../icons/file_type_phpcsfixer.svg" },
963− "_f_phpstan": { "iconPath": "../../icons/file_type_phpstan.svg" },
964− "_f_phpunit": { "iconPath": "../../icons/file_type_phpunit.svg" },
965− "_f_phraseapp": { "iconPath": "../../icons/file_type_phraseapp.svg" },
966− "_f_pine": { "iconPath": "../../icons/file_type_pine.svg" },
967− "_f_pip": { "iconPath": "../../icons/file_type_pip.svg" },
968− "_f_pipeline": { "iconPath": "../../icons/file_type_pipeline.svg" },
969− "_f_plantuml": { "iconPath": "../../icons/file_type_plantuml.svg" },
970− "_f_platformio": { "iconPath": "../../icons/file_type_platformio.svg" },
971− "_f_playwright": { "iconPath": "../../icons/file_type_playwright.svg" },
972− "_f_plsql": { "iconPath": "../../icons/file_type_plsql.svg" },
973− "_f_plsql_package": { "iconPath": "../../icons/file_type_plsql_package.svg" },
974− "_f_plsql_package_body": { "iconPath": "../../icons/file_type_plsql_package_body.svg" },
975− "_f_plsql_package_header": { "iconPath": "../../icons/file_type_plsql_package_header.svg" },
976− "_f_plsql_package_spec": { "iconPath": "../../icons/file_type_plsql_package_spec.svg" },
977− "_f_pm2": { "iconPath": "../../icons/file_type_pm2.svg" },
978− "_f_pnpm": { "iconPath": "../../icons/file_type_pnpm.svg" },
979− "_f_light_pnpm": { "iconPath": "../../icons/file_type_light_pnpm.svg" },
980− "_f_poedit": { "iconPath": "../../icons/file_type_poedit.svg" },
981− "_f_poetry": { "iconPath": "../../icons/file_type_poetry.svg" },
982− "_f_polyglot": { "iconPath": "../../icons/file_type_polyglot.svg" },
983− "_f_polymer": { "iconPath": "../../icons/file_type_polymer.svg" },
984− "_f_pony": { "iconPath": "../../icons/file_type_pony.svg" },
985− "_f_postcss": { "iconPath": "../../icons/file_type_postcss.svg" },
986− "_f_postcssconfig": { "iconPath": "../../icons/file_type_postcssconfig.svg" },
987− "_f_postman": { "iconPath": "../../icons/file_type_postman.svg" },
988− "_f_postscript": { "iconPath": "../../icons/file_type_postscript.svg" },
989− "_f_powerpoint": { "iconPath": "../../icons/file_type_powerpoint.svg" },
990− "_f_powershell": { "iconPath": "../../icons/file_type_powershell.svg" },
991− "_f_powershell_format": { "iconPath": "../../icons/file_type_powershell_format.svg" },
992− "_f_powershell_psd": { "iconPath": "../../icons/file_type_powershell_psd.svg" },
993− "_f_powershell_psm": { "iconPath": "../../icons/file_type_powershell_psm.svg" },
994− "_f_powershell_types": { "iconPath": "../../icons/file_type_powershell_types.svg" },
995− "_f_preact": { "iconPath": "../../icons/file_type_preact.svg" },
996− "_f_precommit": { "iconPath": "../../icons/file_type_precommit.svg" },
997− "_f_prettier": { "iconPath": "../../icons/file_type_prettier.svg" },
998− "_f_light_prettier": { "iconPath": "../../icons/file_type_light_prettier.svg" },
999− "_f_prisma": { "iconPath": "../../icons/file_type_prisma.svg" },
1000− "_f_light_prisma": { "iconPath": "../../icons/file_type_light_prisma.svg" },
1001− "_f_prismaconfig": { "iconPath": "../../icons/file_type_prismaconfig.svg" },
1002− "_f_processinglang": { "iconPath": "../../icons/file_type_processinglang.svg" },
1003− "_f_procfile": { "iconPath": "../../icons/file_type_procfile.svg" },
1004− "_f_progress": { "iconPath": "../../icons/file_type_progress.svg" },
1005− "_f_prolog": { "iconPath": "../../icons/file_type_prolog.svg" },
1006− "_f_prometheus": { "iconPath": "../../icons/file_type_prometheus.svg" },
1007− "_f_protobuf": { "iconPath": "../../icons/file_type_protobuf.svg" },
1008− "_f_protractor": { "iconPath": "../../icons/file_type_protractor.svg" },
1009− "_f_publiccode": { "iconPath": "../../icons/file_type_publiccode.svg" },
1010− "_f_publisher": { "iconPath": "../../icons/file_type_publisher.svg" },
1011− "_f_pug": { "iconPath": "../../icons/file_type_pug.svg" },
1012− "_f_pulumi": { "iconPath": "../../icons/file_type_pulumi.svg" },
1013− "_f_puppet": { "iconPath": "../../icons/file_type_puppet.svg" },
1014− "_f_purescript": { "iconPath": "../../icons/file_type_purescript.svg" },
1015− "_f_light_purescript": { "iconPath": "../../icons/file_type_light_purescript.svg" },
1016− "_f_purgecss": { "iconPath": "../../icons/file_type_purgecss.svg" },
1017− "_f_pyenv": { "iconPath": "../../icons/file_type_pyenv.svg" },
1018− "_f_pypi": { "iconPath": "../../icons/file_type_pypi.svg" },
1019− "_f_pyret": { "iconPath": "../../icons/file_type_pyret.svg" },
1020− "_f_pyscript": { "iconPath": "../../icons/file_type_pyscript.svg" },
1021− "_f_pytest": { "iconPath": "../../icons/file_type_pytest.svg" },
1022− "_f_python": { "iconPath": "../../icons/file_type_python.svg" },
1023− "_f_pythowo": { "iconPath": "../../icons/file_type_pythowo.svg" },
1024− "_f_pytyped": { "iconPath": "../../icons/file_type_pytyped.svg" },
1025− "_f_pyup": { "iconPath": "../../icons/file_type_pyup.svg" },
1026− "_f_q": { "iconPath": "../../icons/file_type_q.svg" },
1027− "_f_qbs": { "iconPath": "../../icons/file_type_qbs.svg" },
1028− "_f_qlikview": { "iconPath": "../../icons/file_type_qlikview.svg" },
1029− "_f_qml": { "iconPath": "../../icons/file_type_qml.svg" },
1030− "_f_qmldir": { "iconPath": "../../icons/file_type_qmldir.svg" },
1031− "_f_qsharp": { "iconPath": "../../icons/file_type_qsharp.svg" },
1032− "_f_quasar": { "iconPath": "../../icons/file_type_quasar.svg" },
1033− "_f_light_quasar": { "iconPath": "../../icons/file_type_light_quasar.svg" },
1034− "_f_r": { "iconPath": "../../icons/file_type_r.svg" },
1035− "_f_ra_syntax_tree": { "iconPath": "../../icons/file_type_ra_syntax_tree.svg" },
1036− "_f_racket": { "iconPath": "../../icons/file_type_racket.svg" },
1037− "_f_rails": { "iconPath": "../../icons/file_type_rails.svg" },
1038− "_f_rake": { "iconPath": "../../icons/file_type_rake.svg" },
1039− "_f_raku": { "iconPath": "../../icons/file_type_raku.svg" },
1040− "_f_light_raku": { "iconPath": "../../icons/file_type_light_raku.svg" },
1041− "_f_raml": { "iconPath": "../../icons/file_type_raml.svg" },
1042− "_f_razor": { "iconPath": "../../icons/file_type_razor.svg" },
1043− "_f_razzle": { "iconPath": "../../icons/file_type_razzle.svg" },
1044− "_f_light_razzle": { "iconPath": "../../icons/file_type_light_razzle.svg" },
1045− "_f_reactjs": { "iconPath": "../../icons/file_type_reactjs.svg" },
1046− "_f_reactrouter": { "iconPath": "../../icons/file_type_reactrouter.svg" },
1047− "_f_light_reactrouter": { "iconPath": "../../icons/file_type_light_reactrouter.svg" },
1048− "_f_reacttemplate": { "iconPath": "../../icons/file_type_reacttemplate.svg" },
1049− "_f_reactts": { "iconPath": "../../icons/file_type_reactts.svg" },
1050− "_f_reason": { "iconPath": "../../icons/file_type_reason.svg" },
1051− "_f_red": { "iconPath": "../../icons/file_type_red.svg" },
1052− "_f_registry": { "iconPath": "../../icons/file_type_registry.svg" },
1053− "_f_rego": { "iconPath": "../../icons/file_type_rego.svg" },
1054− "_f_rehype": { "iconPath": "../../icons/file_type_rehype.svg" },
1055− "_f_light_rehype": { "iconPath": "../../icons/file_type_light_rehype.svg" },
1056− "_f_remark": { "iconPath": "../../icons/file_type_remark.svg" },
1057− "_f_light_remark": { "iconPath": "../../icons/file_type_light_remark.svg" },
1058− "_f_renovate": { "iconPath": "../../icons/file_type_renovate.svg" },
1059− "_f_replit": { "iconPath": "../../icons/file_type_replit.svg" },
1060− "_f_light_replit": { "iconPath": "../../icons/file_type_light_replit.svg" },
1061− "_f_rescript": { "iconPath": "../../icons/file_type_rescript.svg" },
1062− "_f_rest": { "iconPath": "../../icons/file_type_rest.svg" },
1063− "_f_retext": { "iconPath": "../../icons/file_type_retext.svg" },
1064− "_f_light_retext": { "iconPath": "../../icons/file_type_light_retext.svg" },
1065− "_f_rexx": { "iconPath": "../../icons/file_type_rexx.svg" },
1066− "_f_riot": { "iconPath": "../../icons/file_type_riot.svg" },
1067− "_f_ripple": { "iconPath": "../../icons/file_type_ripple.svg" },
1068− "_f_rmd": { "iconPath": "../../icons/file_type_rmd.svg" },
1069− "_f_rnc": { "iconPath": "../../icons/file_type_rnc.svg" },
1070− "_f_robotframework": { "iconPath": "../../icons/file_type_robotframework.svg" },
1071− "_f_robots": { "iconPath": "../../icons/file_type_robots.svg" },
1072− "_f_rolldown": { "iconPath": "../../icons/file_type_rolldown.svg" },
1073− "_f_light_rolldown": { "iconPath": "../../icons/file_type_light_rolldown.svg" },
1074− "_f_rollup": { "iconPath": "../../icons/file_type_rollup.svg" },
1075− "_f_rome": { "iconPath": "../../icons/file_type_rome.svg" },
1076− "_f_light_rome": { "iconPath": "../../icons/file_type_light_rome.svg" },
1077− "_f_ron": { "iconPath": "../../icons/file_type_ron.svg" },
1078− "_f_rproj": { "iconPath": "../../icons/file_type_rproj.svg" },
1079− "_f_rspec": { "iconPath": "../../icons/file_type_rspec.svg" },
1080− "_f_rss": { "iconPath": "../../icons/file_type_rss.svg" },
1081− "_f_rubocop": { "iconPath": "../../icons/file_type_rubocop.svg" },
1082− "_f_light_rubocop": { "iconPath": "../../icons/file_type_light_rubocop.svg" },
1083− "_f_ruby": { "iconPath": "../../icons/file_type_ruby.svg" },
1084− "_f_rust": { "iconPath": "../../icons/file_type_rust.svg" },
1085− "_f_light_rust": { "iconPath": "../../icons/file_type_light_rust.svg" },
1086− "_f_rust_toolchain": { "iconPath": "../../icons/file_type_rust_toolchain.svg" },
1087− "_f_light_rust_toolchain": { "iconPath": "../../icons/file_type_light_rust_toolchain.svg" },
1088− "_f_s-lang": { "iconPath": "../../icons/file_type_s-lang.svg" },
1089− "_f_safetensors": { "iconPath": "../../icons/file_type_safetensors.svg" },
1090− "_f_light_safetensors": { "iconPath": "../../icons/file_type_light_safetensors.svg" },
1091− "_f_sails": { "iconPath": "../../icons/file_type_sails.svg" },
1092− "_f_saltstack": { "iconPath": "../../icons/file_type_saltstack.svg" },
1093− "_f_san": { "iconPath": "../../icons/file_type_san.svg" },
1094− "_f_sapphire_framework_cli": { "iconPath": "../../icons/file_type_sapphire_framework_cli.svg" },
1095− "_f_sas": { "iconPath": "../../icons/file_type_sas.svg" },
1096− "_f_sass": { "iconPath": "../../icons/file_type_sass.svg" },
1097− "_f_sbt": { "iconPath": "../../icons/file_type_sbt.svg" },
1098− "_f_scala": { "iconPath": "../../icons/file_type_scala.svg" },
1099− "_f_scilab": { "iconPath": "../../icons/file_type_scilab.svg" },
1100− "_f_script": { "iconPath": "../../icons/file_type_script.svg" },
1101− "_f_scss": { "iconPath": "../../icons/file_type_scss.svg" },
1102− "_f_sdlang": { "iconPath": "../../icons/file_type_sdlang.svg" },
1103− "_f_search_result": { "iconPath": "../../icons/file_type_search_result.svg" },
1104− "_f_seedkit": { "iconPath": "../../icons/file_type_seedkit.svg" },
1105− "_f_sentry": { "iconPath": "../../icons/file_type_sentry.svg" },
1106− "_f_sequelize": { "iconPath": "../../icons/file_type_sequelize.svg" },
1107− "_f_serverless": { "iconPath": "../../icons/file_type_serverless.svg" },
1108− "_f_shadcn": { "iconPath": "../../icons/file_type_shadcn.svg" },
1109− "_f_light_shadcn": { "iconPath": "../../icons/file_type_light_shadcn.svg" },
1110− "_f_shaderlab": { "iconPath": "../../icons/file_type_shaderlab.svg" },
1111− "_f_light_shaderlab": { "iconPath": "../../icons/file_type_light_shaderlab.svg" },
1112− "_f_shell": { "iconPath": "../../icons/file_type_shell.svg" },
1113− "_f_shellcheck": { "iconPath": "../../icons/file_type_shellcheck.svg" },
1114− "_f_shuttle": { "iconPath": "../../icons/file_type_shuttle.svg" },
1115− "_f_silverstripe": { "iconPath": "../../icons/file_type_silverstripe.svg" },
1116− "_f_sino": { "iconPath": "../../icons/file_type_sino.svg" },
1117− "_f_sitemap": { "iconPath": "../../icons/file_type_sitemap.svg" },
1118− "_f_siyuan": { "iconPath": "../../icons/file_type_siyuan.svg" },
1119− "_f_sketch": { "iconPath": "../../icons/file_type_sketch.svg" },
1120− "_f_skipper": { "iconPath": "../../icons/file_type_skipper.svg" },
1121− "_f_slang": { "iconPath": "../../icons/file_type_slang.svg" },
1122− "_f_slashup": { "iconPath": "../../icons/file_type_slashup.svg" },
1123− "_f_slice": { "iconPath": "../../icons/file_type_slice.svg" },
1124− "_f_slim": { "iconPath": "../../icons/file_type_slim.svg" },
1125− "_f_slint": { "iconPath": "../../icons/file_type_slint.svg" },
1126− "_f_sln": { "iconPath": "../../icons/file_type_sln.svg" },
1127− "_f_smarty": { "iconPath": "../../icons/file_type_smarty.svg" },
1128− "_f_smithery": { "iconPath": "../../icons/file_type_smithery.svg" },
1129− "_f_snakemake": { "iconPath": "../../icons/file_type_snakemake.svg" },
1130− "_f_snapcraft": { "iconPath": "../../icons/file_type_snapcraft.svg" },
1131− "_f_snaplet": { "iconPath": "../../icons/file_type_snaplet.svg" },
1132− "_f_snort": { "iconPath": "../../icons/file_type_snort.svg" },
1133− "_f_snyk": { "iconPath": "../../icons/file_type_snyk.svg" },
1134− "_f_solidarity": { "iconPath": "../../icons/file_type_solidarity.svg" },
1135− "_f_solidity": { "iconPath": "../../icons/file_type_solidity.svg" },
1136− "_f_light_solidity": { "iconPath": "../../icons/file_type_light_solidity.svg" },
1137− "_f_source": { "iconPath": "../../icons/file_type_source.svg" },
1138− "_f_spacengine": { "iconPath": "../../icons/file_type_spacengine.svg" },
1139− "_f_sparql": { "iconPath": "../../icons/file_type_sparql.svg" },
1140− "_f_spin": { "iconPath": "../../icons/file_type_spin.svg" },
1141− "_f_light_spin": { "iconPath": "../../icons/file_type_light_spin.svg" },
1142− "_f_sqf": { "iconPath": "../../icons/file_type_sqf.svg" },
1143− "_f_sql": { "iconPath": "../../icons/file_type_sql.svg" },
1144− "_f_sqlite": { "iconPath": "../../icons/file_type_sqlite.svg" },
1145− "_f_squirrel": { "iconPath": "../../icons/file_type_squirrel.svg" },
1146− "_f_sss": { "iconPath": "../../icons/file_type_sss.svg" },
1147− "_f_sst": { "iconPath": "../../icons/file_type_sst.svg" },
1148− "_f_stackblitz": { "iconPath": "../../icons/file_type_stackblitz.svg" },
1149− "_f_stan": { "iconPath": "../../icons/file_type_stan.svg" },
1150− "_f_stata": { "iconPath": "../../icons/file_type_stata.svg" },
1151− "_f_stencil": { "iconPath": "../../icons/file_type_stencil.svg" },
1152− "_f_storyboard": { "iconPath": "../../icons/file_type_storyboard.svg" },
1153− "_f_storybook": { "iconPath": "../../icons/file_type_storybook.svg" },
1154− "_f_stryker": { "iconPath": "../../icons/file_type_stryker.svg" },
1155− "_f_stylable": { "iconPath": "../../icons/file_type_stylable.svg" },
1156− "_f_style": { "iconPath": "../../icons/file_type_style.svg" },
1157− "_f_styled": { "iconPath": "../../icons/file_type_styled.svg" },
1158− "_f_stylelint": { "iconPath": "../../icons/file_type_stylelint.svg" },
1159− "_f_light_stylelint": { "iconPath": "../../icons/file_type_light_stylelint.svg" },
1160− "_f_stylish_haskell": { "iconPath": "../../icons/file_type_stylish_haskell.svg" },
1161− "_f_stylus": { "iconPath": "../../icons/file_type_stylus.svg" },
1162− "_f_light_stylus": { "iconPath": "../../icons/file_type_light_stylus.svg" },
1163− "_f_sublime": { "iconPath": "../../icons/file_type_sublime.svg" },
1164− "_f_subversion": { "iconPath": "../../icons/file_type_subversion.svg" },
1165− "_f_svelte": { "iconPath": "../../icons/file_type_svelte.svg" },
1166− "_f_svelteconfig": { "iconPath": "../../icons/file_type_svelteconfig.svg" },
1167− "_f_svg": { "iconPath": "../../icons/file_type_svg.svg" },
1168− "_f_svgo": { "iconPath": "../../icons/file_type_svgo.svg" },
1169− "_f_swagger": { "iconPath": "../../icons/file_type_swagger.svg" },
1170− "_f_swc": { "iconPath": "../../icons/file_type_swc.svg" },
1171− "_f_swift": { "iconPath": "../../icons/file_type_swift.svg" },
1172− "_f_swig": { "iconPath": "../../icons/file_type_swig.svg" },
1173− "_f_symfony": { "iconPath": "../../icons/file_type_symfony.svg" },
1174− "_f_light_symfony": { "iconPath": "../../icons/file_type_light_symfony.svg" },
1175− "_f_syncpack": { "iconPath": "../../icons/file_type_syncpack.svg" },
1176− "_f_systemd": { "iconPath": "../../icons/file_type_systemd.svg" },
1177− "_f_light_systemd": { "iconPath": "../../icons/file_type_light_systemd.svg" },
1178− "_f_systemverilog": { "iconPath": "../../icons/file_type_systemverilog.svg" },
1179− "_f_light_systemverilog": { "iconPath": "../../icons/file_type_light_systemverilog.svg" },
1180− "_f_t4tt": { "iconPath": "../../icons/file_type_t4tt.svg" },
1181− "_f_tailwind": { "iconPath": "../../icons/file_type_tailwind.svg" },
1182− "_f_tamagui": { "iconPath": "../../icons/file_type_tamagui.svg" },
1183− "_f_taplo": { "iconPath": "../../icons/file_type_taplo.svg" },
1184− "_f_taskfile": { "iconPath": "../../icons/file_type_taskfile.svg" },
1185− "_f_tauri": { "iconPath": "../../icons/file_type_tauri.svg" },
1186− "_f_tcl": { "iconPath": "../../icons/file_type_tcl.svg" },
1187− "_f_teal": { "iconPath": "../../icons/file_type_teal.svg" },
1188− "_f_templ": { "iconPath": "../../icons/file_type_templ.svg" },
1189− "_f_tera": { "iconPath": "../../icons/file_type_tera.svg" },
1190− "_f_terraform": { "iconPath": "../../icons/file_type_terraform.svg" },
1191− "_f_test": { "iconPath": "../../icons/file_type_test.svg" },
1192− "_f_testcafe": { "iconPath": "../../icons/file_type_testcafe.svg" },
1193− "_f_light_testcafe": { "iconPath": "../../icons/file_type_light_testcafe.svg" },
1194− "_f_testjs": { "iconPath": "../../icons/file_type_testjs.svg" },
1195− "_f_light_testjs": { "iconPath": "../../icons/file_type_light_testjs.svg" },
1196− "_f_testplane": { "iconPath": "../../icons/file_type_testplane.svg" },
1197− "_f_testts": { "iconPath": "../../icons/file_type_testts.svg" },
1198− "_f_tex": { "iconPath": "../../icons/file_type_tex.svg" },
1199− "_f_light_tex": { "iconPath": "../../icons/file_type_light_tex.svg" },
1200− "_f_text": { "iconPath": "../../icons/file_type_text.svg" },
1201− "_f_textile": { "iconPath": "../../icons/file_type_textile.svg" },
1202− "_f_tfs": { "iconPath": "../../icons/file_type_tfs.svg" },
1203− "_f_tiltfile": { "iconPath": "../../icons/file_type_tiltfile.svg" },
1204− "_f_tm": { "iconPath": "../../icons/file_type_tm.svg" },
1205− "_f_light_tm": { "iconPath": "../../icons/file_type_light_tm.svg" },
1206− "_f_tmux": { "iconPath": "../../icons/file_type_tmux.svg" },
1207− "_f_light_tmux": { "iconPath": "../../icons/file_type_light_tmux.svg" },
1208− "_f_todo": { "iconPath": "../../icons/file_type_todo.svg" },
1209− "_f_light_todo": { "iconPath": "../../icons/file_type_light_todo.svg" },
1210− "_f_toit": { "iconPath": "../../icons/file_type_toit.svg" },
1211− "_f_light_toit": { "iconPath": "../../icons/file_type_light_toit.svg" },
1212− "_f_toml": { "iconPath": "../../icons/file_type_toml.svg" },
1213− "_f_light_toml": { "iconPath": "../../icons/file_type_light_toml.svg" },
1214− "_f_toon": { "iconPath": "../../icons/file_type_toon.svg" },
1215− "_f_light_toon": { "iconPath": "../../icons/file_type_light_toon.svg" },
1216− "_f_tox": { "iconPath": "../../icons/file_type_tox.svg" },
1217− "_f_travis": { "iconPath": "../../icons/file_type_travis.svg" },
1218− "_f_tree": { "iconPath": "../../icons/file_type_tree.svg" },
1219− "_f_light_tree": { "iconPath": "../../icons/file_type_light_tree.svg" },
1220− "_f_tres": { "iconPath": "../../icons/file_type_tres.svg" },
1221− "_f_truffle": { "iconPath": "../../icons/file_type_truffle.svg" },
1222− "_f_trunk": { "iconPath": "../../icons/file_type_trunk.svg" },
1223− "_f_tsbuildinfo": { "iconPath": "../../icons/file_type_tsbuildinfo.svg" },
1224− "_f_tscn": { "iconPath": "../../icons/file_type_tscn.svg" },
1225− "_f_tsconfig": { "iconPath": "../../icons/file_type_tsconfig.svg" },
1226− "_f_tsdoc": { "iconPath": "../../icons/file_type_tsdoc.svg" },
1227− "_f_tsdown": { "iconPath": "../../icons/file_type_tsdown.svg" },
1228− "_f_tslint": { "iconPath": "../../icons/file_type_tslint.svg" },
1229− "_f_tt": { "iconPath": "../../icons/file_type_tt.svg" },
1230− "_f_ttcn": { "iconPath": "../../icons/file_type_ttcn.svg" },
1231− "_f_tuc": { "iconPath": "../../icons/file_type_tuc.svg" },
1232− "_f_turbo": { "iconPath": "../../icons/file_type_turbo.svg" },
1233− "_f_light_turbo": { "iconPath": "../../icons/file_type_light_turbo.svg" },
1234− "_f_twig": { "iconPath": "../../icons/file_type_twig.svg" },
1235− "_f_typedoc": { "iconPath": "../../icons/file_type_typedoc.svg" },
1236− "_f_typescript": { "iconPath": "../../icons/file_type_typescript.svg" },
1237− "_f_typescriptdef": { "iconPath": "../../icons/file_type_typescriptdef.svg" },
1238− "_f_typo3": { "iconPath": "../../icons/file_type_typo3.svg" },
1239− "_f_uiua": { "iconPath": "../../icons/file_type_uiua.svg" },
1240− "_f_unibeautify": { "iconPath": "../../icons/file_type_unibeautify.svg" },
1241− "_f_light_unibeautify": { "iconPath": "../../icons/file_type_light_unibeautify.svg" },
1242− "_f_unison": { "iconPath": "../../icons/file_type_unison.svg" },
1243− "_f_unlicense": { "iconPath": "../../icons/file_type_unlicense.svg" },
1244− "_f_unocss": { "iconPath": "../../icons/file_type_unocss.svg" },
1245− "_f_uv": { "iconPath": "../../icons/file_type_uv.svg" },
1246− "_f_vagrant": { "iconPath": "../../icons/file_type_vagrant.svg" },
1247− "_f_vala": { "iconPath": "../../icons/file_type_vala.svg" },
1248− "_f_vanilla_extract": { "iconPath": "../../icons/file_type_vanilla_extract.svg" },
1249− "_f_vapi": { "iconPath": "../../icons/file_type_vapi.svg" },
1250− "_f_vapor": { "iconPath": "../../icons/file_type_vapor.svg" },
1251− "_f_vash": { "iconPath": "../../icons/file_type_vash.svg" },
1252− "_f_light_vash": { "iconPath": "../../icons/file_type_light_vash.svg" },
1253− "_f_vb": { "iconPath": "../../icons/file_type_vb.svg" },
1254− "_f_vba": { "iconPath": "../../icons/file_type_vba.svg" },
1255− "_f_vbhtml": { "iconPath": "../../icons/file_type_vbhtml.svg" },
1256− "_f_vbproj": { "iconPath": "../../icons/file_type_vbproj.svg" },
1257− "_f_vcxproj": { "iconPath": "../../icons/file_type_vcxproj.svg" },
1258− "_f_velocity": { "iconPath": "../../icons/file_type_velocity.svg" },
1259− "_f_vento": { "iconPath": "../../icons/file_type_vento.svg" },
1260− "_f_vercel": { "iconPath": "../../icons/file_type_vercel.svg" },
1261− "_f_light_vercel": { "iconPath": "../../icons/file_type_light_vercel.svg" },
1262− "_f_verilog": { "iconPath": "../../icons/file_type_verilog.svg" },
1263− "_f_vhdl": { "iconPath": "../../icons/file_type_vhdl.svg" },
1264− "_f_video": { "iconPath": "../../icons/file_type_video.svg" },
1265− "_f_view": { "iconPath": "../../icons/file_type_view.svg" },
1266− "_f_vim": { "iconPath": "../../icons/file_type_vim.svg" },
1267− "_f_vite": { "iconPath": "../../icons/file_type_vite.svg" },
1268− "_f_light_vite": { "iconPath": "../../icons/file_type_light_vite.svg" },
1269− "_f_vitest": { "iconPath": "../../icons/file_type_vitest.svg" },
1270− "_f_light_vitest": { "iconPath": "../../icons/file_type_light_vitest.svg" },
1271− "_f_vlang": { "iconPath": "../../icons/file_type_vlang.svg" },
1272− "_f_volt": { "iconPath": "../../icons/file_type_volt.svg" },
1273− "_f_vroom": { "iconPath": "../../icons/file_type_vroom.svg" },
1274− "_f_vscode": { "iconPath": "../../icons/file_type_vscode.svg" },
1275− "_f_vscode_test": { "iconPath": "../../icons/file_type_vscode_test.svg" },
1276− "_f_vsix": { "iconPath": "../../icons/file_type_vsix.svg" },
1277− "_f_light_vsix": { "iconPath": "../../icons/file_type_light_vsix.svg" },
1278− "_f_vsixmanifest": { "iconPath": "../../icons/file_type_vsixmanifest.svg" },
1279− "_f_light_vsixmanifest": { "iconPath": "../../icons/file_type_light_vsixmanifest.svg" },
1280− "_f_vue": { "iconPath": "../../icons/file_type_vue.svg" },
1281− "_f_vueconfig": { "iconPath": "../../icons/file_type_vueconfig.svg" },
1282− "_f_vvvvvv": { "iconPath": "../../icons/file_type_vvvvvv.svg" },
1283− "_f_vyper": { "iconPath": "../../icons/file_type_vyper.svg" },
1284− "_f_wallaby": { "iconPath": "../../icons/file_type_wallaby.svg" },
1285− "_f_wally": { "iconPath": "../../icons/file_type_wally.svg" },
1286− "_f_wasm": { "iconPath": "../../icons/file_type_wasm.svg" },
1287− "_f_watchmanconfig": { "iconPath": "../../icons/file_type_watchmanconfig.svg" },
1288− "_f_wdio": { "iconPath": "../../icons/file_type_wdio.svg" },
1289− "_f_weblate": { "iconPath": "../../icons/file_type_weblate.svg" },
1290− "_f_webpack": { "iconPath": "../../icons/file_type_webpack.svg" },
1291− "_f_wenyan": { "iconPath": "../../icons/file_type_wenyan.svg" },
1292− "_f_wercker": { "iconPath": "../../icons/file_type_wercker.svg" },
1293− "_f_wgsl": { "iconPath": "../../icons/file_type_wgsl.svg" },
1294− "_f_wikitext": { "iconPath": "../../icons/file_type_wikitext.svg" },
1295− "_f_windi": { "iconPath": "../../icons/file_type_windi.svg" },
1296− "_f_wit": { "iconPath": "../../icons/file_type_wit.svg" },
1297− "_f_wolfram": { "iconPath": "../../icons/file_type_wolfram.svg" },
1298− "_f_word": { "iconPath": "../../icons/file_type_word.svg" },
1299− "_f_wpml": { "iconPath": "../../icons/file_type_wpml.svg" },
1300− "_f_wurst": { "iconPath": "../../icons/file_type_wurst.svg" },
1301− "_f_wxml": { "iconPath": "../../icons/file_type_wxml.svg" },
1302− "_f_wxss": { "iconPath": "../../icons/file_type_wxss.svg" },
1303− "_f_wxt": { "iconPath": "../../icons/file_type_wxt.svg" },
1304− "_f_xaml": { "iconPath": "../../icons/file_type_xaml.svg" },
1305− "_f_xcode": { "iconPath": "../../icons/file_type_xcode.svg" },
1306− "_f_xfl": { "iconPath": "../../icons/file_type_xfl.svg" },
1307− "_f_light_xfl": { "iconPath": "../../icons/file_type_light_xfl.svg" },
1308− "_f_xib": { "iconPath": "../../icons/file_type_xib.svg" },
1309− "_f_xliff": { "iconPath": "../../icons/file_type_xliff.svg" },
1310− "_f_xmake": { "iconPath": "../../icons/file_type_xmake.svg" },
1311− "_f_xml": { "iconPath": "../../icons/file_type_xml.svg" },
1312− "_f_xo": { "iconPath": "../../icons/file_type_xo.svg" },
1313− "_f_xorg": { "iconPath": "../../icons/file_type_xorg.svg" },
1314− "_f_light_xorg": { "iconPath": "../../icons/file_type_light_xorg.svg" },
1315− "_f_xquery": { "iconPath": "../../icons/file_type_xquery.svg" },
1316− "_f_xsl": { "iconPath": "../../icons/file_type_xsl.svg" },
1317− "_f_yacc": { "iconPath": "../../icons/file_type_yacc.svg" },
1318− "_f_yaml": { "iconPath": "../../icons/file_type_yaml.svg" },
1319− "_f_light_yaml": { "iconPath": "../../icons/file_type_light_yaml.svg" },
1320− "_f_yamllint": { "iconPath": "../../icons/file_type_yamllint.svg" },
1321− "_f_yandex": { "iconPath": "../../icons/file_type_yandex.svg" },
1322− "_f_yang": { "iconPath": "../../icons/file_type_yang.svg" },
1323− "_f_yarn": { "iconPath": "../../icons/file_type_yarn.svg" },
1324− "_f_yeoman": { "iconPath": "../../icons/file_type_yeoman.svg" },
1325− "_f_zig": { "iconPath": "../../icons/file_type_zig.svg" },
1326− "_f_zip": { "iconPath": "../../icons/file_type_zip.svg" }
1327− },
1328− "file": "_file",
1329− "folder": "_folder",
1330− "folderExpanded": "_folder_open",
1331− "rootFolder": "_root_folder",
1332− "rootFolderExpanded": "_root_folder_open",
1333− "folderNames": {
1334− "android": "_fd_android",
1335− ".angular": "_fd_angular",
1336− "apache": "_fd_apache",
1337− "apache2": "_fd_apache",
1338− "httpd": "_fd_apache",
1339− "api": "_fd_api",
1340− ".api": "_fd_api",
1341− "apis": "_fd_api",
1342− ".apis": "_fd_api",
1343− "app": "_fd_app",
1344− "apps": "_fd_app",
1345− ".app": "_fd_app",
1346− "application": "_fd_app",
1347− "applications": "_fd_app",
1348− "arangodb": "_fd_arangodb",
1349− "arango": "_fd_arangodb",
1350− "assets": "_fd_asset",
1351− ".assets": "_fd_asset",
1352− ".astro": "_fd_astro",
1353− "audio": "_fd_audio",
1354− ".audio": "_fd_audio",
1355− "audios": "_fd_audio",
1356− ".audios": "_fd_audio",
1357− "sound": "_fd_audio",
1358− ".sound": "_fd_audio",
1359− "sounds": "_fd_audio",
1360− ".sounds": "_fd_audio",
1361− "aurelia_project": "_fd_aurelia",
1362− "aws": "_fd_aws",
1363− ".aws": "_fd_aws",
1364− "azure": "_fd_azure",
1365− ".azure": "_fd_azure",
1366− "azure-pipelines": "_fd_azurepipelines",
1367− ".azure-pipelines": "_fd_azurepipelines",
1368− "bin": "_fd_binary",
1369− ".bin": "_fd_binary",
1370− "blocs": "_fd_bloc",
1371− "bloc": "_fd_bloc",
1372− "blueprint": "_fd_blueprint",
1373− ".blueprint": "_fd_blueprint",
1374− "blueprints": "_fd_blueprint",
1375− ".blueprints": "_fd_blueprint",
1376− "bot": "_fd_bot",
1377− ".bot": "_fd_bot",
1378− "bower_components": "_fd_bower",
1379− ".buildkite": "_fd_buildkite",
1380− "cake": "_fd_cake",
1381− ".cake": "_fd_cake",
1382− "cargo": "_fd_cargo",
1383− ".cargo": "_fd_cargo",
1384− "crates": "_fd_cargo",
1385− "certificates": "_fd_certificate",
1386− ".certificates": "_fd_certificate",
1387− "certs": "_fd_certificate",
1388− "certs.": "_fd_certificate",
1389− ".changeset": "_fd_changesets",
1390− "chef": "_fd_chef",
1391− ".chef": "_fd_chef",
1392− ".circleci": "_fd_circleci",
1393− ".claude": "_fd_claude",
1394− "cli": "_fd_cli",
1395− "cmd": "_fd_cli",
1396− "command": "_fd_cli",
1397− "commands": "_fd_cli",
1398− "commandline": "_fd_cli",
1399− "console": "_fd_cli",
1400− "client": "_fd_client",
1401− "clients": "_fd_client",
1402− ".cloudflare": "_fd_cloudflare",
1403− "cloudflare": "_fd_cloudflare",
1404− ".cmake": "_fd_cmake",
1405− "cmake": "_fd_cmake",
1406− "common": "_fd_common",
1407− "component": "_fd_component",
1408− "components": "_fd_component",
1409− ".components": "_fd_component",
1410− "gui": "_fd_component",
1411− "src-ui": "_fd_component",
1412− "ui": "_fd_component",
1413− "widgets": "_fd_component",
1414− "composer": "_fd_composer",
1415− ".composer": "_fd_composer",
1416− "conf": "_fd_config",
1417− ".conf": "_fd_config",
1418− "config": "_fd_config",
1419− ".config": "_fd_config",
1420− "configs": "_fd_config",
1421− ".configs": "_fd_config",
1422− "configuration": "_fd_config",
1423− ".configuration": "_fd_config",
1424− "configurations": "_fd_config",
1425− ".configurations": "_fd_config",
1426− "setting": "_fd_config",
1427− ".setting": "_fd_config",
1428− "settings": "_fd_config",
1429− ".settings": "_fd_config",
1430− "ini": "_fd_config",
1431− ".ini": "_fd_config",
1432− "initializers": "_fd_config",
1433− ".initializers": "_fd_config",
1434− "__controller__": "_fd_controller",
1435− "__controllers__": "_fd_controller",
1436− "controller": "_fd_controller",
1437− "controllers": "_fd_controller",
1438− ".controllers": "_fd_controller",
1439− "__handler__": "_fd_controller",
1440− "__handlers__": "_fd_controller",
1441− "handler": "_fd_controller",
1442− ".handler": "_fd_controller",
1443− "handlers": "_fd_controller",
1444− ".handlers": "_fd_controller",
1445− "coverage": "_fd_coverage",
1446− "css": "_fd_css",
1447− "_css": "_fd_css",
1448− "cubits": "_fd_cubit",
1449− "cubit": "_fd_cubit",
1450− ".cursor": "_fd_cursor",
1451− "cypress": "_fd_cypress",
1452− ".dapr": "_fd_dapr",
1453− "dapr": "_fd_dapr",
1454− "dart": "_fd_dart",
1455− ".dart_tool": "_fd_dart",
1456− "datadog": "_fd_datadog",
1457− ".datadog": "_fd_datadog",
1458− "db": "_fd_db",
1459− "database": "_fd_db",
1460− "sql": "_fd_db",
1461− "data": "_fd_db",
1462− "repo": "_fd_db",
1463− "repository": "_fd_db",
1464− "repositories": "_fd_db",
1465− "store": "_fd_db",
1466− "stores": "_fd_db",
1467− "debian": "_fd_debian",
1468− "deb": "_fd_debian",
1469− ".dependabot": "_fd_dependabot",
1470− ".devcontainer": "_fd_devcontainer",
1471− "dist": "_fd_dist",
1472− ".dist": "_fd_dist",
1473− "dists": "_fd_dist",
1474− "out": "_fd_dist",
1475− "outs": "_fd_dist",
1476− "export": "_fd_dist",
1477− "exports": "_fd_dist",
1478− "build": "_fd_dist",
1479− ".build": "_fd_dist",
1480− "builds": "_fd_dist",
1481− "release": "_fd_dist",
1482− "releases": "_fd_dist",
1483− "target": "_fd_dist",
1484− "targets": "_fd_dist",
1485− "docker": "_fd_docker",
1486− ".docker": "_fd_docker",
1487− "docs": "_fd_docs",
1488− "doc": "_fd_docs",
1489− "document": "_fd_docs",
1490− "documents": "_fd_docs",
1491− "e2e": "_fd_e2e",
1492− ".elasticbeanstalk": "_fd_elasticbeanstalk",
1493− ".ebextensions": "_fd_elasticbeanstalk",
1494− "electron": "_fd_electron",
1495− ".expo": "_fd_expo",
1496− ".expo-shared": "_fd_expo",
1497− "favicon": "_fd_favicon",
1498− "favicons": "_fd_favicon",
1499− "flow": "_fd_flow",
1500− "flow-typed": "_fd_flow",
1501− "flutter": "_fd_flutter",
1502− "Flutter": "_fd_flutter",
1503− "fonts": "_fd_fonts",
1504− "font": "_fd_fonts",
1505− "fnt": "_fd_fonts",
1506− "webfonts": "_fd_fonts",
1507− ".front-commerce": "_fd_frontcommerce",
1508− "gcp": "_fd_gcp",
1509− ".gcp": "_fd_gcp",
1510− ".gemini": "_fd_gemini",
1511− ".git": "_fd_git",
1512− "submodules": "_fd_git",
1513− ".submodules": "_fd_git",
1514− ".github": "_fd_github",
1515− ".gitlab": "_fd_gitlab",
1516− "godot": "_fd_godot",
1517− ".godot": "_fd_godot",
1518− "gradle": "_fd_gradle",
1519− ".gradle": "_fd_gradle",
1520− "graphql": "_fd_graphql",
1521− "grunt": "_fd_grunt",
1522− "gulp": "_fd_gulp",
1523− "gulpfile.js": "_fd_gulp",
1524− "gulpfile.coffee": "_fd_gulp",
1525− "gulpfile.ts": "_fd_gulp",
1526− "gulpfile.babel.js": "_fd_gulp",
1527− "gulpfile.babel.coffee": "_fd_gulp",
1528− "gulpfile.babel.ts": "_fd_gulp",
1529− ".haxelib": "_fd_haxelib",
1530− "haxe_libraries": "_fd_haxelib",
1531− "helper": "_fd_helper",
1532− ".helper": "_fd_helper",
1533− "helpers": "_fd_helper",
1534− ".helpers": "_fd_helper",
1535− ".histoire": "_fd_histoire",
1536− "hook": "_fd_hook",
1537− ".hook": "_fd_hook",
1538− "hooks": "_fd_hook",
1539− ".hooks": "_fd_hook",
1540− ".husky": "_fd_husky",
1541− ".idea": "_fd_idea",
1542− ".fig": "_fd_images",
1543− ".figs": "_fd_images",
1544− "images": "_fd_images",
1545− "image": "_fd_images",
1546− ".img": "_fd_images",
1547− "img": "_fd_images",
1548− ".imgs": "_fd_images",
1549− "imgs": "_fd_images",
1550− "icons": "_fd_images",
1551− "icon": "_fd_images",
1552− "ico": "_fd_images",
1553− "screenshot": "_fd_images",
1554− "screenshots": "_fd_images",
1555− "svg": "_fd_images",
1556− "texture": "_fd_images",
1557− "textures": "_fd_images",
1558− "include": "_fd_include",
1559− "includes": "_fd_include",
1560− "incl": "_fd_include",
1561− "inc": "_fd_include",
1562− ".include": "_fd_include",
1563− ".includes": "_fd_include",
1564− ".incl": "_fd_include",
1565− ".inc": "_fd_include",
1566− "_include": "_fd_include",
1567− "_includes": "_fd_include",
1568− "_incl": "_fd_include",
1569− "_inc": "_fd_include",
1570− "interface": "_fd_interfaces",
1571− "interfaces": "_fd_interfaces",
1572− "ios": "_fd_ios",
1573− "js": "_fd_js",
1574− "json": "_fd_json",
1575− ".junie": "_fd_junie",
1576− "kotlin": "_fd_kotlin",
1577− "Kotlin": "_fd_kotlin",
1578− ".kotlin": "_fd_kotlin",
1579− "kubernetes": "_fd_kubernetes",
1580− "k8s": "_fd_kubernetes",
1581− "kube": "_fd_kubernetes",
1582− "kuber": "_fd_kubernetes",
1583− ".kubernetes": "_fd_kubernetes",
1584− ".k8s": "_fd_kubernetes",
1585− ".kube": "_fd_kubernetes",
1586− ".kuber": "_fd_kubernetes",
1587− "less": "_fd_less",
1588− "_less": "_fd_less",
1589− "lib": "_fd_library",
1590− "libs": "_fd_library",
1591− ".lib": "_fd_library",
1592− ".libs": "_fd_library",
1593− "__lib__": "_fd_library",
1594− "__libs__": "_fd_library",
1595− "library": "_fd_library",
1596− "libraries": "_fd_library",
1597− "linux": "_fd_linux",
1598− "lang": "_fd_locale",
1599− "language": "_fd_locale",
1600− "languages": "_fd_locale",
1601− "locale": "_fd_locale",
1602− "locales": "_fd_locale",
1603− "_locale": "_fd_locale",
1604− "_locales": "_fd_locale",
1605− "internationalization": "_fd_locale",
1606− "globalization": "_fd_locale",
1607− "localization": "_fd_locale",
1608− "i18n": "_fd_locale",
1609− "g11n": "_fd_locale",
1610− "l10n": "_fd_locale",
1611− "log": "_fd_log",
1612− "logs": "_fd_log",
1613− "macos": "_fd_macos",
1614− "darwin": "_fd_macos",
1615− "mariadb": "_fd_mariadb",
1616− "maria": "_fd_mariadb",
1617− ".mvn": "_fd_maven",
1618− "mediawiki": "_fd_mediawiki",
1619− "memcached": "_fd_memcached",
1620− ".memcached": "_fd_memcached",
1621− ".meteor": "_fd_meteor",
1622− "middleware": "_fd_middleware",
1623− "middlewares": "_fd_middleware",
1624− ".minecraft": "_fd_minecraft",
1625− "minikube": "_fd_minikube",
1626− "minik8s": "_fd_minikube",
1627− "minikuber": "_fd_minikube",
1628− "mjml": "_fd_mjml",
1629− ".mjml": "_fd_mjml",
1630− "mocks": "_fd_mock",
1631− ".mocks": "_fd_mock",
1632− "__mocks__": "_fd_mock",
1633− "model": "_fd_model",
1634− ".model": "_fd_model",
1635− "models": "_fd_model",
1636− ".models": "_fd_model",
1637− "entities": "_fd_model",
1638− ".entities": "_fd_model",
1639− "modules": "_fd_module",
1640− "mojo": "_fd_mojo",
1641− "mongodb": "_fd_mongodb",
1642− "mongo": "_fd_mongodb",
1643− ".mypy_cache": "_fd_mypy",
1644− "mysqldb": "_fd_mysql",
1645− "mysql": "_fd_mysql",
1646− "netlify": "_fd_netlify",
1647− ".next": "_fd_next",
1648− "nginx": "_fd_nginx",
1649− "conf.d": "_fd_nginx",
1650− ".niv": "_fd_nix",
1651− ".nix": "_fd_nix",
1652− "nix": "_fd_nix",
1653− "niv": "_fd_nix",
1654− "node_modules": "_fd_node",
1655− "notebooks": "_fd_notebooks",
1656− "notebook": "_fd_notebooks",
1657− "notification": "_fd_notification",
1658− "notifications": "_fd_notification",
1659− "event": "_fd_notification",
1660− "events": "_fd_notification",
1661− ".nuget": "_fd_nuget",
1662− "nuxt": "_fd_nuxt",
1663− ".nuxt": "_fd_nuxt",
1664− "package": "_fd_package",
1665− "packages": "_fd_package",
1666− ".package": "_fd_package",
1667− ".packages": "_fd_package",
1668− "pkg": "_fd_package",
1669− ".paket": "_fd_paket",
1670− "php": "_fd_php",
1671− ".pio": "_fd_platformio",
1672− ".pioenvs": "_fd_platformio",
1673− "plugin": "_fd_plugin",
1674− ".plugin": "_fd_plugin",
1675− "plugins": "_fd_plugin",
1676− ".plugins": "_fd_plugin",
1677− "extension": "_fd_plugin",
1678− ".extension": "_fd_plugin",
1679− "extensions": "_fd_plugin",
1680− ".extensions": "_fd_plugin",
1681− "prisma": "_fd_prisma",
1682− "private": "_fd_private",
1683− ".private": "_fd_private",
1684− "public": "_fd_public",
1685− ".public": "_fd_public",
1686− ".pytest_cache": "_fd_pytest",
1687− ".venv": "_fd_python",
1688− ".virtualenv": "_fd_python",
1689− "__pycache__": "_fd_python",
1690− "ravendb": "_fd_ravendb",
1691− "redis": "_fd_redis",
1692− "redux": "_fd_redux",
1693− "route": "_fd_route",
1694− "routes": "_fd_route",
1695− "_route": "_fd_route",
1696− "_routes": "_fd_route",
1697− "router": "_fd_route",
1698− "routers": "_fd_route",
1699− "sass": "_fd_sass",
1700− "scss": "_fd_sass",
1701− "_sass": "_fd_sass",
1702− "_scss": "_fd_sass",
1703− "script": "_fd_script",
1704− "scripts": "_fd_script",
1705− "seedkit": "_fd_seedkit",
1706− ".seedkit": "_fd_seedkit",
1707− "server": "_fd_server",
1708− "service": "_fd_services",
1709− "services": "_fd_services",
1710− "share": "_fd_shared",
1711− "shared": "_fd_shared",
1712− ".share": "_fd_shared",
1713− ".shared": "_fd_shared",
1714− "__shared__": "_fd_shared",
1715− "__share__": "_fd_shared",
1716− ".snaplet": "_fd_snaplet",
1717− ".spin": "_fd_spin",
1718− "src": "_fd_src",
1719− "source": "_fd_src",
1720− "sources": "_fd_src",
1721− "__src__": "_fd_src",
1722− "sso": "_fd_sso",
1723− "story": "_fd_story",
1724− "stories": "_fd_story",
1725− "__stories__": "_fd_story",
1726− ".storybook": "_fd_story",
1727− "style": "_fd_style",
1728− "styles": "_fd_style",
1729− "supabase": "_fd_supabase",
1730− "svelte": "_fd_svelte",
1731− ".svelte-kit": "_fd_svelte",
1732− "src-tauri": "_fd_tauri",
1733− "temp": "_fd_temp",
1734− ".temp": "_fd_temp",
1735− "tmp": "_fd_temp",
1736− ".tmp": "_fd_temp",
1737− "template": "_fd_template",
1738− ".template": "_fd_template",
1739− "templates": "_fd_template",
1740− ".templates": "_fd_template",
1741− "tests": "_fd_test",
1742− ".tests": "_fd_test",
1743− "test": "_fd_test",
1744− ".test": "_fd_test",
1745− "__tests__": "_fd_test",
1746− "__test__": "_fd_test",
1747− "spec": "_fd_test",
1748− ".spec": "_fd_test",
1749− "specs": "_fd_test",
1750− ".specs": "_fd_test",
1751− "integration": "_fd_test",
1752− "theme": "_fd_theme",
1753− "themes": "_fd_theme",
1754− "tool": "_fd_tools",
1755− "tools": "_fd_tools",
1756− ".tools": "_fd_tools",
1757− "util": "_fd_tools",
1758− "utils": "_fd_tools",
1759− "utilities": "_fd_tools",
1760− "tooling": "_fd_tools",
1761− ".travis": "_fd_travis",
1762− ".trunk": "_fd_trunk",
1763− ".turbo": "_fd_turbo",
1764− "typescript": "_fd_typescript",
1765− "ts": "_fd_typescript",
1766− "typings": "_fd_typings",
1767− "types": "_fd_typings",
1768− "@types": "_fd_typings",
1769− "vagrant": "_fd_vagrant",
1770− ".vagrant": "_fd_vagrant",
1771− ".vercel": "_fd_vercel",
1772− "video": "_fd_video",
1773− ".video": "_fd_video",
1774− "videos": "_fd_video",
1775− ".videos": "_fd_video",
1776− "html": "_fd_view",
1777− "view": "_fd_view",
1778− "views": "_fd_view",
1779− "layout": "_fd_view",
1780− "layouts": "_fd_view",
1781− "page": "_fd_view",
1782− "pages": "_fd_view",
1783− "_view": "_fd_view",
1784− "_views": "_fd_view",
1785− "_layout": "_fd_view",
1786− "_layouts": "_fd_view",
1787− "_page": "_fd_view",
1788− "_pages": "_fd_view",
1789− ".vitepress": "_fd_vitepress",
1790− ".vs": "_fd_vs",
1791− ".vscode": "_fd_vscode",
1792− "vscode": "_fd_vscode",
1793− ".vscode-test": "_fd_vscode_test",
1794− "wasm": "_fd_wasm",
1795− "WASM": "_fd_wasm",
1796− "webassembly": "_fd_wasm",
1797− "WebAssembly": "_fd_wasm",
1798− "webpack": "_fd_webpack",
1799− ".webpack": "_fd_webpack",
1800− "windows": "_fd_windows",
1801− "win32": "_fd_windows",
1802− ".windsurf": "_fd_windsurf",
1803− "wit": "_fd_wit",
1804− ".web": "_fd_www",
1805− "www": "_fd_www",
1806− "wwwroot": "_fd_www",
1807− "web": "_fd_www",
1808− ".yarn": "_fd_yarn",
1809− ".zed": "_fd_zed"
1810− },
1811− "folderNamesExpanded": {
1812− "android": "_fd_android_open",
1813− ".angular": "_fd_angular_open",
1814− "apache": "_fd_apache_open",
1815− "apache2": "_fd_apache_open",
1816− "httpd": "_fd_apache_open",
1817− "api": "_fd_api_open",
1818− ".api": "_fd_api_open",
1819− "apis": "_fd_api_open",
1820− ".apis": "_fd_api_open",
1821− "app": "_fd_app_open",
1822− "apps": "_fd_app_open",
1823− ".app": "_fd_app_open",
1824− "application": "_fd_app_open",
1825− "applications": "_fd_app_open",
1826− "arangodb": "_fd_arangodb_open",
1827− "arango": "_fd_arangodb_open",
1828− "assets": "_fd_asset_open",
1829− ".assets": "_fd_asset_open",
1830− ".astro": "_fd_astro_open",
1831− "audio": "_fd_audio_open",
1832− ".audio": "_fd_audio_open",
1833− "audios": "_fd_audio_open",
1834− ".audios": "_fd_audio_open",
1835− "sound": "_fd_audio_open",
1836− ".sound": "_fd_audio_open",
1837− "sounds": "_fd_audio_open",
1838− ".sounds": "_fd_audio_open",
1839− "aurelia_project": "_fd_aurelia_open",
1840− "aws": "_fd_aws_open",
1841− ".aws": "_fd_aws_open",
1842− "azure": "_fd_azure_open",
1843− ".azure": "_fd_azure_open",
1844− "azure-pipelines": "_fd_azurepipelines_open",
1845− ".azure-pipelines": "_fd_azurepipelines_open",
1846− "bin": "_fd_binary_open",
1847− ".bin": "_fd_binary_open",
1848− "blocs": "_fd_bloc_open",
1849− "bloc": "_fd_bloc_open",
1850− "blueprint": "_fd_blueprint_open",
1851− ".blueprint": "_fd_blueprint_open",
1852− "blueprints": "_fd_blueprint_open",
1853− ".blueprints": "_fd_blueprint_open",
1854− "bot": "_fd_bot_open",
1855− ".bot": "_fd_bot_open",
1856− "bower_components": "_fd_bower_open",
1857− ".buildkite": "_fd_buildkite_open",
1858− "cake": "_fd_cake_open",
1859− ".cake": "_fd_cake_open",
1860− "cargo": "_fd_cargo_open",
1861− ".cargo": "_fd_cargo_open",
1862− "crates": "_fd_cargo_open",
1863− "certificates": "_fd_certificate_open",
1864− ".certificates": "_fd_certificate_open",
1865− "certs": "_fd_certificate_open",
1866− "certs.": "_fd_certificate_open",
1867− ".changeset": "_fd_changesets_open",
1868− "chef": "_fd_chef_open",
1869− ".chef": "_fd_chef_open",
1870− ".circleci": "_fd_circleci_open",
1871− ".claude": "_fd_claude_open",
1872− "cli": "_fd_cli_open",
1873− "cmd": "_fd_cli_open",
1874− "command": "_fd_cli_open",
1875− "commands": "_fd_cli_open",
1876− "commandline": "_fd_cli_open",
1877− "console": "_fd_cli_open",
1878− "client": "_fd_client_open",
1879− "clients": "_fd_client_open",
1880− ".cloudflare": "_fd_cloudflare_open",
1881− "cloudflare": "_fd_cloudflare_open",
1882− ".cmake": "_fd_cmake_open",
1883− "cmake": "_fd_cmake_open",
1884− "common": "_fd_common_open",
1885− "component": "_fd_component_open",
1886− "components": "_fd_component_open",
1887− ".components": "_fd_component_open",
1888− "gui": "_fd_component_open",
1889− "src-ui": "_fd_component_open",
1890− "ui": "_fd_component_open",
1891− "widgets": "_fd_component_open",
1892− "composer": "_fd_composer_open",
1893− ".composer": "_fd_composer_open",
1894− "conf": "_fd_config_open",
1895− ".conf": "_fd_config_open",
1896− "config": "_fd_config_open",
1897− ".config": "_fd_config_open",
1898− "configs": "_fd_config_open",
1899− ".configs": "_fd_config_open",
1900− "configuration": "_fd_config_open",
1901− ".configuration": "_fd_config_open",
1902− "configurations": "_fd_config_open",
1903− ".configurations": "_fd_config_open",
1904− "setting": "_fd_config_open",
1905− ".setting": "_fd_config_open",
1906− "settings": "_fd_config_open",
1907− ".settings": "_fd_config_open",
1908− "ini": "_fd_config_open",
1909− ".ini": "_fd_config_open",
1910− "initializers": "_fd_config_open",
1911− ".initializers": "_fd_config_open",
1912− "__controller__": "_fd_controller_open",
1913− "__controllers__": "_fd_controller_open",
1914− "controller": "_fd_controller_open",
1915− "controllers": "_fd_controller_open",
1916− ".controllers": "_fd_controller_open",
1917− "__handler__": "_fd_controller_open",
1918− "__handlers__": "_fd_controller_open",
1919− "handler": "_fd_controller_open",
1920− ".handler": "_fd_controller_open",
1921− "handlers": "_fd_controller_open",
1922− ".handlers": "_fd_controller_open",
1923− "coverage": "_fd_coverage_open",
1924− "css": "_fd_css_open",
1925− "_css": "_fd_css_open",
1926− "cubits": "_fd_cubit_open",
1927− "cubit": "_fd_cubit_open",
1928− ".cursor": "_fd_cursor_open",
1929− "cypress": "_fd_cypress_open",
1930− ".dapr": "_fd_dapr_open",
1931− "dapr": "_fd_dapr_open",
1932− "dart": "_fd_dart_open",
1933− ".dart_tool": "_fd_dart_open",
1934− "datadog": "_fd_datadog_open",
1935− ".datadog": "_fd_datadog_open",
1936− "db": "_fd_db_open",
1937− "database": "_fd_db_open",
1938− "sql": "_fd_db_open",
1939− "data": "_fd_db_open",
1940− "repo": "_fd_db_open",
1941− "repository": "_fd_db_open",
1942− "repositories": "_fd_db_open",
1943− "store": "_fd_db_open",
1944− "stores": "_fd_db_open",
1945− "debian": "_fd_debian_open",
1946− "deb": "_fd_debian_open",
1947− ".dependabot": "_fd_dependabot_open",
1948− ".devcontainer": "_fd_devcontainer_open",
1949− "dist": "_fd_dist_open",
1950− ".dist": "_fd_dist_open",
1951− "dists": "_fd_dist_open",
1952− "out": "_fd_dist_open",
1953− "outs": "_fd_dist_open",
1954− "export": "_fd_dist_open",
1955− "exports": "_fd_dist_open",
1956− "build": "_fd_dist_open",
1957− ".build": "_fd_dist_open",
1958− "builds": "_fd_dist_open",
1959− "release": "_fd_dist_open",
1960− "releases": "_fd_dist_open",
1961− "target": "_fd_dist_open",
1962− "targets": "_fd_dist_open",
1963− "docker": "_fd_docker_open",
1964− ".docker": "_fd_docker_open",
1965− "docs": "_fd_docs_open",
1966− "doc": "_fd_docs_open",
1967− "document": "_fd_docs_open",
1968− "documents": "_fd_docs_open",
1969− "e2e": "_fd_e2e_open",
1970− ".elasticbeanstalk": "_fd_elasticbeanstalk_open",
1971− ".ebextensions": "_fd_elasticbeanstalk_open",
1972− "electron": "_fd_electron_open",
1973− ".expo": "_fd_expo_open",
1974− ".expo-shared": "_fd_expo_open",
1975− "favicon": "_fd_favicon_open",
1976− "favicons": "_fd_favicon_open",
1977− "flow": "_fd_flow_open",
1978− "flow-typed": "_fd_flow_open",
1979− "flutter": "_fd_flutter_open",
1980− "Flutter": "_fd_flutter_open",
1981− "fonts": "_fd_fonts_open",
1982− "font": "_fd_fonts_open",
1983− "fnt": "_fd_fonts_open",
1984− "webfonts": "_fd_fonts_open",
1985− ".front-commerce": "_fd_frontcommerce_open",
1986− "gcp": "_fd_gcp_open",
1987− ".gcp": "_fd_gcp_open",
1988− ".gemini": "_fd_gemini_open",
1989− ".git": "_fd_git_open",
1990− "submodules": "_fd_git_open",
1991− ".submodules": "_fd_git_open",
1992− ".github": "_fd_github_open",
1993− ".gitlab": "_fd_gitlab_open",
1994− "godot": "_fd_godot_open",
1995− ".godot": "_fd_godot_open",
1996− "gradle": "_fd_gradle_open",
1997− ".gradle": "_fd_gradle_open",
1998− "graphql": "_fd_graphql_open",
1999− "grunt": "_fd_grunt_open",
2000− "gulp": "_fd_gulp_open",
2001− "gulpfile.js": "_fd_gulp_open",
2002− "gulpfile.coffee": "_fd_gulp_open",
2003− "gulpfile.ts": "_fd_gulp_open",
2004− "gulpfile.babel.js": "_fd_gulp_open",
2005− "gulpfile.babel.coffee": "_fd_gulp_open",
2006− "gulpfile.babel.ts": "_fd_gulp_open",
2007− ".haxelib": "_fd_haxelib_open",
2008− "haxe_libraries": "_fd_haxelib_open",
2009− "helper": "_fd_helper_open",
2010− ".helper": "_fd_helper_open",
2011− "helpers": "_fd_helper_open",
2012− ".helpers": "_fd_helper_open",
2013− ".histoire": "_fd_histoire_open",
2014− "hook": "_fd_hook_open",
2015− ".hook": "_fd_hook_open",
2016− "hooks": "_fd_hook_open",
2017− ".hooks": "_fd_hook_open",
2018− ".husky": "_fd_husky_open",
2019− ".idea": "_fd_idea_open",
2020− ".fig": "_fd_images_open",
2021− ".figs": "_fd_images_open",
2022− "images": "_fd_images_open",
2023− "image": "_fd_images_open",
2024− ".img": "_fd_images_open",
2025− "img": "_fd_images_open",
2026− ".imgs": "_fd_images_open",
2027− "imgs": "_fd_images_open",
2028− "icons": "_fd_images_open",
2029− "icon": "_fd_images_open",
2030− "ico": "_fd_images_open",
2031− "screenshot": "_fd_images_open",
2032− "screenshots": "_fd_images_open",
2033− "svg": "_fd_images_open",
2034− "texture": "_fd_images_open",
2035− "textures": "_fd_images_open",
2036− "include": "_fd_include_open",
2037− "includes": "_fd_include_open",
2038− "incl": "_fd_include_open",
2039− "inc": "_fd_include_open",
2040− ".include": "_fd_include_open",
2041− ".includes": "_fd_include_open",
2042− ".incl": "_fd_include_open",
2043− ".inc": "_fd_include_open",
2044− "_include": "_fd_include_open",
2045− "_includes": "_fd_include_open",
2046− "_incl": "_fd_include_open",
2047− "_inc": "_fd_include_open",
2048− "interface": "_fd_interfaces_open",
2049− "interfaces": "_fd_interfaces_open",
2050− "ios": "_fd_ios_open",
2051− "js": "_fd_js_open",
2052− "json": "_fd_json_open",
2053− ".junie": "_fd_junie_open",
2054− "kotlin": "_fd_kotlin_open",
2055− "Kotlin": "_fd_kotlin_open",
2056− ".kotlin": "_fd_kotlin_open",
2057− "kubernetes": "_fd_kubernetes_open",
2058− "k8s": "_fd_kubernetes_open",
2059− "kube": "_fd_kubernetes_open",
2060− "kuber": "_fd_kubernetes_open",
2061− ".kubernetes": "_fd_kubernetes_open",
2062− ".k8s": "_fd_kubernetes_open",
2063− ".kube": "_fd_kubernetes_open",
2064− ".kuber": "_fd_kubernetes_open",
2065− "less": "_fd_less_open",
2066− "_less": "_fd_less_open",
2067− "lib": "_fd_library_open",
2068− "libs": "_fd_library_open",
2069− ".lib": "_fd_library_open",
2070− ".libs": "_fd_library_open",
2071− "__lib__": "_fd_library_open",
2072− "__libs__": "_fd_library_open",
2073− "library": "_fd_library_open",
2074− "libraries": "_fd_library_open",
2075− "linux": "_fd_linux_open",
2076− "lang": "_fd_locale_open",
2077− "language": "_fd_locale_open",
2078− "languages": "_fd_locale_open",
2079− "locale": "_fd_locale_open",
2080− "locales": "_fd_locale_open",
2081− "_locale": "_fd_locale_open",
2082− "_locales": "_fd_locale_open",
2083− "internationalization": "_fd_locale_open",
2084− "globalization": "_fd_locale_open",
2085− "localization": "_fd_locale_open",
2086− "i18n": "_fd_locale_open",
2087− "g11n": "_fd_locale_open",
2088− "l10n": "_fd_locale_open",
2089− "log": "_fd_log_open",
2090− "logs": "_fd_log_open",
2091− "macos": "_fd_macos_open",
2092− "darwin": "_fd_macos_open",
2093− "mariadb": "_fd_mariadb_open",
2094− "maria": "_fd_mariadb_open",
2095− ".mvn": "_fd_maven_open",
2096− "mediawiki": "_fd_mediawiki_open",
2097− "memcached": "_fd_memcached_open",
2098− ".memcached": "_fd_memcached_open",
2099− ".meteor": "_fd_meteor_open",
2100− "middleware": "_fd_middleware_open",
2101− "middlewares": "_fd_middleware_open",
2102− ".minecraft": "_fd_minecraft_open",
2103− "minikube": "_fd_minikube_open",
2104− "minik8s": "_fd_minikube_open",
2105− "minikuber": "_fd_minikube_open",
2106− "mjml": "_fd_mjml_open",
2107− ".mjml": "_fd_mjml_open",
2108− "mocks": "_fd_mock_open",
2109− ".mocks": "_fd_mock_open",
2110− "__mocks__": "_fd_mock_open",
2111− "model": "_fd_model_open",
2112− ".model": "_fd_model_open",
2113− "models": "_fd_model_open",
2114− ".models": "_fd_model_open",
2115− "entities": "_fd_model_open",
2116− ".entities": "_fd_model_open",
2117− "modules": "_fd_module_open",
2118− "mojo": "_fd_mojo_open",
2119− "mongodb": "_fd_mongodb_open",
2120− "mongo": "_fd_mongodb_open",
2121− ".mypy_cache": "_fd_mypy_open",
2122− "mysqldb": "_fd_mysql_open",
2123− "mysql": "_fd_mysql_open",
2124− "netlify": "_fd_netlify_open",
2125− ".next": "_fd_next_open",
2126− "nginx": "_fd_nginx_open",
2127− "conf.d": "_fd_nginx_open",
2128− ".niv": "_fd_nix_open",
2129− ".nix": "_fd_nix_open",
2130− "nix": "_fd_nix_open",
2131− "niv": "_fd_nix_open",
2132− "node_modules": "_fd_node_open",
2133− "notebooks": "_fd_notebooks_open",
2134− "notebook": "_fd_notebooks_open",
2135− "notification": "_fd_notification_open",
2136− "notifications": "_fd_notification_open",
2137− "event": "_fd_notification_open",
2138− "events": "_fd_notification_open",
2139− ".nuget": "_fd_nuget_open",
2140− "nuxt": "_fd_nuxt_open",
2141− ".nuxt": "_fd_nuxt_open",
2142− "package": "_fd_package_open",
2143− "packages": "_fd_package_open",
2144− ".package": "_fd_package_open",
2145− ".packages": "_fd_package_open",
2146− "pkg": "_fd_package_open",
2147− ".paket": "_fd_paket_open",
2148− "php": "_fd_php_open",
2149− ".pio": "_fd_platformio_open",
2150− ".pioenvs": "_fd_platformio_open",
2151− "plugin": "_fd_plugin_open",
2152− ".plugin": "_fd_plugin_open",
2153− "plugins": "_fd_plugin_open",
2154− ".plugins": "_fd_plugin_open",
2155− "extension": "_fd_plugin_open",
2156− ".extension": "_fd_plugin_open",
2157− "extensions": "_fd_plugin_open",
2158− ".extensions": "_fd_plugin_open",
2159− "prisma": "_fd_prisma_open",
2160− "private": "_fd_private_open",
2161− ".private": "_fd_private_open",
2162− "public": "_fd_public_open",
2163− ".public": "_fd_public_open",
2164− ".pytest_cache": "_fd_pytest_open",
2165− ".venv": "_fd_python_open",
2166− ".virtualenv": "_fd_python_open",
2167− "__pycache__": "_fd_python_open",
2168− "ravendb": "_fd_ravendb_open",
2169− "redis": "_fd_redis_open",
2170− "redux": "_fd_redux_open",
2171− "route": "_fd_route_open",
2172− "routes": "_fd_route_open",
2173− "_route": "_fd_route_open",
2174− "_routes": "_fd_route_open",
2175− "router": "_fd_route_open",
2176− "routers": "_fd_route_open",
2177− "sass": "_fd_sass_open",
2178− "scss": "_fd_sass_open",
2179− "_sass": "_fd_sass_open",
2180− "_scss": "_fd_sass_open",
2181− "script": "_fd_script_open",
2182− "scripts": "_fd_script_open",
2183− "seedkit": "_fd_seedkit_open",
2184− ".seedkit": "_fd_seedkit_open",
2185− "server": "_fd_server_open",
2186− "service": "_fd_services_open",
2187− "services": "_fd_services_open",
2188− "share": "_fd_shared_open",
2189− "shared": "_fd_shared_open",
2190− ".share": "_fd_shared_open",
2191− ".shared": "_fd_shared_open",
2192− "__shared__": "_fd_shared_open",
2193− "__share__": "_fd_shared_open",
2194− ".snaplet": "_fd_snaplet_open",
2195− ".spin": "_fd_spin_open",
2196− "src": "_fd_src_open",
2197− "source": "_fd_src_open",
2198− "sources": "_fd_src_open",
2199− "__src__": "_fd_src_open",
2200− "sso": "_fd_sso_open",
2201− "story": "_fd_story_open",
2202− "stories": "_fd_story_open",
2203− "__stories__": "_fd_story_open",
2204− ".storybook": "_fd_story_open",
2205− "style": "_fd_style_open",
2206− "styles": "_fd_style_open",
2207− "supabase": "_fd_supabase_open",
2208− "svelte": "_fd_svelte_open",
2209− ".svelte-kit": "_fd_svelte_open",
2210− "src-tauri": "_fd_tauri_open",
2211− "temp": "_fd_temp_open",
2212− ".temp": "_fd_temp_open",
2213− "tmp": "_fd_temp_open",
2214− ".tmp": "_fd_temp_open",
2215− "template": "_fd_template_open",
2216− ".template": "_fd_template_open",
2217− "templates": "_fd_template_open",
2218− ".templates": "_fd_template_open",
2219− "tests": "_fd_test_open",
2220− ".tests": "_fd_test_open",
2221− "test": "_fd_test_open",
2222− ".test": "_fd_test_open",
2223− "__tests__": "_fd_test_open",
2224− "__test__": "_fd_test_open",
2225− "spec": "_fd_test_open",
2226− ".spec": "_fd_test_open",
2227− "specs": "_fd_test_open",
2228− ".specs": "_fd_test_open",
2229− "integration": "_fd_test_open",
2230− "theme": "_fd_theme_open",
2231− "themes": "_fd_theme_open",
2232− "tool": "_fd_tools_open",
2233− "tools": "_fd_tools_open",
2234− ".tools": "_fd_tools_open",
2235− "util": "_fd_tools_open",
2236− "utils": "_fd_tools_open",
2237− "utilities": "_fd_tools_open",
2238− "tooling": "_fd_tools_open",
2239− ".travis": "_fd_travis_open",
2240− ".trunk": "_fd_trunk_open",
2241− ".turbo": "_fd_turbo_open",
2242− "typescript": "_fd_typescript_open",
2243− "ts": "_fd_typescript_open",
2244− "typings": "_fd_typings_open",
2245− "types": "_fd_typings_open",
2246− "@types": "_fd_typings_open",
2247− "vagrant": "_fd_vagrant_open",
2248− ".vagrant": "_fd_vagrant_open",
2249− ".vercel": "_fd_vercel_open",
2250− "video": "_fd_video_open",
2251− ".video": "_fd_video_open",
2252− "videos": "_fd_video_open",
2253− ".videos": "_fd_video_open",
2254− "html": "_fd_view_open",
2255− "view": "_fd_view_open",
2256− "views": "_fd_view_open",
2257− "layout": "_fd_view_open",
2258− "layouts": "_fd_view_open",
2259− "page": "_fd_view_open",
2260− "pages": "_fd_view_open",
2261− "_view": "_fd_view_open",
2262− "_views": "_fd_view_open",
2263− "_layout": "_fd_view_open",
2264− "_layouts": "_fd_view_open",
2265− "_page": "_fd_view_open",
2266− "_pages": "_fd_view_open",
2267− ".vitepress": "_fd_vitepress_open",
2268− ".vs": "_fd_vs_open",
2269− ".vscode": "_fd_vscode_open",
2270− "vscode": "_fd_vscode_open",
2271− ".vscode-test": "_fd_vscode_test_open",
2272− "wasm": "_fd_wasm_open",
2273− "WASM": "_fd_wasm_open",
2274− "webassembly": "_fd_wasm_open",
2275− "WebAssembly": "_fd_wasm_open",
2276− "webpack": "_fd_webpack_open",
2277− ".webpack": "_fd_webpack_open",
2278− "windows": "_fd_windows_open",
2279− "win32": "_fd_windows_open",
2280− ".windsurf": "_fd_windsurf_open",
2281− "wit": "_fd_wit_open",
2282− ".web": "_fd_www_open",
2283− "www": "_fd_www_open",
2284− "wwwroot": "_fd_www_open",
2285− "web": "_fd_www_open",
2286− ".yarn": "_fd_yarn_open",
2287− ".zed": "_fd_zed_open"
2288− },
2289− "fileExtensions": {
2290− "accdb": "_f_access",
2291− "accdt": "_f_access",
2292− "mdb": "_f_access",
2293− "accda": "_f_access",
2294− "accdc": "_f_access",
2295− "accde": "_f_access",
2296− "accdp": "_f_access",
2297− "accdr": "_f_access",
2298− "accdu": "_f_access",
2299− "ade": "_f_access",
2300− "adp": "_f_access",
2301− "laccdb": "_f_access",
2302− "ldb": "_f_access",
2303− "mam": "_f_access",
2304− "maq": "_f_access",
2305− "mdw": "_f_access",
2306− "af": "_f_affinity",
2307− "aftemplate": "_f_affinity",
2308− "afdesign": "_f_affinitydesigner",
2309− "affinitydesigner": "_f_affinitydesigner",
2310− "afphoto": "_f_affinityphoto",
2311− "affinityphoto": "_f_affinityphoto",
2312− "afpub": "_f_affinitypublisher",
2313− "affinitypublisher": "_f_affinitypublisher",
2314− "ai": "_f_ai",
2315− "dal": "_f_al_dal",
2316− "gs": "_f_appscript",
2317− "ino": "_f_arduino",
2318− "pde": "_f_arduino",
2319− "ase": "_f_aseprite",
2320− "aseprite": "_f_aseprite",
2321− "aspx": "_f_aspx",
2322− "ascx": "_f_aspx",
2323− "asm": "_f_assembly",
2324− "s": "_f_assembly",
2325− "astro": "_f_astro",
2326− "atom": "_f_atom",
2327− "aac": "_f_audio",
2328− "act": "_f_audio",
2329− "aiff": "_f_audio",
2330− "amr": "_f_audio",
2331− "ape": "_f_audio",
2332− "au": "_f_audio",
2333− "dct": "_f_audio",
2334− "dss": "_f_audio",
2335− "dvf": "_f_audio",
2336− "flac": "_f_audio",
2337− "gsm": "_f_audio",
2338− "iklax": "_f_audio",
2339− "ivs": "_f_audio",
2340− "m4a": "_f_audio",
2341− "m4b": "_f_audio",
2342− "m4p": "_f_audio",
2343− "mmf": "_f_audio",
2344− "mogg": "_f_audio",
2345− "mp3": "_f_audio",
2346− "mpc": "_f_audio",
2347− "msv": "_f_audio",
2348− "oga": "_f_audio",
2349− "ogg": "_f_audio",
2350− "opus": "_f_audio",
2351− "ra": "_f_audio",
2352− "raw": "_f_audio",
2353− "tta": "_f_audio",
2354− "vox": "_f_audio",
2355− "wav": "_f_audio",
2356− "wma": "_f_audio",
2357− "avif": "_f_avif",
2358− "awk": "_f_awk",
2359− "back": "_f_bak",
2360− "backup": "_f_bak",
2361− "bak": "_f_bak",
2362− "a": "_f_binary",
2363− "app": "_f_binary",
2364− "bin": "_f_binary",
2365− "cmo": "_f_binary",
2366− "cmx": "_f_binary",
2367− "cma": "_f_binary",
2368− "cmxa": "_f_binary",
2369− "cmi": "_f_binary",
2370− "dll": "_f_binary",
2371− "exe": "_f_binary",
2372− "hl": "_f_binary",
2373− "ilk": "_f_binary",
2374− "lib": "_f_binary",
2375− "n": "_f_binary",
2376− "ndll": "_f_binary",
2377− "o": "_f_binary",
2378− "obj": "_f_binary",
2379− "pyc": "_f_binary",
2380− "pyd": "_f_binary",
2381− "pyo": "_f_binary",
2382− "pdb": "_f_binary",
2383− "scpt": "_f_binary",
2384− "scptd": "_f_binary",
2385− "so": "_f_binary",
2386− "blend": "_f_blender",
2387− "bb": "_f_blitzbasic",
2388− "buf.yaml": "_f_buf",
2389− "buf.yml": "_f_buf",
2390− "buf.gen.yml": "_f_buf",
2391− "buf.gen.yaml": "_f_buf",
2392− "buf.work.yaml": "_f_buf",
2393− "buf.work.yml": "_f_buf",
2394− "gemfile": "_f_bundler",
2395− "gemfile.lock": "_f_bundler",
2396− "cake": "_f_cake",
2397− "csr": "_f_cert",
2398− "crt": "_f_cert",
2399− "cer": "_f_cert",
2400− "der": "_f_cert",
2401− "pfx": "_f_cert",
2402− "p12": "_f_cert",
2403− "p7b": "_f_cert",
2404− "p7r": "_f_cert",
2405− "src": "_f_cert",
2406− "crl": "_f_cert",
2407− "sst": "_f_cert",
2408− "stl": "_f_cert",
2409− "lucee": "_f_cf",
2410− "h": "_f_cheader",
2411− "class": "_f_class",
2412− "cjm": "_f_clojure",
2413− "cljc": "_f_clojure",
2414− "cljs": "_f_clojurescript",
2415− "kit": "_f_codekit",
2416− "plist": "_f_config",
2417− "lcov": "_f_coverage",
2418− "hpp": "_f_cppheader",
2419− "hh": "_f_cppheader",
2420− "hxx": "_f_cppheader",
2421− "h++": "_f_cppheader",
2422− "csx": "_f_csharp",
2423− "csproj": "_f_csproj",
2424− "css.map": "_f_cssmap",
2425− "cy.js": "_f_cypress_spec",
2426− "cy.mjs": "_f_cypress_spec",
2427− "cy.cjs": "_f_cypress_spec",
2428− "cy.coffee": "_f_cypress_spec",
2429− "cy.ts": "_f_cypress_spec",
2430− "cy.tsx": "_f_cypress_spec",
2431− "cy.jsx": "_f_cypress_spec",
2432− "g.dart": "_f_dartlang_generated",
2433− "freezed.dart": "_f_dartlang_generated",
2434− "db": "_f_db",
2435− "deb": "_f_debian",
2436− "resolver.json": "_f_design_tokens",
2437− "resolver.json5": "_f_design_tokens",
2438− "resolver.jsonc": "_f_design_tokens",
2439− "tokens.json": "_f_design_tokens",
2440− "tokens.json5": "_f_design_tokens",
2441− "tokens.jsonc": "_f_design_tokens",
2442− "djt": "_f_django",
2443− "eco": "_f_docpad",
2444− "drawio": "_f_drawio",
2445− "dio": "_f_drawio",
2446− "drawio.png": "_f_drawio",
2447− "drawio.svg": "_f_drawio",
2448− "dio.png": "_f_drawio",
2449− "dio.svg": "_f_drawio",
2450− "dtd": "_f_dtd",
2451− "eex": "_f_eex",
2452− "heex": "_f_eex",
2453− "phoenix-heex": "_f_eex",
2454− "html-heex": "_f_eex",
2455− "ejs": "_f_ejs",
2456− "el": "_f_emacs",
2457− "elc": "_f_emacs",
2458− "ensime": "_f_ensime",
2459− "eps": "_f_eps",
2460− "epub": "_f_epub",
2461− "excalidraw": "_f_excalidraw",
2462− "excalidraw.json": "_f_excalidraw",
2463− "excalidraw.svg": "_f_excalidraw",
2464− "excalidraw.png": "_f_excalidraw",
2465− "xls": "_f_excel",
2466− "xlsx": "_f_excel",
2467− "xlsm": "_f_excel",
2468− "ods": "_f_libreoffice_calc",
2469− "fods": "_f_libreoffice_calc",
2470− "xlsb": "_f_excel",
2471− "fbx": "_f_fbx",
2472− "fba": "_f_fitbit",
2473− "fla": "_f_fla",
2474− "swf": "_f_flash",
2475− "swc": "_f_flash",
2476− "js.flow": "_f_flow",
2477− "woff": "_f_font",
2478− "woff2": "_f_font",
2479− "ttf": "_f_font",
2480− "otf": "_f_libreoffice_math",
2481− "eot": "_f_font",
2482− "pfa": "_f_font",
2483− "pfb": "_f_font",
2484− "sfd": "_f_font",
2485− "fsproj": "_f_fsproj",
2486− "gmx": "_f_gamemaker",
2487− "yy": "_f_gamemaker2",
2488− "yyp": "_f_gamemaker2",
2489− "gd.uid": "_f_gduid",
2490− "geojson": "_f_geojson",
2491− "xcf": "_f_gimp",
2492− "gleam": "_f_gleam",
2493− "glb": "_f_gltf",
2494− "gltf": "_f_gltf",
2495− "am": "_f_gnu",
2496− "ld": "_f_gnu",
2497− "m4": "_f_gnu",
2498− "makefile": "_f_gnu",
2499− "godot": "_f_godot",
2500− "gpg": "_f_gpg",
2501− "pgp": "_f_gpg",
2502− "gradle": "_f_gradle",
2503− "gr": "_f_grain",
2504− "hcl2": "_f_hashicorp",
2505− "sentinel": "_f_hashicorp",
2506− "hxproj": "_f_haxedevelop",
2507− "ejs.t": "_f_hygen",
2508− "idr": "_f_idris",
2509− "lidr": "_f_idris",
2510− "ibc": "_f_idrisbin",
2511− "ipkg": "_f_idrispkg",
2512− "jpeg": "_f_image",
2513− "jpg": "_f_image",
2514− "gif": "_f_image",
2515− "png": "_f_image",
2516− "bmp": "_f_image",
2517− "tiff": "_f_image",
2518− "heic": "_f_image",
2519− "ico": "_f_image",
2520− "icns": "_f_image",
2521− "webp": "_f_image",
2522− "imba": "_f_imba",
2523− "imba2": "_f_imba",
2524− "inc": "_f_inc",
2525− "include": "_f_inc",
2526− "infopathxml": "_f_infopath",
2527− "xsn": "_f_infopath",
2528− "xsf": "_f_infopath",
2529− "xtp2": "_f_infopath",
2530− "jar": "_f_jar",
2531− "jbuilder": "_f_jbuilder",
2532− "iml": "_f_jetbrains",
2533− "js.map": "_f_jsmap",
2534− "cjs.map": "_f_jsmap",
2535− "mjs.map": "_f_jsmap",
2536− "jsonl": "_f_json",
2537− "ndjson": "_f_json",
2538− "json5": "_f_json5",
2539− "schema.json": "_f_json_schema",
2540− "jsonld": "_f_jsonld",
2541− "json-ld": "_f_jsonld",
2542− "jsp": "_f_jsp",
2543− "jss": "_f_jss",
2544− "juice": "_f_juice",
2545− "ipynb": "_f_jupyter",
2546− "key": "_f_key",
2547− "pem": "_f_key",
2548− "ktm": "_f_kotlin",
2549− "language-configuration.json": "_f_language_configuration",
2550− "master": "_f_layout",
2551− "layout.html": "_f_layout",
2552− "layout.htm": "_f_layout",
2553− "odb": "_f_libreoffice_base",
2554− "otb": "_f_libreoffice_base",
2555− "ots": "_f_libreoffice_calc",
2556− "odg": "_f_libreoffice_draw",
2557− "otg": "_f_libreoffice_draw",
2558− "odp": "_f_libreoffice_impress",
2559− "otp": "_f_libreoffice_impress",
2560− "odf": "_f_libreoffice_math",
2561− "odt": "_f_libreoffice_writer",
2562− "ott": "_f_libreoffice_writer",
2563− "enc": "_f_license",
2564− "license": "_f_license",
2565− "lic": "_f_license",
2566− "hxp": "_f_lime",
2567− "liquid": "_f_liquid",
2568− "ls": "_f_livescript",
2569− "lnk": "_f_lnk",
2570− "log": "_f_log",
2571− "tlg": "_f_log",
2572− "luau": "_f_luau",
2573− "crec": "_f_lync",
2574− "ocrec": "_f_lync",
2575− "map": "_f_map",
2576− "mdown": "_f_markdown",
2577− "markdown": "_f_markdown",
2578− "marko.js": "_f_markojs",
2579− "fig": "_f_matlab",
2580− "mex": "_f_matlab",
2581− "mexn": "_f_matlab",
2582− "mexrs6": "_f_matlab",
2583− "mn": "_f_matlab",
2584− "mum": "_f_matlab",
2585− "mx": "_f_matlab",
2586− "mx3": "_f_matlab",
2587− "rwd": "_f_matlab",
2588− "slx": "_f_matlab",
2589− "slddc": "_f_matlab",
2590− "smv": "_f_matlab",
2591− "xvc": "_f_matlab",
2592− "mca": "_f_minecraft",
2593− "mcmeta": "_f_minecraft",
2594− "mojo": "_f_mojo",
2595− "🔥": "_f_mojo",
2596− "mql.yaml": "_f_mondoo",
2597− "mql.yml": "_f_mondoo",
2598− "mustache": "_f_mustache",
2599− "mst": "_f_mustache",
2600− "ndst.yaml": "_f_ndst",
2601− "ndst.yml": "_f_ndst",
2602− "ndst.json": "_f_ndst",
2603− "njsproj": "_f_njsproj",
2604− "noc": "_f_noc",
2605− "nupkg": "_f_nuget",
2606− "snupkg": "_f_nuget",
2607− "nuspec": "_f_nuget",
2608− "psmdcp": "_f_nuget",
2609− "npy": "_f_numpy",
2610− "npz": "_f_numpy",
2611− "nunj": "_f_nunjucks",
2612− "njs": "_f_nunjucks",
2613− "mli": "_f_ocaml_intf",
2614− "one": "_f_onenote",
2615− "onepkg": "_f_onenote",
2616− "onetoc": "_f_onenote",
2617− "onetoc2": "_f_onenote",
2618− "sig": "_f_onenote",
2619− "opam": "_f_opam",
2620− "cl": "_f_opencl",
2621− "opencl": "_f_opencl",
2622− "tofu": "_f_opentofu",
2623− "tofu.json": "_f_opentofu",
2624− "tofutest.hcl": "_f_opentofu",
2625− "tofutest.json": "_f_opentofu",
2626− "org": "_f_org",
2627− "pst": "_f_outlook",
2628− "bcmx": "_f_outlook",
2629− "otm": "_f_outlook",
2630− "msg": "_f_outlook",
2631− "oft": "_f_outlook",
2632− "ovpn": "_f_ovpn",
2633− "pkg": "_f_package",
2634− "paket.references": "_f_paket",
2635− "paket.template": "_f_paket",
2636− "patch": "_f_patch",
2637− "pcd": "_f_pcl",
2638− "pdf": "_f_pdf",
2639− "psd": "_f_photoshop",
2640− "php1": "_f_php",
2641− "php2": "_f_php",
2642− "php3": "_f_php",
2643− "php4": "_f_php",
2644− "php5": "_f_php",
2645− "php6": "_f_php",
2646− "phps": "_f_php",
2647− "phpsa": "_f_php",
2648− "phpt": "_f_php",
2649− "phtml": "_f_php",
2650− "phar": "_f_php",
2651− "pipeline": "_f_pipeline",
2652− "pu": "_f_plantuml",
2653− "plantuml": "_f_plantuml",
2654− "iuml": "_f_plantuml",
2655− "puml": "_f_plantuml",
2656− "pck": "_f_plsql_package",
2657− "pkb": "_f_plsql_package_body",
2658− "pkh": "_f_plsql_package_header",
2659− "pks": "_f_plsql_package_spec",
2660− "po": "_f_poedit",
2661− "mo": "_f_poedit",
2662− "postman_collection.json": "_f_postman",
2663− "postman_environment.json": "_f_postman",
2664− "postman_globals.json": "_f_postman",
2665− "pot": "_f_powerpoint",
2666− "potx": "_f_powerpoint",
2667− "potm": "_f_powerpoint",
2668− "pps": "_f_powerpoint",
2669− "ppsx": "_f_powerpoint",
2670− "ppsm": "_f_powerpoint",
2671− "ppt": "_f_powerpoint",
2672− "pptx": "_f_powerpoint",
2673− "pptm": "_f_powerpoint",
2674− "pa": "_f_powerpoint",
2675− "ppa": "_f_powerpoint",
2676− "ppam": "_f_powerpoint",
2677− "sldm": "_f_powerpoint",
2678− "sldx": "_f_powerpoint",
2679− "format.ps1xml": "_f_powershell_format",
2680− "psd1": "_f_powershell_psd",
2681− "psm1": "_f_powershell_psm",
2682− "types.ps1xml": "_f_powershell_types",
2683− "pro": "_f_prolog",
2684− "pub": "_f_publisher",
2685− "puz": "_f_publisher",
2686− "pyowo": "_f_pythowo",
2687− "q": "_f_q",
2688− "qbs": "_f_qbs",
2689− "qvd": "_f_qlikview",
2690− "qvw": "_f_qlikview",
2691− "rast": "_f_ra_syntax_tree",
2692− "rake": "_f_rake",
2693− "rt": "_f_reacttemplate",
2694− "reg": "_f_registry",
2695− "rego": "_f_rego",
2696− "ripple": "_f_ripple",
2697− "rnc": "_f_rnc",
2698− "ron": "_f_ron",
2699− "rproj": "_f_rproj",
2700− "rss": "_f_rss",
2701− "rbs": "_f_ruby",
2702− "safetensors": "_f_safetensors",
2703− "sls": "_f_saltstack",
2704− "sass": "_f_sass",
2705− "scssm": "_f_scss",
2706− "unity": "_f_shaderlab",
2707− "fish": "_f_shell",
2708− "sy": "_f_siyuan",
2709− "sketch": "_f_sketch",
2710− "eskip": "_f_skipper",
2711− "sln": "_f_sln",
2712− "slnx": "_f_sln",
2713− "slnf": "_f_sln",
2714− "spe": "_f_spacengine",
2715− "sqlite": "_f_sqlite",
2716− "sqlite3": "_f_sqlite",
2717− "db3": "_f_sqlite",
2718− "sss": "_f_sss",
2719− "dta": "_f_stata",
2720− "storyboard": "_f_storyboard",
2721− "story.js": "_f_storybook",
2722− "story.jsx": "_f_storybook",
2723− "story.ts": "_f_storybook",
2724− "story.tsx": "_f_storybook",
2725− "story.mdx": "_f_storybook",
2726− "story.svelte": "_f_storybook",
2727− "stories.js": "_f_storybook",
2728− "stories.jsx": "_f_storybook",
2729− "stories.ts": "_f_storybook",
2730− "stories.tsx": "_f_storybook",
2731− "stories.mdx": "_f_storybook",
2732− "stories.svelte": "_f_storybook",
2733− "sublime-project": "_f_sublime",
2734− "svg": "_f_svg",
2735− "tcl": "_f_tcl",
2736− "exp": "_f_tcl",
2737− "templ": "_f_templ",
2738− "tfstate": "_f_terraform",
2739− "tfvars": "_f_terraform",
2740− "tf": "_f_terraform",
2741− "tf.json": "_f_terraform",
2742− "tst": "_f_test",
2743− "test.js": "_f_testjs",
2744− "test.jsx": "_f_testjs",
2745− "test.mjs": "_f_testjs",
2746− "spec.js": "_f_testjs",
2747− "spec.jsx": "_f_testjs",
2748− "spec.mjs": "_f_testjs",
2749− "testplane.ts": "_f_testplane",
2750− "testplane.js": "_f_testplane",
2751− "testplane.cts": "_f_testplane",
2752− "testplane.cjs": "_f_testplane",
2753− "testplane.tsx": "_f_testplane",
2754− "testplane.jsx": "_f_testplane",
2755− "test.ts": "_f_testts",
2756− "test.tsx": "_f_testts",
2757− "test.mts": "_f_testts",
2758− "spec.ts": "_f_testts",
2759− "spec.tsx": "_f_testts",
2760− "spec.mts": "_f_testts",
2761− "e2e-test.ts": "_f_testts",
2762− "e2e-test.tsx": "_f_testts",
2763− "e2e-test.mts": "_f_testts",
2764− "e2e-spec.ts": "_f_testts",
2765− "e2e-spec.tsx": "_f_testts",
2766− "e2e-spec.mts": "_f_testts",
2767− "test-d.ts": "_f_testts",
2768− "test-d.tsx": "_f_testts",
2769− "test-d.mts": "_f_testts",
2770− "texi": "_f_tex",
2771− "tikz": "_f_tex",
2772− "csv": "_f_text",
2773− "tsv": "_f_text",
2774− "tm": "_f_tm",
2775− "tm.hcl": "_f_tm",
2776− "todo": "_f_todo",
2777− "tree": "_f_tree",
2778− "tres": "_f_tres",
2779− "tsbuildinfo": "_f_tsbuildinfo",
2780− "tscn": "_f_tscn",
2781− "tt2": "_f_tt",
2782− "d.ts": "_f_typescriptdef",
2783− "d.cts": "_f_typescriptdef",
2784− "d.mts": "_f_typescriptdef",
2785− "ua": "_f_uiua",
2786− "u": "_f_unison",
2787− "vala": "_f_vala",
2788− "css.ts": "_f_vanilla_extract",
2789− "vapi": "_f_vapi",
2790− "vash": "_f_vash",
2791− "vbhtml": "_f_vbhtml",
2792− "vbproj": "_f_vbproj",
2793− "vcxproj": "_f_vcxproj",
2794− "vto": "_f_vento",
2795− "vento": "_f_vento",
2796− "3g2": "_f_video",
2797− "3gp": "_f_video",
2798− "asf": "_f_video",
2799− "amv": "_f_video",
2800− "avi": "_f_video",
2801− "divx": "_f_video",
2802− "qt": "_f_video",
2803− "f4a": "_f_video",
2804− "f4b": "_f_video",
2805− "f4p": "_f_video",
2806− "f4v": "_f_video",
2807− "flv": "_f_video",
2808− "m2v": "_f_video",
2809− "m4v": "_f_video",
2810− "mkv": "_f_video",
2811− "mk3d": "_f_video",
2812− "mov": "_f_video",
2813− "mp2": "_f_video",
2814− "mp4": "_f_video",
2815− "mpe": "_f_video",
2816− "mpeg": "_f_video",
2817− "mpeg2": "_f_video",
2818− "mpg": "_f_video",
2819− "mpv": "_f_video",
2820− "nsv": "_f_video",
2821− "ogv": "_f_video",
2822− "rm": "_f_video",
2823− "rmvb": "_f_video",
2824− "svi": "_f_video",
2825− "vob": "_f_video",
2826− "webm": "_f_video",
2827− "wmv": "_f_video",
2828− "code-snippets": "_f_vscode",
2829− "code-workspace": "_f_vscode",
2830− "vsix": "_f_vsix",
2831− "vsixmanifest": "_f_vsixmanifest",
2832− "vvvvvv": "_f_vvvvvv",
2833− "vyi": "_f_vyper",
2834− "wasm": "_f_wasm",
2835− "wikitext": "_f_wikitext",
2836− "wit": "_f_wit",
2837− "doc": "_f_word",
2838− "docx": "_f_word",
2839− "docm": "_f_word",
2840− "dot": "_f_word",
2841− "dotx": "_f_word",
2842− "dotm": "_f_word",
2843− "wll": "_f_word",
2844− "wxml": "_f_wxml",
2845− "wxss": "_f_wxss",
2846− "xaml": "_f_xaml",
2847− "axaml": "_f_xaml",
2848− "xcodeproj": "_f_xcode",
2849− "xfl": "_f_xfl",
2850− "xib": "_f_xib",
2851− "xliff": "_f_xliff",
2852− "xlf": "_f_xliff",
2853− "pex": "_f_xml",
2854− "tmlanguage": "_f_xml",
2855− "zip": "_f_zip",
2856− "rar": "_f_zip",
2857− "7z": "_f_zip",
2858− "tar": "_f_zip",
2859− "tgz": "_f_zip",
2860− "bz": "_f_zip",
2861− "gz": "_f_zip",
2862− "bzip2": "_f_zip",
2863− "xz": "_f_zip",
2864− "bz2": "_f_zip",
2865− "whl": "_f_zip",
2866− "zipx": "_f_zip",
2867− "br": "_f_zip"
2868− },
2869− "fileNames": {
2870− "agents.md": "_f_agents",
2871− "alchemy.run.ts": "_f_alchemy",
2872− ".all-contributorsrc": "_f_allcontributors",
2873− "allurerc.js": "_f_allure",
2874− "allurerc.mjs": "_f_allure",
2875− "allurerc.cjs": "_f_allure",
2876− "allurerc.json": "_f_allure",
2877− "allurerc.yaml": "_f_allure",
2878− "allurerc.yml": "_f_allure",
2879− ".angular-cli.json": "_f_angular",
2880− "angular-cli.json": "_f_angular",
2881− "angular.json": "_f_angular",
2882− ".angular.json": "_f_angular",
2883− "antlers.html": "_f_antlers_html",
2884− "api-extractor.json": "_f_api_extractor",
2885− "api-extractor-base.json": "_f_api_extractor",
2886− ".appsemblerc.yaml": "_f_appsemble",
2887− "app-definition.yaml": "_f_appsemble",
2888− "appveyor.yml": "_f_appveyor",
2889− ".appveyor.yml": "_f_appveyor",
2890− "asconfig.json": "_f_assembly_script",
2891− "astro.config.js": "_f_astroconfig",
2892− "astro.config.cjs": "_f_astroconfig",
2893− "astro.config.mjs": "_f_astroconfig",
2894− "astro.config.ts": "_f_astroconfig",
2895− "astro.config.cts": "_f_astroconfig",
2896− "astro.config.mts": "_f_astroconfig",
2897− ".attw.json": "_f_attw",
2898− "aurelia.json": "_f_aurelia",
2899− "azure-pipelines.yml": "_f_azurepipelines",
2900− ".vsts-ci.yml": "_f_azurepipelines",
2901− ".babelrc": "_f_babel",
2902− ".babelignore": "_f_babel",
2903− ".babelrc.js": "_f_babel",
2904− ".babelrc.cjs": "_f_babel",
2905− ".babelrc.mjs": "_f_babel",
2906− ".babelrc.json": "_f_babel",
2907− "babel.config.js": "_f_babel",
2908− "babel.config.cjs": "_f_babel",
2909− "babel.config.mjs": "_f_babel",
2910− "babel.config.json": "_f_babel",
2911− ".bzrignore": "_f_bazaar",
2912− "BUILD.bazel": "_f_bazel",
2913− ".bazelrc": "_f_bazel",
2914− "bazel.rc": "_f_bazel",
2915− "bazel.bazelrc": "_f_bazel",
2916− ".bazelignore": "_f_bazel_ignore",
2917− ".bazelversion": "_f_bazel_version",
2918− "biome.json": "_f_biome",
2919− "biome.jsonc": "_f_biome",
2920− "bitbucket-pipelines.yml": "_f_bitbucketpipeline",
2921− ".bithoundrc": "_f_bithound",
2922− ".bowerrc": "_f_bower",
2923− "bower.json": "_f_bower",
2924− ".browserslistrc": "_f_browserslist",
2925− "browserslist": "_f_browserslist",
2926− ".buckconfig": "_f_buckbuild",
2927− ".bunfig.toml": "_f_bun",
2928− "bunfig.toml": "_f_bunfig",
2929− "bun.lockb": "_f_bun",
2930− "bun.lock": "_f_bun",
2931− ".bundlemonrc": "_f_bundlemon",
2932− "bundlemon.config.js": "_f_bundlemon",
2933− "bundlemon.config.mjs": "_f_bundlemon",
2934− "bundlemon.config.cjs": "_f_bundlemon",
2935− ".bundlemonrc.js": "_f_bundlemon",
2936− ".bundlemonrc.mjs": "_f_bundlemon",
2937− ".bundlemonrc.cjs": "_f_bundlemon",
2938− ".bundlemonrc.json": "_f_bundlemon",
2939− ".bundlemonrc.yaml": "_f_bundlemon",
2940− ".bundlemonrc.yml": "_f_bundlemon",
2941− "gemfile": "_f_bundler",
2942− "gemfile.lock": "_f_bundler",
2943− "capacitor.config.json": "_f_capacitor",
2944− "capacitor.config.ts": "_f_capacitor",
2945− "Cargo.toml": "_f_cargo",
2946− "Cargo.lock": "_f_cargo",
2947− ".changie.yaml": "_f_changie",
2948− ".changie.yml": "_f_changie",
2949− "chefignore": "_f_chef",
2950− "berksfile": "_f_chef",
2951− "berksfile.lock": "_f_chef",
2952− "policyfile.rb": "_f_chef",
2953− "policyfile.lock.json": "_f_chef",
2954− "circle.yml": "_f_circleci",
2955− "claude.md": "_f_claude",
2956− "wrangler.toml": "_f_cloudflare",
2957− ".cfignore": "_f_cloudfoundry",
2958− ".codacy.yml": "_f_codacy",
2959− ".codacy.yaml": "_f_codacy",
2960− ".codeclimate.yml": "_f_codeclimate",
2961− "codecov.yml": "_f_codecov",
2962− ".codecov.yml": "_f_codecov",
2963− "config.codekit": "_f_codekit",
2964− "config.codekit2": "_f_codekit",
2965− "config.codekit3": "_f_codekit",
2966− ".config.codekit": "_f_codekit",
2967− ".config.codekit2": "_f_codekit",
2968− ".config.codekit3": "_f_codekit",
2969− "codemagic.yaml": "_f_codemagic",
2970− "codeowners": "_f_codeowners",
2971− ".coderabbit.yaml": "_f_coderabbit",
2972− "coffeelint.json": "_f_coffeelint",
2973− ".coffeelintignore": "_f_coffeelint",
2974− ".czrc": "_f_commitizen",
2975− ".cz.json": "_f_commitizen",
2976− ".commitlintrc": "_f_commitlint",
2977− "commitlint.config.js": "_f_commitlint",
2978− "commitlint.config.cjs": "_f_commitlint",
2979− "commitlint.config.mjs": "_f_commitlint",
2980− "commitlint.config.ts": "_f_commitlint",
2981− "commitlint.config.cts": "_f_commitlint",
2982− ".commitlintrc.json": "_f_commitlint",
2983− ".commitlintrc.yaml": "_f_commitlint",
2984− ".commitlintrc.yml": "_f_commitlint",
2985− ".commitlintrc.js": "_f_commitlint",
2986− ".commitlintrc.cjs": "_f_commitlint",
2987− ".commitlintrc.mjs": "_f_commitlint",
2988− ".commitlintrc.ts": "_f_commitlint",
2989− ".commitlintrc.cts": "_f_commitlint",
2990− "composer.json": "_f_composer",
2991− "composer.lock": "_f_composer",
2992− "conanfile.txt": "_f_conan",
2993− "conanfile.py": "_f_conan",
2994− ".condarc": "_f_conda",
2995− ".tool-versions": "_f_config",
2996− "copilot-instructions.md": "_f_copilot",
2997− "github-copilot.xml": "_f_copilot",
2998− ".coverage": "_f_coverage",
2999− "lcov.info": "_f_coverage",
3000− ".coveralls.yml": "_f_coveralls",
3001− "craco.config.ts": "_f_craco",
3002− "craco.config.js": "_f_craco",
3003− "craco.config.cjs": "_f_craco",
3004− ".cracorc.ts": "_f_craco",
3005− ".cracorc.js": "_f_craco",
3006− ".cracorc": "_f_craco",
3007− "crowdin.yml": "_f_crowdin",
3008− "cspell.config.json": "_f_cspell",
3009− "cspell.config.js": "_f_cspell",
3010− "cspell.config.mjs": "_f_cspell",
3011− "cspell.config.cjs": "_f_cspell",
3012− "cspell.config.yaml": "_f_cspell",
3013− "cspell.config.yml": "_f_cspell",
3014− "cspell.json": "_f_cspell",
3015− "cspell.js": "_f_cspell",
3016− "cspell.mjs": "_f_cspell",
3017− "cspell.cjs": "_f_cspell",
3018− "cspell.yaml": "_f_cspell",
3019− "cspell.yml": "_f_cspell",
3020− ".cspell.json": "_f_cspell",
3021− ".cspell.js": "_f_cspell",
3022− ".cspell.mjs": "_f_cspell",
3023− ".cspell.cjs": "_f_cspell",
3024− ".cspell.yaml": "_f_cspell",
3025− ".cspell.yml": "_f_cspell",
3026− ".csscomb.json": "_f_csscomb",
3027− ".csslintrc": "_f_csslint",
3028− ".cursorignore": "_f_cursorrules",
3029− ".cursorindexingignore": "_f_cursorrules",
3030− ".cursorrules": "_f_cursorrules",
3031− ".cvsignore": "_f_cvs",
3032− "cypress.json": "_f_cypress",
3033− "cypress.env.json": "_f_cypress",
3034− "cypress.config.js": "_f_cypress",
3035− "cypress.config.ts": "_f_cypress",
3036− "cypress.config.cjs": "_f_cypress",
3037− "cypress.config.mjs": "_f_cypress",
3038− ".boringignore": "_f_darcs",
3039− ".pubignore": "_f_dartlang_ignore",
3040− "service.datadog.yaml": "_f_datadog",
3041− "datadog-ci.json": "_f_datadog",
3042− "static-analysis.datadog.yml": "_f_datadog",
3043− "static-analysis.datadog.yaml": "_f_datadog",
3044− "aptfile": "_f_debian",
3045− "deno.json": "_f_deno",
3046− "deno.jsonc": "_f_deno",
3047− "deno.lock": "_f_deno",
3048− ".denoifyrc": "_f_denoify",
3049− "denoify.config.json": "_f_denoify",
3050− "denoify.config.js": "_f_denoify",
3051− "dependabot.yml": "_f_dependabot",
3052− "dependabot.yaml": "_f_dependabot",
3053− "dependencies.yml": "_f_dependencies",
3054− "devcontainer.json": "_f_devcontainer",
3055− ".devcontainer.json": "_f_devcontainer",
3056− "devvit.json": "_f_devvit",
3057− "devvit.dev.json": "_f_devvit",
3058− "devvit.prod.json": "_f_devvit",
3059− "devvit.test.json": "_f_devvit",
3060− "devvit.config.js": "_f_devvit",
3061− "devvit.config.cjs": "_f_devvit",
3062− "devvit.config.mjs": "_f_devvit",
3063− "devvit.config.ts": "_f_devvit",
3064− "devvit.config.mts": "_f_devvit",
3065− "devvit.config.dev.js": "_f_devvit",
3066− "devvit.config.dev.cjs": "_f_devvit",
3067− "devvit.config.dev.mjs": "_f_devvit",
3068− "devvit.config.dev.ts": "_f_devvit",
3069− "devvit.config.dev.mts": "_f_devvit",
3070− "devvit.config.prod.js": "_f_devvit",
3071− "devvit.config.prod.cjs": "_f_devvit",
3072− "devvit.config.prod.mjs": "_f_devvit",
3073− "devvit.config.prod.ts": "_f_devvit",
3074− "devvit.config.prod.mts": "_f_devvit",
3075− "devvit.config.test.js": "_f_devvit",
3076− "devvit.config.test.cjs": "_f_devvit",
3077− "devvit.config.test.mjs": "_f_devvit",
3078− "devvit.config.test.ts": "_f_devvit",
3079− "devvit.config.test.mts": "_f_devvit",
3080− ".dockerignore": "_f_docker",
3081− "compose.yaml": "_f_docker",
3082− "compose.yml": "_f_docker",
3083− "docker-compose.yaml": "_f_docker",
3084− "docker-compose.yml": "_f_docker",
3085− "docker-compose.debug.yaml": "_f_docker",
3086− "docker-compose.debug.yml": "_f_docker",
3087− "docker-compose.ci-build.yaml": "_f_docker",
3088− "docker-compose.ci-build.yml": "_f_docker",
3089− "docker-compose.override.yaml": "_f_docker",
3090− "docker-compose.override.yml": "_f_docker",
3091− "docker-compose.vs.debug.yaml": "_f_docker",
3092− "docker-compose.vs.debug.yml": "_f_docker",
3093− "docker-compose.vs.release.yaml": "_f_docker",
3094− "docker-compose.vs.release.yml": "_f_docker",
3095− "docker-cloud.yaml": "_f_docker",
3096− "docker-cloud.yml": "_f_docker",
3097− "docker-compose.test.yml": "_f_dockertest",
3098− "docusaurus.config.ts": "_f_docusaurus",
3099− "docusaurus.config.mts": "_f_docusaurus",
3100− "docusaurus.config.cts": "_f_docusaurus",
3101− "docusaurus.config.js": "_f_docusaurus",
3102− "docusaurus.config.mjs": "_f_docusaurus",
3103− "docusaurus.config.cjs": "_f_docusaurus",
3104− ".doczrc": "_f_docz",
3105− "docz.js": "_f_docz",
3106− "docz.json": "_f_docz",
3107− ".docz.js": "_f_docz",
3108− ".docz.json": "_f_docz",
3109− "doczrc.js": "_f_docz",
3110− "doczrc.json": "_f_docz",
3111− "docz.config.js": "_f_docz",
3112− "docz.config.json": "_f_docz",
3113− ".dojorc": "_f_dojo",
3114− "doppler.yaml": "_f_doppler",
3115− "doppler-template.yaml": "_f_doppler",
3116− ".drone.yml": "_f_drone",
3117− ".drone.yml.sig": "_f_drone",
3118− "dune": "_f_dune",
3119− "dune-project": "_f_dune",
3120− "dune-workspace": "_f_dune",
3121− ".dvc": "_f_dvc",
3122− ".earthlyignore": "_f_earthly",
3123− "Earthfile": "_f_earthly",
3124− "store.config.json": "_f_eas-metadata",
3125− ".editorconfig": "_f_editorconfig",
3126− "forge.config.js": "_f_electron",
3127− "forge.config.ts": "_f_electron",
3128− ".eleventy.js": "_f_eleventy",
3129− "eleventy.config.js": "_f_eleventy",
3130− "eleventy.config.cjs": "_f_eleventy",
3131− "eleventy.config.mjs": "_f_eleventy",
3132− "elm-package.json": "_f_elm",
3133− ".ember-cli": "_f_ember",
3134− "emakefile": "_f_erlang",
3135− ".emakerfile": "_f_erlang",
3136− "esbuild.js": "_f_esbuild",
3137− "esbuild.mjs": "_f_esbuild",
3138− "esbuild.cjs": "_f_esbuild",
3139− "esbuild.ts": "_f_esbuild",
3140− "esbuild.config.js": "_f_esbuild",
3141− "esbuild.config.mjs": "_f_esbuild",
3142− "esbuild.config.cjs": "_f_esbuild",
3143− "esbuild.config.ts": "_f_esbuild",
3144− ".eslintrc": "_f_eslint",
3145− ".eslintignore": "_f_eslint",
3146− ".eslintcache": "_f_eslint",
3147− "eslint.config.js": "_f_eslint",
3148− "eslint.config.mjs": "_f_eslint",
3149− "eslint.config.cjs": "_f_eslint",
3150− "eslint.config.ts": "_f_eslint",
3151− "eslint.config.mts": "_f_eslint",
3152− "eslint.config.cts": "_f_eslint",
3153− ".eslintrc.js": "_f_eslint",
3154− ".eslintrc.mjs": "_f_eslint",
3155− ".eslintrc.cjs": "_f_eslint",
3156− ".eslintrc.ts": "_f_eslint",
3157− ".eslintrc.mts": "_f_eslint",
3158− ".eslintrc.cts": "_f_eslint",
3159− ".eslintrc.json": "_f_eslint",
3160− ".eslintrc.yaml": "_f_eslint",
3161− ".eslintrc.yml": "_f_eslint",
3162− "app.json": "_f_expo",
3163− "app.config.js": "_f_expo",
3164− "app.config.json": "_f_expo",
3165− "app.config.json5": "_f_expo",
3166− ".fantasticonrc": "_f_fantasticon",
3167− "fantasticonrc": "_f_fantasticon",
3168− ".fantasticonrc.json": "_f_fantasticon",
3169− "fantasticonrc.json": "_f_fantasticon",
3170− ".fantasticonrc.js": "_f_fantasticon",
3171− "fantasticonrc.js": "_f_fantasticon",
3172− "fastly.toml": "_f_fastly",
3173− ".faunarc": "_f_fauna",
3174− "favicon.ico": "_f_favicon",
3175− ".firebaserc": "_f_firebase",
3176− "firebase.json": "_f_firebasehosting",
3177− "storage.rules": "_f_firebasestorage",
3178− "firestore.rules": "_f_firestore",
3179− "firestore.indexes.json": "_f_firestore",
3180− "flareact.config.js": "_f_flareact",
3181− ".flooignore": "_f_floobits",
3182− ".flowconfig": "_f_flow",
3183− ".flutter-plugins": "_f_flutter",
3184− ".metadata": "_f_flutter",
3185− ".flutter-plugins-dependencies": "_f_flutter",
3186− "pubspec.lock": "_f_flutter_package",
3187− "pubspec.yaml": "_f_flutter_package",
3188− ".packages": "_f_flutter_package",
3189− "fly.toml": "_f_flyio",
3190− "formkit.config.js": "_f_formkit",
3191− "formkit.config.mjs": "_f_formkit",
3192− "formkit.config.cjs": "_f_formkit",
3193− "formkit.config.ts": "_f_formkit",
3194− ".fossaignore": "_f_fossa",
3195− "ignore-glob": "_f_fossil",
3196− ".front-commerce.js": "_f_frontcommerce",
3197− "front-commerce.config.ts": "_f_frontcommerce",
3198− "funding.yml": "_f_funding",
3199− "fuse.js": "_f_fusebox",
3200− "gatsby-browser.js": "_f_gatsby",
3201− "gatsby-browser.ts": "_f_gatsby",
3202− "gatsby-browser.tsx": "_f_gatsby",
3203− "gatsby-ssr.js": "_f_gatsby",
3204− "gatsby-ssr.ts": "_f_gatsby",
3205− "gatsby-ssr.tsx": "_f_gatsby",
3206− "gatsby-config.js": "_f_gatsby",
3207− "gatsby-config.ts": "_f_gatsby",
3208− "gatsby-config.mjs": "_f_gatsby",
3209− "gatsby-node.js": "_f_gatsby",
3210− "gatsby-node.ts": "_f_gatsby",
3211− "gatsby-node.mjs": "_f_gatsby",
3212− ".gcloudignore": "_f_gcloud",
3213− "gemini.md": "_f_gemini",
3214− "GEMINI.md": "_f_gemini",
3215− ".git": "_f_git",
3216− ".gitattributes": "_f_git",
3217− ".gitconfig": "_f_git",
3218− ".gitignore": "_f_git",
3219− ".gitmodules": "_f_git",
3220− ".gitkeep": "_f_git",
3221− ".git-blame-ignore-revs": "_f_git",
3222− ".mailmap": "_f_git",
3223− ".issuetracker": "_f_git",
3224− ".gitlab-ci.yml": "_f_gitlab",
3225− ".gitpod.yaml": "_f_gitpod",
3226− ".gitpod.yml": "_f_gitpod",
3227− "gitpod.yaml": "_f_gitpod",
3228− "gitpod.yml": "_f_gitpod",
3229− "gleam.toml": "_f_gleamconfig",
3230− "glide.yml": "_f_glide",
3231− ".glitterrc": "_f_glitter",
3232− "go.sum": "_f_go_package",
3233− "go.mod": "_f_go_package",
3234− "go.work": "_f_go_work",
3235− "go.work.sum": "_f_go_work",
3236− ".gqlconfig": "_f_graphql",
3237− ".graphqlconfig": "_f_graphql_config",
3238− ".graphqlconfig.yml": "_f_graphql_config",
3239− ".graphqlconfig.yaml": "_f_graphql_config",
3240− "greenkeeper.json": "_f_greenkeeper",
3241− "gridsome.config.js": "_f_gridsome",
3242− "gridsome.config.ts": "_f_gridsome",
3243− "gridsome.server.js": "_f_gridsome",
3244− "gridsome.server.ts": "_f_gridsome",
3245− "gridsome.client.js": "_f_gridsome",
3246− "gridsome.client.ts": "_f_gridsome",
3247− "gruntfile.js": "_f_grunt",
3248− "gruntfile.cjs": "_f_grunt",
3249− "gruntfile.coffee": "_f_grunt",
3250− "gruntfile.ts": "_f_grunt",
3251− "gruntfile.babel.js": "_f_grunt",
3252− "gruntfile.babel.cjs": "_f_grunt",
3253− "gruntfile.babel.coffee": "_f_grunt",
3254− "gruntfile.babel.ts": "_f_grunt",
3255− "gulpfile.js": "_f_gulp",
3256− "gulpfile.coffee": "_f_gulp",
3257− "gulpfile.ts": "_f_gulp",
3258− "gulpfile.mjs": "_f_gulp",
3259− "gulpfile.esm.js": "_f_gulp",
3260− "gulpfile.esm.coffee": "_f_gulp",
3261− "gulpfile.esm.ts": "_f_gulp",
3262− "gulpfile.esm.mjs": "_f_gulp",
3263− "gulpfile.babel.js": "_f_gulp",
3264− "gulpfile.babel.coffee": "_f_gulp",
3265− "gulpfile.babel.ts": "_f_gulp",
3266− "gulpfile.babel.mjs": "_f_gulp",
3267− "hardhat.config.cjs": "_f_hardhat",
3268− "hardhat.config.js": "_f_hardhat",
3269− "hardhat.config.ts": "_f_hardhat",
3270− "haxelib.json": "_f_haxe",
3271− "checkstyle.json": "_f_haxecheckstyle",
3272− ".p4ignore": "_f_helix",
3273− "chart.lock": "_f_helm",
3274− "chart.yaml": "_f_helm",
3275− "histoire.config.ts": "_f_histoire",
3276− "histoire.config.js": "_f_histoire",
3277− ".histoire.ts": "_f_histoire",
3278− ".histoire.js": "_f_histoire",
3279− "horusec-config.json": "_f_horusec",
3280− ".htmlhintrc": "_f_htmlhint",
3281− ".htmlvalidateignore": "_f_htmlvalidate",
3282− ".htmlvalidate.js": "_f_htmlvalidate",
3283− ".htmlvalidate.cjs": "_f_htmlvalidate",
3284− ".htmlvalidate.json": "_f_htmlvalidate",
3285− "hugo.json": "_f_hugo",
3286− "hugo.toml": "_f_hugo",
3287− "hugo.yaml": "_f_hugo",
3288− ".hugo_build.lock": "_f_hugo",
3289− "humans.txt": "_f_humanstxt",
3290− ".huskyrc": "_f_husky",
3291− "husky.config.js": "_f_husky",
3292− ".huskyrc.js": "_f_husky",
3293− ".huskyrc.json": "_f_husky",
3294− ".huskyrc.yaml": "_f_husky",
3295− ".huskyrc.yml": "_f_husky",
3296− "ionic.project": "_f_ionic",
3297− "ionic.config.json": "_f_ionic",
3298− "jakefile": "_f_jake",
3299− "jakefile.js": "_f_jake",
3300− "jasmine.json": "_f_jasmine",
3301− ".nojekyll": "_f_jekyll",
3302− "jest.json": "_f_jest",
3303− "jest.config.babel.js": "_f_jest",
3304− ".jestrc": "_f_jest",
3305− ".jestrc.js": "_f_jest",
3306− ".jestrc.json": "_f_jest",
3307− "jest.config.js": "_f_jest",
3308− "jest.config.cjs": "_f_jest",
3309− "jest.config.mjs": "_f_jest",
3310− "jest.config.json": "_f_jest",
3311− "jest.config.ts": "_f_jest",
3312− "jest.config.base.js": "_f_jest",
3313− "jest.config.base.cjs": "_f_jest",
3314− "jest.config.base.mjs": "_f_jest",
3315− "jest.config.base.json": "_f_jest",
3316− "jest.config.base.ts": "_f_jest",
3317− "jest.config.common.js": "_f_jest",
3318− "jest.config.common.cjs": "_f_jest",
3319− "jest.config.common.mjs": "_f_jest",
3320− "jest.config.common.json": "_f_jest",
3321− "jest.config.common.ts": "_f_jest",
3322− "jest.config.e2e.js": "_f_jest",
3323− "jest.config.e2e.cjs": "_f_jest",
3324− "jest.config.e2e.mjs": "_f_jest",
3325− "jest.config.e2e.json": "_f_jest",
3326− "jest.config.e2e.ts": "_f_jest",
3327− "jest.config.int.js": "_f_jest",
3328− "jest.config.int.cjs": "_f_jest",
3329− "jest.config.int.mjs": "_f_jest",
3330− "jest.config.int.json": "_f_jest",
3331− "jest.config.int.ts": "_f_jest",
3332− "jest.config.integration.js": "_f_jest",
3333− "jest.config.integration.cjs": "_f_jest",
3334− "jest.config.integration.mjs": "_f_jest",
3335− "jest.config.integration.json": "_f_jest",
3336− "jest.config.integration.ts": "_f_jest",
3337− "jest.config.unit.js": "_f_jest",
3338− "jest.config.unit.cjs": "_f_jest",
3339− "jest.config.unit.mjs": "_f_jest",
3340− "jest.config.unit.json": "_f_jest",
3341− "jest.config.unit.ts": "_f_jest",
3342− ".jpmignore": "_f_jpm",
3343− ".jsbeautifyrc": "_f_jsbeautify",
3344− "jsbeautifyrc": "_f_jsbeautify",
3345− ".jsbeautify": "_f_jsbeautify",
3346− "jsbeautify": "_f_jsbeautify",
3347− "jsconfig.json": "_f_jsconfig",
3348− ".jscpd.json": "_f_jscpd",
3349− "jscpd-report.xml": "_f_jscpd",
3350− "jscpd-report.json": "_f_jscpd",
3351− "jscpd-report.html": "_f_jscpd",
3352− ".jshintrc": "_f_jshint",
3353− ".jshintignore": "_f_jshint",
3354− "jsr.json": "_f_jsr",
3355− "karma.conf.js": "_f_karma",
3356− "karma.conf.coffee": "_f_karma",
3357− "karma.conf.ts": "_f_karma",
3358− ".kitchen.yml": "_f_kitchenci",
3359− "kitchen.yml": "_f_kitchenci",
3360− ".kiteignore": "_f_kite",
3361− "knip.json": "_f_knip",
3362− "knip.jsonc": "_f_knip",
3363− ".knip.json": "_f_knip",
3364− ".knip.jsonc": "_f_knip",
3365− "knip.ts": "_f_knip",
3366− "knip.js": "_f_knip",
3367− "knip.config.ts": "_f_knip",
3368− "knip.config.js": "_f_knip",
3369− "language-configuration.json": "_f_language_configuration",
3370− "layout.html": "_f_layout",
3371− "layout.htm": "_f_layout",
3372− "lakefile.lean": "_f_leanconfig",
3373− "lakefile.toml": "_f_leanconfig",
3374− "lake-manifest.json": "_f_leanconfig",
3375− "lean-toolchain": "_f_leanconfig",
3376− "lefthook.json": "_f_lefthook",
3377− "lefthook.toml": "_f_lefthook",
3378− "lefthook.yaml": "_f_lefthook",
3379− "lefthook.yml": "_f_lefthook",
3380− "lefthook-local.json": "_f_lefthook",
3381− "lefthook-local.toml": "_f_lefthook",
3382− "lefthook-local.yaml": "_f_lefthook",
3383− "lefthook-local.yml": "_f_lefthook",
3384− ".lefthook.json": "_f_lefthook",
3385− ".lefthook.toml": "_f_lefthook",
3386− ".lefthook.yaml": "_f_lefthook",
3387− ".lefthook.yml": "_f_lefthook",
3388− ".lefthook-local.json": "_f_lefthook",
3389− ".lefthook-local.toml": "_f_lefthook",
3390− ".lefthook-local.yaml": "_f_lefthook",
3391− ".lefthook-local.yml": "_f_lefthook",
3392− "lerna.json": "_f_lerna",
3393− "liara.json": "_f_liara",
3394− ".liaraignore": "_f_liara",
3395− "licence": "_f_license",
3396− "LICENCE": "_f_license",
3397− "license": "_f_license",
3398− "LICENSE": "_f_license",
3399− "copying": "_f_license",
3400− "copying.lesser": "_f_license",
3401− "LICENSE-MIT": "_f_license",
3402− "license-mit": "_f_license",
3403− "LICENSE-APACHE": "_f_license",
3404− "license-apache": "_f_license",
3405− "LICENSE-GPL": "_f_license",
3406− "license-gpl": "_f_license",
3407− "LICENSE-AGPL": "_f_license",
3408− "license-agpl": "_f_license",
3409− "LICENCE.md": "_f_license",
3410− "LICENCE.txt": "_f_license",
3411− "licence.md": "_f_license",
3412− "licence.txt": "_f_license",
3413− "LICENSE.md": "_f_license",
3414− "LICENSE.txt": "_f_license",
3415− "license.md": "_f_license",
3416− "license.txt": "_f_license",
3417− "copying.md": "_f_license",
3418− "copying.txt": "_f_license",
3419− "copying.lesser.md": "_f_license",
3420− "copying.lesser.txt": "_f_license",
3421− "LICENSE-MIT.md": "_f_license",
3422− "LICENSE-MIT.txt": "_f_license",
3423− "license-mit.md": "_f_license",
3424− "license-mit.txt": "_f_license",
3425− "LICENSE-APACHE.md": "_f_license",
3426− "LICENSE-APACHE.txt": "_f_license",
3427− "license-apache.md": "_f_license",
3428− "license-apache.txt": "_f_license",
3429− "LICENSE-GPL.md": "_f_license",
3430− "LICENSE-GPL.txt": "_f_license",
3431− "license-gpl.md": "_f_license",
3432− "license-gpl.txt": "_f_license",
3433− "LICENSE-AGPL.md": "_f_license",
3434− "LICENSE-AGPL.txt": "_f_license",
3435− "license-agpl.md": "_f_license",
3436− "license-agpl.txt": "_f_license",
3437− ".licrc": "_f_licensebat",
3438− "budget.json": "_f_lighthouse",
3439− "budgets.json": "_f_lighthouse",
3440− ".lighthouserc.cjs": "_f_lighthouse",
3441− ".lighthouserc.js": "_f_lighthouse",
3442− ".lighthouserc.json": "_f_lighthouse",
3443− ".lighthouserc.yaml": "_f_lighthouse",
3444− ".lighthouserc.yml": "_f_lighthouse",
3445− "include.xml": "_f_lime",
3446− ".lintstagedrc": "_f_lintstagedrc",
3447− ".lintstagedrc.json": "_f_lintstagedrc",
3448− ".lintstagedrc.yaml": "_f_lintstagedrc",
3449− ".lintstagedrc.yml": "_f_lintstagedrc",
3450− ".lintstagedrc.mjs": "_f_lintstagedrc",
3451− ".lintstagedrc.mts": "_f_lintstagedrc",
3452− ".lintstagedrc.js": "_f_lintstagedrc",
3453− ".lintstagedrc.ts": "_f_lintstagedrc",
3454− ".lintstagedrc.cjs": "_f_lintstagedrc",
3455− ".lintstagedrc.cts": "_f_lintstagedrc",
3456− "lint-staged.config.mjs": "_f_lintstagedrc",
3457− "lint-staged.config.mts": "_f_lintstagedrc",
3458− "lint-staged.config.js": "_f_lintstagedrc",
3459− "lint-staged.config.ts": "_f_lintstagedrc",
3460− "lint-staged.config.cjs": "_f_lintstagedrc",
3461− "lint-staged.config.cts": "_f_lintstagedrc",
3462− "mailing.config.json": "_f_mailing",
3463− "manifest": "_f_manifest",
3464− "manifest.bak": "_f_manifest_bak",
3465− "manifest.skip": "_f_manifest_skip",
3466− ".markdownlintrc": "_f_markdownlint",
3467− ".markdownlint.json": "_f_markdownlint",
3468− ".markdownlint.jsonc": "_f_markdownlint",
3469− ".markdownlint.yml": "_f_markdownlint",
3470− ".markdownlint.yaml": "_f_markdownlint",
3471− ".markdownlint.cjs": "_f_markdownlint",
3472− ".markdownlint-cli2.json": "_f_markdownlint",
3473− ".markdownlint-cli2.jsonc": "_f_markdownlint",
3474− ".markdownlint-cli2.yml": "_f_markdownlint",
3475− ".markdownlint-cli2.yaml": "_f_markdownlint",
3476− ".markdownlint-cli2.cjs": "_f_markdownlint",
3477− ".markdownlintignore": "_f_markdownlint_ignore",
3478− ".markuplintrc": "_f_markuplint",
3479− ".markuplintrc.json": "_f_markuplint",
3480− ".markuplintrc.yaml": "_f_markuplint",
3481− ".markuplintrc.yml": "_f_markuplint",
3482− ".markuplintrc.js": "_f_markuplint",
3483− ".markuplintrc.cjs": "_f_markuplint",
3484− ".markuplintrc.mjs": "_f_markuplint",
3485− ".markuplintrc.ts": "_f_markuplint",
3486− "markuplint.config.json": "_f_markuplint",
3487− "markuplint.config.yaml": "_f_markuplint",
3488− "markuplint.config.yml": "_f_markuplint",
3489− "markuplint.config.js": "_f_markuplint",
3490− "markuplint.config.cjs": "_f_markuplint",
3491− "markuplint.config.mjs": "_f_markuplint",
3492− "markuplint.config.ts": "_f_markuplint",
3493− "master.js": "_f_master-co",
3494− "master.ts": "_f_master-co",
3495− "master.mjs": "_f_master-co",
3496− "master.json": "_f_master-co",
3497− "master.css.js": "_f_master-co",
3498− "master.css.ts": "_f_master-co",
3499− "master.css.mjs": "_f_master-co",
3500− "master.css.json": "_f_master-co",
3501− "maven.config": "_f_maven",
3502− "pom.xml": "_f_maven",
3503− "extensions.xml": "_f_maven",
3504− "settings.xml": "_f_maven",
3505− "mcp.json": "_f_mcp",
3506− "mdx-components.cjs": "_f_mdx-components",
3507− "mdx-components.cts": "_f_mdx-components",
3508− "mdx-components.js": "_f_mdx-components",
3509− "mdx-components.jsx": "_f_mdx-components",
3510− "mdx-components.mjs": "_f_mdx-components",
3511− "mdx-components.mts": "_f_mdx-components",
3512− "mdx-components.ts": "_f_mdx-components",
3513− "mdx-components.tsx": "_f_mdx-components",
3514− ".mdxlintrc": "_f_mdxlint",
3515− ".mdxlintignore": "_f_mdxlint",
3516− ".mdxlintrc.cjs": "_f_mdxlint",
3517− ".mdxlintrc.js": "_f_mdxlint",
3518− ".mdxlintrc.json": "_f_mdxlint",
3519− ".mdxlintrc.mjs": "_f_mdxlint",
3520− ".mdxlintrc.yml": "_f_mdxlint",
3521− ".mdxlintrc.yaml": "_f_mdxlint",
3522− ".hgignore": "_f_mercurial",
3523− "mocha.opts": "_f_mocha",
3524− ".mocharc.cjs": "_f_mocha",
3525− ".mocharc.js": "_f_mocha",
3526− ".mocharc.json": "_f_mocha",
3527− ".mocharc.jsonc": "_f_mocha",
3528− ".mocharc.mjs": "_f_mocha",
3529− ".mocharc.yaml": "_f_mocha",
3530− ".mocharc.yml": "_f_mocha",
3531− "modernizr": "_f_modernizr",
3532− "modernizr.js": "_f_modernizr",
3533− "modernizrrc.js": "_f_modernizr",
3534− ".modernizr.js": "_f_modernizr",
3535− ".modernizrrc.js": "_f_modernizr",
3536− "moleculer.config.js": "_f_moleculer",
3537− "moleculer.config.json": "_f_moleculer",
3538− "moleculer.config.ts": "_f_moleculer",
3539− ".mtn-ignore": "_f_monotone",
3540− "motif.json": "_f_motif",
3541− "mypy.ini": "_f_mypy",
3542− ".mypy.ini": "_f_mypy",
3543− ".nano-staged.js": "_f_nanostaged",
3544− "nano-staged.js": "_f_nanostaged",
3545− ".nano-staged.cjs": "_f_nanostaged",
3546− "nano-staged.cjs": "_f_nanostaged",
3547− ".nano-staged.mjs": "_f_nanostaged",
3548− "nano-staged.mjs": "_f_nanostaged",
3549− ".nano-staged.json": "_f_nanostaged",
3550− "nano-staged.json": "_f_nanostaged",
3551− ".nanostagedrc": "_f_nanostaged",
3552− ".nest-cli.json": "_f_nestjs",
3553− "nest-cli.json": "_f_nestjs",
3554− "nestconfig.json": "_f_nestjs",
3555− ".nestconfig.json": "_f_nestjs",
3556− "netlify.toml": "_f_netlify",
3557− "next.config.js": "_f_next",
3558− "next.config.cjs": "_f_next",
3559− "next.config.mjs": "_f_next",
3560− "next.config.ts": "_f_next",
3561− ".nf": "_f_nextflow",
3562− "ng-tailwind.js": "_f_ng_tailwind",
3563− "nginx.conf": "_f_nginx",
3564− "build.ninja": "_f_ninja",
3565− "flake.lock": "_f_nix",
3566− ".node-version": "_f_node",
3567− ".nvmrc": "_f_node",
3568− "node.config.json": "_f_node",
3569− "nodemon.json": "_f_nodemon",
3570− ".npmignore": "_f_npm",
3571− ".npmrc": "_f_npm",
3572− ".package-lock.json": "_f_npm",
3573− "package.json": "_f_npm",
3574− "package-lock.json": "_f_npm",
3575− "npm-shrinkwrap.json": "_f_npm",
3576− ".npmpackagejsonlintrc": "_f_npmpackagejsonlint",
3577− ".npmpackagejsonlintrc.cjs": "_f_npmpackagejsonlint",
3578− ".npmpackagejsonlintrc.js": "_f_npmpackagejsonlint",
3579− ".npmpackagejsonlintrc.json": "_f_npmpackagejsonlint",
3580− ".npmpackagejsonlintrc.yaml": "_f_npmpackagejsonlint",
3581− ".npmpackagejsonlintrc.yml": "_f_npmpackagejsonlint",
3582− ".npmpackagejsonlintrc.mjs": "_f_npmpackagejsonlint",
3583− ".npmpackagejsonlintignore": "_f_npmpackagejsonlint",
3584− "npmpackagejsonlint.config.cjs": "_f_npmpackagejsonlint",
3585− "npmpackagejsonlint.config.js": "_f_npmpackagejsonlint",
3586− "npmpackagejsonlint.config.mjs": "_f_npmpackagejsonlint",
3587− ".nsrirc": "_f_nsri",
3588− ".nsriignore": "_f_nsri",
3589− "nsri.config.js": "_f_nsri",
3590− ".nsrirc.js": "_f_nsri",
3591− ".nsrirc.json": "_f_nsri",
3592− ".nsrirc.yaml": "_f_nsri",
3593− ".nsrirc.yml": "_f_nsri",
3594− ".integrity.json": "_f_nsri-integrity",
3595− ".nuxtignore": "_f_nuxt",
3596− ".nuxtrc": "_f_nuxt",
3597− "nuxt.config.js": "_f_nuxt",
3598− "nuxt.config.ts": "_f_nuxt",
3599− "nuxt.config.mjs": "_f_nuxt",
3600− "nuxt.js": "_f_nuxt",
3601− "nuxt.ts": "_f_nuxt",
3602− "nuxt.mjs": "_f_nuxt",
3603− "nx.json": "_f_nx",
3604− ".nycrc": "_f_nyc",
3605− ".nycrc.json": "_f_nyc",
3606− ".objidconfig": "_f_objidconfig",
3607− ".merlin": "_f_ocaml",
3608− ".oxlintignore": "_f_oxc",
3609− ".oxlintrc.json": "_f_oxc",
3610− ".oxlintrc.jsonc": "_f_oxc",
3611− ".oxfmtrc.json": "_f_oxc",
3612− ".oxfmtrc.jsonc": "_f_oxc",
3613− ".packshiprc": "_f_packship",
3614− ".packshiprc.json": "_f_packship",
3615− ".packshiprc.js": "_f_packship",
3616− ".packshiprc.ts": "_f_packship",
3617− "packship.config.js": "_f_packship",
3618− "packship.config.ts": "_f_packship",
3619− "packship.config.mjs": "_f_packship",
3620− "packship.config.mts": "_f_packship",
3621− "packship.config.json": "_f_packship",
3622− "paket.dependencies": "_f_paket",
3623− "paket.lock": "_f_paket",
3624− "paket.references": "_f_paket",
3625− "paket.template": "_f_paket",
3626− "paket.local": "_f_paket",
3627− "panda.config.js": "_f_pandacss",
3628− "panda.config.mjs": "_f_pandacss",
3629− "panda.config.ts": "_f_pandacss",
3630− ".pdm-python": "_f_pdm",
3631− "pdm.lock": "_f_pdm",
3632− "pdm.toml": "_f_pdm",
3633− "peeky.config.ts": "_f_peeky",
3634− "peeky.config.js": "_f_peeky",
3635− "peeky.config.mjs": "_f_peeky",
3636− ".php-cs-fixer.php": "_f_phpcsfixer",
3637− ".php-cs-fixer.dist.php": "_f_phpcsfixer",
3638− ".php_cs": "_f_phpcsfixer",
3639− ".php_cs.dist": "_f_phpcsfixer",
3640− "phpstan.neon": "_f_phpstan",
3641− "phpstan.dist.neon": "_f_phpstan",
3642− "phpunit": "_f_phpunit",
3643− "phpunit.xml": "_f_phpunit",
3644− "phpunit.xml.dist": "_f_phpunit",
3645− ".phraseapp.yml": "_f_phraseapp",
3646− "pipfile": "_f_pip",
3647− "pipfile.lock": "_f_pip",
3648− "platformio.ini": "_f_platformio",
3649− "playwright.config.js": "_f_playwright",
3650− "playwright.config.ts": "_f_playwright",
3651− "playwright.config.mts": "_f_playwright",
3652− "playwright.config.mjs": "_f_playwright",
3653− "playwright.config.cts": "_f_playwright",
3654− "playwright.config.cjs": "_f_playwright",
3655− "ecosystem.config.js": "_f_pm2",
3656− "ecosystem.config.cjs": "_f_pm2",
3657− "ecosystem.config.json": "_f_pm2",
3658− "ecosystem.config.yaml": "_f_pm2",
3659− "ecosystem.config.yml": "_f_pm2",
3660− ".pnpmfile.cjs": "_f_pnpm",
3661− "pnpmfile.js": "_f_pnpm",
3662− "pnpm-lock.yaml": "_f_pnpm",
3663− "pnpm-workspace.yaml": "_f_pnpm",
3664− "poetry.lock": "_f_poetry",
3665− ".postcssrc": "_f_postcssconfig",
3666− ".postcssrc.json": "_f_postcssconfig",
3667− ".postcssrc.yaml": "_f_postcssconfig",
3668− ".postcssrc.yml": "_f_postcssconfig",
3669− ".postcssrc.ts": "_f_postcssconfig",
3670− ".postcssrc.cts": "_f_postcssconfig",
3671− ".postcssrc.mts": "_f_postcssconfig",
3672− ".postcssrc.js": "_f_postcssconfig",
3673− ".postcssrc.cjs": "_f_postcssconfig",
3674− ".postcssrc.mjs": "_f_postcssconfig",
3675− "postcss.config.ts": "_f_postcssconfig",
3676− "postcss.config.cts": "_f_postcssconfig",
3677− "postcss.config.mts": "_f_postcssconfig",
3678− "postcss.config.js": "_f_postcssconfig",
3679− "postcss.config.cjs": "_f_postcssconfig",
3680− "postcss.config.mjs": "_f_postcssconfig",
3681− "preact.config.js": "_f_preact",
3682− ".pre-commit-config.yaml": "_f_precommit",
3683− ".prettierrc": "_f_prettier",
3684− ".prettierignore": "_f_prettier",
3685− "prettier.config.js": "_f_prettier",
3686− "prettier.config.cjs": "_f_prettier",
3687− "prettier.config.mjs": "_f_prettier",
3688− "prettier.config.ts": "_f_prettier",
3689− "prettier.config.coffee": "_f_prettier",
3690− ".prettierrc.js": "_f_prettier",
3691− ".prettierrc.cjs": "_f_prettier",
3692− ".prettierrc.mjs": "_f_prettier",
3693− ".prettierrc.json": "_f_prettier",
3694− ".prettierrc.json5": "_f_prettier",
3695− ".prettierrc.yml": "_f_prettier",
3696− ".prettierrc.yaml": "_f_prettier",
3697− ".prettierrc.toml": "_f_prettier",
3698− "prisma.config.js": "_f_prismaconfig",
3699− "prisma.config.ts": "_f_prismaconfig",
3700− "procfile": "_f_procfile",
3701− "protractor.conf.js": "_f_protractor",
3702− "protractor.conf.coffee": "_f_protractor",
3703− "protractor.conf.ts": "_f_protractor",
3704− "publiccode.yml": "_f_publiccode",
3705− ".jade-lintrc": "_f_pug",
3706− ".pug-lintrc": "_f_pug",
3707− ".jade-lint.json": "_f_pug",
3708− ".pug-lintrc.js": "_f_pug",
3709− ".pug-lintrc.json": "_f_pug",
3710− "Pulumi.yaml": "_f_pulumi",
3711− "Pulumi.yml": "_f_pulumi",
3712− "Pulumi.dev.yaml": "_f_pulumi",
3713− "Pulumi.dev.yml": "_f_pulumi",
3714− "Pulumi.prod.yaml": "_f_pulumi",
3715− "Pulumi.prod.yml": "_f_pulumi",
3716− "purgecss.config.js": "_f_purgecss",
3717− ".python-version": "_f_pyenv",
3718− "pyproject.toml": "_f_pypi",
3719− "pytest.ini": "_f_pytest",
3720− ".pytest.ini": "_f_pytest",
3721− "pytest.toml": "_f_pytest",
3722− ".pytest.toml": "_f_pytest",
3723− "py.typed": "_f_pytyped",
3724− ".pyup": "_f_pyup",
3725− ".pyup.yml": "_f_pyup",
3726− "qmldir": "_f_qmldir",
3727− "quasar.conf.js": "_f_quasar",
3728− "quasar.config.js": "_f_quasar",
3729− "quasar.config.mjs": "_f_quasar",
3730− "quasar.config.cjs": "_f_quasar",
3731− "quasar.config.ts": "_f_quasar",
3732− "Rakefile": "_f_rake",
3733− "razzle.config.js": "_f_razzle",
3734− "react-router.config.js": "_f_reactrouter",
3735− "react-router.config.ts": "_f_reactrouter",
3736− ".rehyperc": "_f_rehype",
3737− ".rehypeignore": "_f_rehype",
3738− ".rehyperc.cjs": "_f_rehype",
3739− ".rehyperc.js": "_f_rehype",
3740− ".rehyperc.json": "_f_rehype",
3741− ".rehyperc.mjs": "_f_rehype",
3742− ".rehyperc.yml": "_f_rehype",
3743− ".rehyperc.yaml": "_f_rehype",
3744− ".remarkrc": "_f_remark",
3745− ".remarkignore": "_f_remark",
3746− ".remarkrc.cjs": "_f_remark",
3747− ".remarkrc.js": "_f_remark",
3748− ".remarkrc.json": "_f_remark",
3749− ".remarkrc.mjs": "_f_remark",
3750− ".remarkrc.yml": "_f_remark",
3751− ".remarkrc.yaml": "_f_remark",
3752− ".renovaterc": "_f_renovate",
3753− ".renovaterc.json": "_f_renovate",
3754− "renovate.json": "_f_renovate",
3755− "renovate.json5": "_f_renovate",
3756− ".replit": "_f_replit",
3757− "replit.nix": "_f_replit",
3758− ".retextrc": "_f_retext",
3759− ".retextignore": "_f_retext",
3760− ".retextrc.cjs": "_f_retext",
3761− ".retextrc.js": "_f_retext",
3762− ".retextrc.json": "_f_retext",
3763− ".retextrc.mjs": "_f_retext",
3764− ".retextrc.yml": "_f_retext",
3765− ".retextrc.yaml": "_f_retext",
3766− "robots.txt": "_f_robots",
3767− "rolldown.config.js": "_f_rolldown",
3768− "rolldown.config.cjs": "_f_rolldown",
3769− "rolldown.config.mjs": "_f_rolldown",
3770− "rolldown.config.coffee": "_f_rolldown",
3771− "rolldown.config.ts": "_f_rolldown",
3772− "rolldown.config.mts": "_f_rolldown",
3773− "rolldown.config.cts": "_f_rolldown",
3774− "rolldown.config.common.js": "_f_rolldown",
3775− "rolldown.config.common.cjs": "_f_rolldown",
3776− "rolldown.config.common.mjs": "_f_rolldown",
3777− "rolldown.config.common.coffee": "_f_rolldown",
3778− "rolldown.config.common.ts": "_f_rolldown",
3779− "rolldown.config.common.mts": "_f_rolldown",
3780− "rolldown.config.common.cts": "_f_rolldown",
3781− "rolldown.config.dev.js": "_f_rolldown",
3782− "rolldown.config.dev.cjs": "_f_rolldown",
3783− "rolldown.config.dev.mjs": "_f_rolldown",
3784− "rolldown.config.dev.coffee": "_f_rolldown",
3785− "rolldown.config.dev.ts": "_f_rolldown",
3786− "rolldown.config.dev.mts": "_f_rolldown",
3787− "rolldown.config.dev.cts": "_f_rolldown",
3788− "rolldown.config.prod.js": "_f_rolldown",
3789− "rolldown.config.prod.cjs": "_f_rolldown",
3790− "rolldown.config.prod.mjs": "_f_rolldown",
3791− "rolldown.config.prod.coffee": "_f_rolldown",
3792− "rolldown.config.prod.ts": "_f_rolldown",
3793− "rolldown.config.prod.mts": "_f_rolldown",
3794− "rolldown.config.prod.cts": "_f_rolldown",
3795− "rollup.config.js": "_f_rollup",
3796− "rollup.config.cjs": "_f_rollup",
3797− "rollup.config.mjs": "_f_rollup",
3798− "rollup.config.coffee": "_f_rollup",
3799− "rollup.config.ts": "_f_rollup",
3800− "rollup.config.common.js": "_f_rollup",
3801− "rollup.config.common.cjs": "_f_rollup",
3802− "rollup.config.common.mjs": "_f_rollup",
3803− "rollup.config.common.coffee": "_f_rollup",
3804− "rollup.config.common.ts": "_f_rollup",
3805− "rollup.config.dev.js": "_f_rollup",
3806− "rollup.config.dev.cjs": "_f_rollup",
3807− "rollup.config.dev.mjs": "_f_rollup",
3808− "rollup.config.dev.coffee": "_f_rollup",
3809− "rollup.config.dev.ts": "_f_rollup",
3810− "rollup.config.prod.js": "_f_rollup",
3811− "rollup.config.prod.cjs": "_f_rollup",
3812− "rollup.config.prod.mjs": "_f_rollup",
3813− "rollup.config.prod.coffee": "_f_rollup",
3814− "rollup.config.prod.ts": "_f_rollup",
3815− "rome.json": "_f_rome",
3816− ".rspec": "_f_rspec",
3817− ".rubocop.yml": "_f_rubocop",
3818− ".rubocop_todo.yml": "_f_rubocop",
3819− ".ruby-version": "_f_ruby",
3820− "rust-toolchain": "_f_rust_toolchain",
3821− "rust-toolchain.toml": "_f_rust_toolchain",
3822− ".slshrc": "_f_s-lang",
3823− ".isisrc": "_f_s-lang",
3824− ".jedrc": "_f_s-lang",
3825− ".sailsrc": "_f_sails",
3826− ".sapphirerc.json": "_f_sapphire_framework_cli",
3827− ".sapphirerc.yml": "_f_sapphire_framework_cli",
3828− ".sapphirerc": "_f_sapphire_framework_cli",
3829− "seedkit.config.js": "_f_seedkit",
3830− "seedkit.config.ts": "_f_seedkit",
3831− "seedkit.config.mjs": "_f_seedkit",
3832− ".sentryclirc": "_f_sentry",
3833− ".sequelizerc": "_f_sequelize",
3834− ".sequelizerc.js": "_f_sequelize",
3835− ".sequelizerc.json": "_f_sequelize",
3836− "serverless.yml": "_f_serverless",
3837− "serverless.json": "_f_serverless",
3838− "serverless.js": "_f_serverless",
3839− "serverless.ts": "_f_serverless",
3840− "components.json": "_f_shadcn",
3841− ".shellcheckrc": "_f_shellcheck",
3842− "Shuttle.toml": "_f_shuttle",
3843− "sitemap.xml": "_f_sitemap",
3844− "sitemap.rss": "_f_sitemap",
3845− "sitemap.txt": "_f_sitemap",
3846− "sitemap.atom": "_f_sitemap",
3847− "slash-up.config.js": "_f_slashup",
3848− "smithery.yaml": "_f_smithery",
3849− "snapcraft.yaml": "_f_snapcraft",
3850− "snaplet.config.js": "_f_snaplet",
3851− "snaplet.config.ts": "_f_snaplet",
3852− ".snyk": "_f_snyk",
3853− ".solidarity": "_f_solidarity",
3854− ".solidarity.json": "_f_solidarity",
3855− "spin.toml": "_f_spin",
3856− "sst-env.d.ts": "_f_sst",
3857− "sst-env.ts": "_f_sst",
3858− "sst-env.js": "_f_sst",
3859− "sst.config.d.ts": "_f_sst",
3860− "sst.config.ts": "_f_sst",
3861− "sst.config.js": "_f_sst",
3862− ".stackblitzrc": "_f_stackblitz",
3863− "stryker.conf.mjs": "_f_stryker",
3864− "stryker.conf.cjs": "_f_stryker",
3865− "stryker.conf.js": "_f_stryker",
3866− "stryker.conf.conf": "_f_stryker",
3867− "stryker.conf.json": "_f_stryker",
3868− ".stryker.conf.mjs": "_f_stryker",
3869− ".stryker.conf.cjs": "_f_stryker",
3870− ".stryker.conf.js": "_f_stryker",
3871− ".stryker.conf.conf": "_f_stryker",
3872− ".stryker.conf.json": "_f_stryker",
3873− "stryker.config.mjs": "_f_stryker",
3874− "stryker.config.cjs": "_f_stryker",
3875− "stryker.config.js": "_f_stryker",
3876− "stryker.config.conf": "_f_stryker",
3877− "stryker.config.json": "_f_stryker",
3878− ".stryker.config.mjs": "_f_stryker",
3879− ".stryker.config.cjs": "_f_stryker",
3880− ".stryker.config.js": "_f_stryker",
3881− ".stryker.config.conf": "_f_stryker",
3882− ".stryker.config.json": "_f_stryker",
3883− "stryker-config.mjs": "_f_stryker",
3884− "stryker-config.cjs": "_f_stryker",
3885− "stryker-config.js": "_f_stryker",
3886− "stryker-config.conf": "_f_stryker",
3887− "stryker-config.json": "_f_stryker",
3888− "stryker4s.mjs": "_f_stryker",
3889− "stryker4s.cjs": "_f_stryker",
3890− "stryker4s.js": "_f_stryker",
3891− "stryker4s.conf": "_f_stryker",
3892− "stryker4s.json": "_f_stryker",
3893− ".stylelintrc": "_f_stylelint",
3894− ".stylelintignore": "_f_stylelint",
3895− ".stylelintcache": "_f_stylelint",
3896− "stylelint.config.js": "_f_stylelint",
3897− "stylelint.config.json": "_f_stylelint",
3898− "stylelint.config.yaml": "_f_stylelint",
3899− "stylelint.config.yml": "_f_stylelint",
3900− "stylelint.config.ts": "_f_stylelint",
3901− "stylelint.config.cjs": "_f_stylelint",
3902− "stylelint.config.mjs": "_f_stylelint",
3903− ".stylelintrc.js": "_f_stylelint",
3904− ".stylelintrc.json": "_f_stylelint",
3905− ".stylelintrc.yaml": "_f_stylelint",
3906− ".stylelintrc.yml": "_f_stylelint",
3907− ".stylelintrc.ts": "_f_stylelint",
3908− ".stylelintrc.cjs": "_f_stylelint",
3909− ".stylelintrc.mjs": "_f_stylelint",
3910− ".stylish-haskell.yaml": "_f_stylish_haskell",
3911− ".svnignore": "_f_subversion",
3912− "svelte.config.js": "_f_svelteconfig",
3913− "svelte.config.ts": "_f_svelteconfig",
3914− "svgo.config.cjs": "_f_svgo",
3915− "svgo.config.js": "_f_svgo",
3916− "svgo.config.mjs": "_f_svgo",
3917− ".swcrc": "_f_swc",
3918− "package.pins": "_f_swift",
3919− "symfony.lock": "_f_symfony",
3920− ".syncpackrc": "_f_syncpack",
3921− ".syncpackrc.json": "_f_syncpack",
3922− ".syncpackrc.yaml": "_f_syncpack",
3923− ".syncpackrc.yml": "_f_syncpack",
3924− ".syncpackrc.js": "_f_syncpack",
3925− ".syncpackrc.cjs": "_f_syncpack",
3926− "syncpack.config.js": "_f_syncpack",
3927− "syncpack.config.cjs": "_f_syncpack",
3928− "tailwind.js": "_f_tailwind",
3929− "tailwind.cjs": "_f_tailwind",
3930− "tailwind.coffee": "_f_tailwind",
3931− "tailwind.ts": "_f_tailwind",
3932− "tailwind.json": "_f_tailwind",
3933− "tailwind.mjs": "_f_tailwind",
3934− "tailwind.config.js": "_f_tailwind",
3935− "tailwind.config.cjs": "_f_tailwind",
3936− "tailwind.config.coffee": "_f_tailwind",
3937− "tailwind.config.ts": "_f_tailwind",
3938− "tailwind.config.json": "_f_tailwind",
3939− "tailwind.config.mjs": "_f_tailwind",
3940− ".tailwind.js": "_f_tailwind",
3941− ".tailwind.cjs": "_f_tailwind",
3942− ".tailwind.coffee": "_f_tailwind",
3943− ".tailwind.ts": "_f_tailwind",
3944− ".tailwind.json": "_f_tailwind",
3945− ".tailwind.mjs": "_f_tailwind",
3946− ".tailwindrc.js": "_f_tailwind",
3947− ".tailwindrc.cjs": "_f_tailwind",
3948− ".tailwindrc.coffee": "_f_tailwind",
3949− ".tailwindrc.ts": "_f_tailwind",
3950− ".tailwindrc.json": "_f_tailwind",
3951− ".tailwindrc.mjs": "_f_tailwind",
3952− "tamagui.js": "_f_tamagui",
3953− "tamagui.mjs": "_f_tamagui",
3954− "tamagui.cjs": "_f_tamagui",
3955− "tamagui.ts": "_f_tamagui",
3956− "tamagui.mts": "_f_tamagui",
3957− "tamagui.cts": "_f_tamagui",
3958− "tamagui.config.js": "_f_tamagui",
3959− "tamagui.config.mjs": "_f_tamagui",
3960− "tamagui.config.cjs": "_f_tamagui",
3961− "tamagui.config.ts": "_f_tamagui",
3962− "tamagui.config.mts": "_f_tamagui",
3963− "tamagui.config.cts": "_f_tamagui",
3964− ".taplo.toml": "_f_taplo",
3965− "taplo.toml": "_f_taplo",
3966− "taskfile.yml": "_f_taskfile",
3967− "taskfile.yaml": "_f_taskfile",
3968− "taskfile.dist.yml": "_f_taskfile",
3969− "taskfile.dist.yaml": "_f_taskfile",
3970− "tauri.conf.json": "_f_tauri",
3971− ".taurignore": "_f_tauri",
3972− ".testcaferc.json": "_f_testcafe",
3973− "testplane.conf.ts": "_f_testplane",
3974− "testplane.conf.js": "_f_testplane",
3975− "testplane.conf.cts": "_f_testplane",
3976− "testplane.conf.cjs": "_f_testplane",
3977− "testplane.config.ts": "_f_testplane",
3978− "testplane.config.js": "_f_testplane",
3979− "testplane.config.cts": "_f_testplane",
3980− "testplane.config.cjs": "_f_testplane",
3981− ".tfignore": "_f_tfs",
3982− ".tiltignore": "_f_tiltfile",
3983− ".tmux.conf": "_f_tmux",
3984− "tox.ini": "_f_tox",
3985− ".travis.yml": "_f_travis",
3986− "truffle-config.js": "_f_truffle",
3987− "truffle-config.ts": "_f_truffle",
3988− "trunk.yaml": "_f_trunk",
3989− "tsconfig.json": "_f_tsconfig",
3990− "tsconfig.app.json": "_f_tsconfig",
3991− "tsconfig.base.json": "_f_tsconfig",
3992− "tsconfig.build.json": "_f_tsconfig",
3993− "tsconfig.cjs.json": "_f_tsconfig",
3994− "tsconfig.common.json": "_f_tsconfig",
3995− "tsconfig.debug.json": "_f_tsconfig",
3996− "tsconfig.dev.json": "_f_tsconfig",
3997− "tsconfig.development.json": "_f_tsconfig",
3998− "tsconfig.e2e.json": "_f_tsconfig",
3999− "tsconfig.eslint.json": "_f_tsconfig",
4000− "tsconfig.esm.json": "_f_tsconfig",
4001− "tsconfig.mjs.json": "_f_tsconfig",
4002− "tsconfig.node.json": "_f_tsconfig",
4003− "tsconfig.prod.json": "_f_tsconfig",
4004− "tsconfig.production.json": "_f_tsconfig",
4005− "tsconfig.release.json": "_f_tsconfig",
4006− "tsconfig.server.json": "_f_tsconfig",
4007− "tsconfig.spec.json": "_f_tsconfig",
4008− "tsconfig.staging.json": "_f_tsconfig",
4009− "tsconfig.test.json": "_f_tsconfig",
4010− "tsconfig.types.json": "_f_tsconfig",
4011− "tsconfig.lib.json": "_f_tsconfig",
4012− "tsconfig.lib.prod.json": "_f_tsconfig",
4013− "tsdoc.json": "_f_tsdoc",
4014− "tsdown.config.ts": "_f_tsdown",
4015− "tsdown.config.mts": "_f_tsdown",
4016− "tsdown.config.cts": "_f_tsdown",
4017− "tsdown.config.js": "_f_tsdown",
4018− "tsdown.config.mjs": "_f_tsdown",
4019− "tsdown.config.cjs": "_f_tsdown",
4020− "tsdown.config.json": "_f_tsdown",
4021− "tslint.json": "_f_tslint",
4022− "tslint.yaml": "_f_tslint",
4023− "tslint.yml": "_f_tslint",
4024− "turbo.json": "_f_turbo",
4025− "turbo.jsonc": "_f_turbo",
4026− "microfrontends.json": "_f_turbo",
4027− "microfrontends.jsonc": "_f_turbo",
4028− "typedoc.cjs": "_f_typedoc",
4029− "typedoc.js": "_f_typedoc",
4030− "typedoc.json": "_f_typedoc",
4031− "typedoc.jsonc": "_f_typedoc",
4032− "typedoc.mjs": "_f_typedoc",
4033− "typedoc.config.cjs": "_f_typedoc",
4034− "typedoc.config.js": "_f_typedoc",
4035− "typedoc.config.json": "_f_typedoc",
4036− "typedoc.config.jsonc": "_f_typedoc",
4037− "typedoc.config.mjs": "_f_typedoc",
4038− ".unibeautifyrc": "_f_unibeautify",
4039− "unibeautify.config.js": "_f_unibeautify",
4040− ".unibeautifyrc.js": "_f_unibeautify",
4041− ".unibeautifyrc.json": "_f_unibeautify",
4042− ".unibeautifyrc.yaml": "_f_unibeautify",
4043− ".unibeautifyrc.yml": "_f_unibeautify",
4044− "unlicense": "_f_unlicense",
4045− "unlicence": "_f_unlicense",
4046− "UNLICENSE": "_f_unlicense",
4047− "UNLICENCE": "_f_unlicense",
4048− "unlicense.md": "_f_unlicense",
4049− "unlicense.txt": "_f_unlicense",
4050− "unlicence.md": "_f_unlicense",
4051− "unlicence.txt": "_f_unlicense",
4052− "UNLICENSE.md": "_f_unlicense",
4053− "UNLICENSE.txt": "_f_unlicense",
4054− "UNLICENCE.md": "_f_unlicense",
4055− "UNLICENCE.txt": "_f_unlicense",
4056− "uno.config.js": "_f_unocss",
4057− "uno.config.mjs": "_f_unocss",
4058− "uno.config.ts": "_f_unocss",
4059− "uno.config.mts": "_f_unocss",
4060− "unocss.config.js": "_f_unocss",
4061− "unocss.config.mjs": "_f_unocss",
4062− "unocss.config.ts": "_f_unocss",
4063− "unocss.config.mts": "_f_unocss",
4064− "uv.lock": "_f_uv",
4065− "vagrantfile": "_f_vagrant",
4066− "vapor.yml": "_f_vapor",
4067− "now.json": "_f_vercel",
4068− ".nowignore": "_f_vercel",
4069− "vercel.json": "_f_vercel",
4070− ".vercelignore": "_f_vercel",
4071− ".vimrc": "_f_vim",
4072− ".gvimrc": "_f_vim",
4073− "vite.config.js": "_f_vite",
4074− "vite.config.mjs": "_f_vite",
4075− "vite.config.ts": "_f_vite",
4076− "vite.config.cjs": "_f_vite",
4077− "vite.config.mts": "_f_vite",
4078− "vite.config.cts": "_f_vite",
4079− "vitest.config.js": "_f_vitest",
4080− "vitest.config.mjs": "_f_vitest",
4081− "vitest.config.ts": "_f_vitest",
4082− "vitest.config.cjs": "_f_vitest",
4083− "vitest.config.mts": "_f_vitest",
4084− "vitest.config.cts": "_f_vitest",
4085− "vitest.workspace.json": "_f_vitest",
4086− "vitest.workspace.js": "_f_vitest",
4087− "vitest.workspace.mjs": "_f_vitest",
4088− "vitest.workspace.ts": "_f_vitest",
4089− "vitest.workspace.cjs": "_f_vitest",
4090− "vitest.workspace.mts": "_f_vitest",
4091− "vitest.workspace.cts": "_f_vitest",
4092− "vitest.projects.json": "_f_vitest",
4093− "vitest.projects.js": "_f_vitest",
4094− "vitest.projects.mjs": "_f_vitest",
4095− "vitest.projects.ts": "_f_vitest",
4096− "vitest.projects.cjs": "_f_vitest",
4097− "vitest.projects.mts": "_f_vitest",
4098− "vitest.projects.cts": "_f_vitest",
4099− ".vscodeignore": "_f_vscode",
4100− "launch.json": "_f_vscode",
4101− "tasks.json": "_f_vscode",
4102− "vscodeignore.json": "_f_vscode",
4103− ".vscode-test.js": "_f_vscode_test",
4104− ".vscode-test.json": "_f_vscode_test",
4105− ".vscode-test.mjs": "_f_vscode_test",
4106− ".vuerc": "_f_vueconfig",
4107− "vue.config.js": "_f_vueconfig",
4108− "vue.config.cjs": "_f_vueconfig",
4109− "vue.config.mjs": "_f_vueconfig",
4110− "wallaby.json": "_f_wallaby",
4111− "wallaby.js": "_f_wallaby",
4112− "wallaby.ts": "_f_wallaby",
4113− "wallaby.coffee": "_f_wallaby",
4114− "wallaby.conf.json": "_f_wallaby",
4115− "wallaby.conf.js": "_f_wallaby",
4116− "wallaby.conf.ts": "_f_wallaby",
4117− "wallaby.conf.coffee": "_f_wallaby",
4118− ".wallaby.json": "_f_wallaby",
4119− ".wallaby.js": "_f_wallaby",
4120− ".wallaby.ts": "_f_wallaby",
4121− ".wallaby.coffee": "_f_wallaby",
4122− ".wallaby.conf.json": "_f_wallaby",
4123− ".wallaby.conf.js": "_f_wallaby",
4124− ".wallaby.conf.ts": "_f_wallaby",
4125− ".wallaby.conf.coffee": "_f_wallaby",
4126− "wally.toml": "_f_wally",
4127− "wally.lock": "_f_wally",
4128− ".watchmanconfig": "_f_watchmanconfig",
4129− "wdio.json": "_f_wdio",
4130− "wdio.js": "_f_wdio",
4131− "wdio.mjs": "_f_wdio",
4132− "wdio.cjs": "_f_wdio",
4133− "wdio.ts": "_f_wdio",
4134− "wdio.mts": "_f_wdio",
4135− "wdio.cts": "_f_wdio",
4136− "wdio.conf.json": "_f_wdio",
4137− "wdio.conf.js": "_f_wdio",
4138− "wdio.conf.mjs": "_f_wdio",
4139− "wdio.conf.cjs": "_f_wdio",
4140− "wdio.conf.ts": "_f_wdio",
4141− "wdio.conf.mts": "_f_wdio",
4142− "wdio.conf.cts": "_f_wdio",
4143− ".weblate": "_f_weblate",
4144− ".weblate.ini": "_f_weblate",
4145− "weblate": "_f_weblate",
4146− "weblate.ini": "_f_weblate",
4147− "webpack.base.conf.js": "_f_webpack",
4148− "webpack.base.conf.cjs": "_f_webpack",
4149− "webpack.base.conf.mjs": "_f_webpack",
4150− "webpack.base.conf.coffee": "_f_webpack",
4151− "webpack.base.conf.ts": "_f_webpack",
4152− "webpack.common.js": "_f_webpack",
4153− "webpack.common.cjs": "_f_webpack",
4154− "webpack.common.mjs": "_f_webpack",
4155− "webpack.common.coffee": "_f_webpack",
4156− "webpack.common.ts": "_f_webpack",
4157− "webpack.config.js": "_f_webpack",
4158− "webpack.config.cjs": "_f_webpack",
4159− "webpack.config.mjs": "_f_webpack",
4160− "webpack.config.coffee": "_f_webpack",
4161− "webpack.config.ts": "_f_webpack",
4162− "webpack.config.base.js": "_f_webpack",
4163− "webpack.config.base.cjs": "_f_webpack",
4164− "webpack.config.base.mjs": "_f_webpack",
4165− "webpack.config.base.coffee": "_f_webpack",
4166− "webpack.config.base.ts": "_f_webpack",
4167− "webpack.config.build.js": "_f_webpack",
4168− "webpack.config.build.cjs": "_f_webpack",
4169− "webpack.config.build.mjs": "_f_webpack",
4170− "webpack.config.build.coffee": "_f_webpack",
4171− "webpack.config.build.ts": "_f_webpack",
4172− "webpack.config.common.js": "_f_webpack",
4173− "webpack.config.common.cjs": "_f_webpack",
4174− "webpack.config.common.mjs": "_f_webpack",
4175− "webpack.config.common.coffee": "_f_webpack",
4176− "webpack.config.common.ts": "_f_webpack",
4177− "webpack.config.dev.js": "_f_webpack",
4178− "webpack.config.dev.cjs": "_f_webpack",
4179− "webpack.config.dev.mjs": "_f_webpack",
4180− "webpack.config.dev.coffee": "_f_webpack",
4181− "webpack.config.dev.ts": "_f_webpack",
4182− "webpack.config.development.js": "_f_webpack",
4183− "webpack.config.development.cjs": "_f_webpack",
4184− "webpack.config.development.mjs": "_f_webpack",
4185− "webpack.config.development.coffee": "_f_webpack",
4186− "webpack.config.development.ts": "_f_webpack",
4187− "webpack.config.staging.js": "_f_webpack",
4188− "webpack.config.staging.cjs": "_f_webpack",
4189− "webpack.config.staging.mjs": "_f_webpack",
4190− "webpack.config.staging.coffee": "_f_webpack",
4191− "webpack.config.staging.ts": "_f_webpack",
4192− "webpack.config.test.js": "_f_webpack",
4193− "webpack.config.test.cjs": "_f_webpack",
4194− "webpack.config.test.mjs": "_f_webpack",
4195− "webpack.config.test.coffee": "_f_webpack",
4196− "webpack.config.test.ts": "_f_webpack",
4197− "webpack.config.prod.js": "_f_webpack",
4198− "webpack.config.prod.cjs": "_f_webpack",
4199− "webpack.config.prod.mjs": "_f_webpack",
4200− "webpack.config.prod.coffee": "_f_webpack",
4201− "webpack.config.prod.ts": "_f_webpack",
4202− "webpack.config.production.js": "_f_webpack",
4203− "webpack.config.production.cjs": "_f_webpack",
4204− "webpack.config.production.mjs": "_f_webpack",
4205− "webpack.config.production.coffee": "_f_webpack",
4206− "webpack.config.production.ts": "_f_webpack",
4207− "webpack.config.babel.js": "_f_webpack",
4208− "webpack.config.babel.cjs": "_f_webpack",
4209− "webpack.config.babel.mjs": "_f_webpack",
4210− "webpack.config.babel.coffee": "_f_webpack",
4211− "webpack.config.babel.ts": "_f_webpack",
4212− "webpack.config.base.babel.js": "_f_webpack",
4213− "webpack.config.base.babel.cjs": "_f_webpack",
4214− "webpack.config.base.babel.mjs": "_f_webpack",
4215− "webpack.config.base.babel.coffee": "_f_webpack",
4216− "webpack.config.base.babel.ts": "_f_webpack",
4217− "webpack.config.common.babel.js": "_f_webpack",
4218− "webpack.config.common.babel.cjs": "_f_webpack",
4219− "webpack.config.common.babel.mjs": "_f_webpack",
4220− "webpack.config.common.babel.coffee": "_f_webpack",
4221− "webpack.config.common.babel.ts": "_f_webpack",
4222− "webpack.config.dev.babel.js": "_f_webpack",
4223− "webpack.config.dev.babel.cjs": "_f_webpack",
4224− "webpack.config.dev.babel.mjs": "_f_webpack",
4225− "webpack.config.dev.babel.coffee": "_f_webpack",
4226− "webpack.config.dev.babel.ts": "_f_webpack",
4227− "webpack.config.development.babel.js": "_f_webpack",
4228− "webpack.config.development.babel.cjs": "_f_webpack",
4229− "webpack.config.development.babel.mjs": "_f_webpack",
4230− "webpack.config.development.babel.coffee": "_f_webpack",
4231− "webpack.config.development.babel.ts": "_f_webpack",
4232− "webpack.config.staging.babel.js": "_f_webpack",
4233− "webpack.config.staging.babel.cjs": "_f_webpack",
4234− "webpack.config.staging.babel.mjs": "_f_webpack",
4235− "webpack.config.staging.babel.coffee": "_f_webpack",
4236− "webpack.config.staging.babel.ts": "_f_webpack",
4237− "webpack.config.test.babel.js": "_f_webpack",
4238− "webpack.config.test.babel.cjs": "_f_webpack",
4239− "webpack.config.test.babel.mjs": "_f_webpack",
4240− "webpack.config.test.babel.coffee": "_f_webpack",
4241− "webpack.config.test.babel.ts": "_f_webpack",
4242− "webpack.config.prod.babel.js": "_f_webpack",
4243− "webpack.config.prod.babel.cjs": "_f_webpack",
4244− "webpack.config.prod.babel.mjs": "_f_webpack",
4245− "webpack.config.prod.babel.coffee": "_f_webpack",
4246− "webpack.config.prod.babel.ts": "_f_webpack",
4247− "webpack.config.production.babel.js": "_f_webpack",
4248− "webpack.config.production.babel.cjs": "_f_webpack",
4249− "webpack.config.production.babel.mjs": "_f_webpack",
4250− "webpack.config.production.babel.coffee": "_f_webpack",
4251− "webpack.config.production.babel.ts": "_f_webpack",
4252− "webpack.dev.js": "_f_webpack",
4253− "webpack.dev.cjs": "_f_webpack",
4254− "webpack.dev.mjs": "_f_webpack",
4255− "webpack.dev.coffee": "_f_webpack",
4256− "webpack.dev.ts": "_f_webpack",
4257− "webpack.dev.conf.js": "_f_webpack",
4258− "webpack.dev.conf.cjs": "_f_webpack",
4259− "webpack.dev.conf.mjs": "_f_webpack",
4260− "webpack.dev.conf.coffee": "_f_webpack",
4261− "webpack.dev.conf.ts": "_f_webpack",
4262− "webpack.local.js": "_f_webpack",
4263− "webpack.local.cjs": "_f_webpack",
4264− "webpack.local.mjs": "_f_webpack",
4265− "webpack.local.coffee": "_f_webpack",
4266− "webpack.local.ts": "_f_webpack",
4267− "webpack.prod.js": "_f_webpack",
4268− "webpack.prod.cjs": "_f_webpack",
4269− "webpack.prod.mjs": "_f_webpack",
4270− "webpack.prod.coffee": "_f_webpack",
4271− "webpack.prod.ts": "_f_webpack",
4272− "webpack.prod.conf.js": "_f_webpack",
4273− "webpack.prod.conf.cjs": "_f_webpack",
4274− "webpack.prod.conf.mjs": "_f_webpack",
4275− "webpack.prod.conf.coffee": "_f_webpack",
4276− "webpack.prod.conf.ts": "_f_webpack",
4277− "webpack.main.config.js": "_f_webpack",
4278− "webpack.main.config.cjs": "_f_webpack",
4279− "webpack.main.config.mjs": "_f_webpack",
4280− "webpack.main.config.coffee": "_f_webpack",
4281− "webpack.main.config.ts": "_f_webpack",
4282− "webpack.mix.js": "_f_webpack",
4283− "webpack.mix.cjs": "_f_webpack",
4284− "webpack.mix.mjs": "_f_webpack",
4285− "webpack.mix.coffee": "_f_webpack",
4286− "webpack.mix.ts": "_f_webpack",
4287− "webpack.plugins.js": "_f_webpack",
4288− "webpack.plugins.cjs": "_f_webpack",
4289− "webpack.plugins.mjs": "_f_webpack",
4290− "webpack.plugins.coffee": "_f_webpack",
4291− "webpack.plugins.ts": "_f_webpack",
4292− "webpack.renderer.config.js": "_f_webpack",
4293− "webpack.renderer.config.cjs": "_f_webpack",
4294− "webpack.renderer.config.mjs": "_f_webpack",
4295− "webpack.renderer.config.coffee": "_f_webpack",
4296− "webpack.renderer.config.ts": "_f_webpack",
4297− "webpack.rules.js": "_f_webpack",
4298− "webpack.rules.cjs": "_f_webpack",
4299− "webpack.rules.mjs": "_f_webpack",
4300− "webpack.rules.coffee": "_f_webpack",
4301− "webpack.rules.ts": "_f_webpack",
4302− "webpack.test.conf.js": "_f_webpack",
4303− "webpack.test.conf.cjs": "_f_webpack",
4304− "webpack.test.conf.mjs": "_f_webpack",
4305− "webpack.test.conf.coffee": "_f_webpack",
4306− "webpack.test.conf.ts": "_f_webpack",
4307− "wercker.yml": "_f_wercker",
4308− "windi.config.ts": "_f_windi",
4309− "windi.config.js": "_f_windi",
4310− "wpml-config.xml": "_f_wpml",
4311− "wxt.config.js": "_f_wxt",
4312− "wxt.config.cjs": "_f_wxt",
4313− "wxt.config.mjs": "_f_wxt",
4314− "wxt.config.ts": "_f_wxt",
4315− "wxt.config.cts": "_f_wxt",
4316− "wxt.config.mts": "_f_wxt",
4317− ".xo-config": "_f_xo",
4318− "xo.config.js": "_f_xo",
4319− "xo.config.cjs": "_f_xo",
4320− "xo.config.mjs": "_f_xo",
4321− "xo.config.ts": "_f_xo",
4322− "xo.config.cts": "_f_xo",
4323− "xo.config.mts": "_f_xo",
4324− ".xo-config.js": "_f_xo",
4325− ".xo-config.json": "_f_xo",
4326− ".xo-config.cjs": "_f_xo",
4327− ".xcompose": "_f_xorg",
4328− ".yamllint": "_f_yamllint",
4329− ".yaspellerrc": "_f_yandex",
4330− ".yaspeller.json": "_f_yandex",
4331− "yarn.lock": "_f_yarn",
4332− ".yarnrc": "_f_yarn",
4333− ".yarnrc.yml": "_f_yarn",
4334− ".yarnclean": "_f_yarn",
4335− ".yarn-integrity": "_f_yarn",
4336− ".yarn-metadata.json": "_f_yarn",
4337− ".yarn-state.yml": "_f_yarn",
4338− ".yarnignore": "_f_yarn",
4339− ".yo-rc.json": "_f_yeoman"
4340− },
4341− "languageIds": {
4342− "actionscript": "_f_actionscript",
4343− "ada": "_f_ada",
4344− "advpl": "_f_advpl",
4345− "affectscript": "_f_affectscript",
4346− "agda": "_f_agda",
4347− "lagda-md": "_f_agda",
4348− "lagda-rst": "_f_agda",
4349− "lagda-tex": "_f_agda",
4350− "al": "_f_al",
4351− "alloy": "_f_alloy",
4352− "ansible": "_f_ansible",
4353− "antlr": "_f_antlr",
4354− "anyscript": "_f_anyscript",
4355− "apacheconf": "_f_apache",
4356− "apex": "_f_apex",
4357− "apiblueprint": "_f_apib",
4358− "apl": "_f_apl",
4359− "applescript": "_f_applescript",
4360− "asciidoc": "_f_asciidoc",
4361− "asp": "_f_asp",
4362− "asp (html)": "_f_asp",
4363− "arm": "_f_assembly",
4364− "asm": "_f_assembly",
4365− "asm-intel-x86-generic": "_f_assembly",
4366− "platformio-debug.asm": "_f_platformio",
4367− "asm-collection": "_f_assembly",
4368− "astro": "_f_astro",
4369− "ats": "_f_ats",
4370− "ahk": "_f_autohotkey",
4371− "ahk2": "_f_autohotkey",
4372− "autoit": "_f_autoit",
4373− "avro": "_f_avro",
4374− "azcli": "_f_azure",
4375− "azure-pipelines": "_f_azurepipelines",
4376− "ballerina": "_f_ballerina",
4377− "bat": "_f_bat",
4378− "bats": "_f_bats",
4379− "bazel": "_f_bazel",
4380− "bazelrc": "_f_bazel",
4381− "starlark": "_f_bazel",
4382− "befunge": "_f_befunge",
4383− "befunge98": "_f_befunge",
4384− "bicep": "_f_bicep",
4385− "biml": "_f_biml",
4386− "code-text-binary": "_f_binary",
4387− "biome_syntax_tree": "_f_biome",
4388− "blade": "_f_blade",
4389− "laravel-blade": "_f_blade",
4390− "blitzbasic": "_f_blitzbasic",
4391− "bolt": "_f_bolt",
4392− "bosque": "_f_bosque",
4393− "browserslist": "_f_browserslist",
4394− "bruno": "_f_bruno",
4395− "buf": "_f_buf",
4396− "buf-gen": "_f_buf",
4397− "bun.lockb": "_f_bun",
4398− "c": "_f_c",
4399− "c3": "_f_c3",
4400− "c-al": "_f_c_al",
4401− "cabal": "_f_cabal",
4402− "caddyfile": "_f_caddy",
4403− "capnp": "_f_capnp",
4404− "capnproto": "_f_capnp",
4405− "casc": "_f_casc",
4406− "cddl": "_f_cddl",
4407− "ceylon": "_f_ceylon",
4408− "cfml": "_f_cf",
4409− "lang-cfml": "_f_cf",
4410− "cfc": "_f_cfc",
4411− "cfmhtml": "_f_cfm",
4412− "cookbook": "_f_chef_cookbook",
4413− "circom": "_f_circom",
4414− "clojure": "_f_clojure",
4415− "clojurescript": "_f_clojurescript",
4416− "manifest-yaml": "_f_cloudfoundry",
4417− "cmake": "_f_cmake",
4418− "cmake-cache": "_f_cmake",
4419− "cobol": "_f_cobol",
4420− "ql": "_f_codeql",
4421− "coffeescript": "_f_coffeescript",
4422− "java-properties": "_f_config",
4423− "properties": "_f_config",
4424− "spring-boot-properties": "_f_config",
4425− "confluence": "_f_confluence",
4426− "instructions": "_f_copilot",
4427− "prompt": "_f_copilot",
4428− "cpp": "_f_cpp",
4429− "crystal": "_f_crystal",
4430− "csharp": "_f_csharp",
4431− "css": "_f_css",
4432− "cucumber": "_f_cucumber",
4433− "feature": "_f_cucumber",
4434− "cuda": "_f_cuda",
4435− "cuda-cpp": "_f_cuda",
4436− "cython": "_f_cython",
4437− "dal": "_f_dal",
4438− "dart": "_f_dartlang",
4439− "debian-changelog": "_f_debian",
4440− "debian-control": "_f_debian",
4441− "debian-copyright": "_f_debian",
4442− "debian-upstream-metadata": "_f_debian",
4443− "pascal": "_f_delphi",
4444− "objectpascal": "_f_delphi",
4445− "dhall": "_f_dhall",
4446− "diff": "_f_diff",
4447− "django-html": "_f_django",
4448− "django-txt": "_f_django",
4449− "d": "_f_dlang",
4450− "dscript": "_f_dlang",
4451− "dml": "_f_dlang",
4452− "diet": "_f_dlang",
4453− "dockerbake": "_f_docker",
4454− "dockercompose": "_f_docker",
4455− "dockerfile": "_f_docker",
4456− "dotenv": "_f_dotenv",
4457− "env": "_f_dotenv",
4458− "dotjs": "_f_dotjs",
4459− "doxygen": "_f_doxygen",
4460− "drawio": "_f_drawio",
4461− "drools": "_f_drools",
4462− "dtd": "_f_dtd",
4463− "dustjs": "_f_dustjs",
4464− "dylan": "_f_dylan",
4465− "dylan-lid": "_f_dylan",
4466− "earthfile": "_f_earthly",
4467− "edge": "_f_edge",
4468− "editorconfig": "_f_editorconfig",
4469− "eex": "_f_eex",
4470− "html-eex": "_f_eex",
4471− "es": "_f_elastic",
4472− "elixir": "_f_elixir",
4473− "elm": "_f_elm",
4474− "erb": "_f_erb",
4475− "html.erb": "_f_erb",
4476− "erlang": "_f_erlang",
4477− "esphome": "_f_esphome",
4478− "excel": "_f_excel",
4479− "falcon": "_f_falcon",
4480− "fql": "_f_fauna",
4481− "fortran": "_f_fortran",
4482− "fortran-modern": "_f_fortran",
4483− "FortranFreeForm": "_f_fortran",
4484− "FortranFixedForm": "_f_fortran",
4485− "fortran_fixed-form": "_f_fortran",
4486− "ftl": "_f_freemarker",
4487− "fsharp": "_f_fsharp",
4488− "fthtml": "_f_fthtml",
4489− "galen": "_f_galen",
4490− "gml-gms": "_f_gamemaker",
4491− "gml-gms2": "_f_gamemaker2",
4492− "gml-gm81": "_f_gamemaker81",
4493− "gcode": "_f_gcode",
4494− "gdscript": "_f_gdscript",
4495− "genstat": "_f_genstat",
4496− "git-commit": "_f_git",
4497− "git-rebase": "_f_git",
4498− "ignore": "_f_git",
4499− "gleam": "_f_gleam",
4500− "glimmer-js": "_f_glimmer",
4501− "glimmer-ts": "_f_glimmer",
4502− "glsl": "_f_glsl",
4503− "glyphs": "_f_glyphs",
4504− "automake": "_f_gnu",
4505− "m4": "_f_gnu",
4506− "makefile": "_f_gnu",
4507− "makefile2": "_f_gnu",
4508− "gnuplot": "_f_gnuplot",
4509− "go": "_f_go",
4510− "go.mod": "_f_go_package",
4511− "go.work": "_f_go_work",
4512− "goctl": "_f_goctl",
4513− "gradle-kotlin-dsl": "_f_gradle",
4514− "grain": "_f_grain",
4515− "graphql": "_f_graphql",
4516− "dot": "_f_graphviz",
4517− "grit": "_f_grit",
4518− "groovy": "_f_groovy",
4519− "haml": "_f_haml",
4520− "handlebars": "_f_handlebars",
4521− "harbour": "_f_harbour",
4522− "hcl": "_f_hashicorp",
4523− "haskell": "_f_haskell",
4524− "literate haskell": "_f_haskell",
4525− "haxe": "_f_haxe",
4526− "hxml": "_f_haxe",
4527− "Haxe AST dump": "_f_haxe",
4528− "helm": "_f_helm",
4529− "hjson": "_f_hjson",
4530− "hlsl": "_f_hlsl",
4531− "home-assistant": "_f_homeassistant",
4532− "hosts": "_f_host",
4533− "html": "_f_html",
4534− "http": "_f_http",
4535− "hunspell.aff": "_f_hunspell",
4536− "hunspell.dic": "_f_hunspell",
4537− "hy": "_f_hy",
4538− "hypr": "_f_hypr",
4539− "icl": "_f_icl",
4540− "imba": "_f_imba",
4541− "4GL": "_f_informix",
4542− "ini": "_f_ini",
4543− "ink": "_f_ink",
4544− "innosetup": "_f_innosetup",
4545− "io": "_f_io",
4546− "iodine": "_f_iodine",
4547− "janet": "_f_janet",
4548− "java": "_f_java",
4549− "jekyll": "_f_jekyll",
4550− "jenkins": "_f_jenkins",
4551− "declarative": "_f_jenkins",
4552− "jenkinsfile": "_f_jenkins",
4553− "jest-snapshot": "_f_jest_snapshot",
4554− "jinja": "_f_jinja",
4555− "jinja-java": "_f_jinja",
4556− "jinja-html": "_f_jinja",
4557− "jinja-xml": "_f_jinja",
4558− "jinja-css": "_f_jinja",
4559− "jinja-json": "_f_jinja",
4560− "jinja-md": "_f_jinja",
4561− "jinja-py": "_f_jinja",
4562− "jinja-rb": "_f_jinja",
4563− "jinja-js": "_f_jinja",
4564− "jinja-yaml": "_f_jinja",
4565− "jinja-toml": "_f_jinja",
4566− "jinja-latex": "_f_jinja",
4567− "jinja-lua": "_f_jinja",
4568− "jinja-properties": "_f_jinja",
4569− "jinja-shell": "_f_jinja",
4570− "jinja-dockerfile": "_f_jinja",
4571− "jinja-sql": "_f_jinja",
4572− "jinja-terraform": "_f_jinja",
4573− "jinja-nginx": "_f_jinja",
4574− "jinja-groovy": "_f_jinja",
4575− "jinja-systemd": "_f_jinja",
4576− "jinja-cpp": "_f_jinja",
4577− "javascript": "_f_js",
4578− "json": "_f_json",
4579− "json-tmlanguage": "_f_json",
4580− "jsonc": "_f_json",
4581− "jsonl": "_f_json",
4582− "json5": "_f_json5",
4583− "jsonnet": "_f_jsonnet",
4584− "julia": "_f_julia",
4585− "juliamarkdown": "_f_julia",
4586− "just": "_f_just",
4587− "k": "_f_k",
4588− "kivy": "_f_kivy",
4589− "kos": "_f_kos",
4590− "kotlin": "_f_kotlin",
4591− "kotlinscript": "_f_kotlin",
4592− "kusto": "_f_kusto",
4593− "lark": "_f_lark",
4594− "latino": "_f_latino",
4595− "lean4": "_f_lean",
4596− "lean4markdown": "_f_lean",
4597− "less": "_f_less",
4598− "lex": "_f_lex",
4599− "lilypond": "_f_lilypond",
4600− "lisp": "_f_lisp",
4601− "autolisp": "_f_lisp",
4602− "autolispdcl": "_f_lisp",
4603− "log": "_f_log",
4604− "lolcode": "_f_lolcode",
4605− "lsl": "_f_lsl",
4606− "lua": "_f_lua",
4607− "markdown": "_f_markdown",
4608− "marko": "_f_marko",
4609− "matlab": "_f_matlab",
4610− "maxscript": "_f_maxscript",
4611− "mel": "_f_maya",
4612− "mdx": "_f_mdx",
4613− "mediawiki": "_f_mediawiki",
4614− "mermaid": "_f_mermaid",
4615− "meson": "_f_meson",
4616− "metal": "_f_metal",
4617− "bc-mcfunction": "_f_minecraft",
4618− "bc-minecraft-language": "_f_minecraft",
4619− "bc-minecraft-molang": "_f_minecraft",
4620− "bc-minecraft-project": "_f_minecraft",
4621− "mcdoc": "_f_minecraft",
4622− "mcfunction": "_f_minecraft",
4623− "mcmeta": "_f_minecraft",
4624− "mcscript": "_f_minecraft",
4625− "minecraft-lang": "_f_minecraft",
4626− "options-txt": "_f_minecraft",
4627− "snbt": "_f_minecraft",
4628− "mv": "_f_mivascript",
4629− "mjml": "_f_mjml",
4630− "powerquery": "_f_mlang",
4631− "mojo": "_f_mojo",
4632− "mojolicious": "_f_mojolicious",
4633− "mongo": "_f_mongo",
4634− "mson": "_f_mson",
4635− "mvt": "_f_mvt",
4636− "mvtcss": "_f_mvtcss",
4637− "mvtjs": "_f_mvtjs",
4638− "nearley": "_f_nearly",
4639− "cypher": "_f_neo4j",
4640− "nginx": "_f_nginx",
4641− "nim": "_f_nim",
4642− "nimble": "_f_nimble",
4643− "nix": "_f_nix",
4644− "nsis": "_f_nsi",
4645− "nfl": "_f_nsi",
4646− "nsl": "_f_nsi",
4647− "bridlensis": "_f_nsi",
4648− "nunjucks": "_f_nunjucks",
4649− "nushell": "_f_nushell",
4650− "objective-c": "_f_objectivec",
4651− "objective-cpp": "_f_objectivecpp",
4652− "ocaml": "_f_ocaml",
4653− "ocamllex": "_f_ocaml",
4654− "menhir": "_f_ocaml",
4655− "ogone": "_f_ogone",
4656− "openhab": "_f_openHAB",
4657− "scad": "_f_openscad",
4658− "org": "_f_org",
4659− "pddl": "_f_pddl",
4660− "happenings": "_f_pddl_happenings",
4661− "plan": "_f_pddl_plan",
4662− "perl": "_f_perl",
4663− "perl6": "_f_perl6",
4664− "pgsql": "_f_pgsql",
4665− "php": "_f_php",
4666− "pine": "_f_pine",
4667− "pinescript": "_f_pine",
4668− "pip-requirements": "_f_pip",
4669− "platformio-debug.disassembly": "_f_platformio",
4670− "platformio-debug.memoryview": "_f_platformio",
4671− "plsql": "_f_plsql",
4672− "oracle": "_f_plsql",
4673− "oraclesql": "_f_plsql",
4674− "oracle-sql": "_f_plsql",
4675− "po": "_f_poedit",
4676− "polyglot-notebook": "_f_polyglot",
4677− "polymer": "_f_polymer",
4678− "pony": "_f_pony",
4679− "postcss": "_f_postcss",
4680− "postscript": "_f_postscript",
4681− "powershell": "_f_powershell",
4682− "prisma": "_f_prisma",
4683− "pde": "_f_processinglang",
4684− "abl": "_f_progress",
4685− "prolog": "_f_prolog",
4686− "prometheus": "_f_prometheus",
4687− "proto3": "_f_protobuf",
4688− "proto": "_f_protobuf",
4689− "prototext": "_f_protobuf",
4690− "jade": "_f_pug",
4691− "puppet": "_f_puppet",
4692− "purescript": "_f_purescript",
4693− "pyret": "_f_pyret",
4694− "pyscript": "_f_pyscript",
4695− "python": "_f_python",
4696− "pythowo": "_f_pythowo",
4697− "qlik": "_f_qlikview",
4698− "qml": "_f_qml",
4699− "qsharp": "_f_qsharp",
4700− "r": "_f_r",
4701− "ra_syntax_tree": "_f_ra_syntax_tree",
4702− "racket": "_f_racket",
4703− "raku": "_f_raku",
4704− "raml": "_f_raml",
4705− "razor": "_f_razor",
4706− "aspnetcorerazor": "_f_razor",
4707− "javascriptreact": "_f_reactjs",
4708− "typescriptreact": "_f_reactts",
4709− "reason": "_f_reason",
4710− "red": "_f_red",
4711− "rescript": "_f_rescript",
4712− "restructuredtext": "_f_rest",
4713− "rexx": "_f_rexx",
4714− "riot": "_f_riot",
4715− "ripple": "_f_ripple",
4716− "rmd": "_f_rmd",
4717− "rnc": "_f_rnc",
4718− "robot": "_f_robotframework",
4719− "robots-txt": "_f_robots",
4720− "ruby": "_f_ruby",
4721− "rust": "_f_rust",
4722− "s-lang": "_f_s-lang",
4723− "san": "_f_san",
4724− "SAS": "_f_sas",
4725− "sass": "_f_sass",
4726− "sass.hover": "_f_sass",
4727− "sbt": "_f_sbt",
4728− "scala": "_f_scala",
4729− "scilab": "_f_scilab",
4730− "vbscript": "_f_script",
4731− "scss": "_f_scss",
4732− "sdl": "_f_sdlang",
4733− "search-result": "_f_search_result",
4734− "shaderlab": "_f_shaderlab",
4735− "shellscript": "_f_shell",
4736− "silverstripe": "_f_silverstripe",
4737− "sino": "_f_sino",
4738− "eskip": "_f_skipper",
4739− "slang": "_f_slang",
4740− "slice": "_f_slice",
4741− "slim": "_f_slim",
4742− "slint": "_f_slint",
4743− "sln": "_f_sln",
4744− "smarty": "_f_smarty",
4745− "snakemake": "_f_snakemake",
4746− "snort": "_f_snort",
4747− "solidity": "_f_solidity",
4748− "sparql": "_f_sparql",
4749− "sqf": "_f_sqf",
4750− "sql": "_f_sql",
4751− "squirrel": "_f_squirrel",
4752− "stan": "_f_stan",
4753− "stata": "_f_stata",
4754− "stencil": "_f_stencil",
4755− "stencil-html": "_f_stencil",
4756− "stylable": "_f_stylable",
4757− "source.css.styled": "_f_styled",
4758− "stylus": "_f_stylus",
4759− "svelte": "_f_svelte",
4760− "svg": "_f_svg",
4761− "Swagger": "_f_swagger",
4762− "swagger": "_f_swagger",
4763− "swift": "_f_swift",
4764− "swig": "_f_swig",
4765− "systemd-conf": "_f_systemd",
4766− "systemd-unit-file": "_f_systemd",
4767− "systemverilog": "_f_systemverilog",
4768− "t4": "_f_t4tt",
4769− "tailwindcss": "_f_tailwind",
4770− "teal": "_f_teal",
4771− "templ": "_f_templ",
4772− "tera": "_f_tera",
4773− "terraform": "_f_terraform",
4774− "tex": "_f_tex",
4775− "latex": "_f_tex",
4776− "bibtex": "_f_tex",
4777− "doctex": "_f_tex",
4778− "csv": "_f_text",
4779− "csv (pipe)": "_f_text",
4780− "csv (semicolon)": "_f_text",
4781− "csv (whitespace)": "_f_text",
4782− "dynamic csv": "_f_text",
4783− "tsv": "_f_text",
4784− "plaintext": "_f_text",
4785− "vim-help": "_f_text",
4786− "textile": "_f_textile",
4787− "tiltfile": "_f_tiltfile",
4788− "toit": "_f_toit",
4789− "toml": "_f_toml",
4790− "toon": "_f_toon",
4791− "tt": "_f_tt",
4792− "ttcn": "_f_ttcn",
4793− "tuc": "_f_tuc",
4794− "twig": "_f_twig",
4795− "typescript": "_f_typescript",
4796− "typoscript": "_f_typo3",
4797− "uiua": "_f_uiua",
4798− "unison": "_f_unison",
4799− "vb": "_f_vb",
4800− "vba": "_f_vba",
4801− "velocity": "_f_velocity",
4802− "vento": "_f_vento",
4803− "verilog": "_f_verilog",
4804− "vhdl": "_f_vhdl",
4805− "viml": "_f_vim",
4806− "vim-snippet": "_f_vim",
4807− "vitest-snapshot": "_f_vitest",
4808− "v": "_f_vlang",
4809− "volt": "_f_volt",
4810− "vroom": "_f_vroom",
4811− "snippets": "_f_vscode",
4812− "vue": "_f_vue",
4813− "vyper": "_f_vyper",
4814− "wasm": "_f_wasm",
4815− "wat": "_f_wasm",
4816− "wenyan": "_f_wenyan",
4817− "wgsl": "_f_wgsl",
4818− "wikitext": "_f_wikitext",
4819− "wai": "_f_wit",
4820− "wolfram": "_f_wolfram",
4821− "wurstlang": "_f_wurst",
4822− "wurst": "_f_wurst",
4823− "xmake": "_f_xmake",
4824− "xml": "_f_xml",
4825− "xcompose": "_f_xorg",
4826− "xquery": "_f_xquery",
4827− "xsl": "_f_xsl",
4828− "xslt": "_f_xsl",
4829− "yacc": "_f_yacc",
4830− "yaml": "_f_yaml",
4831− "yaml-tmlanguage": "_f_yaml",
4832− "spring-boot-properties-yaml": "_f_yaml",
4833− "yang": "_f_yang",
4834− "yarnlock": "_f_yarn",
4835− "zig": "_f_zig",
4836− "zip": "_f_zip"
4837− },
4838− "light": {
4839− "file": "_file_light",
4840− "folder": "_folder_light",
4841− "folderExpanded": "_folder_light_open",
4842− "rootFolder": "_root_folder_light",
4843− "rootFolderExpanded": "_root_folder_light_open",
4844− "folderNames": {
4845− "android": "_fd_android",
4846− ".angular": "_fd_angular",
4847− "apache": "_fd_apache",
4848− "apache2": "_fd_apache",
4849− "httpd": "_fd_apache",
4850− "api": "_fd_api",
4851− ".api": "_fd_api",
4852− "apis": "_fd_api",
4853− ".apis": "_fd_api",
4854− "app": "_fd_app",
4855− "apps": "_fd_app",
4856− ".app": "_fd_app",
4857− "application": "_fd_app",
4858− "applications": "_fd_app",
4859− "arangodb": "_fd_arangodb",
4860− "arango": "_fd_arangodb",
4861− "assets": "_fd_asset",
4862− ".assets": "_fd_asset",
4863− ".astro": "_fd_astro",
4864− "audio": "_fd_audio",
4865− ".audio": "_fd_audio",
4866− "audios": "_fd_audio",
4867− ".audios": "_fd_audio",
4868− "sound": "_fd_audio",
4869− ".sound": "_fd_audio",
4870− "sounds": "_fd_audio",
4871− ".sounds": "_fd_audio",
4872− "aurelia_project": "_fd_aurelia",
4873− "aws": "_fd_aws",
4874− ".aws": "_fd_aws",
4875− "azure": "_fd_azure",
4876− ".azure": "_fd_azure",
4877− "azure-pipelines": "_fd_azurepipelines",
4878− ".azure-pipelines": "_fd_azurepipelines",
4879− "bin": "_fd_binary",
4880− ".bin": "_fd_binary",
4881− "blocs": "_fd_bloc",
4882− "bloc": "_fd_bloc",
4883− "blueprint": "_fd_blueprint",
4884− ".blueprint": "_fd_blueprint",
4885− "blueprints": "_fd_blueprint",
4886− ".blueprints": "_fd_blueprint",
4887− "bot": "_fd_bot",
4888− ".bot": "_fd_bot",
4889− "bower_components": "_fd_bower",
4890− ".buildkite": "_fd_buildkite",
4891− "cake": "_fd_cake",
4892− ".cake": "_fd_cake",
4893− "cargo": "_fd_cargo",
4894− ".cargo": "_fd_cargo",
4895− "crates": "_fd_cargo",
4896− "certificates": "_fd_certificate",
4897− ".certificates": "_fd_certificate",
4898− "certs": "_fd_certificate",
4899− "certs.": "_fd_certificate",
4900− ".changeset": "_fd_changesets",
4901− "chef": "_fd_chef",
4902− ".chef": "_fd_chef",
4903− ".circleci": "_fd_circleci",
4904− ".claude": "_fd_claude",
4905− "cli": "_fd_cli",
4906− "cmd": "_fd_cli",
4907− "command": "_fd_cli",
4908− "commands": "_fd_cli",
4909− "commandline": "_fd_cli",
4910− "console": "_fd_cli",
4911− "client": "_fd_client",
4912− "clients": "_fd_client",
4913− ".cloudflare": "_fd_cloudflare",
4914− "cloudflare": "_fd_cloudflare",
4915− ".cmake": "_fd_cmake",
4916− "cmake": "_fd_cmake",
4917− "common": "_fd_common",
4918− "component": "_fd_component",
4919− "components": "_fd_component",
4920− ".components": "_fd_component",
4921− "gui": "_fd_component",
4922− "src-ui": "_fd_component",
4923− "ui": "_fd_component",
4924− "widgets": "_fd_component",
4925− "composer": "_fd_composer",
4926− ".composer": "_fd_composer",
4927− "conf": "_fd_config",
4928− ".conf": "_fd_config",
4929− "config": "_fd_config",
4930− ".config": "_fd_config",
4931− "configs": "_fd_config",
4932− ".configs": "_fd_config",
4933− "configuration": "_fd_config",
4934− ".configuration": "_fd_config",
4935− "configurations": "_fd_config",
4936− ".configurations": "_fd_config",
4937− "setting": "_fd_config",
4938− ".setting": "_fd_config",
4939− "settings": "_fd_config",
4940− ".settings": "_fd_config",
4941− "ini": "_fd_config",
4942− ".ini": "_fd_config",
4943− "initializers": "_fd_config",
4944− ".initializers": "_fd_config",
4945− "__controller__": "_fd_controller",
4946− "__controllers__": "_fd_controller",
4947− "controller": "_fd_controller",
4948− "controllers": "_fd_controller",
4949− ".controllers": "_fd_controller",
4950− "__handler__": "_fd_controller",
4951− "__handlers__": "_fd_controller",
4952− "handler": "_fd_controller",
4953− ".handler": "_fd_controller",
4954− "handlers": "_fd_controller",
4955− ".handlers": "_fd_controller",
4956− "coverage": "_fd_coverage",
4957− "css": "_fd_css",
4958− "_css": "_fd_css",
4959− "cubits": "_fd_cubit",
4960− "cubit": "_fd_cubit",
4961− ".cursor": "_fd_light_cursor",
4962− "cypress": "_fd_light_cypress",
4963− ".dapr": "_fd_dapr",
4964− "dapr": "_fd_dapr",
4965− "dart": "_fd_dart",
4966− ".dart_tool": "_fd_dart",
4967− "datadog": "_fd_datadog",
4968− ".datadog": "_fd_datadog",
4969− "db": "_fd_db",
4970− "database": "_fd_db",
4971− "sql": "_fd_db",
4972− "data": "_fd_db",
4973− "repo": "_fd_db",
4974− "repository": "_fd_db",
4975− "repositories": "_fd_db",
4976− "store": "_fd_db",
4977− "stores": "_fd_db",
4978− "debian": "_fd_debian",
4979− "deb": "_fd_debian",
4980− ".dependabot": "_fd_dependabot",
4981− ".devcontainer": "_fd_devcontainer",
4982− "dist": "_fd_dist",
4983− ".dist": "_fd_dist",
4984− "dists": "_fd_dist",
4985− "out": "_fd_dist",
4986− "outs": "_fd_dist",
4987− "export": "_fd_dist",
4988− "exports": "_fd_dist",
4989− "build": "_fd_dist",
4990− ".build": "_fd_dist",
4991− "builds": "_fd_dist",
4992− "release": "_fd_dist",
4993− "releases": "_fd_dist",
4994− "target": "_fd_dist",
4995− "targets": "_fd_dist",
4996− "docker": "_fd_docker",
4997− ".docker": "_fd_docker",
4998− "docs": "_fd_docs",
4999− "doc": "_fd_docs",

3352 more lines aren’t shown here.

apps/web/src/vscode-icons.test.ts+0−52
@@ -1,52 +0,0 @@
1−import { assert, describe, it } from "vite-plus/test";
2−
3−import { getVscodeIconUrlForEntry } from "./vscode-icons";
4−
5−describe("getVscodeIconUrlForEntry", () => {
6− it("uses exact filename matches from the vscode-icons manifest", () => {
7− const darkUrl = getVscodeIconUrlForEntry("pnpm-workspace.yaml", "file", "dark");
8− const lightUrl = getVscodeIconUrlForEntry("pnpm-workspace.yaml", "file", "light");
9−
10− assert.isTrue(darkUrl.endsWith("/file_type_pnpm.svg"));
11− assert.isTrue(lightUrl.endsWith("/file_type_light_pnpm.svg"));
12− });
13−
14− it("uses longest extension match for compound extensions", () => {
15− const iconUrl = getVscodeIconUrlForEntry("tsconfig.tsbuildinfo", "file", "dark");
16− const manifestStyleUrl = getVscodeIconUrlForEntry("buf.yaml", "file", "dark");
17− assert.isTrue(iconUrl.endsWith("/file_type_tsbuildinfo.svg"));
18− assert.isTrue(manifestStyleUrl.endsWith("/file_type_buf.svg"));
19− });
20−
21− it("uses folder mappings and light-aware filename mappings", () => {
22− const folderUrl = getVscodeIconUrlForEntry("packages/src", "directory", "light");
23− const fileUrl = getVscodeIconUrlForEntry("AGENTS.md", "file", "light");
24−
25− assert.isTrue(folderUrl.endsWith("/folder_type_src.svg"));
26− assert.isTrue(fileUrl.endsWith("/file_type_light_agents.svg"));
27− });
28−
29− it("falls back to language-based mappings for path-only cases", () => {
30− const tsxUrl = getVscodeIconUrlForEntry("checkbox.tsx", "file", "light");
31− const dockerfileUrl = getVscodeIconUrlForEntry("Dockerfile", "file", "dark");
32− const shellUrl = getVscodeIconUrlForEntry("entrypoint.sh", "file", "dark");
33− const htmlUrl = getVscodeIconUrlForEntry("index.html", "file", "dark");
34− const cursorRulesUrl = getVscodeIconUrlForEntry("general.mdc", "file", "dark");
35− const githubWorkflowUrl = getVscodeIconUrlForEntry(".github/workflows/ci.yml", "file", "light");
36−
37− assert.isTrue(tsxUrl.endsWith("/file_type_reactts.svg"));
38− assert.isTrue(dockerfileUrl.endsWith("/file_type_docker.svg"));
39− assert.isTrue(shellUrl.endsWith("/file_type_shell.svg"));
40− assert.isTrue(htmlUrl.endsWith("/file_type_html.svg"));
41− assert.isTrue(cursorRulesUrl.endsWith("/file_type_markdown.svg"));
42− assert.isTrue(githubWorkflowUrl.endsWith("/file_type_light_yaml.svg"));
43− });
44−
45− it("falls back to defaults when there is no match", () => {
46− const fileUrl = getVscodeIconUrlForEntry("foo.unknown-ext", "file", "dark");
47− const folderUrl = getVscodeIconUrlForEntry("totally-unknown-folder", "directory", "dark");
48−
49− assert.isTrue(fileUrl.endsWith("/default_file.svg"));
50− assert.isTrue(folderUrl.endsWith("/default_folder.svg"));
51− });
52−});
apps/web/src/vscode-icons.ts+0−211
@@ -1,211 +0,0 @@
1−import vscodeIconsManifest from "./vscode-icons-manifest.json";
2−import languageAssociationsData from "./vscode-icons-language-associations.json";
3−
4−const VSCODE_ICONS_VERSION = "v12.17.0";
5−const VSCODE_ICONS_BASE_URL = `https://cdn.jsdelivr.net/gh/vscode-icons/vscode-icons@${VSCODE_ICONS_VERSION}/icons`;
6−
7−interface IconDefinition {
8− iconPath: string;
9−}
10−
11−interface IconLookupSection {
12− file?: string;
13− folder?: string;
14− fileNames: Record<string, string>;
15− fileExtensions: Record<string, string>;
16− folderNames: Record<string, string>;
17− languageIds?: Record<string, string>;
18−}
19−
20−interface VscodeIconsManifest extends IconLookupSection {
21− iconDefinitions: Record<string, IconDefinition>;
22− light: IconLookupSection;
23−}
24−
25−interface LanguageAssociations {
26− version: string;
27− extensionToLanguageId: Record<string, string>;
28− fileNameToLanguageId: Record<string, string>;
29−}
30−
31−const manifest = vscodeIconsManifest as VscodeIconsManifest;
32−const languageAssociations = languageAssociationsData as LanguageAssociations;
33−const iconDefinitions = manifest.iconDefinitions;
34−
35−const darkFileNames = toLowercaseLookup(manifest.fileNames);
36−const lightFileNames = toLowercaseLookup(manifest.light.fileNames);
37−const darkFileExtensions = toLowercaseLookup(manifest.fileExtensions);
38−const lightFileExtensions = toLowercaseLookup(manifest.light.fileExtensions);
39−const darkFolderNames = toLowercaseLookup(manifest.folderNames);
40−const lightFolderNames = toLowercaseLookup(manifest.light.folderNames);
41−const darkLanguageIds = toLowercaseLookup(manifest.languageIds ?? {});
42−const lightLanguageIds = toLowercaseLookup(manifest.light.languageIds ?? {});
43−const languageIdByExtension = toLowercaseLookup(languageAssociations.extensionToLanguageId);
44−const languageIdByFileName = toLowercaseLookup(languageAssociations.fileNameToLanguageId);
45−const localLanguageIdByExtensionOverrides = {
46− // Cursor rules files (*.mdc) are commonly treated as markdown in VSCode/Cursor.
47− mdc: "markdown",
48− // Upstream languages.ts currently maps .html to django-html before html.
49− // Prefer the base HTML icon for standalone HTML files.
50− html: "html",
51− // Upstream languages.ts maps yml/yaml to specialized language ids that can produce
52− // non-generic YAML icons (for example cloudfoundry/esphome). Prefer the base YAML icon
53− // unless a more specific basename/extension match (e.g. azure-pipelines.yml) is found.
54− yml: "yaml",
55− yaml: "yaml",
56−} as const;
57−
58−const defaultDarkFileIconDefinition = manifest.file ?? "_file";
59−const defaultLightFileIconDefinition = manifest.light.file ?? defaultDarkFileIconDefinition;
60−const defaultDarkFolderIconDefinition = manifest.folder ?? "_folder";
61−const defaultLightFolderIconDefinition = manifest.light.folder ?? defaultDarkFolderIconDefinition;
62−
63−function toLowercaseLookup(source: Record<string, string>): Record<string, string> {
64− const entries = Object.entries(source);
65− const lookup: Record<string, string> = {};
66− for (const [key, value] of entries) {
67− lookup[key.toLowerCase()] = value;
68− }
69− return lookup;
70−}
71−
72−const extensionByLanguageId: Record<string, string> = {};
73−for (const [extension, languageId] of Object.entries(languageAssociations.extensionToLanguageId)) {
74− const key = languageId.toLowerCase();
75− if (!(key in extensionByLanguageId)) {
76− extensionByLanguageId[key] = extension.toLowerCase();
77− }
78−}
79−
80−/**
81− * Synthesizes a file name whose icon resolution best represents a markdown
82− * fence language id — handles both extension-style ids ("ts", "py") and
83− * language ids ("typescript", "python", "shellscript").
84− */
85−export function syntheticFileNameForLanguageId(languageId: string): string {
86− const normalized = languageId.toLowerCase();
87− return `file.${extensionByLanguageId[normalized] ?? normalized}`;
88−}
89−
90−export function basenameOfPath(pathValue: string): string {
91− const slashIndex = pathValue.lastIndexOf("/");
92− if (slashIndex === -1) return pathValue;
93− return pathValue.slice(slashIndex + 1);
94−}
95−
96−export function inferEntryKindFromPath(pathValue: string): "file" | "directory" {
97− const base = basenameOfPath(pathValue);
98− if (base.startsWith(".") && !base.slice(1).includes(".")) {
99− return "directory";
100− }
101− if (base.includes(".")) {
102− return "file";
103− }
104− return "directory";
105−}
106−
107−function extensionCandidates(fileName: string): string[] {
108− const candidates = new Set<string>();
109− if (fileName.includes(".")) {
110− candidates.add(fileName);
111− }
112− let dotIndex = fileName.indexOf(".");
113− while (dotIndex !== -1 && dotIndex < fileName.length - 1) {
114− const candidate = fileName.slice(dotIndex + 1);
115− if (candidate.length > 0) {
116− candidates.add(candidate);
117− }
118− dotIndex = fileName.indexOf(".", dotIndex + 1);
119− }
120− return [...candidates];
121−}
122−
123−function resolveLanguageFallbackDefinition(
124− pathValue: string,
125− theme: "light" | "dark",
126−): string | null {
127− const basename = basenameOfPath(pathValue).toLowerCase();
128− const languageIds = theme === "light" ? lightLanguageIds : darkLanguageIds;
129−
130− const fromBasenameLanguage = languageIdByFileName[basename];
131− if (fromBasenameLanguage) {
132− return languageIds[fromBasenameLanguage] ?? darkLanguageIds[fromBasenameLanguage] ?? null;
133− }
134−
135− for (const candidate of extensionCandidates(basename)) {
136− const languageId =
137− localLanguageIdByExtensionOverrides[
138− candidate as keyof typeof localLanguageIdByExtensionOverrides
139− ] ?? languageIdByExtension[candidate];
140− if (!languageId) continue;
141− return languageIds[languageId] ?? darkLanguageIds[languageId] ?? null;
142− }
143−
144− return null;
145−}
146−
147−function iconFilenameForDefinitionKey(definitionKey: string | undefined): string | null {
148− if (!definitionKey) return null;
149− const iconPath = iconDefinitions[definitionKey]?.iconPath;
150− if (!iconPath) return null;
151− const slashIndex = iconPath.lastIndexOf("/");
152− if (slashIndex === -1) {
153− return iconPath;
154− }
155− return iconPath.slice(slashIndex + 1);
156−}
157−
158−function resolveFileDefinition(pathValue: string, theme: "light" | "dark"): string {
159− const basename = basenameOfPath(pathValue).toLowerCase();
160− const fileNames = theme === "light" ? lightFileNames : darkFileNames;
161− const fileExtensions = theme === "light" ? lightFileExtensions : darkFileExtensions;
162−
163− const fromFileName = fileNames[basename] ?? darkFileNames[basename];
164− if (fromFileName) return fromFileName;
165−
166− for (const candidate of extensionCandidates(basename)) {
167− const fromExtension = fileExtensions[candidate] ?? darkFileExtensions[candidate];
168− if (fromExtension) return fromExtension;
169− }
170−
171− const fromLanguage = resolveLanguageFallbackDefinition(pathValue, theme);
172− if (fromLanguage) return fromLanguage;
173−
174− return theme === "light" ? defaultLightFileIconDefinition : defaultDarkFileIconDefinition;
175−}
176−
177−function resolveFolderDefinition(pathValue: string, theme: "light" | "dark"): string {
178− const basename = basenameOfPath(pathValue).toLowerCase();
179− const folderNames = theme === "light" ? lightFolderNames : darkFolderNames;
180− return (
181− folderNames[basename] ??
182− darkFolderNames[basename] ??
183− (theme === "light" ? defaultLightFolderIconDefinition : defaultDarkFolderIconDefinition)
184− );
185−}
186−
187−/** True when the file name resolves to a real icon rather than the generic default. */
188−export function hasSpecificVscodeIconForFileName(
189− fileName: string,
190− theme: "light" | "dark",
191−): boolean {
192− const definition = resolveFileDefinition(fileName, theme);
193− return (
194− definition !== defaultDarkFileIconDefinition && definition !== defaultLightFileIconDefinition
195− );
196−}
197−
198−export function getVscodeIconUrlForEntry(
199− pathValue: string,
200− kind: "file" | "directory",
201− theme: "light" | "dark",
202−): string {
203− const definitionKey =
204− kind === "directory"
205− ? resolveFolderDefinition(pathValue, theme)
206− : resolveFileDefinition(pathValue, theme);
207− const iconFilename =
208− iconFilenameForDefinitionKey(definitionKey) ??
209− (kind === "directory" ? "default_folder.svg" : "default_file.svg");
210− return `${VSCODE_ICONS_BASE_URL}/${iconFilename}`;
211−}
apps/web/vite.config.ts+1−0
@@ -121,6 +121,7 @@ export default defineConfig(() => { · 120 unmodified lines
121121 optimizeDeps: {
122122 include: [
123123 "@pierre/diffs",
124+ "@pierre/diffs/editor",
124125 "@pierre/diffs/react",
125126 "@pierre/diffs/worker/worker.js",
126127 "effect/Array",
package.json+0−1
@@ -35,7 +35,6 @@ · 34 unmodified lines
3535 "dist:desktop:win:x64": "node scripts/build-desktop-artifact.ts --platform win --target nsis --arch x64",
3636 "release:smoke": "node scripts/release-smoke.ts",
3737 "clean": "rm -rf node_modules apps/*/node_modules packages/*/node_modules apps/*/dist apps/*/dist-electron packages/*/dist .vite-plus apps/*/.vite-plus packages/*/.vite-plus",
38− "sync:vscode-icons": "node scripts/sync-vscode-icons.mjs",
3938 "sync:repos": "node scripts/sync-reference-repos.ts"
4039 },
4140 "devDependencies": {
packages/client-runtime/src/wsRpcClient.ts+6−0
@@ -96,6 +96,8 @@ export interface WsRpcClient { · 95 unmodified lines
9696 readonly subscribePorts: RpcStreamMethod<typeof WS_METHODS.subscribeDiscoveredLocalServers>;
9797 };
9898 readonly projects: {
99+ readonly listEntries: RpcUnaryMethod<typeof WS_METHODS.projectsListEntries>;
100+ readonly readFile: RpcUnaryMethod<typeof WS_METHODS.projectsReadFile>;
99101 readonly searchEntries: RpcUnaryMethod<typeof WS_METHODS.projectsSearchEntries>;
100102 readonly writeFile: RpcUnaryMethod<typeof WS_METHODS.projectsWriteFile>;
101103 };
@@ -267,6 +269,10 @@ export function createWsRpcClient( · 165 unmodified lines
267269 ),
268270 },
269271 projects: {
272+ listEntries: (input) =>
273+ transport.request((client) => client[WS_METHODS.projectsListEntries](input)),
274+ readFile: (input) =>
275+ transport.request((client) => client[WS_METHODS.projectsReadFile](input)),
270276 searchEntries: (input) =>
271277 transport.request((client) => client[WS_METHODS.projectsSearchEntries](input)),
272278 writeFile: (input) =>
packages/contracts/src/ipc.ts+6−0
@@ -22,6 +22,10 @@ import type { ReviewDiffPreviewInput, ReviewDiffPreviewResult } from "./review.t · 21 unmodified lines
2222 import type { FilesystemBrowseInput, FilesystemBrowseResult } from "./filesystem.ts";
2323 import type { AssetCreateUrlInput, AssetCreateUrlResult } from "./assets.ts";
2424 import type {
25+ ProjectListEntriesInput,
26+ ProjectListEntriesResult,
27+ ProjectReadFileInput,
28+ ProjectReadFileResult,
2529 ProjectSearchEntriesInput,
2630 ProjectSearchEntriesResult,
2731 ProjectWriteFileInput,
@@ -1110,6 +1114,8 @@ export interface EnvironmentApi { · 1082 unmodified lines
11101114 ) => () => void;
11111115 };
11121116 projects: {
1117+ listEntries: (input: ProjectListEntriesInput) => Promise<ProjectListEntriesResult>;
1118+ readFile: (input: ProjectReadFileInput) => Promise<ProjectReadFileResult>;
11131119 searchEntries: (input: ProjectSearchEntriesInput) => Promise<ProjectSearchEntriesResult>;
11141120 writeFile: (input: ProjectWriteFileInput) => Promise<ProjectWriteFileResult>;
11151121 };
packages/contracts/src/project.ts+43−1
@@ -1,8 +1,9 @@
11 import * as Schema from "effect/Schema";
2−import { PositiveInt, TrimmedNonEmptyString } from "./baseSchemas.ts";
2+import { NonNegativeInt, PositiveInt, TrimmedNonEmptyString } from "./baseSchemas.ts";
33
44 const PROJECT_SEARCH_ENTRIES_MAX_LIMIT = 200;
55 const PROJECT_WRITE_FILE_PATH_MAX_LENGTH = 512;
6+const PROJECT_READ_FILE_PATH_MAX_LENGTH = 512;
67
78 export const ProjectSearchEntriesInput = Schema.Struct({
89 cwd: TrimmedNonEmptyString,
@@ -26,6 +27,17 @@ export const ProjectSearchEntriesResult = Schema.Struct({ · 17 unmodified lines
2627 });
2728 export type ProjectSearchEntriesResult = typeof ProjectSearchEntriesResult.Type;
2829
30+export const ProjectListEntriesInput = Schema.Struct({
31+ cwd: TrimmedNonEmptyString,
32+});
33+export type ProjectListEntriesInput = typeof ProjectListEntriesInput.Type;
34+
35+export const ProjectListEntriesResult = Schema.Struct({
36+ entries: Schema.Array(ProjectEntry),
37+ truncated: Schema.Boolean,
38+});
39+export type ProjectListEntriesResult = typeof ProjectListEntriesResult.Type;
40+
2941 export class ProjectSearchEntriesError extends Schema.TaggedErrorClass<ProjectSearchEntriesError>()(
3042 "ProjectSearchEntriesError",
3143 {
@@ -34,6 +46,36 @@ export class ProjectSearchEntriesError extends Schema.TaggedErrorClass<ProjectSe · 2 unmodified lines
3446 },
3547 ) {}
3648
49+export class ProjectListEntriesError extends Schema.TaggedErrorClass<ProjectListEntriesError>()(
50+ "ProjectListEntriesError",
51+ {
52+ message: TrimmedNonEmptyString,
53+ cause: Schema.optional(Schema.Defect()),
54+ },
55+) {}
56+
57+export const ProjectReadFileInput = Schema.Struct({
58+ cwd: TrimmedNonEmptyString,
59+ relativePath: TrimmedNonEmptyString.check(Schema.isMaxLength(PROJECT_READ_FILE_PATH_MAX_LENGTH)),
60+});
61+export type ProjectReadFileInput = typeof ProjectReadFileInput.Type;
62+
63+export const ProjectReadFileResult = Schema.Struct({
64+ relativePath: TrimmedNonEmptyString,
65+ contents: Schema.String,
66+ byteLength: NonNegativeInt,
67+ truncated: Schema.Boolean,
68+});
69+export type ProjectReadFileResult = typeof ProjectReadFileResult.Type;
70+
71+export class ProjectReadFileError extends Schema.TaggedErrorClass<ProjectReadFileError>()(
72+ "ProjectReadFileError",
73+ {
74+ message: TrimmedNonEmptyString,
75+ cause: Schema.optional(Schema.Defect()),
76+ },
77+) {}
78+
3779 export const ProjectWriteFileInput = Schema.Struct({
3880 cwd: TrimmedNonEmptyString,
3981 relativePath: TrimmedNonEmptyString.check(Schema.isMaxLength(PROJECT_WRITE_FILE_PATH_MAX_LENGTH)),
packages/contracts/src/rpc.ts+22−0
@@ -65,6 +65,12 @@ import { · 64 unmodified lines
6565 RelayClientStatusSchema,
6666 } from "./relayClient.ts";
6767 import {
68+ ProjectListEntriesError,
69+ ProjectListEntriesInput,
70+ ProjectListEntriesResult,
71+ ProjectReadFileError,
72+ ProjectReadFileInput,
73+ ProjectReadFileResult,
6874 ProjectSearchEntriesError,
6975 ProjectSearchEntriesInput,
7076 ProjectSearchEntriesResult,
@@ -141,6 +147,8 @@ export const WS_METHODS = { · 70 unmodified lines
141147 projectsList: "projects.list",
142148 projectsAdd: "projects.add",
143149 projectsRemove: "projects.remove",
150+ projectsListEntries: "projects.listEntries",
151+ projectsReadFile: "projects.readFile",
144152 projectsSearchEntries: "projects.searchEntries",
145153 projectsWriteFile: "projects.writeFile",
146154
@@ -350,6 +358,18 @@ export const WsProjectsSearchEntriesRpc = Rpc.make(WS_METHODS.projectsSearchEntr · 203 unmodified lines
350358 error: Schema.Union([ProjectSearchEntriesError, EnvironmentAuthorizationError]),
351359 });
352360
361+export const WsProjectsListEntriesRpc = Rpc.make(WS_METHODS.projectsListEntries, {
362+ payload: ProjectListEntriesInput,
363+ success: ProjectListEntriesResult,
364+ error: Schema.Union([ProjectListEntriesError, EnvironmentAuthorizationError]),
365+});
366+
367+export const WsProjectsReadFileRpc = Rpc.make(WS_METHODS.projectsReadFile, {
368+ payload: ProjectReadFileInput,
369+ success: ProjectReadFileResult,
370+ error: Schema.Union([ProjectReadFileError, EnvironmentAuthorizationError]),
371+});
372+
353373 export const WsProjectsWriteFileRpc = Rpc.make(WS_METHODS.projectsWriteFile, {
354374 payload: ProjectWriteFileInput,
355375 success: ProjectWriteFileResult,
@@ -676,6 +696,8 @@ export const WsRpcGroup = RpcGroup.make( · 320 unmodified lines
676696 WsSourceControlLookupRepositoryRpc,
677697 WsSourceControlCloneRepositoryRpc,
678698 WsSourceControlPublishRepositoryRpc,
699+ WsProjectsListEntriesRpc,
700+ WsProjectsReadFileRpc,
679701 WsProjectsSearchEntriesRpc,
680702 WsProjectsWriteFileRpc,
681703 WsShellOpenInEditorRpc,
patches/@pierre%2Fdiffs@1.3.0-beta.4.patchrenamed from patches/@pierre%2Fdiffs@1.1.20.patch+2−2
@@ -1,5 +1,5 @@
11 diff --git a/package.json b/package.json
2−index c0e762b13b56247b256520754e439cbc16bb797d..d298b87c175ec891d1b50f681c9031f4b1929e67 100644
2+index b18c94f3f7b40bdb15084ab7cabcb19dd29c61f7..ab96ac589d368e806ef45480283d6e0fa199117f 100644
33 --- a/package.json
44 +++ b/package.json
55 @@ -51,6 +51,18 @@
@@ -20,4 +20,4 @@ index c0e762b13b56247b256520754e439cbc16bb797d..d298b87c175ec891d1b50f681c9031f4 · 14 unmodified lines
2020 + "import": "./dist/utils/parsePatchFiles.js"
2121 }
2222 },
23− "scripts": {
23+ "publishConfig": {
pnpm-lock.yaml+89−17
@@ -19,8 +19,8 @@ catalogs: · 18 unmodified lines
1919 specifier: 1.8.0
2020 version: 1.8.0
2121 '@pierre/diffs':
22− specifier: 1.1.20
23− version: 1.1.20
22+ specifier: 1.3.0-beta.4
23+ version: 1.3.0-beta.4
2424 '@typescript/native-preview':
2525 specifier: 7.0.0-dev.20260604.1
2626 version: 7.0.0-dev.20260604.1
@@ -66,9 +66,9 @@ patchedDependencies: · 39 unmodified lines
6666 '@expo/metro-config@56.0.13':
6767 hash: 8cb08b5bb7051ed9d2dbe46a2c293c5a1e17f1bd6ddf30de27909e18c921ff46
6868 path: patches/@expo%2Fmetro-config@56.0.13.patch
69− '@pierre/diffs@1.1.20':
70− hash: e4e35ba95100de3708f900e0d9ea62bca732b1e4486024b5055f48cd128dd9e0
71− path: patches/@pierre%2Fdiffs@1.1.20.patch
69+ '@pierre/diffs@1.3.0-beta.4':
70+ hash: f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b
71+ path: patches/@pierre%2Fdiffs@1.3.0-beta.4.patch
7272 effect@4.0.0-beta.78:
7373 hash: 883249d8efbb462e928e21fefef96027b66aec50751178cafdce45f08eee3754
7474 path: patches/effect@4.0.0-beta.78.patch
@@ -198,7 +198,7 @@ importers: · 123 unmodified lines
198198 version: 1.8.0
199199 '@pierre/diffs':
200200 specifier: 'catalog:'
201− version: 1.1.20(patch_hash=e4e35ba95100de3708f900e0d9ea62bca732b1e4486024b5055f48cd128dd9e0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
201+ version: 1.3.0-beta.4(patch_hash=f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b)(@shikijs/themes@3.23.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
202202 '@react-native-menu/menu':
203203 specifier: ^2.0.0
204204 version: 2.0.0(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
@@ -400,7 +400,7 @@ importers: · 195 unmodified lines
400400 version: 1.15.13
401401 '@pierre/diffs':
402402 specifier: 'catalog:'
403− version: 1.1.20(patch_hash=e4e35ba95100de3708f900e0d9ea62bca732b1e4486024b5055f48cd128dd9e0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
403+ version: 1.3.0-beta.4(patch_hash=f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b)(@shikijs/themes@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
404404 effect:
405405 specifier: 4.0.0-beta.78
406406 version: 4.0.0-beta.78(patch_hash=883249d8efbb462e928e21fefef96027b66aec50751178cafdce45f08eee3754)
@@ -482,7 +482,10 @@ importers: · 75 unmodified lines
482482 version: 0.41.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(yjs@13.6.31)
483483 '@pierre/diffs':
484484 specifier: 'catalog:'
485− version: 1.1.20(patch_hash=e4e35ba95100de3708f900e0d9ea62bca732b1e4486024b5055f48cd128dd9e0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
485+ version: 1.3.0-beta.4(patch_hash=f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b)(@shikijs/themes@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
486+ '@pierre/trees':
487+ specifier: 1.0.0-beta.4
488+ version: 1.0.0-beta.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
486489 '@t3tools/client-runtime':
487490 specifier: workspace:*
488491 version: link:../../packages/client-runtime
@@ -3203,16 +3206,42 @@ packages: · 2714 unmodified lines
32033206 resolution: {integrity: sha512-titLmukUt/h8ho7Svlf0xSBjoy2ccZKrXjpXpZCj+v6V4CJccC2KyP45BLSCMx8YIpifMyiDyUptM4+5sruKbQ==}
32043207 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
32053208
3206− '@pierre/diffs@1.1.20':
3207− resolution: {integrity: sha512-lLi+3sLCm3QDd5/aLO9pw+WbF6UzhrkWm2oTZ5WZJTGemOyUNRJ4DDhcEKmVusu4C4bXx9Nssh6fF+wQcapb5w==}
3209+ '@pierre/diffs@1.3.0-beta.4':
3210+ resolution: {integrity: sha512-poFcsvhcQt9lH/InzAPaGs47WYHMidnFCjuYGNU41HiVLJP4mkIQDSdvcnPIkBuh/cYbPOQg/YE3T1kSpr01GA==}
32083211 peerDependencies:
32093212 react: ^18.3.1 || ^19.0.0
32103213 react-dom: ^18.3.1 || ^19.0.0
32113214
3212− '@pierre/theme@0.0.28':
3213− resolution: {integrity: sha512-1j/H/fECBuc9dEvntdWI+l435HZapw+RCJTlqCA6BboQ5TjlnE005j/ROWutXIs8aq5OAc82JI2Kwk4A1WWBgw==}
3215+ '@pierre/theme@1.0.3':
3216+ resolution: {integrity: sha512-sWHv11TMoqKxKDgTIk5VbhQjdPhs8DCcBxbjh3mRlS3YOM/OcrWoGX6MM8eBGn9cUu3M46Py0JnxsG2nJaFTuA==}
32143217 engines: {vscode: ^1.0.0}
32153218
3219+ '@pierre/theming@0.0.1':
3220+ resolution: {integrity: sha512-1thlEtJbqdyLzc1ZS2KQa1q7FzDGHT4dTEdKHoyQjOMeWWOmbVG5/ndEfOKfAb5Fzkz8cNJrOjFLiZoDH/A03A==}
3221+ peerDependencies:
3222+ '@pierre/theme': ^1.0.0
3223+ '@shikijs/themes': ^3.0.0 || ^4.0.0
3224+ react: ^18.3.1 || ^19.0.0
3225+ react-dom: ^18.3.1 || ^19.0.0
3226+ shiki: ^3.0.0 || ^4.0.0
3227+ peerDependenciesMeta:
3228+ '@pierre/theme':
3229+ optional: true
3230+ '@shikijs/themes':
3231+ optional: true
3232+ react:
3233+ optional: true
3234+ react-dom:
3235+ optional: true
3236+ shiki:
3237+ optional: true
3238+
3239+ '@pierre/trees@1.0.0-beta.4':
3240+ resolution: {integrity: sha512-OfT1yk9ne8Te5+GB5zUY8yqE6B8BqjBHQJleH4lu8ltwNpoocZl4vXt1AzlEExpxI/pp+AFX5QG+lR3JjtTEag==}
3241+ peerDependencies:
3242+ react: ^18.3.1 || ^19.0.0
3243+ react-dom: ^18.3.1 || ^19.0.0
3244+
32163245 '@polka/url@1.0.0-next.29':
32173246 resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
32183247
@@ -8078,6 +8107,14 @@ packages: · 4859 unmodified lines
80788107 engines: {node: '>=14.0.0'}
80798108 hasBin: true
80808109
8110+ preact-render-to-string@6.6.5:
8111+ resolution: {integrity: sha512-O6MHzYNIKYaiSX3bOw0gGZfEbOmlIDtDfWwN1JJdc/T3ihzRT6tGGSEWE088dWrEDGa1u7101q+6fzQnO9XCPA==}
8112+ peerDependencies:
8113+ preact: '>=10 || >= 11.0.0-0'
8114+
8115+ preact@11.0.0-beta.0:
8116+ resolution: {integrity: sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg==}
8117+
80818118 prettier@3.8.3:
80828119 resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==}
80838120 engines: {node: '>=14'}
@@ -12439,9 +12476,10 @@ snapshots: · 4355 unmodified lines
1243912476
1244012477 '@oxlint/plugins@1.68.0': {}
1244112478
12442− '@pierre/diffs@1.1.20(patch_hash=e4e35ba95100de3708f900e0d9ea62bca732b1e4486024b5055f48cd128dd9e0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
12479+ '@pierre/diffs@1.3.0-beta.4(patch_hash=f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b)(@shikijs/themes@3.23.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
1244312480 dependencies:
12444− '@pierre/theme': 0.0.28
12481+ '@pierre/theme': 1.0.3
12482+ '@pierre/theming': 0.0.1(@pierre/theme@1.0.3)(@shikijs/themes@3.23.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(shiki@3.23.0)
1244512483 '@shikijs/transformers': 3.23.0
1244612484 diff: 8.0.3
1244712485 hast-util-to-html: 9.0.5
@@ -12449,10 +12487,13 @@ snapshots: · 1 unmodified line
1244912487 react: 19.2.3
1245012488 react-dom: 19.2.3(react@19.2.3)
1245112489 shiki: 3.23.0
12490+ transitivePeerDependencies:
12491+ - '@shikijs/themes'
1245212492
12453− '@pierre/diffs@1.1.20(patch_hash=e4e35ba95100de3708f900e0d9ea62bca732b1e4486024b5055f48cd128dd9e0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
12493+ '@pierre/diffs@1.3.0-beta.4(patch_hash=f5d41705ce94bbafc731d92e9cb1671db710df046dd135cb894e3e3e9164a75b)(@shikijs/themes@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
1245412494 dependencies:
12455− '@pierre/theme': 0.0.28
12495+ '@pierre/theme': 1.0.3
12496+ '@pierre/theming': 0.0.1(@pierre/theme@1.0.3)(@shikijs/themes@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(shiki@3.23.0)
1245612497 '@shikijs/transformers': 3.23.0
1245712498 diff: 8.0.3
1245812499 hast-util-to-html: 9.0.5
@@ -12460,8 +12501,33 @@ snapshots: · 1 unmodified line
1246012501 react: 19.2.6
1246112502 react-dom: 19.2.6(react@19.2.6)
1246212503 shiki: 3.23.0
12504+ transitivePeerDependencies:
12505+ - '@shikijs/themes'
1246312506
12464− '@pierre/theme@0.0.28': {}
12507+ '@pierre/theme@1.0.3': {}
12508+
12509+ '@pierre/theming@0.0.1(@pierre/theme@1.0.3)(@shikijs/themes@3.23.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(shiki@3.23.0)':
12510+ optionalDependencies:
12511+ '@pierre/theme': 1.0.3
12512+ '@shikijs/themes': 3.23.0
12513+ react: 19.2.3
12514+ react-dom: 19.2.3(react@19.2.3)
12515+ shiki: 3.23.0
12516+
12517+ '@pierre/theming@0.0.1(@pierre/theme@1.0.3)(@shikijs/themes@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(shiki@3.23.0)':
12518+ optionalDependencies:
12519+ '@pierre/theme': 1.0.3
12520+ '@shikijs/themes': 4.1.0
12521+ react: 19.2.6
12522+ react-dom: 19.2.6(react@19.2.6)
12523+ shiki: 3.23.0
12524+
12525+ '@pierre/trees@1.0.0-beta.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
12526+ dependencies:
12527+ preact: 11.0.0-beta.0
12528+ preact-render-to-string: 6.6.5(preact@11.0.0-beta.0)
12529+ react: 19.2.6
12530+ react-dom: 19.2.6(react@19.2.6)
1246512531
1246612532 '@polka/url@1.0.0-next.29': {}
1246712533
@@ -17748,6 +17814,12 @@ snapshots: · 5280 unmodified lines
1774817814 commander: 9.5.0
1774917815 optional: true
1775017816
17817+ preact-render-to-string@6.6.5(preact@11.0.0-beta.0):
17818+ dependencies:
17819+ preact: 11.0.0-beta.0
17820+
17821+ preact@11.0.0-beta.0: {}
17822+
1775117823 prettier@3.8.3: {}
1775217824
1775317825 pretty-cache-header@1.0.0:
pnpm-workspace.yaml+4−2
@@ -28,7 +28,7 @@ catalog: · 27 unmodified lines
2828 "@effect/tsgo": 0.13.2
2929 "@noble/curves": 1.9.1
3030 "@noble/hashes": 1.8.0
31− "@pierre/diffs": 1.1.20
31+ "@pierre/diffs": 1.3.0-beta.4
3232 "@vitest/runner": 4.1.8
3333 "@types/node": 24.12.4
3434 "@typescript/native-preview": 7.0.0-dev.20260604.1
@@ -83,8 +83,10 @@ packageExtensions: · 48 unmodified lines
8383 dependencies:
8484 vite: "catalog:"
8585 patchedDependencies:
86+ # Keep non-browser consumers off the root entrypoint, which eagerly imports
87+ # DOM-dependent renderers. These utility/type subpaths are safe for mobile.
88+ "@pierre/diffs@1.3.0-beta.4": patches/@pierre%2Fdiffs@1.3.0-beta.4.patch
8689 "@effect/vitest@4.0.0-beta.78": patches/@effect__vitest@4.0.0-beta.78.patch
8790 "@expo/metro-config@56.0.13": patches/@expo%2Fmetro-config@56.0.13.patch
88− "@pierre/diffs@1.1.20": patches/@pierre%2Fdiffs@1.1.20.patch
8991 effect@4.0.0-beta.78: patches/effect@4.0.0-beta.78.patch
9092 react-native-nitro-modules@0.35.9: patches/react-native-nitro-modules@0.35.9.patch
scripts/sync-vscode-icons.mjs+0−153
@@ -1,153 +0,0 @@
1−#!/usr/bin/env node
2−
3−import fs from "node:fs/promises";
4−import os from "node:os";
5−import path from "node:path";
6−import vm from "node:vm";
7−import { execFile } from "node:child_process";
8−import { promisify } from "node:util";
9−
10−const execFileAsync = promisify(execFile);
11−
12−const VERSION = process.argv[2] ?? "12.17.0";
13−const VERSION_TAG = `v${VERSION}`;
14−const VSIX_URL = `https://open-vsx.org/api/vscode-icons-team/vscode-icons/${VERSION}/file/vscode-icons-team.vscode-icons-${VERSION}.vsix`;
15−const LANGUAGES_URL = `https://raw.githubusercontent.com/vscode-icons/vscode-icons/${VERSION_TAG}/src/iconsManifest/languages.ts`;
16−
17−const REPO_ROOT = process.cwd();
18−const MANIFEST_PATH = path.join(REPO_ROOT, "apps/web/src/vscode-icons-manifest.json");
19−const ASSOCIATIONS_PATH = path.join(
20− REPO_ROOT,
21− "apps/web/src/vscode-icons-language-associations.json",
22−);
23−
24−function normalizeExtension(value) {
25− return value.trim().toLowerCase().replace(/^\./, "");
26−}
27−
28−function normalizeFileName(value) {
29− return value.trim().toLowerCase();
30−}
31−
32−function putIfAbsent(target, key, value) {
33− if (!(key in target)) {
34− target[key] = value;
35− }
36−}
37−
38−async function downloadVsix(tmpDir) {
39− const vsixPath = path.join(tmpDir, `vscode-icons-${VERSION}.vsix`);
40− const response = await fetch(VSIX_URL);
41− if (!response.ok) {
42− throw new Error(`Failed to download VSIX: ${response.status} ${response.statusText}`);
43− }
44− const bytes = Buffer.from(await response.arrayBuffer());
45− await fs.writeFile(vsixPath, bytes);
46− return vsixPath;
47−}
48−
49−async function extractManifestFromVsix(vsixPath) {
50− const { stdout } = await execFileAsync("unzip", [
51− "-p",
52− vsixPath,
53− "extension/dist/src/vsicons-icon-theme.json",
54− ]);
55− if (!stdout || stdout.trim().length === 0) {
56− throw new Error("Could not extract vsicons-icon-theme.json from VSIX");
57− }
58− return JSON.parse(stdout);
59−}
60−
61−async function loadLanguagesCollection() {
62− const response = await fetch(LANGUAGES_URL);
63− if (!response.ok) {
64− throw new Error(`Failed to fetch languages.ts: ${response.status} ${response.statusText}`);
65− }
66− const rawSource = await response.text();
67− const source = rawSource
68− .replace(/^import[^;]+;\s*/gm, "")
69− .replace(/export const languages(?:\s*:\s*[^=]+)?\s*=/, "const languages =")
70− .replace(/\}\s*satisfies\s*Record<[^;]+>;/, "};");
71−
72− const context = {};
73− vm.createContext(context);
74− vm.runInContext(`${source}\n;globalThis.__languages = languages;`, context);
75− const languages = context.__languages;
76− if (!languages || typeof languages !== "object") {
77− throw new Error("Failed to parse languages.ts into a collection");
78− }
79− return languages;
80−}
81−
82−function buildLanguageAssociations(manifest, languages) {
83− const availableLanguageIds = new Set(Object.keys(manifest.languageIds ?? {}));
84− const extensionToLanguageId = {};
85− const fileNameToLanguageId = {};
86−
87− for (const entry of Object.values(languages)) {
88− if (!entry || typeof entry !== "object") continue;
89− const idsRaw = entry.ids;
90− const ids = Array.isArray(idsRaw) ? idsRaw : [idsRaw];
91− const knownExtensions = Array.isArray(entry.knownExtensions) ? entry.knownExtensions : [];
92− const knownFilenames = Array.isArray(entry.knownFilenames) ? entry.knownFilenames : [];
93−
94− for (const idValue of ids) {
95− if (typeof idValue !== "string") continue;
96− const languageId = idValue.trim();
97− if (languageId.length === 0) continue;
98− if (!availableLanguageIds.has(languageId)) continue;
99−
100− for (const extensionValue of knownExtensions) {
101− if (typeof extensionValue !== "string") continue;
102− const extension = normalizeExtension(extensionValue);
103− if (extension.length === 0) continue;
104− putIfAbsent(extensionToLanguageId, extension, languageId);
105− }
106−
107− for (const fileNameValue of knownFilenames) {
108− if (typeof fileNameValue !== "string") continue;
109− const fileName = normalizeFileName(fileNameValue);
110− if (fileName.length === 0) continue;
111− putIfAbsent(fileNameToLanguageId, fileName, languageId);
112− }
113− }
114− }
115−
116− return {
117− version: VERSION,
118− source: LANGUAGES_URL,
119− generatedAt: new Date().toISOString(),
120− extensionToLanguageId,
121− fileNameToLanguageId,
122− };
123−}
124−
125−async function main() {
126− const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "t3-vscode-icons-sync-"));
127− try {
128− const vsixPath = await downloadVsix(tmpDir);
129− const manifest = await extractManifestFromVsix(vsixPath);
130− const languages = await loadLanguagesCollection();
131− const associations = buildLanguageAssociations(manifest, languages);
132−
133− await fs.writeFile(MANIFEST_PATH, `${JSON.stringify(manifest)}\n`, "utf8");
134− await fs.writeFile(ASSOCIATIONS_PATH, `${JSON.stringify(associations)}\n`, "utf8");
135−
136− process.stdout.write(
137− [
138− `Synced vscode-icons ${VERSION}`,
139− `manifest: ${MANIFEST_PATH}`,
140− `language associations: ${ASSOCIATIONS_PATH}`,
141− `extension mappings: ${Object.keys(associations.extensionToLanguageId).length}`,
142− `filename mappings: ${Object.keys(associations.fileNameToLanguageId).length}`,
143− ].join("\n") + "\n",
144− );
145− } finally {
146− await fs.rm(tmpDir, { recursive: true, force: true });
147− }
148−}
149−
150−main().catch((error) => {
151− process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
152− process.exit(1);
153−});