@hasna/todos 0.11.94 → 0.11.95
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/dist/cli/cloud-router.d.ts +12 -1
- package/dist/cli/cloud-router.d.ts.map +1 -1
- package/dist/cli/commands/plan-template-commands.d.ts.map +1 -1
- package/dist/cli/index.js +696 -63
- package/dist/contracts.js +56 -50
- package/dist/db/storage-tombstones.d.ts +1 -1
- package/dist/db/storage-tombstones.d.ts.map +1 -1
- package/dist/db/templates.d.ts.map +1 -1
- package/dist/index.js +169 -55
- package/dist/lib/template-semantics.d.ts +8 -0
- package/dist/lib/template-semantics.d.ts.map +1 -0
- package/dist/mcp/index.js +461 -59
- package/dist/mcp.js +1 -1
- package/dist/registry.js +56 -50
- package/dist/release-provenance.json +5 -5
- package/dist/sdk/index.js +35 -0
- package/dist/sdk/v1.generated.d.ts +103 -1
- package/dist/sdk/v1.generated.d.ts.map +1 -1
- package/dist/server/index.js +467 -65
- package/dist/server/openapi.d.ts +488 -0
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage/interfaces.d.ts +3 -2
- package/dist/storage/interfaces.d.ts.map +1 -1
- package/dist/storage/postgres-adapter.d.ts.map +1 -1
- package/dist/storage/postgres-sync.d.ts +1 -1
- package/dist/storage/postgres-sync.d.ts.map +1 -1
- package/dist/storage/shadow-outbox.d.ts.map +1 -1
- package/dist/storage/shadow.d.ts +1 -1
- package/dist/storage/shadow.d.ts.map +1 -1
- package/dist/storage/sqlite-snapshot.d.ts.map +1 -1
- package/dist/storage.js +168 -54
- package/package.json +1 -1
package/dist/contracts.js
CHANGED
|
@@ -6483,6 +6483,50 @@ var init_recurrence = __esm(() => {
|
|
|
6483
6483
|
};
|
|
6484
6484
|
});
|
|
6485
6485
|
|
|
6486
|
+
// src/lib/template-semantics.ts
|
|
6487
|
+
function resolveTemplateVariables(templateVars, provided) {
|
|
6488
|
+
const merged = { ...provided };
|
|
6489
|
+
for (const variable of templateVars) {
|
|
6490
|
+
if (merged[variable.name] === undefined && variable.default !== undefined) {
|
|
6491
|
+
merged[variable.name] = variable.default;
|
|
6492
|
+
}
|
|
6493
|
+
}
|
|
6494
|
+
const missing = templateVars.filter((variable) => variable.required && merged[variable.name] === undefined).map((variable) => variable.name);
|
|
6495
|
+
if (missing.length > 0) {
|
|
6496
|
+
throw new Error(`Missing required template variable(s): ${missing.join(", ")}`);
|
|
6497
|
+
}
|
|
6498
|
+
return merged;
|
|
6499
|
+
}
|
|
6500
|
+
function substituteTemplateVariables(text, variables) {
|
|
6501
|
+
let result = text;
|
|
6502
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
6503
|
+
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), value);
|
|
6504
|
+
}
|
|
6505
|
+
return result;
|
|
6506
|
+
}
|
|
6507
|
+
function evaluateTemplateCondition(condition, variables) {
|
|
6508
|
+
if (!condition || condition.trim() === "")
|
|
6509
|
+
return true;
|
|
6510
|
+
const trimmed = condition.trim();
|
|
6511
|
+
const equal = trimmed.match(/^\{([^}]+)\}\s*==\s*(.+)$/);
|
|
6512
|
+
if (equal)
|
|
6513
|
+
return (variables[equal[1]] ?? "") === equal[2].trim();
|
|
6514
|
+
const unequal = trimmed.match(/^\{([^}]+)\}\s*!=\s*(.+)$/);
|
|
6515
|
+
if (unequal)
|
|
6516
|
+
return (variables[unequal[1]] ?? "") !== unequal[2].trim();
|
|
6517
|
+
const falsy = trimmed.match(/^!\{([^}]+)\}$/);
|
|
6518
|
+
if (falsy) {
|
|
6519
|
+
const value = variables[falsy[1]];
|
|
6520
|
+
return !value || value === "" || value === "false";
|
|
6521
|
+
}
|
|
6522
|
+
const truthy = trimmed.match(/^\{([^}]+)\}$/);
|
|
6523
|
+
if (truthy) {
|
|
6524
|
+
const value = variables[truthy[1]];
|
|
6525
|
+
return !!value && value !== "" && value !== "false";
|
|
6526
|
+
}
|
|
6527
|
+
return true;
|
|
6528
|
+
}
|
|
6529
|
+
|
|
6486
6530
|
// src/db/templates.ts
|
|
6487
6531
|
function rowToTemplate(row) {
|
|
6488
6532
|
return {
|
|
@@ -6558,6 +6602,14 @@ function deleteTemplate(id, db) {
|
|
|
6558
6602
|
payload: template,
|
|
6559
6603
|
version: template.version
|
|
6560
6604
|
}, d);
|
|
6605
|
+
for (const task of getTemplateTasks(resolved, d)) {
|
|
6606
|
+
recordStorageTombstone({
|
|
6607
|
+
object_type: "template_tasks",
|
|
6608
|
+
object_id: task.id,
|
|
6609
|
+
payload: task,
|
|
6610
|
+
version: 1
|
|
6611
|
+
}, d);
|
|
6612
|
+
}
|
|
6561
6613
|
return d.run("DELETE FROM task_templates WHERE id = ?", [resolved]).changes > 0;
|
|
6562
6614
|
}
|
|
6563
6615
|
function updateTemplate(id, updates, db) {
|
|
@@ -6689,34 +6741,7 @@ function getTemplateTasks(templateId, db) {
|
|
|
6689
6741
|
return rows.map(rowToTemplateTask);
|
|
6690
6742
|
}
|
|
6691
6743
|
function evaluateCondition(condition, variables) {
|
|
6692
|
-
|
|
6693
|
-
return true;
|
|
6694
|
-
const trimmed = condition.trim();
|
|
6695
|
-
const eqMatch = trimmed.match(/^\{([^}]+)\}\s*==\s*(.+)$/);
|
|
6696
|
-
if (eqMatch) {
|
|
6697
|
-
const varName = eqMatch[1];
|
|
6698
|
-
const expected = eqMatch[2].trim();
|
|
6699
|
-
return (variables[varName] ?? "") === expected;
|
|
6700
|
-
}
|
|
6701
|
-
const neqMatch = trimmed.match(/^\{([^}]+)\}\s*!=\s*(.+)$/);
|
|
6702
|
-
if (neqMatch) {
|
|
6703
|
-
const varName = neqMatch[1];
|
|
6704
|
-
const expected = neqMatch[2].trim();
|
|
6705
|
-
return (variables[varName] ?? "") !== expected;
|
|
6706
|
-
}
|
|
6707
|
-
const falsyMatch = trimmed.match(/^!\{([^}]+)\}$/);
|
|
6708
|
-
if (falsyMatch) {
|
|
6709
|
-
const varName = falsyMatch[1];
|
|
6710
|
-
const val = variables[varName];
|
|
6711
|
-
return !val || val === "" || val === "false";
|
|
6712
|
-
}
|
|
6713
|
-
const truthyMatch = trimmed.match(/^\{([^}]+)\}$/);
|
|
6714
|
-
if (truthyMatch) {
|
|
6715
|
-
const varName = truthyMatch[1];
|
|
6716
|
-
const val = variables[varName];
|
|
6717
|
-
return !!val && val !== "" && val !== "false";
|
|
6718
|
-
}
|
|
6719
|
-
return true;
|
|
6744
|
+
return evaluateTemplateCondition(condition, variables);
|
|
6720
6745
|
}
|
|
6721
6746
|
function exportTemplate(id, db) {
|
|
6722
6747
|
const d = db || getDatabase();
|
|
@@ -6789,29 +6814,10 @@ function listTemplateVersions(id, db) {
|
|
|
6789
6814
|
return d.query("SELECT * FROM template_versions WHERE template_id = ? ORDER BY version DESC").all(resolved);
|
|
6790
6815
|
}
|
|
6791
6816
|
function resolveVariables(templateVars, provided) {
|
|
6792
|
-
|
|
6793
|
-
for (const v of templateVars) {
|
|
6794
|
-
if (merged[v.name] === undefined && v.default !== undefined) {
|
|
6795
|
-
merged[v.name] = v.default;
|
|
6796
|
-
}
|
|
6797
|
-
}
|
|
6798
|
-
const missing = [];
|
|
6799
|
-
for (const v of templateVars) {
|
|
6800
|
-
if (v.required && merged[v.name] === undefined) {
|
|
6801
|
-
missing.push(v.name);
|
|
6802
|
-
}
|
|
6803
|
-
}
|
|
6804
|
-
if (missing.length > 0) {
|
|
6805
|
-
throw new Error(`Missing required template variable(s): ${missing.join(", ")}`);
|
|
6806
|
-
}
|
|
6807
|
-
return merged;
|
|
6817
|
+
return resolveTemplateVariables(templateVars, provided);
|
|
6808
6818
|
}
|
|
6809
6819
|
function substituteVars(text, variables) {
|
|
6810
|
-
|
|
6811
|
-
for (const [key, val] of Object.entries(variables)) {
|
|
6812
|
-
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), val);
|
|
6813
|
-
}
|
|
6814
|
-
return result;
|
|
6820
|
+
return substituteTemplateVariables(text, variables);
|
|
6815
6821
|
}
|
|
6816
6822
|
function tasksFromTemplate(templateId, projectId, variables, taskListId, db, _visitedTemplateIds) {
|
|
6817
6823
|
const d = db || getDatabase();
|
|
@@ -10756,7 +10762,7 @@ var init_tasks = __esm(() => {
|
|
|
10756
10762
|
// package.json
|
|
10757
10763
|
var package_default = {
|
|
10758
10764
|
name: "@hasna/todos",
|
|
10759
|
-
version: "0.11.
|
|
10765
|
+
version: "0.11.95",
|
|
10760
10766
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
10761
10767
|
type: "module",
|
|
10762
10768
|
main: "dist/index.js",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Database } from "bun:sqlite";
|
|
2
|
-
export type StorageTombstoneObjectType = "tasks" | "projects" | "project_machine_paths" | "plans" | "agents" | "task_lists" | "templates" | "audit_history";
|
|
2
|
+
export type StorageTombstoneObjectType = "tasks" | "projects" | "project_machine_paths" | "plans" | "agents" | "task_lists" | "templates" | "template_tasks" | "audit_history";
|
|
3
3
|
export interface StorageTombstone {
|
|
4
4
|
id: string;
|
|
5
5
|
object_type: StorageTombstoneObjectType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-tombstones.d.ts","sourceRoot":"","sources":["../../src/db/storage-tombstones.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,MAAM,0BAA0B,GAClC,OAAO,GACP,UAAU,GACV,uBAAuB,GACvB,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,WAAW,GACX,eAAe,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,0BAA0B,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,0BAA0B,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CA2B1G;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,0BAA0B,EACtC,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,gBAAgB,GAAG,IAAI,CAMzB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,gBAAgB,EAAE,CAKvE;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,YAAY,CAAC,EAC9D,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAChC,OAAO,CAOT;AAgCD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAMnE"}
|
|
1
|
+
{"version":3,"file":"storage-tombstones.d.ts","sourceRoot":"","sources":["../../src/db/storage-tombstones.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C,MAAM,MAAM,0BAA0B,GAClC,OAAO,GACP,UAAU,GACV,uBAAuB,GACvB,OAAO,GACP,QAAQ,GACR,YAAY,GACZ,WAAW,GACX,gBAAgB,GAChB,eAAe,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,0BAA0B,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,0BAA0B,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CA2B1G;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,0BAA0B,EACtC,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,gBAAgB,GAAG,IAAI,CAMzB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,gBAAgB,EAAE,CAKvE;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,YAAY,CAAC,EAC9D,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAChC,OAAO,CAOT;AAgCD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,CAMnE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/db/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/db/templates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAUzL,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAClD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AA6BD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CAmBtF;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,IAAI,CAM1E;AAED,wBAAgB,aAAa,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,EAAE,CAG3D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAsBjE;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,IAAI,CA0C3G;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,eAAe,CAiB7H;AAID,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,EAAE,CAsC9G;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,iBAAiB,GAAG,IAAI,CASxF;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,EAAE,CAMlF;AAID;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAE/F;AAID,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,KAAK,EAAE,KAAK,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,oBAAoB,EAAE,MAAM,EAAE,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,CAAC,CAAC;CACJ;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,cAAc,CA4BxE;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,YAAY,CA2BhF;AAID,2CAA2C;AAC3C,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,eAAe,GAAG,IAAI,CAQrG;AAED,sCAAsC;AACtC,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,eAAe,EAAE,CAOjF;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,gBAAgB,EAAE,EAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAExB;AASD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,UAAU,CAAC,EAAE,MAAM,EACnB,EAAE,CAAC,EAAE,QAAQ,EACb,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAChC,IAAI,EAAE,CAwFR;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,EAAE,CAAC,EAAE,QAAQ,GACZ,eAAe,CA2CjB"}
|
package/dist/index.js
CHANGED
|
@@ -6483,6 +6483,50 @@ var init_recurrence = __esm(() => {
|
|
|
6483
6483
|
};
|
|
6484
6484
|
});
|
|
6485
6485
|
|
|
6486
|
+
// src/lib/template-semantics.ts
|
|
6487
|
+
function resolveTemplateVariables(templateVars, provided) {
|
|
6488
|
+
const merged = { ...provided };
|
|
6489
|
+
for (const variable of templateVars) {
|
|
6490
|
+
if (merged[variable.name] === undefined && variable.default !== undefined) {
|
|
6491
|
+
merged[variable.name] = variable.default;
|
|
6492
|
+
}
|
|
6493
|
+
}
|
|
6494
|
+
const missing = templateVars.filter((variable) => variable.required && merged[variable.name] === undefined).map((variable) => variable.name);
|
|
6495
|
+
if (missing.length > 0) {
|
|
6496
|
+
throw new Error(`Missing required template variable(s): ${missing.join(", ")}`);
|
|
6497
|
+
}
|
|
6498
|
+
return merged;
|
|
6499
|
+
}
|
|
6500
|
+
function substituteTemplateVariables(text, variables) {
|
|
6501
|
+
let result = text;
|
|
6502
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
6503
|
+
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), value);
|
|
6504
|
+
}
|
|
6505
|
+
return result;
|
|
6506
|
+
}
|
|
6507
|
+
function evaluateTemplateCondition(condition, variables) {
|
|
6508
|
+
if (!condition || condition.trim() === "")
|
|
6509
|
+
return true;
|
|
6510
|
+
const trimmed = condition.trim();
|
|
6511
|
+
const equal = trimmed.match(/^\{([^}]+)\}\s*==\s*(.+)$/);
|
|
6512
|
+
if (equal)
|
|
6513
|
+
return (variables[equal[1]] ?? "") === equal[2].trim();
|
|
6514
|
+
const unequal = trimmed.match(/^\{([^}]+)\}\s*!=\s*(.+)$/);
|
|
6515
|
+
if (unequal)
|
|
6516
|
+
return (variables[unequal[1]] ?? "") !== unequal[2].trim();
|
|
6517
|
+
const falsy = trimmed.match(/^!\{([^}]+)\}$/);
|
|
6518
|
+
if (falsy) {
|
|
6519
|
+
const value = variables[falsy[1]];
|
|
6520
|
+
return !value || value === "" || value === "false";
|
|
6521
|
+
}
|
|
6522
|
+
const truthy = trimmed.match(/^\{([^}]+)\}$/);
|
|
6523
|
+
if (truthy) {
|
|
6524
|
+
const value = variables[truthy[1]];
|
|
6525
|
+
return !!value && value !== "" && value !== "false";
|
|
6526
|
+
}
|
|
6527
|
+
return true;
|
|
6528
|
+
}
|
|
6529
|
+
|
|
6486
6530
|
// src/db/templates.ts
|
|
6487
6531
|
function rowToTemplate(row) {
|
|
6488
6532
|
return {
|
|
@@ -6558,6 +6602,14 @@ function deleteTemplate(id, db) {
|
|
|
6558
6602
|
payload: template,
|
|
6559
6603
|
version: template.version
|
|
6560
6604
|
}, d);
|
|
6605
|
+
for (const task of getTemplateTasks(resolved, d)) {
|
|
6606
|
+
recordStorageTombstone({
|
|
6607
|
+
object_type: "template_tasks",
|
|
6608
|
+
object_id: task.id,
|
|
6609
|
+
payload: task,
|
|
6610
|
+
version: 1
|
|
6611
|
+
}, d);
|
|
6612
|
+
}
|
|
6561
6613
|
return d.run("DELETE FROM task_templates WHERE id = ?", [resolved]).changes > 0;
|
|
6562
6614
|
}
|
|
6563
6615
|
function updateTemplate(id, updates, db) {
|
|
@@ -6689,34 +6741,7 @@ function getTemplateTasks(templateId, db) {
|
|
|
6689
6741
|
return rows.map(rowToTemplateTask);
|
|
6690
6742
|
}
|
|
6691
6743
|
function evaluateCondition(condition, variables) {
|
|
6692
|
-
|
|
6693
|
-
return true;
|
|
6694
|
-
const trimmed = condition.trim();
|
|
6695
|
-
const eqMatch = trimmed.match(/^\{([^}]+)\}\s*==\s*(.+)$/);
|
|
6696
|
-
if (eqMatch) {
|
|
6697
|
-
const varName = eqMatch[1];
|
|
6698
|
-
const expected = eqMatch[2].trim();
|
|
6699
|
-
return (variables[varName] ?? "") === expected;
|
|
6700
|
-
}
|
|
6701
|
-
const neqMatch = trimmed.match(/^\{([^}]+)\}\s*!=\s*(.+)$/);
|
|
6702
|
-
if (neqMatch) {
|
|
6703
|
-
const varName = neqMatch[1];
|
|
6704
|
-
const expected = neqMatch[2].trim();
|
|
6705
|
-
return (variables[varName] ?? "") !== expected;
|
|
6706
|
-
}
|
|
6707
|
-
const falsyMatch = trimmed.match(/^!\{([^}]+)\}$/);
|
|
6708
|
-
if (falsyMatch) {
|
|
6709
|
-
const varName = falsyMatch[1];
|
|
6710
|
-
const val = variables[varName];
|
|
6711
|
-
return !val || val === "" || val === "false";
|
|
6712
|
-
}
|
|
6713
|
-
const truthyMatch = trimmed.match(/^\{([^}]+)\}$/);
|
|
6714
|
-
if (truthyMatch) {
|
|
6715
|
-
const varName = truthyMatch[1];
|
|
6716
|
-
const val = variables[varName];
|
|
6717
|
-
return !!val && val !== "" && val !== "false";
|
|
6718
|
-
}
|
|
6719
|
-
return true;
|
|
6744
|
+
return evaluateTemplateCondition(condition, variables);
|
|
6720
6745
|
}
|
|
6721
6746
|
function exportTemplate(id, db) {
|
|
6722
6747
|
const d = db || getDatabase();
|
|
@@ -6789,29 +6814,10 @@ function listTemplateVersions(id, db) {
|
|
|
6789
6814
|
return d.query("SELECT * FROM template_versions WHERE template_id = ? ORDER BY version DESC").all(resolved);
|
|
6790
6815
|
}
|
|
6791
6816
|
function resolveVariables(templateVars, provided) {
|
|
6792
|
-
|
|
6793
|
-
for (const v of templateVars) {
|
|
6794
|
-
if (merged[v.name] === undefined && v.default !== undefined) {
|
|
6795
|
-
merged[v.name] = v.default;
|
|
6796
|
-
}
|
|
6797
|
-
}
|
|
6798
|
-
const missing = [];
|
|
6799
|
-
for (const v of templateVars) {
|
|
6800
|
-
if (v.required && merged[v.name] === undefined) {
|
|
6801
|
-
missing.push(v.name);
|
|
6802
|
-
}
|
|
6803
|
-
}
|
|
6804
|
-
if (missing.length > 0) {
|
|
6805
|
-
throw new Error(`Missing required template variable(s): ${missing.join(", ")}`);
|
|
6806
|
-
}
|
|
6807
|
-
return merged;
|
|
6817
|
+
return resolveTemplateVariables(templateVars, provided);
|
|
6808
6818
|
}
|
|
6809
6819
|
function substituteVars(text, variables) {
|
|
6810
|
-
|
|
6811
|
-
for (const [key, val] of Object.entries(variables)) {
|
|
6812
|
-
result = result.replace(new RegExp(`\\{${key}\\}`, "g"), val);
|
|
6813
|
-
}
|
|
6814
|
-
return result;
|
|
6820
|
+
return substituteTemplateVariables(text, variables);
|
|
6815
6821
|
}
|
|
6816
6822
|
function tasksFromTemplate(templateId, projectId, variables, taskListId, db, _visitedTemplateIds) {
|
|
6817
6823
|
const d = db || getDatabase();
|
|
@@ -10861,7 +10867,7 @@ var init_dispatches = __esm(() => {
|
|
|
10861
10867
|
// package.json
|
|
10862
10868
|
var package_default = {
|
|
10863
10869
|
name: "@hasna/todos",
|
|
10864
|
-
version: "0.11.
|
|
10870
|
+
version: "0.11.95",
|
|
10865
10871
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
10866
10872
|
type: "module",
|
|
10867
10873
|
main: "dist/index.js",
|
|
@@ -23215,6 +23221,21 @@ var TEMPLATE_COLUMNS = [
|
|
|
23215
23221
|
"machine_id",
|
|
23216
23222
|
"synced_at"
|
|
23217
23223
|
];
|
|
23224
|
+
var TEMPLATE_TASK_COLUMNS = [
|
|
23225
|
+
"id",
|
|
23226
|
+
"template_id",
|
|
23227
|
+
"position",
|
|
23228
|
+
"title_pattern",
|
|
23229
|
+
"description",
|
|
23230
|
+
"priority",
|
|
23231
|
+
"tags",
|
|
23232
|
+
"task_type",
|
|
23233
|
+
"condition",
|
|
23234
|
+
"include_template_id",
|
|
23235
|
+
"depends_on_positions",
|
|
23236
|
+
"metadata",
|
|
23237
|
+
"created_at"
|
|
23238
|
+
];
|
|
23218
23239
|
var TASK_COLUMNS = [
|
|
23219
23240
|
"id",
|
|
23220
23241
|
"short_id",
|
|
@@ -23283,7 +23304,7 @@ var AUDIT_COLUMNS = [
|
|
|
23283
23304
|
"created_at",
|
|
23284
23305
|
"machine_id"
|
|
23285
23306
|
];
|
|
23286
|
-
var JSON_COLUMNS = new Set(["tags", "metadata", "permissions", "capabilities", "variables"]);
|
|
23307
|
+
var JSON_COLUMNS = new Set(["tags", "metadata", "permissions", "capabilities", "variables", "depends_on_positions"]);
|
|
23287
23308
|
var BOOLEAN_COLUMNS = new Set(["requires_approval"]);
|
|
23288
23309
|
function exportSqliteTodosStorageSnapshot(db) {
|
|
23289
23310
|
const d = db ?? getDatabase();
|
|
@@ -23297,6 +23318,7 @@ function exportSqliteTodosStorageSnapshot(db) {
|
|
|
23297
23318
|
agents: listAgents({ include_archived: true }, d),
|
|
23298
23319
|
taskLists: listTaskLists(undefined, d),
|
|
23299
23320
|
templates: listTemplates(d),
|
|
23321
|
+
templateTasks: listTemplates(d).flatMap((template) => getTemplateTasks(template.id, d)),
|
|
23300
23322
|
auditHistory: getRecentActivity(Number.MAX_SAFE_INTEGER, d),
|
|
23301
23323
|
tombstones: listStorageTombstones(d)
|
|
23302
23324
|
};
|
|
@@ -23346,6 +23368,7 @@ function importSqliteTodosStorageSnapshot(snapshot, db) {
|
|
|
23346
23368
|
applyRows("task_lists", "task_lists", TASK_LIST_COLUMNS, snapshot.taskLists, "updated_at");
|
|
23347
23369
|
applyRows("plans", "plans", PLAN_COLUMNS, snapshot.plans, "updated_at");
|
|
23348
23370
|
applyRows("templates", "task_templates", TEMPLATE_COLUMNS, snapshot.templates);
|
|
23371
|
+
applyRows("template_tasks", "template_tasks", TEMPLATE_TASK_COLUMNS, snapshot.templateTasks ?? []);
|
|
23349
23372
|
applyRows("tasks", "tasks", TASK_COLUMNS, sortedTasks2(snapshot.tasks), "updated_at", (row, changed) => {
|
|
23350
23373
|
if (changed && Array.isArray(row["tags"]) && typeof row["id"] === "string") {
|
|
23351
23374
|
replaceTaskTags(row["id"], row["tags"].filter((tag) => typeof tag === "string"), d);
|
|
@@ -23450,6 +23473,8 @@ function tableForTombstone(objectType) {
|
|
|
23450
23473
|
return "task_lists";
|
|
23451
23474
|
if (objectType === "templates")
|
|
23452
23475
|
return "task_templates";
|
|
23476
|
+
if (objectType === "template_tasks")
|
|
23477
|
+
return "template_tasks";
|
|
23453
23478
|
return "task_history";
|
|
23454
23479
|
}
|
|
23455
23480
|
function listRows(db, table, columns) {
|
|
@@ -23868,6 +23893,7 @@ function snapshotEntries(snapshot) {
|
|
|
23868
23893
|
...snapshot.agents.map((payload) => entry("agents", payload, snapshot.exportedAt)),
|
|
23869
23894
|
...snapshot.taskLists.map((payload) => entry("task_lists", payload, snapshot.exportedAt)),
|
|
23870
23895
|
...snapshot.templates.map((payload) => entry("templates", payload, snapshot.exportedAt)),
|
|
23896
|
+
...(snapshot.templateTasks ?? []).map((payload) => entry("template_tasks", payload, snapshot.exportedAt)),
|
|
23871
23897
|
...snapshot.auditHistory.map((payload) => entry("audit_history", payload, snapshot.exportedAt)),
|
|
23872
23898
|
...(snapshot.tombstones ?? []).map((tombstone) => ({
|
|
23873
23899
|
type: tombstone.object_type,
|
|
@@ -23919,6 +23945,7 @@ function rowsToSnapshot(rows) {
|
|
|
23919
23945
|
agents: [],
|
|
23920
23946
|
taskLists: [],
|
|
23921
23947
|
templates: [],
|
|
23948
|
+
templateTasks: [],
|
|
23922
23949
|
auditHistory: [],
|
|
23923
23950
|
tombstones: []
|
|
23924
23951
|
};
|
|
@@ -23953,6 +23980,8 @@ function rowsToSnapshot(rows) {
|
|
|
23953
23980
|
snapshot.taskLists.push(payload);
|
|
23954
23981
|
else if (row.object_type === "templates")
|
|
23955
23982
|
snapshot.templates.push(payload);
|
|
23983
|
+
else if (row.object_type === "template_tasks")
|
|
23984
|
+
snapshot.templateTasks.push(payload);
|
|
23956
23985
|
else if (row.object_type === "audit_history")
|
|
23957
23986
|
snapshot.auditHistory.push(payload);
|
|
23958
23987
|
}
|
|
@@ -24115,10 +24144,13 @@ function createPostgresTodosStorageAdapter(options) {
|
|
|
24115
24144
|
get: (id) => store.get("templates", id),
|
|
24116
24145
|
list: async () => (await store.list("templates")).sort((a, b) => a.name.localeCompare(b.name)),
|
|
24117
24146
|
update: (id, input) => updateTemplate2(id, input, store),
|
|
24118
|
-
delete: (id, context) =>
|
|
24147
|
+
delete: (id, context) => deleteTemplate2(id, store, context),
|
|
24119
24148
|
getWithTasks: async (id) => {
|
|
24120
24149
|
const template = await store.get("templates", id);
|
|
24121
|
-
|
|
24150
|
+
if (!template)
|
|
24151
|
+
return null;
|
|
24152
|
+
const tasks = (await store.list("template_tasks")).filter((task2) => task2.template_id === id).sort((left, right) => left.position - right.position || left.id.localeCompare(right.id));
|
|
24153
|
+
return { ...template, tasks };
|
|
24122
24154
|
}
|
|
24123
24155
|
},
|
|
24124
24156
|
audit: {
|
|
@@ -24406,6 +24438,57 @@ class PostgresJsonRecordStore {
|
|
|
24406
24438
|
}
|
|
24407
24439
|
return value;
|
|
24408
24440
|
}
|
|
24441
|
+
async createTemplateWithTasks(template, tasks, context = {}) {
|
|
24442
|
+
await this.ensureSchema();
|
|
24443
|
+
const records = [
|
|
24444
|
+
{ object_type: "templates", object_id: template.id, payload: template, updated_at: template.created_at, version: template.version },
|
|
24445
|
+
...tasks.map((task2) => ({ object_type: "template_tasks", object_id: task2.id, payload: task2, updated_at: task2.created_at, version: 1 }))
|
|
24446
|
+
];
|
|
24447
|
+
const result = await this.options.client.query(`/* todos:create-template-with-tasks-atomic */ WITH input AS (
|
|
24448
|
+
SELECT value->>'object_type' AS object_type,
|
|
24449
|
+
value->>'object_id' AS object_id,
|
|
24450
|
+
value->'payload' AS payload,
|
|
24451
|
+
value->>'updated_at' AS updated_at,
|
|
24452
|
+
COALESCE((value->>'version')::integer, 1) AS version
|
|
24453
|
+
FROM jsonb_array_elements($2::jsonb) AS value
|
|
24454
|
+
) INSERT INTO ${this.tableName} (
|
|
24455
|
+
service, object_type, object_id, payload, updated_at,
|
|
24456
|
+
deleted_at, source_machine_id, version
|
|
24457
|
+
) SELECT $1, object_type, object_id, payload, updated_at::timestamptz,
|
|
24458
|
+
NULL, $3, version
|
|
24459
|
+
FROM input
|
|
24460
|
+
ON CONFLICT (service, object_type, object_id) DO UPDATE SET
|
|
24461
|
+
payload = EXCLUDED.payload,
|
|
24462
|
+
updated_at = EXCLUDED.updated_at,
|
|
24463
|
+
deleted_at = NULL,
|
|
24464
|
+
source_machine_id = EXCLUDED.source_machine_id,
|
|
24465
|
+
version = EXCLUDED.version
|
|
24466
|
+
WHERE ${this.tableName}.updated_at IS NULL
|
|
24467
|
+
OR ${this.tableName}.updated_at < EXCLUDED.updated_at
|
|
24468
|
+
OR (${this.tableName}.updated_at = EXCLUDED.updated_at
|
|
24469
|
+
AND COALESCE(${this.tableName}.version, 0) <= COALESCE(EXCLUDED.version, 0))
|
|
24470
|
+
RETURNING object_type, object_id`, [this.service, jsonbParam(records), this.machineId(context)]);
|
|
24471
|
+
if (result.rows.length !== records.length) {
|
|
24472
|
+
throw new Error("Template checklist write was rejected before completion; no partial template was committed");
|
|
24473
|
+
}
|
|
24474
|
+
}
|
|
24475
|
+
async deleteTemplateWithTasks(id, context = {}) {
|
|
24476
|
+
await this.ensureSchema();
|
|
24477
|
+
const timestamp2 = new Date().toISOString();
|
|
24478
|
+
const result = await this.options.client.query(`/* todos:delete-template-with-tasks-atomic */ WITH target AS (
|
|
24479
|
+
SELECT 1 FROM ${this.tableName}
|
|
24480
|
+
WHERE service = $1 AND object_type = 'templates' AND object_id = $2 AND deleted_at IS NULL
|
|
24481
|
+
) UPDATE ${this.tableName} AS record SET
|
|
24482
|
+
deleted_at = $3::timestamptz,
|
|
24483
|
+
updated_at = $3::timestamptz,
|
|
24484
|
+
source_machine_id = COALESCE($4, record.source_machine_id),
|
|
24485
|
+
version = COALESCE(record.version, 0) + 1
|
|
24486
|
+
WHERE record.service = $1 AND record.deleted_at IS NULL AND EXISTS (SELECT 1 FROM target)
|
|
24487
|
+
AND (record.object_type = 'templates' AND record.object_id = $2
|
|
24488
|
+
OR record.object_type = 'template_tasks' AND record.payload->>'template_id' = $2)
|
|
24489
|
+
RETURNING record.object_type`, [this.service, id, timestamp2, this.machineId(context)]);
|
|
24490
|
+
return result.rows.some((row) => row.object_type === "templates");
|
|
24491
|
+
}
|
|
24409
24492
|
async completeTask(id, agentId, options) {
|
|
24410
24493
|
await this.ensureSchema();
|
|
24411
24494
|
const operationTimestamp = new Date().toISOString();
|
|
@@ -25170,7 +25253,7 @@ async function updateTaskList2(id, input, store) {
|
|
|
25170
25253
|
}
|
|
25171
25254
|
async function createTemplate2(input, store, context) {
|
|
25172
25255
|
const timestamp2 = new Date().toISOString();
|
|
25173
|
-
|
|
25256
|
+
const template = {
|
|
25174
25257
|
id: randomUUID3(),
|
|
25175
25258
|
name: input.name,
|
|
25176
25259
|
title_pattern: input.title_pattern,
|
|
@@ -25185,7 +25268,30 @@ async function createTemplate2(input, store, context) {
|
|
|
25185
25268
|
created_at: timestamp2,
|
|
25186
25269
|
machine_id: store.machineId(context),
|
|
25187
25270
|
synced_at: null
|
|
25188
|
-
}
|
|
25271
|
+
};
|
|
25272
|
+
const tasks = buildTemplateTasks(template.id, input.tasks ?? [], timestamp2);
|
|
25273
|
+
await store.createTemplateWithTasks(template, tasks, context);
|
|
25274
|
+
return template;
|
|
25275
|
+
}
|
|
25276
|
+
function buildTemplateTasks(templateId, inputs, timestamp2) {
|
|
25277
|
+
return inputs.map((input, position) => ({
|
|
25278
|
+
id: randomUUID3(),
|
|
25279
|
+
template_id: templateId,
|
|
25280
|
+
position,
|
|
25281
|
+
title_pattern: input.title_pattern,
|
|
25282
|
+
description: input.description ?? null,
|
|
25283
|
+
priority: input.priority ?? "medium",
|
|
25284
|
+
tags: input.tags ?? [],
|
|
25285
|
+
task_type: input.task_type ?? null,
|
|
25286
|
+
condition: input.condition ?? null,
|
|
25287
|
+
include_template_id: input.include_template_id ?? null,
|
|
25288
|
+
depends_on_positions: input.depends_on ?? [],
|
|
25289
|
+
metadata: input.metadata ?? {},
|
|
25290
|
+
created_at: timestamp2
|
|
25291
|
+
}));
|
|
25292
|
+
}
|
|
25293
|
+
async function deleteTemplate2(id, store, context) {
|
|
25294
|
+
return store.deleteTemplateWithTasks(id, context);
|
|
25189
25295
|
}
|
|
25190
25296
|
async function updateTemplate2(id, input, store) {
|
|
25191
25297
|
const template = await store.get("templates", id);
|
|
@@ -25241,6 +25347,7 @@ async function exportSnapshot(store) {
|
|
|
25241
25347
|
agents: await store.list("agents"),
|
|
25242
25348
|
taskLists: await store.list("task_lists"),
|
|
25243
25349
|
templates: await store.list("templates"),
|
|
25350
|
+
templateTasks: await store.list("template_tasks"),
|
|
25244
25351
|
auditHistory: await store.list("audit_history"),
|
|
25245
25352
|
tombstones: await store.listTombstones()
|
|
25246
25353
|
};
|
|
@@ -25265,6 +25372,7 @@ async function importSnapshot(snapshot, store, context) {
|
|
|
25265
25372
|
...snapshot.agents.map((row) => ["agents", row]),
|
|
25266
25373
|
...snapshot.taskLists.map((row) => ["task_lists", row]),
|
|
25267
25374
|
...snapshot.templates.map((row) => ["templates", row]),
|
|
25375
|
+
...(snapshot.templateTasks ?? []).map((row) => ["template_tasks", row]),
|
|
25268
25376
|
...snapshot.auditHistory.map((row) => ["audit_history", row])
|
|
25269
25377
|
];
|
|
25270
25378
|
for (const [type, row] of entries) {
|
|
@@ -25410,6 +25518,7 @@ var SNAPSHOT_TO_OBJECT_TYPE = {
|
|
|
25410
25518
|
agents: "agents",
|
|
25411
25519
|
taskLists: "task_lists",
|
|
25412
25520
|
templates: "templates",
|
|
25521
|
+
templateTasks: "template_tasks",
|
|
25413
25522
|
auditHistory: "audit_history"
|
|
25414
25523
|
};
|
|
25415
25524
|
|
|
@@ -25601,6 +25710,7 @@ function emptySnapshot() {
|
|
|
25601
25710
|
agents: [],
|
|
25602
25711
|
taskLists: [],
|
|
25603
25712
|
templates: [],
|
|
25713
|
+
templateTasks: [],
|
|
25604
25714
|
auditHistory: [],
|
|
25605
25715
|
tombstones: []
|
|
25606
25716
|
};
|
|
@@ -26057,6 +26167,9 @@ class TodosShadowOutbox {
|
|
|
26057
26167
|
case "templates":
|
|
26058
26168
|
snapshot.templates.push(record);
|
|
26059
26169
|
break;
|
|
26170
|
+
case "template_tasks":
|
|
26171
|
+
snapshot.templateTasks.push(record);
|
|
26172
|
+
break;
|
|
26060
26173
|
case "audit_history":
|
|
26061
26174
|
snapshot.auditHistory.push(record);
|
|
26062
26175
|
break;
|
|
@@ -26123,6 +26236,7 @@ function emptySnapshot2() {
|
|
|
26123
26236
|
agents: [],
|
|
26124
26237
|
taskLists: [],
|
|
26125
26238
|
templates: [],
|
|
26239
|
+
templateTasks: [],
|
|
26126
26240
|
auditHistory: [],
|
|
26127
26241
|
tombstones: []
|
|
26128
26242
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TemplateVariable } from "../types/index.js";
|
|
2
|
+
/** Resolve template variables consistently for local and remote execution. */
|
|
3
|
+
export declare function resolveTemplateVariables(templateVars: TemplateVariable[], provided?: Record<string, string>): Record<string, string>;
|
|
4
|
+
/** Replace only variables which have been resolved, leaving unrelated literals intact. */
|
|
5
|
+
export declare function substituteTemplateVariables(text: string, variables: Record<string, string>): string;
|
|
6
|
+
/** Evaluate the intentionally small, documented template-condition language. */
|
|
7
|
+
export declare function evaluateTemplateCondition(condition: string, variables: Record<string, string>): boolean;
|
|
8
|
+
//# sourceMappingURL=template-semantics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-semantics.d.ts","sourceRoot":"","sources":["../../src/lib/template-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,8EAA8E;AAC9E,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,gBAAgB,EAAE,EAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBxB;AAED,0FAA0F;AAC1F,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAMnG;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAkBvG"}
|