ofiere-openclaw-plugin 4.18.3 → 4.18.5

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tools.ts +57 -18
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofiere-openclaw-plugin",
3
- "version": "4.18.3",
3
+ "version": "4.18.5",
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
- type: "project", parent_folder_id: folderId, sort_order: 0,
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) folderId = folderRow.id;
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,72 @@ async function handleExecutePlan(
4428
4433
  }
4429
4434
  }
4430
4435
 
4431
- // Step 3: Create dependencies (sequential chain)
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
+
4445
+ // Helper: insert a dependency row into pm_dependencies
4446
+ async function insertDep(predId: string, succId: string): Promise<boolean> {
4447
+ const { error } = await supabase.from("pm_dependencies").insert({
4448
+ id: `dep-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
4449
+ user_id: userId, predecessor_id: predId, successor_id: succId,
4450
+ dependency_type: "finish_to_start", lag_days: 0,
4451
+ });
4452
+ return !error;
4453
+ }
4454
+
4434
4455
  while (depsQueue.length > 0) {
4435
4456
  const node = depsQueue.shift()!;
4436
- const nodeRealId = idMap.get(node.id);
4457
+ const nodeRealId = resolveTaskId(node);
4458
+
4459
+ // Chain siblings: sequential children of this node get chained left-to-right
4460
+ if (Array.isArray(node.children) && node.children.length > 1 && !node.parallel) {
4461
+ const taskChildren: string[] = [];
4462
+ for (const child of node.children) {
4463
+ const cid = resolveTaskId(child);
4464
+ if (cid) taskChildren.push(cid);
4465
+ }
4466
+ for (let i = 1; i < taskChildren.length; i++) {
4467
+ if (await insertDep(taskChildren[i - 1], taskChildren[i])) depsCreated++;
4468
+ }
4469
+ }
4470
+
4471
+ // Parent → first child link (sequential only)
4437
4472
  if (nodeRealId && !node.parallel && node.children?.length > 0) {
4438
- const firstChildId = idMap.get(node.children[0].id);
4473
+ const firstChildId = resolveTaskId(node.children[0]);
4439
4474
  if (firstChildId) {
4440
- await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: nodeRealId, successor_id: firstChildId, dependency_type: "finish_to_start", lag_days: 0 });
4441
- depsCreated++;
4442
- }
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
- }
4475
+ if (await insertDep(nodeRealId, firstChildId)) depsCreated++;
4450
4476
  }
4451
4477
  }
4478
+
4479
+ // Parallel fan-out: parent → each child
4452
4480
  if (nodeRealId && node.parallel && node.children?.length > 0) {
4453
4481
  for (const child of node.children) {
4454
- const childId = idMap.get(child.id);
4482
+ const childId = resolveTaskId(child);
4455
4483
  if (childId) {
4456
- await supabase.from("task_dependencies").insert({ user_id: userId, predecessor_id: nodeRealId, successor_id: childId, dependency_type: "finish_to_start", lag_days: 0 });
4457
- depsCreated++;
4484
+ if (await insertDep(nodeRealId, childId)) depsCreated++;
4458
4485
  }
4459
4486
  }
4460
4487
  }
4488
+
4461
4489
  if (Array.isArray(node.children)) depsQueue.push(...node.children);
4462
4490
  }
4463
4491
 
4492
+ // Chain root-level siblings (sequential root nodes)
4493
+ const rootTaskIds: string[] = [];
4494
+ for (const rn of rootNodes) {
4495
+ const rid = resolveTaskId(rn);
4496
+ if (rid) rootTaskIds.push(rid);
4497
+ }
4498
+ for (let i = 1; i < rootTaskIds.length; i++) {
4499
+ if (await insertDep(rootTaskIds[i - 1], rootTaskIds[i])) depsCreated++;
4500
+ }
4501
+
4464
4502
  // Mark plan as deployed
4465
4503
  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
4504
 
@@ -4471,6 +4509,7 @@ async function handleExecutePlan(
4471
4509
  folder_id: folderId,
4472
4510
  space_id: spaceId,
4473
4511
  ...(folderSkipped ? { folder_skipped_reason: "No space_id provided — assign the plan to a space to enable folder creation" } : {}),
4512
+ ...(folderError ? { folder_error: folderError } : {}),
4474
4513
  });
4475
4514
  } catch (e) { return err(e instanceof Error ? e.message : String(e)); }
4476
4515
  }