(options)
| 303 | } |
| 304 | |
| 305 | export async function launchObsidianInstance(options) { |
| 306 | // Validate (and create when absent) the profile tree here too, so a future |
| 307 | // "relaunch existing instance" path that calls launch without the normal |
| 308 | // prepareObsidianProfile/main preflight cannot bypass the temp-squat guard. |
| 309 | // Parent-first: a loose profileRoot must not stay attacker-writable around |
| 310 | // the validated instance dir. |
| 311 | await ensureSecureDir(options.profileRoot); |
| 312 | await ensureSecureDir(options.instancePath); |
| 313 | await execFileAsync("/usr/bin/open", [ |
| 314 | "-n", |
| 315 | "-g", |
| 316 | "-a", |
| 317 | options.obsidianApp, |
| 318 | "--env", |
| 319 | `HOME=${options.obsidianHome}`, |
| 320 | "--args", |
| 321 | `--user-data-dir=${options.userDataPath}`, |
| 322 | "--password-store=basic", |
| 323 | ], { |
| 324 | env: obsidianEnv(options), |
| 325 | }); |
| 326 | |
| 327 | return { |
| 328 | pid: null, |
| 329 | pidPath: null, |
| 330 | }; |
| 331 | } |
| 332 | |
| 333 | function obsidianEnv(options) { |
| 334 | return { |
no test coverage detected