mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 09:28:14 +00:00
feat: Windows NSIS installer, embedded icons, GUI auto-launch backend
- Add package/installer.nsi (Full/Server/Client) and toolchain.nsi
- Embed icon.ico (rounded corners) into homed.exe/waiter.exe via .syso
- GUI auto-launches homed.exe from parent dir (Windows only)
- GUI fallback connections.json from app resource dir
- Add initconfig command for config.db seeding
- Replace waiter rawmode* with raw_{unix,windows,other}.go
- Fix .gitignore: /homed instead of homed, add login.json
- Update icon.svg with rounded rect, new mascot.svg
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
homed
|
||||
/homed
|
||||
/waiter
|
||||
*.exe
|
||||
*.log
|
||||
@ -15,6 +15,8 @@ internal/meta/
|
||||
*.hmap
|
||||
dev/
|
||||
|
||||
login.json
|
||||
|
||||
# GUI
|
||||
cmd/gui/node_modules/
|
||||
cmd/gui/dist/
|
||||
|
||||
BIN
cmd/gui/icon.ico
Normal file
BIN
cmd/gui/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 295 KiB |
@ -1,5 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="400" height="400">
|
||||
<rect width="400" height="400" fill="#F8FAFC"/>
|
||||
<rect width="400" height="400" rx="60" ry="60" fill="#F8FAFC"/>
|
||||
|
||||
<g transform="translate(200,200)">
|
||||
<circle cx="0" cy="0" r="105" fill="none" stroke="#E2E8F0" stroke-width="2.5" stroke-dasharray="8,6"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
101
cmd/gui/main.js
101
cmd/gui/main.js
@ -1,9 +1,14 @@
|
||||
const { app, BrowserWindow, ipcMain, dialog } = require('electron');
|
||||
const { app, BrowserWindow, ipcMain, dialog, Menu } = require('electron');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { spawn } = require('child_process');
|
||||
const http = require('http');
|
||||
|
||||
const CONNECTIONS_FILE = path.join(app.getPath('userData'), 'connections.json');
|
||||
|
||||
let homedProcess = null;
|
||||
let mainWindow;
|
||||
|
||||
function loadConnections() {
|
||||
try {
|
||||
if (fs.existsSync(CONNECTIONS_FILE)) {
|
||||
@ -12,6 +17,18 @@ function loadConnections() {
|
||||
} catch (e) {
|
||||
console.error('Failed to load connections:', e);
|
||||
}
|
||||
// Fallback: check app resource dir (installer writes fallback copy there)
|
||||
try {
|
||||
const fallback = path.join(__dirname, 'connections.json');
|
||||
if (fs.existsSync(fallback)) {
|
||||
const data = JSON.parse(fs.readFileSync(fallback, 'utf-8'));
|
||||
saveConnections(data);
|
||||
console.log('Imported connections from app resource dir');
|
||||
return data;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Fallback connections load failed:', e);
|
||||
}
|
||||
return { connections: [], currentId: null };
|
||||
}
|
||||
|
||||
@ -23,9 +40,69 @@ function saveConnections(data) {
|
||||
}
|
||||
}
|
||||
|
||||
let mainWindow;
|
||||
function findHomed() {
|
||||
if (process.platform !== 'win32') return null;
|
||||
const exeDir = path.dirname(app.getPath('exe'));
|
||||
const p = path.resolve(exeDir, '..', 'homed.exe');
|
||||
return fs.existsSync(p) ? p : null;
|
||||
}
|
||||
|
||||
function isServerRunning() {
|
||||
return new Promise((resolve) => {
|
||||
const req = http.get('http://localhost:8080/', () => resolve(true));
|
||||
req.on('error', () => resolve(false));
|
||||
req.setTimeout(2000, () => { req.destroy(); resolve(false); });
|
||||
});
|
||||
}
|
||||
|
||||
function waitForServer(maxWait = 8000) {
|
||||
return new Promise((resolve) => {
|
||||
const start = Date.now();
|
||||
const check = () => {
|
||||
isServerRunning().then((running) => {
|
||||
if (running) return resolve(true);
|
||||
if (Date.now() - start > maxWait) return resolve(false);
|
||||
setTimeout(check, 300);
|
||||
});
|
||||
};
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
function startHomed() {
|
||||
const homedBin = findHomed();
|
||||
if (!homedBin) {
|
||||
console.log('homed.exe not found near GUI, skipping auto-launch');
|
||||
return;
|
||||
}
|
||||
const dataDir = path.resolve(path.dirname(homedBin), 'data');
|
||||
console.log('Starting homed:', homedBin, '-data', dataDir);
|
||||
homedProcess = spawn(homedBin, ['-data', dataDir], {
|
||||
stdio: 'ignore',
|
||||
detached: false,
|
||||
windowsHide: true,
|
||||
});
|
||||
homedProcess.on('error', (err) => {
|
||||
console.error('homed start failed:', err.message);
|
||||
homedProcess = null;
|
||||
});
|
||||
homedProcess.on('exit', (code) => {
|
||||
console.log('homed exited with code', code);
|
||||
homedProcess = null;
|
||||
});
|
||||
}
|
||||
|
||||
function stopHomed() {
|
||||
if (homedProcess) {
|
||||
homedProcess.kill();
|
||||
homedProcess = null;
|
||||
}
|
||||
}
|
||||
|
||||
function createWindow() {
|
||||
const menu = Menu.buildFromTemplate([]);
|
||||
Menu.setApplicationMenu(menu);
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 860,
|
||||
@ -93,12 +170,28 @@ ipcMain.handle('connections:setCurrent', (_, id) => {
|
||||
return data;
|
||||
});
|
||||
|
||||
app.whenReady().then(createWindow);
|
||||
app.whenReady().then(async () => {
|
||||
const running = await isServerRunning();
|
||||
if (!running) {
|
||||
startHomed();
|
||||
const started = await waitForServer();
|
||||
if (started) {
|
||||
console.log('homed started successfully');
|
||||
} else {
|
||||
console.error('homed failed to start within timeout');
|
||||
}
|
||||
}
|
||||
createWindow();
|
||||
});
|
||||
|
||||
app.on('before-quit', stopHomed);
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') app.quit();
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
if (mainWindow === null) createWindow();
|
||||
if (mainWindow === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
|
||||
824
cmd/gui/package-lock.json
generated
824
cmd/gui/package-lock.json
generated
@ -13,9 +13,29 @@
|
||||
"devDependencies": {
|
||||
"asar": "^3.2.0",
|
||||
"electron-builder": "^26.15.3",
|
||||
"electron-packager": "^17.1.2"
|
||||
"electron-packager": "^17.1.2",
|
||||
"icojs": "^0.23.0",
|
||||
"sharp": "^0.35.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@borewit/text-codec": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/@borewit/text-codec/-/text-codec-0.2.2.tgz",
|
||||
"integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/@canvas/image-data": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@canvas/image-data/-/image-data-1.1.0.tgz",
|
||||
"integrity": "sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@electron/asar": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz",
|
||||
@ -367,6 +387,544 @@
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.11.2",
|
||||
"resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.11.2.tgz",
|
||||
"integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/colour": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@img/colour/-/colour-1.1.0.tgz",
|
||||
"integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-darwin-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-freebsd-wasm32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz",
|
||||
"integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"dependencies": {
|
||||
"@img/sharp-wasm32": "0.35.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-arm64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz",
|
||||
"integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-darwin-x64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz",
|
||||
"integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz",
|
||||
"integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-arm64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz",
|
||||
"integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-ppc64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz",
|
||||
"integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-riscv64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz",
|
||||
"integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-s390x": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz",
|
||||
"integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linux-x64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz",
|
||||
"integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz",
|
||||
"integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz",
|
||||
"integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz",
|
||||
"integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-ppc64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz",
|
||||
"integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-riscv64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz",
|
||||
"integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-s390x": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz",
|
||||
"integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linux-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linux-x64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-linuxmusl-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-wasm32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
|
||||
"integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/runtime": "^1.11.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-webcontainers-wasm32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz",
|
||||
"integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@img/sharp-wasm32": "0.35.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-arm64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz",
|
||||
"integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-ia32": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz",
|
||||
"integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@img/sharp-win32-x64": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz",
|
||||
"integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND LGPL-3.0-or-later",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/fs-minipass": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
|
||||
@ -536,6 +1094,31 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tokenizer/inflate": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tokenizer/inflate/-/inflate-0.4.1.tgz",
|
||||
"integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.3",
|
||||
"token-types": "^6.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/@tokenizer/token": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tokenizer/token/-/token-0.3.0.tgz",
|
||||
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/cacheable-request": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||
@ -1278,6 +1861,13 @@
|
||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/bmp-ts": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmmirror.com/bmp-ts/-/bmp-ts-1.0.9.tgz",
|
||||
"integrity": "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/boolean": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||
@ -1640,6 +2230,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decode-bmp": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/decode-bmp/-/decode-bmp-0.2.1.tgz",
|
||||
"integrity": "sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@canvas/image-data": "^1.0.0",
|
||||
"to-data-view": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/decode-ico": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/decode-ico/-/decode-ico-0.4.1.tgz",
|
||||
"integrity": "sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@canvas/image-data": "^1.0.0",
|
||||
"decode-bmp": "^0.2.0",
|
||||
"to-data-view": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
@ -1721,6 +2340,16 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-node": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
|
||||
@ -2301,6 +2930,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/file-type": {
|
||||
"version": "21.3.4",
|
||||
"resolved": "https://registry.npmmirror.com/file-type/-/file-type-21.3.4.tgz",
|
||||
"integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tokenizer/inflate": "^0.4.1",
|
||||
"strtok3": "^10.3.4",
|
||||
"token-types": "^6.1.1",
|
||||
"uint8array-extras": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz",
|
||||
@ -2827,6 +3475,44 @@
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/icojs": {
|
||||
"version": "0.23.0",
|
||||
"resolved": "https://registry.npmmirror.com/icojs/-/icojs-0.23.0.tgz",
|
||||
"integrity": "sha512-l2r+WSRnwF7OAUcyVBh8N5y8j0usPYs9QQPskO1fXygxpLV+l+SeqLtklxUz1WVF3Ao+gGzoY7sh9jZRy04WmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bmp-ts": "^1.0.9",
|
||||
"decode-ico": "^0.4.1",
|
||||
"file-type": "^21.3.4",
|
||||
"jpeg-js": "^0.4.4",
|
||||
"pngjs": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
@ -2951,6 +3637,13 @@
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/jpeg-js": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmmirror.com/jpeg-js/-/jpeg-js-0.4.4.tgz",
|
||||
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
|
||||
@ -3609,6 +4302,16 @@
|
||||
"node": ">=10.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-7.0.0.tgz",
|
||||
"integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postject": {
|
||||
"version": "1.0.0-alpha.6",
|
||||
"resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz",
|
||||
@ -3963,6 +4666,69 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/sharp": {
|
||||
"version": "0.35.3",
|
||||
"resolved": "https://registry.npmmirror.com/sharp/-/sharp-0.35.3.tgz",
|
||||
"integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@img/colour": "^1.1.0",
|
||||
"detect-libc": "^2.1.2",
|
||||
"semver": "^7.8.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/libvips"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@img/sharp-darwin-arm64": "0.35.3",
|
||||
"@img/sharp-darwin-x64": "0.35.3",
|
||||
"@img/sharp-freebsd-wasm32": "0.35.3",
|
||||
"@img/sharp-libvips-darwin-arm64": "1.3.2",
|
||||
"@img/sharp-libvips-darwin-x64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-arm": "1.3.2",
|
||||
"@img/sharp-libvips-linux-arm64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-ppc64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-riscv64": "1.3.2",
|
||||
"@img/sharp-libvips-linux-s390x": "1.3.2",
|
||||
"@img/sharp-libvips-linux-x64": "1.3.2",
|
||||
"@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
|
||||
"@img/sharp-libvips-linuxmusl-x64": "1.3.2",
|
||||
"@img/sharp-linux-arm": "0.35.3",
|
||||
"@img/sharp-linux-arm64": "0.35.3",
|
||||
"@img/sharp-linux-ppc64": "0.35.3",
|
||||
"@img/sharp-linux-riscv64": "0.35.3",
|
||||
"@img/sharp-linux-s390x": "0.35.3",
|
||||
"@img/sharp-linux-x64": "0.35.3",
|
||||
"@img/sharp-linuxmusl-arm64": "0.35.3",
|
||||
"@img/sharp-linuxmusl-x64": "0.35.3",
|
||||
"@img/sharp-webcontainers-wasm32": "0.35.3",
|
||||
"@img/sharp-win32-arm64": "0.35.3",
|
||||
"@img/sharp-win32-ia32": "0.35.3",
|
||||
"@img/sharp-win32-x64": "0.35.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/sharp/node_modules/semver": {
|
||||
"version": "7.8.5",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz",
|
||||
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@ -4146,6 +4912,23 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strtok3": {
|
||||
"version": "10.3.5",
|
||||
"resolved": "https://registry.npmmirror.com/strtok3/-/strtok3-10.3.5.tgz",
|
||||
"integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tokenizer/token": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/sumchecker": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
|
||||
@ -4309,6 +5092,32 @@
|
||||
"tmp": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/to-data-view": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/to-data-view/-/to-data-view-1.1.0.tgz",
|
||||
"integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/token-types": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/token-types/-/token-types-6.1.2.tgz",
|
||||
"integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@borewit/text-codec": "^0.2.1",
|
||||
"@tokenizer/token": "^0.3.0",
|
||||
"ieee754": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Borewit"
|
||||
}
|
||||
},
|
||||
"node_modules/trim-repeated": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
|
||||
@ -4358,6 +5167,19 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/uint8array-extras": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
|
||||
"integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.27.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz",
|
||||
|
||||
@ -13,7 +13,9 @@
|
||||
"devDependencies": {
|
||||
"asar": "^3.2.0",
|
||||
"electron-builder": "^26.15.3",
|
||||
"electron-packager": "^17.1.2"
|
||||
"electron-packager": "^17.1.2",
|
||||
"icojs": "^0.23.0",
|
||||
"sharp": "^0.35.3"
|
||||
},
|
||||
"build": {
|
||||
"appId": "com.homeagent.gui",
|
||||
|
||||
@ -32,7 +32,57 @@ window._i18n = {
|
||||
navAdapters: ['适配器','Adapters'],
|
||||
navKernel: ['内核','Kernel'],
|
||||
navLogout: ['退出登录','Logout'],
|
||||
themeToggle: ['切换亮色/暗色模式','Toggle theme']
|
||||
themeToggle: ['切换亮色/暗色模式','Toggle theme'],
|
||||
clickManage: ['点击管理连接','Click to manage connections'],
|
||||
secondsAgo: ['秒前','s ago'],
|
||||
minutesAgo: ['分钟前','min ago'],
|
||||
hoursAgo: ['小时前','h ago'],
|
||||
noConnection: ['未连接','Not connected'],
|
||||
agentAvatar: ['小宅','Agent'],
|
||||
waitingAI: ['等待AI回复...','Waiting for AI...'],
|
||||
noResponse: ['(无响应)','(no response)'],
|
||||
error: ['错误: ','Error: '],
|
||||
requestFailed: ['请求失败: ','Request failed: '],
|
||||
send: ['发送','Send'],
|
||||
queryFailed: ['查询失败: ','Query failed: '],
|
||||
searchFailed: ['搜索失败: ','Search failed: '],
|
||||
getFailed: ['获取失败: ','Get failed: '],
|
||||
createFailed: ['创建失败','Create failed'],
|
||||
createFailedWith: ['创建失败: ','Create failed: '],
|
||||
nameContentEmpty: ['名称和内容不能为空','Name and content cannot be empty'],
|
||||
knowledgeCreated: ['知识「','Knowledge "'],
|
||||
knowledgeCreatedEnd: ['」已创建','" created'],
|
||||
noContext: ['无上下文','No context'],
|
||||
noSessions: ['暂无终端会话','No terminal sessions'],
|
||||
noHistory: ['暂无命令记录','No command history'],
|
||||
running: ['运行中','Running'],
|
||||
closed: ['已关闭','Closed'],
|
||||
command: ['命令','Command'],
|
||||
status: ['状态','Status'],
|
||||
created: ['创建时间','Created'],
|
||||
uptime: ['运行时长','Uptime'],
|
||||
output: ['输出预览','Output'],
|
||||
time: ['时间','Time'],
|
||||
actions: ['操作','Actions'],
|
||||
name: ['名称','Name'],
|
||||
description: ['描述','Description'],
|
||||
version: ['版本','Version'],
|
||||
details: ['详情','Details'],
|
||||
close: ['关闭','Close'],
|
||||
install: ['安装','Install'],
|
||||
installPlugin: ['安装插件','Install Plugin'],
|
||||
packageUrl: ['.hmap 包下载 URL','Package URL'],
|
||||
uploadHmap: ['选择 .hmap 文件上传','Upload .hmap file'],
|
||||
loadedPlugins: ['已加载插件','Loaded Plugins'],
|
||||
noLoadedPlugins: ['暂无已加载插件','No loaded plugins'],
|
||||
loaded: ['已加载','Loaded'],
|
||||
builtin: ['内置','Built-in'],
|
||||
unload: ['卸载','Unload'],
|
||||
installedExternal: ['已安装外部插件','Installed Plugins'],
|
||||
pluginDetails: ['插件详情','Plugin Details'],
|
||||
registeredTools: ['已注册工具','Registered Tools'],
|
||||
systemOps: ['系统操作','System Operations'],
|
||||
reloadPlugins: ['重载插件','Reload Plugins'],
|
||||
};
|
||||
|
||||
function __(zh, en) { return state.lang === 'en' ? en : zh }
|
||||
@ -84,10 +134,10 @@ function escHtml(s) {
|
||||
|
||||
function timeAgo(t) {
|
||||
var s = Math.floor((Date.now() - new Date(t).getTime()) / 1000);
|
||||
if (s < 60) return s + '秒前';
|
||||
if (s < 60) return s + __('秒前','s ago');
|
||||
var m = Math.floor(s / 60);
|
||||
if (m < 60) return m + '分钟前';
|
||||
return Math.floor(m / 60) + '小时前';
|
||||
if (m < 60) return m + __('分钟前','min ago');
|
||||
return Math.floor(m / 60) + __('小时前','h ago');
|
||||
}
|
||||
|
||||
function toast(m, isError) {
|
||||
@ -325,7 +375,7 @@ function renderChat() {
|
||||
html += '<div class="msg msg-system"><div class="msg-bubble">' + body + '</div></div>';
|
||||
} else {
|
||||
var userAvatar = '<svg viewBox="0 0 24 24" style="width:16px;height:16px" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-6 8-6s8 2 8 6"/></svg>';
|
||||
var aiAvatar = '<img src="/mascot.webp" style="width:28px;height:28px;border-radius:50%;object-fit:cover" alt="小宅">';
|
||||
var aiAvatar = '<img src="mascot.svg" style="width:28px;height:28px;border-radius:50%;object-fit:cover" alt="' + __('小宅','Agent') + '">';
|
||||
html += '<div class="msg msg-' + role + '">'
|
||||
+ '<div class="msg-avatar">' + (role === 'user' ? userAvatar : aiAvatar) + '</div>'
|
||||
+ '<div class="msg-content"><div class="msg-bubble">' + body + '</div></div>'
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
<a onclick="switchTab('adapters')" data-i18n="navAdapters">适配器</a>
|
||||
<a onclick="switchTab('kernel')" data-i18n="navKernel">内核</a>
|
||||
<div style="margin-left:auto;display:flex;align-items:center;gap:8px">
|
||||
<span id="conn-status" class="conn-indicator" onclick="openConnManager()" title="点击管理连接">
|
||||
<span id="conn-status" class="conn-indicator" onclick="openConnManager()" title="点击管理连接 / Click to manage connections">
|
||||
<span class="status-dot dot-gray" id="conn-dot"></span>
|
||||
<span id="conn-name-display">未连接</span>
|
||||
<span style="font-size:10px;margin-left:4px;opacity:0.6">▼</span>
|
||||
|
||||
9
cmd/gui/renderer/mascot.svg
Normal file
9
cmd/gui/renderer/mascot.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
|
||||
<circle cx="50" cy="50" r="48" fill="#3B82F6"/>
|
||||
<circle cx="35" cy="40" r="6" fill="white"/>
|
||||
<circle cx="65" cy="40" r="6" fill="white"/>
|
||||
<circle cx="35" cy="40" r="3" fill="#1E3A5F"/>
|
||||
<circle cx="65" cy="40" r="3" fill="#1E3A5F"/>
|
||||
<path d="M35 65 Q50 80 65 65" stroke="white" stroke-width="3" fill="none" stroke-linecap="round"/>
|
||||
<ellipse cx="50" cy="58" rx="8" ry="4" fill="#F59E0B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 496 B |
1
cmd/homed/homed.rc
Normal file
1
cmd/homed/homed.rc
Normal file
@ -0,0 +1 @@
|
||||
1 ICON "E:/program/homeagent/homeagent/build/icon.ico"
|
||||
BIN
cmd/homed/homed.syso
Normal file
BIN
cmd/homed/homed.syso
Normal file
Binary file not shown.
67
cmd/initconfig/main.go
Normal file
67
cmd/initconfig/main.go
Normal file
@ -0,0 +1,67 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func randomSecret(n int) string {
|
||||
b := make([]byte, n)
|
||||
rand.Read(b)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
func main() {
|
||||
dataDir := flag.String("data", "", "data directory")
|
||||
webuiUsername := flag.String("username", "admin", "webui username")
|
||||
webuiPassword := flag.String("password", "", "webui password (auto-generated if empty)")
|
||||
webuiApiKey := flag.String("apikey", "", "api key (auto-generated if empty)")
|
||||
flag.Parse()
|
||||
|
||||
if *dataDir == "" {
|
||||
fmt.Fprintln(os.Stderr, "-data is required")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.MkdirAll(*dataDir, 0755)
|
||||
|
||||
dbPath := *dataDir + "/config.db"
|
||||
db, err := sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "open db: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
db.Exec("PRAGMA journal_mode=WAL")
|
||||
|
||||
db.Exec(`CREATE TABLE IF NOT EXISTS config (key TEXT PRIMARY KEY, value TEXT NOT NULL)`)
|
||||
db.Exec(`INSERT OR IGNORE INTO config (key, value) VALUES (?, ?)`, "webui.listen_addr", ":8080")
|
||||
|
||||
pw := *webuiPassword
|
||||
if pw == "" {
|
||||
pw = randomSecret(12)
|
||||
}
|
||||
apiKey := *webuiApiKey
|
||||
if apiKey == "" {
|
||||
apiKey = randomSecret(16)
|
||||
}
|
||||
|
||||
pt := "config_webui"
|
||||
db.Exec(fmt.Sprintf(`CREATE TABLE IF NOT EXISTS %s (key TEXT PRIMARY KEY, value TEXT NOT NULL)`, pt))
|
||||
ws := fmt.Sprintf(`INSERT OR REPLACE INTO %s (key, value) VALUES (?, ?)`, pt)
|
||||
db.Exec(ws, "api_key", apiKey)
|
||||
db.Exec(ws, "username", *webuiUsername)
|
||||
db.Exec(ws, "password", pw)
|
||||
db.Exec(ws, "session_ttl_hours", "24")
|
||||
|
||||
fmt.Printf("API_KEY=%s\n", apiKey)
|
||||
fmt.Printf("WEBUI_USERNAME=%s\n", *webuiUsername)
|
||||
fmt.Printf("WEBUI_PASSWORD=%s\n", pw)
|
||||
}
|
||||
11
cmd/waiter/raw_other.go
Normal file
11
cmd/waiter/raw_other.go
Normal file
@ -0,0 +1,11 @@
|
||||
//go:build !linux && !windows
|
||||
|
||||
package main
|
||||
|
||||
func setRawMode(fd int) (func(), error) {
|
||||
return func() {}, nil
|
||||
}
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
return false
|
||||
}
|
||||
43
cmd/waiter/raw_unix.go
Normal file
43
cmd/waiter/raw_unix.go
Normal file
@ -0,0 +1,43 @@
|
||||
//go:build linux
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setRawMode(fd int) (func(), error) {
|
||||
if fd == 0 {
|
||||
fd = int(os.Stdin.Fd())
|
||||
}
|
||||
if !isTerminal(fd) {
|
||||
return func() {}, nil
|
||||
}
|
||||
var oldState syscall.Termios
|
||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
|
||||
return func() {}, fmt.Errorf("tcgets: %v", err)
|
||||
}
|
||||
newState := oldState
|
||||
newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON
|
||||
newState.Oflag &^= syscall.OPOST
|
||||
newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN
|
||||
newState.Cflag &^= syscall.CSIZE | syscall.PARENB
|
||||
newState.Cflag |= syscall.CS8
|
||||
newState.Cc[syscall.VMIN] = 1
|
||||
newState.Cc[syscall.VTIME] = 0
|
||||
if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
|
||||
return func() {}, fmt.Errorf("tcset: %v", err)
|
||||
}
|
||||
return func() {
|
||||
syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCSETS, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
var t syscall.Termios
|
||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), syscall.TCGETS, uintptr(unsafe.Pointer(&t)), 0, 0, 0)
|
||||
return err == 0
|
||||
}
|
||||
52
cmd/waiter/raw_windows.go
Normal file
52
cmd/waiter/raw_windows.go
Normal file
@ -0,0 +1,52 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
||||
procGetStdHandle = kernel32.NewProc("GetStdHandle")
|
||||
)
|
||||
|
||||
const (
|
||||
stdInputHandle = ^uint32(9) + 1 // -10
|
||||
enableVirtualTerminalProcessing = 0x0004
|
||||
enableProcessedOutput = 0x0001
|
||||
enableWrapAtEOLOutput = 0x0002
|
||||
disableNewlineAutoReturn = 0x0008
|
||||
)
|
||||
|
||||
func setRawMode(fd int) (func(), error) {
|
||||
if fd == 0 {
|
||||
fd = int(os.Stdin.Fd())
|
||||
}
|
||||
if !isTerminal(fd) {
|
||||
return func() {}, nil
|
||||
}
|
||||
// Enable virtual terminal processing for ANSI escape sequences on Windows
|
||||
h, _, _ := procGetStdHandle.Call(uintptr(^uint32(10) + 1)) // STD_OUTPUT_HANDLE = -11
|
||||
if h != 0 && h != ^uintptr(0) {
|
||||
var mode uint32
|
||||
procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode)))
|
||||
newMode := mode | enableVirtualTerminalProcessing | enableProcessedOutput | enableWrapAtEOLOutput
|
||||
procSetConsoleMode.Call(h, uintptr(newMode))
|
||||
}
|
||||
return func() {}, nil
|
||||
}
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
var mode uint32
|
||||
h, _, _ := procGetStdHandle.Call(uintptr(^uint32(10) + 1)) // STD_OUTPUT_HANDLE = -11
|
||||
if h == 0 || h == ^uintptr(0) {
|
||||
return false
|
||||
}
|
||||
ret, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode)))
|
||||
return ret != 0
|
||||
}
|
||||
1
cmd/waiter/waiter.rc
Normal file
1
cmd/waiter/waiter.rc
Normal file
@ -0,0 +1 @@
|
||||
1 ICON "E:/program/homeagent/homeagent/build/icon.ico"
|
||||
BIN
cmd/waiter/waiter.syso
Normal file
BIN
cmd/waiter/waiter.syso
Normal file
Binary file not shown.
2
go.mod
2
go.mod
@ -12,4 +12,4 @@ require github.com/yanyiwu/gojieba v1.4.7
|
||||
|
||||
require gitcode.com/JianFeeeee/homeagent-sdk v0.0.0-20260708004841-e9bdcf9304b0 // direct
|
||||
|
||||
replace gitcode.com/JianFeeeee/homeagent-sdk => /tmp/opencode/homeagent-sdk-repo
|
||||
replace gitcode.com/JianFeeeee/homeagent-sdk => E:\program\homeagent\homeagentsdk
|
||||
|
||||
326
package/installer.nsi
Normal file
326
package/installer.nsi
Normal file
@ -0,0 +1,326 @@
|
||||
!include "MUI2.nsh"
|
||||
!include "nsDialogs.nsh"
|
||||
!include "LogicLib.nsh"
|
||||
!include "WinVer.nsh"
|
||||
!include "x64.nsh"
|
||||
|
||||
!ifndef VARIANT
|
||||
!define VARIANT "full"
|
||||
!endif
|
||||
|
||||
!define PRODUCT_NAME "HomeAgent"
|
||||
!define PRODUCT_PUBLISHER "HomeAgent Team"
|
||||
!define PRODUCT_VERSION "0.7.1"
|
||||
|
||||
!if "${VARIANT}" == "full"
|
||||
!define PRODUCT_DISPLAY_NAME "HomeAgent 完整版"
|
||||
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Full_win64.exe"
|
||||
!define HAS_CORE 1
|
||||
!define HAS_WAITER 1
|
||||
!define HAS_GUI 1
|
||||
!define HAS_CREDENTIALS 1
|
||||
!else if "${VARIANT}" == "server"
|
||||
!define PRODUCT_DISPLAY_NAME "HomeAgent 服务端"
|
||||
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Server_win64.exe"
|
||||
!define HAS_CORE 1
|
||||
!define HAS_WAITER 0
|
||||
!define HAS_GUI 0
|
||||
!define HAS_CREDENTIALS 1
|
||||
!else if "${VARIANT}" == "client"
|
||||
!define PRODUCT_DISPLAY_NAME "HomeAgent 客户端"
|
||||
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Client_win64.exe"
|
||||
!define HAS_CORE 0
|
||||
!define HAS_WAITER 1
|
||||
!define HAS_GUI 1
|
||||
!define HAS_CREDENTIALS 0
|
||||
!else
|
||||
!error "Unknown variant: ${VARIANT}"
|
||||
!endif
|
||||
|
||||
Name "${PRODUCT_DISPLAY_NAME}"
|
||||
OutFile "${OUTPUT_FILE}"
|
||||
InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}"
|
||||
InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" ""
|
||||
RequestExecutionLevel admin
|
||||
BrandingText "HomeAgent Installer"
|
||||
SetCompressor /SOLID lzma
|
||||
ShowInstDetails show
|
||||
ShowUninstDetails show
|
||||
|
||||
Var apiKey
|
||||
Var webuiUsername
|
||||
Var webuiPassword
|
||||
Var hwndApiKey
|
||||
Var hwndUsername
|
||||
Var hwndPassword
|
||||
Var autoStart
|
||||
Var startNow
|
||||
Var hwndAutoStart
|
||||
Var hwndStartNow
|
||||
|
||||
Function GenKey
|
||||
nsExec::ExecToStack 'powershell -NoProfile -C "[System.Guid]::NewGuid().ToString($\'N$\')"'
|
||||
Pop $0
|
||||
Pop $1
|
||||
${If} $1 == ""
|
||||
StrCpy $1 "homeagent"
|
||||
${Else}
|
||||
StrCpy $1 $1 32
|
||||
${EndIf}
|
||||
Push $1
|
||||
FunctionEnd
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
|
||||
!if "${HAS_CREDENTIALS}" == "1"
|
||||
Page custom pageApiKeys pageApiKeysLeave
|
||||
Page custom pageCredentials pageCredentialsLeave
|
||||
!endif
|
||||
|
||||
!if "${HAS_CORE}" == "1"
|
||||
Page custom pageStartupOptions pageStartupOptionsLeave
|
||||
!endif
|
||||
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
Page custom pageFinishSummary
|
||||
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
Function .onInit
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
StrCpy $autoStart "1"
|
||||
StrCpy $startNow "1"
|
||||
!if "${HAS_CREDENTIALS}" == "0"
|
||||
Call GenKey
|
||||
Pop $apiKey
|
||||
!endif
|
||||
FunctionEnd
|
||||
|
||||
!if "${HAS_CORE}" == "1"
|
||||
|
||||
Function pageStartupOptions
|
||||
!insertmacro MUI_HEADER_TEXT "启动选项" "设置 HomeAgent 后端的启动方式"
|
||||
nsDialogs::Create 1018
|
||||
Pop $0
|
||||
${If} $0 == error
|
||||
Abort
|
||||
${EndIf}
|
||||
${NSD_CreateLabel} 0 5u 100% 20u "HomeAgent 后端 (homed) 是持续运行的服务进程。$\r$\n请选择启动方式:"
|
||||
Pop $0
|
||||
${NSD_CreateCheckBox} 10u 35u 100% 12u "开机自动启动后端 (添加到注册表启动项)"
|
||||
Pop $hwndAutoStart
|
||||
${If} $autoStart == "1"
|
||||
${NSD_Check} $hwndAutoStart
|
||||
${EndIf}
|
||||
${NSD_CreateCheckBox} 10u 55u 100% 12u "安装完成后立即启动后端"
|
||||
Pop $hwndStartNow
|
||||
${If} $startNow == "1"
|
||||
${NSD_Check} $hwndStartNow
|
||||
${EndIf}
|
||||
${NSD_CreateLabel} 10u 80u 100% 20u "如果选择开机自启动,homed 将在每次登录 Windows 时自动运行。$\r$\n你也可以稍后从开始菜单手动启动。"
|
||||
Pop $0
|
||||
nsDialogs::Show
|
||||
FunctionEnd
|
||||
|
||||
Function pageStartupOptionsLeave
|
||||
${NSD_GetState} $hwndAutoStart $autoStart
|
||||
${NSD_GetState} $hwndStartNow $startNow
|
||||
FunctionEnd
|
||||
|
||||
!endif
|
||||
|
||||
!if "${HAS_CREDENTIALS}" == "1"
|
||||
|
||||
Function pageApiKeys
|
||||
!insertmacro MUI_HEADER_TEXT "生成 API 密钥" "请复制此密钥,安装完成后将无法再次查看"
|
||||
nsDialogs::Create 1018
|
||||
Pop $0
|
||||
${If} $0 == error
|
||||
Abort
|
||||
${EndIf}
|
||||
Call GenKey
|
||||
Pop $apiKey
|
||||
${NSD_CreateLabel} 0 5u 100% 12u "API Key (用于 WebUI 和 GUI 认证):"
|
||||
Pop $0
|
||||
${NSD_CreateText} 0 20u 300u 12u $apiKey
|
||||
Pop $hwndApiKey
|
||||
${NSD_CreateLabel} 0 45u 100% 30u "请用鼠标选中文本框中的密钥并复制 (Ctrl+C)。$\r$\n此密钥同时用于:$\r$\n • Web 管理界面 (http://localhost:8080) 的 API 认证$\r$\n • 桌面 GUI 应用的自动连接配置"
|
||||
Pop $0
|
||||
nsDialogs::Show
|
||||
FunctionEnd
|
||||
|
||||
Function pageApiKeysLeave
|
||||
${NSD_GetText} $hwndApiKey $apiKey
|
||||
FunctionEnd
|
||||
|
||||
Function pageCredentials
|
||||
!insertmacro MUI_HEADER_TEXT "WebUI 登录设置" "设置 Web 管理界面的登录账号和密码"
|
||||
nsDialogs::Create 1018
|
||||
Pop $0
|
||||
${If} $0 == error
|
||||
Abort
|
||||
${EndIf}
|
||||
StrCpy $webuiUsername "admin"
|
||||
${NSD_CreateLabel} 0 5u 70u 12u "用户名:"
|
||||
Pop $0
|
||||
${NSD_CreateText} 85u 5u 180u 12u $webuiUsername
|
||||
Pop $hwndUsername
|
||||
${NSD_CreateLabel} 0 25u 70u 12u "密码:"
|
||||
Pop $0
|
||||
${NSD_CreatePassword} 85u 25u 180u 12u ""
|
||||
Pop $hwndPassword
|
||||
${NSD_CreateLabel} 0 50u 100% 20u "这些凭证用于登录 Web 管理界面 http://localhost:8080"
|
||||
Pop $0
|
||||
nsDialogs::Show
|
||||
FunctionEnd
|
||||
|
||||
Function pageCredentialsLeave
|
||||
${NSD_GetText} $hwndUsername $webuiUsername
|
||||
${NSD_GetText} $hwndPassword $webuiPassword
|
||||
${If} $webuiPassword == ""
|
||||
StrCpy $webuiPassword "homeagent"
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
||||
!endif
|
||||
|
||||
Function pageFinishSummary
|
||||
!insertmacro MUI_HEADER_TEXT "安装完成" "以下为安装的关键信息,请截图或记录"
|
||||
nsDialogs::Create 1018
|
||||
Pop $0
|
||||
${If} $0 == error
|
||||
Abort
|
||||
${EndIf}
|
||||
${NSD_CreateLabel} 0 5u 100% 12u "API Key: $apiKey"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 0 20u 100% 12u "GUI 预配置: 已自动写入连接配置"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 0 35u 100% 12u "WebUI 地址: http://localhost:8080"
|
||||
Pop $0
|
||||
!if "${HAS_CREDENTIALS}" == "1"
|
||||
${NSD_CreateLabel} 0 50u 100% 12u "WebUI 用户名: $webuiUsername"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 0 65u 100% 12u "WebUI 密码: $webuiPassword"
|
||||
Pop $0
|
||||
!endif
|
||||
nsDialogs::Show
|
||||
FunctionEnd
|
||||
|
||||
Section "Install" SEC_INSTALL
|
||||
SetOutPath "$INSTDIR"
|
||||
CreateDirectory "$INSTDIR\data"
|
||||
CreateDirectory "$INSTDIR\data\log"
|
||||
CreateDirectory "$INSTDIR\data\plugins"
|
||||
CreateDirectory "$INSTDIR\data\adapters"
|
||||
|
||||
!if "${HAS_CORE}" == "1"
|
||||
File "initconfig.exe"
|
||||
File "homed.exe"
|
||||
!endif
|
||||
|
||||
!if "${HAS_WAITER}" == "1"
|
||||
File "waiter.exe"
|
||||
!endif
|
||||
|
||||
!if "${HAS_GUI}" == "1"
|
||||
SetOutPath "$INSTDIR\homeagent-gui-win32-x64"
|
||||
File /r "homeagent-gui-win32-x64\*.*"
|
||||
SetOutPath "$INSTDIR"
|
||||
!endif
|
||||
|
||||
!if "${HAS_CORE}" == "1"
|
||||
DetailPrint "初始化配置数据库..."
|
||||
nsExec::Exec '"$INSTDIR\initconfig.exe" -data "$INSTDIR\data" -username "$webuiUsername" -password "$webuiPassword" -apikey "$apiKey"'
|
||||
Pop $0
|
||||
${If} $0 != 0
|
||||
DetailPrint "警告: 数据库初始化可能未成功完成"
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
!if "${HAS_GUI}" == "1"
|
||||
DetailPrint "配置 GUI 连接..."
|
||||
CreateDirectory "$APPDATA\homeagent-gui"
|
||||
FileOpen $0 "$APPDATA\homeagent-gui\connections.json" w
|
||||
FileWrite $0 '{$\r$\n "connections": [$\r$\n {$\r$\n "id": "local",$\r$\n "name": "本地",$\r$\n "url": "http://localhost:8080",$\r$\n "apiKey": "$apiKey"$\r$\n }$\r$\n ],$\r$\n "currentId": "local"$\r$\n}'
|
||||
FileClose $0
|
||||
; 同时写入 GUI 包目录作为备用(适配 UAC 提升后 $APPDATA 异常的情况)
|
||||
CreateDirectory "$INSTDIR\homeagent-gui-win32-x64\resources\app"
|
||||
FileOpen $0 "$INSTDIR\homeagent-gui-win32-x64\resources\app\connections.json" w
|
||||
FileWrite $0 '{$\r$\n "connections": [$\r$\n {$\r$\n "id": "local",$\r$\n "name": "本地",$\r$\n "url": "http://localhost:8080",$\r$\n "apiKey": "$apiKey"$\r$\n }$\r$\n ],$\r$\n "currentId": "local"$\r$\n}'
|
||||
FileClose $0
|
||||
!endif
|
||||
|
||||
!if "${HAS_WAITER}" == "1"
|
||||
DetailPrint "配置 CLI 连接..."
|
||||
FileOpen $0 "$INSTDIR\waiter.yaml" w
|
||||
FileWrite $0 "socket: $\"$INSTDIR\data\cli.sock$\"$\r$\napi_key: $apiKey$\r$\ndefault: local$\r$\nconnections:$\r$\n - name: local$\r$\n socket: $\"$INSTDIR\data\cli.sock$\"$\r$\n api_key: $apiKey$\r$\n"
|
||||
FileClose $0
|
||||
!endif
|
||||
|
||||
DetailPrint "创建快捷方式..."
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
!if "${HAS_CORE}" == "1"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent Server.lnk" "$INSTDIR\homed.exe" '-data "$INSTDIR\data"' "$INSTDIR\homed.exe" 0
|
||||
!endif
|
||||
!if "${HAS_WAITER}" == "1"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent CLI.lnk" "$INSTDIR\waiter.exe" "" "$INSTDIR\waiter.exe" 0
|
||||
!endif
|
||||
!if "${HAS_GUI}" == "1"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent GUI.lnk" "$INSTDIR\homeagent-gui-win32-x64\homeagent-gui.exe" "" "$INSTDIR\homeagent-gui-win32-x64\homeagent-gui.exe" 0
|
||||
!endif
|
||||
|
||||
DetailPrint "设置环境变量..."
|
||||
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_DATA" "$INSTDIR\data"
|
||||
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SOCKET" "$INSTDIR\data\cli.sock"
|
||||
|
||||
!if "${HAS_CORE}" == "1"
|
||||
${If} $autoStart == "1"
|
||||
DetailPrint "设置开机自启动..."
|
||||
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HomeAgent" '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
|
||||
${EndIf}
|
||||
!endif
|
||||
|
||||
DetailPrint "写入注册表..."
|
||||
WriteRegStr HKLM "Software\${PRODUCT_NAME}" "" "$INSTDIR"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_DISPLAY_NAME}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "Publisher" "${PRODUCT_PUBLISHER}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1
|
||||
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
!if "${HAS_CORE}" == "1"
|
||||
${If} $startNow == "1"
|
||||
DetailPrint "启动 HomeAgent 后端..."
|
||||
Exec '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
|
||||
${EndIf}
|
||||
!endif
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
!if "${HAS_CORE}" == "1"
|
||||
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HomeAgent"
|
||||
!endif
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
Delete "$INSTDIR\initconfig.exe"
|
||||
Delete "$INSTDIR\homed.exe"
|
||||
Delete "$INSTDIR\waiter.exe"
|
||||
Delete "$INSTDIR\waiter.yaml"
|
||||
RMDir /r "$INSTDIR\data"
|
||||
RMDir /r "$INSTDIR\homeagent-gui-win32-x64"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent Server.lnk"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent CLI.lnk"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent GUI.lnk"
|
||||
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_DATA"
|
||||
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SOCKET"
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
DeleteRegKey HKLM "Software\${PRODUCT_NAME}"
|
||||
SectionEnd
|
||||
137
package/toolchain.nsi
Normal file
137
package/toolchain.nsi
Normal file
@ -0,0 +1,137 @@
|
||||
!include "MUI2.nsh"
|
||||
!include "nsDialogs.nsh"
|
||||
!include "LogicLib.nsh"
|
||||
!include "x64.nsh"
|
||||
!include "WinVer.nsh"
|
||||
|
||||
!define PRODUCT_NAME "HomeAgent Toolchain"
|
||||
!define PRODUCT_PUBLISHER "HomeAgent Team"
|
||||
!define PRODUCT_VERSION "0.7.1"
|
||||
!define PRODUCT_DISPLAY_NAME "HomeAgent 工具链"
|
||||
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Toolchain_win64.exe"
|
||||
!define SDK_VERSION "v0.7.1"
|
||||
|
||||
Name "${PRODUCT_DISPLAY_NAME} v${PRODUCT_VERSION}"
|
||||
OutFile "${OUTPUT_FILE}"
|
||||
InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}"
|
||||
InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" ""
|
||||
RequestExecutionLevel admin
|
||||
BrandingText "HomeAgent Toolchain Installer"
|
||||
SetCompressor /SOLID lzma
|
||||
ShowInstDetails show
|
||||
ShowUninstDetails show
|
||||
|
||||
Var hasGit
|
||||
Var sdkInstallOk
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
Page custom pageConfirm pageConfirmLeave
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
Function .onInit
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
StrCpy $hasGit "0"
|
||||
StrCpy $sdkInstallOk "0"
|
||||
FunctionEnd
|
||||
|
||||
Function pageConfirm
|
||||
!insertmacro MUI_HEADER_TEXT "确认安装" "将安装 HomeAgent 工具链并自动下载 SDK ${SDK_VERSION}"
|
||||
nsDialogs::Create 1018
|
||||
Pop $0
|
||||
${If} $0 == error
|
||||
Abort
|
||||
${EndIf}
|
||||
${NSD_CreateLabel} 0 5u 100% 12u "将安装以下组件:"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 15u 20u 100% 12u "• plugindev.exe — 插件开发工具"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 15u 35u 100% 12u "• SDK ${SDK_VERSION} — 将从远程仓库自动下载"
|
||||
Pop $0
|
||||
${NSD_CreateLabel} 0 60u 100% 20u "SDK 需要 Git 客户端。如果未安装 Git,请先安装:$\r$\nhttps://git-scm.com/downloads"
|
||||
Pop $0
|
||||
nsDialogs::Show
|
||||
FunctionEnd
|
||||
|
||||
Function pageConfirmLeave
|
||||
FunctionEnd
|
||||
|
||||
Section "Install" SEC_INSTALL
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
DetailPrint "复制工具链文件..."
|
||||
File "plugindev.exe"
|
||||
|
||||
DetailPrint "创建快捷方式..."
|
||||
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\plugindev.lnk" "$INSTDIR\plugindev.exe" "" "$INSTDIR\plugindev.exe" 0
|
||||
|
||||
DetailPrint "配置环境变量..."
|
||||
; Add to system PATH
|
||||
ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH"
|
||||
${If} $0 != ""
|
||||
${If} $0 != "*$INSTDIR*"
|
||||
StrCpy $0 "$0;$INSTDIR"
|
||||
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0
|
||||
${EndIf}
|
||||
${Else}
|
||||
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" "$INSTDIR"
|
||||
${EndIf}
|
||||
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SDK_DIR" "$INSTDIR\sdk"
|
||||
WriteRegStr HKLM "Software\${PRODUCT_NAME}" "" "$INSTDIR"
|
||||
|
||||
DetailPrint "检测 Git 客户端..."
|
||||
nsExec::ExecToStack '"git" --version'
|
||||
Pop $0
|
||||
Pop $1
|
||||
${If} $0 == 0
|
||||
StrCpy $hasGit "1"
|
||||
DetailPrint "Git 已安装: $1"
|
||||
${Else}
|
||||
DetailPrint "未检测到 Git,将跳过 SDK 自动下载"
|
||||
DetailPrint "安装完成后请手动运行: plugindev sdk install ${SDK_VERSION}"
|
||||
${EndIf}
|
||||
|
||||
${If} $hasGit == "1"
|
||||
DetailPrint "正在下载 SDK ${SDK_VERSION}..."
|
||||
nsExec::ExecToStack '"$INSTDIR\plugindev.exe" sdk install ${SDK_VERSION}'
|
||||
Pop $0
|
||||
Pop $1
|
||||
${If} $0 == 0
|
||||
StrCpy $sdkInstallOk "1"
|
||||
DetailPrint "SDK ${SDK_VERSION} 下载完成"
|
||||
DetailPrint "正在激活 SDK ${SDK_VERSION}..."
|
||||
nsExec::Exec '"$INSTDIR\plugindev.exe" sdk use ${SDK_VERSION}'
|
||||
Pop $0
|
||||
${Else}
|
||||
DetailPrint "SDK 下载失败 (错误码: $0)"
|
||||
DetailPrint "请手动运行: plugindev sdk install ${SDK_VERSION}"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_DISPLAY_NAME} v${PRODUCT_VERSION}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "Publisher" "${PRODUCT_PUBLISHER}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${PRODUCT_VERSION}"
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1
|
||||
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
Delete "$INSTDIR\plugindev.exe"
|
||||
RMDir /r "$INSTDIR\sdk"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\${PRODUCT_NAME}\plugindev.lnk"
|
||||
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
|
||||
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SDK_DIR"
|
||||
DeleteRegKey HKLM "Software\Microsoft\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
DeleteRegKey HKLM "Software\${PRODUCT_NAME}"
|
||||
SectionEnd
|
||||
Reference in New Issue
Block a user