diff --git a/.lane/memory/apps/app/src/channel-access.tsx/01M4Z0MYCGYFJFDF7MQ7VKM91D-access-copy-must-not-imply-t.md b/.lane/memory/apps/app/src/channel-access.tsx/01M4Z0MYCGYFJFDF7MQ7VKM91D-access-copy-must-not-imply-t.md index 3bad6b2d..65752d42 100644 --- a/.lane/memory/apps/app/src/channel-access.tsx/01M4Z0MYCGYFJFDF7MQ7VKM91D-access-copy-must-not-imply-t.md +++ b/.lane/memory/apps/app/src/channel-access.tsx/01M4Z0MYCGYFJFDF7MQ7VKM91D-access-copy-must-not-imply-t.md @@ -4,9 +4,9 @@ anchor: function ChannelAccess created: 2026-10-15T05:30:36Z norm: '1' sig: d9bb90f2534024f3 -body_hash: d071cf690a8fbaab -raw_hash: 5df6168beeb7cbb9 -vouched: 2026-10-16T21:22:40Z +body_hash: 5fc15bf520c64275 +raw_hash: 45ec44a5e2b7a0ee +vouched: 2026-10-22T14:31:33Z lines: 63-136 --- diff --git a/.lane/memory/apps/host/src/cli.ts/01M4YY5SXJFQK8VXT78X1E0KAE-every-command-but-serve-must.md b/.lane/memory/apps/host/src/cli.ts/01M4YY5SXJFQK8VXT78X1E0KAE-every-command-but-serve-must.md index 9b9f24de..fa79c66b 100644 --- a/.lane/memory/apps/host/src/cli.ts/01M4YY5SXJFQK8VXT78X1E0KAE-every-command-but-serve-must.md +++ b/.lane/memory/apps/host/src/cli.ts/01M4YY5SXJFQK8VXT78X1E0KAE-every-command-but-serve-must.md @@ -4,9 +4,9 @@ anchor: function main created: 2026-10-15T04:47:23Z norm: '1' sig: 7d5d3f63a3bddde4 -body_hash: 33d554e96630bf6d -raw_hash: f8aa0b8e89a37828 -vouched: 2026-10-20T17:10:51Z +body_hash: fd9cef47cdc61076 +raw_hash: e9c988923aa657a6 +vouched: 2026-10-22T14:31:33Z lines: 253-482 --- diff --git a/.lane/memory/apps/host/src/cli.ts/01M5J0BZWP8SCBK522YT2HMZDZ-ace-info-prints-agent-access.md b/.lane/memory/apps/host/src/cli.ts/01M5J0BZWP8SCBK522YT2HMZDZ-ace-info-prints-agent-access.md new file mode 100644 index 00000000..4d87b9cf --- /dev/null +++ b/.lane/memory/apps/host/src/cli.ts/01M5J0BZWP8SCBK522YT2HMZDZ-ace-info-prints-agent-access.md @@ -0,0 +1,12 @@ +--- +id: 01M5J0BZWP8SCBK522YT2HMZDZ +anchor: function main +created: 2026-10-22T14:31:16Z +norm: '1' +sig: 7d5d3f63a3bddde4 +body_hash: fd9cef47cdc61076 +raw_hash: e9c988923aa657a6 +lines: 332-614 +--- + +ace info prints agent access as `agents`; `shared` stays the wire and storage name diff --git a/apps/app/src/channel-access.tsx b/apps/app/src/channel-access.tsx index 2f7f8c79..29296116 100644 --- a/apps/app/src/channel-access.tsx +++ b/apps/app/src/channel-access.tsx @@ -21,7 +21,7 @@ import { host } from "./host"; import { placement } from "./placement"; /** - * What collaborators' runs can reach. A cloud container has no desktop tools and no macOS + * What teammates' runs can reach. A cloud container has no desktop tools and no macOS * permissions, so its copy names neither. */ function reach(channel: Listing): { agents: string; confirm: string; desktop: boolean } { @@ -29,7 +29,7 @@ function reach(channel: Listing): { agents: string; confirm: string; desktop: bo if (place.kind === "cloud") { return { agents: - `Allow collaborators to invoke agents, which run commands in this channel's cloud container on ${place.service}, with its GitHub access to the repository. No macOS permissions apply. Turning this off leaves chat available and active runs continue.`, + `Let teammates invoke this channel's agents, which run commands in this channel's cloud container on ${place.service}, with its GitHub access to the repository. No macOS permissions apply. Turning this off leaves chat available and active runs continue.`, confirm: "Teammates can run commands in this channel's cloud container, with its GitHub access to the repository. No macOS permissions apply.", desktop: false, @@ -37,7 +37,7 @@ function reach(channel: Listing): { agents: string; confirm: string; desktop: bo } return { agents: - "Allow collaborators to invoke agents, which run commands as you on this machine with Ace's macOS permissions, such as Screen Recording. Turning this off leaves chat available and active runs continue.", + "Let teammates invoke this channel's agents, which run commands as you on this machine with Ace's macOS permissions, such as Screen Recording. Turning this off leaves chat available and active runs continue.", confirm: "Teammates can run commands as you on this machine, with Ace's macOS permissions such as Screen Recording.", desktop: true, @@ -102,7 +102,7 @@ function AccessToggle({ label, value, live, owner, pending, description, childre } /> - +

{label}: {state}

{description}

{!owner &&

Only the channel owner can change this.

} @@ -146,7 +146,7 @@ export function ChannelAccess({ channel, user }: { channel: Listing; user: strin > @@ -172,7 +172,7 @@ export function ChannelAccess({ channel, user }: { channel: Listing; user: strin - Let collaborators invoke agents? + Let teammates invoke agents? {copy.confirm} {copy.desktop && desktop diff --git a/apps/app/src/open-project.tsx b/apps/app/src/open-project.tsx index f54c639d..ddeab402 100644 --- a/apps/app/src/open-project.tsx +++ b/apps/app/src/open-project.tsx @@ -137,6 +137,7 @@ export function OpenProject({ onOpen, onClose }: { {error &&

{error}

} + diff --git a/apps/app/src/palette.tsx b/apps/app/src/palette.tsx index fb9d010f..6c8165ec 100644 --- a/apps/app/src/palette.tsx +++ b/apps/app/src/palette.tsx @@ -31,13 +31,13 @@ const ACTIONS = [ action("dashboard", "Dashboard", "Go to", "1"), action("channels", "Channels", "Go to", "2"), action("issues", "Issues", "Go to", "3"), - action("prs", "Pull Requests", "Go to", "4"), - action("project-open", "Open Folder…", "Project", "o"), + action("prs", "Pull requests", "Go to", "4"), + action("project-open", "Open folder…", "Project", "o"), action("project-clone", "Clone from URL…", "Project"), action("settings", "Settings", "Ace", ","), - ...(desktop ? [action("updates", "Check for Updates…", "Ace")] : []), - action("nav-toggle", "Toggle Navigation", "View", "b"), - action("channels-toggle", "Toggle Channels Sidebar", "View", "b", true), + ...(desktop ? [action("updates", "Check for updates…", "Ace")] : []), + action("nav-toggle", "Toggle navigation", "View", "b"), + action("channels-toggle", "Toggle channels sidebar", "View", "b", true), ]; const CREATE = "channel-new"; @@ -52,6 +52,7 @@ function channelItems( const names = new Map(projects.map((project) => [project.id, label(project, host)])); return channels.map((channel) => { const project = channelProject(channel); + const outcome = attention.get(channel.id); return { kind: "session", id: `channel:${channel.id}`, @@ -61,9 +62,12 @@ function channelItems( archived: channel.state === "archived", // Other projects' channels wait for a search so the current project's stay in reach. hiddenUntilSearch: project !== current, - status: channel.state === "running" && channel.busy + // A run waiting on a question is still busy, but it waits on them, as in the sidebar. + status: outcome === "question" || outcome === "failed" + ? "attention" + : channel.state === "running" && channel.busy ? "busy" - : attention.get(channel.id) === "done" + : outcome === "done" ? "unread" : undefined, }; @@ -112,7 +116,7 @@ export function Palette({ channels, projects, host, project, attention, onChanne if (!open) return null; const items: CommandPaletteItem[] = [ - ...(onCreate ? [action(CREATE, `New Channel in ${onCreate.name}`, "Channel")] : []), + ...(onCreate ? [action(CREATE, `New channel in ${onCreate.name}`, "Channel")] : []), ...ACTIONS, ...tabs, ...channelItems(channels, projects, host, project, attention), diff --git a/apps/host/src/cli.ts b/apps/host/src/cli.ts index 3207567b..9c57b8f2 100755 --- a/apps/host/src/cli.ts +++ b/apps/host/src/cli.ts @@ -510,8 +510,11 @@ async function main() { const { name, session } = await join(ref); try { switch (command) { - case "info": - return console.log(JSON.stringify(await session.request({ op: "info" }), null, 2)); + case "info": { + // docs/terms.md names it agent access, after `ace agents`; `shared` is the wire name. + const { shared, ...info } = await session.request({ op: "info" }); + return console.log(JSON.stringify({ ...info, agents: shared }, null, 2)); + } case "say": if (!text) throw new Error("Nothing to say"); await session.request({ op: "say", chat: chat(), author: catalog.user, text }); diff --git a/packages/ui/src/components/command-palette/command-palette.tsx b/packages/ui/src/components/command-palette/command-palette.tsx index 7762631a..943e82e2 100644 --- a/packages/ui/src/components/command-palette/command-palette.tsx +++ b/packages/ui/src/components/command-palette/command-palette.tsx @@ -45,6 +45,7 @@ function shortcutLabel(shortcut?: CommandPaletteShortcut) { function statusLabel(item: CommandPaletteItem) { if (item.kind !== "session") return shortcutLabel(item.shortcut); if (item.archived) return "Archived"; + if (item.status === "attention") return "Needs you"; if (item.status === "mention") return "Mention"; if (item.status === "unread") return "Unread"; if (item.status === "busy") return "Busy"; @@ -163,7 +164,7 @@ function Palette({ items, onOpenChange, onSelect, placeholder, emptyLabel, title aria-activedescendant={results[index] ? `command-palette-${results[index]!.item.id}` : undefined} - className="block inline-size-full bg-transparent px-4 py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground" + className="block w-full bg-transparent px-4 py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground" /> @@ -171,7 +172,7 @@ function Palette({ items, onOpenChange, onSelect, placeholder, emptyLabel, title ref={list} id="command-palette-results" role="listbox" - className="min-block-size-0 overflow-y-auto p-2 overscroll-contain" + className="min-h-0 overflow-y-auto p-2 overscroll-contain" > {results.length ? ( @@ -190,7 +191,7 @@ function Palette({ items, onOpenChange, onSelect, placeholder, emptyLabel, title onClick={() => choose(item)} onPointerEnter={() => !item.disabled && setSelected(item.id)} className={cn( - "group grid inline-size-full grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-md px-2 py-1.5 text-left text-sm/5 outline-none transition-[background-color,color,transform] duration-150 ease-out", + "group grid w-full grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-md px-2 py-1.5 text-left text-sm/5 outline-none transition-[background-color,color,transform] duration-150 ease-out", selected && "bg-accent text-accent-foreground", !selected && "text-foreground", item.disabled && "cursor-not-allowed opacity-45", @@ -211,7 +212,8 @@ function Palette({ items, onOpenChange, onSelect, placeholder, emptyLabel, title