@@ -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 };
|
||||
Reference in New Issue
Block a user