@kynver-app/runtime 0.1.118 → 0.1.120
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/dist/chat/anthropic-credentials.d.ts +9 -0
- package/dist/chat/anthropic-stream.d.ts +43 -0
- package/dist/chat/chat-claim-loop.d.ts +25 -0
- package/dist/chat/delta-batcher.d.ts +13 -0
- package/dist/cli.js +8143 -6989
- package/dist/cli.js.map +4 -4
- package/dist/config.d.ts +2 -0
- package/dist/cron/cron-env-file.d.ts +15 -0
- package/dist/cron/cron-id.d.ts +3 -0
- package/dist/cron/cron-install-api.d.ts +27 -0
- package/dist/cron/cron-install-cli.d.ts +2 -0
- package/dist/cron/cron-install-plan.d.ts +32 -0
- package/dist/cron/cron-install-secrets.d.ts +6 -0
- package/dist/cron/cron-install-systemd.d.ts +18 -0
- package/dist/cron/cron-install-verify.d.ts +15 -0
- package/dist/cron/cron-install.d.ts +51 -0
- package/dist/cron/cron-store.d.ts +5 -0
- package/dist/index.js +1349 -197
- package/dist/index.js.map +4 -4
- package/dist/server/cleanup.js.map +2 -2
- package/dist/server/default-repo.js.map +2 -2
- package/dist/server/memory-cost-enforce.js.map +1 -1
- package/dist/server/monitor.js.map +2 -2
- package/dist/server/worker-policy.js.map +2 -2
- package/dist/start.d.ts +7 -0
- package/dist/worktree.d.ts +8 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/installed-package-versions.ts", "../../src/memory-cost-package-version-guard.ts", "../../src/default-repo-discovery.ts", "../../src/git.ts", "../../src/util.ts", "../../src/worker-env.ts", "../../src/path-values.ts", "../../src/package-version.ts", "../../src/memory-cost-package-version-guard-enforce.ts"],
|
|
4
|
-
"sourcesContent": ["import { readFile } from \"node:fs/promises\";\r\nimport { homedir } from \"node:os\";\r\nimport path from \"node:path\";\r\nimport { compareSemver } from \"./memory-cost-package-version-guard.js\";\r\n\r\nconst MANAGED_PACKAGES = [\r\n \"@kynver-app/runtime\",\r\n \"@kynver-app/openclaw-agent-os\",\r\n \"@kynver-app/mcp-agent-os\",\r\n] as const;\r\n\r\nexport type InstalledPackageVersionMap = Record<\r\n string,\r\n {\r\n version: string;\r\n observedAt: string;\r\n path: string;\r\n }\r\n>;\r\n\r\nfunction trim(value: string | undefined): string | null {\r\n const out = value?.trim();\r\n return out ? out : null;\r\n}\r\n\r\nfunction unique(values: Array<string | null | undefined>): string[] {\r\n return [...new Set(values.filter((value): value is string => Boolean(value)))];\r\n}\r\n\r\nfunction moduleRoots(): string[] {\r\n const home = homedir();\r\n const openClawPrefix =\r\n trim(process.env.KYNVER_OPENCLAW_NPM_ROOT) ??\r\n trim(process.env.OPENCLAW_NPM_ROOT) ??\r\n path.join(home, \".openclaw\", \"npm\");\r\n const npmGlobalRoot =\r\n trim(process.env.KYNVER_NPM_GLOBAL_ROOT) ??\r\n trim(process.env.KYNVER_NPM_GLOBAL_MODULES_ROOT) ??\r\n (trim(process.env.NPM_CONFIG_PREFIX)\r\n ? path.join(trim(process.env.NPM_CONFIG_PREFIX)!, \"lib\", \"node_modules\")\r\n : path.join(home, \".npm-global\", \"lib\", \"node_modules\"));\r\n\r\n return unique([\r\n path.join(openClawPrefix, \"lib\", \"node_modules\"),\r\n path.join(openClawPrefix, \"node_modules\"),\r\n npmGlobalRoot.endsWith(\"node_modules\") ? npmGlobalRoot : path.join(npmGlobalRoot, \"lib\", \"node_modules\"),\r\n ]);\r\n}\r\n\r\nasync function readVersion(packageJsonPath: string): Promise<string | null> {\r\n try {\r\n const parsed = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as { version?: unknown };\r\n return typeof parsed.version === \"string\" && parsed.version.trim() ? parsed.version.trim() : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/** Candidate install paths for one managed package across OpenClaw + global npm roots. */\r\nexport function installedPackageJsonCandidates(packageName: string): string[] {\r\n const roots = moduleRoots();\r\n const seen = new Set<string>();\r\n const out: string[] = [];\r\n for (const root of roots) {\r\n const candidate = path.join(root, packageName, \"package.json\");\r\n if (seen.has(candidate)) continue;\r\n seen.add(candidate);\r\n out.push(candidate);\r\n }\r\n return out;\r\n}\r\n\r\nexport async function collectInstalledPackageVersions(\r\n observedAt: string = new Date().toISOString(),\r\n): Promise<InstalledPackageVersionMap> {\r\n const out: InstalledPackageVersionMap = {};\r\n for (const packageName of MANAGED_PACKAGES) {\r\n let best: { version: string; path: string } | null = null;\r\n for (const packageJsonPath of installedPackageJsonCandidates(packageName)) {\r\n const version = await readVersion(packageJsonPath);\r\n if (!version) continue;\r\n if (!best || compareSemver(version, best.version) > 0) {\r\n best = { version, path: packageJsonPath };\r\n }\r\n }\r\n if (best) {\r\n out[packageName] = { version: best.version, observedAt, path: best.path };\r\n }\r\n }\r\n return out;\r\n}\r\n", "import { existsSync, readFileSync } from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { discoverDefaultRepo } from \"./default-repo-discovery.js\";\r\n\r\n/** Minimum versions that ship MARM memory cost controls (PR #1159). */\r\nexport const MEMORY_COST_PACKAGE_MIN_VERSIONS = {\r\n \"@kynver-app/runtime\": \"0.1.83\",\r\n \"@kynver-app/openclaw-agent-os\": \"0.1.43\",\r\n \"@kynver-app/mcp-agent-os\": \"0.3.34\",\r\n} as const;\r\n\r\nexport type MemoryCostManagedPackageName = keyof typeof MEMORY_COST_PACKAGE_MIN_VERSIONS;\r\n\r\nexport const MEMORY_COST_MANAGED_PACKAGES = Object.keys(\r\n MEMORY_COST_PACKAGE_MIN_VERSIONS,\r\n) as MemoryCostManagedPackageName[];\r\n\r\nexport type MemoryCostVersionSource = \"self\" | \"installed\" | \"repo\" | \"unknown\";\r\n\r\nexport interface MemoryCostPackageVersionCandidate {\r\n version: string;\r\n source: MemoryCostVersionSource;\r\n path?: string;\r\n}\r\n\r\nexport interface MemoryCostPackageGuardRow {\r\n packageName: MemoryCostManagedPackageName;\r\n displayName: string;\r\n minimumVersion: string;\r\n effectiveVersion: string | null;\r\n effectiveSource: MemoryCostVersionSource;\r\n ok: boolean;\r\n summary: string;\r\n remediation: string[];\r\n}\r\n\r\nexport interface MemoryCostPackageGuardResult {\r\n ok: boolean;\r\n summary: string;\r\n packages: MemoryCostPackageGuardRow[];\r\n}\r\n\r\nconst DISPLAY_NAMES: Record<MemoryCostManagedPackageName, string> = {\r\n \"@kynver-app/runtime\": \"Kynver runtime\",\r\n \"@kynver-app/openclaw-agent-os\": \"OpenClaw AgentOS plugin\",\r\n \"@kynver-app/mcp-agent-os\": \"AgentOS MCP server\",\r\n};\r\n\r\nconst REPO_PACKAGE_JSON_RELATIVE: Record<MemoryCostManagedPackageName, string> = {\r\n \"@kynver-app/runtime\": \"packages/kynver-runtime/package.json\",\r\n \"@kynver-app/openclaw-agent-os\": \"packages/kynver-openclaw-agent-os/package.json\",\r\n \"@kynver-app/mcp-agent-os\": \"packages/kynver-mcp-agent-os/package.json\",\r\n};\r\n\r\n/** Parse `major.minor.patch`; pre-release/build suffixes are ignored. */\r\nexport function parseSemverParts(version: string): [number, number, number] | null {\r\n const core = version.trim().split(\"-\")[0]?.split(\"+\")[0];\r\n if (!core) return null;\r\n const parts = core.split(\".\");\r\n if (parts.length < 1 || parts.length > 3) return null;\r\n const nums = parts.map((p) => Number.parseInt(p, 10));\r\n if (nums.some((n) => !Number.isFinite(n) || n < 0)) return null;\r\n while (nums.length < 3) nums.push(0);\r\n return [nums[0]!, nums[1]!, nums[2]!];\r\n}\r\n\r\n/** Returns 1 if a > b, -1 if a < b, 0 if equal or either unparsable. */\r\nexport function compareSemver(a: string, b: string): number {\r\n const pa = parseSemverParts(a);\r\n const pb = parseSemverParts(b);\r\n if (!pa || !pb) return 0;\r\n for (let i = 0; i < 3; i += 1) {\r\n if (pa[i]! > pb[i]!) return 1;\r\n if (pa[i]! < pb[i]!) return -1;\r\n }\r\n return 0;\r\n}\r\n\r\nexport function semverAtLeast(version: string, minimum: string): boolean {\r\n return compareSemver(version, minimum) >= 0;\r\n}\r\n\r\nfunction maxSemver(versions: readonly string[]): string | null {\r\n let best: string | null = null;\r\n for (const version of versions) {\r\n if (!best || compareSemver(version, best) > 0) best = version;\r\n }\r\n return best;\r\n}\r\n\r\nfunction readPackageJsonVersion(packageJsonPath: string): string | null {\r\n try {\r\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\r\n return typeof parsed.version === \"string\" && parsed.version.trim() ? parsed.version.trim() : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction resolveRepoRoot(cwd: string, explicitRepoRoot?: string): string | null {\r\n const candidates = [explicitRepoRoot, process.env.KYNVER_REPO, cwd].filter(\r\n (value): value is string => Boolean(value?.trim()),\r\n );\r\n for (const candidate of candidates) {\r\n const resolved = path.resolve(candidate);\r\n if (\r\n existsSync(path.join(resolved, \"packages/kynver-runtime/package.json\")) &&\r\n existsSync(path.join(resolved, \"package.json\"))\r\n ) {\r\n return resolved;\r\n }\r\n }\r\n const discovered = discoverDefaultRepo({ cwd });\r\n return discovered?.repo ?? null;\r\n}\r\n\r\nexport function probeRepoPackageVersions(input: {\r\n cwd?: string;\r\n repoRoot?: string;\r\n} = {}): Partial<Record<MemoryCostManagedPackageName, MemoryCostPackageVersionCandidate>> {\r\n const cwd = input.cwd ?? process.cwd();\r\n const repoRoot = resolveRepoRoot(cwd, input.repoRoot);\r\n if (!repoRoot) return {};\r\n\r\n const out: Partial<Record<MemoryCostManagedPackageName, MemoryCostPackageVersionCandidate>> = {};\r\n for (const packageName of MEMORY_COST_MANAGED_PACKAGES) {\r\n const packageJsonPath = path.join(repoRoot, REPO_PACKAGE_JSON_RELATIVE[packageName]);\r\n const version = readPackageJsonVersion(packageJsonPath);\r\n if (!version) continue;\r\n out[packageName] = { version, source: \"repo\", path: packageJsonPath };\r\n }\r\n return out;\r\n}\r\n\r\nfunction repoSourceCommands(packageName: MemoryCostManagedPackageName): string[] {\r\n if (packageName === \"@kynver-app/runtime\") {\r\n return [\"npm run kynver:build\", \"npm run kynver\"];\r\n }\r\n return [`npm run build -w ${packageName}`];\r\n}\r\n\r\nfunction buildRemediation(input: {\r\n packageName: MemoryCostManagedPackageName;\r\n minimumVersion: string;\r\n effectiveVersion: string | null;\r\n effectiveSource: MemoryCostVersionSource;\r\n repoVersion: string | null;\r\n}): string[] {\r\n const { packageName, minimumVersion, effectiveVersion, effectiveSource, repoVersion } = input;\r\n const lines: string[] = [];\r\n if (repoVersion && semverAtLeast(repoVersion, minimumVersion)) {\r\n lines.push(\r\n `Use the monorepo checkout (${repoVersion}) instead of a stale npm install: ${repoSourceCommands(packageName).join(\"; \")}.`,\r\n );\r\n lines.push(\"Do not publish npm packages or wait on an operator release.\");\r\n return lines;\r\n }\r\n if (effectiveVersion) {\r\n lines.push(\r\n `Upgrade ${packageName} from ${effectiveVersion} to >= ${minimumVersion} (npm install -g ${packageName}@latest or align OpenClaw npm prefix).`,\r\n );\r\n } else {\r\n lines.push(`Install ${packageName} >= ${minimumVersion} before running memory-heavy AgentOS paths.`);\r\n }\r\n if (packageName === \"@kynver-app/runtime\") {\r\n lines.push(\"Repo-source alternative: npm run kynver:build && npm run kynver\");\r\n }\r\n if (effectiveSource === \"installed\" && repoVersion) {\r\n lines.push(`Repo checkout reports ${repoVersion}; rebuild/link repo source if you develop from the monorepo.`);\r\n }\r\n return lines;\r\n}\r\n\r\nfunction pickEffectiveCandidate(\r\n candidates: MemoryCostPackageVersionCandidate[],\r\n): { version: string | null; source: MemoryCostVersionSource } {\r\n if (candidates.length === 0) return { version: null, source: \"unknown\" };\r\n const best = maxSemver(candidates.map((candidate) => candidate.version));\r\n if (!best) return { version: null, source: \"unknown\" };\r\n const winner = candidates.find((candidate) => candidate.version === best) ?? candidates[0]!;\r\n return { version: winner.version, source: winner.source };\r\n}\r\n\r\nexport function evaluateMemoryCostPackageVersionGuard(input: {\r\n installed?: Partial<Record<MemoryCostManagedPackageName, string | MemoryCostPackageVersionCandidate>>;\r\n repo?: Partial<Record<MemoryCostManagedPackageName, string | MemoryCostPackageVersionCandidate>>;\r\n self?: Partial<Record<MemoryCostManagedPackageName, string | MemoryCostPackageVersionCandidate>>;\r\n} = {}): MemoryCostPackageGuardResult {\r\n const normalize = (\r\n value: string | MemoryCostPackageVersionCandidate | undefined,\r\n fallbackSource: MemoryCostVersionSource,\r\n ): MemoryCostPackageVersionCandidate | null => {\r\n if (!value) return null;\r\n if (typeof value === \"string\") return { version: value, source: fallbackSource };\r\n return value;\r\n };\r\n\r\n const packages = MEMORY_COST_MANAGED_PACKAGES.map((packageName): MemoryCostPackageGuardRow => {\r\n const minimumVersion = MEMORY_COST_PACKAGE_MIN_VERSIONS[packageName];\r\n const candidates: MemoryCostPackageVersionCandidate[] = [];\r\n const installed = normalize(input.installed?.[packageName], \"installed\");\r\n const repo = normalize(input.repo?.[packageName], \"repo\");\r\n const self = normalize(input.self?.[packageName], \"self\");\r\n if (installed) candidates.push(installed);\r\n if (repo) candidates.push(repo);\r\n if (self) candidates.push(self);\r\n\r\n const { version: effectiveVersion, source: effectiveSource } = pickEffectiveCandidate(candidates);\r\n const repoVersion = repo?.version ?? null;\r\n const ok = effectiveVersion ? semverAtLeast(effectiveVersion, minimumVersion) : false;\r\n const remediation = ok\r\n ? []\r\n : buildRemediation({\r\n packageName,\r\n minimumVersion,\r\n effectiveVersion,\r\n effectiveSource,\r\n repoVersion,\r\n });\r\n\r\n const summary = ok\r\n ? `${DISPLAY_NAMES[packageName]} ${effectiveVersion} meets memory-cost minimum ${minimumVersion} (${effectiveSource}).`\r\n : `${DISPLAY_NAMES[packageName]} is below memory-cost minimum ${minimumVersion}` +\r\n (effectiveVersion ? ` (effective ${effectiveVersion} via ${effectiveSource})` : \" (no version detected)\") +\r\n \".\";\r\n\r\n return {\r\n packageName,\r\n displayName: DISPLAY_NAMES[packageName],\r\n minimumVersion,\r\n effectiveVersion,\r\n effectiveSource,\r\n ok,\r\n summary,\r\n remediation,\r\n };\r\n });\r\n\r\n const violations = packages.filter((row) => !row.ok);\r\n const ok = violations.length === 0;\r\n const summary = ok\r\n ? \"All managed AgentOS packages meet memory-cost minimum versions.\"\r\n : `Memory-cost package guard blocked ${violations.length} stale package(s): ${violations\r\n .map((row) => `${row.packageName} < ${row.minimumVersion}`)\r\n .join(\"; \")}.`;\r\n\r\n return { ok, summary, packages };\r\n}\r\n\r\nexport class MemoryCostPackageVersionGuardError extends Error {\r\n readonly result: MemoryCostPackageGuardResult;\r\n\r\n constructor(result: MemoryCostPackageGuardResult) {\r\n const lines = [\r\n result.summary,\r\n ...result.packages\r\n .filter((row) => !row.ok)\r\n .flatMap((row) => [`- ${row.summary}`, ...row.remediation.map((line) => ` \u2192 ${line}`)]),\r\n ];\r\n super(lines.join(\"\\n\"));\r\n this.name = \"MemoryCostPackageVersionGuardError\";\r\n this.result = result;\r\n }\r\n}\r\n\r\nexport function assertMemoryCostPackageVersionGuard(\r\n input: Parameters<typeof evaluateMemoryCostPackageVersionGuard>[0] = {},\r\n): MemoryCostPackageGuardResult {\r\n const result = evaluateMemoryCostPackageVersionGuard(input);\r\n if (!result.ok) throw new MemoryCostPackageVersionGuardError(result);\r\n return result;\r\n}\r\n\r\nexport function formatMemoryCostPackageGuardError(result: MemoryCostPackageGuardResult): string {\r\n return new MemoryCostPackageVersionGuardError(result).message;\r\n}\r\n", "import { existsSync, readFileSync } from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport path from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport { gitCapture } from \"./git.js\";\r\nimport { resolveUserPath } from \"./path-values.js\";\r\n\r\nexport type DefaultRepoDiscoverySource =\r\n | \"cwd_git\"\r\n | \"runtime_checkout\"\r\n | \"well_known_path\";\r\n\r\nexport interface DiscoveredDefaultRepo {\r\n repo: string;\r\n source: DefaultRepoDiscoverySource;\r\n}\r\n\r\nconst WELL_KNOWN_REPO_DIRS = [\r\n \"Kynver\",\r\n \"repos/Kynver\",\r\n \"repos/kynver-source-main\",\r\n \"code/Kynver\",\r\n \"projects/Kynver\",\r\n] as const;\r\n\r\nfunction readPackageName(repoRoot: string): string | null {\r\n const pkgPath = path.join(repoRoot, \"package.json\");\r\n if (!existsSync(pkgPath)) return null;\r\n try {\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { name?: string };\r\n return typeof pkg.name === \"string\" ? pkg.name.trim() : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function isKynverMonorepoRoot(repoRoot: string): boolean {\r\n return readPackageName(repoRoot) === \"kynver\";\r\n}\r\n\r\nexport function gitRepoRoot(startDir: string): string | null {\r\n const resolvedStart = path.resolve(startDir);\r\n if (!existsSync(resolvedStart)) return null;\r\n const probe = gitCapture(resolvedStart, [\"rev-parse\", \"--show-toplevel\"]);\r\n if (probe.status !== 0) return null;\r\n const root = probe.stdout.trim();\r\n return root.length ? path.resolve(root) : null;\r\n}\r\n\r\nfunction resolveRuntimePackageRoot(moduleUrl: string = import.meta.url): string | null {\r\n let dir = path.dirname(fileURLToPath(moduleUrl));\r\n for (let depth = 0; depth < 8; depth += 1) {\r\n const pkgPath = path.join(dir, \"package.json\");\r\n if (existsSync(pkgPath)) {\r\n try {\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { name?: string };\r\n if (pkg.name === \"@kynver-app/runtime\") return dir;\r\n } catch {\r\n // continue walking\r\n }\r\n }\r\n const parent = path.dirname(dir);\r\n if (parent === dir) break;\r\n dir = parent;\r\n }\r\n return null;\r\n}\r\n\r\nfunction pushCandidate(\r\n seen: Set<string>,\r\n out: DiscoveredDefaultRepo[],\r\n repo: string | null,\r\n source: DefaultRepoDiscoverySource,\r\n): void {\r\n if (!repo) return;\r\n const resolved = path.resolve(repo);\r\n if (seen.has(resolved)) return;\r\n if (!isKynverMonorepoRoot(resolved)) return;\r\n seen.add(resolved);\r\n out.push({ repo: resolved, source });\r\n}\r\n\r\nexport function discoverDefaultRepoCandidates(opts?: {\r\n cwd?: string;\r\n runtimeModuleUrl?: string;\r\n}): DiscoveredDefaultRepo[] {\r\n const cwd = opts?.cwd ?? process.cwd();\r\n const seen = new Set<string>();\r\n const candidates: DiscoveredDefaultRepo[] = [];\r\n\r\n pushCandidate(seen, candidates, gitRepoRoot(cwd), \"cwd_git\");\r\n\r\n const runtimePkgRoot = resolveRuntimePackageRoot(opts?.runtimeModuleUrl ?? import.meta.url);\r\n if (runtimePkgRoot) {\r\n pushCandidate(seen, candidates, gitRepoRoot(runtimePkgRoot), \"runtime_checkout\");\r\n }\r\n\r\n const home = homedir();\r\n for (const rel of WELL_KNOWN_REPO_DIRS) {\r\n pushCandidate(seen, candidates, resolveUserPath(path.join(home, rel)), \"well_known_path\");\r\n }\r\n\r\n return candidates;\r\n}\r\n\r\nexport function discoverDefaultRepo(opts?: {\r\n cwd?: string;\r\n runtimeModuleUrl?: string;\r\n}): DiscoveredDefaultRepo | null {\r\n return discoverDefaultRepoCandidates(opts)[0] ?? null;\r\n}\r\n", "import { spawnSync } from \"node:child_process\";\r\nimport { fail, hiddenSpawnOptions } from \"./util.js\";\r\n\r\nexport interface GitOptions {\r\n allowFailure?: boolean;\r\n throwError?: boolean;\r\n}\r\n\r\nexport function git(cwd: string, args: string[], options: GitOptions = {}): string {\r\n const res = spawnSync(\r\n \"git\",\r\n args,\r\n hiddenSpawnOptions({ cwd, encoding: \"utf8\" as const }),\r\n );\r\n if (res.status !== 0 && !options.allowFailure) {\r\n const message = `git ${args.join(\" \")} failed: ${res.stderr || res.stdout}`;\r\n if (options.throwError) throw new Error(message);\r\n fail(message);\r\n }\r\n return res.stdout || \"\";\r\n}\r\n\r\nexport function ensureGitRepo(repo: string): void {\r\n git(repo, [\"rev-parse\", \"--show-toplevel\"]);\r\n}\r\n\r\nexport function gitStatusShort(worktreePath: string): string[] {\r\n return git(worktreePath, [\"status\", \"--short\"], { allowFailure: true })\r\n .split(\"\\n\")\r\n .map((line) => line.trim())\r\n .filter(Boolean);\r\n}\r\n\r\nexport interface GitCaptureResult {\r\n status: number | null;\r\n stdout: string;\r\n stderr: string;\r\n error: string | null;\r\n}\r\n\r\nexport function gitCapture(cwd: string, args: string[]): GitCaptureResult {\r\n try {\r\n const res = spawnSync(\r\n \"git\",\r\n args,\r\n hiddenSpawnOptions({ cwd, encoding: \"utf8\" as const }),\r\n );\r\n return {\r\n status: res.status,\r\n stdout: res.stdout || \"\",\r\n stderr: res.stderr || \"\",\r\n error: res.error ? res.error.message : null,\r\n };\r\n } catch (error) {\r\n return {\r\n status: null,\r\n stdout: \"\",\r\n stderr: \"\",\r\n error: (error as Error).message,\r\n };\r\n }\r\n}\r\n\r\nexport function gitIsAncestor(\r\n cwd: string,\r\n ancestor: string,\r\n descendant: string,\r\n): { isAncestor: boolean | null; error: string | null } {\r\n const res = gitCapture(cwd, [\"merge-base\", \"--is-ancestor\", ancestor, descendant]);\r\n if (res.status === 0) return { isAncestor: true, error: null };\r\n if (res.status === 1) return { isAncestor: false, error: null };\r\n return { isAncestor: null, error: res.error || res.stderr || res.stdout || `git exited ${res.status}` };\r\n}\r\n\r\nexport type GitAncestryRelation = \"synced\" | \"merged\" | \"ahead\" | \"diverged\" | \"unknown\";\r\n\r\nexport interface GitAncestry {\r\n checked: boolean;\r\n base: string;\r\n head: string | null;\r\n baseHead: string | null;\r\n baseIsAncestorOfHead: boolean | null;\r\n headIsAncestorOfBase: boolean | null;\r\n relation: GitAncestryRelation;\r\n error?: string;\r\n}\r\n\r\nexport interface GitAncestryOptions {\r\n /** Branch or ref name (e.g. origin/main). Used when baseCommit is unset. */\r\n base?: string;\r\n /** Pinned SHA the worktree was created from \u2014 preferred over a moving branch ref. */\r\n baseCommit?: string;\r\n}\r\n\r\nexport function computeGitAncestry(worktreePath: string, baseOrOptions: string | GitAncestryOptions = \"origin/main\"): GitAncestry {\r\n const options: GitAncestryOptions =\r\n typeof baseOrOptions === \"string\" ? { base: baseOrOptions } : baseOrOptions;\r\n const baseLabel = options.baseCommit?.trim() || options.base?.trim() || \"origin/main\";\r\n const pinnedBaseCommit = options.baseCommit?.trim() || null;\r\n\r\n if (!worktreePath) {\r\n return unknownAncestry(baseLabel, \"missing worktree path\");\r\n }\r\n\r\n const head = gitCapture(worktreePath, [\"rev-parse\", \"HEAD\"]);\r\n if (head.status !== 0) {\r\n return unknownAncestry(baseLabel, head.error || head.stderr || head.stdout || \"failed to resolve HEAD\");\r\n }\r\n\r\n let baseSha: string;\r\n if (pinnedBaseCommit) {\r\n baseSha = pinnedBaseCommit;\r\n } else {\r\n const baseHead = gitCapture(worktreePath, [\"rev-parse\", baseLabel]);\r\n if (baseHead.status !== 0) {\r\n return unknownAncestry(\r\n baseLabel,\r\n baseHead.error || baseHead.stderr || baseHead.stdout || `failed to resolve ${baseLabel}`,\r\n head.stdout.trim(),\r\n );\r\n }\r\n baseSha = baseHead.stdout.trim();\r\n }\r\n\r\n const headSha = head.stdout.trim();\r\n if (headSha === baseSha) {\r\n return {\r\n checked: true,\r\n base: baseLabel,\r\n head: headSha,\r\n baseHead: baseSha,\r\n baseIsAncestorOfHead: true,\r\n headIsAncestorOfBase: true,\r\n relation: \"synced\",\r\n };\r\n }\r\n\r\n const baseIsAncestorOfHead = gitIsAncestor(worktreePath, baseSha, headSha);\r\n const headIsAncestorOfBase = gitIsAncestor(worktreePath, headSha, baseSha);\r\n const error = baseIsAncestorOfHead.error || headIsAncestorOfBase.error || undefined;\r\n if (baseIsAncestorOfHead.isAncestor == null || headIsAncestorOfBase.isAncestor == null) {\r\n return {\r\n checked: false,\r\n base: baseLabel,\r\n head: headSha,\r\n baseHead: baseSha,\r\n baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,\r\n headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,\r\n relation: \"unknown\",\r\n ...(error ? { error } : {}),\r\n };\r\n }\r\n\r\n const relation: GitAncestryRelation = baseIsAncestorOfHead.isAncestor\r\n ? \"ahead\"\r\n : headIsAncestorOfBase.isAncestor\r\n ? \"merged\"\r\n : \"diverged\";\r\n\r\n return {\r\n checked: true,\r\n base: baseLabel,\r\n head: headSha,\r\n baseHead: baseSha,\r\n baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,\r\n headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,\r\n relation,\r\n ...(error ? { error } : {}),\r\n };\r\n}\r\n\r\nfunction unknownAncestry(base: string, error: string, head: string | null = null): GitAncestry {\r\n return {\r\n checked: false,\r\n base,\r\n head,\r\n baseHead: null,\r\n baseIsAncestorOfHead: null,\r\n headIsAncestorOfBase: null,\r\n relation: \"unknown\",\r\n error,\r\n };\r\n}\r\n\r\nexport { scrubClaudeEnv, scrubWorkerEnv } from \"./worker-env.js\";\r\n", "import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from \"node:fs\";\r\nimport path from \"node:path\";\r\n\r\nexport function fail(message: string): never {\r\n console.error(message);\r\n process.exit(1);\r\n}\r\n\r\n/** Avoid flashing a visible console on Windows when spawning worker/sidecar children. */\r\nexport function hiddenSpawnOptions<T extends Record<string, unknown>>(opts: T): T {\r\n if (process.platform !== \"win32\") return opts;\r\n return { windowsHide: true, ...opts };\r\n}\r\n\r\nexport function required(value: string | undefined, name: string): string {\r\n if (!value) fail(`missing ${name}`);\r\n return value;\r\n}\r\n\r\nexport function safeJson(line: string): unknown {\r\n try {\r\n return JSON.parse(line);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function readJson<T>(file: string, fallback?: T): T {\r\n try {\r\n return JSON.parse(readFileSync(file, \"utf8\")) as T;\r\n } catch (error) {\r\n if (arguments.length > 1) return fallback as T;\r\n fail(`failed to read ${file}: ${(error as Error).message}`);\r\n }\r\n}\r\n\r\nexport function writeJson(file: string, value: unknown): void {\r\n mkdirSync(path.dirname(file), { recursive: true });\r\n writeFileSync(file, `${JSON.stringify(value, null, 2)}\\n`);\r\n}\r\n\r\nexport function safeSlug(value: string | undefined): string {\r\n return (\r\n String(value || \"\")\r\n .toLowerCase()\r\n .replace(/[^a-z0-9._-]+/g, \"-\")\r\n .replace(/^-+|-+$/g, \"\") || \"worker\"\r\n );\r\n}\r\n\r\nexport function timestampSlug(name: string): string {\r\n return safeSlug(`${new Date().toISOString().replace(/[-:]/g, \"\").replace(/\\..+/, \"Z\")}-${name}`);\r\n}\r\n\r\nexport function splitCsv(value: string | undefined): string[] {\r\n return value ? String(value).split(\",\").map((item) => item.trim()).filter(Boolean) : [];\r\n}\r\n\r\nexport function trimTrailingSlash(url: string): string {\r\n return String(url).replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport function oneLine(value: string): string {\r\n return String(value || \"\")\r\n .replace(/\\s+/g, \" \")\r\n .trim();\r\n}\r\n\r\nexport function fileSize(file: string): number {\r\n try {\r\n return statSync(file).size;\r\n } catch {\r\n return 0;\r\n }\r\n}\r\n\r\nexport function fileMtime(file: string): string | null {\r\n try {\r\n return statSync(file).mtime.toISOString();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function tailFile(file: string, lines: number): string {\r\n if (!existsSync(file)) return \"\";\r\n const data = readFileSync(file, \"utf8\");\r\n return data.split(\"\\n\").slice(-lines).join(\"\\n\");\r\n}\r\n\r\nexport function readMaybeFile(file: string | undefined): string {\r\n return file ? readFileSync(path.resolve(file), \"utf8\") : \"\";\r\n}\r\n\r\nexport function listRunIds(runsDir: string): string[] {\r\n if (!existsSync(runsDir)) return [];\r\n return readdirSync(runsDir, { withFileTypes: true })\r\n .filter((entry) => entry.isDirectory())\r\n .map((entry) => entry.name);\r\n}\r\n\r\nexport function sleepMs(ms: number): void {\r\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\r\n}\r\n\r\n/** Non-blocking sleep for async loops (daemon backoff, interruptible shutdown). */\r\nexport function sleepMsAsync(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport function isPidAlive(pid: number | undefined): boolean {\r\n if (!pid) return false;\r\n try {\r\n process.kill(pid, 0);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function killWorkerProcess(pid: number, signal: NodeJS.Signals): void {\r\n try {\r\n process.kill(-pid, signal);\r\n } catch {\r\n process.kill(pid, signal);\r\n }\r\n}\r\n\r\nexport function latestIso(values: Array<string | null | undefined>): string | null {\r\n let best: string | null = null;\r\n let bestMs = -Infinity;\r\n for (const value of values) {\r\n if (!value) continue;\r\n const ms = Date.parse(value);\r\n if (Number.isFinite(ms) && ms > bestMs) {\r\n bestMs = ms;\r\n best = value;\r\n }\r\n }\r\n return best;\r\n}\r\n\r\nexport function secsAgo(ms: number): number {\r\n return Math.max(0, Math.round((Date.now() - ms) / 1000));\r\n}\r\n", "/**\r\n * Worker spawn env scrub \u2014 harness workers must not inherit host deployment secrets.\r\n */\r\n\r\n/** Exact env keys that must never reach a worker child process. */\r\nexport const FORBIDDEN_WORKER_ENV_KEYS = [\r\n \"ANTHROPIC_API_KEY\",\r\n \"ANALYST_API_KEY\",\r\n \"RECRUITER_API_KEY\",\r\n \"AUTH_SECRET\",\r\n \"NEXTAUTH_SECRET\",\r\n \"DATABASE_URL\",\r\n \"PRODUCTION_DATABASE_URL\",\r\n \"KYNVER_PRODUCTION_DATABASE_URL\",\r\n \"REDIS_URL\",\r\n \"GOOGLE_CLIENT_SECRET\",\r\n \"GITHUB_CLIENT_SECRET\",\r\n \"KYNVER_API_KEY\",\r\n \"KYNVER_SERVICE_SECRET\",\r\n \"KYNVER_RUNTIME_SECRET\",\r\n \"KYNVER_CRON_SECRET\",\r\n \"OPENCLAW_CRON_SECRET\",\r\n \"QSTASH_TOKEN\",\r\n \"QSTASH_CURRENT_SIGNING_KEY\",\r\n \"QSTASH_NEXT_SIGNING_KEY\",\r\n \"TOOL_SECRETS_KEK\",\r\n \"TOOL_EXECUTOR_DISPATCH_SECRET\",\r\n \"CLOUDFLARE_API_TOKEN\",\r\n \"STRIPE_SECRET_KEY\",\r\n \"STRIPE_WEBHOOK_SECRET\",\r\n \"STRIPE_IDENTITY_WEBHOOK_SECRET\",\r\n \"VOYAGE_API_KEY\",\r\n \"PERPLEXITY_API_KEY\",\r\n \"FRED_API_KEY\",\r\n \"FMP_API_KEY\",\r\n \"CURSOR_API_KEY\",\r\n] as const;\r\n\r\nconst FORBIDDEN_KEY_SET = new Set<string>(FORBIDDEN_WORKER_ENV_KEYS);\r\n\r\n/** Keys matching these suffixes are stripped (case-sensitive). */\r\nconst FORBIDDEN_SUFFIXES = [\"_SECRET\", \"_API_KEY\"] as const;\r\n\r\nexport function isForbiddenWorkerEnvKey(key: string): boolean {\r\n if (FORBIDDEN_KEY_SET.has(key)) return true;\r\n return FORBIDDEN_SUFFIXES.some((suffix) => key.endsWith(suffix));\r\n}\r\n\r\nexport function listForbiddenWorkerEnvKeys(env: NodeJS.ProcessEnv): string[] {\r\n return Object.keys(env).filter(isForbiddenWorkerEnvKey).sort();\r\n}\r\n\r\nexport function scrubWorkerEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\r\n const next = { ...env };\r\n for (const key of Object.keys(next)) {\r\n if (isForbiddenWorkerEnvKey(key)) delete next[key];\r\n }\r\n return next;\r\n}\r\n\r\nexport interface WorkerEnvAudit {\r\n forbiddenPresent: string[];\r\n safe: boolean;\r\n}\r\n\r\nexport function auditWorkerEnv(env: NodeJS.ProcessEnv): WorkerEnvAudit {\r\n const forbiddenPresent = listForbiddenWorkerEnvKeys(env);\r\n return { forbiddenPresent, safe: forbiddenPresent.length === 0 };\r\n}\r\n\r\n/** @deprecated Use {@link scrubWorkerEnv} \u2014 kept for existing imports from git.ts */\r\nexport function scrubClaudeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\r\n return scrubWorkerEnv(env);\r\n}\r\n", "import { homedir } from \"node:os\";\r\nimport path from \"node:path\";\r\n\r\nexport function expandHomePath(value: string): string {\r\n if (value === \"~\") return homedir();\r\n if (value.startsWith(\"~/\") || value.startsWith(\"~\\\\\")) {\r\n return path.join(homedir(), value.slice(2));\r\n }\r\n return value;\r\n}\r\n\r\nexport function resolveUserPath(value: string): string {\r\n return path.resolve(expandHomePath(value));\r\n}\r\n\r\nexport function redactHomePath(value: string): string {\r\n const expanded = expandHomePath(value);\r\n const resolved = path.resolve(expanded);\r\n const home = path.resolve(homedir());\r\n\r\n if (resolved === home) return \"~\";\r\n if (resolved.startsWith(`${home}${path.sep}`)) {\r\n return `~/${path.relative(home, resolved).split(path.sep).join(\"/\")}`;\r\n }\r\n\r\n const posix = resolved.replace(/\\\\/g, \"/\");\r\n const redacted = posix\r\n .replace(/^\\/home\\/[^/]+(?=\\/|$)/, \"~\")\r\n .replace(/^\\/Users\\/[^/]+(?=\\/|$)/, \"~\")\r\n // Windows resolves Unix-style `/home/...` paths to `C:\\home\\...`.\r\n .replace(/^[A-Za-z]:\\/home\\/[^/]+(?=\\/|$)/i, \"~\")\r\n .replace(/^[A-Za-z]:\\/Users\\/[^/]+(?=\\/|$)/i, \"~\");\r\n return redacted;\r\n}\r\n\r\n/** User-facing path strings (doctor JSON, setup output). */\r\nexport function displayUserPath(value: string): string {\r\n return redactHomePath(value);\r\n}\r\n", "import { existsSync, readFileSync } from \"node:fs\";\r\nimport { dirname, join } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\n\r\nfunction resolvePackageRoot(moduleUrl: string): string {\r\n let dir = dirname(fileURLToPath(moduleUrl));\r\n for (let depth = 0; depth < 6; depth += 1) {\r\n if (existsSync(join(dir, \"package.json\"))) return dir;\r\n const parent = dirname(dir);\r\n if (parent === dir) break;\r\n dir = parent;\r\n }\r\n throw new Error(`package.json not found above ${dirname(fileURLToPath(moduleUrl))}`);\r\n}\r\n\r\nexport function readOwnPackageVersion(moduleUrl: string = import.meta.url): string {\r\n const pkgPath = join(resolvePackageRoot(moduleUrl), \"package.json\");\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { version?: string };\r\n if (typeof pkg.version !== \"string\" || !pkg.version.trim()) {\r\n throw new Error(`Missing package.json version at ${pkgPath}`);\r\n }\r\n return pkg.version;\r\n}\r\n\r\nexport const PACKAGE_VERSION = readOwnPackageVersion();\r\n\r\nexport function wantsCliVersion(argv: string[]): boolean {\r\n return argv.some((arg) => arg === \"--version\" || arg === \"-v\");\r\n}\r\n\r\nexport function printCliVersionAndExit(version: string, binName?: string): never {\r\n console.log(binName ? `${binName} ${version}` : version);\r\n process.exit(0);\r\n}\r\n\r\nexport function handleCliVersionFlag(\r\n argv: string[],\r\n moduleUrl: string = import.meta.url,\r\n binName?: string,\r\n): boolean {\r\n if (!wantsCliVersion(argv)) return false;\r\n printCliVersionAndExit(readOwnPackageVersion(moduleUrl), binName);\r\n return true;\r\n}\r\n", "import { collectInstalledPackageVersions } from \"./installed-package-versions.js\";\r\nimport {\r\n assertMemoryCostPackageVersionGuard,\r\n evaluateMemoryCostPackageVersionGuard,\r\n probeRepoPackageVersions,\r\n type MemoryCostManagedPackageName,\r\n type MemoryCostPackageGuardResult,\r\n} from \"./memory-cost-package-version-guard.js\";\r\nimport { PACKAGE_VERSION } from \"./package-version.js\";\r\n\r\nfunction installedVersionMap(\r\n observed: Awaited<ReturnType<typeof collectInstalledPackageVersions>>,\r\n): Partial<Record<MemoryCostManagedPackageName, { version: string; source: \"installed\"; path: string }>> {\r\n const out: Partial<\r\n Record<MemoryCostManagedPackageName, { version: string; source: \"installed\"; path: string }>\r\n > = {};\r\n for (const [packageName, row] of Object.entries(observed)) {\r\n if (!row?.version) continue;\r\n out[packageName as MemoryCostManagedPackageName] = {\r\n version: row.version,\r\n source: \"installed\",\r\n path: row.path,\r\n };\r\n }\r\n return out;\r\n}\r\n\r\nexport async function buildMemoryCostPackageGuardInput(input: {\r\n cwd?: string;\r\n repoRoot?: string;\r\n selfPackageName?: MemoryCostManagedPackageName;\r\n selfVersion?: string;\r\n} = {}): Promise<Parameters<typeof evaluateMemoryCostPackageVersionGuard>[0]> {\r\n const [installed, repo] = await Promise.all([\r\n collectInstalledPackageVersions(),\r\n Promise.resolve(probeRepoPackageVersions({ cwd: input.cwd, repoRoot: input.repoRoot })),\r\n ]);\r\n\r\n const self: Partial<Record<MemoryCostManagedPackageName, { version: string; source: \"self\" }>> = {};\r\n const runtimeSelfVersion =\r\n input.selfPackageName === \"@kynver-app/runtime\" && input.selfVersion\r\n ? input.selfVersion\r\n : PACKAGE_VERSION;\r\n self[\"@kynver-app/runtime\"] = { version: runtimeSelfVersion, source: \"self\" };\r\n if (\r\n input.selfPackageName &&\r\n input.selfVersion &&\r\n input.selfPackageName !== \"@kynver-app/runtime\"\r\n ) {\r\n self[input.selfPackageName] = { version: input.selfVersion, source: \"self\" };\r\n }\r\n\r\n return {\r\n installed: installedVersionMap(installed),\r\n repo,\r\n self,\r\n };\r\n}\r\n\r\nexport async function evaluateMemoryCostPackageGuardAtStartup(\r\n input: Parameters<typeof buildMemoryCostPackageGuardInput>[0] = {},\r\n): Promise<MemoryCostPackageGuardResult> {\r\n const guardInput = await buildMemoryCostPackageGuardInput(input);\r\n return evaluateMemoryCostPackageVersionGuard(guardInput);\r\n}\r\n\r\nexport async function enforceMemoryCostPackageGuardAtStartup(\r\n input: Parameters<typeof buildMemoryCostPackageGuardInput>[0] = {},\r\n): Promise<MemoryCostPackageGuardResult> {\r\n const guardInput = await buildMemoryCostPackageGuardInput(input);\r\n return assertMemoryCostPackageVersionGuard(guardInput);\r\n}\r\n\r\nexport function shouldEnforceMemoryCostPackageGuardCli(scope?: string, action?: string): boolean {\r\n if (!scope) return false;\r\n if (scope === \"daemon\") return true;\r\n if (scope === \"worker\") return true;\r\n if (scope === \"monitor\") return true;\r\n if (scope === \"run\" && (action === \"dispatch\" || action === \"sweep\" || action === \"reconcile\" || action === \"unblock\")) {\r\n return true;\r\n }\r\n if (scope === \"cron\" && action === \"tick\") return true;\r\n return false;\r\n}\r\n"],
|
|
4
|
+
"sourcesContent": ["import { readFile } from \"node:fs/promises\";\r\nimport { homedir } from \"node:os\";\r\nimport path from \"node:path\";\r\nimport { compareSemver } from \"./memory-cost-package-version-guard.js\";\r\n\r\nconst MANAGED_PACKAGES = [\r\n \"@kynver-app/runtime\",\r\n \"@kynver-app/openclaw-agent-os\",\r\n \"@kynver-app/mcp-agent-os\",\r\n] as const;\r\n\r\nexport type InstalledPackageVersionMap = Record<\r\n string,\r\n {\r\n version: string;\r\n observedAt: string;\r\n path: string;\r\n }\r\n>;\r\n\r\nfunction trim(value: string | undefined): string | null {\r\n const out = value?.trim();\r\n return out ? out : null;\r\n}\r\n\r\nfunction unique(values: Array<string | null | undefined>): string[] {\r\n return [...new Set(values.filter((value): value is string => Boolean(value)))];\r\n}\r\n\r\nfunction moduleRoots(): string[] {\r\n const home = homedir();\r\n const openClawPrefix =\r\n trim(process.env.KYNVER_OPENCLAW_NPM_ROOT) ??\r\n trim(process.env.OPENCLAW_NPM_ROOT) ??\r\n path.join(home, \".openclaw\", \"npm\");\r\n const npmGlobalRoot =\r\n trim(process.env.KYNVER_NPM_GLOBAL_ROOT) ??\r\n trim(process.env.KYNVER_NPM_GLOBAL_MODULES_ROOT) ??\r\n (trim(process.env.NPM_CONFIG_PREFIX)\r\n ? path.join(trim(process.env.NPM_CONFIG_PREFIX)!, \"lib\", \"node_modules\")\r\n : path.join(home, \".npm-global\", \"lib\", \"node_modules\"));\r\n\r\n return unique([\r\n path.join(openClawPrefix, \"lib\", \"node_modules\"),\r\n path.join(openClawPrefix, \"node_modules\"),\r\n npmGlobalRoot.endsWith(\"node_modules\") ? npmGlobalRoot : path.join(npmGlobalRoot, \"lib\", \"node_modules\"),\r\n ]);\r\n}\r\n\r\nasync function readVersion(packageJsonPath: string): Promise<string | null> {\r\n try {\r\n const parsed = JSON.parse(await readFile(packageJsonPath, \"utf8\")) as { version?: unknown };\r\n return typeof parsed.version === \"string\" && parsed.version.trim() ? parsed.version.trim() : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/** Candidate install paths for one managed package across OpenClaw + global npm roots. */\r\nexport function installedPackageJsonCandidates(packageName: string): string[] {\r\n const roots = moduleRoots();\r\n const seen = new Set<string>();\r\n const out: string[] = [];\r\n for (const root of roots) {\r\n const candidate = path.join(root, packageName, \"package.json\");\r\n if (seen.has(candidate)) continue;\r\n seen.add(candidate);\r\n out.push(candidate);\r\n }\r\n return out;\r\n}\r\n\r\nexport async function collectInstalledPackageVersions(\r\n observedAt: string = new Date().toISOString(),\r\n): Promise<InstalledPackageVersionMap> {\r\n const out: InstalledPackageVersionMap = {};\r\n for (const packageName of MANAGED_PACKAGES) {\r\n let best: { version: string; path: string } | null = null;\r\n for (const packageJsonPath of installedPackageJsonCandidates(packageName)) {\r\n const version = await readVersion(packageJsonPath);\r\n if (!version) continue;\r\n if (!best || compareSemver(version, best.version) > 0) {\r\n best = { version, path: packageJsonPath };\r\n }\r\n }\r\n if (best) {\r\n out[packageName] = { version: best.version, observedAt, path: best.path };\r\n }\r\n }\r\n return out;\r\n}\r\n", "import { existsSync, readFileSync } from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { discoverDefaultRepo } from \"./default-repo-discovery.js\";\r\n\r\n/** Minimum versions that ship MARM memory cost controls (PR #1159). */\r\nexport const MEMORY_COST_PACKAGE_MIN_VERSIONS = {\r\n \"@kynver-app/runtime\": \"0.1.83\",\r\n \"@kynver-app/openclaw-agent-os\": \"0.1.43\",\r\n \"@kynver-app/mcp-agent-os\": \"0.3.34\",\r\n} as const;\r\n\r\nexport type MemoryCostManagedPackageName = keyof typeof MEMORY_COST_PACKAGE_MIN_VERSIONS;\r\n\r\nexport const MEMORY_COST_MANAGED_PACKAGES = Object.keys(\r\n MEMORY_COST_PACKAGE_MIN_VERSIONS,\r\n) as MemoryCostManagedPackageName[];\r\n\r\nexport type MemoryCostVersionSource = \"self\" | \"installed\" | \"repo\" | \"unknown\";\r\n\r\nexport interface MemoryCostPackageVersionCandidate {\r\n version: string;\r\n source: MemoryCostVersionSource;\r\n path?: string;\r\n}\r\n\r\nexport interface MemoryCostPackageGuardRow {\r\n packageName: MemoryCostManagedPackageName;\r\n displayName: string;\r\n minimumVersion: string;\r\n effectiveVersion: string | null;\r\n effectiveSource: MemoryCostVersionSource;\r\n ok: boolean;\r\n summary: string;\r\n remediation: string[];\r\n}\r\n\r\nexport interface MemoryCostPackageGuardResult {\r\n ok: boolean;\r\n summary: string;\r\n packages: MemoryCostPackageGuardRow[];\r\n}\r\n\r\nconst DISPLAY_NAMES: Record<MemoryCostManagedPackageName, string> = {\r\n \"@kynver-app/runtime\": \"Kynver runtime\",\r\n \"@kynver-app/openclaw-agent-os\": \"OpenClaw AgentOS plugin\",\r\n \"@kynver-app/mcp-agent-os\": \"AgentOS MCP server\",\r\n};\r\n\r\nconst REPO_PACKAGE_JSON_RELATIVE: Record<MemoryCostManagedPackageName, string> = {\r\n \"@kynver-app/runtime\": \"packages/kynver-runtime/package.json\",\r\n \"@kynver-app/openclaw-agent-os\": \"packages/kynver-openclaw-agent-os/package.json\",\r\n \"@kynver-app/mcp-agent-os\": \"packages/kynver-mcp-agent-os/package.json\",\r\n};\r\n\r\n/** Parse `major.minor.patch`; pre-release/build suffixes are ignored. */\r\nexport function parseSemverParts(version: string): [number, number, number] | null {\r\n const core = version.trim().split(\"-\")[0]?.split(\"+\")[0];\r\n if (!core) return null;\r\n const parts = core.split(\".\");\r\n if (parts.length < 1 || parts.length > 3) return null;\r\n const nums = parts.map((p) => Number.parseInt(p, 10));\r\n if (nums.some((n) => !Number.isFinite(n) || n < 0)) return null;\r\n while (nums.length < 3) nums.push(0);\r\n return [nums[0]!, nums[1]!, nums[2]!];\r\n}\r\n\r\n/** Returns 1 if a > b, -1 if a < b, 0 if equal or either unparsable. */\r\nexport function compareSemver(a: string, b: string): number {\r\n const pa = parseSemverParts(a);\r\n const pb = parseSemverParts(b);\r\n if (!pa || !pb) return 0;\r\n for (let i = 0; i < 3; i += 1) {\r\n if (pa[i]! > pb[i]!) return 1;\r\n if (pa[i]! < pb[i]!) return -1;\r\n }\r\n return 0;\r\n}\r\n\r\nexport function semverAtLeast(version: string, minimum: string): boolean {\r\n return compareSemver(version, minimum) >= 0;\r\n}\r\n\r\nfunction maxSemver(versions: readonly string[]): string | null {\r\n let best: string | null = null;\r\n for (const version of versions) {\r\n if (!best || compareSemver(version, best) > 0) best = version;\r\n }\r\n return best;\r\n}\r\n\r\nfunction readPackageJsonVersion(packageJsonPath: string): string | null {\r\n try {\r\n const parsed = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\r\n return typeof parsed.version === \"string\" && parsed.version.trim() ? parsed.version.trim() : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction resolveRepoRoot(cwd: string, explicitRepoRoot?: string): string | null {\r\n const candidates = [explicitRepoRoot, process.env.KYNVER_REPO, cwd].filter(\r\n (value): value is string => Boolean(value?.trim()),\r\n );\r\n for (const candidate of candidates) {\r\n const resolved = path.resolve(candidate);\r\n if (\r\n existsSync(path.join(resolved, \"packages/kynver-runtime/package.json\")) &&\r\n existsSync(path.join(resolved, \"package.json\"))\r\n ) {\r\n return resolved;\r\n }\r\n }\r\n const discovered = discoverDefaultRepo({ cwd });\r\n return discovered?.repo ?? null;\r\n}\r\n\r\nexport function probeRepoPackageVersions(input: {\r\n cwd?: string;\r\n repoRoot?: string;\r\n} = {}): Partial<Record<MemoryCostManagedPackageName, MemoryCostPackageVersionCandidate>> {\r\n const cwd = input.cwd ?? process.cwd();\r\n const repoRoot = resolveRepoRoot(cwd, input.repoRoot);\r\n if (!repoRoot) return {};\r\n\r\n const out: Partial<Record<MemoryCostManagedPackageName, MemoryCostPackageVersionCandidate>> = {};\r\n for (const packageName of MEMORY_COST_MANAGED_PACKAGES) {\r\n const packageJsonPath = path.join(repoRoot, REPO_PACKAGE_JSON_RELATIVE[packageName]);\r\n const version = readPackageJsonVersion(packageJsonPath);\r\n if (!version) continue;\r\n out[packageName] = { version, source: \"repo\", path: packageJsonPath };\r\n }\r\n return out;\r\n}\r\n\r\nfunction repoSourceCommands(packageName: MemoryCostManagedPackageName): string[] {\r\n if (packageName === \"@kynver-app/runtime\") {\r\n return [\"npm run kynver:build\", \"npm run kynver\"];\r\n }\r\n return [`npm run build -w ${packageName}`];\r\n}\r\n\r\nfunction buildRemediation(input: {\r\n packageName: MemoryCostManagedPackageName;\r\n minimumVersion: string;\r\n effectiveVersion: string | null;\r\n effectiveSource: MemoryCostVersionSource;\r\n repoVersion: string | null;\r\n}): string[] {\r\n const { packageName, minimumVersion, effectiveVersion, effectiveSource, repoVersion } = input;\r\n const lines: string[] = [];\r\n if (repoVersion && semverAtLeast(repoVersion, minimumVersion)) {\r\n lines.push(\r\n `Use the monorepo checkout (${repoVersion}) instead of a stale npm install: ${repoSourceCommands(packageName).join(\"; \")}.`,\r\n );\r\n lines.push(\"Do not publish npm packages or wait on an operator release.\");\r\n return lines;\r\n }\r\n if (effectiveVersion) {\r\n lines.push(\r\n `Upgrade ${packageName} from ${effectiveVersion} to >= ${minimumVersion} (npm install -g ${packageName}@latest or align OpenClaw npm prefix).`,\r\n );\r\n } else {\r\n lines.push(`Install ${packageName} >= ${minimumVersion} before running memory-heavy AgentOS paths.`);\r\n }\r\n if (packageName === \"@kynver-app/runtime\") {\r\n lines.push(\"Repo-source alternative: npm run kynver:build && npm run kynver\");\r\n }\r\n if (effectiveSource === \"installed\" && repoVersion) {\r\n lines.push(`Repo checkout reports ${repoVersion}; rebuild/link repo source if you develop from the monorepo.`);\r\n }\r\n return lines;\r\n}\r\n\r\nfunction pickEffectiveCandidate(\r\n candidates: MemoryCostPackageVersionCandidate[],\r\n): { version: string | null; source: MemoryCostVersionSource } {\r\n if (candidates.length === 0) return { version: null, source: \"unknown\" };\r\n const best = maxSemver(candidates.map((candidate) => candidate.version));\r\n if (!best) return { version: null, source: \"unknown\" };\r\n const winner = candidates.find((candidate) => candidate.version === best) ?? candidates[0]!;\r\n return { version: winner.version, source: winner.source };\r\n}\r\n\r\nexport function evaluateMemoryCostPackageVersionGuard(input: {\r\n installed?: Partial<Record<MemoryCostManagedPackageName, string | MemoryCostPackageVersionCandidate>>;\r\n repo?: Partial<Record<MemoryCostManagedPackageName, string | MemoryCostPackageVersionCandidate>>;\r\n self?: Partial<Record<MemoryCostManagedPackageName, string | MemoryCostPackageVersionCandidate>>;\r\n} = {}): MemoryCostPackageGuardResult {\r\n const normalize = (\r\n value: string | MemoryCostPackageVersionCandidate | undefined,\r\n fallbackSource: MemoryCostVersionSource,\r\n ): MemoryCostPackageVersionCandidate | null => {\r\n if (!value) return null;\r\n if (typeof value === \"string\") return { version: value, source: fallbackSource };\r\n return value;\r\n };\r\n\r\n const packages = MEMORY_COST_MANAGED_PACKAGES.map((packageName): MemoryCostPackageGuardRow => {\r\n const minimumVersion = MEMORY_COST_PACKAGE_MIN_VERSIONS[packageName];\r\n const candidates: MemoryCostPackageVersionCandidate[] = [];\r\n const installed = normalize(input.installed?.[packageName], \"installed\");\r\n const repo = normalize(input.repo?.[packageName], \"repo\");\r\n const self = normalize(input.self?.[packageName], \"self\");\r\n if (installed) candidates.push(installed);\r\n if (repo) candidates.push(repo);\r\n if (self) candidates.push(self);\r\n\r\n const { version: effectiveVersion, source: effectiveSource } = pickEffectiveCandidate(candidates);\r\n const repoVersion = repo?.version ?? null;\r\n const ok = effectiveVersion ? semverAtLeast(effectiveVersion, minimumVersion) : false;\r\n const remediation = ok\r\n ? []\r\n : buildRemediation({\r\n packageName,\r\n minimumVersion,\r\n effectiveVersion,\r\n effectiveSource,\r\n repoVersion,\r\n });\r\n\r\n const summary = ok\r\n ? `${DISPLAY_NAMES[packageName]} ${effectiveVersion} meets memory-cost minimum ${minimumVersion} (${effectiveSource}).`\r\n : `${DISPLAY_NAMES[packageName]} is below memory-cost minimum ${minimumVersion}` +\r\n (effectiveVersion ? ` (effective ${effectiveVersion} via ${effectiveSource})` : \" (no version detected)\") +\r\n \".\";\r\n\r\n return {\r\n packageName,\r\n displayName: DISPLAY_NAMES[packageName],\r\n minimumVersion,\r\n effectiveVersion,\r\n effectiveSource,\r\n ok,\r\n summary,\r\n remediation,\r\n };\r\n });\r\n\r\n const violations = packages.filter((row) => !row.ok);\r\n const ok = violations.length === 0;\r\n const summary = ok\r\n ? \"All managed AgentOS packages meet memory-cost minimum versions.\"\r\n : `Memory-cost package guard blocked ${violations.length} stale package(s): ${violations\r\n .map((row) => `${row.packageName} < ${row.minimumVersion}`)\r\n .join(\"; \")}.`;\r\n\r\n return { ok, summary, packages };\r\n}\r\n\r\nexport class MemoryCostPackageVersionGuardError extends Error {\r\n readonly result: MemoryCostPackageGuardResult;\r\n\r\n constructor(result: MemoryCostPackageGuardResult) {\r\n const lines = [\r\n result.summary,\r\n ...result.packages\r\n .filter((row) => !row.ok)\r\n .flatMap((row) => [`- ${row.summary}`, ...row.remediation.map((line) => ` \u2192 ${line}`)]),\r\n ];\r\n super(lines.join(\"\\n\"));\r\n this.name = \"MemoryCostPackageVersionGuardError\";\r\n this.result = result;\r\n }\r\n}\r\n\r\nexport function assertMemoryCostPackageVersionGuard(\r\n input: Parameters<typeof evaluateMemoryCostPackageVersionGuard>[0] = {},\r\n): MemoryCostPackageGuardResult {\r\n const result = evaluateMemoryCostPackageVersionGuard(input);\r\n if (!result.ok) throw new MemoryCostPackageVersionGuardError(result);\r\n return result;\r\n}\r\n\r\nexport function formatMemoryCostPackageGuardError(result: MemoryCostPackageGuardResult): string {\r\n return new MemoryCostPackageVersionGuardError(result).message;\r\n}\r\n", "import { existsSync, readFileSync } from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport path from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\nimport { gitCapture } from \"./git.js\";\r\nimport { resolveUserPath } from \"./path-values.js\";\r\n\r\nexport type DefaultRepoDiscoverySource =\r\n | \"cwd_git\"\r\n | \"runtime_checkout\"\r\n | \"well_known_path\";\r\n\r\nexport interface DiscoveredDefaultRepo {\r\n repo: string;\r\n source: DefaultRepoDiscoverySource;\r\n}\r\n\r\nconst WELL_KNOWN_REPO_DIRS = [\r\n \"Kynver\",\r\n \"repos/Kynver\",\r\n \"repos/kynver-source-main\",\r\n \"code/Kynver\",\r\n \"projects/Kynver\",\r\n] as const;\r\n\r\nfunction readPackageName(repoRoot: string): string | null {\r\n const pkgPath = path.join(repoRoot, \"package.json\");\r\n if (!existsSync(pkgPath)) return null;\r\n try {\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { name?: string };\r\n return typeof pkg.name === \"string\" ? pkg.name.trim() : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function isKynverMonorepoRoot(repoRoot: string): boolean {\r\n return readPackageName(repoRoot) === \"kynver\";\r\n}\r\n\r\nexport function gitRepoRoot(startDir: string): string | null {\r\n const resolvedStart = path.resolve(startDir);\r\n if (!existsSync(resolvedStart)) return null;\r\n const probe = gitCapture(resolvedStart, [\"rev-parse\", \"--show-toplevel\"]);\r\n if (probe.status !== 0) return null;\r\n const root = probe.stdout.trim();\r\n return root.length ? path.resolve(root) : null;\r\n}\r\n\r\nfunction resolveRuntimePackageRoot(moduleUrl: string = import.meta.url): string | null {\r\n let dir = path.dirname(fileURLToPath(moduleUrl));\r\n for (let depth = 0; depth < 8; depth += 1) {\r\n const pkgPath = path.join(dir, \"package.json\");\r\n if (existsSync(pkgPath)) {\r\n try {\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { name?: string };\r\n if (pkg.name === \"@kynver-app/runtime\") return dir;\r\n } catch {\r\n // continue walking\r\n }\r\n }\r\n const parent = path.dirname(dir);\r\n if (parent === dir) break;\r\n dir = parent;\r\n }\r\n return null;\r\n}\r\n\r\nfunction pushCandidate(\r\n seen: Set<string>,\r\n out: DiscoveredDefaultRepo[],\r\n repo: string | null,\r\n source: DefaultRepoDiscoverySource,\r\n): void {\r\n if (!repo) return;\r\n const resolved = path.resolve(repo);\r\n if (seen.has(resolved)) return;\r\n if (!isKynverMonorepoRoot(resolved)) return;\r\n seen.add(resolved);\r\n out.push({ repo: resolved, source });\r\n}\r\n\r\nexport function discoverDefaultRepoCandidates(opts?: {\r\n cwd?: string;\r\n runtimeModuleUrl?: string;\r\n}): DiscoveredDefaultRepo[] {\r\n const cwd = opts?.cwd ?? process.cwd();\r\n const seen = new Set<string>();\r\n const candidates: DiscoveredDefaultRepo[] = [];\r\n\r\n pushCandidate(seen, candidates, gitRepoRoot(cwd), \"cwd_git\");\r\n\r\n const runtimePkgRoot = resolveRuntimePackageRoot(opts?.runtimeModuleUrl ?? import.meta.url);\r\n if (runtimePkgRoot) {\r\n pushCandidate(seen, candidates, gitRepoRoot(runtimePkgRoot), \"runtime_checkout\");\r\n }\r\n\r\n const home = homedir();\r\n for (const rel of WELL_KNOWN_REPO_DIRS) {\r\n pushCandidate(seen, candidates, resolveUserPath(path.join(home, rel)), \"well_known_path\");\r\n }\r\n\r\n return candidates;\r\n}\r\n\r\nexport function discoverDefaultRepo(opts?: {\r\n cwd?: string;\r\n runtimeModuleUrl?: string;\r\n}): DiscoveredDefaultRepo | null {\r\n return discoverDefaultRepoCandidates(opts)[0] ?? null;\r\n}\r\n", "import { spawnSync } from \"node:child_process\";\r\nimport { fail, hiddenSpawnOptions } from \"./util.js\";\r\n\r\nexport interface GitOptions {\r\n allowFailure?: boolean;\r\n throwError?: boolean;\r\n}\r\n\r\nexport function git(cwd: string, args: string[], options: GitOptions = {}): string {\r\n const res = spawnSync(\r\n \"git\",\r\n args,\r\n hiddenSpawnOptions({ cwd, encoding: \"utf8\" as const }),\r\n );\r\n if (res.status !== 0 && !options.allowFailure) {\r\n const message = `git ${args.join(\" \")} failed: ${res.stderr || res.stdout}`;\r\n if (options.throwError) throw new Error(message);\r\n fail(message);\r\n }\r\n return res.stdout || \"\";\r\n}\r\n\r\nexport function ensureGitRepo(repo: string): void {\r\n git(repo, [\"rev-parse\", \"--show-toplevel\"]);\r\n}\r\n\r\nexport function gitStatusShort(worktreePath: string): string[] {\r\n return git(worktreePath, [\"status\", \"--short\"], { allowFailure: true })\r\n .split(\"\\n\")\r\n .map((line) => line.trim())\r\n .filter(Boolean);\r\n}\r\n\r\nexport interface GitCaptureResult {\r\n status: number | null;\r\n stdout: string;\r\n stderr: string;\r\n error: string | null;\r\n}\r\n\r\nexport function gitCapture(cwd: string, args: string[]): GitCaptureResult {\r\n try {\r\n const res = spawnSync(\r\n \"git\",\r\n args,\r\n hiddenSpawnOptions({ cwd, encoding: \"utf8\" as const }),\r\n );\r\n return {\r\n status: res.status,\r\n stdout: res.stdout || \"\",\r\n stderr: res.stderr || \"\",\r\n error: res.error ? res.error.message : null,\r\n };\r\n } catch (error) {\r\n return {\r\n status: null,\r\n stdout: \"\",\r\n stderr: \"\",\r\n error: (error as Error).message,\r\n };\r\n }\r\n}\r\n\r\nexport function gitIsAncestor(\r\n cwd: string,\r\n ancestor: string,\r\n descendant: string,\r\n): { isAncestor: boolean | null; error: string | null } {\r\n const res = gitCapture(cwd, [\"merge-base\", \"--is-ancestor\", ancestor, descendant]);\r\n if (res.status === 0) return { isAncestor: true, error: null };\r\n if (res.status === 1) return { isAncestor: false, error: null };\r\n return { isAncestor: null, error: res.error || res.stderr || res.stdout || `git exited ${res.status}` };\r\n}\r\n\r\nexport type GitAncestryRelation = \"synced\" | \"merged\" | \"ahead\" | \"diverged\" | \"unknown\";\r\n\r\nexport interface GitAncestry {\r\n checked: boolean;\r\n base: string;\r\n head: string | null;\r\n baseHead: string | null;\r\n baseIsAncestorOfHead: boolean | null;\r\n headIsAncestorOfBase: boolean | null;\r\n relation: GitAncestryRelation;\r\n error?: string;\r\n}\r\n\r\nexport interface GitAncestryOptions {\r\n /** Branch or ref name (e.g. origin/main). Used when baseCommit is unset. */\r\n base?: string;\r\n /** Pinned SHA the worktree was created from \u2014 preferred over a moving branch ref. */\r\n baseCommit?: string;\r\n}\r\n\r\nexport function computeGitAncestry(worktreePath: string, baseOrOptions: string | GitAncestryOptions = \"origin/main\"): GitAncestry {\r\n const options: GitAncestryOptions =\r\n typeof baseOrOptions === \"string\" ? { base: baseOrOptions } : baseOrOptions;\r\n const baseLabel = options.baseCommit?.trim() || options.base?.trim() || \"origin/main\";\r\n const pinnedBaseCommit = options.baseCommit?.trim() || null;\r\n\r\n if (!worktreePath) {\r\n return unknownAncestry(baseLabel, \"missing worktree path\");\r\n }\r\n\r\n const head = gitCapture(worktreePath, [\"rev-parse\", \"HEAD\"]);\r\n if (head.status !== 0) {\r\n return unknownAncestry(baseLabel, head.error || head.stderr || head.stdout || \"failed to resolve HEAD\");\r\n }\r\n\r\n let baseSha: string;\r\n if (pinnedBaseCommit) {\r\n baseSha = pinnedBaseCommit;\r\n } else {\r\n const baseHead = gitCapture(worktreePath, [\"rev-parse\", baseLabel]);\r\n if (baseHead.status !== 0) {\r\n return unknownAncestry(\r\n baseLabel,\r\n baseHead.error || baseHead.stderr || baseHead.stdout || `failed to resolve ${baseLabel}`,\r\n head.stdout.trim(),\r\n );\r\n }\r\n baseSha = baseHead.stdout.trim();\r\n }\r\n\r\n const headSha = head.stdout.trim();\r\n if (headSha === baseSha) {\r\n return {\r\n checked: true,\r\n base: baseLabel,\r\n head: headSha,\r\n baseHead: baseSha,\r\n baseIsAncestorOfHead: true,\r\n headIsAncestorOfBase: true,\r\n relation: \"synced\",\r\n };\r\n }\r\n\r\n const baseIsAncestorOfHead = gitIsAncestor(worktreePath, baseSha, headSha);\r\n const headIsAncestorOfBase = gitIsAncestor(worktreePath, headSha, baseSha);\r\n const error = baseIsAncestorOfHead.error || headIsAncestorOfBase.error || undefined;\r\n if (baseIsAncestorOfHead.isAncestor == null || headIsAncestorOfBase.isAncestor == null) {\r\n return {\r\n checked: false,\r\n base: baseLabel,\r\n head: headSha,\r\n baseHead: baseSha,\r\n baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,\r\n headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,\r\n relation: \"unknown\",\r\n ...(error ? { error } : {}),\r\n };\r\n }\r\n\r\n const relation: GitAncestryRelation = baseIsAncestorOfHead.isAncestor\r\n ? \"ahead\"\r\n : headIsAncestorOfBase.isAncestor\r\n ? \"merged\"\r\n : \"diverged\";\r\n\r\n return {\r\n checked: true,\r\n base: baseLabel,\r\n head: headSha,\r\n baseHead: baseSha,\r\n baseIsAncestorOfHead: baseIsAncestorOfHead.isAncestor,\r\n headIsAncestorOfBase: headIsAncestorOfBase.isAncestor,\r\n relation,\r\n ...(error ? { error } : {}),\r\n };\r\n}\r\n\r\nfunction unknownAncestry(base: string, error: string, head: string | null = null): GitAncestry {\r\n return {\r\n checked: false,\r\n base,\r\n head,\r\n baseHead: null,\r\n baseIsAncestorOfHead: null,\r\n headIsAncestorOfBase: null,\r\n relation: \"unknown\",\r\n error,\r\n };\r\n}\r\n\r\nexport { scrubClaudeEnv, scrubWorkerEnv } from \"./worker-env.js\";\r\n", "import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from \"node:fs\";\r\nimport path from \"node:path\";\r\n\r\nexport function fail(message: string): never {\r\n console.error(message);\r\n process.exit(1);\r\n}\r\n\r\n/** Avoid flashing a visible console on Windows when spawning worker/sidecar children. */\r\nexport function hiddenSpawnOptions<T extends Record<string, unknown>>(opts: T): T {\r\n if (process.platform !== \"win32\") return opts;\r\n return { windowsHide: true, ...opts };\r\n}\r\n\r\nexport function required(value: string | undefined, name: string): string {\r\n if (!value) fail(`missing ${name}`);\r\n return value;\r\n}\r\n\r\nexport function safeJson(line: string): unknown {\r\n try {\r\n return JSON.parse(line);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function readJson<T>(file: string, fallback?: T): T {\r\n try {\r\n return JSON.parse(readFileSync(file, \"utf8\")) as T;\r\n } catch (error) {\r\n if (arguments.length > 1) return fallback as T;\r\n fail(`failed to read ${file}: ${(error as Error).message}`);\r\n }\r\n}\r\n\r\nexport function writeJson(file: string, value: unknown): void {\r\n mkdirSync(path.dirname(file), { recursive: true });\r\n writeFileSync(file, `${JSON.stringify(value, null, 2)}\\n`);\r\n}\r\n\r\nexport function safeSlug(value: string | undefined): string {\r\n return (\r\n String(value || \"\")\r\n .toLowerCase()\r\n .replace(/[^a-z0-9._-]+/g, \"-\")\r\n .replace(/^-+|-+$/g, \"\") || \"worker\"\r\n );\r\n}\r\n\r\nexport function timestampSlug(name: string): string {\r\n return safeSlug(`${new Date().toISOString().replace(/[-:]/g, \"\").replace(/\\..+/, \"Z\")}-${name}`);\r\n}\r\n\r\nexport function splitCsv(value: string | undefined): string[] {\r\n return value ? String(value).split(\",\").map((item) => item.trim()).filter(Boolean) : [];\r\n}\r\n\r\nexport function trimTrailingSlash(url: string): string {\r\n return String(url).replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport function oneLine(value: string): string {\r\n return String(value || \"\")\r\n .replace(/\\s+/g, \" \")\r\n .trim();\r\n}\r\n\r\nexport function fileSize(file: string): number {\r\n try {\r\n return statSync(file).size;\r\n } catch {\r\n return 0;\r\n }\r\n}\r\n\r\nexport function fileMtime(file: string): string | null {\r\n try {\r\n return statSync(file).mtime.toISOString();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport function tailFile(file: string, lines: number): string {\r\n if (!existsSync(file)) return \"\";\r\n const data = readFileSync(file, \"utf8\");\r\n return data.split(\"\\n\").slice(-lines).join(\"\\n\");\r\n}\r\n\r\nexport function readMaybeFile(file: string | undefined): string {\r\n return file ? readFileSync(path.resolve(file), \"utf8\") : \"\";\r\n}\r\n\r\nexport function listRunIds(runsDir: string): string[] {\r\n if (!existsSync(runsDir)) return [];\r\n return readdirSync(runsDir, { withFileTypes: true })\r\n .filter((entry) => entry.isDirectory())\r\n .map((entry) => entry.name);\r\n}\r\n\r\nexport function sleepMs(ms: number): void {\r\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\r\n}\r\n\r\n/** Non-blocking sleep for async loops (daemon backoff, interruptible shutdown). */\r\nexport function sleepMsAsync(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\nexport function isPidAlive(pid: number | undefined): boolean {\r\n if (!pid) return false;\r\n try {\r\n process.kill(pid, 0);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport function killWorkerProcess(pid: number, signal: NodeJS.Signals): void {\r\n try {\r\n process.kill(-pid, signal);\r\n } catch {\r\n process.kill(pid, signal);\r\n }\r\n}\r\n\r\nexport function latestIso(values: Array<string | null | undefined>): string | null {\r\n let best: string | null = null;\r\n let bestMs = -Infinity;\r\n for (const value of values) {\r\n if (!value) continue;\r\n const ms = Date.parse(value);\r\n if (Number.isFinite(ms) && ms > bestMs) {\r\n bestMs = ms;\r\n best = value;\r\n }\r\n }\r\n return best;\r\n}\r\n\r\nexport function secsAgo(ms: number): number {\r\n return Math.max(0, Math.round((Date.now() - ms) / 1000));\r\n}\r\n", "/**\r\n * Worker spawn env scrub \u2014 harness workers must not inherit host deployment secrets.\r\n */\r\n\r\n/** Exact env keys that must never reach a worker child process. */\r\nexport const FORBIDDEN_WORKER_ENV_KEYS = [\r\n \"ANTHROPIC_API_KEY\",\r\n \"ANALYST_API_KEY\",\r\n \"RECRUITER_API_KEY\",\r\n \"AUTH_SECRET\",\r\n \"NEXTAUTH_SECRET\",\r\n \"DATABASE_URL\",\r\n \"PRODUCTION_DATABASE_URL\",\r\n \"KYNVER_PRODUCTION_DATABASE_URL\",\r\n \"REDIS_URL\",\r\n \"GOOGLE_CLIENT_SECRET\",\r\n \"GITHUB_CLIENT_SECRET\",\r\n \"KYNVER_API_KEY\",\r\n \"KYNVER_SERVICE_SECRET\",\r\n \"KYNVER_RUNTIME_SECRET\",\r\n \"KYNVER_CRON_SECRET\",\r\n \"OPENCLAW_CRON_SECRET\",\r\n \"QSTASH_TOKEN\",\r\n \"QSTASH_CURRENT_SIGNING_KEY\",\r\n \"QSTASH_NEXT_SIGNING_KEY\",\r\n \"TOOL_SECRETS_KEK\",\r\n \"TOOL_EXECUTOR_DISPATCH_SECRET\",\r\n \"CLOUDFLARE_API_TOKEN\",\r\n \"STRIPE_SECRET_KEY\",\r\n \"STRIPE_WEBHOOK_SECRET\",\r\n \"STRIPE_IDENTITY_WEBHOOK_SECRET\",\r\n \"VOYAGE_API_KEY\",\r\n \"PERPLEXITY_API_KEY\",\r\n \"FRED_API_KEY\",\r\n \"FMP_API_KEY\",\r\n \"CURSOR_API_KEY\",\r\n] as const;\r\n\r\nconst FORBIDDEN_KEY_SET = new Set<string>(FORBIDDEN_WORKER_ENV_KEYS);\r\n\r\n/** Keys matching these suffixes are stripped (case-sensitive). */\r\nconst FORBIDDEN_SUFFIXES = [\"_SECRET\", \"_API_KEY\"] as const;\r\n\r\nexport function isForbiddenWorkerEnvKey(key: string): boolean {\r\n if (FORBIDDEN_KEY_SET.has(key)) return true;\r\n return FORBIDDEN_SUFFIXES.some((suffix) => key.endsWith(suffix));\r\n}\r\n\r\nexport function listForbiddenWorkerEnvKeys(env: NodeJS.ProcessEnv): string[] {\r\n return Object.keys(env).filter(isForbiddenWorkerEnvKey).sort();\r\n}\r\n\r\nexport function scrubWorkerEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\r\n const next = { ...env };\r\n for (const key of Object.keys(next)) {\r\n if (isForbiddenWorkerEnvKey(key)) delete next[key];\r\n }\r\n return next;\r\n}\r\n\r\nexport interface WorkerEnvAudit {\r\n forbiddenPresent: string[];\r\n safe: boolean;\r\n}\r\n\r\nexport function auditWorkerEnv(env: NodeJS.ProcessEnv): WorkerEnvAudit {\r\n const forbiddenPresent = listForbiddenWorkerEnvKeys(env);\r\n return { forbiddenPresent, safe: forbiddenPresent.length === 0 };\r\n}\r\n\r\n/** @deprecated Use {@link scrubWorkerEnv} \u2014 kept for existing imports from git.ts */\r\nexport function scrubClaudeEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\r\n return scrubWorkerEnv(env);\r\n}\r\n", "import { homedir } from \"node:os\";\r\nimport path from \"node:path\";\r\n\r\nexport function expandHomePath(value: string): string {\r\n if (value === \"~\") return homedir();\r\n if (value.startsWith(\"~/\") || value.startsWith(\"~\\\\\")) {\r\n return path.join(homedir(), value.slice(2));\r\n }\r\n return value;\r\n}\r\n\r\nexport function resolveUserPath(value: string): string {\r\n return path.resolve(expandHomePath(value));\r\n}\r\n\r\nexport function redactHomePath(value: string): string {\r\n const expanded = expandHomePath(value);\r\n const resolved = path.resolve(expanded);\r\n const home = path.resolve(homedir());\r\n\r\n if (resolved === home) return \"~\";\r\n if (resolved.startsWith(`${home}${path.sep}`)) {\r\n return `~/${path.relative(home, resolved).split(path.sep).join(\"/\")}`;\r\n }\r\n\r\n const posix = resolved.replace(/\\\\/g, \"/\");\r\n const redacted = posix\r\n .replace(/^\\/home\\/[^/]+(?=\\/|$)/, \"~\")\r\n .replace(/^\\/Users\\/[^/]+(?=\\/|$)/, \"~\")\r\n // Windows resolves Unix-style `/home/...` paths to `C:\\home\\...`.\r\n .replace(/^[A-Za-z]:\\/home\\/[^/]+(?=\\/|$)/i, \"~\")\r\n .replace(/^[A-Za-z]:\\/Users\\/[^/]+(?=\\/|$)/i, \"~\");\r\n return redacted;\r\n}\r\n\r\n/** User-facing path strings (doctor JSON, setup output). */\r\nexport function displayUserPath(value: string): string {\r\n return redactHomePath(value);\r\n}\r\n", "import { existsSync, readFileSync } from \"node:fs\";\r\nimport { dirname, join } from \"node:path\";\r\nimport { fileURLToPath } from \"node:url\";\r\n\r\nfunction resolvePackageRoot(moduleUrl: string): string {\r\n let dir = dirname(fileURLToPath(moduleUrl));\r\n for (let depth = 0; depth < 6; depth += 1) {\r\n if (existsSync(join(dir, \"package.json\"))) return dir;\r\n const parent = dirname(dir);\r\n if (parent === dir) break;\r\n dir = parent;\r\n }\r\n throw new Error(`package.json not found above ${dirname(fileURLToPath(moduleUrl))}`);\r\n}\r\n\r\nexport function readOwnPackageVersion(moduleUrl: string = import.meta.url): string {\r\n const pkgPath = join(resolvePackageRoot(moduleUrl), \"package.json\");\r\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { version?: string };\r\n if (typeof pkg.version !== \"string\" || !pkg.version.trim()) {\r\n throw new Error(`Missing package.json version at ${pkgPath}`);\r\n }\r\n return pkg.version;\r\n}\r\n\r\nexport const PACKAGE_VERSION = readOwnPackageVersion();\r\n\r\nexport function wantsCliVersion(argv: string[]): boolean {\r\n return argv.some((arg) => arg === \"--version\" || arg === \"-v\");\r\n}\r\n\r\nexport function printCliVersionAndExit(version: string, binName?: string): never {\r\n console.log(binName ? `${binName} ${version}` : version);\r\n process.exit(0);\r\n}\r\n\r\nexport function handleCliVersionFlag(\r\n argv: string[],\r\n moduleUrl: string = import.meta.url,\r\n binName?: string,\r\n): boolean {\r\n if (!wantsCliVersion(argv)) return false;\r\n printCliVersionAndExit(readOwnPackageVersion(moduleUrl), binName);\r\n return true;\r\n}\r\n", "import { collectInstalledPackageVersions } from \"./installed-package-versions.js\";\r\nimport {\r\n assertMemoryCostPackageVersionGuard,\r\n evaluateMemoryCostPackageVersionGuard,\r\n probeRepoPackageVersions,\r\n type MemoryCostManagedPackageName,\r\n type MemoryCostPackageGuardResult,\r\n} from \"./memory-cost-package-version-guard.js\";\r\nimport { PACKAGE_VERSION } from \"./package-version.js\";\r\n\r\nfunction installedVersionMap(\r\n observed: Awaited<ReturnType<typeof collectInstalledPackageVersions>>,\r\n): Partial<Record<MemoryCostManagedPackageName, { version: string; source: \"installed\"; path: string }>> {\r\n const out: Partial<\r\n Record<MemoryCostManagedPackageName, { version: string; source: \"installed\"; path: string }>\r\n > = {};\r\n for (const [packageName, row] of Object.entries(observed)) {\r\n if (!row?.version) continue;\r\n out[packageName as MemoryCostManagedPackageName] = {\r\n version: row.version,\r\n source: \"installed\",\r\n path: row.path,\r\n };\r\n }\r\n return out;\r\n}\r\n\r\nexport async function buildMemoryCostPackageGuardInput(input: {\r\n cwd?: string;\r\n repoRoot?: string;\r\n selfPackageName?: MemoryCostManagedPackageName;\r\n selfVersion?: string;\r\n} = {}): Promise<Parameters<typeof evaluateMemoryCostPackageVersionGuard>[0]> {\r\n const [installed, repo] = await Promise.all([\r\n collectInstalledPackageVersions(),\r\n Promise.resolve(probeRepoPackageVersions({ cwd: input.cwd, repoRoot: input.repoRoot })),\r\n ]);\r\n\r\n const self: Partial<Record<MemoryCostManagedPackageName, { version: string; source: \"self\" }>> = {};\r\n const runtimeSelfVersion =\r\n input.selfPackageName === \"@kynver-app/runtime\" && input.selfVersion\r\n ? input.selfVersion\r\n : PACKAGE_VERSION;\r\n self[\"@kynver-app/runtime\"] = { version: runtimeSelfVersion, source: \"self\" };\r\n if (\r\n input.selfPackageName &&\r\n input.selfVersion &&\r\n input.selfPackageName !== \"@kynver-app/runtime\"\r\n ) {\r\n self[input.selfPackageName] = { version: input.selfVersion, source: \"self\" };\r\n }\r\n\r\n return {\r\n installed: installedVersionMap(installed),\r\n repo,\r\n self,\r\n };\r\n}\r\n\r\nexport async function evaluateMemoryCostPackageGuardAtStartup(\r\n input: Parameters<typeof buildMemoryCostPackageGuardInput>[0] = {},\r\n): Promise<MemoryCostPackageGuardResult> {\r\n const guardInput = await buildMemoryCostPackageGuardInput(input);\r\n return evaluateMemoryCostPackageVersionGuard(guardInput);\r\n}\r\n\r\nexport async function enforceMemoryCostPackageGuardAtStartup(\r\n input: Parameters<typeof buildMemoryCostPackageGuardInput>[0] = {},\r\n): Promise<MemoryCostPackageGuardResult> {\r\n const guardInput = await buildMemoryCostPackageGuardInput(input);\r\n return assertMemoryCostPackageVersionGuard(guardInput);\r\n}\r\n\r\nexport function shouldEnforceMemoryCostPackageGuardCli(scope?: string, action?: string): boolean {\r\n if (!scope) return false;\r\n if (scope === \"daemon\") return true;\r\n // `start` is the consumer wrapper that ends in the daemon \u2014 same guard.\r\n if (scope === \"start\") return true;\r\n if (scope === \"worker\") return true;\r\n if (scope === \"monitor\") return true;\r\n if (scope === \"run\" && (action === \"dispatch\" || action === \"sweep\" || action === \"reconcile\" || action === \"unblock\")) {\r\n return true;\r\n }\r\n if (scope === \"cron\" && action === \"tick\") return true;\r\n return false;\r\n}\r\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["homedir", "path", "existsSync", "readFileSync", "path", "homedir", "path", "path", "homedir", "readFileSync", "path", "existsSync", "ok", "summary", "homedir", "path", "existsSync", "readFileSync", "fileURLToPath"]
|
|
7
7
|
}
|