@neurocode-ai/desktop 1.18.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -0
- package/README.md +19 -0
- package/electron-builder.config.test.ts +48 -0
- package/electron-builder.config.ts +146 -0
- package/electron.vite.config.ts +106 -0
- package/icons/README.md +14 -0
- package/icons/beta/128x128.png +0 -0
- package/icons/beta/128x128@2x.png +0 -0
- package/icons/beta/32x32.png +0 -0
- package/icons/beta/64x64.png +0 -0
- package/icons/beta/Square107x107Logo.png +0 -0
- package/icons/beta/Square142x142Logo.png +0 -0
- package/icons/beta/Square150x150Logo.png +0 -0
- package/icons/beta/Square284x284Logo.png +0 -0
- package/icons/beta/Square30x30Logo.png +0 -0
- package/icons/beta/Square310x310Logo.png +0 -0
- package/icons/beta/Square44x44Logo.png +0 -0
- package/icons/beta/Square71x71Logo.png +0 -0
- package/icons/beta/Square89x89Logo.png +0 -0
- package/icons/beta/StoreLogo.png +0 -0
- package/icons/beta/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/icons/beta/android/mipmap-hdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-mdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-xhdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/beta/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/icons/beta/android/values/ic_launcher_background.xml +4 -0
- package/icons/beta/dock.png +0 -0
- package/icons/beta/icon.icns +0 -0
- package/icons/beta/icon.ico +0 -0
- package/icons/beta/icon.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@1x.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@2x-1.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@2x.png +0 -0
- package/icons/beta/ios/AppIcon-20x20@3x.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@1x.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@2x-1.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@2x.png +0 -0
- package/icons/beta/ios/AppIcon-29x29@3x.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@1x.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@2x-1.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@2x.png +0 -0
- package/icons/beta/ios/AppIcon-40x40@3x.png +0 -0
- package/icons/beta/ios/AppIcon-512@2x.png +0 -0
- package/icons/beta/ios/AppIcon-60x60@2x.png +0 -0
- package/icons/beta/ios/AppIcon-60x60@3x.png +0 -0
- package/icons/beta/ios/AppIcon-76x76@1x.png +0 -0
- package/icons/beta/ios/AppIcon-76x76@2x.png +0 -0
- package/icons/beta/ios/AppIcon-83.5x83.5@2x.png +0 -0
- package/icons/dev/128x128.png +0 -0
- package/icons/dev/128x128@2x.png +0 -0
- package/icons/dev/32x32.png +0 -0
- package/icons/dev/64x64.png +0 -0
- package/icons/dev/Square107x107Logo.png +0 -0
- package/icons/dev/Square142x142Logo.png +0 -0
- package/icons/dev/Square150x150Logo.png +0 -0
- package/icons/dev/Square284x284Logo.png +0 -0
- package/icons/dev/Square30x30Logo.png +0 -0
- package/icons/dev/Square310x310Logo.png +0 -0
- package/icons/dev/Square44x44Logo.png +0 -0
- package/icons/dev/Square71x71Logo.png +0 -0
- package/icons/dev/Square89x89Logo.png +0 -0
- package/icons/dev/StoreLogo.png +0 -0
- package/icons/dev/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/icons/dev/android/mipmap-hdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-mdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-xhdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/dev/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/icons/dev/android/values/ic_launcher_background.xml +4 -0
- package/icons/dev/dock.png +0 -0
- package/icons/dev/icon.icns +0 -0
- package/icons/dev/icon.ico +0 -0
- package/icons/dev/icon.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@1x.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@2x-1.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@2x.png +0 -0
- package/icons/dev/ios/AppIcon-20x20@3x.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@1x.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@2x-1.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@2x.png +0 -0
- package/icons/dev/ios/AppIcon-29x29@3x.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@1x.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@2x-1.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@2x.png +0 -0
- package/icons/dev/ios/AppIcon-40x40@3x.png +0 -0
- package/icons/dev/ios/AppIcon-512@2x.png +0 -0
- package/icons/dev/ios/AppIcon-60x60@2x.png +0 -0
- package/icons/dev/ios/AppIcon-60x60@3x.png +0 -0
- package/icons/dev/ios/AppIcon-76x76@1x.png +0 -0
- package/icons/dev/ios/AppIcon-76x76@2x.png +0 -0
- package/icons/dev/ios/AppIcon-83.5x83.5@2x.png +0 -0
- package/icons/prod/128x128.png +0 -0
- package/icons/prod/128x128@2x.png +0 -0
- package/icons/prod/32x32.png +0 -0
- package/icons/prod/64x64.png +0 -0
- package/icons/prod/Square107x107Logo.png +0 -0
- package/icons/prod/Square142x142Logo.png +0 -0
- package/icons/prod/Square150x150Logo.png +0 -0
- package/icons/prod/Square284x284Logo.png +0 -0
- package/icons/prod/Square30x30Logo.png +0 -0
- package/icons/prod/Square310x310Logo.png +0 -0
- package/icons/prod/Square44x44Logo.png +0 -0
- package/icons/prod/Square71x71Logo.png +0 -0
- package/icons/prod/Square89x89Logo.png +0 -0
- package/icons/prod/StoreLogo.png +0 -0
- package/icons/prod/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/icons/prod/android/mipmap-hdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-mdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-xhdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/icons/prod/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/icons/prod/android/values/ic_launcher_background.xml +4 -0
- package/icons/prod/dock.png +0 -0
- package/icons/prod/icon.icns +0 -0
- package/icons/prod/icon.ico +0 -0
- package/icons/prod/icon.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@1x.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@2x-1.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@2x.png +0 -0
- package/icons/prod/ios/AppIcon-20x20@3x.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@1x.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@2x-1.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@2x.png +0 -0
- package/icons/prod/ios/AppIcon-29x29@3x.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@1x.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@2x-1.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@2x.png +0 -0
- package/icons/prod/ios/AppIcon-40x40@3x.png +0 -0
- package/icons/prod/ios/AppIcon-512@2x.png +0 -0
- package/icons/prod/ios/AppIcon-60x60@2x.png +0 -0
- package/icons/prod/ios/AppIcon-60x60@3x.png +0 -0
- package/icons/prod/ios/AppIcon-76x76@1x.png +0 -0
- package/icons/prod/ios/AppIcon-76x76@2x.png +0 -0
- package/icons/prod/ios/AppIcon-83.5x83.5@2x.png +0 -0
- package/package.json +75 -0
- package/resources/entitlements.plist +18 -0
- package/resources/linux/opencode-desktop.desktop +10 -0
- package/scripts/copy-bundles.ts +12 -0
- package/scripts/copy-icons.ts +12 -0
- package/scripts/copy-metainfo.ts +47 -0
- package/scripts/finalize-latest-json.ts +219 -0
- package/scripts/finalize-latest-yml.ts +124 -0
- package/scripts/prebuild.ts +10 -0
- package/scripts/predev.ts +5 -0
- package/scripts/prepare.ts +9 -0
- package/scripts/utils.ts +77 -0
- package/src/main/apps.ts +136 -0
- package/src/main/attachment-picker.test.ts +87 -0
- package/src/main/attachment-picker.ts +56 -0
- package/src/main/constants.ts +7 -0
- package/src/main/debug.ts +95 -0
- package/src/main/desktop-menu-actions.ts +84 -0
- package/src/main/env.d.ts +19 -0
- package/src/main/index.test.ts +37 -0
- package/src/main/index.ts +399 -0
- package/src/main/initialization.ts +6 -0
- package/src/main/install-state.test.ts +19 -0
- package/src/main/install-state.ts +8 -0
- package/src/main/ipc.ts +274 -0
- package/src/main/logging.ts +205 -0
- package/src/main/markdown.ts +16 -0
- package/src/main/menu.ts +67 -0
- package/src/main/migrate.ts +91 -0
- package/src/main/onboarding.ts +45 -0
- package/src/main/server.ts +238 -0
- package/src/main/shell-env.test.ts +50 -0
- package/src/main/shell-env.ts +101 -0
- package/src/main/sidecar.ts +157 -0
- package/src/main/store-cleanup.test.ts +93 -0
- package/src/main/store-cleanup.ts +94 -0
- package/src/main/store-keys.ts +7 -0
- package/src/main/store.ts +35 -0
- package/src/main/unresponsive.ts +70 -0
- package/src/main/updater-controller.test.ts +111 -0
- package/src/main/updater-controller.ts +97 -0
- package/src/main/updater-subscriptions.test.ts +16 -0
- package/src/main/updater-subscriptions.ts +20 -0
- package/src/main/updater.ts +85 -0
- package/src/main/window-registry.test.ts +91 -0
- package/src/main/window-registry.ts +47 -0
- package/src/main/window-state.ts +29 -0
- package/src/main/windows.ts +496 -0
- package/src/main/wsl/ipc.ts +103 -0
- package/src/main/wsl/policy.ts +33 -0
- package/src/main/wsl/runtime.ts +400 -0
- package/src/main/wsl/servers.test.ts +231 -0
- package/src/main/wsl/servers.ts +521 -0
- package/src/main/wsl/sidecar.ts +129 -0
- package/src/main/wsl/startup.ts +31 -0
- package/src/preload/index.ts +128 -0
- package/src/preload/types.ts +109 -0
- package/src/renderer/cli.ts +12 -0
- package/src/renderer/env.d.ts +10 -0
- package/src/renderer/html.test.ts +62 -0
- package/src/renderer/i18n/ar.ts +26 -0
- package/src/renderer/i18n/br.ts +27 -0
- package/src/renderer/i18n/bs.ts +28 -0
- package/src/renderer/i18n/da.ts +28 -0
- package/src/renderer/i18n/de.ts +28 -0
- package/src/renderer/i18n/en.ts +27 -0
- package/src/renderer/i18n/es.ts +27 -0
- package/src/renderer/i18n/fr.ts +28 -0
- package/src/renderer/i18n/index.ts +194 -0
- package/src/renderer/i18n/ja.ts +28 -0
- package/src/renderer/i18n/ko.ts +27 -0
- package/src/renderer/i18n/no.ts +28 -0
- package/src/renderer/i18n/pl.ts +28 -0
- package/src/renderer/i18n/ru.ts +27 -0
- package/src/renderer/i18n/uk.ts +28 -0
- package/src/renderer/i18n/zh.ts +26 -0
- package/src/renderer/i18n/zht.ts +26 -0
- package/src/renderer/index.html +21 -0
- package/src/renderer/index.tsx +464 -0
- package/src/renderer/initialization.test.ts +73 -0
- package/src/renderer/initialization.ts +22 -0
- package/src/renderer/onboarding.tsx +53 -0
- package/src/renderer/styles.css +0 -0
- package/src/renderer/webview-zoom.ts +138 -0
- package/src/renderer/wsl/connections.test.ts +43 -0
- package/src/renderer/wsl/connections.ts +28 -0
- package/sst-env.d.ts +10 -0
- package/tsconfig.json +23 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neurocode-ai/desktop",
|
|
3
|
+
"version": "1.18.8",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://opencode.ai",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "OpenCode",
|
|
9
|
+
"email": "hello@opencode.ai"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"typecheck": "tsgo -b",
|
|
13
|
+
"predev": "bun ./scripts/predev.ts",
|
|
14
|
+
"dev": "electron-vite dev",
|
|
15
|
+
"prebuild": "bun ./scripts/prebuild.ts",
|
|
16
|
+
"build": "electron-vite build",
|
|
17
|
+
"preview": "electron-vite preview",
|
|
18
|
+
"package": "electron-builder --config electron-builder.config.ts",
|
|
19
|
+
"package:mac": "electron-builder --mac --config electron-builder.config.ts",
|
|
20
|
+
"package:win": "electron-builder --win --config electron-builder.config.ts",
|
|
21
|
+
"package:linux": "electron-builder --linux --config electron-builder.config.ts",
|
|
22
|
+
"native:build": "bun install --cwd native"
|
|
23
|
+
},
|
|
24
|
+
"main": "./out/main/index.js",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@zip.js/zip.js": "2.7.62",
|
|
27
|
+
"effect": "4.0.0-beta.83",
|
|
28
|
+
"electron-context-menu": "4.1.2",
|
|
29
|
+
"electron-log": "^5",
|
|
30
|
+
"electron-store": "11.0.2",
|
|
31
|
+
"electron-updater": "6.8.9",
|
|
32
|
+
"electron-window-state": "^5.0.3",
|
|
33
|
+
"marked": "^15"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@actions/artifact": "4.0.0",
|
|
37
|
+
"@lydell/node-pty": "1.2.0-beta.12",
|
|
38
|
+
"@neurocode-ai/app": "1.18.8",
|
|
39
|
+
"@neurocode-ai/ui": "1.18.8",
|
|
40
|
+
"@sentry/solid": "10.36.0",
|
|
41
|
+
"@sentry/vite-plugin": "4.6.0",
|
|
42
|
+
"@solid-primitives/i18n": "2.2.1",
|
|
43
|
+
"@solid-primitives/storage": "4.3.3",
|
|
44
|
+
"@solidjs/meta": "0.29.4",
|
|
45
|
+
"@solidjs/router": "0.15.4",
|
|
46
|
+
"@types/bun": "1.3.13",
|
|
47
|
+
"@types/node": "24.12.2",
|
|
48
|
+
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
49
|
+
"@valibot/to-json-schema": "1.6.0",
|
|
50
|
+
"electron": "42.3.3",
|
|
51
|
+
"electron-builder": "26.15.2",
|
|
52
|
+
"electron-vite": "^5",
|
|
53
|
+
"solid-js": "1.9.10",
|
|
54
|
+
"sury": "11.0.0-alpha.4",
|
|
55
|
+
"typescript": "~5.6.2",
|
|
56
|
+
"vite": "7.1.4",
|
|
57
|
+
"zod-openapi": "5.4.6"
|
|
58
|
+
},
|
|
59
|
+
"optionalDependencies": {
|
|
60
|
+
"@lydell/node-pty-darwin-arm64": "1.2.0-beta.12",
|
|
61
|
+
"@lydell/node-pty-darwin-x64": "1.2.0-beta.12",
|
|
62
|
+
"@lydell/node-pty-linux-arm64": "1.2.0-beta.12",
|
|
63
|
+
"@lydell/node-pty-linux-x64": "1.2.0-beta.12",
|
|
64
|
+
"@lydell/node-pty-win32-arm64": "1.2.0-beta.12",
|
|
65
|
+
"@lydell/node-pty-win32-x64": "1.2.0-beta.12",
|
|
66
|
+
"@parcel/watcher-darwin-arm64": "2.5.1",
|
|
67
|
+
"@parcel/watcher-darwin-x64": "2.5.1",
|
|
68
|
+
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
|
|
69
|
+
"@parcel/watcher-linux-arm64-musl": "2.5.1",
|
|
70
|
+
"@parcel/watcher-linux-x64-glibc": "2.5.1",
|
|
71
|
+
"@parcel/watcher-linux-x64-musl": "2.5.1",
|
|
72
|
+
"@parcel/watcher-win32-arm64": "2.5.1",
|
|
73
|
+
"@parcel/watcher-win32-x64": "2.5.1"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>com.apple.security.cs.allow-jit</key>
|
|
6
|
+
<true/>
|
|
7
|
+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
|
8
|
+
<true/>
|
|
9
|
+
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
|
10
|
+
<true/>
|
|
11
|
+
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
|
12
|
+
<true/>
|
|
13
|
+
<key>com.apple.security.cs.disable-library-validation</key>
|
|
14
|
+
<true/>
|
|
15
|
+
<key>com.apple.security.device.audio-input</key>
|
|
16
|
+
<true/>
|
|
17
|
+
</dict>
|
|
18
|
+
</plist>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { $ } from "bun"
|
|
2
|
+
import * as path from "node:path"
|
|
3
|
+
|
|
4
|
+
import { RUST_TARGET } from "./utils"
|
|
5
|
+
|
|
6
|
+
if (!RUST_TARGET) throw new Error("RUST_TARGET not defined")
|
|
7
|
+
|
|
8
|
+
const BUNDLE_DIR = "dist"
|
|
9
|
+
const BUNDLES_OUT_DIR = path.join(process.cwd(), "dist/bundles")
|
|
10
|
+
|
|
11
|
+
await $`mkdir -p ${BUNDLES_OUT_DIR}`
|
|
12
|
+
await $`cp -r ${BUNDLE_DIR}/* ${BUNDLES_OUT_DIR}`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { $ } from "bun"
|
|
2
|
+
import { resolveChannel } from "./utils"
|
|
3
|
+
|
|
4
|
+
const arg = process.argv[2]
|
|
5
|
+
const channel = arg === "dev" || arg === "beta" || arg === "prod" ? arg : resolveChannel()
|
|
6
|
+
|
|
7
|
+
const src = `./icons/${channel}`
|
|
8
|
+
const dest = "resources/icons"
|
|
9
|
+
|
|
10
|
+
await $`rm -rf ${dest}`
|
|
11
|
+
await $`cp -R ${src} ${dest}`
|
|
12
|
+
console.log(`Copied ${channel} icons from ${src} to ${dest}`)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { resolveChannel } from "./utils"
|
|
2
|
+
|
|
3
|
+
const arg = process.argv[2]
|
|
4
|
+
const channel = arg === "dev" || arg === "beta" || arg === "prod" ? arg : resolveChannel()
|
|
5
|
+
|
|
6
|
+
const appId = channel === "prod" ? "ai.opencode.desktop" : `ai.opencode.desktop.${channel}`
|
|
7
|
+
const productName = channel === "prod" ? "OpenCode" : `OpenCode ${channel.charAt(0).toUpperCase() + channel.slice(1)}`
|
|
8
|
+
const summary = `Open source AI coding agent${channel !== "prod" ? ` (${channel})` : ""}`
|
|
9
|
+
|
|
10
|
+
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
11
|
+
<component type="desktop-application">
|
|
12
|
+
<id>${appId}</id>
|
|
13
|
+
|
|
14
|
+
<metadata_license>CC0-1.0</metadata_license>
|
|
15
|
+
<project_license>MIT</project_license>
|
|
16
|
+
|
|
17
|
+
<name>${productName}</name>
|
|
18
|
+
<summary>${summary}</summary>
|
|
19
|
+
|
|
20
|
+
<developer id="ly.anoma">
|
|
21
|
+
<name>Anomaly Innovations Inc.</name>
|
|
22
|
+
</developer>
|
|
23
|
+
|
|
24
|
+
<description>
|
|
25
|
+
<p>
|
|
26
|
+
OpenCode is an open source agent that helps you write and run code with any AI model.
|
|
27
|
+
</p>
|
|
28
|
+
</description>
|
|
29
|
+
|
|
30
|
+
<launchable type="desktop-id">${appId}.desktop</launchable>
|
|
31
|
+
|
|
32
|
+
<content_rating type="oars-1.1" />
|
|
33
|
+
|
|
34
|
+
<url type="bugtracker">https://github.com/bjlamprea12-wq/NeuroAgent/issues</url>
|
|
35
|
+
<url type="homepage">https://opencode.ai</url>
|
|
36
|
+
<url type="vcs-browser">https://github.com/bjlamprea12-wq/NeuroAgent</url>
|
|
37
|
+
|
|
38
|
+
<screenshots>
|
|
39
|
+
<screenshot type="default">
|
|
40
|
+
<image>https://raw.githubusercontent.com/bjlamprea12-wq/NeuroAgent/b75d4d1c5ec449585d515c756fc81f080a157a9a/packages/web/src/assets/lander/screenshot.png</image>
|
|
41
|
+
</screenshot>
|
|
42
|
+
</screenshots>
|
|
43
|
+
</component>
|
|
44
|
+
`
|
|
45
|
+
|
|
46
|
+
await Bun.write(`resources/${appId}.metainfo.xml`, xml)
|
|
47
|
+
console.log(`Generated metainfo for ${channel} at resources/${appId}.metainfo.xml`)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { $ } from "bun"
|
|
4
|
+
import path from "node:path"
|
|
5
|
+
import { parseArgs } from "node:util"
|
|
6
|
+
|
|
7
|
+
const { values } = parseArgs({
|
|
8
|
+
args: Bun.argv.slice(2),
|
|
9
|
+
options: {
|
|
10
|
+
"dry-run": { type: "boolean", default: false },
|
|
11
|
+
},
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const dryRun = values["dry-run"]
|
|
15
|
+
|
|
16
|
+
const repo = process.env.GH_REPO
|
|
17
|
+
if (!repo) throw new Error("GH_REPO is required")
|
|
18
|
+
|
|
19
|
+
const releaseId = process.env.OPENCODE_RELEASE
|
|
20
|
+
if (!releaseId) throw new Error("OPENCODE_RELEASE is required")
|
|
21
|
+
|
|
22
|
+
const version = process.env.OPENCODE_VERSION
|
|
23
|
+
if (!version) throw new Error("OPENCODE_VERSION is required")
|
|
24
|
+
|
|
25
|
+
const dir = process.env.LATEST_YML_DIR
|
|
26
|
+
if (!dir) throw new Error("LATEST_YML_DIR is required")
|
|
27
|
+
const root = dir
|
|
28
|
+
|
|
29
|
+
const token = process.env.GH_TOKEN ?? process.env.GITHUB_TOKEN
|
|
30
|
+
if (!token) throw new Error("GH_TOKEN or GITHUB_TOKEN is required")
|
|
31
|
+
|
|
32
|
+
const rel = await fetch(`https://api.github.com/repos/${repo}/releases/${releaseId}`, {
|
|
33
|
+
headers: {
|
|
34
|
+
Authorization: `token ${token}`,
|
|
35
|
+
Accept: "application/vnd.github+json",
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
if (!rel.ok) {
|
|
40
|
+
throw new Error(`Failed to fetch release: ${rel.status} ${rel.statusText}`)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type Asset = {
|
|
44
|
+
name: string
|
|
45
|
+
url: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type Release = {
|
|
49
|
+
assets?: Asset[]
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const assets = ((await rel.json()) as Release).assets ?? []
|
|
53
|
+
const amap = new Map(assets.map((item) => [item.name, item]))
|
|
54
|
+
|
|
55
|
+
type Item = {
|
|
56
|
+
url: string
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type Yml = {
|
|
60
|
+
version: string
|
|
61
|
+
files: Item[]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parse(text: string): Yml {
|
|
65
|
+
const lines = text.split("\n")
|
|
66
|
+
let version = ""
|
|
67
|
+
const files: Item[] = []
|
|
68
|
+
let url = ""
|
|
69
|
+
|
|
70
|
+
const flush = () => {
|
|
71
|
+
if (!url) return
|
|
72
|
+
files.push({ url })
|
|
73
|
+
url = ""
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (const line of lines) {
|
|
77
|
+
const trim = line.trim()
|
|
78
|
+
if (line.startsWith("version:")) {
|
|
79
|
+
version = line.slice("version:".length).trim()
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
if (trim.startsWith("- url:")) {
|
|
83
|
+
flush()
|
|
84
|
+
url = trim.slice("- url:".length).trim()
|
|
85
|
+
continue
|
|
86
|
+
}
|
|
87
|
+
const indented = line.startsWith(" ") || line.startsWith("\t")
|
|
88
|
+
if (!indented) flush()
|
|
89
|
+
}
|
|
90
|
+
flush()
|
|
91
|
+
|
|
92
|
+
return { version, files }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function read(sub: string, file: string) {
|
|
96
|
+
const item = Bun.file(path.join(root, sub, file))
|
|
97
|
+
if (!(await item.exists())) return undefined
|
|
98
|
+
return parse(await item.text())
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function pick(list: Item[], exts: string[]) {
|
|
102
|
+
for (const ext of exts) {
|
|
103
|
+
const found = list.find((item) => item.url.split("?")[0]?.toLowerCase().endsWith(ext))
|
|
104
|
+
if (found) return found.url
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function link(raw: string) {
|
|
109
|
+
if (raw.startsWith("https://") || raw.startsWith("http://")) return raw
|
|
110
|
+
return `https://github.com/${repo}/releases/download/v${version}/${raw}`
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function sign(url: string, key: string) {
|
|
114
|
+
const name = decodeURIComponent(new URL(url).pathname.split("/").pop() ?? key)
|
|
115
|
+
const asset = amap.get(name)
|
|
116
|
+
const res = await fetch(asset?.url ?? url, {
|
|
117
|
+
headers: {
|
|
118
|
+
Authorization: `token ${token}`,
|
|
119
|
+
...(asset ? { Accept: "application/octet-stream" } : {}),
|
|
120
|
+
},
|
|
121
|
+
})
|
|
122
|
+
if (!res.ok) {
|
|
123
|
+
throw new Error(`Failed to fetch file ${name}: ${res.status} ${res.statusText} (${asset?.url ?? url})`)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const tmp = process.env.RUNNER_TEMP ?? "/tmp"
|
|
127
|
+
const file = path.join(tmp, name)
|
|
128
|
+
await Bun.write(file, await res.arrayBuffer())
|
|
129
|
+
await $`bunx @tauri-apps/cli signer sign ${file}`
|
|
130
|
+
const sigFile = Bun.file(`${file}.sig`)
|
|
131
|
+
if (!(await sigFile.exists())) throw new Error(`Signature file not found for ${name}`)
|
|
132
|
+
return (await sigFile.text()).trim()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const add = async (data: Record<string, { url: string; signature: string }>, key: string, raw: string | undefined) => {
|
|
136
|
+
if (!raw) return
|
|
137
|
+
if (data[key]) return
|
|
138
|
+
const url = link(raw)
|
|
139
|
+
data[key] = { url, signature: await sign(url, key) }
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const alias = (data: Record<string, { url: string; signature: string }>, key: string, src: string) => {
|
|
143
|
+
if (data[key]) return
|
|
144
|
+
if (!data[src]) return
|
|
145
|
+
data[key] = data[src]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const winx = await read("latest-yml-x86_64-pc-windows-msvc", "latest.yml")
|
|
149
|
+
const wina = await read("latest-yml-aarch64-pc-windows-msvc", "latest.yml")
|
|
150
|
+
const macx = await read("latest-yml-x86_64-apple-darwin", "latest-mac.yml")
|
|
151
|
+
const maca = await read("latest-yml-aarch64-apple-darwin", "latest-mac.yml")
|
|
152
|
+
const linx = await read("latest-yml-x86_64-unknown-linux-gnu", "latest-linux.yml")
|
|
153
|
+
const lina = await read("latest-yml-aarch64-unknown-linux-gnu", "latest-linux-arm64.yml")
|
|
154
|
+
|
|
155
|
+
const yver = winx?.version ?? wina?.version ?? macx?.version ?? maca?.version ?? linx?.version ?? lina?.version
|
|
156
|
+
if (yver && yver !== version) throw new Error(`latest.yml version mismatch: expected ${version}, got ${yver}`)
|
|
157
|
+
|
|
158
|
+
const out: Record<string, { url: string; signature: string }> = {}
|
|
159
|
+
|
|
160
|
+
const winxexe = pick(winx?.files ?? [], [".exe"])
|
|
161
|
+
const winaexe = pick(wina?.files ?? [], [".exe"])
|
|
162
|
+
|
|
163
|
+
const macxTarGz = "opencode-desktop-mac-x64.app.tar.gz"
|
|
164
|
+
const macaTarGz = "opencode-desktop-mac-arm64.app.tar.gz"
|
|
165
|
+
|
|
166
|
+
const linxDeb = pick(linx?.files ?? [], [".deb"])
|
|
167
|
+
const linxRpm = pick(linx?.files ?? [], [".rpm"])
|
|
168
|
+
const linxAppImage = pick(linx?.files ?? [], [".appimage"])
|
|
169
|
+
const linaDeb = pick(lina?.files ?? [], [".deb"])
|
|
170
|
+
const linaRpm = pick(lina?.files ?? [], [".rpm"])
|
|
171
|
+
const linaAppImage = pick(lina?.files ?? [], [".appimage"])
|
|
172
|
+
|
|
173
|
+
await add(out, "windows-x86_64-nsis", winxexe)
|
|
174
|
+
await add(out, "windows-aarch64-nsis", winaexe)
|
|
175
|
+
await add(out, "darwin-x86_64-app", macxTarGz)
|
|
176
|
+
await add(out, "darwin-aarch64-app", macaTarGz)
|
|
177
|
+
|
|
178
|
+
await add(out, "linux-x86_64-deb", linxDeb)
|
|
179
|
+
await add(out, "linux-x86_64-rpm", linxRpm)
|
|
180
|
+
await add(out, "linux-x86_64-appimage", linxAppImage)
|
|
181
|
+
await add(out, "linux-aarch64-deb", linaDeb)
|
|
182
|
+
await add(out, "linux-aarch64-rpm", linaRpm)
|
|
183
|
+
await add(out, "linux-aarch64-appimage", linaAppImage)
|
|
184
|
+
|
|
185
|
+
alias(out, "windows-x86_64", "windows-x86_64-nsis")
|
|
186
|
+
alias(out, "windows-aarch64", "windows-aarch64-nsis")
|
|
187
|
+
alias(out, "darwin-x86_64", "darwin-x86_64-app")
|
|
188
|
+
alias(out, "darwin-aarch64", "darwin-aarch64-app")
|
|
189
|
+
alias(out, "linux-x86_64", "linux-x86_64-deb")
|
|
190
|
+
alias(out, "linux-aarch64", "linux-aarch64-deb")
|
|
191
|
+
|
|
192
|
+
const platforms = Object.fromEntries(
|
|
193
|
+
Object.keys(out)
|
|
194
|
+
.sort()
|
|
195
|
+
.map((key) => [key, out[key]]),
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
if (!Object.keys(platforms).length) throw new Error("No updater files found in latest.yml artifacts")
|
|
199
|
+
|
|
200
|
+
const data = {
|
|
201
|
+
version,
|
|
202
|
+
notes: "",
|
|
203
|
+
pub_date: new Date().toISOString(),
|
|
204
|
+
platforms,
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const tmp = process.env.RUNNER_TEMP ?? "/tmp"
|
|
208
|
+
const file = path.join(tmp, "latest.json")
|
|
209
|
+
await Bun.write(file, JSON.stringify(data, null, 2))
|
|
210
|
+
|
|
211
|
+
const tag = `v${version}`
|
|
212
|
+
|
|
213
|
+
if (dryRun) {
|
|
214
|
+
console.log(`dry-run: wrote latest.json for ${tag} to ${file}`)
|
|
215
|
+
process.exit(0)
|
|
216
|
+
}
|
|
217
|
+
await $`gh release upload ${tag} ${file} --clobber --repo ${repo}`
|
|
218
|
+
|
|
219
|
+
console.log(`finalized latest.json for ${tag}`)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { $ } from "bun"
|
|
4
|
+
import path from "path"
|
|
5
|
+
|
|
6
|
+
const dir = process.env.LATEST_YML_DIR!
|
|
7
|
+
if (!dir) throw new Error("LATEST_YML_DIR is required")
|
|
8
|
+
|
|
9
|
+
const repo = process.env.GH_REPO
|
|
10
|
+
if (!repo) throw new Error("GH_REPO is required")
|
|
11
|
+
|
|
12
|
+
const version = process.env.OPENCODE_VERSION
|
|
13
|
+
if (!version) throw new Error("OPENCODE_VERSION is required")
|
|
14
|
+
|
|
15
|
+
type FileEntry = {
|
|
16
|
+
url: string
|
|
17
|
+
sha512: string
|
|
18
|
+
size: number
|
|
19
|
+
blockMapSize?: number
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type LatestYml = {
|
|
23
|
+
version: string
|
|
24
|
+
files: FileEntry[]
|
|
25
|
+
releaseDate: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function parse(content: string): LatestYml {
|
|
29
|
+
const lines = content.split("\n")
|
|
30
|
+
let version = ""
|
|
31
|
+
let releaseDate = ""
|
|
32
|
+
const files: FileEntry[] = []
|
|
33
|
+
let current: Partial<FileEntry> | undefined
|
|
34
|
+
|
|
35
|
+
const flush = () => {
|
|
36
|
+
if (current?.url && current.sha512 && current.size) files.push(current as FileEntry)
|
|
37
|
+
current = undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (const line of lines) {
|
|
41
|
+
const indented = line.startsWith(" ") || line.startsWith(" -")
|
|
42
|
+
if (line.startsWith("version:")) version = line.slice("version:".length).trim()
|
|
43
|
+
else if (line.startsWith("releaseDate:"))
|
|
44
|
+
releaseDate = line.slice("releaseDate:".length).trim().replace(/^'|'$/g, "")
|
|
45
|
+
else if (line.trim().startsWith("- url:")) {
|
|
46
|
+
flush()
|
|
47
|
+
current = { url: line.trim().slice("- url:".length).trim() }
|
|
48
|
+
} else if (indented && current && line.trim().startsWith("sha512:"))
|
|
49
|
+
current.sha512 = line.trim().slice("sha512:".length).trim()
|
|
50
|
+
else if (indented && current && line.trim().startsWith("size:"))
|
|
51
|
+
current.size = Number(line.trim().slice("size:".length).trim())
|
|
52
|
+
else if (indented && current && line.trim().startsWith("blockMapSize:"))
|
|
53
|
+
current.blockMapSize = Number(line.trim().slice("blockMapSize:".length).trim())
|
|
54
|
+
else if (!indented && current) flush()
|
|
55
|
+
}
|
|
56
|
+
flush()
|
|
57
|
+
|
|
58
|
+
return { version, files, releaseDate }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function serialize(data: LatestYml) {
|
|
62
|
+
const lines = [`version: ${data.version}`, "files:"]
|
|
63
|
+
for (const file of data.files) {
|
|
64
|
+
lines.push(` - url: ${file.url}`)
|
|
65
|
+
lines.push(` sha512: ${file.sha512}`)
|
|
66
|
+
lines.push(` size: ${file.size}`)
|
|
67
|
+
if (file.blockMapSize) lines.push(` blockMapSize: ${file.blockMapSize}`)
|
|
68
|
+
}
|
|
69
|
+
lines.push(`releaseDate: '${data.releaseDate}'`)
|
|
70
|
+
return lines.join("\n") + "\n"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function read(subdir: string, filename: string): Promise<LatestYml | undefined> {
|
|
74
|
+
const file = Bun.file(path.join(dir, subdir, filename))
|
|
75
|
+
if (!(await file.exists())) return undefined
|
|
76
|
+
return parse(await file.text())
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const output: Record<string, string> = {}
|
|
80
|
+
|
|
81
|
+
// Windows: merge arm64 + x64 into single file
|
|
82
|
+
const winX64 = await read("latest-yml-x86_64-pc-windows-msvc", "latest.yml")
|
|
83
|
+
const winArm64 = await read("latest-yml-aarch64-pc-windows-msvc", "latest.yml")
|
|
84
|
+
if (winX64 || winArm64) {
|
|
85
|
+
const base = winArm64 ?? winX64!
|
|
86
|
+
output["latest.yml"] = serialize({
|
|
87
|
+
version: base.version,
|
|
88
|
+
files: [...(winArm64?.files ?? []), ...(winX64?.files ?? [])],
|
|
89
|
+
releaseDate: base.releaseDate,
|
|
90
|
+
})
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Linux x64: pass through
|
|
94
|
+
const linuxX64 = await read("latest-yml-x86_64-unknown-linux-gnu", "latest-linux.yml")
|
|
95
|
+
if (linuxX64) output["latest-linux.yml"] = serialize(linuxX64)
|
|
96
|
+
|
|
97
|
+
// Linux arm64: pass through
|
|
98
|
+
const linuxArm64 = await read("latest-yml-aarch64-unknown-linux-gnu", "latest-linux-arm64.yml")
|
|
99
|
+
if (linuxArm64) output["latest-linux-arm64.yml"] = serialize(linuxArm64)
|
|
100
|
+
|
|
101
|
+
// macOS: merge arm64 + x64 into single file
|
|
102
|
+
const macX64 = await read("latest-yml-x86_64-apple-darwin", "latest-mac.yml")
|
|
103
|
+
const macArm64 = await read("latest-yml-aarch64-apple-darwin", "latest-mac.yml")
|
|
104
|
+
if (macX64 || macArm64) {
|
|
105
|
+
const base = macArm64 ?? macX64!
|
|
106
|
+
output["latest-mac.yml"] = serialize({
|
|
107
|
+
version: base.version,
|
|
108
|
+
files: [...(macArm64?.files ?? []), ...(macX64?.files ?? [])],
|
|
109
|
+
releaseDate: base.releaseDate,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Upload to release
|
|
114
|
+
const tag = `v${version}`
|
|
115
|
+
const tmp = process.env.RUNNER_TEMP ?? "/tmp"
|
|
116
|
+
|
|
117
|
+
for (const [filename, content] of Object.entries(output)) {
|
|
118
|
+
const filepath = path.join(tmp, filename)
|
|
119
|
+
await Bun.write(filepath, content)
|
|
120
|
+
await $`gh release upload ${tag} ${filepath} --clobber --repo ${repo}`
|
|
121
|
+
console.log(`uploaded ${filename}`)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.log("finalized latest yml files")
|