zephyr-agent
Version:
Zephyr plugin agent
294 lines (293 loc) • 12.5 kB
JavaScript
;
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