takomi 2.1.15 → 2.1.16
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.
|
@@ -404,6 +404,39 @@ async function findExistingTaskFile(paths: ReturnType<typeof getSessionPaths>, t
|
|
|
404
404
|
return undefined;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
function markdownPreservationScore(content: string): number {
|
|
408
|
+
const trimmed = content.trim();
|
|
409
|
+
if (!trimmed) return 0;
|
|
410
|
+
const lines = trimmed.split(/\r?\n/);
|
|
411
|
+
const headingCount = lines.filter((line) => /^#{1,6}\s+/.test(line)).length;
|
|
412
|
+
const checklistCount = lines.filter((line) => /^\s*- \[[ xX]\]/.test(line)).length;
|
|
413
|
+
const fencedBlockCount = lines.filter((line) => /^```/.test(line)).length;
|
|
414
|
+
return trimmed.length + headingCount * 500 + checklistCount * 120 + fencedBlockCount * 80 + Math.min(lines.length, 200) * 10;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
function shouldPreserveExistingTaskMarkdown(existing: string, incoming: string): boolean {
|
|
418
|
+
const existingTrimmed = existing.trim();
|
|
419
|
+
const incomingTrimmed = incoming.trim();
|
|
420
|
+
if (!existingTrimmed || !incomingTrimmed) return false;
|
|
421
|
+
if (existingTrimmed === incomingTrimmed) return true;
|
|
422
|
+
|
|
423
|
+
const existingScore = markdownPreservationScore(existingTrimmed);
|
|
424
|
+
const incomingScore = markdownPreservationScore(incomingTrimmed);
|
|
425
|
+
const incomingLooksLikeShortPrompt = incomingTrimmed.length < 500 && !/^#{1,6}\s+/m.test(incomingTrimmed);
|
|
426
|
+
|
|
427
|
+
return existingScore > incomingScore * 1.5 || incomingLooksLikeShortPrompt;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
async function writeTaskMarkdownSafely(filePath: string, incomingMarkdown: string): Promise<boolean> {
|
|
431
|
+
const incoming = repairTaskMarkdown(incomingMarkdown).trimEnd() + "\n";
|
|
432
|
+
const existing = await readFile(filePath, "utf8").catch(() => "");
|
|
433
|
+
if (existing && shouldPreserveExistingTaskMarkdown(existing, incoming)) {
|
|
434
|
+
return false;
|
|
435
|
+
}
|
|
436
|
+
await writeFile(filePath, incoming, "utf8");
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
|
|
407
440
|
async function writeTaskArtifact(paths: ReturnType<typeof getSessionPaths>, state: OrchestratorSessionState, task: OrchestratorTask) {
|
|
408
441
|
const targetPath = path.join(getTaskFolder(paths, task.status), getTaskFileName(task));
|
|
409
442
|
const existingPath = await findExistingTaskFile(paths, task);
|
|
@@ -945,7 +978,7 @@ ${stateJson}`
|
|
|
945
978
|
for (const task of nextState.tasks) {
|
|
946
979
|
const authored = (params.tasks as IncomingTask[] | undefined)?.find((input) => (input.id ?? task.id) === task.id)?.taskMarkdown;
|
|
947
980
|
if (authored?.trim()) {
|
|
948
|
-
await
|
|
981
|
+
await writeTaskMarkdownSafely(path.join(getTaskFolder(paths, task.status), getTaskFileName(task)), authored);
|
|
949
982
|
}
|
|
950
983
|
}
|
|
951
984
|
state.activeSessionId = nextState.sessionId;
|
|
@@ -983,7 +1016,7 @@ ${stateJson}`
|
|
|
983
1016
|
for (const task of nextState.tasks) {
|
|
984
1017
|
const authored = (params.tasks as IncomingTask[] | undefined)?.find((input) => (input.id ?? task.id) === task.id)?.taskMarkdown;
|
|
985
1018
|
if (authored?.trim()) {
|
|
986
|
-
await
|
|
1019
|
+
await writeTaskMarkdownSafely(path.join(getTaskFolder(paths, task.status), getTaskFileName(task)), authored);
|
|
987
1020
|
}
|
|
988
1021
|
}
|
|
989
1022
|
state.activeSessionId = nextState.sessionId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "takomi",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.16",
|
|
4
4
|
"description": "🎯 Stop wrestling with AI. Start building with purpose. The artisan's toolkit for agent workflows, Codex skills, and original Takomi capabilities like 21st.dev integration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|