返回 DeepSeek-Reasonix
main.go
根目录 / desktop / main.go
1 // Command reasonix-desktop is the Reasonix desktop service: the Go-side
2 // control.Controller and platform integrations, driven by the Electron shell
3 // over the desktop host protocol (--host-rpc on stdin/stdout). A plain launch
4 // bootstraps the Electron shell installed beside this binary (app/) and exits;
5 // the shell then restarts this binary as its --host-rpc service. It lives in a
6 // nested module (reasonix/desktop) so the desktop build never touches the
7 // CLI's CGO_ENABLED=0 single-static-binary guarantee, while still importing
8 // the same internal/* kernel.
9 package main
10
11 import (
12 "fmt"
13 "os"
14 "strings"
15
16 "reasonix/internal/skill/skillwatch"
17 "reasonix/internal/winaclresidue"
18
19 // Blank imports wire compile-time built-ins into their registries, exactly as
20 // cmd/reasonix does — boot.Build resolves providers/tools from these registries.
21 _ "reasonix/internal/provider/anthropic"
22 _ "reasonix/internal/provider/openai"
23 _ "reasonix/internal/provider/responses"
24 _ "reasonix/internal/tool/builtin"
25 )
26
27 // version is injected at build time via `-ldflags "-X main.version=..."`,
28 // mirroring cmd/reasonix/main.go. The auto-updater reads it (App.Version) to compare
29 // against the published manifest; an un-injected dev build stays "dev" and never
30 // prompts to update.
31 var version = "dev"
32
33 // channel records the build's release line, injected via
34 // `-X main.channel=preview`. Default "stable" tracks the public release;
35 // "preview" tracks the opt-in test line. Legacy "canary" builds are treated as
36 // preview for compatibility.
37 var channel = "stable"
38
39 // macSelfUpdate is injected as "true" only for Developer ID signed + notarized
40 // macOS release builds. Local/ad-hoc macOS builds keep the manual download path.
41 var macSelfUpdate = "false"
42
43 func macSelfUpdateAllowed() bool {
44 switch strings.ToLower(strings.TrimSpace(macSelfUpdate)) {
45 case "1", "true", "yes", "on":
46 return true
47 default:
48 return false
49 }
50 }
51
52 func main() {
53 // Contract generation is a build-time operation. Dispatch it before crash
54 // capture so packaging cannot create files in the operator's Reasonix home.
55 if dir, ok := emitContractDir(os.Args[1:]); ok {
56 os.Exit(runEmitContract(dir))
57 }
58 // Internal watcher-helper entry: the host-shared skill watch service
59 // re-enters this executable so Windows directory watching never runs
60 // in-process. Dispatch before any application initialization.
61 if skillwatch.MaybeRunHelper() {
62 return
63 }
64 // Older Windows builds could leave sandbox ACL residue behind after a
65 // crash; sweep it in the background so startup never waits on icacls.
66 go winaclresidue.SweepStaleMarkers()
67 // The detached macOS self-update child must run before any shell starts.
68 if handled, exitCode := maybeRunMacUpdateHandoff(os.Args[1:]); handled {
69 os.Exit(exitCode)
70 }
71 capturePreviousFatalCrash()
72 installFatalCrashOutput()
73 exitIfHostLaunchMode(os.Args[1:])
74 if maybeRelaunchIfSuperseded() {
75 return
76 }
77 exitIfShellBootstrapped(os.Args[1:])
78
79 fmt.Fprintln(os.Stderr, "reasonix-desktop: no Electron desktop shell (app/) is installed beside this binary; reinstall Reasonix or run the packaged desktop app")
80 os.Exit(1)
81 }
82
82 lines GO