ofiere-openclaw-plugin 4.56.8 → 4.56.10
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/README.md +104 -104
- package/dist/src/prompt.js +130 -130
- package/dist/src/tools.js +49 -5
- package/index.ts +105 -105
- package/package.json +1 -1
- package/src/agent-resolver.ts +90 -90
- package/src/agent-tier.ts +192 -192
- package/src/attach-token.ts +106 -106
- package/src/attachments.ts +601 -601
- package/src/cli.ts +247 -247
- package/src/config.ts +78 -78
- package/src/prompt.ts +267 -267
- package/src/sop-render.ts +216 -216
- package/src/supabase.ts +13 -13
- package/src/tools.ts +48 -5
- package/src/types/openclaw.d.ts +8 -8
- package/src/types.ts +10 -10
package/README.md
CHANGED
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
# Ofiere PM Plugin for OpenClaw
|
|
2
|
-
|
|
3
|
-
Manage your Ofiere PM dashboard directly from OpenClaw agents. Create tasks, manage projects, build workflows, store knowledge — all synced to the dashboard in real time.
|
|
4
|
-
|
|
5
|
-
## Quick Install (One-Click)
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
curl -sSL https://ofiere.com/scripts/install.sh | bash -s -- \
|
|
9
|
-
--supabase-url "https://xxx.supabase.co" \
|
|
10
|
-
--service-key "eyJ..." \
|
|
11
|
-
--user-id "your-uuid"
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
Only 3 parameters needed. All agents get the plugin automatically.
|
|
15
|
-
|
|
16
|
-
## Uninstall
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
curl -sSL https://ofiere.com/scripts/uninstall.sh | bash
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## How It Works
|
|
23
|
-
|
|
24
|
-
Once configured, the plugin connects to your Supabase database at gateway startup and registers 9 PM meta-tools directly into the agent. There's no separate MCP server process — it runs inside the OpenClaw gateway for maximum reliability.
|
|
25
|
-
|
|
26
|
-
Changes made by the agent are immediately visible on the Ofiere dashboard (Vercel) via Supabase real-time subscriptions.
|
|
27
|
-
|
|
28
|
-
## AI Meta-Tools
|
|
29
|
-
|
|
30
|
-
The plugin uses a scalable meta-tool architecture. Each tool handles one domain with an `action` parameter to select the operation.
|
|
31
|
-
|
|
32
|
-
| Tool | Actions | Description |
|
|
33
|
-
|---|---|---|
|
|
34
|
-
| `OFIERE_TASK_OPS` | `list`, `create`, `update`, `delete` | Rich task management with execution plans, goals, constraints |
|
|
35
|
-
| `OFIERE_AGENT_OPS` | `list` | Query available agents for task assignment |
|
|
36
|
-
| `OFIERE_PROJECT_OPS` | `list_spaces`, `create_space`, `create_folder`, `bulk_create_tasks`, etc. | Full project hierarchy: spaces → folders → tasks |
|
|
37
|
-
| `OFIERE_SCHEDULE_OPS` | `list`, `create`, `update`, `delete` | Calendar events with recurrence |
|
|
38
|
-
| `OFIERE_KNOWLEDGE_OPS` | `search`, `list`, `create`, `update`, `delete` | Knowledge library with full content retrieval |
|
|
39
|
-
| `OFIERE_WORKFLOW_OPS` | `list`, `get`, `create`, `update`, `delete`, `list_runs`, `trigger` | Visual workflow builder with 16 node types |
|
|
40
|
-
| `OFIERE_NOTIFY_OPS` | `list`, `mark_read`, `create` | In-app notifications |
|
|
41
|
-
| `OFIERE_MEMORY_OPS` | `list_conversations`, `search_knowledge` | Conversation history & agent memory |
|
|
42
|
-
| `OFIERE_PROMPT_OPS` | `list`, `get`, `create`, `update`, `delete` | System prompt chunk management |
|
|
43
|
-
|
|
44
|
-
### Example
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
// Create a task with execution plan
|
|
48
|
-
OFIERE_TASK_OPS({ action: "create", title: "Deploy v2", agent_id: "ivy",
|
|
49
|
-
execution_plan: [{ step: 1, action: "Build", detail: "Run production build" }] })
|
|
50
|
-
|
|
51
|
-
// Create a workflow with nodes
|
|
52
|
-
OFIERE_WORKFLOW_OPS({ action: "create", name: "Deploy Pipeline",
|
|
53
|
-
nodes: [
|
|
54
|
-
{ type: "agent_step", data: { label: "Build", task: "Run npm build" } },
|
|
55
|
-
{ type: "human_approval", data: { label: "Review", instructions: "Check build output" } },
|
|
56
|
-
{ type: "output", data: { label: "Done" } }
|
|
57
|
-
],
|
|
58
|
-
edges: [
|
|
59
|
-
{ source: "agent_step-...", target: "human_approval-..." },
|
|
60
|
-
{ source: "human_approval-...", target: "output-..." }
|
|
61
|
-
]
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
// Search knowledge library
|
|
65
|
-
OFIERE_KNOWLEDGE_OPS({ action: "search", query: "API rate limits" })
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## CLI Commands
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
openclaw ofiere setup # Configure Supabase connection and agent identity
|
|
72
|
-
openclaw ofiere status # View current configuration
|
|
73
|
-
openclaw ofiere doctor # Test connection and list agents
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Configuration
|
|
77
|
-
|
|
78
|
-
Set via `openclaw ofiere setup` or environment variables:
|
|
79
|
-
|
|
80
|
-
| Option | Env Var | Description |
|
|
81
|
-
|---|---|---|
|
|
82
|
-
| `supabaseUrl` | `OFIERE_SUPABASE_URL` | Supabase project URL |
|
|
83
|
-
| `serviceRoleKey` | `OFIERE_SERVICE_ROLE_KEY` | Supabase service role key |
|
|
84
|
-
| `userId` | `OFIERE_USER_ID` | Your user UUID |
|
|
85
|
-
| `agentId` | `OFIERE_AGENT_ID` | This agent's ID (optional — auto-detected) |
|
|
86
|
-
| `enabled` | — | Enable/disable the plugin (default: `true`) |
|
|
87
|
-
|
|
88
|
-
## Architecture
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
OpenClaw Agent (VPS)
|
|
92
|
-
│ plugin runs IN-PROCESS
|
|
93
|
-
Ofiere Plugin ──► Supabase (shared database)
|
|
94
|
-
▲
|
|
95
|
-
Ofiere Dashboard ─────┘ (Vercel, real-time)
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Both the agent plugin and the Vercel dashboard talk to the same Supabase instance. When the agent creates/updates a task, the dashboard sees it instantly through Supabase real-time subscriptions.
|
|
99
|
-
|
|
100
|
-
## Links
|
|
101
|
-
|
|
102
|
-
- [Ofiere Dashboard](https://github.com/gilanggemar/Ofiere)
|
|
103
|
-
- [OpenClaw](https://openclaw.ai)
|
|
104
|
-
- [Supabase](https://supabase.com)
|
|
1
|
+
# Ofiere PM Plugin for OpenClaw
|
|
2
|
+
|
|
3
|
+
Manage your Ofiere PM dashboard directly from OpenClaw agents. Create tasks, manage projects, build workflows, store knowledge — all synced to the dashboard in real time.
|
|
4
|
+
|
|
5
|
+
## Quick Install (One-Click)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
curl -sSL https://ofiere.com/scripts/install.sh | bash -s -- \
|
|
9
|
+
--supabase-url "https://xxx.supabase.co" \
|
|
10
|
+
--service-key "eyJ..." \
|
|
11
|
+
--user-id "your-uuid"
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Only 3 parameters needed. All agents get the plugin automatically.
|
|
15
|
+
|
|
16
|
+
## Uninstall
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
curl -sSL https://ofiere.com/scripts/uninstall.sh | bash
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## How It Works
|
|
23
|
+
|
|
24
|
+
Once configured, the plugin connects to your Supabase database at gateway startup and registers 9 PM meta-tools directly into the agent. There's no separate MCP server process — it runs inside the OpenClaw gateway for maximum reliability.
|
|
25
|
+
|
|
26
|
+
Changes made by the agent are immediately visible on the Ofiere dashboard (Vercel) via Supabase real-time subscriptions.
|
|
27
|
+
|
|
28
|
+
## AI Meta-Tools
|
|
29
|
+
|
|
30
|
+
The plugin uses a scalable meta-tool architecture. Each tool handles one domain with an `action` parameter to select the operation.
|
|
31
|
+
|
|
32
|
+
| Tool | Actions | Description |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `OFIERE_TASK_OPS` | `list`, `create`, `update`, `delete` | Rich task management with execution plans, goals, constraints |
|
|
35
|
+
| `OFIERE_AGENT_OPS` | `list` | Query available agents for task assignment |
|
|
36
|
+
| `OFIERE_PROJECT_OPS` | `list_spaces`, `create_space`, `create_folder`, `bulk_create_tasks`, etc. | Full project hierarchy: spaces → folders → tasks |
|
|
37
|
+
| `OFIERE_SCHEDULE_OPS` | `list`, `create`, `update`, `delete` | Calendar events with recurrence |
|
|
38
|
+
| `OFIERE_KNOWLEDGE_OPS` | `search`, `list`, `create`, `update`, `delete` | Knowledge library with full content retrieval |
|
|
39
|
+
| `OFIERE_WORKFLOW_OPS` | `list`, `get`, `create`, `update`, `delete`, `list_runs`, `trigger` | Visual workflow builder with 16 node types |
|
|
40
|
+
| `OFIERE_NOTIFY_OPS` | `list`, `mark_read`, `create` | In-app notifications |
|
|
41
|
+
| `OFIERE_MEMORY_OPS` | `list_conversations`, `search_knowledge` | Conversation history & agent memory |
|
|
42
|
+
| `OFIERE_PROMPT_OPS` | `list`, `get`, `create`, `update`, `delete` | System prompt chunk management |
|
|
43
|
+
|
|
44
|
+
### Example
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
// Create a task with execution plan
|
|
48
|
+
OFIERE_TASK_OPS({ action: "create", title: "Deploy v2", agent_id: "ivy",
|
|
49
|
+
execution_plan: [{ step: 1, action: "Build", detail: "Run production build" }] })
|
|
50
|
+
|
|
51
|
+
// Create a workflow with nodes
|
|
52
|
+
OFIERE_WORKFLOW_OPS({ action: "create", name: "Deploy Pipeline",
|
|
53
|
+
nodes: [
|
|
54
|
+
{ type: "agent_step", data: { label: "Build", task: "Run npm build" } },
|
|
55
|
+
{ type: "human_approval", data: { label: "Review", instructions: "Check build output" } },
|
|
56
|
+
{ type: "output", data: { label: "Done" } }
|
|
57
|
+
],
|
|
58
|
+
edges: [
|
|
59
|
+
{ source: "agent_step-...", target: "human_approval-..." },
|
|
60
|
+
{ source: "human_approval-...", target: "output-..." }
|
|
61
|
+
]
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// Search knowledge library
|
|
65
|
+
OFIERE_KNOWLEDGE_OPS({ action: "search", query: "API rate limits" })
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## CLI Commands
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
openclaw ofiere setup # Configure Supabase connection and agent identity
|
|
72
|
+
openclaw ofiere status # View current configuration
|
|
73
|
+
openclaw ofiere doctor # Test connection and list agents
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Configuration
|
|
77
|
+
|
|
78
|
+
Set via `openclaw ofiere setup` or environment variables:
|
|
79
|
+
|
|
80
|
+
| Option | Env Var | Description |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `supabaseUrl` | `OFIERE_SUPABASE_URL` | Supabase project URL |
|
|
83
|
+
| `serviceRoleKey` | `OFIERE_SERVICE_ROLE_KEY` | Supabase service role key |
|
|
84
|
+
| `userId` | `OFIERE_USER_ID` | Your user UUID |
|
|
85
|
+
| `agentId` | `OFIERE_AGENT_ID` | This agent's ID (optional — auto-detected) |
|
|
86
|
+
| `enabled` | — | Enable/disable the plugin (default: `true`) |
|
|
87
|
+
|
|
88
|
+
## Architecture
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
OpenClaw Agent (VPS)
|
|
92
|
+
│ plugin runs IN-PROCESS
|
|
93
|
+
Ofiere Plugin ──► Supabase (shared database)
|
|
94
|
+
▲
|
|
95
|
+
Ofiere Dashboard ─────┘ (Vercel, real-time)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Both the agent plugin and the Vercel dashboard talk to the same Supabase instance. When the agent creates/updates a task, the dashboard sees it instantly through Supabase real-time subscriptions.
|
|
99
|
+
|
|
100
|
+
## Links
|
|
101
|
+
|
|
102
|
+
- [Ofiere Dashboard](https://github.com/gilanggemar/Ofiere)
|
|
103
|
+
- [OpenClaw](https://openclaw.ai)
|
|
104
|
+
- [Supabase](https://supabase.com)
|
package/dist/src/prompt.js
CHANGED
|
@@ -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
|
@@ -56,6 +56,22 @@ function err(message) {
|
|
|
56
56
|
content: [{ type: "text", text: `Error: ${message}` }],
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* D1 fix (2026-05-23): true when an LLM-supplied value is an "empty echo" —
|
|
61
|
+
* a field the model parroted back from a prior read with no real new content
|
|
62
|
+
* (null/undefined, empty or whitespace-only string, or empty array). The task
|
|
63
|
+
* update path is LLM-only; without this guard an echoed blank overwrites a
|
|
64
|
+
* real column. Mirrors isEmptyEcho in dashboard/lib/ofie/tool-executor.ts.
|
|
65
|
+
*/
|
|
66
|
+
function isEmptyEcho(v) {
|
|
67
|
+
if (v === null || v === undefined)
|
|
68
|
+
return true;
|
|
69
|
+
if (typeof v === "string")
|
|
70
|
+
return v.trim() === "";
|
|
71
|
+
if (Array.isArray(v))
|
|
72
|
+
return v.length === 0;
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
59
75
|
// ─── Subagent ↔ chief invariant ──────────────────────────────────────────────
|
|
60
76
|
// Mirrors dashboard/lib/subagentValidation.ts. Used by TASK_OPS + SCHEDULE_OPS
|
|
61
77
|
// when a chief delegates work to one of their staff via tool call.
|
|
@@ -989,8 +1005,17 @@ async function handleUpdateTask(supabase, userId, params) {
|
|
|
989
1005
|
// error instead of nulling the column. Coerce empty/whitespace → null here
|
|
990
1006
|
// to match the dashboard native executor (see tool-executor.ts handleTaskOps).
|
|
991
1007
|
const TIMESTAMP_FIELDS = ["start_date", "due_date"];
|
|
1008
|
+
// D1 parity fix (2026-05-23): this update path is LLM-only. A completing
|
|
1009
|
+
// agent routinely echoes the whole task object back with blank values for
|
|
1010
|
+
// fields it did not change; without this guard those blanks overwrite real
|
|
1011
|
+
// columns. An empty echo on a structural field means "leave unchanged".
|
|
1012
|
+
// status/priority/progress are excluded (0 is valid); start_date/due_date
|
|
1013
|
+
// keep the Fix #8 empty-string -> null coercion below.
|
|
1014
|
+
const STRUCTURE_FIELDS = ["title", "description", "agent_id", "tags"];
|
|
992
1015
|
for (const f of fields) {
|
|
993
1016
|
if (params[f] !== undefined) {
|
|
1017
|
+
if (STRUCTURE_FIELDS.includes(f) && isEmptyEcho(params[f]))
|
|
1018
|
+
continue;
|
|
994
1019
|
if (TIMESTAMP_FIELDS.includes(f)) {
|
|
995
1020
|
const v = params[f];
|
|
996
1021
|
updates[f] = (typeof v === "string" && v.trim() === "") ? null : v;
|
|
@@ -1038,12 +1063,15 @@ async function handleUpdateTask(supabase, userId, params) {
|
|
|
1038
1063
|
updates.subagent_id = subCheck.subagentId;
|
|
1039
1064
|
}
|
|
1040
1065
|
}
|
|
1041
|
-
// If task is being marked DONE or FAILED, auto-complete any linked scheduler events
|
|
1066
|
+
// If task is being marked DONE or FAILED, auto-complete any linked scheduler events.
|
|
1067
|
+
// A-4 plugin parity (2026-05-18) — scope by user_id so cross-tenant task_id
|
|
1068
|
+
// can't trigger foreign scheduler flip via plugin tool path.
|
|
1042
1069
|
if (params.status === "DONE" || params.status === "FAILED") {
|
|
1043
1070
|
try {
|
|
1044
1071
|
await supabase
|
|
1045
1072
|
.from("scheduler_events")
|
|
1046
1073
|
.update({ status: "completed", next_run_at: null, updated_at: new Date().toISOString() })
|
|
1074
|
+
.eq("user_id", userId)
|
|
1047
1075
|
.eq("task_id", params.task_id);
|
|
1048
1076
|
}
|
|
1049
1077
|
catch (_schedErr) {
|
|
@@ -2313,7 +2341,9 @@ function registerWorkflowOps(api, supabase, userId) {
|
|
|
2313
2341
|
const wfId = (params.id || params.workflow_id);
|
|
2314
2342
|
if (!wfId)
|
|
2315
2343
|
return err("Missing required: id");
|
|
2316
|
-
|
|
2344
|
+
// A-4 plugin parity (2026-05-18) — scope cascade so cross-tenant
|
|
2345
|
+
// workflow_id can't trigger foreign workflow_runs wipe via plugin.
|
|
2346
|
+
await supabase.from("workflow_runs").delete().eq("user_id", userId).eq("workflow_id", wfId);
|
|
2317
2347
|
const { error } = await supabase.from("workflows").delete().eq("id", wfId).eq("user_id", userId);
|
|
2318
2348
|
if (error)
|
|
2319
2349
|
return err(error.message);
|
|
@@ -4701,7 +4731,7 @@ function registerPlanOps(api, supabase, userId, resolveAgent) {
|
|
|
4701
4731
|
`- "delete": Remove plan. Required: plan_id\n` +
|
|
4702
4732
|
`- "add_nodes": Add nodes to plan. Required: plan_id, nodes[]. Optional: parent_node_id\n` +
|
|
4703
4733
|
`- "execute": Deploy plan to real PM tasks. Required: plan_id. Optional: create_folder, create_scheduler, space_id, folder_id\n\n` +
|
|
4704
|
-
`Node structure: { type, title, description?, agent_id?, priority?, status?, start_date?, due_date?, tags?, execution_steps?[{text}], goals?[{label,type?}], constraints?[{label,type?}], system_prompt?, children?[], parallel? }`,
|
|
4734
|
+
`Node structure: { type, title, description?, agent_id?, priority?, status?, start_date?, due_date?, tags?, execution_steps?[{text}], goals?[{label,type?}], constraints?[{label,type?}], system_prompt?, gate_condition?, children?[], parallel? }`,
|
|
4705
4735
|
parameters: {
|
|
4706
4736
|
type: "object",
|
|
4707
4737
|
required: ["action"],
|
|
@@ -4734,8 +4764,13 @@ function registerPlanOps(api, supabase, userId, resolveAgent) {
|
|
|
4734
4764
|
goals: { type: "array", items: { type: "object", properties: { label: { type: "string" }, type: { type: "string" } }, required: ["label"] } },
|
|
4735
4765
|
constraints: { type: "array", items: { type: "object", properties: { label: { type: "string" }, type: { type: "string" } }, required: ["label"] } },
|
|
4736
4766
|
system_prompt: { type: "string" },
|
|
4767
|
+
gate_condition: {
|
|
4768
|
+
type: "string",
|
|
4769
|
+
enum: ["manual", "all_predecessors_complete", "any_predecessor_complete"],
|
|
4770
|
+
description: 'For type:"gate" nodes only. manual = human approval required; all_predecessors_complete = AND-join (default for gates); any_predecessor_complete = OR-join.',
|
|
4771
|
+
},
|
|
4737
4772
|
parallel: { type: "boolean" },
|
|
4738
|
-
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"] } },
|
|
4773
|
+
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" }, gate_condition: { type: "string", enum: ["manual", "all_predecessors_complete", "any_predecessor_complete"] } }, required: ["title"] } },
|
|
4739
4774
|
},
|
|
4740
4775
|
required: ["title"],
|
|
4741
4776
|
},
|
|
@@ -4764,6 +4799,15 @@ function generatePlanNodeId() {
|
|
|
4764
4799
|
function generatePlanId() {
|
|
4765
4800
|
return crypto.randomUUID();
|
|
4766
4801
|
}
|
|
4802
|
+
const VALID_GATE_CONDITIONS = ["manual", "all_predecessors_complete", "any_predecessor_complete"];
|
|
4803
|
+
/** Validate a plan node's gate_condition. Invalid/absent values fall back to the
|
|
4804
|
+
* existing default — gates get "all_predecessors_complete", non-gates get nothing. */
|
|
4805
|
+
function normalizeGateCondition(v, nodeType) {
|
|
4806
|
+
if (typeof v === "string" && VALID_GATE_CONDITIONS.includes(v)) {
|
|
4807
|
+
return v;
|
|
4808
|
+
}
|
|
4809
|
+
return nodeType === "gate" ? "all_predecessors_complete" : undefined;
|
|
4810
|
+
}
|
|
4767
4811
|
/** Normalize agent-provided node into the PlanNode shape stored in plan_data */
|
|
4768
4812
|
function normalizeNode(raw) {
|
|
4769
4813
|
const id = raw.id || generatePlanNodeId();
|
|
@@ -4790,7 +4834,7 @@ function normalizeNode(raw) {
|
|
|
4790
4834
|
? raw.constraints.map((c, i) => ({ id: `cstr-${Date.now()}-${i}`, type: c.type || "custom", label: typeof c === "string" ? c : c.label || String(c) }))
|
|
4791
4835
|
: undefined,
|
|
4792
4836
|
systemPrompt: raw.system_prompt || raw.systemPrompt || undefined,
|
|
4793
|
-
gateCondition: raw.gate_condition || raw.gateCondition
|
|
4837
|
+
gateCondition: normalizeGateCondition(raw.gate_condition || raw.gateCondition, raw.type),
|
|
4794
4838
|
children,
|
|
4795
4839
|
parallel: raw.parallel || false,
|
|
4796
4840
|
collapsed: false,
|