{"version":3,"file":"index.cjs","names":["DOOM_HELP_MAX_DIAGNOSTIC_LENGTH","createSyntheticSourceInfo","DOOM_HELP_MAX_DIAGNOSTICS"],"sources":["../../../../src/services/helpSkills/index.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"],"mappings":"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"}