()
| 619 | } |
| 620 | |
| 621 | async function main() { |
| 622 | const rawOptions = parseArgs(process.argv.slice(2)); |
| 623 | if (rawOptions.help) { |
| 624 | printUsage(); |
| 625 | return; |
| 626 | } |
| 627 | |
| 628 | const options = resolveInstanceOptions(rawOptions); |
| 629 | // Validate the profile root we own before the reaper scans/removes anything in |
| 630 | // it, so a hijacked root aborts the run loudly instead of being trusted. |
| 631 | await ensureSecureDir(options.profileRoot); |
| 632 | await reapStaleInstances(options); |
| 633 | const provisionResult = await provisionVault(options); |
| 634 | const profileResult = await prepareObsidianProfile(options); |
| 635 | options.userDataPath = profileResult.userDataPath; |
| 636 | // Resolve and assert the Obsidian app-code version BEFORE launching: a build |
| 637 | // below minAppVersion makes every "missing API" failure a false signal, so fail |
| 638 | // loudly here rather than spawn a doomed sub-minimum instance (which would be |
| 639 | // left running for later reuse) and hit a confusing "QuickAdd did not become |
| 640 | // available" timeout. Filesystem-based, so it needs no running instance. |
| 641 | const compatibility = options.launch |
| 642 | ? await assertObsidianMeetsMinAppVersion(options) |
| 643 | : null; |
| 644 | const launchResult = options.launch |
| 645 | ? await launchObsidianInstance(options) |
| 646 | : { pid: null, pidPath: null }; |
| 647 | const resolvedVaultPath = options.launch |
| 648 | ? await waitForInstanceReady(options) |
| 649 | : null; |
| 650 | const verifiedQuickAdd = options.launch |
| 651 | ? await trustVaultAndVerifyQuickAdd(options) |
| 652 | : false; |
| 653 | const result = { |
| 654 | ...provisionResult, |
| 655 | ...profileResult, |
| 656 | ...launchResult, |
| 657 | ...(compatibility ?? {}), |
| 658 | obsidianHome: options.obsidianHome, |
| 659 | resolvedVaultPath, |
| 660 | verifiedQuickAdd, |
| 661 | }; |
| 662 | |
| 663 | if (rawOptions.json) { |
| 664 | console.log(JSON.stringify(result, null, 2)); |
| 665 | } else { |
| 666 | console.log(`Prepared Obsidian E2E instance ${result.vaultName}`); |
| 667 | console.log(`Vault path: ${result.vaultPath}`); |
| 668 | console.log(`Obsidian HOME: ${result.obsidianHome}`); |
| 669 | if (result.pid) console.log(`Obsidian PID: ${result.pid}`); |
| 670 | if (result.appVersion) { |
| 671 | const installer = result.installerVersion ? `, installer ${result.installerVersion}` : ""; |
| 672 | console.log( |
| 673 | `Obsidian app version: ${result.appVersion}${installer} (plugin minAppVersion ${result.minAppVersion})`, |
| 674 | ); |
| 675 | } |
| 676 | if (result.verifiedQuickAdd) console.log("QuickAdd command check: ok"); |
| 677 | } |
| 678 |
no test coverage detected