{"version":3,"file":"in_memory.cjs","names":["#entries"],"sources":["../../../src/batteries/skills/in_memory/index.ts"],"sourcesContent":["/**\n * Reference in-memory SkillSource for tests and small deployments.\n *\n * @module @nhtio/adk/batteries/skills/in_memory\n */\n\nimport { parseSkillMd } from '../manifest'\nimport type { SkillDescriptor } from '../types'\nimport type { DiscoveredSkill, SkillRef, SkillSource } from '../contracts'\n\ntype Entry = {\n  readonly ref: DiscoveredSkill\n  readonly manifest: string\n  readonly descriptor: SkillDescriptor\n  readonly files?: Readonly<Record<string, string | Uint8Array>>\n}\n\nconst stream = (value: string | Uint8Array): ReadableStream<Uint8Array> => {\n  const bytes = typeof value === 'string' ? new TextEncoder().encode(value) : value\n  return new ReadableStream({\n    start(controller) {\n      controller.enqueue(bytes)\n      controller.close()\n    },\n  })\n}\n\n/** A mutable, deterministic SkillSource backed by SKILL.md strings. */\nexport class InMemorySkillSource implements SkillSource {\n  /** Source provenance stamped onto every discovered reference. */\n  readonly id: string\n  readonly #entries = new Map<string, Entry>()\n\n  constructor(\n    id: string,\n    entries: ReadonlyArray<{\n      readonly id: string\n      readonly version: string\n      readonly manifest: string\n      readonly descriptor: SkillDescriptor\n      readonly files?: Readonly<Record<string, string | Uint8Array>>\n    }>\n  ) {\n    this.id = id\n    for (const entry of entries) {\n      const parsed = parseSkillMd(entry.manifest)\n      const frontmatter = parsed.frontmatter\n      const ref: DiscoveredSkill = {\n        id: entry.id,\n        version: entry.version,\n        name: frontmatter.name as string,\n        description: frontmatter.description as string,\n        ...(typeof frontmatter.license === 'string' ? { license: frontmatter.license } : {}),\n        ...(frontmatter.metadata && typeof frontmatter.metadata === 'object'\n          ? { metadata: frontmatter.metadata as Record<string, string> }\n          : {}),\n        ...(typeof frontmatter.compatibility === 'string'\n          ? { compatibility: frontmatter.compatibility }\n          : {}),\n      }\n      this.#entries.set(entry.id, {\n        ref,\n        manifest: entry.manifest,\n        descriptor: entry.descriptor,\n        files: entry.files,\n      })\n    }\n  }\n\n  /** Yields the precomputed routing metadata without loading descriptors. */\n  async *discover(): AsyncIterable<DiscoveredSkill> {\n    for (const entry of this.#entries.values()) yield entry.ref\n  }\n\n  /** Returns the live descriptor for a discovered id. */\n  async descriptor(ref: SkillRef): Promise<SkillDescriptor> {\n    const entry = this.#entries.get(ref.id)\n    if (!entry) throw new Error(`unknown skill: ${ref.id}`)\n    return entry.descriptor\n  }\n\n  async read(ref: SkillRef, path?: string): Promise<ReadableStream<Uint8Array>> {\n    const entry = this.#entries.get(ref.id)\n    if (!entry) throw new Error(`unknown skill: ${ref.id}`)\n    if (path === undefined) return stream(parseSkillMd(entry.manifest).body)\n    const value = entry.files?.[path]\n    if (value === undefined) throw new Error(`unknown file: ${path}`)\n    return stream(value)\n  }\n\n  /** Reports byte size and current entry version for the body or a bundled file. */\n  async stat(ref: SkillRef, path?: string): Promise<{ size: number; version: string }> {\n    const bytes = await new Response(await this.read(ref, path)).arrayBuffer()\n    return {\n      size: bytes.byteLength,\n      version: this.#entries.get(ref.id)?.ref.version ?? ref.version,\n    }\n  }\n\n  async list(ref: SkillRef): Promise<readonly string[]> {\n    return Object.keys(this.#entries.get(ref.id)?.files ?? {})\n  }\n}\n"],"mappings":";;;;;;;;;AAiBA,IAAM,UAAU,UAA2D;CACzE,MAAM,QAAQ,OAAO,UAAU,WAAW,IAAI,YAAY,EAAE,OAAO,KAAK,IAAI;CAC5E,OAAO,IAAI,eAAe,EACxB,MAAM,YAAY;EAChB,WAAW,QAAQ,KAAK;EACxB,WAAW,MAAM;CACnB,EACF,CAAC;AACH;;AAGA,IAAa,sBAAb,MAAwD;;CAEtD;CACA,2BAAoB,IAAI,IAAmB;CAE3C,YACE,IACA,SAOA;EACA,KAAK,KAAK;EACV,KAAK,MAAM,SAAS,SAAS;GAE3B,MAAM,cADS,iBAAA,aAAa,MAAM,QACd,EAAO;GAC3B,MAAM,MAAuB;IAC3B,IAAI,MAAM;IACV,SAAS,MAAM;IACf,MAAM,YAAY;IAClB,aAAa,YAAY;IACzB,GAAI,OAAO,YAAY,YAAY,WAAW,EAAE,SAAS,YAAY,QAAQ,IAAI,CAAC;IAClF,GAAI,YAAY,YAAY,OAAO,YAAY,aAAa,WACxD,EAAE,UAAU,YAAY,SAAmC,IAC3D,CAAC;IACL,GAAI,OAAO,YAAY,kBAAkB,WACrC,EAAE,eAAe,YAAY,cAAc,IAC3C,CAAC;GACP;GACA,KAAKA,SAAS,IAAI,MAAM,IAAI;IAC1B;IACA,UAAU,MAAM;IAChB,YAAY,MAAM;IAClB,OAAO,MAAM;GACf,CAAC;EACH;CACF;;CAGA,OAAO,WAA2C;EAChD,KAAK,MAAM,SAAS,KAAKA,SAAS,OAAO,GAAG,MAAM,MAAM;CAC1D;;CAGA,MAAM,WAAW,KAAyC;EACxD,MAAM,QAAQ,KAAKA,SAAS,IAAI,IAAI,EAAE;EACtC,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,kBAAkB,IAAI,IAAI;EACtD,OAAO,MAAM;CACf;CAEA,MAAM,KAAK,KAAe,MAAoD;EAC5E,MAAM,QAAQ,KAAKA,SAAS,IAAI,IAAI,EAAE;EACtC,IAAI,CAAC,OAAO,MAAM,IAAI,MAAM,kBAAkB,IAAI,IAAI;EACtD,IAAI,SAAS,KAAA,GAAW,OAAO,OAAO,iBAAA,aAAa,MAAM,QAAQ,EAAE,IAAI;EACvE,MAAM,QAAQ,MAAM,QAAQ;EAC5B,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,MAAM,iBAAiB,MAAM;EAChE,OAAO,OAAO,KAAK;CACrB;;CAGA,MAAM,KAAK,KAAe,MAA2D;EAEnF,OAAO;GACL,OAAM,MAFY,IAAI,SAAS,MAAM,KAAK,KAAK,KAAK,IAAI,CAAC,EAAE,YAAY,GAE3D;GACZ,SAAS,KAAKA,SAAS,IAAI,IAAI,EAAE,GAAG,IAAI,WAAW,IAAI;EACzD;CACF;CAEA,MAAM,KAAK,KAA2C;EACpD,OAAO,OAAO,KAAK,KAAKA,SAAS,IAAI,IAAI,EAAE,GAAG,SAAS,CAAC,CAAC;CAC3D;AACF"}