ofiere-openclaw-plugin 4.36.0 → 4.37.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tools.ts +41 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ofiere-openclaw-plugin",
3
- "version": "4.36.0",
3
+ "version": "4.37.0",
4
4
  "type": "module",
5
5
  "description": "OpenClaw plugin for Ofiere PM - 16 meta-tools covering tasks, agents, projects, scheduling, knowledge, workflows, notifications, memory, prompts, constellation, space file management, execution plan builder, SOP management, agent brain, talent management, and corporate frameworks",
6
6
  "keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
package/src/tools.ts CHANGED
@@ -5213,30 +5213,20 @@ function registerFrameworkOps(
5213
5213
  description:
5214
5214
  `Create and manage Corporate Frameworks — strategic mandates, KPIs, risk governance, and operational boundaries.\n\n` +
5215
5215
  `Actions:\n` +
5216
- `- "create": Create a new framework. Required: agent_id, title, framework_data. Optional: department, category, status\n` +
5216
+ `- "create": Create a new framework. Required: agent_id, title. Provide framework body via 'content' (JSON string). Optional: department, category, status\n` +
5217
5217
  `- "list": List frameworks. Optional: agent_id to filter\n` +
5218
5218
  `- "get": Get full framework details. Required: framework_id\n` +
5219
- `- "update": Modify framework. Required: framework_id. Optional: title, framework_data, status, department, category\n` +
5219
+ `- "update": Modify framework. Required: framework_id. Optional: title, content, status, department, category\n` +
5220
5220
  `- "delete": Remove framework. Required: framework_id\n\n` +
5221
- `framework_data structure (JSON object):\n` +
5222
- `{\n` +
5223
- ` title: string,\n` +
5224
- ` mission: string (strategic mission),\n` +
5225
- ` vision: string,\n` +
5226
- ` core_principles: [string],\n` +
5227
- ` decision_authority: string,\n` +
5228
- ` budget_constraints: string,\n` +
5229
- ` resource_limits: string,\n` +
5230
- ` tool_stack: [string],\n` +
5231
- ` strategic_objectives: [{ objective, target, measurement, frequency }],\n` +
5232
- ` risk_appetite: "conservative"|"moderate"|"aggressive",\n` +
5233
- ` compliance_requirements: [string],\n` +
5234
- ` escalation_matrix: [{ trigger, escalate_to, priority: "P0"|"P1"|"P2"|"P3", response_sla }],\n` +
5235
- ` team_composition: string,\n` +
5236
- ` integration_points: [string],\n` +
5237
- ` review_frequency: string,\n` +
5238
- ` notes: string\n` +
5239
- `}\n\n` +
5221
+ `content: A JSON string containing the full framework body. Example:\n` +
5222
+ `"{\\"mission\\":\\"Drive brand growth\\",\\"vision\\":\\"Market leader by 2027\\",\\"core_principles\\":[\\"Data-driven\\",\\"Customer-first\\"],` +
5223
+ `\\"decision_authority\\":\\"CMO approves >$10k spend\\",\\"budget_constraints\\":\\"$50k monthly cap\\",` +
5224
+ `\\"strategic_objectives\\":[{\\"objective\\":\\"Grow MRR\\",\\"target\\":\\"$100k\\",\\"measurement\\":\\"Revenue dashboard\\"}],` +
5225
+ `\\"risk_appetite\\":\\"moderate\\",\\"escalation_matrix\\":[{\\"trigger\\":\\"Budget >80%\\",\\"escalate_to\\":\\"CEO\\",\\"priority\\":\\"P1\\"}],` +
5226
+ `\\"notes\\":\\"Quarterly review\\"}"\n\n` +
5227
+ `Supported content fields: mission, vision, core_principles, decision_authority, budget_constraints, ` +
5228
+ `resource_limits, tool_stack, strategic_objectives, risk_appetite, compliance_requirements, ` +
5229
+ `escalation_matrix, team_composition, integration_points, review_frequency, notes — or any custom fields.\n\n` +
5240
5230
  `Status values: "draft", "active", "under_review", "archived"`,
5241
5231
  parameters: {
5242
5232
  type: "object",
@@ -5246,10 +5236,10 @@ function registerFrameworkOps(
5246
5236
  framework_id: { type: "string", description: "Framework ID (required for get, update, delete)" },
5247
5237
  agent_id: { type: "string", description: "Agent ID (required for create, optional filter for list)" },
5248
5238
  title: { type: "string", description: "Framework title" },
5239
+ content: { type: "string", description: "Framework body as a JSON string containing mission, vision, core_principles, decision_authority, budget_constraints, strategic_objectives, risk_appetite, escalation_matrix, and any other fields. Pass as stringified JSON." },
5249
5240
  department: { type: "string" },
5250
5241
  category: { type: "string" },
5251
5242
  status: { type: "string", enum: ["draft", "active", "under_review", "archived"] },
5252
- framework_data: { type: "object", description: "Structured framework content — pass a complete FrameworkData JSON object" },
5253
5243
  },
5254
5244
  },
5255
5245
  async execute(_id: string, params: Record<string, unknown>) {
@@ -5279,8 +5269,23 @@ async function handleFWCreate(
5279
5269
  const title = params.title as string;
5280
5270
  if (!title) return err("Missing required field: title");
5281
5271
 
5282
- const fwDataRaw = params.framework_data as Record<string, unknown> | undefined;
5283
- const content = fwDataRaw ? JSON.stringify({ title, ...fwDataRaw }) : JSON.stringify({ title });
5272
+ // Accept content via: (1) 'content' string param (preferred, matches SOP pattern)
5273
+ // (2) 'framework_data' object param (legacy, kept for compat)
5274
+ let content: string;
5275
+ if (typeof params.content === "string" && params.content.trim()) {
5276
+ // Already a JSON string — merge with title
5277
+ try {
5278
+ const parsed = JSON.parse(params.content);
5279
+ content = JSON.stringify({ title, ...parsed });
5280
+ } catch {
5281
+ // Not valid JSON — wrap as notes
5282
+ content = JSON.stringify({ title, notes: params.content });
5283
+ }
5284
+ } else if (params.framework_data && typeof params.framework_data === "object") {
5285
+ content = JSON.stringify({ title, ...(params.framework_data as Record<string, unknown>) });
5286
+ } else {
5287
+ content = JSON.stringify({ title });
5288
+ }
5284
5289
 
5285
5290
  const row = {
5286
5291
  user_id: userId, agent_id: agentIdRaw, title, content,
@@ -5332,10 +5337,21 @@ async function handleFWUpdate(supabase: SupabaseClient, userId: string, params:
5332
5337
  if (params.status !== undefined) updates.status = params.status;
5333
5338
  if (params.department !== undefined) updates.department = params.department;
5334
5339
  if (params.category !== undefined) updates.category = params.category;
5335
- if (params.framework_data) {
5340
+
5341
+ // Accept content via: (1) 'content' string param (preferred)
5342
+ // (2) 'framework_data' object param (legacy compat)
5343
+ if (typeof params.content === "string" && params.content.trim()) {
5344
+ try {
5345
+ const parsed = JSON.parse(params.content);
5346
+ updates.content = JSON.stringify({ title: parsed.title || (params.title as string) || "", ...parsed });
5347
+ } catch {
5348
+ updates.content = JSON.stringify({ title: (params.title as string) || "", notes: params.content });
5349
+ }
5350
+ } else if (params.framework_data && typeof params.framework_data === "object") {
5336
5351
  const raw = params.framework_data as Record<string, unknown>;
5337
5352
  updates.content = JSON.stringify({ title: (raw.title as string) || (params.title as string) || "", ...raw });
5338
5353
  }
5354
+
5339
5355
  const { data, error } = await supabase.from("frameworks").update(updates)
5340
5356
  .eq("id", params.framework_id as string).eq("user_id", userId)
5341
5357
  .select("id, title, status").maybeSingle();