<< All versions
Skill v1.0.0
currentLLM-judged scan90/100yanacuti1121/yana-ai/archive-stream-patterns
──Details
PublishedOctober 23, 2026 at 06:06 AM
Content Hashsha256:333db58c9786fb0c...
Git SHA5b39442837f1
──Files
Files (1 file, 3.6 KB)
SKILL.md3.6 KBactive
SKILL.md · 121 lines · 3.6 KB
name: archive-stream-patterns description: Streaming ZIP and TAR archive creation for agent release packaging. node-archiver streaming API, append files/directories, compression levels, progress events, and integrity verification. Sources: archiverjs/node-archiver. origin: yana-ai — synthesized from archiverjs/node-archiver (MIT) license: Apache-2.0 version: 1.0.0 compatibility: yana-ai >= 1.3.48
/archive-stream-patterns
When to Use
- Building yamtam release packages (zip skills + rules + scripts into versioned archive)
- Streaming archive creation without loading entire archive into RAM
- Progressively adding files to archive during agent session
- Replacing synchronous zip tools with event-driven streaming approach
Do NOT use for
- Extracting/reading existing archives (use [[zip-memory-operations]] for in-memory ops)
- Archives > 4GB (ZIP32 limit — use TAR.GZ instead)
Create release ZIP
javascript
import archiver from 'archiver'import { createWriteStream } from 'fs'import { resolve } from 'path'async function createRelease(projectRoot: string,outputPath: string,version: string): Promise<{ bytes: number; fileCount: number }> {return new Promise((res, rej) => {const output = createWriteStream(outputPath)const archive = archiver('zip', {zlib: { level: 6 }, // 0=store, 9=max compression})let fileCount = 0output.on('close', () => res({ bytes: archive.pointer(), fileCount }))archive.on('error', rej)archive.on('entry', () => fileCount++)archive.on('warning', (err) => {if (err.code !== 'ENOENT') rej(err)})archive.pipe(output)// Add directoriesarchive.directory(resolve(projectRoot, 'core/skills'), `yamtam-${version}/skills`)archive.directory(resolve(projectRoot, 'core/rules'), `yamtam-${version}/rules`)archive.directory(resolve(projectRoot, 'core/scripts'), `yamtam-${version}/scripts`)// Add specific filesarchive.file(resolve(projectRoot, 'MANIFEST.json'), { name: `yamtam-${version}/MANIFEST.json` })archive.file(resolve(projectRoot, 'README.md'), { name: `yamtam-${version}/README.md` })archive.finalize()})}
TAR.GZ for large archives
javascript
const archive = archiver('tar', { gzip: true, gzipOptions: { level: 9 } })const output = createWriteStream('/tmp/yamtam-release.tar.gz')archive.pipe(output)archive.glob('**/*', { cwd: projectRoot, ignore: ['node_modules/**', 'releases/logs/**'] })await new Promise((res, rej) => {output.on('close', res)archive.on('error', rej)archive.finalize()})
Progress reporting
javascript
archive.on('progress', (progress) => {const pct = ((progress.entries.processed / progress.entries.total) * 100).toFixed(0)process.stdout.write(`\r[archive] ${pct}% (${progress.entries.processed}/${progress.entries.total} files)`)})
Integrity check after creation
bash
# Verify zip integrity after archiver finishesunzip -t /tmp/yamtam-release.zip | tail -1# → No errors detected in /tmp/yamtam-release.zip# Check tar integritytar -tzf /tmp/yamtam-release.tar.gz > /dev/null && echo "TAR OK"
Anti-Fake-Pass Checklist
❌ No error handler on archive object → unhandled rejection crashes process❌ archive.finalize() before all .file()/.directory() calls → truncated archive❌ output stream not piped before adding files → buffering fills RAM❌ No 'close' on output stream → promise resolves before file is flushed to disk❌ ZIP > 4GB → use TAR.GZ (archiver zip format uses 32-bit file sizes)❌ node_modules/ not excluded → 50MB archive becomes 1GB