@letrquan/book 0.2.0

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.
Files changed (103) hide show
  1. package/CHANGELOG.md +2504 -0
  2. package/LICENSE +123 -0
  3. package/README.md +1383 -0
  4. package/dist/app-MOXXWEOY.js +18945 -0
  5. package/dist/app-MOXXWEOY.js.map +1 -0
  6. package/dist/chunk-24AXE6SP.js +12 -0
  7. package/dist/chunk-24AXE6SP.js.map +1 -0
  8. package/dist/chunk-3U5IBM24.js +213 -0
  9. package/dist/chunk-3U5IBM24.js.map +1 -0
  10. package/dist/chunk-574C6MQR.js +743 -0
  11. package/dist/chunk-574C6MQR.js.map +1 -0
  12. package/dist/chunk-5GDZ22YP.js +449 -0
  13. package/dist/chunk-5GDZ22YP.js.map +1 -0
  14. package/dist/chunk-5KLVH3PY.js +167 -0
  15. package/dist/chunk-5KLVH3PY.js.map +1 -0
  16. package/dist/chunk-5RDRAO4B.js +92 -0
  17. package/dist/chunk-5RDRAO4B.js.map +1 -0
  18. package/dist/chunk-7N4J557C.js +10 -0
  19. package/dist/chunk-7N4J557C.js.map +1 -0
  20. package/dist/chunk-A7JLBK2Y.js +3506 -0
  21. package/dist/chunk-A7JLBK2Y.js.map +1 -0
  22. package/dist/chunk-ANSJPYGI.js +84 -0
  23. package/dist/chunk-ANSJPYGI.js.map +1 -0
  24. package/dist/chunk-BTZZUCLI.js +264 -0
  25. package/dist/chunk-BTZZUCLI.js.map +1 -0
  26. package/dist/chunk-C7D4NJ2D.js +217 -0
  27. package/dist/chunk-C7D4NJ2D.js.map +1 -0
  28. package/dist/chunk-CAGOB2N4.js +208 -0
  29. package/dist/chunk-CAGOB2N4.js.map +1 -0
  30. package/dist/chunk-DGMQEI6Y.js +98 -0
  31. package/dist/chunk-DGMQEI6Y.js.map +1 -0
  32. package/dist/chunk-E75IPST5.js +289 -0
  33. package/dist/chunk-E75IPST5.js.map +1 -0
  34. package/dist/chunk-EYGD6X2T.js +180 -0
  35. package/dist/chunk-EYGD6X2T.js.map +1 -0
  36. package/dist/chunk-GTVB4HEM.js +765 -0
  37. package/dist/chunk-GTVB4HEM.js.map +1 -0
  38. package/dist/chunk-J7MIZ5CA.js +1907 -0
  39. package/dist/chunk-J7MIZ5CA.js.map +1 -0
  40. package/dist/chunk-KWHQ2XXL.js +626 -0
  41. package/dist/chunk-KWHQ2XXL.js.map +1 -0
  42. package/dist/chunk-L6LK2QIQ.js +657 -0
  43. package/dist/chunk-L6LK2QIQ.js.map +1 -0
  44. package/dist/chunk-MAQXCUR4.js +1007 -0
  45. package/dist/chunk-MAQXCUR4.js.map +1 -0
  46. package/dist/chunk-S4XL7HOM.js +402 -0
  47. package/dist/chunk-S4XL7HOM.js.map +1 -0
  48. package/dist/chunk-URLQAXTR.js +60 -0
  49. package/dist/chunk-URLQAXTR.js.map +1 -0
  50. package/dist/chunk-V4BOYR52.js +3504 -0
  51. package/dist/chunk-V4BOYR52.js.map +1 -0
  52. package/dist/chunk-VZQXX3WW.js +210 -0
  53. package/dist/chunk-VZQXX3WW.js.map +1 -0
  54. package/dist/chunk-WKBO5R4O.js +34 -0
  55. package/dist/chunk-WKBO5R4O.js.map +1 -0
  56. package/dist/chunk-XIFFTATU.js +15753 -0
  57. package/dist/chunk-XIFFTATU.js.map +1 -0
  58. package/dist/command-approvals-6Y57VCWZ.js +28 -0
  59. package/dist/command-approvals-6Y57VCWZ.js.map +1 -0
  60. package/dist/context-ZC5IFEAX.js +25 -0
  61. package/dist/context-ZC5IFEAX.js.map +1 -0
  62. package/dist/hook-approvals-CTUFKEJT.js +22 -0
  63. package/dist/hook-approvals-CTUFKEJT.js.map +1 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +2582 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/interactive-assets-CCAAWVKH.js +31 -0
  68. package/dist/interactive-assets-CCAAWVKH.js.map +1 -0
  69. package/dist/job-runner.d.ts +2 -0
  70. package/dist/job-runner.js +235 -0
  71. package/dist/job-runner.js.map +1 -0
  72. package/dist/loader-4IDS2RIE.js +15 -0
  73. package/dist/loader-4IDS2RIE.js.map +1 -0
  74. package/dist/mcp-approvals-WNPH65BK.js +18 -0
  75. package/dist/mcp-approvals-WNPH65BK.js.map +1 -0
  76. package/dist/mcp-config-YIJIES2C.js +16 -0
  77. package/dist/mcp-config-YIJIES2C.js.map +1 -0
  78. package/dist/model-window-store-YFVNXCIP.js +27 -0
  79. package/dist/model-window-store-YFVNXCIP.js.map +1 -0
  80. package/dist/openai-compatible-RHZUBHV6.js +10 -0
  81. package/dist/openai-compatible-RHZUBHV6.js.map +1 -0
  82. package/dist/permission-approvals-76PVREFD.js +14 -0
  83. package/dist/permission-approvals-76PVREFD.js.map +1 -0
  84. package/dist/permissions-CHCKTFQQ.js +28 -0
  85. package/dist/permissions-CHCKTFQQ.js.map +1 -0
  86. package/dist/sandbox-CNVAQDA7.js +23 -0
  87. package/dist/sandbox-CNVAQDA7.js.map +1 -0
  88. package/dist/scrollback-LUKLIBVI.js +136 -0
  89. package/dist/scrollback-LUKLIBVI.js.map +1 -0
  90. package/dist/sdk.d.ts +4574 -0
  91. package/dist/sdk.js +665 -0
  92. package/dist/sdk.js.map +1 -0
  93. package/dist/settings-loader-M2QP5TX2.js +21 -0
  94. package/dist/settings-loader-M2QP5TX2.js.map +1 -0
  95. package/dist/settings-removed-JWWPT4WA.js +19 -0
  96. package/dist/settings-removed-JWWPT4WA.js.map +1 -0
  97. package/dist/shell-selection-V6QAYXPX.js +17 -0
  98. package/dist/shell-selection-V6QAYXPX.js.map +1 -0
  99. package/package.json +143 -0
  100. package/patches/ink+6.8.0.patch +13 -0
  101. package/scripts/apply-ink-patch.mjs +29 -0
  102. package/scripts/ink-patch.mjs +59 -0
  103. package/scripts/verify-ink-patch.mjs +11 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/skills.ts"],"sourcesContent":["import {\r\n closeSync,\r\n existsSync,\r\n lstatSync,\r\n openSync,\r\n readFileSync,\r\n readSync,\r\n readdirSync,\r\n realpathSync,\r\n statSync,\r\n} from 'node:fs';\r\nimport { createHash } from 'node:crypto';\r\nimport { homedir } from 'node:os';\r\nimport { dirname, isAbsolute, join, parse, relative, resolve, sep } from 'node:path';\r\nimport { parseFrontmatter } from './frontmatter.js';\r\nimport { resolveBookHome } from './book-home.js';\r\nimport type { SkillActivation, SkillExecution } from './settings.js';\r\n\r\nexport const SKILL_ENTRY_FILENAME = 'SKILL.md';\r\nexport const MAX_SKILL_HEADER_BYTES = 64 * 1024;\r\nexport const MAX_SKILL_BODY_BYTES = 100 * 1024;\r\nexport const MAX_SKILL_RESOURCES = 200;\r\nexport const MAX_SKILL_RESOURCE_DEPTH = 4;\r\nexport const MAX_SKILL_RESOURCE_BYTES = 2 * 1024 * 1024;\r\n\r\nconst SKILL_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\r\nconst KNOWN_FRONTMATTER_FIELDS = new Set([\r\n 'name',\r\n 'description',\r\n 'license',\r\n 'compatibility',\r\n 'version',\r\n 'metadata',\r\n 'allowed-tools',\r\n 'tools',\r\n 'when_to_use',\r\n 'model',\r\n 'lifetime',\r\n 'disabled',\r\n // Interoperable Claude/Codex skill metadata. Invocation controls are\r\n // advisory to Book's explicit `$name` UI and do not grant permissions.\r\n 'disable-model-invocation',\r\n 'user-invocable',\r\n 'argument-hint',\r\n]);\r\n\r\nexport type SkillSource = 'user' | 'project';\r\nexport type SkillRootKind = 'book' | 'agents' | 'claude' | 'opencode';\r\nexport type SkillIssueSeverity = 'error' | 'warning';\r\n\r\nexport interface SkillIssue {\r\n code: string;\r\n message: string;\r\n severity: SkillIssueSeverity;\r\n}\r\n\r\nexport interface SkillResource {\r\n relativePath: string;\r\n byteSize: number;\r\n mtimeMs: number;\r\n digest: string;\r\n}\r\n\r\nexport interface ShadowedSkill {\r\n path: string;\r\n source: SkillSource;\r\n rootKind: SkillRootKind;\r\n}\r\n\r\n/** Metadata discovered without retaining or injecting the SKILL.md body. */\r\nexport interface Skill {\r\n id: string;\r\n version: string;\r\n descriptorDigest: string;\r\n resourceDigest: string;\r\n name: string;\r\n description: string;\r\n whenToUse?: string;\r\n license?: string;\r\n compatibility?: string;\r\n metadata: Record<string, string>;\r\n /** Requested tool ceiling. It never grants permission by itself. */\r\n allowedTools?: string[];\r\n model?: string;\r\n lifetime: 'turn' | 'run';\r\n /** Absolute path to the skill entrypoint. */\r\n path: string;\r\n /** Absolute directory that owns the skill and its resources. */\r\n rootPath: string;\r\n source: SkillSource;\r\n rootKind: SkillRootKind;\r\n activation: SkillActivation;\r\n execution: SkillExecution;\r\n invocationCount: number;\r\n entryByteSize: number;\r\n entryMtimeMs: number;\r\n resources: SkillResource[];\r\n issues: SkillIssue[];\r\n valid: boolean;\r\n shadowed: ShadowedSkill[];\r\n}\r\n\r\nexport interface LoadedSkillBody {\r\n body: string;\r\n digest: string;\r\n byteSize: number;\r\n}\r\n\r\nexport interface SkillRoot {\r\n path: string;\r\n source: SkillSource;\r\n kind: SkillRootKind;\r\n}\r\n\r\nexport interface DiscoverSkillsOptions {\r\n homeDir?: string;\r\n bookHomeDir?: string;\r\n includeUser?: boolean;\r\n projectRoot?: string;\r\n includeOpenCode?: boolean;\r\n enabled?: boolean;\r\n executionOverrides?: Readonly<Record<string, SkillExecution>>;\r\n}\r\n\r\nfunction pathKey(path: string): string {\r\n return process.platform === 'win32' ? resolve(path).toLowerCase() : resolve(path);\r\n}\r\n\r\nfunction isInside(root: string, candidate: string): boolean {\r\n const rel = relative(root, candidate);\r\n return rel === '' || (!rel.startsWith(`..${sep}`) && rel !== '..' && !isAbsolute(rel));\r\n}\r\n\r\nfunction projectRootFor(workspace: string): string {\r\n let current = resolve(workspace);\r\n const filesystemRoot = parse(current).root;\r\n while (true) {\r\n if (existsSync(join(current, '.git'))) return current;\r\n if (current === filesystemRoot) return resolve(workspace);\r\n current = dirname(current);\r\n }\r\n}\r\n\r\nfunction directoriesFromRoot(root: string, workspace: string): string[] {\r\n const normalizedRoot = resolve(root);\r\n const normalizedWorkspace = resolve(workspace);\r\n if (!isInside(normalizedRoot, normalizedWorkspace)) return [normalizedWorkspace];\r\n const directories: string[] = [];\r\n let current = normalizedWorkspace;\r\n while (true) {\r\n directories.push(current);\r\n if (pathKey(current) === pathKey(normalizedRoot)) break;\r\n current = dirname(current);\r\n }\r\n return directories.reverse();\r\n}\r\n\r\n/** Roots are ordered from lowest to highest precedence. */\r\nexport function skillRoots(workspace: string, options: DiscoverSkillsOptions = {}): SkillRoot[] {\r\n const roots: SkillRoot[] = [];\r\n if (options.includeUser !== false) {\r\n const home = options.homeDir ?? homedir();\r\n const bookHome =\r\n options.bookHomeDir ?? (options.homeDir ? join(home, '.book') : resolveBookHome());\r\n roots.push(\r\n { path: join(home, '.claude', 'skills'), source: 'user', kind: 'claude' },\r\n { path: join(home, '.agents', 'skills'), source: 'user', kind: 'agents' },\r\n ...(options.includeOpenCode === false\r\n ? []\r\n : [\r\n {\r\n path: join(home, '.config', 'opencode', 'skills'),\r\n source: 'user' as const,\r\n kind: 'opencode' as const,\r\n },\r\n ]),\r\n { path: join(bookHome, 'skills'), source: 'user', kind: 'book' },\r\n );\r\n }\r\n\r\n const projectRoot = options.projectRoot ?? projectRootFor(workspace);\r\n for (const directory of directoriesFromRoot(projectRoot, workspace)) {\r\n roots.push(\r\n { path: join(directory, '.claude', 'skills'), source: 'project', kind: 'claude' },\r\n { path: join(directory, '.agents', 'skills'), source: 'project', kind: 'agents' },\r\n ...(options.includeOpenCode === false\r\n ? []\r\n : [\r\n {\r\n path: join(directory, '.opencode', 'skills'),\r\n source: 'project' as const,\r\n kind: 'opencode' as const,\r\n },\r\n ]),\r\n { path: join(directory, '.book', 'skills'), source: 'project', kind: 'book' },\r\n );\r\n }\r\n const byPath = new Map<string, SkillRoot>();\r\n for (const root of roots) byPath.set(pathKey(root.path), root);\r\n return [...byPath.values()];\r\n}\r\n\r\nfunction readFrontmatterPrefix(path: string): {\r\n frontmatter: Record<string, unknown>;\r\n headerText: string;\r\n issues: SkillIssue[];\r\n} {\r\n const issues: SkillIssue[] = [];\r\n const fd = openSync(path, 'r');\r\n const chunks: Buffer[] = [];\r\n let total = 0;\r\n try {\r\n while (total < MAX_SKILL_HEADER_BYTES) {\r\n const chunk = Buffer.alloc(Math.min(4096, MAX_SKILL_HEADER_BYTES - total));\r\n const count = readSync(fd, chunk, 0, chunk.length, total);\r\n if (count === 0) break;\r\n chunks.push(chunk.subarray(0, count));\r\n total += count;\r\n const text = Buffer.concat(chunks).toString('utf8');\r\n if (/^---\\r?\\n[\\s\\S]*?\\r?\\n---(?:\\r?\\n|$)/.test(text)) {\r\n const match = text.match(/^---\\r?\\n[\\s\\S]*?\\r?\\n---(?:\\r?\\n|$)/);\r\n const headerText = match?.[0] ?? '';\r\n return { frontmatter: parseFrontmatter(headerText).frontmatter, headerText, issues };\r\n }\r\n }\r\n } finally {\r\n closeSync(fd);\r\n }\r\n issues.push({\r\n code: 'invalid_frontmatter',\r\n message: `Missing YAML frontmatter or closing delimiter within ${MAX_SKILL_HEADER_BYTES} bytes.`,\r\n severity: 'error',\r\n });\r\n return { frontmatter: {}, headerText: '', issues };\r\n}\r\n\r\nfunction stringField(frontmatter: Record<string, unknown>, name: string): string | undefined {\r\n const value = frontmatter[name];\r\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\r\n}\r\n\r\nfunction metadataFromHeader(headerText: string): Record<string, string> {\r\n const lines = headerText.split(/\\r?\\n/);\r\n const metadata: Record<string, string> = {};\r\n const start = lines.findIndex((line) => /^metadata\\s*:\\s*$/.test(line.trim()));\r\n if (start < 0) return metadata;\r\n for (const line of lines.slice(start + 1)) {\r\n if (/^---\\s*$/.test(line)) break;\r\n if (line.trim() && !/^\\s+/.test(line)) break;\r\n const match = line.match(/^\\s+([A-Za-z0-9_.-]+)\\s*:\\s*(.*?)\\s*$/);\r\n if (!match) continue;\r\n metadata[match[1]] = match[2].replace(/^[\"'](.*)[\"']$/, '$1');\r\n }\r\n return metadata;\r\n}\r\n\r\nfunction allowedToolsFrom(frontmatter: Record<string, unknown>): string[] | undefined {\r\n const value = frontmatter['allowed-tools'] ?? frontmatter.tools;\r\n if (Array.isArray(value)) {\r\n const tools = value\r\n .map(String)\r\n .map((tool) => tool.trim())\r\n .filter(Boolean);\r\n return tools.length ? tools : undefined;\r\n }\r\n if (typeof value === 'string') {\r\n const tools = value.match(/[^\\s]+(?:\\([^)]*\\))?/g)?.map((tool) => tool.trim()) ?? [];\r\n return tools.length ? tools : undefined;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction collectResources(\r\n rootPath: string,\r\n entryPath: string,\r\n): {\r\n resources: SkillResource[];\r\n issues: SkillIssue[];\r\n} {\r\n const resources: SkillResource[] = [];\r\n const issues: SkillIssue[] = [];\r\n let depthLimitReported = false;\r\n const visit = (directory: string, depth: number): void => {\r\n if (depth > MAX_SKILL_RESOURCE_DEPTH) {\r\n if (!depthLimitReported) {\r\n depthLimitReported = true;\r\n issues.push({\r\n code: 'resource_depth_limit',\r\n message: `Resources deeper than ${MAX_SKILL_RESOURCE_DEPTH} directories are ignored.`,\r\n severity: 'warning',\r\n });\r\n }\r\n return;\r\n }\r\n if (resources.length >= MAX_SKILL_RESOURCES) return;\r\n let entries: string[];\r\n try {\r\n entries = readdirSync(directory).sort();\r\n } catch (error) {\r\n issues.push({\r\n code: 'resource_unreadable',\r\n message: `Could not inspect resources in ${directory}: ${error instanceof Error ? error.message : String(error)}`,\r\n severity: 'warning',\r\n });\r\n return;\r\n }\r\n for (const entry of entries) {\r\n if (resources.length >= MAX_SKILL_RESOURCES) break;\r\n const fullPath = join(directory, entry);\r\n if (pathKey(fullPath) === pathKey(entryPath)) continue;\r\n let info;\r\n try {\r\n info = lstatSync(fullPath);\r\n } catch {\r\n continue;\r\n }\r\n if (info.isSymbolicLink()) {\r\n issues.push({\r\n code: 'resource_symlink_ignored',\r\n message: `Ignored symbolic-link resource: ${relative(rootPath, fullPath)}`,\r\n severity: 'warning',\r\n });\r\n continue;\r\n }\r\n if (info.isDirectory()) {\r\n visit(fullPath, depth + 1);\r\n continue;\r\n }\r\n if (!info.isFile()) continue;\r\n let digest = createHash('sha256')\r\n .update(`unavailable:${info.size}:${info.mtimeMs}`)\r\n .digest('hex');\r\n if (info.size > MAX_SKILL_RESOURCE_BYTES) {\r\n issues.push({\r\n code: 'resource_too_large',\r\n message: `Resource exceeds ${MAX_SKILL_RESOURCE_BYTES} bytes: ${relative(rootPath, fullPath)}`,\r\n severity: 'warning',\r\n });\r\n }\r\n try {\r\n const fd = openSync(fullPath, 'r');\r\n try {\r\n const prefix = Buffer.alloc(Math.min(info.size, 8192));\r\n const read = readSync(fd, prefix, 0, prefix.length, 0);\r\n if (prefix.subarray(0, read).includes(0)) {\r\n issues.push({\r\n code: 'binary_resource',\r\n message: `Binary resource cannot be loaded into model context: ${relative(rootPath, fullPath)}`,\r\n severity: 'warning',\r\n });\r\n }\r\n } finally {\r\n closeSync(fd);\r\n }\r\n } catch (error) {\r\n issues.push({\r\n code: 'resource_unreadable',\r\n message: `Could not validate resource ${relative(rootPath, fullPath)}: ${error instanceof Error ? error.message : String(error)}`,\r\n severity: 'warning',\r\n });\r\n }\r\n if (info.size <= MAX_SKILL_RESOURCE_BYTES) {\r\n try {\r\n digest = createHash('sha256').update(readFileSync(fullPath)).digest('hex');\r\n } catch {\r\n // The visible unreadable-resource issue above is the actionable diagnostic.\r\n }\r\n }\r\n resources.push({\r\n relativePath: relative(rootPath, fullPath).split(sep).join('/'),\r\n byteSize: info.size,\r\n mtimeMs: info.mtimeMs,\r\n digest,\r\n });\r\n }\r\n };\r\n visit(rootPath, 1);\r\n if (resources.length >= MAX_SKILL_RESOURCES) {\r\n issues.push({\r\n code: 'resource_limit',\r\n message: `Only the first ${MAX_SKILL_RESOURCES} resources are available.`,\r\n severity: 'warning',\r\n });\r\n }\r\n return { resources, issues };\r\n}\r\n\r\nfunction descriptorFromEntry(\r\n entryPath: string,\r\n root: SkillRoot,\r\n directoryName: string,\r\n flat = false,\r\n): Skill {\r\n const { frontmatter, headerText, issues: headerIssues } = readFrontmatterPrefix(entryPath);\r\n const issues = [...headerIssues];\r\n const declaredName = stringField(frontmatter, 'name');\r\n const name = declaredName ?? directoryName;\r\n const description = stringField(frontmatter, 'description') ?? '';\r\n\r\n if (!SKILL_NAME_PATTERN.test(name) || name.length > 64) {\r\n issues.push({\r\n code: 'invalid_name',\r\n message: 'Skill names must be 1-64 lowercase letters, numbers, or single hyphens.',\r\n severity: 'error',\r\n });\r\n }\r\n if (!flat && declaredName !== directoryName) {\r\n issues.push({\r\n code: 'name_directory_mismatch',\r\n message: `Declared name \"${declaredName ?? '(missing)'}\" must match directory \"${directoryName}\".`,\r\n severity: 'error',\r\n });\r\n }\r\n if (!declaredName && flat) {\r\n issues.push({\r\n code: 'legacy_flat_skill',\r\n message: 'Flat .skill.md files are supported for compatibility; use <name>/SKILL.md.',\r\n severity: 'warning',\r\n });\r\n }\r\n if (!description || description.length > 1024) {\r\n issues.push({\r\n code: 'invalid_description',\r\n message: 'Skill description is required and must be at most 1024 characters.',\r\n severity: 'error',\r\n });\r\n }\r\n const compatibility = stringField(frontmatter, 'compatibility');\r\n if (compatibility && compatibility.length > 500) {\r\n issues.push({\r\n code: 'invalid_compatibility',\r\n message: 'Skill compatibility must be at most 500 characters.',\r\n severity: 'error',\r\n });\r\n }\r\n const whenToUse = stringField(frontmatter, 'when_to_use');\r\n if (whenToUse && whenToUse.length > 1024) {\r\n issues.push({\r\n code: 'invalid_when_to_use',\r\n message: 'Skill when_to_use must be at most 1024 characters.',\r\n severity: 'error',\r\n });\r\n }\r\n const model = stringField(frontmatter, 'model');\r\n if (model) {\r\n issues.push({\r\n code: 'unsupported_model_hint',\r\n message: 'The model field is retained for compatibility but does not change Book models.',\r\n severity: 'warning',\r\n });\r\n }\r\n const requestedLifetime = stringField(frontmatter, 'lifetime');\r\n if (requestedLifetime && requestedLifetime !== 'run' && requestedLifetime !== 'turn') {\r\n issues.push({\r\n code: 'invalid_lifetime',\r\n message: 'Skill lifetime must be run or turn; Book will use run.',\r\n severity: 'warning',\r\n });\r\n }\r\n const lifetime = requestedLifetime === 'turn' ? 'turn' : 'run';\r\n for (const field of Object.keys(frontmatter)) {\r\n if (!KNOWN_FRONTMATTER_FIELDS.has(field)) {\r\n issues.push({\r\n code: 'unknown_frontmatter_field',\r\n message: `Unknown frontmatter field: ${field}`,\r\n severity: 'warning',\r\n });\r\n }\r\n }\r\n\r\n let entryByteSize = 0;\r\n let entryMtimeMs = 0;\r\n try {\r\n const entryInfo = statSync(entryPath);\r\n entryByteSize = entryInfo.size;\r\n entryMtimeMs = entryInfo.mtimeMs;\r\n if (entryByteSize > MAX_SKILL_BODY_BYTES + MAX_SKILL_HEADER_BYTES) {\r\n issues.push({\r\n code: 'body_too_large',\r\n message: `SKILL.md exceeds the ${MAX_SKILL_BODY_BYTES}-byte body budget.`,\r\n severity: 'error',\r\n });\r\n }\r\n } catch {\r\n issues.push({\r\n code: 'skill_unreadable',\r\n message: 'Skill entrypoint is unreadable.',\r\n severity: 'error',\r\n });\r\n }\r\n\r\n const rootPath = dirname(entryPath);\r\n const resourceResult = flat\r\n ? { resources: [] as SkillResource[], issues: [] as SkillIssue[] }\r\n : collectResources(rootPath, entryPath);\r\n issues.push(...resourceResult.issues);\r\n\r\n const metadata = metadataFromHeader(headerText);\r\n const version = stringField(frontmatter, 'version') ?? metadata.version ?? 'unversioned';\r\n const resourceDigest = createHash('sha256')\r\n .update(JSON.stringify(resourceResult.resources))\r\n .digest('hex');\r\n const descriptorDigest = createHash('sha256')\r\n .update(\r\n JSON.stringify({\r\n name,\r\n description,\r\n whenToUse,\r\n version,\r\n source: root.source,\r\n rootKind: root.kind,\r\n path: pathKey(entryPath),\r\n allowedTools: allowedToolsFrom(frontmatter),\r\n lifetime,\r\n resourceDigest,\r\n }),\r\n )\r\n .digest('hex');\r\n\r\n return {\r\n id: `${root.kind}:${pathKey(entryPath)}`,\r\n version,\r\n descriptorDigest,\r\n resourceDigest,\r\n name,\r\n description,\r\n whenToUse,\r\n license: stringField(frontmatter, 'license'),\r\n compatibility,\r\n metadata,\r\n allowedTools: allowedToolsFrom(frontmatter),\r\n model,\r\n lifetime,\r\n path: entryPath,\r\n rootPath,\r\n source: root.source,\r\n rootKind: root.kind,\r\n activation: String(frontmatter.disabled).toLowerCase() === 'true' ? 'off' : 'manual',\r\n execution: 'inherit',\r\n invocationCount: 0,\r\n entryByteSize,\r\n entryMtimeMs,\r\n resources: resourceResult.resources,\r\n issues,\r\n valid: !issues.some((issue) => issue.severity === 'error'),\r\n shadowed: [],\r\n };\r\n}\r\n\r\nfunction skillsUnderRoot(root: SkillRoot): Skill[] {\r\n if (!existsSync(root.path)) return [];\r\n let entries: string[];\r\n try {\r\n entries = readdirSync(root.path).sort();\r\n } catch {\r\n return [];\r\n }\r\n\r\n const skills: Skill[] = [];\r\n for (const entry of entries) {\r\n const fullPath = join(root.path, entry);\r\n let info;\r\n try {\r\n info = lstatSync(fullPath);\r\n } catch {\r\n continue;\r\n }\r\n let directory = info.isDirectory();\r\n if (info.isSymbolicLink()) {\r\n try {\r\n directory = statSync(fullPath).isDirectory();\r\n } catch {\r\n continue;\r\n }\r\n }\r\n if (directory) {\r\n const entryPath = join(fullPath, SKILL_ENTRY_FILENAME);\r\n if (existsSync(entryPath) && statSync(entryPath).isFile()) {\r\n skills.push(descriptorFromEntry(entryPath, root, entry));\r\n }\r\n } else if (info.isFile() && entry.endsWith('.skill.md')) {\r\n skills.push(descriptorFromEntry(fullPath, root, entry.replace(/\\.skill\\.md$/, ''), true));\r\n }\r\n }\r\n return skills;\r\n}\r\n\r\nexport function discoverSkills(\r\n workspace: string,\r\n overrides: Readonly<Record<string, SkillActivation>> = {},\r\n options: DiscoverSkillsOptions = {},\r\n): Skill[] {\r\n const byName = new Map<string, Skill>();\r\n for (const root of skillRoots(workspace, options)) {\r\n for (const skill of skillsUnderRoot(root)) {\r\n const previous = byName.get(skill.name);\r\n if (previous) {\r\n skill.shadowed = [\r\n ...previous.shadowed,\r\n { path: previous.path, source: previous.source, rootKind: previous.rootKind },\r\n ];\r\n }\r\n byName.set(skill.name, skill);\r\n }\r\n }\r\n return applySkillOverrides(\r\n [...byName.values()].sort((a, b) => a.name.localeCompare(b.name)),\r\n overrides,\r\n options.executionOverrides ?? {},\r\n options.enabled ?? true,\r\n );\r\n}\r\n\r\nexport function applySkillOverrides(\r\n skills: readonly Skill[],\r\n overrides: Readonly<Record<string, SkillActivation>>,\r\n executionOverrides: Readonly<Record<string, SkillExecution>> = {},\r\n enabled = true,\r\n): Skill[] {\r\n return skills.map((skill) => ({\r\n ...skill,\r\n activation: enabled ? (overrides[skill.name] ?? skill.activation ?? 'manual') : 'off',\r\n execution: executionOverrides[skill.name] ?? skill.execution ?? 'inherit',\r\n }));\r\n}\r\n\r\nexport function loadSkillBody(skill: Skill): LoadedSkillBody {\r\n if (!skill.valid) throw new Error(`Skill \"${skill.name}\" is invalid.`);\r\n const canonicalRoot = realpathSync(skill.rootPath);\r\n const canonicalEntry = realpathSync(skill.path);\r\n if (!isInside(canonicalRoot, canonicalEntry)) {\r\n throw new Error(`Skill entrypoint escapes its root: ${skill.path}`);\r\n }\r\n const current = statSync(canonicalEntry);\r\n if (current.size !== skill.entryByteSize || current.mtimeMs !== skill.entryMtimeMs) {\r\n throw new Error(`Skill \"${skill.name}\" changed after discovery; reload skills before use.`);\r\n }\r\n const buffer = readFileSync(canonicalEntry);\r\n if (buffer.includes(0)) {\r\n throw new Error(`Skill \"${skill.name}\" contains binary content.`);\r\n }\r\n const raw = buffer.toString('utf8');\r\n const { body } = parseFrontmatter(raw);\r\n const byteSize = Buffer.byteLength(body);\r\n if (byteSize > MAX_SKILL_BODY_BYTES) {\r\n throw new Error(`Skill body exceeds ${MAX_SKILL_BODY_BYTES} bytes.`);\r\n }\r\n return {\r\n body,\r\n digest: createHash('sha256').update(body).digest('hex'),\r\n byteSize,\r\n };\r\n}\r\n\r\nexport interface SkillListingResult {\r\n text: string;\r\n budgetChars: number;\r\n visibleCount: number;\r\n included: string[];\r\n omitted: string[];\r\n collapsed: string[];\r\n charCount: number;\r\n}\r\n\r\n/**\r\n * Characters the skill listing may occupy in the system prompt.\r\n *\r\n * Lives here so the listing shipped to the model and the /skills diagnostics\r\n * that describe it cannot drift: both call this, neither re-derives the share\r\n * or the cap.\r\n */\r\nexport function skillListingBudgetChars(contextWindow: number): number {\r\n return Math.min(8000, Math.max(512, Math.floor(contextWindow * 0.08)));\r\n}\r\n\r\nexport function buildSkillListing(\r\n skills: readonly Skill[],\r\n budgetChars = 8000,\r\n): SkillListingResult {\r\n const visible = skills.filter(\r\n (skill) => skill.valid && (skill.activation === 'auto' || skill.activation === 'name-only'),\r\n );\r\n if (visible.length === 0) {\r\n return {\r\n text: '',\r\n budgetChars,\r\n visibleCount: 0,\r\n included: [],\r\n omitted: [],\r\n collapsed: [],\r\n charCount: 0,\r\n };\r\n }\r\n\r\n const sorted = [...visible].sort(\r\n (a, b) => b.invocationCount - a.invocationCount || a.name.localeCompare(b.name),\r\n );\r\n const lines = [\r\n '## Available skills',\r\n 'Use InvokeSkill when a request matches a description. A user can force exact use with `$skill-name`.',\r\n ];\r\n let remainingBudget = budgetChars - lines.join('\\n').length;\r\n const includedNames: string[] = [];\r\n const collapsedNames = new Set<string>();\r\n\r\n let included = 0;\r\n for (const skill of sorted) {\r\n if (skill.activation === 'name-only') {\r\n const bare = `- **${skill.name}**`;\r\n if (bare.length > remainingBudget) break;\r\n lines.push(bare);\r\n remainingBudget -= bare.length + 1;\r\n included++;\r\n includedNames.push(skill.name);\r\n collapsedNames.add(skill.name);\r\n continue;\r\n }\r\n const entry = `- **${skill.name}**: ${skill.description}`;\r\n const trigger = skill.whenToUse ? `\\n when: ${skill.whenToUse}` : '';\r\n const full = `${entry}${trigger}`;\r\n if (full.length > remainingBudget) {\r\n const bare = `- **${skill.name}**`;\r\n if (bare.length <= remainingBudget) {\r\n lines.push(bare);\r\n included++;\r\n includedNames.push(skill.name);\r\n collapsedNames.add(skill.name);\r\n }\r\n break;\r\n }\r\n lines.push(full);\r\n remainingBudget -= full.length + 1;\r\n included++;\r\n includedNames.push(skill.name);\r\n }\r\n let omitted = sorted.length - included;\r\n if (omitted > 0) {\r\n let warning = `- ${omitted} additional skill${omitted === 1 ? ' was' : 's were'} omitted from this prompt budget. Use /skills to inspect the full catalog.`;\r\n while (warning.length > remainingBudget && lines.length > 2) {\r\n const removed = lines.pop();\r\n if (!removed) break;\r\n remainingBudget += removed.length + 1;\r\n included--;\r\n const removedName = includedNames.pop();\r\n if (removedName) collapsedNames.delete(removedName);\r\n omitted = sorted.length - included;\r\n warning = `- ${omitted} additional skill${omitted === 1 ? ' was' : 's were'} omitted from this prompt budget. Use /skills to inspect the full catalog.`;\r\n }\r\n if (warning.length <= remainingBudget) lines.push(warning);\r\n }\r\n const text = lines.join('\\n');\r\n const includedSet = new Set(includedNames);\r\n return {\r\n text,\r\n budgetChars,\r\n visibleCount: sorted.length,\r\n included: includedNames,\r\n omitted: sorted.filter((skill) => !includedSet.has(skill.name)).map((skill) => skill.name),\r\n collapsed: includedNames.filter((name) => collapsedNames.has(name)),\r\n charCount: text.length,\r\n };\r\n}\r\n\r\nexport function generateSkillListing(skills: readonly Skill[], budgetChars = 8000): string {\r\n return buildSkillListing(skills, budgetChars).text;\r\n}\r\n\r\nexport function explicitSkillMentions(prompt: string, skills: readonly Skill[]): string[] {\r\n const available = new Set(skills.map((skill) => skill.name));\r\n const mentions: string[] = [];\r\n const pattern = /(?<![A-Za-z0-9_-])\\$([a-z0-9]+(?:-[a-z0-9]+)*)(?![A-Za-z0-9_-])/g;\r\n for (const match of prompt.matchAll(pattern)) {\r\n const name = match[1];\r\n if (available.has(name) && !mentions.includes(name)) mentions.push(name);\r\n }\r\n return mentions;\r\n}\r\n"],"mappings":"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","names":[]}