mirror of
https://github.com/aipoch/open-science.git
synced 2026-10-02 02:14:40 +08:00
* feat(cli): install a terminal launcher for the packaged app and fix daemon follow-ups Terminal launch after install: - Add a "Command line tool" action (Settings -> General) that installs an `open-science` launcher into the user's PATH (~/.local/bin on macOS/Linux; a per-user bin added to the user PATH on Windows) with no elevation. - The shim runs the bundled CLI via the app's own Electron in Node mode (ELECTRON_RUN_AS_NODE), so no separate Node install is needed. - Ship cli/*.mjs as extraResources (outside the asar) so the launcher can reach them; new src/main/cli-install launcher + IPC, preload `cli` bridge, and web API map entry. Document the flow in the README. #206 review follow-ups: - stop: force-kill the whole process group with SIGKILL on POSIX (the daemon is detached) and verify the process actually died before removing state / reporting "stopped", instead of re-sending the ignored SIGTERM to the lone leader. - tray: restore single-click-to-show on Windows (was double-click only) while keeping the right-click menu and headless menu-visibility fix. - Strip ELECTRON_RUN_AS_NODE from the daemon spawn so the launched app starts as the GUI, not another Node process. - locate-app: add ~/Applications on macOS; guard the package.json read when run from packaged resources; explicit flag->key parsing map. - Tests: locate-app, isProcessAlive, cli/app constant-parity guard, launcher. * fix(cli): reliable Windows PATH install, gate tray workaround to headless, cover lifecycle Address PR review: - P1: Windows PATH edit embedded the bin dir via `powershell -Command <script> -args <dir>`, which is unreliable — trailing `-args` can leave $args empty and write the wrong PATH. Build the script with the dir as a single-quoted PowerShell literal (quotes doubled) and drop -args. Derive the PATH separator from the target platform (not the host) so the on-PATH check is correct. Inject a command runner; add tests for the command build + install success/failure hint. - P2: extract an injectable `terminateDaemon` and thread a deps bag through the CLI commands so the lifecycle is testable without real processes/network. New cli/lifecycle.test.ts covers graceful stop, force-kill escalation, "still alive → don't delete state / don't print stopped", status (running/down/--json exit code), and url. - P3: gate the Windows tray right-click workaround to the headless case (electron#48982 is headless-only); the normal desktop app keeps the standard setContextMenu + single-click. Update the tray tests to assert both paths. - Standards: add cli-install IPC handler tests (delegation + error swallowing) and a GeneralPanel render test for the install/uninstall command flow. * fix(cli): single-quote POSIX launcher paths to fully escape shell metacharacters CodeQL js/incomplete-string-escaping: the POSIX shim double-quoted paths and escaped only `"`, leaving `\`, `$`, and backticks interpretable. Switch to single-quoting with the standard '\'' close-escape-reopen idiom, which safely quotes an arbitrary path (nothing is special inside single quotes). Add a metacharacter test covering space/$/backtick/backslash/quote.
16 lines
816 B
TypeScript
16 lines
816 B
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import { TOKEN_FILE as APP_TOKEN_FILE } from '../src/main/web-service/auth'
|
|
import { WEB_SERVICE_STATE_FILE } from '../src/main/web-service/state-file'
|
|
import { STATE_FILE, TOKEN_FILE } from './config-root.mjs'
|
|
|
|
// The CLI (a standalone .mjs, separate module system) can't import the app's TypeScript constants at
|
|
// runtime, so it re-declares the state/token filenames. This guard fails loudly if the app renames one
|
|
// side without the other, which would otherwise silently break `open-science status/stop/url`.
|
|
describe('CLI config-root constants stay in lockstep with the app', () => {
|
|
it('uses the same state and token filenames as the web service', () => {
|
|
expect(STATE_FILE).toBe(WEB_SERVICE_STATE_FILE)
|
|
expect(TOKEN_FILE).toBe(APP_TOKEN_FILE)
|
|
})
|
|
})
|