UNPKG

zephyr-agent

Version:
294 lines (293 loc) • 12.5 kB
"use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.d = (exports1, getters, values)=>{ var define = (defs, kind)=>{ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { enumerable: true, [kind]: defs[key] }); }; define(getters, "get"); define(values, "value"); }; })(); (()=>{ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); })(); (()=>{ __webpack_require__.r = (exports1)=>{ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { value: 'Module' }); Object.defineProperty(exports1, '__esModule', { value: true }); }; })(); var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { committedRanges: ()=>committedRanges, readGitAiWorkingAttribution: ()=>readGitAiWorkingAttribution, unknownOrigin: ()=>unknownOrigin, workingRanges: ()=>workingRanges }); const external_node_child_process_namespaceObject = require("node:child_process"); const external_node_crypto_namespaceObject = require("node:crypto"); const external_node_fs_namespaceObject = require("node:fs"); const external_node_path_namespaceObject = require("node:path"); const unknownOrigin = { kind: 'unknown', evidence: 'none' }; const hash = (text)=>(0, external_node_crypto_namespaceObject.createHash)('sha256').update(text).digest('hex'); function readGitAiWorkingAttribution(gitDir, commit) { const entries = new Map(); const authors = new Map(); const directory = (0, external_node_path_namespaceObject.join)(gitDir, 'ai', 'working_logs', commit || 'empty'); const filename = (0, external_node_path_namespaceObject.join)(directory, 'checkpoints.jsonl'); try { const initialPath = (0, external_node_path_namespaceObject.join)(directory, 'INITIAL'); if ((0, external_node_fs_namespaceObject.existsSync)(initialPath)) { if ((0, external_node_fs_namespaceObject.statSync)(initialPath).size > 20971520) return { entries, authors }; const initial = JSON.parse((0, external_node_fs_namespaceObject.readFileSync)(initialPath, 'utf8')); for (const [file, ranges] of Object.entries(initial.files ?? {}))if (initial.file_blobs?.[file]) entries.set(file, { file, blob_sha: initial.file_blobs[file], line_attributions: ranges }); for (const [id, human] of Object.entries(initial.humans ?? {}))authors.set(id, { kind: 'human', human: human.author, evidence: 'git-ai-checkpoint' }); for (const [id, prompt] of Object.entries(initial.prompts ?? {})){ const value = prompt; if (value.agent_id) authors.set(id, { kind: 'ai', human: value.human_author, tool: value.agent_id.tool, model: value.agent_id.model, session: value.agent_id.id, evidence: 'git-ai-checkpoint' }); } for (const entry of entries.values())for (const range of entry.line_attributions ?? []){ const session = initial.sessions?.[range.author_id.split('::')[0]]; if (session?.agent_id) authors.set(range.author_id, { kind: 'ai', human: session.human_author, tool: session.agent_id.tool, model: session.agent_id.model, session: session.agent_id.id, evidence: 'git-ai-checkpoint' }); } } if ((0, external_node_fs_namespaceObject.existsSync)(filename) && (0, external_node_fs_namespaceObject.statSync)(filename).size > 20971520) throw new Error('Checkpoint log too large'); for (const line of ((0, external_node_fs_namespaceObject.existsSync)(filename) ? (0, external_node_fs_namespaceObject.readFileSync)(filename, 'utf8') : '').split('\n').filter(Boolean)){ const checkpoint = JSON.parse(line); if ('checkpoint/1.0.0' !== checkpoint.api_version || !checkpoint.git_ai_version?.startsWith('1.7.') || !Array.isArray(checkpoint.entries)) throw new Error('Unsupported checkpoint schema'); if (('AiAgent' === checkpoint.kind || 'AiTab' === checkpoint.kind) && checkpoint.agent_id) { const agent = checkpoint.agent_id; const session = `s_${hash(`${agent.tool}:${agent.id}`).slice(0, 14)}`; let nativeSession = agent.id; let toolCall = checkpoint.agent_metadata?.tool_use_id; if ('grok' === agent.tool) try { const invocation = JSON.parse(agent.id); if (Array.isArray(invocation) && 3 === invocation.length && invocation.every((part)=>'string' == typeof part)) { nativeSession = invocation[0]; toolCall = invocation[2]; } } catch {} const origin = { kind: 'ai', human: checkpoint.author, tool: agent.tool, model: agent.model, session: nativeSession, toolCall, evidence: 'git-ai-checkpoint' }; const trace = checkpoint.trace_id; for (const entry of checkpoint.entries)for (const range of entry.line_attributions ?? [])if (range.author_id === session || trace && range.author_id === `${session}::${trace}`) authors.set(range.author_id, origin); } else if ('KnownHuman' === checkpoint.kind) authors.set(`h_${hash(checkpoint.author).slice(0, 14)}`, { kind: 'human', human: checkpoint.author, evidence: 'git-ai-checkpoint' }); for (const entry of checkpoint.entries)entries.set(entry.file, entry); } } catch { entries.clear(); authors.clear(); } return { entries, authors }; } function workingRanges(entry, contentHash, authors) { if (!entry || entry.blob_sha !== contentHash) return; return (entry.line_attributions ?? []).map((range)=>({ start: range.start_line, end: range.end_line, origin: authors.get(range.author_id) ?? unknownOrigin })).filter((range)=>Number.isSafeInteger(range.start) && range.start > 0 && Number.isSafeInteger(range.end) && range.end >= range.start); } function committedRanges(root, binary, file, commit) { let ranges = []; try { const blame = JSON.parse((0, external_node_child_process_namespaceObject.execFileSync)(binary, [ 'blame', '--json', commit, '--', file ], { cwd: root, encoding: 'utf8', timeout: 5000, maxBuffer: 4194304, stdio: [ 'ignore', 'pipe', 'ignore' ] })); ranges = Object.entries(blame.lines ?? {}).map(([key, id])=>{ const [start, end = start] = key.split('-').map(Number); const prompt = blame.prompts?.[String(id)]; const agent = prompt?.agent_id; return { start, end, origin: agent ? { kind: 'ai', human: prompt.human_author, tool: agent.tool, model: agent.model, session: agent.id, evidence: 'git-ai-blame' } : unknownOrigin }; }).filter(({ start, end })=>Number.isSafeInteger(start) && start > 0 && Number.isSafeInteger(end) && end >= start); } catch {} return [ ...ranges, ...committedHumanRanges(root, file, commit).filter((human)=>!ranges.some((range)=>range.start <= human.start && range.end >= human.start)) ]; } function committedHumanRanges(root, file, commit) { const notes = new Map(); const run = (args)=>(0, external_node_child_process_namespaceObject.execFileSync)('git', args, { cwd: root, encoding: 'utf8', timeout: 5000, maxBuffer: 4194304, stdio: [ 'ignore', 'pipe', 'ignore' ] }); function note(sha) { if (notes.has(sha)) return notes.get(sha); try { const text = run([ 'notes', '--ref=ai', 'show', sha ]); const divider = text.indexOf('\n---\n'); if (divider < 0) throw new Error('Unsupported authorship note'); const metadata = JSON.parse(text.slice(divider + 5)); if ('authorship/3.0.0' !== metadata.schema_version || !metadata.git_ai_version?.startsWith('1.7.')) throw new Error('Unsupported authorship note'); const files = new Map(); let current = ''; for (const line of text.slice(0, divider).split('\n'))if (line.startsWith(' ')) { const match = /^ (h_[a-f0-9]{14}) ([\d,-]+)$/.exec(line); if (!match) continue; for (const token of match[2].split(',')){ const [start, end = start] = token.split('-').map(Number); if (Number.isSafeInteger(start) && start > 0 && Number.isSafeInteger(end) && end >= start) files.get(current)?.push({ id: match[1], start, end }); } } else { current = line.startsWith('"') ? JSON.parse(line) : line; files.set(current, []); } const parsed = { metadata, files }; notes.set(sha, parsed); return parsed; } catch { notes.set(sha, void 0); return; } } const ranges = []; try { let sha = ''; let original = 0; let current = 0; let originalFile = file; for (const line of run([ 'blame', '--line-porcelain', commit, '--', file ]).split('\n')){ const header = /^([a-f0-9]{40,64}) (\d+) (\d+)(?: \d+)?$/.exec(line); if (header) { sha = header[1]; original = Number(header[2]); current = Number(header[3]); } else if (line.startsWith('filename ')) { const value = line.slice(9); originalFile = value.startsWith('"') ? JSON.parse(value) : value; } else if (line.startsWith('\t')) { const record = note(sha); const human = record?.files.get(originalFile)?.find((range)=>range.start <= original && range.end >= original); const author = human && record?.metadata.humans?.[human.id]?.author; if ('string' == typeof author) ranges.push({ start: current, end: current, origin: { kind: 'human', human: author, evidence: 'git-ai-blame' } }); } } } catch { return []; } return ranges; } exports.committedRanges = __webpack_exports__.committedRanges; exports.readGitAiWorkingAttribution = __webpack_exports__.readGitAiWorkingAttribution; exports.unknownOrigin = __webpack_exports__.unknownOrigin; exports.workingRanges = __webpack_exports__.workingRanges; for(var __rspack_i in __webpack_exports__)if (-1 === [ "committedRanges", "readGitAiWorkingAttribution", "unknownOrigin", "workingRanges" ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i]; Object.defineProperty(exports, '__esModule', { value: true }); //# sourceMappingURL=git-ai.js.map