@usepipr/runtime 0.3.8 → 0.4.1

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.
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime-tools-core-CW1xenzy.mjs","names":[],"sources":["../src/diff/ranges.ts","../src/pi/runtime-tools-core.ts"],"sourcesContent":["import type { CommentableRange, DiffHunk, DiffManifest, DiffManifestFile } from \"../types.js\";\n\nexport type DiffRangeMatch = {\n file: DiffManifestFile;\n range: CommentableRange;\n};\n\nexport type DiffRangeIndex = {\n fileByPath(filePath: string): DiffManifestFile | undefined;\n excludedReason(filePath: string): string | undefined;\n findRange(rangeId: string): DiffRangeMatch | undefined;\n rangeById(rangeId: string): CommentableRange | undefined;\n requireFile(filePath: string): DiffManifestFile;\n requireRangeInFile(file: DiffManifestFile, rangeId: string): CommentableRange;\n requireHunk(file: DiffManifestFile, range: CommentableRange): DiffHunk;\n};\n\nexport function createDiffRangeIndex(manifest: DiffManifest): DiffRangeIndex {\n const filesByPath = new Map(manifest.files.map((file) => [file.path, file]));\n const rangesById = new Map<string, DiffRangeMatch>();\n for (const file of manifest.files) {\n for (const range of file.commentableRanges) {\n rangesById.set(range.id, { file, range });\n }\n }\n\n return {\n fileByPath(filePath) {\n return filesByPath.get(filePath);\n },\n excludedReason(filePath) {\n return filesByPath.get(filePath)?.excludedReason;\n },\n findRange(rangeId) {\n return rangesById.get(rangeId);\n },\n rangeById(rangeId) {\n return rangesById.get(rangeId)?.range;\n },\n requireFile(filePath) {\n const file = filesByPath.get(filePath);\n if (!file) {\n throw new Error(`Path '${filePath}' is not in the Diff Manifest`);\n }\n return file;\n },\n requireRangeInFile(file, rangeId) {\n const range = file.commentableRanges.find((item) => item.id === rangeId);\n if (range) {\n return range;\n }\n if (rangesById.has(rangeId)) {\n throw new Error(`Diff Manifest range '${rangeId}' is not in path '${file.path}'`);\n }\n throw new Error(`Unknown Diff Manifest range '${rangeId}'`);\n },\n requireHunk(file, range) {\n const hunk = file.hunks.find(\n (item) => item.hunkIndex === range.hunkIndex && item.contentHash === range.hunkContentHash,\n );\n if (!hunk) {\n throw new Error(`Diff Manifest range '${range.id}' has no matching hunk`);\n }\n return hunk;\n },\n };\n}\n","import { lstat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { z } from \"zod\";\nimport { createDiffRangeIndex } from \"../diff/ranges.js\";\nimport type { CommentableRange, DiffHunk, DiffManifest, DiffManifestFile } from \"../types.js\";\n\nconst readAtRefContextLines = 3;\n\nexport type ReadDiffParams = {\n path?: string;\n rangeId?: string;\n};\n\nexport type ReadAtRefParams = {\n path: string;\n ref: \"base\" | \"head\";\n rangeId: string;\n};\n\nexport type RuntimeToolData = {\n manifest: DiffManifest;\n toolResponseMaxBytes: number;\n baseRanges: Record<string, BaseRangeSnapshot>;\n};\n\nexport type BaseRangeSnapshot = {\n path: string;\n ref: \"base\" | \"head\";\n sourcePath: string;\n rangeId: string;\n startLine: number;\n endLine: number;\n available: boolean;\n relativePath?: string;\n bytes?: number;\n truncated?: boolean;\n};\n\nexport type ReadAtRefRequest = {\n file: DiffManifestFile;\n range: CommentableRange;\n hunk: DiffHunk;\n ref: \"base\" | \"head\";\n sourcePath: string;\n window: LineWindow | undefined;\n};\n\nexport type LineWindow = {\n startLine: number;\n endLine: number;\n};\n\nexport type LineSliceResult = {\n available: true;\n content: string;\n bytes: number;\n truncated: boolean;\n};\n\nconst readDiffParamsSchema = z.preprocess(\n (params) => {\n const record =\n typeof params === \"object\" && params !== null && !Array.isArray(params)\n ? (params as Record<string, unknown>)\n : {};\n return {\n path: typeof record.path === \"string\" ? record.path : undefined,\n rangeId: typeof record.rangeId === \"string\" ? record.rangeId : undefined,\n };\n },\n z.object({\n path: z.string().optional(),\n rangeId: z.string().optional(),\n }),\n);\n\nconst readAtRefParamsSchema = z.preprocess(\n (params) =>\n typeof params === \"object\" && params !== null && !Array.isArray(params) ? params : {},\n z.object({\n path: z.unknown(),\n ref: z.enum([\"base\", \"head\"], {\n error: (issue) => `Unsupported ref '${String(issue.input)}'`,\n }),\n rangeId: z.string({ error: \"rangeId must be a string\" }),\n }),\n);\n\nexport function readDiffFromRuntimeData(data: RuntimeToolData, params: ReadDiffParams): unknown {\n const { rangeId } = params;\n const filePath = params.path === undefined ? undefined : parseManifestPath(params.path);\n const ranges = createDiffRangeIndex(data.manifest);\n if (filePath !== undefined) {\n ranges.requireFile(filePath);\n }\n if (rangeId !== undefined && !ranges.findRange(rangeId)) {\n throw new Error(`Unknown Diff Manifest range '${rangeId}'`);\n }\n const files = data.manifest.files\n .filter((file) => filePath === undefined || file.path === filePath)\n .map((file) => filterManifestFileRanges(file, rangeId))\n .filter((file) => rangeId === undefined || file.commentableRanges.length > 0);\n return boundedJson({ files }, data.toolResponseMaxBytes);\n}\n\nfunction boundedJson(value: unknown, maxBytes: number): unknown {\n const text = JSON.stringify(value, null, 2);\n const bytes = Buffer.byteLength(text, \"utf8\");\n if (bytes <= maxBytes) {\n return { truncated: false, bytes, value };\n }\n return {\n truncated: true,\n bytes,\n maxBytes,\n text: Buffer.from(text, \"utf8\").subarray(0, maxBytes).toString(\"utf8\"),\n };\n}\n\nexport function boundedLineSlice(\n content: string,\n window: LineWindow,\n maxBytes: number,\n): LineSliceResult {\n const lines = content.match(/[^\\n]*(?:\\n|$)/g) ?? [];\n if (lines.at(-1) === \"\") {\n lines.pop();\n }\n const slice = lines.slice(window.startLine - 1, window.endLine).join(\"\");\n const buffer = Buffer.from(slice, \"utf8\");\n return {\n available: true,\n content: buffer.subarray(0, maxBytes).toString(\"utf8\"),\n bytes: buffer.byteLength,\n truncated: buffer.byteLength > maxBytes,\n };\n}\n\nexport function resolveReadAtRefRequest(\n manifest: DiffManifest,\n params: ReadAtRefParams,\n): ReadAtRefRequest {\n const filePath = parseManifestPath(params.path);\n const ranges = createDiffRangeIndex(manifest);\n const file = ranges.requireFile(filePath);\n const range = ranges.requireRangeInFile(file, params.rangeId);\n const hunk = ranges.requireHunk(file, range);\n const sourcePath = parseManifestPath(\n params.ref === \"base\" ? (file.previousPath ?? file.path) : file.path,\n );\n return {\n file,\n range,\n hunk,\n ref: params.ref,\n sourcePath,\n window: lineWindowForRange(range, hunk, params.ref),\n };\n}\n\nexport function unavailableReadAtRefResult(request: ReadAtRefRequest): BaseRangeSnapshot {\n return {\n path: request.file.path,\n ref: request.ref,\n sourcePath: request.sourcePath,\n rangeId: request.range.id,\n startLine: 0,\n endLine: 0,\n available: false,\n };\n}\n\nexport function parseManifestPath(filePath: unknown): string {\n if (\n typeof filePath !== \"string\" ||\n filePath.length === 0 ||\n filePath.includes(\"\\0\") ||\n path.isAbsolute(filePath) ||\n filePath.split(/[\\\\/]/).some((part) => part === \"..\" || part === \".git\" || part === \"\")\n ) {\n throw new Error(`Unsafe manifest path '${String(filePath)}'`);\n }\n return filePath;\n}\n\nexport function resolveAllowedPath(root: string, filePath: string): string {\n const resolved = path.resolve(root, filePath);\n const relative = path.relative(root, resolved);\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(`Path '${filePath}' resolves outside the workspace`);\n }\n return resolved;\n}\n\nexport async function assertNoSymlinkPath(root: string, filePath: string): Promise<void> {\n const parts = filePath.split(/[\\\\/]/);\n let current = root;\n for (const part of parts) {\n current = path.join(current, part);\n const stats = await lstat(current);\n if (stats.isSymbolicLink()) {\n throw new Error(`Path '${filePath}' crosses a symlink`);\n }\n }\n}\n\nexport function readDiffParams(params: unknown): ReadDiffParams {\n return readDiffParamsSchema.parse(params);\n}\n\nexport function readAtRefParams(params: unknown): ReadAtRefParams {\n const parsed = readAtRefParamsSchema.parse(params);\n return { path: parseManifestPath(parsed.path), ref: parsed.ref, rangeId: parsed.rangeId };\n}\n\nfunction filterManifestFileRanges(\n file: DiffManifestFile,\n rangeId: string | undefined,\n): DiffManifestFile {\n if (rangeId === undefined) {\n return file;\n }\n return {\n ...file,\n commentableRanges: file.commentableRanges.filter((range) => range.id === rangeId),\n };\n}\n\nfunction lineWindowForRange(\n range: CommentableRange,\n hunk: DiffHunk,\n ref: \"base\" | \"head\",\n): LineWindow | undefined {\n const targetSide: CommentableRange[\"side\"] = ref === \"base\" ? \"LEFT\" : \"RIGHT\";\n if (range.side !== targetSide) {\n return undefined;\n }\n const hunkStart = ref === \"base\" ? hunk.oldStart : hunk.newStart;\n const hunkLines = ref === \"base\" ? hunk.oldLines : hunk.newLines;\n if (hunkLines === 0) {\n return undefined;\n }\n const hunkEnd = hunkStart + hunkLines - 1;\n return {\n startLine: Math.max(hunkStart, range.startLine - readAtRefContextLines),\n endLine: Math.min(hunkEnd, range.endLine + readAtRefContextLines),\n };\n}\n"],"mappings":"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"}