mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 04:47:03 -06:00
f63f2fd3db
* fix(reef): require owner for management commands * fix(reef): preserve general command access * fix: preserve explicit owner authority * fix(discord): separate voice admission from ownership * docs(reef): explain owner command recovery * docs(reef): clarify owner recovery paths
80 lines
3.2 KiB
TypeScript
80 lines
3.2 KiB
TypeScript
import { ReefAutonomySchema } from "./friend-types.js";
|
|
import { getActiveReef } from "./runtime.js";
|
|
|
|
export async function handleReefCommand({
|
|
args,
|
|
senderIsOwner,
|
|
}: {
|
|
args?: string;
|
|
senderIsOwner?: boolean;
|
|
}): Promise<{ text: string }> {
|
|
const words = (args ?? "").trim().split(/\s+/).filter(Boolean);
|
|
const changesFriendship =
|
|
words[0] === "friend" && /^(code|request|remove|block|autonomy)$/.test(words[1] ?? "");
|
|
const decidesReview = words[0] === "review" && /^(approve|deny)$/.test(words[1] ?? "");
|
|
if ((changesFriendship || decidesReview) && senderIsOwner !== true) {
|
|
return {
|
|
text: "Only an owner in commands.ownerAllowFrom can change Reef friends or decide reviews. Ask a configured owner; friendship changes can also use openclaw reef locally.",
|
|
};
|
|
}
|
|
const active = getActiveReef();
|
|
if (words[0] === "friend" && words[1] === "code") {
|
|
const minted = await active.friends.mintCode();
|
|
return {
|
|
text: `Reef friend code: ${minted.code} (expires ${new Date(minted.expires * 1000).toISOString()})`,
|
|
};
|
|
}
|
|
if (words[0] === "friend" && words[1] === "request" && words[2]) {
|
|
await active.friends.request(words[2].replace(/^@/, "").toLowerCase(), words[3]);
|
|
return { text: "Reef friend request submitted." };
|
|
}
|
|
if (words[0] === "friend" && words[1] === "list") {
|
|
const friends = await active.friends.list();
|
|
return {
|
|
text: friends.length
|
|
? friends
|
|
.map(
|
|
(friend) =>
|
|
`@${friend.peer} ${friend.status} epoch=${friend.key_epoch} fingerprint=${friend.fingerprint} autonomy=${friend.autonomy ?? "unapproved"}`,
|
|
)
|
|
.join("\n")
|
|
: "No Reef friends.",
|
|
};
|
|
}
|
|
if (words[0] === "friend" && /^(remove|block)$/.test(words[1] ?? "") && words[2]) {
|
|
const peer = words[2].replace(/^@/, "").toLowerCase();
|
|
await active.friends.remove(peer);
|
|
return { text: `Reef friend @${peer} blocked and removed locally.` };
|
|
}
|
|
if (words[0] === "friend" && words[1] === "autonomy" && words[2] && words[3]) {
|
|
const peer = words[2].replace(/^@/, "").toLowerCase();
|
|
const autonomy = ReefAutonomySchema.parse(words[3]);
|
|
await active.friends.setAutonomy(peer, autonomy);
|
|
return { text: `Reef friend @${peer} autonomy set to ${autonomy}.` };
|
|
}
|
|
if (words[0] === "review" && words[1] === "list") {
|
|
const reviews = await active.reviews.list();
|
|
return {
|
|
text: reviews.length
|
|
? reviews
|
|
.map(
|
|
(review) =>
|
|
`${review.approvalDigest} ${review.direction} ${review.from} -> ${review.to} ${review.verdict.category}`,
|
|
)
|
|
.join("\n")
|
|
: "No pending Reef reviews.",
|
|
};
|
|
}
|
|
if (words[0] === "review" && /^(approve|deny)$/.test(words[1] ?? "") && words[2]) {
|
|
const found = await active.reviews.decide(words[2], words[1] === "approve");
|
|
return {
|
|
text: found
|
|
? `Reef review ${words[1]}d. Retry the identical message to re-run the guard.`
|
|
: "Unknown Reef approval digest.",
|
|
};
|
|
}
|
|
return {
|
|
text: "Usage: /reef friend code|request <handle> [code]|list|remove <handle>|autonomy <handle> <notify-only|bounded|extended>; /reef review list|approve <digest>|deny <digest>",
|
|
};
|
|
}
|