@wairon/sdk 6.7.4-dev.7 → 6.7.4-dev.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var require_package = __commonJS({
|
|
|
35
35
|
"package.json"(exports2, module2) {
|
|
36
36
|
module2.exports = {
|
|
37
37
|
name: "@wairon/sdk",
|
|
38
|
-
version: "6.7.4-dev.
|
|
38
|
+
version: "6.7.4-dev.8",
|
|
39
39
|
description: "Experimental: wairon pack-archive (.wpack) format authority and authoring toolkit \u2014 scaffold, build, inspect, and safely extract wairon extension packs.",
|
|
40
40
|
keywords: [
|
|
41
41
|
"wairon",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/index.ts","../src/orchestrator.ts","../src/codec.ts","../src/errors.ts","../src/treecodec.ts","../src/version.ts","../src/scaffold.ts","../src/archive.ts","../src/authoring.ts"],"sourcesContent":["{\n \"name\": \"@wairon/sdk\",\n \"version\": \"6.7.4-dev.7\",\n \"description\": \"Experimental: wairon pack-archive (.wpack) format authority and authoring toolkit — scaffold, build, inspect, and safely extract wairon extension packs.\",\n \"keywords\": [\n \"wairon\",\n \"sdd\",\n \"pack\",\n \"wpack\",\n \"archive\",\n \"developer-tools\",\n \"experimental\"\n ],\n \"author\": \"SYW\",\n \"license\": \"MIT\",\n \"homepage\": \"https://github.com/SYW-Apps/Waffle-AIron\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/SYW-Apps/Waffle-AIron.git\"\n },\n \"type\": \"commonjs\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"engines\": {\n \"node\": \"^22.23.4 || ^24.22.1 || >=26.12.1\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"clean\": \"rimraf dist\"\n },\n \"dependencies\": {\n \"fflate\": \"^0.8.2\",\n \"js-yaml\": \"^4.3.2\"\n },\n \"devDependencies\": {\n \"@types/js-yaml\": \"^4.0.9\",\n \"@types/node\": \"^20.14.0\",\n \"rimraf\": \"^5.0.7\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.5.2\",\n \"vitest\": \"^4.1.9\"\n }\n}\n","import * as orchestrator from './orchestrator.js';\nimport * as codec from './codec.js';\nimport type {\n PackArchiveInfo,\n PackBuildResult,\n PackContents,\n PackExtractionLimits,\n PackExtractionResult,\n PackFile,\n PackScaffoldRequest,\n TreeArchiveInfo,\n TreeBuildResult,\n TreeExtractionResult,\n TreeRootSource,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// SDK Portal (sdk_portal_impl) — the @wairon/sdk package entry. Each capability\n// is a 1:1 forward to the SDK orchestrator with no logic of its own; the module\n// also re-exports the pure pack-authoring value objects and the rule-authoring\n// contract (compile-time types + the defineRule helper).\n// ---------------------------------------------------------------------------\n\n/** Scaffold a new pack project (declarative or code) into a directory; returns the created file paths. */\nexport function scaffoldPack(request: PackScaffoldRequest): string[] {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.scaffoldPack(request);\n}\n\n/** Build an installable .wpack archive from a pack directory. */\nexport function buildPack(sourceDir: string): PackBuildResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.buildPack(sourceDir);\n}\n\n/**\n * A pack's content integrity (`sha256-<hex>`) over its files as extracted —\n * the digest project.yaml pins and a registry publishes, one implementation\n * for every consumer.\n */\nexport function packContentDigest(files: readonly PackFile[]): string {\n // Step 1: forward to the pack codec.\n return codec.contentDigest(files);\n}\n\n/** Inspect + verify a .wpack archive without extracting it. */\nexport function inspectArchive(archive: Uint8Array, limits?: PackExtractionLimits): PackArchiveInfo {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.inspectArchive(archive, limits);\n}\n\n/** Read a .wpack archive in memory under the extraction guards; nothing is written. */\nexport function readPack(archive: Uint8Array, limits?: PackExtractionLimits): PackContents {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.readPack(archive, limits);\n}\n\n/** Safely extract a .wpack archive into a destination directory under enforced limits. */\nexport function extractPack(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n): PackExtractionResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.extractPack(archive, destDir, limits);\n}\n\n/** Pack a project's spec tree — the supplied roots' .wai directories — into a .waitree archive. */\nexport function buildTreeArchive(\n roots: TreeRootSource[],\n projectName: string,\n stateId?: string,\n includeDerived?: boolean,\n): TreeBuildResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.buildTreeArchive(roots, projectName, stateId, includeDerived);\n}\n\n/** Inspect a .waitree archive without extracting it. */\nexport function inspectTreeArchive(archive: Uint8Array): TreeArchiveInfo {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.inspectTreeArchive(archive);\n}\n\n/** Safely extract a .waitree archive into a destination project root under enforced limits. */\nexport function extractTreeArchive(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n refuseExecutableEntries?: boolean,\n): TreeExtractionResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.extractTreeArchive(archive, destDir, limits, refuseExecutableEntries);\n}\n\n// Re-export the pure pack-archive value objects...\nexport * from './types.js';\n// ...and the rule-authoring contract (SddRule + stable RuleContext/Finding facade + defineRule).\nexport * from './authoring.js';\n// ...and the one error every .wpack reader fails with, plus its code union.\nexport { PackArchiveError } from './errors.js';\nexport type { PackArchiveErrorCode } from './errors.js';\n","import * as path from 'path';\nimport { load as yamlLoad } from 'js-yaml';\nimport * as codec from './codec.js';\nimport * as treecodec from './treecodec.js';\nimport * as scaffold from './scaffold.js';\nimport * as packArchive from './archive.js';\nimport { SDK_VERSION } from './version.js';\nimport { PackArchiveError } from './errors.js';\nimport type {\n ArchiveEntryMeta,\n PackArchiveInfo,\n PackArchiveManifest,\n PackBuildResult,\n PackContents,\n PackExtractionLimits,\n PackExtractionResult,\n PackFile,\n PackScaffoldRequest,\n TreeArchiveInfo,\n TreeArchiveManifest,\n TreeBuildResult,\n TreeExtractionResult,\n TreeRootSource,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// SDK Orchestrator (sdk_orchestrator_impl) — the four pack workflows and the\n// three spec-tree archive workflows. Delegates format/safety decisions to the\n// codecs, template rendering to the pack scaffold, and all zip+fs I/O to\n// the archive adapter. Holds no state.\n//\n// Root DISCOVERY stays with the caller: the SDK never walks a spec tree, it\n// only archives the roots it is handed.\n// ---------------------------------------------------------------------------\n\nconst decode = (b: Uint8Array): string => new TextDecoder().decode(b);\nconst encode = (s: string): Uint8Array => new TextEncoder().encode(s);\n\n/** Render the scaffold file map and write it under the target directory. */\nexport function scaffoldPack(request: PackScaffoldRequest): string[] {\n // Step 1: render the scaffold file map for the requested pack.\n const files = scaffold.render(request);\n // Step 2: write the rendered files as a directory tree under targetDir.\n packArchive.writeTree(request.targetDir, files);\n // Step 3: return the created file paths (targetDir-joined).\n return files.map((file) => path.join(request.targetDir, file.path));\n}\n\n/** Build an installable .wpack archive from a pack directory. */\nexport function buildPack(sourceDir: string): PackBuildResult {\n // Step 1: read the source pack directory into a file map.\n const files = packArchive.readPackDir(sourceDir);\n // Step 2: require an envelope.\n const envelope = files.find((file) => file.path === codec.ENVELOPE_FILENAME);\n if (!envelope) {\n // Step 3: reject a pack directory with no envelope.\n throw new Error('pack build requires a wairon-pack.yaml envelope (run `wairon pack init` to scaffold one)');\n }\n // Step 4 (parse): parse + validate the envelope (also version-gates the format).\n const manifest = codec.parseManifest(decode(envelope.contents));\n // Step 5: read the inner pack identity (pack.yaml, or package.json for code).\n const identity = readInnerIdentity(files, manifest);\n // Step 6: assert the envelope's name/version match the inner pack manifest.\n codec.verifyIdentity(manifest, identity.name, identity.version);\n // Step 7: seal integrity (entryDigests + digest + generatedBy) with no build time,\n // so the same content always builds the same archive and content digest.\n const sealed = codec.sealIntegrity(manifest, files, `@wairon/sdk@${SDK_VERSION}`);\n // Step 8: serialize the sealed manifest back to canonical envelope text.\n const sealedText = codec.serializeManifest(sealed);\n // Step 9: upsert wairon-pack.yaml (sealed envelope text) into the file map.\n const finalFiles = upsertEnvelope(files, sealedText);\n // Step 10: deflate the files + envelope into .wpack archive bytes.\n const archiveBytes = packArchive.assembleArchive(finalFiles);\n // Step 11: assemble PackArchiveInfo + suggestedFileName.\n const info = buildInfo(sealed, finalFiles);\n const suggestedFileName = `${sealed.name}-${sealed.version}.wpack`;\n // Step 12: return the build result.\n return { archive: archiveBytes, info, suggestedFileName };\n}\n\n/** The archive's entries; bytes that are not a readable ZIP carry no envelope, so they are NOT_A_PACK. */\nfunction listPackEntries(archive: Uint8Array): ArchiveEntryMeta[] {\n try {\n return packArchive.listEntries(archive);\n } catch (e) {\n throw new PackArchiveError('NOT_A_PACK', `not a .wpack archive (unreadable ZIP: ${e instanceof Error ? e.message : String(e)})`);\n }\n}\n\n/** Inspect + verify a .wpack archive without extracting it; every entry is vetted under the limits before anything is inflated. */\nexport function inspectArchive(archive: Uint8Array, limits?: PackExtractionLimits): PackArchiveInfo {\n // Step 1: did the caller omit limits?\n const effectiveLimits = limits === undefined\n // Step 2: fall back to the codec's default limit profile.\n ? codec.defaultLimits()\n : limits;\n // Step 3: enumerate archive entries without inflating.\n const entries = listPackEntries(archive);\n // Step 4: vet every entry under the effective limits, the envelope included.\n codec.planExtraction(entries, effectiveLimits);\n // Step 5: is there no wairon-pack.yaml entry?\n if (!entries.some((entry) => entry.path === codec.ENVELOPE_FILENAME)) {\n // Step 6: reject a non-.wpack archive.\n throw new PackArchiveError('NOT_A_PACK', 'not a .wpack archive (missing wairon-pack.yaml envelope)');\n }\n // Step 7 (readEnv): inflate just the envelope entry.\n const envelopeBytes = packArchive.inflateEntry(archive, codec.ENVELOPE_FILENAME);\n // Step 8: parse + version-check the envelope text.\n const manifest = codec.parseManifest(decode(envelopeBytes));\n // Step 9: compute compatibility against the running wairon version.\n const compatible = codec.checkCompatibility(manifest, SDK_VERSION);\n // Step 10: assemble PackArchiveInfo from the manifest + archive stats.\n const fileEntries = entries.filter((entry) => entry.kind === 'file');\n const totalUncompressedBytes = entries.reduce((sum, entry) => sum + entry.uncompressedSize, 0);\n const info: PackArchiveInfo = {\n name: manifest.name,\n version: manifest.version,\n kind: manifest.kind,\n entry: manifest.entry,\n formatVersion: manifest.formatVersion,\n entryCount: fileEntries.length,\n totalUncompressedBytes,\n compatible,\n };\n if (manifest.minWaironVersion !== undefined) info.minWaironVersion = manifest.minWaironVersion;\n // Step 11: return the PackArchiveInfo (no extraction performed).\n return info;\n}\n\n/** Read a .wpack archive in memory under the limits: guards, envelope, integrity, inner manifest, identity. */\nexport function readPack(archive: Uint8Array, limits?: PackExtractionLimits): PackContents {\n // Step 1: did the caller omit limits?\n const effectiveLimits = limits === undefined\n // Step 2: fall back to the codec's default limit profile.\n ? codec.defaultLimits()\n : limits;\n // Step 3 (list): enumerate archive entries without inflating.\n const entries = listPackEntries(archive);\n // Step 4: compute the safe extraction plan under the effective limits.\n const plan = codec.planExtraction(entries, effectiveLimits);\n // Step 5: is there no wairon-pack.yaml among the approved paths?\n if (!plan.paths.includes(codec.ENVELOPE_FILENAME)) {\n // Step 6: reject a non-.wpack archive.\n throw new PackArchiveError('NOT_A_PACK', 'not a .wpack archive (missing wairon-pack.yaml envelope)');\n }\n // Step 7: initialize an empty file list.\n const files: PackFile[] = [];\n // Step 8: inflate each approved path from the plan.\n for (const approvedPath of plan.paths) {\n // Step 9: inflate one approved entry.\n const contents = packArchive.inflateEntry(archive, approvedPath);\n // Step 10 (inflateEnd): append { path, contents } to the file list.\n files.push({ path: approvedPath, contents });\n }\n // Step 11: parse the wairon-pack.yaml text into the envelope.\n const envelope = files.find((file) => file.path === codec.ENVELOPE_FILENAME) as PackFile;\n const manifest = codec.parseManifest(decode(envelope.contents));\n // Step 12: verify each inflated file against the envelope digests.\n codec.verifyIntegrity(manifest, files);\n // Step 13: read the inner pack manifest.\n const packManifest = codec.parseInnerManifest(manifest, files);\n // Step 14: verify the envelope's name and version against the inner manifest's.\n codec.verifyIdentity(manifest, String(packManifest.name), String(packManifest.version));\n // Step 15: return the envelope, the inner pack manifest and the files.\n return { manifest, packManifest, files };\n}\n\n/** Safely extract a .wpack archive into a destination directory under enforced limits. */\nexport function extractPack(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n): PackExtractionResult {\n // Step 1: read the archive in memory under the limits (fails before anything is written).\n const { manifest, files } = readPack(archive, limits);\n // Step 2: write the approved, integrity-checked files as a directory tree.\n const directory = path.resolve(destDir);\n packArchive.writeTree(directory, files);\n // Step 3: assemble PackExtractionResult.\n const result: PackExtractionResult = {\n directory,\n entryPath: manifest.entry,\n manifest,\n name: manifest.name,\n kind: manifest.kind,\n entryCount: files.length,\n };\n // Step 4: return where the pack landed + its parsed manifest.\n return result;\n}\n\n// ── Spec-tree archive workflows (.waitree) ──────────────────────────────────\n\n/** Pack a project's spec tree — the supplied roots' .wai directories — into a .waitree. */\nexport function buildTreeArchive(\n roots: TreeRootSource[],\n projectName: string,\n stateId?: string,\n includeDerived?: boolean,\n): TreeBuildResult {\n // Step 1: initialize an empty archive file map and an empty packed-roots list.\n const files: PackFile[] = [];\n const packedRoots: string[] = [];\n // Step 2: pack each supplied root.\n for (const root of roots) {\n // Step 3: read this root's .wai directory recursively into a file map.\n const rootFiles = packArchive.readPackDir(root.waiDir);\n // Step 4: keep only portable design state.\n const portable = treecodec.selectTreeFiles(rootFiles, includeDerived === true);\n // Step 5 (packEnd): prefix with this root's project-relative path + '.wai/'.\n const prefix = treeRootPrefix(root.relativePath);\n for (const file of portable) files.push({ path: `${prefix}${file.path}`, contents: file.contents });\n packedRoots.push(normalizeRootPath(root.relativePath));\n }\n // Step 6: did the roots yield no files at all?\n if (files.length === 0) {\n // Step 7: an export that silently carries nothing is worse than a failure.\n throw new Error('tree export found no spec-tree files under the supplied roots');\n }\n // Step 8: build the unsealed envelope.\n const manifest: TreeArchiveManifest = {\n formatVersion: 1,\n projectName,\n roots: packedRoots,\n waironVersion: SDK_VERSION,\n includesDerived: includeDerived === true,\n };\n if (stateId !== undefined) manifest.stateId = stateId;\n // Step 9: seal integrity (entryDigests + digest + generatedBy/generatedAt).\n const sealed = treecodec.sealTreeIntegrity(\n manifest,\n files,\n `@wairon/sdk@${SDK_VERSION}`,\n new Date().toISOString(),\n );\n // Step 10: serialize the sealed manifest to canonical envelope text.\n const sealedText = treecodec.serializeTreeManifest(sealed);\n // Step 11: upsert wairon-tree.yaml (sealed envelope text) into the file map.\n const finalFiles: PackFile[] = [\n ...files.filter((file) => file.path !== treecodec.TREE_ENVELOPE_FILENAME),\n { path: treecodec.TREE_ENVELOPE_FILENAME, contents: encode(sealedText) },\n ];\n // Step 12: deflate the files + envelope into .waitree archive bytes.\n const archiveBytes = packArchive.assembleArchive(finalFiles);\n // Step 13: derive the suggested file name from the project name.\n const suggestedFileName = `${slugify(projectName)}.waitree`;\n // Step 14: return the build result.\n return { archive: archiveBytes, manifest: sealed, suggestedFileName, fileCount: files.length };\n}\n\n/** Inspect a .waitree archive without extracting it. */\nexport function inspectTreeArchive(archive: Uint8Array): TreeArchiveInfo {\n // Step 1: enumerate archive entries without inflating.\n const entries = packArchive.listEntries(archive);\n // Step 2: is there no wairon-tree.yaml entry?\n if (!entries.some((entry) => entry.path === treecodec.TREE_ENVELOPE_FILENAME)) {\n // Step 3: reject a non-.waitree archive.\n throw new Error('not a .waitree archive (missing wairon-tree.yaml envelope)');\n }\n // Step 4 (readEnv): inflate just the envelope entry.\n const envelopeBytes = packArchive.inflateEntry(archive, treecodec.TREE_ENVELOPE_FILENAME);\n // Step 5: parse + version-check the envelope text.\n const manifest = treecodec.parseTreeManifest(decode(envelopeBytes));\n // Step 6: compute compatibility against the running wairon version.\n const compatible = treecodec.checkTreeCompatibility(manifest, SDK_VERSION);\n // Step 7: assemble TreeArchiveInfo from the manifest + archive stats.\n const fileEntries = entries.filter((entry) => entry.kind === 'file');\n const totalUncompressedBytes = entries.reduce((sum, entry) => sum + entry.uncompressedSize, 0);\n // Step 8: return the TreeArchiveInfo (no extraction performed).\n return { manifest, entryCount: fileEntries.length, totalUncompressedBytes, compatible };\n}\n\n/** Safely extract a .waitree archive into a destination project root under enforced limits. */\nexport function extractTreeArchive(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n refuseExecutableEntries?: boolean,\n): TreeExtractionResult {\n // Step 1: did the caller omit limits?\n const effectiveLimits = limits === undefined\n // Step 2: fall back to the codec's tree limit profile.\n ? treecodec.defaultTreeLimits()\n : limits;\n // Step 3 (list): enumerate archive entries without inflating (caps run pre-decompress).\n const entries = packArchive.listEntries(archive);\n // Step 4: compute the safe extraction plan (throws on any unsafe/oversized entry).\n const plan = treecodec.planTreeExtraction(entries, effectiveLimits);\n // Step 5: did the caller ask for the over-the-wire portability guard?\n if (refuseExecutableEntries === true) {\n // Step 6: refuse executable or non-spec-tree entries before anything is inflated.\n treecodec.assertPortableTreePaths(plan.paths);\n }\n // Step 7 (inflate): initialize an empty file list.\n const files: PackFile[] = [];\n // Step 8: inflate each approved path from the plan.\n for (const approvedPath of plan.paths) {\n // Step 9: inflate one approved entry.\n const contents = packArchive.inflateEntry(archive, approvedPath);\n // Step 10 (inflateEnd): append { path, contents } to the file list.\n files.push({ path: approvedPath, contents });\n }\n // Step 11: is the wairon-tree.yaml envelope missing from the inflated files?\n const envelope = files.find((file) => file.path === treecodec.TREE_ENVELOPE_FILENAME);\n if (!envelope) {\n // Step 12: reject a non-.waitree archive.\n throw new Error('not a .waitree archive (missing wairon-tree.yaml envelope)');\n }\n // Step 13 (parse): parse the envelope into the result manifest.\n const manifest = treecodec.parseTreeManifest(decode(envelope.contents));\n // Step 14: enforce integrity BEFORE writing (throws on mismatch; no-op when none carried).\n treecodec.verifyTreeIntegrity(manifest, files);\n // Step 15: write the approved, integrity-checked files as a directory tree.\n const directory = path.resolve(destDir);\n packArchive.writeTree(directory, files);\n // Step 16: assemble TreeExtractionResult.\n const result: TreeExtractionResult = {\n destDir: directory,\n manifest,\n roots: manifest.roots,\n writtenPaths: files.map((file) => file.path),\n };\n // Step 17: return where the tree landed + its parsed manifest.\n return result;\n}\n\n// --- helpers ---------------------------------------------------------------\n\n/** The archive-path prefix for one packed root: '.wai/' at the top, else '<dir>/.wai/'. */\nfunction treeRootPrefix(relativePath: string): string {\n const normalized = normalizeRootPath(relativePath);\n return normalized === '.' ? '.wai/' : `${normalized}/.wai/`;\n}\n\n/** A packed root's canonical project-relative form: POSIX separators, '.' for the top root. */\nfunction normalizeRootPath(relativePath: string): string {\n const posix = relativePath.split(path.sep).join('/').replace(/^\\.\\//, '').replace(/\\/+$/, '');\n return posix === '' || posix === '.' ? '.' : posix;\n}\n\n/** A file-name-safe stem for a project name. */\nfunction slugify(projectName: string): string {\n const slug = projectName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'spec-tree';\n}\n\nfunction readInnerIdentity(files: PackFile[], manifest: PackArchiveManifest): { name: string; version: string } {\n const innerPath = manifest.kind === 'code' ? 'package.json' : manifest.entry;\n const inner = files.find((file) => file.path === innerPath);\n if (!inner) throw new Error(`pack build: inner pack manifest \"${innerPath}\" is missing`);\n const parsed = (manifest.kind === 'code'\n ? JSON.parse(decode(inner.contents))\n : yamlLoad(decode(inner.contents))) as Record<string, unknown> | null;\n const name = parsed?.name;\n const version = parsed?.version;\n if (typeof name !== 'string' || typeof version !== 'string') {\n throw new Error(`pack build: inner pack manifest \"${innerPath}\" lacks a name/version`);\n }\n return { name, version };\n}\n\nfunction upsertEnvelope(files: PackFile[], envelopeText: string): PackFile[] {\n const others = files.filter((file) => file.path !== codec.ENVELOPE_FILENAME);\n return [...others, { path: codec.ENVELOPE_FILENAME, contents: encode(envelopeText) }];\n}\n\nfunction buildInfo(manifest: PackArchiveManifest, files: PackFile[]): PackArchiveInfo {\n const totalUncompressedBytes = files.reduce((sum, file) => sum + file.contents.length, 0);\n const info: PackArchiveInfo = {\n name: manifest.name,\n version: manifest.version,\n kind: manifest.kind,\n entry: manifest.entry,\n formatVersion: manifest.formatVersion,\n entryCount: files.length,\n totalUncompressedBytes,\n compatible: true,\n };\n if (manifest.minWaironVersion !== undefined) info.minWaironVersion = manifest.minWaironVersion;\n return info;\n}\n","import { load as yamlLoad, dump as yamlDump } from 'js-yaml';\nimport { createHash } from 'crypto';\nimport { PackArchiveError } from './errors.js';\nimport type {\n ArchiveEntryMeta,\n PackArchiveManifest,\n PackExtractionLimits,\n PackExtractionPlan,\n PackFile,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Pack Codec (pack_codec_impl) — PURE format + safety logic, no I/O.\n//\n// planExtraction is the single safety chokepoint (zip-slip / size / ratio /\n// depth / symlink guards, all pre-decompress). sealIntegrity/verifyIntegrity\n// are the produce/verify integrity pair. The codec stays pure: build time is\n// passed in, never read here.\n// ---------------------------------------------------------------------------\n\n/** Never part of a pack's content integrity: any path segment with one of these names. */\nconst DIGEST_EXCLUDED = new Set(['.install.yaml', '.git', 'node_modules', '.DS_Store']);\n\n/**\n * pack_codec.contentDigest — a pack's content integrity: sha256 folding each\n * file in sorted order as `<forward-slash path> NUL <bytes> NUL`, skipping\n * `.install.yaml`, `.git`, `node_modules` and `.DS_Store` wherever they sit,\n * written `sha256-<lowercase hex>`. The digest wairon's pack store computes\n * over an installed pack directory and project.yaml pins. Pure.\n */\nexport function contentDigest(files: readonly PackFile[]): string {\n // Steps 1-2: normalized paths, the skipped ones dropped, in sorted order.\n const kept = files\n .map((file) => ({ path: file.path.replace(/\\\\/g, '/').replace(/^\\/+/, ''), contents: file.contents }))\n .filter((file) => !file.path.split('/').some((segment) => DIGEST_EXCLUDED.has(segment)))\n .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n // Step 3: path NUL bytes NUL, folded in order.\n const hash = createHash('sha256');\n for (const file of kept) {\n hash.update(file.path);\n hash.update('\\0');\n hash.update(file.contents);\n hash.update('\\0');\n }\n // Step 4.\n return `sha256-${hash.digest('hex')}`;\n}\n\n/** The archive-root envelope filename. */\nexport const ENVELOPE_FILENAME = 'wairon-pack.yaml';\n\n/** The highest pack-archive format major this SDK understands. */\nconst SUPPORTED_FORMAT_VERSION = 1;\n\n/** The default extraction-safety profile: 4096 / 32 MiB / 8 MiB / 100:1 / depth 16. */\nconst DEFAULTS = {\n maxEntries: 4096,\n maxTotalUncompressedBytes: 32 * 1024 * 1024,\n maxEntryBytes: 8 * 1024 * 1024,\n maxCompressionRatio: 100,\n maxDepth: 16,\n} as const;\n\n/** Parse + validate the envelope text into a PackArchiveManifest; throws on malformed/newer-major. */\nexport function parseManifest(text: string): PackArchiveManifest {\n // Step 1: parse the envelope YAML text (ENVELOPE_INVALID on malformed YAML).\n let raw: unknown;\n try {\n raw = yamlLoad(text);\n } catch (err) {\n throw new PackArchiveError('ENVELOPE_INVALID', `malformed pack envelope (not valid YAML): ${(err as Error).message}`);\n }\n // Step 2: validate the required fields are present and well-typed.\n const manifest = validateEnvelope(raw);\n // Step 3: is the format major newer than this wairon supports?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: fail loudly rather than silently mis-read a newer format.\n throw new PackArchiveError(\n 'FORMAT_VERSION_UNSUPPORTED',\n `unsupported pack-archive formatVersion ${manifest.formatVersion} (newer than this wairon understands)`,\n );\n }\n // Step 5: return the parsed manifest.\n return manifest;\n}\n\n/** Serialize a manifest to canonical wairon-pack.yaml text (build path). */\nexport function serializeManifest(manifest: PackArchiveManifest): string {\n // Step 1: drop undefined optional fields for a clean, canonical envelope.\n const clean: Record<string, unknown> = {\n formatVersion: manifest.formatVersion,\n name: manifest.name,\n version: manifest.version,\n kind: manifest.kind,\n entry: manifest.entry,\n };\n if (manifest.minWaironVersion !== undefined) clean.minWaironVersion = manifest.minWaironVersion;\n if (manifest.digest !== undefined) clean.digest = manifest.digest;\n if (manifest.entryDigests !== undefined) clean.entryDigests = manifest.entryDigests;\n if (manifest.generatedBy !== undefined) clean.generatedBy = manifest.generatedBy;\n if (manifest.generatedAt !== undefined) clean.generatedAt = manifest.generatedAt;\n // Step 2: return the wairon-pack.yaml text.\n return yamlDump(clean, { sortKeys: false });\n}\n\n/** The default extraction-safety profile; callers override individual caps. */\nexport function defaultLimits(): PackExtractionLimits {\n // Step 1: return the default caps profile.\n return { ...DEFAULTS };\n}\n\n/** Compute the safe extraction plan from enumerated entries under `limits`, or throw. */\nexport function planExtraction(entries: ArchiveEntryMeta[], limits: PackExtractionLimits): PackExtractionPlan {\n // Step 1: resolve effective caps — each field of `limits` over the defaults.\n const caps = {\n maxEntries: limits.maxEntries ?? DEFAULTS.maxEntries,\n maxTotalUncompressedBytes: limits.maxTotalUncompressedBytes ?? DEFAULTS.maxTotalUncompressedBytes,\n maxEntryBytes: limits.maxEntryBytes ?? DEFAULTS.maxEntryBytes,\n maxCompressionRatio: limits.maxCompressionRatio ?? DEFAULTS.maxCompressionRatio,\n maxDepth: limits.maxDepth ?? DEFAULTS.maxDepth,\n };\n // Step 2: initialize an empty approved-path list and a running total of 0.\n const approved: string[] = [];\n let total = 0;\n // Step 3: vet each enumerated entry.\n for (const entry of entries) {\n // Step 4: reject symlinks/non-regular entries and structurally unsafe paths.\n if (isSymlinkOrNonRegular(entry.kind) || isStructurallyUnsafePath(entry.path)) {\n rejectUnsafe(entry.path);\n }\n // Directory entries are structural (writeTree recreates them from file\n // paths) — skip without approving, never inflate a 0-byte dir marker.\n if (entry.kind === 'dir') continue;\n // Step 5: normalize the entry path to a destination-relative POSIX path.\n const normalized = normalizeRelPath(entry.path);\n // Step 6: reject zip-slip and over-deep paths.\n if (escapesDestination(normalized)) {\n rejectUnsafe(entry.path);\n }\n if (pathDepth(normalized) > caps.maxDepth) {\n rejectLimit(`entry \"${entry.path}\" is nested deeper than maxDepth (${caps.maxDepth})`);\n }\n // Step 7: reject oversized entries and zip bombs.\n if (entry.uncompressedSize > caps.maxEntryBytes) {\n rejectLimit(`entry \"${entry.path}\" is larger than maxEntryBytes (${caps.maxEntryBytes})`);\n }\n if (compressionRatio(entry) > caps.maxCompressionRatio) {\n rejectLimit(`entry \"${entry.path}\" exceeds maxCompressionRatio (${caps.maxCompressionRatio}:1)`);\n }\n // Step 8 (vetEnd): accept — append the path and add its inflated size.\n approved.push(normalized);\n total += entry.uncompressedSize;\n }\n // Step 9: reject archives exceeding the aggregate caps.\n if (approved.length > caps.maxEntries) {\n rejectLimit(`archive holds more than maxEntries (${caps.maxEntries}) files`);\n }\n if (total > caps.maxTotalUncompressedBytes) {\n rejectLimit(`archive inflates beyond maxTotalUncompressedBytes (${caps.maxTotalUncompressedBytes})`);\n }\n // Step 11: return the approved plan.\n return { paths: approved, totalUncompressedBytes: total };\n}\n\n/** Assert the envelope's name/version match the inner pack manifest; throw on mismatch. */\nexport function verifyIdentity(manifest: PackArchiveManifest, packName: string, packVersion: string): void {\n // Step 1: do envelope name/version differ from the inner pack manifest?\n if (manifest.name !== packName || manifest.version !== packVersion) {\n // Step 2: reject a tampered/mis-assembled archive.\n throw new PackArchiveError(\n 'IDENTITY_MISMATCH',\n `envelope identity mismatch: envelope says ${manifest.name}@${manifest.version}, inner pack manifest says ${packName}@${packVersion}`,\n );\n }\n // Step 3: identity verified.\n}\n\n/** Verify every entry's sha256 against entryDigests; false when none carried, throws on mismatch. */\nexport function verifyIntegrity(manifest: PackArchiveManifest, files: PackFile[]): boolean {\n // Step 1: did the envelope carry no integrity data?\n if (!manifest.entryDigests) {\n // Step 2: no integrity data present — return false.\n return false;\n }\n const digests = manifest.entryDigests;\n // Step 3: does entryDigests name a file the archive does not hold, or does the\n // envelope's overall digest differ from the one recomputed over entryDigests?\n const held = new Set(files.map((file) => file.path));\n const missing = Object.keys(digests).find((path) => !held.has(path));\n if (missing !== undefined) {\n // Step 8 (mismatch): the envelope lists a file the archive does not hold.\n throw new PackArchiveError('DIGEST_MISMATCH', `integrity digest lists \"${missing}\", which the archive does not hold`);\n }\n if (manifest.digest !== undefined && manifest.digest !== sha256(canonicalDigestBytes(digests))) {\n // Step 8 (mismatch): the overall digest does not match the entry digests.\n throw new PackArchiveError('DIGEST_MISMATCH', 'integrity digest mismatch for the overall digest');\n }\n // Step 4: check each file's digest.\n for (const file of files) {\n // The envelope carries these digests and cannot digest itself — skip it.\n if (file.path === ENVELOPE_FILENAME) continue;\n // Step 5: does the recomputed sha256 differ from the recorded digest?\n if (sha256(file.contents) !== digests[file.path]) {\n // Step 8 (mismatch): a digest mismatch means tampering.\n throw new PackArchiveError('DIGEST_MISMATCH', `integrity digest mismatch for \"${file.path}\"`);\n }\n // Step 6 (checkEnd): this file's digest matches.\n }\n // Step 7: all digests matched — return true.\n return true;\n}\n\n/** Produce-side partner of verifyIntegrity: fill entryDigests + digest + stamps. */\nexport function sealIntegrity(\n manifest: PackArchiveManifest,\n files: PackFile[],\n generatedBy: string,\n generatedAt?: string,\n): PackArchiveManifest {\n // Step 1: initialize an empty entryDigests map.\n const entryDigests: Record<string, string> = {};\n // Step 2: hash each file.\n for (const file of files) {\n // The envelope is the carrier of these digests — never hash it into itself.\n if (file.path === ENVELOPE_FILENAME) continue;\n // Step 3 (hashEnd): compute sha256(file.contents) and record it under file.path.\n entryDigests[file.path] = sha256(file.contents);\n }\n // Step 4: compute an overall manifest digest over the sorted entryDigests.\n const digest = sha256(canonicalDigestBytes(entryDigests));\n // Step 5: set entryDigests, digest, generatedBy, and generatedAt when one is given.\n const sealed: PackArchiveManifest = { ...manifest, entryDigests, digest, generatedBy };\n if (generatedAt !== undefined) sealed.generatedAt = generatedAt;\n else delete sealed.generatedAt;\n // Step 6: return the sealed manifest.\n return sealed;\n}\n\n/** Whether the archive's formatVersion + minWaironVersion are compatible with `waironVersion`. */\nexport function checkCompatibility(manifest: PackArchiveManifest, waironVersion: string): boolean {\n // Step 1: is the archive format unsupported?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: incompatible.\n return false;\n }\n // Step 2: is the running wairon below the pack's minimum?\n if (manifest.minWaironVersion && isBelow(waironVersion, manifest.minWaironVersion)) {\n // Step 4: incompatible.\n return false;\n }\n // Step 3: compatible.\n return true;\n}\n\n/**\n * Read the inner pack manifest from the inflated files: package.json of a code\n * pack, the envelope's entry (pack.yaml) of a declarative pack. Throws\n * PACK_MANIFEST_INVALID when it is missing, unparseable or not a mapping.\n */\nexport function parseInnerManifest(manifest: PackArchiveManifest, files: readonly PackFile[]): Record<string, unknown> {\n // Step 1: pick the inner manifest's path.\n const innerPath = manifest.kind === 'code' ? 'package.json' : manifest.entry;\n // Step 2: is it missing among the files?\n const inner = files.find((file) => file.path === innerPath);\n if (!inner) {\n throw new PackArchiveError('PACK_MANIFEST_INVALID', `inner pack manifest \"${innerPath}\" is missing`);\n }\n // Step 3: parse it — JSON for package.json, YAML for pack.yaml.\n const text = new TextDecoder().decode(inner.contents);\n let parsed: unknown;\n try {\n parsed = manifest.kind === 'code' ? JSON.parse(text) : yamlLoad(text);\n } catch {\n parsed = undefined;\n }\n // Step 4-5: unparseable or not a mapping — refuse, naming the path.\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new PackArchiveError('PACK_MANIFEST_INVALID', `inner pack manifest \"${innerPath}\" is not a readable mapping`);\n }\n // Step 6: return the mapping as authored.\n return parsed as Record<string, unknown>;\n}\n\n// --- helpers ---------------------------------------------------------------\n\nfunction rejectUnsafe(entryPath: string): never {\n throw new PackArchiveError('UNSAFE_PATH', `unsafe archive entry \"${entryPath}\" (symlink, non-file kind, or an unsafe or escaping path)`);\n}\n\nfunction rejectLimit(what: string): never {\n throw new PackArchiveError('LIMIT_EXCEEDED', `archive over a cap: ${what}`);\n}\n\nfunction invalidEnvelope(message: string): never {\n throw new PackArchiveError('ENVELOPE_INVALID', message);\n}\n\nfunction validateEnvelope(raw: unknown): PackArchiveManifest {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return invalidEnvelope('malformed pack envelope (not a YAML mapping)');\n }\n const o = raw as Record<string, unknown>;\n if (typeof o.formatVersion !== 'number') invalidEnvelope('pack envelope: formatVersion must be a number');\n if (typeof o.name !== 'string' || !o.name) invalidEnvelope('pack envelope: name is required');\n if (typeof o.version !== 'string' || !o.version) invalidEnvelope('pack envelope: version is required');\n if (typeof o.kind !== 'string' || (o.kind !== 'declarative' && o.kind !== 'code')) {\n invalidEnvelope('pack envelope: kind must be \"declarative\" or \"code\"');\n }\n if (typeof o.entry !== 'string' || !o.entry) invalidEnvelope('pack envelope: entry is required');\n // The integrity fields, when present, must be well-typed: an unquoted all-digit digest reads as\n // a YAML number, and skipping it would accept the archive unchecked.\n if (o.digest !== undefined && typeof o.digest !== 'string') {\n invalidEnvelope('pack envelope: digest must be a string (quote an all-digit digest)');\n }\n if (o.entryDigests !== undefined) {\n const digests = o.entryDigests;\n if (!digests || typeof digests !== 'object' || Array.isArray(digests)) {\n invalidEnvelope('pack envelope: entryDigests must be a mapping of path to digest');\n }\n for (const [entryPath, value] of Object.entries(digests as Record<string, unknown>)) {\n if (typeof value !== 'string') invalidEnvelope(`pack envelope: entryDigests[\"${entryPath}\"] must be a string (quote an all-digit digest)`);\n }\n }\n const manifest: PackArchiveManifest = {\n formatVersion: o.formatVersion,\n name: o.name,\n version: o.version,\n kind: o.kind,\n entry: o.entry,\n };\n if (typeof o.minWaironVersion === 'string') manifest.minWaironVersion = o.minWaironVersion;\n if (typeof o.digest === 'string') manifest.digest = o.digest;\n if (o.entryDigests && typeof o.entryDigests === 'object') {\n manifest.entryDigests = o.entryDigests as Record<string, string>;\n }\n if (typeof o.generatedBy === 'string') manifest.generatedBy = o.generatedBy;\n if (typeof o.generatedAt === 'string') manifest.generatedAt = o.generatedAt;\n return manifest;\n}\n\nfunction isSymlinkOrNonRegular(kind: string): boolean {\n return kind !== 'file' && kind !== 'dir';\n}\n\nfunction isStructurallyUnsafePath(p: string): boolean {\n if (p.includes('\\\\')) return true; // backslash\n if (/^[A-Za-z]:/.test(p)) return true; // drive letter\n if (p.startsWith('/')) return true; // absolute POSIX\n return p.split('/').some((seg) => seg === '..'); // parent traversal\n}\n\nfunction normalizeRelPath(p: string): string {\n return p\n .split('/')\n .filter((seg) => seg !== '' && seg !== '.')\n .join('/');\n}\n\nfunction escapesDestination(normalized: string): boolean {\n return normalized.startsWith('/') || normalized.split('/').some((seg) => seg === '..');\n}\n\nfunction pathDepth(normalized: string): number {\n return normalized.split('/').filter((seg) => seg !== '').length;\n}\n\nfunction compressionRatio(entry: ArchiveEntryMeta): number {\n if (entry.compressedSize > 0) return entry.uncompressedSize / entry.compressedSize;\n return entry.uncompressedSize > 0 ? Infinity : 0;\n}\n\nfunction canonicalDigestBytes(entryDigests: Record<string, string>): Uint8Array {\n const lines = Object.keys(entryDigests)\n .sort()\n .map((key) => `${key}:${entryDigests[key]}`)\n .join('\\n');\n return new TextEncoder().encode(lines);\n}\n\nfunction sha256(data: Uint8Array): string {\n return createHash('sha256').update(data).digest('hex');\n}\n\nfunction isBelow(running: string, minimum: string): boolean {\n const [rMaj, rMin, rPat] = parseSemverCore(running);\n const [mMaj, mMin, mPat] = parseSemverCore(minimum);\n if (rMaj !== mMaj) return rMaj < mMaj;\n if (rMin !== mMin) return rMin < mMin;\n return rPat < mPat;\n}\n\nfunction parseSemverCore(v: string): [number, number, number] {\n const cleaned = v.trim().replace(/^[^0-9]*/, ''); // strip leading ^, ~, >=, v, etc.\n const core = cleaned.split(/[-+]/)[0]; // drop prerelease/build metadata\n const parts = core.split('.').map((n) => parseInt(n, 10));\n return [parts[0] || 0, parts[1] || 0, parts[2] || 0];\n}\n","// ---------------------------------------------------------------------------\n// Pack archive errors (pack_archive_error, pack_archive_error_code) — the one\n// error every .wpack reader of the SDK fails with. A caller matches on `code`,\n// never on message text.\n// ---------------------------------------------------------------------------\n\n/** Why a .wpack archive was refused. */\nexport type PackArchiveErrorCode =\n | 'NOT_A_PACK'\n | 'UNSAFE_PATH'\n | 'LIMIT_EXCEEDED'\n | 'ENVELOPE_INVALID'\n | 'FORMAT_VERSION_UNSUPPORTED'\n | 'PACK_MANIFEST_INVALID'\n | 'IDENTITY_MISMATCH'\n | 'DIGEST_MISMATCH';\n\n/** A .wpack archive was refused: a stable `code` beside a human message. */\nexport class PackArchiveError extends Error {\n readonly code: PackArchiveErrorCode;\n\n constructor(code: PackArchiveErrorCode, message: string) {\n super(message);\n this.name = 'PackArchiveError';\n this.code = code;\n Object.setPrototypeOf(this, PackArchiveError.prototype);\n }\n}\n","import { load as yamlLoad, dump as yamlDump } from 'js-yaml';\nimport { createHash } from 'crypto';\nimport type {\n ArchiveEntryMeta,\n PackExtractionLimits,\n PackExtractionPlan,\n PackFile,\n TreeArchiveManifest,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Tree Codec (tree_codec_impl) — PURE format + safety logic for the `.waitree`\n// spec-tree archive, no I/O and no clock.\n//\n// selectTreeFiles is the single portability decision (what belongs in a tree\n// archive at all); planTreeExtraction is the single pre-decompress safety\n// chokepoint; assertPortableTreePaths is the over-the-wire executable guard;\n// sealTreeIntegrity/verifyTreeIntegrity are the produce/verify pair.\n//\n// The small pure path/digest helpers below deliberately mirror the pack codec's\n// rather than importing them: tree_codec declares NO dependencies, and reaching\n// into pack_codec for them would make one codec depend on the other for a\n// handful of one-line functions.\n// ---------------------------------------------------------------------------\n\n/** The tree-archive envelope filename. */\nexport const TREE_ENVELOPE_FILENAME = 'wairon-tree.yaml';\n\n/** The highest tree-archive format major this SDK understands. */\nconst SUPPORTED_FORMAT_VERSION = 1;\n\n/**\n * The tree caps profile: looser than the pack profile on entry count and total\n * size (a real spec tree is thousands of small YAML files across several\n * chained roots) and stricter on nothing.\n */\nconst TREE_DEFAULTS = {\n maxEntries: 20000,\n maxTotalUncompressedBytes: 64 * 1024 * 1024,\n maxEntryBytes: 8 * 1024 * 1024,\n maxCompressionRatio: 100,\n maxDepth: 24,\n} as const;\n\n/** Root-relative directories holding REGENERABLE artifacts — never portable design state. */\nconst DERIVED_ROOTS = ['generated', 'docs'];\n\n/** Executable extensions: a bundled code pack's entry can ride inside a tree. */\nconst EXECUTABLE_EXT_RE = /\\.(c|m)?js$/i;\n\n/** The directory every packed root's content lives under, inside the archive. */\nconst WAI_SEGMENT = '.wai';\n\n/** Parse + validate the envelope text into a TreeArchiveManifest; throws on malformed/newer-major. */\nexport function parseTreeManifest(text: string): TreeArchiveManifest {\n // Step 1: parse the envelope YAML text (throws on malformed YAML).\n const raw = yamlLoad(text);\n // Step 2: validate the required fields are present and well-typed.\n const manifest = validateEnvelope(raw);\n // Step 3: is the format major newer than this wairon supports?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: fail loudly rather than silently mis-read a newer format.\n throw new Error('unsupported tree-archive formatVersion (newer than this wairon understands)');\n }\n // Step 5: return the parsed manifest.\n return manifest;\n}\n\n/** Serialize a manifest to canonical wairon-tree.yaml text (export path). */\nexport function serializeTreeManifest(manifest: TreeArchiveManifest): string {\n // Step 1: drop undefined optional fields for a clean, canonical envelope.\n const clean: Record<string, unknown> = {\n formatVersion: manifest.formatVersion,\n projectName: manifest.projectName,\n roots: manifest.roots,\n };\n if (manifest.stateId !== undefined) clean.stateId = manifest.stateId;\n if (manifest.waironVersion !== undefined) clean.waironVersion = manifest.waironVersion;\n if (manifest.minWaironVersion !== undefined) clean.minWaironVersion = manifest.minWaironVersion;\n if (manifest.includesDerived !== undefined) clean.includesDerived = manifest.includesDerived;\n if (manifest.digest !== undefined) clean.digest = manifest.digest;\n if (manifest.entryDigests !== undefined) clean.entryDigests = manifest.entryDigests;\n if (manifest.generatedBy !== undefined) clean.generatedBy = manifest.generatedBy;\n if (manifest.generatedAt !== undefined) clean.generatedAt = manifest.generatedAt;\n // Step 2: return the wairon-tree.yaml text.\n return yamlDump(clean, { sortKeys: false });\n}\n\n/** The tree extraction-safety profile; callers override individual caps. */\nexport function defaultTreeLimits(): PackExtractionLimits {\n // Step 1: return the tree caps profile.\n return { ...TREE_DEFAULTS };\n}\n\n/**\n * Decide which of a root's files are portable design state: keep authored spec\n * state, drop regenerable artifacts unless the caller asked for them. Paths are\n * relative to the root's `.wai/` directory.\n */\nexport function selectTreeFiles(files: PackFile[], includeDerived: boolean): PackFile[] {\n // Step 1: did the caller ask for regenerable artifacts too?\n if (includeDerived) {\n // Step 2: return the file map unchanged — an explicit full-fidelity archive.\n return files;\n }\n // Step 3: drop every file under a regenerable root — a moved tree carries the\n // design, not its rendered output, which the destination regenerates.\n const kept = files.filter((file) => !isDerivedPath(file.path));\n // Step 4: return the portable design state.\n return kept;\n}\n\n/** Compute the safe extraction plan from enumerated entries under `limits`, or throw. */\nexport function planTreeExtraction(entries: ArchiveEntryMeta[], limits: PackExtractionLimits): PackExtractionPlan {\n // Step 1: resolve effective caps — each field of `limits` over the tree defaults.\n const caps = {\n maxEntries: limits.maxEntries ?? TREE_DEFAULTS.maxEntries,\n maxTotalUncompressedBytes: limits.maxTotalUncompressedBytes ?? TREE_DEFAULTS.maxTotalUncompressedBytes,\n maxEntryBytes: limits.maxEntryBytes ?? TREE_DEFAULTS.maxEntryBytes,\n maxCompressionRatio: limits.maxCompressionRatio ?? TREE_DEFAULTS.maxCompressionRatio,\n maxDepth: limits.maxDepth ?? TREE_DEFAULTS.maxDepth,\n };\n // Step 2: initialize an empty approved-path list and a running total of 0.\n const approved: string[] = [];\n let total = 0;\n // Step 3: vet each enumerated entry.\n for (const entry of entries) {\n // Step 4: reject symlinks/non-regular entries and structurally unsafe paths.\n if (isSymlinkOrNonRegular(entry.kind) || isStructurallyUnsafePath(entry.path)) {\n rejectUnsafe();\n }\n // Directory entries are structural (writeTree recreates them from file\n // paths) — skip without approving, never inflate a 0-byte dir marker.\n if (entry.kind === 'dir') continue;\n // Step 5: normalize the entry path to a destination-relative POSIX path.\n const normalized = normalizeRelPath(entry.path);\n // Step 6: reject zip-slip and over-deep paths.\n if (escapesDestination(normalized) || pathDepth(normalized) > caps.maxDepth) {\n rejectUnsafe();\n }\n // Step 7: reject oversized entries and zip bombs.\n if (entry.uncompressedSize > caps.maxEntryBytes || compressionRatio(entry) > caps.maxCompressionRatio) {\n rejectUnsafe();\n }\n // Step 8 (vetEnd): accept — append the path and add its inflated size.\n approved.push(normalized);\n total += entry.uncompressedSize;\n }\n // Step 9: reject archives exceeding the aggregate caps.\n if (approved.length > caps.maxEntries || total > caps.maxTotalUncompressedBytes) {\n rejectUnsafe();\n }\n // Step 11: return the approved plan.\n return { paths: approved, totalUncompressedBytes: total };\n}\n\n/**\n * Assert the planned paths carry no executable content and nothing outside a\n * spec-tree root. Called by any surface accepting an archive over the wire; a\n * local extraction on the developer's own machine may skip it.\n */\nexport function assertPortableTreePaths(paths: string[]): void {\n // Step 1: check each planned path.\n for (const entryPath of paths) {\n // Step 2: is this an executable file (a bundled code pack's entry)?\n if (EXECUTABLE_EXT_RE.test(entryPath)) {\n // Step 6 (rejectExecutable): same guidance the pack surface gives.\n throw new Error(\n 'refused: the archive carries executable content. Only declarative spec state transfers over this ' +\n 'surface; rule/code packs are executable and install via the trusted filesystem (mount into ' +\n 'WAIRON_PACKS_DIR, or run `wairon packs add`).',\n );\n }\n // Step 3: does the path sit outside any recognized spec-tree root?\n if (entryPath !== TREE_ENVELOPE_FILENAME && !isUnderWaiRoot(entryPath)) {\n // Step 7 (rejectForeign): a tree archive carries .wai trees, never arbitrary project files.\n throw new Error(`refused: the archive carries an entry outside any spec-tree root (\"${entryPath}\")`);\n }\n // Step 4 (checkEnd): this path is portable spec-tree content.\n }\n // Step 5: every path is portable.\n}\n\n/** Verify every entry's sha256 against entryDigests; false when none carried, throws on mismatch. */\nexport function verifyTreeIntegrity(manifest: TreeArchiveManifest, files: PackFile[]): boolean {\n // Step 1: did the envelope carry no integrity data?\n if (!manifest.entryDigests) {\n // Step 2: no integrity data present — return false.\n return false;\n }\n const digests = manifest.entryDigests;\n // Step 3: check each file's digest.\n for (const file of files) {\n // The envelope carries these digests and cannot digest itself — skip it.\n if (file.path === TREE_ENVELOPE_FILENAME) continue;\n // Step 4: does the recomputed sha256 differ from the recorded digest?\n if (sha256(file.contents) !== digests[file.path]) {\n // Step 7: a digest mismatch means tampering.\n throw new Error('tree integrity digest mismatch');\n }\n // Step 5 (checkEnd): this file's digest matches.\n }\n // Step 6: all digests matched — return true.\n return true;\n}\n\n/** Produce-side partner of verifyTreeIntegrity: fill entryDigests + digest + stamps. */\nexport function sealTreeIntegrity(\n manifest: TreeArchiveManifest,\n files: PackFile[],\n generatedBy: string,\n generatedAt: string,\n): TreeArchiveManifest {\n // Step 1: initialize an empty entryDigests map.\n const entryDigests: Record<string, string> = {};\n // Step 2: hash each file.\n for (const file of files) {\n // The envelope is the carrier of these digests — never hash it into itself.\n if (file.path === TREE_ENVELOPE_FILENAME) continue;\n // Step 3 (hashEnd): compute sha256(file.contents) and record it under file.path.\n entryDigests[file.path] = sha256(file.contents);\n }\n // Step 4: compute an overall manifest digest over the sorted entryDigests.\n const digest = sha256(canonicalDigestBytes(entryDigests));\n // Step 5: set entryDigests, digest, generatedBy, generatedAt.\n // Step 6: return the sealed manifest.\n return { ...manifest, entryDigests, digest, generatedBy, generatedAt };\n}\n\n/** Whether the archive's formatVersion + minWaironVersion are compatible with `waironVersion`. */\nexport function checkTreeCompatibility(manifest: TreeArchiveManifest, waironVersion: string): boolean {\n // Step 1: is the archive format unsupported?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: incompatible.\n return false;\n }\n // Step 2: is the running wairon below the archive's minimum?\n if (manifest.minWaironVersion && isBelow(waironVersion, manifest.minWaironVersion)) {\n // Step 4: incompatible.\n return false;\n }\n // Step 3: compatible.\n return true;\n}\n\n// --- helpers ---------------------------------------------------------------\n\nfunction rejectUnsafe(): never {\n throw new Error('reject: unsafe or oversized tree-archive entry (zip-slip / size / ratio / depth guard)');\n}\n\nfunction validateEnvelope(raw: unknown): TreeArchiveManifest {\n if (!raw || typeof raw !== 'object') {\n throw new Error('malformed tree envelope (not a YAML mapping)');\n }\n const o = raw as Record<string, unknown>;\n if (typeof o.formatVersion !== 'number') throw new Error('tree envelope: formatVersion must be a number');\n if (typeof o.projectName !== 'string' || !o.projectName) throw new Error('tree envelope: projectName is required');\n if (!Array.isArray(o.roots) || o.roots.length === 0 || o.roots.some((r) => typeof r !== 'string' || !r)) {\n throw new Error('tree envelope: roots must be a non-empty list of project-relative directories');\n }\n const manifest: TreeArchiveManifest = {\n formatVersion: o.formatVersion,\n projectName: o.projectName,\n roots: o.roots as string[],\n };\n if (typeof o.stateId === 'string') manifest.stateId = o.stateId;\n if (typeof o.waironVersion === 'string') manifest.waironVersion = o.waironVersion;\n if (typeof o.minWaironVersion === 'string') manifest.minWaironVersion = o.minWaironVersion;\n if (typeof o.includesDerived === 'boolean') manifest.includesDerived = o.includesDerived;\n if (typeof o.digest === 'string') manifest.digest = o.digest;\n if (o.entryDigests && typeof o.entryDigests === 'object') {\n manifest.entryDigests = o.entryDigests as Record<string, string>;\n }\n if (typeof o.generatedBy === 'string') manifest.generatedBy = o.generatedBy;\n if (typeof o.generatedAt === 'string') manifest.generatedAt = o.generatedAt;\n return manifest;\n}\n\n/** True for a path under a regenerable root, relative to a root's .wai/ directory. */\nfunction isDerivedPath(relPath: string): boolean {\n const first = relPath.split('/')[0];\n return DERIVED_ROOTS.includes(first);\n}\n\n/** True when an archive path lives under some root's .wai/ directory. */\nfunction isUnderWaiRoot(archivePath: string): boolean {\n const segments = archivePath.split('/');\n // The .wai segment must exist AND carry content beneath it — a bare '.wai'\n // entry names a directory, not spec-tree state.\n const at = segments.indexOf(WAI_SEGMENT);\n return at >= 0 && at < segments.length - 1;\n}\n\nfunction isSymlinkOrNonRegular(kind: string): boolean {\n return kind !== 'file' && kind !== 'dir';\n}\n\nfunction isStructurallyUnsafePath(p: string): boolean {\n if (p.includes('\\\\')) return true; // backslash\n if (/^[A-Za-z]:/.test(p)) return true; // drive letter\n if (p.startsWith('/')) return true; // absolute POSIX\n return p.split('/').some((seg) => seg === '..'); // parent traversal\n}\n\nfunction normalizeRelPath(p: string): string {\n return p\n .split('/')\n .filter((seg) => seg !== '' && seg !== '.')\n .join('/');\n}\n\nfunction escapesDestination(normalized: string): boolean {\n return normalized.startsWith('/') || normalized.split('/').some((seg) => seg === '..');\n}\n\nfunction pathDepth(normalized: string): number {\n return normalized.split('/').filter((seg) => seg !== '').length;\n}\n\nfunction compressionRatio(entry: ArchiveEntryMeta): number {\n if (entry.compressedSize > 0) return entry.uncompressedSize / entry.compressedSize;\n return entry.uncompressedSize > 0 ? Infinity : 0;\n}\n\nfunction canonicalDigestBytes(entryDigests: Record<string, string>): Uint8Array {\n const lines = Object.keys(entryDigests)\n .sort()\n .map((key) => `${key}:${entryDigests[key]}`)\n .join('\\n');\n return new TextEncoder().encode(lines);\n}\n\nfunction sha256(data: Uint8Array): string {\n return createHash('sha256').update(data).digest('hex');\n}\n\nfunction isBelow(running: string, minimum: string): boolean {\n const [rMaj, rMin, rPat] = parseSemverCore(running);\n const [mMaj, mMin, mPat] = parseSemverCore(minimum);\n if (rMaj !== mMaj) return rMaj < mMaj;\n if (rMin !== mMin) return rMin < mMin;\n return rPat < mPat;\n}\n\nfunction parseSemverCore(v: string): [number, number, number] {\n const cleaned = v.trim().replace(/^[^0-9]*/, ''); // strip leading ^, ~, >=, v, etc.\n const core = cleaned.split(/[-+]/)[0]; // drop prerelease/build metadata\n const parts = core.split('.').map((n) => parseInt(n, 10));\n return [parts[0] || 0, parts[1] || 0, parts[2] || 0];\n}\n","// The running @wairon/sdk version — stamped into built archives (generatedBy)\n// and used as the \"running wairon version\" for pack version-compatibility\n// checks. tsup inlines package.json at build time; at runtime the require\n// resolves against the shipped package (../package.json from dist/).\n\nexport const SDK_VERSION: string = loadVersion();\n\nfunction loadVersion(): string {\n try {\n const pkg = require('../package.json') as { version?: string };\n return pkg.version ?? '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n","import type { PackFile, PackScaffoldRequest } from './types.js';\nimport { SDK_VERSION } from './version.js';\n\n// ---------------------------------------------------------------------------\n// Pack Scaffold (pack_scaffold_impl) — PURE template rendering for\n// `wairon pack init`. Produces an in-memory file map; writes nothing. Code\n// packs pin @wairon/sdk to the running SDK version.\n// ---------------------------------------------------------------------------\n\nconst enc = (s: string): Uint8Array => new TextEncoder().encode(s);\n\n/** Render the scaffold file map for the requested pack (declarative or code). */\nexport function render(request: PackScaffoldRequest): PackFile[] {\n const version = request.version ?? '0.1.0';\n let files: PackFile[];\n // Step 1: which variant?\n if (request.kind === 'code') {\n // Step 2: render the code-pack file map.\n files = renderCodePack(request.name, version);\n // Step 3: skip the declarative variant (fall through to the skill gate).\n } else {\n // Step 4 (declVariant): render the declarative-pack file map.\n files = renderDeclarativePack(request.name, version);\n }\n // Step 5 (skillGate): include a skill stub?\n if (request.withSkill) {\n // Step 6: append a skills/<id>/SKILL.md stub to the file map.\n files.push(renderSkillStub(request.name, version));\n }\n // Step 7 (done): return the rendered file map.\n return files;\n}\n\n// --- variant renderers -----------------------------------------------------\n\nfunction renderDeclarativePack(name: string, version: string): PackFile[] {\n return [\n { path: 'wairon-pack.yaml', contents: enc(declarativeEnvelope(name, version)) },\n { path: 'pack.yaml', contents: enc(declarativeManifest(name, version)) },\n { path: 'README.md', contents: enc(readme(name, 'declarative', 'pack.yaml')) },\n ];\n}\n\nfunction renderCodePack(name: string, version: string): PackFile[] {\n return [\n { path: 'wairon-pack.yaml', contents: enc(codeEnvelope(name, version)) },\n { path: 'package.json', contents: enc(codePackageJson(name, version)) },\n { path: 'tsconfig.json', contents: enc(codeTsconfig()) },\n { path: 'pack.ts', contents: enc(codeEntry(name, version)) },\n { path: 'README.md', contents: enc(readme(name, 'code', 'pack.cjs')) },\n ];\n}\n\nfunction renderSkillStub(name: string, _version: string): PackFile {\n const id = slug(name);\n return { path: `skills/${id}/SKILL.md`, contents: enc(skillStub(name)) };\n}\n\n// --- templates -------------------------------------------------------------\n\nfunction declarativeEnvelope(name: string, version: string): string {\n return [\n 'formatVersion: 1',\n `name: ${name}`,\n `version: ${version}`,\n 'kind: declarative',\n 'entry: pack.yaml',\n '',\n ].join('\\n');\n}\n\n/** A version's release core (major.minor.patch): a pre-release never becomes a minimum. */\nfunction releaseCore(version: string): string {\n return version.split(/[-+]/)[0];\n}\n\nfunction codeEnvelope(name: string, version: string): string {\n return [\n 'formatVersion: 1',\n `name: ${name}`,\n `version: ${version}`,\n 'kind: code',\n 'entry: pack.cjs',\n `minWaironVersion: ${releaseCore(SDK_VERSION)}`,\n '',\n ].join('\\n');\n}\n\nfunction declarativeManifest(name: string, version: string): string {\n return [\n `name: ${name}`,\n `version: ${version}`,\n '',\n '# Custom architectural profiles this pack contributes (example, commented):',\n '# profiles:',\n '# my-profile:',\n '# family: backend-like',\n '# forbiddenStereotypes:',\n '# - types: [Adapter]',\n '# reason: \"Domain components must not touch adapters directly.\"',\n 'profiles: {}',\n '',\n '# Target language / platform tables (example, commented):',\n '# languages:',\n '# rust:',\n '# unsupportedFlow: {}',\n 'languages: {}',\n '',\n '# Reusable, versioned architecture patterns:',\n 'patterns: []',\n '',\n ].join('\\n');\n}\n\nfunction codePackageJson(name: string, version: string): string {\n const pkg = {\n name,\n version,\n private: true,\n scripts: {\n build: 'esbuild pack.ts --bundle --platform=node --packages=external --format=cjs --outfile=pack.cjs',\n },\n dependencies: {\n '@wairon/sdk': SDK_VERSION,\n },\n devDependencies: {\n esbuild: '^0.21.0',\n typescript: '^5.0.0',\n },\n };\n return `${JSON.stringify(pkg, null, 2)}\\n`;\n}\n\nfunction codeTsconfig(): string {\n const tsconfig = {\n compilerOptions: {\n target: 'ES2020',\n module: 'CommonJS',\n moduleResolution: 'node',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: false,\n noEmit: true,\n },\n include: ['pack.ts'],\n };\n return `${JSON.stringify(tsconfig, null, 2)}\\n`;\n}\n\nfunction codeEntry(name: string, version: string): string {\n const code = slug(name).toUpperCase().replace(/-/g, '_');\n return [\n \"import { defineRule } from '@wairon/sdk';\",\n \"import type { RuleContext, Finding } from '@wairon/sdk';\",\n '',\n 'const exampleRule = defineRule({',\n ` name: '${slug(name)}-example',`,\n \" description: 'Example architectural rule. Replace with your own doctrine.',\",\n ` codes: ['${code}_EXAMPLE'],`,\n ' check(ctx: RuleContext): Finding[] {',\n ' const findings: Finding[] = [];',\n ' for (const component of ctx.components) {',\n ' // Inspect the spec tree and push findings as needed.',\n ' void component;',\n ' }',\n ' return findings;',\n ' },',\n '});',\n '',\n 'export default {',\n ` name: '${name}',`,\n ` version: '${version}',`,\n ' rules: [exampleRule],',\n '};',\n '',\n ].join('\\n');\n}\n\nfunction readme(name: string, kind: string, entry: string): string {\n return [\n `# ${name}`,\n '',\n `A wairon ${kind} pack.`,\n '',\n `- Envelope: \\`wairon-pack.yaml\\``,\n `- Entry: \\`${entry}\\``,\n '',\n 'Build an installable `.wpack` archive with `wairon pack build`.',\n '',\n ].join('\\n');\n}\n\nfunction skillStub(name: string): string {\n return [\n '---',\n `name: ${name}`,\n `description: ${name} authoring skill (stub).`,\n '---',\n '',\n `# ${name}`,\n '',\n 'Describe when this skill applies and what it guides.',\n '',\n ].join('\\n');\n}\n\nfunction slug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { zipSync, unzipSync, type Zippable } from 'fflate';\nimport type { ArchiveEntryMeta, PackFile } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Pack Archive Adapter (pack_archive_adapter_impl) — the ONLY zip-library + fs\n// I/O boundary of the SDK. Technology: fflate (pure-JS ZIP, no native deps).\n//\n// Acts only on already-validated inputs: it makes no path-safety or format\n// decisions (that is the codec's job). Enumeration reads sizes WITHOUT\n// inflating so the codec can enforce zip-bomb / size caps before any bytes are\n// decompressed.\n// ---------------------------------------------------------------------------\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', '.hg', '.svn']);\n\n/**\n * Enumerate every entry's metadata (path, compressed + uncompressed size, kind)\n * WITHOUT decompressing any bytes, so the codec can enforce caps before\n * inflation.\n */\nexport function listEntries(archive: Uint8Array): ArchiveEntryMeta[] {\n // Step 1: read the central directory via the zip library, mapping each record\n // to ArchiveEntryMeta without inflating any data. fflate's filter reports\n // {name, size (compressed), originalSize (uncompressed)} for every entry;\n // returning false skips decompression. Symlink detection reads the central\n // directory's external attributes (fflate's metadata omits the unix mode).\n const symlinks = detectSymlinkNames(archive);\n const metas: ArchiveEntryMeta[] = [];\n unzipSync(archive, {\n filter: (info): boolean => {\n metas.push({\n path: info.name,\n uncompressedSize: info.originalSize,\n compressedSize: info.size,\n kind: classifyKind(info.name, symlinks),\n });\n return false;\n },\n });\n // Step 2: return the entry metadata list.\n return metas;\n}\n\n/** Decompress and return the bytes of a single named entry. */\nexport function inflateEntry(archive: Uint8Array, entryPath: string): Uint8Array {\n // Step 1: locate the named entry and inflate only it.\n const inflated = unzipSync(archive, { filter: (info): boolean => info.name === entryPath });\n const bytes = inflated[entryPath];\n if (!bytes) throw new Error(`archive entry not found: ${entryPath}`);\n // Step 2: return the entry's decompressed bytes.\n return bytes;\n}\n\n/** Deflate a set of files (the envelope + pack contents) into a single ZIP buffer. */\nexport function assembleArchive(files: PackFile[]): Uint8Array {\n // Step 1: add each file to a zip container (deflating) and finalize.\n const zippable: Zippable = {};\n for (const file of files) zippable[file.path] = file.contents;\n const bytes = zipSync(zippable);\n // Step 2: return the archive bytes.\n return bytes;\n}\n\n/** Read a source pack directory recursively into a file map (POSIX paths + bytes). */\nexport function readPackDir(dir: string): PackFile[] {\n // Step 1: walk the directory recursively, reading each file into\n // { path: POSIX-relative, contents } (skipping node_modules and VCS dirs).\n const files: PackFile[] = [];\n walkPackDir(dir, dir, files);\n // Step 2: return the file map.\n return files;\n}\n\n/** Write a file map as a directory tree under destDir, creating parent directories. */\nexport function writeTree(destDir: string, files: PackFile[]): void {\n // Step 1: write each approved file.\n for (const file of files) {\n // Step 2 (writeEnd): create parent directories and write the file's bytes.\n const absolute = path.join(destDir, file.path);\n fs.mkdirSync(path.dirname(absolute), { recursive: true });\n fs.writeFileSync(absolute, file.contents);\n }\n // Step 3: done.\n}\n\n// --- helpers ---------------------------------------------------------------\n\nfunction classifyKind(name: string, symlinks: Set<string>): string {\n if (symlinks.has(name)) return 'symlink';\n if (name.endsWith('/')) return 'dir';\n return 'file';\n}\n\nfunction walkPackDir(root: string, current: string, out: PackFile[]): void {\n for (const entry of fs.readdirSync(current, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) continue;\n walkPackDir(root, path.join(current, entry.name), out);\n } else if (entry.isFile()) {\n const absolute = path.join(current, entry.name);\n const relative = path.relative(root, absolute).split(path.sep).join('/');\n out.push({ path: relative, contents: fs.readFileSync(absolute) });\n }\n }\n}\n\n// Best-effort central-directory scan for symlink entries (unix S_IFLNK in the\n// external file attributes). fflate's high-level metadata omits the unix mode,\n// so the codec's symlink rejection needs this. Any parse trouble yields an\n// empty set — no worse than fflate alone, and confinement/size caps still apply.\nfunction detectSymlinkNames(archive: Uint8Array): Set<string> {\n const names = new Set<string>();\n try {\n const eocd = findEocd(archive);\n if (eocd < 0) return names;\n let p = readU32(archive, eocd + 16); // central directory offset\n const count = readU16(archive, eocd + 10);\n const decoder = new TextDecoder();\n for (let i = 0; i < count; i++) {\n if (readU32(archive, p) !== 0x02014b50) break; // central file header sig\n const versionMadeBy = readU16(archive, p + 4);\n const nameLen = readU16(archive, p + 28);\n const extraLen = readU16(archive, p + 30);\n const commentLen = readU16(archive, p + 32);\n const externalAttrs = readU32(archive, p + 38);\n const name = decoder.decode(archive.subarray(p + 46, p + 46 + nameLen));\n if ((versionMadeBy >> 8) === 3) { // unix host\n const unixMode = (externalAttrs >>> 16) & 0xffff;\n if ((unixMode & 0o170000) === 0o120000) names.add(name);\n }\n p += 46 + nameLen + extraLen + commentLen;\n }\n } catch {\n return names;\n }\n return names;\n}\n\nfunction findEocd(buf: Uint8Array): number {\n const minRecord = 22;\n const lowerBound = Math.max(0, buf.length - (minRecord + 0xffff));\n for (let i = buf.length - minRecord; i >= lowerBound; i--) {\n if (readU32(buf, i) === 0x06054b50) return i;\n }\n return -1;\n}\n\nfunction readU16(buf: Uint8Array, off: number): number {\n return buf[off] | (buf[off + 1] << 8);\n}\n\nfunction readU32(buf: Uint8Array, off: number): number {\n return (buf[off] | (buf[off + 1] << 8) | (buf[off + 2] << 16) | (buf[off + 3] << 24)) >>> 0;\n}\n","// ---------------------------------------------------------------------------\n// Rule-authoring contract (the code-pack compile target).\n//\n// Code packs are written against `@wairon/sdk`, never against wairon core. This\n// is a small, stable, hand-authored facade — deliberately NOT core's fat\n// RuleContext. `defineRule` returns the rule unchanged (identity + type\n// inference); the runtime shape `{ name, description?, codes: string[], check }`\n// is exactly what the core extension loader duck-types.\n// ---------------------------------------------------------------------------\n\n/** Severity of a finding a pack rule emits. */\nexport type RuleSeverity = 'error' | 'warning';\n\n/** A single issue a pack rule reports about the spec tree. */\nexport interface Finding {\n /** Pack-local issue code (surfaced namespaced by wairon, e.g. `<PACK>_<CODE>`). */\n code: string;\n /** 'error' | 'warning'. */\n severity: RuleSeverity;\n /** Human-readable explanation of the violation. */\n message: string;\n /** The spec id the finding is anchored to (optional). */\n specId?: string;\n}\n\n/**\n * A read-only spec node as seen by a pack rule: its id/name plus arbitrary\n * further fields (kept open so the facade stays stable as the spec model grows).\n */\nexport interface RuleSpecNode {\n id: string;\n name?: string;\n [key: string]: unknown;\n}\n\n/**\n * The minimal, stable view of the spec tree a code-pack rule inspects. A rule\n * reads these collections and returns findings — it never mutates state and\n * never reaches into wairon core internals.\n */\nexport interface RuleContext {\n /** The L0 system spec. */\n system: RuleSpecNode;\n /** All L1 subsystem specs. */\n subsystems: RuleSpecNode[];\n /** All L2 component specs. */\n components: RuleSpecNode[];\n /** All L3 interface specs. */\n interfaces: RuleSpecNode[];\n /** All L4 implementation specs. */\n implementations: RuleSpecNode[];\n /** All shared type/value-object specs. */\n types: RuleSpecNode[];\n}\n\n/**\n * A programmatic conformance rule shipped by a code pack. Its runtime shape —\n * `{ name, description?, codes: string[], check }` — is what wairon's extension\n * loader duck-types when it loads a `pack.cjs`.\n */\nexport interface SddRule {\n /** Stable rule id (kebab-case), e.g. \"my-portal-transport\". */\n name: string;\n /** One-line description of what the rule enforces and why. */\n description?: string;\n /** The issue codes this rule can emit. */\n codes: string[];\n /** Inspect the spec tree and return findings (empty when clean). */\n check(ctx: RuleContext): Finding[];\n}\n\n/**\n * Author an SddRule with full type inference. Returns the rule unchanged — it\n * exists purely so code packs get typed authoring without importing anything\n * from wairon core.\n */\nexport function defineRule(rule: SddRule): SddRule {\n return rule;\n}\n"],"mappings":"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","names":["exports","module","buildPack","buildTreeArchive","extractPack","extractTreeArchive","inspectArchive","inspectTreeArchive","readPack","scaffoldPack","path","import_js_yaml","yamlLoad","yamlDump","path","import_js_yaml","import_crypto","SUPPORTED_FORMAT_VERSION","yamlLoad","validateEnvelope","yamlDump","isSymlinkOrNonRegular","isStructurallyUnsafePath","rejectUnsafe","normalizeRelPath","escapesDestination","pathDepth","compressionRatio","sha256","canonicalDigestBytes","isBelow","parseSemverCore","relative","slug","yamlLoad","scaffoldPack","buildPack","inspectArchive","readPack","extractPack","buildTreeArchive","inspectTreeArchive","extractTreeArchive"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/index.ts","../src/orchestrator.ts","../src/codec.ts","../src/errors.ts","../src/treecodec.ts","../src/version.ts","../src/scaffold.ts","../src/archive.ts","../src/authoring.ts"],"sourcesContent":["{\n \"name\": \"@wairon/sdk\",\n \"version\": \"6.7.4-dev.8\",\n \"description\": \"Experimental: wairon pack-archive (.wpack) format authority and authoring toolkit — scaffold, build, inspect, and safely extract wairon extension packs.\",\n \"keywords\": [\n \"wairon\",\n \"sdd\",\n \"pack\",\n \"wpack\",\n \"archive\",\n \"developer-tools\",\n \"experimental\"\n ],\n \"author\": \"SYW\",\n \"license\": \"MIT\",\n \"homepage\": \"https://github.com/SYW-Apps/Waffle-AIron\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/SYW-Apps/Waffle-AIron.git\"\n },\n \"type\": \"commonjs\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"dist\",\n \"README.md\"\n ],\n \"engines\": {\n \"node\": \"^22.23.4 || ^24.22.1 || >=26.12.1\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"clean\": \"rimraf dist\"\n },\n \"dependencies\": {\n \"fflate\": \"^0.8.2\",\n \"js-yaml\": \"^4.3.2\"\n },\n \"devDependencies\": {\n \"@types/js-yaml\": \"^4.0.9\",\n \"@types/node\": \"^20.14.0\",\n \"rimraf\": \"^5.0.7\",\n \"tsup\": \"^8.1.0\",\n \"typescript\": \"^5.5.2\",\n \"vitest\": \"^4.1.9\"\n }\n}\n","import * as orchestrator from './orchestrator.js';\nimport * as codec from './codec.js';\nimport type {\n PackArchiveInfo,\n PackBuildResult,\n PackContents,\n PackExtractionLimits,\n PackExtractionResult,\n PackFile,\n PackScaffoldRequest,\n TreeArchiveInfo,\n TreeBuildResult,\n TreeExtractionResult,\n TreeRootSource,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// SDK Portal (sdk_portal_impl) — the @wairon/sdk package entry. Each capability\n// is a 1:1 forward to the SDK orchestrator with no logic of its own; the module\n// also re-exports the pure pack-authoring value objects and the rule-authoring\n// contract (compile-time types + the defineRule helper).\n// ---------------------------------------------------------------------------\n\n/** Scaffold a new pack project (declarative or code) into a directory; returns the created file paths. */\nexport function scaffoldPack(request: PackScaffoldRequest): string[] {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.scaffoldPack(request);\n}\n\n/** Build an installable .wpack archive from a pack directory. */\nexport function buildPack(sourceDir: string): PackBuildResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.buildPack(sourceDir);\n}\n\n/**\n * A pack's content integrity (`sha256-<hex>`) over its files as extracted —\n * the digest project.yaml pins and a registry publishes, one implementation\n * for every consumer.\n */\nexport function packContentDigest(files: readonly PackFile[]): string {\n // Step 1: forward to the pack codec.\n return codec.contentDigest(files);\n}\n\n/** Inspect + verify a .wpack archive without extracting it. */\nexport function inspectArchive(archive: Uint8Array, limits?: PackExtractionLimits): PackArchiveInfo {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.inspectArchive(archive, limits);\n}\n\n/** Read a .wpack archive in memory under the extraction guards; nothing is written. */\nexport function readPack(archive: Uint8Array, limits?: PackExtractionLimits): PackContents {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.readPack(archive, limits);\n}\n\n/** Safely extract a .wpack archive into a destination directory under enforced limits. */\nexport function extractPack(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n): PackExtractionResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.extractPack(archive, destDir, limits);\n}\n\n/** Pack a project's spec tree — the supplied roots' .wai directories — into a .waitree archive. */\nexport function buildTreeArchive(\n roots: TreeRootSource[],\n projectName: string,\n stateId?: string,\n includeDerived?: boolean,\n): TreeBuildResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.buildTreeArchive(roots, projectName, stateId, includeDerived);\n}\n\n/** Inspect a .waitree archive without extracting it. */\nexport function inspectTreeArchive(archive: Uint8Array): TreeArchiveInfo {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.inspectTreeArchive(archive);\n}\n\n/** Safely extract a .waitree archive into a destination project root under enforced limits. */\nexport function extractTreeArchive(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n refuseExecutableEntries?: boolean,\n): TreeExtractionResult {\n // Step 1: forward to the SDK orchestrator.\n return orchestrator.extractTreeArchive(archive, destDir, limits, refuseExecutableEntries);\n}\n\n// Re-export the pure pack-archive value objects...\nexport * from './types.js';\n// ...and the rule-authoring contract (SddRule + stable RuleContext/Finding facade + defineRule).\nexport * from './authoring.js';\n// ...and the one error every .wpack reader fails with, plus its code union.\nexport { PackArchiveError } from './errors.js';\nexport type { PackArchiveErrorCode } from './errors.js';\n","import * as path from 'path';\nimport { load as yamlLoad } from 'js-yaml';\nimport * as codec from './codec.js';\nimport * as treecodec from './treecodec.js';\nimport * as scaffold from './scaffold.js';\nimport * as packArchive from './archive.js';\nimport { SDK_VERSION } from './version.js';\nimport { PackArchiveError } from './errors.js';\nimport type {\n ArchiveEntryMeta,\n PackArchiveInfo,\n PackArchiveManifest,\n PackBuildResult,\n PackContents,\n PackExtractionLimits,\n PackExtractionResult,\n PackFile,\n PackScaffoldRequest,\n TreeArchiveInfo,\n TreeArchiveManifest,\n TreeBuildResult,\n TreeExtractionResult,\n TreeRootSource,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// SDK Orchestrator (sdk_orchestrator_impl) — the four pack workflows and the\n// three spec-tree archive workflows. Delegates format/safety decisions to the\n// codecs, template rendering to the pack scaffold, and all zip+fs I/O to\n// the archive adapter. Holds no state.\n//\n// Root DISCOVERY stays with the caller: the SDK never walks a spec tree, it\n// only archives the roots it is handed.\n// ---------------------------------------------------------------------------\n\nconst decode = (b: Uint8Array): string => new TextDecoder().decode(b);\nconst encode = (s: string): Uint8Array => new TextEncoder().encode(s);\n\n/** Render the scaffold file map and write it under the target directory. */\nexport function scaffoldPack(request: PackScaffoldRequest): string[] {\n // Step 1: render the scaffold file map for the requested pack.\n const files = scaffold.render(request);\n // Step 2: write the rendered files as a directory tree under targetDir.\n packArchive.writeTree(request.targetDir, files);\n // Step 3: return the created file paths (targetDir-joined).\n return files.map((file) => path.join(request.targetDir, file.path));\n}\n\n/** Build an installable .wpack archive from a pack directory. */\nexport function buildPack(sourceDir: string): PackBuildResult {\n // Step 1: read the source pack directory into a file map.\n const files = packArchive.readPackDir(sourceDir);\n // Step 2: require an envelope.\n const envelope = files.find((file) => file.path === codec.ENVELOPE_FILENAME);\n if (!envelope) {\n // Step 3: reject a pack directory with no envelope.\n throw new Error('pack build requires a wairon-pack.yaml envelope (run `wairon pack init` to scaffold one)');\n }\n // Step 4 (parse): parse + validate the envelope (also version-gates the format).\n const manifest = codec.parseManifest(decode(envelope.contents));\n // Step 5: read the inner pack identity (pack.yaml, or package.json for code).\n const identity = readInnerIdentity(files, manifest);\n // Step 6: assert the envelope's name/version match the inner pack manifest.\n codec.verifyIdentity(manifest, identity.name, identity.version);\n // Step 7: seal integrity (entryDigests + digest + generatedBy) with no build time,\n // so the same content always builds the same archive and content digest.\n const sealed = codec.sealIntegrity(manifest, files, `@wairon/sdk@${SDK_VERSION}`);\n // Step 8: serialize the sealed manifest back to canonical envelope text.\n const sealedText = codec.serializeManifest(sealed);\n // Step 9: upsert wairon-pack.yaml (sealed envelope text) into the file map.\n const finalFiles = upsertEnvelope(files, sealedText);\n // Step 10: deflate the files + envelope into .wpack archive bytes.\n const archiveBytes = packArchive.assembleArchive(finalFiles);\n // Step 11: assemble PackArchiveInfo + suggestedFileName.\n const info = buildInfo(sealed, finalFiles);\n const suggestedFileName = `${sealed.name}-${sealed.version}.wpack`;\n // Step 12: return the build result.\n return { archive: archiveBytes, info, suggestedFileName };\n}\n\n/** The archive's entries; bytes that are not a readable ZIP carry no envelope, so they are NOT_A_PACK. */\nfunction listPackEntries(archive: Uint8Array): ArchiveEntryMeta[] {\n try {\n return packArchive.listEntries(archive);\n } catch (e) {\n throw new PackArchiveError('NOT_A_PACK', `not a .wpack archive (unreadable ZIP: ${e instanceof Error ? e.message : String(e)})`);\n }\n}\n\n/** Inspect + verify a .wpack archive without extracting it; every entry is vetted under the limits before anything is inflated. */\nexport function inspectArchive(archive: Uint8Array, limits?: PackExtractionLimits): PackArchiveInfo {\n // Step 1: did the caller omit limits?\n const effectiveLimits = limits === undefined\n // Step 2: fall back to the codec's default limit profile.\n ? codec.defaultLimits()\n : limits;\n // Step 3: enumerate archive entries without inflating.\n const entries = listPackEntries(archive);\n // Step 4: vet every entry under the effective limits, the envelope included.\n codec.planExtraction(entries, effectiveLimits);\n // Step 5: is there no wairon-pack.yaml entry?\n if (!entries.some((entry) => entry.path === codec.ENVELOPE_FILENAME)) {\n // Step 6: reject a non-.wpack archive.\n throw new PackArchiveError('NOT_A_PACK', 'not a .wpack archive (missing wairon-pack.yaml envelope)');\n }\n // Step 7 (readEnv): inflate just the envelope entry.\n const envelopeBytes = packArchive.inflateEntry(archive, codec.ENVELOPE_FILENAME);\n // Step 8: parse + version-check the envelope text.\n const manifest = codec.parseManifest(decode(envelopeBytes));\n // Step 9: compute compatibility against the running wairon version.\n const compatible = codec.checkCompatibility(manifest, SDK_VERSION);\n // Step 10: assemble PackArchiveInfo from the manifest + archive stats.\n const fileEntries = entries.filter((entry) => entry.kind === 'file');\n const totalUncompressedBytes = entries.reduce((sum, entry) => sum + entry.uncompressedSize, 0);\n const info: PackArchiveInfo = {\n name: manifest.name,\n version: manifest.version,\n kind: manifest.kind,\n entry: manifest.entry,\n formatVersion: manifest.formatVersion,\n entryCount: fileEntries.length,\n totalUncompressedBytes,\n compatible,\n };\n if (manifest.minWaironVersion !== undefined) info.minWaironVersion = manifest.minWaironVersion;\n // Step 11: return the PackArchiveInfo (no extraction performed).\n return info;\n}\n\n/** Read a .wpack archive in memory under the limits: guards, envelope, integrity, inner manifest, identity. */\nexport function readPack(archive: Uint8Array, limits?: PackExtractionLimits): PackContents {\n // Step 1: did the caller omit limits?\n const effectiveLimits = limits === undefined\n // Step 2: fall back to the codec's default limit profile.\n ? codec.defaultLimits()\n : limits;\n // Step 3 (list): enumerate archive entries without inflating.\n const entries = listPackEntries(archive);\n // Step 4: compute the safe extraction plan under the effective limits.\n const plan = codec.planExtraction(entries, effectiveLimits);\n // Step 5: is there no wairon-pack.yaml among the approved paths?\n if (!plan.paths.includes(codec.ENVELOPE_FILENAME)) {\n // Step 6: reject a non-.wpack archive.\n throw new PackArchiveError('NOT_A_PACK', 'not a .wpack archive (missing wairon-pack.yaml envelope)');\n }\n // Step 7: initialize an empty file list.\n const files: PackFile[] = [];\n // Step 8: inflate each approved path from the plan.\n for (const approvedPath of plan.paths) {\n // Step 9: inflate one approved entry.\n const contents = packArchive.inflateEntry(archive, approvedPath);\n // Step 10 (inflateEnd): append { path, contents } to the file list.\n files.push({ path: approvedPath, contents });\n }\n // Step 11: parse the wairon-pack.yaml text into the envelope.\n const envelope = files.find((file) => file.path === codec.ENVELOPE_FILENAME) as PackFile;\n const manifest = codec.parseManifest(decode(envelope.contents));\n // Step 12: verify each inflated file against the envelope digests.\n codec.verifyIntegrity(manifest, files);\n // Step 13: read the inner pack manifest.\n const packManifest = codec.parseInnerManifest(manifest, files);\n // Step 14: verify the envelope's name and version against the inner manifest's.\n codec.verifyIdentity(manifest, String(packManifest.name), String(packManifest.version));\n // Step 15: return the envelope, the inner pack manifest and the files.\n return { manifest, packManifest, files };\n}\n\n/** Safely extract a .wpack archive into a destination directory under enforced limits. */\nexport function extractPack(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n): PackExtractionResult {\n // Step 1: read the archive in memory under the limits (fails before anything is written).\n const { manifest, files } = readPack(archive, limits);\n // Step 2: write the approved, integrity-checked files as a directory tree.\n const directory = path.resolve(destDir);\n packArchive.writeTree(directory, files);\n // Step 3: assemble PackExtractionResult.\n const result: PackExtractionResult = {\n directory,\n entryPath: manifest.entry,\n manifest,\n name: manifest.name,\n kind: manifest.kind,\n entryCount: files.length,\n };\n // Step 4: return where the pack landed + its parsed manifest.\n return result;\n}\n\n// ── Spec-tree archive workflows (.waitree) ──────────────────────────────────\n\n/** Pack a project's spec tree — the supplied roots' .wai directories — into a .waitree. */\nexport function buildTreeArchive(\n roots: TreeRootSource[],\n projectName: string,\n stateId?: string,\n includeDerived?: boolean,\n): TreeBuildResult {\n // Step 1: initialize an empty archive file map and an empty packed-roots list.\n const files: PackFile[] = [];\n const packedRoots: string[] = [];\n // Step 2: pack each supplied root.\n for (const root of roots) {\n // Step 3: read this root's .wai directory recursively into a file map.\n const rootFiles = packArchive.readPackDir(root.waiDir);\n // Step 4: keep only portable design state.\n const portable = treecodec.selectTreeFiles(rootFiles, includeDerived === true);\n // Step 5 (packEnd): prefix with this root's project-relative path + '.wai/'.\n const prefix = treeRootPrefix(root.relativePath);\n for (const file of portable) files.push({ path: `${prefix}${file.path}`, contents: file.contents });\n packedRoots.push(normalizeRootPath(root.relativePath));\n }\n // Step 6: did the roots yield no files at all?\n if (files.length === 0) {\n // Step 7: an export that silently carries nothing is worse than a failure.\n throw new Error('tree export found no spec-tree files under the supplied roots');\n }\n // Step 8: build the unsealed envelope.\n const manifest: TreeArchiveManifest = {\n formatVersion: 1,\n projectName,\n roots: packedRoots,\n waironVersion: SDK_VERSION,\n includesDerived: includeDerived === true,\n };\n if (stateId !== undefined) manifest.stateId = stateId;\n // Step 9: seal integrity (entryDigests + digest + generatedBy/generatedAt).\n const sealed = treecodec.sealTreeIntegrity(\n manifest,\n files,\n `@wairon/sdk@${SDK_VERSION}`,\n new Date().toISOString(),\n );\n // Step 10: serialize the sealed manifest to canonical envelope text.\n const sealedText = treecodec.serializeTreeManifest(sealed);\n // Step 11: upsert wairon-tree.yaml (sealed envelope text) into the file map.\n const finalFiles: PackFile[] = [\n ...files.filter((file) => file.path !== treecodec.TREE_ENVELOPE_FILENAME),\n { path: treecodec.TREE_ENVELOPE_FILENAME, contents: encode(sealedText) },\n ];\n // Step 12: deflate the files + envelope into .waitree archive bytes.\n const archiveBytes = packArchive.assembleArchive(finalFiles);\n // Step 13: derive the suggested file name from the project name.\n const suggestedFileName = `${slugify(projectName)}.waitree`;\n // Step 14: return the build result.\n return { archive: archiveBytes, manifest: sealed, suggestedFileName, fileCount: files.length };\n}\n\n/** Inspect a .waitree archive without extracting it. */\nexport function inspectTreeArchive(archive: Uint8Array): TreeArchiveInfo {\n // Step 1: enumerate archive entries without inflating.\n const entries = packArchive.listEntries(archive);\n // Step 2: is there no wairon-tree.yaml entry?\n if (!entries.some((entry) => entry.path === treecodec.TREE_ENVELOPE_FILENAME)) {\n // Step 3: reject a non-.waitree archive.\n throw new Error('not a .waitree archive (missing wairon-tree.yaml envelope)');\n }\n // Step 4 (readEnv): inflate just the envelope entry.\n const envelopeBytes = packArchive.inflateEntry(archive, treecodec.TREE_ENVELOPE_FILENAME);\n // Step 5: parse + version-check the envelope text.\n const manifest = treecodec.parseTreeManifest(decode(envelopeBytes));\n // Step 6: compute compatibility against the running wairon version.\n const compatible = treecodec.checkTreeCompatibility(manifest, SDK_VERSION);\n // Step 7: assemble TreeArchiveInfo from the manifest + archive stats.\n const fileEntries = entries.filter((entry) => entry.kind === 'file');\n const totalUncompressedBytes = entries.reduce((sum, entry) => sum + entry.uncompressedSize, 0);\n // Step 8: return the TreeArchiveInfo (no extraction performed).\n return { manifest, entryCount: fileEntries.length, totalUncompressedBytes, compatible };\n}\n\n/** Safely extract a .waitree archive into a destination project root under enforced limits. */\nexport function extractTreeArchive(\n archive: Uint8Array,\n destDir: string,\n limits?: PackExtractionLimits,\n refuseExecutableEntries?: boolean,\n): TreeExtractionResult {\n // Step 1: did the caller omit limits?\n const effectiveLimits = limits === undefined\n // Step 2: fall back to the codec's tree limit profile.\n ? treecodec.defaultTreeLimits()\n : limits;\n // Step 3 (list): enumerate archive entries without inflating (caps run pre-decompress).\n const entries = packArchive.listEntries(archive);\n // Step 4: compute the safe extraction plan (throws on any unsafe/oversized entry).\n const plan = treecodec.planTreeExtraction(entries, effectiveLimits);\n // Step 5: did the caller ask for the over-the-wire portability guard?\n if (refuseExecutableEntries === true) {\n // Step 6: refuse executable or non-spec-tree entries before anything is inflated.\n treecodec.assertPortableTreePaths(plan.paths);\n }\n // Step 7 (inflate): initialize an empty file list.\n const files: PackFile[] = [];\n // Step 8: inflate each approved path from the plan.\n for (const approvedPath of plan.paths) {\n // Step 9: inflate one approved entry.\n const contents = packArchive.inflateEntry(archive, approvedPath);\n // Step 10 (inflateEnd): append { path, contents } to the file list.\n files.push({ path: approvedPath, contents });\n }\n // Step 11: is the wairon-tree.yaml envelope missing from the inflated files?\n const envelope = files.find((file) => file.path === treecodec.TREE_ENVELOPE_FILENAME);\n if (!envelope) {\n // Step 12: reject a non-.waitree archive.\n throw new Error('not a .waitree archive (missing wairon-tree.yaml envelope)');\n }\n // Step 13 (parse): parse the envelope into the result manifest.\n const manifest = treecodec.parseTreeManifest(decode(envelope.contents));\n // Step 14: enforce integrity BEFORE writing (throws on mismatch; no-op when none carried).\n treecodec.verifyTreeIntegrity(manifest, files);\n // Step 15: write the approved, integrity-checked files as a directory tree.\n const directory = path.resolve(destDir);\n packArchive.writeTree(directory, files);\n // Step 16: assemble TreeExtractionResult.\n const result: TreeExtractionResult = {\n destDir: directory,\n manifest,\n roots: manifest.roots,\n writtenPaths: files.map((file) => file.path),\n };\n // Step 17: return where the tree landed + its parsed manifest.\n return result;\n}\n\n// --- helpers ---------------------------------------------------------------\n\n/** The archive-path prefix for one packed root: '.wai/' at the top, else '<dir>/.wai/'. */\nfunction treeRootPrefix(relativePath: string): string {\n const normalized = normalizeRootPath(relativePath);\n return normalized === '.' ? '.wai/' : `${normalized}/.wai/`;\n}\n\n/** A packed root's canonical project-relative form: POSIX separators, '.' for the top root. */\nfunction normalizeRootPath(relativePath: string): string {\n const posix = relativePath.split(path.sep).join('/').replace(/^\\.\\//, '').replace(/\\/+$/, '');\n return posix === '' || posix === '.' ? '.' : posix;\n}\n\n/** A file-name-safe stem for a project name. */\nfunction slugify(projectName: string): string {\n const slug = projectName\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug || 'spec-tree';\n}\n\nfunction readInnerIdentity(files: PackFile[], manifest: PackArchiveManifest): { name: string; version: string } {\n const innerPath = manifest.kind === 'code' ? 'package.json' : manifest.entry;\n const inner = files.find((file) => file.path === innerPath);\n if (!inner) throw new Error(`pack build: inner pack manifest \"${innerPath}\" is missing`);\n const parsed = (manifest.kind === 'code'\n ? JSON.parse(decode(inner.contents))\n : yamlLoad(decode(inner.contents))) as Record<string, unknown> | null;\n const name = parsed?.name;\n const version = parsed?.version;\n if (typeof name !== 'string' || typeof version !== 'string') {\n throw new Error(`pack build: inner pack manifest \"${innerPath}\" lacks a name/version`);\n }\n return { name, version };\n}\n\nfunction upsertEnvelope(files: PackFile[], envelopeText: string): PackFile[] {\n const others = files.filter((file) => file.path !== codec.ENVELOPE_FILENAME);\n return [...others, { path: codec.ENVELOPE_FILENAME, contents: encode(envelopeText) }];\n}\n\nfunction buildInfo(manifest: PackArchiveManifest, files: PackFile[]): PackArchiveInfo {\n const totalUncompressedBytes = files.reduce((sum, file) => sum + file.contents.length, 0);\n const info: PackArchiveInfo = {\n name: manifest.name,\n version: manifest.version,\n kind: manifest.kind,\n entry: manifest.entry,\n formatVersion: manifest.formatVersion,\n entryCount: files.length,\n totalUncompressedBytes,\n compatible: true,\n };\n if (manifest.minWaironVersion !== undefined) info.minWaironVersion = manifest.minWaironVersion;\n return info;\n}\n","import { load as yamlLoad, dump as yamlDump } from 'js-yaml';\nimport { createHash } from 'crypto';\nimport { PackArchiveError } from './errors.js';\nimport type {\n ArchiveEntryMeta,\n PackArchiveManifest,\n PackExtractionLimits,\n PackExtractionPlan,\n PackFile,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Pack Codec (pack_codec_impl) — PURE format + safety logic, no I/O.\n//\n// planExtraction is the single safety chokepoint (zip-slip / size / ratio /\n// depth / symlink guards, all pre-decompress). sealIntegrity/verifyIntegrity\n// are the produce/verify integrity pair. The codec stays pure: build time is\n// passed in, never read here.\n// ---------------------------------------------------------------------------\n\n/** Never part of a pack's content integrity: any path segment with one of these names. */\nconst DIGEST_EXCLUDED = new Set(['.install.yaml', '.git', 'node_modules', '.DS_Store']);\n\n/**\n * pack_codec.contentDigest — a pack's content integrity: sha256 folding each\n * file in sorted order as `<forward-slash path> NUL <bytes> NUL`, skipping\n * `.install.yaml`, `.git`, `node_modules` and `.DS_Store` wherever they sit,\n * written `sha256-<lowercase hex>`. The digest wairon's pack store computes\n * over an installed pack directory and project.yaml pins. Pure.\n */\nexport function contentDigest(files: readonly PackFile[]): string {\n // Steps 1-2: normalized paths, the skipped ones dropped, in sorted order.\n const kept = files\n .map((file) => ({ path: file.path.replace(/\\\\/g, '/').replace(/^\\/+/, ''), contents: file.contents }))\n .filter((file) => !file.path.split('/').some((segment) => DIGEST_EXCLUDED.has(segment)))\n .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n // Step 3: path NUL bytes NUL, folded in order.\n const hash = createHash('sha256');\n for (const file of kept) {\n hash.update(file.path);\n hash.update('\\0');\n hash.update(file.contents);\n hash.update('\\0');\n }\n // Step 4.\n return `sha256-${hash.digest('hex')}`;\n}\n\n/** The archive-root envelope filename. */\nexport const ENVELOPE_FILENAME = 'wairon-pack.yaml';\n\n/** The highest pack-archive format major this SDK understands. */\nconst SUPPORTED_FORMAT_VERSION = 1;\n\n/** The default extraction-safety profile: 4096 / 32 MiB / 8 MiB / 100:1 / depth 16. */\nconst DEFAULTS = {\n maxEntries: 4096,\n maxTotalUncompressedBytes: 32 * 1024 * 1024,\n maxEntryBytes: 8 * 1024 * 1024,\n maxCompressionRatio: 100,\n maxDepth: 16,\n} as const;\n\n/** Parse + validate the envelope text into a PackArchiveManifest; throws on malformed/newer-major. */\nexport function parseManifest(text: string): PackArchiveManifest {\n // Step 1: parse the envelope YAML text (ENVELOPE_INVALID on malformed YAML).\n let raw: unknown;\n try {\n raw = yamlLoad(text);\n } catch (err) {\n throw new PackArchiveError('ENVELOPE_INVALID', `malformed pack envelope (not valid YAML): ${(err as Error).message}`);\n }\n // Step 2: validate the required fields are present and well-typed.\n const manifest = validateEnvelope(raw);\n // Step 3: is the format major newer than this wairon supports?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: fail loudly rather than silently mis-read a newer format.\n throw new PackArchiveError(\n 'FORMAT_VERSION_UNSUPPORTED',\n `unsupported pack-archive formatVersion ${manifest.formatVersion} (newer than this wairon understands)`,\n );\n }\n // Step 5: return the parsed manifest.\n return manifest;\n}\n\n/** Serialize a manifest to canonical wairon-pack.yaml text (build path). */\nexport function serializeManifest(manifest: PackArchiveManifest): string {\n // Step 1: drop undefined optional fields for a clean, canonical envelope.\n const clean: Record<string, unknown> = {\n formatVersion: manifest.formatVersion,\n name: manifest.name,\n version: manifest.version,\n kind: manifest.kind,\n entry: manifest.entry,\n };\n if (manifest.minWaironVersion !== undefined) clean.minWaironVersion = manifest.minWaironVersion;\n if (manifest.digest !== undefined) clean.digest = manifest.digest;\n if (manifest.entryDigests !== undefined) clean.entryDigests = manifest.entryDigests;\n if (manifest.generatedBy !== undefined) clean.generatedBy = manifest.generatedBy;\n if (manifest.generatedAt !== undefined) clean.generatedAt = manifest.generatedAt;\n // Step 2: return the wairon-pack.yaml text.\n return yamlDump(clean, { sortKeys: false });\n}\n\n/** The default extraction-safety profile; callers override individual caps. */\nexport function defaultLimits(): PackExtractionLimits {\n // Step 1: return the default caps profile.\n return { ...DEFAULTS };\n}\n\n/** Compute the safe extraction plan from enumerated entries under `limits`, or throw. */\nexport function planExtraction(entries: ArchiveEntryMeta[], limits: PackExtractionLimits): PackExtractionPlan {\n // Step 1: resolve effective caps — each field of `limits` over the defaults.\n const caps = {\n maxEntries: limits.maxEntries ?? DEFAULTS.maxEntries,\n maxTotalUncompressedBytes: limits.maxTotalUncompressedBytes ?? DEFAULTS.maxTotalUncompressedBytes,\n maxEntryBytes: limits.maxEntryBytes ?? DEFAULTS.maxEntryBytes,\n maxCompressionRatio: limits.maxCompressionRatio ?? DEFAULTS.maxCompressionRatio,\n maxDepth: limits.maxDepth ?? DEFAULTS.maxDepth,\n };\n // Step 2: initialize an empty approved-path list and a running total of 0.\n const approved: string[] = [];\n let total = 0;\n // Step 3: vet each enumerated entry.\n for (const entry of entries) {\n // Step 4: reject symlinks/non-regular entries and structurally unsafe paths.\n if (isSymlinkOrNonRegular(entry.kind) || isStructurallyUnsafePath(entry.path)) {\n rejectUnsafe(entry.path);\n }\n // Directory entries are structural (writeTree recreates them from file\n // paths) — skip without approving, never inflate a 0-byte dir marker.\n if (entry.kind === 'dir') continue;\n // Step 5: normalize the entry path to a destination-relative POSIX path.\n const normalized = normalizeRelPath(entry.path);\n // Step 6: reject zip-slip and over-deep paths.\n if (escapesDestination(normalized)) {\n rejectUnsafe(entry.path);\n }\n if (pathDepth(normalized) > caps.maxDepth) {\n rejectLimit(`entry \"${entry.path}\" is nested deeper than maxDepth (${caps.maxDepth})`);\n }\n // Step 7: reject oversized entries and zip bombs.\n if (entry.uncompressedSize > caps.maxEntryBytes) {\n rejectLimit(`entry \"${entry.path}\" is larger than maxEntryBytes (${caps.maxEntryBytes})`);\n }\n if (compressionRatio(entry) > caps.maxCompressionRatio) {\n rejectLimit(`entry \"${entry.path}\" exceeds maxCompressionRatio (${caps.maxCompressionRatio}:1)`);\n }\n // Step 8 (vetEnd): accept — append the path and add its inflated size.\n approved.push(normalized);\n total += entry.uncompressedSize;\n }\n // Step 9: reject archives exceeding the aggregate caps.\n if (approved.length > caps.maxEntries) {\n rejectLimit(`archive holds more than maxEntries (${caps.maxEntries}) files`);\n }\n if (total > caps.maxTotalUncompressedBytes) {\n rejectLimit(`archive inflates beyond maxTotalUncompressedBytes (${caps.maxTotalUncompressedBytes})`);\n }\n // Step 11: return the approved plan.\n return { paths: approved, totalUncompressedBytes: total };\n}\n\n/** Assert the envelope's name/version match the inner pack manifest; throw on mismatch. */\nexport function verifyIdentity(manifest: PackArchiveManifest, packName: string, packVersion: string): void {\n // Step 1: do envelope name/version differ from the inner pack manifest?\n if (manifest.name !== packName || manifest.version !== packVersion) {\n // Step 2: reject a tampered/mis-assembled archive.\n throw new PackArchiveError(\n 'IDENTITY_MISMATCH',\n `envelope identity mismatch: envelope says ${manifest.name}@${manifest.version}, inner pack manifest says ${packName}@${packVersion}`,\n );\n }\n // Step 3: identity verified.\n}\n\n/** Verify every entry's sha256 against entryDigests; false when none carried, throws on mismatch. */\nexport function verifyIntegrity(manifest: PackArchiveManifest, files: PackFile[]): boolean {\n // Step 1: did the envelope carry no integrity data?\n if (!manifest.entryDigests) {\n // Step 2: no integrity data present — return false.\n return false;\n }\n const digests = manifest.entryDigests;\n // Step 3: does entryDigests name a file the archive does not hold, or does the\n // envelope's overall digest differ from the one recomputed over entryDigests?\n const held = new Set(files.map((file) => file.path));\n const missing = Object.keys(digests).find((path) => !held.has(path));\n if (missing !== undefined) {\n // Step 8 (mismatch): the envelope lists a file the archive does not hold.\n throw new PackArchiveError('DIGEST_MISMATCH', `integrity digest lists \"${missing}\", which the archive does not hold`);\n }\n if (manifest.digest !== undefined && manifest.digest !== sha256(canonicalDigestBytes(digests))) {\n // Step 8 (mismatch): the overall digest does not match the entry digests.\n throw new PackArchiveError('DIGEST_MISMATCH', 'integrity digest mismatch for the overall digest');\n }\n // Step 4: check each file's digest.\n for (const file of files) {\n // The envelope carries these digests and cannot digest itself — skip it.\n if (file.path === ENVELOPE_FILENAME) continue;\n // Step 5: does the recomputed sha256 differ from the recorded digest?\n if (sha256(file.contents) !== digests[file.path]) {\n // Step 8 (mismatch): a digest mismatch means tampering.\n throw new PackArchiveError('DIGEST_MISMATCH', `integrity digest mismatch for \"${file.path}\"`);\n }\n // Step 6 (checkEnd): this file's digest matches.\n }\n // Step 7: all digests matched — return true.\n return true;\n}\n\n/** Produce-side partner of verifyIntegrity: fill entryDigests + digest + stamps. */\nexport function sealIntegrity(\n manifest: PackArchiveManifest,\n files: PackFile[],\n generatedBy: string,\n generatedAt?: string,\n): PackArchiveManifest {\n // Step 1: initialize an empty entryDigests map.\n const entryDigests: Record<string, string> = {};\n // Step 2: hash each file.\n for (const file of files) {\n // The envelope is the carrier of these digests — never hash it into itself.\n if (file.path === ENVELOPE_FILENAME) continue;\n // Step 3 (hashEnd): compute sha256(file.contents) and record it under file.path.\n entryDigests[file.path] = sha256(file.contents);\n }\n // Step 4: compute an overall manifest digest over the sorted entryDigests.\n const digest = sha256(canonicalDigestBytes(entryDigests));\n // Step 5: set entryDigests, digest, generatedBy, and generatedAt when one is given.\n const sealed: PackArchiveManifest = { ...manifest, entryDigests, digest, generatedBy };\n if (generatedAt !== undefined) sealed.generatedAt = generatedAt;\n else delete sealed.generatedAt;\n // Step 6: return the sealed manifest.\n return sealed;\n}\n\n/** Whether the archive's formatVersion + minWaironVersion are compatible with `waironVersion`. */\nexport function checkCompatibility(manifest: PackArchiveManifest, waironVersion: string): boolean {\n // Step 1: is the archive format unsupported?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: incompatible.\n return false;\n }\n // Step 2: is the running wairon below the pack's minimum?\n if (manifest.minWaironVersion && isBelow(waironVersion, manifest.minWaironVersion)) {\n // Step 4: incompatible.\n return false;\n }\n // Step 3: compatible.\n return true;\n}\n\n/**\n * Read the inner pack manifest from the inflated files: package.json of a code\n * pack, the envelope's entry (pack.yaml) of a declarative pack. Throws\n * PACK_MANIFEST_INVALID when it is missing, unparseable or not a mapping.\n */\nexport function parseInnerManifest(manifest: PackArchiveManifest, files: readonly PackFile[]): Record<string, unknown> {\n // Step 1: pick the inner manifest's path.\n const innerPath = manifest.kind === 'code' ? 'package.json' : manifest.entry;\n // Step 2: is it missing among the files?\n const inner = files.find((file) => file.path === innerPath);\n if (!inner) {\n throw new PackArchiveError('PACK_MANIFEST_INVALID', `inner pack manifest \"${innerPath}\" is missing`);\n }\n // Step 3: parse it — JSON for package.json, YAML for pack.yaml.\n const text = new TextDecoder().decode(inner.contents);\n let parsed: unknown;\n try {\n parsed = manifest.kind === 'code' ? JSON.parse(text) : yamlLoad(text);\n } catch {\n parsed = undefined;\n }\n // Step 4-5: unparseable or not a mapping — refuse, naming the path.\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new PackArchiveError('PACK_MANIFEST_INVALID', `inner pack manifest \"${innerPath}\" is not a readable mapping`);\n }\n // Step 6: return the mapping as authored.\n return parsed as Record<string, unknown>;\n}\n\n// --- helpers ---------------------------------------------------------------\n\nfunction rejectUnsafe(entryPath: string): never {\n throw new PackArchiveError('UNSAFE_PATH', `unsafe archive entry \"${entryPath}\" (symlink, non-file kind, or an unsafe or escaping path)`);\n}\n\nfunction rejectLimit(what: string): never {\n throw new PackArchiveError('LIMIT_EXCEEDED', `archive over a cap: ${what}`);\n}\n\nfunction invalidEnvelope(message: string): never {\n throw new PackArchiveError('ENVELOPE_INVALID', message);\n}\n\nfunction validateEnvelope(raw: unknown): PackArchiveManifest {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return invalidEnvelope('malformed pack envelope (not a YAML mapping)');\n }\n const o = raw as Record<string, unknown>;\n if (typeof o.formatVersion !== 'number') invalidEnvelope('pack envelope: formatVersion must be a number');\n if (typeof o.name !== 'string' || !o.name) invalidEnvelope('pack envelope: name is required');\n if (typeof o.version !== 'string' || !o.version) invalidEnvelope('pack envelope: version is required');\n if (typeof o.kind !== 'string' || (o.kind !== 'declarative' && o.kind !== 'code')) {\n invalidEnvelope('pack envelope: kind must be \"declarative\" or \"code\"');\n }\n if (typeof o.entry !== 'string' || !o.entry) invalidEnvelope('pack envelope: entry is required');\n // The integrity fields, when present, must be well-typed: an unquoted all-digit digest reads as\n // a YAML number, and skipping it would accept the archive unchecked.\n if (o.digest !== undefined && typeof o.digest !== 'string') {\n invalidEnvelope('pack envelope: digest must be a string (quote an all-digit digest)');\n }\n if (o.entryDigests !== undefined) {\n const digests = o.entryDigests;\n if (!digests || typeof digests !== 'object' || Array.isArray(digests)) {\n invalidEnvelope('pack envelope: entryDigests must be a mapping of path to digest');\n }\n for (const [entryPath, value] of Object.entries(digests as Record<string, unknown>)) {\n if (typeof value !== 'string') invalidEnvelope(`pack envelope: entryDigests[\"${entryPath}\"] must be a string (quote an all-digit digest)`);\n }\n }\n const manifest: PackArchiveManifest = {\n formatVersion: o.formatVersion,\n name: o.name,\n version: o.version,\n kind: o.kind,\n entry: o.entry,\n };\n if (typeof o.minWaironVersion === 'string') manifest.minWaironVersion = o.minWaironVersion;\n if (typeof o.digest === 'string') manifest.digest = o.digest;\n if (o.entryDigests && typeof o.entryDigests === 'object') {\n manifest.entryDigests = o.entryDigests as Record<string, string>;\n }\n if (typeof o.generatedBy === 'string') manifest.generatedBy = o.generatedBy;\n if (typeof o.generatedAt === 'string') manifest.generatedAt = o.generatedAt;\n return manifest;\n}\n\nfunction isSymlinkOrNonRegular(kind: string): boolean {\n return kind !== 'file' && kind !== 'dir';\n}\n\nfunction isStructurallyUnsafePath(p: string): boolean {\n if (p.includes('\\\\')) return true; // backslash\n if (/^[A-Za-z]:/.test(p)) return true; // drive letter\n if (p.startsWith('/')) return true; // absolute POSIX\n return p.split('/').some((seg) => seg === '..'); // parent traversal\n}\n\nfunction normalizeRelPath(p: string): string {\n return p\n .split('/')\n .filter((seg) => seg !== '' && seg !== '.')\n .join('/');\n}\n\nfunction escapesDestination(normalized: string): boolean {\n return normalized.startsWith('/') || normalized.split('/').some((seg) => seg === '..');\n}\n\nfunction pathDepth(normalized: string): number {\n return normalized.split('/').filter((seg) => seg !== '').length;\n}\n\nfunction compressionRatio(entry: ArchiveEntryMeta): number {\n if (entry.compressedSize > 0) return entry.uncompressedSize / entry.compressedSize;\n return entry.uncompressedSize > 0 ? Infinity : 0;\n}\n\nfunction canonicalDigestBytes(entryDigests: Record<string, string>): Uint8Array {\n const lines = Object.keys(entryDigests)\n .sort()\n .map((key) => `${key}:${entryDigests[key]}`)\n .join('\\n');\n return new TextEncoder().encode(lines);\n}\n\nfunction sha256(data: Uint8Array): string {\n return createHash('sha256').update(data).digest('hex');\n}\n\nfunction isBelow(running: string, minimum: string): boolean {\n const [rMaj, rMin, rPat] = parseSemverCore(running);\n const [mMaj, mMin, mPat] = parseSemverCore(minimum);\n if (rMaj !== mMaj) return rMaj < mMaj;\n if (rMin !== mMin) return rMin < mMin;\n return rPat < mPat;\n}\n\nfunction parseSemverCore(v: string): [number, number, number] {\n const cleaned = v.trim().replace(/^[^0-9]*/, ''); // strip leading ^, ~, >=, v, etc.\n const core = cleaned.split(/[-+]/)[0]; // drop prerelease/build metadata\n const parts = core.split('.').map((n) => parseInt(n, 10));\n return [parts[0] || 0, parts[1] || 0, parts[2] || 0];\n}\n","// ---------------------------------------------------------------------------\n// Pack archive errors (pack_archive_error, pack_archive_error_code) — the one\n// error every .wpack reader of the SDK fails with. A caller matches on `code`,\n// never on message text.\n// ---------------------------------------------------------------------------\n\n/** Why a .wpack archive was refused. */\nexport type PackArchiveErrorCode =\n | 'NOT_A_PACK'\n | 'UNSAFE_PATH'\n | 'LIMIT_EXCEEDED'\n | 'ENVELOPE_INVALID'\n | 'FORMAT_VERSION_UNSUPPORTED'\n | 'PACK_MANIFEST_INVALID'\n | 'IDENTITY_MISMATCH'\n | 'DIGEST_MISMATCH';\n\n/** A .wpack archive was refused: a stable `code` beside a human message. */\nexport class PackArchiveError extends Error {\n readonly code: PackArchiveErrorCode;\n\n constructor(code: PackArchiveErrorCode, message: string) {\n super(message);\n this.name = 'PackArchiveError';\n this.code = code;\n Object.setPrototypeOf(this, PackArchiveError.prototype);\n }\n}\n","import { load as yamlLoad, dump as yamlDump } from 'js-yaml';\nimport { createHash } from 'crypto';\nimport type {\n ArchiveEntryMeta,\n PackExtractionLimits,\n PackExtractionPlan,\n PackFile,\n TreeArchiveManifest,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Tree Codec (tree_codec_impl) — PURE format + safety logic for the `.waitree`\n// spec-tree archive, no I/O and no clock.\n//\n// selectTreeFiles is the single portability decision (what belongs in a tree\n// archive at all); planTreeExtraction is the single pre-decompress safety\n// chokepoint; assertPortableTreePaths is the over-the-wire executable guard;\n// sealTreeIntegrity/verifyTreeIntegrity are the produce/verify pair.\n//\n// The small pure path/digest helpers below deliberately mirror the pack codec's\n// rather than importing them: tree_codec declares NO dependencies, and reaching\n// into pack_codec for them would make one codec depend on the other for a\n// handful of one-line functions.\n// ---------------------------------------------------------------------------\n\n/** The tree-archive envelope filename. */\nexport const TREE_ENVELOPE_FILENAME = 'wairon-tree.yaml';\n\n/** The highest tree-archive format major this SDK understands. */\nconst SUPPORTED_FORMAT_VERSION = 1;\n\n/**\n * The tree caps profile: looser than the pack profile on entry count and total\n * size (a real spec tree is thousands of small YAML files across several\n * chained roots) and stricter on nothing.\n */\nconst TREE_DEFAULTS = {\n maxEntries: 20000,\n maxTotalUncompressedBytes: 64 * 1024 * 1024,\n maxEntryBytes: 8 * 1024 * 1024,\n maxCompressionRatio: 100,\n maxDepth: 24,\n} as const;\n\n/** Root-relative directories holding REGENERABLE artifacts — never portable design state. */\nconst DERIVED_ROOTS = ['generated', 'docs'];\n\n/** Executable extensions: a bundled code pack's entry can ride inside a tree. */\nconst EXECUTABLE_EXT_RE = /\\.(c|m)?js$/i;\n\n/** The directory every packed root's content lives under, inside the archive. */\nconst WAI_SEGMENT = '.wai';\n\n/** Parse + validate the envelope text into a TreeArchiveManifest; throws on malformed/newer-major. */\nexport function parseTreeManifest(text: string): TreeArchiveManifest {\n // Step 1: parse the envelope YAML text (throws on malformed YAML).\n const raw = yamlLoad(text);\n // Step 2: validate the required fields are present and well-typed.\n const manifest = validateEnvelope(raw);\n // Step 3: is the format major newer than this wairon supports?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: fail loudly rather than silently mis-read a newer format.\n throw new Error('unsupported tree-archive formatVersion (newer than this wairon understands)');\n }\n // Step 5: return the parsed manifest.\n return manifest;\n}\n\n/** Serialize a manifest to canonical wairon-tree.yaml text (export path). */\nexport function serializeTreeManifest(manifest: TreeArchiveManifest): string {\n // Step 1: drop undefined optional fields for a clean, canonical envelope.\n const clean: Record<string, unknown> = {\n formatVersion: manifest.formatVersion,\n projectName: manifest.projectName,\n roots: manifest.roots,\n };\n if (manifest.stateId !== undefined) clean.stateId = manifest.stateId;\n if (manifest.waironVersion !== undefined) clean.waironVersion = manifest.waironVersion;\n if (manifest.minWaironVersion !== undefined) clean.minWaironVersion = manifest.minWaironVersion;\n if (manifest.includesDerived !== undefined) clean.includesDerived = manifest.includesDerived;\n if (manifest.digest !== undefined) clean.digest = manifest.digest;\n if (manifest.entryDigests !== undefined) clean.entryDigests = manifest.entryDigests;\n if (manifest.generatedBy !== undefined) clean.generatedBy = manifest.generatedBy;\n if (manifest.generatedAt !== undefined) clean.generatedAt = manifest.generatedAt;\n // Step 2: return the wairon-tree.yaml text.\n return yamlDump(clean, { sortKeys: false });\n}\n\n/** The tree extraction-safety profile; callers override individual caps. */\nexport function defaultTreeLimits(): PackExtractionLimits {\n // Step 1: return the tree caps profile.\n return { ...TREE_DEFAULTS };\n}\n\n/**\n * Decide which of a root's files are portable design state: keep authored spec\n * state, drop regenerable artifacts unless the caller asked for them. Paths are\n * relative to the root's `.wai/` directory.\n */\nexport function selectTreeFiles(files: PackFile[], includeDerived: boolean): PackFile[] {\n // Step 1: did the caller ask for regenerable artifacts too?\n if (includeDerived) {\n // Step 2: return the file map unchanged — an explicit full-fidelity archive.\n return files;\n }\n // Step 3: drop every file under a regenerable root — a moved tree carries the\n // design, not its rendered output, which the destination regenerates.\n const kept = files.filter((file) => !isDerivedPath(file.path));\n // Step 4: return the portable design state.\n return kept;\n}\n\n/** Compute the safe extraction plan from enumerated entries under `limits`, or throw. */\nexport function planTreeExtraction(entries: ArchiveEntryMeta[], limits: PackExtractionLimits): PackExtractionPlan {\n // Step 1: resolve effective caps — each field of `limits` over the tree defaults.\n const caps = {\n maxEntries: limits.maxEntries ?? TREE_DEFAULTS.maxEntries,\n maxTotalUncompressedBytes: limits.maxTotalUncompressedBytes ?? TREE_DEFAULTS.maxTotalUncompressedBytes,\n maxEntryBytes: limits.maxEntryBytes ?? TREE_DEFAULTS.maxEntryBytes,\n maxCompressionRatio: limits.maxCompressionRatio ?? TREE_DEFAULTS.maxCompressionRatio,\n maxDepth: limits.maxDepth ?? TREE_DEFAULTS.maxDepth,\n };\n // Step 2: initialize an empty approved-path list and a running total of 0.\n const approved: string[] = [];\n let total = 0;\n // Step 3: vet each enumerated entry.\n for (const entry of entries) {\n // Step 4: reject symlinks/non-regular entries and structurally unsafe paths.\n if (isSymlinkOrNonRegular(entry.kind) || isStructurallyUnsafePath(entry.path)) {\n rejectUnsafe();\n }\n // Directory entries are structural (writeTree recreates them from file\n // paths) — skip without approving, never inflate a 0-byte dir marker.\n if (entry.kind === 'dir') continue;\n // Step 5: normalize the entry path to a destination-relative POSIX path.\n const normalized = normalizeRelPath(entry.path);\n // Step 6: reject zip-slip and over-deep paths.\n if (escapesDestination(normalized) || pathDepth(normalized) > caps.maxDepth) {\n rejectUnsafe();\n }\n // Step 7: reject oversized entries and zip bombs.\n if (entry.uncompressedSize > caps.maxEntryBytes || compressionRatio(entry) > caps.maxCompressionRatio) {\n rejectUnsafe();\n }\n // Step 8 (vetEnd): accept — append the path and add its inflated size.\n approved.push(normalized);\n total += entry.uncompressedSize;\n }\n // Step 9: reject archives exceeding the aggregate caps.\n if (approved.length > caps.maxEntries || total > caps.maxTotalUncompressedBytes) {\n rejectUnsafe();\n }\n // Step 11: return the approved plan.\n return { paths: approved, totalUncompressedBytes: total };\n}\n\n/**\n * Assert the planned paths carry no executable content and nothing outside a\n * spec-tree root. Called by any surface accepting an archive over the wire; a\n * local extraction on the developer's own machine may skip it.\n */\nexport function assertPortableTreePaths(paths: string[]): void {\n // Step 1: check each planned path.\n for (const entryPath of paths) {\n // Step 2: is this an executable file (a bundled code pack's entry)?\n if (EXECUTABLE_EXT_RE.test(entryPath)) {\n // Step 6 (rejectExecutable): same guidance the pack surface gives.\n throw new Error(\n 'refused: the archive carries executable content. Only declarative spec state transfers over this ' +\n 'surface; rule/code packs are executable and install via the trusted filesystem (mount into ' +\n 'WAIRON_PACKS_DIR, or run `wairon packs add`).',\n );\n }\n // Step 3: does the path sit outside any recognized spec-tree root?\n if (entryPath !== TREE_ENVELOPE_FILENAME && !isUnderWaiRoot(entryPath)) {\n // Step 7 (rejectForeign): a tree archive carries .wai trees, never arbitrary project files.\n throw new Error(`refused: the archive carries an entry outside any spec-tree root (\"${entryPath}\")`);\n }\n // Step 4 (checkEnd): this path is portable spec-tree content.\n }\n // Step 5: every path is portable.\n}\n\n/** Verify every entry's sha256 against entryDigests; false when none carried, throws on mismatch. */\nexport function verifyTreeIntegrity(manifest: TreeArchiveManifest, files: PackFile[]): boolean {\n // Step 1: did the envelope carry no integrity data?\n if (!manifest.entryDigests) {\n // Step 2: no integrity data present — return false.\n return false;\n }\n const digests = manifest.entryDigests;\n // Step 3: check each file's digest.\n for (const file of files) {\n // The envelope carries these digests and cannot digest itself — skip it.\n if (file.path === TREE_ENVELOPE_FILENAME) continue;\n // Step 4: does the recomputed sha256 differ from the recorded digest?\n if (sha256(file.contents) !== digests[file.path]) {\n // Step 7: a digest mismatch means tampering.\n throw new Error('tree integrity digest mismatch');\n }\n // Step 5 (checkEnd): this file's digest matches.\n }\n // Step 6: all digests matched — return true.\n return true;\n}\n\n/** Produce-side partner of verifyTreeIntegrity: fill entryDigests + digest + stamps. */\nexport function sealTreeIntegrity(\n manifest: TreeArchiveManifest,\n files: PackFile[],\n generatedBy: string,\n generatedAt: string,\n): TreeArchiveManifest {\n // Step 1: initialize an empty entryDigests map.\n const entryDigests: Record<string, string> = {};\n // Step 2: hash each file.\n for (const file of files) {\n // The envelope is the carrier of these digests — never hash it into itself.\n if (file.path === TREE_ENVELOPE_FILENAME) continue;\n // Step 3 (hashEnd): compute sha256(file.contents) and record it under file.path.\n entryDigests[file.path] = sha256(file.contents);\n }\n // Step 4: compute an overall manifest digest over the sorted entryDigests.\n const digest = sha256(canonicalDigestBytes(entryDigests));\n // Step 5: set entryDigests, digest, generatedBy, generatedAt.\n // Step 6: return the sealed manifest.\n return { ...manifest, entryDigests, digest, generatedBy, generatedAt };\n}\n\n/** Whether the archive's formatVersion + minWaironVersion are compatible with `waironVersion`. */\nexport function checkTreeCompatibility(manifest: TreeArchiveManifest, waironVersion: string): boolean {\n // Step 1: is the archive format unsupported?\n if (Math.trunc(manifest.formatVersion) > SUPPORTED_FORMAT_VERSION) {\n // Step 4: incompatible.\n return false;\n }\n // Step 2: is the running wairon below the archive's minimum?\n if (manifest.minWaironVersion && isBelow(waironVersion, manifest.minWaironVersion)) {\n // Step 4: incompatible.\n return false;\n }\n // Step 3: compatible.\n return true;\n}\n\n// --- helpers ---------------------------------------------------------------\n\nfunction rejectUnsafe(): never {\n throw new Error('reject: unsafe or oversized tree-archive entry (zip-slip / size / ratio / depth guard)');\n}\n\nfunction validateEnvelope(raw: unknown): TreeArchiveManifest {\n if (!raw || typeof raw !== 'object') {\n throw new Error('malformed tree envelope (not a YAML mapping)');\n }\n const o = raw as Record<string, unknown>;\n if (typeof o.formatVersion !== 'number') throw new Error('tree envelope: formatVersion must be a number');\n if (typeof o.projectName !== 'string' || !o.projectName) throw new Error('tree envelope: projectName is required');\n if (!Array.isArray(o.roots) || o.roots.length === 0 || o.roots.some((r) => typeof r !== 'string' || !r)) {\n throw new Error('tree envelope: roots must be a non-empty list of project-relative directories');\n }\n const manifest: TreeArchiveManifest = {\n formatVersion: o.formatVersion,\n projectName: o.projectName,\n roots: o.roots as string[],\n };\n if (typeof o.stateId === 'string') manifest.stateId = o.stateId;\n if (typeof o.waironVersion === 'string') manifest.waironVersion = o.waironVersion;\n if (typeof o.minWaironVersion === 'string') manifest.minWaironVersion = o.minWaironVersion;\n if (typeof o.includesDerived === 'boolean') manifest.includesDerived = o.includesDerived;\n if (typeof o.digest === 'string') manifest.digest = o.digest;\n if (o.entryDigests && typeof o.entryDigests === 'object') {\n manifest.entryDigests = o.entryDigests as Record<string, string>;\n }\n if (typeof o.generatedBy === 'string') manifest.generatedBy = o.generatedBy;\n if (typeof o.generatedAt === 'string') manifest.generatedAt = o.generatedAt;\n return manifest;\n}\n\n/** True for a path under a regenerable root, relative to a root's .wai/ directory. */\nfunction isDerivedPath(relPath: string): boolean {\n const first = relPath.split('/')[0];\n return DERIVED_ROOTS.includes(first);\n}\n\n/** True when an archive path lives under some root's .wai/ directory. */\nfunction isUnderWaiRoot(archivePath: string): boolean {\n const segments = archivePath.split('/');\n // The .wai segment must exist AND carry content beneath it — a bare '.wai'\n // entry names a directory, not spec-tree state.\n const at = segments.indexOf(WAI_SEGMENT);\n return at >= 0 && at < segments.length - 1;\n}\n\nfunction isSymlinkOrNonRegular(kind: string): boolean {\n return kind !== 'file' && kind !== 'dir';\n}\n\nfunction isStructurallyUnsafePath(p: string): boolean {\n if (p.includes('\\\\')) return true; // backslash\n if (/^[A-Za-z]:/.test(p)) return true; // drive letter\n if (p.startsWith('/')) return true; // absolute POSIX\n return p.split('/').some((seg) => seg === '..'); // parent traversal\n}\n\nfunction normalizeRelPath(p: string): string {\n return p\n .split('/')\n .filter((seg) => seg !== '' && seg !== '.')\n .join('/');\n}\n\nfunction escapesDestination(normalized: string): boolean {\n return normalized.startsWith('/') || normalized.split('/').some((seg) => seg === '..');\n}\n\nfunction pathDepth(normalized: string): number {\n return normalized.split('/').filter((seg) => seg !== '').length;\n}\n\nfunction compressionRatio(entry: ArchiveEntryMeta): number {\n if (entry.compressedSize > 0) return entry.uncompressedSize / entry.compressedSize;\n return entry.uncompressedSize > 0 ? Infinity : 0;\n}\n\nfunction canonicalDigestBytes(entryDigests: Record<string, string>): Uint8Array {\n const lines = Object.keys(entryDigests)\n .sort()\n .map((key) => `${key}:${entryDigests[key]}`)\n .join('\\n');\n return new TextEncoder().encode(lines);\n}\n\nfunction sha256(data: Uint8Array): string {\n return createHash('sha256').update(data).digest('hex');\n}\n\nfunction isBelow(running: string, minimum: string): boolean {\n const [rMaj, rMin, rPat] = parseSemverCore(running);\n const [mMaj, mMin, mPat] = parseSemverCore(minimum);\n if (rMaj !== mMaj) return rMaj < mMaj;\n if (rMin !== mMin) return rMin < mMin;\n return rPat < mPat;\n}\n\nfunction parseSemverCore(v: string): [number, number, number] {\n const cleaned = v.trim().replace(/^[^0-9]*/, ''); // strip leading ^, ~, >=, v, etc.\n const core = cleaned.split(/[-+]/)[0]; // drop prerelease/build metadata\n const parts = core.split('.').map((n) => parseInt(n, 10));\n return [parts[0] || 0, parts[1] || 0, parts[2] || 0];\n}\n","// The running @wairon/sdk version — stamped into built archives (generatedBy)\n// and used as the \"running wairon version\" for pack version-compatibility\n// checks. tsup inlines package.json at build time; at runtime the require\n// resolves against the shipped package (../package.json from dist/).\n\nexport const SDK_VERSION: string = loadVersion();\n\nfunction loadVersion(): string {\n try {\n const pkg = require('../package.json') as { version?: string };\n return pkg.version ?? '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n","import type { PackFile, PackScaffoldRequest } from './types.js';\nimport { SDK_VERSION } from './version.js';\n\n// ---------------------------------------------------------------------------\n// Pack Scaffold (pack_scaffold_impl) — PURE template rendering for\n// `wairon pack init`. Produces an in-memory file map; writes nothing. Code\n// packs pin @wairon/sdk to the running SDK version.\n// ---------------------------------------------------------------------------\n\nconst enc = (s: string): Uint8Array => new TextEncoder().encode(s);\n\n/** Render the scaffold file map for the requested pack (declarative or code). */\nexport function render(request: PackScaffoldRequest): PackFile[] {\n const version = request.version ?? '0.1.0';\n let files: PackFile[];\n // Step 1: which variant?\n if (request.kind === 'code') {\n // Step 2: render the code-pack file map.\n files = renderCodePack(request.name, version);\n // Step 3: skip the declarative variant (fall through to the skill gate).\n } else {\n // Step 4 (declVariant): render the declarative-pack file map.\n files = renderDeclarativePack(request.name, version);\n }\n // Step 5 (skillGate): include a skill stub?\n if (request.withSkill) {\n // Step 6: append a skills/<id>/SKILL.md stub to the file map.\n files.push(renderSkillStub(request.name, version));\n }\n // Step 7 (done): return the rendered file map.\n return files;\n}\n\n// --- variant renderers -----------------------------------------------------\n\nfunction renderDeclarativePack(name: string, version: string): PackFile[] {\n return [\n { path: 'wairon-pack.yaml', contents: enc(declarativeEnvelope(name, version)) },\n { path: 'pack.yaml', contents: enc(declarativeManifest(name, version)) },\n { path: 'README.md', contents: enc(readme(name, 'declarative', 'pack.yaml')) },\n ];\n}\n\nfunction renderCodePack(name: string, version: string): PackFile[] {\n return [\n { path: 'wairon-pack.yaml', contents: enc(codeEnvelope(name, version)) },\n { path: 'package.json', contents: enc(codePackageJson(name, version)) },\n { path: 'tsconfig.json', contents: enc(codeTsconfig()) },\n { path: 'pack.ts', contents: enc(codeEntry(name, version)) },\n { path: 'README.md', contents: enc(readme(name, 'code', 'pack.cjs')) },\n ];\n}\n\nfunction renderSkillStub(name: string, _version: string): PackFile {\n const id = slug(name);\n return { path: `skills/${id}/SKILL.md`, contents: enc(skillStub(name)) };\n}\n\n// --- templates -------------------------------------------------------------\n\nfunction declarativeEnvelope(name: string, version: string): string {\n return [\n 'formatVersion: 1',\n `name: ${name}`,\n `version: ${version}`,\n 'kind: declarative',\n 'entry: pack.yaml',\n '',\n ].join('\\n');\n}\n\n/** A version's release core (major.minor.patch): a pre-release never becomes a minimum. */\nfunction releaseCore(version: string): string {\n return version.split(/[-+]/)[0];\n}\n\nfunction codeEnvelope(name: string, version: string): string {\n return [\n 'formatVersion: 1',\n `name: ${name}`,\n `version: ${version}`,\n 'kind: code',\n 'entry: pack.cjs',\n `minWaironVersion: ${releaseCore(SDK_VERSION)}`,\n '',\n ].join('\\n');\n}\n\nfunction declarativeManifest(name: string, version: string): string {\n return [\n `name: ${name}`,\n `version: ${version}`,\n '',\n '# Custom architectural profiles this pack contributes (example, commented):',\n '# profiles:',\n '# my-profile:',\n '# family: backend-like',\n '# forbiddenStereotypes:',\n '# - types: [Adapter]',\n '# reason: \"Domain components must not touch adapters directly.\"',\n 'profiles: {}',\n '',\n '# Target language / platform tables (example, commented):',\n '# languages:',\n '# rust:',\n '# unsupportedFlow: {}',\n 'languages: {}',\n '',\n '# Reusable, versioned architecture patterns:',\n 'patterns: []',\n '',\n ].join('\\n');\n}\n\nfunction codePackageJson(name: string, version: string): string {\n const pkg = {\n name,\n version,\n private: true,\n scripts: {\n build: 'esbuild pack.ts --bundle --platform=node --packages=external --format=cjs --outfile=pack.cjs',\n },\n dependencies: {\n '@wairon/sdk': SDK_VERSION,\n },\n devDependencies: {\n esbuild: '^0.21.0',\n typescript: '^5.0.0',\n },\n };\n return `${JSON.stringify(pkg, null, 2)}\\n`;\n}\n\nfunction codeTsconfig(): string {\n const tsconfig = {\n compilerOptions: {\n target: 'ES2020',\n module: 'CommonJS',\n moduleResolution: 'node',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n declaration: false,\n noEmit: true,\n },\n include: ['pack.ts'],\n };\n return `${JSON.stringify(tsconfig, null, 2)}\\n`;\n}\n\nfunction codeEntry(name: string, version: string): string {\n const code = slug(name).toUpperCase().replace(/-/g, '_');\n return [\n \"import { defineRule } from '@wairon/sdk';\",\n \"import type { RuleContext, Finding } from '@wairon/sdk';\",\n '',\n 'const exampleRule = defineRule({',\n ` name: '${slug(name)}-example',`,\n \" description: 'Example architectural rule. Replace with your own doctrine.',\",\n ` codes: ['${code}_EXAMPLE'],`,\n ' check(ctx: RuleContext): Finding[] {',\n ' const findings: Finding[] = [];',\n ' for (const component of ctx.components) {',\n ' // Inspect the spec tree and push findings as needed.',\n ' void component;',\n ' }',\n ' return findings;',\n ' },',\n '});',\n '',\n 'export default {',\n ` name: '${name}',`,\n ` version: '${version}',`,\n ' rules: [exampleRule],',\n '};',\n '',\n ].join('\\n');\n}\n\nfunction readme(name: string, kind: string, entry: string): string {\n return [\n `# ${name}`,\n '',\n `A wairon ${kind} pack.`,\n '',\n `- Envelope: \\`wairon-pack.yaml\\``,\n `- Entry: \\`${entry}\\``,\n '',\n 'Build an installable `.wpack` archive with `wairon pack build`.',\n '',\n ].join('\\n');\n}\n\nfunction skillStub(name: string): string {\n return [\n '---',\n `name: ${name}`,\n `description: ${name} authoring skill (stub).`,\n '---',\n '',\n `# ${name}`,\n '',\n 'Describe when this skill applies and what it guides.',\n '',\n ].join('\\n');\n}\n\nfunction slug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { zipSync, unzipSync, type Zippable } from 'fflate';\nimport type { ArchiveEntryMeta, PackFile } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Pack Archive Adapter (pack_archive_adapter_impl) — the ONLY zip-library + fs\n// I/O boundary of the SDK. Technology: fflate (pure-JS ZIP, no native deps).\n//\n// Acts only on already-validated inputs: it makes no path-safety or format\n// decisions (that is the codec's job). Enumeration reads sizes WITHOUT\n// inflating so the codec can enforce zip-bomb / size caps before any bytes are\n// decompressed.\n// ---------------------------------------------------------------------------\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', '.hg', '.svn']);\n\n/**\n * Enumerate every entry's metadata (path, compressed + uncompressed size, kind)\n * WITHOUT decompressing any bytes, so the codec can enforce caps before\n * inflation.\n */\nexport function listEntries(archive: Uint8Array): ArchiveEntryMeta[] {\n // Step 1: read the central directory via the zip library, mapping each record\n // to ArchiveEntryMeta without inflating any data. fflate's filter reports\n // {name, size (compressed), originalSize (uncompressed)} for every entry;\n // returning false skips decompression. Symlink detection reads the central\n // directory's external attributes (fflate's metadata omits the unix mode).\n const symlinks = detectSymlinkNames(archive);\n const metas: ArchiveEntryMeta[] = [];\n unzipSync(archive, {\n filter: (info): boolean => {\n metas.push({\n path: info.name,\n uncompressedSize: info.originalSize,\n compressedSize: info.size,\n kind: classifyKind(info.name, symlinks),\n });\n return false;\n },\n });\n // Step 2: return the entry metadata list.\n return metas;\n}\n\n/** Decompress and return the bytes of a single named entry. */\nexport function inflateEntry(archive: Uint8Array, entryPath: string): Uint8Array {\n // Step 1: locate the named entry and inflate only it.\n const inflated = unzipSync(archive, { filter: (info): boolean => info.name === entryPath });\n const bytes = inflated[entryPath];\n if (!bytes) throw new Error(`archive entry not found: ${entryPath}`);\n // Step 2: return the entry's decompressed bytes.\n return bytes;\n}\n\n/** Deflate a set of files (the envelope + pack contents) into a single ZIP buffer. */\nexport function assembleArchive(files: PackFile[]): Uint8Array {\n // Step 1: add each file to a zip container (deflating) and finalize.\n const zippable: Zippable = {};\n for (const file of files) zippable[file.path] = file.contents;\n const bytes = zipSync(zippable);\n // Step 2: return the archive bytes.\n return bytes;\n}\n\n/** Read a source pack directory recursively into a file map (POSIX paths + bytes). */\nexport function readPackDir(dir: string): PackFile[] {\n // Step 1: walk the directory recursively, reading each file into\n // { path: POSIX-relative, contents } (skipping node_modules and VCS dirs).\n const files: PackFile[] = [];\n walkPackDir(dir, dir, files);\n // Step 2: return the file map.\n return files;\n}\n\n/** Write a file map as a directory tree under destDir, creating parent directories. */\nexport function writeTree(destDir: string, files: PackFile[]): void {\n // Step 1: write each approved file.\n for (const file of files) {\n // Step 2 (writeEnd): create parent directories and write the file's bytes.\n const absolute = path.join(destDir, file.path);\n fs.mkdirSync(path.dirname(absolute), { recursive: true });\n fs.writeFileSync(absolute, file.contents);\n }\n // Step 3: done.\n}\n\n// --- helpers ---------------------------------------------------------------\n\nfunction classifyKind(name: string, symlinks: Set<string>): string {\n if (symlinks.has(name)) return 'symlink';\n if (name.endsWith('/')) return 'dir';\n return 'file';\n}\n\nfunction walkPackDir(root: string, current: string, out: PackFile[]): void {\n for (const entry of fs.readdirSync(current, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name)) continue;\n walkPackDir(root, path.join(current, entry.name), out);\n } else if (entry.isFile()) {\n const absolute = path.join(current, entry.name);\n const relative = path.relative(root, absolute).split(path.sep).join('/');\n out.push({ path: relative, contents: fs.readFileSync(absolute) });\n }\n }\n}\n\n// Best-effort central-directory scan for symlink entries (unix S_IFLNK in the\n// external file attributes). fflate's high-level metadata omits the unix mode,\n// so the codec's symlink rejection needs this. Any parse trouble yields an\n// empty set — no worse than fflate alone, and confinement/size caps still apply.\nfunction detectSymlinkNames(archive: Uint8Array): Set<string> {\n const names = new Set<string>();\n try {\n const eocd = findEocd(archive);\n if (eocd < 0) return names;\n let p = readU32(archive, eocd + 16); // central directory offset\n const count = readU16(archive, eocd + 10);\n const decoder = new TextDecoder();\n for (let i = 0; i < count; i++) {\n if (readU32(archive, p) !== 0x02014b50) break; // central file header sig\n const versionMadeBy = readU16(archive, p + 4);\n const nameLen = readU16(archive, p + 28);\n const extraLen = readU16(archive, p + 30);\n const commentLen = readU16(archive, p + 32);\n const externalAttrs = readU32(archive, p + 38);\n const name = decoder.decode(archive.subarray(p + 46, p + 46 + nameLen));\n if ((versionMadeBy >> 8) === 3) { // unix host\n const unixMode = (externalAttrs >>> 16) & 0xffff;\n if ((unixMode & 0o170000) === 0o120000) names.add(name);\n }\n p += 46 + nameLen + extraLen + commentLen;\n }\n } catch {\n return names;\n }\n return names;\n}\n\nfunction findEocd(buf: Uint8Array): number {\n const minRecord = 22;\n const lowerBound = Math.max(0, buf.length - (minRecord + 0xffff));\n for (let i = buf.length - minRecord; i >= lowerBound; i--) {\n if (readU32(buf, i) === 0x06054b50) return i;\n }\n return -1;\n}\n\nfunction readU16(buf: Uint8Array, off: number): number {\n return buf[off] | (buf[off + 1] << 8);\n}\n\nfunction readU32(buf: Uint8Array, off: number): number {\n return (buf[off] | (buf[off + 1] << 8) | (buf[off + 2] << 16) | (buf[off + 3] << 24)) >>> 0;\n}\n","// ---------------------------------------------------------------------------\n// Rule-authoring contract (the code-pack compile target).\n//\n// Code packs are written against `@wairon/sdk`, never against wairon core. This\n// is a small, stable, hand-authored facade — deliberately NOT core's fat\n// RuleContext. `defineRule` returns the rule unchanged (identity + type\n// inference); the runtime shape `{ name, description?, codes: string[], check }`\n// is exactly what the core extension loader duck-types.\n// ---------------------------------------------------------------------------\n\n/** Severity of a finding a pack rule emits. */\nexport type RuleSeverity = 'error' | 'warning';\n\n/** A single issue a pack rule reports about the spec tree. */\nexport interface Finding {\n /** Pack-local issue code (surfaced namespaced by wairon, e.g. `<PACK>_<CODE>`). */\n code: string;\n /** 'error' | 'warning'. */\n severity: RuleSeverity;\n /** Human-readable explanation of the violation. */\n message: string;\n /** The spec id the finding is anchored to (optional). */\n specId?: string;\n}\n\n/**\n * A read-only spec node as seen by a pack rule: its id/name plus arbitrary\n * further fields (kept open so the facade stays stable as the spec model grows).\n */\nexport interface RuleSpecNode {\n id: string;\n name?: string;\n [key: string]: unknown;\n}\n\n/**\n * The minimal, stable view of the spec tree a code-pack rule inspects. A rule\n * reads these collections and returns findings — it never mutates state and\n * never reaches into wairon core internals.\n */\nexport interface RuleContext {\n /** The L0 system spec. */\n system: RuleSpecNode;\n /** All L1 subsystem specs. */\n subsystems: RuleSpecNode[];\n /** All L2 component specs. */\n components: RuleSpecNode[];\n /** All L3 interface specs. */\n interfaces: RuleSpecNode[];\n /** All L4 implementation specs. */\n implementations: RuleSpecNode[];\n /** All shared type/value-object specs. */\n types: RuleSpecNode[];\n}\n\n/**\n * A programmatic conformance rule shipped by a code pack. Its runtime shape —\n * `{ name, description?, codes: string[], check }` — is what wairon's extension\n * loader duck-types when it loads a `pack.cjs`.\n */\nexport interface SddRule {\n /** Stable rule id (kebab-case), e.g. \"my-portal-transport\". */\n name: string;\n /** One-line description of what the rule enforces and why. */\n description?: string;\n /** The issue codes this rule can emit. */\n codes: string[];\n /** Inspect the spec tree and return findings (empty when clean). */\n check(ctx: RuleContext): Finding[];\n}\n\n/**\n * Author an SddRule with full type inference. Returns the rule unchanged — it\n * exists purely so code packs get typed authoring without importing anything\n * from wairon core.\n */\nexport function defineRule(rule: SddRule): SddRule {\n return rule;\n}\n"],"mappings":"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","names":["exports","module","buildPack","buildTreeArchive","extractPack","extractTreeArchive","inspectArchive","inspectTreeArchive","readPack","scaffoldPack","path","import_js_yaml","yamlLoad","yamlDump","path","import_js_yaml","import_crypto","SUPPORTED_FORMAT_VERSION","yamlLoad","validateEnvelope","yamlDump","isSymlinkOrNonRegular","isStructurallyUnsafePath","rejectUnsafe","normalizeRelPath","escapesDestination","pathDepth","compressionRatio","sha256","canonicalDigestBytes","isBelow","parseSemverCore","relative","slug","yamlLoad","scaffoldPack","buildPack","inspectArchive","readPack","extractPack","buildTreeArchive","inspectTreeArchive","extractTreeArchive"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wairon/sdk",
|
|
3
|
-
"version": "6.7.4-dev.
|
|
3
|
+
"version": "6.7.4-dev.8",
|
|
4
4
|
"description": "Experimental: wairon pack-archive (.wpack) format authority and authoring toolkit — scaffold, build, inspect, and safely extract wairon extension packs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wairon",
|