Actually vendor harness

This commit is contained in:
2026-09-11 13:41:22 -04:00
parent 1acd371668
commit 04e013b090
52 changed files with 8550 additions and 1 deletions
+57
View File
@@ -0,0 +1,57 @@
/**
* Session todo list: merge-by-id, grok-shaped statuses. No Bare imports.
*/
const STATUSES = ['pending', 'in_progress', 'completed', 'cancelled'];
function normalizeStatus(s) {
const v = String(s || 'pending')
.toLowerCase()
.replace(/[\s-]+/g, '_');
if (v === 'done' || v === 'complete') return 'completed';
if (v === 'progress' || v === 'doing' || v === 'inprogress') return 'in_progress';
if (v === 'cancel' || v === 'canceled') return 'cancelled';
if (STATUSES.indexOf(v) >= 0) return v;
return 'pending';
}
function normalizeItem(t, i) {
t = t || {};
return {
id: String(t.id || 'todo_' + (i + 1)),
content: String(t.content || t.text || t.title || ''),
status: normalizeStatus(t.status),
};
}
function merge(existing, incoming, mode) {
const next = Array.isArray(incoming) ? incoming.map(normalizeItem) : [];
if (mode === 'replace' || !existing || !existing.length) return next;
const byId = new Map();
for (const t of existing) {
const n = normalizeItem(t, 0);
byId.set(n.id, n);
}
for (const t of next) {
const prev = byId.get(t.id) || {};
const merged = Object.assign({}, prev, t);
if (!t.content && prev.content) merged.content = prev.content;
byId.set(t.id, merged);
}
return Array.from(byId.values());
}
function hasOpen(list) {
return (list || []).some((t) => t.status === 'pending' || t.status === 'in_progress');
}
function formatBlock(list) {
const todos = list || [];
if (!todos.length) return '[todos]\n(none)';
return (
'[todos]\n' +
todos.map((t) => '- [' + t.status + '] ' + t.id + ': ' + t.content).join('\n')
);
}
module.exports = { STATUSES, normalizeStatus, normalizeItem, merge, hasOpen, formatBlock };