ofiere-openclaw-plugin 4.18.0 → 4.18.2

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 +12 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofiere-openclaw-plugin",
3
- "version": "4.18.0",
3
+ "version": "4.18.2",
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
@@ -4101,7 +4101,7 @@ function registerPlanOps(
4101
4101
  constraints: { type: "array", items: { type: "object", properties: { label: { type: "string" }, type: { type: "string" } }, required: ["label"] } },
4102
4102
  system_prompt: { type: "string" },
4103
4103
  parallel: { type: "boolean" },
4104
- children: { type: "array", description: "Nested child nodes (recursive)" },
4104
+ children: { type: "array", description: "Nested child nodes (recursive)", items: { type: "object", properties: { title: { type: "string" }, type: { type: "string", enum: ["task", "gate", "milestone"] }, description: { type: "string" }, agent_id: { type: "string" }, priority: { type: "number" }, status: { type: "string" }, start_date: { type: "string" }, due_date: { type: "string" }, parallel: { type: "boolean" } }, required: ["title"] } },
4105
4105
  },
4106
4106
  required: ["title"],
4107
4107
  },
@@ -4131,7 +4131,7 @@ function generatePlanNodeId(): string {
4131
4131
  }
4132
4132
 
4133
4133
  function generatePlanId(): string {
4134
- return `plan-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
4134
+ return crypto.randomUUID();
4135
4135
  }
4136
4136
 
4137
4137
  /** Normalize agent-provided node into the PlanNode shape stored in plan_data */
@@ -4233,11 +4233,13 @@ async function handleListPlans(supabase: SupabaseClient, userId: string, params:
4233
4233
  async function handleGetPlan(supabase: SupabaseClient, userId: string, params: Record<string, unknown>): Promise<ToolResult> {
4234
4234
  try {
4235
4235
  if (!params.plan_id) return err("Missing required field: plan_id");
4236
- const { data, error } = await supabase.from("pm_plans").select("*").eq("id", params.plan_id as string).eq("user_id", userId).single();
4236
+ const { data, error } = await supabase.from("pm_plans").select("*").eq("id", params.plan_id as string).eq("user_id", userId);
4237
4237
  if (error) return err(error.message);
4238
+ if (!data || data.length === 0) return err("Plan not found");
4239
+ const plan = data[0];
4238
4240
  let parsed: any = null;
4239
- try { parsed = JSON.parse(data.plan_data || "{}"); } catch { parsed = {}; }
4240
- return ok({ plan: { ...data, plan_data: parsed } });
4241
+ try { parsed = JSON.parse(plan.plan_data || "{}"); } catch { parsed = {}; }
4242
+ return ok({ plan: { ...plan, plan_data: parsed } });
4241
4243
  } catch (e) { return err(e instanceof Error ? e.message : String(e)); }
4242
4244
  }
4243
4245
 
@@ -4268,8 +4270,9 @@ async function handleUpdatePlan(supabase: SupabaseClient, userId: string, params
4268
4270
  const rootNodes = Array.isArray(params.nodes) ? (params.nodes as any[]).map(normalizeNode) : [];
4269
4271
  updates.plan_data = buildPlanJson(params.plan_id as string, (params.name as string) || "Plan", params.description as string | undefined, rootNodes);
4270
4272
  }
4271
- const { error } = await supabase.from("pm_plans").update(updates).eq("id", params.plan_id as string).eq("user_id", userId);
4273
+ const { data, error } = await supabase.from("pm_plans").update(updates).eq("id", params.plan_id as string).eq("user_id", userId).select("id");
4272
4274
  if (error) return err(error.message);
4275
+ if (!data || data.length === 0) return err("Plan not found");
4273
4276
  return ok({ message: `Plan updated` });
4274
4277
  } catch (e) { return err(e instanceof Error ? e.message : String(e)); }
4275
4278
  }
@@ -4277,8 +4280,9 @@ async function handleUpdatePlan(supabase: SupabaseClient, userId: string, params
4277
4280
  async function handleDeletePlan(supabase: SupabaseClient, userId: string, params: Record<string, unknown>): Promise<ToolResult> {
4278
4281
  try {
4279
4282
  if (!params.plan_id) return err("Missing required field: plan_id");
4280
- const { error } = await supabase.from("pm_plans").delete().eq("id", params.plan_id as string).eq("user_id", userId);
4283
+ const { data, error } = await supabase.from("pm_plans").delete().eq("id", params.plan_id as string).eq("user_id", userId).select("id");
4281
4284
  if (error) return err(error.message);
4285
+ if (!data || data.length === 0) return err("Plan not found — nothing deleted");
4282
4286
  return ok({ message: `Plan deleted`, deleted: true });
4283
4287
  } catch (e) { return err(e instanceof Error ? e.message : String(e)); }
4284
4288
  }
@@ -4332,7 +4336,7 @@ async function handleExecutePlan(
4332
4336
  // Step 1: Create project folder
4333
4337
  if (createFolder && spaceId) {
4334
4338
  const folderRow = {
4335
- id: `folder-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
4339
+ id: crypto.randomUUID(),
4336
4340
  user_id: userId, space_id: spaceId, name: plan.name || "Untitled Plan",
4337
4341
  type: "project", parent_folder_id: folderId, sort_order: 0,
4338
4342
  created_at: new Date().toISOString(), updated_at: new Date().toISOString(),