Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
15be28d
refactor(vscode): enhance launch configurations and tasks
luxass Jan 13, 2026
7e009b9
chore(vscode): add README for extension development workspace
luxass Jan 13, 2026
ffbc26f
ci: add build step for vscode extension in CI workflow
luxass Jan 13, 2026
45d3dc0
chore(vscode): add initial settings configuration
luxass Jan 13, 2026
b8ac00a
feat(vscode): enhance UCD store configuration options
luxass Jan 13, 2026
a01a7a1
refactor(vscode): update store URL and improve icon logic
luxass Jan 14, 2026
a43a214
refactor(fs-bridge): update base URL and adjust path handling
luxass Jan 14, 2026
7ed1021
feat(vscode): add new commands and update command structure
luxass Jan 14, 2026
598abe7
feat(vscode): integrate UCD client and enhance content provider
luxass Jan 14, 2026
8899124
feat(vscode): add new commands for remote exploration and Unicode
luxass Jan 14, 2026
9149b0c
feat(vscode): add inspect file command and update commands
luxass Jan 14, 2026
3b84e97
feat(vscode): enhance hover messages with detailed Markdown
luxass Jan 14, 2026
e5b8abe
feat(vscode): add parser override generation command
luxass Jan 14, 2026
5c6dbc1
feat(vscode): implement auto decorations and hover information
luxass Jan 14, 2026
d2dda6c
chore: lint
luxass Jan 15, 2026
b253420
fix(turbo): add missing dependency to build task
luxass Jan 15, 2026
f7aebf2
feat(vscode): add selection view functionality and integration
luxass Jan 15, 2026
52977b1
chore: update typecheck command in package.json files
luxass Jan 15, 2026
571a177
chore(turbo): add $TURBO_EXTENDS$ dependency to tasks
luxass Jan 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
469 changes: 469 additions & 0 deletions .github/prompts/unicode-utils-parser-overrides.plan.md

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,28 @@ jobs:
- name: build packages
run: pnpm build

build-vscode:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: setup pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0

- name: setup node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version: lts/*
cache: pnpm

- name: install dependencies
run: pnpm install --frozen-lockfile

- name: build vscode extension
run: pnpm build:vscode

build-apps:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -77,6 +99,7 @@ jobs:
needs:
- build-packages
- build-apps
- build-vscode
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
Expand All @@ -95,7 +118,7 @@ jobs:
run: pnpm install --frozen-lockfile

- name: build
run: pnpm build
run: pnpm build && pnpm build:apps && pnpm build:vscode

- name: lint
run: pnpm lint
Expand All @@ -105,6 +128,7 @@ jobs:
needs:
- build-packages
- build-apps
- build-vscode
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
Expand All @@ -123,7 +147,7 @@ jobs:
run: pnpm install --frozen-lockfile

- name: build
run: pnpm build
run: pnpm build && pnpm build:apps && pnpm build:vscode

- name: typecheck
run: pnpm typecheck
17 changes: 16 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,32 @@
"version": "0.2.0",
"configurations": [
{
"name": "Extension",
"name": "Extension (Extension Only)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/vscode/playground",
"--extensionDevelopmentPath=${workspaceFolder}/vscode"
],
"outFiles": [
"${workspaceFolder}/vscode/dist/**/*.js"
],
"preLaunchTask": "npm: dev:vscode"
},
{
"name": "Extension (Full Watch)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/vscode/playground",
"--extensionDevelopmentPath=${workspaceFolder}/vscode"
],
"outFiles": [
"${workspaceFolder}/vscode/dist/**/*.js"
],
"preLaunchTask": "npm: dev:packages+vscode"
}
]
}
33 changes: 30 additions & 3 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,39 @@
"base": "$ts-webpack-watch",
"background": {
"activeOnStart": true,
"beginsPattern": "Build start",
"endsPattern": "Build complete"
"beginsPattern": "vscode-ucd:dev:.*Build start",
"endsPattern": "vscode-ucd:dev:.*✔ Rebuilt in"
}
}
],
"group": "build"
"group": {
"kind": "build",
"isDefault": false
}
},
{
"label": "npm: dev:packages+vscode",
"type": "shell",
"command": "turbo",
"args": ["watch", "dev", "--filter", "./packages/*", "--filter", "./vscode"],
"isBackground": true,
"presentation": {
"reveal": "never"
},
"problemMatcher": [
{
"base": "$ts-webpack-watch",
"background": {
"activeOnStart": true,
"beginsPattern": "vscode-ucd:dev:.*Build start",
"endsPattern": "vscode-ucd:dev:.*✔ Rebuilt in"
}
}
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
"build": "turbo run build --filter \"./packages/*\" --concurrency=15",
"build:apps": "turbo run build --filter \"./apps/*\"",
"build:app": "turbo run build --filter \"./apps/${APP_NAME}\"",
"build:vscode": "turbo run build --filter ./vscode",
"clean": "turbo run clean && git clean -xdf node_modules",
"dev": "turbo watch dev --filter \"./packages/*\"",
"dev:apps": "turbo run dev --filter \"./apps/*\"",
"dev:vscode": "turbo run dev --filter ./vscode",
"lint": "turbo run lint",
"test": "vitest run",
"test:watch": "vitest",
Expand Down
12 changes: 6 additions & 6 deletions packages/fs-bridge/playgrounds/http-playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface TestCase {
run: () => Promise<void>;
}

const BASE_URL = process.env.FS_BRIDGE_HTTP_BASE_URL || "https://api.ucdjs.dev/api/v1/files";
const BASE_URL = process.env.FS_BRIDGE_HTTP_BASE_URL || "https://ucd-store.ucdjs.dev";

console.log("fs-bridge HTTP Playground\n");
console.log("=".repeat(60));
Expand Down Expand Up @@ -176,7 +176,7 @@ const testCases: TestCase[] = [
{
description: "Listdir ensure correct paths",
async run() {
const entries = await bridge.listdir("16.0.0/ucd", true);
const entries = await bridge.listdir("16.0.0", true);

// eslint-disable-next-line ts/explicit-function-return-type
function checkPaths(nodes: typeof entries, parentPath: string) {
Expand All @@ -191,7 +191,7 @@ const testCases: TestCase[] = [
}
}

checkPaths(entries, "16.0.0/ucd/");
checkPaths(entries, "16.0.0/");
},
},

Expand Down Expand Up @@ -243,15 +243,15 @@ const testCases: TestCase[] = [
{
description: "Discover and read UnicodeData.txt",
async run() {
const entries = await bridge.listdir("16.0.0/ucd");
const entries = await bridge.listdir("16.0.0");
const unicodeData = entries.find((e) => e.name === "UnicodeData.txt");
if (!unicodeData) throw new Error("UnicodeData.txt not found");
if (unicodeData.type !== "file") throw new Error("Should be a file");

const exists = await bridge.exists("16.0.0/ucd/UnicodeData.txt");
const exists = await bridge.exists("16.0.0/UnicodeData.txt");
if (!exists) throw new Error("Should exist");

const content = await bridge.read("16.0.0/ucd/UnicodeData.txt");
const content = await bridge.read("16.0.0/UnicodeData.txt");
if (!content.includes(";")) throw new Error("Should contain semicolons");
},
},
Expand Down
2 changes: 1 addition & 1 deletion packages/fs-bridge/src/bridges/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const HTTPFileSystemBridge = defineFileSystemBridge({
for (const entry of data) {
if (entry.type === "directory") {
const children = await this.listdir!(
joinURL(path, entry.path),
entry.path,
true,
);

Expand Down
65 changes: 42 additions & 23 deletions packages/fs-bridge/test/bridges/http/http.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { FileEntry } from "@ucdjs/schemas";
import HTTPFileSystemBridge from "#internal:bridge/http";
import { HttpResponse, mockFetch } from "#test-utils/msw";
import { joinURL } from "@luxass/utils/path";
import { flattenFilePaths } from "@ucdjs-internal/shared";
import { UCDJS_STORE_BASE_URL } from "@ucdjs/env";
import { describe, expect, it } from "vitest";
Expand Down Expand Up @@ -169,29 +170,47 @@ describe("http fs-bridge", () => {
path: "/subdir/",
type: "directory",
},

]);
});

it("should list directory contents recursively", async () => {
const subdirData = [
{
type: "file" as const,
name: "nested.txt",
path: "/subdir/nested.txt",
lastModified: Date.now(),
},
] satisfies FileEntry[];

mockFetch([
["GET", `${baseUrl}/dir`, () => {
return new HttpResponse(JSON.stringify(mockDirectoryData), {
["GET", `${baseUrl}/dir`, ({ request }) => {
const url = new URL(request.url);
return new HttpResponse(JSON.stringify([
{
type: "file" as const,
name: "file1.txt",
path: joinURL(url.pathname, "file1.txt"),
lastModified: Date.now(),
},
{
type: "file" as const,
name: "file2.txt",
path: joinURL(url.pathname, "file2.txt"),
lastModified: Date.now(),
},
{
type: "directory" as const,
name: "subdir",
path: joinURL(url.pathname, "subdir/"),
lastModified: Date.now(),
},
] satisfies FileEntry[]), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}],
["GET", `${baseUrl}/dir/subdir`, () => {
return new HttpResponse(JSON.stringify(subdirData), {
["GET", `${baseUrl}/dir/subdir`, ({ request }) => {
const url = new URL(request.url);
return new HttpResponse(JSON.stringify([
{
type: "file" as const,
name: "nested.txt",
path: joinURL(url.pathname, "nested.txt"),
lastModified: Date.now(),
},
] satisfies FileEntry[]), {
status: 200,
headers: { "Content-Type": "application/json" },
});
Expand All @@ -200,14 +219,14 @@ describe("http fs-bridge", () => {

const files = await bridge.listdir("dir", true);
expect(files).toEqual([
{ type: "file", name: "file1.txt", path: "/file1.txt" },
{ type: "file", name: "file2.txt", path: "/file2.txt" },
{ type: "file", name: "file1.txt", path: "/dir/file1.txt" },
{ type: "file", name: "file2.txt", path: "/dir/file2.txt" },
{
type: "directory",
name: "subdir",
path: "/subdir/",
path: "/dir/subdir/",
children: [
{ type: "file", name: "nested.txt", path: "/subdir/nested.txt" },
{ type: "file", name: "nested.txt", path: "/dir/subdir/nested.txt" },
],
},
]);
Expand Down Expand Up @@ -261,13 +280,13 @@ describe("http fs-bridge", () => {
{
type: "file" as const,
name: "accessible.txt",
path: "/accessible.txt",
path: "/dir/accessible.txt",
lastModified: Date.now(),
},
{
type: "directory" as const,
name: "inaccessible",
path: "/inaccessible/",
path: "/dir/inaccessible/",
lastModified: Date.now(),
},
] satisfies FileEntry[]), {
Expand All @@ -291,10 +310,10 @@ describe("http fs-bridge", () => {

const files = await bridge.listdir("dir", true);
expect(files).toEqual([
{ type: "file", name: "accessible.txt", path: "/accessible.txt" },
{ type: "directory", name: "inaccessible", path: "/inaccessible/", children: [] },
{ type: "file", name: "accessible.txt", path: "/dir/accessible.txt" },
{ type: "directory", name: "inaccessible", path: "/dir/inaccessible/", children: [] },
]);
expect(flattenFilePaths(files)).not.toContain("/inaccessible/another-file.txt");
expect(flattenFilePaths(files)).not.toContain("/dir/inaccessible/another-file.txt");
});
});

Expand Down
Loading
Loading