openclaw-remote 0.5.5 → 0.5.7
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 +238 -4
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2781,6 +2781,55 @@ 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
|
+
}
|
|
2819
|
+
async function updateRoleBundle(account, roleId, data) {
|
|
2820
|
+
return apiFetch(
|
|
2821
|
+
buildUrl(account, `/api/v1/roles/${encodeURIComponent(roleId)}/bundle`),
|
|
2822
|
+
{
|
|
2823
|
+
method: "PATCH",
|
|
2824
|
+
headers: buildHeaders(account),
|
|
2825
|
+
body: JSON.stringify({
|
|
2826
|
+
bundle_slug: data.bundle_slug,
|
|
2827
|
+
bundle_version: data.bundle_version,
|
|
2828
|
+
status: data.generation_status
|
|
2829
|
+
})
|
|
2830
|
+
}
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2784
2833
|
async function getTeam(account) {
|
|
2785
2834
|
return apiFetch(
|
|
2786
2835
|
buildUrl(account, "/api/v1/team"),
|
|
@@ -3130,6 +3179,9 @@ function createRemotePlugin() {
|
|
|
3130
3179
|
),
|
|
3131
3180
|
epic_id: Type.Optional(
|
|
3132
3181
|
Type.String({ description: "Epic ID to group the task under" })
|
|
3182
|
+
),
|
|
3183
|
+
goal_id: Type.Optional(
|
|
3184
|
+
Type.String({ description: "Goal ID to link the task to" })
|
|
3133
3185
|
)
|
|
3134
3186
|
}),
|
|
3135
3187
|
execute: async (_toolCallId, args) => {
|
|
@@ -3140,7 +3192,8 @@ function createRemotePlugin() {
|
|
|
3140
3192
|
type: args.type,
|
|
3141
3193
|
priority: args.priority,
|
|
3142
3194
|
assigned_role_id: args.assigned_role_id,
|
|
3143
|
-
epic_id: args.epic_id
|
|
3195
|
+
epic_id: args.epic_id,
|
|
3196
|
+
goal_id: args.goal_id
|
|
3144
3197
|
});
|
|
3145
3198
|
if (!result.ok) {
|
|
3146
3199
|
return {
|
|
@@ -3187,6 +3240,9 @@ function createRemotePlugin() {
|
|
|
3187
3240
|
epic_id: Type.Optional(
|
|
3188
3241
|
Type.String({ description: "Epic ID to group the task under (or null to remove)" })
|
|
3189
3242
|
),
|
|
3243
|
+
goal_id: Type.Optional(
|
|
3244
|
+
Type.String({ description: "Goal ID to link the task to (or null to remove)" })
|
|
3245
|
+
),
|
|
3190
3246
|
assigned_role_id: Type.Optional(
|
|
3191
3247
|
Type.String({ description: "Role ID to assign the task to" })
|
|
3192
3248
|
)
|
|
@@ -3485,6 +3541,177 @@ function createRemotePlugin() {
|
|
|
3485
3541
|
details: { ok: true, team, total, humans, agents }
|
|
3486
3542
|
};
|
|
3487
3543
|
}
|
|
3544
|
+
},
|
|
3545
|
+
// 9. remote_list_goals
|
|
3546
|
+
{
|
|
3547
|
+
name: "remote_list_goals",
|
|
3548
|
+
label: "List goals on the Remote project board",
|
|
3549
|
+
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).",
|
|
3550
|
+
parameters: Type.Object({
|
|
3551
|
+
status: optionalStringEnum(["active", "achieved", "abandoned"], {
|
|
3552
|
+
description: "Filter by status: active, achieved, or abandoned"
|
|
3553
|
+
}),
|
|
3554
|
+
parent_id: Type.Optional(
|
|
3555
|
+
Type.String({ description: "Filter by parent goal ID. Use 'null' for top-level goals." })
|
|
3556
|
+
),
|
|
3557
|
+
assigned_to: Type.Optional(
|
|
3558
|
+
Type.String({ description: "Filter by assignee. Use 'me' for goals owned by your roles." })
|
|
3559
|
+
)
|
|
3560
|
+
}),
|
|
3561
|
+
execute: async (_toolCallId, args) => {
|
|
3562
|
+
const account = resolveToolAccount();
|
|
3563
|
+
const result = await getGoals(account, {
|
|
3564
|
+
status: args.status,
|
|
3565
|
+
parent_id: args.parent_id,
|
|
3566
|
+
assigned_to: args.assigned_to
|
|
3567
|
+
});
|
|
3568
|
+
if (!result.ok) {
|
|
3569
|
+
return {
|
|
3570
|
+
content: [{ type: "text", text: `\u274C Failed to list goals: ${result.error}` }],
|
|
3571
|
+
details: { ok: false, error: result.error }
|
|
3572
|
+
};
|
|
3573
|
+
}
|
|
3574
|
+
const goals = result.data.goals;
|
|
3575
|
+
if (goals.length === 0) {
|
|
3576
|
+
return {
|
|
3577
|
+
content: [{ type: "text", text: `\u{1F3AF} No goals found.` }],
|
|
3578
|
+
details: { ok: true, goals: [] }
|
|
3579
|
+
};
|
|
3580
|
+
}
|
|
3581
|
+
const lines = [`\u{1F3AF} **${goals.length} goal(s):**`, ""];
|
|
3582
|
+
for (const g of goals) {
|
|
3583
|
+
const pct = g.progress ?? 0;
|
|
3584
|
+
const bar = "\u2588".repeat(Math.round(pct / 10)) + "\u2591".repeat(10 - Math.round(pct / 10));
|
|
3585
|
+
const role = g.project_roles?.role_name || "";
|
|
3586
|
+
const date = g.target_date ? ` \u{1F3AF} ${new Date(g.target_date).toLocaleDateString()}` : "";
|
|
3587
|
+
const kids = g.children_count ? ` (${g.children_count} sub-goals)` : "";
|
|
3588
|
+
lines.push(`- **${g.title}** [${g.status}] ${bar} ${pct}%${role ? ` \u2014 ${role}` : ""}${date}${kids} (id: ${g.id})`);
|
|
3589
|
+
}
|
|
3590
|
+
return {
|
|
3591
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
3592
|
+
details: { ok: true, goals }
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3595
|
+
},
|
|
3596
|
+
// 10. remote_create_goal
|
|
3597
|
+
{
|
|
3598
|
+
name: "remote_create_goal",
|
|
3599
|
+
label: "Create a goal on the Remote project board",
|
|
3600
|
+
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.",
|
|
3601
|
+
parameters: Type.Object({
|
|
3602
|
+
title: Type.String({ description: "Goal title" }),
|
|
3603
|
+
description: Type.Optional(Type.String({ description: "Goal description" })),
|
|
3604
|
+
success_criteria: Type.Optional(Type.String({ description: "How to measure achievement" })),
|
|
3605
|
+
parent_id: Type.Optional(Type.String({ description: "Parent goal ID (for sub-goals)" })),
|
|
3606
|
+
owner_role_id: Type.Optional(Type.String({ description: "Role ID that owns this goal" })),
|
|
3607
|
+
target_date: Type.Optional(Type.String({ description: "Target date (ISO format)" }))
|
|
3608
|
+
}),
|
|
3609
|
+
execute: async (_toolCallId, args) => {
|
|
3610
|
+
const account = resolveToolAccount();
|
|
3611
|
+
const result = await createGoal(account, {
|
|
3612
|
+
title: args.title,
|
|
3613
|
+
description: args.description,
|
|
3614
|
+
success_criteria: args.success_criteria,
|
|
3615
|
+
parent_id: args.parent_id,
|
|
3616
|
+
owner_role_id: args.owner_role_id,
|
|
3617
|
+
target_date: args.target_date
|
|
3618
|
+
});
|
|
3619
|
+
if (!result.ok) {
|
|
3620
|
+
return {
|
|
3621
|
+
content: [{ type: "text", text: `\u274C Failed to create goal: ${result.error}` }],
|
|
3622
|
+
details: { ok: false, error: result.error }
|
|
3623
|
+
};
|
|
3624
|
+
}
|
|
3625
|
+
const goal = result.data.goal;
|
|
3626
|
+
const text = [
|
|
3627
|
+
`\u2705 Goal created!`,
|
|
3628
|
+
`- **Title**: ${goal.title}`,
|
|
3629
|
+
`- **ID**: ${goal.id}`,
|
|
3630
|
+
`- **Status**: ${goal.status}`,
|
|
3631
|
+
goal.parent_id ? `- **Parent**: ${goal.parent_id}` : null
|
|
3632
|
+
].filter(Boolean).join("\n");
|
|
3633
|
+
return {
|
|
3634
|
+
content: [{ type: "text", text }],
|
|
3635
|
+
details: { ok: true, goal }
|
|
3636
|
+
};
|
|
3637
|
+
}
|
|
3638
|
+
},
|
|
3639
|
+
// 11. remote_update_goal
|
|
3640
|
+
{
|
|
3641
|
+
name: "remote_update_goal",
|
|
3642
|
+
label: "Update a goal on the Remote project board",
|
|
3643
|
+
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.",
|
|
3644
|
+
parameters: Type.Object({
|
|
3645
|
+
goal_id: Type.String({ description: "ID of the goal to update" }),
|
|
3646
|
+
title: Type.Optional(Type.String({ description: "New goal title" })),
|
|
3647
|
+
description: Type.Optional(Type.String({ description: "New description" })),
|
|
3648
|
+
status: optionalStringEnum(["active", "achieved", "abandoned"], {
|
|
3649
|
+
description: "New status: active, achieved, or abandoned"
|
|
3650
|
+
}),
|
|
3651
|
+
success_criteria: Type.Optional(Type.String({ description: "New success criteria" })),
|
|
3652
|
+
target_date: Type.Optional(Type.String({ description: "New target date (ISO format)" })),
|
|
3653
|
+
owner_role_id: Type.Optional(Type.String({ description: "New owner role ID" }))
|
|
3654
|
+
}),
|
|
3655
|
+
execute: async (_toolCallId, args) => {
|
|
3656
|
+
const account = resolveToolAccount();
|
|
3657
|
+
const { goal_id, ...updates } = args;
|
|
3658
|
+
const result = await updateGoal(account, goal_id, updates);
|
|
3659
|
+
if (!result.ok) {
|
|
3660
|
+
return {
|
|
3661
|
+
content: [{ type: "text", text: `\u274C Failed to update goal: ${result.error}` }],
|
|
3662
|
+
details: { ok: false, error: result.error }
|
|
3663
|
+
};
|
|
3664
|
+
}
|
|
3665
|
+
const goal = result.data.goal;
|
|
3666
|
+
const text = [
|
|
3667
|
+
`\u2705 Goal updated!`,
|
|
3668
|
+
`- **Title**: ${goal.title}`,
|
|
3669
|
+
`- **Status**: ${goal.status}`,
|
|
3670
|
+
`- **Progress**: ${goal.progress}%`
|
|
3671
|
+
].join("\n");
|
|
3672
|
+
return {
|
|
3673
|
+
content: [{ type: "text", text }],
|
|
3674
|
+
details: { ok: true, goal }
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3677
|
+
},
|
|
3678
|
+
// remote_update_role — update role bundle info (agent callback)
|
|
3679
|
+
{
|
|
3680
|
+
name: "remote_update_role",
|
|
3681
|
+
label: "Update a role's agent bundle info",
|
|
3682
|
+
description: "Update a role's bundle_slug, bundle_version, and generation_status. Used by the agent-builder to report back after generating a bundle.",
|
|
3683
|
+
parameters: Type.Object({
|
|
3684
|
+
role_id: Type.String({ description: "ID of the role to update" }),
|
|
3685
|
+
bundle_slug: Type.Optional(Type.String({ description: "Published bundle slug (e.g. @org/agent-name)" })),
|
|
3686
|
+
bundle_version: Type.Optional(Type.String({ description: "Published bundle version" })),
|
|
3687
|
+
generation_status: optionalStringEnum(["published", "failed"], {
|
|
3688
|
+
description: "Generation status: published or failed"
|
|
3689
|
+
})
|
|
3690
|
+
}),
|
|
3691
|
+
execute: async (_toolCallId, args) => {
|
|
3692
|
+
const account = resolveToolAccount();
|
|
3693
|
+
const result = await updateRoleBundle(account, args.role_id, {
|
|
3694
|
+
bundle_slug: args.bundle_slug,
|
|
3695
|
+
bundle_version: args.bundle_version,
|
|
3696
|
+
generation_status: args.generation_status
|
|
3697
|
+
});
|
|
3698
|
+
if (!result.ok) {
|
|
3699
|
+
return {
|
|
3700
|
+
content: [{ type: "text", text: `\u274C Failed to update role bundle: ${result.error}` }],
|
|
3701
|
+
details: { ok: false, error: result.error }
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
const text = [
|
|
3705
|
+
`\u2705 Role bundle updated!`,
|
|
3706
|
+
args.bundle_slug ? `- **Bundle**: ${args.bundle_slug}` : "",
|
|
3707
|
+
args.bundle_version ? `- **Version**: ${args.bundle_version}` : "",
|
|
3708
|
+
args.generation_status ? `- **Status**: ${args.generation_status}` : ""
|
|
3709
|
+
].filter(Boolean).join("\n");
|
|
3710
|
+
return {
|
|
3711
|
+
content: [{ type: "text", text }],
|
|
3712
|
+
details: { ok: true }
|
|
3713
|
+
};
|
|
3714
|
+
}
|
|
3488
3715
|
}
|
|
3489
3716
|
];
|
|
3490
3717
|
}),
|
|
@@ -3497,14 +3724,18 @@ function createRemotePlugin() {
|
|
|
3497
3724
|
"**Replying**: When you reply to a task notification, your reply is posted as a comment on that task.",
|
|
3498
3725
|
"",
|
|
3499
3726
|
"**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)",
|
|
3727
|
+
"- `remote_create_task` \u2014 Create a new task (title, type, priority, assigned_role_id, epic_id, goal_id)",
|
|
3728
|
+
"- `remote_update_task` \u2014 Update a task (status, priority, title, description, type, epic_id, goal_id, assigned_role_id)",
|
|
3502
3729
|
"- `remote_list_tasks` \u2014 List/filter tasks on the board",
|
|
3503
3730
|
"- `remote_board_health` \u2014 Get board health stats (task counts, epics, roles, recent activity)",
|
|
3504
3731
|
"- `remote_list_roles` \u2014 List project roles with vacancy info (find valid assigned_role_id values)",
|
|
3505
3732
|
"- `remote_list_epics` \u2014 List epics with task counts (find valid epic_id values)",
|
|
3506
3733
|
"- `remote_create_epic` \u2014 Create a new epic (name, description, color)",
|
|
3507
3734
|
"- `remote_list_team` \u2014 List all team members with roles and @mention handles",
|
|
3735
|
+
"- `remote_list_goals` \u2014 List goals with progress (filter by status, parent_id, assigned_to)",
|
|
3736
|
+
"- `remote_create_goal` \u2014 Create a goal (title, description, success_criteria, parent_id, owner_role_id, target_date)",
|
|
3737
|
+
"- `remote_update_goal` \u2014 Update a goal (status, title, description, success_criteria, target_date, owner_role_id)",
|
|
3738
|
+
"- `remote_update_role` \u2014 Update a role's bundle info (bundle_slug, bundle_version, generation_status)",
|
|
3508
3739
|
"",
|
|
3509
3740
|
"**Task lifecycle**: todo \u2192 in_progress \u2192 review \u2192 done",
|
|
3510
3741
|
"**Task types**: feature, task, bug",
|
|
@@ -3518,7 +3749,10 @@ function createRemotePlugin() {
|
|
|
3518
3749
|
"- Use `remote_list_roles` before creating tasks to find valid role IDs for assignment",
|
|
3519
3750
|
"- Use `remote_list_epics` before creating tasks to find valid epic IDs for grouping",
|
|
3520
3751
|
"- 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"
|
|
3752
|
+
"- Tag team members with @name in comments when you need their input or want to delegate",
|
|
3753
|
+
"- Use `remote_list_goals` to see goal hierarchy and progress",
|
|
3754
|
+
"- Goals auto-calculate progress from linked tasks (leaf goals) or child goals",
|
|
3755
|
+
"- Link tasks to goals with goal_id when creating or updating tasks"
|
|
3522
3756
|
]
|
|
3523
3757
|
}
|
|
3524
3758
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-remote",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "Remote project board channel plugin for OpenClaw",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,4 +25,4 @@
|
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"openclaw": "*"
|
|
27
27
|
}
|
|
28
|
-
}
|
|
28
|
+
}
|