@creezio/tasks 0.22.0
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/README.md +279 -0
- package/dist/.creezio-src-hash.json +4 -0
- package/dist/ai-task-agent.d.ts +47 -0
- package/dist/ai-task-agent.d.ts.map +1 -0
- package/dist/ai-task-agent.js +558 -0
- package/dist/ai-task-agent.js.map +1 -0
- package/dist/ai-task-runner.d.ts +78 -0
- package/dist/ai-task-runner.d.ts.map +1 -0
- package/dist/ai-task-runner.js +645 -0
- package/dist/ai-task-runner.js.map +1 -0
- package/dist/api-mount.d.ts +4 -0
- package/dist/api-mount.d.ts.map +1 -0
- package/dist/api-mount.js +91 -0
- package/dist/api-mount.js.map +1 -0
- package/dist/assistant-adapter.d.ts +7 -0
- package/dist/assistant-adapter.d.ts.map +1 -0
- package/dist/assistant-adapter.js +96 -0
- package/dist/assistant-adapter.js.map +1 -0
- package/dist/brand/config.d.ts +165 -0
- package/dist/brand/config.d.ts.map +1 -0
- package/dist/brand/config.js +39 -0
- package/dist/brand/config.js.map +1 -0
- package/dist/env-bridge.d.ts +12 -0
- package/dist/env-bridge.d.ts.map +1 -0
- package/dist/env-bridge.js +33 -0
- package/dist/env-bridge.js.map +1 -0
- package/dist/hono-routes.d.ts +8 -0
- package/dist/hono-routes.d.ts.map +1 -0
- package/dist/hono-routes.js +563 -0
- package/dist/hono-routes.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/kanban-service.d.ts +136 -0
- package/dist/kanban-service.d.ts.map +1 -0
- package/dist/kanban-service.js +580 -0
- package/dist/kanban-service.js.map +1 -0
- package/dist/mcp-host-tools.d.ts +59 -0
- package/dist/mcp-host-tools.d.ts.map +1 -0
- package/dist/mcp-host-tools.js +326 -0
- package/dist/mcp-host-tools.js.map +1 -0
- package/dist/mcp-workspace-tools.d.ts +15 -0
- package/dist/mcp-workspace-tools.d.ts.map +1 -0
- package/dist/mcp-workspace-tools.js +338 -0
- package/dist/mcp-workspace-tools.js.map +1 -0
- package/dist/memory-store.d.ts +3 -0
- package/dist/memory-store.d.ts.map +1 -0
- package/dist/memory-store.js +75 -0
- package/dist/memory-store.js.map +1 -0
- package/dist/sqlite-driver.d.ts +13 -0
- package/dist/sqlite-driver.d.ts.map +1 -0
- package/dist/sqlite-driver.js +13 -0
- package/dist/sqlite-driver.js.map +1 -0
- package/dist/sqlite-store.d.ts +15 -0
- package/dist/sqlite-store.d.ts.map +1 -0
- package/dist/sqlite-store.js +113 -0
- package/dist/sqlite-store.js.map +1 -0
- package/dist/task-runs.d.ts +108 -0
- package/dist/task-runs.d.ts.map +1 -0
- package/dist/task-runs.js +427 -0
- package/dist/task-runs.js.map +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/dist-cjs/ai-task-agent.js +569 -0
- package/dist-cjs/ai-task-agent.js.map +1 -0
- package/dist-cjs/ai-task-runner.js +660 -0
- package/dist-cjs/ai-task-runner.js.map +1 -0
- package/dist-cjs/api-mount.js +94 -0
- package/dist-cjs/api-mount.js.map +1 -0
- package/dist-cjs/assistant-adapter.js +99 -0
- package/dist-cjs/assistant-adapter.js.map +1 -0
- package/dist-cjs/brand/config.js +47 -0
- package/dist-cjs/brand/config.js.map +1 -0
- package/dist-cjs/env-bridge.js +36 -0
- package/dist-cjs/env-bridge.js.map +1 -0
- package/dist-cjs/hono-routes.js +566 -0
- package/dist-cjs/hono-routes.js.map +1 -0
- package/dist-cjs/index.js +117 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/kanban-service.js +601 -0
- package/dist-cjs/kanban-service.js.map +1 -0
- package/dist-cjs/mcp-host-tools.js +333 -0
- package/dist-cjs/mcp-host-tools.js.map +1 -0
- package/dist-cjs/mcp-workspace-tools.js +342 -0
- package/dist-cjs/mcp-workspace-tools.js.map +1 -0
- package/dist-cjs/memory-store.js +81 -0
- package/dist-cjs/memory-store.js.map +1 -0
- package/dist-cjs/package.json +3 -0
- package/dist-cjs/sqlite-driver.js +16 -0
- package/dist-cjs/sqlite-driver.js.map +1 -0
- package/dist-cjs/sqlite-store.js +119 -0
- package/dist-cjs/sqlite-store.js.map +1 -0
- package/dist-cjs/task-runs.js +457 -0
- package/dist-cjs/task-runs.js.map +1 -0
- package/dist-cjs/types.js +18 -0
- package/dist-cjs/types.js.map +1 -0
- package/package.json +79 -0
- package/scripts/port-from-tempoflow.mjs +405 -0
- package/ui/ai-activity-panel.tsx +559 -0
- package/ui/index.ts +7 -0
- package/ui/task-detail-sheet.tsx +668 -0
- package/ui/tasks-kanban-client.tsx +647 -0
- package/ui/tasks-types.ts +120 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kanban unifié « Tâches » (schéma tasks plateforme) — une tâche a un exécutant :
|
|
3
|
+
* - `human` : collaborateur humain (kanban simple)
|
|
4
|
+
* - `ai` : collaborateur IA (runs `task_runs` + workspace Electron dédié)
|
|
5
|
+
* - `hermes` : agent central Hermes (carte kanban WebUI, sync bidirectionnelle)
|
|
6
|
+
*
|
|
7
|
+
* Remplace `cabinet-tasks.ts` et `todo-queries.ts`.
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from "node:crypto";
|
|
10
|
+
import { hermesCronCreate, hermesKanbanConfigured, hermesKanbanCreateTask, hermesKanbanDispatch, hermesKanbanGetTask, hermesKanbanListTasks, hermesKanbanPatchTask, } from "@creezio/assistant";
|
|
11
|
+
import { requireTasksBrand } from "./brand/config.js";
|
|
12
|
+
import { upsertKitPlatformTask } from "./env-bridge.js";
|
|
13
|
+
function getWriteDb() {
|
|
14
|
+
return requireTasksBrand().db.getWriteDb();
|
|
15
|
+
}
|
|
16
|
+
function queryAll(sql, params = []) {
|
|
17
|
+
return requireTasksBrand().db.queryAll(sql, params);
|
|
18
|
+
}
|
|
19
|
+
function queryOne(sql, params = []) {
|
|
20
|
+
return requireTasksBrand().db.queryOne(sql, params);
|
|
21
|
+
}
|
|
22
|
+
function tableExists(name) {
|
|
23
|
+
return requireTasksBrand().db.tableExists(name);
|
|
24
|
+
}
|
|
25
|
+
function getUserById(id) {
|
|
26
|
+
return requireTasksBrand().users.getById(id);
|
|
27
|
+
}
|
|
28
|
+
export const TASK_STATUSES = [
|
|
29
|
+
"backlog",
|
|
30
|
+
"in_progress",
|
|
31
|
+
"blocked",
|
|
32
|
+
"done",
|
|
33
|
+
"cancelled",
|
|
34
|
+
];
|
|
35
|
+
export const EXECUTOR_KINDS = ["human", "ai", "hermes"];
|
|
36
|
+
export const KANBAN_COLUMNS = [
|
|
37
|
+
{ id: "backlog", label: "Backlog" },
|
|
38
|
+
{ id: "in_progress", label: "En cours" },
|
|
39
|
+
{ id: "blocked", label: "Bloqué" },
|
|
40
|
+
{ id: "done", label: "Terminé" },
|
|
41
|
+
];
|
|
42
|
+
/** Statut Hermes (9 états) → statut kanban unifié (5 états). */
|
|
43
|
+
export function hermesToTaskStatus(status) {
|
|
44
|
+
switch (status) {
|
|
45
|
+
case "ready":
|
|
46
|
+
case "running":
|
|
47
|
+
return "in_progress";
|
|
48
|
+
case "blocked":
|
|
49
|
+
case "review":
|
|
50
|
+
return "blocked";
|
|
51
|
+
case "done":
|
|
52
|
+
return "done";
|
|
53
|
+
case "archived":
|
|
54
|
+
return "cancelled";
|
|
55
|
+
default:
|
|
56
|
+
// triage / todo / scheduled / inconnu
|
|
57
|
+
return "backlog";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Statut kanban unifié → statut Hermes (pour pousser un drag & drop). */
|
|
61
|
+
export function taskToHermesStatus(status) {
|
|
62
|
+
switch (status) {
|
|
63
|
+
case "backlog":
|
|
64
|
+
return "todo";
|
|
65
|
+
case "in_progress":
|
|
66
|
+
return "ready";
|
|
67
|
+
case "blocked":
|
|
68
|
+
return "blocked";
|
|
69
|
+
case "done":
|
|
70
|
+
return "done";
|
|
71
|
+
case "cancelled":
|
|
72
|
+
return "archived";
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const enrich = (r) => ({
|
|
76
|
+
...r,
|
|
77
|
+
assignee: r.assignee_user_id ? getUserById(r.assignee_user_id) : null,
|
|
78
|
+
});
|
|
79
|
+
export const tasksReady = () => tableExists("tasks");
|
|
80
|
+
function nowIso() {
|
|
81
|
+
return new Date().toISOString();
|
|
82
|
+
}
|
|
83
|
+
function nextPosition(status) {
|
|
84
|
+
return ((queryOne("SELECT MAX(position) m FROM tasks WHERE status=?", [status])?.m || 0) + 1);
|
|
85
|
+
}
|
|
86
|
+
export function listTasks(opts) {
|
|
87
|
+
if (!tasksReady())
|
|
88
|
+
return [];
|
|
89
|
+
const where = [];
|
|
90
|
+
const args = [];
|
|
91
|
+
if (opts?.status) {
|
|
92
|
+
where.push("status=?");
|
|
93
|
+
args.push(opts.status);
|
|
94
|
+
}
|
|
95
|
+
else if (!opts?.includeCancelled) {
|
|
96
|
+
where.push("status != 'cancelled'");
|
|
97
|
+
}
|
|
98
|
+
if (opts?.assigneeUserId) {
|
|
99
|
+
where.push("assignee_user_id=?");
|
|
100
|
+
args.push(opts.assigneeUserId);
|
|
101
|
+
}
|
|
102
|
+
if (opts?.executor) {
|
|
103
|
+
where.push("executor_kind=?");
|
|
104
|
+
args.push(opts.executor);
|
|
105
|
+
}
|
|
106
|
+
if (opts?.parentTaskId) {
|
|
107
|
+
where.push("parent_task_id=?");
|
|
108
|
+
args.push(opts.parentTaskId);
|
|
109
|
+
}
|
|
110
|
+
const sql = `SELECT * FROM tasks ${where.length ? `WHERE ${where.join(" AND ")}` : ""}
|
|
111
|
+
ORDER BY status, position, updated_at DESC`;
|
|
112
|
+
return queryAll(sql, args).map(enrich);
|
|
113
|
+
}
|
|
114
|
+
export const tasksByColumn = (tasks) => ({
|
|
115
|
+
backlog: tasks.filter((t) => t.status === "backlog"),
|
|
116
|
+
in_progress: tasks.filter((t) => t.status === "in_progress"),
|
|
117
|
+
blocked: tasks.filter((t) => t.status === "blocked"),
|
|
118
|
+
done: tasks.filter((t) => t.status === "done"),
|
|
119
|
+
});
|
|
120
|
+
export const getTask = (id) => {
|
|
121
|
+
const r = tasksReady()
|
|
122
|
+
? queryOne("SELECT * FROM tasks WHERE id=?", [id])
|
|
123
|
+
: null;
|
|
124
|
+
return r ? enrich(r) : null;
|
|
125
|
+
};
|
|
126
|
+
export const getTaskByHermesId = (hermesId) => {
|
|
127
|
+
const r = tasksReady()
|
|
128
|
+
? queryOne("SELECT * FROM tasks WHERE hermes_task_id=?", [hermesId])
|
|
129
|
+
: null;
|
|
130
|
+
return r ? enrich(r) : null;
|
|
131
|
+
};
|
|
132
|
+
export const getTaskByIdempotency = (key) => {
|
|
133
|
+
const r = tasksReady()
|
|
134
|
+
? queryOne("SELECT * FROM tasks WHERE idempotency_key=?", [key])
|
|
135
|
+
: null;
|
|
136
|
+
return r ? enrich(r) : null;
|
|
137
|
+
};
|
|
138
|
+
export const listSubtasks = (parentTaskId) => listTasks({ parentTaskId, includeCancelled: true });
|
|
139
|
+
/** Invariants exécutant / assigné (levés en Error → 400 côté API). */
|
|
140
|
+
function assertExecutorInvariants(executor, assigneeUserId) {
|
|
141
|
+
if (executor === "hermes") {
|
|
142
|
+
if (assigneeUserId) {
|
|
143
|
+
throw new Error("Une tâche Hermes n'a pas d'assigné (exécutant central)");
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (!assigneeUserId) {
|
|
148
|
+
if (executor === "ai") {
|
|
149
|
+
throw new Error("Une tâche IA doit être assignée à un collaborateur IA");
|
|
150
|
+
}
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const user = getUserById(assigneeUserId);
|
|
154
|
+
if (!user)
|
|
155
|
+
throw new Error("Assigné introuvable");
|
|
156
|
+
if (executor === "ai" && user.kind !== "ai") {
|
|
157
|
+
throw new Error("L'assigné d'une tâche IA doit être un collaborateur IA");
|
|
158
|
+
}
|
|
159
|
+
if (executor === "human" && user.kind !== "human") {
|
|
160
|
+
throw new Error("L'assigné d'une tâche humaine doit être un humain");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function insertLocal(row) {
|
|
164
|
+
// C1 — SoT kit d’abord (même UUID), puis extension brand kanban/AI
|
|
165
|
+
upsertKitPlatformTask({
|
|
166
|
+
id: row.id,
|
|
167
|
+
userId: row.assignee_user_id || row.created_by || "system",
|
|
168
|
+
title: row.title,
|
|
169
|
+
body: row.body || "",
|
|
170
|
+
status: row.status === "done" || row.status === "cancelled"
|
|
171
|
+
? row.status
|
|
172
|
+
: "open",
|
|
173
|
+
});
|
|
174
|
+
getWriteDb()
|
|
175
|
+
.prepare(`INSERT INTO tasks (
|
|
176
|
+
id, title, body, status, position, executor_kind, assignee_user_id,
|
|
177
|
+
parent_task_id, created_by, priority, hermes_task_id, hermes_cron_id,
|
|
178
|
+
hermes_status, recurring_schedule, source, conversation_id,
|
|
179
|
+
idempotency_key, result, last_synced_at, created_at, updated_at
|
|
180
|
+
) VALUES (
|
|
181
|
+
@id, @title, @body, @status, @position, @executor_kind, @assignee_user_id,
|
|
182
|
+
@parent_task_id, @created_by, @priority, @hermes_task_id, @hermes_cron_id,
|
|
183
|
+
@hermes_status, @recurring_schedule, @source, @conversation_id,
|
|
184
|
+
@idempotency_key, @result, @last_synced_at, @created_at, @updated_at
|
|
185
|
+
)`)
|
|
186
|
+
.run(row);
|
|
187
|
+
}
|
|
188
|
+
function updateLocal(id, patch) {
|
|
189
|
+
const old = getTask(id);
|
|
190
|
+
if (!old)
|
|
191
|
+
return null;
|
|
192
|
+
// Les clés `undefined` du patch ne doivent pas écraser les valeurs.
|
|
193
|
+
const defined = Object.fromEntries(Object.entries(patch).filter(([, v]) => v !== undefined));
|
|
194
|
+
const next = { ...old, ...defined, updated_at: nowIso() };
|
|
195
|
+
// Changement de colonne → fin de colonne cible.
|
|
196
|
+
if (patch.status && patch.status !== old.status && patch.position == null) {
|
|
197
|
+
next.position = nextPosition(patch.status);
|
|
198
|
+
}
|
|
199
|
+
upsertKitPlatformTask({
|
|
200
|
+
id: next.id,
|
|
201
|
+
userId: next.assignee_user_id || next.created_by || "system",
|
|
202
|
+
title: next.title,
|
|
203
|
+
body: next.body || "",
|
|
204
|
+
status: next.status === "done" || next.status === "cancelled"
|
|
205
|
+
? next.status
|
|
206
|
+
: "open",
|
|
207
|
+
});
|
|
208
|
+
getWriteDb()
|
|
209
|
+
.prepare(`UPDATE tasks SET
|
|
210
|
+
title=@title, body=@body, status=@status, position=@position,
|
|
211
|
+
executor_kind=@executor_kind, assignee_user_id=@assignee_user_id,
|
|
212
|
+
priority=@priority, hermes_task_id=@hermes_task_id,
|
|
213
|
+
hermes_cron_id=@hermes_cron_id, hermes_status=@hermes_status,
|
|
214
|
+
recurring_schedule=@recurring_schedule, result=@result,
|
|
215
|
+
last_synced_at=@last_synced_at, updated_at=@updated_at
|
|
216
|
+
WHERE id=@id`)
|
|
217
|
+
.run(next);
|
|
218
|
+
return getTask(id);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Pousse une tâche executor=hermes vers le kanban Hermes WebUI.
|
|
222
|
+
* Retourne la carte, ou une erreur (tâche laissée `blocked` par l'appelant).
|
|
223
|
+
*/
|
|
224
|
+
async function pushTaskToHermes(task, opts) {
|
|
225
|
+
if (!hermesKanbanConfigured()) {
|
|
226
|
+
return { error: "Hermes non configuré (gateway/WebUI hors ligne)" };
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
const hermes = await hermesKanbanCreateTask({
|
|
230
|
+
title: task.title,
|
|
231
|
+
body: [
|
|
232
|
+
task.body,
|
|
233
|
+
"",
|
|
234
|
+
"—",
|
|
235
|
+
`Source: ${requireTasksBrand().hermesSourceLabel}`,
|
|
236
|
+
task.conversation_id ? `Conversation: ${task.conversation_id}` : null,
|
|
237
|
+
`CRM task: ${task.id}`,
|
|
238
|
+
task.recurring_schedule ? `Récurrence: ${task.recurring_schedule}` : null,
|
|
239
|
+
]
|
|
240
|
+
.filter(Boolean)
|
|
241
|
+
.join("\n"),
|
|
242
|
+
status: "ready",
|
|
243
|
+
priority: task.priority,
|
|
244
|
+
idempotencyKey: task.idempotency_key || `${requireTasksBrand().idempotencyPrefix}:${task.id}`,
|
|
245
|
+
});
|
|
246
|
+
let cronId = null;
|
|
247
|
+
let error;
|
|
248
|
+
if (task.recurring_schedule?.trim()) {
|
|
249
|
+
try {
|
|
250
|
+
const cron = await hermesCronCreate({
|
|
251
|
+
schedule: task.recurring_schedule.trim(),
|
|
252
|
+
name: task.title.slice(0, 80),
|
|
253
|
+
prompt: [
|
|
254
|
+
`Tâche récurrente ${requireTasksBrand().hermesSourceLabel} « ${task.title} ».`,
|
|
255
|
+
task.body || "Exécute la mission et mets à jour le kanban.",
|
|
256
|
+
`Charge le skill ${requireTasksBrand().hermesSkill}.`,
|
|
257
|
+
`CRM task id: ${task.id}`,
|
|
258
|
+
].join("\n"),
|
|
259
|
+
});
|
|
260
|
+
cronId = cron.id || null;
|
|
261
|
+
}
|
|
262
|
+
catch (e) {
|
|
263
|
+
error = `cron: ${e instanceof Error ? e.message : String(e)}`;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (opts?.dispatch !== false && hermes.status === "ready") {
|
|
267
|
+
try {
|
|
268
|
+
await hermesKanbanDispatch();
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
/* dispatch best-effort */
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return { hermes, cronId, error };
|
|
275
|
+
}
|
|
276
|
+
catch (e) {
|
|
277
|
+
return { error: e instanceof Error ? e.message : String(e) };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Crée une tâche. Pour executor=hermes : pousse la carte Hermes ; si Hermes
|
|
282
|
+
* est indisponible la tâche reste `blocked` et sera re-poussée à la synchro.
|
|
283
|
+
*/
|
|
284
|
+
export async function createTask(input) {
|
|
285
|
+
if (!tasksReady())
|
|
286
|
+
throw new Error("Table tasks absente (schéma tasks plateforme requis)");
|
|
287
|
+
const title = input.title.trim();
|
|
288
|
+
if (!title)
|
|
289
|
+
throw new Error("title requis");
|
|
290
|
+
const executor = input.executorKind || "human";
|
|
291
|
+
assertExecutorInvariants(executor, input.assigneeUserId);
|
|
292
|
+
if (input.parentTaskId && !getTask(input.parentTaskId)) {
|
|
293
|
+
throw new Error("Tâche parente introuvable");
|
|
294
|
+
}
|
|
295
|
+
if (input.idempotencyKey) {
|
|
296
|
+
const existing = getTaskByIdempotency(input.idempotencyKey);
|
|
297
|
+
if (existing)
|
|
298
|
+
return { task: existing };
|
|
299
|
+
}
|
|
300
|
+
const ts = nowIso();
|
|
301
|
+
const id = randomUUID();
|
|
302
|
+
const status = input.status || "backlog";
|
|
303
|
+
const row = {
|
|
304
|
+
id,
|
|
305
|
+
title,
|
|
306
|
+
body: (input.body || "").trim(),
|
|
307
|
+
status,
|
|
308
|
+
position: nextPosition(status),
|
|
309
|
+
executor_kind: executor,
|
|
310
|
+
assignee_user_id: input.assigneeUserId || null,
|
|
311
|
+
parent_task_id: input.parentTaskId || null,
|
|
312
|
+
created_by: input.createdBy || null,
|
|
313
|
+
priority: input.priority || 0,
|
|
314
|
+
hermes_task_id: null,
|
|
315
|
+
hermes_cron_id: null,
|
|
316
|
+
hermes_status: null,
|
|
317
|
+
recurring_schedule: input.recurringSchedule?.trim() || null,
|
|
318
|
+
source: input.source || "ui",
|
|
319
|
+
conversation_id: input.conversationId || null,
|
|
320
|
+
idempotency_key: input.idempotencyKey?.trim() || `${requireTasksBrand().idempotencyPrefix}:${id}`,
|
|
321
|
+
result: null,
|
|
322
|
+
last_synced_at: null,
|
|
323
|
+
created_at: ts,
|
|
324
|
+
updated_at: ts,
|
|
325
|
+
};
|
|
326
|
+
insertLocal(row);
|
|
327
|
+
if (executor !== "hermes") {
|
|
328
|
+
return { task: getTask(id) };
|
|
329
|
+
}
|
|
330
|
+
const pushed = await pushTaskToHermes(getTask(id), {
|
|
331
|
+
dispatch: input.dispatch,
|
|
332
|
+
});
|
|
333
|
+
if (pushed.hermes) {
|
|
334
|
+
updateLocal(id, {
|
|
335
|
+
hermes_task_id: pushed.hermes.id,
|
|
336
|
+
hermes_cron_id: pushed.cronId ?? null,
|
|
337
|
+
hermes_status: String(pushed.hermes.status || "ready"),
|
|
338
|
+
status: hermesToTaskStatus(String(pushed.hermes.status || "ready")),
|
|
339
|
+
last_synced_at: nowIso(),
|
|
340
|
+
});
|
|
341
|
+
return { task: getTask(id), hermes: pushed.hermes, warning: pushed.error };
|
|
342
|
+
}
|
|
343
|
+
// Hermes indisponible : la tâche attend, re-push à la prochaine synchro.
|
|
344
|
+
updateLocal(id, {
|
|
345
|
+
status: "blocked",
|
|
346
|
+
result: `En attente d'Hermes — ${pushed.error || "indisponible"}`,
|
|
347
|
+
});
|
|
348
|
+
return { task: getTask(id), warning: pushed.error };
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Met à jour une tâche ; si elle est liée à une carte Hermes, propage le
|
|
352
|
+
* changement (statut traduit) avant l'écriture locale.
|
|
353
|
+
*/
|
|
354
|
+
export async function updateTask(id, patch) {
|
|
355
|
+
const old = getTask(id);
|
|
356
|
+
if (!old)
|
|
357
|
+
throw new Error("Tâche introuvable");
|
|
358
|
+
if (patch.assigneeUserId !== undefined && old.executor_kind !== "hermes") {
|
|
359
|
+
assertExecutorInvariants(old.executor_kind, patch.assigneeUserId);
|
|
360
|
+
}
|
|
361
|
+
if (patch.assigneeUserId && old.executor_kind === "hermes") {
|
|
362
|
+
throw new Error("Une tâche Hermes n'a pas d'assigné");
|
|
363
|
+
}
|
|
364
|
+
let hermesStatus;
|
|
365
|
+
if (old.hermes_task_id && hermesKanbanConfigured()) {
|
|
366
|
+
try {
|
|
367
|
+
const ht = await hermesKanbanPatchTask(old.hermes_task_id, {
|
|
368
|
+
title: patch.title,
|
|
369
|
+
body: patch.body,
|
|
370
|
+
status: patch.status ? taskToHermesStatus(patch.status) : undefined,
|
|
371
|
+
priority: patch.priority,
|
|
372
|
+
result: patch.result,
|
|
373
|
+
});
|
|
374
|
+
hermesStatus = String(ht.status || "");
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
/* Hermes injoignable — mise à jour locale quand même, resync plus tard */
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return updateLocal(id, {
|
|
381
|
+
title: patch.title,
|
|
382
|
+
body: patch.body,
|
|
383
|
+
status: patch.status,
|
|
384
|
+
assignee_user_id: patch.assigneeUserId === undefined ? old.assignee_user_id : patch.assigneeUserId,
|
|
385
|
+
priority: patch.priority,
|
|
386
|
+
result: patch.result,
|
|
387
|
+
...(hermesStatus ? { hermes_status: hermesStatus, last_synced_at: nowIso() } : {}),
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
/** Mise à jour locale directe (runner / interne — pas de propagation Hermes). */
|
|
391
|
+
export function updateTaskLocal(id, patch) {
|
|
392
|
+
return updateLocal(id, patch);
|
|
393
|
+
}
|
|
394
|
+
/** Colonne next_run_at présente (migration 031 — récurrence IA). */
|
|
395
|
+
export function tasksRecurrenceReady() {
|
|
396
|
+
if (!tasksReady())
|
|
397
|
+
return false;
|
|
398
|
+
try {
|
|
399
|
+
const cols = queryAll(`PRAGMA table_info(tasks)`);
|
|
400
|
+
return cols.some((c) => c.name === "next_run_at");
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/** Tâches IA récurrentes actives (pilotées par le tick du runner). */
|
|
407
|
+
export function listRecurringAiTasks() {
|
|
408
|
+
if (!tasksRecurrenceReady())
|
|
409
|
+
return [];
|
|
410
|
+
return queryAll(`SELECT * FROM tasks
|
|
411
|
+
WHERE executor_kind = 'ai'
|
|
412
|
+
AND recurring_schedule IS NOT NULL AND recurring_schedule != ''
|
|
413
|
+
AND status != 'cancelled'
|
|
414
|
+
ORDER BY created_at ASC`).map(enrich);
|
|
415
|
+
}
|
|
416
|
+
export function setTaskNextRun(id, nextRunAt) {
|
|
417
|
+
if (!tasksRecurrenceReady())
|
|
418
|
+
return;
|
|
419
|
+
getWriteDb()
|
|
420
|
+
.prepare(`UPDATE tasks SET next_run_at = ?, updated_at = ? WHERE id = ?`)
|
|
421
|
+
.run(nextRunAt, nowIso(), id);
|
|
422
|
+
}
|
|
423
|
+
export async function deleteTask(id) {
|
|
424
|
+
const task = getTask(id);
|
|
425
|
+
if (!task)
|
|
426
|
+
return false;
|
|
427
|
+
if (task.hermes_task_id && hermesKanbanConfigured()) {
|
|
428
|
+
try {
|
|
429
|
+
await hermesKanbanPatchTask(task.hermes_task_id, { status: "archived" });
|
|
430
|
+
}
|
|
431
|
+
catch {
|
|
432
|
+
/* best-effort */
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return getWriteDb().prepare("DELETE FROM tasks WHERE id=?").run(id).changes > 0;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Synchronisation Hermes ↔ tasks :
|
|
439
|
+
* 1. tire le board WebUI → met à jour les tâches liées (statut mappé, résultat) ;
|
|
440
|
+
* 2. importe les cartes inconnues (source `hermes`) ;
|
|
441
|
+
* 3. re-pousse les tâches executor=hermes jamais liées (création hors ligne).
|
|
442
|
+
*/
|
|
443
|
+
export async function syncHermesTasks() {
|
|
444
|
+
const errors = [];
|
|
445
|
+
if (!tasksReady()) {
|
|
446
|
+
return { updated: 0, created: 0, pushed: 0, errors: ["table tasks absente"] };
|
|
447
|
+
}
|
|
448
|
+
if (!hermesKanbanConfigured()) {
|
|
449
|
+
return { updated: 0, created: 0, pushed: 0, errors: ["Hermes non configuré"] };
|
|
450
|
+
}
|
|
451
|
+
let remote = [];
|
|
452
|
+
try {
|
|
453
|
+
remote = await hermesKanbanListTasks();
|
|
454
|
+
}
|
|
455
|
+
catch (e) {
|
|
456
|
+
return {
|
|
457
|
+
updated: 0,
|
|
458
|
+
created: 0,
|
|
459
|
+
pushed: 0,
|
|
460
|
+
errors: [e instanceof Error ? e.message : String(e)],
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
let updated = 0;
|
|
464
|
+
let created = 0;
|
|
465
|
+
let pushed = 0;
|
|
466
|
+
const ts = nowIso();
|
|
467
|
+
for (const ht of remote) {
|
|
468
|
+
try {
|
|
469
|
+
const local = getTaskByHermesId(ht.id);
|
|
470
|
+
if (local) {
|
|
471
|
+
const mapped = hermesToTaskStatus(String(ht.status));
|
|
472
|
+
const changed = local.hermes_status !== String(ht.status) ||
|
|
473
|
+
local.title !== ht.title ||
|
|
474
|
+
(ht.result && local.result !== ht.result);
|
|
475
|
+
updateLocal(local.id, {
|
|
476
|
+
title: ht.title,
|
|
477
|
+
body: ht.body || local.body,
|
|
478
|
+
status: mapped,
|
|
479
|
+
hermes_status: String(ht.status),
|
|
480
|
+
priority: ht.priority ?? local.priority,
|
|
481
|
+
result: ht.result ?? local.result,
|
|
482
|
+
last_synced_at: ts,
|
|
483
|
+
});
|
|
484
|
+
if (changed)
|
|
485
|
+
updated += 1;
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
const id = randomUUID();
|
|
489
|
+
insertLocal({
|
|
490
|
+
id,
|
|
491
|
+
title: ht.title,
|
|
492
|
+
body: ht.body || "",
|
|
493
|
+
status: hermesToTaskStatus(String(ht.status)),
|
|
494
|
+
position: nextPosition(hermesToTaskStatus(String(ht.status))),
|
|
495
|
+
executor_kind: "hermes",
|
|
496
|
+
assignee_user_id: null,
|
|
497
|
+
parent_task_id: null,
|
|
498
|
+
created_by: null,
|
|
499
|
+
priority: ht.priority ?? 0,
|
|
500
|
+
hermes_task_id: ht.id,
|
|
501
|
+
hermes_cron_id: null,
|
|
502
|
+
hermes_status: String(ht.status),
|
|
503
|
+
recurring_schedule: null,
|
|
504
|
+
source: "hermes",
|
|
505
|
+
conversation_id: null,
|
|
506
|
+
idempotency_key: ht.idempotency_key || `hermes:${ht.id}`,
|
|
507
|
+
result: ht.result || null,
|
|
508
|
+
last_synced_at: ts,
|
|
509
|
+
created_at: ts,
|
|
510
|
+
updated_at: ts,
|
|
511
|
+
});
|
|
512
|
+
created += 1;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
catch (e) {
|
|
516
|
+
errors.push(e instanceof Error ? e.message : String(e));
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// Re-push des tâches Hermes créées hors ligne (jamais liées).
|
|
520
|
+
const pending = queryAll(`SELECT * FROM tasks
|
|
521
|
+
WHERE executor_kind='hermes' AND hermes_task_id IS NULL
|
|
522
|
+
AND status NOT IN ('done','cancelled')`);
|
|
523
|
+
for (const row of pending) {
|
|
524
|
+
try {
|
|
525
|
+
const result = await pushTaskToHermes(enrich(row));
|
|
526
|
+
if (result.hermes) {
|
|
527
|
+
updateLocal(row.id, {
|
|
528
|
+
hermes_task_id: result.hermes.id,
|
|
529
|
+
hermes_cron_id: result.cronId ?? null,
|
|
530
|
+
hermes_status: String(result.hermes.status || "ready"),
|
|
531
|
+
status: hermesToTaskStatus(String(result.hermes.status || "ready")),
|
|
532
|
+
result: null,
|
|
533
|
+
last_synced_at: ts,
|
|
534
|
+
});
|
|
535
|
+
pushed += 1;
|
|
536
|
+
}
|
|
537
|
+
else if (result.error) {
|
|
538
|
+
errors.push(result.error);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
catch (e) {
|
|
542
|
+
errors.push(e instanceof Error ? e.message : String(e));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return { updated, created, pushed, errors };
|
|
546
|
+
}
|
|
547
|
+
/** Détail tâche + rafraîchissement Hermes si liée. */
|
|
548
|
+
export async function getTaskDetail(id) {
|
|
549
|
+
const task = getTask(id);
|
|
550
|
+
if (!task)
|
|
551
|
+
return null;
|
|
552
|
+
if (task.hermes_task_id && hermesKanbanConfigured()) {
|
|
553
|
+
try {
|
|
554
|
+
const hermes = await hermesKanbanGetTask(task.hermes_task_id);
|
|
555
|
+
const ht = hermes.task;
|
|
556
|
+
if (String(ht.status) !== task.hermes_status ||
|
|
557
|
+
(ht.result && ht.result !== task.result) ||
|
|
558
|
+
ht.title !== task.title) {
|
|
559
|
+
updateLocal(task.id, {
|
|
560
|
+
title: ht.title,
|
|
561
|
+
body: ht.body || task.body,
|
|
562
|
+
status: hermesToTaskStatus(String(ht.status)),
|
|
563
|
+
hermes_status: String(ht.status),
|
|
564
|
+
result: ht.result ?? task.result,
|
|
565
|
+
last_synced_at: nowIso(),
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
return { task: getTask(id), hermes, hermesError: null };
|
|
569
|
+
}
|
|
570
|
+
catch (e) {
|
|
571
|
+
return {
|
|
572
|
+
task,
|
|
573
|
+
hermes: null,
|
|
574
|
+
hermesError: e instanceof Error ? e.message : String(e),
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return { task, hermes: null, hermesError: null };
|
|
579
|
+
}
|
|
580
|
+
//# sourceMappingURL=kanban-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kanban-service.js","sourceRoot":"","sources":["../src/kanban-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* D-P18 — tools MCP host-only pour workflows tâches IA.
|
|
3
|
+
* Partagé TF/CV (ex-jumeaux hono-host-tools). Métier marque reste hors kit.
|
|
4
|
+
*
|
|
5
|
+
* Prérequis : `configureTasksBrand()` déjà appelé (users + runtime kanban).
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
export declare const CREEZIO_AI_TASK_HOST_MCP_TOOL_NAMES: readonly ["list_ai_collaborators", "create_ai_task", "get_ai_task", "get_ai_run_logs", "answer_ai_question"];
|
|
9
|
+
export type CreezioAiTaskHostMcpToolName = (typeof CREEZIO_AI_TASK_HOST_MCP_TOOL_NAMES)[number];
|
|
10
|
+
/** Optionnel (Certivan) — liste kanban générique. */
|
|
11
|
+
export declare const CREEZIO_LIST_TASKS_MCP_TOOL_NAME: "list_tasks";
|
|
12
|
+
export type AiTaskHostMcpToolConfig = {
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: Record<string, z.ZodType>;
|
|
16
|
+
};
|
|
17
|
+
export type AiTaskHostMcpRegisterFn = (name: string, config: AiTaskHostMcpToolConfig, handler: (input: any) => Promise<unknown> | unknown) => void;
|
|
18
|
+
/**
|
|
19
|
+
* JSON Schema d'un `inputSchema` de tool host (zod v4 `toJSONSchema`).
|
|
20
|
+
* Exposé ici pour que les intégrateurs (façade MCP kit, marques) n'aient pas
|
|
21
|
+
* besoin d'importer la même instance zod que @creezio/tasks.
|
|
22
|
+
*/
|
|
23
|
+
export declare function aiTaskToolJsonSchema(shape: Record<string, z.ZodType>): Record<string, unknown>;
|
|
24
|
+
export type AiTaskToolParseResult = {
|
|
25
|
+
ok: true;
|
|
26
|
+
input: Record<string, unknown>;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
error: string;
|
|
30
|
+
};
|
|
31
|
+
/** Valide/normalise des arguments contre un `inputSchema` de tool host. */
|
|
32
|
+
export declare function parseAiTaskToolInput(shape: Record<string, z.ZodType>, args: Record<string, unknown>): AiTaskToolParseResult;
|
|
33
|
+
export type CreateAiTaskHostMcpToolsOptions = {
|
|
34
|
+
/** Enregistrement marque (`registerMcpTool` ou `server.registerTool`). */
|
|
35
|
+
registerTool: AiTaskHostMcpRegisterFn;
|
|
36
|
+
/** `userId` du token MCP (Bearer / API key). */
|
|
37
|
+
getActorUserId: () => string | null | undefined;
|
|
38
|
+
/** Certivan : expose aussi `list_tasks`. Défaut false. */
|
|
39
|
+
includeListTasks?: boolean;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Gate acteur des tools host « qui agissent » : l'acteur doit être l'owner.
|
|
43
|
+
*
|
|
44
|
+
* Décision H1 (« Hermes cerveau unique ») : la clé CRM service Hermes
|
|
45
|
+
* (provisionnée par `ensure-crm-key-db`, `user_id NULL` + scopes `full`) est
|
|
46
|
+
* MAPPÉE SUR L'OWNER par le résolveur Bearer de la façade MCP
|
|
47
|
+
* (`createApiKeyBearerActorResolver`, @creezio/app-runtime) — même niveau de
|
|
48
|
+
* confiance que l'API REST CRM complète qu'elle ouvre déjà (parité TF2 gold).
|
|
49
|
+
* Pas de scope `tasks:run` dédié : `normalizeScopes` côté auth ne conserve
|
|
50
|
+
* que `full`/`crm:*`, et une clé restreinte (`crm:read`/`crm:write`) n'est
|
|
51
|
+
* PAS mappée owner → refusée ici (fail-closed).
|
|
52
|
+
*/
|
|
53
|
+
export declare function actorIsOwner(actorId: string | null | undefined): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Enregistre les tools MCP host tâches IA (SoT kit).
|
|
56
|
+
* Retourne la liste des noms enregistrés.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createAiTaskHostMcpTools(options: CreateAiTaskHostMcpToolsOptions): readonly string[];
|
|
59
|
+
//# sourceMappingURL=mcp-host-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-host-tools.d.ts","sourceRoot":"","sources":["../src/mcp-host-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwBxB,eAAO,MAAM,mCAAmC,8GAMtC,CAAC;AAEX,MAAM,MAAM,4BAA4B,GACtC,CAAC,OAAO,mCAAmC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,qDAAqD;AACrD,eAAO,MAAM,gCAAgC,EAAG,YAAqB,CAAC;AAEtE,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,uBAAuB,EAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,KAChD,IAAI,CAAC;AAEV;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC5C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,qBAAqB,CAYvB;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC5C,0EAA0E;IAC1E,YAAY,EAAE,uBAAuB,CAAC;IACtC,gDAAgD;IAChD,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAsBF;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAQxE;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,+BAA+B,GACvC,SAAS,MAAM,EAAE,CAiRnB"}
|