diff --git a/scripts/init-cli-agent.ts b/scripts/init-cli-agent.ts index ccd9387a9..4a56827bc 100644 --- a/scripts/init-cli-agent.ts +++ b/scripts/init-cli-agent.ts @@ -30,7 +30,6 @@ import { } from '../src/db/messaging-groups.js'; import { runMigrations } from '../src/db/migrations/index.js'; import { normalizeName } from '../src/modules/agent-to-agent/db/agent-destinations.js'; -import { grantRole, hasAnyOwner } from '../src/modules/permissions/db/user-roles.js'; import { upsertUser } from '../src/modules/permissions/db/users.js'; import { initGroupFilesystem } from '../src/group-init.js'; import type { AgentGroup, MessagingGroup } from '../src/types.js'; @@ -91,17 +90,9 @@ async function main(): Promise { created_at: now, }); - let promotedToOwner = false; - if (!hasAnyOwner()) { - grantRole({ - user_id: CLI_SYNTHETIC_USER_ID, - role: 'owner', - agent_group_id: null, - granted_by: null, - granted_at: now, - }); - promotedToOwner = true; - } + // Owner grant deferred to init-first-agent when the real channel user is + // wired — cli:local is a scratch identity, not the operator. + const promotedToOwner = false; // 2. Agent group + filesystem. const folder = `cli-with-${normalizeName(args.displayName)}`; diff --git a/src/modules/permissions/user-dm.ts b/src/modules/permissions/user-dm.ts index ef9566ad8..a5274d19f 100644 --- a/src/modules/permissions/user-dm.ts +++ b/src/modules/permissions/user-dm.ts @@ -136,11 +136,14 @@ async function resolveDmPlatformId(channelType: string, handle: string): Promise function parseUserId(user: User): { channelType: string; handle: string } | { channelType: null; handle: null } { const idx = user.id.indexOf(':'); if (idx < 0) return { channelType: null, handle: null }; - const channelType = user.id.slice(0, idx); + const prefix = user.id.slice(0, idx); const handle = user.id.slice(idx + 1); - if (!channelType || !handle) return { channelType: null, handle: null }; - // The `kind` on users mirrors the channel_type prefix in our current - // scheme. Pull it from `user.kind` if we ever decouple them later, but - // today the id prefix is authoritative. - return { channelType, handle }; + if (!prefix || !handle) return { channelType: null, handle: null }; + // Teams user IDs use a `29:` prefix, not `teams:`. When the id prefix + // isn't a registered adapter, fall back to user.kind and treat the full + // id as the handle. + if (!getChannelAdapter(prefix) && user.kind && getChannelAdapter(user.kind)) { + return { channelType: user.kind, handle: user.id }; + } + return { channelType: prefix, handle }; }