saeeol 1.4.4 → 1.4.5
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/desktop.js +142 -0
- package/package.json +9 -4
package/desktop.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// saeeol desktop — launches saeeol web server + Electron window
|
|
4
|
+
const { existsSync, realpathSync } = require("fs")
|
|
5
|
+
const { join, dirname } = require("path")
|
|
6
|
+
const { spawn } = require("child_process")
|
|
7
|
+
|
|
8
|
+
function getBinaryName() {
|
|
9
|
+
const archMap = { x64: "x64", arm64: "arm64" }
|
|
10
|
+
const platformMap = { win32: "windows", darwin: "darwin", linux: "linux" }
|
|
11
|
+
const p = platformMap[process.platform] || process.platform
|
|
12
|
+
const a = archMap[process.arch] || process.arch
|
|
13
|
+
return `saeeol-${p}-${a}`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function findBinary() {
|
|
17
|
+
const binaryName = getBinaryName()
|
|
18
|
+
const binaryRel = process.platform === "win32" ? "bin/saeeol.exe" : "bin/saeeol"
|
|
19
|
+
const scriptDir = dirname(realpathSync(__filename))
|
|
20
|
+
|
|
21
|
+
// 1. node_modules of this package
|
|
22
|
+
const local = join(scriptDir, "node_modules", binaryName, binaryRel)
|
|
23
|
+
if (existsSync(local)) return local
|
|
24
|
+
|
|
25
|
+
// 2. Walk up
|
|
26
|
+
let current = scriptDir
|
|
27
|
+
for (let i = 0; i < 10; i++) {
|
|
28
|
+
const candidate = join(current, "node_modules", binaryName, binaryRel)
|
|
29
|
+
if (existsSync(candidate)) return candidate
|
|
30
|
+
const parent = dirname(current)
|
|
31
|
+
if (parent === current) break
|
|
32
|
+
current = parent
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 3. Download dir
|
|
36
|
+
const dl = join(scriptDir, "download", process.platform === "win32" ? `${binaryName}.exe` : "saeeol")
|
|
37
|
+
if (existsSync(dl)) return dl
|
|
38
|
+
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function findElectron() {
|
|
43
|
+
const scriptDir = dirname(realpathSync(__filename))
|
|
44
|
+
const electronPath = join(scriptDir, "node_modules", "electron", "dist", process.platform === "win32" ? "electron.exe" : "electron")
|
|
45
|
+
if (existsSync(electronPath)) return electronPath
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function main() {
|
|
50
|
+
const binaryPath = findBinary()
|
|
51
|
+
if (!binaryPath) {
|
|
52
|
+
console.error(`saeeol binary not found (${getBinaryName()})`)
|
|
53
|
+
console.error(`Run: npm install saeeol`)
|
|
54
|
+
process.exit(1)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const electronPath = findElectron()
|
|
58
|
+
|
|
59
|
+
// If no electron, fall back to CLI mode
|
|
60
|
+
if (!electronPath) {
|
|
61
|
+
console.log("Electron not found. Install with: npm install -g saeeol")
|
|
62
|
+
console.log("Starting in terminal mode...\n")
|
|
63
|
+
const child = spawn(binaryPath, process.argv.slice(2), {
|
|
64
|
+
stdio: "inherit",
|
|
65
|
+
env: { ...process.env },
|
|
66
|
+
windowsHide: false,
|
|
67
|
+
})
|
|
68
|
+
child.on("exit", (code) => process.exit(code || 0))
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Find free port
|
|
73
|
+
const port = 30000 + Math.floor(Math.random() * 10000)
|
|
74
|
+
|
|
75
|
+
console.log(`Starting saeeol server on port ${port}...`)
|
|
76
|
+
|
|
77
|
+
// Start saeeol web in background
|
|
78
|
+
const server = spawn(binaryPath, ["web", "--port", String(port), "--hostname", "127.0.0.1"], {
|
|
79
|
+
stdio: "pipe",
|
|
80
|
+
env: { ...process.env },
|
|
81
|
+
windowsHide: true,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
server.stdout.on("data", (data) => {
|
|
85
|
+
const msg = data.toString().trim()
|
|
86
|
+
if (msg) console.log(`[server] ${msg}`)
|
|
87
|
+
})
|
|
88
|
+
server.stderr.on("data", (data) => {
|
|
89
|
+
const msg = data.toString().trim()
|
|
90
|
+
if (msg) console.error(`[server] ${msg}`)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Create a minimal Electron app that loads the saeeol web URL
|
|
94
|
+
const electronApp = join(__dirname, "desktop-app.js")
|
|
95
|
+
const desktopAppCode = `
|
|
96
|
+
const { app, BrowserWindow } = require("electron")
|
|
97
|
+
const url = "http://127.0.0.1:${port}"
|
|
98
|
+
|
|
99
|
+
function createWindow() {
|
|
100
|
+
const win = new BrowserWindow({
|
|
101
|
+
width: 1400,
|
|
102
|
+
height: 900,
|
|
103
|
+
minWidth: 800,
|
|
104
|
+
minHeight: 600,
|
|
105
|
+
title: "파불리스트 — FABULIST",
|
|
106
|
+
autoHideMenuBar: true,
|
|
107
|
+
webPreferences: { nodeIntegration: false, contextIsolation: true },
|
|
108
|
+
})
|
|
109
|
+
win.loadURL(url)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
app.whenReady().then(createWindow)
|
|
113
|
+
app.on("window-all-closed", () => {
|
|
114
|
+
app.quit()
|
|
115
|
+
process.kill(${server.pid})
|
|
116
|
+
process.exit(0)
|
|
117
|
+
})
|
|
118
|
+
`
|
|
119
|
+
require("fs").writeFileSync(electronApp, desktopAppCode)
|
|
120
|
+
|
|
121
|
+
// Wait a bit for server to start
|
|
122
|
+
await new Promise((r) => setTimeout(r, 3000))
|
|
123
|
+
|
|
124
|
+
console.log("Opening FABULIST desktop...")
|
|
125
|
+
|
|
126
|
+
const electron = spawn(electronPath, [electronApp], {
|
|
127
|
+
stdio: "inherit",
|
|
128
|
+
env: { ...process.env },
|
|
129
|
+
windowsHide: false,
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
electron.on("exit", (code) => {
|
|
133
|
+
server.kill()
|
|
134
|
+
try { require("fs").unlinkSync(electronApp) } catch {}
|
|
135
|
+
process.exit(code || 0)
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
main().catch((err) => {
|
|
140
|
+
console.error(err.message)
|
|
141
|
+
process.exit(1)
|
|
142
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "saeeol",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "AI agent engine for SAEEOL",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
"url": "https://github.com/byfabulist/fabulist"
|
|
9
9
|
},
|
|
10
10
|
"bin": {
|
|
11
|
-
"saeeol": "cli.js"
|
|
11
|
+
"saeeol": "cli.js",
|
|
12
|
+
"fabulist": "desktop.js"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"cli.js",
|
|
16
|
+
"desktop.js",
|
|
15
17
|
"postinstall.js"
|
|
16
18
|
],
|
|
17
19
|
"scripts": {
|
|
@@ -29,7 +31,8 @@
|
|
|
29
31
|
"saeeol-linux-arm64-musl": "1.4.3",
|
|
30
32
|
"saeeol-linux-x64-musl": "1.4.3",
|
|
31
33
|
"saeeol-linux-x64-musl-baseline": "1.4.3",
|
|
32
|
-
"saeeol-win32-arm64": "1.4.3"
|
|
34
|
+
"saeeol-win32-arm64": "1.4.3",
|
|
35
|
+
"electron": "^35.2.1"
|
|
33
36
|
},
|
|
34
37
|
"publishConfig": {
|
|
35
38
|
"access": "public",
|
|
@@ -44,6 +47,8 @@
|
|
|
44
47
|
"cli",
|
|
45
48
|
"coding",
|
|
46
49
|
"assistant",
|
|
47
|
-
"saeeol"
|
|
50
|
+
"saeeol",
|
|
51
|
+
"fabulist",
|
|
52
|
+
"desktop"
|
|
48
53
|
]
|
|
49
54
|
}
|