{"version":3,"file":"pi.mjs","names":["requireDoomConfigContext","requireDoomConfigContext","rootSession","commandSkills","hookBeforeAgentStart","hookInput","hookSessionStart","resourceHelp"],"sources":["../../src/services/helpSkills/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/skillReadiness.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/skillsCommand.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/skillRuntime.ts","../../src/extensions/workspaces/sessions/(backend)/root.cli.ts","../../src/extensions/workspaces/sessions/(backend)/command/skills.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/beforeAgentStart.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/input.cli.ts","../../src/extensions/workspaces/sessions/(backend)/hook/sessionStart.cli.ts","../../src/extensions/workspaces/sessions/(backend)/resource/help.cli.ts","../../generated/pi.ts"],"sourcesContent":["import {\n  DOOM_HELP_MAX_DIAGNOSTIC_LENGTH,\n  DOOM_HELP_MAX_DIAGNOSTICS,\n  type DoomHelpService,\n  type DoomHelpSkill,\n  type DoomHelpSnapshot,\n} from '@agimon-ai/doompi-core/help';\nimport { createSyntheticSourceInfo, type Skill } from '@earendil-works/pi-coding-agent';\n\nexport interface SkillInventoryInput {\n  normalSkills: readonly Skill[];\n  deferredSkills: readonly Skill[];\n  /** Names from Pi's command catalog when full normal Skill records are unavailable. */\n  normalSkillNames?: readonly string[];\n}\n\nexport interface MergedSkillInventory {\n  /** Pi-native, unique deferred, then accepted Help skills in invocation-precedence order. */\n  skills: readonly Skill[];\n  /** Deferred and Help skills that are absent from Pi's existing prompt inventory. */\n  additionalSkills: readonly Skill[];\n  /** Accepted Help skills, retained separately for the Help catalog group. */\n  helpSkills: readonly Skill[];\n  diagnostics: readonly string[];\n  diagnosticKey: string;\n}\n\nexport interface ActiveHelpSkillView {\n  bind(service: DoomHelpService): () => void;\n  merge(input: SkillInventoryInput): MergedSkillInventory;\n  dispose(): void;\n}\n\nfunction boundedDiagnostic(message: string): string {\n  return message.slice(0, DOOM_HELP_MAX_DIAGNOSTIC_LENGTH);\n}\n\nfunction toSkill(skill: DoomHelpSkill): Skill {\n  return {\n    name: skill.name,\n    description: skill.description,\n    filePath: skill.filePath,\n    baseDir: skill.baseDir,\n    sourceInfo: createSyntheticSourceInfo(skill.filePath, {\n      source: skill.source,\n      scope: 'temporary',\n      origin: 'package',\n      baseDir: skill.baseDir,\n    }),\n    disableModelInvocation: false,\n  };\n}\n\nfunction activeHelpSkills(snapshot: DoomHelpSnapshot | undefined): DoomHelpSkill[] {\n  if (!snapshot || snapshot.activation === 'inactive') return [];\n  return [...snapshot.skills].sort(\n    (left, right) =>\n      left.source.localeCompare(right.source) ||\n      left.name.localeCompare(right.name) ||\n      left.filePath.localeCompare(right.filePath),\n  );\n}\n\nfunction snapshotDiagnostics(snapshot: DoomHelpSnapshot | undefined): string[] {\n  if (!snapshot) return [];\n  return snapshot.diagnostics.map((entry) =>\n    boundedDiagnostic(`Help ${entry.source ?? 'host'} [${entry.code}]: ${entry.message}`),\n  );\n}\n\nexport function mergeActiveHelpSkills(\n  input: SkillInventoryInput,\n  snapshot: DoomHelpSnapshot | undefined,\n  clientDiagnostics: readonly string[] = [],\n): MergedSkillInventory {\n  const nativeNames = new Set([...input.normalSkills.map((skill) => skill.name), ...(input.normalSkillNames ?? [])]);\n  const deferredSkills = input.deferredSkills.filter((skill) => !nativeNames.has(skill.name));\n  const occupiedNames = new Set([...nativeNames, ...deferredSkills.map((skill) => skill.name)]);\n  const helpSkills: Skill[] = [];\n  const diagnostics = [...snapshotDiagnostics(snapshot), ...clientDiagnostics.map(boundedDiagnostic)];\n\n  for (const candidate of activeHelpSkills(snapshot)) {\n    if (occupiedNames.has(candidate.name)) {\n      diagnostics.push(\n        boundedDiagnostic(\n          `Help ${candidate.source} [HELP_SKILL_COLLISION]: '${candidate.name}' was ignored because a normal skill wins.`,\n        ),\n      );\n      continue;\n    }\n    occupiedNames.add(candidate.name);\n    helpSkills.push(toSkill(candidate));\n  }\n\n  const boundedDiagnostics = diagnostics.slice(0, DOOM_HELP_MAX_DIAGNOSTICS);\n  const additionalSkills = [...deferredSkills, ...helpSkills];\n  return {\n    skills: [...input.normalSkills, ...additionalSkills],\n    additionalSkills,\n    helpSkills,\n    diagnostics: boundedDiagnostics,\n    diagnosticKey: `${snapshot?.hostGeneration ?? 'absent'}:${snapshot?.revision ?? 0}:${boundedDiagnostics.join('\\u0001')}`,\n  };\n}\n\nexport function createActiveHelpSkillView(): ActiveHelpSkillView {\n  let binding: { readonly token: symbol; snapshot: DoomHelpSnapshot; unsubscribe(): void } | undefined;\n  let disposed = false;\n  return {\n    bind(service) {\n      if (disposed) throw new Error('The Help skill view is disposed.');\n      const token = Symbol(service.generation);\n      const current = binding;\n      binding = undefined;\n      current?.unsubscribe();\n      const next: { readonly token: symbol; snapshot: DoomHelpSnapshot; unsubscribe(): void } = {\n        token,\n        snapshot: service.getSnapshot(),\n        unsubscribe: service.subscribeSnapshot((snapshot) => {\n          if (binding?.token === token) binding.snapshot = snapshot;\n        }),\n      };\n      binding = next;\n      let bindingDisposed = false;\n      return () => {\n        if (bindingDisposed) return;\n        bindingDisposed = true;\n        next.unsubscribe();\n        if (binding?.token === token) binding = undefined;\n      };\n    },\n    merge(input) {\n      return mergeActiveHelpSkills(input, binding?.snapshot);\n    },\n    dispose() {\n      if (disposed) return;\n      disposed = true;\n      const current = binding;\n      binding = undefined;\n      current?.unsubscribe();\n    },\n  };\n}\n","import { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport type { PiEventHandlers } from '@agimon-ai/doompi-core/piExtension';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext, Skill } from '@earendil-works/pi-coding-agent';\n\nimport type { DeferredSkillSnapshot } from '../../../../../services/deferredSkills';\nimport type { createActiveHelpSkillView } from '../../../../../services/helpSkills';\nimport { SKILL_COMMAND_PREFIX, SKILL_INVOCATION_PREFIX } from '../../../../../types/skills';\n\nconst WARNING = 'warning';\n\ntype HelpSkillView = ReturnType<typeof createActiveHelpSkillView>;\n\ninterface SkillReadinessGeneration {\n  readonly id: number;\n  readonly ready: Promise<DeferredSkillSnapshot>;\n  diagnosticsShown: boolean;\n}\n\nexport interface SkillReadiness {\n  readonly events: PiEventHandlers;\n  onStop(this: void): void;\n  /** The snapshot for the live generation, or undefined once it is superseded. */\n  current(): Promise<DeferredSkillSnapshot | undefined>;\n}\n\nexport function loadedSkillCommandNames(pi: ExtensionAPI): string[] {\n  if (typeof pi.getCommands !== 'function') return [];\n  return pi\n    .getCommands()\n    .filter((command) => command.source === 'skill' && command.name.startsWith(SKILL_COMMAND_PREFIX))\n    .map((command) => command.name.slice(SKILL_COMMAND_PREFIX.length));\n}\n\nfunction failedSnapshot(cwd: string, error: unknown): DeferredSkillSnapshot {\n  return {\n    skills: [],\n    diagnostics: [`${cwd}: ${error instanceof Error ? error.message : String(error)}`],\n  };\n}\n\n/**\n * Discovery that starts with the session and is awaited only when something\n * needs it.\n *\n * Scanning every skill directory is the slowest thing this package does, so it\n * runs as a generation started on session_start. A reload starts a new one, and\n * a snapshot from a superseded generation is discarded rather than shown.\n */\nexport function createSkillReadiness(\n  pi: ExtensionAPI,\n  helpSkillView: HelpSkillView,\n  loadDeferredSkills: () => Promise<typeof import('../../../../../services/deferredSkills')>,\n  cordisContext: () => Context,\n): SkillReadiness {\n  let generationSequence = 0;\n  let currentGeneration: SkillReadinessGeneration | undefined;\n  let shownHelpDiagnosticKey = '';\n\n  const currentSnapshot = async (generation: SkillReadinessGeneration): Promise<DeferredSkillSnapshot | undefined> => {\n    const snapshot = await generation.ready;\n    return currentGeneration === generation ? snapshot : undefined;\n  };\n\n  return {\n    events: {\n      session_start: (_event, ctx) => {\n        const state = requireDoomConfigContext(cordisContext()).harness;\n        const id = ++generationSequence;\n        const ready = loadDeferredSkills()\n          .then(({ DeferredSkillLoader }) =>\n            new DeferredSkillLoader({ cwd: ctx.cwd, skillPaths: state.skillDirectories }).start(),\n          )\n          .catch((error: unknown) => failedSnapshot(ctx.cwd, error));\n        currentGeneration = { id, ready, diagnosticsShown: false };\n        shownHelpDiagnosticKey = '';\n      },\n      input: async (event) => {\n        if (!event.text.startsWith(SKILL_INVOCATION_PREFIX)) return { action: 'continue' };\n\n        const generation = currentGeneration;\n        if (!generation) return { action: 'continue' };\n        const snapshot = await currentSnapshot(generation);\n        if (!snapshot) return { action: 'continue' };\n\n        const inventory = helpSkillView.merge({\n          normalSkills: [],\n          deferredSkills: snapshot.skills,\n          normalSkillNames: loadedSkillCommandNames(pi),\n        });\n        const { expandDeferredSkillCommand } = await loadDeferredSkills();\n        const text = expandDeferredSkillCommand(event.text, inventory.additionalSkills);\n        return text === event.text ? { action: 'continue' } : { action: 'transform', text, images: event.images };\n      },\n      before_agent_start: async (event, ctx) => {\n        const generation = currentGeneration;\n        if (!generation) return undefined;\n        const snapshot = await currentSnapshot(generation);\n        if (!snapshot) return undefined;\n\n        if (!generation.diagnosticsShown && snapshot.diagnostics.length > 0) {\n          generation.diagnosticsShown = true;\n          ctx.ui.notify(`Skill discovery:\\n${snapshot.diagnostics.join('\\n')}`, WARNING);\n        }\n        const inventory = helpSkillView.merge({\n          normalSkills: event.systemPromptOptions.skills ?? [],\n          deferredSkills: snapshot.skills,\n        });\n        if (inventory.diagnosticKey !== shownHelpDiagnosticKey) {\n          shownHelpDiagnosticKey = inventory.diagnosticKey;\n          if (inventory.diagnostics.length > 0) {\n            ctx.ui.notify(`Package Help:\\n${inventory.diagnostics.join('\\n')}`, WARNING);\n          }\n        }\n        if (inventory.additionalSkills.length === 0) return undefined;\n\n        const { buildPromptWithDeferredSkills } = await loadDeferredSkills();\n        return {\n          systemPrompt: buildPromptWithDeferredSkills(event.systemPrompt, event.systemPromptOptions, [\n            ...inventory.additionalSkills,\n          ]),\n        };\n      },\n    },\n    onStop() {\n      currentGeneration = undefined;\n    },\n    current: async () => (currentGeneration ? currentSnapshot(currentGeneration) : undefined),\n  };\n}\n\n/** The merged skill inventory the /skills catalogue is built from. */\nexport function skillInventory(helpSkillView: HelpSkillView, readiness: SkillReadiness) {\n  return async (ctx: ExtensionContext) => {\n    const snapshot = await readiness.current();\n    const inventory = helpSkillView.merge({\n      // Present on the runtime context; absent from the published ExtensionContext type.\n      normalSkills:\n        (ctx as unknown as { getSystemPromptOptions(): { skills?: Skill[] } }).getSystemPromptOptions().skills ?? [],\n      deferredSkills: snapshot?.skills ?? [],\n    });\n    return { helpSkills: inventory.helpSkills, diagnostics: inventory.diagnostics };\n  };\n}\n","import { requireDoomConfigContext } from '@agimon-ai/doompi-config/piContext';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport type { SkillCatalog, SkillCatalogOptions } from '../../../../../services/skillCatalog';\nimport { skillInvocation } from '../../../../../services/skillText';\nimport type { SkillsOverlayResult } from '../../../../../tui/skillsOverlay';\nimport { SKILLS_COMMAND } from '../../../../../types/skills';\n\nconst INFO = 'info';\nconst ERROR = 'error';\n\nexport interface SkillsCommandDependencies {\n  readonly cordisContext: () => Context;\n  /** Skill directories every loaded extension has contributed this session. */\n  readonly extensionSources: () => readonly { source: string; directories: readonly string[] }[];\n  /** Merged view of normal, deferred and package Help skills. */\n  readonly inventory: (ctx: ExtensionContext) => Promise<{\n    readonly helpSkills: SkillCatalogOptions['helpSkills'];\n    readonly diagnostics: readonly string[];\n  }>;\n  readonly repositoryRoot: (ctx: ExtensionContext) => Promise<string>;\n  readonly buildCatalog: (request: SkillCatalogOptions) => Promise<SkillCatalog>;\n  readonly openOverlay: (\n    ctx: ExtensionContext,\n    options: { catalog: SkillCatalog; repoRoot: string },\n  ) => Promise<SkillsOverlayResult | undefined>;\n}\n\nexport function createSkillsCommand(\n  dependencies: SkillsCommandDependencies,\n): Parameters<ExtensionAPI['registerCommand']> {\n  return [\n    SKILLS_COMMAND,\n    {\n      description: 'Browse the skills this session loaded, and what other domains would add',\n      handler: async (_args, ctx) => {\n        if (!ctx.hasUI || ctx.mode !== 'tui') {\n          ctx.ui.notify('/skills requires interactive mode', ERROR);\n          return;\n        }\n\n        const state = requireDoomConfigContext(dependencies.cordisContext()).harness;\n        const [repoRoot, inventory] = await Promise.all([\n          dependencies.repositoryRoot(ctx),\n          dependencies.inventory(ctx),\n        ]);\n        const catalog = await dependencies.buildCatalog({\n          repoRoot,\n          activeSkillDirectories: state.skillDirectories,\n          extensionSources: dependencies.extensionSources(),\n          helpSkills: inventory.helpSkills,\n          helpDiagnostics: [...inventory.diagnostics],\n        });\n\n        const result = await dependencies.openOverlay(ctx, { catalog, repoRoot });\n        if (!result) return;\n        ctx.ui.setEditorText(skillInvocation(result.skill.name));\n        ctx.ui.notify(`Loaded ${result.skill.name} into the prompt. Press enter to run it.`, INFO);\n      },\n    },\n  ];\n}\n","import { requireDoomConfigContext } from '@agimon-ai/doompi-config';\nimport { requireHarnessRoot } from '@agimon-ai/doompi-config/harnessStore';\nimport { DOOM_CONFIG_SERVICE } from '@agimon-ai/doompi-core/config';\nimport { DOOM_CORDIS_SESSION_SERVICE, type DoomCordisSessionService } from '@agimon-ai/doompi-core/cordisHost';\nimport { DOOM_HELP_SERVICE, requireDoomHelpService } from '@agimon-ai/doompi-core/help';\nimport { type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport {\n  createDoomSkillSourcesService,\n  DOOM_SKILL_SOURCES_SERVICE,\n  type DoomSkillSourcesService,\n} from '@agimon-ai/doompi-core/skills';\nimport { DOOM_UI_HUB_SERVICE, requireDoomUiHub } from '@agimon-ai/doompi-core/uiHub';\nimport type { Context } from '@deepseek-ai/cordis';\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport { createActiveHelpSkillView } from '../../../../../services/helpSkills';\nimport { SKILLS_LEADER_CONTRIBUTION } from '../../../../../types/skills';\nimport { createSkillReadiness, loadedSkillCommandNames, skillInventory } from './skillReadiness';\nimport { createSkillsCommand, type SkillsCommandDependencies } from './skillsCommand';\n\n/**\n * The catalogue and the overlay load on first use.\n *\n * Discovery has to start with the session, but building the catalogue and\n * rendering it are only reached by `/skills`, so they stay off the startup path.\n */\nfunction lazyModules() {\n  let catalog: Promise<typeof import('../../../../../services/skillCatalog')> | undefined;\n  let deferred: Promise<typeof import('../../../../../services/deferredSkills')> | undefined;\n  return {\n    catalog: () => (catalog ??= import('../../../../../services/skillCatalog')),\n    deferred: () => (deferred ??= import('../../../../../services/deferredSkills')),\n  };\n}\n\ninterface SkillPluginConfig {\n  readonly pi: ExtensionAPI;\n  readonly openOverlay: SkillsCommandDependencies['openOverlay'];\n}\n\nexport function createSkillRuntime({ pi, openOverlay }: SkillPluginConfig): PiPluginContributions {\n  const load = lazyModules();\n  let activeContext: Context | undefined;\n  let activeSources: DoomSkillSourcesService | undefined;\n  const bindConfig = (cordis: Context) => {\n    cordis.inject([DOOM_CONFIG_SERVICE], (context) => {\n      activeContext = context;\n      return () => {\n        if (activeContext === context) activeContext = undefined;\n      };\n    });\n  };\n  const requireRuntimeContext = (): Context => {\n    if (!activeContext) throw new Error('Doom skill runtime is waiting for the session config service.');\n    return activeContext;\n  };\n  const requireSkillSources = (): DoomSkillSourcesService => {\n    if (!activeSources) throw new Error('Doom skill sources are waiting for the active session service.');\n    return activeSources;\n  };\n  const bindSources = (cordis: Context) => {\n    cordis.inject([DOOM_CORDIS_SESSION_SERVICE], (sessionContext) => {\n      const session = sessionContext.get(DOOM_CORDIS_SESSION_SERVICE) as DoomCordisSessionService;\n      const service = createDoomSkillSourcesService(`${session.generation}:skill-sources`);\n      sessionContext.plugin((providerContext) => {\n        providerContext.provide(DOOM_SKILL_SOURCES_SERVICE, service);\n      });\n      activeSources = service;\n      return () => {\n        if (activeSources === service) activeSources = undefined;\n        service.dispose();\n      };\n    });\n  };\n  const helpSkillView = createActiveHelpSkillView();\n\n  const bindHelp = (cordis: Context) => {\n    cordis.inject([DOOM_HELP_SERVICE], (helpContext) => {\n      const help = requireDoomHelpService(helpContext);\n      const unbind = helpSkillView.bind(help);\n      const unbindInventory = help.bindSkillInventory(async () => {\n        const deferred = await readiness.current();\n        if (!deferred) return undefined;\n        return helpSkillView\n          .merge({\n            normalSkills: [],\n            normalSkillNames: loadedSkillCommandNames(pi),\n            deferredSkills: deferred.skills,\n          })\n          .helpSkills.map((skill) => skill.filePath);\n      });\n      return () => {\n        unbindInventory();\n        unbind();\n      };\n    });\n  };\n  const bindUi = (cordis: Context) => {\n    cordis.inject([DOOM_UI_HUB_SERVICE], (uiContext) => {\n      const contribution = requireDoomUiHub(uiContext).registerLeader(SKILLS_LEADER_CONTRIBUTION);\n      return () => contribution.dispose();\n    });\n  };\n  const readiness = createSkillReadiness(pi, helpSkillView, load.deferred, requireRuntimeContext);\n  return {\n    services: [bindConfig, bindSources, bindHelp, bindUi],\n    commands: [\n      createSkillsCommand({\n        cordisContext: requireRuntimeContext,\n        extensionSources: () => requireSkillSources().list(),\n        inventory: async (ctx) => {\n          return skillInventory(helpSkillView, readiness)(ctx);\n        },\n        repositoryRoot: async (_ctx: ExtensionContext) =>\n          requireHarnessRoot(requireDoomConfigContext(requireRuntimeContext()).harness),\n        buildCatalog: async (request) => (await load.catalog()).buildSkillCatalog(request),\n        openOverlay,\n      }),\n    ],\n    events: readiness.events,\n    onStop: readiness.onStop,\n    onDispose() {\n      helpSkillView.dispose();\n    },\n  };\n}\n","import { defineRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createSkillRuntime } from './_lib/skillRuntime';\nexport default defineRoot(({ pi }: PiPluginContext) => {\n  const runtime = createSkillRuntime({\n    pi,\n    openOverlay: async (context, options) =>\n      (await import('../../../../tui/skillsOverlay')).openSkillsOverlay(context, options),\n  });\n  return { value: runtime, services: runtime.services, onStop: runtime.onStop, onDispose: runtime.onDispose };\n});\n","import { defineCliCommand } from '@agimon-ai/doompi-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createSkillRuntime } from '../_lib/skillRuntime';\nexport default defineCliCommand(\n  (context: WithRoot<PiPluginContext<unknown>, ReturnType<typeof createSkillRuntime>>) => context.root.commands![0]!,\n);\n","import { defineCliHook } from '@agimon-ai/doompi-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createSkillRuntime } from '../_lib/skillRuntime';\nexport default defineCliHook(\n  (context: WithRoot<PiPluginContext<unknown>, ReturnType<typeof createSkillRuntime>>) =>\n    context.root.events!.before_agent_start,\n);\n","import { defineCliHook } from '@agimon-ai/doompi-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createSkillRuntime } from '../_lib/skillRuntime';\nexport default defineCliHook(\n  (context: WithRoot<PiPluginContext<unknown>, ReturnType<typeof createSkillRuntime>>) => context.root.events!.input,\n);\n","import { defineCliHook } from '@agimon-ai/doompi-core/extensionFile';\nimport type { WithRoot } from '@agimon-ai/doompi-core/extensionFile';\nimport type { PiPluginContext } from '@agimon-ai/doompi-core/piExtension';\n\nimport { createSkillRuntime } from '../_lib/skillRuntime';\nexport default defineCliHook(\n  (context: WithRoot<PiPluginContext<unknown>, ReturnType<typeof createSkillRuntime>>) =>\n    context.root.events!.session_start,\n);\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { LEADER_SOURCE } from '../../../../../types/skills';\nexport default defineResource({\n  source: LEADER_SOURCE,\n  moduleUrl: import.meta.url,\n  skills: [\n    {\n      name: 'doompi-author-skill',\n      description:\n        'Author and distribute DoomPi agent skills. Use when creating a SKILL.md, adding supporting references or scripts, contributing a runtime skill directory through Cordis, or publishing activation-gated Help prompts from a DoomPi package.',\n    },\n    {\n      name: 'doompi-use-skill',\n      description:\n        \"Use DoomPi's skill catalog and deferred discovery. Use when browsing available skills, invoking /skill:name, understanding Help and extension-owned skill groups, or diagnosing why a skill is absent or shadowed.\",\n    },\n  ],\n});\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { definePiExtension, type PiPluginContext, type PiPluginContributions } from '@agimon-ai/doompi-core/piExtension';\nimport { composeRootHooks } from '@agimon-ai/doompi-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.cli';\nimport commandSkills from '../src/extensions/workspaces/sessions/(backend)/command/skills.cli';\nimport hookBeforeAgentStart from '../src/extensions/workspaces/sessions/(backend)/hook/beforeAgentStart.cli';\nimport hookInput from '../src/extensions/workspaces/sessions/(backend)/hook/input.cli';\nimport hookSessionStart from '../src/extensions/workspaces/sessions/(backend)/hook/sessionStart.cli';\nimport resourceHelp from '../src/extensions/workspaces/sessions/(backend)/resource/help.cli';\n\ntype OptionsOf<T> = T extends (context: PiPluginContext<infer Options>) => unknown ? Options : never;\ntype InferredOptions = Exclude<OptionsOf<typeof rootSession> | OptionsOf<typeof commandSkills> | OptionsOf<typeof hookBeforeAgentStart> | OptionsOf<typeof hookInput> | OptionsOf<typeof hookSessionStart> | OptionsOf<typeof resourceHelp>, undefined>;\ntype Intersect<Union> =\n  (Union extends unknown ? (value: Union) => void : never) extends (value: infer Value) => void ? Value : never;\ntype ExtensionOptions = [InferredOptions] extends [never] ? undefined : Intersect<InferredOptions>;\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;\n\nexport const extension = definePiExtension<ExtensionOptions>('@agimon-ai/doompi-skill', async (context) => {\n  const scopeSession = await rootSession(context);\n  const contextSession = { ...context, root: scopeSession.value };\n  return {\n    ...composeRootHooks(scopeSession),\n    get commands(): PiPluginContributions['commands'] { return [at(commandSkills, contextSession)]; },\n    events: {\n      before_agent_start: at(hookBeforeAgentStart, contextSession) as NonNullable<PiPluginContributions['events']>['before_agent_start'],\n      input: at(hookInput, contextSession) as NonNullable<PiPluginContributions['events']>['input'],\n      session_start: at(hookSessionStart, contextSession) as NonNullable<PiPluginContributions['events']>['session_start'],\n    },\n    get resources(): PiPluginContributions['resources'] { return [at(resourceHelp, contextSession)]; },\n    services: [...(scopeSession.services ?? [])],\n  };\n});\n\nexport default extension;\n"],"mappings":";;;;;;;;;;;;;;AAiCA,SAAS,kBAAkB,SAAyB;CAClD,OAAO,QAAQ,MAAM,GAAG,+BAA+B;AACzD;AAEA,SAAS,QAAQ,OAA6B;CAC5C,OAAO;EACL,MAAM,MAAM;EACZ,aAAa,MAAM;EACnB,UAAU,MAAM;EAChB,SAAS,MAAM;EACf,YAAY,0BAA0B,MAAM,UAAU;GACpD,QAAQ,MAAM;GACd,OAAO;GACP,QAAQ;GACR,SAAS,MAAM;EACjB,CAAC;EACD,wBAAwB;CAC1B;AACF;AAEA,SAAS,iBAAiB,UAAyD;CACjF,IAAI,CAAC,YAAY,SAAS,eAAe,YAAY,OAAO,CAAC;CAC7D,OAAO,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC,MACzB,MAAM,UACL,KAAK,OAAO,cAAc,MAAM,MAAM,KACtC,KAAK,KAAK,cAAc,MAAM,IAAI,KAClC,KAAK,SAAS,cAAc,MAAM,QAAQ,CAC9C;AACF;AAEA,SAAS,oBAAoB,UAAkD;CAC7E,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,OAAO,SAAS,YAAY,KAAK,UAC/B,kBAAkB,QAAQ,MAAM,UAAU,OAAO,IAAI,MAAM,KAAK,KAAK,MAAM,SAAS,CACtF;AACF;AAEA,SAAgB,sBACd,OACA,UACA,oBAAuC,CAAC,GAClB;CACtB,MAAM,8BAAc,IAAI,IAAI,CAAC,GAAG,MAAM,aAAa,KAAK,UAAU,MAAM,IAAI,GAAG,GAAI,MAAM,oBAAoB,CAAC,CAAE,CAAC;CACjH,MAAM,iBAAiB,MAAM,eAAe,QAAQ,UAAU,CAAC,YAAY,IAAI,MAAM,IAAI,CAAC;CAC1F,MAAM,gCAAgB,IAAI,IAAI,CAAC,GAAG,aAAa,GAAG,eAAe,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC;CAC5F,MAAM,aAAsB,CAAC;CAC7B,MAAM,cAAc,CAAC,GAAG,oBAAoB,QAAQ,GAAG,GAAG,kBAAkB,IAAI,iBAAiB,CAAC;CAElG,KAAK,MAAM,aAAa,iBAAiB,QAAQ,GAAG;EAClD,IAAI,cAAc,IAAI,UAAU,IAAI,GAAG;GACrC,YAAY,KACV,kBACE,QAAQ,UAAU,OAAO,4BAA4B,UAAU,KAAK,2CACtE,CACF;GACA;EACF;EACA,cAAc,IAAI,UAAU,IAAI;EAChC,WAAW,KAAK,QAAQ,SAAS,CAAC;CACpC;CAEA,MAAM,qBAAqB,YAAY,MAAM,GAAG,yBAAyB;CACzE,MAAM,mBAAmB,CAAC,GAAG,gBAAgB,GAAG,UAAU;CAC1D,OAAO;EACL,QAAQ,CAAC,GAAG,MAAM,cAAc,GAAG,gBAAgB;EACnD;EACA;EACA,aAAa;EACb,eAAe,GAAG,UAAU,kBAAkB,SAAS,GAAG,UAAU,YAAY,EAAE,GAAG,mBAAmB,KAAK,GAAQ;CACvH;AACF;AAEA,SAAgB,4BAAiD;CAC/D,IAAI;CACJ,IAAI,WAAW;CACf,OAAO;EACL,KAAK,SAAS;GACZ,IAAI,UAAU,MAAM,IAAI,MAAM,kCAAkC;GAChE,MAAM,QAAQ,OAAO,QAAQ,UAAU;GACvC,MAAM,UAAU;GAChB,UAAU,KAAA;GACV,SAAS,YAAY;GACrB,MAAM,OAAoF;IACxF;IACA,UAAU,QAAQ,YAAY;IAC9B,aAAa,QAAQ,mBAAmB,aAAa;KACnD,IAAI,SAAS,UAAU,OAAO,QAAQ,WAAW;IACnD,CAAC;GACH;GACA,UAAU;GACV,IAAI,kBAAkB;GACtB,aAAa;IACX,IAAI,iBAAiB;IACrB,kBAAkB;IAClB,KAAK,YAAY;IACjB,IAAI,SAAS,UAAU,OAAO,UAAU,KAAA;GAC1C;EACF;EACA,MAAM,OAAO;GACX,OAAO,sBAAsB,OAAO,SAAS,QAAQ;EACvD;EACA,UAAU;GACR,IAAI,UAAU;GACd,WAAW;GACX,MAAM,UAAU;GAChB,UAAU,KAAA;GACV,SAAS,YAAY;EACvB;CACF;AACF;;;ACrIA,MAAM,UAAU;AAiBhB,SAAgB,wBAAwB,IAA4B;CAClE,IAAI,OAAO,GAAG,gBAAgB,YAAY,OAAO,CAAC;CAClD,OAAO,GACJ,YAAY,CAAC,CACb,QAAQ,YAAY,QAAQ,WAAW,WAAW,QAAQ,KAAK,WAAA,QAA+B,CAAC,CAAC,CAChG,KAAK,YAAY,QAAQ,KAAK,MAAM,qBAAqB,MAAM,CAAC;AACrE;AAEA,SAAS,eAAe,KAAa,OAAuC;CAC1E,OAAO;EACL,QAAQ,CAAC;EACT,aAAa,CAAC,GAAG,IAAI,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;CACnF;AACF;;;;;;;;;AAUA,SAAgB,qBACd,IACA,eACA,oBACA,eACgB;CAChB,IAAI,qBAAqB;CACzB,IAAI;CACJ,IAAI,yBAAyB;CAE7B,MAAM,kBAAkB,OAAO,eAAqF;EAClH,MAAM,WAAW,MAAM,WAAW;EAClC,OAAO,sBAAsB,aAAa,WAAW,KAAA;CACvD;CAEA,OAAO;EACL,QAAQ;GACN,gBAAgB,QAAQ,QAAQ;IAC9B,MAAM,QAAQA,2BAAyB,cAAc,CAAC,CAAC,CAAC;IAOxD,oBAAoB;KAAE,IAAA,EANT;KAMa,OALZ,mBAAmB,CAAC,CAC/B,MAAM,EAAE,0BACP,IAAI,oBAAoB;MAAE,KAAK,IAAI;MAAK,YAAY,MAAM;KAAiB,CAAC,CAAC,CAAC,MAAM,CACtF,CAAC,CACA,OAAO,UAAmB,eAAe,IAAI,KAAK,KAAK,CAC5B;KAAG,kBAAkB;IAAM;IACzD,yBAAyB;GAC3B;GACA,OAAO,OAAO,UAAU;IACtB,IAAI,CAAC,MAAM,KAAK,WAAA,SAAkC,GAAG,OAAO,EAAE,QAAQ,WAAW;IAEjF,MAAM,aAAa;IACnB,IAAI,CAAC,YAAY,OAAO,EAAE,QAAQ,WAAW;IAC7C,MAAM,WAAW,MAAM,gBAAgB,UAAU;IACjD,IAAI,CAAC,UAAU,OAAO,EAAE,QAAQ,WAAW;IAE3C,MAAM,YAAY,cAAc,MAAM;KACpC,cAAc,CAAC;KACf,gBAAgB,SAAS;KACzB,kBAAkB,wBAAwB,EAAE;IAC9C,CAAC;IACD,MAAM,EAAE,+BAA+B,MAAM,mBAAmB;IAChE,MAAM,OAAO,2BAA2B,MAAM,MAAM,UAAU,gBAAgB;IAC9E,OAAO,SAAS,MAAM,OAAO,EAAE,QAAQ,WAAW,IAAI;KAAE,QAAQ;KAAa;KAAM,QAAQ,MAAM;IAAO;GAC1G;GACA,oBAAoB,OAAO,OAAO,QAAQ;IACxC,MAAM,aAAa;IACnB,IAAI,CAAC,YAAY,OAAO,KAAA;IACxB,MAAM,WAAW,MAAM,gBAAgB,UAAU;IACjD,IAAI,CAAC,UAAU,OAAO,KAAA;IAEtB,IAAI,CAAC,WAAW,oBAAoB,SAAS,YAAY,SAAS,GAAG;KACnE,WAAW,mBAAmB;KAC9B,IAAI,GAAG,OAAO,qBAAqB,SAAS,YAAY,KAAK,IAAI,KAAK,OAAO;IAC/E;IACA,MAAM,YAAY,cAAc,MAAM;KACpC,cAAc,MAAM,oBAAoB,UAAU,CAAC;KACnD,gBAAgB,SAAS;IAC3B,CAAC;IACD,IAAI,UAAU,kBAAkB,wBAAwB;KACtD,yBAAyB,UAAU;KACnC,IAAI,UAAU,YAAY,SAAS,GACjC,IAAI,GAAG,OAAO,kBAAkB,UAAU,YAAY,KAAK,IAAI,KAAK,OAAO;IAE/E;IACA,IAAI,UAAU,iBAAiB,WAAW,GAAG,OAAO,KAAA;IAEpD,MAAM,EAAE,kCAAkC,MAAM,mBAAmB;IACnE,OAAO,EACL,cAAc,8BAA8B,MAAM,cAAc,MAAM,qBAAqB,CACzF,GAAG,UAAU,gBACf,CAAC,EACH;GACF;EACF;EACA,SAAS;GACP,oBAAoB,KAAA;EACtB;EACA,SAAS,YAAa,oBAAoB,gBAAgB,iBAAiB,IAAI,KAAA;CACjF;AACF;;AAGA,SAAgB,eAAe,eAA8B,WAA2B;CACtF,OAAO,OAAO,QAA0B;EACtC,MAAM,WAAW,MAAM,UAAU,QAAQ;EACzC,MAAM,YAAY,cAAc,MAAM;GAEpC,cACG,IAAsE,uBAAuB,CAAC,CAAC,UAAU,CAAC;GAC7G,gBAAgB,UAAU,UAAU,CAAC;EACvC,CAAC;EACD,OAAO;GAAE,YAAY,UAAU;GAAY,aAAa,UAAU;EAAY;CAChF;AACF;;;ACtIA,MAAM,OAAO;AACb,MAAM,QAAQ;AAmBd,SAAgB,oBACd,cAC6C;CAC7C,OAAO,CACL,gBACA;EACE,aAAa;EACb,SAAS,OAAO,OAAO,QAAQ;GAC7B,IAAI,CAAC,IAAI,SAAS,IAAI,SAAS,OAAO;IACpC,IAAI,GAAG,OAAO,qCAAqC,KAAK;IACxD;GACF;GAEA,MAAM,QAAQC,2BAAyB,aAAa,cAAc,CAAC,CAAC,CAAC;GACrE,MAAM,CAAC,UAAU,aAAa,MAAM,QAAQ,IAAI,CAC9C,aAAa,eAAe,GAAG,GAC/B,aAAa,UAAU,GAAG,CAC5B,CAAC;GACD,MAAM,UAAU,MAAM,aAAa,aAAa;IAC9C;IACA,wBAAwB,MAAM;IAC9B,kBAAkB,aAAa,iBAAiB;IAChD,YAAY,UAAU;IACtB,iBAAiB,CAAC,GAAG,UAAU,WAAW;GAC5C,CAAC;GAED,MAAM,SAAS,MAAM,aAAa,YAAY,KAAK;IAAE;IAAS;GAAS,CAAC;GACxE,IAAI,CAAC,QAAQ;GACb,IAAI,GAAG,cAAc,gBAAgB,OAAO,MAAM,IAAI,CAAC;GACvD,IAAI,GAAG,OAAO,UAAU,OAAO,MAAM,KAAK,2CAA2C,IAAI;EAC3F;CACF,CACF;AACF;;;;;;;;;ACpCA,SAAS,cAAc;CACrB,IAAI;CACJ,IAAI;CACJ,OAAO;EACL,eAAgB,YAAY,OAAO,+BAAuC,CAAA,MAAA,MAAA,EAAA,CAAA;EAC1E,gBAAiB,aAAa,OAAO,iCAAyC,CAAA,MAAA,MAAA,EAAA,CAAA;CAChF;AACF;AAOA,SAAgB,mBAAmB,EAAE,IAAI,eAAyD;CAChG,MAAM,OAAO,YAAY;CACzB,IAAI;CACJ,IAAI;CACJ,MAAM,cAAc,WAAoB;EACtC,OAAO,OAAO,CAAC,mBAAmB,IAAI,YAAY;GAChD,gBAAgB;GAChB,aAAa;IACX,IAAI,kBAAkB,SAAS,gBAAgB,KAAA;GACjD;EACF,CAAC;CACH;CACA,MAAM,8BAAuC;EAC3C,IAAI,CAAC,eAAe,MAAM,IAAI,MAAM,+DAA+D;EACnG,OAAO;CACT;CACA,MAAM,4BAAqD;EACzD,IAAI,CAAC,eAAe,MAAM,IAAI,MAAM,gEAAgE;EACpG,OAAO;CACT;CACA,MAAM,eAAe,WAAoB;EACvC,OAAO,OAAO,CAAC,2BAA2B,IAAI,mBAAmB;GAC/D,MAAM,UAAU,eAAe,IAAI,2BAA2B;GAC9D,MAAM,UAAU,8BAA8B,GAAG,QAAQ,WAAW,eAAe;GACnF,eAAe,QAAQ,oBAAoB;IACzC,gBAAgB,QAAQ,4BAA4B,OAAO;GAC7D,CAAC;GACD,gBAAgB;GAChB,aAAa;IACX,IAAI,kBAAkB,SAAS,gBAAgB,KAAA;IAC/C,QAAQ,QAAQ;GAClB;EACF,CAAC;CACH;CACA,MAAM,gBAAgB,0BAA0B;CAEhD,MAAM,YAAY,WAAoB;EACpC,OAAO,OAAO,CAAC,iBAAiB,IAAI,gBAAgB;GAClD,MAAM,OAAO,uBAAuB,WAAW;GAC/C,MAAM,SAAS,cAAc,KAAK,IAAI;GACtC,MAAM,kBAAkB,KAAK,mBAAmB,YAAY;IAC1D,MAAM,WAAW,MAAM,UAAU,QAAQ;IACzC,IAAI,CAAC,UAAU,OAAO,KAAA;IACtB,OAAO,cACJ,MAAM;KACL,cAAc,CAAC;KACf,kBAAkB,wBAAwB,EAAE;KAC5C,gBAAgB,SAAS;IAC3B,CAAC,CAAC,CACD,WAAW,KAAK,UAAU,MAAM,QAAQ;GAC7C,CAAC;GACD,aAAa;IACX,gBAAgB;IAChB,OAAO;GACT;EACF,CAAC;CACH;CACA,MAAM,UAAU,WAAoB;EAClC,OAAO,OAAO,CAAC,mBAAmB,IAAI,cAAc;GAClD,MAAM,eAAe,iBAAiB,SAAS,CAAC,CAAC,eAAe,0BAA0B;GAC1F,aAAa,aAAa,QAAQ;EACpC,CAAC;CACH;CACA,MAAM,YAAY,qBAAqB,IAAI,eAAe,KAAK,UAAU,qBAAqB;CAC9F,OAAO;EACL,UAAU;GAAC;GAAY;GAAa;GAAU;EAAM;EACpD,UAAU,CACR,oBAAoB;GAClB,eAAe;GACf,wBAAwB,oBAAoB,CAAC,CAAC,KAAK;GACnD,WAAW,OAAO,QAAQ;IACxB,OAAO,eAAe,eAAe,SAAS,CAAC,CAAC,GAAG;GACrD;GACA,gBAAgB,OAAO,SACrB,mBAAmB,yBAAyB,sBAAsB,CAAC,CAAC,CAAC,OAAO;GAC9E,cAAc,OAAO,aAAa,MAAM,KAAK,QAAQ,EAAA,CAAG,kBAAkB,OAAO;GACjF;EACF,CAAC,CACH;EACA,QAAQ,UAAU;EAClB,QAAQ,UAAU;EAClB,YAAY;GACV,cAAc,QAAQ;EACxB;CACF;AACF;;;ACzHA,IAAA,mBAAe,YAAY,EAAE,SAA0B;CACrD,MAAM,UAAU,mBAAmB;EACjC;EACA,aAAa,OAAO,SAAS,aAC1B,MAAM,OAAO,gCAAgC,CAAA,MAAA,MAAA,EAAA,CAAA,EAAA,CAAE,kBAAkB,SAAS,OAAO;CACtF,CAAC;CACD,OAAO;EAAE,OAAO;EAAS,UAAU,QAAQ;EAAU,QAAQ,QAAQ;EAAQ,WAAW,QAAQ;CAAU;AAC5G,CAAC;;;ACND,IAAA,qBAAe,kBACZ,YAAuF,QAAQ,KAAK,SAAU,EACjH;;;ACFA,IAAA,+BAAe,eACZ,YACC,QAAQ,KAAK,OAAQ,kBACzB;;;ACHA,IAAA,oBAAe,eACZ,YAAuF,QAAQ,KAAK,OAAQ,KAC/G;;;ACFA,IAAA,2BAAe,eACZ,YACC,QAAQ,KAAK,OAAQ,aACzB;;;ACLA,IAAA,mBAAe,eAAe;CAC5B,QAAQ;CACR,WAAW,YAAY;CACvB,QAAQ,CACN;EACE,MAAM;EACN,aACE;CACJ,GACA;EACE,MAAM;EACN,aACE;CACJ,CACF;AACF,CAAC;;;ACAD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,YAAY,kBAAoC,2BAA2B,OAAO,YAAY;CACzG,MAAM,eAAe,MAAMC,iBAAY,OAAO;CAC9C,MAAM,iBAAiB;EAAE,GAAG;EAAS,MAAM,aAAa;CAAM;CAC9D,OAAO;EACL,GAAG,iBAAiB,YAAY;EAChC,IAAI,WAA8C;GAAE,OAAO,CAAC,GAAGC,oBAAe,cAAc,CAAC;EAAG;EAChG,QAAQ;GACN,oBAAoB,GAAGC,8BAAsB,cAAc;GAC3D,OAAO,GAAGC,mBAAW,cAAc;GACnC,eAAe,GAAGC,0BAAkB,cAAc;EACpD;EACA,IAAI,YAAgD;GAAE,OAAO,CAAC,GAAGC,kBAAc,cAAc,CAAC;EAAG;EACjG,UAAU,CAAC,GAAI,aAAa,YAAY,CAAC,CAAE;CAC7C;AACF,CAAC"}