{"version":3,"file":"server.cjs","names":["readFile","Type","readFile","path","readHarnessState","os","listDomainNames","materializePluginEntries","resolvePluginEntries","collectResources","discoverSkillsAsync","resolveSharedSkills","DeferredSkillLoader","formatSkillsForPrompt","SKILL_COMMAND_PREFIX","SKILL_INVOCATION_PREFIX","expandDeferredSkillCommand","SKILLS_COMMAND","readFile","packageResourcePath","readPackageResource","defineRoot","defineRoutedContribution","defineRoutedContribution","defineRoutedContribution","defineServerPlugin","rootSession","composeRootHooks","commandSkills","resourceSkills","toolLoadSkill"],"sources":["../../src/services/mcpSkills/index.ts","../../src/schemas/mcpSkillTools.ts","../../src/services/mcpSkillTools/index.ts","../../src/services/serverInventory/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/skillCommands.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/skillServer.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/command/skills.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/skills.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/load_skill.server.ts","../../generated/server.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\n\nimport type { DoomMcpPluginContext, DoomMcpSkill } from '@agimon-ai/doompi-core/mcpFacet';\nimport type { Context } from '@deepseek-ai/cordis';\n\nimport type { ServerSkillGroup } from '../serverInventory';\n\nexport const MCP_SKILLS_SERVICE = 'doom/discovered-mcp-skills';\n\nexport interface McpSkillProvider {\n  list(context: DoomMcpPluginContext): readonly DoomMcpSkill[];\n}\n\n/** Explicit remote provider, never a projection of the local resource registry. */\nexport function mountMcpSkills(groups: readonly ServerSkillGroup[], signal: AbortSignal) {\n  return (context: Context): void => {\n    context.provide(MCP_SKILLS_SERVICE, {\n      list(remote) {\n        signal.throwIfAborted();\n        remote.signal.throwIfAborted();\n        const domains = remote.selection.read().domains;\n        const skills = new Map<string, DoomMcpSkill>();\n        for (const group of groups) {\n          if (group.domain !== undefined && !domains.includes(group.domain)) continue;\n          for (const skill of group.skills) {\n            // Match command precedence, including shared copies across domains.\n            if (skills.has(skill.name)) continue;\n            skills.set(skill.name, {\n              name: skill.name,\n              description: skill.description,\n              async read() {\n                const readSignal = AbortSignal.any([signal, remote.signal]);\n                readSignal.throwIfAborted();\n                const text = await readFile(skill.filePath, { encoding: 'utf8', signal: readSignal });\n                readSignal.throwIfAborted();\n                return text;\n              },\n            });\n          }\n        }\n        return [...skills.values()];\n      },\n    } satisfies McpSkillProvider);\n  };\n}\n\nexport function bindMcpSkills(context: DoomMcpPluginContext): readonly DoomMcpSkill[] {\n  const provider = context.services.get<McpSkillProvider>(MCP_SKILLS_SERVICE);\n  if (!provider) throw new Error('Discovered MCP skills are unavailable.');\n  return provider.list(context);\n}\n","import { Type } from 'typebox';\n\nexport const searchSkillsParameters = Type.Object({ query: Type.Optional(Type.String()) });\nexport const loadSkillParameters = Type.Object({ name: Type.String() });\n","import type { DoomHeadlessHostService, DoomHeadlessTool } from '@agimon-ai/doompi-core/headless';\n\nimport { loadSkillParameters, searchSkillsParameters } from '../../schemas/mcpSkillTools';\n\nfunction text(text: string) {\n  return { content: [{ type: 'text' as const, text }] };\n}\n\nfunction skills(context: Parameters<DoomHeadlessTool['execute']>[4]) {\n  if (context.mcpSkills === undefined) throw new Error('Remote skill access is unavailable.');\n  return context.mcpSkills;\n}\n\nexport function createSearchSkillsTool(): DoomHeadlessTool<typeof searchSkillsParameters> {\n  return {\n    // web-plugin-tool-renderers: ignore search_skills (remote MCP only)\n    name: 'search_skills',\n    label: 'Search skills',\n    description: 'Discover repository and active-domain skills available to this remote connection.',\n    parameters: searchSkillsParameters,\n    annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },\n    async execute(_toolCallId, { query }, _signal, _onUpdate, context) {\n      const needle = query?.trim().toLocaleLowerCase();\n      const available = await skills(context).list();\n      const matches =\n        needle === undefined || needle === ''\n          ? available\n          : available.filter(({ name, description }) => `${name}\\n${description}`.toLocaleLowerCase().includes(needle));\n      return { ...text(JSON.stringify(matches)), structuredContent: { skills: matches } };\n    },\n  };\n}\n\n/**\n * The session agent's way into a skill. Its skills are listed in the prompt, which DoomPi\n * controls, so it needs no search; a remote agent's prompt is not ours, hence the pair above.\n */\nexport function createSessionLoadSkillTool(\n  host: Pick<DoomHeadlessHostService, 'readSkill'>,\n): DoomHeadlessTool<typeof loadSkillParameters> {\n  return {\n    // web-plugin-tool-renderers: ignore load_skill (server session only, shown as a generic call)\n    // DOOM_LOAD_SKILL_TOOL, spelled out so the renderer rule can read it.\n    name: 'load_skill',\n    label: 'Load skill',\n    description: 'Load the full instructions of a skill from the available skills list by exact name.',\n    parameters: loadSkillParameters,\n    executionMode: 'parallel',\n    async execute(_toolCallId, { name }) {\n      const body = host.readSkill(name);\n      if (body === undefined) return { ...text(`No skill named ${name} is available in this session.`), isError: true };\n      return text(body);\n    },\n  };\n}\n\nexport function createLoadSkillTool(): DoomHeadlessTool<typeof loadSkillParameters> {\n  return {\n    // web-plugin-tool-renderers: ignore load_skill (remote MCP only)\n    name: 'load_skill',\n    label: 'Load skill',\n    description: 'Load the full Markdown instructions for an available remote skill by exact name.',\n    parameters: loadSkillParameters,\n    annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },\n    async execute(_toolCallId, { name }, _signal, _onUpdate, context) {\n      return text(await skills(context).read(name));\n    },\n  };\n}\n","import { readFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport {\n  listDomainNames,\n  resolvePluginEntries,\n  resolveSharedSkills,\n  type PluginEntry,\n} from '@agimon-ai/doompi-config/domains';\nimport { readHarnessState } from '@agimon-ai/doompi-config/harnessState';\nimport type { DoomHeadlessExecutionContext } from '@agimon-ai/doompi-core/headless';\nimport { materializePluginEntries } from '@agimon-ai/doompi-domain/plugins';\nimport { collectResources, discoverSkillsAsync } from '@agimon-ai/doompi-domain/resources';\nimport { formatSkillsForPrompt, type Skill } from '@earendil-works/pi-coding-agent';\n\nimport { DeferredSkillLoader, type DeferredSkillSnapshot } from '../deferredSkills';\n\n/** Skills and the domain whose selection activates them, or always-on when absent. */\nexport interface ServerSkillGroup {\n  readonly domain?: string;\n  readonly skills: readonly Skill[];\n}\n\nexport interface ServerSkillInventory {\n  /** Every skill any selection can reach, so an activated command can still expand. */\n  readonly inventory: DeferredSkillSnapshot;\n  readonly groups: readonly ServerSkillGroup[];\n  readonly mcpGroups: readonly ServerSkillGroup[];\n  /**\n   * The shared and repository skills this package advertises itself. Domain plugin skills are\n   * left out: doompi-domain already contributes each one, and listing them twice was noise.\n   */\n  readonly listed: readonly ServerSkillGroup[];\n  readonly catalog: string;\n}\n\ninterface SkillSource {\n  readonly domain?: string;\n  readonly paths: readonly string[];\n  readonly mcpPaths: readonly string[];\n  /** Advertised by this package rather than by doompi-domain. */\n  readonly listed?: boolean;\n}\n\nconst LOCAL_ONLY_MCP_PACKAGES = new Set([\n  '@agimon-ai/doompi-author',\n  '@agimon-ai/doompi-git',\n  '@agimon-ai/doompi-goal',\n  '@agimon-ai/doompi-help',\n  '@agimon-ai/doompi-loop',\n  '@agimon-ai/doompi-user-feedback',\n  '@agimon-ai/doompi-voice',\n  '@agimon-ai/doompi-workflow',\n]);\n\nasync function isMcpSkillPlugin(entry: PluginEntry): Promise<boolean> {\n  if (entry.source?.type === 'npm') return !LOCAL_ONLY_MCP_PACKAGES.has(entry.source.package);\n  try {\n    const manifest = JSON.parse(await readFile(path.join(entry.directory, 'package.json'), 'utf8')) as unknown;\n    if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) return false;\n    const name = (manifest as { name?: unknown }).name;\n    return typeof name === 'string' && name.length > 0 && name.trim() === name && !LOCAL_ONLY_MCP_PACKAGES.has(name);\n  } catch (error) {\n    // A package manifest is optional for catalog plugins, but a present identity\n    // that cannot be read or parsed must never make the plugin remotely eligible.\n    return (error as NodeJS.ErrnoException).code === 'ENOENT';\n  }\n}\n\n/**\n * Whether a discovered skill came from one of these paths.\n *\n * A source holds exact SKILL.md files for plugin and shared skills, but a bare\n * directory for `.doom/skills`, so membership is containment rather than\n * equality.\n */\nfunction within(filePath: string, roots: readonly string[]): boolean {\n  const resolved = path.resolve(filePath);\n  return roots.some((root) => {\n    const base = path.resolve(root);\n    return resolved === base || resolved.startsWith(`${base}${path.sep}`);\n  });\n}\n/**\n * Every skill the session could reach, grouped by what activates it.\n *\n * A cockpit `/domains` switch reconciles contributions rather than rebuilding\n * the facet: the session declaration is mounted once. So enumerating only the\n * launch selection would freeze the command list at whatever was selected when\n * the session host was built. Enumerating every domain up front and tagging\n * each group with its `when` lets the existing kernel refresh do the work, the\n * same way domainServerResources registers per-domain skill resources.\n */\nexport async function discoverServerSkills(\n  execution: DoomHeadlessExecutionContext,\n  signal: AbortSignal,\n): Promise<ServerSkillInventory> {\n  signal.throwIfAborted();\n  const state = readHarnessState(execution.environment);\n  const home = execution.environment.HOME ?? os.homedir();\n  const repoSkills = path.join(execution.repoRoot, '.doom', 'skills');\n  const sources: SkillSource[] = [];\n  const diagnostics: string[] = [];\n  // A malformed domain is a configuration error in one domain, so it must not\n  // remove every other domain's skills. Enumerating the whole manifest is new\n  // exposure here: reading the launch selection could not fail this way.\n  const domains: string[] = [];\n  try {\n    domains.push(...listDomainNames(execution.repoRoot, home));\n  } catch (error) {\n    diagnostics.push(`Domain skills are unavailable: ${error instanceof Error ? error.message : String(error)}`);\n  }\n\n  // Domain-scoped plugin skills come first. The host keeps the first command\n  // registered for a name, so this ordering reproduces the collector's rule\n  // that a selected plugin outranks a shared fallback of the same name.\n  for (const domain of domains) {\n    signal.throwIfAborted();\n    try {\n      const plugins = await materializePluginEntries(resolvePluginEntries(execution.repoRoot, [domain], [], home));\n      const mcpPluginRoots = (\n        await Promise.all(\n          plugins.map(async (plugin) =>\n            (await isMcpSkillPlugin(plugin)) ? path.join(plugin.directory, 'skills') : undefined,\n          ),\n        )\n      ).filter((root): root is string => root !== undefined);\n      const collected = await collectResources(execution.repoRoot, plugins, {\n        agents: false,\n        mcp: false,\n        sharedSkills: false,\n      });\n      try {\n        if (collected.skillDirectories.length > 0) {\n          const paths = [...collected.skillDirectories];\n          sources.push({\n            domain,\n            paths,\n            // Exact collected paths retain this domain's per-plugin skill subset.\n            // A plugin root would also admit skills loaded for another domain.\n            mcpPaths: paths.filter((skillPath) => within(skillPath, mcpPluginRoots)),\n          });\n        }\n      } finally {\n        await collected.cleanup();\n      }\n    } catch (error) {\n      diagnostics.push(`Domain '${domain}': ${error instanceof Error ? error.message : String(error)}`);\n    }\n  }\n\n  // Shared .claude/skills are not owned by any one domain, and a domain can opt\n  // out of them. `when` cannot express \"unless every selected domain opts out\",\n  // but registering a copy per domain that keeps them says the same thing: the\n  // group is active if any such domain is selected, which is exactly what\n  // resolveSharedSkills computes.\n  signal.throwIfAborted();\n  const shared = await discoverSkillsAsync(execution.repoRoot, path.join(execution.repoRoot, '.claude', 'skills'));\n  if (shared.length > 0) {\n    const sharedPaths = shared.map((skill) => skill.path);\n    for (const domain of domains) {\n      if (resolveSharedSkills(execution.repoRoot, [domain], home)) {\n        sources.push({ domain, paths: sharedPaths, mcpPaths: sharedPaths, listed: true });\n      }\n    }\n  }\n\n  // Repository-local skills belong to the repository, not to a selection.\n  sources.push({ paths: [repoSkills], mcpPaths: [repoSkills], listed: true });\n\n  signal.throwIfAborted();\n  // One walk for every group. Pi drops a path it has already loaded, so the\n  // loader gets the unique set and each group selects its own skills back out.\n  const unique = [...new Set([...sources.flatMap((source) => source.paths), ...(state.skillDirectories ?? [])])];\n  const inventory = await new DeferredSkillLoader({ cwd: execution.cwd, skillPaths: unique }).ready();\n  signal.throwIfAborted();\n\n  const groups = sources\n    .map((source) => ({\n      ...(source.domain === undefined ? {} : { domain: source.domain }),\n      skills: inventory.skills.filter((skill) => within(skill.filePath, source.paths)),\n    }))\n    .filter((group) => group.skills.length > 0);\n  const listed = sources\n    .filter((source) => source.listed === true)\n    .map((source) => ({\n      ...(source.domain === undefined ? {} : { domain: source.domain }),\n      skills: inventory.skills.filter((skill) => within(skill.filePath, source.paths)),\n    }))\n    .filter((group) => group.skills.length > 0);\n  const mcpGroups = sources\n    .map((source) => ({\n      ...(source.domain === undefined ? {} : { domain: source.domain }),\n      skills: inventory.skills.filter((skill) => within(skill.filePath, source.mcpPaths)),\n    }))\n    .filter((group) => group.skills.length > 0);\n\n  // The catalog still describes the active selection rather than everything on\n  // disk, because it is prompt text rather than a menu.\n  const activeSkills = inventory.skills.filter((skill) =>\n    within(skill.filePath, [...(state.skillDirectories ?? []), repoSkills]),\n  );\n  return {\n    inventory: { skills: inventory.skills, diagnostics: [...inventory.diagnostics, ...diagnostics] },\n    groups,\n    mcpGroups,\n    listed,\n    catalog: formatSkillsForPrompt(activeSkills) || '(no discovered skills)',\n  };\n}\n","import type { DoomHeadlessCommand, DoomHeadlessExecutionContext } from '@agimon-ai/doompi-core/headless';\nimport type { Skill } from '@earendil-works/pi-coding-agent';\n\nimport { expandDeferredSkillCommand, type DeferredSkillSnapshot } from '../../../../../services/deferredSkills';\nimport type { ServerSkillGroup } from '../../../../../services/serverInventory';\nimport { SKILL_COMMAND_PREFIX, SKILL_INVOCATION_PREFIX, SKILLS_COMMAND } from '../../../../../types/skills';\n\n/**\n * Admits the expanded skill without awaiting its turn.\n *\n * A command's `execute` is the prompt's admission acknowledgement: the web\n * composer keeps the draft until it returns. `session.prompt` awaits the whole\n * turn, so the `/skill:` draft stayed in the composer until the agent finished.\n */\nasync function admitSkill(execution: DoomHeadlessExecutionContext, text: string): Promise<void> {\n  if (!execution.session.admitPrompt) throw new Error('The session cannot admit a skill prompt.');\n  await execution.session.admitPrompt(text, 'prompt', 'operator');\n}\n/**\n * One command per skill, gated by whatever activates that skill.\n *\n * Expansion always reads the full inventory, not the group: a command is only\n * dispatchable while its condition holds, so by the time one runs its skill is\n * active, and looking it up in the union keeps one lookup table instead of one\n * per domain.\n */\nfunction skillCommand(skill: Skill, domain: string | undefined, inventory: DeferredSkillSnapshot): DoomHeadlessCommand {\n  return {\n    ...(domain === undefined ? {} : { when: { domain } }),\n    name: `${SKILL_COMMAND_PREFIX}${skill.name}`,\n    description: skill.description,\n    execute: async (args, execution) => {\n      const text = `${SKILL_INVOCATION_PREFIX}${skill.name}${args ? ` ${args}` : ''}`;\n      const expanded = expandDeferredSkillCommand(text, inventory.skills);\n      if (expanded === text) throw new Error(`Skill '${skill.name}' is no longer readable.`);\n      await admitSkill(execution, expanded);\n    },\n  };\n}\n\nexport function createSkillCommands(\n  inventory: DeferredSkillSnapshot,\n  catalog: string,\n  groups: readonly ServerSkillGroup[],\n): readonly DoomHeadlessCommand[] {\n  return [\n    {\n      name: SKILLS_COMMAND,\n      description: 'List discovered skills or invoke one by name.',\n      async execute(args, execution) {\n        const requested = args.trim();\n        if (requested) {\n          await admitSkill(\n            execution,\n            expandDeferredSkillCommand(`${SKILL_INVOCATION_PREFIX}${requested}`, inventory.skills),\n          );\n          return;\n        }\n        await execution.client.notify({\n          title: 'DoomPi skills',\n          body: catalog,\n          level: 'info',\n        });\n      },\n    },\n    ...groups.flatMap((group) => group.skills.map((skill) => skillCommand(skill, group.domain, inventory))),\n  ];\n}\n","import { readFile } from 'node:fs/promises';\n\nimport type { DoomHeadlessHostService } from '@agimon-ai/doompi-core/headless';\nimport {\n  type DoomServerSessionPlugin,\n  packageResourcePath,\n  readPackageResource,\n} from '@agimon-ai/doompi-core/serverFacet';\n\nimport { mountMcpSkills } from '../../../../../services/mcpSkills';\nimport { createSessionLoadSkillTool } from '../../../../../services/mcpSkillTools';\nimport { discoverServerSkills } from '../../../../../services/serverInventory';\nimport { createSkillCommands } from './skillCommands';\n\nexport async function createSkillServer(\n  agent: DoomHeadlessHostService,\n  signal: AbortSignal,\n): Promise<DoomServerSessionPlugin> {\n  const { inventory, catalog, groups, mcpGroups, listed } = await discoverServerSkills(agent.context, signal);\n  return {\n    commands: createSkillCommands(inventory, catalog, groups),\n    tools: [createSessionLoadSkillTool(agent)],\n    services: [mountMcpSkills(mcpGroups, signal)],\n    resources: [\n      // Each skill joins the prompt's one <available_skills> list, gated like the rest.\n      ...listed.flatMap((group) =>\n        group.skills.map((skill) => ({\n          name: skill.name,\n          description: skill.description,\n          path: skill.filePath,\n          kind: 'skill' as const,\n          ...(group.domain === undefined\n            ? {}\n            : { when: { domain: group.domain, attribution: { kind: 'domain' as const, mode: group.domain } } }),\n          read: () => readFile(skill.filePath, 'utf8'),\n        })),\n      ),\n      ...[\n        {\n          name: 'doompi-author-skill',\n          description:\n            'Author and distribute DoomPi agent skills. Use when creating a SKILL.md, contributing a runtime skill directory, or publishing activation-gated Help prompts and diagnostic tools.',\n        },\n        {\n          name: 'doompi-use-skill',\n          description:\n            \"Use DoomPi's skill catalog and deferred discovery. Diagnose missing or shadowed skills and invoke the narrowest available guidance.\",\n        },\n      ].map((skill) => ({\n        ...skill,\n        when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor' as const, mode: 'help' } },\n        kind: 'skill' as const,\n        path: packageResourcePath(import.meta.url, `src/prompts/${skill.name}/SKILL.md`),\n        read: () => readPackageResource(import.meta.url, `src/prompts/${skill.name}/SKILL.md`),\n      })),\n    ],\n  };\n}\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { createSkillServer } from './_lib/skillServer';\n\nexport default defineRoot(async ({ agent, signal }: DoomServerPluginContext) => {\n  const runtime: DoomServerSessionPlugin = agent\n    ? await createSkillServer(agent, signal)\n    : { commands: [], resources: [] };\n  return { value: runtime, services: runtime.services };\n});\n","import { defineRoutedContribution } from '@agimon-ai/doompi-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n  (context: WithRoot<DoomServerPluginContext, DoomServerSessionPlugin>) => context.root.commands!,\n  { cardinality: 'many' },\n);\n","import { defineRoutedContribution } from '@agimon-ai/doompi-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nexport default defineRoutedContribution(\n  (context: WithRoot<DoomServerPluginContext, DoomServerSessionPlugin>) => context.root.resources!,\n  { cardinality: 'many' },\n);\n","import { defineRoutedContribution, type WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext, DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\n/** The session agent's skill loader; the Pi CLI keeps Pi's own skill handling. */\nexport default defineRoutedContribution(\n  (context: WithRoot<DoomServerPluginContext, DoomServerSessionPlugin>) => context.root.tools?.[0],\n  { cardinality: 'optional' },\n);\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport commandSkills from '../src/extensions/workspaces/sessions/(backend)/command/skills.server';\nimport resourceSkills from '../src/extensions/workspaces/sessions/(backend)/resource/skills.server';\nimport toolLoadSkill from '../src/extensions/workspaces/sessions/(backend)/tool/load_skill.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n  typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\ntype ManyFactory<T, C> = (context: C) => T | readonly T[];\nconst many = <T, C>(value: T | readonly T[] | ManyFactory<T, C>, context: C): readonly T[] => {\n  const resolved = typeof value === 'function' ? (value as ManyFactory<T, C>)(context) : value;\n  return Array.isArray(resolved) ? resolved : [resolved as T];\n};\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n  values.filter((value): value is T => value !== undefined);\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n  (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const facet = defineServerPlugin({\n  name: '@agimon-ai/doompi-skill',\n  session: async (context) => {\n    const scopeSession = await rootSession(context);\n    const contextSession = { ...context, root: scopeSession.value };\n    return {\n      ...composeRootHooks(scopeSession),\n      get commands(): DoomServerSessionPlugin['commands'] { return [...many(commandSkills, contextSession)]; },\n      get resources(): DoomServerSessionPlugin['resources'] { return [...many(resourceSkills, contextSession)]; },\n      get tools(): DoomServerSessionPlugin['tools'] { return defined([via({ name: 'load_skill' }, at(toolLoadSkill, contextSession))]); },\n      services: [...(scopeSession.services ?? [])],\n      get activities(): DoomServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n    };\n  },\n});\n\nexport default facet;\n"],"mappings":"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"}