Skip to content

Commit 71cadde

Browse files
Merge pull request #34 from georgeistes/ui-ux-patch-1
CI workflow and esbuild
2 parents 0930129 + 4fba9ec commit 71cadde

File tree

17 files changed

+2218
-965
lines changed

17 files changed

+2218
-965
lines changed

.github/workflows/publish.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# .github/workflows/publish.yml
2+
name: Publish VSCode Extension
3+
4+
on:
5+
release:
6+
types: [published]
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v4
14+
15+
- name: Install Node.js
16+
uses: actions/setup-node@v4
17+
with:
18+
node-version: 18.x
19+
20+
- run: npm install
21+
22+
- name: Publish Extension
23+
run: npm run deploy
24+
env:
25+
VSCE_PAT: ${{ secrets.VSCE_PAT }}

.github/workflows/test.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# .github/workflows/test.yml
2+
name: Test VSCode Extension
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
9+
jobs:
10+
test:
11+
strategy:
12+
matrix:
13+
os: [macos-latest, ubuntu-latest, windows-latest]
14+
runs-on: ${{ matrix.os }}
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Install Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: 18.x
23+
24+
- run: npm install
25+
26+
- name: Run tests (Linux)
27+
if: runner.os == 'Linux'
28+
run: xvfb-run -a npm test
29+
30+
- name: Run tests (non-Linux)
31+
if: runner.os != 'Linux'
32+
run: npm test

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"type": "extensionHost",
1111
"request": "launch",
1212
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
13-
"outFiles": ["${workspaceFolder}/out/**/*.js"],
13+
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
1414
"preLaunchTask": "${defaultBuildTask}"
1515
}
1616
]

.vscodeignore

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,25 @@
44

55
# Source code
66
src/**
7-
out/test/**
7+
out/**
88
**/tsconfig.json
99
**/.eslintrc.json
1010
**/*.map
1111
**/*.ts
12+
live2d-container/**
13+
recordings/**
1214

1315
# Development files
1416
.vscode/**
1517
.vscode-test.mjs
1618
.vscode-test/**
17-
node_modules/**
18-
test/**
19-
live2d-container/node_modules/**
19+
**/node_modules/**
20+
**/test/**
2021
.env
22+
eslint.config.mjs
23+
esbuild.js
24+
build.js
25+
overlay-build.js
2126

2227
# Build tools and config
2328
.github/**

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Cheerleader brings a fun, interactive anime assistant to your VS Code environment that helps you stay motivated, productive, and engaged while coding with editor support and AI mentor.
1111

1212
<p align="center">
13-
<img src="assets/screenshots/demo.png" alt="Coding with Cheerleader" width="600">
13+
<img src="resources/screenshots/demo.png" alt="Coding with Cheerleader" width="600">
1414
<br>
1515
<em>Coding with your anime companion</em>
1616
</p>
@@ -30,7 +30,7 @@ Cheerleader brings a fun, interactive anime assistant to your VS Code environmen
3030
Some background features can be configured in the sidebar, refer to the [Setup and Configuration](#setup-and-configuration) section below. Other features can be accessed through the overlay UI:
3131

3232
<p align="center">
33-
<img src="assets/screenshots/buttons.png" alt="Try out interactive features" width="600">
33+
<img src="resources/screenshots/buttons.png" alt="Try out interactive features" width="600">
3434
<br>
3535
<em>Try out interactive features!</em>
3636
</p>
@@ -67,6 +67,14 @@ You can configure the following settings in the sidebar (with cheerleader icon):
6767

6868
We are officially listed on the VSCode Marketplace. Just search for "Cheerleader" in the extensions tab of VSCode and install it from there.
6969

70+
### From VSIX
71+
72+
We provide a packaged version of the extension for every major and minor release. You can find the latest version and download the `cheerleader-<version>.vsix` file from the [Releases]() page.
73+
74+
Then, open VSCode and go to the extensions tab. Under more options, select "Install from VSIX" and select the `.vsix` file you just built to install it.
75+
76+
<img src="resources/screenshots/install.png" alt="Install from VSIX" width="500">
77+
7078
### From Source
7179

7280
`node.js` and `npm` are required for installing from source. You can install them from npm's [official website](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
@@ -102,7 +110,7 @@ We are officially listed on the VSCode Marketplace. Just search for "Cheerleader
102110
vsce package
103111
```
104112

105-
6. Open VSCode and go to the extensions tab. Under more options, select "Install from VSIX" and select the `.vsix` file you just built to install it.
113+
6. This tool will generate a `.vsix` file in the current directory. You can then install it in VSCode following the instructions in [From VSIX](#from-vsix).
106114

107115
## Commands Catalog
108116

assets/cheerleader_icon.png

29.4 KB
Loading

build.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
const esbuild = require("esbuild");
2+
const fs = require("fs-extra");
3+
const path = require("path");
4+
const production = process.argv.includes("--production");
5+
const watch = process.argv.includes("--watch");
6+
7+
async function main() {
8+
// First, clear the dist directory
9+
await fs.emptyDir("./dist");
10+
11+
// Bundle the main extension
12+
const ctx = await esbuild.context({
13+
entryPoints: ["src/extension.ts"],
14+
bundle: true,
15+
format: "cjs",
16+
minify: production,
17+
sourcemap: !production,
18+
sourcesContent: false,
19+
platform: "node",
20+
outfile: "dist/extension.js",
21+
external: [
22+
"vscode",
23+
"mock-aws-s3",
24+
"aws-sdk",
25+
"nock",
26+
"@mapbox/node-pre-gyp",
27+
// "@ffprobe-installer/",
28+
],
29+
logLevel: "warning",
30+
plugins: [esbuildProblemMatcherPlugin],
31+
});
32+
33+
if (watch) {
34+
await ctx.watch();
35+
} else {
36+
await ctx.rebuild();
37+
await ctx.dispose();
38+
}
39+
40+
// Copy package.json and update it if needed
41+
await fs.copy("package.json", "dist/package.json");
42+
43+
// Build the overlay app using the separate build script
44+
console.log("Building overlay app...");
45+
const { exec } = require("child_process");
46+
return new Promise((resolve, reject) => {
47+
exec(`node overlay-build.js${production ? " --production" : ""}`, (error, stdout, stderr) => {
48+
if (error) {
49+
console.error(`Overlay build error: ${error.message}`);
50+
reject(error);
51+
return;
52+
}
53+
if (stderr) {
54+
console.error(`Overlay build stderr: ${stderr}`);
55+
}
56+
console.log(stdout);
57+
resolve();
58+
});
59+
}).then(() => {
60+
console.log("Main extension and overlay build complete!");
61+
});
62+
}
63+
64+
/**
65+
* @type {import('esbuild').Plugin}
66+
*/
67+
const esbuildProblemMatcherPlugin = {
68+
name: "esbuild-problem-matcher",
69+
setup(build) {
70+
build.onStart(() => {
71+
console.log("[watch] build started");
72+
});
73+
build.onEnd((result) => {
74+
result.errors.forEach(({ text, location }) => {
75+
console.error(`✘ [ERROR] ${text}`);
76+
if (location == null) return;
77+
console.error(
78+
` ${location.file}:${location.line}:${location.column}:`
79+
);
80+
});
81+
console.log("[watch] build finished");
82+
});
83+
},
84+
};
85+
86+
main().catch((e) => {
87+
console.error(e);
88+
process.exit(1);
89+
});

overlay-build.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
const esbuild = require("esbuild");
2+
const fs = require("fs-extra");
3+
const path = require("path");
4+
const production = process.argv.includes("--production");
5+
6+
async function main() {
7+
// Ensure output directory exists
8+
await fs.ensureDir("./dist/live2d-container");
9+
10+
// Bundle the Electron main process
11+
await esbuild.build({
12+
entryPoints: ["live2d-container/main.js"],
13+
bundle: true,
14+
platform: "node",
15+
target: ["node16"],
16+
minify: production,
17+
sourcemap: !production,
18+
outfile: "dist/live2d-container/main.js",
19+
external: ["electron"],
20+
logLevel: "info"
21+
});
22+
23+
// Bundle the Electron preload script
24+
await esbuild.build({
25+
entryPoints: ["live2d-container/preload.js"],
26+
bundle: true,
27+
platform: "node",
28+
target: ["node16"],
29+
minify: production,
30+
sourcemap: !production,
31+
outfile: "dist/live2d-container/preload.js",
32+
external: ["electron"],
33+
logLevel: "info"
34+
});
35+
36+
// Bundle the Electron renderer process (named index.js)
37+
await esbuild.build({
38+
entryPoints: ["live2d-container/index.js"],
39+
bundle: true,
40+
platform: "browser",
41+
target: ["chrome90"],
42+
minify: production,
43+
sourcemap: !production,
44+
outfile: "dist/live2d-container/index.js",
45+
external: ["electron"],
46+
logLevel: "info"
47+
});
48+
49+
// Copy any HTML files
50+
const htmlFiles = await fs.readdir("live2d-container")
51+
.then(files => files.filter(file => file.endsWith(".html")));
52+
53+
for (const htmlFile of htmlFiles) {
54+
await fs.copy(
55+
path.join("live2d-container", htmlFile),
56+
path.join("dist/live2d-container", htmlFile)
57+
);
58+
}
59+
60+
// Copy all the .css files
61+
const cssFiles = await fs.readdir("live2d-container")
62+
.then(files => files.filter(file => file.endsWith(".css")));
63+
for (const cssFile of cssFiles) {
64+
await fs.copy(
65+
path.join("live2d-container", cssFile),
66+
path.join("dist/live2d-container", cssFile)
67+
);
68+
}
69+
70+
await fs.copy("live2d-container/package.json", "dist/live2d-container/package.json");
71+
72+
console.log("Overlay build complete!");
73+
}
74+
75+
main().catch(error => {
76+
console.error("Build failed:", error);
77+
process.exit(1);
78+
});

0 commit comments

Comments
 (0)