@hasna/todos 0.11.21 → 0.11.22
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/index.js +213 -200
- package/dist/db/pg-migrations.d.ts.map +1 -1
- package/dist/db/projects.d.ts.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/tasks.d.ts.map +1 -1
- package/dist/index.js +180 -166
- package/dist/mcp/index.js +194 -191
- package/dist/server/index.js +114 -107
- package/package.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -1105,6 +1105,12 @@ var init_schema = __esm(() => {
|
|
|
1105
1105
|
ALTER TABLE tasks ADD COLUMN archived_at TEXT;
|
|
1106
1106
|
CREATE INDEX IF NOT EXISTS idx_tasks_archived ON tasks(archived_at) WHERE archived_at IS NOT NULL;
|
|
1107
1107
|
INSERT OR IGNORE INTO _migrations (id) VALUES (43);
|
|
1108
|
+
`,
|
|
1109
|
+
`
|
|
1110
|
+
DROP INDEX IF EXISTS idx_tasks_short_id;
|
|
1111
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_short_id ON tasks(short_id, machine_id) WHERE short_id IS NOT NULL AND machine_id IS NOT NULL;
|
|
1112
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_short_id_lookup ON tasks(short_id) WHERE short_id IS NOT NULL;
|
|
1113
|
+
INSERT OR IGNORE INTO _migrations (id) VALUES (44);
|
|
1108
1114
|
`
|
|
1109
1115
|
];
|
|
1110
1116
|
});
|
|
@@ -12533,159 +12539,6 @@ var init_types2 = __esm(() => {
|
|
|
12533
12539
|
};
|
|
12534
12540
|
});
|
|
12535
12541
|
|
|
12536
|
-
// src/db/projects.ts
|
|
12537
|
-
function slugify(name) {
|
|
12538
|
-
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
12539
|
-
}
|
|
12540
|
-
function generatePrefix(name, db) {
|
|
12541
|
-
const words = name.replace(/[^a-zA-Z0-9\s]/g, "").trim().split(/\s+/);
|
|
12542
|
-
let prefix;
|
|
12543
|
-
if (words.length >= 3) {
|
|
12544
|
-
prefix = words.slice(0, 3).map((w) => w[0].toUpperCase()).join("");
|
|
12545
|
-
} else if (words.length === 2) {
|
|
12546
|
-
prefix = (words[0].slice(0, 2) + words[1][0]).toUpperCase();
|
|
12547
|
-
} else {
|
|
12548
|
-
prefix = words[0].slice(0, 3).toUpperCase();
|
|
12549
|
-
}
|
|
12550
|
-
let candidate = prefix;
|
|
12551
|
-
let suffix = 1;
|
|
12552
|
-
while (true) {
|
|
12553
|
-
const existing = db.query("SELECT id FROM projects WHERE task_prefix = ?").get(candidate);
|
|
12554
|
-
if (!existing)
|
|
12555
|
-
return candidate;
|
|
12556
|
-
suffix++;
|
|
12557
|
-
candidate = `${prefix}${suffix}`;
|
|
12558
|
-
}
|
|
12559
|
-
}
|
|
12560
|
-
function createProject(input, db) {
|
|
12561
|
-
const d = db || getDatabase();
|
|
12562
|
-
const id = uuid();
|
|
12563
|
-
const timestamp = now();
|
|
12564
|
-
const taskListId = input.task_list_id ?? `todos-${slugify(input.name)}`;
|
|
12565
|
-
const taskPrefix = input.task_prefix || generatePrefix(input.name, d);
|
|
12566
|
-
d.run(`INSERT INTO projects (id, name, path, description, task_list_id, task_prefix, task_counter, created_at, updated_at)
|
|
12567
|
-
VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)`, [id, input.name, input.path, input.description || null, taskListId, taskPrefix, timestamp, timestamp]);
|
|
12568
|
-
return getProject(id, d);
|
|
12569
|
-
}
|
|
12570
|
-
function getProject(id, db) {
|
|
12571
|
-
const d = db || getDatabase();
|
|
12572
|
-
const row = d.query("SELECT * FROM projects WHERE id = ?").get(id);
|
|
12573
|
-
return row;
|
|
12574
|
-
}
|
|
12575
|
-
function listProjects(db) {
|
|
12576
|
-
const d = db || getDatabase();
|
|
12577
|
-
return d.query("SELECT * FROM projects ORDER BY name").all();
|
|
12578
|
-
}
|
|
12579
|
-
function updateProject(id, input, db) {
|
|
12580
|
-
const d = db || getDatabase();
|
|
12581
|
-
const project = getProject(id, d);
|
|
12582
|
-
if (!project)
|
|
12583
|
-
throw new ProjectNotFoundError(id);
|
|
12584
|
-
const sets = ["updated_at = ?"];
|
|
12585
|
-
const params = [now()];
|
|
12586
|
-
if (input.name !== undefined) {
|
|
12587
|
-
sets.push("name = ?");
|
|
12588
|
-
params.push(input.name);
|
|
12589
|
-
}
|
|
12590
|
-
if (input.description !== undefined) {
|
|
12591
|
-
sets.push("description = ?");
|
|
12592
|
-
params.push(input.description);
|
|
12593
|
-
}
|
|
12594
|
-
if (input.task_list_id !== undefined) {
|
|
12595
|
-
sets.push("task_list_id = ?");
|
|
12596
|
-
params.push(input.task_list_id);
|
|
12597
|
-
}
|
|
12598
|
-
if (input.path !== undefined) {
|
|
12599
|
-
sets.push("path = ?");
|
|
12600
|
-
params.push(input.path);
|
|
12601
|
-
}
|
|
12602
|
-
params.push(id);
|
|
12603
|
-
d.run(`UPDATE projects SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
12604
|
-
return getProject(id, d);
|
|
12605
|
-
}
|
|
12606
|
-
function renameProject(id, input, db) {
|
|
12607
|
-
const d = db || getDatabase();
|
|
12608
|
-
const project = getProject(id, d);
|
|
12609
|
-
if (!project)
|
|
12610
|
-
throw new ProjectNotFoundError(id);
|
|
12611
|
-
let taskListsUpdated = 0;
|
|
12612
|
-
const ts = now();
|
|
12613
|
-
if (input.new_slug !== undefined) {
|
|
12614
|
-
const normalised = input.new_slug.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "");
|
|
12615
|
-
if (!normalised)
|
|
12616
|
-
throw new Error("Invalid slug \u2014 must be non-empty kebab-case");
|
|
12617
|
-
const conflict = d.query("SELECT id FROM projects WHERE task_list_id = ? AND id != ?").get(normalised, id);
|
|
12618
|
-
if (conflict)
|
|
12619
|
-
throw new Error(`Slug "${normalised}" is already used by another project`);
|
|
12620
|
-
const oldSlug = project.task_list_id;
|
|
12621
|
-
d.run("UPDATE projects SET task_list_id = ?, updated_at = ? WHERE id = ?", [normalised, ts, id]);
|
|
12622
|
-
if (oldSlug) {
|
|
12623
|
-
const result = d.run("UPDATE task_lists SET slug = ?, name = COALESCE(?, name), updated_at = ? WHERE project_id = ? AND slug = ?", [normalised, input.name ?? null, ts, id, oldSlug]);
|
|
12624
|
-
taskListsUpdated = result.changes;
|
|
12625
|
-
}
|
|
12626
|
-
}
|
|
12627
|
-
if (input.name !== undefined) {
|
|
12628
|
-
d.run("UPDATE projects SET name = ?, updated_at = ? WHERE id = ?", [input.name, ts, id]);
|
|
12629
|
-
}
|
|
12630
|
-
return { project: getProject(id, d), task_lists_updated: taskListsUpdated };
|
|
12631
|
-
}
|
|
12632
|
-
function rowToSource(row) {
|
|
12633
|
-
return {
|
|
12634
|
-
...row,
|
|
12635
|
-
metadata: row.metadata ? JSON.parse(row.metadata) : {}
|
|
12636
|
-
};
|
|
12637
|
-
}
|
|
12638
|
-
function addProjectSource(input, db) {
|
|
12639
|
-
const d = db || getDatabase();
|
|
12640
|
-
const id = uuid();
|
|
12641
|
-
const timestamp = now();
|
|
12642
|
-
d.run(`INSERT INTO project_sources (id, project_id, type, name, uri, description, metadata, created_at, updated_at)
|
|
12643
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
12644
|
-
id,
|
|
12645
|
-
input.project_id,
|
|
12646
|
-
input.type,
|
|
12647
|
-
input.name,
|
|
12648
|
-
input.uri,
|
|
12649
|
-
input.description || null,
|
|
12650
|
-
JSON.stringify(input.metadata || {}),
|
|
12651
|
-
timestamp,
|
|
12652
|
-
timestamp
|
|
12653
|
-
]);
|
|
12654
|
-
return rowToSource(d.query("SELECT * FROM project_sources WHERE id = ?").get(id));
|
|
12655
|
-
}
|
|
12656
|
-
function removeProjectSource(id, db) {
|
|
12657
|
-
const d = db || getDatabase();
|
|
12658
|
-
const result = d.run("DELETE FROM project_sources WHERE id = ?", [id]);
|
|
12659
|
-
return result.changes > 0;
|
|
12660
|
-
}
|
|
12661
|
-
function listProjectSources(projectId, db) {
|
|
12662
|
-
const d = db || getDatabase();
|
|
12663
|
-
const rows = d.query("SELECT * FROM project_sources WHERE project_id = ? ORDER BY name").all(projectId);
|
|
12664
|
-
return rows.map(rowToSource);
|
|
12665
|
-
}
|
|
12666
|
-
function nextTaskShortId(projectId, db) {
|
|
12667
|
-
const d = db || getDatabase();
|
|
12668
|
-
const project = getProject(projectId, d);
|
|
12669
|
-
if (!project || !project.task_prefix)
|
|
12670
|
-
return null;
|
|
12671
|
-
const prefix = project.task_prefix;
|
|
12672
|
-
const prefixLen = prefix.length + 2;
|
|
12673
|
-
const maxRow = d.query(`SELECT MAX(CAST(SUBSTR(short_id, ?) AS INTEGER)) as max_counter FROM tasks WHERE short_id LIKE ?`).get(prefixLen, `${prefix}-%`);
|
|
12674
|
-
const syncedMax = maxRow?.max_counter ?? 0;
|
|
12675
|
-
if (syncedMax >= (project.task_counter ?? 0)) {
|
|
12676
|
-
d.run("UPDATE projects SET task_counter = ?, updated_at = ? WHERE id = ?", [syncedMax, now(), projectId]);
|
|
12677
|
-
}
|
|
12678
|
-
d.run("UPDATE projects SET task_counter = task_counter + 1, updated_at = ? WHERE id = ?", [now(), projectId]);
|
|
12679
|
-
const updated = getProject(projectId, d);
|
|
12680
|
-
const padded = String(updated.task_counter).padStart(5, "0");
|
|
12681
|
-
return `${updated.task_prefix}-${padded}`;
|
|
12682
|
-
}
|
|
12683
|
-
var init_projects = __esm(() => {
|
|
12684
|
-
init_types2();
|
|
12685
|
-
init_database();
|
|
12686
|
-
init_machines();
|
|
12687
|
-
});
|
|
12688
|
-
|
|
12689
12542
|
// src/lib/sync-utils.ts
|
|
12690
12543
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync3, readdirSync as readdirSync4, statSync, writeFileSync as writeFileSync3 } from "fs";
|
|
12691
12544
|
import { join as join7 } from "path";
|
|
@@ -12831,6 +12684,142 @@ var init_config2 = __esm(() => {
|
|
|
12831
12684
|
};
|
|
12832
12685
|
});
|
|
12833
12686
|
|
|
12687
|
+
// src/db/projects.ts
|
|
12688
|
+
function slugify(name) {
|
|
12689
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
12690
|
+
}
|
|
12691
|
+
function generatePrefix(name, db) {
|
|
12692
|
+
const words = name.replace(/[^a-zA-Z0-9\s]/g, "").trim().split(/\s+/);
|
|
12693
|
+
let prefix;
|
|
12694
|
+
if (words.length >= 3) {
|
|
12695
|
+
prefix = words.slice(0, 3).map((w) => w[0].toUpperCase()).join("");
|
|
12696
|
+
} else if (words.length === 2) {
|
|
12697
|
+
prefix = (words[0].slice(0, 2) + words[1][0]).toUpperCase();
|
|
12698
|
+
} else {
|
|
12699
|
+
prefix = words[0].slice(0, 3).toUpperCase();
|
|
12700
|
+
}
|
|
12701
|
+
let candidate = prefix;
|
|
12702
|
+
let suffix = 1;
|
|
12703
|
+
while (true) {
|
|
12704
|
+
const existing = db.query("SELECT id FROM projects WHERE task_prefix = ?").get(candidate);
|
|
12705
|
+
if (!existing)
|
|
12706
|
+
return candidate;
|
|
12707
|
+
suffix++;
|
|
12708
|
+
candidate = `${prefix}${suffix}`;
|
|
12709
|
+
}
|
|
12710
|
+
}
|
|
12711
|
+
function createProject(input, db) {
|
|
12712
|
+
const d = db || getDatabase();
|
|
12713
|
+
const id = uuid();
|
|
12714
|
+
const timestamp = now();
|
|
12715
|
+
const taskListId = input.task_list_id ?? `todos-${slugify(input.name)}`;
|
|
12716
|
+
const taskPrefix = input.task_prefix || generatePrefix(input.name, d);
|
|
12717
|
+
d.run(`INSERT INTO projects (id, name, path, description, task_list_id, task_prefix, task_counter, created_at, updated_at)
|
|
12718
|
+
VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)`, [id, input.name, input.path, input.description || null, taskListId, taskPrefix, timestamp, timestamp]);
|
|
12719
|
+
return getProject(id, d);
|
|
12720
|
+
}
|
|
12721
|
+
function getProject(id, db) {
|
|
12722
|
+
const d = db || getDatabase();
|
|
12723
|
+
const row = d.query("SELECT * FROM projects WHERE id = ?").get(id);
|
|
12724
|
+
return row;
|
|
12725
|
+
}
|
|
12726
|
+
function listProjects(db) {
|
|
12727
|
+
const d = db || getDatabase();
|
|
12728
|
+
return d.query("SELECT * FROM projects ORDER BY name").all();
|
|
12729
|
+
}
|
|
12730
|
+
function updateProject(id, input, db) {
|
|
12731
|
+
const d = db || getDatabase();
|
|
12732
|
+
const project = getProject(id, d);
|
|
12733
|
+
if (!project)
|
|
12734
|
+
throw new ProjectNotFoundError(id);
|
|
12735
|
+
const sets = ["updated_at = ?"];
|
|
12736
|
+
const params = [now()];
|
|
12737
|
+
if (input.name !== undefined) {
|
|
12738
|
+
sets.push("name = ?");
|
|
12739
|
+
params.push(input.name);
|
|
12740
|
+
}
|
|
12741
|
+
if (input.description !== undefined) {
|
|
12742
|
+
sets.push("description = ?");
|
|
12743
|
+
params.push(input.description);
|
|
12744
|
+
}
|
|
12745
|
+
if (input.task_list_id !== undefined) {
|
|
12746
|
+
sets.push("task_list_id = ?");
|
|
12747
|
+
params.push(input.task_list_id);
|
|
12748
|
+
}
|
|
12749
|
+
if (input.path !== undefined) {
|
|
12750
|
+
sets.push("path = ?");
|
|
12751
|
+
params.push(input.path);
|
|
12752
|
+
}
|
|
12753
|
+
params.push(id);
|
|
12754
|
+
d.run(`UPDATE projects SET ${sets.join(", ")} WHERE id = ?`, params);
|
|
12755
|
+
return getProject(id, d);
|
|
12756
|
+
}
|
|
12757
|
+
function renameProject(id, input, db) {
|
|
12758
|
+
const d = db || getDatabase();
|
|
12759
|
+
const project = getProject(id, d);
|
|
12760
|
+
if (!project)
|
|
12761
|
+
throw new ProjectNotFoundError(id);
|
|
12762
|
+
let taskListsUpdated = 0;
|
|
12763
|
+
const ts = now();
|
|
12764
|
+
if (input.new_slug !== undefined) {
|
|
12765
|
+
const normalised = input.new_slug.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-|-$/g, "");
|
|
12766
|
+
if (!normalised)
|
|
12767
|
+
throw new Error("Invalid slug \u2014 must be non-empty kebab-case");
|
|
12768
|
+
const conflict = d.query("SELECT id FROM projects WHERE task_list_id = ? AND id != ?").get(normalised, id);
|
|
12769
|
+
if (conflict)
|
|
12770
|
+
throw new Error(`Slug "${normalised}" is already used by another project`);
|
|
12771
|
+
const oldSlug = project.task_list_id;
|
|
12772
|
+
d.run("UPDATE projects SET task_list_id = ?, updated_at = ? WHERE id = ?", [normalised, ts, id]);
|
|
12773
|
+
if (oldSlug) {
|
|
12774
|
+
const result = d.run("UPDATE task_lists SET slug = ?, name = COALESCE(?, name), updated_at = ? WHERE project_id = ? AND slug = ?", [normalised, input.name ?? null, ts, id, oldSlug]);
|
|
12775
|
+
taskListsUpdated = result.changes;
|
|
12776
|
+
}
|
|
12777
|
+
}
|
|
12778
|
+
if (input.name !== undefined) {
|
|
12779
|
+
d.run("UPDATE projects SET name = ?, updated_at = ? WHERE id = ?", [input.name, ts, id]);
|
|
12780
|
+
}
|
|
12781
|
+
return { project: getProject(id, d), task_lists_updated: taskListsUpdated };
|
|
12782
|
+
}
|
|
12783
|
+
function rowToSource(row) {
|
|
12784
|
+
return {
|
|
12785
|
+
...row,
|
|
12786
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {}
|
|
12787
|
+
};
|
|
12788
|
+
}
|
|
12789
|
+
function addProjectSource(input, db) {
|
|
12790
|
+
const d = db || getDatabase();
|
|
12791
|
+
const id = uuid();
|
|
12792
|
+
const timestamp = now();
|
|
12793
|
+
d.run(`INSERT INTO project_sources (id, project_id, type, name, uri, description, metadata, created_at, updated_at)
|
|
12794
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
12795
|
+
id,
|
|
12796
|
+
input.project_id,
|
|
12797
|
+
input.type,
|
|
12798
|
+
input.name,
|
|
12799
|
+
input.uri,
|
|
12800
|
+
input.description || null,
|
|
12801
|
+
JSON.stringify(input.metadata || {}),
|
|
12802
|
+
timestamp,
|
|
12803
|
+
timestamp
|
|
12804
|
+
]);
|
|
12805
|
+
return rowToSource(d.query("SELECT * FROM project_sources WHERE id = ?").get(id));
|
|
12806
|
+
}
|
|
12807
|
+
function removeProjectSource(id, db) {
|
|
12808
|
+
const d = db || getDatabase();
|
|
12809
|
+
const result = d.run("DELETE FROM project_sources WHERE id = ?", [id]);
|
|
12810
|
+
return result.changes > 0;
|
|
12811
|
+
}
|
|
12812
|
+
function listProjectSources(projectId, db) {
|
|
12813
|
+
const d = db || getDatabase();
|
|
12814
|
+
const rows = d.query("SELECT * FROM project_sources WHERE project_id = ? ORDER BY name").all(projectId);
|
|
12815
|
+
return rows.map(rowToSource);
|
|
12816
|
+
}
|
|
12817
|
+
var init_projects = __esm(() => {
|
|
12818
|
+
init_types2();
|
|
12819
|
+
init_database();
|
|
12820
|
+
init_machines();
|
|
12821
|
+
});
|
|
12822
|
+
|
|
12834
12823
|
// src/lib/completion-guard.ts
|
|
12835
12824
|
function checkCompletionGuard(task, agentId, db, configOverride) {
|
|
12836
12825
|
let config;
|
|
@@ -13709,47 +13698,56 @@ function replaceTaskTags(taskId, tags, db) {
|
|
|
13709
13698
|
}
|
|
13710
13699
|
function createTask(input, db) {
|
|
13711
13700
|
const d = db || getDatabase();
|
|
13712
|
-
const id = uuid();
|
|
13713
13701
|
const timestamp = now();
|
|
13714
13702
|
const tags = input.tags || [];
|
|
13715
|
-
const shortId = input.project_id ? nextTaskShortId(input.project_id, d) : null;
|
|
13716
|
-
const title = shortId ? `${shortId}: ${input.title}` : input.title;
|
|
13717
13703
|
const assignedBy = input.assigned_by || input.agent_id;
|
|
13718
13704
|
const assignedFromProject = input.assigned_from_project || null;
|
|
13719
|
-
|
|
13720
|
-
|
|
13721
|
-
|
|
13722
|
-
|
|
13723
|
-
|
|
13724
|
-
|
|
13725
|
-
|
|
13726
|
-
|
|
13727
|
-
|
|
13728
|
-
|
|
13729
|
-
|
|
13730
|
-
|
|
13731
|
-
|
|
13732
|
-
|
|
13733
|
-
|
|
13734
|
-
|
|
13735
|
-
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13741
|
-
|
|
13742
|
-
|
|
13743
|
-
|
|
13744
|
-
|
|
13745
|
-
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13749
|
-
|
|
13750
|
-
|
|
13751
|
-
|
|
13752
|
-
|
|
13705
|
+
let id = uuid();
|
|
13706
|
+
for (let attempt = 0;attempt < 3; attempt++) {
|
|
13707
|
+
try {
|
|
13708
|
+
d.run(`INSERT INTO tasks (id, short_id, project_id, parent_id, plan_id, task_list_id, title, description, status, priority, agent_id, assigned_to, session_id, working_dir, tags, metadata, version, created_at, updated_at, due_at, estimated_minutes, requires_approval, approved_by, approved_at, recurrence_rule, recurrence_parent_id, spawns_template_id, reason, spawned_from_session, assigned_by, assigned_from_project, task_type)
|
|
13709
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
13710
|
+
id,
|
|
13711
|
+
null,
|
|
13712
|
+
input.project_id || null,
|
|
13713
|
+
input.parent_id || null,
|
|
13714
|
+
input.plan_id || null,
|
|
13715
|
+
input.task_list_id || null,
|
|
13716
|
+
input.title,
|
|
13717
|
+
input.description || null,
|
|
13718
|
+
input.status || "pending",
|
|
13719
|
+
input.priority || "medium",
|
|
13720
|
+
input.agent_id || null,
|
|
13721
|
+
input.assigned_to || null,
|
|
13722
|
+
input.session_id || null,
|
|
13723
|
+
input.working_dir || null,
|
|
13724
|
+
JSON.stringify(tags),
|
|
13725
|
+
JSON.stringify(input.metadata || {}),
|
|
13726
|
+
timestamp,
|
|
13727
|
+
timestamp,
|
|
13728
|
+
input.due_at || null,
|
|
13729
|
+
input.estimated_minutes || null,
|
|
13730
|
+
input.requires_approval ? 1 : 0,
|
|
13731
|
+
null,
|
|
13732
|
+
null,
|
|
13733
|
+
input.recurrence_rule || null,
|
|
13734
|
+
input.recurrence_parent_id || null,
|
|
13735
|
+
input.spawns_template_id || null,
|
|
13736
|
+
input.reason || null,
|
|
13737
|
+
input.spawned_from_session || null,
|
|
13738
|
+
assignedBy || null,
|
|
13739
|
+
assignedFromProject || null,
|
|
13740
|
+
input.task_type || null
|
|
13741
|
+
]);
|
|
13742
|
+
break;
|
|
13743
|
+
} catch (e) {
|
|
13744
|
+
if (attempt < 2 && e?.message?.includes("UNIQUE constraint failed: tasks.id")) {
|
|
13745
|
+
id = uuid();
|
|
13746
|
+
continue;
|
|
13747
|
+
}
|
|
13748
|
+
throw e;
|
|
13749
|
+
}
|
|
13750
|
+
}
|
|
13753
13751
|
if (tags.length > 0) {
|
|
13754
13752
|
insertTaskTags(id, tags, d);
|
|
13755
13753
|
}
|
|
@@ -14835,7 +14833,6 @@ function getOverdueTasks(projectId, db) {
|
|
|
14835
14833
|
var init_tasks = __esm(() => {
|
|
14836
14834
|
init_types2();
|
|
14837
14835
|
init_database();
|
|
14838
|
-
init_projects();
|
|
14839
14836
|
init_completion_guard();
|
|
14840
14837
|
init_audit();
|
|
14841
14838
|
init_recurrence();
|
|
@@ -17819,6 +17816,12 @@ var init_pg_migrations = __esm(() => {
|
|
|
17819
17816
|
CREATE INDEX IF NOT EXISTS idx_template_versions_template ON template_versions(template_id);
|
|
17820
17817
|
|
|
17821
17818
|
INSERT INTO _migrations (id) VALUES (39) ON CONFLICT DO NOTHING;
|
|
17819
|
+
`,
|
|
17820
|
+
`
|
|
17821
|
+
DROP INDEX IF EXISTS idx_tasks_short_id;
|
|
17822
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_short_id ON tasks(short_id, machine_id) WHERE short_id IS NOT NULL AND machine_id IS NOT NULL;
|
|
17823
|
+
CREATE INDEX IF NOT EXISTS idx_tasks_short_id_lookup ON tasks(short_id) WHERE short_id IS NOT NULL;
|
|
17824
|
+
INSERT INTO _migrations (id) VALUES (40) ON CONFLICT DO NOTHING;
|
|
17822
17825
|
`
|
|
17823
17826
|
];
|
|
17824
17827
|
});
|