@wrongstack/core 0.277.2 → 0.280.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 (83) hide show
  1. package/dist/{agent-bridge-BFJ2ODzI.d.ts → agent-bridge-DXC6QDJ4.d.ts} +1 -1
  2. package/dist/{agent-subagent-runner-BimKihiC.d.ts → agent-subagent-runner-PoqNKiR4.d.ts} +563 -471
  3. package/dist/{compactor-D3BGw26y.d.ts → compactor-U3agvUIG.d.ts} +1 -1
  4. package/dist/{config-DAOjriz9.d.ts → config-Cr3312zc.d.ts} +102 -4
  5. package/dist/coordination/index.d.ts +1087 -998
  6. package/dist/coordination/index.js +12235 -12052
  7. package/dist/coordination/index.js.map +1 -1
  8. package/dist/defaults/index.d.ts +31 -30
  9. package/dist/defaults/index.js +403 -189
  10. package/dist/defaults/index.js.map +1 -1
  11. package/dist/{brain-CCfuEOdp.d.ts → events-Bs2fmldo.d.ts} +117 -112
  12. package/dist/execution/index.d.ts +27 -19
  13. package/dist/execution/index.js +216 -63
  14. package/dist/execution/index.js.map +1 -1
  15. package/dist/execution/prompt-enhancer.d.ts +1 -1
  16. package/dist/execution/prompt-enhancer.js.map +1 -1
  17. package/dist/extension/index.d.ts +8 -7
  18. package/dist/{global-mailbox-Dr4cTKqL.d.ts → global-mailbox-Ct7IorLJ.d.ts} +84 -6
  19. package/dist/{goal-store-C1uH4srH.d.ts → goal-store-C4F6DjC0.d.ts} +1 -1
  20. package/dist/hq/index.d.ts +504 -7
  21. package/dist/hq/index.js +1069 -20
  22. package/dist/hq/index.js.map +1 -1
  23. package/dist/{index-DJXj-dcr.d.ts → index-kidebiDh.d.ts} +8 -5
  24. package/dist/{index-cMEmzCVN.d.ts → index-nP09-oP2.d.ts} +2 -2
  25. package/dist/index.d.ts +153 -76
  26. package/dist/index.js +5791 -3163
  27. package/dist/index.js.map +1 -1
  28. package/dist/infrastructure/index.d.ts +7 -6
  29. package/dist/kernel/index.d.ts +14 -13
  30. package/dist/kernel/index.js +31 -15
  31. package/dist/kernel/index.js.map +1 -1
  32. package/dist/{mailbox-types-DTl7bRH3.d.ts → mailbox-types-BGZWrYTJ.d.ts} +38 -0
  33. package/dist/{mcp-servers-CFb60-pH.d.ts → mcp-servers-D910X5_r.d.ts} +3 -3
  34. package/dist/models/index.d.ts +5 -5
  35. package/dist/models/index.js.map +1 -1
  36. package/dist/{models-registry-5Ufn7f2m.d.ts → models-registry-CLkoOcHk.d.ts} +1 -1
  37. package/dist/{multi-agent-coordinator-CcrcncvG.d.ts → multi-agent-coordinator-CieyUoEL.d.ts} +1 -1
  38. package/dist/{null-fleet-bus-C9KsYyrI.d.ts → null-fleet-bus-DkdmZJ_W.d.ts} +464 -464
  39. package/dist/observability/index.d.ts +3 -2
  40. package/dist/{path-resolver-CEeX9I7O.d.ts → path-resolver-XfZ9eLxG.d.ts} +3 -3
  41. package/dist/{permission-DbsGOA1C.d.ts → permission-Dx6dIqS2.d.ts} +2 -7
  42. package/dist/{permission-policy-BpEea3r7.d.ts → permission-policy-C8vJcnX5.d.ts} +2 -2
  43. package/dist/{pipeline-CEjBjzVA.d.ts → pipeline-BwAP21_4.d.ts} +9 -4
  44. package/dist/{provider-model-resolve-BpfXp3Jj.d.ts → provider-model-resolve-CwQNZWt_.d.ts} +3 -3
  45. package/dist/{provider-runner-CnOSr5BN.d.ts → provider-runner-CYHFImzV.d.ts} +3 -3
  46. package/dist/{retry-policy-Git9WF6d.d.ts → retry-policy-D4feSLk3.d.ts} +1 -1
  47. package/dist/sdd/index.d.ts +11 -10
  48. package/dist/sdd/index.js +2 -2
  49. package/dist/sdd/index.js.map +1 -1
  50. package/dist/secret-scrubber-3MHDDAtm.d.ts +6 -0
  51. package/dist/{secret-vault-DDSMHqIm.d.ts → secret-vault-CImt2XrR.d.ts} +1 -1
  52. package/dist/security/index.d.ts +6 -5
  53. package/dist/security/index.js.map +1 -1
  54. package/dist/{selector-Cq72C0Oy.d.ts → selector-Dy-MzKp1.d.ts} +1 -1
  55. package/dist/{session-event-bridge-DG94B3Bk.d.ts → session-event-bridge-CqdiGnfU.d.ts} +1 -1
  56. package/dist/{session-reader-BzT-iMQT.d.ts → session-reader-Hk0WbNm9.d.ts} +1 -1
  57. package/dist/{skill-DGIXCtdv.d.ts → skill-DHniprNl.d.ts} +15 -1
  58. package/dist/skills/index.d.ts +472 -26
  59. package/dist/skills/index.js +872 -129
  60. package/dist/skills/index.js.map +1 -1
  61. package/dist/storage/index.d.ts +27 -14
  62. package/dist/storage/index.js +264 -85
  63. package/dist/storage/index.js.map +1 -1
  64. package/dist/{strategy-compactor-Bt_ZH6R0.d.ts → strategy-compactor-CQwhbErd.d.ts} +32 -17
  65. package/dist/{todos-checkpoint-CH1pcua9.d.ts → todos-checkpoint-Bk2uP7Ex.d.ts} +6 -6
  66. package/dist/{context-DPlA6kid.d.ts → tool-BkOgs_KL.d.ts} +306 -286
  67. package/dist/{tool-executor-SVFq7IOR.d.ts → tool-executor-SiE1wlZo.d.ts} +9 -9
  68. package/dist/tools/index.d.ts +2 -2
  69. package/dist/tools/index.js.map +1 -1
  70. package/dist/types/index.d.ts +22 -21
  71. package/dist/types/index.js +7 -9
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/index.d.ts +30 -4
  74. package/dist/utils/index.js +50 -1
  75. package/dist/utils/index.js.map +1 -1
  76. package/dist/{worktree-manager-C4YIf1Fa.d.ts → worktree-manager-BjOFF6bt.d.ts} +1 -1
  77. package/dist/{wstack-paths-_NrRovdr.d.ts → wstack-paths-CMl_cYgq.d.ts} +8 -0
  78. package/package.json +1 -1
  79. package/skills/mailbox-bridge/SKILL.md +1 -0
  80. package/skills/plugin-author/SKILL.md +350 -0
  81. package/skills/sdd/SKILL.md +134 -134
  82. package/skills/skill-creator/SKILL.md +45 -7
  83. package/skills/wrongstack-mailbox/SKILL.md +40 -21
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/expect-defined.ts","../../src/utils/error.ts","../../src/utils/atomic-write.ts","../../src/types/errors.ts","../../src/skills/github-fetcher.ts","../../src/skills/manifest-store.ts","../../src/skills/skill-installer.ts"],"names":["path","fs","stat","resolve","fs2","path2","fs3","path3"],"mappings":"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","file":"index.js","sourcesContent":["/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits — the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write — the content is already on disk.\n }\n }\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error — thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 → transient, 404 → not_found, 401 → permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error — thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error — thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed — e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","import { expectDefined } from '../utils/expect-defined.js';\nimport * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { createGunzip } from 'node:zlib';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { WrongStackError, ERROR_CODES } from '../types/errors.js';\nexport interface ParsedRef {\n owner: string;\n repo: string;\n ref: string;\n}\n\n/**\n * Parse a skill reference string.\n * Formats: `user/repo` (default ref: main), `user/repo@ref`\n */\nexport function parseSkillRef(input: string): ParsedRef {\n const trimmed = input.trim().replace(/^https?:\\/\\/github\\.com\\//, '').replace(/\\.git$/, '');\n const atIdx = trimmed.indexOf('@');\n let refPath: string;\n let ref: string;\n if (atIdx > 0) {\n refPath = trimmed.slice(0, atIdx);\n ref = trimmed.slice(atIdx + 1);\n } else {\n refPath = trimmed;\n ref = 'main';\n }\n const parts = refPath.split('/').filter(Boolean);\n if (parts.length < 2) {\n throw new WrongStackError({\n message: `Invalid skill reference \"${input}\". Expected format: user/repo or user/repo@ref`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { input },\n });\n }\n return { owner: expectDefined(parts[0]), repo: expectDefined(parts[1]), ref };\n}\n\nexport interface DownloadResult {\n /** Temp directory containing the extracted repo. Caller must clean up. */\n tempDir: string;\n}\n\nconst MAX_TARBALL_SIZE = 50 * 1024 * 1024; // 50MB\n\n/**\n * Download and extract a GitHub repository tarball.\n * Uses the public GitHub API — no auth token required for public repos.\n * Returns the path to a temp directory with the extracted contents.\n */\nexport async function downloadGitHubTarball(parsed: ParsedRef): Promise<DownloadResult> {\n const url = `https://api.github.com/repos/${parsed.owner}/${parsed.repo}/tarball/${parsed.ref}`;\n\n const response = await fetch(url, {\n signal: AbortSignal.timeout(30_000),\n headers: {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'wrongstack-skill-installer',\n },\n redirect: 'follow',\n });\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new WrongStackError({\n message:\n `Repository not found: ${parsed.owner}/${parsed.repo}` +\n (parsed.ref !== 'main' ? ` (ref: ${parsed.ref})` : ''),\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, ref: parsed.ref, status: 404 },\n });\n }\n if (response.status === 403) {\n throw new WrongStackError({\n message: `Access denied: ${parsed.owner}/${parsed.repo}. The repository may be private or rate-limited.`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, status: 403 },\n });\n }\n throw new WrongStackError({\n message: `GitHub API error (${response.status}): ${response.statusText}`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, status: response.status },\n });\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && Number.parseInt(contentLength, 10) > MAX_TARBALL_SIZE) {\n throw new WrongStackError({\n message:\n `Tarball too large (${(Number.parseInt(contentLength, 10) / 1024 / 1024).toFixed(1)}MB). ` +\n `Max: ${MAX_TARBALL_SIZE / 1024 / 1024}MB`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: {\n owner: parsed.owner,\n repo: parsed.repo,\n contentLengthBytes: Number.parseInt(contentLength, 10),\n maxBytes: MAX_TARBALL_SIZE,\n },\n });\n }\n\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'wskill-'));\n\n try {\n if (!response.body) {\n throw new WrongStackError({\n message: 'Empty response body from GitHub API',\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo },\n });\n }\n\n // Gunzip the response body, then extract the tar stream\n const nodeStream = Readable.fromWeb(response.body as import('node:stream/web').ReadableStream);\n const gunzip = createGunzip();\n\n // Collect the uncompressed tar data into a buffer, then extract\n const chunks: Buffer[] = [];\n await pipeline(nodeStream, gunzip, async (source) => {\n for await (const chunk of source) {\n chunks.push(Buffer.from(chunk));\n }\n });\n const tarBuf = Buffer.concat(chunks);\n\n // Extract tar archive (POSIX ustar format)\n await extractTar(tarBuf, tempDir);\n\n return { tempDir };\n } catch (err) {\n await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});\n throw err;\n }\n}\n\n/**\n * Minimal POSIX tar extractor. Handles the ustar format produced by GitHub.\n * Only extracts regular files and directories — symlinks and special entries\n * are skipped for security.\n */\nasync function extractTar(buf: Buffer, destDir: string): Promise<void> {\n let offset = 0;\n\n while (offset + 512 <= buf.length) {\n // Check for end-of-archive (two consecutive zero blocks)\n const header = buf.subarray(offset, offset + 512);\n if (header.every((b) => b === 0)) break;\n\n // Parse ustar header\n const name = readTarString(buf, offset, 100); // name field\n const prefix = readTarString(buf, offset + 345, 155); // ustar prefix\n const size = Number.parseInt(readTarString(buf, offset + 124, 12).trim(), 8) || 0;\n const typeflag = buf[offset + 156] ?? 0;\n\n // Full path: prefix/name (ustar) or just name\n const fullPath = prefix ? `${prefix}/${name}` : name;\n // Strip the top-level directory (GitHub tarballs have owner-repo-sha/)\n const relPath = stripTopDir(fullPath);\n\n if (relPath && relPath !== '.' && relPath !== '..') {\n const destPath = path.join(destDir, relPath);\n\n // Zip-slip guard: reject any entry whose resolved path escapes destDir\n // (e.g. a crafted entry name like `x/../../../etc/cron.d/evil`). GitHub\n // tarballs are built from git trees and so cannot carry `..` components,\n // but this extractor is generic — never trust archive entry names.\n const resolvedDest = path.resolve(destPath);\n const resolvedRoot = path.resolve(destDir);\n if (resolvedDest !== resolvedRoot && !resolvedDest.startsWith(resolvedRoot + path.sep)) {\n // Skip the entry entirely; advance past its data below.\n offset += 512 + Math.ceil(size / 512) * 512;\n continue;\n }\n\n // typeflag: '0' or '\\0' = regular file, '5' = directory\n if (typeflag === 0x35 || typeflag === 0) {\n // Directory\n if (relPath.endsWith('/') || typeflag === 0x35) {\n await fs.mkdir(destPath, { recursive: true });\n }\n }\n\n if ((typeflag === 0x30 || typeflag === 0 || typeflag === 0x00) && size > 0) {\n // Regular file\n const dir = path.dirname(destPath);\n await fs.mkdir(dir, { recursive: true });\n const dataStart = offset + 512;\n const dataEnd = dataStart + size;\n if (dataEnd > buf.length) break; // truncated archive\n await fs.writeFile(destPath, buf.subarray(dataStart, dataEnd));\n }\n }\n\n // Advance: 512-byte header + data padded to 512-byte boundary\n offset += 512 + Math.ceil(size / 512) * 512;\n }\n}\n\nfunction readTarString(buf: Buffer, start: number, maxLen: number): string {\n let end = start;\n while (end < start + maxLen && end < buf.length && buf[end] !== 0) {\n end++;\n }\n return buf.subarray(start, end).toString('utf8');\n}\n\n/**\n * Strip the top-level directory from a tar path.\n * GitHub tarballs have a single root dir like `owner-repo-sha/`.\n */\nfunction stripTopDir(p: string): string {\n const idx = p.indexOf('/');\n if (idx === -1) return ''; // top-level file, skip\n return p.slice(idx + 1);\n}\n","import * as fs from 'node:fs/promises';\r\nimport * as path from 'node:path';\r\nimport { atomicWrite } from '../utils/atomic-write.js';\r\n\r\nexport interface InstalledSkillEntry {\r\n name: string;\r\n /** Source identifier, e.g. \"github:user/repo\" */\r\n source: string;\r\n /** Git ref that was installed (branch, tag, commit) */\r\n ref: string;\r\n /** Installation scope */\r\n scope: 'project' | 'user';\r\n /** Project hash — only set when scope=project */\r\n projectHash?: string | undefined;\r\n /** ISO 8601 timestamp */\r\n installedAt: string;\r\n /** List of files that were installed (relative to skill dir) */\r\n files: string[];\r\n}\r\n\r\nexport interface ManifestData {\r\n skills: InstalledSkillEntry[];\r\n}\r\n\r\nexport class SkillManifestStore {\r\n private readonly manifestPath: string;\r\n private cache?: ManifestData | undefined;\r\n\r\n constructor(manifestPath: string) {\r\n this.manifestPath = manifestPath;\r\n }\r\n\r\n async read(): Promise<ManifestData> {\r\n if (this.cache) return this.cache;\r\n try {\r\n const raw = await fs.readFile(this.manifestPath, 'utf8');\r\n const data = JSON.parse(raw) as ManifestData;\r\n if (!Array.isArray(data.skills)) {\r\n this.cache = { skills: [] };\r\n } else {\r\n this.cache = data;\r\n }\r\n } catch {\r\n this.cache = { skills: [] };\r\n }\r\n return this.cache;\r\n }\r\n\r\n async write(data: ManifestData): Promise<void> {\r\n const dir = path.dirname(this.manifestPath);\r\n await fs.mkdir(dir, { recursive: true });\r\n await atomicWrite(this.manifestPath, JSON.stringify(data, null, 2) + '\\n');\r\n this.cache = data;\r\n }\r\n\r\n async addEntry(entry: InstalledSkillEntry): Promise<void> {\r\n const data = await this.read();\r\n // Remove existing entry with the same name + scope\r\n data.skills = data.skills.filter(\r\n (s) => !(s.name === entry.name && s.scope === entry.scope),\r\n );\r\n data.skills.push(entry);\r\n await this.write(data);\r\n }\r\n\r\n async removeEntry(name: string, scope: 'project' | 'user'): Promise<boolean> {\r\n const data = await this.read();\r\n const before = data.skills.length;\r\n data.skills = data.skills.filter(\r\n (s) => !(s.name === name && s.scope === scope),\r\n );\r\n if (data.skills.length === before) return false;\r\n await this.write(data);\r\n return true;\r\n }\r\n\r\n async findByName(name: string): Promise<InstalledSkillEntry[]> {\r\n const data = await this.read();\r\n return data.skills.filter((s) => s.name === name);\r\n }\r\n\r\n async findBySource(source: string): Promise<InstalledSkillEntry[]> {\r\n const data = await this.read();\r\n return data.skills.filter((s) => s.source === source);\r\n }\r\n\r\n async listAll(): Promise<InstalledSkillEntry[]> {\r\n const data = await this.read();\r\n return data.skills;\r\n }\r\n\r\n /** Invalidate the in-memory cache (e.g. after external file changes). */\r\n invalidateCache(): void {\r\n this.cache = undefined;\r\n }\r\n}\r\n","import { expectDefined } from '../utils/expect-defined.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { SkillLoader } from '../types/skill.js';\nimport { downloadGitHubTarball, parseSkillRef } from './github-fetcher.js';\nimport { type InstalledSkillEntry, SkillManifestStore } from './manifest-store.js';\nimport { FsError, WrongStackError, ERROR_CODES } from '../types/errors.js';\nexport interface SkillInstallerOptions {\n /** Path to the manifest file (~/.wrongstack/installed-skills.json) */\n manifestPath: string;\n /** Path to project-level skills dir (<project>/.wrongstack/skills/) */\n projectSkillsDir: string;\n /** Path to user-global skills dir (~/.wrongstack/skills/) */\n globalSkillsDir: string;\n /** Current project hash (for manifest tracking) */\n projectHash: string;\n /** Skill loader — cache will be invalidated after mutations */\n skillLoader?: SkillLoader | undefined;\n /** Logger for status messages */\n log?: (((msg: string) => void)) | undefined;\n}\n\nexport interface InstallResult {\n name: string;\n path: string;\n scope: 'project' | 'user';\n source: string;\n ref: string;\n skillCount: number;\n}\n\nexport interface UpdateResult {\n updated: Array<{ name: string; oldRef: string; newRef: string }>;\n unchanged: string[];\n errors: Array<{ name: string; error: string }>;\n}\n\nconst MAX_SKILL_FILE_SIZE = 100 * 1024; // 100KB\n\nexport class SkillInstaller {\n private readonly opts: SkillInstallerOptions;\n private readonly manifest: SkillManifestStore;\n\n constructor(opts: SkillInstallerOptions) {\n this.opts = opts;\n this.manifest = new SkillManifestStore(opts.manifestPath);\n }\n\n /**\n * Install skills from a GitHub repository.\n * Supports both single-skill repos (SKILL.md at root) and multi-skill repos (skills/ subdirectory).\n */\n async install(refInput: string, opts?: { global?: boolean | undefined }): Promise<InstallResult[]> {\n const parsed = parseSkillRef(refInput);\n const scope: 'project' | 'user' = opts?.global ? 'user' : 'project';\n const targetDir = scope === 'project' ? this.opts.projectSkillsDir : this.opts.globalSkillsDir;\n const source = `github:${parsed.owner}/${parsed.repo}`;\n\n this.opts.log?.(`Downloading ${parsed.owner}/${parsed.repo}@${parsed.ref}...`);\n\n const { tempDir } = await downloadGitHubTarball(parsed);\n\n try {\n // Detect skill structure\n const skills = await this.detectSkills(tempDir);\n\n if (skills.length === 0) {\n throw new WrongStackError({\n message: 'No skills found in repository. Expected SKILL.md at root or skills/ subdirectory.',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, ref: parsed.ref },\n });\n }\n\n const results: InstallResult[] = [];\n\n for (const skill of skills) {\n // Check for overwrite\n const existing = await this.manifest.findByName(skill.name);\n const existingInScope = existing.find((e) => e.scope === scope);\n if (existingInScope) {\n this.opts.log?.(`Overwriting existing skill \"${skill.name}\" (${scope})...`);\n await this.removeSkillFiles(skill.name, scope);\n }\n\n // Copy skill files\n const destDir = path.join(targetDir, skill.name);\n await fs.mkdir(destDir, { recursive: true });\n const copiedFiles: string[] = [];\n\n for (const file of skill.files) {\n const srcPath = path.join(skill.baseDir, file);\n const destPath = path.join(destDir, file);\n\n // Path traversal check\n const resolved = path.resolve(destPath);\n if (!resolved.startsWith(path.resolve(destDir))) {\n throw new FsError({\n message: `Path traversal detected in skill file: ${file}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: destPath,\n context: { reason: 'path_traversal', skillName: skill.name },\n });\n }\n\n // Size check\n const stat = await fs.stat(srcPath);\n if (stat.size > MAX_SKILL_FILE_SIZE) {\n throw new FsError({\n message:\n `Skill file \"${file}\" is too large (${(stat.size / 1024).toFixed(1)}KB). ` +\n `Max: ${MAX_SKILL_FILE_SIZE / 1024}KB`,\n code: ERROR_CODES.FS_WRITE_FAILED,\n path: srcPath,\n context: { skillName: skill.name, fileSize: stat.size, maxSize: MAX_SKILL_FILE_SIZE },\n });\n }\n\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n await fs.copyFile(srcPath, destPath);\n copiedFiles.push(file);\n }\n\n // Write manifest entry\n const entry: InstalledSkillEntry = {\n name: skill.name,\n source,\n ref: parsed.ref,\n scope,\n projectHash: scope === 'project' ? this.opts.projectHash : undefined,\n installedAt: new Date().toISOString(),\n files: copiedFiles,\n };\n await this.manifest.addEntry(entry);\n\n results.push({\n name: skill.name,\n path: destDir,\n scope,\n source,\n ref: parsed.ref,\n skillCount: 1,\n });\n }\n\n this.invalidateLoaderCache();\n return results;\n } finally {\n // Clean up temp directory\n await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});\n }\n }\n\n /**\n * Update installed skills.\n * - No args: update all\n * - Name: update that specific skill\n * - Name + newRef: update to a different ref\n */\n async update(\n nameOrRef?: string | undefined,\n _opts?: { global?: boolean | undefined } | undefined,\n ): Promise<UpdateResult> {\n const result: UpdateResult = { updated: [], unchanged: [], errors: [] };\n const allEntries = await this.manifest.listAll();\n\n let targets: InstalledSkillEntry[];\n if (nameOrRef) {\n // Check if it's a name or a ref (user/repo@ref)\n const byName = allEntries.filter((e) => e.name === nameOrRef);\n if (byName.length > 0) {\n targets = byName;\n } else {\n // Treat as a new ref — find matching source\n try {\n const parsed = parseSkillRef(nameOrRef);\n const source = `github:${parsed.owner}/${parsed.repo}`;\n targets = allEntries.filter((e) => e.source === source);\n if (targets.length === 0) {\n result.errors.push({\n name: nameOrRef,\n error: `No installed skills found matching \"${nameOrRef}\"`,\n });\n return result;\n }\n } catch {\n result.errors.push({\n name: nameOrRef,\n error: `Invalid reference: ${nameOrRef}`,\n });\n return result;\n }\n }\n } else {\n targets = allEntries;\n }\n\n // Group by source to avoid downloading the same repo multiple times\n const bySource = new Map<string, InstalledSkillEntry[]>();\n for (const entry of targets) {\n const key = `${entry.source}@${entry.ref}`;\n if (!bySource.has(key)) bySource.set(key, []);\n bySource.get(key)?.push(entry);\n }\n\n for (const [, entries] of bySource) {\n const first = expectDefined(entries[0]);\n const scope = first.scope;\n const isGlobal = scope === 'user';\n\n try {\n // Parse the original source to get the ref\n const sourceRepo = first.source.replace('github:', '');\n let refToInstall = first.ref;\n\n // If nameOrRef looks like a new ref, use it\n if (nameOrRef && !allEntries.find((e) => e.name === nameOrRef)) {\n try {\n const parsed = parseSkillRef(nameOrRef);\n refToInstall = parsed.ref;\n } catch {\n // keep original ref\n }\n }\n\n this.opts.log?.(`Updating ${first.source}@${refToInstall}...`);\n const results = await this.install(`${sourceRepo}@${refToInstall}`, { global: isGlobal });\n\n for (const r of results) {\n result.updated.push({\n name: r.name,\n oldRef: first.ref,\n newRef: refToInstall,\n });\n }\n } catch (err) {\n const msg = toErrorMessage(err);\n for (const entry of entries) {\n result.errors.push({ name: entry.name, error: msg });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Uninstall a skill by name.\n */\n async uninstall(name: string, opts?: { global?: boolean | undefined }): Promise<void> {\n const scope: 'project' | 'user' = opts?.global ? 'user' : 'project';\n const entries = await this.manifest.findByName(name);\n const entry = entries.find((e) => e.scope === scope);\n\n if (!entry) {\n throw new WrongStackError({\n message: `Skill \"${name}\" is not installed${scope === 'user' ? ' (global)' : ''}.`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { skillName: name, scope },\n });\n }\n\n // Remove files\n await this.removeSkillFiles(name, scope);\n\n // Remove from manifest\n await this.manifest.removeEntry(name, scope);\n this.invalidateLoaderCache();\n }\n\n /**\n * List all installed skills from the manifest.\n */\n async listInstalled(): Promise<InstalledSkillEntry[]> {\n return this.manifest.listAll();\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n /**\n * Detect skills in an extracted repository.\n * Returns an array of detected skills with their files.\n */\n private async detectSkills(\n baseDir: string,\n ): Promise<Array<{ name: string; baseDir: string; files: string[] }>> {\n const results: Array<{ name: string; baseDir: string; files: string[] }> = [];\n\n // Check for SKILL.md at root (single-skill repo)\n const rootSkillMd = path.join(baseDir, 'SKILL.md');\n try {\n await fs.access(rootSkillMd);\n const content = await fs.readFile(rootSkillMd, 'utf8');\n const meta = parseFrontmatter(content);\n if (meta.name && meta.description) {\n results.push({\n name: meta.name,\n baseDir,\n files: ['SKILL.md'],\n });\n return results; // Single-skill repo — don't look for skills/\n }\n } catch {\n // No root SKILL.md\n }\n\n // Check for skills/ subdirectory (multi-skill repo)\n const skillsDir = path.join(baseDir, 'skills');\n try {\n const entries = await fs.readdir(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const skillFile = path.join(skillsDir, entry.name, 'SKILL.md');\n try {\n const content = await fs.readFile(skillFile, 'utf8');\n const meta = parseFrontmatter(content);\n if (meta.name && meta.description) {\n // Collect all files in the skill directory\n const skillDir = path.join(skillsDir, entry.name);\n const files = await collectFiles(skillDir, skillDir);\n results.push({\n name: meta.name,\n baseDir: skillDir,\n files,\n });\n }\n } catch {\n // Skip malformed skills\n }\n }\n } catch {\n // No skills/ directory\n }\n\n return results;\n }\n\n /**\n * Remove all files for an installed skill.\n */\n private async removeSkillFiles(name: string, scope: 'project' | 'user'): Promise<void> {\n const targetDir =\n scope === 'project' ? this.opts.projectSkillsDir : this.opts.globalSkillsDir;\n const skillDir = path.join(targetDir, name);\n await fs.rm(skillDir, { recursive: true, force: true });\n }\n\n /**\n * Invalidate the skill loader's cache so newly installed skills appear.\n */\n private invalidateLoaderCache(): void {\n // The SkillLoader interface has a cache internally.\n // We access it via the 'any' cast to call invalidateCache if available.\n const loader = this.opts.skillLoader as never as { invalidateCache?: () => void };\n if (loader && typeof loader.invalidateCache === 'function') {\n loader.invalidateCache();\n }\n }\n}\n\n// ── Utilities ──────────────────────────────────────────────────────\n\ninterface Frontmatter {\n name?: string | undefined;\n description?: string | undefined;\n}\n\nfunction parseFrontmatter(raw: string): Frontmatter {\n if (!raw.startsWith('---')) return {};\n const end = raw.indexOf('\\n---', 4);\n if (end === -1) return {};\n const block = raw.slice(4, end);\n const out: Frontmatter = {};\n let key: keyof Frontmatter | null = null;\n let value: string[] = [];\n const flush = () => {\n if (key) {\n out[key] = value.join('\\n').trim();\n }\n key = null;\n value = [];\n };\n for (const line of block.split('\\n')) {\n const m = /^([a-zA-Z_]+):\\s*(\\|?)\\s*(.*)$/.exec(line);\n if (m) {\n flush();\n key = (m[1] ?? '') as keyof Frontmatter;\n const pipe = m[2];\n const rest = m[3] ?? '';\n if (pipe === '|') {\n value = [];\n } else if (rest) {\n value = [rest];\n } else {\n value = [];\n }\n } else if (key) {\n value.push(line.replace(/^\\s+/, ''));\n }\n }\n flush();\n return out;\n}\n\n/**\n * Recursively collect all files in a directory (relative paths).\n */\nasync function collectFiles(dir: string, baseDir: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relPath = path.relative(baseDir, fullPath);\n if (entry.isDirectory()) {\n // Skip hidden dirs and node_modules\n if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;\n results.push(...(await collectFiles(fullPath, baseDir)));\n } else {\n results.push(relPath);\n }\n }\n return results;\n}\n"]}
1
+ {"version":3,"sources":["../../src/skills/foreign-sources.ts","../../src/skills/frontmatter.ts","../../src/utils/atomic-write.ts","../../src/utils/error.ts","../../src/utils/expect-defined.ts","../../src/types/errors.ts","../../src/skills/limits.ts","../../src/skills/github-fetcher.ts","../../src/skills/manifest-store.ts","../../src/skills/registry/github-direct-adapter.ts","../../src/skills/registry/skills-sh-adapter.ts","../../src/skills/skill-generator.ts","../../src/skills/skill-installer.ts"],"names":["path","fs","stat","resolve","fs2","path2","fs3","path3","path4","fs4","resolved"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Well-known foreign coding-agent skill directories. All follow the\n * agentskills.io `SKILL.md` format, so the same loader reads them — this just\n * tells it WHERE each agent keeps them.\n *\n * Claude is handled separately by the loader (`claude-project` / `claude-user`\n * sources); this list covers the OTHER agents. Every tool here stores skills\n * under `~/.<tool>/skills` (+ `<project>/.<tool>/skills`).\n *\n * Dirs that don't exist are skipped gracefully, so listing many is cheap.\n *\n * NOTE: Cursor previously used a non-standard `skills-cursor` subdir. As of the\n * 2026-07 alignment with the broader skills.sh / antfu-skills-cli / vercel-labs\n * ecosystem, Cursor uses the standard `skills` subdir like everyone else.\n * (`skills-cursor` was WrongStack-only and meant real Cursor skills were never\n * discovered — see docs/skills.md.)\n */\nexport interface ForeignSkillTool {\n /** Tool id — also the directory name segment (`~/.<id>/…`). */\n id: string;\n /** Skills subdirectory name under `~/.<id>/`. */\n subdir: string;\n}\n\nexport const FOREIGN_SKILL_TOOLS: readonly ForeignSkillTool[] = [\n { id: 'agents', subdir: 'skills' }, // shared store (asm / agentskills.io ecosystem)\n { id: 'codex', subdir: 'skills' }, // OpenAI Codex CLI\n { id: 'gemini', subdir: 'skills' }, // Gemini CLI\n { id: 'cursor', subdir: 'skills' }, // Cursor (standard subdir, aligned with skills.sh ecosystem)\n { id: 'qwen', subdir: 'skills' }, // Qwen Code\n { id: 'trae', subdir: 'skills' }, // Trae\n { id: 'windsurf', subdir: 'skills' }, // Windsurf\n];\n\n/** Set of known tool ids — used to flag typos in `config.skills.foreignSources`. */\nconst KNOWN_FOREIGN_IDS = new Set(FOREIGN_SKILL_TOOLS.map((t) => t.id));\n\n/** Result of resolving a `foreignSources` config option. */\nexport interface ResolvedForeignTools {\n /** Tool ids that will be scanned (subset of {@link FOREIGN_SKILL_TOOLS}). */\n ids: string[];\n /** Tool ids the user asked for that aren't known — likely typos (e.g. `corser`). */\n unknownIds: string[];\n}\n\n/**\n * Resolve the `config.skills.foreignSources` option into the list of tool ids\n * to scan. Kept for backward compatibility (returns only `ids`).\n * - `false` → none\n * - `string[]` → only those ids (unknown ids silently dropped — see\n * {@link resolveForeignToolIdsWithWarnings} to surface them)\n * - `true` / `undefined` → all well-known tools\n */\nexport function resolveForeignToolIds(opt: boolean | string[] | undefined): string[] {\n return resolveForeignToolIdsWithWarnings(opt).ids;\n}\n\n/**\n * Like {@link resolveForeignToolIds}, but also returns tool ids the caller asked\n * for that don't match any known agent. Callers that want to warn the user\n * about a likely typo (e.g. `foreignSources: [\"corser\"]`) should prefer this.\n *\n * - `false` → none\n * - `string[]` → known ids included, unknown ones returned in `unknownIds`\n * - `true` / `undefined` → all well-known tools (no unknowns possible)\n */\nexport function resolveForeignToolIdsWithWarnings(\n opt: boolean | string[] | undefined,\n): ResolvedForeignTools {\n if (opt === false) return { ids: [], unknownIds: [] };\n if (Array.isArray(opt)) {\n const ids: string[] = [];\n const unknownIds: string[] = [];\n for (const id of opt) {\n if (KNOWN_FOREIGN_IDS.has(id)) ids.push(id);\n else unknownIds.push(id);\n }\n return { ids, unknownIds };\n }\n return { ids: FOREIGN_SKILL_TOOLS.map((t) => t.id), unknownIds: [] };\n}\n\n/**\n * Security tier bucket for a registry skill's `securityScore` (0–100).\n * Mirrors the ags (agentskill-sh/ags) thresholds: skills below 30 need\n * explicit confirmation before install.\n */\nexport type SkillSecurityTier = 'low' | 'medium' | 'high';\n\n/** Classify a 0–100 security score into a tier. 0/undefined → unknown → `low`. */\nexport function securityScoreToTier(score: number | undefined | null): SkillSecurityTier {\n if (score == null || Number.isNaN(score)) return 'low';\n if (score < 30) return 'low';\n if (score < 70) return 'medium';\n return 'high';\n}\n","/**\n * Shared SKILL.md frontmatter parser + agentskills.io name validation.\n *\n * The SKILL.md format (https://agentskills.io/specification) is YAML\n * frontmatter between `---` markers followed by a Markdown body. This parser is\n * intentionally minimal — it handles the fields skills actually use, with YAML\n * block scalars (`|` / `>`) for multi-line values and an indented map for\n * `metadata`. It is NOT a general YAML parser; skill files are trusted markdown.\n */\nexport interface ParsedSkillFrontmatter {\n name?: string | undefined;\n description?: string | undefined;\n /** WrongStack extension; informational only. */\n version?: string | undefined;\n license?: string | undefined;\n compatibility?: string | undefined;\n metadata?: Record<string, string> | undefined;\n /** `allowed-tools` (spec, experimental) → split on whitespace. */\n allowedTools?: string[] | undefined;\n}\n\n/** Fields whose value is a single scalar string. */\nconst SCALAR_KEYS = new Set(['name', 'description', 'version', 'license', 'compatibility']);\n\n/**\n * Parse the YAML frontmatter block from a raw SKILL.md file. Returns `{}` when\n * there is no (or unclosed) frontmatter — callers treat that as \"skip\".\n *\n * Line endings are normalized first: CRLF (and lone CR) would otherwise leave a\n * trailing `\\r` on each line, and since `.` / `$` don't match `\\r`, the\n * `key: value` regex would fail on every line and silently drop the whole\n * frontmatter. Real skill files are frequently CRLF (Windows / some editors).\n */\nexport function parseSkillFrontmatter(raw: string): ParsedSkillFrontmatter {\n const text = normalizeLineEndings(raw);\n if (!text.startsWith('---')) return {};\n const end = text.indexOf('\\n---', 4);\n if (end === -1) return {};\n return parseFrontmatterBlock(text.slice(4, end));\n}\n\n/** Strip leading YAML frontmatter (`---\\n…\\n---`) from a SKILL.md file. */\nexport function stripFrontmatter(raw: string): string {\n const text = normalizeLineEndings(raw);\n if (!text.startsWith('---')) return text;\n const end = text.indexOf('\\n---', 4);\n if (end === -1) return text;\n let body = text.slice(end + 4);\n if (body.startsWith('\\n')) body = body.slice(1);\n return body;\n}\n\n/** Normalize CRLF and lone CR to LF. */\nfunction normalizeLineEndings(s: string): string {\n return s.replace(/\\r\\n?/g, '\\n');\n}\n\nfunction parseFrontmatterBlock(block: string): ParsedSkillFrontmatter {\n const out: ParsedSkillFrontmatter = {};\n const lines = block.split('\\n');\n let i = 0;\n while (i < lines.length) {\n const line = lines[i] ?? '';\n const m = /^([a-zA-Z][a-zA-Z0-9_-]*):\\s*(.*)$/.exec(line);\n if (!m) {\n i++;\n continue;\n }\n const key = m[1] ?? '';\n const rest = (m[2] ?? '').trim();\n\n if (key === 'metadata') {\n const map: Record<string, string> = {};\n i++;\n while (i < lines.length) {\n const sub = lines[i] ?? '';\n const sm = /^\\s+([a-zA-Z0-9_.-]+):\\s*(.*)$/.exec(sub);\n if (!sm) break;\n map[sm[1] ?? ''] = unquote((sm[2] ?? '').trim());\n i++;\n }\n if (Object.keys(map).length > 0) out.metadata = map;\n continue;\n }\n\n if (rest === '|' || rest === '>') {\n // Block scalar — collect following indented (or blank) lines.\n const collected: string[] = [];\n i++;\n while (i < lines.length) {\n const sub = lines[i] ?? '';\n if (sub === '' || sub.startsWith(' ') || sub.startsWith('\\t')) {\n collected.push(sub.replace(/^\\s+/, ''));\n i++;\n } else break;\n }\n (out as Record<string, unknown>)[normalizeKey(key)] = collected.join('\\n').trim();\n continue;\n }\n\n if (key === 'allowed-tools' || key === 'allowedTools') {\n // Spec: space-separated; tolerate comma-separated (common in real skills).\n out.allowedTools = rest.split(/[\\s,]+/).filter(Boolean);\n i++;\n continue;\n }\n\n if (SCALAR_KEYS.has(key)) {\n (out as Record<string, unknown>)[key] = unquote(rest);\n i++;\n continue;\n }\n\n // Unknown key — ignore.\n i++;\n }\n return out;\n}\n\n/** `allowed-tools` (hyphen) → `allowedTools` (camel); other keys pass through. */\nfunction normalizeKey(key: string): string {\n return key === 'allowed-tools' ? 'allowedTools' : key;\n}\n\n/** Strip surrounding single/double YAML quotes from a scalar value. */\nfunction unquote(s: string): string {\n if (\n s.length >= 2 &&\n ((s.startsWith('\"') && s.endsWith('\"')) || (s.startsWith(\"'\") && s.endsWith(\"'\")))\n ) {\n return s.slice(1, -1);\n }\n return s;\n}\n\n/** True when `name` matches the agentskills.io name format (chars + length only). */\nexport function isValidSkillNameFormat(name: string): boolean {\n return name.length >= 1 && name.length <= 64 && /^[a-z0-9]+(-[a-z0-9]+)*$/.test(name);\n}\n\n/**\n * Validate a skill `name` against the agentskills.io spec:\n * 1-64 chars; lowercase letters, digits, and single hyphens only; no\n * leading/trailing/consecutive hyphens. Pass the parent directory name to also\n * enforce the \"name must match the parent directory\" rule.\n *\n * Returns a list of human-readable violations (empty = valid).\n */\nexport function validateSkillName(name: string, parentDirName?: string): string[] {\n const errors: string[] = [];\n if (!name || name.trim().length === 0) {\n errors.push('name is empty');\n return errors;\n }\n if (name.length > 64) errors.push(`name is ${name.length} characters (max 64)`);\n if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(name)) {\n errors.push(\n 'name must be lowercase letters, digits, and single hyphens only ' +\n '(no leading/trailing/consecutive hyphens)',\n );\n }\n if (parentDirName !== undefined && name !== parentDirName) {\n errors.push(`name \"${name}\" must match its parent directory \"${parentDirName}\"`);\n }\n return errors;\n}\n","import { randomBytes } from 'node:crypto';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { FsError } from '../types/errors.js';\n\nexport interface AtomicWriteOptions {\n mode?: number | undefined;\n encoding?: BufferEncoding | undefined;\n}\n\nexport interface FileLockOptions {\n timeoutMs?: number | undefined;\n staleMs?: number | undefined;\n}\n\nexport async function atomicWrite(\n targetPath: string,\n content: string | Uint8Array,\n opts: AtomicWriteOptions = {},\n): Promise<void> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const tmp = path.join(dir, `.${path.basename(targetPath)}.${randomBytes(6).toString('hex')}.tmp`);\n\n // Write content to tmp first; 'wx' ensures exclusive creation (fails if\n // tmp already exists — extremely unlikely with 6-byte random suffix).\n try {\n if (typeof content === 'string') {\n await fs.writeFile(tmp, content, { flag: 'wx', encoding: opts.encoding ?? 'utf8' });\n } else {\n await fs.writeFile(tmp, content, { flag: 'wx' });\n }\n try {\n const fh = await fs.open(tmp, 'r+');\n try {\n await fh.sync();\n } finally {\n await fh.close();\n }\n } catch {\n // fsync best-effort\n }\n // Now safely read mode from target (if it exists) and apply to tmp before rename.\n // Prefer opts.mode for new files; for existing files preserve their mode.\n let mode: number | undefined;\n try {\n const stat = await fs.stat(targetPath);\n mode = stat.mode & 0o777;\n } catch {\n mode = opts.mode;\n }\n if (mode !== undefined) {\n await fs.chmod(tmp, mode);\n }\n await renameWithRetry(tmp, targetPath);\n // P3 #20 (before-release.md): on Windows, fs.rename (MoveFileExW) does\n // not preserve Unix permission bits — the chmod above applies to the tmp\n // file, but the rename may reset the destination's mode to the Windows\n // default. Re-apply the mode after rename on win32 so an edited file\n // keeps its executable bit (or any non-default permission). On POSIX,\n // rename preserves metadata so this is a no-op (chmod is idempotent and\n // cheap), but we gate it on win32 to avoid the extra stat+chmod on the\n // common path.\n if (mode !== undefined && process.platform === 'win32') {\n try {\n await fs.chmod(targetPath, mode);\n } catch {\n // Best-effort: a transient EPERM (antivirus lock) should not fail\n // the write — the content is already on disk.\n }\n }\n } catch (err) {\n try {\n await fs.unlink(tmp);\n } catch {\n // ignore cleanup error\n }\n throw err;\n }\n}\n\nexport async function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function withFileLock<T>(\n targetPath: string,\n fn: () => Promise<T>,\n opts: FileLockOptions = {},\n): Promise<T> {\n const dir = path.dirname(targetPath);\n await fs.mkdir(dir, { recursive: true });\n const lockPath = path.join(dir, `.${path.basename(targetPath)}.lock`);\n const timeoutMs = opts.timeoutMs ?? 5_000;\n const staleMs = opts.staleMs ?? 30_000;\n const started = Date.now();\n let handle: fs.FileHandle | undefined;\n\n for (;;) {\n try {\n handle = await fs.open(lockPath, 'wx');\n await handle.writeFile(`${process.pid}:${Date.now()}`);\n break;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n // ENOENT means the directory was deleted (e.g. by concurrent cleanup).\n // Recreate it and retry acquiring the lock.\n if (code === 'ENOENT') {\n await fs.mkdir(dir, { recursive: true });\n continue;\n }\n if (code !== 'EEXIST') throw err;\n try {\n const stat = await fs.stat(lockPath);\n if (Date.now() - stat.mtimeMs > staleMs) {\n await fs.unlink(lockPath);\n continue;\n }\n } catch {\n continue;\n }\n if (Date.now() - started >= timeoutMs) {\n throw new FsError({\n message: `Timed out waiting for file lock: ${targetPath}`,\n code: 'FS_ATOMIC_WRITE_FAILED',\n path: targetPath,\n context: { timeoutMs },\n });\n }\n await new Promise((resolve) => setTimeout(resolve, 25));\n }\n }\n\n try {\n return await fn();\n } finally {\n try {\n await handle?.close();\n } catch {\n // ignore\n }\n try {\n await fs.unlink(lockPath);\n } catch {\n // ignore\n }\n }\n}\n\n// On Windows, fs.rename over an existing file can fail with EPERM/EBUSY/EACCES\n// when antivirus, file indexers, editor file watchers, or a concurrent writer\n// briefly hold a handle on the destination. These are transient — retry with a\n// short backoff before giving up. POSIX renames are atomic and won't hit this.\nconst TRANSIENT_RENAME_CODES = new Set(['EPERM', 'EBUSY', 'EACCES', 'ENOTEMPTY']);\n\nasync function renameWithRetry(from: string, to: string): Promise<void> {\n if (process.platform !== 'win32') {\n await fs.rename(from, to);\n return;\n }\n const delays = [10, 25, 60, 120, 250];\n let lastErr: unknown;\n for (let i = 0; i <= delays.length; i++) {\n try {\n await fs.rename(from, to);\n return;\n } catch (err) {\n lastErr = err;\n const code = (err as NodeJS.ErrnoException)?.code;\n if (!code || !TRANSIENT_RENAME_CODES.has(code) || i === delays.length) {\n throw err;\n }\n await new Promise((resolve) => setTimeout(resolve, delays[i]));\n }\n }\n throw lastErr;\n}\n","/**\n * Converts an unknown error value to a human-readable string.\n * Used in 40+ files across the codebase to normalize error messaging.\n */\nexport function toErrorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/** Assert a value is neither null nor undefined. Throws if it is.\n * Useful after optional chaining and indexed access when the\n * control flow guarantees the value exists but TypeScript can't\n * prove it (e.g. after a check on a related field). */\nexport function expectDefined<T>(value: T | null | undefined, label?: string): T {\n if (value === null || value === undefined) {\n const err = new Error(label ? `Expected ${label} to be defined` : 'Expected value to be defined');\n err.name = 'ExpectDefinedError';\n throw err;\n }\n return value;\n}\n","import { toErrorMessage } from '../utils/index.js';\n\n/**\n * WrongStack error hierarchy.\n *\n * Every error thrown by the framework is a `WrongStackError` with a\n * machine-readable `code`, a `subsystem` tag, and a `severity` level.\n * This lets consumers (CLI, TUI, plugins, tests) branch on structured\n * data instead of parsing error messages.\n */\n\n// ── Error codes ──────────────────────────────────────────────────────\n\n/**\n * Machine-readable error codes as frozen constants.\n *\n * Use `ERROR_CODES.X` instead of raw string literals for:\n * - IDE autocomplete and compile-time validation\n * - Safe refactoring (rename updates all usages)\n * - Plugin extensibility (extend the object to add custom codes)\n *\n * The `ErrorCode` type is derived from this object, so adding a new\n * code here automatically updates the type without extra changes.\n */\nexport const ERROR_CODES = {\n // Provider\n PROVIDER_RATE_LIMITED: 'PROVIDER_RATE_LIMITED',\n PROVIDER_AUTH_FAILED: 'PROVIDER_AUTH_FAILED',\n PROVIDER_OVERLOADED: 'PROVIDER_OVERLOADED',\n PROVIDER_INVALID_REQUEST: 'PROVIDER_INVALID_REQUEST',\n PROVIDER_SERVER_ERROR: 'PROVIDER_SERVER_ERROR',\n PROVIDER_NETWORK_ERROR: 'PROVIDER_NETWORK_ERROR',\n PROVIDER_CONTEXT_OVERFLOW: 'PROVIDER_CONTEXT_OVERFLOW',\n // Tool\n TOOL_NOT_FOUND: 'TOOL_NOT_FOUND',\n TOOL_PERMISSION_DENIED: 'TOOL_PERMISSION_DENIED',\n TOOL_EXECUTION_FAILED: 'TOOL_EXECUTION_FAILED',\n TOOL_TIMEOUT: 'TOOL_TIMEOUT',\n TOOL_INPUT_INVALID: 'TOOL_INPUT_INVALID',\n // Config\n CONFIG_INVALID: 'CONFIG_INVALID',\n CONFIG_NOT_FOUND: 'CONFIG_NOT_FOUND',\n CONFIG_PARSE_FAILED: 'CONFIG_PARSE_FAILED',\n CONFIG_MIGRATION_NEEDED: 'CONFIG_MIGRATION_NEEDED',\n // Plugin\n PLUGIN_LOAD_FAILED: 'PLUGIN_LOAD_FAILED',\n PLUGIN_API_MISMATCH: 'PLUGIN_API_MISMATCH',\n PLUGIN_MISSING_DEPENDENCY: 'PLUGIN_MISSING_DEPENDENCY',\n // Agent\n AGENT_ITERATION_LIMIT: 'AGENT_ITERATION_LIMIT',\n AGENT_CONTEXT_OVERFLOW: 'AGENT_CONTEXT_OVERFLOW',\n AGENT_ABORTED: 'AGENT_ABORTED',\n AGENT_RUN_FAILED: 'AGENT_RUN_FAILED',\n // Session\n SESSION_NOT_FOUND: 'SESSION_NOT_FOUND',\n SESSION_CORRUPTED: 'SESSION_CORRUPTED',\n SESSION_WRITE_FAILED: 'SESSION_WRITE_FAILED',\n // Container / Registry\n CONTAINER_TOKEN_ALREADY_BOUND: 'CONTAINER_TOKEN_ALREADY_BOUND',\n CONTAINER_TOKEN_NOT_BOUND: 'CONTAINER_TOKEN_NOT_BOUND',\n CONTAINER_CIRCULAR_DEPENDENCY: 'CONTAINER_CIRCULAR_DEPENDENCY',\n REGISTRY_DUPLICATE: 'REGISTRY_DUPLICATE',\n REGISTRY_NOT_FOUND: 'REGISTRY_NOT_FOUND',\n REGISTRY_INVALID: 'REGISTRY_INVALID',\n // File system\n FS_READ_FAILED: 'FS_READ_FAILED',\n FS_WRITE_FAILED: 'FS_WRITE_FAILED',\n FS_MKDIR_FAILED: 'FS_MKDIR_FAILED',\n FS_DELETE_FAILED: 'FS_DELETE_FAILED',\n FS_ATOMIC_WRITE_FAILED: 'FS_ATOMIC_WRITE_FAILED',\n // SDD (Spec-Driven Development)\n SDD_VALIDATION_FAILED: 'SDD_VALIDATION_FAILED',\n SDD_PARSE_FAILED: 'SDD_PARSE_FAILED',\n SDD_INVALID_STATE: 'SDD_INVALID_STATE',\n SDD_NOT_READY: 'SDD_NOT_READY',\n // General\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n PARSE_FAILED: 'PARSE_FAILED',\n UNKNOWN: 'UNKNOWN',\n} as const;\n\n/**\n * Union type derived from `ERROR_CODES`. Using `typeof ERROR_CODES[keyof typeof ERROR_CODES]`\n * instead of a string literal union means TypeScript auto-updates the type whenever\n * a new code is added to `ERROR_CODES` — no need to keep two lists in sync.\n */\nexport type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];\n\nexport type ErrorSubsystem =\n | 'provider'\n | 'tool'\n | 'config'\n | 'plugin'\n | 'agent'\n | 'session'\n | 'sdd'\n | 'container'\n | 'fs'\n | 'general';\nexport type ErrorSeverity = 'fatal' | 'error' | 'warning';\n\n// ── Base error class ─────────────────────────────────────────────────\n\nexport class WrongStackError extends Error {\n readonly code: ErrorCode;\n readonly subsystem: ErrorSubsystem;\n readonly severity: ErrorSeverity;\n readonly recoverable: boolean;\n readonly context?: Record<string, unknown> | undefined;\n\n constructor(opts: {\n message: string;\n code: ErrorCode;\n subsystem: ErrorSubsystem;\n severity?: ErrorSeverity | undefined;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super(opts.message, { cause: opts.cause });\n this.name = 'WrongStackError';\n this.code = opts.code;\n this.subsystem = opts.subsystem;\n this.severity = opts.severity ?? 'error';\n this.recoverable = opts.recoverable ?? false;\n this.context = opts.context;\n }\n\n /**\n * Render a one-line user-facing description.\n * Subclasses should override for domain-specific formatting.\n */\n describe(): string {\n const ctx = this.context ? ` ${formatContext(this.context)}` : '';\n return `${this.code}: ${this.message}${ctx}`;\n }\n}\n\nfunction formatContext(ctx: Record<string, unknown>): string {\n const parts = Object.entries(ctx)\n .filter(([, v]) => v !== undefined)\n .slice(0, 3)\n .map(([k, v]) => `${k}=${String(v)}`);\n return parts.length > 0 ? `[${parts.join(' ')}]` : '';\n}\n\n// ── Specific error classes ───────────────────────────────────────────\n\n/**\n * Tool execution errors — thrown by ToolExecutor and individual tools.\n */\nexport class ToolError extends WrongStackError {\n readonly toolName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n | 'TOOL_NOT_FOUND'\n | 'TOOL_PERMISSION_DENIED'\n | 'TOOL_EXECUTION_FAILED'\n | 'TOOL_TIMEOUT'\n | 'TOOL_INPUT_INVALID'\n >;\n toolName: string;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'tool',\n recoverable: opts.recoverable,\n context: { tool: opts.toolName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolError';\n this.toolName = opts.toolName;\n }\n}\n\n/**\n * Config loading / validation errors.\n */\nexport class ConfigError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'CONFIG_INVALID' | 'CONFIG_NOT_FOUND' | 'CONFIG_PARSE_FAILED' | 'CONFIG_MIGRATION_NEEDED'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'config',\n severity: 'fatal',\n recoverable: false,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Plugin loading / lifecycle errors.\n */\nexport class PluginError extends WrongStackError {\n readonly pluginName: string;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'PLUGIN_LOAD_FAILED' | 'PLUGIN_API_MISMATCH' | 'PLUGIN_MISSING_DEPENDENCY'\n >;\n pluginName: string;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'plugin',\n severity: 'error',\n recoverable: opts.code === ERROR_CODES.PLUGIN_MISSING_DEPENDENCY,\n context: { plugin: opts.pluginName, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'PluginError';\n this.pluginName = opts.pluginName;\n }\n}\n\n/**\n * Agent runtime errors — thrown by Agent.run when a non-WrongStackError\n * escapes the inner loop, so callers always see a structured error.\n */\nexport class AgentError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'AGENT_ITERATION_LIMIT' | 'AGENT_CONTEXT_OVERFLOW' | 'AGENT_ABORTED' | 'AGENT_RUN_FAILED'\n >;\n recoverable?: boolean | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'agent',\n severity: opts.code === ERROR_CODES.AGENT_ABORTED ? 'warning' : 'error',\n recoverable: opts.recoverable ?? opts.code === ERROR_CODES.AGENT_ITERATION_LIMIT,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'AgentError';\n }\n}\n\n/**\n * Wrap an arbitrary thrown value into a `WrongStackError` so the caller\n * always gets a structured error. Pass-throughs WrongStackError instances\n * unchanged; raw `Error`s and primitives get an `AGENT_RUN_FAILED` wrapper\n * with the original preserved as `cause`.\n */\nexport function toWrongStackError(\n err: unknown,\n code: Extract<ErrorCode, 'AGENT_RUN_FAILED' | 'AGENT_ABORTED' | 'UNKNOWN'> = ERROR_CODES.AGENT_RUN_FAILED,\n): WrongStackError {\n if (err instanceof WrongStackError) return err;\n const message = toErrorMessage(err);\n return new AgentError({\n message,\n code: code === 'UNKNOWN' ? ERROR_CODES.AGENT_RUN_FAILED : code,\n cause: err,\n });\n}\n\n/**\n * Session storage errors.\n */\nexport class SessionError extends WrongStackError {\n readonly sessionId?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<ErrorCode, 'SESSION_NOT_FOUND' | 'SESSION_CORRUPTED' | 'SESSION_WRITE_FAILED'>;\n sessionId?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'session',\n severity: opts.code === ERROR_CODES.SESSION_WRITE_FAILED ? 'error' : 'warning',\n recoverable: opts.code !== ERROR_CODES.SESSION_CORRUPTED,\n context: { sessionId: opts.sessionId, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'SessionError';\n this.sessionId = opts.sessionId;\n }\n}\n\n/**\n * SDD (Spec-Driven Development) errors — spec validation, parsing, and\n * state machine violations in the AISpecBuilder, TaskFlow, and TaskTracker.\n */\nexport class SddError extends WrongStackError {\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'SDD_VALIDATION_FAILED' | 'SDD_PARSE_FAILED' | 'SDD_INVALID_STATE' | 'SDD_NOT_READY'\n >;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'sdd',\n severity: opts.code === ERROR_CODES.SDD_PARSE_FAILED ? 'warning' : 'error',\n recoverable: opts.code === ERROR_CODES.SDD_NOT_READY,\n context: opts.context,\n cause: opts.cause,\n });\n this.name = 'SddError';\n }\n}\n\n/**\n * File system operation errors.\n */\nexport class FsError extends WrongStackError {\n readonly path?: string | undefined;\n\n constructor(opts: {\n message: string;\n code: Extract<\n ErrorCode,\n 'FS_READ_FAILED' | 'FS_WRITE_FAILED' | 'FS_MKDIR_FAILED' | 'FS_DELETE_FAILED' | 'FS_ATOMIC_WRITE_FAILED'\n >;\n path?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: opts.code,\n subsystem: 'fs',\n severity: 'error',\n recoverable: opts.code !== ERROR_CODES.FS_READ_FAILED,\n context: { path: opts.path, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FsError';\n this.path = opts.path;\n }\n}\n\n/**\n * HTTP fetch error — thrown when a network request returns a non-OK status.\n * Carries the response status so {@link classifyToolError} can branch on it\n * (429 → transient, 404 → not_found, 401 → permission) without duck-typing\n * the error via `'response' in err`.\n *\n * P3 #18 (before-release.md): the previous `'response' in err` check caught\n * any Error with a `response` property, including custom errors, proxy\n * objects, or mocked errors in tests. `instanceof FetchError` is reliable.\n *\n * Tools and providers that make HTTP requests and need the executor to\n * classify their failures should throw `new FetchError({ status, message })`\n * instead of a bare `Error` with an ad-hoc `response` field.\n */\nexport class FetchError extends WrongStackError {\n readonly status: number;\n\n constructor(opts: {\n message: string;\n status: number;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: opts.status === 429 || opts.status >= 500,\n context: { status: opts.status, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'FetchError';\n this.status = opts.status;\n }\n}\n\n/**\n * Tool input validation error — thrown when a tool's input fails a validation\n * check that the JSON Schema cannot express (e.g. `old_string === new_string`\n * in edit, or a cross-field invariant). Use this instead of a bare\n * `throw new Error('...validation...')` so {@link classifyToolError} can\n * match on `instanceof` rather than a locale-dependent message substring.\n *\n * P2 #6 (before-release.md): the previous `err.message.includes('validation')`\n * check misclassified any error whose message happened to contain \"validation\"\n * (e.g. a third-party \"input validation timeout\") as a VALIDATION error.\n *\n * Named `ToolValidationError` (not `ValidationError`) to avoid colliding with\n * the existing `ValidationError` interface exported by json-schema-validate.ts\n * (a validation-result shape, not an Error subclass).\n */\nexport class ToolValidationError extends WrongStackError {\n constructor(opts: {\n message: string;\n /** Field path or tool name that failed validation, for diagnostics. */\n field?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { field: opts.field, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ToolValidationError';\n }\n}\n\n/**\n * Response / payload parse error — thrown when an upstream HTTP response,\n * file, or data structure is well-formed at the transport layer (HTTP 200,\n * valid JSON) but is missing required fields or has an unexpected shape.\n *\n * Distinct from `ConfigError(CONFIG_PARSE_FAILED)` (which is specifically\n * for config-file parsing) and `FetchError` (which covers HTTP non-OK\n * responses). `ParseError` fills the gap: the request succeeded but the\n * response body couldn't be interpreted.\n *\n * Common sites: OAuth token responses missing `access_token`, device-code\n * responses missing `device_code`, registry responses with unexpected\n * schemas.\n */\nexport class ParseError extends WrongStackError {\n readonly source?: string | undefined;\n\n constructor(opts: {\n message: string;\n /**\n * What was being parsed — e.g. `'oauth-token-response'`,\n * `'device-code-response'`. Lets consumers distinguish parse failures\n * from different upstream APIs without parsing the message.\n */\n source?: string | undefined;\n context?: Record<string, unknown> | undefined;\n cause?: unknown | undefined;\n }) {\n super({\n message: opts.message,\n code: ERROR_CODES.PARSE_FAILED,\n subsystem: 'general',\n severity: 'error',\n recoverable: false,\n context: { source: opts.source, ...opts.context },\n cause: opts.cause,\n });\n this.name = 'ParseError';\n this.source = opts.source;\n }\n}\n\n// ── Type guards ──────────────────────────────────────────────────────\n\nexport function isWrongStackError(err: unknown): err is WrongStackError {\n return err instanceof WrongStackError;\n}\n\nexport function isToolError(err: unknown): err is ToolError {\n return err instanceof ToolError;\n}\n\nexport function isConfigError(err: unknown): err is ConfigError {\n return err instanceof ConfigError;\n}\n\nexport function isPluginError(err: unknown): err is PluginError {\n return err instanceof PluginError;\n}\n\nexport function isSessionError(err: unknown): err is SessionError {\n return err instanceof SessionError;\n}\n\nexport function isAgentError(err: unknown): err is AgentError {\n return err instanceof AgentError;\n}\n\nexport function isFsError(err: unknown): err is FsError {\n return err instanceof FsError;\n}\n\nexport function isToolValidationError(err: unknown): err is ToolValidationError {\n return err instanceof ToolValidationError;\n}\n\nexport function isFetchError(err: unknown): err is FetchError {\n return err instanceof FetchError;\n}\n\nexport function isParseError(err: unknown): err is ParseError {\n return err instanceof ParseError;\n}\n\nexport function isSddError(err: unknown): err is SddError {\n return err instanceof SddError;\n}\n","/**\n * Centralized skill system limits.\n *\n * Before this file existed, the magic numbers below were scattered across five\n * modules (`skill-installer`, `github-fetcher`, `skill` tool, system-prompt\n * builder, skill-loader), sometimes duplicated (e.g. per-skill body cap was\n * defined independently in the builder and the tool). Centralizing them here\n * keeps the budget model coherent — change one, change everywhere — and makes\n * the trade-offs visible in one place.\n *\n * Values are frozen at their pre-centralization defaults so this is a pure\n * refactor (no behavior change).\n */\nexport const SKILL_LIMITS = {\n /**\n * Per-skill body cap when injecting a full skill body into the system prompt\n * (eager mode), and when returning a skill body from the `skill` tool.\n * ~4k tokens. Oversized bodies are truncated at a paragraph boundary.\n *\n * Consumers: `system-prompt-builder.capSkillBody`, `skill` tool body return.\n */\n MAX_SKILL_BODY_CHARS: 16_000,\n\n /**\n * Per-resource cap when the `skill` tool loads a bundled file\n * (`scripts/`, `references/`, `assets/`). ~8k tokens.\n *\n * Consumer: `skill` tool `loadResource`.\n */\n MAX_RESOURCE_CHARS: 32_000,\n\n /**\n * Maximum number of bundled resource paths the `skill` tool lists in one\n * response. Caps a pathological skill (huge `assets/` tree) from blowing up\n * the tool result.\n *\n * Consumer: `skill` tool resource listing.\n */\n MAX_LISTED_RESOURCES: 100,\n\n /**\n * Max size of a single installed skill file (SKILL.md or a bundled resource).\n * Guards against a malicious registry skill shipping a multi-MB blob that\n * then flows into the prompt. 100KB.\n *\n * Consumer: `SkillInstaller.install` / `importFromDir`.\n */\n MAX_SKILL_FILE_SIZE: 100 * 1024,\n\n /**\n * Max size of a GitHub tarball downloaded by the skill installer. Guards\n * against a repo accidentally (or maliciously) shipping a giant tarball that\n * would be extracted into a temp dir. 50MB.\n *\n * Consumer: `downloadGitHubTarball`.\n */\n MAX_TARBALL_SIZE: 50 * 1024 * 1024,\n\n /**\n * Default total char budget for skill bodies injected in eager mode when\n * `config.skills.eagerMaxChars` is unset. ~6k tokens. Skills are injected\n * highest-priority first; once the budget is exhausted the remaining skills\n * are listed as a manifest the agent loads via the `skill` tool. Set very\n * high to effectively disable budgeting.\n *\n * Consumer: `DefaultSystemPromptBuilder.buildMemoryAndSkills` (default for\n * `skillEagerMaxChars`).\n */\n EAGER_DEFAULT_MAX_CHARS: 24_000,\n\n /**\n * Auto-compact body limits (the token-saving fallback used when a skill has\n * no hand-crafted `SKILL.save.md`). The Overview and Rules sections are\n * extracted and trimmed to these char budgets, then the total is capped.\n *\n * Consumer: `DefaultSkillLoader.compactSkillBody`.\n */\n COMPACT_OVERVIEW_MAX: 200,\n COMPACT_RULES_MAX: 350,\n COMPACT_TOTAL_MAX: 450,\n\n /**\n * Max length of a skill name (agentskills.io spec). Enforced by the\n * frontmatter validator's format regex plus this length bound.\n *\n * Consumer: `isValidSkillNameFormat`.\n */\n SKILL_NAME_MAX_LEN: 64,\n\n /**\n * Soft line limit for a SKILL.md body, per the bundled `skill-creator` rule.\n * Not enforced in code (a skill can exceed it) — surfaced by `/skill-gen\n * validate` and the `skill-creator` skill as guidance to move deep material\n * into `references/`.\n *\n * Consumer: `skill-creator` skill, `/skill-gen validate` advisory.\n */\n SKILL_BODY_LINE_LIMIT: 500,\n} as const;\n","import * as fs from 'node:fs/promises';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { createGunzip } from 'node:zlib';\nimport { ERROR_CODES, FetchError, WrongStackError } from '../types/errors.js';\nimport { expectDefined } from '../utils/expect-defined.js';\nimport { SKILL_LIMITS } from './limits.js';\n\nexport interface ParsedRef {\n owner: string;\n repo: string;\n ref: string;\n}\n\n/**\n * Parse a skill reference string.\n * Formats: `user/repo` (default ref: main), `user/repo@ref`\n */\nexport function parseSkillRef(input: string): ParsedRef {\n const trimmed = input\n .trim()\n .replace(/^https?:\\/\\/github\\.com\\//, '')\n .replace(/\\.git$/, '');\n const atIdx = trimmed.indexOf('@');\n let refPath: string;\n let ref: string;\n if (atIdx > 0) {\n refPath = trimmed.slice(0, atIdx);\n ref = trimmed.slice(atIdx + 1);\n } else {\n refPath = trimmed;\n ref = 'main';\n }\n const parts = refPath.split('/').filter(Boolean);\n if (parts.length < 2) {\n throw new WrongStackError({\n message: `Invalid skill reference \"${input}\". Expected format: user/repo or user/repo@ref`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { input },\n });\n }\n return { owner: expectDefined(parts[0]), repo: expectDefined(parts[1]), ref };\n}\n\nexport interface DownloadResult {\n /** Temp directory containing the extracted repo. Caller must clean up. */\n tempDir: string;\n}\n\n/**\n * Resolve a GitHub auth token, if one is configured.\n *\n * Order: `WRONGSTACK_GITHUB_TOKEN` (WrongStack-specific override) → `GITHUB_TOKEN`\n * → `GH_TOKEN` (the gh CLI convention). Returns `undefined` when none are set,\n * which means only public repos can be fetched.\n *\n * Exposed for testing and for the installer's user-facing messaging (so it can\n * say \"set GITHUB_TOKEN to install private repos\" rather than just \"403\").\n */\nexport function resolveGitHubToken(env: NodeJS.ProcessEnv = process.env): string | undefined {\n const raw = env['WRONGSTACK_GITHUB_TOKEN'] ?? env['GITHUB_TOKEN'] ?? env['GH_TOKEN'];\n if (!raw) return undefined;\n const trimmed = raw.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\n/**\n * Download and extract a GitHub repository tarball.\n *\n * Auth: reads `WRONGSTACK_GITHUB_TOKEN` / `GITHUB_TOKEN` / `GH_TOKEN` (in that\n * order). Without a token only public repos work; with one, private repos the\n * token can read also work, and the API rate limit is the authenticated\n * (much higher) limit instead of the anonymous 60/hour.\n *\n * Returns the path to a temp directory with the extracted contents. The caller\n * must remove it (the installer does this in a `finally`).\n */\nexport async function downloadGitHubTarball(parsed: ParsedRef): Promise<DownloadResult> {\n const url = `https://api.github.com/repos/${parsed.owner}/${parsed.repo}/tarball/${parsed.ref}`;\n const token = resolveGitHubToken();\n\n const headers: Record<string, string> = {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'wrongstack-skill-installer',\n };\n if (token) headers['Authorization'] = `Bearer ${token}`;\n\n let response: Response;\n try {\n response = await fetch(url, {\n signal: AbortSignal.timeout(30_000),\n headers,\n redirect: 'follow',\n });\n } catch (err) {\n // Network error / timeout — surface as a recoverable FetchError so callers\n // can retry if they want. Don't leak the raw error (may contain the URL).\n throw new FetchError({\n message: `Network error fetching ${parsed.owner}/${parsed.repo}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n status: 0,\n context: { owner: parsed.owner, repo: parsed.repo, ref: parsed.ref, op: 'tarball' },\n cause: err,\n });\n }\n\n if (!response.ok) {\n if (response.status === 404) {\n throw new WrongStackError({\n message:\n `Repository not found: ${parsed.owner}/${parsed.repo}` +\n (parsed.ref !== 'main' ? ` (ref: ${parsed.ref})` : '') +\n (token ? '' : '. If this is a private repo, set GITHUB_TOKEN (or GH_TOKEN).'),\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, ref: parsed.ref, status: 404 },\n });\n }\n if (response.status === 403) {\n // Distinguish rate-limit (anonymous 60/hour) from a real access denial.\n const remaining = response.headers.get('x-ratelimit-remaining');\n const isRateLimited = remaining === '0';\n throw new WrongStackError({\n message: isRateLimited\n ? `GitHub API rate limit exceeded. Set GITHUB_TOKEN (or GH_TOKEN) to use the higher authenticated limit.`\n : `Access denied: ${parsed.owner}/${parsed.repo}. The repository may be private (set GITHUB_TOKEN to install private repos) or rate-limited.`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: {\n owner: parsed.owner,\n repo: parsed.repo,\n status: 403,\n rateLimited: isRateLimited,\n hasToken: Boolean(token),\n },\n });\n }\n throw new WrongStackError({\n message: `GitHub API error (${response.status}): ${response.statusText}`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, status: response.status },\n });\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && Number.parseInt(contentLength, 10) > SKILL_LIMITS.MAX_TARBALL_SIZE) {\n throw new WrongStackError({\n message:\n `Tarball too large (${(Number.parseInt(contentLength, 10) / 1024 / 1024).toFixed(1)}MB). ` +\n `Max: ${SKILL_LIMITS.MAX_TARBALL_SIZE / 1024 / 1024}MB`,\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: {\n owner: parsed.owner,\n repo: parsed.repo,\n contentLengthBytes: Number.parseInt(contentLength, 10),\n maxBytes: SKILL_LIMITS.MAX_TARBALL_SIZE,\n },\n });\n }\n\n const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'wskill-'));\n\n try {\n if (!response.body) {\n throw new WrongStackError({\n message: 'Empty response body from GitHub API',\n code: ERROR_CODES.UNKNOWN,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo },\n });\n }\n\n // Gunzip the response body, then extract the tar stream\n const nodeStream = Readable.fromWeb(response.body as import('node:stream/web').ReadableStream);\n const gunzip = createGunzip();\n\n // Collect the uncompressed tar data into a buffer, then extract\n const chunks: Buffer[] = [];\n await pipeline(nodeStream, gunzip, async (source) => {\n for await (const chunk of source) {\n chunks.push(Buffer.from(chunk));\n }\n });\n const tarBuf = Buffer.concat(chunks);\n\n // Extract tar archive (POSIX ustar format)\n await extractTar(tarBuf, tempDir);\n\n return { tempDir };\n } catch (err) {\n await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});\n throw err;\n }\n}\n\n/**\n * Minimal POSIX tar extractor. Handles the ustar format produced by GitHub.\n * Only extracts regular files and directories — symlinks and special entries\n * are skipped for security.\n */\nasync function extractTar(buf: Buffer, destDir: string): Promise<void> {\n let offset = 0;\n\n while (offset + 512 <= buf.length) {\n // Check for end-of-archive (two consecutive zero blocks)\n const header = buf.subarray(offset, offset + 512);\n if (header.every((b) => b === 0)) break;\n\n // Parse ustar header\n const name = readTarString(buf, offset, 100); // name field\n const prefix = readTarString(buf, offset + 345, 155); // ustar prefix\n const size = Number.parseInt(readTarString(buf, offset + 124, 12).trim(), 8) || 0;\n const typeflag = buf[offset + 156] ?? 0;\n\n // Full path: prefix/name (ustar) or just name\n const fullPath = prefix ? `${prefix}/${name}` : name;\n // Strip the top-level directory (GitHub tarballs have owner-repo-sha/)\n const relPath = stripTopDir(fullPath);\n\n if (relPath && relPath !== '.' && relPath !== '..') {\n const destPath = path.join(destDir, relPath);\n\n // Zip-slip guard: reject any entry whose resolved path escapes destDir\n // (e.g. a crafted entry name like `x/../../../etc/cron.d/evil`). GitHub\n // tarballs are built from git trees and so cannot carry `..` components,\n // but this extractor is generic — never trust archive entry names.\n const resolvedDest = path.resolve(destPath);\n const resolvedRoot = path.resolve(destDir);\n if (resolvedDest !== resolvedRoot && !resolvedDest.startsWith(resolvedRoot + path.sep)) {\n // Skip the entry entirely; advance past its data below.\n offset += 512 + Math.ceil(size / 512) * 512;\n continue;\n }\n\n // typeflag: '0' or '\\0' = regular file, '5' = directory\n if (typeflag === 0x35 || typeflag === 0) {\n // Directory\n if (relPath.endsWith('/') || typeflag === 0x35) {\n await fs.mkdir(destPath, { recursive: true });\n }\n }\n\n if ((typeflag === 0x30 || typeflag === 0 || typeflag === 0x00) && size > 0) {\n // Regular file\n const dir = path.dirname(destPath);\n await fs.mkdir(dir, { recursive: true });\n const dataStart = offset + 512;\n const dataEnd = dataStart + size;\n if (dataEnd > buf.length) break; // truncated archive\n await fs.writeFile(destPath, buf.subarray(dataStart, dataEnd));\n }\n }\n\n // Advance: 512-byte header + data padded to 512-byte boundary\n offset += 512 + Math.ceil(size / 512) * 512;\n }\n}\n\nfunction readTarString(buf: Buffer, start: number, maxLen: number): string {\n let end = start;\n while (end < start + maxLen && end < buf.length && buf[end] !== 0) {\n end++;\n }\n return buf.subarray(start, end).toString('utf8');\n}\n\n/**\n * Strip the top-level directory from a tar path.\n * GitHub tarballs have a single root dir like `owner-repo-sha/`.\n */\nfunction stripTopDir(p: string): string {\n const idx = p.indexOf('/');\n if (idx === -1) return ''; // top-level file, skip\n return p.slice(idx + 1);\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { atomicWrite } from '../utils/atomic-write.js';\n\nexport interface InstalledSkillEntry {\n name: string;\n /** Source identifier, e.g. \"github:user/repo\" */\n source: string;\n /** Git ref that was installed (branch, tag, commit) */\n ref: string;\n /** Installation scope */\n scope: 'project' | 'user';\n /** Project hash — only set when scope=project */\n projectHash?: string | undefined;\n /** ISO 8601 timestamp */\n installedAt: string;\n /** List of files that were installed (relative to skill dir) */\n files: string[];\n /**\n * When the install was resolved through a registry (e.g. `skills.sh`), the\n * adapter id + registry id that mapped to the GitHub `source`. Absent for\n * direct `user/repo` installs.\n */\n registryFrom?: { adapterId: string; registryId: string } | undefined;\n}\n\nexport interface ManifestData {\n skills: InstalledSkillEntry[];\n}\n\nexport class SkillManifestStore {\n private readonly manifestPath: string;\n private cache?: ManifestData | undefined;\n\n constructor(manifestPath: string) {\n this.manifestPath = manifestPath;\n }\n\n async read(): Promise<ManifestData> {\n if (this.cache) return this.cache;\n try {\n const raw = await fs.readFile(this.manifestPath, 'utf8');\n const data = JSON.parse(raw) as ManifestData;\n if (!Array.isArray(data.skills)) {\n this.cache = { skills: [] };\n } else {\n this.cache = data;\n }\n } catch {\n this.cache = { skills: [] };\n }\n return this.cache;\n }\n\n async write(data: ManifestData): Promise<void> {\n const dir = path.dirname(this.manifestPath);\n await fs.mkdir(dir, { recursive: true });\n await atomicWrite(this.manifestPath, JSON.stringify(data, null, 2) + '\\n');\n this.cache = data;\n }\n\n async addEntry(entry: InstalledSkillEntry): Promise<void> {\n const data = await this.read();\n // Remove existing entry with the same name + scope\n data.skills = data.skills.filter((s) => !(s.name === entry.name && s.scope === entry.scope));\n data.skills.push(entry);\n await this.write(data);\n }\n\n async removeEntry(name: string, scope: 'project' | 'user'): Promise<boolean> {\n const data = await this.read();\n const before = data.skills.length;\n data.skills = data.skills.filter((s) => !(s.name === name && s.scope === scope));\n if (data.skills.length === before) return false;\n await this.write(data);\n return true;\n }\n\n async findByName(name: string): Promise<InstalledSkillEntry[]> {\n const data = await this.read();\n return data.skills.filter((s) => s.name === name);\n }\n\n async findBySource(source: string): Promise<InstalledSkillEntry[]> {\n const data = await this.read();\n return data.skills.filter((s) => s.source === source);\n }\n\n async listAll(): Promise<InstalledSkillEntry[]> {\n const data = await this.read();\n return data.skills;\n }\n\n /** Invalidate the in-memory cache (e.g. after external file changes). */\n invalidateCache(): void {\n this.cache = undefined;\n }\n}\n","/**\n * GitHub-direct registry adapter.\n *\n * This is the original pre-registry install path wrapped in the adapter\n * interface: the user types `user/repo[@ref]` directly. It does NOT search\n * (GitHub code search is a separate API with its own auth/rate-limit story and\n * isn't a skill catalog), so `search()` returns an empty result. Its job is\n * solely to make `user/repo` flow through the same `<adapterId>:<registryId>`\n * resolution as the skills.sh adapter — except here the \"registry id\" IS the\n * install ref already.\n *\n * Registered as the fallback adapter so `/skill-install user/repo` keeps\n * working unchanged when no `<adapterId>:` prefix is given.\n */\nimport type {\n RegistrySearchOptions,\n RegistrySearchResult,\n SkillRegistryAdapter,\n} from './registry-adapter.js';\n\nexport const githubDirectAdapter: SkillRegistryAdapter = {\n id: 'github',\n displayName: 'GitHub (direct)',\n\n async search(_query: string, _opts: RegistrySearchOptions = {}): Promise<RegistrySearchResult> {\n // GitHub direct is not a searchable catalog. Returning empty keeps the\n // unified `/skill-search` UX (it just shows results from other adapters).\n return { adapterId: 'github', results: [], hasMore: false };\n },\n\n resolveInstallRef(registryId: string): string {\n // For the direct adapter the registry id is already the install ref.\n // Light validation: must contain a slash (owner/repo). Full parsing is done\n // by `parseSkillRef` downstream.\n const trimmed = registryId.trim();\n if (!trimmed.includes('/')) {\n // Defer to parseSkillRef for the structured error message.\n return trimmed;\n }\n return trimmed;\n },\n};\n","/**\n * skills.sh registry adapter.\n *\n * skills.sh is the open agent-skills marketplace (backed by mastra-ai/skills-api)\n * indexing 34k+ skills from 2.8k+ GitHub repos. Every entry is an\n * agentskills.io `SKILL.md` skill whose source repo is known, so resolving a\n * registry hit to a `user/repo@ref` install ref is just a lookup.\n *\n * API shape (https://skills.sh/api/skills):\n * GET /api/skills?query=<q>&page=<p>&pageSize=<ps>&sortBy=installs\n * → { results: Array<{ name, description, owner, repo, ref?, installs?, score?, updatedAt? }> }\n *\n * The base URL is configurable (`config.skills.registryUrl`, user-config only —\n * stripped from in-project config because the parsed response flows into the\n * prompt and a repo-controlled URL would be an SSRF / prompt-injection vector).\n *\n * This adapter is defensive about the response schema: skills.sh is a\n * third-party service and its exact JSON shape has changed before. We parse\n * loosely (missing fields become `undefined`) and throw `ParseError` only when\n * the response isn't the expected shape at all (no `results` array), so a\n * minor additive schema change degrades gracefully instead of crashing the\n * command.\n */\nimport { FetchError, ParseError } from '../../types/errors.js';\nimport type {\n RegistrySearchOptions,\n RegistrySearchResult,\n RegistrySkillSummary,\n SkillRegistryAdapter,\n} from './registry-adapter.js';\n\n/** Default skills.sh base URL. Override via `config.skills.registryUrl`. */\nexport const DEFAULT_SKILLS_SH_URL = 'https://skills.sh';\n\nconst SEARCH_TIMEOUT_MS = 15_000;\nconst MAX_PAGE_SIZE = 50;\n\n/** Injectable fetcher (mirrors the `prompt-installer` JsonFetcher pattern). */\nexport type SkillsShFetcher = (url: string) => Promise<unknown>;\n\nconst defaultFetcher: SkillsShFetcher = async (url) => {\n let res: Response;\n try {\n res = await fetch(url, {\n signal: AbortSignal.timeout(SEARCH_TIMEOUT_MS),\n headers: {\n Accept: 'application/json',\n 'User-Agent': 'wrongstack-skill-installer',\n },\n redirect: 'follow',\n });\n } catch (err) {\n throw new FetchError({\n message: `Network error querying skill registry: ${\n err instanceof Error ? err.message : String(err)\n }`,\n status: 0,\n context: { url, op: 'skills.sh.search' },\n cause: err,\n });\n }\n if (!res.ok) {\n // 429 / 5xx are recoverable; everything else is a hard failure.\n throw new FetchError({\n message: `Skill registry returned ${res.status} ${res.statusText}`,\n status: res.status,\n context: { url, op: 'skills.sh.search' },\n });\n }\n try {\n return await res.json();\n } catch (err) {\n throw new ParseError({\n message: `Skill registry response was not valid JSON: ${\n err instanceof Error ? err.message : String(err)\n }`,\n source: 'skills.sh.search',\n context: { url },\n cause: err,\n });\n }\n};\n\nexport interface SkillsShAdapterOptions {\n /** Base URL (no trailing slash). Defaults to {@link DEFAULT_SKILLS_SH_URL}. */\n baseUrl?: string | undefined;\n /** Injectable fetcher for tests. */\n fetcher?: SkillsShFetcher | undefined;\n}\n\nexport function createSkillsShAdapter(opts: SkillsShAdapterOptions = {}): SkillRegistryAdapter {\n const baseUrl = (opts.baseUrl ?? DEFAULT_SKILLS_SH_URL).replace(/\\/+$/, '');\n const fetcher = opts.fetcher ?? defaultFetcher;\n const id = 'skills.sh';\n\n return {\n id,\n displayName: 'skills.sh',\n\n async search(query: string, sopts: RegistrySearchOptions = {}): Promise<RegistrySearchResult> {\n const page = Math.max(1, sopts.page ?? 1);\n const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, sopts.pageSize ?? 20));\n const q = query.trim();\n if (!q) return { adapterId: id, results: [], hasMore: false };\n\n const url =\n `${baseUrl}/api/skills?query=${encodeURIComponent(q)}` +\n `&page=${page}&pageSize=${pageSize}&sortBy=installs`;\n\n const raw = await fetcher(url);\n const results = parseResults(raw, url);\n\n return {\n adapterId: id,\n results,\n hasMore: results.length === pageSize,\n };\n },\n\n resolveInstallRef(registryId: string): string {\n // skills.sh ids are `<owner>/<repo>` (optionally `@<ref>`). We accept both\n // the bare id and an explicit `@ref` suffix; if a ref isn't given we let\n // the github-fetcher default to `main`.\n const trimmed = registryId.trim();\n if (!trimmed) {\n throw new ParseError({\n message: 'Empty skills.sh registry id.',\n source: 'skills.sh.resolveInstallRef',\n });\n }\n // Validate it looks like owner/repo (with optional @ref).\n const atIdx = trimmed.indexOf('@');\n const repoPart = atIdx > 0 ? trimmed.slice(0, atIdx) : trimmed;\n const segs = repoPart.split('/').filter(Boolean);\n if (segs.length !== 2) {\n throw new ParseError({\n message:\n `Invalid skills.sh id \"${registryId}\". Expected \"<owner>/<repo>\" or ` +\n `\"<owner>/<repo>@<ref>\".`,\n source: 'skills.sh.resolveInstallRef',\n context: { registryId },\n });\n }\n return trimmed;\n },\n };\n}\n\n/**\n * Parse the skills.sh search response into normalized summaries.\n *\n * The schema is parsed defensively: the top-level must be an object with a\n * `results` array (else `ParseError`), but individual entries may miss fields —\n * those become `undefined` on the summary. An entry without a usable\n * `installRef` (`owner` + `repo`) is dropped since the installer can't act on it.\n */\nfunction parseResults(raw: unknown, url: string): RegistrySkillSummary[] {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new ParseError({\n message: 'Skill registry response was not a JSON object.',\n source: 'skills.sh.search',\n context: { url },\n });\n }\n const results = (raw as { results?: unknown }).results;\n if (!Array.isArray(results)) {\n // Some deployments wrap results differently. Treat a missing/Non-array\n // `results` field as an empty result set rather than crashing — the user\n // just sees \"no matches\", which is correct if the schema shifted.\n return [];\n }\n\n const out: RegistrySkillSummary[] = [];\n for (let i = 0; i < results.length; i++) {\n const entry = results[i] as Record<string, unknown> | null;\n if (!entry || typeof entry !== 'object') continue;\n\n const name = strField(entry, 'name') ?? strField(entry, 'slug');\n const description = strField(entry, 'description') ?? '';\n const owner = strField(entry, 'owner') ?? strField(entry, 'author');\n const repo = strField(entry, 'repo') ?? strField(entry, 'repository');\n if (!name || !owner || !repo) continue; // can't build an install ref\n\n const ref = strField(entry, 'ref') ?? strField(entry, 'branch') ?? strField(entry, 'tag');\n const installRef = ref ? `${owner}/${repo}@${ref}` : `${owner}/${repo}`;\n\n out.push({\n id: strField(entry, 'id') ?? `${owner}/${repo}`,\n name,\n description,\n author: owner,\n installs: numField(entry, 'installs') ?? numField(entry, 'installCount'),\n stars: numField(entry, 'stars') ?? numField(entry, 'starCount'),\n securityScore: numField(entry, 'securityScore') ?? numField(entry, 'score'),\n updatedAt: strField(entry, 'updatedAt') ?? strField(entry, 'updated_at'),\n installRef,\n });\n }\n return out;\n}\n\nfunction strField(rec: Record<string, unknown>, key: string): string | undefined {\n const v = rec[key];\n return typeof v === 'string' && v.length > 0 ? v : undefined;\n}\n\nfunction numField(rec: Record<string, unknown>, key: string): number | undefined {\n const v = rec[key];\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n if (typeof v === 'string' && /^\\d+(\\.\\d+)?$/.test(v.trim())) {\n const n = Number(v);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n","/**\n * Skill authoring helpers — deterministic (no LLM) utilities that power the\n * `/skill-gen` sub-commands: validate, skeleton, from-prompt, edit.\n *\n * These are pure functions over the skill loader + filesystem so they're trivial\n * to test and don't need a running agent. The interactive `/skill-gen` wizard\n * (default, no sub-command) still delegates to the `skill-creator` skill via\n * `runText` — that's the right call for the open-ended \"help me write one\"\n * flow. These utilities cover the deterministic parts: name/format checks,\n * scaffold generation, prompt→skill extraction, and opening in `$EDITOR`.\n *\n * Distinct from `security-scanner/skill-generator.ts`, which deterministically\n * generates a *security-scanning* skill from a tech stack — that one builds a\n * specific skill from a fixed pattern library; this one is the general-purpose\n * authoring toolkit.\n */\nimport { spawn } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { ERROR_CODES, WrongStackError } from '../types/errors.js';\nimport type { SkillEntry, SkillLoader } from '../types/skill.js';\nimport { isValidSkillNameFormat, parseSkillFrontmatter, validateSkillName } from './frontmatter.js';\nimport { SKILL_LIMITS } from './limits.js';\n\n/** Result of validating a proposed skill name. */\nexport interface SkillNameValidation {\n /** Whether the name is valid kebab-case AND free of collisions. */\n ok: boolean;\n /** Format violations (empty when the name is valid kebab-case). */\n formatViolations: string[];\n /** Existing skills with the same name (empty when there's no collision). */\n conflicts: SkillEntry[];\n}\n\n/**\n * Validate a proposed skill name: format (kebab-case, ≤64 chars) plus collision\n * check against every skill the loader can see (project, user, foreign,\n * bundled). A collision isn't fatal — project skills intentionally shadow\n * lower layers — so `ok` is true when the only collision is with a foreign or\n * bundled skill (intended shadowing), but `conflicts` is still populated so the\n * user can decide. A collision with another project or user skill of the same\n * name does fail (`ok: false`), since that would silently overwrite it.\n */\nexport async function validateSkillNameAvailable(\n name: string,\n loader?: SkillLoader,\n): Promise<SkillNameValidation> {\n const formatViolations = validateSkillName(name);\n const conflicts = loader ? (await loader.listEntries()).filter((e) => e.name === name) : [];\n const formatOk = formatViolations.length === 0;\n // A collision with a same-or-higher priority layer (project↔project, user↔user)\n // is a real conflict. Collisions with foreign/bundled skills are intended\n // shadowing (project skills win by priority) and don't fail validation.\n const collisionBlocks = conflicts.some((c) => c.source === 'project' || c.source === 'user');\n return {\n ok: formatOk && !collisionBlocks,\n formatViolations,\n conflicts,\n };\n}\n\nexport interface SkillSkeletonOptions {\n name: string;\n description: string;\n /** Trigger keywords for the `Triggers:` line. */\n triggerKeywords?: string[] | undefined;\n /** Optional version (default `1.0.0`). */\n version?: string | undefined;\n}\n\n/**\n * Generate a SKILL.md body (with frontmatter) following the agentskills.io\n * format and the `skill-creator` skill's recommended skeleton. Deterministic:\n * the same inputs always produce the same output, and the result round-trips\n * through `parseSkillFrontmatter` (so what we write is what the loader reads).\n *\n * The body is a skeleton — the user fills in Rules/Patterns/etc. The\n * `skill-creator` skill is the right tool for the open-ended authoring; this\n * is the scaffold.\n */\nexport function generateSkillSkeleton(opts: SkillSkeletonOptions): string {\n const name = opts.name.trim();\n if (!isValidSkillNameFormat(name)) {\n throw new WrongStackError({\n message: `Cannot generate skeleton: invalid skill name \"${name}\". Names must be kebab-case (a-z0-9 and hyphens), ≤64 chars.`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { name },\n });\n }\n const description = opts.description.trim();\n const triggers = (opts.triggerKeywords ?? [])\n .map((k) => k.trim())\n .filter(Boolean)\n .map((k) => `\"${k}\"`)\n .join(', ');\n const triggerLine = triggers ? `\\n Triggers: user says ${triggers}.` : '';\n const version = opts.version?.trim() || '1.0.0';\n const title = name\n .split('-')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n\n return `---\nname: ${name}\ndescription: |\n ${description || `Use this skill when <trigger situation>.`}${triggerLine}\nversion: ${version}\n---\n\n# ${title}\n\n## Overview\n\n${description || 'One-line description of what this skill does.'}\n\n## Rules\n\n1. Rule one\n2. Rule two\n\n## Patterns\n\n### Do\n\n\\`\\`\\`ts\n// good example\n\\`\\`\\`\n\n### Don't\n\n\\`\\`\\`ts\n// bad example\n\\`\\`\\`\n\n## Skills in scope\n\n- \\`other-skill\\` — for delegation when this skill needs help\n`;\n}\n\n/** Result of extracting a skill draft from a free-form prompt. */\nexport interface ExtractedSkillDraft {\n /** Suggested name (kebab-case) derived from the prompt, or empty. */\n suggestedName: string;\n /** Description (first paragraph of the prompt). */\n description: string;\n /** Remaining prompt text, used as the skill body. */\n body: string;\n /** Trigger keywords extracted from the prompt. */\n triggerKeywords: string[];\n}\n\n/**\n * Heuristically extract a skill draft from a free-form prompt. No LLM — just\n * light structure detection:\n * - First non-empty paragraph → `description`.\n * - A `# heading` or the first line → suggested kebab-case `suggestedName`.\n * - Remaining text → `body`.\n * - Quoted tokens and the heading words → `triggerKeywords`.\n *\n * The output is a starting point the user (or the skill-creator wizard) refines.\n */\nexport function extractSkillFromPrompt(prompt: string): ExtractedSkillDraft {\n const text = prompt.trim();\n if (!text) {\n return { suggestedName: '', description: '', body: '', triggerKeywords: [] };\n }\n\n // Detect a markdown heading as the title; fall back to the first line.\n const headingMatch = text.match(/^#{1,6}\\s+(.+?)\\s*$/m);\n const firstLine =\n text\n .split('\\n')\n .find((l) => l.trim().length > 0)\n ?.trim() ?? text;\n const titleSource = headingMatch?.[1] ?? firstLine.replace(/^#+\\s*/, '');\n const suggestedName = toKebab(titleSource).slice(0, SKILL_LIMITS.SKILL_NAME_MAX_LEN);\n\n // Split into paragraphs (blocks separated by blank lines).\n const paragraphs = text\n .split(/\\n\\s*\\n/)\n .map((p) => p.trim())\n .filter(Boolean);\n const description = paragraphs[0]?.replace(/^#{1,6}\\s+/m, '').trim() ?? titleSource;\n const body = paragraphs.slice(1).join('\\n\\n');\n\n // Trigger keywords: quoted tokens (\"...\"), plus a few significant words from\n // the title (lowercased, >3 chars, not stopwords).\n const quoted = [...text.matchAll(/\"([^\"]{2,40})\"/g)]\n .map((m) => m[1])\n .filter((q): q is string => typeof q === 'string')\n .map((q) => q.toLowerCase());\n const titleWords = titleSource\n .split(/\\W+/)\n .map((w) => w.toLowerCase())\n .filter((w) => w.length > 3 && !STOPWORDS.has(w));\n const triggerKeywords = dedupe([...quoted, ...titleWords]).slice(0, 8);\n\n return { suggestedName, description, body, triggerKeywords };\n}\n\n/**\n * Open a file in the user's editor (`$VISUAL` → `$EDITOR` → platform default).\n * Detached + unref'd so the editor outlives the WrongStack process. Throws a\n * `WrongStackError` when no editor can be resolved.\n */\nexport async function openInEditor(\n filePath: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const editor =\n (env['VISUAL']?.trim() && env['VISUAL']) ||\n (env['EDITOR']?.trim() && env['EDITOR']) ||\n defaultEditor();\n if (!editor) {\n throw new WrongStackError({\n message:\n 'No editor found. Set the EDITOR or VISUAL environment variable ' +\n '(e.g. `export EDITOR=code` or `export EDITOR=vim`).',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { filePath },\n });\n }\n const shell = process.platform === 'win32';\n // Split editor into command + args (e.g. `code --wait`). The file path is\n // appended last so it works whether the editor is a single binary or a\n // command-with-flags string.\n const parts = editor.split(/\\s+/).filter(Boolean);\n if (parts.length === 0) {\n throw new WrongStackError({\n message: 'Resolved editor command is empty.',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { filePath },\n });\n }\n const child = spawn(parts[0] as string, [...parts.slice(1), filePath], {\n stdio: 'ignore',\n detached: true,\n shell,\n });\n child.unref();\n}\n\n/**\n * Write a skeleton skill to `<skillsDir>/<name>/SKILL.md`. Returns the written\n * path. Used by `/skill-gen skeleton` and `/skill-gen from-prompt`. Refuses to\n * overwrite an existing SKILL.md unless `overwrite` is set — a guard against\n * clobbering a hand-edited skill.\n */\nexport async function writeSkeletonSkill(\n skillsDir: string,\n body: string,\n opts: { overwrite?: boolean | undefined } = {},\n): Promise<string> {\n // Parse the frontmatter to find the name (so the dir matches the skill name).\n const fm = parseSkillFrontmatter(body);\n const name = fm.name;\n if (!name || !isValidSkillNameFormat(name)) {\n throw new WrongStackError({\n message: 'Skeleton body has no valid `name` in its frontmatter.',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n });\n }\n const skillDir = path.join(skillsDir, name);\n const skillFile = path.join(skillDir, 'SKILL.md');\n if (!opts.overwrite) {\n try {\n await fs.access(skillFile);\n throw new WrongStackError({\n message: `A skill already exists at ${skillFile}. Use --force to overwrite.`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { skillFile },\n });\n } catch (err) {\n // re-throw the WrongStackError from above; swallow ENOENT (file absent).\n if (err instanceof WrongStackError) throw err;\n }\n }\n await fs.mkdir(skillDir, { recursive: true });\n await fs.writeFile(skillFile, body, 'utf8');\n return skillFile;\n}\n\n/** Soft length advisory for a SKILL.md body (the `skill-creator` 500-line rule). */\nexport function bodyLineAdvisory(body: string): { lines: number; over: boolean } {\n const lines = body.split('\\n').length;\n return { lines, over: lines > SKILL_LIMITS.SKILL_BODY_LINE_LIMIT };\n}\n\n// ── Utilities ─────────────────────────────────────────────────────────────\n\nconst STOPWORDS = new Set([\n 'the',\n 'and',\n 'for',\n 'with',\n 'that',\n 'this',\n 'from',\n 'your',\n 'have',\n 'will',\n 'are',\n 'was',\n 'were',\n 'been',\n 'into',\n 'when',\n 'use',\n 'skill',\n 'about',\n]);\n\nfunction toKebab(s: string): string {\n return (\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, SKILL_LIMITS.SKILL_NAME_MAX_LEN) || 'skill'\n );\n}\n\nfunction dedupe<T>(arr: T[]): T[] {\n return [...new Set(arr)];\n}\n\nfunction defaultEditor(): string | undefined {\n if (process.platform === 'win32') return 'notepad';\n if (process.platform === 'darwin') return 'open';\n return undefined; // linux: require explicit EDITOR/VISUAL\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { ERROR_CODES, FsError, WrongStackError } from '../types/errors.js';\nimport type { SkillLoader } from '../types/skill.js';\nimport { toErrorMessage } from '../utils/error.js';\nimport { expectDefined } from '../utils/expect-defined.js';\nimport { isValidSkillNameFormat, parseSkillFrontmatter } from './frontmatter.js';\nimport { downloadGitHubTarball, parseSkillRef } from './github-fetcher.js';\nimport { SKILL_LIMITS } from './limits.js';\nimport { type InstalledSkillEntry, SkillManifestStore } from './manifest-store.js';\nimport { githubDirectAdapter } from './registry/github-direct-adapter.js';\nimport type {\n RegistrySearchOptions,\n RegistrySearchResult,\n RegistrySkillSummary,\n SkillRegistryAdapter,\n} from './registry/registry-adapter.js';\nexport interface SkillInstallerOptions {\n /** Path to the manifest file (~/.wrongstack/installed-skills.json) */\n manifestPath: string;\n /** Path to project-level skills dir (<project>/.wrongstack/skills/) */\n projectSkillsDir: string;\n /** Path to user-global skills dir (~/.wrongstack/skills/) */\n globalSkillsDir: string;\n /** Current project hash (for manifest tracking) */\n projectHash: string;\n /** Skill loader — cache will be invalidated after mutations */\n skillLoader?: SkillLoader | undefined;\n /** Logger for status messages */\n log?: ((msg: string) => void) | undefined;\n /**\n * Skill registries used to resolve `<adapterId>:<registryId>` refs and to\n * serve `/skill-search`. Defaults to `[githubDirectAdapter]` (the original\n * direct `user/repo` install path). Add a skills.sh adapter to enable\n * searching the marketplace and installing registry hits by id.\n */\n registryAdapters?: SkillRegistryAdapter[] | undefined;\n}\n\nexport interface InstallResult {\n name: string;\n path: string;\n scope: 'project' | 'user';\n source: string;\n ref: string;\n skillCount: number;\n}\n\nexport interface UpdateResult {\n updated: Array<{ name: string; oldRef: string; newRef: string }>;\n unchanged: string[];\n errors: Array<{ name: string; error: string }>;\n}\n\nconst MAX_SKILL_FILE_SIZE = SKILL_LIMITS.MAX_SKILL_FILE_SIZE;\n\nexport class SkillInstaller {\n private readonly opts: SkillInstallerOptions;\n private readonly manifest: SkillManifestStore;\n private readonly adapters: SkillRegistryAdapter[];\n\n constructor(opts: SkillInstallerOptions) {\n this.opts = opts;\n this.manifest = new SkillManifestStore(opts.manifestPath);\n this.adapters = opts.registryAdapters?.length ? opts.registryAdapters : [githubDirectAdapter];\n }\n\n /**\n * Install skills from a skill reference.\n *\n * Accepts two ref formats:\n * - `user/repo[@ref]` — direct GitHub install (original path)\n * - `<adapterId>:<registryId>` — registry-resolved (e.g.\n * `skills.sh:owner/repo@v1`); the\n * adapter resolves it to a `user/repo`\n * ref and the install proceeds as above.\n *\n * Supports both single-skill repos (SKILL.md at root) and multi-skill repos\n * (skills/ subdirectory). The manifest records the GitHub source as\n * `github:owner/repo` (so `/skill-update` keeps working) plus the originating\n * registry in `registryFrom` when the install came through a registry.\n */\n async install(\n refInput: string,\n opts?: { global?: boolean | undefined },\n ): Promise<InstallResult[]> {\n const resolved = this.resolveRef(refInput);\n const parsed = parseSkillRef(resolved.installRef);\n const scope: 'project' | 'user' = opts?.global ? 'user' : 'project';\n const targetDir = scope === 'project' ? this.opts.projectSkillsDir : this.opts.globalSkillsDir;\n const source = `github:${parsed.owner}/${parsed.repo}`;\n\n this.opts.log?.(\n resolved.fromRegistry\n ? `Resolving ${refInput} → ${resolved.installRef} (${resolved.adapterId}), downloading...`\n : `Downloading ${parsed.owner}/${parsed.repo}@${parsed.ref}...`,\n );\n\n const { tempDir } = await downloadGitHubTarball(parsed);\n\n try {\n // Detect skill structure\n const skills = await this.detectSkills(tempDir);\n\n if (skills.length === 0) {\n throw new WrongStackError({\n message:\n 'No skills found in repository. Expected SKILL.md at root or skills/ subdirectory.',\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { owner: parsed.owner, repo: parsed.repo, ref: parsed.ref },\n });\n }\n\n const results: InstallResult[] = [];\n\n for (const skill of skills) {\n // Check for overwrite\n const existing = await this.manifest.findByName(skill.name);\n const existingInScope = existing.find((e) => e.scope === scope);\n if (existingInScope) {\n this.opts.log?.(`Overwriting existing skill \"${skill.name}\" (${scope})...`);\n await this.removeSkillFiles(skill.name, scope);\n }\n\n // Copy skill files\n const destDir = path.join(targetDir, skill.name);\n await fs.mkdir(destDir, { recursive: true });\n const copiedFiles: string[] = [];\n\n for (const file of skill.files) {\n const srcPath = path.join(skill.baseDir, file);\n const destPath = path.join(destDir, file);\n\n // Path traversal check\n const resolved = path.resolve(destPath);\n if (!resolved.startsWith(path.resolve(destDir))) {\n throw new FsError({\n message: `Path traversal detected in skill file: ${file}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: destPath,\n context: { reason: 'path_traversal', skillName: skill.name },\n });\n }\n\n // Size check\n const stat = await fs.stat(srcPath);\n if (stat.size > MAX_SKILL_FILE_SIZE) {\n throw new FsError({\n message:\n `Skill file \"${file}\" is too large (${(stat.size / 1024).toFixed(1)}KB). ` +\n `Max: ${MAX_SKILL_FILE_SIZE / 1024}KB`,\n code: ERROR_CODES.FS_WRITE_FAILED,\n path: srcPath,\n context: { skillName: skill.name, fileSize: stat.size, maxSize: MAX_SKILL_FILE_SIZE },\n });\n }\n\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n await fs.copyFile(srcPath, destPath);\n copiedFiles.push(file);\n }\n\n // Write manifest entry\n const entry: InstalledSkillEntry = {\n name: skill.name,\n source,\n ref: parsed.ref,\n scope,\n projectHash: scope === 'project' ? this.opts.projectHash : undefined,\n installedAt: new Date().toISOString(),\n files: copiedFiles,\n // When the install came through a registry (e.g. skills.sh), record\n // which adapter + registry id resolved to this GitHub repo, so the\n // source is traceable. `source` stays `github:owner/repo` for\n // backward compat with `/skill-update`.\n ...(resolved.fromRegistry\n ? { registryFrom: { adapterId: resolved.adapterId, registryId: resolved.registryId } }\n : {}),\n };\n await this.manifest.addEntry(entry);\n\n results.push({\n name: skill.name,\n path: destDir,\n scope,\n source,\n ref: parsed.ref,\n skillCount: 1,\n });\n }\n\n this.invalidateLoaderCache();\n return results;\n } finally {\n // Clean up temp directory\n await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});\n }\n }\n\n /**\n * Import skills from a local directory (e.g. `.claude/skills`) into the\n * project or user skills dir, optionally as symlinks. Used by `/skill-import`\n * to take ownership of foreign skills so they can be edited/committed.\n * Each direct subdirectory containing a valid `SKILL.md` is copied verbatim.\n */\n async importFromDir(\n srcDir: string,\n opts?: { global?: boolean | undefined; link?: boolean | undefined },\n ): Promise<InstallResult[]> {\n const scope: 'project' | 'user' = opts?.global ? 'user' : 'project';\n const targetDir = scope === 'project' ? this.opts.projectSkillsDir : this.opts.globalSkillsDir;\n let entries: import('node:fs').Dirent[];\n try {\n entries = await fs.readdir(srcDir, { withFileTypes: true });\n } catch {\n throw new WrongStackError({\n message: `Source directory not found or not readable: ${srcDir}`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { srcDir },\n });\n }\n\n const results: InstallResult[] = [];\n for (const e of entries) {\n if (!(await entryIsDirectory(srcDir, e))) continue;\n const skillMdPath = path.join(srcDir, e.name, 'SKILL.md');\n let content: string;\n try {\n content = await fs.readFile(skillMdPath, 'utf8');\n } catch {\n continue; // subdirectory without a SKILL.md — not a skill\n }\n const fm = parseSkillFrontmatter(content);\n if (!fm.name || !fm.description || !isValidSkillNameFormat(fm.name)) continue;\n\n const existing = await this.manifest.findByName(fm.name);\n if (existing.find((x) => x.scope === scope)) {\n await this.removeSkillFiles(fm.name, scope);\n }\n\n const destDir = path.join(targetDir, fm.name);\n await fs.mkdir(destDir, { recursive: true });\n const srcSkillDir = path.join(srcDir, e.name);\n const files = await collectFiles(srcSkillDir, srcSkillDir);\n const copiedFiles: string[] = [];\n for (const file of files) {\n const srcPath = path.join(srcSkillDir, file);\n const destPath = path.join(destDir, file);\n const resolved = path.resolve(destPath);\n if (!resolved.startsWith(path.resolve(destDir))) {\n throw new FsError({\n message: `Path traversal detected in skill file: ${file}`,\n code: ERROR_CODES.FS_DELETE_FAILED,\n path: destPath,\n context: { reason: 'path_traversal', skillName: fm.name },\n });\n }\n await fs.mkdir(path.dirname(destPath), { recursive: true });\n if (opts?.link) {\n try {\n await fs.symlink(srcPath, destPath);\n } catch (err) {\n // Symlink unavailable (e.g. Windows without Developer Mode) — copy.\n await fs.copyFile(srcPath, destPath);\n this.opts.log?.(`symlink failed for ${file} (${toErrorMessage(err)}); copied instead`);\n }\n } else {\n await fs.copyFile(srcPath, destPath);\n }\n copiedFiles.push(file);\n }\n\n await this.manifest.addEntry({\n name: fm.name,\n source: `import:${srcDir}`,\n ref: '-',\n scope,\n projectHash: scope === 'project' ? this.opts.projectHash : undefined,\n installedAt: new Date().toISOString(),\n files: copiedFiles,\n });\n results.push({\n name: fm.name,\n path: destDir,\n scope,\n source: `import:${srcDir}`,\n ref: '-',\n skillCount: 1,\n });\n }\n\n this.invalidateLoaderCache();\n return results;\n }\n\n /**\n * Update installed skills.\n * - No args: update all\n * - Name: update that specific skill\n * - Name + newRef: update to a different ref\n */\n async update(\n nameOrRef?: string | undefined,\n _opts?: { global?: boolean | undefined } | undefined,\n ): Promise<UpdateResult> {\n const result: UpdateResult = { updated: [], unchanged: [], errors: [] };\n const allEntries = await this.manifest.listAll();\n\n let targets: InstalledSkillEntry[];\n if (nameOrRef) {\n // Check if it's a name or a ref (user/repo@ref)\n const byName = allEntries.filter((e) => e.name === nameOrRef);\n if (byName.length > 0) {\n targets = byName;\n } else {\n // Treat as a new ref — find matching source\n try {\n const parsed = parseSkillRef(nameOrRef);\n const source = `github:${parsed.owner}/${parsed.repo}`;\n targets = allEntries.filter((e) => e.source === source);\n if (targets.length === 0) {\n result.errors.push({\n name: nameOrRef,\n error: `No installed skills found matching \"${nameOrRef}\"`,\n });\n return result;\n }\n } catch {\n result.errors.push({\n name: nameOrRef,\n error: `Invalid reference: ${nameOrRef}`,\n });\n return result;\n }\n }\n } else {\n targets = allEntries;\n }\n\n // Group by source to avoid downloading the same repo multiple times\n const bySource = new Map<string, InstalledSkillEntry[]>();\n for (const entry of targets) {\n const key = `${entry.source}@${entry.ref}`;\n if (!bySource.has(key)) bySource.set(key, []);\n bySource.get(key)?.push(entry);\n }\n\n for (const [, entries] of bySource) {\n const first = expectDefined(entries[0]);\n const scope = first.scope;\n const isGlobal = scope === 'user';\n\n try {\n // Parse the original source to get the ref\n const sourceRepo = first.source.replace('github:', '');\n let refToInstall = first.ref;\n\n // If nameOrRef looks like a new ref, use it\n if (nameOrRef && !allEntries.find((e) => e.name === nameOrRef)) {\n try {\n const parsed = parseSkillRef(nameOrRef);\n refToInstall = parsed.ref;\n } catch {\n // keep original ref\n }\n }\n\n this.opts.log?.(`Updating ${first.source}@${refToInstall}...`);\n const results = await this.install(`${sourceRepo}@${refToInstall}`, { global: isGlobal });\n\n for (const r of results) {\n result.updated.push({\n name: r.name,\n oldRef: first.ref,\n newRef: refToInstall,\n });\n }\n } catch (err) {\n const msg = toErrorMessage(err);\n for (const entry of entries) {\n result.errors.push({ name: entry.name, error: msg });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Uninstall a skill by name.\n */\n async uninstall(name: string, opts?: { global?: boolean | undefined }): Promise<void> {\n const scope: 'project' | 'user' = opts?.global ? 'user' : 'project';\n const entries = await this.manifest.findByName(name);\n const entry = entries.find((e) => e.scope === scope);\n\n if (!entry) {\n throw new WrongStackError({\n message: `Skill \"${name}\" is not installed${scope === 'user' ? ' (global)' : ''}.`,\n code: ERROR_CODES.VALIDATION_ERROR,\n subsystem: 'general',\n context: { skillName: name, scope },\n });\n }\n\n // Remove files\n await this.removeSkillFiles(name, scope);\n\n // Remove from manifest\n await this.manifest.removeEntry(name, scope);\n this.invalidateLoaderCache();\n }\n\n /**\n * List all installed skills from the manifest.\n */\n async listInstalled(): Promise<InstalledSkillEntry[]> {\n return this.manifest.listAll();\n }\n\n /**\n * Search across all configured registry adapters. Results from each adapter\n * are merged (deduplicated by `installRef`, adapters earlier in the list win\n * conflicts). Adapters that don't support search (e.g. github-direct)\n * contribute nothing.\n */\n async search(query: string, opts?: RegistrySearchOptions): Promise<RegistrySearchResult[]> {\n const settled = await Promise.allSettled(this.adapters.map((a) => a.search(query, opts)));\n const perAdapter: RegistrySearchResult[] = [];\n const errors: string[] = [];\n settled.forEach((s, i) => {\n if (s.status === 'fulfilled') perAdapter.push(s.value);\n else {\n const id = this.adapters[i]?.id ?? '?';\n errors.push(`${id}: ${toErrorMessage(s.reason)}`);\n }\n });\n // Surface adapter errors via the log so a single broken registry doesn't\n // silently hide results — but don't throw, since other adapters may have\n // returned useful results.\n if (errors.length > 0) {\n this.opts.log?.(`Some registries failed during search: ${errors.join('; ')}`);\n }\n return dedupeSearchResults(perAdapter);\n }\n\n // ── Private helpers ──────────────────────────────────────────────\n\n /**\n * Detect skills in an extracted repository.\n * Returns an array of detected skills with their files.\n */\n private async detectSkills(\n baseDir: string,\n ): Promise<Array<{ name: string; baseDir: string; files: string[] }>> {\n const results: Array<{ name: string; baseDir: string; files: string[] }> = [];\n\n // Check for SKILL.md at root (single-skill repo)\n const rootSkillMd = path.join(baseDir, 'SKILL.md');\n try {\n await fs.access(rootSkillMd);\n const content = await fs.readFile(rootSkillMd, 'utf8');\n const fm = parseSkillFrontmatter(content);\n if (fm.name && fm.description && isValidSkillNameFormat(fm.name)) {\n results.push({\n name: fm.name,\n baseDir,\n files: ['SKILL.md'],\n });\n return results; // Single-skill repo — don't look for skills/\n }\n } catch {\n // No root SKILL.md\n }\n\n // Check for skills/ subdirectory (multi-skill repo)\n const skillsDir = path.join(baseDir, 'skills');\n try {\n const entries = await fs.readdir(skillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const skillFile = path.join(skillsDir, entry.name, 'SKILL.md');\n try {\n const content = await fs.readFile(skillFile, 'utf8');\n const fm = parseSkillFrontmatter(content);\n if (fm.name && fm.description && isValidSkillNameFormat(fm.name)) {\n // Collect all files in the skill directory\n const skillDir = path.join(skillsDir, entry.name);\n const files = await collectFiles(skillDir, skillDir);\n results.push({\n name: fm.name,\n baseDir: skillDir,\n files,\n });\n }\n } catch {\n // Skip malformed skills\n }\n }\n } catch {\n // No skills/ directory\n }\n\n return results;\n }\n\n /**\n * Remove all files for an installed skill.\n */\n private async removeSkillFiles(name: string, scope: 'project' | 'user'): Promise<void> {\n const targetDir = scope === 'project' ? this.opts.projectSkillsDir : this.opts.globalSkillsDir;\n const skillDir = path.join(targetDir, name);\n await fs.rm(skillDir, { recursive: true, force: true });\n }\n\n /**\n * Invalidate the skill loader's cache so newly installed skills appear.\n */\n private invalidateLoaderCache(): void {\n // The SkillLoader interface has a cache internally.\n // We access it via the 'any' cast to call invalidateCache if available.\n const loader = this.opts.skillLoader as never as { invalidateCache?: () => void };\n if (loader && typeof loader.invalidateCache === 'function') {\n loader.invalidateCache();\n }\n }\n\n /**\n * Resolve an install ref, dispatching registry-prefixed refs to the matching\n * adapter. Returns the concrete `user/repo[@ref]` install ref plus provenance\n * (which adapter resolved it, if any).\n */\n private resolveRef(refInput: string): {\n installRef: string;\n fromRegistry: boolean;\n adapterId: string;\n registryId: string;\n } {\n const trimmed = refInput.trim();\n const colonIdx = trimmed.indexOf(':');\n // A colon prefix matches `<adapterId>:<registryId>`. We require the segment\n // before the colon to be a known adapter id so plain `user/repo` refs (and\n // Windows-style `C:\\...` paths that should never reach here) aren't\n // misread as registry refs.\n if (colonIdx > 0) {\n const maybeAdapterId = trimmed.slice(0, colonIdx);\n const adapter = this.adapters.find((a) => a.id === maybeAdapterId);\n if (adapter) {\n const registryId = trimmed.slice(colonIdx + 1);\n const installRef = adapter.resolveInstallRef(registryId);\n return { installRef, fromRegistry: true, adapterId: adapter.id, registryId };\n }\n }\n return { installRef: trimmed, fromRegistry: false, adapterId: '', registryId: '' };\n }\n}\n\n// ── Utilities ──────────────────────────────────────────────────────\n\n/**\n * True if `entry` is a directory, following symlinks (Claude Code/agents\n * symlink skill dirs — see DefaultSkillLoader.entryIsDirectory).\n */\nasync function entryIsDirectory(dir: string, entry: import('node:fs').Dirent): Promise<boolean> {\n if (entry.isDirectory()) return true;\n if (entry.isSymbolicLink()) {\n try {\n return (await fs.stat(path.join(dir, entry.name))).isDirectory();\n } catch {\n return false; // broken symlink\n }\n }\n return false;\n}\n\n/**\n * Recursively collect all files in a directory (relative paths).\n */\nasync function collectFiles(dir: string, baseDir: string): Promise<string[]> {\n const results: string[] = [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n const relPath = path.relative(baseDir, fullPath);\n if (entry.isDirectory()) {\n // Skip hidden dirs and node_modules\n if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;\n results.push(...(await collectFiles(fullPath, baseDir)));\n } else {\n results.push(relPath);\n }\n }\n return results;\n}\n\n/**\n * Merge per-adapter search results, deduplicating by `installRef`.\n *\n * Two adapters may index the same GitHub repo (e.g. skills.sh and a future\n * internal hub both list `obra/superpowers`). When they do, the first adapter\n * in the configured order wins — its metadata (security score, install count)\n * is the one shown, and the dedup key is the concrete `user/repo[@ref]` so a\n * ref difference still surfaces both. Per-adapter result boundaries are\n * preserved (the caller renders them grouped by adapter).\n */\nfunction dedupeSearchResults(perAdapter: RegistrySearchResult[]): RegistrySearchResult[] {\n const seen = new Set<string>();\n const out: RegistrySearchResult[] = [];\n for (const block of perAdapter) {\n const kept: RegistrySkillSummary[] = [];\n for (const r of block.results) {\n const key = r.installRef;\n if (seen.has(key)) continue;\n seen.add(key);\n kept.push(r);\n }\n if (kept.length > 0 || block.results.length > 0) {\n out.push({ ...block, results: kept });\n }\n }\n return out;\n}\n"]}