Add dual-prefix AI command

This commit is contained in:
Codex
2026-05-14 13:24:47 +02:00
parent 27b2760079
commit 2a731600e0
16 changed files with 607 additions and 16 deletions

View File

@@ -82,7 +82,8 @@ def shared_access_check() -> CommandCheck:
return CheckResult.deny("Permission store is not initialized")
if store.is_allowed(ctx.actor_id, ctx.command.name):
return CheckResult.allow()
return CheckResult.deny(f"No access to {ctx.command.prefix}{ctx.command.name}")
required_prefix = ctx.command.expected_prefix(ctx.is_owner)
return CheckResult.deny(f"No access to {required_prefix}{ctx.command.name}")
return CommandCheck("shared_access", _check, "Allow owner or ACL-granted users")
@@ -185,7 +186,8 @@ class CommandDefinition:
name: str
description: str
handler: CommandHandler
prefix: str = "."
owner_prefix: str = "."
guest_prefix: str | None = None
aliases: tuple[str, ...] = ()
usage: str | None = None
category: str = "general"
@@ -193,11 +195,21 @@ class CommandDefinition:
@property
def is_shared(self) -> bool:
return self.prefix == ".."
return self.guest_prefix is not None
@property
def display_name(self) -> str:
return f"{self.prefix}{self.name}"
if self.guest_prefix is None:
return f"{self.owner_prefix}{self.name}"
return f"{self.owner_prefix}{self.name} / {self.guest_prefix}{self.name}"
def expected_prefix(self, is_owner: bool) -> str:
if self.guest_prefix is None:
return self.owner_prefix
return self.owner_prefix if is_owner else self.guest_prefix
def accepts_prefix(self, prefix: str, *, is_owner: bool) -> bool:
return prefix == self.expected_prefix(is_owner)
def help_line(self, ctx: CommandContext | None = None) -> str:
usage = self.usage or self.display_name
@@ -231,15 +243,16 @@ class CommandBuilder:
self.aliases = [normalize_command_name(alias) for alias in aliases]
self.usage = usage
self.category = category
self.prefix = "."
self.owner_prefix = "."
self.guest_prefix: str | None = None
self.checks: list[CommandCheck] = []
def private(self) -> "CommandBuilder":
self.prefix = "."
self.guest_prefix = None
return self
def shared(self) -> "CommandBuilder":
self.prefix = ".."
self.guest_prefix = ".."
return self
def alias(self, *aliases: str) -> "CommandBuilder":
@@ -264,7 +277,7 @@ class CommandBuilder:
def build(self, handler: CommandHandler) -> CommandDefinition:
default_checks: list[CommandCheck] = []
if self.prefix == "..":
if self.guest_prefix is not None:
default_checks.append(shared_access_check())
else:
default_checks.append(owner_only_check())
@@ -273,7 +286,8 @@ class CommandBuilder:
name=self.name,
description=self.description,
handler=handler,
prefix=self.prefix,
owner_prefix=self.owner_prefix,
guest_prefix=self.guest_prefix,
aliases=tuple(self.aliases),
usage=self.usage,
category=self.category,