openclaw-remote 0.5.4 → 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.
- package/dist/index.js +199 -13
- 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 {
|
|
@@ -3167,11 +3206,11 @@ function createRemotePlugin() {
|
|
|
3167
3206
|
{
|
|
3168
3207
|
name: "remote_update_task",
|
|
3169
3208
|
label: "Update a task on the Remote project board",
|
|
3170
|
-
description: "Update an existing task on the Remote project board. Specify the task_id and any fields to change: status (todo/in_progress/review/done), priority, assigned_to, title, description, type, epic_id, or assigned_role_id.",
|
|
3209
|
+
description: "Update an existing task on the Remote project board. Specify the task_id and any fields to change: status (todo/in_progress/blocked/review/done), priority, assigned_to, title, description, type, epic_id, or assigned_role_id.",
|
|
3171
3210
|
parameters: Type.Object({
|
|
3172
3211
|
task_id: Type.String({ description: "ID of the task to update" }),
|
|
3173
|
-
status: optionalStringEnum(["todo", "in_progress", "review", "done"], {
|
|
3174
|
-
description: "New status: todo, in_progress, review, or done"
|
|
3212
|
+
status: optionalStringEnum(["todo", "in_progress", "blocked", "review", "done"], {
|
|
3213
|
+
description: "New status: todo, in_progress, blocked, review, or done"
|
|
3175
3214
|
}),
|
|
3176
3215
|
priority: optionalStringEnum(["low", "medium", "high", "urgent"], {
|
|
3177
3216
|
description: "New priority: low, medium, high, or urgent"
|
|
@@ -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
|
)
|
|
@@ -3219,10 +3261,10 @@ function createRemotePlugin() {
|
|
|
3219
3261
|
{
|
|
3220
3262
|
name: "remote_list_tasks",
|
|
3221
3263
|
label: "List tasks on the Remote project board",
|
|
3222
|
-
description: "List tasks on the Remote project board. Optionally filter by status (todo/in_progress/review/done) and assigned_to (use 'me' for tasks assigned to the agent).",
|
|
3264
|
+
description: "List tasks on the Remote project board. Optionally filter by status (todo/in_progress/blocked/review/done) and assigned_to (use 'me' for tasks assigned to the agent).",
|
|
3223
3265
|
parameters: Type.Object({
|
|
3224
|
-
status: optionalStringEnum(["todo", "in_progress", "review", "done"], {
|
|
3225
|
-
description: "Filter by status: todo, in_progress, review, or done"
|
|
3266
|
+
status: optionalStringEnum(["todo", "in_progress", "blocked", "review", "done"], {
|
|
3267
|
+
description: "Filter by status: todo, in_progress, blocked, review, or done"
|
|
3226
3268
|
}),
|
|
3227
3269
|
assigned_to: Type.Optional(
|
|
3228
3270
|
Type.String({ description: "Filter by assignee. Use 'me' for self." })
|
|
@@ -3309,7 +3351,7 @@ function createRemotePlugin() {
|
|
|
3309
3351
|
`\u{1F4CA} **Board Health \u2014 ${h.project.name}**`,
|
|
3310
3352
|
"",
|
|
3311
3353
|
`**Tasks** (${s.total_tasks} total):`,
|
|
3312
|
-
` todo: ${s.by_status.todo} | in_progress: ${s.by_status.in_progress} | review: ${s.by_status.review} | done: ${s.by_status.done}`,
|
|
3354
|
+
` todo: ${s.by_status.todo} | in_progress: ${s.by_status.in_progress} | blocked: ${s.by_status.blocked || 0} | review: ${s.by_status.review} | done: ${s.by_status.done}`,
|
|
3313
3355
|
` unassigned: ${s.unassigned}`,
|
|
3314
3356
|
"",
|
|
3315
3357
|
`**By priority**: urgent: ${s.by_priority.urgent} | high: ${s.by_priority.high} | medium: ${s.by_priority.medium} | low: ${s.by_priority.low}`
|
|
@@ -3470,16 +3512,154 @@ function createRemotePlugin() {
|
|
|
3470
3512
|
}
|
|
3471
3513
|
const lines = [`\u{1F465} **Team** (${total} members: ${humans} human, ${agents} agent)`, ""];
|
|
3472
3514
|
for (const m of team) {
|
|
3473
|
-
const
|
|
3515
|
+
const roleDetails = m.project_roles.length > 0 ? m.project_roles.map((r) => {
|
|
3516
|
+
let detail = r.name;
|
|
3517
|
+
if (r.manager) detail += ` (reports to: ${r.manager.name})`;
|
|
3518
|
+
if (r.direct_reports?.length > 0) detail += ` [${r.direct_reports.length} direct report(s)]`;
|
|
3519
|
+
return detail;
|
|
3520
|
+
}).join(", ") : "no role";
|
|
3474
3521
|
const me = m.is_me ? " \u2B50 (you)" : "";
|
|
3475
3522
|
const status = m.type === "agent" && m.status ? ` [${m.status}]` : "";
|
|
3476
|
-
lines.push(`- **${m.name}** (${m.type}${status}) \u2014 ${
|
|
3523
|
+
lines.push(`- **${m.name}** (${m.type}${status}) \u2014 ${roleDetails} \u2014 mention: \`${m.mention}\`${me}`);
|
|
3477
3524
|
}
|
|
3478
3525
|
return {
|
|
3479
3526
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
3480
3527
|
details: { ok: true, team, total, humans, agents }
|
|
3481
3528
|
};
|
|
3482
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
|
+
}
|
|
3483
3663
|
}
|
|
3484
3664
|
];
|
|
3485
3665
|
}),
|
|
@@ -3492,14 +3672,17 @@ function createRemotePlugin() {
|
|
|
3492
3672
|
"**Replying**: When you reply to a task notification, your reply is posted as a comment on that task.",
|
|
3493
3673
|
"",
|
|
3494
3674
|
"**Available tools**:",
|
|
3495
|
-
"- `remote_create_task` \u2014 Create a new task (title, type, priority, assigned_role_id, epic_id)",
|
|
3496
|
-
"- `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)",
|
|
3497
3677
|
"- `remote_list_tasks` \u2014 List/filter tasks on the board",
|
|
3498
3678
|
"- `remote_board_health` \u2014 Get board health stats (task counts, epics, roles, recent activity)",
|
|
3499
3679
|
"- `remote_list_roles` \u2014 List project roles with vacancy info (find valid assigned_role_id values)",
|
|
3500
3680
|
"- `remote_list_epics` \u2014 List epics with task counts (find valid epic_id values)",
|
|
3501
3681
|
"- `remote_create_epic` \u2014 Create a new epic (name, description, color)",
|
|
3502
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)",
|
|
3503
3686
|
"",
|
|
3504
3687
|
"**Task lifecycle**: todo \u2192 in_progress \u2192 review \u2192 done",
|
|
3505
3688
|
"**Task types**: feature, task, bug",
|
|
@@ -3513,7 +3696,10 @@ function createRemotePlugin() {
|
|
|
3513
3696
|
"- Use `remote_list_roles` before creating tasks to find valid role IDs for assignment",
|
|
3514
3697
|
"- Use `remote_list_epics` before creating tasks to find valid epic IDs for grouping",
|
|
3515
3698
|
"- Use `remote_list_team` to find teammates and their @mention handles for tagging in comments",
|
|
3516
|
-
"- 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"
|
|
3517
3703
|
]
|
|
3518
3704
|
}
|
|
3519
3705
|
};
|