ofiere-openclaw-plugin 4.55.0 → 4.56.1

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.
@@ -31,92 +31,92 @@ const TOOL_SUMMARIES = {
31
31
  // These are used as tool descriptions in registerTools(), NOT in the system prompt.
32
32
  // The LLM sees them only when exploring available tools or preparing a tool call.
33
33
  export const TOOL_DOCS = {
34
- OFIERE_TASK_OPS: `Manage tasks and approvals.
35
- Actions: "list", "create", "update", "delete", "add_approval", "list_approvals", "resolve_approval"
36
- - list: Filter by status, agent_id, space_id, folder_id, limit. Returns execution_plan, goals, constraints if present
37
- - create: Requires title. IMPORTANT: Always pass agent_id with your own name to self-assign (e.g. agent_id: "celia")
38
- - Optional: description, instructions, execution_plan, goals, constraints, system_prompt, priority, tags, dates
39
- - For COMPLEX tasks: include execution_plan (step-by-step), goals, constraints, and system_prompt
40
- - For SIMPLE tasks: just title and optionally description
41
- - update: Requires task_id. All create fields + progress
42
- - delete: Requires task_id. Removes task and subtasks
43
- - add_approval: Request sign-off. Requires: task_id, approver_name. Optional: approver_type (human|agent), due_date, comment
44
- - list_approvals: List approvals. Optional: task_id, approval_status (pending|approved|rejected)
34
+ OFIERE_TASK_OPS: `Manage tasks and approvals.
35
+ Actions: "list", "create", "update", "delete", "add_approval", "list_approvals", "resolve_approval"
36
+ - list: Filter by status, agent_id, space_id, folder_id, limit. Returns execution_plan, goals, constraints if present
37
+ - create: Requires title. IMPORTANT: Always pass agent_id with your own name to self-assign (e.g. agent_id: "celia")
38
+ - Optional: description, instructions, execution_plan, goals, constraints, system_prompt, priority, tags, dates
39
+ - For COMPLEX tasks: include execution_plan (step-by-step), goals, constraints, and system_prompt
40
+ - For SIMPLE tasks: just title and optionally description
41
+ - update: Requires task_id. All create fields + progress
42
+ - delete: Requires task_id. Removes task and subtasks
43
+ - add_approval: Request sign-off. Requires: task_id, approver_name. Optional: approver_type (human|agent), due_date, comment
44
+ - list_approvals: List approvals. Optional: task_id, approval_status (pending|approved|rejected)
45
45
  - resolve_approval: Approve/reject. Requires: approval_id, approval_status. Optional: comment`,
46
- OFIERE_AGENT_OPS: `Query + manage agents and their staff subagents.
47
- Actions: "list", "list_subagents", "create_subagent", "delete_subagent", "invalidate_tier_cache"
48
- - list: All top-level agents (chiefs / native + OpenClaw) with IDs, names, roles. Use for task assignment lookup.
49
- - list_subagents: Staff under a chief. Required: chief_agent_id.
50
- - create_subagent: Add a staff subagent under a chief (max 5 per chief). Required: chief_agent_id, name. Optional: role (default "Staff"), codename, color_hex.
51
- - delete_subagent: Remove a staff subagent. Required: subagent_id.
46
+ OFIERE_AGENT_OPS: `Query + manage agents and their staff subagents.
47
+ Actions: "list", "list_subagents", "create_subagent", "delete_subagent", "invalidate_tier_cache"
48
+ - list: All top-level agents (chiefs / native + OpenClaw) with IDs, names, roles. Use for task assignment lookup.
49
+ - list_subagents: Staff under a chief. Required: chief_agent_id.
50
+ - create_subagent: Add a staff subagent under a chief (max 5 per chief). Required: chief_agent_id, name. Optional: role (default "Staff"), codename, color_hex.
51
+ - delete_subagent: Remove a staff subagent. Required: subagent_id.
52
52
  - invalidate_tier_cache: Flush plugin's in-process tier cache (5 min TTL). Optional: agent_id. Use after direct-DB mutation of agent_tier_overrides.`,
53
- OFIERE_PROJECT_OPS: `Manage PM hierarchy.
54
- Actions: "list_spaces", "create_space", "update_space", "delete_space", "list_folders", "create_folder", "update_folder", "delete_folder", "list_dependencies", "add_dependency", "remove_dependency"
55
- - Spaces: Top-level containers. CRUD with name, icon, icon_color
56
- - Folders: Inside spaces. Nest via parent_folder_id. Types: folder, project
53
+ OFIERE_PROJECT_OPS: `Manage PM hierarchy.
54
+ Actions: "list_spaces", "create_space", "update_space", "delete_space", "list_folders", "create_folder", "update_folder", "delete_folder", "list_dependencies", "add_dependency", "remove_dependency"
55
+ - Spaces: Top-level containers. CRUD with name, icon, icon_color
56
+ - Folders: Inside spaces. Nest via parent_folder_id. Types: folder, project
57
57
  - Dependencies: Link tasks. Types: finish_to_start (default), start_to_start, finish_to_finish, start_to_finish. lag_days optional`,
58
- OFIERE_SCHEDULE_OPS: `Calendar events.
59
- Actions: "list", "create", "update", "delete"
60
- - list: Filter by start_date, end_date, agent_id
61
- - create: Requires title + scheduled_date (YYYY-MM-DD). Optional: scheduled_time, duration_minutes, task_id, agent_id, recurrence_type, color
58
+ OFIERE_SCHEDULE_OPS: `Calendar events.
59
+ Actions: "list", "create", "update", "delete"
60
+ - list: Filter by start_date, end_date, agent_id
61
+ - create: Requires title + scheduled_date (YYYY-MM-DD). Optional: scheduled_time, duration_minutes, task_id, agent_id, recurrence_type, color
62
62
  - Recurrence: none, hourly, daily, weekly, monthly with interval`,
63
- OFIERE_KNOWLEDGE_OPS: `Ofiere Knowledge Library.
64
- Actions: "search", "list", "create", "update", "delete"
65
- - ALWAYS use when user mentions "knowledge base", "knowledge library", or asks to recall stored knowledge
66
- - search: Keyword search. Requires: query
67
- - list: Paginated listing with full content. Optional: search filter
68
- - create: Requires: file_name. Optional: content, source, author, credibility_tier
63
+ OFIERE_KNOWLEDGE_OPS: `Ofiere Knowledge Library.
64
+ Actions: "search", "list", "create", "update", "delete"
65
+ - ALWAYS use when user mentions "knowledge base", "knowledge library", or asks to recall stored knowledge
66
+ - search: Keyword search. Requires: query
67
+ - list: Paginated listing with full content. Optional: search filter
68
+ - create: Requires: file_name. Optional: content, source, author, credibility_tier
69
69
  - update/delete: By document ID`,
70
- OFIERE_WORKFLOW_OPS: `Full workflow automation (13 actions).
71
- Actions: "list", "get", "create", "update", "delete", "list_runs", "trigger", "add_nodes", "update_node", "delete_nodes", "add_edges", "delete_edges", "insert_node_between"
72
- - ALWAYS call "get" before modifying to see node IDs and graph structure
73
- - Node types: manual_trigger, webhook_trigger, agent_step, formatter_step, http_request, task_call, variable_set, condition, human_approval, delay, loop, convergence, output, checkpoint, note
74
- - Edge handles: condition edges use "condition-true"/"condition-false". Loop edges use "loop_body"/"done"
70
+ OFIERE_WORKFLOW_OPS: `Full workflow automation (13 actions).
71
+ Actions: "list", "get", "create", "update", "delete", "list_runs", "trigger", "add_nodes", "update_node", "delete_nodes", "add_edges", "delete_edges", "insert_node_between"
72
+ - ALWAYS call "get" before modifying to see node IDs and graph structure
73
+ - Node types: manual_trigger, webhook_trigger, agent_step, formatter_step, http_request, task_call, variable_set, condition, human_approval, delay, loop, convergence, output, checkpoint, note
74
+ - Edge handles: condition edges use "condition-true"/"condition-false". Loop edges use "loop_body"/"done"
75
75
  - Variables: {{prev.nodeId.outputText}}, {{variables.key}}`,
76
- OFIERE_NOTIFY_OPS: `Notifications & Channel Reports.
77
- Actions: "list", "mark_read", "mark_all_read", "delete", "send_report", "get_task_detail", "schedule_report", "list_schedules", "delete_schedule"
78
- - send_report: Send PM progress report to YOUR channels. Required: scope_type, agent_id (YOUR name)
79
- - get_task_detail: Get full task result by report number. Required: task_number
76
+ OFIERE_NOTIFY_OPS: `Notifications & Channel Reports.
77
+ Actions: "list", "mark_read", "mark_all_read", "delete", "send_report", "get_task_detail", "schedule_report", "list_schedules", "delete_schedule"
78
+ - send_report: Send PM progress report to YOUR channels. Required: scope_type, agent_id (YOUR name)
79
+ - get_task_detail: Get full task result by report number. Required: task_number
80
80
  - schedule_report: Recurring reports. Required: scope_type, recurrence_type, agent_id`,
81
- OFIERE_MEMORY_OPS: `Conversation history & knowledge memory.
81
+ OFIERE_MEMORY_OPS: `Conversation history & knowledge memory.
82
82
  Actions: "list_conversations", "get_messages", "search_messages", "add_knowledge", "search_knowledge"`,
83
- OFIERE_PROMPT_OPS: `Manage prompt instruction chunks.
84
- Actions: "list", "get", "create", "update", "delete"
83
+ OFIERE_PROMPT_OPS: `Manage prompt instruction chunks.
84
+ Actions: "list", "get", "create", "update", "delete"
85
85
  - create: New chunk with name (max 30 chars) + content. Optional: color (hex), category`,
86
- OFIERE_CONSTELLATION_OPS: `Create/edit/delete OpenClaw agents from chat.
87
- Actions: "list_agents", "get_agent", "read_file", "write_file", "create_agent", "delete_agent", "delete_file", "read_blueprint", "list_agent_mesh"
88
- - CRITICAL: ALWAYS call read_blueprint before creating/editing agents
86
+ OFIERE_CONSTELLATION_OPS: `Create/edit/delete OpenClaw agents from chat.
87
+ Actions: "list_agents", "get_agent", "read_file", "write_file", "create_agent", "delete_agent", "delete_file", "read_blueprint", "list_agent_mesh"
88
+ - CRITICAL: ALWAYS call read_blueprint before creating/editing agents
89
89
  - delete_agent: IRREVERSIBLE. Always ask user for explicit confirmation first`,
90
- OFIERE_FILE_OPS: `Manage Space Files.
91
- Actions: "list_files", "list_folders", "create_folder", "create_text_file", "upload_file", "read_text_file", "rename_file", "rename_folder", "move_file", "move_folder", "delete_file", "delete_folder", "share_file", "unshare_file"
92
- - read_text_file: Use when task references @[name](file:ID)
90
+ OFIERE_FILE_OPS: `Manage Space Files.
91
+ Actions: "list_files", "list_folders", "create_folder", "create_text_file", "upload_file", "read_text_file", "rename_file", "rename_folder", "move_file", "move_folder", "delete_file", "delete_folder", "share_file", "unshare_file"
92
+ - read_text_file: Use when task references @[name](file:ID)
93
93
  - Files appear in PM Space Files tab immediately`,
94
- OFIERE_PLAN_OPS: `Visual execution plan builder.
95
- Actions: "list", "get", "create", "update", "delete", "add_nodes", "execute"
96
- - Plans are visual DAG drafts — not real tasks until "execute"
97
- - Node types: task, gate, milestone
94
+ OFIERE_PLAN_OPS: `Visual execution plan builder.
95
+ Actions: "list", "get", "create", "update", "delete", "add_nodes", "execute"
96
+ - Plans are visual DAG drafts — not real tasks until "execute"
97
+ - Node types: task, gate, milestone
98
98
  - Execution maps ALL fields: execution_steps, goals, constraints, system_prompt`,
99
- OFIERE_SOP_OPS: `Standard Operating Procedures.
100
- Actions: "list_templates", "create", "list", "get", "update", "delete", "list_subagents", "apply_template", "propose_attach", "commit_attach"
101
- - sop_data: { title, purpose, scope, applicability, prerequisites:{ conditions, required_tools, required_permissions, safety_warnings }, procedure_steps[], expected_outputs[], escalation_rules[], acceptance_criteria[], rollback_procedure, notes }
102
- - Legacy field names still accepted (objective→purpose, steps→procedure_steps, deliverables→expected_outputs, escalationRules→escalation_rules, successCriteria→acceptance_criteria) — prefer new names.
103
- - propose_attach / commit_attach: attach SOPs to a run (target_kind: conversation|task|scheduler_event). Tier rule: SOPs only attach to STAFF-tier targets; for c-suite use OFIERE_FRAMEWORK_OPS instead. propose_attach returns a token-cost summary + confirmation_token (5-min ttl). You MUST surface the cost and ask the user before calling commit_attach. The user must explicitly approve.
99
+ OFIERE_SOP_OPS: `Standard Operating Procedures.
100
+ Actions: "list_templates", "create", "list", "get", "update", "delete", "list_subagents", "apply_template", "propose_attach", "commit_attach"
101
+ - sop_data: { title, purpose, scope, applicability, prerequisites:{ conditions, required_tools, required_permissions, safety_warnings }, procedure_steps[], expected_outputs[], escalation_rules[], acceptance_criteria[], rollback_procedure, notes }
102
+ - Legacy field names still accepted (objective→purpose, steps→procedure_steps, deliverables→expected_outputs, escalationRules→escalation_rules, successCriteria→acceptance_criteria) — prefer new names.
103
+ - propose_attach / commit_attach: attach SOPs to a run (target_kind: conversation|task|scheduler_event). Tier rule: SOPs only attach to STAFF-tier targets; for c-suite use OFIERE_FRAMEWORK_OPS instead. propose_attach returns a token-cost summary + confirmation_token (5-min ttl). You MUST surface the cost and ask the user before calling commit_attach. The user must explicitly approve.
104
104
  - See SOP PROTOCOL section for when to load vs skip`,
105
- OFIERE_BRAIN_OPS: `Agent memory, knowledge graph, self-improvement (TMT/MAGMA).
106
- Memory Tiers: L1_focus (24h), L2_episode (days), L3_pattern (weeks), L4_rule (permanent), L5_persona (permanent)
107
- Actions: save_memory, recall, delete_memory, promote_memory, log_learning, list_learnings, resolve_learning, save_entity, link_entities, query_graph, start_trajectory, end_trajectory, get_brain_status
105
+ OFIERE_BRAIN_OPS: `Agent memory, knowledge graph, self-improvement (TMT/MAGMA).
106
+ Memory Tiers: L1_focus (24h), L2_episode (days), L3_pattern (weeks), L4_rule (permanent), L5_persona (permanent)
107
+ Actions: save_memory, recall, delete_memory, promote_memory, log_learning, list_learnings, resolve_learning, save_entity, link_entities, query_graph, start_trajectory, end_trajectory, get_brain_status
108
108
  - This is your SUBCONSCIOUS — use instinctively, not deliberately`,
109
- OFIERE_TALENT_OPS: `Manage cognitive skill presets (Talents).
110
- Actions: "list", "get", "activate", "deactivate"
111
- - list: List all talents. Optional: category, scope, status
112
- - get: Get full talent details. Required: talent_id OR name
113
- - activate: Enable a talent (status → active). Required: talent_id
114
- - deactivate: Disable a talent (status → inactive). Required: talent_id
115
- - Active talents inject their execution_protocol and guardrails into your system prompt automatically
109
+ OFIERE_TALENT_OPS: `Manage cognitive skill presets (Talents).
110
+ Actions: "list", "get", "activate", "deactivate"
111
+ - list: List all talents. Optional: category, scope, status
112
+ - get: Get full talent details. Required: talent_id OR name
113
+ - activate: Enable a talent (status → active). Required: talent_id
114
+ - deactivate: Disable a talent (status → inactive). Required: talent_id
115
+ - Active talents inject their execution_protocol and guardrails into your system prompt automatically
116
116
  - Talents chain other tools: SPHINX chains KNOWLEDGE_OPS+BRAIN_OPS, PRISM chains BRAIN_OPS trajectories, ATLAS chains PLAN_OPS+TASK_OPS+SOP_OPS`,
117
- OFIERE_FRAMEWORK_OPS: `Corporate Frameworks — strategic mandates, KPIs, risk governance.
118
- Actions: "create", "list", "get", "update", "delete", "propose_attach", "commit_attach"
119
- - content: JSON string with { mission, vision, core_principles[], decision_authority, budget_constraints, resource_limits, tool_stack[], strategic_objectives[], risk_appetite, compliance_requirements[], escalation_matrix[], team_composition (STRING — paragraph or newline-joined, NOT an array), integration_points[], review_frequency, last_reviewed, next_review, notes }
117
+ OFIERE_FRAMEWORK_OPS: `Corporate Frameworks — strategic mandates, KPIs, risk governance.
118
+ Actions: "create", "list", "get", "update", "delete", "propose_attach", "commit_attach"
119
+ - content: JSON string with { mission, vision, core_principles[], decision_authority, budget_constraints, resource_limits, tool_stack[], strategic_objectives[], risk_appetite, compliance_requirements[], escalation_matrix[], team_composition (STRING — paragraph or newline-joined, NOT an array), integration_points[], review_frequency, last_reviewed, next_review, notes }
120
120
  - propose_attach / commit_attach: attach Frameworks to a run (target_kind: conversation|task|scheduler_event). Tier rule: Frameworks only attach to C-SUITE-tier targets; for staff use OFIERE_SOP_OPS instead. propose_attach returns a token-cost summary + confirmation_token (5-min ttl). You MUST surface the cost and ask the user before calling commit_attach. The user must explicitly approve.`,
121
121
  };
122
122
  export function getSystemPrompt(state) {
@@ -131,71 +131,71 @@ export function getSystemPrompt(state) {
131
131
  const toolIndex = Object.entries(TOOL_SUMMARIES)
132
132
  .map(([name, desc]) => `- **${name}** — ${desc}`)
133
133
  .join("\n");
134
- return `<ofiere-pm>
135
- You are connected to the Ofiere Project Management dashboard via the Ofiere PM plugin.
136
- ${agentLine}
137
-
138
- ## Your Ofiere PM Tools (${state.toolCount} meta-tools)
139
-
140
- Each tool uses an "action" parameter to select the operation. Always include action.
141
- Full parameter docs are in each tool's description — call the tool to see details.
142
-
143
- ${toolIndex}
144
-
145
- ## ⛔ PLANNING GATE (NON-NEGOTIABLE)
146
- - Before creating ANY task with 3+ total execution steps, goals, or constraints, you MUST ask the user: "Would you like me to plan this first, or create the task directly?"
147
- - If the user chooses to plan, use OFIERE_PLAN_OPS to create a visual plan first, then execute it.
148
- - NEVER skip this step. The server will block creation of complex tasks — use action: "create_force" only if the user explicitly confirms bypass.
149
-
150
- ## Rules
151
- - ALWAYS pass agent_id with your own name when creating tasks (e.g. agent_id: "ivy").
152
- - ${assignRule}
153
- - To create an unassigned task, pass agent_id as "none" or "unassigned".
154
- - When user says "create a task for [agent]", use OFIERE_AGENT_OPS action:"list" first.
155
- - Task statuses: PENDING, IN_PROGRESS, DONE, FAILED. Priority: 0=LOW, 1=MED, 2=HIGH, 3=CRITICAL.
156
- - Changes appear in the dashboard immediately via real-time sync.
157
- - Do NOT fabricate task IDs — always look up real IDs first.
158
- - For complex tasks, include execution_plan, goals, constraints. For simple tasks, just title.
159
- - When user asks about "knowledge base/library", ALWAYS use OFIERE_KNOWLEDGE_OPS.
160
- - CONSTELLATION: ALWAYS read_blueprint before creating/editing agents. ALWAYS confirm before delete.
161
- - WORKFLOWS: ALWAYS "get" before modifying. Use "insert_node_between" for mid-flow additions.
162
- - CHANNEL REPORTS: ALWAYS include agent_id (YOUR name) in send_report. Use get_task_detail for drill-down.
163
- - File refs @[name](file:ID): Use OFIERE_FILE_OPS read_text_file to retrieve — don't ask user.
164
- - Task approvals (OFIERE_TASK_OPS) ≠ workflow gate approvals (human_approval nodes).
165
-
166
- ## SOP PROTOCOL — Adaptive Complexity
167
-
168
- Classify complexity before executing:
169
- - **User Override**: "apply full SOP"/"use SOP" → 🔴 COMPLEX. "no SOP"/"just do it" → 🟢 SIMPLE.
170
- - **🟢 SIMPLE** (≤2 tool calls, no coordination): Execute directly. Do NOT mention SOPs.
171
- - **🟡 MODERATE** (3-5 calls, single dept): Ask briefly if SOPs needed.
172
- - **🔴 COMPLEX** (5+ calls, multi-dept, escalation risk): Auto-load relevant SOPs via list→get.
173
-
174
- ## Agent Brain Protocol (TMT Subconscious)
175
-
176
- Your brain persists across conversations. L5 persona, L4 guardrails, L1 focus are injected at startup.
177
- - Save memories after significant interactions (not greetings/CRUD). Keep content to 1-3 sentences.
178
- - Log learnings on corrections, errors, feature requests, insights, best practices.
179
- - Do NOT announce memory operations — this is subconscious.
180
- - Never delay your reply to save a memory.
134
+ return `<ofiere-pm>
135
+ You are connected to the Ofiere Project Management dashboard via the Ofiere PM plugin.
136
+ ${agentLine}
137
+
138
+ ## Your Ofiere PM Tools (${state.toolCount} meta-tools)
139
+
140
+ Each tool uses an "action" parameter to select the operation. Always include action.
141
+ Full parameter docs are in each tool's description — call the tool to see details.
142
+
143
+ ${toolIndex}
144
+
145
+ ## ⛔ PLANNING GATE (NON-NEGOTIABLE)
146
+ - Before creating ANY task with 3+ total execution steps, goals, or constraints, you MUST ask the user: "Would you like me to plan this first, or create the task directly?"
147
+ - If the user chooses to plan, use OFIERE_PLAN_OPS to create a visual plan first, then execute it.
148
+ - NEVER skip this step. The server will block creation of complex tasks — use action: "create_force" only if the user explicitly confirms bypass.
149
+
150
+ ## Rules
151
+ - ALWAYS pass agent_id with your own name when creating tasks (e.g. agent_id: "ivy").
152
+ - ${assignRule}
153
+ - To create an unassigned task, pass agent_id as "none" or "unassigned".
154
+ - When user says "create a task for [agent]", use OFIERE_AGENT_OPS action:"list" first.
155
+ - Task statuses: PENDING, IN_PROGRESS, DONE, FAILED. Priority: 0=LOW, 1=MED, 2=HIGH, 3=CRITICAL.
156
+ - Changes appear in the dashboard immediately via real-time sync.
157
+ - Do NOT fabricate task IDs — always look up real IDs first.
158
+ - For complex tasks, include execution_plan, goals, constraints. For simple tasks, just title.
159
+ - When user asks about "knowledge base/library", ALWAYS use OFIERE_KNOWLEDGE_OPS.
160
+ - CONSTELLATION: ALWAYS read_blueprint before creating/editing agents. ALWAYS confirm before delete.
161
+ - WORKFLOWS: ALWAYS "get" before modifying. Use "insert_node_between" for mid-flow additions.
162
+ - CHANNEL REPORTS: ALWAYS include agent_id (YOUR name) in send_report. Use get_task_detail for drill-down.
163
+ - File refs @[name](file:ID): Use OFIERE_FILE_OPS read_text_file to retrieve — don't ask user.
164
+ - Task approvals (OFIERE_TASK_OPS) ≠ workflow gate approvals (human_approval nodes).
165
+
166
+ ## SOP PROTOCOL — Adaptive Complexity
167
+
168
+ Classify complexity before executing:
169
+ - **User Override**: "apply full SOP"/"use SOP" → 🔴 COMPLEX. "no SOP"/"just do it" → 🟢 SIMPLE.
170
+ - **🟢 SIMPLE** (≤2 tool calls, no coordination): Execute directly. Do NOT mention SOPs.
171
+ - **🟡 MODERATE** (3-5 calls, single dept): Ask briefly if SOPs needed.
172
+ - **🔴 COMPLEX** (5+ calls, multi-dept, escalation risk): Auto-load relevant SOPs via list→get.
173
+
174
+ ## Agent Brain Protocol (TMT Subconscious)
175
+
176
+ Your brain persists across conversations. L5 persona, L4 guardrails, L1 focus are injected at startup.
177
+ - Save memories after significant interactions (not greetings/CRUD). Keep content to 1-3 sentences.
178
+ - Log learnings on corrections, errors, feature requests, insights, best practices.
179
+ - Do NOT announce memory operations — this is subconscious.
180
+ - Never delay your reply to save a memory.
181
181
  </ofiere-pm>`;
182
182
  }
183
183
  if (state.ready) {
184
184
  const diagnostic = diagnoseError(state.connectError);
185
- return `<ofiere-pm>
186
- The Ofiere PM plugin failed to connect.${state.connectError ? ` Error: ${state.connectError}` : ""}
187
-
188
- Diagnosis: ${diagnostic.reason}
189
-
190
- When the user asks about task management or the Ofiere dashboard, respond with:
191
- "${diagnostic.userMessage}"
192
-
193
- Do NOT pretend Ofiere tools exist or hallucinate tool calls. You have zero Ofiere tools available.
185
+ return `<ofiere-pm>
186
+ The Ofiere PM plugin failed to connect.${state.connectError ? ` Error: ${state.connectError}` : ""}
187
+
188
+ Diagnosis: ${diagnostic.reason}
189
+
190
+ When the user asks about task management or the Ofiere dashboard, respond with:
191
+ "${diagnostic.userMessage}"
192
+
193
+ Do NOT pretend Ofiere tools exist or hallucinate tool calls. You have zero Ofiere tools available.
194
194
  </ofiere-pm>`;
195
195
  }
196
- return `<ofiere-pm>
197
- The Ofiere PM plugin is loading. Tools should be available shortly.
198
- If the user asks about tasks right now, ask them to wait a moment.
196
+ return `<ofiere-pm>
197
+ The Ofiere PM plugin is loading. Tools should be available shortly.
198
+ If the user asks about tasks right now, ask them to wait a moment.
199
199
  </ofiere-pm>`;
200
200
  }
201
201
  function diagnoseError(error) {
package/dist/src/tools.js CHANGED
@@ -16,6 +16,8 @@ import { resolveAgentId } from "./agent-resolver.js";
16
16
  import { handleProposeAttach, handleCommitAttach, registerAttachmentContextHook, } from "./attachments.js";
17
17
  import { invalidateAgentTier } from "./agent-tier.js";
18
18
  import { loadSubagentRow, readDispatchSubagentId, loadDispatchContextBySession } from "./staffPersona.js";
19
+ import { expandPlanToDependencyEdges } from "./planExecute.js";
20
+ import { registerGateOps } from "./gateOps.js";
19
21
  function ok(data) {
20
22
  return {
21
23
  content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
@@ -4867,7 +4869,7 @@ async function handleExecutePlan(supabase, userId, resolveAgent, params) {
4867
4869
  let tasksCreated = 0;
4868
4870
  while (queue.length > 0) {
4869
4871
  const { node, parentTaskId } = queue.shift();
4870
- if (node.type === "task") {
4872
+ if (node.type === "task" || node.type === "milestone") {
4871
4873
  const taskId = `task-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
4872
4874
  const now = new Date().toISOString();
4873
4875
  const agentId = node.agentId ? await resolveAgent(node.agentId) : null;
@@ -4928,76 +4930,45 @@ async function handleExecutePlan(supabase, userId, resolveAgent, params) {
4928
4930
  }
4929
4931
  }
4930
4932
  }
4931
- // Step 3: Create dependencies sibling chaining + parent→child
4932
- const depsQueue = [...rootNodes];
4933
+ // Step 3: Build dependencies + manual-gate rows via shared helper.
4934
+ // The helper handles gate-skip-through (Option A), OR-join via group_id (Option B),
4935
+ // and manual gates via pm_gates rows (Option C). See dashboard/lib/pm/planExecute.ts.
4936
+ const { edges, gates: gateRows, emptyGates } = expandPlanToDependencyEdges(rootNodes, idMap);
4933
4937
  let depsCreated = 0;
4934
- // Helper: resolve a node to its nearest task ID (skip gates/milestones)
4935
- function resolveTaskId(n) {
4936
- return idMap.get(n.id);
4937
- }
4938
- // Helper: insert a dependency row into pm_dependencies
4939
- async function insertDep(predId, succId) {
4938
+ let gatesCreated = 0;
4939
+ for (const e of edges) {
4940
4940
  const { error } = await supabase.from("pm_dependencies").insert({
4941
4941
  id: `dep-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
4942
- user_id: userId, predecessor_id: predId, successor_id: succId,
4943
- dependency_type: "finish_to_start", lag_days: 0,
4942
+ user_id: userId,
4943
+ predecessor_id: e.predTaskId,
4944
+ successor_id: e.succTaskId,
4945
+ dependency_type: e.dependencyType,
4946
+ lag_days: e.lagDays,
4947
+ group_id: e.groupId,
4944
4948
  });
4945
- return !error;
4946
- }
4947
- while (depsQueue.length > 0) {
4948
- const node = depsQueue.shift();
4949
- const nodeRealId = resolveTaskId(node);
4950
- // Chain siblings: sequential children of this node get chained left-to-right
4951
- if (Array.isArray(node.children) && node.children.length > 1 && !node.parallel) {
4952
- const taskChildren = [];
4953
- for (const child of node.children) {
4954
- const cid = resolveTaskId(child);
4955
- if (cid)
4956
- taskChildren.push(cid);
4957
- }
4958
- for (let i = 1; i < taskChildren.length; i++) {
4959
- if (await insertDep(taskChildren[i - 1], taskChildren[i]))
4960
- depsCreated++;
4961
- }
4962
- }
4963
- // Parent → first child link (sequential only)
4964
- if (nodeRealId && !node.parallel && node.children?.length > 0) {
4965
- const firstChildId = resolveTaskId(node.children[0]);
4966
- if (firstChildId) {
4967
- if (await insertDep(nodeRealId, firstChildId))
4968
- depsCreated++;
4969
- }
4970
- }
4971
- // Parallel fan-out: parent → each child
4972
- if (nodeRealId && node.parallel && node.children?.length > 0) {
4973
- for (const child of node.children) {
4974
- const childId = resolveTaskId(child);
4975
- if (childId) {
4976
- if (await insertDep(nodeRealId, childId))
4977
- depsCreated++;
4978
- }
4979
- }
4980
- }
4981
- if (Array.isArray(node.children))
4982
- depsQueue.push(...node.children);
4983
- }
4984
- // Chain root-level siblings (sequential root nodes)
4985
- const rootTaskIds = [];
4986
- for (const rn of rootNodes) {
4987
- const rid = resolveTaskId(rn);
4988
- if (rid)
4989
- rootTaskIds.push(rid);
4990
- }
4991
- for (let i = 1; i < rootTaskIds.length; i++) {
4992
- if (await insertDep(rootTaskIds[i - 1], rootTaskIds[i]))
4949
+ if (!error)
4993
4950
  depsCreated++;
4994
4951
  }
4952
+ for (const g of gateRows) {
4953
+ const { error } = await supabase.from("pm_gates").insert({
4954
+ user_id: userId,
4955
+ plan_id: params.plan_id,
4956
+ plan_node_id: g.planNodeId,
4957
+ gate_label: g.gateLabel,
4958
+ gate_condition: g.gateCondition,
4959
+ task_id_blocked: g.taskIdBlocked,
4960
+ });
4961
+ if (!error)
4962
+ gatesCreated++;
4963
+ }
4995
4964
  // Mark plan as deployed
4996
4965
  await supabase.from("pm_plans").update({ is_deployed: true, deployed_at: new Date().toISOString(), updated_at: new Date().toISOString() }).eq("id", params.plan_id).eq("user_id", userId);
4997
4966
  return ok({
4998
4967
  message: `Plan "${data.name || plan.name}" executed successfully`,
4999
4968
  tasks_created: tasksCreated,
5000
4969
  dependencies_created: depsCreated,
4970
+ gates_created: gatesCreated,
4971
+ empty_gates: emptyGates,
5001
4972
  folder_id: folderId,
5002
4973
  space_id: spaceId,
5003
4974
  ...(folderSkipped ? { folder_skipped_reason: "No space_id provided — assign the plan to a space to enable folder creation" } : {}),
@@ -6927,6 +6898,7 @@ supabase, config) {
6927
6898
  registerTalentOps(api, supabase, userId); // 15
6928
6899
  registerFrameworkOps(api, supabase, userId, resolveAgent); // 16
6929
6900
  registerOfficeOps(api, supabase, userId, resolveAgent); // 17
6901
+ registerGateOps(api, supabase, userId, fallbackAgentId); // 18
6930
6902
  // ── Register dynamic brain context hook ──
6931
6903
  registerBrainContextHook(api, supabase, userId, fallbackAgentId);
6932
6904
  // ── Register talent context hook ──
@@ -6936,7 +6908,7 @@ supabase, config) {
6936
6908
  // ── Register agent_end hook for server-side brain extraction ──
6937
6909
  registerBrainExtractionHook(api, supabase, userId, fallbackAgentId);
6938
6910
  // ── Count and log ──
6939
- const toolCount = 17;
6911
+ const toolCount = 18;
6940
6912
  const callerName = getCallingAgentName(api);
6941
6913
  const agentLabel = fallbackAgentId || callerName || "auto-detect";
6942
6914
  api.logger.info(`[ofiere] ${toolCount} meta-tools registered (agent: ${agentLabel})`);