ofiere-openclaw-plugin 4.32.0 → 4.33.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.
- package/package.json +1 -1
- package/src/prompt.ts +1 -1
- package/src/tools.ts +35 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ofiere-openclaw-plugin",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.33.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw plugin for Ofiere PM - 14 meta-tools covering tasks, agents, projects, scheduling, knowledge, workflows, notifications, memory, prompts, constellation, space file management, execution plan builder, SOP management, and agent brain (memory + self-improvement)",
|
|
6
6
|
"keywords": ["openclaw", "ofiere", "project-management", "agents", "plugin"],
|
package/src/prompt.ts
CHANGED
|
@@ -159,7 +159,7 @@ ${toolIndex}
|
|
|
159
159
|
- CONSTELLATION: ALWAYS read_blueprint before creating/editing agents. ALWAYS confirm before delete.
|
|
160
160
|
- WORKFLOWS: ALWAYS "get" before modifying. Use "insert_node_between" for mid-flow additions.
|
|
161
161
|
- CHANNEL REPORTS: ALWAYS include agent_id (YOUR name) in send_report. Use get_task_detail for drill-down.
|
|
162
|
-
- PLANNING GATE
|
|
162
|
+
- **PLANNING GATE (MANDATORY):** Before creating ANY task with 3+ execution steps, goals, constraints, OR a due_date, you MUST ask the user: "Would you like me to plan this first, or create the task directly?" If the user chooses to plan, use OFIERE_PLAN_OPS to create a visual plan first, then execute it to generate the real tasks. Do NOT skip this step.
|
|
163
163
|
- File refs @[name](file:ID): Use OFIERE_FILE_OPS read_text_file to retrieve — don't ask user.
|
|
164
164
|
- Task approvals (OFIERE_TASK_OPS) ≠ workflow gate approvals (human_approval nodes).
|
|
165
165
|
|
package/src/tools.ts
CHANGED
|
@@ -198,7 +198,7 @@ function registerTaskOps(
|
|
|
198
198
|
`Actions:\n` +
|
|
199
199
|
`- "list": List/filter tasks. Optional: status, agent_id, space_id, folder_id, task_id, limit\n` +
|
|
200
200
|
`- "get": Get a single task by ID. Required: task_id\n` +
|
|
201
|
-
`- "create": Create a task. Required: title. Optional: agent_id, description, status, priority, space_id, folder_id, start_date, due_date, tags, instructions, execution_plan, goals, constraints, system_prompt, recurrence_type, recurrence_interval, scheduled_time
|
|
201
|
+
`- "create": Create a task. Required: title. Optional: agent_id, description, status, priority, space_id, folder_id, start_date, due_date, tags, instructions, execution_plan, goals, constraints, system_prompt, recurrence_type, recurrence_interval, scheduled_time. ⚠️ PLANNING GATE: If the task has 3+ execution steps, goals, or constraints, FIRST ask the user "Plan first or create directly?" If they choose to plan, use OFIERE_PLAN_OPS instead.\n` +
|
|
202
202
|
`- "update": Update a task. Required: task_id. Optional: all create fields + progress\n` +
|
|
203
203
|
`- "delete": Delete task + subtasks. Required: task_id\n` +
|
|
204
204
|
`- "add_approval": Request approval on a task. Required: task_id, approver_name. Optional: approver_type (human|agent, auto-detected), due_date, comment\n` +
|
|
@@ -241,7 +241,7 @@ function registerTaskOps(
|
|
|
241
241
|
folder_id: { type: "string", description: "PM Folder ID" },
|
|
242
242
|
start_date: { type: "string", description: "Start date (ISO 8601). Required for scheduled/recurring tasks." },
|
|
243
243
|
due_date: { type: "string", description: "Due date (ISO 8601)" },
|
|
244
|
-
scheduled_time: { type: "string", description: "Time to execute in HH:MM format (
|
|
244
|
+
scheduled_time: { type: "string", description: "Time to execute in HH:MM format (user's LOCAL time, e.g. 10:00 for 10 AM WIB). The system converts to UTC automatically." },
|
|
245
245
|
recurrence_type: {
|
|
246
246
|
type: "string",
|
|
247
247
|
description: "How often the task recurs. 'none' for one-shot.",
|
|
@@ -542,8 +542,12 @@ async function handleCreateTask(
|
|
|
542
542
|
// ── Auto-create scheduler event if task has a start_date ──────────────
|
|
543
543
|
// This bridges the plugin → scheduler so the pg_cron task-dispatcher
|
|
544
544
|
// Edge Function picks up the task at the right time.
|
|
545
|
+
//
|
|
546
|
+
// TIMEZONE: scheduled_time is treated as the user's LOCAL time (default WIB, UTC+7).
|
|
547
|
+
// We convert to UTC epoch for next_run_at so the edge function fires correctly.
|
|
545
548
|
const startDate = params.start_date as string | undefined;
|
|
546
549
|
const effectiveAgentId = (insertData.agent_id as string) || assignee;
|
|
550
|
+
const WIB_OFFSET_HOURS = 7; // Asia/Jakarta = UTC+7
|
|
547
551
|
if (startDate && effectiveAgentId) {
|
|
548
552
|
try {
|
|
549
553
|
// Parse start_date robustly — it can be:
|
|
@@ -563,23 +567,41 @@ async function handleCreateTask(
|
|
|
563
567
|
const hasTimeInfo = /[T ]\d{2}:\d{2}/.test(startDate);
|
|
564
568
|
|
|
565
569
|
if (explicitScheduledTime) {
|
|
566
|
-
// Agent explicitly passed a scheduled_time —
|
|
570
|
+
// Agent explicitly passed a scheduled_time — treat as WIB local time
|
|
567
571
|
const dateStr = parsedDate.toISOString().split("T")[0]; // YYYY-MM-DD
|
|
568
|
-
const
|
|
572
|
+
const [localH, localM] = explicitScheduledTime.split(":").map(Number);
|
|
573
|
+
const utcH = localH - WIB_OFFSET_HOURS;
|
|
574
|
+
const dt = new Date(`${dateStr}T00:00:00Z`);
|
|
575
|
+
dt.setUTCHours(utcH, localM, 0, 0);
|
|
569
576
|
nextRunAtEpoch = Math.floor(dt.getTime() / 1000);
|
|
570
|
-
scheduledTimeFinal = explicitScheduledTime;
|
|
577
|
+
scheduledTimeFinal = explicitScheduledTime; // Store as user's local time
|
|
571
578
|
scheduledDateFinal = dateStr;
|
|
572
579
|
} else if (hasTimeInfo) {
|
|
573
|
-
// start_date already contains time —
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
580
|
+
// start_date already contains time — assume it's in the user's local timezone (WIB)
|
|
581
|
+
// Extract the local hour:minute from the string, NOT from UTC parsing
|
|
582
|
+
const timeMatch = startDate.match(/(\d{2}):(\d{2})/);
|
|
583
|
+
if (timeMatch) {
|
|
584
|
+
const localH = parseInt(timeMatch[1], 10);
|
|
585
|
+
const localM = parseInt(timeMatch[2], 10);
|
|
586
|
+
const dateStr = parsedDate.toISOString().split("T")[0];
|
|
587
|
+
const dt = new Date(`${dateStr}T00:00:00Z`);
|
|
588
|
+
dt.setUTCHours(localH - WIB_OFFSET_HOURS, localM, 0, 0);
|
|
589
|
+
nextRunAtEpoch = Math.floor(dt.getTime() / 1000);
|
|
590
|
+
scheduledTimeFinal = `${String(localH).padStart(2, "0")}:${String(localM).padStart(2, "0")}`;
|
|
591
|
+
scheduledDateFinal = dateStr;
|
|
592
|
+
} else {
|
|
593
|
+
// Can't extract time — fall back to UTC parsing
|
|
594
|
+
nextRunAtEpoch = Math.floor(parsedDate.getTime() / 1000);
|
|
595
|
+
scheduledTimeFinal = `${String(parsedDate.getUTCHours()).padStart(2, "0")}:${String(parsedDate.getUTCMinutes()).padStart(2, "0")}`;
|
|
596
|
+
scheduledDateFinal = parsedDate.toISOString().split("T")[0];
|
|
597
|
+
}
|
|
577
598
|
} else {
|
|
578
|
-
// Date only, no time — default to 09:00 UTC
|
|
599
|
+
// Date only, no time — default to 09:00 WIB (= 02:00 UTC)
|
|
579
600
|
const dateStr = parsedDate.toISOString().split("T")[0];
|
|
580
|
-
const dt = new Date(`${dateStr}
|
|
601
|
+
const dt = new Date(`${dateStr}T00:00:00Z`);
|
|
602
|
+
dt.setUTCHours(9 - WIB_OFFSET_HOURS, 0, 0, 0); // 09:00 WIB = 02:00 UTC
|
|
581
603
|
nextRunAtEpoch = Math.floor(dt.getTime() / 1000);
|
|
582
|
-
scheduledTimeFinal = "09:00";
|
|
604
|
+
scheduledTimeFinal = "09:00"; // Stored as WIB local time
|
|
583
605
|
scheduledDateFinal = dateStr;
|
|
584
606
|
}
|
|
585
607
|
} else {
|
|
@@ -611,6 +633,7 @@ async function handleCreateTask(
|
|
|
611
633
|
next_run_at: nextRunAtEpoch,
|
|
612
634
|
run_count: 0,
|
|
613
635
|
priority: params.priority !== undefined ? params.priority : 1,
|
|
636
|
+
timezone: "Asia/Jakarta",
|
|
614
637
|
});
|
|
615
638
|
} catch (schedErr) {
|
|
616
639
|
// Non-fatal: task was created, just the scheduler event failed
|