loadSkillFromZipBytes function

Skill loadSkillFromZipBytes(
  1. List<int> zipBytes
)

Loads a Skill from ZIP bytes containing a root-level SKILL.md.

Implementation

Skill loadSkillFromZipBytes(List<int> zipBytes) {
  final archive.Archive skillArchive = archive.ZipDecoder().decodeBytes(
    zipBytes,
  );
  final Map<String, archive.ArchiveFile> files =
      <String, archive.ArchiveFile>{};
  for (final archive.ArchiveFile entry in skillArchive) {
    final String name = _normalizeArchiveEntryName(entry.name);
    _assertSafeArchiveEntry(entry.name, name);
    if (!entry.isFile) {
      continue;
    }
    if (entry.isSymbolicLink) {
      throw ArgumentError('Dangerous zip entry ignored: ${entry.name}');
    }
    files[name] = entry;
  }

  final archive.ArchiveFile? skillMd = files['SKILL.md'] ?? files['skill.md'];
  if (skillMd == null) {
    throw StateError('SKILL.md not found in zipped filesystem.');
  }
  final List<int>? skillMdBytes = skillMd.readBytes();
  if (skillMdBytes == null) {
    throw const FormatException(
      'SKILL.md could not be read from zipped filesystem.',
    );
  }

  final _ParsedSkillMd parsed = _parseSkillMdContent(
    _decodeSkillText(skillMdBytes),
  );
  final Object? skillName = parsed.frontmatter['name'];
  if (skillName == null) {
    throw ArgumentError("SKILL.md frontmatter must contain 'name'");
  }
  if (skillName is! String || _isInvalidArchiveSkillName(skillName)) {
    throw ArgumentError('Invalid skill name in SKILL.md: $skillName');
  }
  final Frontmatter frontmatter = Frontmatter.fromMap(parsed.frontmatter);

  final Map<String, SkillResourceData> references =
      <String, SkillResourceData>{};
  final Map<String, SkillResourceData> assets = <String, SkillResourceData>{};
  final Map<String, Script> scripts = <String, Script>{};
  for (final MapEntry<String, archive.ArchiveFile> entry in files.entries) {
    if (entry.key == 'SKILL.md' || entry.key == 'skill.md') {
      continue;
    }
    if (_containsIgnoredArchiveSegment(entry.key)) {
      continue;
    }
    final List<int>? bytes = entry.value.readBytes();
    if (bytes == null) {
      continue;
    }
    if (entry.key.startsWith('references/')) {
      final String resourceId = entry.key.substring('references/'.length);
      if (resourceId.isNotEmpty) {
        references[resourceId] = _decodeSkillResource(resourceId, bytes);
      }
      continue;
    }
    if (entry.key.startsWith('assets/')) {
      final String resourceId = entry.key.substring('assets/'.length);
      if (resourceId.isNotEmpty) {
        assets[resourceId] = _decodeSkillResource(resourceId, bytes);
      }
      continue;
    }
    if (entry.key.startsWith('scripts/')) {
      final String scriptId = entry.key.substring('scripts/'.length);
      if (scriptId.isEmpty) {
        continue;
      }
      try {
        scripts[scriptId] = Script(src: _decodeSkillText(bytes));
      } on FormatException {
        continue;
      }
    }
  }

  return Skill(
    frontmatter: frontmatter,
    instructions: parsed.body,
    resources: Resources(
      references: references,
      assets: assets,
      scripts: scripts,
    ),
  );
}