{
  "specVersion": "1.0",
  "host": {
    "displayName": "StealthStack",
    "identifier": "did:web:stealthstack.ai"
  },
  "entries": [
    {
      "identifier": "urn:air:stealthstack.ai:skill:archives",
      "displayName": "Archive Container Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/archives/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, list, and extract archive containers (.zip, .tar, .gz, .7z) to JSON or text. Use when inspecting or unpacking compressed file bundles.",
      "tags": [
        "archive",
        "zip",
        "tar",
        "gzip",
        "7z",
        "extraction",
        "compression",
        "conversion"
      ],
      "capabilities": [
        "ListContents",
        "ExtractFiles",
        "ReadArchive",
        "ConvertToJson",
        "InspectMetadata"
      ],
      "representativeQueries": [
        "Read a .zip file and show me what's inside",
        "Extract files from a tar.gz archive",
        "List contents of a .7z archive",
        "Convert archive contents to JSON",
        "Inspect files in a compressed archive"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.203Z",
      "metadata": {
        "context": "- .zip: local file headers at byte offsets + central directory at end-of-file. Python stdlib zipfile handles deflate, stored, bzip2, lzma. Password-protected ZIPs are not supported by this script (no --password argument); the stdlib API does accept a pwd= parameter but it is not wired up here.\n- .tar / .tar.gz / .tar.bz2 / .tar.xz: GNU/POSIX tape archive, optionally compressed. Use tarfile.open() with mode 'r:*' to auto-detect compression. tarfile does NOT support zip64 extra headers.\n- .gz (bare gzip, not tar): a single compressed file — gzip wraps exactly one stream. Use gzip.open() to decompress. There is no file listing; the original filename is stored in the header (fname field) but is optional.\n- .7z: proprietary format. The Python stdlib has NO native 7z support. The py7zr third-party library is required for extraction. Without it, the script reports the magic bytes (37 7A BC AF 27 1C) and exits with a clear message. The script uses subprocess to call the system `7z` CLI if available as a fallback.\n- ZIP path traversal: zipfile raises BadZipFile for structurally invalid ZIPs; always sanitize extracted paths (strip leading '/' and '..') when writing to disk.\n- tarfile path traversal: the script manually iterates members with extractfile() rather than calling tarfile.extractall(), so the filter parameter is not used. Path traversal is prevented by sanitizing member paths before writing to disk.\n- Symlink bombs: tar archives can contain symlinks pointing outside the destination. The script skips non-regular-file members (symlinks, devices) during --extract-all.\n- Large archives: listing does not decompress member content — it reads only headers. Extraction can be selective (single member) to avoid expanding multi-GB archives.\n- .tar.gz is the same as .tgz; tarfile.open() with 'r:*' handles both extensions identically.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:ard-skill-builder",
      "displayName": "ARD Skill Builder",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/ard-skill-builder/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Author StealthStack ARD-1 SKILL.md files that drop straight into the catalog. Use when creating, scaffolding, or validating a new skill for the ARD registry.",
      "tags": [
        "meta",
        "skill-authoring",
        "ard",
        "catalog",
        "builder"
      ],
      "capabilities": [
        "ClassifyPrimitive",
        "ComposeSkillMd",
        "GenerateRepresentativeQueries",
        "ExtractContext",
        "ValidateFrontmatter"
      ],
      "representativeQueries": [
        "Create a new ARD skill for sending Slack messages",
        "Turn this API into a catalog skill",
        "Scaffold a SKILL.md that passes ARD validation",
        "Help me author a skill for the StealthStack catalog",
        "Generate a skill folder I can drop into ard-1/public/skills"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-19T20:56:57.000Z",
      "metadata": {
        "context": "- The catalog generator maps frontmatter -> one ARD entry of type application/ai-skill+md; never set auto fields (identifier, type, url, trustManifest, updatedAt, host).\n- representativeQueries MUST be 2-5 items or the field is dropped (losing the ranking surface) — aim for 4-5 real user phrasings, not keywords.\n- The folder name IS the slug, URL and URN; it must equal frontmatter `name` (kebab-case), be unique and stable. A folder starting with `_` is an excluded draft.\n- `context` is the trust root: extract from real source only, never invent; ship `context_verified: false` until a human signs off. (Unlike representativeQueries, do not free-generate it.)\n- Faithful-minimal beats example-rich: fabricated tool slugs/params/examples are the top failure mode. Don't claim capabilities the skill can't deliver.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:arrow",
      "displayName": "Arrow / Feather Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/arrow/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert Apache Arrow columnar files (.arrow, .feather) to CSV or JSON. Use when opening or transforming Arrow/Feather data files.",
      "tags": [
        "data",
        "arrow",
        "feather",
        "columnar",
        "csv",
        "json",
        "converter",
        "extractor"
      ],
      "capabilities": [
        "ReadArrow",
        "InspectSchema",
        "ConvertToCsv",
        "ConvertToJson",
        "ExtractSample"
      ],
      "representativeQueries": [
        "Read a .arrow or .feather file and show me the data",
        "Convert an Arrow file to CSV",
        "What is the schema of this .feather file?",
        "Extract a sample of rows from an Arrow dataset",
        "Convert Arrow columnar data to JSON"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.204Z",
      "metadata": {
        "context": "- Apache Arrow IPC format uses two sub-formats: IPC Stream (no magic bytes, unbounded record batches) and IPC File/Random-Access (magic \"ARROW1\" at offset 0, allows seeking). The script tries ipc.open_file first and falls back to ipc.open_stream on failure — pyarrow itself does not auto-detect the sub-format.\n- Feather v1 (legacy) and Feather v2 (Arrow IPC File with LZ4/ZSTD compression) are distinct on-disk formats. pyarrow.feather.read_feather handles both transparently.\n- Column types map to Arrow types (int8..int64, float16/32/64, utf8, large_utf8, binary, list, struct, dictionary). Dictionary-encoded columns decode to their value types on to_pandas().\n- Null handling: Arrow distinguishes null (missing) from NaN (float not-a-number). The converter uses csv.writer directly (not pandas): Arrow nulls become empty CSV fields; NaN floats appear as the string 'nan'.\n- Large files: reading the full table into memory can OOM. Use pyarrow.dataset or ipc.open_file(...).get_batch(i) to page through record batches. For JSON output the converter buffers all records in memory before writing; use --rows N to cap output size.\n- pyarrow requires: pip install pyarrow (includes both arrow and feather support).",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:avro",
      "displayName": "Avro Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/avro/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert Apache Avro (.avro) files to CSV, JSON, or JSONL. Use when opening .avro files, extracting embedded schema, or exporting records.",
      "tags": [
        "data",
        "avro",
        "schema",
        "csv",
        "json",
        "conversion",
        "extractor"
      ],
      "capabilities": [
        "ReadAvro",
        "InspectSchema",
        "ConvertToCsv",
        "ConvertToJson",
        "ConvertToJsonl",
        "SampleRows"
      ],
      "representativeQueries": [
        "Read a .avro file and show me the data",
        "Convert avro to CSV",
        "Extract the schema from an avro file",
        "Convert avro to JSON or JSONL",
        "Sample the first rows of an avro file"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.204Z",
      "metadata": {
        "context": "- Avro is a binary row-based format; it cannot be read as plain text — always use fastavro or a compatible library.\n- Every Avro file embeds its writer schema in the file header (the first object container block). The schema is always recoverable from the file itself without any external registry.\n- Avro supports rich types: record, array, map, union, enum, fixed, bytes, and logical types (date, time-millis, timestamp-millis, decimal). Union fields commonly appear as [\"null\", \"someType\"] for nullable columns — fastavro resolves unions to Python None or the concrete value automatically.\n- Logical type \"decimal\" is stored as bytes/fixed with scale/precision metadata; fastavro returns it as a Python Decimal — cast to string or float before JSON serialisation.\n- Large Avro files are written in sync-delimited blocks; fastavro iterates records lazily (reader is a generator) so memory usage is low even for multi-GB files.\n- fastavro's `reader` returns dicts by default; nested records become nested dicts, arrays become lists, maps become dicts.\n- Avro does NOT store column statistics or row counts in the header — you must iterate all records to count rows.\n- Schema evolution (reader vs writer schema) is supported: pass a reader_schema to fastavro.reader to project/promote fields.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:dbf",
      "displayName": "dBase DBF Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/dbf/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts dBase .dbf binary table files to text, CSV, or JSON. Use when inspecting or extracting data from legacy GIS, FoxPro, or dBase databases.",
      "tags": [
        "dbf",
        "dbase",
        "foxpro",
        "extractor",
        "csv",
        "json",
        "converter",
        "gis",
        "legacy"
      ],
      "capabilities": [
        "ReadDbf",
        "ConvertToCsv",
        "ConvertToJson",
        "DumpSchema",
        "InspectFields"
      ],
      "representativeQueries": [
        "read a .dbf file and show me what's inside",
        "convert dbf to CSV",
        "extract data from a dBase or FoxPro database file",
        "what fields are in this .dbf file",
        "export a DBF table to JSON"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.206Z",
      "metadata": {
        "context": "- dBase .dbf files begin with a 1-byte version code (0x03 = dBase III+, 0x83 = with memo, 0x30 = Visual FoxPro, 0xF5 = FoxPro 2.x with memo). Files that don't start with a recognised version byte are likely not valid .dbf files.\n- The header encodes number of records (bytes 4-7, little-endian uint32), header size (bytes 8-9), and record size (bytes 10-11). Field descriptors start at byte 32, each 32 bytes long, terminated by a 0x0D byte.\n- Field types: C (Character), N (Numeric), F (Float), D (Date, YYYYMMDD), L (Logical, T/F/Y/N), M (Memo pointer — needs a .dbt or .fpt sidecar), I (Integer, FoxPro), B (Double, FoxPro), @ (DateTime, FoxPro), + (Autoincrement, FoxPro).\n- Character encoding is not stored in the header in older versions; byte 29 of the header is the \"language driver ID\" (codepage mark) in dBase IV+ and FoxPro. Common values: 0x00 = unknown/DOS 437, 0x03 = Windows ANSI (CP1252), 0x04 = Macintosh, 0x64 = Eastern European (CP1250). When unknown, try cp1252 then fall back to latin-1.\n- The `dbfread` Python library (pip install dbfread) handles version detection, codepage lookup, and memo sidecar files automatically. Use it over raw struct parsing unless dbfread fails.\n- Deleted records have a '*' (0x2A) in their first byte; dbfread skips them by default (set `deleted=True` to include). Raw struct parsers must skip 0x1A (EOF marker) records.\n- Memo fields (.dbt for dBase III/IV, .fpt for FoxPro/Visual FoxPro) must reside in the same directory as the .dbf. Missing sidecar = memo values read as None/empty.\n- Numeric fields stored as blank strings represent NULL; do not coerce to 0.\n- Date fields come back as datetime.date objects from dbfread; serialise via .isoformat() for JSON.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:doc",
      "displayName": "Legacy Word (.doc) Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/doc/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert legacy OLE/CFB binary Word .doc files to plain text, JSON, or CSV. Use when you need to open or extract content from pre-2007 Word documents.",
      "tags": [
        "document",
        "word",
        "doc",
        "ole",
        "cfb",
        "convert",
        "extract",
        "legacy"
      ],
      "capabilities": [
        "ReadDoc",
        "ConvertToText",
        "ConvertToJson",
        "ConvertToCsv",
        "ExtractMetadata"
      ],
      "representativeQueries": [
        "Read a .doc file and show me the text",
        "Convert a legacy Word doc to plain text",
        "Extract content from a .doc file to JSON or CSV",
        "Open an old Word document and get the text out",
        "Convert a pre-2007 .doc file to a readable format"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.206Z",
      "metadata": {
        "context": "- .doc files use the OLE Compound File Binary (CFB) format, not ZIP/XML like .docx. Standard ZIP tools and XML parsers will fail on them.\n- The python-docx library only supports .docx (OOXML); it cannot open .doc files at all.\n- Recommended extraction libraries: olefile (low-level OLE stream reader, `pip install olefile`), textract, or antiword CLI. Note: olefile and oletools (python-oletools) are separate packages with different purposes — olefile reads OLE streams, oletools is a security-analysis toolkit. antiword is fast but may not be available on all platforms. textract wraps several backends (antiword, LibreOffice) and is the most portable Python option.\n- LibreOffice --headless can batch-convert .doc to .docx or .txt: `soffice --headless --convert-to txt <file>`. Reliable but slow (LibreOffice runtime initialisation overhead, not JVM — LibreOffice is a C++ application).\n- Binary .doc files may contain embedded OLE objects, macros (VBA), revision marks, and proprietary fields that lose fidelity on extraction. Track-changes and comments are often lost.\n- Password-protected .doc files will fail extraction silently or with a generic error; surface this clearly to the user.\n- Encoding issues are common: older .doc files may use Windows-1252 or other legacy codepages. Use errors='replace' or errors='ignore' when decoding extracted bytes.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:eml",
      "displayName": "EML Email Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/eml/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts RFC 822 email files (.eml) to plain text, JSON, or CSV. Use when opening .eml files, extracting email content, headers, or attachments metadata.",
      "tags": [
        "eml",
        "email",
        "rfc822",
        "document",
        "converter",
        "mime"
      ],
      "capabilities": [
        "ReadEml",
        "ConvertToJson",
        "ConvertToCsv",
        "ConvertToText",
        "ExtractHeaders",
        "ExtractAttachmentMetadata"
      ],
      "representativeQueries": [
        "Read a .eml file and show me the email content",
        "Convert an eml email to JSON or CSV",
        "Extract headers from an .eml file",
        "What attachments are in this email file?",
        "Parse an RFC 822 email message"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.206Z",
      "metadata": {
        "context": "- EML files follow RFC 822 / RFC 2822 / RFC 5322. They are plain-text files with headers (From, To, Subject, Date, Message-ID, etc.) separated from the body by a blank line.\n- Multi-part messages use MIME (RFC 2045-2049): the Content-Type header includes a boundary string that delimits each part. A single email may nest multipart/mixed, multipart/alternative, and multipart/related parts.\n- The body part to display to humans is typically the last text/plain or text/html leaf in a multipart/alternative block; prefer text/plain over text/html for readability.\n- Header values may be encoded as RFC 2047 encoded-words: =?charset?encoding?text?= (B=base64, Q=quoted-printable). Python's email.header.decode_header() handles this.\n- Attachment parts have Content-Disposition: attachment (sometimes inline) and a filename parameter. Payload is usually base64-encoded; email.message.get_payload(decode=True) decodes it.\n- Dates in the Date header follow RFC 2822 format and are returned as decoded strings; email.utils.parsedate_to_datetime() can be used downstream to convert them to datetime objects if needed.\n- Some EML files omit the leading \"From \" (mbox separator). The script reads raw bytes, decodes to a string (UTF-8, then latin-1 fallback), and passes the result to email.message_from_string().\n- Charset defaults to ASCII/US-ASCII when not declared; real-world emails often include UTF-8 or ISO-8859-1 without declaring it — decode with errors='replace' to avoid crashes.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:epub",
      "displayName": "EPUB Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/epub/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts EPUB e-books to plain text, JSON, or CSV. Use when opening .epub files, extracting book content, or converting e-books to structured data.",
      "tags": [
        "epub",
        "ebook",
        "document",
        "converter",
        "text-extraction"
      ],
      "capabilities": [
        "ReadEpub",
        "ConvertToJson",
        "ConvertToCsv",
        "ConvertToText",
        "ExtractMetadata"
      ],
      "representativeQueries": [
        "Read a .epub file and show me the content",
        "Convert an epub to JSON or CSV",
        "Extract text from an epub e-book",
        "Get the chapter list from an epub",
        "What metadata is in this epub file?"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.207Z",
      "metadata": {
        "context": "- An EPUB is a ZIP archive. The container file at META-INF/container.xml points to the OPF package document (usually content.opf or similar), which lists spine items (reading order) and metadata.\n- Spine items reference XHTML/HTML documents inside the archive; reading order follows <spine> <itemref> elements, not the filesystem order.\n- Metadata fields live in the OPF <metadata> block: dc:title, dc:creator, dc:language, dc:publisher, dc:date, dc:identifier, dc:description.\n- Body text is inside XHTML files; strip tags to get plain text. Images, CSS, and fonts are also bundled but contain no readable prose.\n- EPUB 2 uses NCX (toc.ncx) for the table of contents; EPUB 3 uses a nav document (nav.xhtml with <nav epub:type=\"toc\">). Both may be present.\n- Some EPUBs encrypt content (DRM); the converter will find no readable text in encrypted items and should warn the user.\n- Chapter filenames are arbitrary — always follow the spine order from the OPF, not filename sort order.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:geojson",
      "displayName": "GeoJSON Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/geojson/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert .geojson files to CSV or JSON. Use when opening a GeoJSON file, extracting features, or exporting geometry and properties to another format.",
      "tags": [
        "geospatial",
        "geojson",
        "converter",
        "reader",
        "gis"
      ],
      "capabilities": [
        "ReadGeojson",
        "ConvertToCsv",
        "ConvertToJson",
        "ExtractFeatures",
        "SummarizeProperties"
      ],
      "representativeQueries": [
        "Read a .geojson file and show me its contents",
        "Convert GeoJSON to CSV",
        "Extract all features from a GeoJSON file",
        "Summarize the properties in a GeoJSON FeatureCollection",
        "Export GeoJSON geometry and attributes to JSON"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.208Z",
      "metadata": {
        "context": "- GeoJSON (RFC 7946) defines six geometry types: Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon; plus GeometryCollection.\n- The top-level object is usually a FeatureCollection containing a `features` array; each Feature has `type`, `geometry`, and `properties`.\n- A valid GeoJSON file may also be a bare Geometry or a single Feature (not wrapped in FeatureCollection).\n- Coordinates are [longitude, latitude] (x, y order) — not [lat, lon]. Elevation is an optional third element.\n- Properties are arbitrary JSON objects and may be null; values are not typed by the spec.\n- Large files can have thousands of features; reading the whole file into memory is fine for typical GIS exports (< 500 MB).\n- When converting to CSV, geometry is serialized as a JSON string in a `geometry` column; nested property objects are also serialized as JSON strings.\n- Files with extension .json are sometimes valid GeoJSON — check for `\"type\": \"FeatureCollection\"` or `\"type\": \"Feature\"` at root.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:gpx",
      "displayName": "GPX Track Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/gpx/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert .gpx GPS track files to CSV or JSON. Use when opening a GPX file, extracting waypoints/tracks, or exporting route data.",
      "tags": [
        "gps",
        "gpx",
        "geospatial",
        "converter",
        "reader",
        "tracks"
      ],
      "capabilities": [
        "ReadGpx",
        "ConvertToCsv",
        "ConvertToJson",
        "ConvertToGeoJson",
        "ExtractWaypoints",
        "ExtractTracks",
        "ExtractRoutes",
        "SummarizeTracks"
      ],
      "representativeQueries": [
        "Read a .gpx file and show me its contents",
        "Convert GPX tracks to CSV",
        "Extract waypoints from a GPX file",
        "Export GPX track points to JSON",
        "Convert a GPX file to GeoJSON for use in a mapping tool"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.208Z",
      "metadata": {
        "context": "- GPX (GPS Exchange Format) is an XML schema. The three main data types are: wpt (waypoints), rte/rtept (routes and route points), trk/trkseg/trkpt (tracks, track segments, track points).\n- Track points (trkpt) and waypoints (wpt) both carry lat/lon attributes and optional child elements: ele (elevation in meters), time (ISO 8601 UTC), name, desc, cmt, sym.\n- A track (trk) may contain multiple segments (trkseg); each segment is a continuous recording. A gap in recording produces a new segment.\n- GPX 1.1 (the current standard) uses namespace http://www.topografix.com/GPX/1/1; GPX 1.0 uses http://www.topografix.com/GPX/1/0. Always strip or handle the namespace when parsing with ElementTree.\n- Extension elements (under gpxtpx:TrackPointExtension) may carry heart rate, cadence, temperature, power — these are vendor-specific and optional.\n- Elevation is in meters above mean sea level (orthometric height, referenced to the geoid — not the WGS 84 ellipsoid). Time is UTC.\n- Files from Garmin, Strava, Komoot, AllTrails, and most GPS devices follow GPX 1.1; some older units export GPX 1.0.\n- Coordinates follow WGS 84: lat/lon in decimal degrees. Lat range -90 to 90, lon range -180 to 180.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:hcl",
      "displayName": "HCL / Terraform Config Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/hcl/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert HCL and Terraform (.tf, .hcl) config files to JSON or CSV. Use when opening Terraform configs, extracting resources, or exporting structured data.",
      "tags": [
        "hcl",
        "terraform",
        "config",
        "iac",
        "json",
        "conversion",
        "extractor"
      ],
      "capabilities": [
        "ReadHcl",
        "InspectBlocks",
        "ConvertToJson",
        "ExtractResources",
        "ConvertToCsv"
      ],
      "representativeQueries": [
        "Read a .tf file and show me the resources",
        "Convert HCL config to JSON",
        "Extract all resources from a Terraform file",
        "What blocks are defined in this .hcl file?",
        "Export Terraform config to CSV"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.209Z",
      "metadata": {
        "context": "- HCL (HashiCorp Configuration Language) is the native format for Terraform (.tf), Packer, Vault, Consul, and Nomad configs; python-hcl2 parses HCL2 only (the version used by Terraform 0.12+).\n- A .tf file typically contains multiple block types at the top level: resource, data, variable, output, locals, provider, terraform, module. Each block has a type label and one or two name labels, e.g. `resource \"aws_s3_bucket\" \"my_bucket\" { ... }`.\n- python-hcl2 returns a dict keyed by block type; within each type the value is a list of dicts. Each resource dict maps the first label (e.g. \"aws_s3_bucket\") to another dict keyed by the second label (e.g. \"my_bucket\"). In python-hcl2 >=4, both identifier label keys AND plain string attribute values are wrapped in extra double-quotes (e.g. `'\"aws_s3_bucket\"'`, `'\"us-east-1\"'`); the script strips these from all strings before output.\n- HCL expressions (function calls, references like `var.foo`, `local.bar`, template strings `\"${...}\"`) are returned as raw strings by python-hcl2; they are NOT evaluated.\n- Multi-file Terraform roots: Terraform merges all .tf files in a directory; python-hcl2 parses one file at a time — iterate over the directory to collect the full picture.\n- The `terraform` block and `required_providers` sub-block carry version constraints that are useful for inventory.\n- HCL2 supports `for` expressions, conditional expressions, and splat operators; python-hcl2 returns these as-is in string form — do not attempt to evaluate them.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:hdf5",
      "displayName": "HDF5 Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/hdf5/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert HDF5 (.h5, .hdf5) files to JSON or CSV. Use when inspecting scientific or ML datasets stored in hierarchical binary format.",
      "tags": [
        "data",
        "hdf5",
        "h5",
        "converter",
        "extractor",
        "scientific-data"
      ],
      "capabilities": [
        "ReadHdf5",
        "InspectStructure",
        "ConvertToCsv",
        "ConvertToJson",
        "SliceDataset"
      ],
      "representativeQueries": [
        "Read a .h5 file and show me its contents",
        "Convert HDF5 to CSV",
        "What datasets are inside this .hdf5 file?",
        "Extract a specific group or dataset from an HDF5 file",
        "Convert HDF5 to JSON for downstream processing"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.209Z",
      "metadata": {
        "context": "- HDF5 files are hierarchical: the root \"/\" contains Groups (like directories) and Datasets (like n-dimensional arrays or tables). Attributes attach metadata to either.\n- Datasets can be any NumPy dtype: float32/64, int, compound (struct-like), variable-length strings, or opaque bytes. Compound datasets map naturally to CSV rows; numeric arrays may need reshaping first.\n- Large datasets (millions of rows or multi-GB arrays) should be sliced with h5py dataset[start:end] — never load the whole array unless the file is small. The script supports this via --start N --rows M.\n- HDF5 files are sometimes written with SWMR (single-writer/multiple-reader) mode; open with mode='r' to avoid accidental corruption (true SWMR reading also requires swmr=True in h5py.File, but mode='r' prevents write-side errors).\n- Some HDF5 files use external links (h5py.ExternalLink) or virtual datasets pointing to other files on the original machine — these will error if those paths are absent.\n- Scalar datasets (shape ()) and 0-d attributes are common in ML checkpoints (e.g. epoch number, loss). They print as plain values, not arrays.\n- HDF5 compound types (structured arrays) are the closest HDF5 equivalent to a relational table and convert directly to CSV with column headers.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:ical",
      "displayName": "iCalendar Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/ical/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, parse, and convert .ics iCalendar files to text, JSON, or CSV. Use when opening a calendar export, extracting events, or transforming schedule data.",
      "tags": [
        "calendar",
        "ics",
        "icalendar",
        "converter",
        "schedule",
        "events"
      ],
      "capabilities": [
        "ReadIcal",
        "ConvertToJson",
        "ConvertToCsv",
        "ExtractEvents",
        "ListAttendees",
        "MergeIcal"
      ],
      "representativeQueries": [
        "Read a .ics file and show me the events",
        "Convert iCal to CSV",
        "Extract all events from a calendar export",
        "What attendees are in this .ics file?",
        "Merge multiple .ics calendar files into one"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.210Z",
      "metadata": {
        "context": "- iCalendar (RFC 5545) uses CRLF line endings and line-folding: long lines are split with CRLF + a single leading space/tab; unfold before parsing.\n- Property values use backslash escaping: \\n = newline, \\, = comma, \\; = semicolon, \\\\ = backslash.\n- DTSTART/DTEND may be a date (YYYYMMDD, all-day event) or datetime (YYYYMMDDTHHmmssZ for UTC, or with TZID param for local time).\n- VCALENDAR wraps one or more components: VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE. Most calendar exports contain only VEVENTs.\n- RRULE (recurrence rule) defines repeating events; each occurrence is NOT expanded in the raw .ics — only the base event appears.\n- ATTENDEE and ORGANIZER values are mailto: URIs; display name is in the CN parameter.\n- UID is the stable identifier for an event across edits; SEQUENCE tracks revision number.\n- Multi-value properties (RDATE, EXDATE, CATEGORIES) use comma-separated values within a single property line.\n- Encoding: most modern .ics files are UTF-8; older files may use quoted-printable or base64 (ENCODING param).",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:image-ocr",
      "displayName": "Image OCR",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/image-ocr/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Extract and convert text from images (.png, .jpg, .tiff) using OCR. Use when you need to read, copy, or export text from scanned documents, screenshots, or photos.",
      "tags": [
        "ocr",
        "image",
        "text-extraction",
        "png",
        "jpg",
        "tiff",
        "converter"
      ],
      "capabilities": [
        "ReadImageText",
        "ExtractTextFromImage",
        "ConvertImageToJson",
        "ConvertImageToCsv"
      ],
      "representativeQueries": [
        "Read text from a PNG file",
        "Extract text from a scanned TIFF document",
        "Convert image text to JSON or CSV",
        "OCR a JPG photo and get the text out",
        "What does this image say"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.211Z",
      "metadata": {
        "context": "- pytesseract wraps the system Tesseract binary; both must be present: `brew install tesseract` (macOS) or `apt-get install tesseract-ocr` (Linux), then `pip install pytesseract pillow`.\n- Tesseract default language is English (`lang='eng'`); install additional language packs (e.g. `tesseract-ocr-fra`) and pass `lang='fra'` for non-English text.\n- Multi-page TIFF: Pillow iterates frames with `img.seek(frame_idx) + img.copy()`; `ImageSequence.Iterator` is deliberately avoided because it does not copy each frame before advancing the pointer, causing all frames to alias the last page.\n- Output modes: plain text (layout-preserving, reconstructed from `image_to_data` line/paragraph coordinates), word-level boxes as JSON (`--format json`), or CSV (`--format csv`).\n- Image quality matters: convert to grayscale before OCR for best accuracy; upscaling to >=300 DPI and thresholding are additional steps you can apply with Pillow (`Image.resize`, `ImageFilter.SHARPEN`) before passing the frame to the script.\n- Tesseract 4+ defaults to `--oem 3` (\"default, based on what is available\"); pure LSTM is `--oem 1`, legacy engine `--oem 0` can be faster but less accurate on printed text.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:ipynb",
      "displayName": "Jupyter Notebook Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/ipynb/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert Jupyter notebook (.ipynb) files to text, Markdown, or JSON. Use when opening, summarising, or extracting content from a notebook.",
      "tags": [
        "jupyter",
        "notebook",
        "ipynb",
        "convert",
        "data-science"
      ],
      "capabilities": [
        "ReadNotebook",
        "ConvertToMarkdown",
        "ConvertToScript",
        "ExtractCodeCells",
        "StripOutputs"
      ],
      "representativeQueries": [
        "Read a .ipynb file and show me what's in it",
        "Convert a Jupyter notebook to Markdown",
        "Extract all code cells from a notebook",
        "Strip outputs from a notebook and save a clean version",
        "Export a .ipynb notebook as a Python script"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.212Z",
      "metadata": {
        "context": "- An .ipynb file is JSON with a top-level \"nbformat\" int (3 or 4) and a \"cells\" list (nbformat 4) or per-worksheet \"worksheets[].cells\" list (nbformat 3).\n- Each cell has a \"cell_type\": \"code\" | \"markdown\" | \"raw\"; source is typically a list of strings (join with \"\") but may also be a plain string in some serializers.\n- Code cells have an \"outputs\" list; each output has an \"output_type\": \"stream\", \"display_data\", \"execute_result\", or \"error\".\n- Kernel metadata lives in metadata.kernelspec; language in metadata.kernelspec.language or metadata.language_info.name.\n- Cell execution_count may be null (not yet run). Output data in display_data/execute_result is a \"data\" dict keyed by MIME type (text/plain, image/png, …).\n- nbconvert is the canonical converter but requires a separate install; scripts/read_ipynb.py uses only stdlib json so it always works.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:kml",
      "displayName": "KML/KMZ Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/kml/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert .kml and .kmz files to JSON or CSV. Use when opening a KML/KMZ file, extracting placemarks, or exporting geospatial data to another format.",
      "tags": [
        "geospatial",
        "kml",
        "kmz",
        "converter",
        "reader",
        "gis"
      ],
      "capabilities": [
        "ReadKml",
        "ReadKmz",
        "ConvertToCsv",
        "ConvertToJson",
        "ConvertToGeoJson",
        "ExtractPlacemarks",
        "SummarizeFeatures"
      ],
      "representativeQueries": [
        "Read a .kml file and show me its contents",
        "Convert KML to CSV",
        "Extract all placemarks from a KMZ file",
        "Convert KML to GeoJSON",
        "What placemarks are in this .kml file?"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.213Z",
      "metadata": {
        "context": "- KML (Keyhole Markup Language) is an XML dialect (OGC standard, originally Google Earth). A .kmz file is a ZIP archive containing a root KML file (usually doc.kml) plus optional image/model assets.\n- The primary XML namespace is http://www.opengis.net/kml/2.2 (older files may use http://earth.google.com/kml/2.0 or 2.1). ElementTree must namespace-qualify every tag: {http://www.opengis.net/kml/2.2}Placemark.\n- Core geometry elements: Point (lon,lat[,alt] in <coordinates>), LineString, LinearRing, Polygon (outerBoundaryIs/innerBoundaryIs), MultiGeometry. Coordinates are comma-separated lon,lat,alt triplets; multiple points are whitespace-separated.\n- Placemarks are the primary data-carrying elements: <name>, <description>, <Point|LineString|Polygon|...>, <ExtendedData> (structured key/value pairs via <SchemaData>/<SimpleData> or <Data>/<value>).\n- Folders and Documents provide hierarchical organization; a KML file may contain nested Folder/Document/Placemark trees of arbitrary depth.\n- <ExtendedData> is the KML equivalent of GeoJSON properties; <Data name=\"key\"><value>val</value></Data> is the most common pattern; <SchemaData schemaUrl=\"#id\"> references a Schema element.\n- KMZ: open with zipfile; find the entry whose name ends with .kml (prioritize doc.kml if present) and parse that.\n- Altitude is optional; coordinate strings often have only lon,lat. Strip and split on whitespace+commas carefully.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:mbox",
      "displayName": "mbox Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/mbox/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert .mbox mailbox files to JSON, CSV, or plain text. Use when opening, inspecting, or exporting email archives in the mbox format.",
      "tags": [
        "email",
        "mbox",
        "mailbox",
        "converter",
        "extractor"
      ],
      "capabilities": [
        "ReadMbox",
        "ConvertToJson",
        "ConvertToCsv",
        "ConvertToText",
        "ExtractHeaders",
        "SplitToEml"
      ],
      "representativeQueries": [
        "Read a .mbox file and show me the emails",
        "Convert mbox to CSV or JSON",
        "Extract subjects and senders from a mailbox archive",
        "Export emails from an mbox file to plain text",
        "Split an mbox archive into individual .eml files"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.213Z",
      "metadata": {
        "context": "- mbox is a family of related file formats for storing collections of email. The most common variant is mboxrd (used by Gmail Takeout, Thunderbird, Apple Mail exports).\n- Each message begins with a \"From \" line (note: no colon) containing the sender address and a timestamp; this line is the message separator. A line inside a message body that starts with \"From \" is escaped by prepending \">\".\n- Python stdlib mailbox.mbox() handles multipart MIME transparently and strips the \"From \" separator line between messages. However, it does NOT unescape \">From \" body lines that were escaped by mboxrd writers (e.g. Gmail Takeout). Forwarded emails or quoted text containing \"From \" at the start of a line will appear with a literal \">\" prefix in the extracted body.\n- Large mbox files (>1 GB) are common in Gmail Takeout; the extractor streams messages rather than loading the whole file.\n- Message bodies may be multipart/mixed, multipart/alternative, or simple text/plain or text/html; prefer text/plain when available, fall back to text/html with tags stripped.\n- Gmail Takeout mbox files include X-Gmail-Labels and X-GM-THRID headers for label and thread metadata.\n- Character encoding varies per part; always decode with the Content-Type charset, falling back to utf-8 with errors='replace'.\n- Attachments are identified by Content-Disposition: attachment; skip them unless the user asks for attachment metadata.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:msg",
      "displayName": "MSG Outlook Email Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/msg/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts Outlook .msg files (OLE/CFB binary format) to text, JSON, or CSV. Use when opening .msg email files, extracting message content, headers, or attachment metadata.",
      "tags": [
        "msg",
        "outlook",
        "email",
        "ole",
        "cfb",
        "document",
        "converter",
        "mapi"
      ],
      "capabilities": [
        "ReadMsg",
        "ConvertToJson",
        "ConvertToCsv",
        "ConvertToText",
        "ExtractHeaders",
        "ExtractAttachmentMetadata"
      ],
      "representativeQueries": [
        "Read a .msg file and show me the email content",
        "Convert an Outlook msg file to JSON or CSV",
        "Extract headers and body from a .msg email",
        "What attachments are in this Outlook message file?",
        "Parse an Outlook .msg file and get the sender and subject"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.214Z",
      "metadata": {
        "context": "- .msg files use the OLE Compound File Binary (CFB) format (Microsoft Structured Storage), not plain text. They cannot be parsed with Python's standard `email` module.\n- The `extract-msg` library (pip install extract-msg) is the primary Python tool; it exposes a `Message` object with `.sender`, `.to`, `.cc`, `.subject`, `.date`, `.body`, `.htmlBody`, and `.attachments`.\n- Each `Attachment` on a message has `.longFilename` (or `.shortFilename`), `.data` (bytes), and `.mimetype`. Inline attachments (OLE embedded objects) may lack a filename.\n- MAPI property encoding: string values may be stored as UTF-16LE internally; extract-msg decodes them automatically to Python str. Dates are stored as UTC FILETIME; the library converts them to `datetime` objects.\n- Some .msg files are meeting requests or calendar items (IPM.Schedule.*), not plain emails. `msg.classType` reveals the message class.\n- Nested/embedded .msg attachments (forwarded messages stored as attachments) are exposed as sub-Message objects in some extract-msg versions — iterate carefully.\n- The `--no-attachments` flag in extract-msg's CLI skips attachment extraction. When using the Python API, simply don't read `.data` to avoid loading large binary blobs into memory.\n- RTF bodies are stored in a MAPI PR_RTF_COMPRESSED stream; extract-msg decompresses and exposes them. Prefer `.body` (plain text) or `.htmlBody` when available.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:odp",
      "displayName": "ODP (OpenDocument Presentation) Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/odp/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, extract text, and convert .odp OpenDocument Presentation files to JSON or plain text. Use when a user shares or references a .odp file.",
      "tags": [
        "document",
        "presentation",
        "odp",
        "opendocument",
        "libreoffice",
        "convert",
        "extract"
      ],
      "capabilities": [
        "ReadOdp",
        "ExtractSlideText",
        "ExtractSpeakerNotes",
        "ConvertToJson",
        "ConvertToText"
      ],
      "representativeQueries": [
        "Read a .odp file and show me the content",
        "Convert an ODP presentation to JSON",
        "Extract all slide text from an OpenDocument presentation",
        "What is in this .odp file?",
        "Pull the speaker notes out of an ODP file"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.214Z",
      "metadata": {
        "context": "- An .odp file is a ZIP archive containing XML files (ODF spec). The primary content lives in content.xml using the draw:page element per slide.\n- Slide text is in text:p elements nested inside draw:frame > draw:text-box. Speaker notes follow a different path: draw:page > presentation:notes > draw:frame > draw:text-box > text:p.\n- The XML namespace prefixes used are declared at the top of content.xml: text:, draw:, presentation:, office:.\n- Speaker notes live in a presentation:notes child of each draw:page; they are distinct from slide body text.\n- Fonts, styles, and theme data live in styles.xml and meta.xml — not needed for plain text extraction.\n- Some ODP files embed images/media in sub-folders (Pictures/, Object/); these are binary and should be skipped during text extraction.\n- The stdlib zipfile + xml.etree.ElementTree modules are sufficient; no pip installs needed.\n- ElementTree converts namespace prefixes to Clark notation {uri}localname when parsing; use that notation (not bare prefix:local) when querying elements.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:ods",
      "displayName": "ODS Spreadsheet Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/ods/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads OpenDocument Spreadsheet (.ods) files and converts them to CSV or JSON. Use when you need to extract tabular data from an ODS file or convert it to a portable format.",
      "tags": [
        "ods",
        "spreadsheet",
        "opendocument",
        "csv",
        "json",
        "convert",
        "read"
      ],
      "capabilities": [
        "ReadOds",
        "ConvertToCsv",
        "ConvertToJson",
        "ListSheets",
        "ExtractFormulas"
      ],
      "representativeQueries": [
        "Read a .ods file and show me the data",
        "Convert an ODS spreadsheet to CSV",
        "Extract data from an OpenDocument spreadsheet as JSON",
        "What sheets are in this ODS file?",
        "Export ODS file contents to CSV format"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.216Z",
      "metadata": {
        "context": "- ODS is a ZIP archive; the tabular data lives in content.xml inside it.\n- Namespaces matter: table rows are in the table: namespace, cells in table:table-cell. The office:value-type attribute distinguishes float/percentage/currency/date/time/boolean/string cells; office:value, office:date-value, office:time-value, or office:boolean-value holds the typed value; text content (text:p) is the display string.\n- Repeated cells use table:number-columns-repeated — a single element can represent many empty columns; always expand before emitting.\n- Formulas are stored in table:formula but the cached display value is in the text content; prefer the cached value for data extraction, surface the formula only on request.\n- Trailing empty rows at the bottom of a sheet are common and should be stripped.\n- Multi-sheet files: each sheet is a table:table element; the first sheet is the default target unless the user names one explicitly.\n- Python stdlib zipfile + xml.etree.ElementTree is sufficient — no third-party packages needed.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:odt",
      "displayName": "ODT Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/odt/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert OpenDocument Text (.odt) files to plain text, JSON, or CSV. Use when extracting content, tables, or metadata from .odt documents.",
      "tags": [
        "document",
        "odt",
        "openDocument",
        "convert",
        "extract",
        "text"
      ],
      "capabilities": [
        "ReadOdt",
        "ConvertToText",
        "ConvertToJson",
        "ConvertToCsv",
        "ExtractTables"
      ],
      "representativeQueries": [
        "read a .odt file and show me its contents",
        "convert odt to plain text or JSON",
        "extract tables from an OpenDocument Text file",
        "what is in this .odt document",
        "pull the text out of an odt file"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.216Z",
      "metadata": {
        "context": "- ODT is a ZIP archive; content.xml holds the document body using ODF XML namespaces (text:, table:, draw:, etc.).\n- Text paragraphs are <text:p> elements; headings are <text:h text:outline-level=\"N\"> (level read from the text:outline-level attribute); list items are <text:list-item>.\n- Tables are <table:table> containing <table:table-row> and <table:table-cell>; cells may be merged (table:number-columns-spanned) or repeated (table:number-columns-repeated).\n- Styles are defined in styles.xml and content.xml's <office:automatic-styles>; text formatting (bold, italic) uses <text:span text:style-name=\"...\">.\n- Images and embedded objects are stored as additional ZIP entries; they are not extracted by this skill.\n- The file must be a valid ZIP; password-protected ODT files cannot be read (no encryption support in stdlib).\n- pandoc (if installed) produces higher-fidelity Markdown output but is not required; the stdlib path uses zipfile + ElementTree.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:orc",
      "displayName": "ORC Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/orc/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert Apache ORC columnar files to CSV or JSON. Use when opening .orc files, extracting schema, or exporting data.",
      "tags": [
        "data",
        "orc",
        "columnar",
        "csv",
        "conversion",
        "extractor"
      ],
      "capabilities": [
        "ReadOrc",
        "InspectSchema",
        "ConvertToCsv",
        "ConvertToJson",
        "SampleRows"
      ],
      "representativeQueries": [
        "Read a .orc file and show me the data",
        "Convert ORC to CSV",
        "What is the schema of this ORC file?",
        "Extract rows from an ORC file to JSON",
        "Sample the first 10 rows of an ORC file"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.217Z",
      "metadata": {
        "context": "- ORC (Optimized Row Columnar) is a binary columnar format; it cannot be read as plain text — always use pyarrow.orc or pyorc.\n- Each ORC file embeds its own schema (column names + ORC types such as bigint, string, struct, list, map, uniontype).\n- ORC supports lightweight compression codecs: NONE, ZLIB, SNAPPY, LZO, LZ4, ZSTD — pyarrow decompresses all of these transparently.\n- Nested types (struct, list, map, uniontype) are legal in ORC but do not flatten cleanly to CSV; cast to string or flatten before exporting.\n- ORC stripes are the unit of IO (analogous to Parquet row groups); pyarrow reads all stripes in one call by default.\n- ORC files produced by Hive may include an ORC footer with Hive-specific metadata (e.g., hive.acid.version); this is harmless and readable.\n- ACID transactional ORC files (produced by Hive ACID or ORC writer in insert/update/delete mode) contain hidden columns (_operation, _originalTransaction, etc.); filter these out if exporting to CSV/JSON.\n- pyarrow.orc is the recommended Python reader; install via `pip install pyarrow`.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:parquet",
      "displayName": "Parquet Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/parquet/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert Apache Parquet columnar files to CSV or JSON. Use when opening .parquet files, extracting schema, or exporting data.",
      "tags": [
        "data",
        "parquet",
        "columnar",
        "csv",
        "conversion",
        "extractor"
      ],
      "capabilities": [
        "ReadParquet",
        "InspectSchema",
        "ConvertToCsv",
        "ConvertToJson",
        "SampleRows"
      ],
      "representativeQueries": [
        "Read a .parquet file and show me the data",
        "Convert parquet to CSV",
        "What is the schema of this parquet file?",
        "Extract rows from a parquet file to JSON",
        "Sample the first 10 rows of a parquet file"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.217Z",
      "metadata": {
        "context": "- Parquet is a binary columnar format; it cannot be read as plain text — always use pyarrow or a compatible library.\n- Each file embeds its own schema (column names + Arrow/Parquet types). Run schema inspection first when the column layout is unknown.\n- Row groups are the unit of IO; very large files can be sampled with --sample N to avoid reading the full dataset.\n- Nested/repeated fields (structs, lists, maps) are legal in Parquet but do not map cleanly to flat CSV — flatten or cast to string before exporting.\n- Timestamps are stored as int64 with a logical type annotation; pyarrow converts them to Python datetime objects, which this script serialises as ISO-8601 strings in all output modes.\n- Parquet files produced by Spark may have _metadata or _common_metadata sidecar files; these are not required for reading individual part files.\n- Snappy, GZIP, ZSTD, and LZ4 compression are transparently decompressed by pyarrow; no manual decompression step is needed.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:plist",
      "displayName": "Apple Plist Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/plist/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts Apple property list files (.plist, XML or binary) to text, JSON, or CSV. Use when inspecting or extracting data from macOS/iOS config and preference files.",
      "tags": [
        "plist",
        "apple",
        "macos",
        "ios",
        "xml",
        "binary",
        "converter",
        "extractor"
      ],
      "capabilities": [
        "ReadPlist",
        "ConvertToJson",
        "ConvertToCsv",
        "ExtractKeys",
        "ConvertFormat"
      ],
      "representativeQueries": [
        "read a .plist file and show me what's inside",
        "convert plist to JSON",
        "extract values from a macOS preference file",
        "convert this binary plist to XML plist format",
        "convert plist to CSV"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.218Z",
      "metadata": {
        "context": "- Apple plist files come in two flavors: XML (text, starts with `<?xml` or `<!DOCTYPE plist`) and binary (starts with magic bytes `bplist00`). Python's stdlib `plistlib` reads both transparently — no format detection needed before calling `plistlib.load()`.\n- `plistlib.load(fp)` auto-detects format; `plistlib.loads(data)` works on bytes. Both raise `plistlib.InvalidFileException` for corrupt or unrecognized files.\n- Plist value types map to Python: dict → dict, array → list, string → str, integer → int, real → float, true/false → bool, date → datetime.datetime, data → bytes. `bytes` values are base64-encoded for JSON/text output.\n- Nested dicts and arrays are common in complex plists (e.g. `NSUserDefaults`, Xcode project files). The converter flattens one level for CSV; JSON preserves full depth.\n- Binary plists (`bplist00`) are not human-readable; always convert before inspecting. Some Apple tools write `bplist15` or `bplist16` (NSKeyedArchiver) — the script detects these by their magic bytes and exits early with a clear error before plistlib is called; advise the user to use `plutil -convert xml1` on macOS to normalize first.\n- `plutil -lint <file>` (macOS only) validates any plist; `plutil -convert xml1 -o - <file>` converts binary to XML on stdout without third-party tools.\n- plist dates use UTC datetime objects; JSON output serializes them as ISO 8601 strings.\n- Very large plists (e.g. iOS backups, Xcode derived data) may have thousands of keys — use `--key` to drill into a specific path.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:reg",
      "displayName": "Windows Registry Export Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/reg/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts Windows registry export files (.reg) to text, JSON, or CSV. Use when inspecting, extracting, or transforming .reg file contents.",
      "tags": [
        "registry",
        "windows",
        "reg",
        "converter",
        "extractor",
        "json",
        "csv"
      ],
      "capabilities": [
        "ReadReg",
        "ConvertToJson",
        "ConvertToCsv",
        "ExtractKeys",
        "ExtractValues"
      ],
      "representativeQueries": [
        "read a .reg file and show me what's inside",
        "convert a Windows registry export to JSON",
        "extract registry keys and values from a .reg file",
        "parse a .reg file to CSV for analysis",
        "what keys and values are in this registry export"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.219Z",
      "metadata": {
        "context": "- Windows registry export files (.reg) are UTF-16 LE (with BOM \\xff\\xfe) in Windows Vista+ and UTF-8 or ASCII in older exports; always detect the BOM and decode accordingly.\n- The first line of a valid .reg file is \"Windows Registry Editor Version 5.00\" (Win2000+) or \"REGEDIT4\" (Win9x/NT4, ANSI-only); reject files that lack this header.\n- Section headers are bracketed hive paths: [HKEY_LOCAL_MACHINE\\SOFTWARE\\Example]; a header prefixed with a minus sign [-HKEY_...] signals deletion of that key.\n- Value names are double-quoted strings before the equals sign; the default value uses @.\n- Supported data types: \"\" (REG_SZ, bare double-quoted string), dword:XXXXXXXX (REG_DWORD, 8 hex digits, little-endian), hex:XX,XX,... (REG_BINARY), hex(2):XX,XX,... (REG_EXPAND_SZ as UTF-16 LE hex), hex(7):XX,XX,... (REG_MULTI_SZ as UTF-16 LE hex), hex(b):XX,XX,... (REG_QWORD as 8-byte LE hex).\n- Long value data lines are continued with a trailing backslash; continuation lines are indented with two spaces.\n- A value name prefixed with a minus sign (-\"ValueName\"=) signals deletion of that value.\n- Empty lines separate key blocks; comment lines start with a semicolon (;).\n- REG_EXPAND_SZ and REG_MULTI_SZ are stored as little-endian UTF-16 byte sequences; decode with bytes.decode('utf-16-le') after stripping the null terminator(s).",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:rtf",
      "displayName": "RTF Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/rtf/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert Rich Text Format (.rtf) files to plain text, JSON, or Markdown. Use when extracting content from .rtf documents or converting them for downstream processing.",
      "tags": [
        "rtf",
        "document",
        "converter",
        "reader",
        "rich-text-format"
      ],
      "capabilities": [
        "ReadRtf",
        "ConvertToText",
        "ConvertToJson",
        "ConvertToMarkdown",
        "ExtractRtfContent"
      ],
      "representativeQueries": [
        "Read a .rtf file and show me the content",
        "Convert RTF to plain text",
        "Extract text from an RTF document",
        "Convert RTF file to JSON or Markdown",
        "What does this .rtf file contain?"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.220Z",
      "metadata": {
        "context": "- RTF files are plain-text files that encode rich formatting using control words (backslash sequences like \\b, \\i, \\par) and control symbols. The entire document is wrapped in a {\\rtf1 ...} group.\n- Character encoding: RTF uses \\ansicpg to declare the ANSI codepage (e.g. \\ansicpg1252 for Windows-1252). Non-ASCII chars appear as \\'XX hex escapes; Unicode chars appear as \\uNNNN? where ? is the ASCII fallback.\n- Stripping RTF: Remove all { } group delimiters and \\controlword sequences. The remaining text contains the actual content. Literal backslash is \\\\, literal { is \\{, literal } is \\}.\n- \\par and \\line produce paragraph/line breaks. \\tab produces a tab character.\n- Common pitfall: binary blobs (pictures, fonts, stylesheets) are embedded in RTF groups — always skip \\*\\... groups (tagged as optional/ignorable destinations) to avoid outputting binary garbage.\n- Heading detection heuristic: RTF uses \\outlinelevel (paragraph outline level, 0-based) or \\pard\\s1...\\s9 paragraph styles for headings; without full stylesheet parsing, detect by \\sN style markers where N maps to heading level.\n- RTF files often begin with a Byte Order Mark or \\rtf1 header; validate presence before processing.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:shapefile",
      "displayName": "Shapefile & GeoPackage Reader / Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/shapefile/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read, inspect, and convert .shp/.dbf/.shx Shapefiles and .gpkg GeoPackage files to GeoJSON, CSV, or JSON. Use when opening vector GIS data in these formats.",
      "tags": [
        "geospatial",
        "shapefile",
        "geopackage",
        "gis",
        "converter",
        "reader"
      ],
      "capabilities": [
        "ReadShapefile",
        "ReadGeopackage",
        "ConvertToGeojson",
        "ConvertToCsv",
        "ExtractAttributes",
        "SummarizeGeometry"
      ],
      "representativeQueries": [
        "Read a .shp file and show me its contents",
        "Convert a shapefile to GeoJSON",
        "Extract the attribute table from a shapefile to CSV",
        "Open a GeoPackage .gpkg file and list its layers",
        "What features and fields are in this shapefile?"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.222Z",
      "metadata": {
        "context": "- A Shapefile is always a bundle of co-named files: .shp (geometry), .dbf (attributes as dBASE III table), .shx (geometry index). All three must be present. Optional: .prj (CRS as WKT), .cpg (encoding hint), .sbn/.sbx (spatial index).\n- dBASE (.dbf) field types: C=character, N=numeric, F=float, L=logical, D=date. Field names are capped at 10 characters.\n- .prj absence means the CRS is unknown (often EPSG:4326 or a local projection); never assume WGS 84 unless the .prj says so.\n- GeoPackage (.gpkg) is a single SQLite database file containing one or more vector (and raster) layers in the `gpkg_contents` table. Geometries are stored as a GPKG binary encoding (not WKB directly).\n- Both formats can hold any geometry type: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, plus 3D variants.\n- Shapefiles cannot store NULL geometry; GeoPackage can.\n- Character encoding for .dbf is frequently Windows-1252 (Latin-1) even when no .cpg file is present; mis-detecting as UTF-8 is a common source of garbled text.\n- fiona reads Shapefiles and GeoPackages via GDAL; geopandas wraps fiona and adds pandas DataFrame support. Both require GDAL native libs.\n- Install: `pip install fiona geopandas` (or `pip install fiona` alone for lightweight reads).",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:sqlite",
      "displayName": "SQLite Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/sqlite/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Reads and converts SQLite database files (.db .sqlite .sqlite3) to text, JSON, or CSV. Use when inspecting or extracting data from a SQLite single-file database.",
      "tags": [
        "sqlite",
        "database",
        "extractor",
        "csv",
        "json",
        "converter"
      ],
      "capabilities": [
        "ReadSqlite",
        "ConvertToCsv",
        "ConvertToJson",
        "DumpSchema",
        "QueryTable",
        "SchemaDiff"
      ],
      "representativeQueries": [
        "read a .db file and show me what's inside",
        "convert sqlite to CSV",
        "extract data from a sqlite3 database file",
        "what tables are in this .sqlite file",
        "compare the schema of two sqlite databases and show what changed"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.222Z",
      "metadata": {
        "context": "- SQLite stores the entire database in a single cross-platform file; magic bytes are \"SQLite format 3\\000\" (16 bytes at offset 0) — check before parsing to confirm format.\n- Python stdlib `sqlite3` module reads any valid SQLite 3.x file; no third-party packages needed.\n- The schema is stored in the system table `sqlite_master` (or its alias `sqlite_schema`); query `SELECT type, name, sql FROM sqlite_master WHERE type IN ('table','view') ORDER BY name` to enumerate objects.\n- Column metadata is derived from `cursor.description` after executing `SELECT * FROM <table>`; this gives column names but not type/notnull/pk — use `PRAGMA table_info(<table>)` if you need full column metadata.\n- WAL-mode databases (.db-wal, .db-shm sidecar files) must be in the same directory as the main file or SQLite will open the DB in read-only rollback mode and the WAL changes won't be visible.\n- Text encoding is stored in `PRAGMA encoding`; defaults to UTF-8 but may be UTF-16le or UTF-16be in older DBs.\n- Opening with `uri=True` and `?mode=ro` (e.g. `sqlite3.connect(\"file:path?mode=ro\", uri=True)`) prevents accidental writes.\n- BLOB columns are binary; the converter hex-encodes them for safe text output.\n- `WITHOUT ROWID` tables lack the implicit `rowid`/`oid` columns; `SELECT *` does not request rowid, so they are read correctly without special handling.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:vcard",
      "displayName": "vCard (.vcf) Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/vcard/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert vCard .vcf contact files to plain text, JSON, or CSV. Use when you need to open, extract, or bulk-export contacts from a .vcf file.",
      "tags": [
        "document",
        "vcard",
        "vcf",
        "contacts",
        "convert",
        "extract"
      ],
      "capabilities": [
        "ReadVcard",
        "ConvertToText",
        "ConvertToJson",
        "ConvertToCsv",
        "ExtractContacts"
      ],
      "representativeQueries": [
        "Read a .vcf file and show me the contacts",
        "Convert vcard to CSV",
        "Extract contacts from a .vcf file to JSON",
        "Parse a vCard file and list all phone numbers and emails",
        "Export my .vcf contacts to a spreadsheet-friendly format"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.223Z",
      "metadata": {
        "context": "- vCard files are plain-text with CRLF line endings; a single .vcf may contain one or many contacts (each delimited by BEGIN:VCARD / END:VCARD).\n- vCard versions 2.1, 3.0, and 4.0 coexist in the wild. Version 2.1 uses a different quoting syntax (no =? encoding header), 3.0 and 4.0 use RFC 6350 conventions.\n- Property values may be folded (long lines wrapped with a leading space/tab on continuation lines); the parser must unfold before splitting on ':'.\n- Base64-encoded blobs (PHOTO;ENCODING=BASE64 or PHOTO;ENCODING=b) can make files very large; skip or flag them rather than printing binary to stdout.\n- CHARSET parameter on values (common in 2.1 files) may require decoding bytes from non-UTF-8 encodings; use errors='replace' when decoding.\n- Quoted-printable encoding (QP) is used in vCard 2.1 for high-byte characters; lines ending with '=' are continuation lines in QP mode.\n- Multiple values in a single property (e.g. multiple TEL lines per contact) are normal; collect them as a list rather than overwriting.\n- The stdlib has no vCard parser; vobject is a third-party package and may not be installed. The bundled script uses only stdlib modules (quopri + re) so no pip installs are needed.",
        "context_verified": false
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:skill:xls",
      "displayName": "Legacy Excel (.xls) Reader & Converter",
      "type": "application/ai-skill+md",
      "url": "https://stealthstack.ai/skills/xls/SKILL.md",
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      },
      "description": "Read and convert legacy Excel OLE/CFB binary (.xls) files to CSV or JSON. Use when opening pre-2007 .xls files that cannot be read as plain ZIP/XML.",
      "tags": [
        "excel",
        "xls",
        "spreadsheet",
        "csv",
        "conversion",
        "legacy"
      ],
      "capabilities": [
        "ReadXls",
        "ConvertToCsv",
        "ConvertToJson",
        "ListSheets",
        "ExtractSheet"
      ],
      "representativeQueries": [
        "Read a .xls file and show me its contents",
        "Convert an xls spreadsheet to CSV",
        "Extract data from a legacy Excel file",
        "What sheets are in this .xls file?",
        "Export xls to JSON"
      ],
      "version": "0.1.0",
      "updatedAt": "2026-06-20T03:53:41.223Z",
      "metadata": {
        "context": "- .xls is the legacy OLE Compound File Binary (CFB) format used by Excel 97-2003. It is NOT a ZIP archive — the modern .xlsx format is. Tools that unzip or parse XML will fail silently or with a decode error.\n- xlrd 2.0 removed .xlsx support and now exclusively handles legacy .xls files. Both xlrd 1.x and 2.x can read .xls; the recommended pinned version here is `xlrd==1.2.0` for stability.\n- Cell type codes: 0=empty, 1=text, 2=number, 3=date, 4=boolean, 5=error. Dates are stored as floats; use xlrd.xldate_as_datetime() to decode them.\n- Hidden sheets are still parsed; check sheet.visibility (0=visible, 1=hidden, 2=very-hidden).\n- Formula cells expose the cached result, not the formula string. Error cells return a code (e.g. 0x2a = #N/A).\n- Merged cells: the top-left cell holds the value; other cells in the range are empty. xlrd exposes `sheet.merged_cells` as `(row_lo, row_hi, col_lo, col_hi)` tuples (upper bounds exclusive); only populated when the workbook is opened with `formatting_info=True`. The script opens workbooks without `formatting_info=True`, so `sheet.merged_cells` is always `[]` at runtime — merged-cell metadata is not surfaced.\n- xlrd does not support password-protected workbooks; they will raise an `xlrd.biffh.XLRDError`.\n- Multi-byte characters (CJK, Arabic, etc.) are stored as UTF-16 internally; xlrd decodes them correctly to Python str.",
        "context_verified": true
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:archives",
      "displayName": "Archive Container Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'archives' skill — the same tools executed server-side (no local setup). Tools: archives_extract_all, archives_extract_member, archives_list.",
      "capabilities": [
        "archives_extract_all",
        "archives_extract_member",
        "archives_list"
      ],
      "tags": [
        "archive",
        "zip",
        "tar",
        "gzip",
        "7z",
        "extraction",
        "compression",
        "conversion"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:arrow",
      "displayName": "Arrow / Feather Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'arrow' skill — the same tools executed server-side (no local setup). Tools: arrow_read, arrow_schema, arrow_to_csv, arrow_to_json.",
      "capabilities": [
        "arrow_read",
        "arrow_schema",
        "arrow_to_csv",
        "arrow_to_json"
      ],
      "tags": [
        "data",
        "arrow",
        "feather",
        "columnar",
        "csv",
        "json",
        "converter",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:avro",
      "displayName": "Avro Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'avro' skill — the same tools executed server-side (no local setup). Tools: avro_sample, avro_schema, avro_to_csv, avro_to_json, avro_to_jsonl.",
      "capabilities": [
        "avro_sample",
        "avro_schema",
        "avro_to_csv",
        "avro_to_json",
        "avro_to_jsonl"
      ],
      "tags": [
        "data",
        "avro",
        "schema",
        "csv",
        "json",
        "conversion",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:dbf",
      "displayName": "dBase DBF Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'dbf' skill — the same tools executed server-side (no local setup). Tools: dbf_schema, dbf_to_csv, dbf_to_json, dbf_to_text.",
      "capabilities": [
        "dbf_schema",
        "dbf_to_csv",
        "dbf_to_json",
        "dbf_to_text"
      ],
      "tags": [
        "dbf",
        "dbase",
        "foxpro",
        "extractor",
        "csv",
        "json",
        "converter",
        "gis",
        "legacy"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:doc",
      "displayName": "Legacy Word (.doc) Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'doc' skill — the same tools executed server-side (no local setup). Tools: doc_to_csv, doc_to_json, doc_to_text.",
      "capabilities": [
        "doc_to_csv",
        "doc_to_json",
        "doc_to_text"
      ],
      "tags": [
        "document",
        "word",
        "doc",
        "ole",
        "cfb",
        "convert",
        "extract",
        "legacy"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:eml",
      "displayName": "EML Email Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'eml' skill — the same tools executed server-side (no local setup). Tools: eml_extract_attachments, eml_read, eml_to_csv, eml_to_json.",
      "capabilities": [
        "eml_extract_attachments",
        "eml_read",
        "eml_to_csv",
        "eml_to_json"
      ],
      "tags": [
        "eml",
        "email",
        "rfc822",
        "document",
        "converter",
        "mime"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:epub",
      "displayName": "EPUB Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'epub' skill — the same tools executed server-side (no local setup). Tools: epub_summary, epub_to_csv, epub_to_json, epub_to_text.",
      "capabilities": [
        "epub_summary",
        "epub_to_csv",
        "epub_to_json",
        "epub_to_text"
      ],
      "tags": [
        "epub",
        "ebook",
        "document",
        "converter",
        "text-extraction"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:geojson",
      "displayName": "GeoJSON Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'geojson' skill — the same tools executed server-side (no local setup). Tools: geojson_summary, geojson_to_csv, geojson_to_json.",
      "capabilities": [
        "geojson_summary",
        "geojson_to_csv",
        "geojson_to_json"
      ],
      "tags": [
        "geospatial",
        "geojson",
        "converter",
        "reader",
        "gis"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:gpx",
      "displayName": "GPX Track Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'gpx' skill — the same tools executed server-side (no local setup). Tools: gpx_summarize, gpx_to_csv, gpx_to_geojson, gpx_to_json.",
      "capabilities": [
        "gpx_summarize",
        "gpx_to_csv",
        "gpx_to_geojson",
        "gpx_to_json"
      ],
      "tags": [
        "gps",
        "gpx",
        "geospatial",
        "converter",
        "reader",
        "tracks"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:hcl",
      "displayName": "HCL / Terraform Config Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'hcl' skill — the same tools executed server-side (no local setup). Tools: hcl_blocks, hcl_resources, hcl_to_csv, hcl_to_json.",
      "capabilities": [
        "hcl_blocks",
        "hcl_resources",
        "hcl_to_csv",
        "hcl_to_json"
      ],
      "tags": [
        "hcl",
        "terraform",
        "config",
        "iac",
        "json",
        "conversion",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:hdf5",
      "displayName": "HDF5 Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'hdf5' skill — the same tools executed server-side (no local setup). Tools: hdf5_to_csv, hdf5_to_json, hdf5_tree.",
      "capabilities": [
        "hdf5_to_csv",
        "hdf5_to_json",
        "hdf5_tree"
      ],
      "tags": [
        "data",
        "hdf5",
        "h5",
        "converter",
        "extractor",
        "scientific-data"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:ical",
      "displayName": "iCalendar Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'ical' skill — the same tools executed server-side (no local setup). Tools: ical_merge, ical_to_csv, ical_to_json, ical_to_text.",
      "capabilities": [
        "ical_merge",
        "ical_to_csv",
        "ical_to_json",
        "ical_to_text"
      ],
      "tags": [
        "calendar",
        "ics",
        "icalendar",
        "converter",
        "schedule",
        "events"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:image-ocr",
      "displayName": "Image OCR (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'image-ocr' skill — the same tools executed server-side (no local setup). Tools: image-ocr_extract_text, image-ocr_extract_to_csv, image-ocr_extract_to_json.",
      "capabilities": [
        "image-ocr_extract_text",
        "image-ocr_extract_to_csv",
        "image-ocr_extract_to_json"
      ],
      "tags": [
        "ocr",
        "image",
        "text-extraction",
        "png",
        "jpg",
        "tiff",
        "converter"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:ipynb",
      "displayName": "Jupyter Notebook Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'ipynb' skill — the same tools executed server-side (no local setup). Tools: ipynb_read, ipynb_strip_outputs.",
      "capabilities": [
        "ipynb_read",
        "ipynb_strip_outputs"
      ],
      "tags": [
        "jupyter",
        "notebook",
        "ipynb",
        "convert",
        "data-science"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:kml",
      "displayName": "KML/KMZ Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'kml' skill — the same tools executed server-side (no local setup). Tools: kml_summary, kml_to_csv, kml_to_geojson, kml_to_json.",
      "capabilities": [
        "kml_summary",
        "kml_to_csv",
        "kml_to_geojson",
        "kml_to_json"
      ],
      "tags": [
        "geospatial",
        "kml",
        "kmz",
        "converter",
        "reader",
        "gis"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:mbox",
      "displayName": "mbox Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'mbox' skill — the same tools executed server-side (no local setup). Tools: mbox_split, mbox_to_csv, mbox_to_json, mbox_to_text.",
      "capabilities": [
        "mbox_split",
        "mbox_to_csv",
        "mbox_to_json",
        "mbox_to_text"
      ],
      "tags": [
        "email",
        "mbox",
        "mailbox",
        "converter",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:msg",
      "displayName": "MSG Outlook Email Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'msg' skill — the same tools executed server-side (no local setup). Tools: msg_to_csv, msg_to_json, msg_to_text.",
      "capabilities": [
        "msg_to_csv",
        "msg_to_json",
        "msg_to_text"
      ],
      "tags": [
        "msg",
        "outlook",
        "email",
        "ole",
        "cfb",
        "document",
        "converter",
        "mapi"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:odp",
      "displayName": "ODP (OpenDocument Presentation) Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'odp' skill — the same tools executed server-side (no local setup). Tools: odp_to_json, odp_to_text.",
      "capabilities": [
        "odp_to_json",
        "odp_to_text"
      ],
      "tags": [
        "document",
        "presentation",
        "odp",
        "opendocument",
        "libreoffice",
        "convert",
        "extract"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:ods",
      "displayName": "ODS Spreadsheet Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'ods' skill — the same tools executed server-side (no local setup). Tools: ods_list_sheets, ods_to_csv, ods_to_json.",
      "capabilities": [
        "ods_list_sheets",
        "ods_to_csv",
        "ods_to_json"
      ],
      "tags": [
        "ods",
        "spreadsheet",
        "opendocument",
        "csv",
        "json",
        "convert",
        "read"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:odt",
      "displayName": "ODT Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'odt' skill — the same tools executed server-side (no local setup). Tools: odt_read, odt_to_csv, odt_to_json.",
      "capabilities": [
        "odt_read",
        "odt_to_csv",
        "odt_to_json"
      ],
      "tags": [
        "document",
        "odt",
        "openDocument",
        "convert",
        "extract",
        "text"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:orc",
      "displayName": "ORC Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'orc' skill — the same tools executed server-side (no local setup). Tools: orc_sample, orc_schema, orc_to_csv, orc_to_json.",
      "capabilities": [
        "orc_sample",
        "orc_schema",
        "orc_to_csv",
        "orc_to_json"
      ],
      "tags": [
        "data",
        "orc",
        "columnar",
        "csv",
        "conversion",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:parquet",
      "displayName": "Parquet Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'parquet' skill — the same tools executed server-side (no local setup). Tools: parquet_sample, parquet_schema, parquet_to_csv, parquet_to_json.",
      "capabilities": [
        "parquet_sample",
        "parquet_schema",
        "parquet_to_csv",
        "parquet_to_json"
      ],
      "tags": [
        "data",
        "parquet",
        "columnar",
        "csv",
        "conversion",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:plist",
      "displayName": "Apple Plist Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'plist' skill — the same tools executed server-side (no local setup). Tools: plist_convert, plist_read.",
      "capabilities": [
        "plist_convert",
        "plist_read"
      ],
      "tags": [
        "plist",
        "apple",
        "macos",
        "ios",
        "xml",
        "binary",
        "converter",
        "extractor"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:reg",
      "displayName": "Windows Registry Export Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'reg' skill — the same tools executed server-side (no local setup). Tools: reg_read, reg_to_csv, reg_to_json.",
      "capabilities": [
        "reg_read",
        "reg_to_csv",
        "reg_to_json"
      ],
      "tags": [
        "registry",
        "windows",
        "reg",
        "converter",
        "extractor",
        "json",
        "csv"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:rtf",
      "displayName": "RTF Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'rtf' skill — the same tools executed server-side (no local setup). Tools: rtf_to_json, rtf_to_markdown, rtf_to_text.",
      "capabilities": [
        "rtf_to_json",
        "rtf_to_markdown",
        "rtf_to_text"
      ],
      "tags": [
        "rtf",
        "document",
        "converter",
        "reader",
        "rich-text-format"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:shapefile",
      "displayName": "Shapefile & GeoPackage Reader / Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'shapefile' skill — the same tools executed server-side (no local setup). Tools: shapefile_summary, shapefile_to_csv, shapefile_to_geojson, shapefile_to_ndjson.",
      "capabilities": [
        "shapefile_summary",
        "shapefile_to_csv",
        "shapefile_to_geojson",
        "shapefile_to_ndjson"
      ],
      "tags": [
        "geospatial",
        "shapefile",
        "geopackage",
        "gis",
        "converter",
        "reader"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:sqlite",
      "displayName": "SQLite Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'sqlite' skill — the same tools executed server-side (no local setup). Tools: sqlite_query, sqlite_read, sqlite_schema_diff.",
      "capabilities": [
        "sqlite_query",
        "sqlite_read",
        "sqlite_schema_diff"
      ],
      "tags": [
        "sqlite",
        "database",
        "extractor",
        "csv",
        "json",
        "converter"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:vcard",
      "displayName": "vCard (.vcf) Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'vcard' skill — the same tools executed server-side (no local setup). Tools: vcard_to_csv, vcard_to_json, vcard_to_text.",
      "capabilities": [
        "vcard_to_csv",
        "vcard_to_json",
        "vcard_to_text"
      ],
      "tags": [
        "document",
        "vcard",
        "vcf",
        "contacts",
        "convert",
        "extract"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    },
    {
      "identifier": "urn:air:stealthstack.ai:mcp:xls",
      "displayName": "Legacy Excel (.xls) Reader & Converter (runner)",
      "type": "application/mcp",
      "url": "https://runner.stealthstack.ai/mcp",
      "description": "Runner twin of the 'xls' skill — the same tools executed server-side (no local setup). Tools: xls_list_sheets, xls_to_csv, xls_to_json.",
      "capabilities": [
        "xls_list_sheets",
        "xls_to_csv",
        "xls_to_json"
      ],
      "tags": [
        "excel",
        "xls",
        "spreadsheet",
        "csv",
        "conversion",
        "legacy"
      ],
      "trustManifest": {
        "identity": "did:web:stealthstack.ai",
        "identityType": "did"
      }
    }
  ]
}