skilld-harness 3.6.5 → 3.6.7

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/README.md CHANGED
@@ -41,6 +41,7 @@ const result = await skillHarness.run({
41
41
  ```
42
42
 
43
43
  Every run returns a tagged `Ok` or `Err` value.
44
+ A `PackageSkill` run whose destination already holds the Skill runs `update-package-skill`, which tests only what the release changed. Without one it runs `generate-package-skill`.
44
45
  The input tag sets the `Ok` value: `PackageSkill` and `ProjectSkill` return a `GeneratedSkill`, and `ReviewSkill` returns a `SkillReview`.
45
46
  Both `Ok` and `Err` carry a `report`, so a failed run still reports its cost.
46
47
  `report.usage` holds input, cached input, and output tokens.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/harness.ts"],"mappings":";;UAGiB;WACN;WACA;;KAGC;WAEC;WACA;;WAGA;WACA;WACA;;KAGD;WAEC;WACA,QAAQ;WACR,aAAa;;WAGb;WACA;WACA,aAAa;;WAGb;WACA;;UAGI;WACN;WACA;WACA;WACA;WACA;WACA;;;UAIM;;WAEN;;WAEA;WACA;;;KAIC;WACK;WAA4B;;WAE9B;WACA;WACA;WACA;WACA;;WAGA;WACA;WACA;WACA,OAAO;;UAGL;WACN,SAAS;;;;;WAKT,WAAW,OAAO;;UAGZ;WACN;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA,OAAO,cAAc;WACrB,gBAAgB,cAAc;;UAGxB;WACN;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA,UAAU,cAAc;;KAGvB;WACK;WAA+B;;WAEjC;WACA;WACA,UAAU,cAAc;WACxB;;WAEE;WAA8B;WAA0B;;WACxD;WAA+B;WAA0B,QAAQ;;WACjE;WAAmC;WAA0B;;WAC7D;WAA6B;WAA0B;;WACvD;WAAkC;WAA0B;WAAuB;;WACnF;WAA4B;;;UAG5B;WACN,cAAc;WACd,cAAc;WACd,aAAa;;;;;;UAOP;;WAEN,OAAO;;WAEP;;;;;WAKA,UAAU;;KAGT,eAAe,YAAY,mBAAmB;WACzC;WAAqB,OAAO,eAAe;WAAe,QAAQ;;WAClE;WAAsB,OAAO;WAAwB,QAAQ;;UAE7D;WACN,MAAM,YAAY,UAAU,OAAO,KAAK,UAAU,oBAAoB,QAAQ,eAAe;;UAGvF;WACN,SAAS;;WAET,SAAS;;WAET,gBAAgB;WAChB,eAAe,QAAQ;;WAEvB,SAAS,gBAAgB,MAAM,SAAS,OAAO,gBAAgB,QAAQ;;wBC6HlE,mBAAmB,SAAS,4BAA4B"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/harness.ts"],"mappings":";;UAGiB;WACN;WACA;;KAGC;WAEC;WACA;;WAGA;WACA;WACA;;KAGD;WAEC;WACA,QAAQ;WACR,aAAa;;WAGb;WACA;WACA,aAAa;;WAGb;WACA;;UAGI;WACN;WACA;WACA;WACA;WACA;WACA;;;UAIM;;WAEN;;WAEA;WACA;;;KAIC;WACK;WAA4B;;WAE9B;WACA;WACA;WACA;WACA;;WAGA;WACA;WACA;WACA,OAAO;;UAGL;WACN,SAAS;;;;;WAKT,WAAW,OAAO;;UAGZ;WACN;WACA;;UAGM;WACN;WACA;WACA;;UAGM;WACN;WACA;WACA;WACA,OAAO,cAAc;WACrB,gBAAgB,cAAc;;UAGxB;WACN;WACA;WACA;WACA;;UAGM;WACN;WACA;WACA,UAAU,cAAc;;KAGvB;WACK;WAA+B;;WAEjC;WACA;WACA,UAAU,cAAc;WACxB;;WAEE;WAA8B;WAA0B;;WACxD;WAA+B;WAA0B,QAAQ;;WACjE;WAAmC;WAA0B;;WAC7D;WAA6B;WAA0B;;WACvD;WAAkC;WAA0B;WAAuB;;WACnF;WAA4B;;;UAG5B;WACN,cAAc;WACd,cAAc;WACd,aAAa;;;;;;UAOP;;WAEN,OAAO;;WAEP;;;;;WAKA,UAAU;;KAGT,eAAe,YAAY,mBAAmB;WACzC;WAAqB,OAAO,eAAe;WAAe,QAAQ;;WAClE;WAAsB,OAAO;WAAwB,QAAQ;;UAE7D;WACN,MAAM,YAAY,UAAU,OAAO,KAAK,UAAU,oBAAoB,QAAQ,eAAe;;UAGvF;WACN,SAAS;;WAET,SAAS;;WAET,gBAAgB;WAChB,eAAe,QAAQ;;WAEvB,SAAS,gBAAgB,MAAM,SAAS,OAAO,gBAAgB,QAAQ;;wBCkIlE,mBAAmB,SAAS,4BAA4B"}
package/dist/index.mjs CHANGED
@@ -1240,7 +1240,7 @@ async function prepareRun(input, policy, fetchClient, signal) {
1240
1240
  message: "Skill run was cancelled."
1241
1241
  });
1242
1242
  return source._tag === "Err" ? source : ok({
1243
- skillName: "generate-package-skill",
1243
+ skillName: packageSkillName(current.value),
1244
1244
  outputName: input.destination.name,
1245
1245
  source: source.value,
1246
1246
  sourceDir: "",
@@ -1265,7 +1265,7 @@ async function prepareRun(input, policy, fetchClient, signal) {
1265
1265
  });
1266
1266
  const source = await collectHostDirectory(packageDir, policy, packageDir, signal);
1267
1267
  return source._tag === "Err" ? source : ok({
1268
- skillName: "generate-package-skill",
1268
+ skillName: packageSkillName(current.value),
1269
1269
  outputName: input.destination.name,
1270
1270
  source: source.value,
1271
1271
  sourceDir: "",
@@ -1273,6 +1273,9 @@ async function prepareRun(input, policy, fetchClient, signal) {
1273
1273
  destination: input.destination
1274
1274
  });
1275
1275
  }
1276
+ function packageSkillName(current) {
1277
+ return current === void 0 ? "generate-package-skill" : "update-package-skill";
1278
+ }
1276
1279
  function requestContent(skill) {
1277
1280
  const request = skill.files?.find((file) => file.path === "assets/harness-request.md");
1278
1281
  if (!request) throw new Error(`Harness request asset is missing for ${skill.name}.`);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["invalid","invalid","unavailable"],"sources":["../src/internal/result.ts","../src/internal/input.ts","../src/internal/output/collect.ts","../src/internal/output/promote.ts","../src/internal/output/project.ts","../src/internal/output/validate.ts","../src/internal/source/host.ts","../src/internal/source/archive.ts","../src/internal/source/npm.ts","../src/harness.ts"],"sourcesContent":["export type Result<T, E>\n = | { readonly _tag: 'Ok', readonly value: T }\n | { readonly _tag: 'Err', readonly error: E }\n\nexport const ok = <T>(value: T): Result<T, never> => ({ _tag: 'Ok', value })\nexport const err = <E>(error: E): Result<never, E> => ({ _tag: 'Err', error })\n","import type { SkillOutputPolicy, SkillRun, SkillRunError } from '../types.ts'\nimport type { Result } from './result.ts'\nimport { resolve } from 'node:path'\nimport { isSkillName, resolveWithin } from './paths.ts'\nimport { err, ok } from './result.ts'\n\nfunction invalid(message: string): Result<never, SkillRunError> {\n return err({ _tag: 'InvalidInput', message })\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0\n}\n\nexport function parseSkillRun(input: SkillRun): Result<SkillRun, SkillRunError> {\n if (!input || typeof input !== 'object' || !('_tag' in input))\n return invalid('Skill run input must be an object with a tag.')\n\n if (input._tag === 'PackageSkill') {\n if (!input.source || !input.destination)\n return invalid('Package Skill input is incomplete.')\n if (!isNonEmptyString(input.destination.rootDir) || !isSkillName(input.destination.name))\n return invalid('Package Skill destination is invalid.')\n if (input.source._tag === 'NpmPackage') {\n if (!isNonEmptyString(input.source.spec))\n return invalid('npm package spec is required.')\n return ok({\n _tag: 'PackageSkill',\n source: { _tag: 'NpmPackage', spec: input.source.spec },\n destination: { rootDir: resolve(input.destination.rootDir), name: input.destination.name },\n })\n }\n if (input.source._tag === 'LocalPackage') {\n if (!isNonEmptyString(input.source.rootDir) || !isNonEmptyString(input.source.packageDir))\n return invalid('Local package paths are required.')\n if (resolveWithin(input.source.rootDir, input.source.packageDir) === null)\n return invalid('Local package directory must stay inside its root directory.')\n return ok({\n _tag: 'PackageSkill',\n source: {\n _tag: 'LocalPackage',\n rootDir: resolve(input.source.rootDir),\n packageDir: input.source.packageDir,\n },\n destination: { rootDir: resolve(input.destination.rootDir), name: input.destination.name },\n })\n }\n return invalid('Package source tag is invalid.')\n }\n\n if (input._tag === 'ProjectSkill') {\n if (!isNonEmptyString(input.projectDir) || !input.destination)\n return invalid('Project Skill input is incomplete.')\n if (!isNonEmptyString(input.destination.rootDir) || !isSkillName(input.destination.name))\n return invalid('Project Skill destination is invalid.')\n return ok({\n _tag: 'ProjectSkill',\n projectDir: resolve(input.projectDir),\n destination: { rootDir: resolve(input.destination.rootDir), name: input.destination.name },\n })\n }\n\n if (input._tag === 'ReviewSkill') {\n if (!isNonEmptyString(input.skillDir))\n return invalid('Skill review directory is required.')\n return ok({ _tag: 'ReviewSkill', skillDir: resolve(input.skillDir) })\n }\n\n return invalid('Skill run tag is invalid.')\n}\n\nexport function parseOutputPolicy(policy: SkillOutputPolicy): SkillOutputPolicy {\n for (const [name, value] of Object.entries(policy)) {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new TypeError(`${name} must be a positive integer.`)\n }\n return Object.freeze(policy)\n}\n","import type { SkillOutputPolicy, SkillRunError } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { HarnessAgentSandboxConfig } from '@ai-sdk/harness/agent'\nimport { normalizeOutputPath } from '../paths.ts'\nimport { err, ok } from '../result.ts'\n\nexport type SandboxSession = Parameters<NonNullable<HarnessAgentSandboxConfig['onSession']>>[0]['session']\n\nexport interface CollectedFile {\n readonly path: string\n readonly content: Uint8Array\n}\n\nconst invalid = (message: string, issues: ReadonlyArray<string>): Result<never, SkillRunError> =>\n err({ _tag: 'InvalidSkill', message, issues })\n\nconst inventory = async (\n sandbox: SandboxSession,\n outputDir: string,\n signal?: AbortSignal,\n): Promise<Result<ReadonlyArray<{ type: string, path: string, size: number }>, SkillRunError>> => {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n const command = 'find -P \"$SKILLD_OUTPUT\" -mindepth 1 -printf \\'%y\\\\0%P\\\\0%s\\\\0\\''\n const result = await Promise.resolve().then(() => sandbox.run({\n command,\n env: { LC_ALL: 'C', SKILLD_OUTPUT: outputDir },\n abortSignal: signal,\n })).catch(error => error as Error)\n if (result instanceof Error)\n return invalid('Harness output cannot be inspected.', [result.message])\n if (result.exitCode !== 0)\n return invalid('Harness output directory is missing.', [result.stderr.trim() || 'No output directory.'])\n\n const fields = result.stdout.split('\\0')\n if (fields.at(-1) === '')\n fields.pop()\n if (fields.length % 3 !== 0)\n return invalid('Harness output inventory is invalid.', ['File inventory has an incomplete entry.'])\n\n const entries: Array<{ type: string, path: string, size: number }> = []\n for (let index = 0; index < fields.length; index += 3) {\n const type = fields[index]\n const path = fields[index + 1]\n const size = Number(fields[index + 2])\n if (!type || !path || !Number.isSafeInteger(size) || size < 0)\n return invalid('Harness output inventory is invalid.', ['File inventory has invalid fields.'])\n entries.push({ type, path, size })\n }\n return ok(entries)\n}\n\nexport const collectSandboxOutput = async (\n sandbox: SandboxSession,\n outputDir: string,\n policy: SkillOutputPolicy,\n signal?: AbortSignal,\n): Promise<Result<ReadonlyArray<CollectedFile>, SkillRunError>> => {\n const before = await inventory(sandbox, outputDir, signal)\n if (before._tag === 'Err')\n return before\n\n const files: CollectedFile[] = []\n const seen = new Set<string>()\n let totalBytes = 0\n for (const entry of before.value) {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n const path = normalizeOutputPath(entry.path)\n if (path === null)\n return invalid('Harness output contains an invalid path.', [entry.path])\n if (entry.type === 'd')\n continue\n if (entry.type !== 'f')\n return invalid('Harness output contains a linked or special entry.', [path])\n if (seen.has(path))\n return invalid('Harness output contains duplicate paths.', [path])\n if (files.length >= policy.maxOutputFiles)\n return invalid('Harness output contains too many files.', [`Limit: ${policy.maxOutputFiles}`])\n if (entry.size > policy.maxOutputFileBytes)\n return invalid('Harness output contains an oversized file.', [path])\n if (totalBytes + entry.size > policy.maxOutputBytes)\n return invalid('Harness output exceeds the total byte limit.', [`Limit: ${policy.maxOutputBytes}`])\n\n const content = await Promise.resolve().then(() => sandbox.readBinaryFile({ path: `${outputDir}/${path}`, abortSignal: signal })).catch(error => error as Error)\n if (content instanceof Error) {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n return invalid('Harness output cannot be read.', [path, content.message])\n }\n if (content === null || content.byteLength !== entry.size)\n return invalid('Harness output changed during collection.', [path])\n seen.add(path)\n files.push({ path, content: Uint8Array.from(content) })\n totalBytes += content.byteLength\n }\n\n const after = await inventory(sandbox, outputDir, signal)\n if (after._tag === 'Err')\n return after\n if (JSON.stringify(before.value) !== JSON.stringify(after.value))\n return invalid('Harness output changed during collection.', ['File inventory changed.'])\n\n files.sort((left, right) => left.path.localeCompare(right.path))\n return ok(files)\n}\n","import type { GeneratedSkill, SkillRunError, SourceAttempt } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { CollectedFile } from './collect.ts'\nimport { randomUUID } from 'node:crypto'\nimport { lstat, mkdir, open, realpath, rename, rm, rmdir, unlink, writeFile } from 'node:fs/promises'\nimport { dirname, join, resolve } from 'node:path'\nimport { err, ok } from '../result.ts'\n\nfunction pathError(message: string, path: string): Result<never, SkillRunError> {\n return err({ _tag: 'UnsafeOutputPath', message, path })\n}\n\nconst missing = Symbol('missing')\n\n/** A Skill at its destination, and the cleanup problems left behind. */\nexport interface PromotedSkill {\n readonly skill: GeneratedSkill\n readonly warnings: ReadonlyArray<string>\n}\n\nasync function statOrMissing(path: string) {\n return lstat(path).catch(error => (error as NodeJS.ErrnoException).code === 'ENOENT' ? missing : Promise.reject(error))\n}\n\nexport const promoteSkill = async (\n rootDir: string,\n name: string,\n files: ReadonlyArray<CollectedFile>,\n attempts: ReadonlyArray<SourceAttempt>,\n): Promise<Result<PromotedSkill, SkillRunError>> => {\n const root = resolve(rootDir)\n let rootStat = await statOrMissing(root).catch(error => error as Error)\n if (rootStat instanceof Error)\n return pathError('Output root cannot be inspected.', root)\n let createdRoot = false\n if (rootStat === missing) {\n const parent = dirname(root)\n const parentStat = await statOrMissing(parent).catch(error => error as Error)\n if (parentStat instanceof Error || parentStat === missing || !parentStat.isDirectory() || parentStat.isSymbolicLink())\n return pathError('Output root parent must be an existing directory.', parent)\n const canonicalParent = await realpath(parent).catch(error => error as Error)\n if (canonicalParent instanceof Error || canonicalParent !== parent)\n return pathError('Output root parent must not pass through a symbolic link.', parent)\n const created = await mkdir(root, { mode: 0o700 }).then(() => true, error => error as NodeJS.ErrnoException)\n if (created instanceof Error && created.code !== 'EEXIST')\n return pathError('Output root cannot be created.', root)\n createdRoot = created === true\n rootStat = await statOrMissing(root).catch(error => error as Error)\n }\n if (rootStat instanceof Error || rootStat === missing || !rootStat.isDirectory() || rootStat.isSymbolicLink())\n return pathError('Output root must be a directory, not a symbolic link.', root)\n const canonicalRoot = await realpath(root).catch(error => error as Error)\n if (canonicalRoot instanceof Error)\n return pathError('Output root cannot be resolved.', root)\n if (canonicalRoot !== root)\n return pathError('Output root must not pass through a symbolic link.', root)\n\n const target = join(root, name)\n const targetStat = await statOrMissing(target).catch(error => error as Error)\n if (targetStat instanceof Error)\n return pathError('Output path cannot be inspected.', target)\n if (targetStat !== missing && (!targetStat.isDirectory() || targetStat.isSymbolicLink()))\n return pathError('Output path must be a directory, not a symbolic link.', target)\n\n const lockPath = join(root, `.skilld-${name}.lock`)\n const lock = await open(lockPath, 'wx').catch(error => error as NodeJS.ErrnoException)\n if (lock instanceof Error) {\n if (lock.code === 'EEXIST')\n return err({ _tag: 'OutputBusy', message: 'Another Skill run owns this output path.', path: target })\n return err({ _tag: 'PromotionFailed', message: 'Output lock could not be created.', path: target, cause: lock })\n }\n\n const nonce = randomUUID()\n const staging = join(root, `.skilld-${name}-${nonce}.next`)\n const backup = join(root, `.skilld-${name}-${nonce}.previous`)\n let movedCurrent = false\n let promoted = false\n let failureMessage = 'Skill output could not be promoted.'\n let failureCause: unknown\n\n try {\n await mkdir(staging, { mode: 0o700 })\n for (const file of files) {\n const destination = join(staging, file.path)\n await mkdir(dirname(destination), { recursive: true, mode: 0o700 })\n await writeFile(destination, file.content, { flag: 'wx', mode: 0o600 })\n }\n\n if (targetStat !== missing) {\n await rename(target, backup)\n movedCurrent = true\n }\n await rename(staging, target)\n promoted = true\n }\n catch (cause) {\n failureCause = cause\n if (movedCurrent && !promoted) {\n const current = await statOrMissing(target).catch(error => error as Error)\n if (current instanceof Error) {\n failureMessage = 'Skill output rollback could not inspect its destination.'\n failureCause = new AggregateError([cause, current])\n }\n if (current === missing) {\n const rollback = await rename(backup, target).catch(error => error as Error)\n if (rollback instanceof Error) {\n failureMessage = 'Skill output rollback failed.'\n failureCause = new AggregateError([cause, rollback])\n }\n }\n }\n }\n\n const lockCleanupErrors: unknown[] = []\n await lock.close().catch(error => lockCleanupErrors.push(error))\n await unlink(lockPath).catch(error => lockCleanupErrors.push(error))\n\n if (promoted) {\n const warnings: string[] = []\n if (lockCleanupErrors.length > 0) {\n const detail = lockCleanupErrors.map(error => error instanceof Error ? error.message : String(error)).join('; ')\n warnings.push(`Output lock cleanup failed at ${lockPath}: ${detail}`)\n }\n if (movedCurrent) {\n const backupCleanup = await rm(backup, { recursive: true }).catch(error => error as Error)\n if (backupCleanup instanceof Error)\n warnings.push(`Previous Skill cleanup failed at ${backup}: ${backupCleanup.message}`)\n }\n return ok({\n skill: {\n _tag: 'GeneratedSkill',\n name,\n outputDir: target,\n files: files.map(file => ({ path: file.path, bytes: file.content.byteLength })),\n sourceAttempts: attempts,\n },\n warnings,\n })\n }\n\n const cleanupErrors = [...lockCleanupErrors]\n await rm(staging, { recursive: true, force: true }).catch(error => cleanupErrors.push(error))\n if (createdRoot)\n await rmdir(root).catch(error => cleanupErrors.push(error))\n const causes = failureCause === undefined ? cleanupErrors : [failureCause, ...cleanupErrors]\n const cause = causes.length <= 1 ? causes[0] : new AggregateError(causes, 'Skill output cleanup failed.')\n return err({ _tag: 'PromotionFailed', message: failureMessage, path: target, cause })\n}\n","/** A search command the Agent can repeat, matched on whole words. */\nconst searchCommand = /\\b(?:git grep|grep|rg)\\b/\n\n/** Inline code spans, which is where a Skill writes its file pointers. */\nconst inlineCode = /`([^`\\n]+)`/g\n\n/** Fenced blocks, which hold commands rather than pointers. */\nconst fencedBlock = /```[^\\n]*\\n[\\s\\S]*?```/g\n\n/**\n * A Skill may report a file the project lacks, such as a missing entry point.\n * A sentence that denies a path states a fact about the project, not a pointer.\n * A sentence that tells the Agent to create a file gives a task, not a pointer.\n * The check reads whole paragraphs, so a hard-wrapped denial still covers the\n * code spans in its own sentence.\n */\nconst denial = /\\b(no|not|none|never|absent|missing|lacks|without|instead|rather|empty|undeclared|unavailable|nothing)\\b|\\bdoes ?n[o']t\\b/i\n\nconst creation = /\\b(?:copy|create|write|generate)\\b/i\n\nfunction fencedBlocks(markdown: string): ReadonlyArray<string> {\n return markdown.match(fencedBlock) ?? []\n}\n\n/**\n * Prose paragraphs, with fenced commands removed so a command never reads as a\n * pointer. A soft-wrapped sentence keeps its words together: the lines of a\n * paragraph join before any check runs.\n */\nfunction proseParagraphs(markdown: string): ReadonlyArray<string> {\n return markdown\n .replace(fencedBlock, '')\n .split(/\\n[ \\t]*\\n/)\n .map(paragraph => paragraph.replace(/\\n/g, ' ').trim())\n .filter(paragraph => paragraph.length > 0)\n}\n\n/**\n * Extensions a real file pointer carries. A token ending elsewhere, such as\n * the `.0` in a version, carries no path shape.\n */\nconst pathExtension = /\\.(?:md|mdx|json|jsonc|ts|tsx|mts|cts|js|mjs|cjs|jsx|vue|svelte|txt|yml|yaml|toml|html|css|scss|rs|py|go|sh|lock|env|csv|xml)$/i\n\n/** A release number such as `20.19.0` or `v20` states a version, never a path. */\nconst versionShape = /^v?\\d+(?:\\.\\d+)*$/i\n\n/** A product name such as `Node.js` or `node.js` names a tool, never a file. */\nconst productName = /^[A-Za-z][A-Za-z0-9_]*\\.[A-Za-z0-9]+$/\n\n/**\n * A token counts as a file pointer only when it cannot be anything else.\n * A false pointer fails a correct Skill, so every rule here excludes rather than includes.\n */\nfunction pathCandidate(token: string): string | null {\n if (token.length === 0 || /\\s/.test(token))\n return null\n // A flag, a variable, a comment, or a placeholder is never a pointer.\n if (/^[-$#<{[]/.test(token))\n return null\n // A URL, a package specifier, or a shell construct is never a pointer.\n if (token.includes('://') || /[()|;&\"'@:]/.test(token))\n return null\n const trimmed = token.replace(/^\\.\\//, '').replace(/\\/+$/, '')\n if (trimmed.length === 0 || trimmed.startsWith('..'))\n return null\n // A version, a product name, or a numbered reference such as `HTTP/2` is never a pointer.\n if (versionShape.test(trimmed) || productName.test(trimmed) || /\\/\\d+$/.test(trimmed))\n return null\n // A pointer carries a slash-qualified path or a known file extension.\n if (!trimmed.includes('/') && !pathExtension.test(trimmed))\n return null\n return trimmed\n}\n\n/** The literal prefix of a glob, which is the part a real path must start with. */\nfunction literalPrefix(candidate: string): string {\n const wildcard = candidate.search(/[*?]/)\n if (wildcard === -1)\n return candidate\n const cut = candidate.slice(0, wildcard).replace(/[^/]*$/, '')\n return cut.replace(/\\/+$/, '')\n}\n\nfunction resolves(candidate: string, known: ReadonlySet<string>): boolean {\n if (known.has(candidate))\n return true\n const prefix = literalPrefix(candidate)\n if (prefix.length === 0)\n return true\n for (const path of known) {\n // A known template such as `.env.example` implies the file it is copied to.\n if (path.startsWith(`${candidate}.`))\n return true\n // A directory pointer resolves when the project holds a file under it.\n if (path === prefix || path.startsWith(`${prefix}/`))\n return true\n }\n return false\n}\n\nexport interface ProjectSkillInput {\n /** The generated SKILL.md text. */\n readonly markdown: string\n /** Project-relative paths the Harness prepared for the Agent. */\n readonly projectPaths: ReadonlyArray<string>\n /** Output-relative paths the Skill writes beside SKILL.md. */\n readonly outputPaths: ReadonlyArray<string>\n}\n\n/**\n * Check that a project Skill points at files the project contains and gives a\n * search the Agent can repeat. The Agent cannot verify its own pointers.\n *\n * The Harness hides generated directories from the Agent, so a pointer at one is\n * invention like any other. A sentence that states a path is missing, or that\n * tells the Agent to create one, passes: it reports a fact or gives a task, not\n * a pointer. The sentence may wrap across prose lines within its paragraph.\n */\nexport function checkProjectSkill(input: ProjectSkillInput): ReadonlyArray<string> {\n const issues: string[] = []\n const known = new Set([...input.projectPaths, ...input.outputPaths])\n const unknown = new Set<string>()\n\n for (const paragraph of proseParagraphs(input.markdown)) {\n if (denial.test(paragraph) || creation.test(paragraph))\n continue\n for (const match of paragraph.matchAll(inlineCode)) {\n const candidate = pathCandidate(match[1]!.trim())\n if (candidate !== null && !resolves(candidate, known))\n unknown.add(candidate)\n }\n }\n\n for (const path of [...unknown].sort())\n issues.push(`SKILL.md points at a path the project does not contain: ${path}.`)\n\n const inline = [...input.markdown.matchAll(inlineCode)].map(match => match[1]!)\n const commands = [...fencedBlocks(input.markdown), ...inline].join('\\n')\n if (!searchCommand.test(commands))\n issues.push('SKILL.md must give the Agent at least one search command it can repeat.')\n\n return issues\n}\n","import type { SkillReview, SkillReviewFinding, SkillRunError } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { CollectedFile } from './collect.ts'\nimport { isScalar, parseDocument, Scalar } from 'yaml'\nimport { isSkillName, normalizeOutputPath } from '../paths.ts'\nimport { checkProjectSkill } from './project.ts'\nimport { err, ok } from '../result.ts'\n\n/** Both generation Skills say the frontmatter must contain only these fields. */\nconst allowedFrontmatter = new Set(['name', 'description'])\n\n/** `generate-package-skill`: \"Keep `SKILL.md` under 500 lines.\" */\nconst packageSkillLineLimit = 500\n\n/** `generate-package-skill`: \"Write at most eight reference files.\" */\nconst packageSkillReferenceLimit = 8\n\n/**\n * Skill loaders and viewers parse frontmatter with different YAML parsers.\n * A plain one-line description without these characters reads the same in all of them.\n */\nconst riskyDescription = /[\"`%]/\n\n/**\n * The Skill that produced the output decides which of its written rules apply.\n * A project Skill also carries the project paths its pointers must resolve to.\n */\nexport type GenerationContract\n = | { readonly _tag: 'PackageSkill' }\n | { readonly _tag: 'ProjectSkill', readonly projectPaths: ReadonlyArray<string> }\n\nconst invalid = (issues: ReadonlyArray<string>): Result<never, SkillRunError> =>\n err({ _tag: 'InvalidSkill', message: 'Skill output failed deterministic checks.', issues })\n\nfunction decodeText(content: Uint8Array): string | null {\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(content)\n }\n catch {\n return null\n }\n}\n\n/** Markdown link targets, inline or reference style, without anchors or titles. */\nfunction linkTargets(markdown: string): ReadonlySet<string> {\n const targets = new Set<string>()\n const add = (raw: string): void => {\n const target = raw.trim().replace(/^<|>$/g, '').split(/\\s/)[0]!.replace(/[#?].*$/, '').replace(/^\\.\\//, '')\n if (target.length > 0)\n targets.add(target)\n }\n for (const match of markdown.matchAll(/\\]\\(([^)\\n]+)\\)/g))\n add(match[1]!)\n for (const match of markdown.matchAll(/^\\s*\\[[^\\]\\n]+\\]:\\s*(\\S+)/gm))\n add(match[1]!)\n for (const match of markdown.matchAll(/`([^`\\n]+)`/g))\n add(match[1]!)\n return targets\n}\n\nfunction lineCount(text: string): number {\n const lines = text.split('\\n')\n return lines.at(-1) === '' ? lines.length - 1 : lines.length\n}\n\n/** The written structure rules of the generation Skills, checked on the output. */\nfunction structureIssues(markdown: string, files: ReadonlyArray<CollectedFile>, contract: GenerationContract): ReadonlyArray<string> {\n const issues: string[] = []\n const referencePaths = files.map(file => file.path).filter(path => path.startsWith('references/')).sort()\n if (contract._tag === 'PackageSkill') {\n const lines = lineCount(markdown)\n if (lines >= packageSkillLineLimit)\n issues.push(`SKILL.md must stay under ${packageSkillLineLimit} lines; it has ${lines}.`)\n if (referencePaths.length > packageSkillReferenceLimit)\n issues.push(`A package Skill may write at most ${packageSkillReferenceLimit} reference files; it wrote ${referencePaths.length}.`)\n }\n const linked = linkTargets(markdown)\n for (const path of referencePaths) {\n if (!linked.has(path))\n issues.push(`SKILL.md must link ${path}.`)\n }\n return issues\n}\n\nexport const validateGeneratedSkill = (\n name: string,\n files: ReadonlyArray<CollectedFile>,\n contract: GenerationContract,\n): Result<void, SkillRunError> => {\n const issues: string[] = []\n const skillFiles = files.filter(file => file.path === 'SKILL.md')\n if (skillFiles.length !== 1)\n return invalid(['Output must contain exactly one SKILL.md file.'])\n\n const source = decodeText(skillFiles[0]!.content)\n if (source === null)\n return invalid(['SKILL.md must contain valid UTF-8 text.'])\n if (contract._tag === 'ProjectSkill') {\n issues.push(...checkProjectSkill({\n markdown: source,\n projectPaths: contract.projectPaths,\n outputPaths: files.map(file => file.path),\n }))\n }\n const match = source.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/)\n if (!match)\n return invalid(['SKILL.md must start with YAML frontmatter.'])\n if (match[2]?.trim().length === 0)\n issues.push('SKILL.md instructions must not be empty.')\n\n const document = parseDocument(match[1]!, { uniqueKeys: true })\n for (const error of document.errors)\n issues.push(`Frontmatter: ${error.message}`)\n for (const warning of document.warnings)\n issues.push(`Frontmatter: ${warning.message}`)\n\n const value = document.errors.length === 0 ? document.toJS() as unknown : null\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n issues.push('Frontmatter must be a mapping.')\n return invalid(issues)\n }\n\n const frontmatter = value as Record<string, unknown>\n for (const key of Object.keys(frontmatter)) {\n if (!allowedFrontmatter.has(key))\n issues.push(`Frontmatter field is not supported: ${key}`)\n }\n if (frontmatter.name !== name)\n issues.push('Frontmatter name must match the Skill directory name.')\n if (typeof frontmatter.name !== 'string' || !isSkillName(frontmatter.name))\n issues.push('Frontmatter name is invalid.')\n if (typeof frontmatter.description !== 'string' || frontmatter.description.trim().length === 0 || frontmatter.description.length > 1024)\n issues.push('Frontmatter description must contain 1 to 1024 characters.')\n const description = document.get('description', true)\n if (typeof frontmatter.description === 'string' && (!isScalar(description) || description.type !== Scalar.PLAIN || riskyDescription.test(frontmatter.description)))\n issues.push('Frontmatter description must be one plain line without double quotes, backticks, or %. Name symptoms in plain words.')\n issues.push(...structureIssues(source, files, contract))\n\n return issues.length === 0 ? ok(undefined) : invalid(issues)\n}\n\nconst findingLevels = new Set(['error', 'warning', 'note'])\n\nexport const validateSkillReview = (\n files: ReadonlyArray<CollectedFile>,\n): Result<SkillReview, SkillRunError> => {\n if (files.length !== 1 || files[0]?.path !== 'review.json')\n return invalid(['Review output must contain only review.json.'])\n\n let value: unknown\n try {\n const source = decodeText(files[0].content)\n if (source === null)\n return invalid(['review.json must contain valid UTF-8 text.'])\n value = JSON.parse(source)\n }\n catch {\n return invalid(['review.json must contain valid JSON.'])\n }\n if (!value || typeof value !== 'object' || Array.isArray(value))\n return invalid(['review.json must contain an object.'])\n\n const review = value as Record<string, unknown>\n if (Object.keys(review).some(key => key !== 'summary' && key !== 'findings'))\n return invalid(['review.json contains unsupported fields.'])\n if (typeof review.summary !== 'string' || review.summary.trim().length === 0)\n return invalid(['Review summary is required.'])\n if (!Array.isArray(review.findings))\n return invalid(['Review findings must be an array.'])\n\n const findings: SkillReviewFinding[] = []\n for (const item of review.findings) {\n if (!item || typeof item !== 'object' || Array.isArray(item))\n return invalid(['Each review finding must be an object.'])\n const finding = item as Record<string, unknown>\n if (Object.keys(finding).some(key => !['level', 'path', 'message', 'fix'].includes(key)))\n return invalid(['A review finding contains unsupported fields.'])\n if (typeof finding.level !== 'string' || !findingLevels.has(finding.level))\n return invalid(['A review finding level is invalid.'])\n if (typeof finding.path !== 'string' || normalizeOutputPath(finding.path) === null)\n return invalid(['A review finding path is invalid.'])\n if (typeof finding.message !== 'string' || finding.message.trim().length === 0 || typeof finding.fix !== 'string' || finding.fix.trim().length === 0)\n return invalid(['A review finding is incomplete.'])\n findings.push(finding as unknown as SkillReviewFinding)\n }\n\n return ok({ _tag: 'SkillReview', summary: review.summary, findings })\n}\n","import type { SkillOutputPolicy, SkillRunError, SourceAttempt } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport { constants } from 'node:fs'\nimport { lstat, open, opendir, realpath } from 'node:fs/promises'\nimport { join, relative, resolve, sep } from 'node:path'\nimport { err, ok } from '../result.ts'\n\nexport interface PreparedFile {\n readonly path: string\n readonly content: Uint8Array\n}\n\n/** A source file the Harness left out because it exceeds the file byte limit. */\nexport interface SkippedSourceFile {\n readonly path: string\n readonly bytes: number\n}\n\nexport interface PreparedSource {\n readonly files: ReadonlyArray<PreparedFile>\n /** Files left out for size. The Agent and the caller both see this list. */\n readonly skippedFiles: ReadonlyArray<SkippedSourceFile>\n readonly attempts: ReadonlyArray<SourceAttempt>\n readonly npmResolution?: {\n readonly package: string\n readonly version: string\n }\n}\n\n/** One warning per skipped file, in the words the result reports. */\nexport function skippedFileWarnings(skipped: ReadonlyArray<SkippedSourceFile>, policy: SkillOutputPolicy): ReadonlyArray<string> {\n return skipped.map(file =>\n `Source file ${file.path} was left out: ${file.bytes} bytes exceeds the ${policy.maxSourceFileBytes} byte file limit.`)\n}\n\nconst ignoredNames = new Set([\n '.git',\n '.hg',\n '.next',\n '.nuxt',\n '.output',\n '.skilld',\n '.turbo',\n 'coverage',\n 'dist',\n 'node_modules',\n 'target',\n])\n\nexport async function collectHostDirectory(directory: string, policy: SkillOutputPolicy, sourceLabel = directory, signal?: AbortSignal): Promise<Result<PreparedSource, SkillRunError>> {\n const root = resolve(directory)\n const unavailable = (message: string, cause?: unknown): Result<never, SkillRunError> => err({\n _tag: 'SourceUnavailable',\n message,\n attempts: [{ source: sourceLabel, status: 'skipped', reason: message }],\n cause,\n })\n const cancelled = (): Result<never, SkillRunError> => err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n if (signal?.aborted)\n return cancelled()\n const rootStat = await lstat(root).catch(error => error as NodeJS.ErrnoException)\n if (rootStat instanceof Error)\n return unavailable('Source directory is unavailable.', rootStat)\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink())\n return unavailable('Source path must be a directory, not a symbolic link.')\n const canonicalRoot = await realpath(root).catch(error => error as NodeJS.ErrnoException)\n if (canonicalRoot instanceof Error)\n return unavailable('Source directory cannot be resolved.', canonicalRoot)\n if (canonicalRoot !== root)\n return unavailable('Source path must not pass through a symbolic link.')\n\n const files: PreparedFile[] = []\n const skippedFiles: SkippedSourceFile[] = []\n let totalBytes = 0\n const relativePath = (absolute: string): string => relative(root, absolute).split(sep).join('/')\n /** An entry-level failure names the entry, so the caller can find and fix it. */\n const entryUnavailable = (absolute: string, message: string, cause?: unknown, fix?: string): Result<never, SkillRunError> =>\n unavailable(`${message}: ${relativePath(absolute)}.${fix === undefined ? '' : ` ${fix}`}`, cause)\n\n const walk = async (current: string): Promise<Result<void, SkillRunError>> => {\n if (signal?.aborted)\n return cancelled()\n const canonicalCurrent = await realpath(current).catch(error => error as NodeJS.ErrnoException)\n if (canonicalCurrent instanceof Error || canonicalCurrent !== current)\n return unavailable('Source directory changed during collection.', canonicalCurrent instanceof Error ? canonicalCurrent : undefined)\n const directoryHandle = await opendir(current).catch(error => error as NodeJS.ErrnoException)\n if (directoryHandle instanceof Error)\n return unavailable('Source directory cannot be read.', directoryHandle)\n\n for await (const entry of directoryHandle) {\n if (signal?.aborted)\n return cancelled()\n if (ignoredNames.has(entry.name))\n continue\n const absolute = join(current, entry.name)\n const stat = await lstat(absolute).catch(error => error as NodeJS.ErrnoException)\n if (stat instanceof Error)\n return entryUnavailable(absolute, 'Source entry cannot be read', stat)\n if (stat.isSymbolicLink())\n return entryUnavailable(absolute, 'Source contains a symbolic link', undefined, 'Remove the link, or pass a clean export such as a `git archive` of the directory.')\n if (stat.isDirectory()) {\n const nested = await walk(absolute)\n if (nested._tag === 'Err')\n return nested\n continue\n }\n if (!stat.isFile())\n return entryUnavailable(absolute, 'Source contains a special file')\n\n const path = relativePath(absolute)\n const handle = await open(absolute, constants.O_RDONLY | constants.O_NOFOLLOW).catch(error => error as NodeJS.ErrnoException)\n if (handle instanceof Error)\n return entryUnavailable(absolute, 'Source file cannot be opened without following links', handle)\n const openedStat = await handle.stat().catch(error => error as NodeJS.ErrnoException)\n if (openedStat instanceof Error) {\n await handle.close()\n return entryUnavailable(absolute, 'Source file cannot be inspected', openedStat)\n }\n if (!openedStat.isFile() || openedStat.dev !== stat.dev || openedStat.ino !== stat.ino) {\n await handle.close()\n return entryUnavailable(absolute, 'Source file changed during collection')\n }\n if (openedStat.size > policy.maxSourceFileBytes) {\n await handle.close()\n skippedFiles.push({ path, bytes: openedStat.size })\n continue\n }\n if (files.length >= policy.maxSourceFiles) {\n await handle.close()\n return unavailable('Source contains too many files.')\n }\n if (totalBytes + openedStat.size > policy.maxSourceBytes) {\n await handle.close()\n return unavailable('Source exceeds the total byte limit.')\n }\n\n const content = await handle.readFile().catch(error => error as NodeJS.ErrnoException)\n await handle.close()\n if (content instanceof Error)\n return entryUnavailable(absolute, 'Source file cannot be read', content)\n if (content.byteLength !== openedStat.size)\n return entryUnavailable(absolute, 'Source file changed during collection')\n if (signal?.aborted)\n return cancelled()\n files.push({ path, content })\n totalBytes += content.byteLength\n }\n return ok(undefined)\n }\n\n const walked = await walk(root)\n if (walked._tag === 'Err')\n return walked\n if (files.length === 0)\n return unavailable('Source directory has no usable files.')\n\n files.sort((left, right) => left.path.localeCompare(right.path))\n skippedFiles.sort((left, right) => left.path.localeCompare(right.path))\n return ok({ files, skippedFiles, attempts: [{ source: sourceLabel, status: 'used' }] })\n}\n","import type { SkillOutputPolicy, SkillRunError } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { PreparedFile, SkippedSourceFile } from './host.ts'\nimport { Readable } from 'node:stream'\nimport { createGunzip } from 'node:zlib'\nimport { normalizeOutputPath } from '../paths.ts'\nimport { err, ok } from '../result.ts'\n\nconst blockBytes = 512\n\nexport type ArchiveLayout = 'npm' | 'github'\n\ninterface PendingEntry {\n readonly kind: 'directory' | 'file' | 'metadata' | 'skip'\n readonly path?: string\n readonly metadataType?: 'long-path' | 'pax'\n readonly size: number\n remaining: number\n padding: number\n readonly chunks: Array<Buffer<ArrayBufferLike>>\n}\n\nfunction unavailable(message: string, cause?: unknown): Result<never, SkillRunError> {\n return err({ _tag: 'SourceUnavailable', message, attempts: [], cause })\n}\n\nfunction readString(buffer: Uint8Array, start: number, length: number): string {\n const bytes = buffer.subarray(start, start + length)\n const zero = bytes.indexOf(0)\n return Buffer.from(zero === -1 ? bytes : bytes.subarray(0, zero)).toString('utf8').trim()\n}\n\nfunction readOctal(buffer: Uint8Array, start: number, length: number): number | null {\n const value = readString(buffer, start, length).replace(/^\\s+|\\s+$/g, '')\n if (!/^[0-7]+$/.test(value))\n return null\n const parsed = Number.parseInt(value, 8)\n return Number.isSafeInteger(parsed) ? parsed : null\n}\n\nfunction hasValidChecksum(header: Uint8Array): boolean {\n const expected = readOctal(header, 148, 8)\n if (expected === null)\n return false\n let actual = 0\n for (let index = 0; index < header.byteLength; index += 1)\n actual += index >= 148 && index < 156 ? 32 : header[index]!\n return actual === expected\n}\n\nfunction parsePaxPath(content: Uint8Array): string | null {\n const text = Buffer.from(content).toString('utf8')\n let offset = 0\n let path: string | null = null\n while (offset < text.length) {\n const space = text.indexOf(' ', offset)\n if (space === -1)\n return null\n const length = Number.parseInt(text.slice(offset, space), 10)\n if (!Number.isSafeInteger(length) || length <= 0 || offset + length > text.length)\n return null\n const record = text.slice(space + 1, offset + length - 1)\n const equals = record.indexOf('=')\n if (equals !== -1 && record.slice(0, equals) === 'path')\n path = record.slice(equals + 1)\n offset += length\n }\n return path\n}\n\nfunction archivePath(value: string, layout: ArchiveLayout): string | null {\n const normalized = normalizeOutputPath(value)\n if (normalized === null)\n return null\n const segments = normalized.split('/')\n if (layout === 'npm') {\n if (segments[0] !== 'package' || segments.length < 2)\n return null\n }\n else if (segments.length < 2) {\n return null\n }\n return normalizeOutputPath(segments.slice(1).join('/'))\n}\n\nfunction entryContent(entry: PendingEntry): Buffer<ArrayBufferLike> {\n return entry.chunks.length === 1\n ? entry.chunks[0]!\n : Buffer.concat(entry.chunks, entry.size)\n}\n\nexport interface ExtractedArchive {\n readonly files: ReadonlyArray<PreparedFile>\n readonly skippedFiles: ReadonlyArray<SkippedSourceFile>\n}\n\nexport async function extractArchive(\n compressed: AsyncIterable<Uint8Array>,\n policy: SkillOutputPolicy,\n layout: ArchiveLayout,\n): Promise<Result<ExtractedArchive, SkillRunError>> {\n const source = Readable.from(compressed)\n const gunzip = createGunzip()\n source.on('error', error => gunzip.destroy(error))\n source.pipe(gunzip)\n const files: PreparedFile[] = []\n const skippedFiles: SkippedSourceFile[] = []\n const seen = new Set<string>()\n const maxArchiveBytes = policy.maxSourceBytes + (policy.maxSourceFiles + 2) * blockBytes * 2\n let archiveBytes = 0\n let fileEntries = 0\n let nextPath: string | null = null\n let pending: Buffer<ArrayBufferLike> = Buffer.alloc(0)\n let entry: PendingEntry | null = null\n let totalBytes = 0\n let ended = false\n\n try {\n for await (const value of gunzip) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value as Uint8Array)\n archiveBytes += chunk.byteLength\n if (archiveBytes > maxArchiveBytes)\n return unavailable('Source archive exceeds the uncompressed byte limit.')\n pending = pending.byteLength === 0 ? chunk : Buffer.concat([pending, chunk])\n\n while (pending.byteLength > 0) {\n if (ended) {\n if (pending.some(byte => byte !== 0))\n return unavailable('Source archive has data after its end marker.')\n pending = Buffer.alloc(0)\n break\n }\n\n if (entry !== null) {\n if (entry.remaining > 0) {\n const consumed = Math.min(entry.remaining, pending.byteLength)\n if (entry.kind === 'file' || entry.kind === 'metadata')\n entry.chunks.push(pending.subarray(0, consumed))\n pending = pending.subarray(consumed)\n entry.remaining -= consumed\n if (entry.remaining > 0)\n break\n }\n if (entry.padding > 0) {\n const consumed = Math.min(entry.padding, pending.byteLength)\n pending = pending.subarray(consumed)\n entry.padding -= consumed\n if (entry.padding > 0)\n break\n }\n\n if (entry.kind === 'metadata') {\n const content = entryContent(entry)\n nextPath = entry.metadataType === 'pax'\n ? parsePaxPath(content)\n : content.toString('utf8').replace(/\\0.*$/s, '').trim()\n if (nextPath === null || nextPath.length === 0)\n return unavailable('Source archive has invalid path metadata.')\n }\n else if (entry.kind === 'file' && entry.path) {\n files.push({ path: entry.path, content: Uint8Array.from(entryContent(entry)) })\n totalBytes += entry.size\n }\n entry = null\n continue\n }\n\n if (pending.byteLength < blockBytes)\n break\n const header = pending.subarray(0, blockBytes)\n pending = pending.subarray(blockBytes)\n if (header.every(byte => byte === 0)) {\n ended = true\n continue\n }\n if (!hasValidChecksum(header))\n return unavailable('Source archive has an invalid header checksum.')\n\n const size = readOctal(header, 124, 12)\n if (size === null)\n return unavailable('Source archive has an invalid entry size.')\n const name = readString(header, 0, 100)\n const prefix = readString(header, 345, 155)\n const headerPath = prefix.length > 0 ? `${prefix}/${name}` : name\n const type = String.fromCharCode(header[156] ?? 0)\n const padding = (blockBytes - size % blockBytes) % blockBytes\n\n if (type === 'x' || type === 'L') {\n if (size > policy.maxSourceFileBytes)\n return unavailable('Source archive path metadata exceeds the file byte limit.')\n entry = {\n kind: 'metadata',\n metadataType: type === 'x' ? 'pax' : 'long-path',\n size,\n remaining: size,\n padding,\n chunks: [],\n }\n continue\n }\n if (type === '5') {\n nextPath = null\n entry = { kind: 'directory', size, remaining: size, padding, chunks: [] }\n continue\n }\n if (type !== '0' && type !== '\\0')\n return unavailable(`Source archive contains a linked or special entry: ${nextPath ?? headerPath}.`)\n\n const path = archivePath(nextPath ?? headerPath, layout)\n nextPath = null\n if (path === null)\n return unavailable('Source archive contains an invalid path.')\n if (seen.has(path))\n return unavailable('Source archive contains duplicate paths.')\n seen.add(path)\n fileEntries += 1\n if (fileEntries > policy.maxSourceFiles)\n return unavailable('Source archive contains too many files.')\n if (size <= policy.maxSourceFileBytes && totalBytes + size > policy.maxSourceBytes)\n return unavailable('Source archive exceeds the total byte limit.')\n if (size > policy.maxSourceFileBytes)\n skippedFiles.push({ path, bytes: size })\n\n entry = {\n kind: size > policy.maxSourceFileBytes ? 'skip' : 'file',\n path,\n size,\n remaining: size,\n padding,\n chunks: [],\n }\n }\n }\n }\n catch (cause) {\n const message = cause instanceof Error ? cause.message : ''\n return unavailable(message.startsWith('Source archive ')\n ? message\n : 'Source archive is not valid gzip data.', cause)\n }\n\n if (entry !== null || pending.some(byte => byte !== 0) || !ended)\n return unavailable('Source archive ended before its final entry.')\n if (files.length === 0)\n return unavailable('Source archive has no usable files.')\n files.sort((left, right) => left.path.localeCompare(right.path))\n skippedFiles.sort((left, right) => left.path.localeCompare(right.path))\n return ok({ files, skippedFiles })\n}\n","import type { Hash } from 'node:crypto'\nimport type { SkillOutputPolicy, SkillRunError, SourceAttempt } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { ExtractedArchive } from './archive.ts'\nimport type { PreparedFile, PreparedSource } from './host.ts'\nimport { createHash } from 'node:crypto'\nimport { posix } from 'node:path'\nimport { err, ok } from '../result.ts'\nimport { extractArchive } from './archive.ts'\n\ninterface NpmDist {\n readonly tarball: string\n readonly integrity?: string\n readonly shasum?: string\n}\n\ninterface NpmRepository {\n readonly type?: string\n readonly url?: string\n}\n\ninterface NpmVersion {\n readonly version: string\n readonly dist: NpmDist\n readonly gitHead?: string\n readonly repository?: NpmRepository | string\n}\n\ninterface IntegrityVerifier {\n readonly update: (content: Uint8Array) => void\n readonly valid: () => boolean\n}\n\nconst packageSpecPattern = /^(@[^/@]+\\/[^/@]+|[^/@]+)(?:@(\\S+))?$/\nconst exactVersionPattern = /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?$/i\nconst gitCommitPattern = /^[0-9a-f]{40}$/i\nconst npmRequestTimeoutMs = 30_000\nconst npmRedirectLimit = 3\nconst packumentByteLimit = 10 * 1024 * 1024\n\nexport type FetchClient = (input: string | URL | Request, init?: RequestInit) => Promise<Response>\n\nfunction unavailable(message: string, attempts: ReadonlyArray<SourceAttempt>, cause?: unknown): Result<never, SkillRunError> {\n return err({ _tag: 'SourceUnavailable', message, attempts, cause })\n}\n\nfunction parsePackageSpec(spec: string): { name: string, version: string } | null {\n const match = spec.match(packageSpecPattern)\n return match?.[1] ? { name: match[1], version: match[2] ?? 'latest' } : null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction parseRepository(value: unknown): NpmRepository | string | undefined {\n if (typeof value === 'string')\n return value\n if (!isRecord(value))\n return undefined\n return {\n type: typeof value.type === 'string' ? value.type : undefined,\n url: typeof value.url === 'string' ? value.url : undefined,\n }\n}\n\nfunction parseVersion(packument: unknown, requested: string): { resolvedVersion: string, version: NpmVersion, repository?: NpmRepository | string } | null {\n if (!isRecord(packument) || !isRecord(packument['dist-tags']) || !isRecord(packument.versions))\n return null\n const tagged = packument['dist-tags'][requested]\n const resolvedVersion = typeof tagged === 'string' ? tagged : requested\n const value = packument.versions[resolvedVersion]\n if (!isRecord(value) || typeof value.version !== 'string' || !isRecord(value.dist) || typeof value.dist.tarball !== 'string')\n return null\n return {\n resolvedVersion,\n repository: parseRepository(packument.repository),\n version: {\n version: value.version,\n gitHead: typeof value.gitHead === 'string' ? value.gitHead : undefined,\n repository: parseRepository(value.repository),\n dist: {\n tarball: value.dist.tarball,\n integrity: typeof value.dist.integrity === 'string' ? value.dist.integrity : undefined,\n shasum: typeof value.dist.shasum === 'string' ? value.dist.shasum : undefined,\n },\n },\n }\n}\n\nasync function cancelBody(response: Response): Promise<void> {\n if (!response.body)\n return\n // A failed cleanup cannot replace the source failure.\n await response.body.cancel().catch(() => undefined)\n}\n\nfunction declaredBytes(response: Response): number | null {\n const value = response.headers.get('content-length')\n if (value === null || !/^\\d+$/.test(value))\n return null\n const bytes = Number(value)\n return Number.isSafeInteger(bytes) ? bytes : null\n}\n\nasync function* responseChunks(\n response: Response,\n maxBytes: number,\n limitMessage: string,\n onChunk: (content: Uint8Array) => void = () => {},\n): AsyncGenerator<Uint8Array> {\n const declared = declaredBytes(response)\n if (declared !== null && declared > maxBytes) {\n await cancelBody(response)\n throw new Error(limitMessage)\n }\n if (!response.body)\n return\n\n const reader = response.body.getReader()\n let complete = false\n let totalBytes = 0\n try {\n while (true) {\n const result = await reader.read()\n if (result.done) {\n complete = true\n return\n }\n totalBytes += result.value.byteLength\n if (totalBytes > maxBytes)\n throw new Error(limitMessage)\n onChunk(result.value)\n yield result.value\n }\n }\n finally {\n if (!complete) {\n // A failed cleanup cannot replace the source failure.\n await reader.cancel().catch(() => undefined)\n }\n reader.releaseLock()\n }\n}\n\nasync function readBoundedResponse(response: Response, maxBytes: number): Promise<Result<Uint8Array, SkillRunError>> {\n const chunks: Uint8Array[] = []\n let totalBytes = 0\n try {\n for await (const chunk of responseChunks(response, maxBytes, 'npm response exceeds the byte limit.')) {\n chunks.push(chunk)\n totalBytes += chunk.byteLength\n }\n }\n catch (cause) {\n return unavailable(cause instanceof Error ? cause.message : 'npm response cannot be read.', [], cause)\n }\n return ok(Uint8Array.from(Buffer.concat(chunks, totalBytes)))\n}\n\nasync function fetchWithRedirects(fetchClient: FetchClient, url: string, init: RequestInit = {}, signal?: AbortSignal): Promise<Result<Response, SkillRunError>> {\n const timeout = AbortSignal.timeout(npmRequestTimeoutMs)\n const requestSignal = signal ? AbortSignal.any([signal, timeout]) : timeout\n let current = url\n for (let redirects = 0; redirects <= npmRedirectLimit; redirects += 1) {\n const response = await fetchClient(current, { ...init, redirect: 'manual', signal: requestSignal }).catch(error => error as Error)\n if (response instanceof Error)\n return unavailable(timeout.aborted ? 'npm request timed out.' : 'npm request failed.', [], response)\n if (![301, 302, 303, 307, 308].includes(response.status))\n return ok(response)\n if (redirects === npmRedirectLimit) {\n await cancelBody(response)\n return unavailable('npm request exceeded the redirect limit.', [])\n }\n const location = response.headers.get('location')\n if (!location) {\n await cancelBody(response)\n return unavailable('npm redirect is missing its location.', [])\n }\n const redirected = await Promise.resolve().then(() => new URL(location, current)).catch(() => null)\n if (redirected === null) {\n await cancelBody(response)\n return unavailable('npm redirect location is invalid.', [])\n }\n if (redirected.protocol !== 'https:') {\n await cancelBody(response)\n return unavailable('npm redirect URL must use HTTPS.', [])\n }\n await cancelBody(response)\n current = redirected.href\n }\n return unavailable('npm request exceeded the redirect limit.', [])\n}\n\nfunction createIntegrityVerifier(dist: NpmDist): IntegrityVerifier | null {\n const values = dist.integrity?.split(/\\s+/).filter(Boolean) ?? []\n let expected = values.flatMap((value) => {\n const match = value.match(/^(sha(?:1|256|384|512))-([A-Za-z0-9+/=]+)$/)\n return match?.[1] && match[2] ? [{ algorithm: match[1], digest: match[2] }] : []\n })\n if (expected.length > 0) {\n const strength = { sha1: 1, sha256: 2, sha384: 3, sha512: 4 } as const\n const strongest = Math.max(...expected.map(value => strength[value.algorithm as keyof typeof strength]))\n expected = expected.filter(value => strength[value.algorithm as keyof typeof strength] === strongest)\n }\n if (values.length === 0 && dist.shasum && /^[0-9a-f]{40}$/i.test(dist.shasum))\n expected.push({ algorithm: 'sha1', digest: Buffer.from(dist.shasum, 'hex').toString('base64') })\n if (expected.length === 0)\n return null\n\n const hashes = new Map<string, Hash>()\n for (const value of expected)\n hashes.set(value.algorithm, createHash(value.algorithm))\n return {\n update(content) {\n for (const hash of hashes.values())\n hash.update(content)\n },\n valid() {\n const actual = new Map([...hashes].map(([algorithm, hash]) => [algorithm, hash.digest('base64')]))\n return expected.some(value => actual.get(value.algorithm) === value.digest)\n },\n }\n}\n\nfunction repositoryUrl(repository: NpmRepository | string | undefined): string | null {\n if (typeof repository === 'string')\n return repository\n return typeof repository?.url === 'string' ? repository.url : null\n}\n\nfunction githubArchiveUrl(repository: NpmRepository | string | undefined, gitHead: string | undefined): string | null {\n if (!gitHead || !gitCommitPattern.test(gitHead))\n return null\n const source = repositoryUrl(repository)\n if (source === null)\n return null\n const match = source.match(/^(?:(?:git\\+)?https?:\\/\\/(?:git@)?github\\.com\\/|git:\\/\\/github\\.com\\/|git@github\\.com:)([\\w.-]+)\\/([\\w.-]+?)(?:\\.git)?\\/?$/)\n if (!match?.[1] || !match[2])\n return null\n return `https://codeload.github.com/${encodeURIComponent(match[1])}/${encodeURIComponent(match[2])}/tar.gz/${gitHead}`\n}\n\nfunction skipped(source: string, reason: string): SourceAttempt {\n return { source, status: 'skipped', reason }\n}\n\nfunction used(source: string): SourceAttempt {\n return { source, status: 'used' }\n}\n\nfunction withAttempts(error: SkillRunError, attempts: ReadonlyArray<SourceAttempt>): Result<never, SkillRunError> {\n return error._tag === 'SourceUnavailable'\n ? unavailable(error.message, attempts, error.cause)\n : err(error)\n}\n\nfunction remainingPolicy(policy: SkillOutputPolicy, files: ReadonlyArray<PreparedFile>): SkillOutputPolicy | null {\n const usedBytes = files.reduce((total, file) => total + file.content.byteLength, 0)\n const maxSourceFiles = policy.maxSourceFiles - files.length\n const maxSourceBytes = policy.maxSourceBytes - usedBytes\n if (maxSourceFiles <= 0 || maxSourceBytes <= 0)\n return null\n return { ...policy, maxSourceFiles, maxSourceBytes }\n}\n\nasync function extractResponse(\n response: Response,\n policy: SkillOutputPolicy,\n layout: 'github' | 'npm',\n verifier?: IntegrityVerifier,\n): Promise<Result<ExtractedArchive, SkillRunError>> {\n return extractArchive(\n responseChunks(\n response,\n policy.maxSourceBytes,\n 'Source archive exceeds the compressed byte limit.',\n content => verifier?.update(content),\n ),\n policy,\n layout,\n )\n}\n\nexport async function prepareNpmPackage(spec: string, policy: SkillOutputPolicy, fetchClient: FetchClient, signal?: AbortSignal): Promise<Result<PreparedSource, SkillRunError>> {\n const parsed = parsePackageSpec(spec)\n if (parsed === null)\n return unavailable('npm package spec is invalid.', [])\n\n const attempts: SourceAttempt[] = []\n const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(parsed.name)}`\n const registryResponse = await fetchWithRedirects(fetchClient, registryUrl, {\n headers: { accept: 'application/vnd.npm.install-v1+json' },\n }, signal)\n if (registryResponse._tag === 'Err')\n return withAttempts(registryResponse.error, [skipped(registryUrl, registryResponse.error.message)])\n const response = registryResponse.value\n if (!response.ok) {\n await cancelBody(response)\n const message = `npm registry returned HTTP ${response.status}.`\n return unavailable(message, [skipped(registryUrl, message)])\n }\n\n const packumentBytes = await readBoundedResponse(response, packumentByteLimit)\n if (packumentBytes._tag === 'Err')\n return withAttempts(packumentBytes.error, [skipped(registryUrl, packumentBytes.error.message)])\n\n let packument: unknown\n try {\n packument = JSON.parse(Buffer.from(packumentBytes.value).toString('utf8')) as unknown\n }\n catch (cause) {\n const message = 'npm registry returned invalid package data.'\n return unavailable(message, [skipped(registryUrl, message)], cause)\n }\n\n const resolution = parseVersion(packument, parsed.version)\n if (resolution === null || !exactVersionPattern.test(resolution.resolvedVersion) || resolution.version.version !== resolution.resolvedVersion) {\n const message = 'npm package did not resolve to an exact version.'\n return unavailable(message, [skipped(registryUrl, message)])\n }\n const { repository, resolvedVersion, version } = resolution\n if (!version.dist.tarball.startsWith('https://')) {\n const message = 'npm package archive URL must use HTTPS.'\n return unavailable(message, [skipped(registryUrl, message)])\n }\n attempts.push(used(registryUrl))\n\n const fetchedArchive = await fetchWithRedirects(fetchClient, version.dist.tarball, {}, signal)\n if (fetchedArchive._tag === 'Err')\n return withAttempts(fetchedArchive.error, [...attempts, skipped(version.dist.tarball, fetchedArchive.error.message)])\n const archiveResponse = fetchedArchive.value\n if (!archiveResponse.ok) {\n await cancelBody(archiveResponse)\n const message = `npm package archive returned HTTP ${archiveResponse.status}.`\n return unavailable(message, [...attempts, skipped(version.dist.tarball, message)])\n }\n\n const verifier = createIntegrityVerifier(version.dist)\n if (verifier === null) {\n await cancelBody(archiveResponse)\n const message = 'npm package archive has no supported integrity value.'\n return unavailable(message, [...attempts, skipped(version.dist.tarball, message)])\n }\n const extracted = await extractResponse(archiveResponse, policy, 'npm', verifier)\n if (extracted._tag === 'Err')\n return withAttempts(extracted.error, [...attempts, skipped(version.dist.tarball, extracted.error.message)])\n if (!verifier.valid()) {\n const message = 'npm package archive integrity check failed.'\n return unavailable(message, [...attempts, skipped(version.dist.tarball, message)])\n }\n attempts.push(used(version.dist.tarball))\n let files = [...extracted.value.files]\n let skippedFiles = [...extracted.value.skippedFiles]\n\n const repositoryArchive = githubArchiveUrl(version.repository ?? repository, version.gitHead)\n const available = remainingPolicy(policy, files)\n if (repositoryArchive !== null && available === null) {\n attempts.push(skipped(repositoryArchive, 'Prepared package files reached the source limit.'))\n }\n else if (repositoryArchive !== null && available !== null) {\n const fetchedRepository = await fetchWithRedirects(fetchClient, repositoryArchive, {}, signal)\n if (fetchedRepository._tag === 'Err') {\n attempts.push(skipped(repositoryArchive, fetchedRepository.error.message))\n }\n else if (!fetchedRepository.value.ok) {\n const message = `GitHub source archive returned HTTP ${fetchedRepository.value.status}.`\n await cancelBody(fetchedRepository.value)\n attempts.push(skipped(repositoryArchive, message))\n }\n else {\n const repositoryFiles = await extractResponse(fetchedRepository.value, available, 'github')\n if (repositoryFiles._tag === 'Err') {\n attempts.push(skipped(repositoryArchive, repositoryFiles.error.message))\n }\n else {\n files = [\n ...files,\n ...repositoryFiles.value.files.map(file => ({ ...file, path: posix.join('repository', file.path) })),\n ]\n skippedFiles = [\n ...skippedFiles,\n ...repositoryFiles.value.skippedFiles.map(file => ({ ...file, path: posix.join('repository', file.path) })),\n ]\n attempts.push(used(repositoryArchive))\n }\n }\n }\n\n files.sort((left, right) => left.path.localeCompare(right.path))\n skippedFiles.sort((left, right) => left.path.localeCompare(right.path))\n return ok({\n files,\n skippedFiles,\n attempts,\n npmResolution: { package: parsed.name, version: resolvedVersion },\n })\n}\n","import type { HarnessV1NetworkSandboxSession, HarnessV1Skill } from '@ai-sdk/harness'\nimport type { CollectedFile, SandboxSession } from './internal/output/collect.ts'\nimport type { Result } from './internal/result.ts'\nimport type { PreparedSource } from './internal/source/host.ts'\nimport type { FetchClient } from './internal/source/npm.ts'\nimport type {\n CreateSkillHarnessOptions,\n GeneratedSkill,\n SkillDestination,\n SkillHarness,\n SkillOutputPolicy,\n SkillReview,\n SkillRun,\n SkillRunError,\n SkillRunEvent,\n SkillRunOptions,\n SkillRunReport,\n SkillRunResult,\n SkillRunUsage,\n} from './types.ts'\nimport { lstat, realpath } from 'node:fs/promises'\nimport { basename, join, posix, resolve } from 'node:path'\nimport { HarnessAgent } from '@ai-sdk/harness/agent'\nimport { parseOutputPolicy, parseSkillRun } from './internal/input.ts'\nimport { collectSandboxOutput } from './internal/output/collect.ts'\nimport { promoteSkill } from './internal/output/promote.ts'\nimport { validateGeneratedSkill, validateSkillReview } from './internal/output/validate.ts'\nimport { resolveWithin } from './internal/paths.ts'\nimport { err, ok } from './internal/result.ts'\nimport { collectHostDirectory, skippedFileWarnings } from './internal/source/host.ts'\nimport { prepareNpmPackage } from './internal/source/npm.ts'\nimport { DEFAULT_OUTPUT_POLICY, loadSkilldMaintainedSkill } from './skills.ts'\n\ninterface PreparedRun {\n readonly skillName: 'generate-package-skill' | 'generate-project-skill' | 'review-skill'\n readonly outputName: string\n readonly source: PreparedSource\n // Path under `input/source`. A reviewed Skill keeps its directory name, so\n // review-skill can compare that name with the frontmatter `name`.\n readonly sourceDir: string\n readonly current?: PreparedSource\n readonly destination?: SkillDestination\n}\n\ninterface ActiveSandbox {\n readonly sandbox: SandboxSession\n readonly workDir: string\n}\n\n/** The outcome of one Skill run before the Harness attaches its report. */\ntype RunOutcome = Result<GeneratedSkill | SkillReview, SkillRunError>\n\n/** Collects the cost of one Skill run and every warning beside its outcome. */\ninterface RunLog {\n /** Forwards an event to the caller and counts each finished step. */\n readonly emit: (event: SkillRunEvent) => void\n readonly warn: (warning: string) => void\n /** Replaces the counted steps with the totals the Agent reported at its end. */\n readonly settle: (usage: SkillRunUsage, steps: number) => void\n readonly report: () => SkillRunReport\n}\n\nfunction addCount(total: number | undefined, count: number | undefined): number | undefined {\n return total === undefined ? count : count === undefined ? total : total + count\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (typeof value === 'object' || typeof value === 'function')\n && value !== null\n && typeof (value as { then?: unknown }).then === 'function'\n}\n\nfunction createRunLog(onEvent: SkillRunOptions['onEvent']): RunLog {\n const warnings: string[] = []\n const eventFailures = new Set<string>()\n let usage: SkillRunUsage = { inputTokens: undefined, cachedInputTokens: undefined, outputTokens: undefined }\n let steps = 0\n // The Agent SDK drops callback errors, so surface them on the report instead.\n const fail = (cause: unknown) => {\n eventFailures.add(`onEvent failed: ${cause instanceof Error ? cause.message : String(cause)}`)\n }\n return {\n emit: (event) => {\n if (event._tag === 'StepFinish') {\n steps += 1\n usage = {\n inputTokens: addCount(usage.inputTokens, event.usage.inputTokens),\n cachedInputTokens: addCount(usage.cachedInputTokens, event.usage.cachedInputTokens),\n outputTokens: addCount(usage.outputTokens, event.usage.outputTokens),\n }\n }\n if (!onEvent)\n return\n try {\n const returned: unknown = onEvent(event)\n // An async listener or custom thenable would otherwise reject unhandled and can end the host process.\n if (isPromiseLike(returned))\n Promise.resolve(returned).catch(fail)\n }\n catch (cause) {\n fail(cause)\n }\n },\n warn: warning => warnings.push(warning),\n settle: (total, count) => {\n usage = total\n steps = count\n },\n report: () => ({ usage, steps, warnings: [...warnings, ...eventFailures] }),\n }\n}\n\n/** The fields this package reads from the Agent SDK usage report. */\ninterface AgentUsage {\n readonly inputTokens: number | undefined\n readonly inputTokenDetails: { readonly cacheReadTokens: number | undefined }\n readonly outputTokens: number | undefined\n}\n\nfunction toUsage(usage: AgentUsage): SkillRunUsage {\n return {\n inputTokens: usage.inputTokens,\n cachedInputTokens: usage.inputTokenDetails.cacheReadTokens,\n outputTokens: usage.outputTokens,\n }\n}\n\n/** An unknown count in any turn keeps the total unknown. */\nfunction sumUsage(a: SkillRunUsage, b: SkillRunUsage): SkillRunUsage {\n const sum = (x: number | undefined, y: number | undefined) => x === undefined || y === undefined ? undefined : x + y\n return { inputTokens: sum(a.inputTokens, b.inputTokens), cachedInputTokens: sum(a.cachedInputTokens, b.cachedInputTokens), outputTokens: sum(a.outputTokens, b.outputTokens) }\n}\n\n/** Turns the Agent gets to fix output that failed the deterministic checks, in the same session. */\nconst OUTPUT_REPAIR_TURNS = 2\n\nfunction repairRequest(outputPath: string, issues: ReadonlyArray<string>): string {\n return [\n `The Harness checked the output at \\`${outputPath}\\` and found these problems:`,\n '',\n ...issues.map(issue => `- ${issue}`),\n '',\n `Fix each problem in place. Write no files outside \\`${outputPath}\\`. Finish when the output passes these checks.`,\n ].join('\\n')\n}\n\nasync function prepareCurrentSkill(destination: SkillDestination, policy: SkillOutputPolicy, signal?: AbortSignal): Promise<Result<PreparedSource | undefined, SkillRunError>> {\n const root = resolve(destination.rootDir)\n const rootStat = await lstat(root).catch(error => error as NodeJS.ErrnoException)\n if (rootStat instanceof Error) {\n if (rootStat.code === 'ENOENT')\n return ok(undefined)\n return err({ _tag: 'UnsafeOutputPath', message: 'Output root cannot be inspected.', path: root })\n }\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink())\n return err({ _tag: 'UnsafeOutputPath', message: 'Output root must be a directory, not a symbolic link.', path: root })\n const canonicalRoot = await realpath(root).catch(error => error as Error)\n if (canonicalRoot instanceof Error || canonicalRoot !== root)\n return err({ _tag: 'UnsafeOutputPath', message: 'Output root must not pass through a symbolic link.', path: root })\n\n const target = join(root, destination.name)\n const targetStat = await lstat(target).catch(error => error as NodeJS.ErrnoException)\n if (targetStat instanceof Error) {\n if (targetStat.code === 'ENOENT')\n return ok(undefined)\n return err({ _tag: 'UnsafeOutputPath', message: 'Output path cannot be inspected.', path: target })\n }\n if (!targetStat.isDirectory() || targetStat.isSymbolicLink())\n return err({ _tag: 'UnsafeOutputPath', message: 'Output path must be a directory, not a symbolic link.', path: target })\n return collectHostDirectory(target, policy, 'current Skill', signal)\n}\n\nasync function prepareRun(input: SkillRun, policy: SkillOutputPolicy, fetchClient: FetchClient, signal?: AbortSignal): Promise<Result<PreparedRun, SkillRunError>> {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n\n const current = input._tag === 'ReviewSkill'\n ? ok(undefined)\n : await prepareCurrentSkill(input.destination, policy, signal)\n if (current._tag === 'Err')\n return current\n\n if (input._tag === 'ProjectSkill') {\n const source = await collectHostDirectory(input.projectDir, policy, input.projectDir, signal)\n return source._tag === 'Err'\n ? source\n : ok({ skillName: 'generate-project-skill', outputName: input.destination.name, source: source.value, sourceDir: '', current: current.value, destination: input.destination })\n }\n\n if (input._tag === 'ReviewSkill') {\n const source = await collectHostDirectory(input.skillDir, policy, input.skillDir, signal)\n return source._tag === 'Err'\n ? source\n : ok({ skillName: 'review-skill', outputName: 'review', source: source.value, sourceDir: basename(input.skillDir) })\n }\n\n if (input.source._tag === 'NpmPackage') {\n const source = await prepareNpmPackage(input.source.spec, policy, fetchClient, signal)\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n return source._tag === 'Err'\n ? source\n : ok({ skillName: 'generate-package-skill', outputName: input.destination.name, source: source.value, sourceDir: '', current: current.value, destination: input.destination })\n }\n\n const packageDir = resolveWithin(input.source.rootDir, input.source.packageDir)\n if (packageDir === null)\n return err({ _tag: 'InvalidInput', message: 'Local package directory must stay inside its root directory.' })\n const manifest = await lstat(join(packageDir, 'package.json')).catch(error => error as NodeJS.ErrnoException)\n if (manifest instanceof Error || !manifest.isFile() || manifest.isSymbolicLink()) {\n return err({\n _tag: 'SourceUnavailable',\n message: 'Local package directory must contain package.json.',\n attempts: [{ source: packageDir, status: 'skipped', reason: 'package.json is unavailable.' }],\n })\n }\n\n const source = await collectHostDirectory(packageDir, policy, packageDir, signal)\n return source._tag === 'Err'\n ? source\n : ok({ skillName: 'generate-package-skill', outputName: input.destination.name, source: source.value, sourceDir: '', current: current.value, destination: input.destination })\n}\n\nfunction requestContent(skill: HarnessV1Skill): string {\n const request = skill.files?.find(file => file.path === 'assets/harness-request.md')\n if (!request)\n throw new Error(`Harness request asset is missing for ${skill.name}.`)\n return request.content\n}\n\nfunction renderRequest(template: string, sourcePath: string, currentSkillPath: string, outputPath: string, skillName: string): string {\n return template\n .replaceAll('{{SOURCE_PATH}}', sourcePath)\n .replaceAll('{{CURRENT_SKILL_PATH}}', currentSkillPath)\n .replaceAll('{{OUTPUT_PATH}}', outputPath)\n .replaceAll('{{SKILL_NAME}}', skillName)\n}\n\nfunction sourcePathOf(active: ActiveSandbox, prepared: PreparedRun): string {\n return posix.join(active.workDir, 'input/source', prepared.sourceDir)\n}\n\nasync function writePreparedSource(active: ActiveSandbox, prepared: PreparedRun, signal?: AbortSignal): Promise<void> {\n const sourcePath = sourcePathOf(active, prepared)\n const reset = await active.sandbox.run({\n command: 'rm -rf -- \"$SKILLD_INPUT\" \"$SKILLD_OUTPUT\" && mkdir -p -- \"$SKILLD_INPUT\"',\n env: {\n SKILLD_INPUT: posix.join(active.workDir, 'input'),\n SKILLD_OUTPUT: posix.join(active.workDir, 'skilld-output'),\n },\n abortSignal: signal,\n })\n if (reset.exitCode !== 0)\n throw new Error(reset.stderr.trim() || 'Harness work directory cannot be prepared.')\n for (const file of prepared.source.files) {\n await active.sandbox.writeBinaryFile({\n path: posix.join(sourcePath, file.path),\n content: file.content,\n abortSignal: signal,\n })\n }\n for (const file of prepared.current?.files ?? []) {\n await active.sandbox.writeBinaryFile({\n path: posix.join(active.workDir, 'input/current-skill', file.path),\n content: file.content,\n abortSignal: signal,\n })\n }\n await active.sandbox.writeTextFile({\n path: posix.join(active.workDir, 'input/source-manifest.json'),\n content: `${JSON.stringify({\n sourceAttempts: prepared.source.attempts,\n skippedFiles: prepared.source.skippedFiles,\n npmResolution: prepared.source.npmResolution,\n hasCurrentSkill: prepared.current !== undefined,\n }, null, 2)}\\n`,\n abortSignal: signal,\n })\n}\n\nfunction agentError(cause: unknown, signal?: AbortSignal): SkillRunError {\n return signal?.aborted\n ? { _tag: 'Cancelled', message: 'Skill run was cancelled.' }\n : { _tag: 'AgentFailed', message: 'Harness Agent failed during the Skill run.', cause }\n}\n\nfunction toAgentError(cause: unknown, signal?: AbortSignal): RunOutcome {\n return err(agentError(cause, signal))\n}\n\nexport function createSkillHarness(options: CreateSkillHarnessOptions): SkillHarness {\n const policy = parseOutputPolicy({ ...DEFAULT_OUTPUT_POLICY, ...options.outputPolicy })\n const fetchClient: FetchClient = options.fetch ?? globalThis.fetch.bind(globalThis)\n const sandboxConfig = { ...options.sandboxConfig }\n const harness = options.harness\n const sandbox = options.sandbox\n\n return {\n // Each input tag maps to one Skill, and that Skill decides the value tag,\n // so the wide result is the narrowed result for this input.\n run: <Run extends SkillRun>(input: Run, runOptions: SkillRunOptions = {}) =>\n runSkill(input, runOptions) as Promise<SkillRunResult<Run['_tag']>>,\n }\n\n async function runSkill(input: SkillRun, runOptions: SkillRunOptions): Promise<SkillRunResult> {\n const log = createRunLog(runOptions.onEvent)\n const outcome = await runLogged(input, runOptions, log)\n const report = log.report()\n return outcome._tag === 'Ok'\n ? { _tag: 'Ok', value: outcome.value, report }\n : { _tag: 'Err', error: outcome.error, report }\n }\n\n async function runLogged(input: SkillRun, runOptions: SkillRunOptions, log: RunLog): Promise<RunOutcome> {\n const parsed = parseSkillRun(input)\n if (parsed._tag === 'Err')\n return parsed\n\n const prepared = await prepareRun(parsed.value, policy, fetchClient, runOptions.signal)\n if (prepared._tag === 'Err')\n return prepared\n for (const warning of skippedFileWarnings(prepared.value.source.skippedFiles, policy))\n log.warn(warning)\n\n const skill = await loadSkilldMaintainedSkill(prepared.value.skillName)\n // The Harness creates and owns the sandbox session, and hands it to the\n // Agent. The Agent never sees the provider, so it never destroys the\n // session itself, and the deprecated provider path stays unused.\n const sandboxSession = await sandbox.createSession({ abortSignal: runOptions.signal }).then(ok, cause => err(cause))\n if (sandboxSession._tag === 'Err')\n return toAgentError(sandboxSession.error, runOptions.signal)\n const result = await runAgent(prepared.value, skill, sandboxSession.value, log, runOptions.signal)\n const destroyed = await Promise.resolve(sandboxSession.value.destroy()).then(() => undefined, cause => cause as unknown)\n if (destroyed !== undefined)\n log.warn(`Sandbox session cleanup failed: ${destroyed instanceof Error ? destroyed.message : String(destroyed)}`)\n return result\n }\n\n async function runAgent(\n prepared: PreparedRun,\n skill: HarnessV1Skill,\n sandboxSession: HarnessV1NetworkSandboxSession,\n log: RunLog,\n signal?: AbortSignal,\n ): Promise<RunOutcome> {\n let active: ActiveSandbox | undefined\n const userOnSession = sandboxConfig.onSession\n const agent = new HarnessAgent({\n harness,\n skills: [skill],\n permissionMode: 'allow-all',\n sandboxConfig: {\n ...sandboxConfig,\n onSession: async (sessionOptions) => {\n active = { sandbox: sessionOptions.session, workDir: sessionOptions.sessionWorkDir }\n await writePreparedSource(active, prepared, signal)\n await userOnSession?.(sessionOptions)\n },\n },\n })\n\n const sessionResult = await agent.createSession({ sandboxSession, abortSignal: signal }).then(ok, cause => err(cause))\n if (sessionResult._tag === 'Err')\n return toAgentError(sessionResult.error, signal)\n const session = sessionResult.value\n\n try {\n if (!active)\n return err({ _tag: 'AgentFailed', message: 'Harness did not provide its sandbox session.' })\n const sourcePath = sourcePathOf(active, prepared)\n const currentSkillPath = posix.join(active.workDir, 'input/current-skill')\n const outputPath = posix.join(active.workDir, 'skilld-output', prepared.outputName)\n const prompt = renderRequest(requestContent(skill), sourcePath, currentSkillPath, outputPath, prepared.outputName)\n const outputSandbox = active.sandbox\n // Steps count across turns, so a repair turn continues the numbering.\n let step = 0\n let stepOffset = 0\n let usage: SkillRunUsage | undefined\n const turn = async (text: string): Promise<Result<void, SkillRunError>> => {\n const generated = await agent.generate({\n session,\n prompt: text,\n abortSignal: signal,\n onStepStart: (event) => {\n step = stepOffset + event.stepNumber\n log.emit({ _tag: 'StepStart', step })\n },\n onToolExecutionStart: ({ toolCall }) => {\n log.emit({ _tag: 'ToolCall', step, toolName: toolCall.toolName, toolCallId: toolCall.toolCallId, input: toolCall.input })\n },\n onStepEnd: (result) => {\n log.emit({ _tag: 'StepFinish', step: stepOffset + result.stepNumber, finishReason: result.finishReason, usage: toUsage(result.usage) })\n },\n }).then(ok, cause => err(cause))\n if (generated._tag === 'Err')\n return err(agentError(generated.error, signal))\n const turnUsage = toUsage(generated.value.totalUsage)\n usage = usage ? sumUsage(usage, turnUsage) : turnUsage\n stepOffset += generated.value.steps.length\n log.settle(usage, stepOffset)\n return signal?.aborted ? err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' }) : ok(undefined)\n }\n const check = async (): Promise<Result<ReadonlyArray<CollectedFile>, SkillRunError>> => {\n const collected = await collectSandboxOutput(outputSandbox, outputPath, policy, signal)\n if (collected._tag === 'Err')\n return collected\n const validated = prepared.skillName === 'review-skill'\n ? validateSkillReview(collected.value)\n : validateGeneratedSkill(\n prepared.outputName,\n collected.value,\n prepared.skillName === 'generate-project-skill'\n ? { _tag: 'ProjectSkill', projectPaths: prepared.source.files.map(file => file.path) }\n : { _tag: 'PackageSkill' },\n )\n return validated._tag === 'Err' ? validated : ok(collected.value)\n }\n\n const first = await turn(prompt)\n if (first._tag === 'Err')\n return first\n let checked = await check()\n // A failed check goes back to the Agent, which still holds its context, instead of failing the run.\n for (let repair = 1; repair <= OUTPUT_REPAIR_TURNS && checked._tag === 'Err' && checked.error._tag === 'InvalidSkill'; repair++) {\n log.warn(`Output checks failed; repair turn ${repair} of ${OUTPUT_REPAIR_TURNS}: ${checked.error.issues.join(' ')}`)\n const repaired = await turn(repairRequest(outputPath, checked.error.issues))\n if (repaired._tag === 'Err')\n return repaired\n checked = await check()\n }\n if (checked._tag === 'Err')\n return checked\n const collected = checked\n\n if (prepared.skillName === 'review-skill')\n return validateSkillReview(collected.value)\n\n if (!prepared.destination)\n return err({ _tag: 'InvalidInput', message: 'Skill destination is required.' })\n const promoted = await promoteSkill(\n prepared.destination.rootDir,\n prepared.destination.name,\n collected.value,\n prepared.source.attempts,\n )\n if (promoted._tag === 'Err')\n return promoted\n for (const warning of promoted.value.warnings)\n log.warn(warning)\n return ok(promoted.value.skill)\n }\n finally {\n await session.destroy()\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["invalid","invalid","unavailable"],"sources":["../src/internal/result.ts","../src/internal/input.ts","../src/internal/output/collect.ts","../src/internal/output/promote.ts","../src/internal/output/project.ts","../src/internal/output/validate.ts","../src/internal/source/host.ts","../src/internal/source/archive.ts","../src/internal/source/npm.ts","../src/harness.ts"],"sourcesContent":["export type Result<T, E>\n = | { readonly _tag: 'Ok', readonly value: T }\n | { readonly _tag: 'Err', readonly error: E }\n\nexport const ok = <T>(value: T): Result<T, never> => ({ _tag: 'Ok', value })\nexport const err = <E>(error: E): Result<never, E> => ({ _tag: 'Err', error })\n","import type { SkillOutputPolicy, SkillRun, SkillRunError } from '../types.ts'\nimport type { Result } from './result.ts'\nimport { resolve } from 'node:path'\nimport { isSkillName, resolveWithin } from './paths.ts'\nimport { err, ok } from './result.ts'\n\nfunction invalid(message: string): Result<never, SkillRunError> {\n return err({ _tag: 'InvalidInput', message })\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0\n}\n\nexport function parseSkillRun(input: SkillRun): Result<SkillRun, SkillRunError> {\n if (!input || typeof input !== 'object' || !('_tag' in input))\n return invalid('Skill run input must be an object with a tag.')\n\n if (input._tag === 'PackageSkill') {\n if (!input.source || !input.destination)\n return invalid('Package Skill input is incomplete.')\n if (!isNonEmptyString(input.destination.rootDir) || !isSkillName(input.destination.name))\n return invalid('Package Skill destination is invalid.')\n if (input.source._tag === 'NpmPackage') {\n if (!isNonEmptyString(input.source.spec))\n return invalid('npm package spec is required.')\n return ok({\n _tag: 'PackageSkill',\n source: { _tag: 'NpmPackage', spec: input.source.spec },\n destination: { rootDir: resolve(input.destination.rootDir), name: input.destination.name },\n })\n }\n if (input.source._tag === 'LocalPackage') {\n if (!isNonEmptyString(input.source.rootDir) || !isNonEmptyString(input.source.packageDir))\n return invalid('Local package paths are required.')\n if (resolveWithin(input.source.rootDir, input.source.packageDir) === null)\n return invalid('Local package directory must stay inside its root directory.')\n return ok({\n _tag: 'PackageSkill',\n source: {\n _tag: 'LocalPackage',\n rootDir: resolve(input.source.rootDir),\n packageDir: input.source.packageDir,\n },\n destination: { rootDir: resolve(input.destination.rootDir), name: input.destination.name },\n })\n }\n return invalid('Package source tag is invalid.')\n }\n\n if (input._tag === 'ProjectSkill') {\n if (!isNonEmptyString(input.projectDir) || !input.destination)\n return invalid('Project Skill input is incomplete.')\n if (!isNonEmptyString(input.destination.rootDir) || !isSkillName(input.destination.name))\n return invalid('Project Skill destination is invalid.')\n return ok({\n _tag: 'ProjectSkill',\n projectDir: resolve(input.projectDir),\n destination: { rootDir: resolve(input.destination.rootDir), name: input.destination.name },\n })\n }\n\n if (input._tag === 'ReviewSkill') {\n if (!isNonEmptyString(input.skillDir))\n return invalid('Skill review directory is required.')\n return ok({ _tag: 'ReviewSkill', skillDir: resolve(input.skillDir) })\n }\n\n return invalid('Skill run tag is invalid.')\n}\n\nexport function parseOutputPolicy(policy: SkillOutputPolicy): SkillOutputPolicy {\n for (const [name, value] of Object.entries(policy)) {\n if (!Number.isSafeInteger(value) || value <= 0)\n throw new TypeError(`${name} must be a positive integer.`)\n }\n return Object.freeze(policy)\n}\n","import type { SkillOutputPolicy, SkillRunError } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { HarnessAgentSandboxConfig } from '@ai-sdk/harness/agent'\nimport { normalizeOutputPath } from '../paths.ts'\nimport { err, ok } from '../result.ts'\n\nexport type SandboxSession = Parameters<NonNullable<HarnessAgentSandboxConfig['onSession']>>[0]['session']\n\nexport interface CollectedFile {\n readonly path: string\n readonly content: Uint8Array\n}\n\nconst invalid = (message: string, issues: ReadonlyArray<string>): Result<never, SkillRunError> =>\n err({ _tag: 'InvalidSkill', message, issues })\n\nconst inventory = async (\n sandbox: SandboxSession,\n outputDir: string,\n signal?: AbortSignal,\n): Promise<Result<ReadonlyArray<{ type: string, path: string, size: number }>, SkillRunError>> => {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n const command = 'find -P \"$SKILLD_OUTPUT\" -mindepth 1 -printf \\'%y\\\\0%P\\\\0%s\\\\0\\''\n const result = await Promise.resolve().then(() => sandbox.run({\n command,\n env: { LC_ALL: 'C', SKILLD_OUTPUT: outputDir },\n abortSignal: signal,\n })).catch(error => error as Error)\n if (result instanceof Error)\n return invalid('Harness output cannot be inspected.', [result.message])\n if (result.exitCode !== 0)\n return invalid('Harness output directory is missing.', [result.stderr.trim() || 'No output directory.'])\n\n const fields = result.stdout.split('\\0')\n if (fields.at(-1) === '')\n fields.pop()\n if (fields.length % 3 !== 0)\n return invalid('Harness output inventory is invalid.', ['File inventory has an incomplete entry.'])\n\n const entries: Array<{ type: string, path: string, size: number }> = []\n for (let index = 0; index < fields.length; index += 3) {\n const type = fields[index]\n const path = fields[index + 1]\n const size = Number(fields[index + 2])\n if (!type || !path || !Number.isSafeInteger(size) || size < 0)\n return invalid('Harness output inventory is invalid.', ['File inventory has invalid fields.'])\n entries.push({ type, path, size })\n }\n return ok(entries)\n}\n\nexport const collectSandboxOutput = async (\n sandbox: SandboxSession,\n outputDir: string,\n policy: SkillOutputPolicy,\n signal?: AbortSignal,\n): Promise<Result<ReadonlyArray<CollectedFile>, SkillRunError>> => {\n const before = await inventory(sandbox, outputDir, signal)\n if (before._tag === 'Err')\n return before\n\n const files: CollectedFile[] = []\n const seen = new Set<string>()\n let totalBytes = 0\n for (const entry of before.value) {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n const path = normalizeOutputPath(entry.path)\n if (path === null)\n return invalid('Harness output contains an invalid path.', [entry.path])\n if (entry.type === 'd')\n continue\n if (entry.type !== 'f')\n return invalid('Harness output contains a linked or special entry.', [path])\n if (seen.has(path))\n return invalid('Harness output contains duplicate paths.', [path])\n if (files.length >= policy.maxOutputFiles)\n return invalid('Harness output contains too many files.', [`Limit: ${policy.maxOutputFiles}`])\n if (entry.size > policy.maxOutputFileBytes)\n return invalid('Harness output contains an oversized file.', [path])\n if (totalBytes + entry.size > policy.maxOutputBytes)\n return invalid('Harness output exceeds the total byte limit.', [`Limit: ${policy.maxOutputBytes}`])\n\n const content = await Promise.resolve().then(() => sandbox.readBinaryFile({ path: `${outputDir}/${path}`, abortSignal: signal })).catch(error => error as Error)\n if (content instanceof Error) {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n return invalid('Harness output cannot be read.', [path, content.message])\n }\n if (content === null || content.byteLength !== entry.size)\n return invalid('Harness output changed during collection.', [path])\n seen.add(path)\n files.push({ path, content: Uint8Array.from(content) })\n totalBytes += content.byteLength\n }\n\n const after = await inventory(sandbox, outputDir, signal)\n if (after._tag === 'Err')\n return after\n if (JSON.stringify(before.value) !== JSON.stringify(after.value))\n return invalid('Harness output changed during collection.', ['File inventory changed.'])\n\n files.sort((left, right) => left.path.localeCompare(right.path))\n return ok(files)\n}\n","import type { GeneratedSkill, SkillRunError, SourceAttempt } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { CollectedFile } from './collect.ts'\nimport { randomUUID } from 'node:crypto'\nimport { lstat, mkdir, open, realpath, rename, rm, rmdir, unlink, writeFile } from 'node:fs/promises'\nimport { dirname, join, resolve } from 'node:path'\nimport { err, ok } from '../result.ts'\n\nfunction pathError(message: string, path: string): Result<never, SkillRunError> {\n return err({ _tag: 'UnsafeOutputPath', message, path })\n}\n\nconst missing = Symbol('missing')\n\n/** A Skill at its destination, and the cleanup problems left behind. */\nexport interface PromotedSkill {\n readonly skill: GeneratedSkill\n readonly warnings: ReadonlyArray<string>\n}\n\nasync function statOrMissing(path: string) {\n return lstat(path).catch(error => (error as NodeJS.ErrnoException).code === 'ENOENT' ? missing : Promise.reject(error))\n}\n\nexport const promoteSkill = async (\n rootDir: string,\n name: string,\n files: ReadonlyArray<CollectedFile>,\n attempts: ReadonlyArray<SourceAttempt>,\n): Promise<Result<PromotedSkill, SkillRunError>> => {\n const root = resolve(rootDir)\n let rootStat = await statOrMissing(root).catch(error => error as Error)\n if (rootStat instanceof Error)\n return pathError('Output root cannot be inspected.', root)\n let createdRoot = false\n if (rootStat === missing) {\n const parent = dirname(root)\n const parentStat = await statOrMissing(parent).catch(error => error as Error)\n if (parentStat instanceof Error || parentStat === missing || !parentStat.isDirectory() || parentStat.isSymbolicLink())\n return pathError('Output root parent must be an existing directory.', parent)\n const canonicalParent = await realpath(parent).catch(error => error as Error)\n if (canonicalParent instanceof Error || canonicalParent !== parent)\n return pathError('Output root parent must not pass through a symbolic link.', parent)\n const created = await mkdir(root, { mode: 0o700 }).then(() => true, error => error as NodeJS.ErrnoException)\n if (created instanceof Error && created.code !== 'EEXIST')\n return pathError('Output root cannot be created.', root)\n createdRoot = created === true\n rootStat = await statOrMissing(root).catch(error => error as Error)\n }\n if (rootStat instanceof Error || rootStat === missing || !rootStat.isDirectory() || rootStat.isSymbolicLink())\n return pathError('Output root must be a directory, not a symbolic link.', root)\n const canonicalRoot = await realpath(root).catch(error => error as Error)\n if (canonicalRoot instanceof Error)\n return pathError('Output root cannot be resolved.', root)\n if (canonicalRoot !== root)\n return pathError('Output root must not pass through a symbolic link.', root)\n\n const target = join(root, name)\n const targetStat = await statOrMissing(target).catch(error => error as Error)\n if (targetStat instanceof Error)\n return pathError('Output path cannot be inspected.', target)\n if (targetStat !== missing && (!targetStat.isDirectory() || targetStat.isSymbolicLink()))\n return pathError('Output path must be a directory, not a symbolic link.', target)\n\n const lockPath = join(root, `.skilld-${name}.lock`)\n const lock = await open(lockPath, 'wx').catch(error => error as NodeJS.ErrnoException)\n if (lock instanceof Error) {\n if (lock.code === 'EEXIST')\n return err({ _tag: 'OutputBusy', message: 'Another Skill run owns this output path.', path: target })\n return err({ _tag: 'PromotionFailed', message: 'Output lock could not be created.', path: target, cause: lock })\n }\n\n const nonce = randomUUID()\n const staging = join(root, `.skilld-${name}-${nonce}.next`)\n const backup = join(root, `.skilld-${name}-${nonce}.previous`)\n let movedCurrent = false\n let promoted = false\n let failureMessage = 'Skill output could not be promoted.'\n let failureCause: unknown\n\n try {\n await mkdir(staging, { mode: 0o700 })\n for (const file of files) {\n const destination = join(staging, file.path)\n await mkdir(dirname(destination), { recursive: true, mode: 0o700 })\n await writeFile(destination, file.content, { flag: 'wx', mode: 0o600 })\n }\n\n if (targetStat !== missing) {\n await rename(target, backup)\n movedCurrent = true\n }\n await rename(staging, target)\n promoted = true\n }\n catch (cause) {\n failureCause = cause\n if (movedCurrent && !promoted) {\n const current = await statOrMissing(target).catch(error => error as Error)\n if (current instanceof Error) {\n failureMessage = 'Skill output rollback could not inspect its destination.'\n failureCause = new AggregateError([cause, current])\n }\n if (current === missing) {\n const rollback = await rename(backup, target).catch(error => error as Error)\n if (rollback instanceof Error) {\n failureMessage = 'Skill output rollback failed.'\n failureCause = new AggregateError([cause, rollback])\n }\n }\n }\n }\n\n const lockCleanupErrors: unknown[] = []\n await lock.close().catch(error => lockCleanupErrors.push(error))\n await unlink(lockPath).catch(error => lockCleanupErrors.push(error))\n\n if (promoted) {\n const warnings: string[] = []\n if (lockCleanupErrors.length > 0) {\n const detail = lockCleanupErrors.map(error => error instanceof Error ? error.message : String(error)).join('; ')\n warnings.push(`Output lock cleanup failed at ${lockPath}: ${detail}`)\n }\n if (movedCurrent) {\n const backupCleanup = await rm(backup, { recursive: true }).catch(error => error as Error)\n if (backupCleanup instanceof Error)\n warnings.push(`Previous Skill cleanup failed at ${backup}: ${backupCleanup.message}`)\n }\n return ok({\n skill: {\n _tag: 'GeneratedSkill',\n name,\n outputDir: target,\n files: files.map(file => ({ path: file.path, bytes: file.content.byteLength })),\n sourceAttempts: attempts,\n },\n warnings,\n })\n }\n\n const cleanupErrors = [...lockCleanupErrors]\n await rm(staging, { recursive: true, force: true }).catch(error => cleanupErrors.push(error))\n if (createdRoot)\n await rmdir(root).catch(error => cleanupErrors.push(error))\n const causes = failureCause === undefined ? cleanupErrors : [failureCause, ...cleanupErrors]\n const cause = causes.length <= 1 ? causes[0] : new AggregateError(causes, 'Skill output cleanup failed.')\n return err({ _tag: 'PromotionFailed', message: failureMessage, path: target, cause })\n}\n","/** A search command the Agent can repeat, matched on whole words. */\nconst searchCommand = /\\b(?:git grep|grep|rg)\\b/\n\n/** Inline code spans, which is where a Skill writes its file pointers. */\nconst inlineCode = /`([^`\\n]+)`/g\n\n/** Fenced blocks, which hold commands rather than pointers. */\nconst fencedBlock = /```[^\\n]*\\n[\\s\\S]*?```/g\n\n/**\n * A Skill may report a file the project lacks, such as a missing entry point.\n * A sentence that denies a path states a fact about the project, not a pointer.\n * A sentence that tells the Agent to create a file gives a task, not a pointer.\n * The check reads whole paragraphs, so a hard-wrapped denial still covers the\n * code spans in its own sentence.\n */\nconst denial = /\\b(no|not|none|never|absent|missing|lacks|without|instead|rather|empty|undeclared|unavailable|nothing)\\b|\\bdoes ?n[o']t\\b/i\n\nconst creation = /\\b(?:copy|create|write|generate)\\b/i\n\nfunction fencedBlocks(markdown: string): ReadonlyArray<string> {\n return markdown.match(fencedBlock) ?? []\n}\n\n/**\n * Prose paragraphs, with fenced commands removed so a command never reads as a\n * pointer. A soft-wrapped sentence keeps its words together: the lines of a\n * paragraph join before any check runs.\n */\nfunction proseParagraphs(markdown: string): ReadonlyArray<string> {\n return markdown\n .replace(fencedBlock, '')\n .split(/\\n[ \\t]*\\n/)\n .map(paragraph => paragraph.replace(/\\n/g, ' ').trim())\n .filter(paragraph => paragraph.length > 0)\n}\n\n/**\n * Extensions a real file pointer carries. A token ending elsewhere, such as\n * the `.0` in a version, carries no path shape.\n */\nconst pathExtension = /\\.(?:md|mdx|json|jsonc|ts|tsx|mts|cts|js|mjs|cjs|jsx|vue|svelte|txt|yml|yaml|toml|html|css|scss|rs|py|go|sh|lock|env|csv|xml)$/i\n\n/** A release number such as `20.19.0` or `v20` states a version, never a path. */\nconst versionShape = /^v?\\d+(?:\\.\\d+)*$/i\n\n/** A product name such as `Node.js` or `node.js` names a tool, never a file. */\nconst productName = /^[A-Za-z][A-Za-z0-9_]*\\.[A-Za-z0-9]+$/\n\n/**\n * A token counts as a file pointer only when it cannot be anything else.\n * A false pointer fails a correct Skill, so every rule here excludes rather than includes.\n */\nfunction pathCandidate(token: string): string | null {\n if (token.length === 0 || /\\s/.test(token))\n return null\n // A flag, a variable, a comment, or a placeholder is never a pointer.\n if (/^[-$#<{[]/.test(token))\n return null\n // A URL, a package specifier, or a shell construct is never a pointer.\n if (token.includes('://') || /[()|;&\"'@:]/.test(token))\n return null\n const trimmed = token.replace(/^\\.\\//, '').replace(/\\/+$/, '')\n if (trimmed.length === 0 || trimmed.startsWith('..'))\n return null\n // A version, a product name, or a numbered reference such as `HTTP/2` is never a pointer.\n if (versionShape.test(trimmed) || productName.test(trimmed) || /\\/\\d+$/.test(trimmed))\n return null\n // A pointer carries a slash-qualified path or a known file extension.\n if (!trimmed.includes('/') && !pathExtension.test(trimmed))\n return null\n return trimmed\n}\n\n/** The literal prefix of a glob, which is the part a real path must start with. */\nfunction literalPrefix(candidate: string): string {\n const wildcard = candidate.search(/[*?]/)\n if (wildcard === -1)\n return candidate\n const cut = candidate.slice(0, wildcard).replace(/[^/]*$/, '')\n return cut.replace(/\\/+$/, '')\n}\n\nfunction resolves(candidate: string, known: ReadonlySet<string>): boolean {\n if (known.has(candidate))\n return true\n const prefix = literalPrefix(candidate)\n if (prefix.length === 0)\n return true\n for (const path of known) {\n // A known template such as `.env.example` implies the file it is copied to.\n if (path.startsWith(`${candidate}.`))\n return true\n // A directory pointer resolves when the project holds a file under it.\n if (path === prefix || path.startsWith(`${prefix}/`))\n return true\n }\n return false\n}\n\nexport interface ProjectSkillInput {\n /** The generated SKILL.md text. */\n readonly markdown: string\n /** Project-relative paths the Harness prepared for the Agent. */\n readonly projectPaths: ReadonlyArray<string>\n /** Output-relative paths the Skill writes beside SKILL.md. */\n readonly outputPaths: ReadonlyArray<string>\n}\n\n/**\n * Check that a project Skill points at files the project contains and gives a\n * search the Agent can repeat. The Agent cannot verify its own pointers.\n *\n * The Harness hides generated directories from the Agent, so a pointer at one is\n * invention like any other. A sentence that states a path is missing, or that\n * tells the Agent to create one, passes: it reports a fact or gives a task, not\n * a pointer. The sentence may wrap across prose lines within its paragraph.\n */\nexport function checkProjectSkill(input: ProjectSkillInput): ReadonlyArray<string> {\n const issues: string[] = []\n const known = new Set([...input.projectPaths, ...input.outputPaths])\n const unknown = new Set<string>()\n\n for (const paragraph of proseParagraphs(input.markdown)) {\n if (denial.test(paragraph) || creation.test(paragraph))\n continue\n for (const match of paragraph.matchAll(inlineCode)) {\n const candidate = pathCandidate(match[1]!.trim())\n if (candidate !== null && !resolves(candidate, known))\n unknown.add(candidate)\n }\n }\n\n for (const path of [...unknown].sort())\n issues.push(`SKILL.md points at a path the project does not contain: ${path}.`)\n\n const inline = [...input.markdown.matchAll(inlineCode)].map(match => match[1]!)\n const commands = [...fencedBlocks(input.markdown), ...inline].join('\\n')\n if (!searchCommand.test(commands))\n issues.push('SKILL.md must give the Agent at least one search command it can repeat.')\n\n return issues\n}\n","import type { SkillReview, SkillReviewFinding, SkillRunError } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { CollectedFile } from './collect.ts'\nimport { isScalar, parseDocument, Scalar } from 'yaml'\nimport { isSkillName, normalizeOutputPath } from '../paths.ts'\nimport { checkProjectSkill } from './project.ts'\nimport { err, ok } from '../result.ts'\n\n/** Both generation Skills say the frontmatter must contain only these fields. */\nconst allowedFrontmatter = new Set(['name', 'description'])\n\n/** `generate-package-skill`: \"Keep `SKILL.md` under 500 lines.\" */\nconst packageSkillLineLimit = 500\n\n/** `generate-package-skill`: \"Write at most eight reference files.\" */\nconst packageSkillReferenceLimit = 8\n\n/**\n * Skill loaders and viewers parse frontmatter with different YAML parsers.\n * A plain one-line description without these characters reads the same in all of them.\n */\nconst riskyDescription = /[\"`%]/\n\n/**\n * The Skill that produced the output decides which of its written rules apply.\n * A project Skill also carries the project paths its pointers must resolve to.\n */\nexport type GenerationContract\n = | { readonly _tag: 'PackageSkill' }\n | { readonly _tag: 'ProjectSkill', readonly projectPaths: ReadonlyArray<string> }\n\nconst invalid = (issues: ReadonlyArray<string>): Result<never, SkillRunError> =>\n err({ _tag: 'InvalidSkill', message: 'Skill output failed deterministic checks.', issues })\n\nfunction decodeText(content: Uint8Array): string | null {\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(content)\n }\n catch {\n return null\n }\n}\n\n/** Markdown link targets, inline or reference style, without anchors or titles. */\nfunction linkTargets(markdown: string): ReadonlySet<string> {\n const targets = new Set<string>()\n const add = (raw: string): void => {\n const target = raw.trim().replace(/^<|>$/g, '').split(/\\s/)[0]!.replace(/[#?].*$/, '').replace(/^\\.\\//, '')\n if (target.length > 0)\n targets.add(target)\n }\n for (const match of markdown.matchAll(/\\]\\(([^)\\n]+)\\)/g))\n add(match[1]!)\n for (const match of markdown.matchAll(/^\\s*\\[[^\\]\\n]+\\]:\\s*(\\S+)/gm))\n add(match[1]!)\n for (const match of markdown.matchAll(/`([^`\\n]+)`/g))\n add(match[1]!)\n return targets\n}\n\nfunction lineCount(text: string): number {\n const lines = text.split('\\n')\n return lines.at(-1) === '' ? lines.length - 1 : lines.length\n}\n\n/** The written structure rules of the generation Skills, checked on the output. */\nfunction structureIssues(markdown: string, files: ReadonlyArray<CollectedFile>, contract: GenerationContract): ReadonlyArray<string> {\n const issues: string[] = []\n const referencePaths = files.map(file => file.path).filter(path => path.startsWith('references/')).sort()\n if (contract._tag === 'PackageSkill') {\n const lines = lineCount(markdown)\n if (lines >= packageSkillLineLimit)\n issues.push(`SKILL.md must stay under ${packageSkillLineLimit} lines; it has ${lines}.`)\n if (referencePaths.length > packageSkillReferenceLimit)\n issues.push(`A package Skill may write at most ${packageSkillReferenceLimit} reference files; it wrote ${referencePaths.length}.`)\n }\n const linked = linkTargets(markdown)\n for (const path of referencePaths) {\n if (!linked.has(path))\n issues.push(`SKILL.md must link ${path}.`)\n }\n return issues\n}\n\nexport const validateGeneratedSkill = (\n name: string,\n files: ReadonlyArray<CollectedFile>,\n contract: GenerationContract,\n): Result<void, SkillRunError> => {\n const issues: string[] = []\n const skillFiles = files.filter(file => file.path === 'SKILL.md')\n if (skillFiles.length !== 1)\n return invalid(['Output must contain exactly one SKILL.md file.'])\n\n const source = decodeText(skillFiles[0]!.content)\n if (source === null)\n return invalid(['SKILL.md must contain valid UTF-8 text.'])\n if (contract._tag === 'ProjectSkill') {\n issues.push(...checkProjectSkill({\n markdown: source,\n projectPaths: contract.projectPaths,\n outputPaths: files.map(file => file.path),\n }))\n }\n const match = source.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/)\n if (!match)\n return invalid(['SKILL.md must start with YAML frontmatter.'])\n if (match[2]?.trim().length === 0)\n issues.push('SKILL.md instructions must not be empty.')\n\n const document = parseDocument(match[1]!, { uniqueKeys: true })\n for (const error of document.errors)\n issues.push(`Frontmatter: ${error.message}`)\n for (const warning of document.warnings)\n issues.push(`Frontmatter: ${warning.message}`)\n\n const value = document.errors.length === 0 ? document.toJS() as unknown : null\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n issues.push('Frontmatter must be a mapping.')\n return invalid(issues)\n }\n\n const frontmatter = value as Record<string, unknown>\n for (const key of Object.keys(frontmatter)) {\n if (!allowedFrontmatter.has(key))\n issues.push(`Frontmatter field is not supported: ${key}`)\n }\n if (frontmatter.name !== name)\n issues.push('Frontmatter name must match the Skill directory name.')\n if (typeof frontmatter.name !== 'string' || !isSkillName(frontmatter.name))\n issues.push('Frontmatter name is invalid.')\n if (typeof frontmatter.description !== 'string' || frontmatter.description.trim().length === 0 || frontmatter.description.length > 1024)\n issues.push('Frontmatter description must contain 1 to 1024 characters.')\n const description = document.get('description', true)\n if (typeof frontmatter.description === 'string' && (!isScalar(description) || description.type !== Scalar.PLAIN || riskyDescription.test(frontmatter.description)))\n issues.push('Frontmatter description must be one plain line without double quotes, backticks, or %. Name symptoms in plain words.')\n issues.push(...structureIssues(source, files, contract))\n\n return issues.length === 0 ? ok(undefined) : invalid(issues)\n}\n\nconst findingLevels = new Set(['error', 'warning', 'note'])\n\nexport const validateSkillReview = (\n files: ReadonlyArray<CollectedFile>,\n): Result<SkillReview, SkillRunError> => {\n if (files.length !== 1 || files[0]?.path !== 'review.json')\n return invalid(['Review output must contain only review.json.'])\n\n let value: unknown\n try {\n const source = decodeText(files[0].content)\n if (source === null)\n return invalid(['review.json must contain valid UTF-8 text.'])\n value = JSON.parse(source)\n }\n catch {\n return invalid(['review.json must contain valid JSON.'])\n }\n if (!value || typeof value !== 'object' || Array.isArray(value))\n return invalid(['review.json must contain an object.'])\n\n const review = value as Record<string, unknown>\n if (Object.keys(review).some(key => key !== 'summary' && key !== 'findings'))\n return invalid(['review.json contains unsupported fields.'])\n if (typeof review.summary !== 'string' || review.summary.trim().length === 0)\n return invalid(['Review summary is required.'])\n if (!Array.isArray(review.findings))\n return invalid(['Review findings must be an array.'])\n\n const findings: SkillReviewFinding[] = []\n for (const item of review.findings) {\n if (!item || typeof item !== 'object' || Array.isArray(item))\n return invalid(['Each review finding must be an object.'])\n const finding = item as Record<string, unknown>\n if (Object.keys(finding).some(key => !['level', 'path', 'message', 'fix'].includes(key)))\n return invalid(['A review finding contains unsupported fields.'])\n if (typeof finding.level !== 'string' || !findingLevels.has(finding.level))\n return invalid(['A review finding level is invalid.'])\n if (typeof finding.path !== 'string' || normalizeOutputPath(finding.path) === null)\n return invalid(['A review finding path is invalid.'])\n if (typeof finding.message !== 'string' || finding.message.trim().length === 0 || typeof finding.fix !== 'string' || finding.fix.trim().length === 0)\n return invalid(['A review finding is incomplete.'])\n findings.push(finding as unknown as SkillReviewFinding)\n }\n\n return ok({ _tag: 'SkillReview', summary: review.summary, findings })\n}\n","import type { SkillOutputPolicy, SkillRunError, SourceAttempt } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport { constants } from 'node:fs'\nimport { lstat, open, opendir, realpath } from 'node:fs/promises'\nimport { join, relative, resolve, sep } from 'node:path'\nimport { err, ok } from '../result.ts'\n\nexport interface PreparedFile {\n readonly path: string\n readonly content: Uint8Array\n}\n\n/** A source file the Harness left out because it exceeds the file byte limit. */\nexport interface SkippedSourceFile {\n readonly path: string\n readonly bytes: number\n}\n\nexport interface PreparedSource {\n readonly files: ReadonlyArray<PreparedFile>\n /** Files left out for size. The Agent and the caller both see this list. */\n readonly skippedFiles: ReadonlyArray<SkippedSourceFile>\n readonly attempts: ReadonlyArray<SourceAttempt>\n readonly npmResolution?: {\n readonly package: string\n readonly version: string\n }\n}\n\n/** One warning per skipped file, in the words the result reports. */\nexport function skippedFileWarnings(skipped: ReadonlyArray<SkippedSourceFile>, policy: SkillOutputPolicy): ReadonlyArray<string> {\n return skipped.map(file =>\n `Source file ${file.path} was left out: ${file.bytes} bytes exceeds the ${policy.maxSourceFileBytes} byte file limit.`)\n}\n\nconst ignoredNames = new Set([\n '.git',\n '.hg',\n '.next',\n '.nuxt',\n '.output',\n '.skilld',\n '.turbo',\n 'coverage',\n 'dist',\n 'node_modules',\n 'target',\n])\n\nexport async function collectHostDirectory(directory: string, policy: SkillOutputPolicy, sourceLabel = directory, signal?: AbortSignal): Promise<Result<PreparedSource, SkillRunError>> {\n const root = resolve(directory)\n const unavailable = (message: string, cause?: unknown): Result<never, SkillRunError> => err({\n _tag: 'SourceUnavailable',\n message,\n attempts: [{ source: sourceLabel, status: 'skipped', reason: message }],\n cause,\n })\n const cancelled = (): Result<never, SkillRunError> => err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n if (signal?.aborted)\n return cancelled()\n const rootStat = await lstat(root).catch(error => error as NodeJS.ErrnoException)\n if (rootStat instanceof Error)\n return unavailable('Source directory is unavailable.', rootStat)\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink())\n return unavailable('Source path must be a directory, not a symbolic link.')\n const canonicalRoot = await realpath(root).catch(error => error as NodeJS.ErrnoException)\n if (canonicalRoot instanceof Error)\n return unavailable('Source directory cannot be resolved.', canonicalRoot)\n if (canonicalRoot !== root)\n return unavailable('Source path must not pass through a symbolic link.')\n\n const files: PreparedFile[] = []\n const skippedFiles: SkippedSourceFile[] = []\n let totalBytes = 0\n const relativePath = (absolute: string): string => relative(root, absolute).split(sep).join('/')\n /** An entry-level failure names the entry, so the caller can find and fix it. */\n const entryUnavailable = (absolute: string, message: string, cause?: unknown, fix?: string): Result<never, SkillRunError> =>\n unavailable(`${message}: ${relativePath(absolute)}.${fix === undefined ? '' : ` ${fix}`}`, cause)\n\n const walk = async (current: string): Promise<Result<void, SkillRunError>> => {\n if (signal?.aborted)\n return cancelled()\n const canonicalCurrent = await realpath(current).catch(error => error as NodeJS.ErrnoException)\n if (canonicalCurrent instanceof Error || canonicalCurrent !== current)\n return unavailable('Source directory changed during collection.', canonicalCurrent instanceof Error ? canonicalCurrent : undefined)\n const directoryHandle = await opendir(current).catch(error => error as NodeJS.ErrnoException)\n if (directoryHandle instanceof Error)\n return unavailable('Source directory cannot be read.', directoryHandle)\n\n for await (const entry of directoryHandle) {\n if (signal?.aborted)\n return cancelled()\n if (ignoredNames.has(entry.name))\n continue\n const absolute = join(current, entry.name)\n const stat = await lstat(absolute).catch(error => error as NodeJS.ErrnoException)\n if (stat instanceof Error)\n return entryUnavailable(absolute, 'Source entry cannot be read', stat)\n if (stat.isSymbolicLink())\n return entryUnavailable(absolute, 'Source contains a symbolic link', undefined, 'Remove the link, or pass a clean export such as a `git archive` of the directory.')\n if (stat.isDirectory()) {\n const nested = await walk(absolute)\n if (nested._tag === 'Err')\n return nested\n continue\n }\n if (!stat.isFile())\n return entryUnavailable(absolute, 'Source contains a special file')\n\n const path = relativePath(absolute)\n const handle = await open(absolute, constants.O_RDONLY | constants.O_NOFOLLOW).catch(error => error as NodeJS.ErrnoException)\n if (handle instanceof Error)\n return entryUnavailable(absolute, 'Source file cannot be opened without following links', handle)\n const openedStat = await handle.stat().catch(error => error as NodeJS.ErrnoException)\n if (openedStat instanceof Error) {\n await handle.close()\n return entryUnavailable(absolute, 'Source file cannot be inspected', openedStat)\n }\n if (!openedStat.isFile() || openedStat.dev !== stat.dev || openedStat.ino !== stat.ino) {\n await handle.close()\n return entryUnavailable(absolute, 'Source file changed during collection')\n }\n if (openedStat.size > policy.maxSourceFileBytes) {\n await handle.close()\n skippedFiles.push({ path, bytes: openedStat.size })\n continue\n }\n if (files.length >= policy.maxSourceFiles) {\n await handle.close()\n return unavailable('Source contains too many files.')\n }\n if (totalBytes + openedStat.size > policy.maxSourceBytes) {\n await handle.close()\n return unavailable('Source exceeds the total byte limit.')\n }\n\n const content = await handle.readFile().catch(error => error as NodeJS.ErrnoException)\n await handle.close()\n if (content instanceof Error)\n return entryUnavailable(absolute, 'Source file cannot be read', content)\n if (content.byteLength !== openedStat.size)\n return entryUnavailable(absolute, 'Source file changed during collection')\n if (signal?.aborted)\n return cancelled()\n files.push({ path, content })\n totalBytes += content.byteLength\n }\n return ok(undefined)\n }\n\n const walked = await walk(root)\n if (walked._tag === 'Err')\n return walked\n if (files.length === 0)\n return unavailable('Source directory has no usable files.')\n\n files.sort((left, right) => left.path.localeCompare(right.path))\n skippedFiles.sort((left, right) => left.path.localeCompare(right.path))\n return ok({ files, skippedFiles, attempts: [{ source: sourceLabel, status: 'used' }] })\n}\n","import type { SkillOutputPolicy, SkillRunError } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { PreparedFile, SkippedSourceFile } from './host.ts'\nimport { Readable } from 'node:stream'\nimport { createGunzip } from 'node:zlib'\nimport { normalizeOutputPath } from '../paths.ts'\nimport { err, ok } from '../result.ts'\n\nconst blockBytes = 512\n\nexport type ArchiveLayout = 'npm' | 'github'\n\ninterface PendingEntry {\n readonly kind: 'directory' | 'file' | 'metadata' | 'skip'\n readonly path?: string\n readonly metadataType?: 'long-path' | 'pax'\n readonly size: number\n remaining: number\n padding: number\n readonly chunks: Array<Buffer<ArrayBufferLike>>\n}\n\nfunction unavailable(message: string, cause?: unknown): Result<never, SkillRunError> {\n return err({ _tag: 'SourceUnavailable', message, attempts: [], cause })\n}\n\nfunction readString(buffer: Uint8Array, start: number, length: number): string {\n const bytes = buffer.subarray(start, start + length)\n const zero = bytes.indexOf(0)\n return Buffer.from(zero === -1 ? bytes : bytes.subarray(0, zero)).toString('utf8').trim()\n}\n\nfunction readOctal(buffer: Uint8Array, start: number, length: number): number | null {\n const value = readString(buffer, start, length).replace(/^\\s+|\\s+$/g, '')\n if (!/^[0-7]+$/.test(value))\n return null\n const parsed = Number.parseInt(value, 8)\n return Number.isSafeInteger(parsed) ? parsed : null\n}\n\nfunction hasValidChecksum(header: Uint8Array): boolean {\n const expected = readOctal(header, 148, 8)\n if (expected === null)\n return false\n let actual = 0\n for (let index = 0; index < header.byteLength; index += 1)\n actual += index >= 148 && index < 156 ? 32 : header[index]!\n return actual === expected\n}\n\nfunction parsePaxPath(content: Uint8Array): string | null {\n const text = Buffer.from(content).toString('utf8')\n let offset = 0\n let path: string | null = null\n while (offset < text.length) {\n const space = text.indexOf(' ', offset)\n if (space === -1)\n return null\n const length = Number.parseInt(text.slice(offset, space), 10)\n if (!Number.isSafeInteger(length) || length <= 0 || offset + length > text.length)\n return null\n const record = text.slice(space + 1, offset + length - 1)\n const equals = record.indexOf('=')\n if (equals !== -1 && record.slice(0, equals) === 'path')\n path = record.slice(equals + 1)\n offset += length\n }\n return path\n}\n\nfunction archivePath(value: string, layout: ArchiveLayout): string | null {\n const normalized = normalizeOutputPath(value)\n if (normalized === null)\n return null\n const segments = normalized.split('/')\n if (layout === 'npm') {\n if (segments[0] !== 'package' || segments.length < 2)\n return null\n }\n else if (segments.length < 2) {\n return null\n }\n return normalizeOutputPath(segments.slice(1).join('/'))\n}\n\nfunction entryContent(entry: PendingEntry): Buffer<ArrayBufferLike> {\n return entry.chunks.length === 1\n ? entry.chunks[0]!\n : Buffer.concat(entry.chunks, entry.size)\n}\n\nexport interface ExtractedArchive {\n readonly files: ReadonlyArray<PreparedFile>\n readonly skippedFiles: ReadonlyArray<SkippedSourceFile>\n}\n\nexport async function extractArchive(\n compressed: AsyncIterable<Uint8Array>,\n policy: SkillOutputPolicy,\n layout: ArchiveLayout,\n): Promise<Result<ExtractedArchive, SkillRunError>> {\n const source = Readable.from(compressed)\n const gunzip = createGunzip()\n source.on('error', error => gunzip.destroy(error))\n source.pipe(gunzip)\n const files: PreparedFile[] = []\n const skippedFiles: SkippedSourceFile[] = []\n const seen = new Set<string>()\n const maxArchiveBytes = policy.maxSourceBytes + (policy.maxSourceFiles + 2) * blockBytes * 2\n let archiveBytes = 0\n let fileEntries = 0\n let nextPath: string | null = null\n let pending: Buffer<ArrayBufferLike> = Buffer.alloc(0)\n let entry: PendingEntry | null = null\n let totalBytes = 0\n let ended = false\n\n try {\n for await (const value of gunzip) {\n const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value as Uint8Array)\n archiveBytes += chunk.byteLength\n if (archiveBytes > maxArchiveBytes)\n return unavailable('Source archive exceeds the uncompressed byte limit.')\n pending = pending.byteLength === 0 ? chunk : Buffer.concat([pending, chunk])\n\n while (pending.byteLength > 0) {\n if (ended) {\n if (pending.some(byte => byte !== 0))\n return unavailable('Source archive has data after its end marker.')\n pending = Buffer.alloc(0)\n break\n }\n\n if (entry !== null) {\n if (entry.remaining > 0) {\n const consumed = Math.min(entry.remaining, pending.byteLength)\n if (entry.kind === 'file' || entry.kind === 'metadata')\n entry.chunks.push(pending.subarray(0, consumed))\n pending = pending.subarray(consumed)\n entry.remaining -= consumed\n if (entry.remaining > 0)\n break\n }\n if (entry.padding > 0) {\n const consumed = Math.min(entry.padding, pending.byteLength)\n pending = pending.subarray(consumed)\n entry.padding -= consumed\n if (entry.padding > 0)\n break\n }\n\n if (entry.kind === 'metadata') {\n const content = entryContent(entry)\n nextPath = entry.metadataType === 'pax'\n ? parsePaxPath(content)\n : content.toString('utf8').replace(/\\0.*$/s, '').trim()\n if (nextPath === null || nextPath.length === 0)\n return unavailable('Source archive has invalid path metadata.')\n }\n else if (entry.kind === 'file' && entry.path) {\n files.push({ path: entry.path, content: Uint8Array.from(entryContent(entry)) })\n totalBytes += entry.size\n }\n entry = null\n continue\n }\n\n if (pending.byteLength < blockBytes)\n break\n const header = pending.subarray(0, blockBytes)\n pending = pending.subarray(blockBytes)\n if (header.every(byte => byte === 0)) {\n ended = true\n continue\n }\n if (!hasValidChecksum(header))\n return unavailable('Source archive has an invalid header checksum.')\n\n const size = readOctal(header, 124, 12)\n if (size === null)\n return unavailable('Source archive has an invalid entry size.')\n const name = readString(header, 0, 100)\n const prefix = readString(header, 345, 155)\n const headerPath = prefix.length > 0 ? `${prefix}/${name}` : name\n const type = String.fromCharCode(header[156] ?? 0)\n const padding = (blockBytes - size % blockBytes) % blockBytes\n\n if (type === 'x' || type === 'L') {\n if (size > policy.maxSourceFileBytes)\n return unavailable('Source archive path metadata exceeds the file byte limit.')\n entry = {\n kind: 'metadata',\n metadataType: type === 'x' ? 'pax' : 'long-path',\n size,\n remaining: size,\n padding,\n chunks: [],\n }\n continue\n }\n if (type === '5') {\n nextPath = null\n entry = { kind: 'directory', size, remaining: size, padding, chunks: [] }\n continue\n }\n if (type !== '0' && type !== '\\0')\n return unavailable(`Source archive contains a linked or special entry: ${nextPath ?? headerPath}.`)\n\n const path = archivePath(nextPath ?? headerPath, layout)\n nextPath = null\n if (path === null)\n return unavailable('Source archive contains an invalid path.')\n if (seen.has(path))\n return unavailable('Source archive contains duplicate paths.')\n seen.add(path)\n fileEntries += 1\n if (fileEntries > policy.maxSourceFiles)\n return unavailable('Source archive contains too many files.')\n if (size <= policy.maxSourceFileBytes && totalBytes + size > policy.maxSourceBytes)\n return unavailable('Source archive exceeds the total byte limit.')\n if (size > policy.maxSourceFileBytes)\n skippedFiles.push({ path, bytes: size })\n\n entry = {\n kind: size > policy.maxSourceFileBytes ? 'skip' : 'file',\n path,\n size,\n remaining: size,\n padding,\n chunks: [],\n }\n }\n }\n }\n catch (cause) {\n const message = cause instanceof Error ? cause.message : ''\n return unavailable(message.startsWith('Source archive ')\n ? message\n : 'Source archive is not valid gzip data.', cause)\n }\n\n if (entry !== null || pending.some(byte => byte !== 0) || !ended)\n return unavailable('Source archive ended before its final entry.')\n if (files.length === 0)\n return unavailable('Source archive has no usable files.')\n files.sort((left, right) => left.path.localeCompare(right.path))\n skippedFiles.sort((left, right) => left.path.localeCompare(right.path))\n return ok({ files, skippedFiles })\n}\n","import type { Hash } from 'node:crypto'\nimport type { SkillOutputPolicy, SkillRunError, SourceAttempt } from '../../types.ts'\nimport type { Result } from '../result.ts'\nimport type { ExtractedArchive } from './archive.ts'\nimport type { PreparedFile, PreparedSource } from './host.ts'\nimport { createHash } from 'node:crypto'\nimport { posix } from 'node:path'\nimport { err, ok } from '../result.ts'\nimport { extractArchive } from './archive.ts'\n\ninterface NpmDist {\n readonly tarball: string\n readonly integrity?: string\n readonly shasum?: string\n}\n\ninterface NpmRepository {\n readonly type?: string\n readonly url?: string\n}\n\ninterface NpmVersion {\n readonly version: string\n readonly dist: NpmDist\n readonly gitHead?: string\n readonly repository?: NpmRepository | string\n}\n\ninterface IntegrityVerifier {\n readonly update: (content: Uint8Array) => void\n readonly valid: () => boolean\n}\n\nconst packageSpecPattern = /^(@[^/@]+\\/[^/@]+|[^/@]+)(?:@(\\S+))?$/\nconst exactVersionPattern = /^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[\\da-z-]+(?:\\.[\\da-z-]+)*)?(?:\\+[\\da-z-]+(?:\\.[\\da-z-]+)*)?$/i\nconst gitCommitPattern = /^[0-9a-f]{40}$/i\nconst npmRequestTimeoutMs = 30_000\nconst npmRedirectLimit = 3\nconst packumentByteLimit = 10 * 1024 * 1024\n\nexport type FetchClient = (input: string | URL | Request, init?: RequestInit) => Promise<Response>\n\nfunction unavailable(message: string, attempts: ReadonlyArray<SourceAttempt>, cause?: unknown): Result<never, SkillRunError> {\n return err({ _tag: 'SourceUnavailable', message, attempts, cause })\n}\n\nfunction parsePackageSpec(spec: string): { name: string, version: string } | null {\n const match = spec.match(packageSpecPattern)\n return match?.[1] ? { name: match[1], version: match[2] ?? 'latest' } : null\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction parseRepository(value: unknown): NpmRepository | string | undefined {\n if (typeof value === 'string')\n return value\n if (!isRecord(value))\n return undefined\n return {\n type: typeof value.type === 'string' ? value.type : undefined,\n url: typeof value.url === 'string' ? value.url : undefined,\n }\n}\n\nfunction parseVersion(packument: unknown, requested: string): { resolvedVersion: string, version: NpmVersion, repository?: NpmRepository | string } | null {\n if (!isRecord(packument) || !isRecord(packument['dist-tags']) || !isRecord(packument.versions))\n return null\n const tagged = packument['dist-tags'][requested]\n const resolvedVersion = typeof tagged === 'string' ? tagged : requested\n const value = packument.versions[resolvedVersion]\n if (!isRecord(value) || typeof value.version !== 'string' || !isRecord(value.dist) || typeof value.dist.tarball !== 'string')\n return null\n return {\n resolvedVersion,\n repository: parseRepository(packument.repository),\n version: {\n version: value.version,\n gitHead: typeof value.gitHead === 'string' ? value.gitHead : undefined,\n repository: parseRepository(value.repository),\n dist: {\n tarball: value.dist.tarball,\n integrity: typeof value.dist.integrity === 'string' ? value.dist.integrity : undefined,\n shasum: typeof value.dist.shasum === 'string' ? value.dist.shasum : undefined,\n },\n },\n }\n}\n\nasync function cancelBody(response: Response): Promise<void> {\n if (!response.body)\n return\n // A failed cleanup cannot replace the source failure.\n await response.body.cancel().catch(() => undefined)\n}\n\nfunction declaredBytes(response: Response): number | null {\n const value = response.headers.get('content-length')\n if (value === null || !/^\\d+$/.test(value))\n return null\n const bytes = Number(value)\n return Number.isSafeInteger(bytes) ? bytes : null\n}\n\nasync function* responseChunks(\n response: Response,\n maxBytes: number,\n limitMessage: string,\n onChunk: (content: Uint8Array) => void = () => {},\n): AsyncGenerator<Uint8Array> {\n const declared = declaredBytes(response)\n if (declared !== null && declared > maxBytes) {\n await cancelBody(response)\n throw new Error(limitMessage)\n }\n if (!response.body)\n return\n\n const reader = response.body.getReader()\n let complete = false\n let totalBytes = 0\n try {\n while (true) {\n const result = await reader.read()\n if (result.done) {\n complete = true\n return\n }\n totalBytes += result.value.byteLength\n if (totalBytes > maxBytes)\n throw new Error(limitMessage)\n onChunk(result.value)\n yield result.value\n }\n }\n finally {\n if (!complete) {\n // A failed cleanup cannot replace the source failure.\n await reader.cancel().catch(() => undefined)\n }\n reader.releaseLock()\n }\n}\n\nasync function readBoundedResponse(response: Response, maxBytes: number): Promise<Result<Uint8Array, SkillRunError>> {\n const chunks: Uint8Array[] = []\n let totalBytes = 0\n try {\n for await (const chunk of responseChunks(response, maxBytes, 'npm response exceeds the byte limit.')) {\n chunks.push(chunk)\n totalBytes += chunk.byteLength\n }\n }\n catch (cause) {\n return unavailable(cause instanceof Error ? cause.message : 'npm response cannot be read.', [], cause)\n }\n return ok(Uint8Array.from(Buffer.concat(chunks, totalBytes)))\n}\n\nasync function fetchWithRedirects(fetchClient: FetchClient, url: string, init: RequestInit = {}, signal?: AbortSignal): Promise<Result<Response, SkillRunError>> {\n const timeout = AbortSignal.timeout(npmRequestTimeoutMs)\n const requestSignal = signal ? AbortSignal.any([signal, timeout]) : timeout\n let current = url\n for (let redirects = 0; redirects <= npmRedirectLimit; redirects += 1) {\n const response = await fetchClient(current, { ...init, redirect: 'manual', signal: requestSignal }).catch(error => error as Error)\n if (response instanceof Error)\n return unavailable(timeout.aborted ? 'npm request timed out.' : 'npm request failed.', [], response)\n if (![301, 302, 303, 307, 308].includes(response.status))\n return ok(response)\n if (redirects === npmRedirectLimit) {\n await cancelBody(response)\n return unavailable('npm request exceeded the redirect limit.', [])\n }\n const location = response.headers.get('location')\n if (!location) {\n await cancelBody(response)\n return unavailable('npm redirect is missing its location.', [])\n }\n const redirected = await Promise.resolve().then(() => new URL(location, current)).catch(() => null)\n if (redirected === null) {\n await cancelBody(response)\n return unavailable('npm redirect location is invalid.', [])\n }\n if (redirected.protocol !== 'https:') {\n await cancelBody(response)\n return unavailable('npm redirect URL must use HTTPS.', [])\n }\n await cancelBody(response)\n current = redirected.href\n }\n return unavailable('npm request exceeded the redirect limit.', [])\n}\n\nfunction createIntegrityVerifier(dist: NpmDist): IntegrityVerifier | null {\n const values = dist.integrity?.split(/\\s+/).filter(Boolean) ?? []\n let expected = values.flatMap((value) => {\n const match = value.match(/^(sha(?:1|256|384|512))-([A-Za-z0-9+/=]+)$/)\n return match?.[1] && match[2] ? [{ algorithm: match[1], digest: match[2] }] : []\n })\n if (expected.length > 0) {\n const strength = { sha1: 1, sha256: 2, sha384: 3, sha512: 4 } as const\n const strongest = Math.max(...expected.map(value => strength[value.algorithm as keyof typeof strength]))\n expected = expected.filter(value => strength[value.algorithm as keyof typeof strength] === strongest)\n }\n if (values.length === 0 && dist.shasum && /^[0-9a-f]{40}$/i.test(dist.shasum))\n expected.push({ algorithm: 'sha1', digest: Buffer.from(dist.shasum, 'hex').toString('base64') })\n if (expected.length === 0)\n return null\n\n const hashes = new Map<string, Hash>()\n for (const value of expected)\n hashes.set(value.algorithm, createHash(value.algorithm))\n return {\n update(content) {\n for (const hash of hashes.values())\n hash.update(content)\n },\n valid() {\n const actual = new Map([...hashes].map(([algorithm, hash]) => [algorithm, hash.digest('base64')]))\n return expected.some(value => actual.get(value.algorithm) === value.digest)\n },\n }\n}\n\nfunction repositoryUrl(repository: NpmRepository | string | undefined): string | null {\n if (typeof repository === 'string')\n return repository\n return typeof repository?.url === 'string' ? repository.url : null\n}\n\nfunction githubArchiveUrl(repository: NpmRepository | string | undefined, gitHead: string | undefined): string | null {\n if (!gitHead || !gitCommitPattern.test(gitHead))\n return null\n const source = repositoryUrl(repository)\n if (source === null)\n return null\n const match = source.match(/^(?:(?:git\\+)?https?:\\/\\/(?:git@)?github\\.com\\/|git:\\/\\/github\\.com\\/|git@github\\.com:)([\\w.-]+)\\/([\\w.-]+?)(?:\\.git)?\\/?$/)\n if (!match?.[1] || !match[2])\n return null\n return `https://codeload.github.com/${encodeURIComponent(match[1])}/${encodeURIComponent(match[2])}/tar.gz/${gitHead}`\n}\n\nfunction skipped(source: string, reason: string): SourceAttempt {\n return { source, status: 'skipped', reason }\n}\n\nfunction used(source: string): SourceAttempt {\n return { source, status: 'used' }\n}\n\nfunction withAttempts(error: SkillRunError, attempts: ReadonlyArray<SourceAttempt>): Result<never, SkillRunError> {\n return error._tag === 'SourceUnavailable'\n ? unavailable(error.message, attempts, error.cause)\n : err(error)\n}\n\nfunction remainingPolicy(policy: SkillOutputPolicy, files: ReadonlyArray<PreparedFile>): SkillOutputPolicy | null {\n const usedBytes = files.reduce((total, file) => total + file.content.byteLength, 0)\n const maxSourceFiles = policy.maxSourceFiles - files.length\n const maxSourceBytes = policy.maxSourceBytes - usedBytes\n if (maxSourceFiles <= 0 || maxSourceBytes <= 0)\n return null\n return { ...policy, maxSourceFiles, maxSourceBytes }\n}\n\nasync function extractResponse(\n response: Response,\n policy: SkillOutputPolicy,\n layout: 'github' | 'npm',\n verifier?: IntegrityVerifier,\n): Promise<Result<ExtractedArchive, SkillRunError>> {\n return extractArchive(\n responseChunks(\n response,\n policy.maxSourceBytes,\n 'Source archive exceeds the compressed byte limit.',\n content => verifier?.update(content),\n ),\n policy,\n layout,\n )\n}\n\nexport async function prepareNpmPackage(spec: string, policy: SkillOutputPolicy, fetchClient: FetchClient, signal?: AbortSignal): Promise<Result<PreparedSource, SkillRunError>> {\n const parsed = parsePackageSpec(spec)\n if (parsed === null)\n return unavailable('npm package spec is invalid.', [])\n\n const attempts: SourceAttempt[] = []\n const registryUrl = `https://registry.npmjs.org/${encodeURIComponent(parsed.name)}`\n const registryResponse = await fetchWithRedirects(fetchClient, registryUrl, {\n headers: { accept: 'application/vnd.npm.install-v1+json' },\n }, signal)\n if (registryResponse._tag === 'Err')\n return withAttempts(registryResponse.error, [skipped(registryUrl, registryResponse.error.message)])\n const response = registryResponse.value\n if (!response.ok) {\n await cancelBody(response)\n const message = `npm registry returned HTTP ${response.status}.`\n return unavailable(message, [skipped(registryUrl, message)])\n }\n\n const packumentBytes = await readBoundedResponse(response, packumentByteLimit)\n if (packumentBytes._tag === 'Err')\n return withAttempts(packumentBytes.error, [skipped(registryUrl, packumentBytes.error.message)])\n\n let packument: unknown\n try {\n packument = JSON.parse(Buffer.from(packumentBytes.value).toString('utf8')) as unknown\n }\n catch (cause) {\n const message = 'npm registry returned invalid package data.'\n return unavailable(message, [skipped(registryUrl, message)], cause)\n }\n\n const resolution = parseVersion(packument, parsed.version)\n if (resolution === null || !exactVersionPattern.test(resolution.resolvedVersion) || resolution.version.version !== resolution.resolvedVersion) {\n const message = 'npm package did not resolve to an exact version.'\n return unavailable(message, [skipped(registryUrl, message)])\n }\n const { repository, resolvedVersion, version } = resolution\n if (!version.dist.tarball.startsWith('https://')) {\n const message = 'npm package archive URL must use HTTPS.'\n return unavailable(message, [skipped(registryUrl, message)])\n }\n attempts.push(used(registryUrl))\n\n const fetchedArchive = await fetchWithRedirects(fetchClient, version.dist.tarball, {}, signal)\n if (fetchedArchive._tag === 'Err')\n return withAttempts(fetchedArchive.error, [...attempts, skipped(version.dist.tarball, fetchedArchive.error.message)])\n const archiveResponse = fetchedArchive.value\n if (!archiveResponse.ok) {\n await cancelBody(archiveResponse)\n const message = `npm package archive returned HTTP ${archiveResponse.status}.`\n return unavailable(message, [...attempts, skipped(version.dist.tarball, message)])\n }\n\n const verifier = createIntegrityVerifier(version.dist)\n if (verifier === null) {\n await cancelBody(archiveResponse)\n const message = 'npm package archive has no supported integrity value.'\n return unavailable(message, [...attempts, skipped(version.dist.tarball, message)])\n }\n const extracted = await extractResponse(archiveResponse, policy, 'npm', verifier)\n if (extracted._tag === 'Err')\n return withAttempts(extracted.error, [...attempts, skipped(version.dist.tarball, extracted.error.message)])\n if (!verifier.valid()) {\n const message = 'npm package archive integrity check failed.'\n return unavailable(message, [...attempts, skipped(version.dist.tarball, message)])\n }\n attempts.push(used(version.dist.tarball))\n let files = [...extracted.value.files]\n let skippedFiles = [...extracted.value.skippedFiles]\n\n const repositoryArchive = githubArchiveUrl(version.repository ?? repository, version.gitHead)\n const available = remainingPolicy(policy, files)\n if (repositoryArchive !== null && available === null) {\n attempts.push(skipped(repositoryArchive, 'Prepared package files reached the source limit.'))\n }\n else if (repositoryArchive !== null && available !== null) {\n const fetchedRepository = await fetchWithRedirects(fetchClient, repositoryArchive, {}, signal)\n if (fetchedRepository._tag === 'Err') {\n attempts.push(skipped(repositoryArchive, fetchedRepository.error.message))\n }\n else if (!fetchedRepository.value.ok) {\n const message = `GitHub source archive returned HTTP ${fetchedRepository.value.status}.`\n await cancelBody(fetchedRepository.value)\n attempts.push(skipped(repositoryArchive, message))\n }\n else {\n const repositoryFiles = await extractResponse(fetchedRepository.value, available, 'github')\n if (repositoryFiles._tag === 'Err') {\n attempts.push(skipped(repositoryArchive, repositoryFiles.error.message))\n }\n else {\n files = [\n ...files,\n ...repositoryFiles.value.files.map(file => ({ ...file, path: posix.join('repository', file.path) })),\n ]\n skippedFiles = [\n ...skippedFiles,\n ...repositoryFiles.value.skippedFiles.map(file => ({ ...file, path: posix.join('repository', file.path) })),\n ]\n attempts.push(used(repositoryArchive))\n }\n }\n }\n\n files.sort((left, right) => left.path.localeCompare(right.path))\n skippedFiles.sort((left, right) => left.path.localeCompare(right.path))\n return ok({\n files,\n skippedFiles,\n attempts,\n npmResolution: { package: parsed.name, version: resolvedVersion },\n })\n}\n","import type { HarnessV1NetworkSandboxSession, HarnessV1Skill } from '@ai-sdk/harness'\nimport type { CollectedFile, SandboxSession } from './internal/output/collect.ts'\nimport type { Result } from './internal/result.ts'\nimport type { PreparedSource } from './internal/source/host.ts'\nimport type { FetchClient } from './internal/source/npm.ts'\nimport type {\n CreateSkillHarnessOptions,\n GeneratedSkill,\n SkillDestination,\n SkillHarness,\n SkillOutputPolicy,\n SkillReview,\n SkillRun,\n SkillRunError,\n SkillRunEvent,\n SkillRunOptions,\n SkillRunReport,\n SkillRunResult,\n SkillRunUsage,\n} from './types.ts'\nimport { lstat, realpath } from 'node:fs/promises'\nimport { basename, join, posix, resolve } from 'node:path'\nimport { HarnessAgent } from '@ai-sdk/harness/agent'\nimport { parseOutputPolicy, parseSkillRun } from './internal/input.ts'\nimport { collectSandboxOutput } from './internal/output/collect.ts'\nimport { promoteSkill } from './internal/output/promote.ts'\nimport { validateGeneratedSkill, validateSkillReview } from './internal/output/validate.ts'\nimport { resolveWithin } from './internal/paths.ts'\nimport { err, ok } from './internal/result.ts'\nimport { collectHostDirectory, skippedFileWarnings } from './internal/source/host.ts'\nimport { prepareNpmPackage } from './internal/source/npm.ts'\nimport { DEFAULT_OUTPUT_POLICY, loadSkilldMaintainedSkill } from './skills.ts'\n\ninterface PreparedRun {\n readonly skillName: 'generate-package-skill' | 'update-package-skill' | 'generate-project-skill' | 'review-skill'\n readonly outputName: string\n readonly source: PreparedSource\n // Path under `input/source`. A reviewed Skill keeps its directory name, so\n // review-skill can compare that name with the frontmatter `name`.\n readonly sourceDir: string\n readonly current?: PreparedSource\n readonly destination?: SkillDestination\n}\n\ninterface ActiveSandbox {\n readonly sandbox: SandboxSession\n readonly workDir: string\n}\n\n/** The outcome of one Skill run before the Harness attaches its report. */\ntype RunOutcome = Result<GeneratedSkill | SkillReview, SkillRunError>\n\n/** Collects the cost of one Skill run and every warning beside its outcome. */\ninterface RunLog {\n /** Forwards an event to the caller and counts each finished step. */\n readonly emit: (event: SkillRunEvent) => void\n readonly warn: (warning: string) => void\n /** Replaces the counted steps with the totals the Agent reported at its end. */\n readonly settle: (usage: SkillRunUsage, steps: number) => void\n readonly report: () => SkillRunReport\n}\n\nfunction addCount(total: number | undefined, count: number | undefined): number | undefined {\n return total === undefined ? count : count === undefined ? total : total + count\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (typeof value === 'object' || typeof value === 'function')\n && value !== null\n && typeof (value as { then?: unknown }).then === 'function'\n}\n\nfunction createRunLog(onEvent: SkillRunOptions['onEvent']): RunLog {\n const warnings: string[] = []\n const eventFailures = new Set<string>()\n let usage: SkillRunUsage = { inputTokens: undefined, cachedInputTokens: undefined, outputTokens: undefined }\n let steps = 0\n // The Agent SDK drops callback errors, so surface them on the report instead.\n const fail = (cause: unknown) => {\n eventFailures.add(`onEvent failed: ${cause instanceof Error ? cause.message : String(cause)}`)\n }\n return {\n emit: (event) => {\n if (event._tag === 'StepFinish') {\n steps += 1\n usage = {\n inputTokens: addCount(usage.inputTokens, event.usage.inputTokens),\n cachedInputTokens: addCount(usage.cachedInputTokens, event.usage.cachedInputTokens),\n outputTokens: addCount(usage.outputTokens, event.usage.outputTokens),\n }\n }\n if (!onEvent)\n return\n try {\n const returned: unknown = onEvent(event)\n // An async listener or custom thenable would otherwise reject unhandled and can end the host process.\n if (isPromiseLike(returned))\n Promise.resolve(returned).catch(fail)\n }\n catch (cause) {\n fail(cause)\n }\n },\n warn: warning => warnings.push(warning),\n settle: (total, count) => {\n usage = total\n steps = count\n },\n report: () => ({ usage, steps, warnings: [...warnings, ...eventFailures] }),\n }\n}\n\n/** The fields this package reads from the Agent SDK usage report. */\ninterface AgentUsage {\n readonly inputTokens: number | undefined\n readonly inputTokenDetails: { readonly cacheReadTokens: number | undefined }\n readonly outputTokens: number | undefined\n}\n\nfunction toUsage(usage: AgentUsage): SkillRunUsage {\n return {\n inputTokens: usage.inputTokens,\n cachedInputTokens: usage.inputTokenDetails.cacheReadTokens,\n outputTokens: usage.outputTokens,\n }\n}\n\n/** An unknown count in any turn keeps the total unknown. */\nfunction sumUsage(a: SkillRunUsage, b: SkillRunUsage): SkillRunUsage {\n const sum = (x: number | undefined, y: number | undefined) => x === undefined || y === undefined ? undefined : x + y\n return { inputTokens: sum(a.inputTokens, b.inputTokens), cachedInputTokens: sum(a.cachedInputTokens, b.cachedInputTokens), outputTokens: sum(a.outputTokens, b.outputTokens) }\n}\n\n/** Turns the Agent gets to fix output that failed the deterministic checks, in the same session. */\nconst OUTPUT_REPAIR_TURNS = 2\n\nfunction repairRequest(outputPath: string, issues: ReadonlyArray<string>): string {\n return [\n `The Harness checked the output at \\`${outputPath}\\` and found these problems:`,\n '',\n ...issues.map(issue => `- ${issue}`),\n '',\n `Fix each problem in place. Write no files outside \\`${outputPath}\\`. Finish when the output passes these checks.`,\n ].join('\\n')\n}\n\nasync function prepareCurrentSkill(destination: SkillDestination, policy: SkillOutputPolicy, signal?: AbortSignal): Promise<Result<PreparedSource | undefined, SkillRunError>> {\n const root = resolve(destination.rootDir)\n const rootStat = await lstat(root).catch(error => error as NodeJS.ErrnoException)\n if (rootStat instanceof Error) {\n if (rootStat.code === 'ENOENT')\n return ok(undefined)\n return err({ _tag: 'UnsafeOutputPath', message: 'Output root cannot be inspected.', path: root })\n }\n if (!rootStat.isDirectory() || rootStat.isSymbolicLink())\n return err({ _tag: 'UnsafeOutputPath', message: 'Output root must be a directory, not a symbolic link.', path: root })\n const canonicalRoot = await realpath(root).catch(error => error as Error)\n if (canonicalRoot instanceof Error || canonicalRoot !== root)\n return err({ _tag: 'UnsafeOutputPath', message: 'Output root must not pass through a symbolic link.', path: root })\n\n const target = join(root, destination.name)\n const targetStat = await lstat(target).catch(error => error as NodeJS.ErrnoException)\n if (targetStat instanceof Error) {\n if (targetStat.code === 'ENOENT')\n return ok(undefined)\n return err({ _tag: 'UnsafeOutputPath', message: 'Output path cannot be inspected.', path: target })\n }\n if (!targetStat.isDirectory() || targetStat.isSymbolicLink())\n return err({ _tag: 'UnsafeOutputPath', message: 'Output path must be a directory, not a symbolic link.', path: target })\n return collectHostDirectory(target, policy, 'current Skill', signal)\n}\n\nasync function prepareRun(input: SkillRun, policy: SkillOutputPolicy, fetchClient: FetchClient, signal?: AbortSignal): Promise<Result<PreparedRun, SkillRunError>> {\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n\n const current = input._tag === 'ReviewSkill'\n ? ok(undefined)\n : await prepareCurrentSkill(input.destination, policy, signal)\n if (current._tag === 'Err')\n return current\n\n if (input._tag === 'ProjectSkill') {\n const source = await collectHostDirectory(input.projectDir, policy, input.projectDir, signal)\n return source._tag === 'Err'\n ? source\n : ok({ skillName: 'generate-project-skill', outputName: input.destination.name, source: source.value, sourceDir: '', current: current.value, destination: input.destination })\n }\n\n if (input._tag === 'ReviewSkill') {\n const source = await collectHostDirectory(input.skillDir, policy, input.skillDir, signal)\n return source._tag === 'Err'\n ? source\n : ok({ skillName: 'review-skill', outputName: 'review', source: source.value, sourceDir: basename(input.skillDir) })\n }\n\n if (input.source._tag === 'NpmPackage') {\n const source = await prepareNpmPackage(input.source.spec, policy, fetchClient, signal)\n if (signal?.aborted)\n return err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' })\n return source._tag === 'Err'\n ? source\n : ok({ skillName: packageSkillName(current.value), outputName: input.destination.name, source: source.value, sourceDir: '', current: current.value, destination: input.destination })\n }\n\n const packageDir = resolveWithin(input.source.rootDir, input.source.packageDir)\n if (packageDir === null)\n return err({ _tag: 'InvalidInput', message: 'Local package directory must stay inside its root directory.' })\n const manifest = await lstat(join(packageDir, 'package.json')).catch(error => error as NodeJS.ErrnoException)\n if (manifest instanceof Error || !manifest.isFile() || manifest.isSymbolicLink()) {\n return err({\n _tag: 'SourceUnavailable',\n message: 'Local package directory must contain package.json.',\n attempts: [{ source: packageDir, status: 'skipped', reason: 'package.json is unavailable.' }],\n })\n }\n\n const source = await collectHostDirectory(packageDir, policy, packageDir, signal)\n return source._tag === 'Err'\n ? source\n : ok({ skillName: packageSkillName(current.value), outputName: input.destination.name, source: source.value, sourceDir: '', current: current.value, destination: input.destination })\n}\n\n/** A destination that already holds the Skill gets an update run, which tests only what the release changed. */\nfunction packageSkillName(current: PreparedSource | undefined): 'generate-package-skill' | 'update-package-skill' {\n return current === undefined ? 'generate-package-skill' : 'update-package-skill'\n}\n\nfunction requestContent(skill: HarnessV1Skill): string {\n const request = skill.files?.find(file => file.path === 'assets/harness-request.md')\n if (!request)\n throw new Error(`Harness request asset is missing for ${skill.name}.`)\n return request.content\n}\n\nfunction renderRequest(template: string, sourcePath: string, currentSkillPath: string, outputPath: string, skillName: string): string {\n return template\n .replaceAll('{{SOURCE_PATH}}', sourcePath)\n .replaceAll('{{CURRENT_SKILL_PATH}}', currentSkillPath)\n .replaceAll('{{OUTPUT_PATH}}', outputPath)\n .replaceAll('{{SKILL_NAME}}', skillName)\n}\n\nfunction sourcePathOf(active: ActiveSandbox, prepared: PreparedRun): string {\n return posix.join(active.workDir, 'input/source', prepared.sourceDir)\n}\n\nasync function writePreparedSource(active: ActiveSandbox, prepared: PreparedRun, signal?: AbortSignal): Promise<void> {\n const sourcePath = sourcePathOf(active, prepared)\n const reset = await active.sandbox.run({\n command: 'rm -rf -- \"$SKILLD_INPUT\" \"$SKILLD_OUTPUT\" && mkdir -p -- \"$SKILLD_INPUT\"',\n env: {\n SKILLD_INPUT: posix.join(active.workDir, 'input'),\n SKILLD_OUTPUT: posix.join(active.workDir, 'skilld-output'),\n },\n abortSignal: signal,\n })\n if (reset.exitCode !== 0)\n throw new Error(reset.stderr.trim() || 'Harness work directory cannot be prepared.')\n for (const file of prepared.source.files) {\n await active.sandbox.writeBinaryFile({\n path: posix.join(sourcePath, file.path),\n content: file.content,\n abortSignal: signal,\n })\n }\n for (const file of prepared.current?.files ?? []) {\n await active.sandbox.writeBinaryFile({\n path: posix.join(active.workDir, 'input/current-skill', file.path),\n content: file.content,\n abortSignal: signal,\n })\n }\n await active.sandbox.writeTextFile({\n path: posix.join(active.workDir, 'input/source-manifest.json'),\n content: `${JSON.stringify({\n sourceAttempts: prepared.source.attempts,\n skippedFiles: prepared.source.skippedFiles,\n npmResolution: prepared.source.npmResolution,\n hasCurrentSkill: prepared.current !== undefined,\n }, null, 2)}\\n`,\n abortSignal: signal,\n })\n}\n\nfunction agentError(cause: unknown, signal?: AbortSignal): SkillRunError {\n return signal?.aborted\n ? { _tag: 'Cancelled', message: 'Skill run was cancelled.' }\n : { _tag: 'AgentFailed', message: 'Harness Agent failed during the Skill run.', cause }\n}\n\nfunction toAgentError(cause: unknown, signal?: AbortSignal): RunOutcome {\n return err(agentError(cause, signal))\n}\n\nexport function createSkillHarness(options: CreateSkillHarnessOptions): SkillHarness {\n const policy = parseOutputPolicy({ ...DEFAULT_OUTPUT_POLICY, ...options.outputPolicy })\n const fetchClient: FetchClient = options.fetch ?? globalThis.fetch.bind(globalThis)\n const sandboxConfig = { ...options.sandboxConfig }\n const harness = options.harness\n const sandbox = options.sandbox\n\n return {\n // Each input tag maps to one Skill, and that Skill decides the value tag,\n // so the wide result is the narrowed result for this input.\n run: <Run extends SkillRun>(input: Run, runOptions: SkillRunOptions = {}) =>\n runSkill(input, runOptions) as Promise<SkillRunResult<Run['_tag']>>,\n }\n\n async function runSkill(input: SkillRun, runOptions: SkillRunOptions): Promise<SkillRunResult> {\n const log = createRunLog(runOptions.onEvent)\n const outcome = await runLogged(input, runOptions, log)\n const report = log.report()\n return outcome._tag === 'Ok'\n ? { _tag: 'Ok', value: outcome.value, report }\n : { _tag: 'Err', error: outcome.error, report }\n }\n\n async function runLogged(input: SkillRun, runOptions: SkillRunOptions, log: RunLog): Promise<RunOutcome> {\n const parsed = parseSkillRun(input)\n if (parsed._tag === 'Err')\n return parsed\n\n const prepared = await prepareRun(parsed.value, policy, fetchClient, runOptions.signal)\n if (prepared._tag === 'Err')\n return prepared\n for (const warning of skippedFileWarnings(prepared.value.source.skippedFiles, policy))\n log.warn(warning)\n\n const skill = await loadSkilldMaintainedSkill(prepared.value.skillName)\n // The Harness creates and owns the sandbox session, and hands it to the\n // Agent. The Agent never sees the provider, so it never destroys the\n // session itself, and the deprecated provider path stays unused.\n const sandboxSession = await sandbox.createSession({ abortSignal: runOptions.signal }).then(ok, cause => err(cause))\n if (sandboxSession._tag === 'Err')\n return toAgentError(sandboxSession.error, runOptions.signal)\n const result = await runAgent(prepared.value, skill, sandboxSession.value, log, runOptions.signal)\n const destroyed = await Promise.resolve(sandboxSession.value.destroy()).then(() => undefined, cause => cause as unknown)\n if (destroyed !== undefined)\n log.warn(`Sandbox session cleanup failed: ${destroyed instanceof Error ? destroyed.message : String(destroyed)}`)\n return result\n }\n\n async function runAgent(\n prepared: PreparedRun,\n skill: HarnessV1Skill,\n sandboxSession: HarnessV1NetworkSandboxSession,\n log: RunLog,\n signal?: AbortSignal,\n ): Promise<RunOutcome> {\n let active: ActiveSandbox | undefined\n const userOnSession = sandboxConfig.onSession\n const agent = new HarnessAgent({\n harness,\n skills: [skill],\n permissionMode: 'allow-all',\n sandboxConfig: {\n ...sandboxConfig,\n onSession: async (sessionOptions) => {\n active = { sandbox: sessionOptions.session, workDir: sessionOptions.sessionWorkDir }\n await writePreparedSource(active, prepared, signal)\n await userOnSession?.(sessionOptions)\n },\n },\n })\n\n const sessionResult = await agent.createSession({ sandboxSession, abortSignal: signal }).then(ok, cause => err(cause))\n if (sessionResult._tag === 'Err')\n return toAgentError(sessionResult.error, signal)\n const session = sessionResult.value\n\n try {\n if (!active)\n return err({ _tag: 'AgentFailed', message: 'Harness did not provide its sandbox session.' })\n const sourcePath = sourcePathOf(active, prepared)\n const currentSkillPath = posix.join(active.workDir, 'input/current-skill')\n const outputPath = posix.join(active.workDir, 'skilld-output', prepared.outputName)\n const prompt = renderRequest(requestContent(skill), sourcePath, currentSkillPath, outputPath, prepared.outputName)\n const outputSandbox = active.sandbox\n // Steps count across turns, so a repair turn continues the numbering.\n let step = 0\n let stepOffset = 0\n let usage: SkillRunUsage | undefined\n const turn = async (text: string): Promise<Result<void, SkillRunError>> => {\n const generated = await agent.generate({\n session,\n prompt: text,\n abortSignal: signal,\n onStepStart: (event) => {\n step = stepOffset + event.stepNumber\n log.emit({ _tag: 'StepStart', step })\n },\n onToolExecutionStart: ({ toolCall }) => {\n log.emit({ _tag: 'ToolCall', step, toolName: toolCall.toolName, toolCallId: toolCall.toolCallId, input: toolCall.input })\n },\n onStepEnd: (result) => {\n log.emit({ _tag: 'StepFinish', step: stepOffset + result.stepNumber, finishReason: result.finishReason, usage: toUsage(result.usage) })\n },\n }).then(ok, cause => err(cause))\n if (generated._tag === 'Err')\n return err(agentError(generated.error, signal))\n const turnUsage = toUsage(generated.value.totalUsage)\n usage = usage ? sumUsage(usage, turnUsage) : turnUsage\n stepOffset += generated.value.steps.length\n log.settle(usage, stepOffset)\n return signal?.aborted ? err({ _tag: 'Cancelled', message: 'Skill run was cancelled.' }) : ok(undefined)\n }\n const check = async (): Promise<Result<ReadonlyArray<CollectedFile>, SkillRunError>> => {\n const collected = await collectSandboxOutput(outputSandbox, outputPath, policy, signal)\n if (collected._tag === 'Err')\n return collected\n const validated = prepared.skillName === 'review-skill'\n ? validateSkillReview(collected.value)\n : validateGeneratedSkill(\n prepared.outputName,\n collected.value,\n prepared.skillName === 'generate-project-skill'\n ? { _tag: 'ProjectSkill', projectPaths: prepared.source.files.map(file => file.path) }\n : { _tag: 'PackageSkill' },\n )\n return validated._tag === 'Err' ? validated : ok(collected.value)\n }\n\n const first = await turn(prompt)\n if (first._tag === 'Err')\n return first\n let checked = await check()\n // A failed check goes back to the Agent, which still holds its context, instead of failing the run.\n for (let repair = 1; repair <= OUTPUT_REPAIR_TURNS && checked._tag === 'Err' && checked.error._tag === 'InvalidSkill'; repair++) {\n log.warn(`Output checks failed; repair turn ${repair} of ${OUTPUT_REPAIR_TURNS}: ${checked.error.issues.join(' ')}`)\n const repaired = await turn(repairRequest(outputPath, checked.error.issues))\n if (repaired._tag === 'Err')\n return repaired\n checked = await check()\n }\n if (checked._tag === 'Err')\n return checked\n const collected = checked\n\n if (prepared.skillName === 'review-skill')\n return validateSkillReview(collected.value)\n\n if (!prepared.destination)\n return err({ _tag: 'InvalidInput', message: 'Skill destination is required.' })\n const promoted = await promoteSkill(\n prepared.destination.rootDir,\n prepared.destination.name,\n collected.value,\n prepared.source.attempts,\n )\n if (promoted._tag === 'Err')\n return promoted\n for (const warning of promoted.value.warnings)\n log.warn(warning)\n return ok(promoted.value.skill)\n }\n finally {\n await session.destroy()\n }\n }\n}\n"],"mappings":";;;;;;;;;AAIA,MAAa,MAAS,WAAgC;CAAE,MAAM;CAAM;AAAM;AAC1E,MAAa,OAAU,WAAgC;CAAE,MAAM;CAAO;AAAM;ACC5E,SAASA,UAAQ,SAA+C;CAC9D,OAAO,IAAI;EAAE,MAAM;EAAgB;CAAQ,CAAC;AAC9C;AAEA,SAAS,iBAAiB,OAAiC;CACzD,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,CAAC,CAAC,SAAS;AAC5D;AAEA,SAAgB,cAAc,OAAkD;CAC9E,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,UAAU,QACrD,OAAOA,UAAQ,+CAA+C;CAEhE,IAAI,MAAM,SAAS,gBAAgB;EACjC,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,aAC1B,OAAOA,UAAQ,oCAAoC;EACrD,IAAI,CAAC,iBAAiB,MAAM,YAAY,OAAO,KAAK,CAAC,YAAY,MAAM,YAAY,IAAI,GACrF,OAAOA,UAAQ,uCAAuC;EACxD,IAAI,MAAM,OAAO,SAAS,cAAc;GACtC,IAAI,CAAC,iBAAiB,MAAM,OAAO,IAAI,GACrC,OAAOA,UAAQ,+BAA+B;GAChD,OAAO,GAAG;IACR,MAAM;IACN,QAAQ;KAAE,MAAM;KAAc,MAAM,MAAM,OAAO;IAAK;IACtD,aAAa;KAAE,SAAS,QAAQ,MAAM,YAAY,OAAO;KAAG,MAAM,MAAM,YAAY;IAAK;GAC3F,CAAC;EACH;EACA,IAAI,MAAM,OAAO,SAAS,gBAAgB;GACxC,IAAI,CAAC,iBAAiB,MAAM,OAAO,OAAO,KAAK,CAAC,iBAAiB,MAAM,OAAO,UAAU,GACtF,OAAOA,UAAQ,mCAAmC;GACpD,IAAI,cAAc,MAAM,OAAO,SAAS,MAAM,OAAO,UAAU,MAAM,MACnE,OAAOA,UAAQ,8DAA8D;GAC/E,OAAO,GAAG;IACR,MAAM;IACN,QAAQ;KACN,MAAM;KACN,SAAS,QAAQ,MAAM,OAAO,OAAO;KACrC,YAAY,MAAM,OAAO;IAC3B;IACA,aAAa;KAAE,SAAS,QAAQ,MAAM,YAAY,OAAO;KAAG,MAAM,MAAM,YAAY;IAAK;GAC3F,CAAC;EACH;EACA,OAAOA,UAAQ,gCAAgC;CACjD;CAEA,IAAI,MAAM,SAAS,gBAAgB;EACjC,IAAI,CAAC,iBAAiB,MAAM,UAAU,KAAK,CAAC,MAAM,aAChD,OAAOA,UAAQ,oCAAoC;EACrD,IAAI,CAAC,iBAAiB,MAAM,YAAY,OAAO,KAAK,CAAC,YAAY,MAAM,YAAY,IAAI,GACrF,OAAOA,UAAQ,uCAAuC;EACxD,OAAO,GAAG;GACR,MAAM;GACN,YAAY,QAAQ,MAAM,UAAU;GACpC,aAAa;IAAE,SAAS,QAAQ,MAAM,YAAY,OAAO;IAAG,MAAM,MAAM,YAAY;GAAK;EAC3F,CAAC;CACH;CAEA,IAAI,MAAM,SAAS,eAAe;EAChC,IAAI,CAAC,iBAAiB,MAAM,QAAQ,GAClC,OAAOA,UAAQ,qCAAqC;EACtD,OAAO,GAAG;GAAE,MAAM;GAAe,UAAU,QAAQ,MAAM,QAAQ;EAAE,CAAC;CACtE;CAEA,OAAOA,UAAQ,2BAA2B;AAC5C;AAEA,SAAgB,kBAAkB,QAA8C;CAC9E,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAC/C,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GAC3C,MAAM,IAAI,UAAU,GAAG,KAAK,6BAA6B;CAE7D,OAAO,OAAO,OAAO,MAAM;AAC7B;AChEA,MAAMC,aAAW,SAAiB,WAChC,IAAI;CAAE,MAAM;CAAgB;CAAS;AAAO,CAAC;AAE/C,MAAM,YAAY,OAChB,SACA,WACA,WACgG;CAChG,IAAI,QAAQ,SACV,OAAO,IAAI;EAAE,MAAM;EAAa,SAAS;CAA2B,CAAC;CACvE,MAAM,UAAU;CAChB,MAAM,SAAS,MAAM,QAAQ,QAAQ,CAAC,CAAC,WAAW,QAAQ,IAAI;EAC5D;EACA,KAAK;GAAE,QAAQ;GAAK,eAAe;EAAU;EAC7C,aAAa;CACf,CAAC,CAAC,CAAC,CAAC,OAAM,UAAS,KAAc;CACjC,IAAI,kBAAkB,OACpB,OAAOA,UAAQ,uCAAuC,CAAC,OAAO,OAAO,CAAC;CACxE,IAAI,OAAO,aAAa,GACtB,OAAOA,UAAQ,wCAAwC,CAAC,OAAO,OAAO,KAAK,KAAK,sBAAsB,CAAC;CAEzG,MAAM,SAAS,OAAO,OAAO,MAAM,IAAI;CACvC,IAAI,OAAO,GAAG,EAAE,MAAM,IACpB,OAAO,IAAI;CACb,IAAI,OAAO,SAAS,MAAM,GACxB,OAAOA,UAAQ,wCAAwC,CAAC,yCAAyC,CAAC;CAEpG,MAAM,UAA+D,CAAC;CACtE,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;EACrD,MAAM,OAAO,OAAO;EACpB,MAAM,OAAO,OAAO,QAAQ;EAC5B,MAAM,OAAO,OAAO,OAAO,QAAQ,EAAE;EACrC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GAC1D,OAAOA,UAAQ,wCAAwC,CAAC,oCAAoC,CAAC;EAC/F,QAAQ,KAAK;GAAE;GAAM;GAAM;EAAK,CAAC;CACnC;CACA,OAAO,GAAG,OAAO;AACnB;AAEA,MAAa,uBAAuB,OAClC,SACA,WACA,QACA,WACiE;CACjE,MAAM,SAAS,MAAM,UAAU,SAAS,WAAW,MAAM;CACzD,IAAI,OAAO,SAAS,OAClB,OAAO;CAET,MAAM,QAAyB,CAAC;CAChC,MAAM,uBAAO,IAAI,IAAY;CAC7B,IAAI,aAAa;CACjB,KAAK,MAAM,SAAS,OAAO,OAAO;EAChC,IAAI,QAAQ,SACV,OAAO,IAAI;GAAE,MAAM;GAAa,SAAS;EAA2B,CAAC;EACvE,MAAM,OAAO,oBAAoB,MAAM,IAAI;EAC3C,IAAI,SAAS,MACX,OAAOA,UAAQ,4CAA4C,CAAC,MAAM,IAAI,CAAC;EACzE,IAAI,MAAM,SAAS,KACjB;EACF,IAAI,MAAM,SAAS,KACjB,OAAOA,UAAQ,sDAAsD,CAAC,IAAI,CAAC;EAC7E,IAAI,KAAK,IAAI,IAAI,GACf,OAAOA,UAAQ,4CAA4C,CAAC,IAAI,CAAC;EACnE,IAAI,MAAM,UAAU,OAAO,gBACzB,OAAOA,UAAQ,2CAA2C,CAAC,UAAU,OAAO,gBAAgB,CAAC;EAC/F,IAAI,MAAM,OAAO,OAAO,oBACtB,OAAOA,UAAQ,8CAA8C,CAAC,IAAI,CAAC;EACrE,IAAI,aAAa,MAAM,OAAO,OAAO,gBACnC,OAAOA,UAAQ,gDAAgD,CAAC,UAAU,OAAO,gBAAgB,CAAC;EAEpG,MAAM,UAAU,MAAM,QAAQ,QAAQ,CAAC,CAAC,WAAW,QAAQ,eAAe;GAAE,MAAM,GAAG,UAAU,GAAG;GAAQ,aAAa;EAAO,CAAC,CAAC,CAAC,CAAC,OAAM,UAAS,KAAc;EAC/J,IAAI,mBAAmB,OAAO;GAC5B,IAAI,QAAQ,SACV,OAAO,IAAI;IAAE,MAAM;IAAa,SAAS;GAA2B,CAAC;GACvE,OAAOA,UAAQ,kCAAkC,CAAC,MAAM,QAAQ,OAAO,CAAC;EAC1E;EACA,IAAI,YAAY,QAAQ,QAAQ,eAAe,MAAM,MACnD,OAAOA,UAAQ,6CAA6C,CAAC,IAAI,CAAC;EACpE,KAAK,IAAI,IAAI;EACb,MAAM,KAAK;GAAE;GAAM,SAAS,WAAW,KAAK,OAAO;EAAE,CAAC;EACtD,cAAc,QAAQ;CACxB;CAEA,MAAM,QAAQ,MAAM,UAAU,SAAS,WAAW,MAAM;CACxD,IAAI,MAAM,SAAS,OACjB,OAAO;CACT,IAAI,KAAK,UAAU,OAAO,KAAK,MAAM,KAAK,UAAU,MAAM,KAAK,GAC7D,OAAOA,UAAQ,6CAA6C,CAAC,yBAAyB,CAAC;CAEzF,MAAM,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;CAC/D,OAAO,GAAG,KAAK;AACjB;ACjGA,SAAS,UAAU,SAAiB,MAA4C;CAC9E,OAAO,IAAI;EAAE,MAAM;EAAoB;EAAS;CAAK,CAAC;AACxD;AAEA,MAAM,UAAU,OAAO,SAAS;AAQhC,eAAe,cAAc,MAAc;CACzC,OAAO,MAAM,IAAI,CAAC,CAAC,OAAM,UAAU,MAAgC,SAAS,WAAW,UAAU,QAAQ,OAAO,KAAK,CAAC;AACxH;AAEA,MAAa,eAAe,OAC1B,SACA,MACA,OACA,aACkD;CAClD,MAAM,OAAO,QAAQ,OAAO;CAC5B,IAAI,WAAW,MAAM,cAAc,IAAI,CAAC,CAAC,OAAM,UAAS,KAAc;CACtE,IAAI,oBAAoB,OACtB,OAAO,UAAU,oCAAoC,IAAI;CAC3D,IAAI,cAAc;CAClB,IAAI,aAAa,SAAS;EACxB,MAAM,SAAS,QAAQ,IAAI;EAC3B,MAAM,aAAa,MAAM,cAAc,MAAM,CAAC,CAAC,OAAM,UAAS,KAAc;EAC5E,IAAI,sBAAsB,SAAS,eAAe,WAAW,CAAC,WAAW,YAAY,KAAK,WAAW,eAAe,GAClH,OAAO,UAAU,qDAAqD,MAAM;EAC9E,MAAM,kBAAkB,MAAM,SAAS,MAAM,CAAC,CAAC,OAAM,UAAS,KAAc;EAC5E,IAAI,2BAA2B,SAAS,oBAAoB,QAC1D,OAAO,UAAU,6DAA6D,MAAM;EACtF,MAAM,UAAU,MAAM,MAAM,MAAM,EAAE,MAAM,IAAM,CAAC,CAAC,CAAC,WAAW,OAAM,UAAS,KAA8B;EAC3G,IAAI,mBAAmB,SAAS,QAAQ,SAAS,UAC/C,OAAO,UAAU,kCAAkC,IAAI;EACzD,cAAc,YAAY;EAC1B,WAAW,MAAM,cAAc,IAAI,CAAC,CAAC,OAAM,UAAS,KAAc;CACpE;CACA,IAAI,oBAAoB,SAAS,aAAa,WAAW,CAAC,SAAS,YAAY,KAAK,SAAS,eAAe,GAC1G,OAAO,UAAU,yDAAyD,IAAI;CAChF,MAAM,gBAAgB,MAAM,SAAS,IAAI,CAAC,CAAC,OAAM,UAAS,KAAc;CACxE,IAAI,yBAAyB,OAC3B,OAAO,UAAU,mCAAmC,IAAI;CAC1D,IAAI,kBAAkB,MACpB,OAAO,UAAU,sDAAsD,IAAI;CAE7E,MAAM,SAAS,KAAK,MAAM,IAAI;CAC9B,MAAM,aAAa,MAAM,cAAc,MAAM,CAAC,CAAC,OAAM,UAAS,KAAc;CAC5E,IAAI,sBAAsB,OACxB,OAAO,UAAU,oCAAoC,MAAM;CAC7D,IAAI,eAAe,YAAY,CAAC,WAAW,YAAY,KAAK,WAAW,eAAe,IACpF,OAAO,UAAU,yDAAyD,MAAM;CAElF,MAAM,WAAW,KAAK,MAAM,WAAW,KAAK,MAAM;CAClD,MAAM,OAAO,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,OAAM,UAAS,KAA8B;CACrF,IAAI,gBAAgB,OAAO;EACzB,IAAI,KAAK,SAAS,UAChB,OAAO,IAAI;GAAE,MAAM;GAAc,SAAS;GAA4C,MAAM;EAAO,CAAC;EACtG,OAAO,IAAI;GAAE,MAAM;GAAmB,SAAS;GAAqC,MAAM;GAAQ,OAAO;EAAK,CAAC;CACjH;CAEA,MAAM,QAAQ,WAAW;CACzB,MAAM,UAAU,KAAK,MAAM,WAAW,KAAK,GAAG,MAAM,MAAM;CAC1D,MAAM,SAAS,KAAK,MAAM,WAAW,KAAK,GAAG,MAAM,UAAU;CAC7D,IAAI,eAAe;CACnB,IAAI,WAAW;CACf,IAAI,iBAAiB;CACrB,IAAI;CAEJ,IAAI;EACF,MAAM,MAAM,SAAS,EAAE,MAAM,IAAM,CAAC;EACpC,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,cAAc,KAAK,SAAS,KAAK,IAAI;GAC3C,MAAM,MAAM,QAAQ,WAAW,GAAG;IAAE,WAAW;IAAM,MAAM;GAAM,CAAC;GAClE,MAAM,UAAU,aAAa,KAAK,SAAS;IAAE,MAAM;IAAM,MAAM;GAAM,CAAC;EACxE;EAEA,IAAI,eAAe,SAAS;GAC1B,MAAM,OAAO,QAAQ,MAAM;GAC3B,eAAe;EACjB;EACA,MAAM,OAAO,SAAS,MAAM;EAC5B,WAAW;CACb,SACO,OAAO;EACZ,eAAe;EACf,IAAI,gBAAgB,CAAC,UAAU;GAC7B,MAAM,UAAU,MAAM,cAAc,MAAM,CAAC,CAAC,OAAM,UAAS,KAAc;GACzE,IAAI,mBAAmB,OAAO;IAC5B,iBAAiB;IACjB,eAAe,IAAI,eAAe,CAAC,OAAO,OAAO,CAAC;GACpD;GACA,IAAI,YAAY,SAAS;IACvB,MAAM,WAAW,MAAM,OAAO,QAAQ,MAAM,CAAC,CAAC,OAAM,UAAS,KAAc;IAC3E,IAAI,oBAAoB,OAAO;KAC7B,iBAAiB;KACjB,eAAe,IAAI,eAAe,CAAC,OAAO,QAAQ,CAAC;IACrD;GACF;EACF;CACF;CAEA,MAAM,oBAA+B,CAAC;CACtC,MAAM,KAAK,MAAM,CAAC,CAAC,OAAM,UAAS,kBAAkB,KAAK,KAAK,CAAC;CAC/D,MAAM,OAAO,QAAQ,CAAC,CAAC,OAAM,UAAS,kBAAkB,KAAK,KAAK,CAAC;CAEnE,IAAI,UAAU;EACZ,MAAM,WAAqB,CAAC;EAC5B,IAAI,kBAAkB,SAAS,GAAG;GAChC,MAAM,SAAS,kBAAkB,KAAI,UAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;GAC/G,SAAS,KAAK,iCAAiC,SAAS,IAAI,QAAQ;EACtE;EACA,IAAI,cAAc;GAChB,MAAM,gBAAgB,MAAM,GAAG,QAAQ,EAAE,WAAW,KAAK,CAAC,CAAC,CAAC,OAAM,UAAS,KAAc;GACzF,IAAI,yBAAyB,OAC3B,SAAS,KAAK,oCAAoC,OAAO,IAAI,cAAc,SAAS;EACxF;EACA,OAAO,GAAG;GACR,OAAO;IACL,MAAM;IACN;IACA,WAAW;IACX,OAAO,MAAM,KAAI,UAAS;KAAE,MAAM,KAAK;KAAM,OAAO,KAAK,QAAQ;IAAW,EAAE;IAC9E,gBAAgB;GAClB;GACA;EACF,CAAC;CACH;CAEA,MAAM,gBAAgB,CAAC,GAAG,iBAAiB;CAC3C,MAAM,GAAG,SAAS;EAAE,WAAW;EAAM,OAAO;CAAK,CAAC,CAAC,CAAC,OAAM,UAAS,cAAc,KAAK,KAAK,CAAC;CAC5F,IAAI,aACF,MAAM,MAAM,IAAI,CAAC,CAAC,OAAM,UAAS,cAAc,KAAK,KAAK,CAAC;CAC5D,MAAM,SAAS,iBAAiB,KAAA,IAAY,gBAAgB,CAAC,cAAc,GAAG,aAAa;CAC3F,MAAM,QAAQ,OAAO,UAAU,IAAI,OAAO,KAAK,IAAI,eAAe,QAAQ,8BAA8B;CACxG,OAAO,IAAI;EAAE,MAAM;EAAmB,SAAS;EAAgB,MAAM;EAAQ;CAAM,CAAC;AACtF;AClJA,MAAM,gBAAgB;AAGtB,MAAM,aAAa;AAGnB,MAAM,cAAc;;;;;;AASpB,SAAM,gBAAS,UAAA;CAEf,OAAM,SAAW,QAAA,aAAA,EAAA,CAAA,CAAA,MAAA,YAAA,CAAA,CAAA,KAAA,cAAA,UAAA,QAAA,OAAA,GAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,QAAA,cAAA,UAAA,SAAA,CAAA;AAEjB;AAEA,MAAA,gBAAA;;;AAOA,SAAS,cAAA,OAAgB;CACvB,IAAA,MAAO,WACJ,KAAQ,KAAA,KAAA,KACR,GAAA,OAAM;CAGX,IAAA,YAAA,KAAA,KAAA,GAAA,OAAA;;;;;CAMA,IAAA,CAAM,QAAA,SAAgB,GAAA,KAAA,CAAA,cAAA,KAAA,OAAA,GAAA,OAAA;;AAGtB;AAGA,SAAM,cAAc,WAAA;;;;;AAMpB,SAAS,SAAA,WAAc,OAA8B;CACnD,IAAI,MAAM,IAAA,SAAW,GAAK,OAAK;CAG/B,MAAI,SAAA,cACF,SAAO;CAET,IAAI,OAAM,WAAS,GAAK,OAAK;CAE7B,KAAA,MAAM,QAAU,OAAM;EACtB,IAAI,KAAA,WAAQ,GAAW,UAAK,EAAQ,GAAA,OAAA;EAGpC,IAAI,SAAA,UAAkB,KAAO,WAAK,GAAA,OAAY,EAAK,GAAA,OAAO;CAG1D;CAEA,OAAO;AACT;AAGA,SAAS,kBAAc,OAA2B;CAChD,MAAM,SAAA,CAAA;CACN,MAAI,wBACK,IAAA,IAAA,CAAA,GAAA,MAAA,cAAA,GAAA,MAAA,WAAA,CAAA;CAET,MAAA,0BAD+B,IAAU,IAAA;CAE3C,KAAA,MAAA,aAAA,gBAAA,MAAA,QAAA,GAAA;EAEA,IAAA,OAAS,KAAS,SAAA,KAAmB,SAAqC,KAAA,SAAA,GAAA;EACxE,KAAI,MAAM,SAAI,UACZ,SAAO,UAAA,GAAA;GACT,MAAM,YAAS,cAAc,MAAS,EAAA,CAAA,KAAA,CAAA;GACtC,IAAI,cAAO,QACT,CAAA,SAAO,WAAA,KAAA,GAAA,QAAA,IAAA,SAAA;EACT;CAEE;CAGA,KAAI,MAAA,QAAS,CAAA,GAAA,OAAe,CAAA,CAAA,KAAA,GAAW,OAAG,KAAS,2DAC1C,KAAA,EAAA;CACX,MAAA,SAAA,CAAA,GAAA,MAAA,SAAA,SAAA,UAAA,CAAA,CAAA,CAAA,KAAA,UAAA,MAAA,EAAA;CACA,MAAA,WAAO,CAAA,GAAA,aAAA,MAAA,QAAA,GAAA,GAAA,MAAA,CAAA,CAAA,KAAA,IAAA;CACT,IAAA,CAAA,cAAA,KAAA,QAAA,GAAA,OAAA,KAAA,yEAAA;;;;;;AAqBE,MAAA,mBAA0B;AAC1B,MAAA,WAAM,WAAA,IAAQ;CACd,MAAM;CAEN,SAAK;CACH;AAEA,CAAA;AACE,SAAM,WAAA,SAAY;CAClB,IAAA;EAEF,OAAA,IAAA,YAAA,SAAA,EAAA,OAAA,KAAA,CAAA,CAAA,CAAA,OAAA,OAAA;CACF,QAAA;EAEA,OAAK;CAGL;AACA;AAIA,SAAO,YAAA,UAAA;CACT,MAAA,0BAAA,IAAA,IAAA;;;ECrIA,IAAM,OAAA,SAAA,GAAA,QAAA,IAAA,MAAqB;;CAG3B,KAAM,MAAA,SAAA,SAAwB,SAAA,kBAAA,GAAA,IAAA,MAAA,EAAA;;CAG9B,KAAM,MAAA,SAAA,SAAA,SAA6B,cAAA,GAAA,IAAA,MAAA,EAAA;;;;;CAMnC,OAAM,MAAA,GAAA,EAAA,MAAmB,KAAA,MAAA,SAAA,IAAA,MAAA;AAUzB;AAC8B,SAAA,gBAAS,UAAA,OAAA,UAAA;CAA6C,MAAA,SAAA,CAAA;CAAQ,MAAA,iBAAA,MAAA,KAAA,SAAA,KAAA,IAAA,CAAA,CAAA,QAAA,SAAA,KAAA,WAAA,aAAA,CAAA,CAAA,CAAA,KAAA;CAE5F,IAAA,SAAS,SAAW,gBAAoC;EACtD,MAAI,QAAA,UAAA,QAAA;EACF,IAAA,SAAW,uBAAuB,OAAO,KAAO,4BAAe,sBAAA,iBAAA,MAAA,EAAA;EACjE,IAAA,eACM,SAAA,4BAAA,OAAA,KAAA,qCAAA,2BAAA,6BAAA,eAAA,OAAA,EAAA;CACJ;CACF,MAAA,SAAA,YAAA,QAAA;CACF,KAAA,MAAA,QAAA,gBAAA,IAAA,CAAA,OAAA,IAAA,IAAA,GAAA,OAAA,KAAA,sBAAA,KAAA,EAAA;;AAGA;AACE,MAAA,0BAAM,MAAc,OAAY,aAAA;CAChC,MAAM,SAAO,CAAA;CACX,MAAA,aAAe,MAAS,QAAE,SAAQ,KAAY,SAAQ,UAAU;CAChE,IAAA,WAAW,WACT,GAAA,OAAY,QAAM,CAAA,gDAAA,CAAA;CACtB,MAAA,SAAA,WAAA,WAAA,EAAA,CAAA,OAAA;CACA,IAAA,WAAW,MAAS,OAAA,QAAS,CAAA,yCACd,CAAA;CACf,IAAA,SAAW,SAAS,gBAAkB,OAAA,KAAA,GAAA,kBACpC;EACF,UAAW;EAEX,cAAO,SAAA;EACT,aAAA,MAAA,KAAA,SAAA,KAAA,IAAA;CAEA,CAAA,CAAA;CACE,MAAM,QAAQ,OAAK,MAAM,4CAAI;CAC7B,IAAA,CAAA,OAAO,OAAW,QAAM,CAAA,4CAA8B,CAAA;CACxD,IAAA,MAAA,EAAA,EAAA,KAAA,CAAA,CAAA,WAAA,GAAA,OAAA,KAAA,0CAAA;;CAGA,KAAA,MAAS,SAAA,SAAgB,QAAkB,OAAqC,KAAA,gBAAqD,MAAA,SAAA;CACnI,KAAA,MAAM,WAAoB,SAAA,UAAA,OAAA,KAAA,gBAAA,QAAA,SAAA;CAC1B,MAAM,QAAA,SAAiB,OAAM,WAAI,IAAQ,SAAW,KAAA,IAAO;CAC3D,IAAI,CAAA,SAAS,OAAA,UAAS,YAAgB,MAAA,QAAA,KAAA,GAAA;EACpC,OAAM,KAAA,gCAA0B;EAChC,OAAI,QAAS,MAAA;CAEb;CAEF,MAAA,cAAA;CACA,KAAA,MAAM,OAAS,OAAA,KAAY,WAAQ,GAAA,IAAA,CAAA,mBAAA,IAAA,GAAA,GAAA,OAAA,KAAA,uCAAA,KAAA;CACnC,IAAA,YAAW,SAAQ,MAAA,OACjB,KAAK,uDACoC;CAE3C,IAAA,OAAO,YAAA,SAAA,YAAA,CAAA,YAAA,YAAA,IAAA,GAAA,OAAA,KAAA,8BAAA;CACT,IAAA,OAAA,YAAA,gBAAA,YAAA,YAAA,YAAA,KAAA,CAAA,CAAA,WAAA,KAAA,YAAA,YAAA,SAAA,MAAA,OAAA,KAAA,4DAAA;CAEA,MAAa,cAAA,SAAA,IACX,eAEA,IAAA;CAEA,IAAA,OAAM,YAAoB,gBAAA,aAAA,CAAA,SAAA,WAAA,KAAA,YAAA,SAAA,OAAA,SAAA,iBAAA,KAAA,YAAA,WAAA,IAAA,OAAA,KAAA,sHAAA;CAC1B,OAAM,KAAA,GAAA,gBAAmB,QAAO,OAAQ,QAAK,CAAA;CAC7C,OAAI,OAAA,WAAW,IACb,GAAA,KAAO,CAAA,IAAA,QAAS,MAAA;AAElB;AACA,MAAI,gCACc,IAAA,IAAA;CAClB;CAEI;CACA;AACA,CAAA;AACF,MAAE,uBAAA,UAAA;CAEJ,IAAA,MAAM,WAAe,KAAA,MAAM,EAAA,EAAA,SAAA,eAAA,OAAA,QAA4C,CAAA,8CAAA,CAAA;CACvE,IAAI;CAEJ,IAAI;EAGJ,MAAM,SAAA,WAAW,MAAc,EAAA,CAAA,OAAa;EAC5C,IAAK,WAAM,MAAS,OAAS,QAC3B,CAAA,4CAA2C,CAAA;EAC7C,QAAK,KAAM,MAAA,MAAW;CAGtB,QAAM;EACN,OAAK,QAAS,CAAA,sCAAmC,CAAA;CAC/C;CACA,IAAA,CAAA,SAAO,OAAQ,UAAM,YAAA,MAAA,QAAA,KAAA,GAAA,OAAA,QAAA,CAAA,qCAAA,CAAA;CACvB,MAAA,SAAA;CAEA,IAAA,OAAM,KAAA,MAAc,CAAA,CAAA,MAAA,QAAA,QAAA,aAAA,QAAA,UAAA,GAAA,OAAA,QAAA,CAAA,0CAAA,CAAA;CACpB,IAAA,OAAW,OAAO,YAAY,YAAW,OAClC,QAAA,KAAA,CAAA,CAAA,WAA0B,GAC7B,OAAO,QAAK,CAAA,6BAAA,CAAA;CAEhB,IAAI,CAAA,MAAA,QAAY,OAAS,QACvB,GAAA,OAAY,QAAA,CAAA,mCAAA,CAAA;CACd,MAAI,WAAO,CAAA;CAEX,KAAI,MAAO,QAAA,OAAY,UAAA;EAEvB,IAAA,CAAM,QAAA,OAAc,SAAS,YAAI,MAAe,QAAI,IAAA,GAAA,OAAA,QAAA,CAAA,wCAAA,CAAA;EACpD,MAAI,UAAO;EAEX,IAAA,OAAY,KAAG,OAAA,CAAA,CAAA,MAAgB,QAAQ,CAAA;GAEvC;GACF;GAEA;GAA+B;EAAS,CAAA,CAAA,SAAA,GAAA,CAAA,GAAA,OAAA,QAAA,CAAA,+CAAA,CAAA;EAAW,IAAA,OAAA,QAAA,UAAA,YAAA,CAAA,cAAA,IAAA,QAAA,KAAA,GAAA,OAAA,QAAA,CAAA,oCAAA,CAAA;EAAO,IAAA,OAAA,QAAA,SAAA,YAAA,oBAAA,QAAA,IAAA,MAAA,MAAA,OAAA,QAAA,CAAA,mCAAA,CAAA;EAE1D,IAAa,OAAA,QAAA,YACX,YACuC,QAAA,QAAA,KAAA,CAAA,CAAA,WAAA,KAAA,OAAA,QAAA,QAAA,YAAA,QAAA,IAAA,KAAA,CAAA,CAAA,WAAA,GAAA,OAAA,QAAA,CAAA,iCAAA,CAAA;EACvC,SAAU,KAAA,OAAW;CAGrB;CACA,OAAI,GAAA;EACF,MAAM;EACN,SAAI,OAAW;EAEf;CACF,CAAA;AAEE;AAKF,SAAM,oBAAS,SAAA,QAAA;CACf,OAAI,QAAO,KAAK,SAAQ,eAAY,KAAQ,KAAA,iBAAqB,KAAA,MAC/D,qBAAgB,OAAA,mBAAA,kBAA2C;AAC7D;AAEA,MAAK,+BAA6B,IAChC,IAAO;CAET;CACA;CACE;CAEA;CACA;CAAuC;CAAS;CAAQ;CAAW;CAAK;CAExE;AAEA,CAAA;AAEA,eAAW,qBAAoB,WAAY,QAAQ,cAAe,WAAW,QAAK;CAElF,MAAA,OAAS,QAAK,SAAwC;CACxD,MAAA,eAAA,SAAA,UAAA,IAAA;EAEA,MAAO;EAAK;EAAqB,UAAS,CAAA;GAAgB,QAAA;GAAU,QAAA;GACtE,QAAA;;;CC7JA,CAAA;CACE,MAAA,kBAAmB,IAAA;EAErB,MAAA;EAEA,SAAM;CACJ,CAAA;CACA,IAAA,QAAA,SAAA,OAAA,UAAA;CACA,MAAA,WAAA,MAAA,MAAA,IAAA,CAAA,CAAA,OAAA,UAAA,KAAA;CACA,IAAA,oBAAA,OAAA,OAAA,YAAA,oCAAA,QAAA;CACA,IAAA,CAAA,SAAA,YAAA,KAAA,SAAA,eAAA,GAAA,OAAA,YAAA,uDAAA;CACA,MAAA,gBAAA,MAAA,SAAA,IAAA,CAAA,CAAA,OAAA,UAAA,KAAA;CACA,IAAA,yBAAA,OAAA,OAAA,YAAA,wCAAA,aAAA;CACA,IAAA,kBAAA,MAAA,OAAA,YAAA,oDAAA;CACA,MAAA,QAAA,CAAA;CACA,MAAA,eAAA,CAAA;CACA,IAAA,aAAA;CACD,MAAA,gBAAA,aAAA,SAAA,MAAA,QAAA,CAAA,CAAA,MAAA,GAAA,CAAA,CAAA,KAAA,GAAA;CAGC,MAAM,oBAAe,UAAS,SAAA,OAAA,QAAA,YAAA,GAAA,QAAA,IAAA,aAAA,QAAA,EAAA,GAAA,QAAA,KAAA,IAAA,KAAA,IAAA,SAAA,KAAA;CAC9B,MAAM,OAAA,OAAA,YAAgC;EACpC,IAAA,QAAM,SAAA,OAAA,UAAA;EACN,MAAA,mBAAA,MAAA,SAAA,OAAA,CAAA,CAAA,OAAA,UAAA,KAAA;EACA,IAAA,4BAAW,SAAA,qBAAA,SAAA,OAAA,YAAA,+CAAA,4BAAA,QAAA,mBAAA,KAAA,CAAA;EAAE,MAAA,kBAAQ,MAAA,QAAA,OAAA,CAAA,CAAA,OAAA,UAAA,KAAA;EAAa,IAAA,2BAAQ,OAAA,OAAA,YAAA,oCAAA,eAAA;EAAW,WAAQ,MAAA,SAAA,iBAAA;GAAS,IAAA,QAAA,SAAA,OAAA,UAAA;GACtE,IAAA,aAAA,IAAA,MAAA,IAAA,GAAA;GACD,MAAA,WAAA,KAAA,SAAA,MAAA,IAAA;GACD,MAAM,OAAA,MAAA,MAAgD,QAAI,CAAA,CAAA,OAAA,UAAA,KAAA;GAAE,IAAA,gBAAM,OAAA,OAAA,iBAAA,UAAA,+BAAA,IAAA;GAAa,IAAA,KAAS,eAAA,GAAA,OAAA,iBAAA,UAAA,mCAAA,KAAA,GAAA,mFAAA;GAA4B,IAAA,KAAA,YAAA,GAAA;IACpH,MAAI,SAAQ,MACV,KAAO,QAAA;IACT,IAAM,OAAA,SAAiB,OAAM,OAAM;IACnC;GAEA;GAEA,IAAM,CAAA,KAAA,OAAA,GAAgB,OAAM,iBAAe,UAAM,gCAAuC;GACxF,MAAI,OAAA,aAAA,QACF;GACF,MAAI,SAAA,MAAkB,KACpB,UAAO,UAAY,WAAA,UAAA,UAAA,CAAA,CAAA,OAAA,UAAA,KAAoD;GAEzE,IAAM,kBAAyB,OAAA,OAAA,iBAAA,UAAA,wDAAA,MAAA;GAC/B,MAAM,aAAoC,MAAC,OAAA,KAAA,CAAA,CAAA,OAAA,UAAA,KAAA;GAC3C,IAAI,sBAAa,OAAA;IACjB,MAAM,OAAA,MAAgB;;GAEtB;GAGA,IAAM,CAAA,WAAO,OAAO,KAAA,WAA0D,QAAA,KAAA,OAAA,WAAA,QAAA,KAAA,KAAA;IAC5E,MAAI,OAAQ,MACV;IACF,OAAM,iBAAmB,UAAM,uCAA+D;GAC9F;GAEA,IAAA,WAAM,OAAA,OAAwB,oBAAiB;IAC/C,MAAI,OAAA,MAAA;IAGJ,aAAW,KAAM;KACf;KAEA,OAAI,WAAa;IAEjB,CAAA;IACA;GACA;GAEA,IAAI,MAAK,UAAA,OACP,gBAAO;IACT,MAAI,OAAK,MAAA;IACP,OAAM,YAAS,iCAAmB;GAClC;GAEA,IAAA,aAAA,WAAA,OAAA,OAAA,gBAAA;IACF,MAAA,OAAA,MAAA;IACA,OAAK,YACH,sCAAkC;GAEpC;GACA,MAAM,UAAS,MAAM,OAAK,SAAU,CAAA,CAAA,OAAU,UAAW,KAAA;GACzD,MAAI,OAAA,MAAA;GAEJ,IAAA,mBAAmB,OAAM,OAAY,iBAAQ,UAAuC,8BAAA,OAAA;GACpF,IAAI,QAAA,eAAsB,WAAO,MAAA,OAAA,iBAAA,UAAA,uCAAA;GAC/B,IAAA,QAAM,SAAa,OAAA,UAAA;GACnB,MAAA,KAAO;IACT;IACA;GACE,CAAA;GACA,cAAO,QAAA;EACT;EACA,OAAI,GAAA,KAAA,CAAW;CACb;CACA,MAAA,SAAA,MAAkB,KAAA,IAAA;CAAE,IAAA,OAAA,SAAA,OAAA,OAAA;CAAM,IAAA,MAAA,WAAO,GAAW,OAAA,YAAA,uCAAA;CAAK,MAAC,MAAA,MAAA,UAAA,KAAA,KAAA,cAAA,MAAA,IAAA,CAAA;CAClD,aAAA,MAAA,MAAA,UAAA,KAAA,KAAA,cAAA,MAAA,IAAA,CAAA;CACF,OAAA,GAAA;EACA;EACE;EACA,UAAO,CAAA;GACT,QAAA;GACA,QAAI;EACF,CAAA;CACA,CAAA;AACF;AAGA,MAAA,aAAa;AACb,SAAI,cAAA,SAAmB,OACrB;CACF,OAAI,IAAA;EAEJ,MAAI;EAEJ;EAAa,UAAA,CAAA;EAAM;CAAQ,CAAA;AAC3B;AACF,SAAA,WAAA,QAAA,OAAA,QAAA;CACA,MAAA,QAAU,OAAS,SAAA,OAAA,QAAA,MAAA;CACrB,MAAA,OAAA,MAAA,QAAA,CAAA;CAEA,OAAM,OAAA,KAAS,SAAW,KAAI,QAAA,MAAA,SAAA,GAAA,IAAA,CAAA,CAAA,CAAA,SAAA,MAAA,CAAA,CAAA,KAAA;AAC9B;AAEA,SAAI,UAAM,QACR,OAAO,QAAA;CAET,MAAM,QAAM,WAAM,QAAe,OAAK,MAAA,CAAA,CAAA,QAAc,cAAW,EAAA;CAC/D,IAAA,CAAA,WAAa,KAAM,KAAM,GAAA,OAAU;CACnC,MAAA,SAAU,OAAA,SAAA,OAAA,CAAA;CAAE,OAAA,OAAA,cAAA,MAAA,IAAA,SAAA;AAAO;AAAc,SAAA,iBAAW,QAAA;CAAE,MAAA,WAAQ,UAAA,QAAA,KAAA,CAAA;CAAa,IAAA,aAAQ,MAAA,OAAA;CAAO,IAAC,SAAA;CAAE,KAAC,IAAA,QAAA,GAAA,QAAA,OAAA,YAAA,SAAA,GAAA,UAAA,SAAA,OAAA,QAAA,MAAA,KAAA,OAAA;CACxF,OAAA,WAAA;;ACvJA,SAAM,aAAa,SAAA;CAcnB,MAAA,OAASC,OAAAA,KAAY,OAAiB,CAAA,CAAA,SAA+C,MAAA;CACnF,IAAA,SAAW;CAAE,IAAA,OAAM;CAAqB,OAAA,SAAA,KAAA,QAAA;EAAS,MAAA,QAAW,KAAA,QAAA,KAAA,MAAA;EAAG,IAAA,UAAA,IAAA,OAAA;EAAO,MAAA,SAAA,OAAA,SAAA,KAAA,MAAA,QAAA,KAAA,GAAA,EAAA;EACxE,IAAA,CAAA,OAAA,cAAA,MAAA,KAAA,UAAA,KAAA,SAAA,SAAA,KAAA,QAAA,OAAA;EAEA,MAAA,SAAS,KAAW,MAAoB,QAAe,GAAA,SAAwB,SAAA,CAAA;EAC7E,MAAM,SAAQ,OAAO,QAAS,GAAA;EAC9B,IAAA,WAAa,MAAM,OAAS,MAAA,GAAA,MAAA,MAAA,QAAA,OAAA,OAAA,MAAA,SAAA,CAAA;EAC5B,UAAO;CACT;CAEA,OAAA;AACE;AACA,SAAK,YAAW,OAAU,QACxB;CACF,MAAM,aAAS,oBAAwB,KAAA;CACvC,IAAA,eAAc,MAAA,OAAc;CAC9B,MAAA,WAAA,WAAA,MAAA,GAAA;CAEA,IAAA,WAAS,OACP;MAAA,SAAM,OAAW,aAAU,SAAc,SAAA,GAAA,OAAA;CAAA,OACrC,IAAA,SAAa,SACf,GAAO,OAAA;CACT,OAAI,oBAAS,SAAA,MAAA,CAAA,CAAA,CAAA,KAAA,GAAA,CAAA;AACb;AAEA,SAAO,aAAW,OAAA;CACpB,OAAA,MAAA,OAAA,WAAA,IAAA,MAAA,OAAA,KAAA,OAAA,OAAA,MAAA,QAAA,MAAA,IAAA;AAEA;AACE,eAAa,eAAY,YAAS,QAAe,QAAA;CACjD,MAAI,SAAS,SAAA,KAAA,UAAA;CACb,MAAI,SAAsB,aAAA;CAC1B,OAAO,GAAA,UAAS,UAAa,OAAA,QAAA,KAAA,CAAA;CAC3B,OAAM,KAAA,MAAQ;CACd,MAAI,QAAA,CAAU;CAEd,MAAA,eAAe,CAAA;CACf,MAAK,uBAAqB,IAAM,IAAA;CAEhC,MAAA,kBAAoB,OAAM,kBAAoB,OAAS,iBAAC,KAAA,aAAA;CACxD,IAAA,eAAe;CACf,IAAA,cAAe;CAEf,IAAA,WAAU;CACZ,IAAA,UAAA,OAAA,MAAA,CAAA;CACA,IAAA,QAAO;CACT,IAAA,aAAA;CAEA,IAAA,QAAS;CACP,IAAA;EACA,WAAI,MAAA,SACF,QAAO;GACT,MAAM,QAAA,OAAW,SAAW,KAAS,IAAA,QAAA,OAAA,KAAA,KAAA;GACrC,gBAAe,MACb;GAAI,IAAA,eAAgB,iBAAa,OAAS,cACxC,qDAAO;GAAG,UAEL,QAAS,eAChB,IAAO,QAAA,OAAA,OAAA,CAAA,SAAA,KAAA,CAAA;GAET,OAAO,QAAA,aAAoB,GAAA;IAC7B,IAAA,OAAA;KAEA,IAAS,QAAA,MAAa,SAA8C,SAAA,CAAA,GAAA,OAAA,cAAA,+CAAA;KAClE,UAAa,OAAO,MAAA,CAAA;KAGtB;IAOA;IAKE,IAAM,UAAS,MAAA;KACf,IAAM,MAAA,YAAS,GAAa;MAC5B,MAAU,WAAS,KAAA,IAAS,MAAO,WAAQ,QAAM,UAAA;MACjD,IAAO,MAAK,SAAM,UAAA,MAAA,SAAA,YAAA,MAAA,OAAA,KAAA,QAAA,SAAA,GAAA,QAAA,CAAA;MAClB,UAA+B,QAAA,SAAA,QAAA;MAC/B,MAAM,aAAqC;MAC3C,IAAM,MAAA,YAAA,GAAO;KACb;KACI,IAAA,MAAA,UAAe,GAAA;MACf,MAAA,WAAc,KAAA,IAAA,MAAA,SAAA,QAAA,UAAA;MACd,UAA0B,QAAA,SAAA,QAAA;MAC1B,MAAA,WAA0C;MAC1C,IAAA,MAA6B,UAAA,GAAA;KAC7B;KACA,IAAA,MAAQ,SAAA,YAAA;MAER,MAAA,UAAA,aAAA,KAAA;MACF,WAAW,MAAM,iBAAiB,QAAA,aAAA,OAAA,IAAA,QAAA,SAAA,MAAA,CAAA,CAAA,QAAA,UAAA,EAAA,CAAA,CAAA,KAAA;MAChC,IAAM,aAAQ,QAAO,SAAc,WAAY,GAAA,OAAO,cAAwB,2CAAA;KAC9E,OAAA,IAAA,MAAgB,SAAM,UAAA,MAAA,MAAA;MACtB,MAAI,KAAA;OAEJ,MAAU,MAAA;OAEV,SAAO,WAAQ,KAAa,aAAG,KAAA,CAAA;MAC7B,CAAA;MACE,cAAY,MAAK;KAEjB;KACA,QAAA;KACF;IAEA;IACE,IAAA,QAAU,aAAY,YAAG;IACvB,MAAA,SAAM,QAAW,SAAS,GAAM,UAAW;IAC3C,UAAI,QAAM,SAAS,UAAgB;IAEnC,IAAA,OAAA,OAAU,SAAQ,SAAS,CAAQ,GAAA;KACnC,QAAM;KACN;IAEF;IACA,IAAA,CAAI,iBAAgB,MAAG,GAAA,OAAA,cAAA,gDAAA;IACrB,MAAA,OAAM,UAAW,QAAS,KAAM,EAAA;IAChC,IAAA,SAAU,MAAA,OAAQ,cAAiB,2CAAA;IACnC,MAAA,OAAM,WAAW,QAAA,GAAA,GAAA;IACjB,MAAI,SAAM,WACR,QAAA,KAAA,GAAA;IACJ,MAAA,aAAA,OAAA,SAAA,IAAA,GAAA,OAAA,GAAA,SAAA;IAEA,MAAI,OAAM,OAAS,aAAY,OAAA,QAAA,CAAA;IAC7B,MAAA,WAAM,aAAU,OAAkB,cAAA;IAClC,IAAA,SAAW,OAAM,SAAA,KAAA;KAGjB,IAAA,OAAI,OAAa,oBAAiB,OAAA,cACzBA,2DAAuD;KAClE,QACK;MACH,MAAM;MAAO,cAAY,SAAA,MAAA,QAAA;MAAM;MAA8C,WAAC;MAC9E;MACF,QAAA,CAAA;KACA;KACA;IACF;IAEA,IAAI,SAAQ,KAAA;KAEZ,WAAM;KACN,QAAA;MACA,MAAI;MACF;MACA,WAAA;MACF;MACA,QAAK,CAAA;KAGL;KACA;IAEA;IACA,IAAA,SAAM,OAAS,SAAW,MAAQ,OAAQ,cAAA,sDAAA,YAAA,WAAA,EAAA;IAC1C,MAAM,OAAA,YAAa,YAAgB,YAAc,MAAG;IACpD,WAAM;IACN,IAAA,SAAM,MAAW,OAAA,cAAoB,0CAAc;IAEnD,IAAI,KAAA,IAAS,IAAA,GAAO,OAAA,cAAc,0CAAA;IAChC,KAAI,IAAA,IAAO;IAEX,eAAQ;IACN,IAAA,cAAM,OAAA,gBAAA,OAAA,cAAA,yCAAA;IACN,IAAA,QAAA,OAAc,sBAAuB,aAAA,OAAA,OAAA,gBAAA,OAAA,cAAA,8CAAA;IACrC,IAAA,OAAA,OAAA,oBAAA,aAAA,KAAA;KACA;KACA,OAAA;IACA,CAAA;IACF,QAAA;KACA,MAAA,OAAA,OAAA,qBAAA,SAAA;KACF;KACA;KACE,WAAW;KACX;KAAU,QAAM,CAAA;IAAa;GAAM;EAAiB;CAAS,SAAA,OAAS;EAAE,MAAA,UAAA,iBAAA,QAAA,MAAA,UAAA;EACxE,OAAA,cAAA,QAAA,WAAA,iBAAA,IAAA,UAAA,0CAAA,KAAA;CACF;CACA,IAAA,UAAI,QAAS,QAAO,MAAS,SACpBA,SAAAA,CAAAA,KAAY,CAAA,OAAA,OAAA,cAAA,8CAAkE;CAEvF,IAAA,MAAM,WAAO,GAAA,OAAY,cAAY,qCAAkB;CACvD,MAAA,MAAA,MAAW,UAAA,KAAA,KAAA,cAAA,MAAA,IAAA,CAAA;CACX,aAAI,MAAS,MACX,UAAOA,KAAAA,KAAY,cAAA,MAAA,IAAA,CAAA;CACrB,OAAI,GAAA;EAEJ;EACA;CACA,CAAA;AAEA;AAGsB,MAAA,qBAAA;AAAM,MAAA,sBAAO;AAAK,MAAC,mBAAA;AAEzC,MAAA,sBAAQ;AACN,MAAA,mBAAoB;AACpB,MAAA,qBAAA;AACA,SAAA,YAAA,SAAA,UAAA,OAAA;CACA,OAAA,IAAA;EACA,MAAA;EACA;EACF;EACF;CACF,CAAA;AACF;AAEE,SAAM,iBAAU,MAAA;CAChB,MAAA,QAAOA,KAAAA,MAAY,kBAAmB;CAGxC,OAAA,QAAA,KAAA;EAEA,MAAI,MAAA;EAEJ,SAAU,MAAA,MAAW;CAErB,IAAA;AACA;AACA,SAAO,SAAG,OAAA;CAAE,OAAA,OAAA,UAAA,YAAA,UAAA,QAAA,CAAA,MAAA,QAAA,KAAA;AAAO;AAAa,SAAC,gBAAA,OAAA;CACnC,IAAA,OAAA,UAAA,UAAA,OAAA;;CCvNA,OAAM;EACN,MAAM,OAAA,MAAA,SAAsB,WAAA,MAAA,OAAA,KAAA;EAC5B,KAAM,OAAA,MAAA,QAAmB,WAAA,MAAA,MAAA,KAAA;CACzB;AACA;AACA,SAAM,aAAA,WAAqB,WAAA;CAI3B,IAAA,CAAA,SAAS,SAAY,KAAA,CAAiB,SAAA,UAAuF,YAAA,KAAA,CAAA,SAAA,UAAA,QAAA,GAAA,OAAA;CAC3H,MAAA,SAAW,UAAA,YAAA,CAAA;CAAE,MAAA,kBAAM,OAAA,WAAA,WAAA,SAAA;CAAqB,MAAA,QAAA,UAAA,SAAA;CAAS,IAAA,CAAA,SAAA,KAAA,KAAA,OAAA,MAAA,YAAA,YAAA,CAAA,SAAA,MAAA,IAAA,KAAA,OAAA,MAAA,KAAA,YAAA,UAAA,OAAA;CAAU,OAAA;EAAO;EACpE,YAAA,gBAAA,UAAA,UAAA;EAEA,SAAS;GACP,SAAM,MAAQ;GACd,SAAO,OAAQ,MAAK,YAAA,WAAA,MAAA,UAAA,KAAA;GAAE,YAAY,gBAAA,MAAA,UAAA;GAAI,MAAA;IAA8B,SAAI,MAAA,KAAA;IAC1E,WAAA,OAAA,MAAA,KAAA,cAAA,WAAA,MAAA,KAAA,YAAA,KAAA;IAEA,QAAS,OAAS,MAAkD,KAAA,WAAA,WAAA,MAAA,KAAA,SAAA,KAAA;GAClE;EACF;CAEA;AACE;AAEA,eAAc,WACZ,UAAO;CACT,IAAA,CAAA,SAAO,MAAA;CACL,MAAA,SAAa,KAAM,OAAA,CAAA,CAAS,YAAW,KAAM,CAAA;AAC7C;AACF,SAAA,cAAA,UAAA;CACF,MAAA,QAAA,SAAA,QAAA,IAAA,gBAAA;CAEA,IAAA,UAAS,QAAa,CAAA,QAAA,KAAoB,KAAA,GAAiH,OAAA;CACzJ,MAAK,QAAS,OAAA,KAAS;CAEvB,OAAM,OAAA,cAAmB,KAAA,IAAY,QAAC;AACtC;AACA,gBAAc,eAAU,UAAS,UAAA,cAAA,gBAAA,CAAA,GAAA;CACjC,MAAK,WAAS,cAAiB,QAAM;CAErC,IAAA,aAAO,QAAA,WAAA,UAAA;EACL,MAAA,WAAA,QAAA;EACA,MAAA,IAAA,MAAY,YAAgB;CAC5B;CACE,IAAA,CAAA,SAAS,MAAM;CACf,MAAA,SAAS,SAAa,KAAA,UAAY;CAClC,IAAA,WAAY;CACZ,IAAA,aAAM;CACJ,IAAA;EACA,OAAA,MAAW;GACX,MAAA,SAAQ,MAAO,OAAW,KAAA;GAC5B,IAAA,OAAA,MAAA;IACF,WAAA;IACF;GACF;GAEA,cAAe,OAAA,MAAW;GACxB,IAAK,aAAS,UACZ,MAAA,IAAA,MAAA,YAAA;GAEF,QAAM,OAAS,KAAK;GACtB,MAAA,OAAA;EAEA;CACE,UAAM;EACN,IAAI,CAAA,UAAU,MAAQ,OAAC,OAAa,CAAA,CAAA,YAClC,KAAO,CAAA;EACT,OAAM,YAAQ;CACd;AACF;AAEA,eAAA,oBACE,UACA,UACA;CAGA,MAAM,SAAA,CAAA;CACN,IAAI,aAAa;CACf,IAAA;EACA,WAAU,MAAM,SAAA,eAAY,UAAA,UAAA,sCAAA,GAAA;GAC9B,OAAA,KAAA,KAAA;GACA,cAAc,MACZ;EAEF;CACA,SAAI,OAAW;EACf,OAAI,YAAa,iBAAA,QAAA,MAAA,UAAA,gCAAA,CAAA,GAAA,KAAA;CACjB;CACE,OAAA,GAAO,WAAM,KAAA,OAAA,OAAA,QAAA,UAAA,CAAA,CAAA;AACX;AACA,eAAW,mBAAM,aAAA,KAAA,OAAA,CAAA,GAAA,QAAA;CACf,MAAA,UAAW,YAAA,QAAA,mBAAA;CACX,MAAA,gBAAA,SAAA,YAAA,IAAA,CAAA,QAAA,OAAA,CAAA,IAAA;CACF,IAAA,UAAA;CACA,KAAA,IAAA,YAAc,GAAO,aAAM,kBAAA,aAAA,GAAA;EAC3B,MAAI,WAAA,MAAa,YACT,SAAU;GAClB,GAAA;GACA,UAAM;GACR,QAAA;EACF,CAAA,CAAA,CAAA,OACQ,UAAA,KAAA;EACN,IAAI,oBAEI,OAAO,OAAS,YAAY,QAAS,UAAA,2BAAA,uBAAA,CAAA,GAAA,QAAA;EAE7C,IAAA,CAAA;GACF;GACF;GAEA;GACE;GACA;EACA,CAAA,CAAA,SAAI,SAAA,MAAA,GAAA,OAAA,GAAA,QAAA;EACF,IAAA,cAAiB,kBAAS;GACxB,MAAA,WAAiB,QAAA;GACjB,OAAA,YAAc,4CAAM,CAAA,CAAA;EACtB;EACF,MAAA,WACc,SAAA,QAAA,IAAA,UAAA;EACZ,IAAA,CAAA,UAAO;GACT,MAAA,WAAA,QAAA;GACA,OAAO,YAAc,yCAAuC,CAAA,CAAA;EAC9D;EAEA,MAAA,aAAe,MAAA,QAAmB,QAAA,CAAA,CAAA,WAAuC,IAAqB,IAAG,UAAgE,OAAA,CAAA,CAAA,CAAA,YAAA,IAAA;EAC/J,IAAA,eAAgB,MAAA;GAChB,MAAM,WAAA,QAAgB;GACtB,OAAI,YAAU,qCAAA,CAAA,CAAA;EACd;EACE,IAAA,WAAM,aAAiB,UAAY;GAAW,MAAG,WAAA,QAAA;GAAM,OAAA,YAAU,oCAAA,CAAA,CAAA;EAAU;EAAsB,MAAG,WAAM,QAAuB;EACjI,UAAI,WAAA;CAEJ;CAAM,OAAA,YAAA,4CAAA,CAAA,CAAA;AAAK;AAAK,SAAA,wBAAA,MAAA;CAAK,MAAA,SAAA,KAAA,WAAA,MAAA,KAAA,CAAA,CAAA,OAAA,OAAA,KAAA,CAAA;CAAK,IAAA,WAAA,OAAA,SAAA,UAAA;EAAG,MAAE,QAAS,MAAS,MAAM,4CACnC;EACpB,OAAI,QAAA,MAAc,MAAA,KAAA,CAAA;GAChB,WAAM,MAAW;GACjB,QAAO,MAAA;EACT,CAAA,IAAA,CAAA;CACA,CAAA;CACA,IAAA,SAAK,SAAU,GAAA;EACb,MAAA,WAAM;GACN,MAAA;GACF,QAAA;GACA,QAAM;GACN,QAAI;EACF;EACA,MAAA,YAAO,KAAY,IAAA,GAAA,SAAA,KAAA,UAAA,SAAuC,MAAA,UAAA,CAAA;EAC5D,WAAA,SAAA,QAAA,UAAA,SAAA,MAAA,eAAA,SAAA;CACA;CACE,IAAA,OAAM,WAAW,KAAQ,KAAA,UAAA,kBAAA,KAAA,KAAA,MAAA,GAAA,SAAA,KAAA;EACzB,WAAO;EACT,QAAA,OAAA,KAAA,KAAA,QAAA,KAAA,CAAA,CAAA,SAAA,QAAA;CACA,CAAA;CACA,IAAA,SAAU,WAAW,GAAA,OAAA;CACvB,MAAA,yBAAA,IAAA,IAAA;CACA,KAAA,MAAO,SAAY,UAAA,OAAA,IAAA,MAAA,WAAA,WAA8C,MAAA,SAAA,CAAA;CACnE,OAAA;EAEA,OAAS,SAAA;GACP,KAAM,MAAA,QAAc,OAAA,OAAW,GAAM,KAAM,OAAC,OAAO;EACnD;EACE,QAAM;GACN,MAAO,SAAQ,IAAA,IAAM,CAAA,GAAM,MAAM,CAAA,CAAA,KAAA,CAAA,WAAA,UAAA,CAAA,WAAA,KAAA,OAAA,QAAA,CAAA,CAAA,CAAA;GAAE,OAAA,SAAW,MAAM,UAAA,OAAA,IAAA,MAAA,SAAA,MAAA,MAAA,MAAA;EAAI;CAAiB;AAC3E;AACA,SAAI,cAAkB,YAAG;CACvB,IAAA,OAAM,eAAW,UAAA,OAAA;CAAE,OAAA,OAAM,YAAA,QAAA,WAAA,WAAA,MAAA;AAAG;AAAW,SAAA,iBAAQ,YAAA,SAAA;CAAG,IAAA,CAAA,WAAQ,CAAA,iBAAA,KAAA,OAAA,GAAA,OAAA;CAAE,MAAA,SAAA,cAAA,UAAA;CAC5D,IAAA,WAAM,MAAY,OAAS;CAC3B,MAAA,QAAW,OAAS,MAAA,4HAAgF;CACtG,IAAA,CAAA,QAAA,MAAA,CAAA,MAAA,IAAA,OAAA;CACA,OAAI,+BAA4B,mBAAU,MAAkB,EAAK,EAAA,GAAK,mBAC3D,MAAK,EAAA,EAAA,UAAA;AAAE;AAAmB,SAAA,QAAe,QAAK,QAAK;CAAkC,OAAC;EACjG;EAGA,QAAM;EACN;CAEA;AACE;AACE,SAAK,KAAM,QAAQ;CAErB,OAAA;EACA;EACE,QAAM;CACN;AACF;AACF,SAAA,aAAA,OAAA,UAAA;CACF,OAAA,MAAA,SAAA,sBAAA,YAAA,MAAA,SAAA,UAAA,MAAA,KAAA,IAAA,IAAA,KAAA;AAEA;AACE,SAAI,gBAAO,QAAe,OACxB;CACF,MAAA,YAAc,MAAA,QAAY,OAAQ,SAAW,QAAW,KAAA,QAAM,YAAA,CAAA;CAChE,MAAA,iBAAA,OAAA,iBAAA,MAAA;CAEA,MAAA,iBAAS,OAAiB,iBAA4F;CACpH,IAAI,kBAAa,KAAA,kBAAsB,GAAO,OAC5C;CACF,OAAM;EACN,GAAI;EAEJ;EACA;CAEA;AACF;AAEA,eAAS,gBAAwB,UAA+B,QAAA,QAAA,UAAA;CAC9D,OAAO,eAAA,eAAA,UAAA,OAAA,gBAAA,sDAAA,YAAA,UAAA,OAAA,OAAA,CAAA,GAAA,QAAA,MAAA;AAAE;AAAQ,eAAQ,kBAAA,MAAA,QAAA,aAAA,QAAA;CAAW,MAAA,SAAA,iBAAA,IAAA;CAAO,IAAA,WAAA,MAAA,OAAA,YAAA,gCAAA,CAAA,CAAA;CAC7C,MAAA,WAAA,CAAA;CAEA,MAAA,cAAc,8BAA+B,mBAAA,OAAA,IAAA;CAC3C,MAAA,mBAAO,MAAA,mBAAA,aAAA,aAAA,EAAA,SAAA,EAAA,QAAA,sCAAA,EAAA,GAAA,MAAA;CAAE,IAAA,iBAAA,SAAA,OAAA,OAAA,aAAA,iBAAA,OAAA,CAAA,QAAA,aAAA,iBAAA,MAAA,OAAA,CAAA,CAAA;CAAQ,MAAA,WAAQ,iBAAA;CAAO,IAAA,CAAA,SAAA,IAAA;EAClC,MAAA,WAAA,QAAA;EAEA,MAAA,UAAS,8BAAyG,SAAA,OAAA;EAChH,OAAO,YAAM,SAAS,CAAA,QAAA,aAClB,OAAY,CAAA,CAAA;CAElB;CAEA,MAAA,iBAAS,MAAgB,oBAAyF,UAAA,kBAAA;CAChH,IAAA,eAAkB,SAAM,OAAQ,OAAO,aAAS,eAAqB,OAAA,CAAA,QAAa,aAAA,eAAA,MAAA,OAAA,CAAA,CAAA;CAClF,IAAA;CACA,IAAA;EACA,YAAI,KAAA,MAAkB,OAAK,KAAA,eACzB,KAAO,CAAA,CAAA,SAAA,MAAA,CAAA;CACT,SAAO,OAAA;EAAE,MAAG,UAAA;EAAQ,OAAA,YAAA,SAAA,CAAA,QAAA,aAAA,OAAA,CAAA,GAAA,KAAA;CAAgB;CAAe,MAAA,aAAA,aAAA,WAAA,OAAA,OAAA;CACrD,IAAA,eAAA,QAAA,CAAA,oBAAA,KAAA,WAAA,eAAA,KAAA,WAAA,QAAA,YAAA,WAAA,iBAAA;EAEA,MAAA,UAAe;EAMb,OAAO,YAAA,SACL,CAAA,QACE,aACA,OAAO,CAAA,CAAA;CAOb;CAEA,MAAA,EAAA,YAAsB,iBAAkB,YAAyC;CAC/E,IAAA,CAAA,QAAM,KAAS,QAAA,WAAqB,UAAA,GAAA;EACpC,MAAI,UAAW;EAGf,OAAM,YAA6B,SAAA,CAAA,QAAA,aAAA,OAAA,CAAA,CAAA;CACnC;CACA,SAAM,KAAA,KAAA,WAAmB,CAAM;CAG/B,MAAI,iBAAiB,MAAA,mBACZ,aAAa,QAAA,KAAiB,SAAQ,CAAA,GAAA,MAAQ;CACvD,IAAA,eAAiB,SAAA,OAAiB,OAAA,aAAA,eAAA,OAAA,CAAA,GAAA,UAAA,QAAA,QAAA,KAAA,SAAA,eAAA,MAAA,OAAA,CAAA,CAAA;CAClC,MAAK,kBAAa,eAAA;CAChB,IAAA,CAAA,gBAAiB,IAAA;EACjB,MAAM,WAAU,eAAA;EAChB,MAAA,UAAO,qCAA2C,gBAAS,OAAA;EAC7D,OAAA,YAAA,SAAA,CAAA,GAAA,UAAA,QAAA,QAAA,KAAA,SAAA,OAAA,CAAA,CAAA;CAEA;CACA,MAAI,WAAA,wBACF,QAAO,IAAA;CAET,IAAI,aAAA,MAAA;EACJ,MAAI,WAAA,eAAA;EACF,MAAA,UAAY;EACd,OAAA,YACc,SAAA,CAAA,GAAA,UAAA,QAAA,QAAA,KAAA,SAAA,OAAA,CAAA,CAAA;CACZ;CACA,MAAA,YAAO,MAAY,gBAAkB,iBAAa,QAAW,OAAK,QAAA;CACpE,IAAA,UAAA,SAAA,OAAA,OAAA,aAAA,UAAA,OAAA,CAAA,GAAA,UAAA,QAAA,QAAA,KAAA,SAAA,UAAA,MAAA,OAAA,CAAA,CAAA;CAEA,IAAA,CAAA,SAAM,MAAa,GAAA;EACnB,MAAI,UAAA;EACF,OAAM,YAAU,SAAA,CAAA,GAAA,UAAA,QAAA,QAAA,KAAA,SAAA,OAAA,CAAA,CAAA;CAChB;CACF,SAAA,KAAA,KAAA,QAAA,KAAA,OAAA,CAAA;CACA,IAAA,QAAQ,CAAA,GAAA,UAAY,MAAA,KAAiB;CACrC,IAAI,eAAc,CAAA,GAAA,UAAQ,MAAW,YAAa;CAChD,MAAA,oBAAgB,iBAAA,QAAA,cAAA,YAAA,QAAA,OAAA;CAChB,MAAA,YAAO,gBAAsB,QAAQ,KAAA;CACvC,IAAA,sBAAA,QAAA,cAAA,MAAA,SAAA,KAAA,QAAA,mBAAA,kDAAA,CAAA;MACA,IAAS,sBAAsB,QAAA,cAAA,MAAA;EAE/B,MAAM,oBAAiB,MAAM,mBAAmB,aAAa,mBAAuB,CAAA,GAAG,MAAM;EAC7F,IAAI,kBAAe,SAAS,OAC1B,SAAO,KAAA,QAAa,mBAAuB,kBAAa,MAAQ,OAAQ,CAAK;OACzE,IAAA,CAAA,kBAAkB,MAAA,IAAe;GACvC,MAAK,UAAA,uCAAoB,kBAAA,MAAA,OAAA;GACvB,MAAM,WAAW,kBAAe,KAAA;GAChC,SAAM,KAAA,QAAU,mBAAA,OAAA,CAAA;EAChB,OAAO;GACT,MAAA,kBAAA,MAAA,gBAAA,kBAAA,OAAA,WAAA,QAAA;GAEA,IAAM,gBAAW,SAAA,OAAA,SAAwB,KAAQ,QAAI,mBAAA,gBAAA,MAAA,OAAA,CAAA;QACjD;IACF,QAAM,CAAA,GAAA,OAAW,GAAA,gBAAe,MAAA,MAAA,KAAA,UAAA;KAChC,GAAM;KACN,MAAO,MAAA,KAAY,cAAa,KAAA,IAAU;IAC5C,EAAA,CAAA;IACA,eAAkB,CAAA,GAAA,cAAM,GAAA,gBAAgB,MAAiB,aAAe,KAAA,UAAQ;KAC5E,GAAA;KAEA,MAAC,MAAS,KAAM,cAAG,KAAA,IAAA;IACrB,EAAA,CAAA;IACA,SAAO,KAAA,KAAY,iBAAa,CAAA;GAClC;EACA;CACA;CACA,MAAI,MAAA,MAAA,UAAmB,KAAU,KAAA,cAAkB,MAAA,IAAA,CAAA;CAEnD,aAAM,MAAA,MAAA,UAAoB,KAAA,KAAiB,cAAQ,MAAc,IAAA,CAAA;CACjE,OAAM,GAAA;EACN;EAGK;EACH;EACA,eAAI;GAGC,SAAK,OAAA;GACR,SAAM;EACN;CACA,CAAA;AACF;AAGE,SAAI,SAAA,OAAgB,OAAS;CAGxB,OAAA,UAAA,KAAA,IAAA,QAAA,UAAA,KAAA,IAAA,QAAA,QAAA;AACH;AAEgD,SAAG,cAAA,OAAA;CAAM,QAAA,OAAM,UAAW,YAAc,OAAS,UAAA,eAAA,UAAA,QAAA,OAAA,MAAA,SAAA;AAAE;AAEnG,SAAA,aACE,SAAG;CACkD,MAAA,WAAG,CAAA;CAAM,MAAA,gCAA+B,IAAK,IAAI;CAAE,IAAA,QAC1G;EACA,aAAS,KAAK;EAChB,mBAAA,KAAA;EACF,cAAA,KAAA;CACF;CAEA,IAAA,QAAY;CACZ,MAAA,QAAa,UAAM;EACnB,cAAU,IAAA,mBAAA,iBAAA,QAAA,MAAA,UAAA,OAAA,KAAA,GAAA;CACR;CACA,OAAA;EACA,OAAA,UAAA;GACA,IAAA,MAAA,SAAe,cAAA;IAAE,SAAS;IAAa,QAAS;KAAgB,aAAA,SAAA,MAAA,aAAA,MAAA,MAAA,WAAA;KACjE,mBAAA,SAAA,MAAA,mBAAA,MAAA,MAAA,iBAAA;KACH,cAAA,SAAA,MAAA,cAAA,MAAA,MAAA,YAAA;;GC/UA;GACE,IAAA,CAAO,SAAA;GACT,IAAA;IAEA,MAAS,WAAA,QAAc,KAA+C;IACpE,IAAA,cAAe,QAAU,GAAA,QAAY,QAAO,QAAU,CAAA,CAAA,MAAA,IAAA;GAGxD,SAAA,OAAA;IAEA,KAAS,KAAA;GACP;EACA;EACA,OAAI,YAAuB,SAAA,KAAA,OAAA;EAAE,SAAA,OAAa,UAAA;GAAW,QAAA;GAA8B,QAAA;EAAwB;EAC3G,eAAY;GAEZ;GACE;GACF,UAAA,CAAA,GAAA,UAAA,GAAA,aAAA;EACA;CACE;AACE;AACE,SAAA,QAAS,OAAA;CACT,OAAA;EACE,aAAA,MAAa;EACb,mBAAA,MAAmB,kBAAe;EAClC,cAAA,MAAc;CAChB;AACF;AAGA,SAAI,SAAA,GAAA,GAAA;CACF,MAAA,OAAM,GAAA,MAAoB,MAAQ,KAAK,KAAA,MAAA,KAAA,IAAA,KAAA,IAAA,IAAA;CAEvC,OAAI;EAEN,aACO,IAAO,EAAA,aAAA,EAAA,WAAA;EACZ,mBAAU,IAAA,EAAA,mBAAA,EAAA,iBAAA;EACZ,cAAA,IAAA,EAAA,cAAA,EAAA,YAAA;CACF;AACA;AAEE,MAAA,sBAAQ;AACR,SAAA,cAAQ,YAAA,QAAA;CACV,OAAA;EACA,uCAAe,WAAA;EAAE;EAAO,GAAA,OAAA,KAAA,UAAA,KAAA,OAAA;EAAO;EAA0C,uDAAA,WAAA;CAC3E,CAAA,CAAA,KAAA,IAAA;AACF;AASA,eAAS,oBAA0C,aAAA,QAAA,QAAA;CACjD,MAAA,OAAO,QAAA,YAAA,OAAA;CACL,MAAA,WAAa,MAAM,MAAA,IAAA,CAAA,CAAA,OAAA,UAAA,KAAA;CACnB,IAAA,oBAAmB,OAAM;EACzB,IAAA,SAAA,SAAoB,UAAA,OAAA,GAAA,KAAA,CAAA;EACtB,OAAA,IAAA;GACF,MAAA;;GAGA,MAAS;EACP,CAAA;CACA;CAAS,IAAA,CAAA,SAAa,YAAM,KAAA,SAAe,eAAW,GAAA,OAAA,IAAA;EAAG,MAAA;EAAkE,SAAA;EAAkD,MAAA;CAC/K,CAAA;;CAGA,IAAA,yBAA4B,SAAA,kBAAA,MAAA,OAAA,IAAA;EAE5B,MAAA;EACE,SAAO;EACL,MAAA;CACA,CAAA;CACA,MAAG,SAAO,KAAI,MAAS,YAAY,IAAA;CACnC,MAAA,aAAA,MAAA,MAAA,MAAA,CAAA,CAAA,OAAA,UAAA,KAAA;CACA,IAAA,sBAAA,OAAA;EACD,IAAC,WAAS,SAAA,UAAA,OAAA,GAAA,KAAA,CAAA;EACb,OAAA,IAAA;GAEA,MAAA;GACE,SAAM;GACN,MAAM;EACN,CAAA;CACE;CAEA,IAAA,CAAA,WAAW,YAAA,KAAA,WAAA,eAAA,GAAA,OAAA,IAAA;EAAE,MAAA;EAA0B,SAAA;EAA6C,MAAA;CAAW,CAAA;CACjG,OAAA,qBAAA,QAAA,QAAA,iBAAA,MAAA;AACA;AACe,eAAM,WAAA,OAAA,QAAA,aAAA,QAAA;CAAoB,IAAA,QAAS,SAAA,OAAA,IAAA;EAAyD,MAAM;EAAM,SAAA;CACvH,CAAA;CACA,MAAI,UAAA,MAAA,SAAyB,gBAAS,GAAA,KAAA,CAAkB,IAAA,MACtD,oBAAW,MAAA,aAAA,QAAA,MAAA;CAAE,IAAA,QAAM,SAAA,OAAA,OAAA;CAAoB,IAAA,MAAS,SAAA,gBAAA;EAAsD,MAAM,SAAA,MAAA,qBAAA,MAAA,YAAA,QAAA,MAAA,YAAA,MAAA;EAAM,OAAA,OAAA,SAAA,QAAA,SAAA,GAAA;GAEpH,WAAM;GACN,YAAM,MAAa,YAAY;GAC/B,QAAI,OAAA;GACF,WAAI;GAEJ,SAAO,QAAI;GAAE,aAAM,MAAA;EAAoB,CAAA;CAA6C;CAAa,IAAC,MAAA,SAAA,eAAA;EACpG,MAAA,SAAA,MAAA,qBAAA,MAAA,UAAA,QAAA,MAAA,UAAA,MAAA;EACA,OAAK,OAAA,SAAW,QAAY,SAAK,GAAW;GAC7B,WAAM;GAAoB,YAAS;GAAyD,QAAM,OAAA;GAAQ,WAAA,SAAA,MAAA,QAAA;EACzH,CAAA;CACF;CAEA,IAAA,MAAA,OAAe,SAAW,cAA4C;EACpE,MAAI,SAAQ,MACV,kBAAW,MAAA,OAAA,MAAA,QAAA,aAAA,MAAA;EAAE,IAAA,QAAM,SAAA,OAAA,IAAA;GAAa,MAAA;GAAqC,SAAA;EAEvE,CAAA;EAGA,OAAI,OAAQ,SAAS,QACnB,SAAO,GAAA;GAET,WAAU,iBAAS,QAAgB,KAAA;GACjC,YAAM,MAAS,YAAM;GACrB,QAAO,OAAO;GAEL,WAAW;GAA0B,SAAA,QAAY;GAAwB,aAAQ,MAAO;EAAO,CAAA;CAAe;CAAwB,MAAA,aAAa,cAAM,MAAA,OAAA,SAAA,MAAA,OAAA,UAAA;CAAY,IAAC,eAAA,MAAA,OAAA,IAAA;EACjL,MAAA;EAEA,SAAU;CACR,CAAA;CACA,MAAA,WAAc,MAAA,MAAS,KACnB,YACG,cAAA,CAAA,CAAA,CAAA,OAAA,UAAA,KAAA;CAAE,IAAA,oBAAW,SAAA,CAAA,SAAA,OAAA,KAAA,SAAA,eAAA,GAAA,OAAA,IAAA;EAAgB,MAAA;EAAsB,SAAQ;EAAc,UAAA,CAAA;GAAqC,QAAA;GACvH,QAAA;GAEA,QAAU;EACR,CAAA;CACA,CAAA;CACe,MAAA,SAAM,MAAA,qBAAA,YAAA,QAAA,YAAA,MAAA;CAAa,OAAA,OAAS,SAAA,QAAA,SAAA,GAAA;EAA2B,WAAC,iBAAA,QAAA,KAAA;EACvE,YAAO,MAAO,YAAS;EAEd,QAAA,OAAW;EAAiC,WAAA;EAAoC,SAAQ,QAAO;EAAO,aAAW,MAAA;CAAI,CAAA;AAAwB;AACxJ,SAAA,iBAAA,SAAA;CAEA,OAAM,YAAa,KAAA,IAAA,2BAAoC;AACvD;AACe,SAAM,eAAA,OAAA;CAAgB,MAAA,UAAS,MAAA,OAAA,MAAA,SAAA,KAAA,SAAA,2BAAA;CAA+D,IAAC,CAAA,SAAA,MAAA,IAAA,MAAA,wCAAA,MAAA,KAAA,EAAA;CAC9G,OAAM,QAAA;AACN;AAEI,SAAM,cAAA,UAAA,YAAA,kBAAA,YAAA,WAAA;CACN,OAAA,SAAS,WAAA,mBAAA,UAAA,CAAA,CAAA,WAAA,0BAAA,gBAAA,CAAA,CAAA,WAAA,mBAAA,UAAA,CAAA,CAAA,WAAA,kBAAA,SAAA;AACT;AAAa,SAAA,aAAQ,QAAA,UAAA;CAAY,OAAA,MAAQ,KAAA,OAAA,SAAA,gBAAA,SAAA,SAAA;AAAW;AAAuC,eAAC,oBAAA,QAAA,UAAA,QAAA;CAC9F,MAAC,aAAA,aAAA,QAAA,QAAA;CAGH,MAAM,QAAA,MAAS,OAAM,QAAA,IAAA;EACrB,SAAO;EAEE,KAAA;GAA4C,cAAY,MAAM,KAAA,OAAY,SAAA,OAAA;GAAM,eAAe,MAAA,KAAA,OAAA,SAAA,eAAA;EAAO;EAAe,aAAS;CAAe,CAAA;CAA+B,IAAC,MAAA,aAAA,GAAA,MAAA,IAAA,MAAA,MAAA,OAAA,KAAA,KAAA,4CAAA;CACxL,KAAA,MAAA,QAAA,SAAA,OAAA,OAAA,MAAA,OAAA,QAAA,gBAAA;;EAGA,SAAS,KAAA;EACP,aAAO;CACT,CAAA;CAEA,KAAA,MAAS,QAAA,SAAe,SAA+B,SAAA,CAAA,GAAA,MAAA,OAAA,QAAA,gBAAA;EACrD,MAAM,MAAA,KAAU,OAAM,SAAO,uBAAkB,KAAS,IAAA;EACxD,SAAK,KACH;EACF,aAAO;CACT,CAAA;CAEA,MAAA,OAAS,QAAA,cAAgC;EACvC,MAAO,MAAA,KACJ,OAAA,SAAW,4BACX;EAGL,SAAA,GAAA,KAAA,UAAA;GAEA,gBAAS,SAAa,OAAuB;GAC3C,cAAa,SAAY,OAAA;GAC3B,eAAA,SAAA,OAAA;GAEA,iBAAe,SAAA,YAAoB,KAAuB;EACxD,GAAA,MAAM,CAAA,EAAA;EACN,aAAc;CACZ,CAAA;AACA;AACE,SAAA,WAAc,OAAM,QAAY;CAChC,OAAA,QAAA,UAAqB;EACvB,MAAA;EACA,SAAA;CACF,IAAC;EACD,MAAI;EAEJ,SAAK;EAED;CACA;AACA;AACF,SAAC,aAAA,OAAA,QAAA;CAEH,OAAK,IAAM,WAAQ,OAAS,MAAA,CAAA;AAExB;AACA,SAAA,mBAAc,SAAA;CACd,MAAA,SAAa,kBAAA;EACd,GAAA;EAEH,GAAA,QAAM;CACJ,CAAA;CACA,MAAA,cAAiB,QAAU,SAAA,WAAA,MAAA,KAAA,UAAA;CACzB,MAAA,gBAAgB,EAAA,GAAS,QAAO,cAAA;CAChC,MAAA,UAAc,QAAA;CACd,MAAA,UAAA,QAAe;CACf,OAAA,EAAA,MAAA,OAAiB,aAAS,CAAA,MAAY,SAAA,OAAA,UAAA,EAAA;CACxC,eAAY,SAAA,OAAA,YAAA;EACZ,MAAA,MAAA,aAAa,WAAA,OAAA;EACd,MAAA,UAAA,MAAA,UAAA,OAAA,YAAA,GAAA;EACH,MAAA,SAAA,IAAA,OAAA;EAEA,OAAS,QAAA,SAAW,OAAgB;GAClC,MAAO;GACD,OAAM,QAAA;GAAa;EAAoC,IACzD;GAAE,MAAM;GAAe,OAAA,QAAS;GAA8C;EAAM;CAC1F;CAEA,eAAS,UAAa,OAAgB,YAAkC,KAAA;EACtE,MAAO,SAAI,cAAkB,KAAM;EACrC,IAAA,OAAA,SAAA,OAAA,OAAA;EAEA,MAAA,WAAgB,MAAA,WAAmB,OAAkD,OAAA,QAAA,aAAA,WAAA,MAAA;EACnF,IAAA,SAAM,SAAS,OAAA,OAAkB;EAAE,KAAG,MAAA,WAAA,oBAAA,SAAA,MAAA,OAAA,cAAA,MAAA,GAAA,IAAA,KAAA,OAAA;EAAuB,MAAG,QAAQ,MAAA,0BAAA,SAAA,MAAA,SAAA;EAAc,MAAA,iBAAA,MAAA,QAAA,cAAA,EAAA,aAAA,WAAA,OAAA,CAAA,CAAA,CAAA,KAAA,KAAA,UAAA,IAAA,KAAA,CAAA;EACtF,IAAA,eAAiC,SAAQ,OAAA,OAAS,aAAiB,eAAe,OAAA,WAAA,MAAA;EAClF,MAAM,SAAA,MAAgB,SAAK,SAAQ,OAAA,OAAc,eAAA,OAAA,KAAA,WAAA,MAAA;EACjD,MAAM,YAAU,MAAQ,QAAA,QAAA,eAAA,MAAA,QAAA,CAAA,CAAA,CAAA,WAAA,KAAA,IAAA,UAAA,KAAA;EACxB,IAAA,cAAgB,KAAQ,GAAA,IAAA,KAAA,mCAAA,qBAAA,QAAA,UAAA,UAAA,OAAA,SAAA,GAAA;EAExB,OAAO;CAOP;CACE,eAAY,SAAA,UAAa,OAAW,gBAAO,KAAA,QAAA;EAC3C,IAAA;EACA,MAAM,gBAAa,cAAO;EAC1B,MAAA,QAAO,IAAQ,aACX;GAAE;GAAY,QAAO,CAAA,KAAA;GAAe,gBAAA;GAAO,eAC3C;IAAE,GAAA;IAAa,WAAO,OAAQ,mBAAA;KAAO,SAAA;MAAO,SAAA,eAAA;MAClD,SAAA,eAAA;KAEA;KACE,MAAM,oBAAuB,QAAK,UAAA,MAAA;KAClC,MAAI,gBAAgB,cACX;IAET;GACA;EAEA,CAAA;EAGA,MAAM,gBAAc,MAAA,MAAA,cAA0B;GAI9C;GACA,aAAI;EAEJ,CAAA,CAAA,CAAA,KAAM,KAAA,UAAe,IAAA,KAAS,CAAA;EAC9B,IAAA,cAAkB,SAAM,OAAQ,OAAQ,aAAA,cAAqB,OAAW,MAAA;EACxE,MAAI,UAAA,cACE;EACN,IAAA;GACF,IAAA,CAAA,QAAA,OAAA,IAAA;IAEA,MAAA;IAOE,SAAI;GACJ,CAAA;GACA,MAAM,aAAY,aAAa,QAAA,QAAA;GAC7B,MAAA,mBAAA,MAAA,KAAA,OAAA,SAAA,qBAAA;GACA,MAAA,aAAc,MAAA,KAAA,OAAA,SAAA,iBAAA,SAAA,UAAA;GACd,MAAA,SAAA,cAAgB,eAAA,KAAA,GAAA,YAAA,kBAAA,YAAA,SAAA,UAAA;GAChB,MAAA,gBAAe,OAAA;GACb,IAAG,OAAA;GACH,IAAA,aAAW;GACT,IAAA;GAAW,MAAA,OAAS,OAAA,SAAe;IAAS,MAAA,YAAS,MAAA,MAAe,SAAA;KAAe;KACnF,QAAM;KACN,aAAM;KACR,cAAA,UAAA;MACF,OAAA,aAAA,MAAA;MACD,IAAA,KAAA;OAED,MAAM;OAA4C;MAAgB,CAAA;KAAuB;KACzF,uBAAkB,EAAS,eAClB;MACT,IAAM,KAAA;OAEF,MAAA;OACE;OACW,UAAM,SAAA;OAAe,YAAS,SAAA;OAAgD,OAAA,SAAA;MAC7F,CAAA;KACA;KACA,YAAM,WAAmB;MACzB,IAAM,KAAA;OACN,MAAM;OAEF,MAAA,aAAO,OAAA;OACP,cAAa,OAAA;OACb,OAAA,QAAA,OAAA,KAAA;MACJ,CAAA;KACE;IACE,CAAA,CAAA,CAAA,KAAA,KAAA,UAAA,IAAA,KAAA,CAAA;IACA,IAAA,UAAQ,SAAA,OAAA,OAAA,IAAA,WAAA,UAAA,OAAA,MAAA,CAAA;IACR,MAAA,YAAa,QAAA,UAAA,MAAA,UAAA;IACb,QAAA,QAAc,SAAU,OAAA,SAAA,IAAA;IACtB,cAAO,UAAa,MAAM,MAAA;IAC1B,IAAA,OAAS,OAAA,UAAA;IAAE,OAAA,QAAM,UAAA,IAAA;KAAa,MAAA;KAAK,SAAC;IACtC,CAAA,IAAA,GAAA,KAAA,CAAA;GACA;GACE,MAAA,QAAS,YAAA;IAAE,MAAA,YAAM,MAAA,qBAAA,eAAA,YAAA,QAAA,MAAA;IAAY,IAAA,UAAA,SAAA,OAAA,OAAA;IAAM,MAAA,YAAU,SAAS,cAAA,iBAAA,oBAAA,UAAA,KAAA,IAAA,uBAAA,SAAA,YAAA,UAAA,OAAA,SAAA,cAAA,2BAAA;KAAU,MAAA;KAAiC,cAAO,SAAS,OAAA,MAAA,KAAA,SAAA,KAAA,IAAA;IAAM,IAAC,EAAA,MAAA,eAAA,CAAA;IAC1H,OAAA,UAAA,SAAA,QAAA,YAAA,GAAA,UAAA,KAAA;GACA;GACE,MAAA,QAAS,MAAA,KAAA,MAAA;GAAE,IAAA,MAAM,SAAA,OAAA,OAAA;GAAc,IAAA,UAAM,MAAA,MAAa;GAAmB,KAAA,IAAA,SAAc,GAAA,UAAO,uBAAA,QAAA,SAAA,SAAA,QAAA,MAAA,SAAA,gBAAA,UAAA;IAAc,IAAA,KAAA,qCAA2B,OAAA,MAAA,oBAAA,IAAA,QAAA,MAAA,OAAA,KAAA,GAAA,GAAA;IAAE,MAAC,WAAA,MAAA,KAAA,cAAA,YAAA,QAAA,MAAA,MAAA,CAAA;IACxI,IAAA,SAAA,SAAA,OAAA,OAAA;IACF,UAAQ,MAAI,MAAA;GACZ;GAEA,IAAA,QAAM,SAAY,OAAQ,OAAA;GAC1B,MAAA,YAAgB;GAChB,IAAA,SAAA,cAAwB,gBAAY,OAAA,oBAAA,UAAA,KAAA;GACpC,IAAA,CAAI,SAAO,aAAO,OAAU,IAAA;IAC5B,MAAA;IAA+B,SAAM;GAAa,CAAA;GAAoC,MAAK,WAAY,MAAA,aAAA,SAAA,YAAA,SAAA,SAAA,YAAA,MAAA,UAAA,OAAA,SAAA,OAAA,QAAA;GACzG,IAAA,SAAA,SAAA,OAAA,OAAA;GACA,KAAA,MAAM,WAAQ,SAA0E,MAAA,UAAA,IAAA,KAAA,OAAA;GACtF,OAAM,GAAA,SAAY,MAAM,KAAA;EACxB,UAAI;GAEJ,MAAA,QAAM,QAAY;EAMN;CAAsB;AAA2D;AAI/F,SAAA"}
@@ -27,7 +27,7 @@ Skip an internal package, whose users are the repository's own packages, such as
27
27
  5. Read the current official docs and examples, and release notes only for breaking changes and removed APIs.
28
28
  When docs cover several frameworks, read the consumer's framework pages first, then the core pages they link.
29
29
 
30
- Test an existing Skill's claims; do not copy its layout.
30
+ To update an existing Skill after a release, use `update-package-skill`. It tests only what the release changed.
31
31
 
32
32
  ## 2. Test the examples
33
33
 
@@ -57,7 +57,7 @@ Observed behaviour beats documentation.
57
57
  For a binary, use `--fetch-raw PATH --out DIR`. `DIR/responses.json` lists each status, content type, and response headers.
58
58
  For an HTTP client package, start a fake target on port 0 inside the test, and assert on the requests it receives.
59
59
  Without `--fetch`, it holds the server until SIGTERM. Background it with your tool's option; `&` and `nohup` die with the shell call.
60
- Never kill by port or with `pkill -f`: another Agent can own that process.
60
+ Start servers from your own test script and record each process ID you start; stop only those. Never kill by port or with `pkill -f`: another Agent can own that process.
61
61
  In a browser, set a desktop user agent; a package can treat `HeadlessChrome` as a bot.
62
62
  4. If documentation and behaviour disagree, write the behaviour and report the mismatch.
63
63
  5. Keep an unrunnable example only when the types prove it; report it untested.
@@ -1,7 +1,6 @@
1
1
  # Harness request
2
2
 
3
3
  Use the prepared package source at `{{SOURCE_PATH}}`.
4
- If it exists, use the current Skill at `{{CURRENT_SKILL_PATH}}` as the update baseline.
5
4
  Generate the package Skill at `{{OUTPUT_PATH}}`.
6
5
  The Skill directory name must be `{{SKILL_NAME}}`.
7
6
 
@@ -13,4 +12,4 @@ List each documentation and behaviour mismatch in your final message.
13
12
  Write no files outside `{{OUTPUT_PATH}}`. Build fixtures in a scratch directory outside it.
14
13
  Write only `SKILL.md` and Markdown files under `references/`: at most 9 files and 64 KiB in total. Skillgen rejects other output.
15
14
  Finish only after checking every output rule in this Skill.
16
- After you finish, the Harness checks the output. It returns each failed check to you; fix them in place.
15
+ Do not install or run `skilld`. After you finish, the Harness checks the output and returns each failed check to you; fix them in place.
@@ -1,5 +1,6 @@
1
1
  [
2
2
  "generate-package-skill",
3
+ "update-package-skill",
3
4
  "generate-project-skill",
4
5
  "review-skill"
5
6
  ]
@@ -1,5 +1,6 @@
1
1
  [
2
2
  "generate-package-skill",
3
+ "update-package-skill",
3
4
  "generate-project-skill",
4
5
  "review-skill",
5
6
  "skilld"
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: update-package-skill
3
+ description: Updates an existing package Skill for a new release of its npm or local package by testing only what changed since the version the Skill names. Use when a maintainer asks to refresh a package Skill after a release, or when a SKILL.md names an older tested version than the package.
4
+ ---
5
+
6
+ # Update a package Skill
7
+
8
+ Bring an existing package Skill to a new package version with the smallest correct edit.
9
+ The current Skill was tested against an earlier version. Trust what the release did not touch.
10
+ To write a Skill from nothing, use `generate-package-skill`.
11
+
12
+ ## Inputs
13
+
14
+ - The current Skill directory, and the package at the new version: a name and version, a directory, or prepared source.
15
+ - The tested version is the version the Skill's first paragraph names. If it names none, stop and report that the Skill needs a full rewrite.
16
+ - If the tested version equals the new version, change nothing and report that.
17
+
18
+ ## 1. Copy, then diff
19
+
20
+ 1. Copy the current Skill to the destination unchanged. Edit only the copy.
21
+ 2. Diff the two published versions: `npm diff --diff=PACKAGE@OLD --diff=PACKAGE@NEW`. For a local package, diff the old tarball against the packed build.
22
+ 3. Read the changelog or release notes between the two versions.
23
+ 4. List what changed for a consumer: exports, types, options and their defaults, config keys, error messages, CLI flags, peer ranges, engines, and behaviour the notes describe.
24
+
25
+ ## 2. Map changes to the Skill
26
+
27
+ For each change, find the Skill lines it affects: a claim, an example, a trap, a version limit.
28
+ A change is relevant when it affects a Skill line, or when it adds or breaks something an Agent would get wrong: a new trap, a renamed call, a new required setup step.
29
+ Internals, refactors, and fixes the Skill never mentioned are not relevant.
30
+
31
+ If no change is relevant, leave the copy byte-identical and stop. Report "no change needed" with a one-line diff summary.
32
+
33
+ ## 3. Test the affected lines
34
+
35
+ 1. Create one consumer fixture outside the package source, with its own `pnpm-workspace.yaml`. Install the new version and the documented peers.
36
+ 2. Run each affected example and claim, and each example you add. Compare output with the claim: return values, type errors, build logs, exit codes.
37
+ 3. Run each with one failure input as well, such as a bad option or an unreachable URL.
38
+ 4. Do not re-run untouched examples. The earlier version's tests cover them.
39
+ 5. Wrap every run in `timeout 120`. Start servers from your own script, record each process ID you start, and stop only those. Never kill by port or with `pkill -f`.
40
+ 6. Spend about 20 tool calls on testing. Report an affected claim you could not test as untested; never claim it passed.
41
+
42
+ ## 4. Edit
43
+
44
+ - Change only affected lines, and add what the release needs: a new trap, an old call → new call row, a new common task.
45
+ - Delete lines the release made false, and version limits it fixed.
46
+ - Update the tested version in the first paragraph. Other version literals go stale; avoid them.
47
+ - Keep the wording, order, and formatting of untouched lines exactly. The diff must show only what the release changed.
48
+ - Update the description only when a trigger changed, such as a renamed export or a new config key.
49
+
50
+ Keep the format rules:
51
+
52
+ - The frontmatter contains only `name` and `description`. The name matches the directory.
53
+ - The description is one plain YAML line without double quotes, backticks, or `%`.
54
+ - `SKILL.md` stays under 500 lines. Write at most eight reference files, each linked from `SKILL.md`.
55
+
56
+ ## 5. Report
57
+
58
+ - The tested version, old → new, and the files you changed.
59
+ - Each changed line with the diff hunk or release note behind it.
60
+ - Each affected claim left untested.
61
+ - Each mismatch between the new docs and observed behaviour: example, documented result, observed result. These are package bugs.
62
+
63
+ For a direct run, show the Skill diff for review. A direct run has no Harness checks; never claim it passed them.
@@ -0,0 +1,13 @@
1
+ # Harness request
2
+
3
+ The current Skill is at `{{CURRENT_SKILL_PATH}}`.
4
+ The prepared package source for the new version is at `{{SOURCE_PATH}}`.
5
+ Write the updated Skill at `{{OUTPUT_PATH}}`. The Skill directory name must be `{{SKILL_NAME}}`.
6
+
7
+ Read this Skill fully before writing files.
8
+ Copy the current Skill to `{{OUTPUT_PATH}}` first. If no change is relevant, leave it byte-identical and finish.
9
+ The network allows the npm registry and GitHub source archives only. Fetch the tested version from npm for the diff.
10
+ Build fixtures in a scratch directory. Write no other files outside `{{OUTPUT_PATH}}`.
11
+ Write only `SKILL.md` and Markdown files under `references/`: at most 9 files and 64 KiB in total. Skillgen rejects other output.
12
+ Do not install or run `skilld`. After you finish, the Harness checks the output and returns each failed check to you.
13
+ List each untested affected claim and each documentation mismatch in your final message.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "skilld-harness",
3
3
  "type": "module",
4
- "version": "3.6.5",
4
+ "version": "3.6.7",
5
5
  "description": "Run skilld-maintained Skills with checked, atomic output",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",