symbiot 0.41.6 → 0.41.7
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.
- package/core.mjs +38 -1
- package/package.json +1 -1
package/core.mjs
CHANGED
|
@@ -41,12 +41,49 @@ function saveTasks(t) { try { mkdirSync(CONFIG_DIR, { recursive: true }); writeF
|
|
|
41
41
|
// with a clause more on the end. An extension only counts when the shorter one
|
|
42
42
|
// is a whole sentence (8+ words), so "Fix the bug" never swallows "Fix the bug
|
|
43
43
|
// in the login form".
|
|
44
|
+
// Or nearly the same (nearTask): an agent that suggests a task again rewords
|
|
45
|
+
// it, and TASKS.md listed both.
|
|
44
46
|
const taskWords = (s) => String(s || "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
45
47
|
function sameTask(a, b) {
|
|
46
48
|
const x = taskWords(a), y = taskWords(b); if (!x || !y) return false;
|
|
47
49
|
if (x === y) return true;
|
|
48
50
|
const [s, l] = x.length < y.length ? [x, y] : [y, x];
|
|
49
|
-
return s.split(" ").length >= 8 && l.startsWith(s + " ");
|
|
51
|
+
return (s.split(" ").length >= 8 && l.startsWith(s + " ")) || nearTask(a, b);
|
|
52
|
+
}
|
|
53
|
+
// Nearly the same task, two ways:
|
|
54
|
+
// - nearly all the same words in the same order, 12+ words each ("…nothing
|
|
55
|
+
// recorded since 2026-08-03" and "…since 2026-08-04")
|
|
56
|
+
// - the same first sentence of 5+ words, with only what follows it different:
|
|
57
|
+
// "Set `WA_WABA_ID` in `.env`. It's needed to list templates" / "…to create Flows"
|
|
58
|
+
// Never when each names something the other doesn't: "Watch Gmail…" and
|
|
59
|
+
// "Watch WhatsApp…" are two tasks, however alike the rest. A name is a word
|
|
60
|
+
// with a capital that doesn't just start a sentence (Gmail, WhatsApp, WA).
|
|
61
|
+
const NEAR = 0.85, NEAR_WORDS = 12, LEAD_WORDS = 5;
|
|
62
|
+
function wordsOf(s) {
|
|
63
|
+
s = String(s || "");
|
|
64
|
+
return [...s.matchAll(/[\p{L}\p{N}]+/gu)].map((m) => {
|
|
65
|
+
const w = m[0], before = s.slice(0, m.index);
|
|
66
|
+
const starts = !before.trim() || /[.!?]["'`)\]]*\s*$/.test(before);
|
|
67
|
+
return { w: w.toLowerCase(), name: w.length > 1 && /\p{Lu}/u.test(w) && (!starts || /\p{Lu}/u.test(w.slice(1))) };
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// The first sentence's words, when more follows it ("" when it's all one sentence).
|
|
71
|
+
function leadOf(s) { const m = String(s || "").match(/^(.*?[.!?])["'`)\]]*\s+\S/s); return m ? taskWords(m[1]) : ""; }
|
|
72
|
+
function nearTask(a, b) {
|
|
73
|
+
const x = wordsOf(a), y = wordsOf(b), m = x.length, n = y.length; if (!m || !n) return false;
|
|
74
|
+
const lead = leadOf(a), sameLead = !!lead && lead === leadOf(b) && lead.split(" ").length >= LEAD_WORDS;
|
|
75
|
+
if (!sameLead && (Math.min(m, n) < NEAR_WORDS || Math.min(m, n) / Math.max(m, n) < NEAR)) return false;
|
|
76
|
+
// the longest run of words both have in order, and the words left over on each side
|
|
77
|
+
const L = Array.from({ length: m + 1 }, () => new Uint16Array(n + 1));
|
|
78
|
+
for (let i = m - 1; i >= 0; i--) for (let j = n - 1; j >= 0; j--) L[i][j] = x[i].w === y[j].w ? L[i + 1][j + 1] + 1 : Math.max(L[i + 1][j], L[i][j + 1]);
|
|
79
|
+
if (!sameLead && (2 * L[0][0]) / (m + n) < NEAR) return false;
|
|
80
|
+
let i = 0, j = 0, nx = false, ny = false;
|
|
81
|
+
while (i < m && j < n) {
|
|
82
|
+
if (x[i].w === y[j].w) { i++; j++; } else if (L[i + 1][j] >= L[i][j + 1]) { if (x[i++].name) nx = true; } else if (y[j++].name) ny = true;
|
|
83
|
+
}
|
|
84
|
+
for (; i < m; i++) if (x[i].name) nx = true;
|
|
85
|
+
for (; j < n; j++) if (y[j].name) ny = true;
|
|
86
|
+
return !(nx && ny);
|
|
50
87
|
}
|
|
51
88
|
// One of each: near-duplicates collapse into the wording that says the most.
|
|
52
89
|
function uniqueTasks(texts) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "symbiot",
|
|
3
|
-
"version": "0.41.
|
|
3
|
+
"version": "0.41.7",
|
|
4
4
|
"description": "Your week, written from your real work. Reads your local git and writes it up with the AI of your choice — Claude, OpenAI, Gemini, or a local model.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|