@geravant/sinain 1.6.2 → 1.6.4
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/launcher.js +36 -2
- package/package.json +1 -1
- package/sense_client/requirements.txt +1 -0
- package/setup-overlay.js +39 -20
package/launcher.js
CHANGED
|
@@ -129,7 +129,7 @@ async function main() {
|
|
|
129
129
|
try {
|
|
130
130
|
const depCheck = IS_WINDOWS
|
|
131
131
|
? 'python3 -c "import PIL; import skimage"'
|
|
132
|
-
: 'python3 -c "import PIL; import skimage; import Quartz"';
|
|
132
|
+
: 'python3 -c "import PIL; import skimage; import Quartz; import Vision"';
|
|
133
133
|
execSync(depCheck, { stdio: "pipe" });
|
|
134
134
|
} catch {
|
|
135
135
|
log("Installing sense_client Python dependencies...");
|
|
@@ -216,7 +216,41 @@ async function main() {
|
|
|
216
216
|
warn("flutter not found — overlay source found but can't build");
|
|
217
217
|
}
|
|
218
218
|
} else {
|
|
219
|
-
|
|
219
|
+
// Auto-download overlay if not found
|
|
220
|
+
log("overlay not found — downloading from GitHub Releases...");
|
|
221
|
+
try {
|
|
222
|
+
const { downloadOverlay } = await import("./setup-overlay.js");
|
|
223
|
+
const success = await downloadOverlay({ silent: false });
|
|
224
|
+
if (success) {
|
|
225
|
+
// Re-find and launch the freshly downloaded overlay
|
|
226
|
+
const freshOverlay = findOverlay();
|
|
227
|
+
if (freshOverlay?.type === "prebuilt") {
|
|
228
|
+
if (!IS_WINDOWS) {
|
|
229
|
+
try {
|
|
230
|
+
execSync(`xattr -cr "${freshOverlay.path}"`, { stdio: "pipe" });
|
|
231
|
+
} catch { /* no quarantine */ }
|
|
232
|
+
}
|
|
233
|
+
log("Starting overlay (pre-built)...");
|
|
234
|
+
const binary = IS_WINDOWS
|
|
235
|
+
? freshOverlay.path
|
|
236
|
+
: path.join(freshOverlay.path, "Contents/MacOS/sinain_hud");
|
|
237
|
+
startProcess("overlay", binary, [], { color: MAGENTA });
|
|
238
|
+
await sleep(2000);
|
|
239
|
+
const overlayChild = children.find(c => c.name === "overlay");
|
|
240
|
+
if (overlayChild && !overlayChild.proc.killed && overlayChild.proc.exitCode === null) {
|
|
241
|
+
ok(`overlay running (pid:${overlayChild.pid})`);
|
|
242
|
+
overlayStatus = "running";
|
|
243
|
+
} else {
|
|
244
|
+
warn("overlay exited early — check logs above");
|
|
245
|
+
overlayStatus = "failed";
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
warn("overlay auto-download failed — run: sinain setup-overlay");
|
|
250
|
+
}
|
|
251
|
+
} catch (e) {
|
|
252
|
+
warn(`overlay auto-download failed: ${e.message}`);
|
|
253
|
+
}
|
|
220
254
|
}
|
|
221
255
|
}
|
|
222
256
|
|
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ numpy>=1.24
|
|
|
4
4
|
pytesseract>=0.3
|
|
5
5
|
requests>=2.31
|
|
6
6
|
pyobjc-framework-Quartz>=10.0; sys_platform == "darwin"
|
|
7
|
+
pyobjc-framework-Vision>=10.0; sys_platform == "darwin"
|
|
7
8
|
mss>=9.0; sys_platform == "win32"
|
|
8
9
|
psutil>=5.9; sys_platform == "win32"
|
|
9
10
|
winrt-Windows.Media.Ocr>=2.0; sys_platform == "win32"
|
package/setup-overlay.js
CHANGED
|
@@ -37,25 +37,36 @@ function ok(msg) { console.log(`${BOLD}[setup-overlay]${RESET} ${GREEN}✓${RE
|
|
|
37
37
|
function warn(msg) { console.log(`${BOLD}[setup-overlay]${RESET} ${YELLOW}⚠${RESET} ${msg}`); }
|
|
38
38
|
function fail(msg) { console.error(`${BOLD}[setup-overlay]${RESET} ${RED}✗${RESET} ${msg}`); process.exit(1); }
|
|
39
39
|
|
|
40
|
-
// ──
|
|
40
|
+
// ── Entry point (only when run directly, not when imported) ──────────────────
|
|
41
41
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const isMain = process.argv[1] && (
|
|
43
|
+
import.meta.url === `file://${process.argv[1]}` ||
|
|
44
|
+
import.meta.url === new URL(process.argv[1], "file://").href
|
|
45
|
+
);
|
|
45
46
|
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (isMain) {
|
|
48
|
+
const args = process.argv.slice(2);
|
|
49
|
+
const fromSource = args.includes("--from-source");
|
|
50
|
+
const forceUpdate = args.includes("--update");
|
|
51
|
+
|
|
52
|
+
if (fromSource) {
|
|
53
|
+
await buildFromSource();
|
|
54
|
+
} else {
|
|
55
|
+
await downloadOverlay({ forceUpdate });
|
|
56
|
+
}
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
// ── Download pre-built .app ──────────────────────────────────────────────────
|
|
53
60
|
|
|
54
|
-
async function
|
|
61
|
+
export async function downloadOverlay({ silent = false, forceUpdate = false } = {}) {
|
|
62
|
+
const _log = silent ? () => {} : log;
|
|
63
|
+
const _ok = silent ? () => {} : ok;
|
|
64
|
+
const _warn = silent ? () => {} : warn;
|
|
65
|
+
|
|
55
66
|
fs.mkdirSync(APP_DIR, { recursive: true });
|
|
56
67
|
|
|
57
68
|
// Find latest overlay release
|
|
58
|
-
|
|
69
|
+
_log("Checking for latest overlay release...");
|
|
59
70
|
let release;
|
|
60
71
|
try {
|
|
61
72
|
const res = await fetch(`${RELEASES_API}?per_page=20`, {
|
|
@@ -67,6 +78,7 @@ async function downloadPrebuilt() {
|
|
|
67
78
|
release = releases.find(r => r.tag_name?.startsWith("overlay-v"));
|
|
68
79
|
if (!release) throw new Error("No overlay release found");
|
|
69
80
|
} catch (e) {
|
|
81
|
+
if (silent) return false;
|
|
70
82
|
fail(`Failed to fetch releases: ${e.message}\n Try: sinain setup-overlay --from-source`);
|
|
71
83
|
}
|
|
72
84
|
|
|
@@ -78,21 +90,22 @@ async function downloadPrebuilt() {
|
|
|
78
90
|
try {
|
|
79
91
|
const local = JSON.parse(fs.readFileSync(VERSION_FILE, "utf-8"));
|
|
80
92
|
if (local.tag === tag) {
|
|
81
|
-
|
|
82
|
-
return;
|
|
93
|
+
_ok(`Overlay already up-to-date (${version})`);
|
|
94
|
+
return true;
|
|
83
95
|
}
|
|
84
|
-
|
|
96
|
+
_log(`Updating: ${local.tag} → ${tag}`);
|
|
85
97
|
} catch { /* corrupt version file — re-download */ }
|
|
86
98
|
}
|
|
87
99
|
|
|
88
100
|
// Find the .zip asset for this platform
|
|
89
101
|
const zipAsset = release.assets?.find(a => a.name === ASSET_NAME);
|
|
90
102
|
if (!zipAsset) {
|
|
103
|
+
if (silent) return false;
|
|
91
104
|
fail(`Release ${tag} has no ${ASSET_NAME} asset.\n Try: sinain setup-overlay --from-source`);
|
|
92
105
|
}
|
|
93
106
|
|
|
94
107
|
// Download with progress
|
|
95
|
-
|
|
108
|
+
_log(`Downloading overlay ${version} for ${IS_WINDOWS ? "Windows" : "macOS"} (${formatBytes(zipAsset.size)})...`);
|
|
96
109
|
const zipPath = path.join(APP_DIR, ASSET_NAME);
|
|
97
110
|
|
|
98
111
|
try {
|
|
@@ -112,17 +125,18 @@ async function downloadPrebuilt() {
|
|
|
112
125
|
if (done) break;
|
|
113
126
|
chunks.push(value);
|
|
114
127
|
downloaded += value.length;
|
|
115
|
-
if (total > 0) {
|
|
128
|
+
if (total > 0 && !silent) {
|
|
116
129
|
const pct = Math.round((downloaded / total) * 100);
|
|
117
130
|
process.stdout.write(`\r${BOLD}[setup-overlay]${RESET} ${DIM}${pct}% (${formatBytes(downloaded)} / ${formatBytes(total)})${RESET}`);
|
|
118
131
|
}
|
|
119
132
|
}
|
|
120
|
-
process.stdout.write("\n");
|
|
133
|
+
if (!silent) process.stdout.write("\n");
|
|
121
134
|
|
|
122
135
|
const buffer = Buffer.concat(chunks);
|
|
123
136
|
fs.writeFileSync(zipPath, buffer);
|
|
124
|
-
|
|
137
|
+
_ok(`Downloaded ${formatBytes(buffer.length)}`);
|
|
125
138
|
} catch (e) {
|
|
139
|
+
if (silent) return false;
|
|
126
140
|
fail(`Download failed: ${e.message}`);
|
|
127
141
|
}
|
|
128
142
|
|
|
@@ -132,7 +146,7 @@ async function downloadPrebuilt() {
|
|
|
132
146
|
}
|
|
133
147
|
|
|
134
148
|
// Extract
|
|
135
|
-
|
|
149
|
+
_log("Extracting...");
|
|
136
150
|
if (IS_WINDOWS) {
|
|
137
151
|
try {
|
|
138
152
|
execSync(
|
|
@@ -140,6 +154,7 @@ async function downloadPrebuilt() {
|
|
|
140
154
|
{ stdio: "pipe" }
|
|
141
155
|
);
|
|
142
156
|
} catch (e) {
|
|
157
|
+
if (silent) return false;
|
|
143
158
|
fail(`Extraction failed: ${e.message}`);
|
|
144
159
|
}
|
|
145
160
|
} else {
|
|
@@ -150,6 +165,7 @@ async function downloadPrebuilt() {
|
|
|
150
165
|
try {
|
|
151
166
|
execSync(`unzip -o -q "${zipPath}" -d "${APP_DIR}"`, { stdio: "pipe" });
|
|
152
167
|
} catch (e) {
|
|
168
|
+
if (silent) return false;
|
|
153
169
|
fail(`Extraction failed: ${e.message}`);
|
|
154
170
|
}
|
|
155
171
|
}
|
|
@@ -170,12 +186,15 @@ async function downloadPrebuilt() {
|
|
|
170
186
|
// Clean up zip
|
|
171
187
|
fs.unlinkSync(zipPath);
|
|
172
188
|
|
|
173
|
-
|
|
174
|
-
|
|
189
|
+
_ok(`Overlay ${version} installed`);
|
|
190
|
+
if (!silent) {
|
|
191
|
+
console.log(`
|
|
175
192
|
${GREEN}✓${RESET} Overlay ready!
|
|
176
193
|
Location: ${APP_PATH}
|
|
177
194
|
The overlay will auto-start with: ${BOLD}sinain start${RESET}
|
|
178
195
|
`);
|
|
196
|
+
}
|
|
197
|
+
return true;
|
|
179
198
|
}
|
|
180
199
|
|
|
181
200
|
// ── Build from source (legacy) ───────────────────────────────────────────────
|