diff --git a/cli/src/checks/service-health-check.ts b/cli/src/checks/service-health-check.ts index aa84ad6e6ae..b8fa905e9b7 100644 --- a/cli/src/checks/service-health-check.ts +++ b/cli/src/checks/service-health-check.ts @@ -100,7 +100,10 @@ export async function serviceHealthChecks( }, ); - const expectedVersion = readInstallManifest()?.version ?? null; + let expectedVersion: string | null = null; + try { + expectedVersion = readInstallManifest()?.version ?? null; + } catch {} results.push( !health.ok ? { diff --git a/cli/src/onboard-service.ts b/cli/src/onboard-service.ts index 476d599a946..50cc8e052f6 100644 --- a/cli/src/onboard-service.ts +++ b/cli/src/onboard-service.ts @@ -14,6 +14,7 @@ export type OnboardServiceOptions = { type OnboardServiceDependencies = { detect: (instanceId: string) => Promise; confirm: () => Promise; + confirmLinger: () => Promise; isInteractive: () => boolean; info: (message: string) => void; success: (message: string) => void; @@ -29,6 +30,13 @@ const defaultDependencies: OnboardServiceDependencies = { }); return !p.isCancel(answer) && answer === true; }, + confirmLinger: async () => { + const answer = await p.confirm({ + message: "Allow Paperclip to keep running after logout? This may request system authorization.", + initialValue: false, + }); + return !p.isCancel(answer) && answer === true; + }, isInteractive: () => process.stdin.isTTY === true && process.stdout.isTTY === true, info: (message) => p.log.message(pc.dim(message)), success: (message) => p.log.success(message), @@ -61,6 +69,9 @@ export async function handleOnboardService( if (!explicitlyRequested && !(await deps.confirm())) return false; await detection.manager.install({ startNow: true, startOnLogin: true }); + if (!explicitlyRequested && detection.manager.enableLinger && await deps.confirmLinger()) { + await detection.manager.enableLinger(); + } deps.success(`Installed and started ${detection.manager.serviceName}.`); return true; } diff --git a/doc/INSTALLING.md b/doc/INSTALLING.md index ff24052ed7e..216940a8794 100644 --- a/doc/INSTALLING.md +++ b/doc/INSTALLING.md @@ -32,7 +32,8 @@ If the vanity installer endpoint is unavailable, fetch the same release-controlled source from GitHub raw content: ```sh -curl -fsSL https://raw.githubusercontent.com/paperclipai/paperclip/master/scripts/install.sh | bash +raw_base=https://raw.githubusercontent.com/paperclipai/paperclip +curl -fsSL "$raw_base/master/scripts/install.sh" | bash ``` For audits or incident response, pin the raw URL to a release tag or commit @@ -40,7 +41,7 @@ SHA instead of `master`, download it first, and compare it with the published checksum at `https://paperclip.ing/install.sh.sha256`. Each installer flag also has a `PAPERCLIP_INSTALL_*` environment-variable -equivalent for environments where passing arguments through a pipe is awkward. +equivalent. This helps where passing arguments through a pipe is awkward. ## Managed Install Layout diff --git a/scripts/clean-install-npm.sh b/scripts/clean-install-npm.sh index 831b5d1d378..73fa082c538 100755 --- a/scripts/clean-install-npm.sh +++ b/scripts/clean-install-npm.sh @@ -1,6 +1,9 @@ #!/bin/bash set -euo pipefail +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +PC_INSTALL_DRIVER="${PC_INSTALL_DRIVER:-source}" + PC_TEST_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/paperclip-clean-install.XXXXXX")" PC_HOME="$PC_TEST_ROOT/home" PC_CACHE="$PC_TEST_ROOT/npm-cache" @@ -13,8 +16,11 @@ export npm_config_cache="$PC_CACHE" export npm_config_userconfig="$PC_HOME/.npmrc" export PATH="$PC_HOME/.local/bin:$PATH" -cd "$PC_TEST_ROOT" -npx --yes --registry https://registry.npmjs.org paperclipai install +if [ "$PC_INSTALL_DRIVER" = "published" ]; then + (cd "$PC_TEST_ROOT" && npx --yes --registry https://registry.npmjs.org paperclipai install) +else + (cd "$REPO_ROOT" && pnpm paperclipai install --yes) +fi test -x "$PC_HOME/.local/bin/paperclipai" test -L "$PAPERCLIP_HOME/cli/current" @@ -23,7 +29,7 @@ paperclipai --version mkdir -p "$PAPERCLIP_HOME/instances/default" touch "$PAPERCLIP_HOME/instances/default/user-data-marker" -paperclipai uninstall +(cd "$REPO_ROOT" && pnpm paperclipai uninstall) test ! -e "$PAPERCLIP_HOME/cli" test ! -e "$PC_HOME/.local/bin/paperclipai"