Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
328 lines
14 KiB
JavaScript
328 lines
14 KiB
JavaScript
const { moshExtraResources } = require('./scripts/mosh-extra-resources.cjs');
|
|
const { etExtraResources } = require('./scripts/et-extra-resources.cjs');
|
|
|
|
/**
|
|
* @type {import('electron-builder').Configuration}
|
|
*/
|
|
module.exports = {
|
|
appId: 'com.netcatty.app',
|
|
productName: 'Netcatty',
|
|
artifactName: '${productName}-${version}-${os}-${arch}.${ext}',
|
|
protocols: [
|
|
{
|
|
name: 'SSH URL',
|
|
schemes: ['ssh']
|
|
},
|
|
{
|
|
name: 'Telnet URL',
|
|
schemes: ['telnet']
|
|
},
|
|
{
|
|
name: 'JumpServer URL',
|
|
schemes: ['jms']
|
|
}
|
|
],
|
|
electronLanguages: ['en', 'en-US', 'zh_CN', 'zh-CN', 'zh_TW', 'zh-TW', 'ru'],
|
|
// Give the macOS build a unique Mach-O LC_UUID before signing, so macOS
|
|
// Local Network privacy treats Netcatty distinctly from every other
|
|
// Electron app (which all share Electron's prebuilt LC_UUID) — see #1040
|
|
// and scripts/afterPackMacUuid.cjs. No-op on Windows/Linux.
|
|
beforePack: './scripts/beforePackCursorSdk.cjs',
|
|
afterPack: './scripts/afterPackMacUuid.cjs',
|
|
// Platform-split icons (#813):
|
|
// - public/icon.png keeps Apple's HIG grid margin so the rendered
|
|
// squircle sits at ~88% of the PNG canvas. macOS needs this —
|
|
// the dock renders icons with its own rounding/shadow and most
|
|
// third-party apps (#803) leave that grid margin alone so the
|
|
// squircle lines up with neighbors.
|
|
// - public/icon-win.png uses a tight-crop viewBox so the squircle
|
|
// fills 100% of the PNG. Windows / Linux taskbars render icons
|
|
// full-bleed, so the Apple margin showed up as visible padding,
|
|
// making the app icon look smaller than other apps in taskbar /
|
|
// Start menu / desktop shortcuts.
|
|
icon: 'public/icon.png',
|
|
// npmRebuild must stay enabled for macOS and Windows builds — without it,
|
|
// node-pty's native module is not recompiled for the Electron ABI, causing
|
|
// "posix_spawnp failed" on macOS. Linux builds set npm_config_arch in CI
|
|
// and run ensure-node-pty-linux.sh before packaging, so the rebuild is
|
|
// redundant but harmless there.
|
|
npmRebuild: true,
|
|
directories: {
|
|
buildResources: 'build',
|
|
output: 'release'
|
|
},
|
|
files: [
|
|
'dist/**/*',
|
|
'electron/**/*',
|
|
// The Windows Hello helper is shipped once through win.extraResources.
|
|
// Exclude local per-arch build output from app.asar on every platform.
|
|
'!electron/bridges/windowsHelloHelper/build/**/*',
|
|
// Runtime smoke fixtures are built test packages, not host resources.
|
|
// Keep them out of production ASARs so no example plugin can be
|
|
// mistaken for an installed or host-trusted package.
|
|
'!electron/plugins/fixtures/**/*',
|
|
// Main-process terminal flow control reads shared thresholds from here
|
|
// (terminalFlowAck.cjs). Must ship beside electron/ in app.asar.
|
|
'infrastructure/config/terminalFlowConstants.cjs',
|
|
'infrastructure/config/terminalFlowConstants.json',
|
|
// Renderer and Mosh's main-process bootstrap share the same
|
|
// fail-closed prompt classifier at runtime.
|
|
'domain/terminalPromptSecurity.shared.cjs',
|
|
'lib/**/*.cjs',
|
|
'lib/**/*.json',
|
|
'skills/**/*',
|
|
'!public/**/*',
|
|
'!**/*.map',
|
|
'!**/*.d.ts',
|
|
'!**/*.d.mts',
|
|
'!**/*.d.cts',
|
|
'!**/*.ts',
|
|
'!**/*.tsx',
|
|
'!**/*.test.*',
|
|
'!**/*.spec.*',
|
|
'!**/__tests__/**/*',
|
|
'!**/test/**/*',
|
|
'!**/tests/**/*',
|
|
'!**/example/**/*',
|
|
'!**/examples/**/*',
|
|
'!node_modules/**/docs/**/*',
|
|
'!node_modules/**/doc/**/*',
|
|
'!node_modules/**/benchmark/**/*',
|
|
'!node_modules/**/benchmarks/**/*',
|
|
// Renderer-only packages are compiled into dist by Vite. Keep them
|
|
// installed for npm run dev/build, but do not ship the duplicate source
|
|
// packages in release artifacts.
|
|
'!node_modules/@fontsource/**/*',
|
|
'!node_modules/@monaco-editor/**/*',
|
|
'!node_modules/@radix-ui/**/*',
|
|
'!node_modules/@xterm/**/*',
|
|
'!node_modules/lucide-react/**/*',
|
|
'!node_modules/monaco-editor/**/*',
|
|
'!node_modules/react/**/*',
|
|
'!node_modules/react-dom/**/*',
|
|
'!node_modules/ai/**/*',
|
|
'!node_modules/@ai-sdk/**/*',
|
|
'!node_modules/@mdxeditor/**/*',
|
|
'!node_modules/streamdown/**/*',
|
|
'!node_modules/@streamdown/**/*',
|
|
'!node_modules/@tanstack/react-virtual/**/*',
|
|
'!node_modules/pinyin-pro/**/*',
|
|
'!node_modules/re2js/**/*',
|
|
'!node_modules/@eslint-community/regexpp/**/*',
|
|
'!node_modules/clsx/**/*',
|
|
'!node_modules/tailwind-merge/**/*',
|
|
'!node_modules/use-stick-to-bottom/**/*',
|
|
'!node_modules/lexical/**/*',
|
|
'!node_modules/@lexical/**/*',
|
|
'!node_modules/@codemirror/**/*',
|
|
'!node_modules/katex/**/*',
|
|
'!node_modules/shiki/**/*',
|
|
'!node_modules/@shiki/**/*',
|
|
// Heavy cloud completion specs are intentionally not bundled. The main
|
|
// process filters the same prefixes so dev and packaged builds behave
|
|
// consistently.
|
|
'!node_modules/@withfig/autocomplete/build/aws.js',
|
|
'!node_modules/@withfig/autocomplete/build/aws/**/*',
|
|
'!node_modules/@withfig/autocomplete/build/gcloud.js',
|
|
'!node_modules/@withfig/autocomplete/build/gcloud/**/*',
|
|
'!node_modules/@withfig/autocomplete/build/az/**/*',
|
|
// Fig specs are already compiled JavaScript; TypeScript is only pulled
|
|
// in by Fig helper packages as build tooling and is not needed at app
|
|
// runtime.
|
|
'!node_modules/typescript/**/*',
|
|
// ── Exclude per-platform native agent binaries (~100s of MB each). ──
|
|
// Netcatty is "bring your own CLI": each SDK is pointed at the user's
|
|
// system-installed CLI via an absolute path override (claude
|
|
// pathToClaudeCodeExecutable / codex codexPathOverride / copilot cliPath).
|
|
// Only the SDKs' JS is bundled; the heavy per-arch binaries are dropped.
|
|
// NOTE: claude-agent-sdk vendors the `claude` binary as a NESTED package
|
|
// (claude-agent-sdk/node_modules/@anthropic-ai/claude-agent-sdk-<arch>),
|
|
// so this exclusion must match at any depth (**/), not just top-level.
|
|
// The codex/copilot exclusions target only the per-arch binary packages
|
|
// (codex-<arch> / copilot-<arch>) — NOT @openai/codex-sdk / copilot-sdk,
|
|
// whose JS we DO bundle. @github/copilot is the full ~288MB CLI (with
|
|
// per-platform prebuilds); netcatty uses the user's copilot via cliPath,
|
|
// so it is excluded entirely.
|
|
'!**/@anthropic-ai/claude-agent-sdk-*/**/*',
|
|
'!node_modules/@anthropic-ai/claude-code-*/**/*',
|
|
'!node_modules/@openai/codex-{darwin,linux,linuxmusl,win32}-*/**/*',
|
|
'!node_modules/@github/copilot-{darwin,linux,linuxmusl,win32}-*/**/*',
|
|
'!node_modules/@github/copilot/**/*',
|
|
'!node_modules/opencode-{darwin,linux,linuxmusl,windows}-*/**/*',
|
|
'!node_modules/opencode-ai/**/*',
|
|
// CodeBuddy follows the same first-party integration model as the
|
|
// other coding agents: Netcatty discovers and passes the user's
|
|
// installed CLI path to the SDK. Keep the small SDK wrapper, but do not
|
|
// bundle the full CodeBuddy CLI payload (rg vendors + web UI).
|
|
'!node_modules/@tencent-ai/agent-sdk/cli/**/*',
|
|
// Netcatty loads Cursor SDK through ESM dynamic import, so the duplicate
|
|
// CommonJS build and type metadata are not needed at runtime.
|
|
'!node_modules/@cursor/sdk/dist/cjs/**/*',
|
|
'!node_modules/@cursor/sdk/dist/**/*.d.ts',
|
|
'!node_modules/@cursor/sdk/dist/**/*.d.ts.map',
|
|
// sqlite3 rebuilds a native module for Electron; its upstream source
|
|
// tarball is build-time payload only.
|
|
'!node_modules/sqlite3/deps/**/*'
|
|
],
|
|
asarUnpack: [
|
|
'node_modules/node-pty/**/*',
|
|
'node_modules/ssh2/**/*',
|
|
'node_modules/cpu-features/**/*',
|
|
'node_modules/@vscode/windows-process-tree/**/*',
|
|
'node_modules/@anthropic-ai/claude-agent-sdk/**/*',
|
|
'node_modules/@cursor/sdk-*/**/*',
|
|
'node_modules/sqlite3/**/*',
|
|
'node_modules/@modelcontextprotocol/sdk/**/*',
|
|
'lib/**/*.cjs',
|
|
'lib/**/*.json',
|
|
'node_modules/zod/**/*',
|
|
'node_modules/zod-to-json-schema/**/*',
|
|
'node_modules/@netcatty/plugin-cli/**/*',
|
|
'node_modules/@netcatty/plugin-contract/**/*',
|
|
'node_modules/@netcatty/plugin-sdk/**/*',
|
|
'electron/plugins/runtime/**/*',
|
|
'node_modules/ajv/**/*',
|
|
'node_modules/ajv-formats/**/*',
|
|
'node_modules/fast-deep-equal/**/*',
|
|
'node_modules/fast-uri/**/*',
|
|
'node_modules/json-schema-traverse/**/*',
|
|
'electron/cli/**/*',
|
|
'electron/capabilities/**/*',
|
|
'electron/shared/**/*',
|
|
'electron/mcp/**/*',
|
|
'skills/**/*'
|
|
],
|
|
mac: {
|
|
// app-builder's PNG-to-ICNS conversion can corrupt the 16px/32px 1x
|
|
// representations even though the source PNG is valid RGBA. Use the
|
|
// iconutil-generated bundle instead so Finder and app switchers do not
|
|
// render those representations as colored noise.
|
|
icon: 'build/icon.icns',
|
|
target: [
|
|
{
|
|
target: 'dmg',
|
|
arch: ['arm64', 'x64']
|
|
},
|
|
{
|
|
target: 'zip',
|
|
arch: ['arm64', 'x64']
|
|
}
|
|
],
|
|
category: 'public.app-category.developer-tools',
|
|
hardenedRuntime: true,
|
|
notarize: true,
|
|
entitlements: 'electron/entitlements.mac.plist',
|
|
entitlementsInherit: 'electron/entitlements.mac.plist',
|
|
extendInfo: {
|
|
NSCameraUsageDescription: 'Netcatty may use the camera for video calls',
|
|
NSMicrophoneUsageDescription: 'Netcatty may use the microphone for audio',
|
|
NSLocalNetworkUsageDescription: 'Netcatty needs local network access for SSH connections',
|
|
CFBundleDocumentTypes: [
|
|
{
|
|
CFBundleTypeName: 'Folder',
|
|
CFBundleTypeRole: 'Viewer',
|
|
LSHandlerRank: 'Alternate',
|
|
LSItemContentTypes: ['public.folder']
|
|
}
|
|
]
|
|
},
|
|
extraResources: [...moshExtraResources('darwin'), ...etExtraResources('darwin')]
|
|
},
|
|
dmg: {
|
|
title: '${productName}',
|
|
iconSize: 100,
|
|
iconTextSize: 12,
|
|
window: {
|
|
width: 540,
|
|
height: 380
|
|
},
|
|
contents: [
|
|
{ x: 140, y: 158 },
|
|
{ x: 400, y: 158, type: 'link', path: '/Applications' }
|
|
]
|
|
},
|
|
win: {
|
|
icon: 'public/icon-win.png',
|
|
// Do not hard-code arch here. pack:win-x64 / pack:win pass --x64/--arm64,
|
|
// and electron-builder unions config arch with the CLI set. Hard-coding
|
|
// ['x64', 'arm64'] made the official x64 CI job also emit win-arm64 and
|
|
// a universal win.exe whose 32-bit NSIS stub can mis-detect on ARM
|
|
// Windows, install to Program Files (x86), and leave Netcatty.exe
|
|
// missing (#2570). Keep official releases on pack:win-x64 until win32
|
|
// arm64 bundled mosh/et + native rebuilds are ready.
|
|
target: ['nsis', 'portable', 'zip'],
|
|
extraResources: [
|
|
...moshExtraResources('win32'),
|
|
...etExtraResources('win32'),
|
|
{
|
|
from: 'electron/bridges/windowsHelloHelper/build/${arch}/NetcattyWindowsHello.exe',
|
|
to: 'windowsHello/NetcattyWindowsHello.exe',
|
|
filter: ['**/*']
|
|
}
|
|
]
|
|
},
|
|
portable: {
|
|
artifactName: '${productName}-${version}-portable-${os}-${arch}.${ext}',
|
|
},
|
|
nsis: {
|
|
include: 'build/installer.nsh',
|
|
oneClick: false,
|
|
perMachine: false,
|
|
allowElevation: true,
|
|
allowToChangeInstallationDirectory: true,
|
|
createDesktopShortcut: true,
|
|
createStartMenuShortcut: true,
|
|
shortcutName: 'Netcatty'
|
|
},
|
|
linux: {
|
|
// Linux .deb/.rpm/AppImage icons come from build/icons/* (see
|
|
// scripts/generate-linux-icons.sh). Point at the icons directory
|
|
// under buildResources — electron-builder still falls back to the
|
|
// top-level icon (public/icon.png) when linux.icon is unset, which
|
|
// installs only hicolor/1024x1024 and launchers miss the icon (#274,
|
|
// #1340). Do NOT set linux.icon to a single 1024px PNG either.
|
|
icon: 'icons',
|
|
target: ['AppImage', 'deb', 'rpm', 'pacman'],
|
|
category: 'Development',
|
|
extraResources: [...moshExtraResources('linux'), ...etExtraResources('linux')]
|
|
},
|
|
deb: {
|
|
// Use gzip instead of default xz(lzma) for better compatibility with
|
|
// Deepin OS and other distros that have issues with lzma decompression
|
|
compression: 'gz',
|
|
afterInstall: 'scripts/linux/after-install.tpl'
|
|
},
|
|
rpm: {
|
|
// Default fpm/electron-builder RPM compression is "xzmt" (multi-threaded
|
|
// xz). AlmaLinux/RHEL 8 images provide `xz` but not the `xzmt` shim, so
|
|
// rpmbuild fails with exit 127 during packaging. gzip is portable and
|
|
// matches our deb preference for older distros.
|
|
compression: 'gzip',
|
|
afterInstall: 'scripts/linux/after-install.tpl',
|
|
fpm: [
|
|
// Avoid rpm's generated /usr/lib/.build-id symlinks. Those hashes
|
|
// are global on the host, so owning them can conflict with other RPMs.
|
|
'--rpm-rpmbuild-define', '_build_id_links none',
|
|
// Electron ships prebuilt binaries. RHEL/Alma brp post-install
|
|
// scripts (strip/compress/etc.) can exit 127 when a helper is
|
|
// missing or a gcc-toolset `strip` is on PATH; skip them.
|
|
'--rpm-rpmbuild-define', '__os_install_post %{nil}',
|
|
]
|
|
},
|
|
pacman: {
|
|
// FPM-generated .pacman packages bypass Arch's alpm hooks that
|
|
// normally refresh the hicolor icon cache. Without this, KDE cannot
|
|
// resolve Icon=netcatty and shows a generic placeholder (#1358).
|
|
afterInstall: 'scripts/linux/after-install.tpl',
|
|
afterRemove: 'scripts/linux/after-remove.tpl',
|
|
},
|
|
publish: [
|
|
{
|
|
provider: 'github',
|
|
owner: 'binaricat',
|
|
repo: 'Netcatty',
|
|
releaseType: 'release'
|
|
}
|
|
]
|
|
};
|