ofiere-openclaw-plugin 4.18.3 → 4.18.4
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/package.json +1 -1
- package/src/tools.ts +48 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ofiere-openclaw-plugin",
|
|
3
|
-
"version": "4.18.
|
|
3
|
+
"version": "4.18.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw plugin for Ofiere PM - 12 meta-tools covering tasks, agents, projects, scheduling, knowledge, workflows, notifications, memory, prompts, constellation, space file management, and execution plan builder",
|
|
6
6
|
"keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
|
package/src/tools.ts
CHANGED
|
@@ -4347,15 +4347,20 @@ async function handleExecutePlan(
|
|
|
4347
4347
|
|
|
4348
4348
|
// Step 1: Create project folder
|
|
4349
4349
|
let folderSkipped = false;
|
|
4350
|
+
let folderError: string | null = null;
|
|
4350
4351
|
if (createFolder && spaceId) {
|
|
4351
4352
|
const folderRow = {
|
|
4352
4353
|
id: crypto.randomUUID(),
|
|
4353
4354
|
user_id: userId, space_id: spaceId, name: data.name || plan.name || "Untitled Plan",
|
|
4354
|
-
|
|
4355
|
+
folder_type: "project", parent_folder_id: folderId, sort_order: 0,
|
|
4355
4356
|
created_at: new Date().toISOString(), updated_at: new Date().toISOString(),
|
|
4356
4357
|
};
|
|
4357
4358
|
const { error: folderErr } = await supabase.from("pm_folders").insert(folderRow);
|
|
4358
|
-
if (!folderErr)
|
|
4359
|
+
if (!folderErr) {
|
|
4360
|
+
folderId = folderRow.id;
|
|
4361
|
+
} else {
|
|
4362
|
+
folderError = folderErr.message;
|
|
4363
|
+
}
|
|
4359
4364
|
} else if (createFolder && !spaceId) {
|
|
4360
4365
|
folderSkipped = true;
|
|
4361
4366
|
}
|
|
@@ -4428,39 +4433,67 @@ async function handleExecutePlan(
|
|
|
4428
4433
|
}
|
|
4429
4434
|
}
|
|
4430
4435
|
|
|
4431
|
-
// Step 3: Create dependencies
|
|
4436
|
+
// Step 3: Create dependencies — sibling chaining + parent→child
|
|
4432
4437
|
const depsQueue = [...rootNodes];
|
|
4433
4438
|
let depsCreated = 0;
|
|
4439
|
+
|
|
4440
|
+
// Helper: resolve a node to its nearest task ID (skip gates/milestones)
|
|
4441
|
+
function resolveTaskId(n: any): string | undefined {
|
|
4442
|
+
return idMap.get(n.id);
|
|
4443
|
+
}
|
|
4444
|
+
|
|
4434
4445
|
while (depsQueue.length > 0) {
|
|
4435
4446
|
const node = depsQueue.shift()!;
|
|
4436
|
-
const nodeRealId =
|
|
4447
|
+
const nodeRealId = resolveTaskId(node);
|
|
4448
|
+
|
|
4449
|
+
// Chain siblings: sequential children of this node get chained left-to-right
|
|
4450
|
+
if (Array.isArray(node.children) && node.children.length > 1 && !node.parallel) {
|
|
4451
|
+
// Collect task-type children in order for chaining
|
|
4452
|
+
const taskChildren: string[] = [];
|
|
4453
|
+
for (const child of node.children) {
|
|
4454
|
+
const cid = resolveTaskId(child);
|
|
4455
|
+
if (cid) taskChildren.push(cid);
|
|
4456
|
+
}
|
|
4457
|
+
for (let i = 1; i < taskChildren.length; i++) {
|
|
4458
|
+
await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: taskChildren[i - 1], successor_id: taskChildren[i], dependency_type: "finish_to_start", lag_days: 0 });
|
|
4459
|
+
depsCreated++;
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
|
|
4463
|
+
// Parent → first child link (sequential only)
|
|
4437
4464
|
if (nodeRealId && !node.parallel && node.children?.length > 0) {
|
|
4438
|
-
const firstChildId =
|
|
4465
|
+
const firstChildId = resolveTaskId(node.children[0]);
|
|
4439
4466
|
if (firstChildId) {
|
|
4440
4467
|
await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: nodeRealId, successor_id: firstChildId, dependency_type: "finish_to_start", lag_days: 0 });
|
|
4441
4468
|
depsCreated++;
|
|
4442
4469
|
}
|
|
4443
|
-
for (let i = 1; i < node.children.length; i++) {
|
|
4444
|
-
const prevId = idMap.get(node.children[i - 1].id);
|
|
4445
|
-
const currId = idMap.get(node.children[i].id);
|
|
4446
|
-
if (prevId && currId) {
|
|
4447
|
-
await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: prevId, successor_id: currId, dependency_type: "finish_to_start", lag_days: 0 });
|
|
4448
|
-
depsCreated++;
|
|
4449
|
-
}
|
|
4450
|
-
}
|
|
4451
4470
|
}
|
|
4471
|
+
|
|
4472
|
+
// Parallel fan-out: parent → each child
|
|
4452
4473
|
if (nodeRealId && node.parallel && node.children?.length > 0) {
|
|
4453
4474
|
for (const child of node.children) {
|
|
4454
|
-
const childId =
|
|
4475
|
+
const childId = resolveTaskId(child);
|
|
4455
4476
|
if (childId) {
|
|
4456
4477
|
await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: nodeRealId, successor_id: childId, dependency_type: "finish_to_start", lag_days: 0 });
|
|
4457
4478
|
depsCreated++;
|
|
4458
4479
|
}
|
|
4459
4480
|
}
|
|
4460
4481
|
}
|
|
4482
|
+
|
|
4461
4483
|
if (Array.isArray(node.children)) depsQueue.push(...node.children);
|
|
4462
4484
|
}
|
|
4463
4485
|
|
|
4486
|
+
// Chain root-level siblings (sequential root nodes)
|
|
4487
|
+
const rootTaskIds: string[] = [];
|
|
4488
|
+
for (const rn of rootNodes) {
|
|
4489
|
+
const rid = resolveTaskId(rn);
|
|
4490
|
+
if (rid) rootTaskIds.push(rid);
|
|
4491
|
+
}
|
|
4492
|
+
for (let i = 1; i < rootTaskIds.length; i++) {
|
|
4493
|
+
await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: rootTaskIds[i - 1], successor_id: rootTaskIds[i], dependency_type: "finish_to_start", lag_days: 0 });
|
|
4494
|
+
depsCreated++;
|
|
4495
|
+
}
|
|
4496
|
+
|
|
4464
4497
|
// Mark plan as deployed
|
|
4465
4498
|
await supabase.from("pm_plans").update({ is_deployed: true, deployed_at: new Date().toISOString(), updated_at: new Date().toISOString() }).eq("id", params.plan_id as string).eq("user_id", userId);
|
|
4466
4499
|
|
|
@@ -4471,6 +4504,7 @@ async function handleExecutePlan(
|
|
|
4471
4504
|
folder_id: folderId,
|
|
4472
4505
|
space_id: spaceId,
|
|
4473
4506
|
...(folderSkipped ? { folder_skipped_reason: "No space_id provided — assign the plan to a space to enable folder creation" } : {}),
|
|
4507
|
+
...(folderError ? { folder_error: folderError } : {}),
|
|
4474
4508
|
});
|
|
4475
4509
|
} catch (e) { return err(e instanceof Error ? e.message : String(e)); }
|
|
4476
4510
|
}
|