@greppleai/grip 0.1.3 → 0.1.5
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/CHANGELOG.md +52 -0
- package/README.md +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +3 -1
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/types.d.ts +5 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/grip-agent.d.ts.map +1 -1
- package/dist/core/grip-agent.js +4 -2
- package/dist/core/grip-agent.js.map +1 -1
- package/dist/core/sandbox/lima.d.ts.map +1 -1
- package/dist/core/sandbox/lima.js +6 -6
- package/dist/core/sandbox/lima.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +2 -3
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +2 -3
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +2 -3
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +3 -3
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +1 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +5 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -3
- package/dist/core/tools/write.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +18 -7
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/hook-execution.d.ts +3 -0
- package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/hook-execution.js +17 -0
- package/dist/modes/interactive/components/hook-execution.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +26 -18
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +220 -192
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +118 -8
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/grip-user-agent.d.ts.map +1 -1
- package/dist/utils/grip-user-agent.js +1 -1
- package/dist/utils/grip-user-agent.js.map +1 -1
- package/docs/extensions.md +3 -0
- package/docs/keybindings.md +3 -1
- package/docs/providers.md +3 -1
- package/docs/sandbox.md +1 -1
- package/docs/usage.md +37 -1
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lima.js","sourceRoot":"","sources":["../../../src/core/sandbox/lima.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport { realpath } from \"node:fs/promises\";\nimport { createConnection } from \"node:net\";\nimport { basename, resolve } from \"node:path\";\nimport { VERSION } from \"../../config.ts\";\nimport { DAEMON_WEBSOCKET_PATH } from \"../../daemon/config.ts\";\nimport { spawnProcess } from \"../../utils/child-process.ts\";\nimport { acquireSharedLimaOwnerLock, type SharedLimaOwnerLock } from \"../remote-workspace-protocol/lima-owner-lock.ts\";\nimport type { SettingsManager } from \"../settings-manager.ts\";\nimport type {\n\tSandboxCommandOptions,\n\tSandboxCommandResult,\n\tSandboxConfig,\n\tSandboxConfigOverrides,\n\tSandboxContainer,\n\tSandboxListOptions,\n\tSandboxRunner,\n\tSandboxStartOptions,\n\tSandboxStartResult,\n\tSandboxStopOptions,\n\tSandboxStopResult,\n} from \"./config.ts\";\nimport { allocateSandboxDaemonPort, redactSecrets, resolveSandboxConfig, SANDBOX_LABEL_PREFIX } from \"./config.ts\";\nimport { inspectLocalGuestBinary, installLocalGuestBinary, type LocalGuestBinary } from \"./lima-guest-binary.ts\";\nimport { resolveSharedLimaWorkspace, type SharedLimaWorkspaceBinding } from \"./shared-lima-roots.ts\";\nimport { stageSharedGuestBinary } from \"./update-shared-guest-binary.ts\";\nexport interface SharedLimaInstanceInspection extends SharedLimaWorkspaceBinding {\n\tinstanceName: string;\n\tdaemonUrl: string;\n}\n\nexport interface SharedLimaInstanceOptions {\n\tinstanceName: string;\n\thostParent: string;\n\thostRoot: string;\n}\n\nexport interface ManagedLimaInstance {\n\tworkspaceRoot: string;\n\tdaemonPort: number;\n\townerId?: string;\n\tmanaged: boolean;\n}\n\nexport interface LimaSandboxServiceOptions {\n\tsettingsManager?: Pick<SettingsManager, \"getSandboxSettings\">;\n\tenv?: NodeJS.ProcessEnv;\n\trunner?: SandboxRunner;\n\tportAllocator?: (host: string, preferredPort: number) => Promise<number>;\n\treadinessWaiter?: (host: string, port: number) => Promise<void>;\n\tmanagedInstances?: Map<string, ManagedLimaInstance>;\n}\n\ninterface LimaMount {\n\tlocation?: string;\n\tmountPoint?: string;\n\twritable?: boolean;\n}\n\ninterface LimaPortForward {\n\tguestPort?: number;\n\thostPort?: number;\n\thostIP?: string;\n}\n\ninterface LimaConfig {\n\tmounts?: LimaMount[];\n\tportForwards?: LimaPortForward[];\n}\n\ninterface LimaListRecord {\n\tname?: string;\n\tstatus?: string;\n\tarch?: string;\n\tvmType?: string;\n\tdir?: string;\n\tconfig?: LimaConfig;\n}\n\ninterface KnownLimaRecord {\n\trecord: LimaListRecord | undefined;\n}\n\nclass ProcessLimaRunner implements SandboxRunner {\n\trun(command: string, args: string[], options: SandboxCommandOptions = {}): Promise<SandboxCommandResult> {\n\t\treturn new Promise((resolveCommand, reject) => {\n\t\t\tconst child = spawnProcess(command, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\tenv: { ...process.env, ...options.env },\n\t\t\t});\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => {\n\t\t\t\tstdout += chunk.toString(\"utf8\");\n\t\t\t});\n\t\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => {\n\t\t\t\tstderr += chunk.toString(\"utf8\");\n\t\t\t});\n\t\t\tchild.once(\"error\", reject);\n\t\t\tchild.once(\"close\", (exitCode) => resolveCommand({ exitCode, stdout, stderr }));\n\t\t});\n\t}\n}\n\nfunction shellQuote(value: string): string {\n\treturn `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction parseLimaRecords(output: string): LimaListRecord[] {\n\tconst text = output.trim();\n\tif (!text) return [];\n\ttry {\n\t\tconst parsed = JSON.parse(text) as unknown;\n\t\treturn Array.isArray(parsed) ? (parsed as LimaListRecord[]) : [parsed as LimaListRecord];\n\t} catch {\n\t\treturn text\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.filter(Boolean)\n\t\t\t.map((line) => JSON.parse(line) as LimaListRecord);\n\t}\n}\n\nfunction ensureLimaSuccessful(binary: string, result: SandboxCommandResult, args: string[]): void {\n\tif (result.exitCode === 0) return;\n\tconst detail = result.stderr.trim() || result.stdout.trim() || `exit code ${result.exitCode ?? \"unknown\"}`;\n\tthrow new Error(redactSecrets(`Lima command failed: ${binary} ${args.join(\" \")}: ${detail}`));\n}\n\nfunction daemonConnectionHost(host: string): string {\n\tif (host === \"0.0.0.0\") return \"127.0.0.1\";\n\tif (host === \"::\") return \"::1\";\n\treturn host;\n}\n\nfunction urlHost(host: string): string {\n\treturn host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host;\n}\n\nasync function canConnect(host: string, port: number): Promise<boolean> {\n\treturn new Promise((resolveConnection) => {\n\t\tconst socket = createConnection({ host, port });\n\t\tlet settled = false;\n\t\tconst finish = (connected: boolean): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tsocket.destroy();\n\t\t\tresolveConnection(connected);\n\t\t};\n\t\tsocket.setTimeout(250, () => finish(false));\n\t\tsocket.once(\"connect\", () => finish(true));\n\t\tsocket.once(\"error\", () => finish(false));\n\t});\n}\n\nasync function waitForLimaDaemon(host: string, port: number): Promise<void> {\n\tconst deadline = Date.now() + 30_000;\n\twhile (Date.now() < deadline) {\n\t\tif (await canConnect(daemonConnectionHost(host), port)) return;\n\t\tawait new Promise((resolveDelay) => setTimeout(resolveDelay, 100));\n\t}\n\tthrow new Error(`Lima sandbox daemon did not become reachable on ${daemonConnectionHost(host)}:${port}`);\n}\n\nfunction createInstanceName(\n\tconfig: SandboxConfig,\n\tworkspaceRoot: string,\n\tsessionId: string,\n\tdaemonPort: number,\n): string {\n\tconst clean = (value: string): string =>\n\t\tvalue\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z0-9-]+/g, \"-\")\n\t\t\t.replace(/^-+|-+$/g, \"\") || \"workspace\";\n\tconst hash = createHash(\"sha256\").update(resolve(workspaceRoot)).digest(\"hex\").slice(0, 12);\n\treturn `${clean(config.limaInstanceNamePrefix)}-${clean(basename(resolve(workspaceRoot)))}-${hash}-${clean(sessionId).slice(0, 8).replace(/-+$/, \"\")}-p${daemonPort}-${randomBytes(4).toString(\"hex\")}`;\n}\n\nfunction findWorkspaceMount(record: LimaListRecord, workspaceMountPath: string): LimaMount | undefined {\n\treturn record.config?.mounts?.find((mount) => mount.mountPoint === workspaceMountPath);\n}\n\nfunction findDaemonForward(record: LimaListRecord, preferredPort?: number): LimaPortForward | undefined {\n\tconst namePort = Number(record.name?.match(/-p(\\d+)-[a-f0-9]+$/)?.[1]);\n\tconst daemonPort = Number.isInteger(namePort) && namePort > 0 ? namePort : preferredPort;\n\tconst forwards = record.config?.portForwards?.filter(\n\t\t(forward) => forward.guestPort === forward.hostPort && forward.hostPort !== undefined,\n\t);\n\treturn (\n\t\tforwards?.find((forward) => forward.guestPort === daemonPort) ??\n\t\t(forwards?.length === 1 ? forwards[0] : undefined)\n\t);\n}\n\nfunction toSandboxContainer(record: LimaListRecord, workspaceMountPath: string): SandboxContainer {\n\tconst mount = findWorkspaceMount(record, workspaceMountPath);\n\tconst forward = findDaemonForward(record);\n\tconst daemonEndpoint = forward?.hostPort\n\t\t? `ws://${urlHost(daemonConnectionHost(forward.hostIP || \"127.0.0.1\"))}:${forward.hostPort}${DAEMON_WEBSOCKET_PATH}`\n\t\t: undefined;\n\treturn {\n\t\tid: record.name ?? \"\",\n\t\tname: record.name ?? \"\",\n\t\timage: `lima:${record.vmType ?? \"vm\"}/${record.arch ?? \"unknown\"}`,\n\t\tstatus: record.status ?? \"\",\n\t\tstate: record.status?.toLowerCase(),\n\t\tcreatedAt: undefined,\n\t\tworkspaceRoot: mount?.location ? resolve(mount.location) : undefined,\n\t\tworkspaceMountPath: mount?.mountPoint,\n\t\tdaemonPort: forward?.guestPort,\n\t\tdaemonEndpoint,\n\t\tlabels: { [`${SANDBOX_LABEL_PREFIX}.runtime`]: \"lima\", [`${SANDBOX_LABEL_PREFIX}.version`]: VERSION },\n\t};\n}\n\nfunction selectLimaSandbox(instances: SandboxContainer[], target: string | undefined): SandboxContainer | undefined {\n\tif (!target) return instances.length === 1 ? instances[0] : undefined;\n\treturn instances.find((instance) => instance.name === target || instance.id.startsWith(target));\n}\ntype LegacyLimaGuestStateOperation = \"attach\" | \"stop\";\n\nexport class LimaSandboxService {\n\tprivate readonly settingsManager: Pick<SettingsManager, \"getSandboxSettings\"> | undefined;\n\tprivate readonly env: NodeJS.ProcessEnv;\n\tprivate readonly runner: SandboxRunner;\n\tprivate readonly portAllocator: (host: string, preferredPort: number) => Promise<number>;\n\tprivate readonly readinessWaiter: (host: string, port: number) => Promise<void>;\n\tprivate readonly managedInstances: Map<string, ManagedLimaInstance>;\n\n\tconstructor(options: LimaSandboxServiceOptions = {}) {\n\t\tthis.settingsManager = options.settingsManager;\n\t\tthis.env = options.env ?? process.env;\n\t\tthis.runner = options.runner ?? new ProcessLimaRunner();\n\t\tthis.portAllocator = options.portAllocator ?? allocateSandboxDaemonPort;\n\t\tthis.readinessWaiter = options.readinessWaiter ?? waitForLimaDaemon;\n\t\tthis.managedInstances = options.managedInstances ?? new Map();\n\t}\n\n\tresolveConfig(overrides: SandboxConfigOverrides = {}): SandboxConfig {\n\t\treturn resolveSandboxConfig(this.settingsManager?.getSandboxSettings(), this.env, overrides);\n\t}\n\n\tprivate async listRecords(config: SandboxConfig, name?: string): Promise<LimaListRecord[]> {\n\t\tconst args = [\"list\", \"--json\", ...(name ? [name] : [])];\n\t\ttry {\n\t\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\t\tif (\n\t\t\t\tname &&\n\t\t\t\tresult.exitCode !== 0 &&\n\t\t\t\t/unmatched|not found|does not exist/i.test(`${result.stderr}\\n${result.stdout}`)\n\t\t\t) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tensureLimaSuccessful(config.limaBinary, result, args);\n\t\t\treturn parseLimaRecords(result.stdout);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(redactSecrets(`Lima is unavailable or not reachable via ${config.limaBinary}: ${message}`));\n\t\t}\n\t}\n\n\t/** Read-only validation: no VM creation, daemon restart, token rotation or ownership claim. */\n\tasync inspectSharedInstance(options: SharedLimaInstanceOptions): Promise<SharedLimaInstanceInspection> {\n\t\tconst config = this.resolveConfig();\n\t\tconst { instanceName } = options;\n\t\tif (!/^[a-z0-9][a-z0-9-]*$/.test(instanceName)) throw new Error(\"Invalid shared Lima instance name\");\n\t\tif (config.daemonHostBind !== \"127.0.0.1\" && config.daemonHostBind !== \"::1\") {\n\t\t\tthrow new Error(\"Shared Lima daemon forward must bind to loopback\");\n\t\t}\n\t\tconst binding = await resolveSharedLimaWorkspace(options.hostParent, config.workspaceMountPath, options.hostRoot);\n\t\tconst records = await this.listRecords(config, instanceName);\n\t\tif (records.length !== 1 || records[0]?.name !== instanceName) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} does not exist by exact name`);\n\t\t}\n\t\tconst record = records[0];\n\t\tif (record.status?.toLowerCase() !== \"running\") {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} is not running`);\n\t\t}\n\t\tconst mounts = record.config?.mounts?.filter((mount) => mount.mountPoint === binding.guestParent) ?? [];\n\t\tif (mounts.length !== 1 || !mounts[0]?.writable || !mounts[0].location) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} requires one writable fixed parent mount`);\n\t\t}\n\t\tif ((await realpath(mounts[0].location)) !== binding.hostParent) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} mounts a different host parent`);\n\t\t}\n\t\tconst forwards =\n\t\t\trecord.config?.portForwards?.filter(\n\t\t\t\t(forward) => forward.guestPort === config.daemonPort || forward.hostPort === config.daemonPort,\n\t\t\t) ?? [];\n\t\tif (\n\t\t\tforwards.length !== 1 ||\n\t\t\tforwards[0]?.guestPort !== config.daemonPort ||\n\t\t\tforwards[0].hostPort !== config.daemonPort ||\n\t\t\tforwards[0].hostIP !== config.daemonHostBind\n\t\t) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} requires one matching loopback daemon forward`);\n\t\t}\n\t\treturn {\n\t\t\t...binding,\n\t\t\tinstanceName,\n\t\t\tdaemonUrl: `ws://${urlHost(config.daemonHostBind)}:${config.daemonPort}${DAEMON_WEBSOCKET_PATH}`,\n\t\t};\n\t}\n\t/** Reinspect and reuse the supervised guest daemon under the exclusive named-VM owner lock. */\n\tasync ensureSharedDaemon(\n\t\toptions: SharedLimaInstanceOptions,\n\t\towner: SharedLimaOwnerLock,\n\t\tupdated = false,\n\t): Promise<string> {\n\t\tif (owner.instanceName !== options.instanceName) throw new Error(\"Shared Lima owner lock names a different VM\");\n\t\tawait owner.assertHeld();\n\t\tawait this.inspectSharedInstance(options);\n\t\tconst config = this.resolveConfig();\n\t\tconst local = this.env.GRIP_SANDBOX_GUEST_BINARY\n\t\t\t? await inspectLocalGuestBinary(this.env.GRIP_SANDBOX_GUEST_BINARY)\n\t\t\t: undefined;\n\t\tconst versionArgs = [\n\t\t\t\"shell\",\n\t\t\t\"--tty=false\",\n\t\t\toptions.instanceName,\n\t\t\t\"sh\",\n\t\t\t\"-lc\",\n\t\t\tlocal || updated ? '\"$HOME/.local/bin/grip\" --version' : \"grip --version\",\n\t\t];\n\t\tconst version = await this.runner.run(config.limaBinary, versionArgs);\n\t\tif (version.exitCode !== 0 || version.stdout.trim() !== VERSION) {\n\t\t\tthrow new Error(\"Shared Lima grip version mismatch or binary missing; install the matching version manually\");\n\t\t}\n\t\tawait owner.assertHeld();\n\t\tconst directory = \"$HOME/.cache/grip/shared-lima\";\n\t\t// /proc start time plus boot ID distinguishes a recycled PID or a rebooted guest.\n\t\t// kill -0 also succeeds for zombies, which must never be reused as a live daemon.\n\t\tconst processStartTime = `awk '{ sub(/^.*\\\\) /, \"\"); if ($1 == \"Z\" || $1 == \"X\") exit 1; print $20 }'`;\n\t\tconst script = [\n\t\t\t\"set -eu\",\n\t\t\t\"umask 077\",\n\t\t\t`directory=\"${directory}\"`,\n\t\t\t// Both current modes reserve the guest transition; a crashed reservation is operator-owned.\n\t\t\t'mkdir -p \"$HOME/.cache/grip\"',\n\t\t\t'mode_lock=\"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t'mkdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap 'rmdir \\\"$mode_lock\\\" 2>/dev/null || true' EXIT\",\n\t\t\t// A legacy per-session daemon may own this VM or its port. Do not start a second daemon.\n\t\t\t'for legacy_file in \"$HOME/.cache/grip\"/sandbox-daemon-*.pid \"$HOME/.cache/grip\"/sandbox-daemon-*.log; do',\n\t\t\t' if test -e \"$legacy_file\" || test -L \"$legacy_file\"; then exit 27; fi',\n\t\t\t\"done\",\n\t\t\t// A transient user service must outlive the Lima SSH session. Do not mutate\n\t\t\t// private state unless the guest manager is running and linger was enabled by an operator.\n\t\t\t\"command -v systemd-run >/dev/null && systemctl --user show-environment >/dev/null || exit 29\",\n\t\t\t'test \"$(loginctl show-user \"$(id -un)\" --property=Linger --value)\" = yes || exit 29',\n\t\t\t`mkdir -p \"$directory\"; test ! -L \"$directory\"; chmod 700 \"$directory\"`,\n\t\t\t'rmdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap - EXIT\",\n\t\t\t`token_file=\"$directory/daemon-${config.daemonPort}.token\"`,\n\t\t\t`pid_file=\"$directory/daemon-${config.daemonPort}.pid\"`,\n\t\t\t`identity_file=\"$directory/daemon-${config.daemonPort}.identity\"`,\n\t\t\t`log_file=\"$directory/daemon-${config.daemonPort}.log\"`,\n\t\t\t`start_lock=\"$directory/daemon-${config.daemonPort}.starting\"`,\n\t\t\t`unit=\"grip-shared-lima-${config.daemonPort}.service\"`,\n\t\t\t'test ! -L \"$token_file\"; test ! -L \"$pid_file\"; test ! -L \"$identity_file\"; test ! -L \"$log_file\"',\n\t\t\t'if test -e \"$log_file\"; then test -f \"$log_file\" && test \"$(stat -c %a \"$log_file\")\" = 600 || exit 22; fi',\n\t\t\t'test ! -e \"$start_lock\" && test ! -L \"$start_lock\" || exit 26',\n\t\t\t'if test -e \"$token_file\" || test -e \"$pid_file\" || test -e \"$identity_file\"; then',\n\t\t\t' test -f \"$token_file\" && test -f \"$pid_file\" && test -f \"$identity_file\" || exit 21',\n\t\t\t' test \"$(stat -c %a \"$token_file\")\" = 600 || exit 22',\n\t\t\t' test \"$(stat -c %a \"$pid_file\")\" = 600 || exit 22',\n\t\t\t' test \"$(stat -c %a \"$identity_file\")\" = 600 || exit 22',\n\t\t\t' pid=\"$(cat \"$pid_file\")\"',\n\t\t\t\" case \\\"$pid\\\" in ''|*[!0-9]*) exit 23;; esac\",\n\t\t\t' kill -0 \"$pid\" || exit 24',\n\t\t\t` start_time=\"$(${processStartTime} \"/proc/$pid/stat\")\" || exit 25`,\n\t\t\t' boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\" || exit 25',\n\t\t\t' test -n \"$start_time\" && test -n \"$boot_id\" && test \"$(cat \"$identity_file\")\" = \"$boot_id:$start_time\" || exit 25',\n\t\t\t' test \"$(systemctl --user show -P MainPID \"$unit\")\" = \"$pid\" && systemctl --user is-active --quiet \"$unit\" || exit 25',\n\t\t\t' token=\"$(cat \"$token_file\")\"',\n\t\t\t\"else\",\n\t\t\t' mkdir \"$start_lock\" || exit 26',\n\t\t\t\" trap 'rmdir \\\"$start_lock\\\" 2>/dev/null || true' EXIT\",\n\t\t\t\" token=\\\"$(head -c 32 /dev/urandom | base64 | tr -d '\\\\n')\\\"\",\n\t\t\t' printf \\'%s\\' \"$token\" >\"$token_file\"',\n\t\t\t' chmod 600 \"$token_file\"',\n\t\t\t// The systemd user manager owns the process. It reads the private token file\n\t\t\t// inside the unit, never from a systemd-run argument or environment property.\n\t\t\tlocal\n\t\t\t\t? ' grip_bin=\"$HOME/.local/bin/grip\"; test -x \"$grip_bin\"'\n\t\t\t\t: ' grip_bin=\"$(command -v grip)\"; case \"$grip_bin\" in /*) ;; *) exit 25;; esac',\n\t\t\t` systemd-run --user --unit=\"$unit\" --property=Restart=no --property=KillMode=control-group -- sh -c 'set -eu; umask 077; GRIP_DAEMON_TOKEN=\"$(cat \"$HOME/.cache/grip/shared-lima/daemon-${config.daemonPort}.token\")\"; test -n \"$GRIP_DAEMON_TOKEN\"; export GRIP_DAEMON_TOKEN; exec \"$1\" --daemon --daemon-host 127.0.0.1 --daemon-allow-insecure-transport --daemon-port ${config.daemonPort} --daemon-cwd \"$2\" --daemon-shared-parent \"$2\" --daemon-allow-root --daemon-allow-process-exec >\"$HOME/.cache/grip/shared-lima/daemon-${config.daemonPort}.log\" 2>&1 </dev/null' sh \"$grip_bin\" ${shellQuote(config.workspaceMountPath)} >/dev/null`,\n\t\t\t' pid=\"\"; attempts=0',\n\t\t\t' while test \"$attempts\" -lt 50; do',\n\t\t\t' pid=\"$(systemctl --user show -P MainPID \"$unit\")\" || exit 25',\n\t\t\t' case \"$pid\" in \"\"|0) sleep 0.1;; *[!0-9]*) exit 25;; *) break;; esac',\n\t\t\t\" attempts=$((attempts + 1))\",\n\t\t\t\" done\",\n\t\t\t' case \"$pid\" in \"\"|0|*[!0-9]*) exit 25;; esac',\n\t\t\t' systemctl --user is-active --quiet \"$unit\" || exit 25',\n\t\t\t' printf \\'%s\\' \"$pid\" >\"$pid_file\"',\n\t\t\t' chmod 600 \"$pid_file\"',\n\t\t\t` start_time=\"$(${processStartTime} \"/proc/$pid/stat\")\" || exit 25`,\n\t\t\t' boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\" || exit 25',\n\t\t\t' test -n \"$start_time\" && test -n \"$boot_id\" || exit 25',\n\t\t\t' printf \\'%s:%s\\' \"$boot_id\" \"$start_time\" >\"$identity_file\"',\n\t\t\t' chmod 600 \"$identity_file\"',\n\t\t\t' rmdir \"$start_lock\" || exit 26',\n\t\t\t\" trap - EXIT\",\n\t\t\t\"fi\",\n\t\t\t\"printf 'GRIP_SHARED_TOKEN=%s\\\\n' \\\"$token\\\"\",\n\t\t].join(\"\\n\");\n\t\tconst args = [\"shell\", \"--tty=false\", options.instanceName, \"sh\", \"-lc\", script];\n\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\t// Never include stdout/stderr from a credential-bearing shell in an error.\n\t\tif (result.exitCode !== 0)\n\t\t\tthrow new Error(\"Shared Lima daemon state is uncertain; reconcile guest PID/token files manually\");\n\t\tconst token = result.stdout.match(/(?:^|\\n)GRIP_SHARED_TOKEN=([A-Za-z0-9+/]{43}=)(?:\\r?\\n|$)/)?.[1];\n\t\tif (!token) throw new Error(\"Shared Lima daemon did not return a valid credential; reconcile manually\");\n\t\tawait this.readinessWaiter(config.daemonHostBind, config.daemonPort);\n\t\t// Readiness can outlive the owner. Never hand a guest credential to a lost owner.\n\t\tawait owner.assertHeld();\n\t\treturn token;\n\t}\n\n\t/** Update only a verified supervised daemon. Staging happens before disconnecting peers. */\n\tprivate async updateSharedDaemon(options: SharedLimaInstanceOptions, owner: SharedLimaOwnerLock): Promise<void> {\n\t\tawait owner.assertHeld();\n\t\tawait this.inspectSharedInstance(options);\n\t\tconst config = this.resolveConfig();\n\t\tconst name = options.instanceName;\n\t\tconst port = config.daemonPort;\n\t\tif (!this.env.GRIP_SANDBOX_GUEST_BINARY && process.argv[1]?.endsWith(\"/packages/coding-agent/src/cli.ts\")) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Development sandbox update requires GRIP_SANDBOX_GUEST_BINARY pointing to a built Linux Grip executable\",\n\t\t\t);\n\t\t}\n\t\tconst local = this.env.GRIP_SANDBOX_GUEST_BINARY\n\t\t\t? await inspectLocalGuestBinary(this.env.GRIP_SANDBOX_GUEST_BINARY)\n\t\t\t: undefined;\n\t\tconst shell = (script: string) =>\n\t\t\tthis.runner.run(config.limaBinary, [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script]);\n\t\tconst directory = \"$HOME/.cache/grip/shared-lima\";\n\t\tconst unit = `grip-shared-lima-${port}.service`;\n\t\tconst verify = [\n\t\t\t\"set -eu\",\n\t\t\t`directory=\"${directory}\"`,\n\t\t\t`unit=${shellQuote(unit)}`,\n\t\t\t'test -d \"$directory\" && test ! -L \"$directory\"',\n\t\t\t'test ! -e \"$HOME/.cache/grip/daemon-mode.lock\" && test ! -L \"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t`token_file=\"$directory/daemon-${port}.token\"`,\n\t\t\t`pid_file=\"$directory/daemon-${port}.pid\"`,\n\t\t\t`identity_file=\"$directory/daemon-${port}.identity\"`,\n\t\t\t'for file in \"$token_file\" \"$pid_file\" \"$identity_file\"; do test -f \"$file\" && test ! -L \"$file\" && test \"$(stat -c %a \"$file\")\" = 600; done',\n\t\t\t'pid=\"$(cat \"$pid_file\")\"; case \"$pid\" in \"\"|0|*[!0-9]*) exit 45;; esac',\n\t\t\t'kill -0 \"$pid\"',\n\t\t\t`start_time=\"$(awk '{ sub(/^.*\\\\) /, \"\"); if ($1 == \"Z\" || $1 == \"X\") exit 1; print $20 }' \"/proc/$pid/stat\")\"`,\n\t\t\t'boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\"',\n\t\t\t'test -n \"$start_time\" && test \"$(cat \"$identity_file\")\" = \"$boot_id:$start_time\"',\n\t\t\t'test \"$(systemctl --user show -P MainPID \"$unit\")\" = \"$pid\" && systemctl --user is-active --quiet \"$unit\"',\n\t\t\t'case \"$(systemctl --user show -P ExecStart \"$unit\")\" in *\"$HOME/.local/bin/grip\"*) ;; *) exit 46;; esac',\n\t\t];\n\t\tconst preflight = await shell(verify.join(\"\\n\"));\n\t\tif (preflight.exitCode !== 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Shared Lima daemon identity or binary path is uncertain; update refused without disconnecting clients\",\n\t\t\t);\n\t\t}\n\t\tconst staged = await stageSharedGuestBinary(this.runner, config.limaBinary, name, unit, VERSION, local);\n\t\ttry {\n\t\t\tawait owner.assertHeld();\n\t\t\tconst stop = await shell(\n\t\t\t\t[\n\t\t\t\t\t...verify,\n\t\t\t\t\t'mkdir \"$HOME/.cache/grip/daemon-mode.lock\" || exit 45',\n\t\t\t\t\t'trap \\u0027rmdir \"$HOME/.cache/grip/daemon-mode.lock\" 2>/dev/null || true\\u0027 EXIT',\n\t\t\t\t\t'systemctl --user stop \"$unit\"',\n\t\t\t\t\t'test \"$(systemctl --user show -P MainPID \"$unit\")\" = 0',\n\t\t\t\t\t'! kill -0 \"$pid\" 2>/dev/null',\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tif (stop.exitCode !== 0)\n\t\t\t\tthrow new Error(\"Shared daemon stop is uncertain; inspect the guest before retrying update\");\n\t\t\tawait owner.assertHeld();\n\t\t\tawait staged.install();\n\t\t\tawait owner.assertHeld();\n\t\t\tconst restart = await shell(\n\t\t\t\t[\n\t\t\t\t\t\"set -eu\",\n\t\t\t\t\t`directory=\"${directory}\"`,\n\t\t\t\t\t`unit=${shellQuote(unit)}`,\n\t\t\t\t\t'test -d \"$directory\" && test ! -L \"$directory\"',\n\t\t\t\t\t`token_file=\"$directory/daemon-${port}.token\"`,\n\t\t\t\t\t`pid_file=\"$directory/daemon-${port}.pid\"`,\n\t\t\t\t\t`identity_file=\"$directory/daemon-${port}.identity\"`,\n\t\t\t\t\t'for file in \"$token_file\" \"$pid_file\" \"$identity_file\"; do test -f \"$file\" && test ! -L \"$file\" && test \"$(stat -c %a \"$file\")\" = 600; done',\n\t\t\t\t\t'test ! -e \"$HOME/.cache/grip/daemon-mode.lock\" && test ! -L \"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t\t\t'mkdir \"$HOME/.cache/grip/daemon-mode.lock\" || exit 45',\n\t\t\t\t\t'trap \\u0027rmdir \"$HOME/.cache/grip/daemon-mode.lock\" 2>/dev/null || true\\u0027 EXIT',\n\t\t\t\t\t'old_pid=\"$(cat \"$pid_file\")\"; case \"$old_pid\" in \"\"|0|*[!0-9]*) exit 45;; esac',\n\t\t\t\t\t'! kill -0 \"$old_pid\" 2>/dev/null',\n\t\t\t\t\t`test \"$(\"$HOME/.local/bin/grip\" --version)\" = ${shellQuote(VERSION)}`,\n\t\t\t\t\t'load=\"$(systemctl --user show -P LoadState \"$unit\" 2>/dev/null || true)\"',\n\t\t\t\t\t'case \"$load\" in',\n\t\t\t\t\t' loaded) test \"$(systemctl --user show -P MainPID \"$unit\")\" = 0; systemctl --user start \"$unit\" ;;',\n\t\t\t\t\t' not-found|\"\")',\n\t\t\t\t\t` systemd-run --user --unit=\"$unit\" --property=Restart=no --property=KillMode=control-group -- sh -c 'set -eu; umask 077; GRIP_DAEMON_TOKEN=\"$(cat \"$HOME/.cache/grip/shared-lima/daemon-${port}.token\")\"; test -n \"$GRIP_DAEMON_TOKEN\"; export GRIP_DAEMON_TOKEN; exec \"$1\" --daemon --daemon-host 127.0.0.1 --daemon-allow-insecure-transport --daemon-port ${port} --daemon-cwd \"$2\" --daemon-shared-parent \"$2\" --daemon-allow-root --daemon-allow-process-exec >\"$HOME/.cache/grip/shared-lima/daemon-${port}.log\" 2>&1 </dev/null' sh \"$HOME/.local/bin/grip\" ${shellQuote(config.workspaceMountPath)} >/dev/null ;;`,\n\t\t\t\t\t\" *) exit 45 ;;\",\n\t\t\t\t\t\"esac\",\n\t\t\t\t\t'pid=\"\"; attempts=0',\n\t\t\t\t\t'while test \"$attempts\" -lt 50; do',\n\t\t\t\t\t' pid=\"$(systemctl --user show -P MainPID \"$unit\")\" || exit 45',\n\t\t\t\t\t' case \"$pid\" in \"\"|0) sleep 0.1;; *[!0-9]*) exit 45;; *) break;; esac',\n\t\t\t\t\t\" attempts=$((attempts + 1))\",\n\t\t\t\t\t\"done\",\n\t\t\t\t\t'case \"$pid\" in \"\"|0|*[!0-9]*) exit 45;; esac',\n\t\t\t\t\t'kill -0 \"$pid\"; systemctl --user is-active --quiet \"$unit\"',\n\t\t\t\t\t`start_time=\"$(awk '{ sub(/^.*\\\\) /, \"\"); if ($1 == \"Z\" || $1 == \"X\") exit 1; print $20 }' \"/proc/$pid/stat\")\"`,\n\t\t\t\t\t'boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\"',\n\t\t\t\t\t'test -n \"$start_time\" && test -n \"$boot_id\"',\n\t\t\t\t\t'printf \"%s\" \"$pid\" >\"$pid_file\"',\n\t\t\t\t\t'printf \"%s:%s\" \"$boot_id\" \"$start_time\" >\"$identity_file\"',\n\t\t\t\t\t'chmod 600 \"$pid_file\" \"$identity_file\"',\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tif (restart.exitCode !== 0)\n\t\t\t\tthrow new Error(\"Shared daemon restart is uncertain; inspect the guest before retrying update\");\n\t\t\tawait this.readinessWaiter(config.daemonHostBind, port);\n\t\t\tawait owner.assertHeld();\n\t\t} finally {\n\t\t\tawait staged.cleanup();\n\t\t}\n\t}\n\n\tprivate async startInstance(\n\t\tconfig: SandboxConfig,\n\t\tworkspaceRoot: string,\n\t\tname: string,\n\t\tdaemonPort: number,\n\t): Promise<void> {\n\t\tconst mountExpression = `.mounts = [{\"location\":${JSON.stringify(workspaceRoot)},\"mountPoint\":${JSON.stringify(config.workspaceMountPath)},\"writable\":true}]`;\n\t\tconst forwardExpression = `.portForwards += [{\"guestPort\":${daemonPort},\"hostPort\":${daemonPort},\"hostIP\":${JSON.stringify(config.daemonHostBind)}}]`;\n\t\tconst args = [\n\t\t\t\"start\",\n\t\t\t\"--tty=false\",\n\t\t\t\"--name\",\n\t\t\tname,\n\t\t\t\"--mount-none\",\n\t\t\t\"--set\",\n\t\t\tmountExpression,\n\t\t\t\"--set\",\n\t\t\tforwardExpression,\n\t\t\tconfig.limaTemplate,\n\t\t];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\n\tprivate async ensureGrip(\n\t\tconfig: SandboxConfig,\n\t\tname: string,\n\t\tmanaged: boolean,\n\t\tlocal?: LocalGuestBinary,\n\t): Promise<void> {\n\t\tif (local) {\n\t\t\tawait installLocalGuestBinary(this.runner, config.limaBinary, name, local, VERSION);\n\t\t\treturn;\n\t\t}\n\t\tconst checkArgs = [\n\t\t\t\"shell\",\n\t\t\t\"--tty=false\",\n\t\t\tname,\n\t\t\t\"sh\",\n\t\t\t\"-lc\",\n\t\t\t'command -v grip >/dev/null || test -x \"$HOME/.local/bin/grip\"',\n\t\t];\n\t\tconst check = await this.runner.run(config.limaBinary, checkArgs);\n\t\tif (check.exitCode === 0) return;\n\t\tif (!managed) {\n\t\t\tthrow new Error(\n\t\t\t\t`Lima instance ${name} does not provide grip; install the matching Linux release in the VM first`,\n\t\t\t);\n\t\t}\n\t\tconst script = `set -eu; tmp=\"$(mktemp)\"; trap 'rm -f \"$tmp\"' EXIT; curl -fsSL -o \"$tmp\" https://raw.githubusercontent.com/greppleai/grip/main/install.sh; GRIP_VERSION=${shellQuote(`v${VERSION}`)} sh \"$tmp\"; test -x \"$HOME/.local/bin/grip\"`;\n\t\tconst args = [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\t/** A legacy named attach or stop must not rotate or kill a shared guest daemon. */\n\tprivate async assertNoSharedGuestState(\n\t\tconfig: SandboxConfig,\n\t\tname: string,\n\t\toperation: LegacyLimaGuestStateOperation = \"attach\",\n\t): Promise<void> {\n\t\tconst script = 'test ! -e \"$HOME/.cache/grip/shared-lima\" && test ! -L \"$HOME/.cache/grip/shared-lima\"';\n\t\tconst args = [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script];\n\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\t// A guest shell failure is ambiguous too; never guess that shared state is absent.\n\t\tif (result.exitCode !== 0) {\n\t\t\tthrow new Error(`Lima named VM may host a shared daemon; legacy ${operation} refused; reconcile manually`);\n\t\t}\n\t}\n\n\tprivate async startDaemon(config: SandboxConfig, name: string): Promise<string> {\n\t\tconst pidFile = `.cache/grip/sandbox-daemon-${config.daemonPort}.pid`;\n\t\tconst logFile = `.cache/grip/sandbox-daemon-${config.daemonPort}.log`;\n\t\tconst script = [\n\t\t\t\"set -eu\",\n\t\t\t\"umask 077\",\n\t\t\t`mkdir -p \"$HOME/.cache/grip\"`,\n\t\t\t'mode_lock=\"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t'mkdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap 'rmdir \\\"$mode_lock\\\" 2>/dev/null || true' EXIT\",\n\t\t\t'test ! -e \"$HOME/.cache/grip/shared-lima\" && test ! -L \"$HOME/.cache/grip/shared-lima\" || exit 29',\n\t\t\t`if test -f \"$HOME/${pidFile}\"; then old_pid=\"$(cat \"$HOME/${pidFile}\")\"; kill \"$old_pid\" 2>/dev/null || true; fi`,\n\t\t\t`token=\"$(head -c 32 /dev/urandom | base64 | tr -d '\\\\n')\"`,\n\t\t\t`nohup env GRIP_DAEMON_TOKEN=\"$token\" \"${this.env.GRIP_SANDBOX_GUEST_BINARY ? \"$HOME/.local/bin/grip\" : '$(command -v grip || printf %s \"$HOME/.local/bin/grip\")'}\" --daemon --daemon-host 127.0.0.1 --daemon-allow-insecure-transport --daemon-port ${config.daemonPort} --daemon-cwd ${shellQuote(config.workspaceMountPath)} --daemon-allow-root --daemon-allow-process-exec >\"$HOME/${logFile}\" 2>&1 </dev/null &`,\n\t\t\t`echo $! >\"$HOME/${pidFile}\"`,\n\t\t\t'rmdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap - EXIT\",\n\t\t\t`printf 'GRIP_SANDBOX_TOKEN=%s\\\\n' \"$token\"`,\n\t\t].join(\"\\n\");\n\t\tconst args = [\"shell\", \"--tty=false\", \"--workdir\", config.workspaceMountPath, name, \"sh\", \"-lc\", script];\n\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\tensureLimaSuccessful(config.limaBinary, result, args);\n\t\tconst token = result.stdout.match(/(?:^|\\n)GRIP_SANDBOX_TOKEN=([^\\r\\n]+)/)?.[1];\n\t\tif (!token) throw new Error(`Lima instance ${name} started the daemon without returning an authentication token`);\n\t\treturn token;\n\t}\n\n\tprivate async prepareExistingInstance(\n\t\tconfig: SandboxConfig,\n\t\trecord: LimaListRecord,\n\t\tname: string,\n\t\tworkspaceRoot: string,\n\t): Promise<void> {\n\t\tconst mount = findWorkspaceMount(record, config.workspaceMountPath);\n\t\tif (!mount || resolve(mount.location ?? \"\") !== workspaceRoot || !mount.writable) {\n\t\t\tthrow new Error(\n\t\t\t\t`Lima instance ${name} must mount ${workspaceRoot} read-write at ${config.workspaceMountPath}`,\n\t\t\t);\n\t\t}\n\t\tconst status = record.status?.toLowerCase();\n\t\tif (status === \"running\") return;\n\t\tif (status !== \"stopped\") {\n\t\t\tthrow new Error(`Lima instance ${name} is in an uncertain state; refusing to resume`);\n\t\t}\n\t\tconst args = [\"start\", \"--tty=false\", name];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\n\tprivate async findExactLegacyInstance(config: SandboxConfig, name?: string): Promise<LimaListRecord | undefined> {\n\t\tif (!name) return undefined;\n\t\tconst records = await this.listRecords(config, name);\n\t\tif (records.length === 0) return undefined;\n\t\tif (records.length !== 1 || records[0]?.name !== name) {\n\t\t\tthrow new Error(\"Lima instance lookup did not return one exact name; refusing to attach or create\");\n\t\t}\n\t\treturn records[0];\n\t}\n\n\tasync start(options: SandboxStartOptions): Promise<SandboxStartResult> {\n\t\tconst requestedName = options.name?.trim();\n\t\tif (!requestedName) {\n\t\t\tif (options.update) throw new Error(\"Sandbox update requires a named running shared VM\");\n\t\t\treturn this.startWithLegacyInstance(options);\n\t\t}\n\t\t// Coordinate VM resume/create as well as guest daemon launch with a named shared owner.\n\t\t// A stale lock is ambiguous, not permission to start an existing VM.\n\t\tconst owner = await acquireSharedLimaOwnerLock(requestedName);\n\t\ttry {\n\t\t\tconst config = this.resolveConfig(options);\n\t\t\tconst existing = await this.findExactLegacyInstance(config, requestedName);\n\t\t\tif (options.update && existing?.status?.toLowerCase() !== \"running\") {\n\t\t\t\tthrow new Error(\"Sandbox update requires an existing running shared VM\");\n\t\t\t}\n\t\t\tif (existing?.status?.toLowerCase() !== \"running\") {\n\t\t\t\treturn await this.startWithLegacyInstance(options, { record: existing });\n\t\t\t}\n\t\t\t// Select the guest mode before any legacy setup. An unreadable or ambiguous\n\t\t\t// marker is not permission to start a per-session daemon in this VM.\n\t\t\tconst probe = await this.runner.run(config.limaBinary, [\n\t\t\t\t\"shell\",\n\t\t\t\t\"--tty=false\",\n\t\t\t\trequestedName,\n\t\t\t\t\"sh\",\n\t\t\t\t\"-lc\",\n\t\t\t\t'if test -e \"$HOME/.cache/grip/shared-lima\" || test -L \"$HOME/.cache/grip/shared-lima\"; then if test -d \"$HOME/.cache/grip/shared-lima\" && test ! -L \"$HOME/.cache/grip/shared-lima\"; then printf \"GRIP_SHARED_GUEST\\\\n\"; else exit 42; fi; else printf \"GRIP_LEGACY_GUEST\\\\n\"; fi',\n\t\t\t]);\n\t\t\tif (probe.exitCode !== 0) throw new Error(\"Lima guest daemon mode is uncertain; refusing named attach\");\n\t\t\tif (probe.stdout.trim() === \"GRIP_LEGACY_GUEST\") {\n\t\t\t\tif (options.update)\n\t\t\t\t\tthrow new Error(\"Sandbox update requires a supervised shared guest; legacy guest is unchanged\");\n\t\t\t\treturn await this.startWithLegacyInstance(options, { record: existing });\n\t\t\t}\n\t\t\tif (probe.stdout.trim() !== \"GRIP_SHARED_GUEST\") {\n\t\t\t\tthrow new Error(\"Lima guest daemon mode is uncertain; refusing named attach\");\n\t\t\t}\n\t\t\tawait owner.assertHeld();\n\t\t\tconst mount = findWorkspaceMount(existing, config.workspaceMountPath);\n\t\t\tif (!mount?.location) throw new Error(\"Shared Lima instance mount is unavailable; refusing attach\");\n\t\t\tconst sharedOptions = {\n\t\t\t\tinstanceName: requestedName,\n\t\t\t\thostParent: resolve(mount.location),\n\t\t\t\thostRoot: resolve(options.workspaceRoot),\n\t\t\t};\n\t\t\tconst inspection = await this.inspectSharedInstance(sharedOptions);\n\t\t\tif (options.update) await this.updateSharedDaemon(sharedOptions, owner);\n\t\t\tconst token = await this.ensureSharedDaemon(sharedOptions, owner, options.update);\n\t\t\tconst daemonUrl = `grip+${inspection.daemonUrl}?root=${encodeURIComponent(inspection.guestRoot)}`;\n\t\t\treturn {\n\t\t\t\tcontainerId: requestedName,\n\t\t\t\tcontainerName: requestedName,\n\t\t\t\tworkspaceRoot: inspection.hostRoot,\n\t\t\t\tworkspaceMountPath: inspection.guestRoot,\n\t\t\t\tdaemonUrl,\n\t\t\t\tdaemonUrlRedacted: inspection.daemonUrl,\n\t\t\t\ttoken,\n\t\t\t\tlabels: { [`${SANDBOX_LABEL_PREFIX}.runtime`]: \"lima\", [`${SANDBOX_LABEL_PREFIX}.version`]: VERSION },\n\t\t\t};\n\t\t} finally {\n\t\t\tawait owner.release();\n\t\t}\n\t}\n\n\tprivate async startWithLegacyInstance(\n\t\toptions: SandboxStartOptions,\n\t\tknown?: KnownLimaRecord,\n\t): Promise<SandboxStartResult> {\n\t\tconst workspaceRoot = resolve(options.workspaceRoot);\n\t\tconst local = this.env.GRIP_SANDBOX_GUEST_BINARY\n\t\t\t? await inspectLocalGuestBinary(this.env.GRIP_SANDBOX_GUEST_BINARY)\n\t\t\t: undefined;\n\t\tconst config = this.resolveConfig(options);\n\t\tconst requestedName = options.name?.trim();\n\t\tconst managed = !requestedName;\n\t\tconst existing = known ? known.record : await this.findExactLegacyInstance(config, requestedName);\n\t\tif (existing) await this.prepareExistingInstance(config, existing, requestedName!, workspaceRoot);\n\t\tconst configuredForward = existing ? findDaemonForward(existing, config.daemonPort) : undefined;\n\t\tif (configuredForward && configuredForward.guestPort !== configuredForward.hostPort) {\n\t\t\tthrow new Error(\n\t\t\t\t`Lima instance ${requestedName} must forward the sandbox daemon on the same guest and host port`,\n\t\t\t);\n\t\t}\n\t\tconst daemonPort =\n\t\t\tconfiguredForward?.hostPort ?? (await this.portAllocator(config.daemonHostBind, config.daemonPort));\n\t\tconst name =\n\t\t\trequestedName ?? createInstanceName(config, workspaceRoot, options.sessionId ?? \"session\", daemonPort);\n\t\tconst effectiveConfig = { ...config, daemonPort };\n\t\tif (!existing) await this.startInstance(effectiveConfig, workspaceRoot, name, daemonPort);\n\t\t// A failed guest install/start can have changed state; never delete an uncertain VM.\n\t\tif (existing) await this.assertNoSharedGuestState(effectiveConfig, name);\n\t\tawait this.ensureGrip(effectiveConfig, name, !existing, local);\n\t\tconst token = await this.startDaemon(effectiveConfig, name);\n\t\tawait this.readinessWaiter(config.daemonHostBind, daemonPort);\n\t\t// A failed readiness check is not proof that this daemon is ours to stop.\n\t\t// Leave uncertain guest state for explicit operator reconciliation.\n\t\tthis.managedInstances.set(name, { workspaceRoot, daemonPort, ownerId: options.sessionId, managed });\n\t\tconst daemonUrl = `ws://${urlHost(daemonConnectionHost(config.daemonHostBind))}:${daemonPort}${DAEMON_WEBSOCKET_PATH}`;\n\t\treturn {\n\t\t\tcontainerId: name,\n\t\t\tcontainerName: name,\n\t\t\tworkspaceRoot,\n\t\t\tworkspaceMountPath: config.workspaceMountPath,\n\t\t\tdaemonUrl,\n\t\t\tdaemonUrlRedacted: daemonUrl,\n\t\t\ttoken,\n\t\t\tlabels: { [`${SANDBOX_LABEL_PREFIX}.runtime`]: \"lima\", [`${SANDBOX_LABEL_PREFIX}.version`]: VERSION },\n\t\t};\n\t}\n\n\tasync list(options: SandboxListOptions): Promise<SandboxContainer[]> {\n\t\tconst config = this.resolveConfig();\n\t\tconst workspaceRoot = resolve(options.workspaceRoot);\n\t\treturn (await this.listRecords(config))\n\t\t\t.map((record) => toSandboxContainer(record, config.workspaceMountPath))\n\t\t\t.filter(\n\t\t\t\t(instance) => instance.workspaceRoot && (options.allWorkspaces || instance.workspaceRoot === workspaceRoot),\n\t\t\t);\n\t}\n\n\tprivate async stopDaemon(config: SandboxConfig, name: string, daemonPort: number): Promise<void> {\n\t\tconst pidFile = `.cache/grip/sandbox-daemon-${daemonPort}.pid`;\n\t\tconst script = `if test -f \"$HOME/${pidFile}\"; then pid=\"$(cat \"$HOME/${pidFile}\")\"; kill \"$pid\" 2>/dev/null || true; rm -f \"$HOME/${pidFile}\"; fi`;\n\t\tconst args = [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\n\tasync stop(options: SandboxStopOptions): Promise<SandboxStopResult> {\n\t\tconst config = this.resolveConfig();\n\t\tconst instances = await this.list({ workspaceRoot: options.workspaceRoot });\n\t\tconst selected = selectLimaSandbox(instances, options.target ?? options.currentContainerId);\n\t\tif (!selected) return { status: \"not-found\", message: \"No matching Grip Lima sandbox found\" };\n\t\tif (instances.filter((instance) => instance.name === selected.name).length !== 1) {\n\t\t\tthrow new Error(\"Lima sandbox identity is ambiguous; refusing to stop a VM or daemon\");\n\t\t}\n\t\tconst tracked = this.managedInstances.get(selected.name);\n\t\t// Names and Lima's list output do not establish ownership. In particular, a\n\t\t// shared named VM can have the ordinary sandbox prefix without being ours.\n\t\t// Only a VM started by this session may be stopped or have its daemon touched.\n\t\tif (!tracked || tracked.workspaceRoot !== selected.workspaceRoot || tracked.daemonPort !== selected.daemonPort) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Lima sandbox ownership is unknown or daemon port changed; refusing to stop an untracked VM or daemon\",\n\t\t\t);\n\t\t}\n\t\t// A shared guest must never lose its daemon or VM to a legacy\n\t\t// in-process record. Resolve the selected VM again under the host owner lock.\n\t\tconst owner = await acquireSharedLimaOwnerLock(selected.name);\n\t\ttry {\n\t\t\tconst matches = (await this.list({ workspaceRoot: options.workspaceRoot })).filter(\n\t\t\t\t(instance) => instance.name === selected.name,\n\t\t\t);\n\t\t\tconst current = matches[0];\n\t\t\tif (\n\t\t\t\tmatches.length !== 1 ||\n\t\t\t\t!current ||\n\t\t\t\tcurrent.id !== selected.id ||\n\t\t\t\tcurrent.state !== selected.state ||\n\t\t\t\tcurrent.workspaceRoot !== selected.workspaceRoot ||\n\t\t\t\tcurrent.daemonPort !== selected.daemonPort\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Lima sandbox identity changed during stop; refusing to touch the VM or daemon\");\n\t\t\t}\n\t\t\treturn await this.stopTrackedInstance(config, current, tracked);\n\t\t} finally {\n\t\t\tawait owner.release();\n\t\t}\n\t}\n\n\tprivate async stopTrackedInstance(\n\t\tconfig: SandboxConfig,\n\t\tselected: SandboxContainer,\n\t\ttracked: ManagedLimaInstance,\n\t): Promise<SandboxStopResult> {\n\t\tconst ownsInstance = tracked.managed;\n\t\tif (selected.state !== \"running\") {\n\t\t\tif (ownsInstance && config.cleanup === \"remove\") {\n\t\t\t\t// An already stopped VM cannot be probed without resuming it. Its\n\t\t\t\t// in-memory record is not proof it was never repurposed externally.\n\t\t\t\tthrow new Error(\"Lima sandbox is stopped; refusing to delete an unverifiable VM; reconcile manually\");\n\t\t\t}\n\t\t\tthis.managedInstances.delete(selected.name);\n\t\t\treturn { status: \"already-stopped\", container: selected };\n\t\t}\n\t\tawait this.assertNoSharedGuestState(config, selected.name, \"stop\");\n\t\tawait this.stopDaemon(config, selected.name, tracked?.daemonPort ?? selected.daemonPort ?? config.daemonPort);\n\t\tif (ownsInstance) {\n\t\t\tconst args = config.cleanup === \"remove\" ? [\"delete\", \"--force\", selected.name] : [\"stop\", selected.name];\n\t\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t\t}\n\t\tthis.managedInstances.delete(selected.name);\n\t\treturn { status: ownsInstance && config.cleanup === \"remove\" ? \"removed\" : \"stopped\", container: selected };\n\t}\n\n\tasync stopManagedInstances(): Promise<void> {\n\t\tconst failures: unknown[] = [];\n\t\tfor (const [name, instance] of [...this.managedInstances]) {\n\t\t\ttry {\n\t\t\t\tawait this.stop({ workspaceRoot: instance.workspaceRoot, target: name, currentContainerId: name });\n\t\t\t} catch (error) {\n\t\t\t\tfailures.push(error);\n\t\t\t}\n\t\t}\n\t\tif (failures.length > 0) throw new AggregateError(failures, \"Failed to stop managed Lima sandbox instances\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lima.js","sourceRoot":"","sources":["../../../src/core/sandbox/lima.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport { realpath } from \"node:fs/promises\";\nimport { createConnection } from \"node:net\";\nimport { basename, resolve } from \"node:path\";\nimport { VERSION } from \"../../config.ts\";\nimport { DAEMON_WEBSOCKET_PATH } from \"../../daemon/config.ts\";\nimport { spawnProcess } from \"../../utils/child-process.ts\";\nimport { acquireSharedLimaOwnerLock, type SharedLimaOwnerLock } from \"../remote-workspace-protocol/lima-owner-lock.ts\";\nimport type { SettingsManager } from \"../settings-manager.ts\";\nimport type {\n\tSandboxCommandOptions,\n\tSandboxCommandResult,\n\tSandboxConfig,\n\tSandboxConfigOverrides,\n\tSandboxContainer,\n\tSandboxListOptions,\n\tSandboxRunner,\n\tSandboxStartOptions,\n\tSandboxStartResult,\n\tSandboxStopOptions,\n\tSandboxStopResult,\n} from \"./config.ts\";\nimport { allocateSandboxDaemonPort, redactSecrets, resolveSandboxConfig, SANDBOX_LABEL_PREFIX } from \"./config.ts\";\nimport { inspectLocalGuestBinary, installLocalGuestBinary, type LocalGuestBinary } from \"./lima-guest-binary.ts\";\nimport { resolveSharedLimaWorkspace, type SharedLimaWorkspaceBinding } from \"./shared-lima-roots.ts\";\nimport { stageSharedGuestBinary } from \"./update-shared-guest-binary.ts\";\nexport interface SharedLimaInstanceInspection extends SharedLimaWorkspaceBinding {\n\tinstanceName: string;\n\tdaemonUrl: string;\n}\n\nexport interface SharedLimaInstanceOptions {\n\tinstanceName: string;\n\thostParent: string;\n\thostRoot: string;\n}\n\nexport interface ManagedLimaInstance {\n\tworkspaceRoot: string;\n\tdaemonPort: number;\n\townerId?: string;\n\tmanaged: boolean;\n}\n\nexport interface LimaSandboxServiceOptions {\n\tsettingsManager?: Pick<SettingsManager, \"getSandboxSettings\">;\n\tenv?: NodeJS.ProcessEnv;\n\trunner?: SandboxRunner;\n\tportAllocator?: (host: string, preferredPort: number) => Promise<number>;\n\treadinessWaiter?: (host: string, port: number) => Promise<void>;\n\tmanagedInstances?: Map<string, ManagedLimaInstance>;\n}\n\ninterface LimaMount {\n\tlocation?: string;\n\tmountPoint?: string;\n\twritable?: boolean;\n}\n\ninterface LimaPortForward {\n\tguestPort?: number;\n\thostPort?: number;\n\thostIP?: string;\n}\n\ninterface LimaConfig {\n\tmounts?: LimaMount[];\n\tportForwards?: LimaPortForward[];\n}\n\ninterface LimaListRecord {\n\tname?: string;\n\tstatus?: string;\n\tarch?: string;\n\tvmType?: string;\n\tdir?: string;\n\tconfig?: LimaConfig;\n}\n\ninterface KnownLimaRecord {\n\trecord: LimaListRecord | undefined;\n}\n\nclass ProcessLimaRunner implements SandboxRunner {\n\trun(command: string, args: string[], options: SandboxCommandOptions = {}): Promise<SandboxCommandResult> {\n\t\treturn new Promise((resolveCommand, reject) => {\n\t\t\tconst child = spawnProcess(command, args, {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\tenv: { ...process.env, ...options.env },\n\t\t\t});\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tchild.stdout?.on(\"data\", (chunk: Buffer) => {\n\t\t\t\tstdout += chunk.toString(\"utf8\");\n\t\t\t});\n\t\t\tchild.stderr?.on(\"data\", (chunk: Buffer) => {\n\t\t\t\tstderr += chunk.toString(\"utf8\");\n\t\t\t});\n\t\t\tchild.once(\"error\", reject);\n\t\t\tchild.once(\"close\", (exitCode) => resolveCommand({ exitCode, stdout, stderr }));\n\t\t});\n\t}\n}\n\nfunction shellQuote(value: string): string {\n\treturn `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction parseLimaRecords(output: string): LimaListRecord[] {\n\tconst text = output.trim();\n\tif (!text) return [];\n\ttry {\n\t\tconst parsed = JSON.parse(text) as unknown;\n\t\treturn Array.isArray(parsed) ? (parsed as LimaListRecord[]) : [parsed as LimaListRecord];\n\t} catch {\n\t\treturn text\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.filter(Boolean)\n\t\t\t.map((line) => JSON.parse(line) as LimaListRecord);\n\t}\n}\n\nfunction ensureLimaSuccessful(binary: string, result: SandboxCommandResult, args: string[]): void {\n\tif (result.exitCode === 0) return;\n\tconst detail = result.stderr.trim() || result.stdout.trim() || `exit code ${result.exitCode ?? \"unknown\"}`;\n\tthrow new Error(redactSecrets(`Lima command failed: ${binary} ${args.join(\" \")}: ${detail}`));\n}\n\nfunction daemonConnectionHost(host: string): string {\n\tif (host === \"0.0.0.0\") return \"127.0.0.1\";\n\tif (host === \"::\") return \"::1\";\n\treturn host;\n}\n\nfunction urlHost(host: string): string {\n\treturn host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host;\n}\n\nasync function canConnect(host: string, port: number): Promise<boolean> {\n\treturn new Promise((resolveConnection) => {\n\t\tconst socket = createConnection({ host, port });\n\t\tlet settled = false;\n\t\tconst finish = (connected: boolean): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tsocket.destroy();\n\t\t\tresolveConnection(connected);\n\t\t};\n\t\tsocket.setTimeout(250, () => finish(false));\n\t\tsocket.once(\"connect\", () => finish(true));\n\t\tsocket.once(\"error\", () => finish(false));\n\t});\n}\n\nasync function waitForLimaDaemon(host: string, port: number): Promise<void> {\n\tconst deadline = Date.now() + 30_000;\n\twhile (Date.now() < deadline) {\n\t\tif (await canConnect(daemonConnectionHost(host), port)) return;\n\t\tawait new Promise((resolveDelay) => setTimeout(resolveDelay, 100));\n\t}\n\tthrow new Error(`Lima sandbox daemon did not become reachable on ${daemonConnectionHost(host)}:${port}`);\n}\n\nfunction createInstanceName(\n\tconfig: SandboxConfig,\n\tworkspaceRoot: string,\n\tsessionId: string,\n\tdaemonPort: number,\n): string {\n\tconst clean = (value: string): string =>\n\t\tvalue\n\t\t\t.toLowerCase()\n\t\t\t.replace(/[^a-z0-9-]+/g, \"-\")\n\t\t\t.replace(/^-+|-+$/g, \"\") || \"workspace\";\n\tconst hash = createHash(\"sha256\").update(resolve(workspaceRoot)).digest(\"hex\").slice(0, 12);\n\treturn `${clean(config.limaInstanceNamePrefix)}-${clean(basename(resolve(workspaceRoot)))}-${hash}-${clean(sessionId).slice(0, 8).replace(/-+$/, \"\")}-p${daemonPort}-${randomBytes(4).toString(\"hex\")}`;\n}\n\nfunction findWorkspaceMount(record: LimaListRecord, workspaceMountPath: string): LimaMount | undefined {\n\treturn record.config?.mounts?.find((mount) => mount.mountPoint === workspaceMountPath);\n}\n\nfunction findDaemonForward(record: LimaListRecord, preferredPort?: number): LimaPortForward | undefined {\n\tconst namePort = Number(record.name?.match(/-p(\\d+)-[a-f0-9]+$/)?.[1]);\n\tconst daemonPort = Number.isInteger(namePort) && namePort > 0 ? namePort : preferredPort;\n\tconst forwards = record.config?.portForwards?.filter(\n\t\t(forward) => forward.guestPort === forward.hostPort && forward.hostPort !== undefined,\n\t);\n\treturn (\n\t\tforwards?.find((forward) => forward.guestPort === daemonPort) ??\n\t\t(forwards?.length === 1 ? forwards[0] : undefined)\n\t);\n}\n\nfunction toSandboxContainer(record: LimaListRecord, workspaceMountPath: string): SandboxContainer {\n\tconst mount = findWorkspaceMount(record, workspaceMountPath);\n\tconst forward = findDaemonForward(record);\n\tconst daemonEndpoint = forward?.hostPort\n\t\t? `ws://${urlHost(daemonConnectionHost(forward.hostIP || \"127.0.0.1\"))}:${forward.hostPort}${DAEMON_WEBSOCKET_PATH}`\n\t\t: undefined;\n\treturn {\n\t\tid: record.name ?? \"\",\n\t\tname: record.name ?? \"\",\n\t\timage: `lima:${record.vmType ?? \"vm\"}/${record.arch ?? \"unknown\"}`,\n\t\tstatus: record.status ?? \"\",\n\t\tstate: record.status?.toLowerCase(),\n\t\tcreatedAt: undefined,\n\t\tworkspaceRoot: mount?.location ? resolve(mount.location) : undefined,\n\t\tworkspaceMountPath: mount?.mountPoint,\n\t\tdaemonPort: forward?.guestPort,\n\t\tdaemonEndpoint,\n\t\tlabels: { [`${SANDBOX_LABEL_PREFIX}.runtime`]: \"lima\", [`${SANDBOX_LABEL_PREFIX}.version`]: VERSION },\n\t};\n}\n\nfunction selectLimaSandbox(instances: SandboxContainer[], target: string | undefined): SandboxContainer | undefined {\n\tif (!target) return instances.length === 1 ? instances[0] : undefined;\n\treturn instances.find((instance) => instance.name === target || instance.id.startsWith(target));\n}\ntype LegacyLimaGuestStateOperation = \"attach\" | \"stop\";\n\nexport class LimaSandboxService {\n\tprivate readonly settingsManager: Pick<SettingsManager, \"getSandboxSettings\"> | undefined;\n\tprivate readonly env: NodeJS.ProcessEnv;\n\tprivate readonly runner: SandboxRunner;\n\tprivate readonly portAllocator: (host: string, preferredPort: number) => Promise<number>;\n\tprivate readonly readinessWaiter: (host: string, port: number) => Promise<void>;\n\tprivate readonly managedInstances: Map<string, ManagedLimaInstance>;\n\n\tconstructor(options: LimaSandboxServiceOptions = {}) {\n\t\tthis.settingsManager = options.settingsManager;\n\t\tthis.env = options.env ?? process.env;\n\t\tthis.runner = options.runner ?? new ProcessLimaRunner();\n\t\tthis.portAllocator = options.portAllocator ?? allocateSandboxDaemonPort;\n\t\tthis.readinessWaiter = options.readinessWaiter ?? waitForLimaDaemon;\n\t\tthis.managedInstances = options.managedInstances ?? new Map();\n\t}\n\n\tresolveConfig(overrides: SandboxConfigOverrides = {}): SandboxConfig {\n\t\treturn resolveSandboxConfig(this.settingsManager?.getSandboxSettings(), this.env, overrides);\n\t}\n\n\tprivate async listRecords(config: SandboxConfig, name?: string): Promise<LimaListRecord[]> {\n\t\tconst args = [\"list\", \"--json\", ...(name ? [name] : [])];\n\t\ttry {\n\t\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\t\tif (\n\t\t\t\tname &&\n\t\t\t\tresult.exitCode !== 0 &&\n\t\t\t\t/unmatched|not found|does not exist/i.test(`${result.stderr}\\n${result.stdout}`)\n\t\t\t) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tensureLimaSuccessful(config.limaBinary, result, args);\n\t\t\treturn parseLimaRecords(result.stdout);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(redactSecrets(`Lima is unavailable or not reachable via ${config.limaBinary}: ${message}`));\n\t\t}\n\t}\n\n\t/** Read-only validation: no VM creation, daemon restart, token rotation or ownership claim. */\n\tasync inspectSharedInstance(options: SharedLimaInstanceOptions): Promise<SharedLimaInstanceInspection> {\n\t\tconst config = this.resolveConfig();\n\t\tconst { instanceName } = options;\n\t\tif (!/^[a-z0-9][a-z0-9-]*$/.test(instanceName)) throw new Error(\"Invalid shared Lima instance name\");\n\t\tif (config.daemonHostBind !== \"127.0.0.1\" && config.daemonHostBind !== \"::1\") {\n\t\t\tthrow new Error(\"Shared Lima daemon forward must bind to loopback\");\n\t\t}\n\t\tconst binding = await resolveSharedLimaWorkspace(options.hostParent, config.workspaceMountPath, options.hostRoot);\n\t\tconst records = await this.listRecords(config, instanceName);\n\t\tif (records.length !== 1 || records[0]?.name !== instanceName) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} does not exist by exact name`);\n\t\t}\n\t\tconst record = records[0];\n\t\tif (record.status?.toLowerCase() !== \"running\") {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} is not running`);\n\t\t}\n\t\tconst mounts = record.config?.mounts?.filter((mount) => mount.mountPoint === binding.guestParent) ?? [];\n\t\tif (mounts.length !== 1 || !mounts[0]?.writable || !mounts[0].location) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} requires one writable fixed parent mount`);\n\t\t}\n\t\tif ((await realpath(mounts[0].location)) !== binding.hostParent) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} mounts a different host parent`);\n\t\t}\n\t\tconst forwards =\n\t\t\trecord.config?.portForwards?.filter(\n\t\t\t\t(forward) => forward.guestPort === config.daemonPort || forward.hostPort === config.daemonPort,\n\t\t\t) ?? [];\n\t\tif (\n\t\t\tforwards.length !== 1 ||\n\t\t\tforwards[0]?.guestPort !== config.daemonPort ||\n\t\t\tforwards[0].hostPort !== config.daemonPort ||\n\t\t\tforwards[0].hostIP !== config.daemonHostBind\n\t\t) {\n\t\t\tthrow new Error(`Shared Lima instance ${instanceName} requires one matching loopback daemon forward`);\n\t\t}\n\t\treturn {\n\t\t\t...binding,\n\t\t\tinstanceName,\n\t\t\tdaemonUrl: `ws://${urlHost(config.daemonHostBind)}:${config.daemonPort}${DAEMON_WEBSOCKET_PATH}`,\n\t\t};\n\t}\n\t/** Reinspect and reuse the supervised guest daemon under the exclusive named-VM owner lock. */\n\tasync ensureSharedDaemon(\n\t\toptions: SharedLimaInstanceOptions,\n\t\towner: SharedLimaOwnerLock,\n\t\tupdated = false,\n\t): Promise<string> {\n\t\tif (owner.instanceName !== options.instanceName) throw new Error(\"Shared Lima owner lock names a different VM\");\n\t\tawait owner.assertHeld();\n\t\tawait this.inspectSharedInstance(options);\n\t\tconst config = this.resolveConfig();\n\t\tconst local = this.env.GRIP_SANDBOX_GUEST_BINARY\n\t\t\t? await inspectLocalGuestBinary(this.env.GRIP_SANDBOX_GUEST_BINARY)\n\t\t\t: undefined;\n\t\tconst versionArgs = [\n\t\t\t\"shell\",\n\t\t\t\"--tty=false\",\n\t\t\toptions.instanceName,\n\t\t\t\"sh\",\n\t\t\t\"-lc\",\n\t\t\tlocal || updated ? '\"$HOME/.local/bin/grip\" --version' : \"grip --version\",\n\t\t];\n\t\tconst version = await this.runner.run(config.limaBinary, versionArgs);\n\t\tif (version.exitCode !== 0 || version.stdout.trim() !== VERSION) {\n\t\t\tthrow new Error(\"Shared Lima grip version mismatch or binary missing; install the matching version manually\");\n\t\t}\n\t\tawait owner.assertHeld();\n\t\tconst directory = \"$HOME/.cache/grip/shared-lima\";\n\t\t// /proc start time plus boot ID distinguishes a recycled PID or a rebooted guest.\n\t\t// kill -0 also succeeds for zombies, which must never be reused as a live daemon.\n\t\tconst processStartTime = `awk '{ sub(/^.*\\\\) /, \"\"); if ($1 == \"Z\" || $1 == \"X\") exit 1; print $20 }'`;\n\t\tconst script = [\n\t\t\t\"set -eu\",\n\t\t\t\"umask 077\",\n\t\t\t`directory=\"${directory}\"`,\n\t\t\t// Both current modes reserve the guest transition; a crashed reservation is operator-owned.\n\t\t\t'mkdir -p \"$HOME/.cache/grip\"',\n\t\t\t'mode_lock=\"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t'mkdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap 'rmdir \\\"$mode_lock\\\" 2>/dev/null || true' EXIT\",\n\t\t\t// A legacy per-session daemon may own this VM or its port. Do not start a second daemon.\n\t\t\t'for legacy_file in \"$HOME/.cache/grip\"/sandbox-daemon-*.pid \"$HOME/.cache/grip\"/sandbox-daemon-*.log; do',\n\t\t\t' if test -e \"$legacy_file\" || test -L \"$legacy_file\"; then exit 27; fi',\n\t\t\t\"done\",\n\t\t\t// A transient user service must outlive the Lima SSH session. Do not mutate\n\t\t\t// private state unless the guest manager is running and linger was enabled by an operator.\n\t\t\t\"command -v systemd-run >/dev/null && systemctl --user show-environment >/dev/null || exit 29\",\n\t\t\t'test \"$(loginctl show-user \"$(id -un)\" --property=Linger --value)\" = yes || exit 29',\n\t\t\t`mkdir -p \"$directory\"; test ! -L \"$directory\"; chmod 700 \"$directory\"`,\n\t\t\t'rmdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap - EXIT\",\n\t\t\t`token_file=\"$directory/daemon-${config.daemonPort}.token\"`,\n\t\t\t`pid_file=\"$directory/daemon-${config.daemonPort}.pid\"`,\n\t\t\t`identity_file=\"$directory/daemon-${config.daemonPort}.identity\"`,\n\t\t\t`log_file=\"$directory/daemon-${config.daemonPort}.log\"`,\n\t\t\t`start_lock=\"$directory/daemon-${config.daemonPort}.starting\"`,\n\t\t\t`unit=\"grip-shared-lima-${config.daemonPort}.service\"`,\n\t\t\t'test ! -L \"$token_file\"; test ! -L \"$pid_file\"; test ! -L \"$identity_file\"; test ! -L \"$log_file\"',\n\t\t\t'if test -e \"$log_file\"; then test -f \"$log_file\" && test \"$(stat -c %a \"$log_file\")\" = 600 || exit 22; fi',\n\t\t\t'test ! -e \"$start_lock\" && test ! -L \"$start_lock\" || exit 26',\n\t\t\t'if test -e \"$token_file\" || test -e \"$pid_file\" || test -e \"$identity_file\"; then',\n\t\t\t' test -f \"$token_file\" && test -f \"$pid_file\" && test -f \"$identity_file\" || exit 21',\n\t\t\t' test \"$(stat -c %a \"$token_file\")\" = 600 || exit 22',\n\t\t\t' test \"$(stat -c %a \"$pid_file\")\" = 600 || exit 22',\n\t\t\t' test \"$(stat -c %a \"$identity_file\")\" = 600 || exit 22',\n\t\t\t' pid=\"$(cat \"$pid_file\")\"',\n\t\t\t\" case \\\"$pid\\\" in ''|*[!0-9]*) exit 23;; esac\",\n\t\t\t' kill -0 \"$pid\" || exit 24',\n\t\t\t` start_time=\"$(${processStartTime} \"/proc/$pid/stat\")\" || exit 25`,\n\t\t\t' boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\" || exit 25',\n\t\t\t' test -n \"$start_time\" && test -n \"$boot_id\" && test \"$(cat \"$identity_file\")\" = \"$boot_id:$start_time\" || exit 25',\n\t\t\t' test \"$(systemctl --user show -P MainPID \"$unit\")\" = \"$pid\" && systemctl --user is-active --quiet \"$unit\" || exit 25',\n\t\t\t' token=\"$(cat \"$token_file\")\"',\n\t\t\t\"else\",\n\t\t\t' mkdir \"$start_lock\" || exit 26',\n\t\t\t\" trap 'rmdir \\\"$start_lock\\\" 2>/dev/null || true' EXIT\",\n\t\t\t\" token=\\\"$(head -c 32 /dev/urandom | base64 | tr -d '\\\\n')\\\"\",\n\t\t\t' printf \\'%s\\' \"$token\" >\"$token_file\"',\n\t\t\t' chmod 600 \"$token_file\"',\n\t\t\t// The systemd user manager owns the process. It reads the private token file\n\t\t\t// inside the unit, never from a systemd-run argument or environment property.\n\t\t\tlocal\n\t\t\t\t? ' grip_bin=\"$HOME/.local/bin/grip\"; test -x \"$grip_bin\"'\n\t\t\t\t: ' grip_bin=\"$(command -v grip)\"; case \"$grip_bin\" in /*) ;; *) exit 25;; esac',\n\t\t\t` systemd-run --user --unit=\"$unit\" --property=Restart=no --property=KillMode=control-group -- sh -c 'set -eu; umask 077; GRIP_DAEMON_TOKEN=\"$(cat \"$HOME/.cache/grip/shared-lima/daemon-${config.daemonPort}.token\")\"; test -n \"$GRIP_DAEMON_TOKEN\"; export GRIP_DAEMON_TOKEN; exec \"$1\" --daemon --daemon-host 127.0.0.1 --daemon-allow-insecure-transport --daemon-port ${config.daemonPort} --daemon-cwd \"$2\" --daemon-shared-parent \"$2\" --daemon-allow-root --daemon-allow-process-exec >\"$HOME/.cache/grip/shared-lima/daemon-${config.daemonPort}.log\" 2>&1 </dev/null' sh \"$grip_bin\" ${shellQuote(config.workspaceMountPath)} >/dev/null`,\n\t\t\t' pid=\"\"; attempts=0',\n\t\t\t' while test \"$attempts\" -lt 50; do',\n\t\t\t' pid=\"$(systemctl --user show -P MainPID \"$unit\")\" || exit 25',\n\t\t\t' case \"$pid\" in \"\"|0) sleep 0.1;; *[!0-9]*) exit 25;; *) break;; esac',\n\t\t\t\" attempts=$((attempts + 1))\",\n\t\t\t\" done\",\n\t\t\t' case \"$pid\" in \"\"|0|*[!0-9]*) exit 25;; esac',\n\t\t\t' systemctl --user is-active --quiet \"$unit\" || exit 25',\n\t\t\t' printf \\'%s\\' \"$pid\" >\"$pid_file\"',\n\t\t\t' chmod 600 \"$pid_file\"',\n\t\t\t` start_time=\"$(${processStartTime} \"/proc/$pid/stat\")\" || exit 25`,\n\t\t\t' boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\" || exit 25',\n\t\t\t' test -n \"$start_time\" && test -n \"$boot_id\" || exit 25',\n\t\t\t' printf \\'%s:%s\\' \"$boot_id\" \"$start_time\" >\"$identity_file\"',\n\t\t\t' chmod 600 \"$identity_file\"',\n\t\t\t' rmdir \"$start_lock\" || exit 26',\n\t\t\t\" trap - EXIT\",\n\t\t\t\"fi\",\n\t\t\t\"printf 'GRIP_SHARED_TOKEN=%s\\\\n' \\\"$token\\\"\",\n\t\t].join(\"\\n\");\n\t\tconst args = [\"shell\", \"--tty=false\", options.instanceName, \"sh\", \"-lc\", script];\n\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\t// Never include stdout/stderr from a credential-bearing shell in an error.\n\t\tif (result.exitCode !== 0)\n\t\t\tthrow new Error(\"Shared Lima daemon state is uncertain; reconcile guest PID/token files manually\");\n\t\tconst token = result.stdout.match(/(?:^|\\n)GRIP_SHARED_TOKEN=([A-Za-z0-9+/]{43}=)(?:\\r?\\n|$)/)?.[1];\n\t\tif (!token) throw new Error(\"Shared Lima daemon did not return a valid credential; reconcile manually\");\n\t\tawait this.readinessWaiter(config.daemonHostBind, config.daemonPort);\n\t\t// Readiness can outlive the owner. Never hand a guest credential to a lost owner.\n\t\tawait owner.assertHeld();\n\t\treturn token;\n\t}\n\n\t/** Update only a verified supervised daemon. Staging happens before disconnecting peers. */\n\tprivate async updateSharedDaemon(options: SharedLimaInstanceOptions, owner: SharedLimaOwnerLock): Promise<void> {\n\t\tawait owner.assertHeld();\n\t\tawait this.inspectSharedInstance(options);\n\t\tconst config = this.resolveConfig();\n\t\tconst name = options.instanceName;\n\t\tconst port = config.daemonPort;\n\t\tif (!this.env.GRIP_SANDBOX_GUEST_BINARY && process.argv[1]?.endsWith(\"/packages/coding-agent/src/cli.ts\")) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Development sandbox update requires GRIP_SANDBOX_GUEST_BINARY pointing to a built Linux Grip executable\",\n\t\t\t);\n\t\t}\n\t\tconst local = this.env.GRIP_SANDBOX_GUEST_BINARY\n\t\t\t? await inspectLocalGuestBinary(this.env.GRIP_SANDBOX_GUEST_BINARY)\n\t\t\t: undefined;\n\t\tconst shell = (script: string) =>\n\t\t\tthis.runner.run(config.limaBinary, [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script]);\n\t\tconst directory = \"$HOME/.cache/grip/shared-lima\";\n\t\tconst unit = `grip-shared-lima-${port}.service`;\n\t\tconst verify = [\n\t\t\t\"set -eu\",\n\t\t\t`directory=\"${directory}\"`,\n\t\t\t`unit=${shellQuote(unit)}`,\n\t\t\t'test -d \"$directory\" && test ! -L \"$directory\"',\n\t\t\t'test ! -e \"$HOME/.cache/grip/daemon-mode.lock\" && test ! -L \"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t`token_file=\"$directory/daemon-${port}.token\"`,\n\t\t\t`pid_file=\"$directory/daemon-${port}.pid\"`,\n\t\t\t`identity_file=\"$directory/daemon-${port}.identity\"`,\n\t\t\t'for file in \"$token_file\" \"$pid_file\" \"$identity_file\"; do test -f \"$file\" && test ! -L \"$file\" && test \"$(stat -c %a \"$file\")\" = 600; done',\n\t\t\t'pid=\"$(cat \"$pid_file\")\"; case \"$pid\" in \"\"|0|*[!0-9]*) exit 45;; esac',\n\t\t\t'kill -0 \"$pid\"',\n\t\t\t`start_time=\"$(awk '{ sub(/^.*\\\\) /, \"\"); if ($1 == \"Z\" || $1 == \"X\") exit 1; print $20 }' \"/proc/$pid/stat\")\"`,\n\t\t\t'boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\"',\n\t\t\t'test -n \"$start_time\" && test \"$(cat \"$identity_file\")\" = \"$boot_id:$start_time\"',\n\t\t\t'test \"$(systemctl --user show -P MainPID \"$unit\")\" = \"$pid\" && systemctl --user is-active --quiet \"$unit\"',\n\t\t\t'case \"$(systemctl --user show -P ExecStart \"$unit\")\" in *\"$HOME/.local/bin/grip\"*) ;; *) exit 46;; esac',\n\t\t];\n\t\tconst preflight = await shell(verify.join(\"\\n\"));\n\t\tif (preflight.exitCode !== 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Shared Lima daemon identity or binary path is uncertain; update refused without disconnecting clients\",\n\t\t\t);\n\t\t}\n\t\tconst staged = await stageSharedGuestBinary(this.runner, config.limaBinary, name, unit, VERSION, local);\n\t\ttry {\n\t\t\tawait owner.assertHeld();\n\t\t\tconst stop = await shell(\n\t\t\t\t[\n\t\t\t\t\t...verify,\n\t\t\t\t\t'mkdir \"$HOME/.cache/grip/daemon-mode.lock\" || exit 45',\n\t\t\t\t\t'trap \\u0027rmdir \"$HOME/.cache/grip/daemon-mode.lock\" 2>/dev/null || true\\u0027 EXIT',\n\t\t\t\t\t'systemctl --user stop \"$unit\"',\n\t\t\t\t\t'test \"$(systemctl --user show -P MainPID \"$unit\")\" = 0',\n\t\t\t\t\t'! kill -0 \"$pid\" 2>/dev/null',\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tif (stop.exitCode !== 0)\n\t\t\t\tthrow new Error(\"Shared daemon stop is uncertain; inspect the guest before retrying update\");\n\t\t\tawait owner.assertHeld();\n\t\t\tawait staged.install();\n\t\t\tawait owner.assertHeld();\n\t\t\tconst restart = await shell(\n\t\t\t\t[\n\t\t\t\t\t\"set -eu\",\n\t\t\t\t\t`directory=\"${directory}\"`,\n\t\t\t\t\t`unit=${shellQuote(unit)}`,\n\t\t\t\t\t'test -d \"$directory\" && test ! -L \"$directory\"',\n\t\t\t\t\t`token_file=\"$directory/daemon-${port}.token\"`,\n\t\t\t\t\t`pid_file=\"$directory/daemon-${port}.pid\"`,\n\t\t\t\t\t`identity_file=\"$directory/daemon-${port}.identity\"`,\n\t\t\t\t\t'for file in \"$token_file\" \"$pid_file\" \"$identity_file\"; do test -f \"$file\" && test ! -L \"$file\" && test \"$(stat -c %a \"$file\")\" = 600; done',\n\t\t\t\t\t'test ! -e \"$HOME/.cache/grip/daemon-mode.lock\" && test ! -L \"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t\t\t'mkdir \"$HOME/.cache/grip/daemon-mode.lock\" || exit 45',\n\t\t\t\t\t'trap \\u0027rmdir \"$HOME/.cache/grip/daemon-mode.lock\" 2>/dev/null || true\\u0027 EXIT',\n\t\t\t\t\t'old_pid=\"$(cat \"$pid_file\")\"; case \"$old_pid\" in \"\"|0|*[!0-9]*) exit 45;; esac',\n\t\t\t\t\t'! kill -0 \"$old_pid\" 2>/dev/null',\n\t\t\t\t\t`test \"$(\"$HOME/.local/bin/grip\" --version)\" = ${shellQuote(VERSION)}`,\n\t\t\t\t\t'load=\"$(systemctl --user show -P LoadState \"$unit\" 2>/dev/null || true)\"',\n\t\t\t\t\t'case \"$load\" in',\n\t\t\t\t\t' loaded) test \"$(systemctl --user show -P MainPID \"$unit\")\" = 0; systemctl --user start \"$unit\" ;;',\n\t\t\t\t\t' not-found|\"\")',\n\t\t\t\t\t` systemd-run --user --unit=\"$unit\" --property=Restart=no --property=KillMode=control-group -- sh -c 'set -eu; umask 077; GRIP_DAEMON_TOKEN=\"$(cat \"$HOME/.cache/grip/shared-lima/daemon-${port}.token\")\"; test -n \"$GRIP_DAEMON_TOKEN\"; export GRIP_DAEMON_TOKEN; exec \"$1\" --daemon --daemon-host 127.0.0.1 --daemon-allow-insecure-transport --daemon-port ${port} --daemon-cwd \"$2\" --daemon-shared-parent \"$2\" --daemon-allow-root --daemon-allow-process-exec >\"$HOME/.cache/grip/shared-lima/daemon-${port}.log\" 2>&1 </dev/null' sh \"$HOME/.local/bin/grip\" ${shellQuote(config.workspaceMountPath)} >/dev/null ;;`,\n\t\t\t\t\t\" *) exit 45 ;;\",\n\t\t\t\t\t\"esac\",\n\t\t\t\t\t'pid=\"\"; attempts=0',\n\t\t\t\t\t'while test \"$attempts\" -lt 50; do',\n\t\t\t\t\t' pid=\"$(systemctl --user show -P MainPID \"$unit\")\" || exit 45',\n\t\t\t\t\t' case \"$pid\" in \"\"|0) sleep 0.1;; *[!0-9]*) exit 45;; *) break;; esac',\n\t\t\t\t\t\" attempts=$((attempts + 1))\",\n\t\t\t\t\t\"done\",\n\t\t\t\t\t'case \"$pid\" in \"\"|0|*[!0-9]*) exit 45;; esac',\n\t\t\t\t\t'kill -0 \"$pid\"; systemctl --user is-active --quiet \"$unit\"',\n\t\t\t\t\t`start_time=\"$(awk '{ sub(/^.*\\\\) /, \"\"); if ($1 == \"Z\" || $1 == \"X\") exit 1; print $20 }' \"/proc/$pid/stat\")\"`,\n\t\t\t\t\t'boot_id=\"$(cat /proc/sys/kernel/random/boot_id)\"',\n\t\t\t\t\t'test -n \"$start_time\" && test -n \"$boot_id\"',\n\t\t\t\t\t'printf \"%s\" \"$pid\" >\"$pid_file\"',\n\t\t\t\t\t'printf \"%s:%s\" \"$boot_id\" \"$start_time\" >\"$identity_file\"',\n\t\t\t\t\t'chmod 600 \"$pid_file\" \"$identity_file\"',\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tif (restart.exitCode !== 0)\n\t\t\t\tthrow new Error(\"Shared daemon restart is uncertain; inspect the guest before retrying update\");\n\t\t\tawait this.readinessWaiter(config.daemonHostBind, port);\n\t\t\tawait owner.assertHeld();\n\t\t} finally {\n\t\t\tawait staged.cleanup();\n\t\t}\n\t}\n\n\tprivate async startInstance(\n\t\tconfig: SandboxConfig,\n\t\tworkspaceRoot: string,\n\t\tname: string,\n\t\tdaemonPort: number,\n\t): Promise<void> {\n\t\tconst mountExpression = `.mounts = [{\"location\":${JSON.stringify(workspaceRoot)},\"mountPoint\":${JSON.stringify(config.workspaceMountPath)},\"writable\":true}]`;\n\t\tconst forwardExpression = `.portForwards += [{\"guestPort\":${daemonPort},\"hostPort\":${daemonPort},\"hostIP\":${JSON.stringify(config.daemonHostBind)}}]`;\n\t\tconst args = [\n\t\t\t\"start\",\n\t\t\t\"--tty=false\",\n\t\t\t\"--name\",\n\t\t\tname,\n\t\t\t\"--mount-none\",\n\t\t\t\"--set\",\n\t\t\tmountExpression,\n\t\t\t\"--set\",\n\t\t\tforwardExpression,\n\t\t\tconfig.limaTemplate,\n\t\t];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\n\tprivate async ensureGrip(\n\t\tconfig: SandboxConfig,\n\t\tname: string,\n\t\texisting: boolean,\n\t\tlocal?: LocalGuestBinary,\n\t): Promise<void> {\n\t\tif (local) {\n\t\t\tawait installLocalGuestBinary(this.runner, config.limaBinary, name, local, VERSION);\n\t\t\treturn;\n\t\t}\n\t\tconst checkArgs = [\n\t\t\t\"shell\",\n\t\t\t\"--tty=false\",\n\t\t\tname,\n\t\t\t\"sh\",\n\t\t\t\"-lc\",\n\t\t\t'command -v grip >/dev/null || test -x \"$HOME/.local/bin/grip\"',\n\t\t];\n\t\tconst check = await this.runner.run(config.limaBinary, checkArgs);\n\t\tif (check.exitCode === 0) return;\n\t\t// Existing named VMs can be bootstrapped too. Keep managed VMs pinned to\n\t\t// the host release; use the latest published release for user-owned VMs.\n\t\tconst version = existing ? \"\" : `GRIP_VERSION=${shellQuote(`v${VERSION}`)} `;\n\t\tconst script = `set -eu; tmp=\"$(mktemp)\"; trap 'rm -f \"$tmp\"' EXIT; curl -fsSL -o \"$tmp\" https://raw.githubusercontent.com/greppleai/grip/main/install.sh; ${version}sh \"$tmp\"; test -x \"$HOME/.local/bin/grip\"`;\n\t\tconst args = [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\t/** A legacy named attach or stop must not rotate or kill a shared guest daemon. */\n\tprivate async assertNoSharedGuestState(\n\t\tconfig: SandboxConfig,\n\t\tname: string,\n\t\toperation: LegacyLimaGuestStateOperation = \"attach\",\n\t): Promise<void> {\n\t\tconst script = 'test ! -e \"$HOME/.cache/grip/shared-lima\" && test ! -L \"$HOME/.cache/grip/shared-lima\"';\n\t\tconst args = [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script];\n\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\t// A guest shell failure is ambiguous too; never guess that shared state is absent.\n\t\tif (result.exitCode !== 0) {\n\t\t\tthrow new Error(`Lima named VM may host a shared daemon; legacy ${operation} refused; reconcile manually`);\n\t\t}\n\t}\n\n\tprivate async startDaemon(config: SandboxConfig, name: string): Promise<string> {\n\t\tconst pidFile = `.cache/grip/sandbox-daemon-${config.daemonPort}.pid`;\n\t\tconst logFile = `.cache/grip/sandbox-daemon-${config.daemonPort}.log`;\n\t\tconst script = [\n\t\t\t\"set -eu\",\n\t\t\t\"umask 077\",\n\t\t\t`mkdir -p \"$HOME/.cache/grip\"`,\n\t\t\t'mode_lock=\"$HOME/.cache/grip/daemon-mode.lock\"',\n\t\t\t'mkdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap 'rmdir \\\"$mode_lock\\\" 2>/dev/null || true' EXIT\",\n\t\t\t'test ! -e \"$HOME/.cache/grip/shared-lima\" && test ! -L \"$HOME/.cache/grip/shared-lima\" || exit 29',\n\t\t\t`if test -f \"$HOME/${pidFile}\"; then old_pid=\"$(cat \"$HOME/${pidFile}\")\"; kill \"$old_pid\" 2>/dev/null || true; fi`,\n\t\t\t`token=\"$(head -c 32 /dev/urandom | base64 | tr -d '\\\\n')\"`,\n\t\t\t`nohup env GRIP_DAEMON_TOKEN=\"$token\" \"${this.env.GRIP_SANDBOX_GUEST_BINARY ? \"$HOME/.local/bin/grip\" : '$(command -v grip || printf %s \"$HOME/.local/bin/grip\")'}\" --daemon --daemon-host 127.0.0.1 --daemon-allow-insecure-transport --daemon-port ${config.daemonPort} --daemon-cwd ${shellQuote(config.workspaceMountPath)} --daemon-allow-root --daemon-allow-process-exec >\"$HOME/${logFile}\" 2>&1 </dev/null &`,\n\t\t\t`echo $! >\"$HOME/${pidFile}\"`,\n\t\t\t'rmdir \"$mode_lock\" || exit 28',\n\t\t\t\"trap - EXIT\",\n\t\t\t`printf 'GRIP_SANDBOX_TOKEN=%s\\\\n' \"$token\"`,\n\t\t].join(\"\\n\");\n\t\tconst args = [\"shell\", \"--tty=false\", \"--workdir\", config.workspaceMountPath, name, \"sh\", \"-lc\", script];\n\t\tconst result = await this.runner.run(config.limaBinary, args);\n\t\tensureLimaSuccessful(config.limaBinary, result, args);\n\t\tconst token = result.stdout.match(/(?:^|\\n)GRIP_SANDBOX_TOKEN=([^\\r\\n]+)/)?.[1];\n\t\tif (!token) throw new Error(`Lima instance ${name} started the daemon without returning an authentication token`);\n\t\treturn token;\n\t}\n\n\tprivate async prepareExistingInstance(\n\t\tconfig: SandboxConfig,\n\t\trecord: LimaListRecord,\n\t\tname: string,\n\t\tworkspaceRoot: string,\n\t): Promise<void> {\n\t\tconst mount = findWorkspaceMount(record, config.workspaceMountPath);\n\t\tif (!mount || resolve(mount.location ?? \"\") !== workspaceRoot || !mount.writable) {\n\t\t\tthrow new Error(\n\t\t\t\t`Lima instance ${name} must mount ${workspaceRoot} read-write at ${config.workspaceMountPath}`,\n\t\t\t);\n\t\t}\n\t\tconst status = record.status?.toLowerCase();\n\t\tif (status === \"running\") return;\n\t\tif (status !== \"stopped\") {\n\t\t\tthrow new Error(`Lima instance ${name} is in an uncertain state; refusing to resume`);\n\t\t}\n\t\tconst args = [\"start\", \"--tty=false\", name];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\n\tprivate async findExactLegacyInstance(config: SandboxConfig, name?: string): Promise<LimaListRecord | undefined> {\n\t\tif (!name) return undefined;\n\t\tconst records = await this.listRecords(config, name);\n\t\tif (records.length === 0) return undefined;\n\t\tif (records.length !== 1 || records[0]?.name !== name) {\n\t\t\tthrow new Error(\"Lima instance lookup did not return one exact name; refusing to attach or create\");\n\t\t}\n\t\treturn records[0];\n\t}\n\n\tasync start(options: SandboxStartOptions): Promise<SandboxStartResult> {\n\t\tconst requestedName = options.name?.trim();\n\t\tif (!requestedName) {\n\t\t\tif (options.update) throw new Error(\"Sandbox update requires a named running shared VM\");\n\t\t\treturn this.startWithLegacyInstance(options);\n\t\t}\n\t\t// Coordinate VM resume/create as well as guest daemon launch with a named shared owner.\n\t\t// A stale lock is ambiguous, not permission to start an existing VM.\n\t\tconst owner = await acquireSharedLimaOwnerLock(requestedName);\n\t\ttry {\n\t\t\tconst config = this.resolveConfig(options);\n\t\t\tconst existing = await this.findExactLegacyInstance(config, requestedName);\n\t\t\tif (options.update && existing?.status?.toLowerCase() !== \"running\") {\n\t\t\t\tthrow new Error(\"Sandbox update requires an existing running shared VM\");\n\t\t\t}\n\t\t\tif (existing?.status?.toLowerCase() !== \"running\") {\n\t\t\t\treturn await this.startWithLegacyInstance(options, { record: existing });\n\t\t\t}\n\t\t\t// Select the guest mode before any legacy setup. An unreadable or ambiguous\n\t\t\t// marker is not permission to start a per-session daemon in this VM.\n\t\t\tconst probe = await this.runner.run(config.limaBinary, [\n\t\t\t\t\"shell\",\n\t\t\t\t\"--tty=false\",\n\t\t\t\trequestedName,\n\t\t\t\t\"sh\",\n\t\t\t\t\"-lc\",\n\t\t\t\t'if test -e \"$HOME/.cache/grip/shared-lima\" || test -L \"$HOME/.cache/grip/shared-lima\"; then if test -d \"$HOME/.cache/grip/shared-lima\" && test ! -L \"$HOME/.cache/grip/shared-lima\"; then printf \"GRIP_SHARED_GUEST\\\\n\"; else exit 42; fi; else printf \"GRIP_LEGACY_GUEST\\\\n\"; fi',\n\t\t\t]);\n\t\t\tif (probe.exitCode !== 0) throw new Error(\"Lima guest daemon mode is uncertain; refusing named attach\");\n\t\t\tif (probe.stdout.trim() === \"GRIP_LEGACY_GUEST\") {\n\t\t\t\tif (options.update)\n\t\t\t\t\tthrow new Error(\"Sandbox update requires a supervised shared guest; legacy guest is unchanged\");\n\t\t\t\treturn await this.startWithLegacyInstance(options, { record: existing });\n\t\t\t}\n\t\t\tif (probe.stdout.trim() !== \"GRIP_SHARED_GUEST\") {\n\t\t\t\tthrow new Error(\"Lima guest daemon mode is uncertain; refusing named attach\");\n\t\t\t}\n\t\t\tawait owner.assertHeld();\n\t\t\tconst mount = findWorkspaceMount(existing, config.workspaceMountPath);\n\t\t\tif (!mount?.location) throw new Error(\"Shared Lima instance mount is unavailable; refusing attach\");\n\t\t\tconst sharedOptions = {\n\t\t\t\tinstanceName: requestedName,\n\t\t\t\thostParent: resolve(mount.location),\n\t\t\t\thostRoot: resolve(options.workspaceRoot),\n\t\t\t};\n\t\t\tconst inspection = await this.inspectSharedInstance(sharedOptions);\n\t\t\tif (options.update) await this.updateSharedDaemon(sharedOptions, owner);\n\t\t\tconst token = await this.ensureSharedDaemon(sharedOptions, owner, options.update);\n\t\t\tconst daemonUrl = `grip+${inspection.daemonUrl}?root=${encodeURIComponent(inspection.guestRoot)}`;\n\t\t\treturn {\n\t\t\t\tcontainerId: requestedName,\n\t\t\t\tcontainerName: requestedName,\n\t\t\t\tworkspaceRoot: inspection.hostRoot,\n\t\t\t\tworkspaceMountPath: inspection.guestRoot,\n\t\t\t\tdaemonUrl,\n\t\t\t\tdaemonUrlRedacted: inspection.daemonUrl,\n\t\t\t\ttoken,\n\t\t\t\tlabels: { [`${SANDBOX_LABEL_PREFIX}.runtime`]: \"lima\", [`${SANDBOX_LABEL_PREFIX}.version`]: VERSION },\n\t\t\t};\n\t\t} finally {\n\t\t\tawait owner.release();\n\t\t}\n\t}\n\n\tprivate async startWithLegacyInstance(\n\t\toptions: SandboxStartOptions,\n\t\tknown?: KnownLimaRecord,\n\t): Promise<SandboxStartResult> {\n\t\tconst workspaceRoot = resolve(options.workspaceRoot);\n\t\tconst local = this.env.GRIP_SANDBOX_GUEST_BINARY\n\t\t\t? await inspectLocalGuestBinary(this.env.GRIP_SANDBOX_GUEST_BINARY)\n\t\t\t: undefined;\n\t\tconst config = this.resolveConfig(options);\n\t\tconst requestedName = options.name?.trim();\n\t\tconst managed = !requestedName;\n\t\tconst existing = known ? known.record : await this.findExactLegacyInstance(config, requestedName);\n\t\tif (existing) await this.prepareExistingInstance(config, existing, requestedName!, workspaceRoot);\n\t\tconst configuredForward = existing ? findDaemonForward(existing, config.daemonPort) : undefined;\n\t\tif (configuredForward && configuredForward.guestPort !== configuredForward.hostPort) {\n\t\t\tthrow new Error(\n\t\t\t\t`Lima instance ${requestedName} must forward the sandbox daemon on the same guest and host port`,\n\t\t\t);\n\t\t}\n\t\tconst daemonPort =\n\t\t\tconfiguredForward?.hostPort ?? (await this.portAllocator(config.daemonHostBind, config.daemonPort));\n\t\tconst name =\n\t\t\trequestedName ?? createInstanceName(config, workspaceRoot, options.sessionId ?? \"session\", daemonPort);\n\t\tconst effectiveConfig = { ...config, daemonPort };\n\t\tif (!existing) await this.startInstance(effectiveConfig, workspaceRoot, name, daemonPort);\n\t\t// A failed guest install/start can have changed state; never delete an uncertain VM.\n\t\tif (existing) await this.assertNoSharedGuestState(effectiveConfig, name);\n\t\tawait this.ensureGrip(effectiveConfig, name, !!existing, local);\n\t\tconst token = await this.startDaemon(effectiveConfig, name);\n\t\tawait this.readinessWaiter(config.daemonHostBind, daemonPort);\n\t\t// A failed readiness check is not proof that this daemon is ours to stop.\n\t\t// Leave uncertain guest state for explicit operator reconciliation.\n\t\tthis.managedInstances.set(name, { workspaceRoot, daemonPort, ownerId: options.sessionId, managed });\n\t\tconst daemonUrl = `ws://${urlHost(daemonConnectionHost(config.daemonHostBind))}:${daemonPort}${DAEMON_WEBSOCKET_PATH}`;\n\t\treturn {\n\t\t\tcontainerId: name,\n\t\t\tcontainerName: name,\n\t\t\tworkspaceRoot,\n\t\t\tworkspaceMountPath: config.workspaceMountPath,\n\t\t\tdaemonUrl,\n\t\t\tdaemonUrlRedacted: daemonUrl,\n\t\t\ttoken,\n\t\t\tlabels: { [`${SANDBOX_LABEL_PREFIX}.runtime`]: \"lima\", [`${SANDBOX_LABEL_PREFIX}.version`]: VERSION },\n\t\t};\n\t}\n\n\tasync list(options: SandboxListOptions): Promise<SandboxContainer[]> {\n\t\tconst config = this.resolveConfig();\n\t\tconst workspaceRoot = resolve(options.workspaceRoot);\n\t\treturn (await this.listRecords(config))\n\t\t\t.map((record) => toSandboxContainer(record, config.workspaceMountPath))\n\t\t\t.filter(\n\t\t\t\t(instance) => instance.workspaceRoot && (options.allWorkspaces || instance.workspaceRoot === workspaceRoot),\n\t\t\t);\n\t}\n\n\tprivate async stopDaemon(config: SandboxConfig, name: string, daemonPort: number): Promise<void> {\n\t\tconst pidFile = `.cache/grip/sandbox-daemon-${daemonPort}.pid`;\n\t\tconst script = `if test -f \"$HOME/${pidFile}\"; then pid=\"$(cat \"$HOME/${pidFile}\")\"; kill \"$pid\" 2>/dev/null || true; rm -f \"$HOME/${pidFile}\"; fi`;\n\t\tconst args = [\"shell\", \"--tty=false\", name, \"sh\", \"-lc\", script];\n\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t}\n\n\tasync stop(options: SandboxStopOptions): Promise<SandboxStopResult> {\n\t\tconst config = this.resolveConfig();\n\t\tconst instances = await this.list({ workspaceRoot: options.workspaceRoot });\n\t\tconst selected = selectLimaSandbox(instances, options.target ?? options.currentContainerId);\n\t\tif (!selected) return { status: \"not-found\", message: \"No matching Grip Lima sandbox found\" };\n\t\tif (instances.filter((instance) => instance.name === selected.name).length !== 1) {\n\t\t\tthrow new Error(\"Lima sandbox identity is ambiguous; refusing to stop a VM or daemon\");\n\t\t}\n\t\tconst tracked = this.managedInstances.get(selected.name);\n\t\t// Names and Lima's list output do not establish ownership. In particular, a\n\t\t// shared named VM can have the ordinary sandbox prefix without being ours.\n\t\t// Only a VM started by this session may be stopped or have its daemon touched.\n\t\tif (!tracked || tracked.workspaceRoot !== selected.workspaceRoot || tracked.daemonPort !== selected.daemonPort) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Lima sandbox ownership is unknown or daemon port changed; refusing to stop an untracked VM or daemon\",\n\t\t\t);\n\t\t}\n\t\t// A shared guest must never lose its daemon or VM to a legacy\n\t\t// in-process record. Resolve the selected VM again under the host owner lock.\n\t\tconst owner = await acquireSharedLimaOwnerLock(selected.name);\n\t\ttry {\n\t\t\tconst matches = (await this.list({ workspaceRoot: options.workspaceRoot })).filter(\n\t\t\t\t(instance) => instance.name === selected.name,\n\t\t\t);\n\t\t\tconst current = matches[0];\n\t\t\tif (\n\t\t\t\tmatches.length !== 1 ||\n\t\t\t\t!current ||\n\t\t\t\tcurrent.id !== selected.id ||\n\t\t\t\tcurrent.state !== selected.state ||\n\t\t\t\tcurrent.workspaceRoot !== selected.workspaceRoot ||\n\t\t\t\tcurrent.daemonPort !== selected.daemonPort\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Lima sandbox identity changed during stop; refusing to touch the VM or daemon\");\n\t\t\t}\n\t\t\treturn await this.stopTrackedInstance(config, current, tracked);\n\t\t} finally {\n\t\t\tawait owner.release();\n\t\t}\n\t}\n\n\tprivate async stopTrackedInstance(\n\t\tconfig: SandboxConfig,\n\t\tselected: SandboxContainer,\n\t\ttracked: ManagedLimaInstance,\n\t): Promise<SandboxStopResult> {\n\t\tconst ownsInstance = tracked.managed;\n\t\tif (selected.state !== \"running\") {\n\t\t\tif (ownsInstance && config.cleanup === \"remove\") {\n\t\t\t\t// An already stopped VM cannot be probed without resuming it. Its\n\t\t\t\t// in-memory record is not proof it was never repurposed externally.\n\t\t\t\tthrow new Error(\"Lima sandbox is stopped; refusing to delete an unverifiable VM; reconcile manually\");\n\t\t\t}\n\t\t\tthis.managedInstances.delete(selected.name);\n\t\t\treturn { status: \"already-stopped\", container: selected };\n\t\t}\n\t\tawait this.assertNoSharedGuestState(config, selected.name, \"stop\");\n\t\tawait this.stopDaemon(config, selected.name, tracked?.daemonPort ?? selected.daemonPort ?? config.daemonPort);\n\t\tif (ownsInstance) {\n\t\t\tconst args = config.cleanup === \"remove\" ? [\"delete\", \"--force\", selected.name] : [\"stop\", selected.name];\n\t\t\tensureLimaSuccessful(config.limaBinary, await this.runner.run(config.limaBinary, args), args);\n\t\t}\n\t\tthis.managedInstances.delete(selected.name);\n\t\treturn { status: ownsInstance && config.cleanup === \"remove\" ? \"removed\" : \"stopped\", container: selected };\n\t}\n\n\tasync stopManagedInstances(): Promise<void> {\n\t\tconst failures: unknown[] = [];\n\t\tfor (const [name, instance] of [...this.managedInstances]) {\n\t\t\ttry {\n\t\t\t\tawait this.stop({ workspaceRoot: instance.workspaceRoot, target: name, currentContainerId: name });\n\t\t\t} catch (error) {\n\t\t\t\tfailures.push(error);\n\t\t\t}\n\t\t}\n\t\tif (failures.length > 0) throw new AggregateError(failures, \"Failed to stop managed Lima sandbox instances\");\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,4BAA4B,CAAC;AAI7E,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAItD,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAMnG,QAAA,MAAM,UAAU;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAItD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;CAAG;AAwPnC,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;AAEhG,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAoCnH;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAElH","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport { formatBackendIcon, getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\nexport interface FindToolOptions {}\n\nfunction formatFindCall(args: FindToolInput | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: AgentToolResult<FindToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\ntype FindExecutionResult = AgentToolResult<FindToolDetails | undefined>;\n\ninterface FindExecutionRequest {\n\toperations: ToolOperations;\n\tcwd: string;\n\tpattern: string;\n\tsearchDir: string | undefined;\n\tlimit: number | undefined;\n\tsignal: AbortSignal | undefined;\n}\n\ntype RegisterFindChildStop = (stop: () => void) => void;\n\nfunction throwIfFindAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n}\n\nfunction noFindResults(): FindExecutionResult {\n\treturn { content: [{ type: \"text\", text: \"No files found matching pattern\" }], details: undefined };\n}\n\nfunction formatFindMatches(paths: string[], limit: number, includeRefineHint: boolean): FindExecutionResult {\n\tconst resultLimitReached = paths.length >= limit;\n\tconst truncation = truncateHead(paths.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: FindToolDetails = {};\n\tconst notices: string[] = [];\n\tif (resultLimitReached) {\n\t\tnotices.push(\n\t\t\tincludeRefineHint\n\t\t\t\t? `${limit} results limit reached. Use limit=${limit * 2} for more, or refine pattern`\n\t\t\t\t: `${limit} results limit reached`,\n\t\t);\n\t\tdetails.resultLimitReached = limit;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nfunction relativizeGlobMatches(paths: string[], searchPath: string): string[] {\n\treturn paths.map((matchedPath) => {\n\t\tif (matchedPath.startsWith(searchPath)) return toPosixPath(matchedPath.slice(searchPath.length + 1));\n\t\treturn toPosixPath(path.relative(searchPath, matchedPath));\n\t});\n}\n\nasync function executeOperationsFind(\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n): Promise<FindExecutionResult> {\n\ttry {\n\t\tawait request.operations.access(searchPath, \"exists\");\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tthrowIfFindAborted(request.signal);\n\tif (!request.operations.glob) throw new Error(\"Glob operation is unavailable\");\n\tconst results = await request.operations.glob(request.pattern, searchPath, {\n\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\tlimit: effectiveLimit,\n\t});\n\tthrowIfFindAborted(request.signal);\n\tif (results.length === 0) return noFindResults();\n\treturn formatFindMatches(relativizeGlobMatches(results, searchPath), effectiveLimit, false);\n}\n\nfunction buildFdArguments(pattern: string, searchPath: string, limit: number): string[] {\n\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(limit)];\n\tlet effectivePattern = pattern;\n\tif (pattern.includes(\"/\")) {\n\t\targs.push(\"--full-path\");\n\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t}\n\targs.push(\"--\", effectivePattern, searchPath);\n\treturn args;\n}\n\nfunction relativizeFdMatches(lines: string[], searchPath: string): string[] {\n\tconst relativized: string[] = [];\n\tfor (const rawLine of lines) {\n\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\tif (!line) continue;\n\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\tlet relativePath = line;\n\t\tif (line.startsWith(searchPath)) {\n\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t} else {\n\t\t\trelativePath = path.relative(searchPath, line);\n\t\t}\n\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\trelativized.push(toPosixPath(relativePath));\n\t}\n\treturn relativized;\n}\n\nfunction executeFdFind(\n\tfdPath: string,\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tconst child = spawn(fdPath, buildFdArguments(request.pattern, searchPath, effectiveLimit), {\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tlet stderr = \"\";\n\t\tconst lines: string[] = [];\n\t\tregisterStop(() => {\n\t\t\tif (!child.killed) child.kill();\n\t\t});\n\t\tconst cleanup = (): void => rl.close();\n\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => lines.push(line));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\trejectFind(new Error(`Failed to run fd: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tif (request.signal?.aborted) {\n\t\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst output = lines.join(\"\\n\");\n\t\t\tif (code !== 0 && !output) {\n\t\t\t\trejectFind(new Error(stderr.trim() || `fd exited with code ${code}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!output) {\n\t\t\t\tresolveFind(noFindResults());\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolveFind(formatFindMatches(relativizeFdMatches(lines, searchPath), effectiveLimit, true));\n\t\t});\n\t});\n}\n\nasync function dispatchFindExecution(\n\trequest: FindExecutionRequest,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\tconst searchPath = resolveToCwd(request.searchDir || \".\", request.cwd);\n\tconst effectiveLimit = request.limit ?? DEFAULT_LIMIT;\n\tif (request.operations.glob) return executeOperationsFind(request, searchPath, effectiveLimit);\n\tconst fdPath = await ensureTool(\"fd\", true);\n\tthrowIfFindAborted(request.signal);\n\tif (!fdPath) throw new Error(\"fd is not available and could not be downloaded\");\n\treturn executeFdFind(fdPath, request, searchPath, effectiveLimit, registerStop);\n}\n\nfunction executeFind(request: FindExecutionRequest): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tif (request.signal?.aborted) {\n\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\treturn;\n\t\t}\n\t\tlet settled = false;\n\t\tlet stopChild: (() => void) | undefined;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\trequest.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tstopChild = undefined;\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstopChild?.();\n\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t};\n\t\trequest.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid dispatchFindExecution(request, (stop) => {\n\t\t\tstopChild = stop;\n\t\t}).then(\n\t\t\t(result) => settle(() => resolveFind(result)),\n\t\t\t(error: unknown) => {\n\t\t\t\tif (request.signal?.aborted) {\n\t\t\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(() => rejectFind(error instanceof Error ? error : new Error(String(error))));\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport type FindToolDefinition = ToolDefinition<typeof findSchema, FindToolDetails | undefined>;\n\nexport function createFindToolDefinition(operations: ToolOperations, _options?: FindToolOptions): FindToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: FindToolInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn executeFind({\n\t\t\t\toperations: ops,\n\t\t\t\tcwd,\n\t\t\t\tpattern,\n\t\t\t\tsearchDir,\n\t\t\t\tlimit,\n\t\t\t\tsignal,\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(operations: ToolOperations, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(operations, options));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,4BAA4B,CAAC;AAI7E,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAWtD,OAAO,EAAiC,KAAK,gBAAgB,EAAgB,MAAM,eAAe,CAAC;AAMnG,QAAA,MAAM,UAAU;;;;EAMd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAItD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;CAAG;AAwPnC,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;AAEhG,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,kBAAkB,CAoCnH;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAElH","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatBackendIcon,\n\tformatHiddenLinesHint,\n\tgetTextOutput,\n\tinvalidArgText,\n\tshortenPath,\n\tstr,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\nexport interface FindToolOptions {}\n\nfunction formatFindCall(args: FindToolInput | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: AgentToolResult<FindToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `\\n\\n${formatHiddenLinesHint(remaining, theme)}`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\ntype FindExecutionResult = AgentToolResult<FindToolDetails | undefined>;\n\ninterface FindExecutionRequest {\n\toperations: ToolOperations;\n\tcwd: string;\n\tpattern: string;\n\tsearchDir: string | undefined;\n\tlimit: number | undefined;\n\tsignal: AbortSignal | undefined;\n}\n\ntype RegisterFindChildStop = (stop: () => void) => void;\n\nfunction throwIfFindAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n}\n\nfunction noFindResults(): FindExecutionResult {\n\treturn { content: [{ type: \"text\", text: \"No files found matching pattern\" }], details: undefined };\n}\n\nfunction formatFindMatches(paths: string[], limit: number, includeRefineHint: boolean): FindExecutionResult {\n\tconst resultLimitReached = paths.length >= limit;\n\tconst truncation = truncateHead(paths.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: FindToolDetails = {};\n\tconst notices: string[] = [];\n\tif (resultLimitReached) {\n\t\tnotices.push(\n\t\t\tincludeRefineHint\n\t\t\t\t? `${limit} results limit reached. Use limit=${limit * 2} for more, or refine pattern`\n\t\t\t\t: `${limit} results limit reached`,\n\t\t);\n\t\tdetails.resultLimitReached = limit;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nfunction relativizeGlobMatches(paths: string[], searchPath: string): string[] {\n\treturn paths.map((matchedPath) => {\n\t\tif (matchedPath.startsWith(searchPath)) return toPosixPath(matchedPath.slice(searchPath.length + 1));\n\t\treturn toPosixPath(path.relative(searchPath, matchedPath));\n\t});\n}\n\nasync function executeOperationsFind(\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n): Promise<FindExecutionResult> {\n\ttry {\n\t\tawait request.operations.access(searchPath, \"exists\");\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tthrowIfFindAborted(request.signal);\n\tif (!request.operations.glob) throw new Error(\"Glob operation is unavailable\");\n\tconst results = await request.operations.glob(request.pattern, searchPath, {\n\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\tlimit: effectiveLimit,\n\t});\n\tthrowIfFindAborted(request.signal);\n\tif (results.length === 0) return noFindResults();\n\treturn formatFindMatches(relativizeGlobMatches(results, searchPath), effectiveLimit, false);\n}\n\nfunction buildFdArguments(pattern: string, searchPath: string, limit: number): string[] {\n\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(limit)];\n\tlet effectivePattern = pattern;\n\tif (pattern.includes(\"/\")) {\n\t\targs.push(\"--full-path\");\n\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t}\n\targs.push(\"--\", effectivePattern, searchPath);\n\treturn args;\n}\n\nfunction relativizeFdMatches(lines: string[], searchPath: string): string[] {\n\tconst relativized: string[] = [];\n\tfor (const rawLine of lines) {\n\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\tif (!line) continue;\n\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\tlet relativePath = line;\n\t\tif (line.startsWith(searchPath)) {\n\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t} else {\n\t\t\trelativePath = path.relative(searchPath, line);\n\t\t}\n\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\trelativized.push(toPosixPath(relativePath));\n\t}\n\treturn relativized;\n}\n\nfunction executeFdFind(\n\tfdPath: string,\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tconst child = spawn(fdPath, buildFdArguments(request.pattern, searchPath, effectiveLimit), {\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tlet stderr = \"\";\n\t\tconst lines: string[] = [];\n\t\tregisterStop(() => {\n\t\t\tif (!child.killed) child.kill();\n\t\t});\n\t\tconst cleanup = (): void => rl.close();\n\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => lines.push(line));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\trejectFind(new Error(`Failed to run fd: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tif (request.signal?.aborted) {\n\t\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst output = lines.join(\"\\n\");\n\t\t\tif (code !== 0 && !output) {\n\t\t\t\trejectFind(new Error(stderr.trim() || `fd exited with code ${code}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!output) {\n\t\t\t\tresolveFind(noFindResults());\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolveFind(formatFindMatches(relativizeFdMatches(lines, searchPath), effectiveLimit, true));\n\t\t});\n\t});\n}\n\nasync function dispatchFindExecution(\n\trequest: FindExecutionRequest,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\tconst searchPath = resolveToCwd(request.searchDir || \".\", request.cwd);\n\tconst effectiveLimit = request.limit ?? DEFAULT_LIMIT;\n\tif (request.operations.glob) return executeOperationsFind(request, searchPath, effectiveLimit);\n\tconst fdPath = await ensureTool(\"fd\", true);\n\tthrowIfFindAborted(request.signal);\n\tif (!fdPath) throw new Error(\"fd is not available and could not be downloaded\");\n\treturn executeFdFind(fdPath, request, searchPath, effectiveLimit, registerStop);\n}\n\nfunction executeFind(request: FindExecutionRequest): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tif (request.signal?.aborted) {\n\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\treturn;\n\t\t}\n\t\tlet settled = false;\n\t\tlet stopChild: (() => void) | undefined;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\trequest.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tstopChild = undefined;\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstopChild?.();\n\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t};\n\t\trequest.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid dispatchFindExecution(request, (stop) => {\n\t\t\tstopChild = stop;\n\t\t}).then(\n\t\t\t(result) => settle(() => resolveFind(result)),\n\t\t\t(error: unknown) => {\n\t\t\t\tif (request.signal?.aborted) {\n\t\t\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(() => rejectFind(error instanceof Error ? error : new Error(String(error))));\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport type FindToolDefinition = ToolDefinition<typeof findSchema, FindToolDetails | undefined>;\n\nexport function createFindToolDefinition(operations: ToolOperations, _options?: FindToolOptions): FindToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: FindToolInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn executeFind({\n\t\t\t\toperations: ops,\n\t\t\t\tcwd,\n\t\t\t\tpattern,\n\t\t\t\tsearchDir,\n\t\t\t\tlimit,\n\t\t\t\tsignal,\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(operations: ToolOperations, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(operations, options));\n}\n"]}
|
package/dist/core/tools/find.js
CHANGED
|
@@ -3,10 +3,9 @@ import { Text } from "@greppleai/grip-tui";
|
|
|
3
3
|
import { spawn } from "child_process";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { Type } from "typebox";
|
|
6
|
-
import { keyHint } from "../../modes/interactive/components/keybinding-hints.js";
|
|
7
6
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
8
7
|
import { resolveToCwd } from "./path-utils.js";
|
|
9
|
-
import { formatBackendIcon, getTextOutput, invalidArgText, shortenPath, str } from "./render-utils.js";
|
|
8
|
+
import { formatBackendIcon, formatHiddenLinesHint, getTextOutput, invalidArgText, shortenPath, str, } from "./render-utils.js";
|
|
10
9
|
import { wrapToolDefinition } from "./tool-definition-wrapper.js";
|
|
11
10
|
import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
|
|
12
11
|
function toPosixPath(value) {
|
|
@@ -45,7 +44,7 @@ function formatFindResult(result, options, theme, showImages) {
|
|
|
45
44
|
const remaining = lines.length - maxLines;
|
|
46
45
|
text += `\n${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
|
|
47
46
|
if (remaining > 0) {
|
|
48
|
-
text +=
|
|
47
|
+
text += `\n\n${formatHiddenLinesHint(remaining, theme)}`;
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
const resultLimit = result.details?.resultLimitReached;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport { formatBackendIcon, getTextOutput, invalidArgText, shortenPath, str } from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\nexport interface FindToolOptions {}\n\nfunction formatFindCall(args: FindToolInput | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: AgentToolResult<FindToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `${theme.fg(\"muted\", `\\n... (${remaining} more lines,`)} ${keyHint(\"app.tools.expand\", \"to expand\")})`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\ntype FindExecutionResult = AgentToolResult<FindToolDetails | undefined>;\n\ninterface FindExecutionRequest {\n\toperations: ToolOperations;\n\tcwd: string;\n\tpattern: string;\n\tsearchDir: string | undefined;\n\tlimit: number | undefined;\n\tsignal: AbortSignal | undefined;\n}\n\ntype RegisterFindChildStop = (stop: () => void) => void;\n\nfunction throwIfFindAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n}\n\nfunction noFindResults(): FindExecutionResult {\n\treturn { content: [{ type: \"text\", text: \"No files found matching pattern\" }], details: undefined };\n}\n\nfunction formatFindMatches(paths: string[], limit: number, includeRefineHint: boolean): FindExecutionResult {\n\tconst resultLimitReached = paths.length >= limit;\n\tconst truncation = truncateHead(paths.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: FindToolDetails = {};\n\tconst notices: string[] = [];\n\tif (resultLimitReached) {\n\t\tnotices.push(\n\t\t\tincludeRefineHint\n\t\t\t\t? `${limit} results limit reached. Use limit=${limit * 2} for more, or refine pattern`\n\t\t\t\t: `${limit} results limit reached`,\n\t\t);\n\t\tdetails.resultLimitReached = limit;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nfunction relativizeGlobMatches(paths: string[], searchPath: string): string[] {\n\treturn paths.map((matchedPath) => {\n\t\tif (matchedPath.startsWith(searchPath)) return toPosixPath(matchedPath.slice(searchPath.length + 1));\n\t\treturn toPosixPath(path.relative(searchPath, matchedPath));\n\t});\n}\n\nasync function executeOperationsFind(\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n): Promise<FindExecutionResult> {\n\ttry {\n\t\tawait request.operations.access(searchPath, \"exists\");\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tthrowIfFindAborted(request.signal);\n\tif (!request.operations.glob) throw new Error(\"Glob operation is unavailable\");\n\tconst results = await request.operations.glob(request.pattern, searchPath, {\n\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\tlimit: effectiveLimit,\n\t});\n\tthrowIfFindAborted(request.signal);\n\tif (results.length === 0) return noFindResults();\n\treturn formatFindMatches(relativizeGlobMatches(results, searchPath), effectiveLimit, false);\n}\n\nfunction buildFdArguments(pattern: string, searchPath: string, limit: number): string[] {\n\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(limit)];\n\tlet effectivePattern = pattern;\n\tif (pattern.includes(\"/\")) {\n\t\targs.push(\"--full-path\");\n\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t}\n\targs.push(\"--\", effectivePattern, searchPath);\n\treturn args;\n}\n\nfunction relativizeFdMatches(lines: string[], searchPath: string): string[] {\n\tconst relativized: string[] = [];\n\tfor (const rawLine of lines) {\n\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\tif (!line) continue;\n\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\tlet relativePath = line;\n\t\tif (line.startsWith(searchPath)) {\n\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t} else {\n\t\t\trelativePath = path.relative(searchPath, line);\n\t\t}\n\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\trelativized.push(toPosixPath(relativePath));\n\t}\n\treturn relativized;\n}\n\nfunction executeFdFind(\n\tfdPath: string,\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tconst child = spawn(fdPath, buildFdArguments(request.pattern, searchPath, effectiveLimit), {\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tlet stderr = \"\";\n\t\tconst lines: string[] = [];\n\t\tregisterStop(() => {\n\t\t\tif (!child.killed) child.kill();\n\t\t});\n\t\tconst cleanup = (): void => rl.close();\n\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => lines.push(line));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\trejectFind(new Error(`Failed to run fd: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tif (request.signal?.aborted) {\n\t\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst output = lines.join(\"\\n\");\n\t\t\tif (code !== 0 && !output) {\n\t\t\t\trejectFind(new Error(stderr.trim() || `fd exited with code ${code}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!output) {\n\t\t\t\tresolveFind(noFindResults());\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolveFind(formatFindMatches(relativizeFdMatches(lines, searchPath), effectiveLimit, true));\n\t\t});\n\t});\n}\n\nasync function dispatchFindExecution(\n\trequest: FindExecutionRequest,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\tconst searchPath = resolveToCwd(request.searchDir || \".\", request.cwd);\n\tconst effectiveLimit = request.limit ?? DEFAULT_LIMIT;\n\tif (request.operations.glob) return executeOperationsFind(request, searchPath, effectiveLimit);\n\tconst fdPath = await ensureTool(\"fd\", true);\n\tthrowIfFindAborted(request.signal);\n\tif (!fdPath) throw new Error(\"fd is not available and could not be downloaded\");\n\treturn executeFdFind(fdPath, request, searchPath, effectiveLimit, registerStop);\n}\n\nfunction executeFind(request: FindExecutionRequest): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tif (request.signal?.aborted) {\n\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\treturn;\n\t\t}\n\t\tlet settled = false;\n\t\tlet stopChild: (() => void) | undefined;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\trequest.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tstopChild = undefined;\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstopChild?.();\n\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t};\n\t\trequest.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid dispatchFindExecution(request, (stop) => {\n\t\t\tstopChild = stop;\n\t\t}).then(\n\t\t\t(result) => settle(() => resolveFind(result)),\n\t\t\t(error: unknown) => {\n\t\t\t\tif (request.signal?.aborted) {\n\t\t\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(() => rejectFind(error instanceof Error ? error : new Error(String(error))));\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport type FindToolDefinition = ToolDefinition<typeof findSchema, FindToolDetails | undefined>;\n\nexport function createFindToolDefinition(operations: ToolOperations, _options?: FindToolOptions): FindToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: FindToolInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn executeFind({\n\t\t\t\toperations: ops,\n\t\t\t\tcwd,\n\t\t\t\tpattern,\n\t\t\t\tsearchDir,\n\t\t\t\tlimit,\n\t\t\t\tsignal,\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(operations: ToolOperations, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(operations, options));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInterface } from \"node:readline\";\nimport type { AgentTool, AgentToolResult } from \"@greppleai/grip-agent-core\";\nimport { Text } from \"@greppleai/grip-tui\";\nimport { spawn } from \"child_process\";\nimport path from \"path\";\nimport { type Static, Type } from \"typebox\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { ensureTool } from \"../../utils/tools-manager.ts\";\nimport type { ToolDefinition, ToolRenderResultOptions } from \"../extensions/types.ts\";\nimport type { ToolOperations } from \"./operations.ts\";\nimport { resolveToCwd } from \"./path-utils.ts\";\nimport {\n\tformatBackendIcon,\n\tformatHiddenLinesHint,\n\tgetTextOutput,\n\tinvalidArgText,\n\tshortenPath,\n\tstr,\n} from \"./render-utils.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\nimport { DEFAULT_MAX_BYTES, formatSize, type TruncationResult, truncateHead } from \"./truncate.ts\";\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(path.sep).join(\"/\");\n}\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'\",\n\t}),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search in (default: current directory)\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of results (default: 1000)\" })),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nconst DEFAULT_LIMIT = 1000;\n\nexport interface FindToolDetails {\n\ttruncation?: TruncationResult;\n\tresultLimitReached?: number;\n}\n\nexport interface FindToolOptions {}\n\nfunction formatFindCall(args: FindToolInput | undefined, theme: Theme): string {\n\tconst pattern = str(args?.pattern);\n\tconst rawPath = str(args?.path);\n\tconst path = rawPath !== null ? shortenPath(rawPath || \".\") : null;\n\tconst limit = args?.limit;\n\tconst invalidArg = invalidArgText(theme);\n\tlet text =\n\t\ttheme.fg(\"toolTitle\", theme.bold(\"find\")) +\n\t\t\" \" +\n\t\t(pattern === null ? invalidArg : theme.fg(\"accent\", pattern || \"\")) +\n\t\ttheme.fg(\"toolOutput\", ` in ${path === null ? invalidArg : path}`);\n\tif (limit !== undefined) {\n\t\ttext += theme.fg(\"toolOutput\", ` (limit ${limit})`);\n\t}\n\treturn text;\n}\n\nfunction formatFindResult(\n\tresult: AgentToolResult<FindToolDetails | undefined>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tshowImages: boolean,\n): string {\n\tconst output = getTextOutput(result, showImages).trim();\n\tlet text = \"\";\n\tif (output) {\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst maxLines = options.expanded ? lines.length : 20;\n\t\tconst displayLines = lines.slice(0, maxLines);\n\t\tconst remaining = lines.length - maxLines;\n\t\ttext += `\\n${displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\")}`;\n\t\tif (remaining > 0) {\n\t\t\ttext += `\\n\\n${formatHiddenLinesHint(remaining, theme)}`;\n\t\t}\n\t}\n\n\tconst resultLimit = result.details?.resultLimitReached;\n\tconst truncation = result.details?.truncation;\n\tif (resultLimit || truncation?.truncated) {\n\t\tconst warnings: string[] = [];\n\t\tif (resultLimit) warnings.push(`${resultLimit} results limit`);\n\t\tif (truncation?.truncated) warnings.push(`${formatSize(truncation.maxBytes ?? DEFAULT_MAX_BYTES)} limit`);\n\t\ttext += `\\n${theme.fg(\"warning\", `[Truncated: ${warnings.join(\", \")}]`)}`;\n\t}\n\treturn text;\n}\n\ntype FindExecutionResult = AgentToolResult<FindToolDetails | undefined>;\n\ninterface FindExecutionRequest {\n\toperations: ToolOperations;\n\tcwd: string;\n\tpattern: string;\n\tsearchDir: string | undefined;\n\tlimit: number | undefined;\n\tsignal: AbortSignal | undefined;\n}\n\ntype RegisterFindChildStop = (stop: () => void) => void;\n\nfunction throwIfFindAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n}\n\nfunction noFindResults(): FindExecutionResult {\n\treturn { content: [{ type: \"text\", text: \"No files found matching pattern\" }], details: undefined };\n}\n\nfunction formatFindMatches(paths: string[], limit: number, includeRefineHint: boolean): FindExecutionResult {\n\tconst resultLimitReached = paths.length >= limit;\n\tconst truncation = truncateHead(paths.join(\"\\n\"), { maxLines: Number.MAX_SAFE_INTEGER });\n\tlet output = truncation.content;\n\tconst details: FindToolDetails = {};\n\tconst notices: string[] = [];\n\tif (resultLimitReached) {\n\t\tnotices.push(\n\t\t\tincludeRefineHint\n\t\t\t\t? `${limit} results limit reached. Use limit=${limit * 2} for more, or refine pattern`\n\t\t\t\t: `${limit} results limit reached`,\n\t\t);\n\t\tdetails.resultLimitReached = limit;\n\t}\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);\n\t\tdetails.truncation = truncation;\n\t}\n\tif (notices.length > 0) output += `\\n\\n[${notices.join(\". \")}]`;\n\treturn {\n\t\tcontent: [{ type: \"text\", text: output }],\n\t\tdetails: Object.keys(details).length > 0 ? details : undefined,\n\t};\n}\n\nfunction relativizeGlobMatches(paths: string[], searchPath: string): string[] {\n\treturn paths.map((matchedPath) => {\n\t\tif (matchedPath.startsWith(searchPath)) return toPosixPath(matchedPath.slice(searchPath.length + 1));\n\t\treturn toPosixPath(path.relative(searchPath, matchedPath));\n\t});\n}\n\nasync function executeOperationsFind(\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n): Promise<FindExecutionResult> {\n\ttry {\n\t\tawait request.operations.access(searchPath, \"exists\");\n\t} catch {\n\t\tthrow new Error(`Path not found: ${searchPath}`);\n\t}\n\tthrowIfFindAborted(request.signal);\n\tif (!request.operations.glob) throw new Error(\"Glob operation is unavailable\");\n\tconst results = await request.operations.glob(request.pattern, searchPath, {\n\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\tlimit: effectiveLimit,\n\t});\n\tthrowIfFindAborted(request.signal);\n\tif (results.length === 0) return noFindResults();\n\treturn formatFindMatches(relativizeGlobMatches(results, searchPath), effectiveLimit, false);\n}\n\nfunction buildFdArguments(pattern: string, searchPath: string, limit: number): string[] {\n\tconst args = [\"--glob\", \"--color=never\", \"--hidden\", \"--no-require-git\", \"--max-results\", String(limit)];\n\tlet effectivePattern = pattern;\n\tif (pattern.includes(\"/\")) {\n\t\targs.push(\"--full-path\");\n\t\tif (!pattern.startsWith(\"/\") && !pattern.startsWith(\"**/\") && pattern !== \"**\") {\n\t\t\teffectivePattern = `**/${pattern}`;\n\t\t}\n\t}\n\targs.push(\"--\", effectivePattern, searchPath);\n\treturn args;\n}\n\nfunction relativizeFdMatches(lines: string[], searchPath: string): string[] {\n\tconst relativized: string[] = [];\n\tfor (const rawLine of lines) {\n\t\tconst line = rawLine.replace(/\\r$/, \"\").trim();\n\t\tif (!line) continue;\n\t\tconst hadTrailingSlash = line.endsWith(\"/\") || line.endsWith(\"\\\\\");\n\t\tlet relativePath = line;\n\t\tif (line.startsWith(searchPath)) {\n\t\t\trelativePath = line.slice(searchPath.length + 1);\n\t\t} else {\n\t\t\trelativePath = path.relative(searchPath, line);\n\t\t}\n\t\tif (hadTrailingSlash && !relativePath.endsWith(\"/\")) relativePath += \"/\";\n\t\trelativized.push(toPosixPath(relativePath));\n\t}\n\treturn relativized;\n}\n\nfunction executeFdFind(\n\tfdPath: string,\n\trequest: FindExecutionRequest,\n\tsearchPath: string,\n\teffectiveLimit: number,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tconst child = spawn(fdPath, buildFdArguments(request.pattern, searchPath, effectiveLimit), {\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\t\tconst rl = createInterface({ input: child.stdout });\n\t\tlet stderr = \"\";\n\t\tconst lines: string[] = [];\n\t\tregisterStop(() => {\n\t\t\tif (!child.killed) child.kill();\n\t\t});\n\t\tconst cleanup = (): void => rl.close();\n\t\tchild.stderr?.on(\"data\", (chunk) => {\n\t\t\tstderr += chunk.toString();\n\t\t});\n\t\trl.on(\"line\", (line) => lines.push(line));\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\trejectFind(new Error(`Failed to run fd: ${error.message}`));\n\t\t});\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tif (request.signal?.aborted) {\n\t\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst output = lines.join(\"\\n\");\n\t\t\tif (code !== 0 && !output) {\n\t\t\t\trejectFind(new Error(stderr.trim() || `fd exited with code ${code}`));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!output) {\n\t\t\t\tresolveFind(noFindResults());\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolveFind(formatFindMatches(relativizeFdMatches(lines, searchPath), effectiveLimit, true));\n\t\t});\n\t});\n}\n\nasync function dispatchFindExecution(\n\trequest: FindExecutionRequest,\n\tregisterStop: RegisterFindChildStop,\n): Promise<FindExecutionResult> {\n\tconst searchPath = resolveToCwd(request.searchDir || \".\", request.cwd);\n\tconst effectiveLimit = request.limit ?? DEFAULT_LIMIT;\n\tif (request.operations.glob) return executeOperationsFind(request, searchPath, effectiveLimit);\n\tconst fdPath = await ensureTool(\"fd\", true);\n\tthrowIfFindAborted(request.signal);\n\tif (!fdPath) throw new Error(\"fd is not available and could not be downloaded\");\n\treturn executeFdFind(fdPath, request, searchPath, effectiveLimit, registerStop);\n}\n\nfunction executeFind(request: FindExecutionRequest): Promise<FindExecutionResult> {\n\treturn new Promise((resolveFind, rejectFind) => {\n\t\tif (request.signal?.aborted) {\n\t\t\trejectFind(new Error(\"Operation aborted\"));\n\t\t\treturn;\n\t\t}\n\t\tlet settled = false;\n\t\tlet stopChild: (() => void) | undefined;\n\t\tconst settle = (complete: () => void): void => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\trequest.signal?.removeEventListener(\"abort\", onAbort);\n\t\t\tstopChild = undefined;\n\t\t\tcomplete();\n\t\t};\n\t\tconst onAbort = (): void => {\n\t\t\tstopChild?.();\n\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t};\n\t\trequest.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid dispatchFindExecution(request, (stop) => {\n\t\t\tstopChild = stop;\n\t\t}).then(\n\t\t\t(result) => settle(() => resolveFind(result)),\n\t\t\t(error: unknown) => {\n\t\t\t\tif (request.signal?.aborted) {\n\t\t\t\t\tsettle(() => rejectFind(new Error(\"Operation aborted\")));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettle(() => rejectFind(error instanceof Error ? error : new Error(String(error))));\n\t\t\t},\n\t\t);\n\t});\n}\n\nexport type FindToolDefinition = ToolDefinition<typeof findSchema, FindToolDetails | undefined>;\n\nexport function createFindToolDefinition(operations: ToolOperations, _options?: FindToolOptions): FindToolDefinition {\n\tconst ops = operations;\n\tconst cwd = operations.cwd;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Respects .gitignore. Output is truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first).`,\n\t\tpromptSnippet: \"Find files by glob pattern (respects .gitignore)\",\n\t\tparameters: findSchema,\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ pattern, path: searchDir, limit }: FindToolInput,\n\t\t\tsignal?: AbortSignal,\n\t\t\t_onUpdate?,\n\t\t\t_ctx?,\n\t\t) {\n\t\t\treturn executeFind({\n\t\t\t\toperations: ops,\n\t\t\t\tcwd,\n\t\t\t\tpattern,\n\t\t\t\tsearchDir,\n\t\t\t\tlimit,\n\t\t\t\tsignal,\n\t\t\t});\n\t\t},\n\t\trenderCall(args, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatBackendIcon(ops.getBackendInfo?.(), theme) + formatFindCall(args, theme));\n\t\t\treturn text;\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tconst text = (context.lastComponent as Text | undefined) ?? new Text(\"\", 0, 0);\n\t\t\ttext.setText(formatFindResult(result as any, options, theme, context.showImages));\n\t\t\treturn text;\n\t\t},\n\t};\n}\n\nexport function createFindTool(operations: ToolOperations, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\treturn wrapToolDefinition(createFindToolDefinition(operations, options));\n}\n"]}
|