openclaw-remote 0.5.5 → 0.5.6

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/dist/index.js +185 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2781,6 +2781,41 @@ async function getBoardHealth(account) {
2781
2781
  }
2782
2782
  );
2783
2783
  }
2784
+ async function getGoals(account, filters) {
2785
+ const params = new URLSearchParams();
2786
+ if (filters?.status) params.set("status", filters.status);
2787
+ if (filters?.parent_id !== void 0) params.set("parent_id", filters.parent_id);
2788
+ if (filters?.assigned_to) params.set("assigned_to", filters.assigned_to);
2789
+ const qs = params.toString();
2790
+ const path = `/api/v1/goals${qs ? `?${qs}` : ""}`;
2791
+ return apiFetch(
2792
+ buildUrl(account, path),
2793
+ {
2794
+ method: "GET",
2795
+ headers: buildHeaders(account)
2796
+ }
2797
+ );
2798
+ }
2799
+ async function createGoal(account, data) {
2800
+ return apiFetch(
2801
+ buildUrl(account, "/api/v1/goals"),
2802
+ {
2803
+ method: "POST",
2804
+ headers: buildHeaders(account),
2805
+ body: JSON.stringify(data)
2806
+ }
2807
+ );
2808
+ }
2809
+ async function updateGoal(account, goalId, updates) {
2810
+ return apiFetch(
2811
+ buildUrl(account, `/api/v1/goals/${encodeURIComponent(goalId)}`),
2812
+ {
2813
+ method: "PATCH",
2814
+ headers: buildHeaders(account),
2815
+ body: JSON.stringify(updates)
2816
+ }
2817
+ );
2818
+ }
2784
2819
  async function getTeam(account) {
2785
2820
  return apiFetch(
2786
2821
  buildUrl(account, "/api/v1/team"),
@@ -3130,6 +3165,9 @@ function createRemotePlugin() {
3130
3165
  ),
3131
3166
  epic_id: Type.Optional(
3132
3167
  Type.String({ description: "Epic ID to group the task under" })
3168
+ ),
3169
+ goal_id: Type.Optional(
3170
+ Type.String({ description: "Goal ID to link the task to" })
3133
3171
  )
3134
3172
  }),
3135
3173
  execute: async (_toolCallId, args) => {
@@ -3140,7 +3178,8 @@ function createRemotePlugin() {
3140
3178
  type: args.type,
3141
3179
  priority: args.priority,
3142
3180
  assigned_role_id: args.assigned_role_id,
3143
- epic_id: args.epic_id
3181
+ epic_id: args.epic_id,
3182
+ goal_id: args.goal_id
3144
3183
  });
3145
3184
  if (!result.ok) {
3146
3185
  return {
@@ -3187,6 +3226,9 @@ function createRemotePlugin() {
3187
3226
  epic_id: Type.Optional(
3188
3227
  Type.String({ description: "Epic ID to group the task under (or null to remove)" })
3189
3228
  ),
3229
+ goal_id: Type.Optional(
3230
+ Type.String({ description: "Goal ID to link the task to (or null to remove)" })
3231
+ ),
3190
3232
  assigned_role_id: Type.Optional(
3191
3233
  Type.String({ description: "Role ID to assign the task to" })
3192
3234
  )
@@ -3485,6 +3527,139 @@ function createRemotePlugin() {
3485
3527
  details: { ok: true, team, total, humans, agents }
3486
3528
  };
3487
3529
  }
3530
+ },
3531
+ // 9. remote_list_goals
3532
+ {
3533
+ name: "remote_list_goals",
3534
+ label: "List goals on the Remote project board",
3535
+ description: "List goals on the Remote project board. Optionally filter by status (active/achieved/abandoned), parent_id (null for top-level), or assigned_to (me).",
3536
+ parameters: Type.Object({
3537
+ status: optionalStringEnum(["active", "achieved", "abandoned"], {
3538
+ description: "Filter by status: active, achieved, or abandoned"
3539
+ }),
3540
+ parent_id: Type.Optional(
3541
+ Type.String({ description: "Filter by parent goal ID. Use 'null' for top-level goals." })
3542
+ ),
3543
+ assigned_to: Type.Optional(
3544
+ Type.String({ description: "Filter by assignee. Use 'me' for goals owned by your roles." })
3545
+ )
3546
+ }),
3547
+ execute: async (_toolCallId, args) => {
3548
+ const account = resolveToolAccount();
3549
+ const result = await getGoals(account, {
3550
+ status: args.status,
3551
+ parent_id: args.parent_id,
3552
+ assigned_to: args.assigned_to
3553
+ });
3554
+ if (!result.ok) {
3555
+ return {
3556
+ content: [{ type: "text", text: `\u274C Failed to list goals: ${result.error}` }],
3557
+ details: { ok: false, error: result.error }
3558
+ };
3559
+ }
3560
+ const goals = result.data.goals;
3561
+ if (goals.length === 0) {
3562
+ return {
3563
+ content: [{ type: "text", text: `\u{1F3AF} No goals found.` }],
3564
+ details: { ok: true, goals: [] }
3565
+ };
3566
+ }
3567
+ const lines = [`\u{1F3AF} **${goals.length} goal(s):**`, ""];
3568
+ for (const g of goals) {
3569
+ const pct = g.progress ?? 0;
3570
+ const bar = "\u2588".repeat(Math.round(pct / 10)) + "\u2591".repeat(10 - Math.round(pct / 10));
3571
+ const role = g.project_roles?.role_name || "";
3572
+ const date = g.target_date ? ` \u{1F3AF} ${new Date(g.target_date).toLocaleDateString()}` : "";
3573
+ const kids = g.children_count ? ` (${g.children_count} sub-goals)` : "";
3574
+ lines.push(`- **${g.title}** [${g.status}] ${bar} ${pct}%${role ? ` \u2014 ${role}` : ""}${date}${kids} (id: ${g.id})`);
3575
+ }
3576
+ return {
3577
+ content: [{ type: "text", text: lines.join("\n") }],
3578
+ details: { ok: true, goals }
3579
+ };
3580
+ }
3581
+ },
3582
+ // 10. remote_create_goal
3583
+ {
3584
+ name: "remote_create_goal",
3585
+ label: "Create a goal on the Remote project board",
3586
+ description: "Create a new goal on the Remote project board. Specify title, and optionally description, success_criteria, parent_id (for sub-goals), owner_role_id, and target_date.",
3587
+ parameters: Type.Object({
3588
+ title: Type.String({ description: "Goal title" }),
3589
+ description: Type.Optional(Type.String({ description: "Goal description" })),
3590
+ success_criteria: Type.Optional(Type.String({ description: "How to measure achievement" })),
3591
+ parent_id: Type.Optional(Type.String({ description: "Parent goal ID (for sub-goals)" })),
3592
+ owner_role_id: Type.Optional(Type.String({ description: "Role ID that owns this goal" })),
3593
+ target_date: Type.Optional(Type.String({ description: "Target date (ISO format)" }))
3594
+ }),
3595
+ execute: async (_toolCallId, args) => {
3596
+ const account = resolveToolAccount();
3597
+ const result = await createGoal(account, {
3598
+ title: args.title,
3599
+ description: args.description,
3600
+ success_criteria: args.success_criteria,
3601
+ parent_id: args.parent_id,
3602
+ owner_role_id: args.owner_role_id,
3603
+ target_date: args.target_date
3604
+ });
3605
+ if (!result.ok) {
3606
+ return {
3607
+ content: [{ type: "text", text: `\u274C Failed to create goal: ${result.error}` }],
3608
+ details: { ok: false, error: result.error }
3609
+ };
3610
+ }
3611
+ const goal = result.data.goal;
3612
+ const text = [
3613
+ `\u2705 Goal created!`,
3614
+ `- **Title**: ${goal.title}`,
3615
+ `- **ID**: ${goal.id}`,
3616
+ `- **Status**: ${goal.status}`,
3617
+ goal.parent_id ? `- **Parent**: ${goal.parent_id}` : null
3618
+ ].filter(Boolean).join("\n");
3619
+ return {
3620
+ content: [{ type: "text", text }],
3621
+ details: { ok: true, goal }
3622
+ };
3623
+ }
3624
+ },
3625
+ // 11. remote_update_goal
3626
+ {
3627
+ name: "remote_update_goal",
3628
+ label: "Update a goal on the Remote project board",
3629
+ description: "Update an existing goal. Specify goal_id and any fields to change: title, description, status (active/achieved/abandoned), success_criteria, target_date, owner_role_id.",
3630
+ parameters: Type.Object({
3631
+ goal_id: Type.String({ description: "ID of the goal to update" }),
3632
+ title: Type.Optional(Type.String({ description: "New goal title" })),
3633
+ description: Type.Optional(Type.String({ description: "New description" })),
3634
+ status: optionalStringEnum(["active", "achieved", "abandoned"], {
3635
+ description: "New status: active, achieved, or abandoned"
3636
+ }),
3637
+ success_criteria: Type.Optional(Type.String({ description: "New success criteria" })),
3638
+ target_date: Type.Optional(Type.String({ description: "New target date (ISO format)" })),
3639
+ owner_role_id: Type.Optional(Type.String({ description: "New owner role ID" }))
3640
+ }),
3641
+ execute: async (_toolCallId, args) => {
3642
+ const account = resolveToolAccount();
3643
+ const { goal_id, ...updates } = args;
3644
+ const result = await updateGoal(account, goal_id, updates);
3645
+ if (!result.ok) {
3646
+ return {
3647
+ content: [{ type: "text", text: `\u274C Failed to update goal: ${result.error}` }],
3648
+ details: { ok: false, error: result.error }
3649
+ };
3650
+ }
3651
+ const goal = result.data.goal;
3652
+ const text = [
3653
+ `\u2705 Goal updated!`,
3654
+ `- **Title**: ${goal.title}`,
3655
+ `- **Status**: ${goal.status}`,
3656
+ `- **Progress**: ${goal.progress}%`
3657
+ ].join("\n");
3658
+ return {
3659
+ content: [{ type: "text", text }],
3660
+ details: { ok: true, goal }
3661
+ };
3662
+ }
3488
3663
  }
3489
3664
  ];
3490
3665
  }),
@@ -3497,14 +3672,17 @@ function createRemotePlugin() {
3497
3672
  "**Replying**: When you reply to a task notification, your reply is posted as a comment on that task.",
3498
3673
  "",
3499
3674
  "**Available tools**:",
3500
- "- `remote_create_task` \u2014 Create a new task (title, type, priority, assigned_role_id, epic_id)",
3501
- "- `remote_update_task` \u2014 Update a task (status, priority, title, description, type, epic_id, assigned_role_id)",
3675
+ "- `remote_create_task` \u2014 Create a new task (title, type, priority, assigned_role_id, epic_id, goal_id)",
3676
+ "- `remote_update_task` \u2014 Update a task (status, priority, title, description, type, epic_id, goal_id, assigned_role_id)",
3502
3677
  "- `remote_list_tasks` \u2014 List/filter tasks on the board",
3503
3678
  "- `remote_board_health` \u2014 Get board health stats (task counts, epics, roles, recent activity)",
3504
3679
  "- `remote_list_roles` \u2014 List project roles with vacancy info (find valid assigned_role_id values)",
3505
3680
  "- `remote_list_epics` \u2014 List epics with task counts (find valid epic_id values)",
3506
3681
  "- `remote_create_epic` \u2014 Create a new epic (name, description, color)",
3507
3682
  "- `remote_list_team` \u2014 List all team members with roles and @mention handles",
3683
+ "- `remote_list_goals` \u2014 List goals with progress (filter by status, parent_id, assigned_to)",
3684
+ "- `remote_create_goal` \u2014 Create a goal (title, description, success_criteria, parent_id, owner_role_id, target_date)",
3685
+ "- `remote_update_goal` \u2014 Update a goal (status, title, description, success_criteria, target_date, owner_role_id)",
3508
3686
  "",
3509
3687
  "**Task lifecycle**: todo \u2192 in_progress \u2192 review \u2192 done",
3510
3688
  "**Task types**: feature, task, bug",
@@ -3518,7 +3696,10 @@ function createRemotePlugin() {
3518
3696
  "- Use `remote_list_roles` before creating tasks to find valid role IDs for assignment",
3519
3697
  "- Use `remote_list_epics` before creating tasks to find valid epic IDs for grouping",
3520
3698
  "- Use `remote_list_team` to find teammates and their @mention handles for tagging in comments",
3521
- "- Tag team members with @name in comments when you need their input or want to delegate"
3699
+ "- Tag team members with @name in comments when you need their input or want to delegate",
3700
+ "- Use `remote_list_goals` to see goal hierarchy and progress",
3701
+ "- Goals auto-calculate progress from linked tasks (leaf goals) or child goals",
3702
+ "- Link tasks to goals with goal_id when creating or updating tasks"
3522
3703
  ]
3523
3704
  }
3524
3705
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-remote",
3
- "version": "0.5.5",
3
+ "version": "0.5.6",
4
4
  "description": "Remote project board channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",