{"version":3,"file":"startup-checks.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/startup-checks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgB7G;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA6C1E;AAQD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE;IAC/C,yEAAyE;IACzE,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,eAAe,CAAC;CACjC,GAAG,MAAM,GAAG,SAAS,CA+BrB","sourcesContent":["/**\n * Startup environment probes and the changelog-on-update lookup, shown as\n * notices when the interactive mode starts. Extracted from interactive-mode.ts.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { APP_NAME, getAgentDir, VERSION } from \"../../config.js\";\nimport { DefaultPackageManager } from \"../../core/package-manager.js\";\nimport type { SettingsManager } from \"../../core/settings-manager.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"../../utils/changelog.js\";\n\nexport async function checkForPackageUpdates(cwd: string, settingsManager: SettingsManager): Promise<string[]> {\n\tif (process.env.HOOCODE_OFFLINE) {\n\t\treturn [];\n\t}\n\n\ttry {\n\t\tconst packageManager = new DefaultPackageManager({\n\t\t\tcwd,\n\t\t\tagentDir: getAgentDir(),\n\t\t\tsettingsManager,\n\t\t});\n\t\tconst updates = await packageManager.checkForAvailableUpdates();\n\t\treturn updates.map((update) => update.displayName);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nexport async function checkTmuxKeyboardSetup(): Promise<string | undefined> {\n\tif (!process.env.TMUX) return undefined;\n\n\tconst runTmuxShow = (option: string): Promise<string | undefined> => {\n\t\treturn new Promise((resolve) => {\n\t\t\tconst proc = spawn(\"tmux\", [\"show\", \"-gv\", option], {\n\t\t\t\tstdio: [\"ignore\", \"pipe\", \"ignore\"],\n\t\t\t});\n\t\t\tlet stdout = \"\";\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tproc.kill();\n\t\t\t\tresolve(undefined);\n\t\t\t}, 2000);\n\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"error\", () => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(undefined);\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(code === 0 ? stdout.trim() : undefined);\n\t\t\t});\n\t\t});\n\t};\n\n\tconst [extendedKeys, extendedKeysFormat] = await Promise.all([\n\t\trunTmuxShow(\"extended-keys\"),\n\t\trunTmuxShow(\"extended-keys-format\"),\n\t]);\n\n\t// If we couldn't query tmux (timeout, sandbox, etc.), don't warn\n\tif (extendedKeys === undefined) return undefined;\n\n\tif (extendedKeys !== \"on\" && extendedKeys !== \"always\") {\n\t\treturn \"tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.\";\n\t}\n\n\tif (extendedKeysFormat === \"xterm\") {\n\t\treturn `tmux extended-keys-format is xterm. ${APP_NAME} works best with csi-u. Add \\`set -g extended-keys-format csi-u\\` to ~/.tmux.conf and restart tmux.`;\n\t}\n\n\treturn undefined;\n}\n\nfunction reportInstallTelemetry(_version: string): void {\n\t// HooCode reports no install telemetry. The hook is kept because the caller\n\t// below marks a fresh install, which is a useful seam -- but nothing leaves\n\t// the machine, and `enableInstallTelemetry` in settings.json is inert.\n}\n\n/**\n * Get changelog entries to display on startup.\n * Only shows new entries since last seen version, skips for resumed sessions.\n */\nexport function getChangelogForDisplay(options: {\n\t/** True for resumed/continued sessions (which already have messages). */\n\thasMessages: boolean;\n\tsettingsManager: SettingsManager;\n}): string | undefined {\n\t// Skip changelog for resumed/continued sessions (already have messages)\n\tif (options.hasMessages) {\n\t\treturn undefined;\n\t}\n\n\tconst settingsManager = options.settingsManager;\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\t// Fresh install - record the latest entry's version (not VERSION, which may\n\t\t// overshoot the latest entry and silently swallow it once it appears).\n\t\t// Fall back to VERSION only if no entries exist yet.\n\t\tconst seedVersion = entries.length > 0 ? `${entries[0].major}.${entries[0].minor}.${entries[0].patch}` : VERSION;\n\t\tsettingsManager.setLastChangelogVersion(seedVersion);\n\t\treportInstallTelemetry(seedVersion);\n\t\treturn undefined;\n\t}\n\n\tconst newEntries = getNewEntries(entries, lastVersion);\n\tif (newEntries.length > 0) {\n\t\tconst latest = newEntries[0];\n\t\tconst latestVersion = `${latest.major}.${latest.minor}.${latest.patch}`;\n\t\tsettingsManager.setLastChangelogVersion(latestVersion);\n\t\treportInstallTelemetry(latestVersion);\n\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t}\n\n\treturn undefined;\n}\n"]}