@limrun/cli
Advanced tools
| export declare const DEFAULT_SKILLS_OWNER = "limrun-inc"; | ||
| export declare const DEFAULT_SKILLS_REPO = "skills"; | ||
| export declare const DEFAULT_SKILLS_REF = "main"; | ||
| export interface RemoteSkill { | ||
| name: string; | ||
| description: string; | ||
| defaultSelected: boolean; | ||
| sourceDir: string; | ||
| } | ||
| export interface LoadedRemoteSkills { | ||
| owner: string; | ||
| repo: string; | ||
| ref: string; | ||
| commit: string; | ||
| rootDir: string; | ||
| skillsRoot: string; | ||
| skills: RemoteSkill[]; | ||
| cleanup(): void; | ||
| } | ||
| export interface LoadRemoteSkillsOptions { | ||
| owner?: string; | ||
| repo?: string; | ||
| ref?: string; | ||
| cloneImpl?: (owner: string, repo: string, ref: string) => Promise<ClonedSkillsRepo>; | ||
| } | ||
| export declare class RemoteSkillsError extends Error { | ||
| constructor(message: string); | ||
| } | ||
| export interface ClonedSkillsRepo { | ||
| rootDir: string; | ||
| commit: string; | ||
| } | ||
| declare function cleanupSkillsTempDir(rootDir: string): void; | ||
| declare function loadSkillsFromCheckout(params: { | ||
| owner: string; | ||
| repo: string; | ||
| ref: string; | ||
| commit: string; | ||
| rootDir: string; | ||
| }): LoadedRemoteSkills; | ||
| export declare function loadRemoteSkills(options?: LoadRemoteSkillsOptions): Promise<LoadedRemoteSkills>; | ||
| export declare const __remoteSkillsTestUtils: { | ||
| cleanupSkillsTempDir: typeof cleanupSkillsTempDir; | ||
| loadSkillsFromCheckout: typeof loadSkillsFromCheckout; | ||
| }; | ||
| export {}; | ||
| //# sourceMappingURL=remote-skills.d.ts.map |
| {"version":3,"file":"remote-skills.d.ts","sourceRoot":"","sources":["../../src/lib/remote-skills.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,oBAAoB,eAAe,CAAC;AACjD,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAC5C,eAAO,MAAM,kBAAkB,SAAS,CAAC;AAkBzC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACrF;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAoBD,iBAAS,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAOnD;AA0ID,iBAAS,sBAAsB,CAAC,MAAM,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,kBAAkB,CA+CrB;AAED,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkBzG;AAED,eAAO,MAAM,uBAAuB;;;CAGnC,CAAC"} |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.__remoteSkillsTestUtils = exports.RemoteSkillsError = exports.DEFAULT_SKILLS_REF = exports.DEFAULT_SKILLS_REPO = exports.DEFAULT_SKILLS_OWNER = void 0; | ||
| exports.loadRemoteSkills = loadRemoteSkills; | ||
| const fs_1 = __importDefault(require("fs")); | ||
| const os_1 = __importDefault(require("os")); | ||
| const path_1 = __importDefault(require("path")); | ||
| const child_process_1 = require("child_process"); | ||
| const util_1 = require("util"); | ||
| const yaml = require('js-yaml'); | ||
| exports.DEFAULT_SKILLS_OWNER = 'limrun-inc'; | ||
| exports.DEFAULT_SKILLS_REPO = 'skills'; | ||
| exports.DEFAULT_SKILLS_REF = 'main'; | ||
| const DEFAULT_CLONE_TIMEOUT_MS = 300000; | ||
| const CLONE_TIMEOUT_MS = (() => { | ||
| const raw = process.env['LIM_SKILLS_CLONE_TIMEOUT_MS']; | ||
| if (!raw) | ||
| return DEFAULT_CLONE_TIMEOUT_MS; | ||
| const parsed = Number.parseInt(raw, 10); | ||
| return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_CLONE_TIMEOUT_MS; | ||
| })(); | ||
| const execFileAsync = (0, util_1.promisify)(child_process_1.execFile); | ||
| class RemoteSkillsError extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = 'RemoteSkillsError'; | ||
| } | ||
| } | ||
| exports.RemoteSkillsError = RemoteSkillsError; | ||
| function assertString(value, label) { | ||
| if (typeof value !== 'string' || value.trim() === '') { | ||
| throw new RemoteSkillsError(`${label} must be a non-empty string`); | ||
| } | ||
| } | ||
| function isPathInside(basePath, targetPath) { | ||
| const normalizedBase = path_1.default.normalize(path_1.default.resolve(basePath)); | ||
| const normalizedTarget = path_1.default.normalize(path_1.default.resolve(targetPath)); | ||
| return normalizedTarget === normalizedBase || normalizedTarget.startsWith(normalizedBase + path_1.default.sep); | ||
| } | ||
| function assertSafeSkillName(value, label) { | ||
| if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value)) { | ||
| throw new RemoteSkillsError(`${label} must be a lowercase hyphenated skill name`); | ||
| } | ||
| } | ||
| function cleanupSkillsTempDir(rootDir) { | ||
| const tmpRoot = os_1.default.tmpdir(); | ||
| if (!isPathInside(tmpRoot, rootDir) || path_1.default.resolve(rootDir) === path_1.default.resolve(tmpRoot)) { | ||
| throw new RemoteSkillsError(`Refusing to clean up non-temporary skills directory: ${rootDir}`); | ||
| } | ||
| fs_1.default.rmSync(rootDir, { recursive: true, force: true }); | ||
| } | ||
| function parseCatalog(text) { | ||
| let catalog; | ||
| try { | ||
| catalog = JSON.parse(text); | ||
| } | ||
| catch (err) { | ||
| throw new RemoteSkillsError(`catalog.json is invalid JSON: ${err instanceof Error ? err.message : String(err)}`); | ||
| } | ||
| if (!catalog || typeof catalog !== 'object' || Array.isArray(catalog)) { | ||
| throw new RemoteSkillsError('catalog.json must be an object'); | ||
| } | ||
| const parsed = catalog; | ||
| if (parsed.schemaVersion !== 1) { | ||
| throw new RemoteSkillsError('catalog.json schemaVersion must be 1'); | ||
| } | ||
| if (!Array.isArray(parsed.skills)) { | ||
| throw new RemoteSkillsError('catalog.json skills must be an array'); | ||
| } | ||
| for (const [index, skill] of parsed.skills.entries()) { | ||
| if (!skill || typeof skill !== 'object' || Array.isArray(skill)) { | ||
| throw new RemoteSkillsError(`catalog.json skills[${index}] must be an object`); | ||
| } | ||
| assertString(skill.name, `catalog.json skills[${index}].name`); | ||
| assertSafeSkillName(skill.name, `catalog.json skills[${index}].name`); | ||
| if (typeof skill.defaultSelected !== 'boolean') { | ||
| throw new RemoteSkillsError(`catalog.json skills[${index}].defaultSelected must be a boolean`); | ||
| } | ||
| } | ||
| return parsed; | ||
| } | ||
| function parseSkillFrontmatter(skillName, text) { | ||
| const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n/); | ||
| if (!match) { | ||
| throw new RemoteSkillsError(`skills/${skillName}/SKILL.md is missing YAML frontmatter`); | ||
| } | ||
| const frontmatterText = match[1]; | ||
| if (frontmatterText === undefined) { | ||
| throw new RemoteSkillsError(`skills/${skillName}/SKILL.md is missing YAML frontmatter`); | ||
| } | ||
| let frontmatter; | ||
| try { | ||
| frontmatter = yaml.load(frontmatterText); | ||
| } | ||
| catch (err) { | ||
| throw new RemoteSkillsError(`skills/${skillName}/SKILL.md has invalid YAML frontmatter: ${err instanceof Error ? err.message : String(err)}`); | ||
| } | ||
| if (!frontmatter || typeof frontmatter !== 'object' || Array.isArray(frontmatter)) { | ||
| throw new RemoteSkillsError(`skills/${skillName}/SKILL.md frontmatter must be an object`); | ||
| } | ||
| const parsed = frontmatter; | ||
| assertString(parsed.name, `skills/${skillName}/SKILL.md frontmatter name`); | ||
| assertSafeSkillName(parsed.name, `skills/${skillName}/SKILL.md frontmatter name`); | ||
| assertString(parsed.description, `skills/${skillName}/SKILL.md frontmatter description`); | ||
| if (parsed.name !== skillName) { | ||
| throw new RemoteSkillsError(`skills/${skillName}/SKILL.md frontmatter name must match directory name`); | ||
| } | ||
| return { name: parsed.name, description: parsed.description }; | ||
| } | ||
| function readJsonFile(filePath) { | ||
| try { | ||
| return fs_1.default.readFileSync(filePath, 'utf8'); | ||
| } | ||
| catch (err) { | ||
| throw new RemoteSkillsError(`Failed to read ${path_1.default.basename(filePath)}: ${err instanceof Error ? err.message : String(err)}`); | ||
| } | ||
| } | ||
| async function cloneSkillsRepo(owner, repo, ref) { | ||
| const rootDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'limrun-skills-')); | ||
| const repoUrl = `https://github.com/${owner}/${repo}.git`; | ||
| const cloneArgs = [ | ||
| '-c', | ||
| 'filter.lfs.required=false', | ||
| '-c', | ||
| 'filter.lfs.smudge=', | ||
| '-c', | ||
| 'filter.lfs.clean=', | ||
| '-c', | ||
| 'filter.lfs.process=', | ||
| 'clone', | ||
| '--depth', | ||
| '1', | ||
| '--branch', | ||
| ref, | ||
| repoUrl, | ||
| rootDir, | ||
| ]; | ||
| const env = { | ||
| ...process.env, | ||
| GIT_TERMINAL_PROMPT: '0', | ||
| GIT_LFS_SKIP_SMUDGE: '1', | ||
| }; | ||
| try { | ||
| await execFileAsync('git', cloneArgs, { env, timeout: CLONE_TIMEOUT_MS }); | ||
| const { stdout } = await execFileAsync('git', ['-C', rootDir, 'rev-parse', 'HEAD'], { | ||
| env, | ||
| timeout: 30000, | ||
| }); | ||
| return { rootDir, commit: stdout.trim() }; | ||
| } | ||
| catch (err) { | ||
| cleanupSkillsTempDir(rootDir); | ||
| const message = err instanceof Error ? err.message : String(err); | ||
| const code = typeof err === 'object' && err && 'code' in err ? String(err.code) : ''; | ||
| if (code === 'ENOENT') { | ||
| throw new RemoteSkillsError('Failed to clone Limrun skills: git executable was not found'); | ||
| } | ||
| if (message.includes('timed out') || message.includes('ETIMEDOUT')) { | ||
| throw new RemoteSkillsError(`Failed to clone Limrun skills: clone timed out after ${Math.round(CLONE_TIMEOUT_MS / 1000)}s`); | ||
| } | ||
| if (message.includes('Authentication failed') || | ||
| message.includes('could not read Username') || | ||
| message.includes('Permission denied') || | ||
| message.includes('Repository not found')) { | ||
| throw new RemoteSkillsError(`Failed to clone Limrun skills: authentication failed for ${repoUrl}`); | ||
| } | ||
| throw new RemoteSkillsError(`Failed to clone Limrun skills: ${message}`); | ||
| } | ||
| } | ||
| function loadSkillsFromCheckout(params) { | ||
| const { owner, repo, ref, commit, rootDir } = params; | ||
| const skillsRoot = path_1.default.join(rootDir, 'skills'); | ||
| const catalogPath = path_1.default.join(rootDir, 'catalog.json'); | ||
| const catalog = parseCatalog(readJsonFile(catalogPath)); | ||
| const catalogNames = catalog.skills.map((skill) => skill.name); | ||
| const duplicateCatalogNames = catalogNames.filter((name, index) => catalogNames.indexOf(name) !== index); | ||
| if (duplicateCatalogNames.length > 0) { | ||
| throw new RemoteSkillsError(`catalog.json has duplicate skill names: ${[...new Set(duplicateCatalogNames)].join(', ')}`); | ||
| } | ||
| if (!catalog.skills.some((skill) => skill.defaultSelected)) { | ||
| throw new RemoteSkillsError('catalog.json must mark at least one skill as defaultSelected'); | ||
| } | ||
| const skills = catalog.skills.map((catalogSkill) => { | ||
| const sourceDir = path_1.default.join(skillsRoot, catalogSkill.name); | ||
| if (!isPathInside(skillsRoot, sourceDir)) { | ||
| throw new RemoteSkillsError(`catalog.json skill escapes skills directory: ${catalogSkill.name}`); | ||
| } | ||
| if (!fs_1.default.existsSync(sourceDir) || !fs_1.default.statSync(sourceDir).isDirectory()) { | ||
| throw new RemoteSkillsError(`catalog.json entries missing from skills/: ${catalogSkill.name}`); | ||
| } | ||
| const skillMdPath = path_1.default.join(sourceDir, 'SKILL.md'); | ||
| if (!fs_1.default.existsSync(skillMdPath)) { | ||
| throw new RemoteSkillsError(`Downloaded skill is missing skills/${catalogSkill.name}/SKILL.md`); | ||
| } | ||
| const frontmatter = parseSkillFrontmatter(catalogSkill.name, fs_1.default.readFileSync(skillMdPath, 'utf8')); | ||
| return { | ||
| name: frontmatter.name, | ||
| description: frontmatter.description, | ||
| defaultSelected: catalogSkill.defaultSelected, | ||
| sourceDir, | ||
| }; | ||
| }); | ||
| return { | ||
| owner, | ||
| repo, | ||
| ref, | ||
| commit, | ||
| rootDir, | ||
| skillsRoot, | ||
| skills, | ||
| cleanup: () => cleanupSkillsTempDir(rootDir), | ||
| }; | ||
| } | ||
| async function loadRemoteSkills(options = {}) { | ||
| const owner = options.owner ?? exports.DEFAULT_SKILLS_OWNER; | ||
| const repo = options.repo ?? exports.DEFAULT_SKILLS_REPO; | ||
| const ref = options.ref ?? exports.DEFAULT_SKILLS_REF; | ||
| const cloneImpl = options.cloneImpl ?? cloneSkillsRepo; | ||
| const cloned = await cloneImpl(owner, repo, ref); | ||
| try { | ||
| return loadSkillsFromCheckout({ | ||
| owner, | ||
| repo, | ||
| ref, | ||
| commit: cloned.commit, | ||
| rootDir: cloned.rootDir, | ||
| }); | ||
| } | ||
| catch (err) { | ||
| cleanupSkillsTempDir(cloned.rootDir); | ||
| throw err; | ||
| } | ||
| } | ||
| exports.__remoteSkillsTestUtils = { | ||
| cleanupSkillsTempDir, | ||
| loadSkillsFromCheckout, | ||
| }; | ||
| //# sourceMappingURL=remote-skills.js.map |
| {"version":3,"file":"remote-skills.js","sourceRoot":"","sources":["../../src/lib/remote-skills.ts"],"names":[],"mappings":";;;;;;AA2RA,4CAkBC;AA7SD,4CAAoB;AACpB,4CAAoB;AACpB,gDAAwB;AACxB,iDAAyC;AACzC,+BAAiC;AAEjC,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAqC,CAAC;AAEvD,QAAA,oBAAoB,GAAG,YAAY,CAAC;AACpC,QAAA,mBAAmB,GAAG,QAAQ,CAAC;AAC/B,QAAA,kBAAkB,GAAG,MAAM,CAAC;AACzC,MAAM,wBAAwB,GAAG,MAAO,CAAC;AACzC,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE;IAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IACvD,IAAI,CAAC,GAAG;QAAE,OAAO,wBAAwB,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,wBAAwB,CAAC;AACnF,CAAC,CAAC,EAAE,CAAC;AACL,MAAM,aAAa,GAAG,IAAA,gBAAS,EAAC,wBAAQ,CAAC,CAAC;AAmC1C,MAAa,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AALD,8CAKC;AAOD,SAAS,YAAY,CAAC,KAAc,EAAE,KAAa;IACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,iBAAiB,CAAC,GAAG,KAAK,6BAA6B,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB,EAAE,UAAkB;IACxD,MAAM,cAAc,GAAG,cAAI,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9D,MAAM,gBAAgB,GAAG,cAAI,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAClE,OAAO,gBAAgB,KAAK,cAAc,IAAI,gBAAgB,CAAC,UAAU,CAAC,cAAc,GAAG,cAAI,CAAC,GAAG,CAAC,CAAC;AACvG,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa,EAAE,KAAa;IACvD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,iBAAiB,CAAC,GAAG,KAAK,4CAA4C,CAAC,CAAC;IACpF,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe;IAC3C,MAAM,OAAO,GAAG,YAAE,CAAC,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,iBAAiB,CAAC,wDAAwD,OAAO,EAAE,CAAC,CAAC;IACjG,CAAC;IAED,YAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,iBAAiB,CACzB,iCAAiC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACpF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,iBAAiB,CAAC,gCAAgC,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,MAAM,GAAG,OAA+B,CAAC;IAC/C,IAAI,MAAM,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;IACtE,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,iBAAiB,CAAC,uBAAuB,KAAK,qBAAqB,CAAC,CAAC;QACjF,CAAC;QACD,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,uBAAuB,KAAK,QAAQ,CAAC,CAAC;QAC/D,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,uBAAuB,KAAK,QAAQ,CAAC,CAAC;QACtE,IAAI,OAAO,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC/C,MAAM,IAAI,iBAAiB,CAAC,uBAAuB,KAAK,qCAAqC,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IACD,OAAO,MAAqB,CAAC;AAC/B,CAAC;AAED,SAAS,qBAAqB,CAAC,SAAiB,EAAE,IAAY;IAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC7D,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,iBAAiB,CAAC,UAAU,SAAS,uCAAuC,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CAAC,UAAU,SAAS,uCAAuC,CAAC,CAAC;IAC1F,CAAC;IAED,IAAI,WAAoB,CAAC;IACzB,IAAI,CAAC;QACH,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,iBAAiB,CACzB,UAAU,SAAS,2CACjB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,iBAAiB,CAAC,UAAU,SAAS,yCAAyC,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,MAAM,GAAG,WAAwD,CAAC;IACxE,YAAY,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,SAAS,4BAA4B,CAAC,CAAC;IAC3E,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,SAAS,4BAA4B,CAAC,CAAC;IAClF,YAAY,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,SAAS,mCAAmC,CAAC,CAAC;IACzF,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,IAAI,iBAAiB,CAAC,UAAU,SAAS,sDAAsD,CAAC,CAAC;IACzG,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB;IACpC,IAAI,CAAC;QACH,OAAO,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,iBAAiB,CACzB,kBAAkB,cAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACjG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,KAAa,EAAE,IAAY,EAAE,GAAW;IACrE,MAAM,OAAO,GAAG,YAAE,CAAC,WAAW,CAAC,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,sBAAsB,KAAK,IAAI,IAAI,MAAM,CAAC;IAC1D,MAAM,SAAS,GAAG;QAChB,IAAI;QACJ,2BAA2B;QAC3B,IAAI;QACJ,oBAAoB;QACpB,IAAI;QACJ,mBAAmB;QACnB,IAAI;QACJ,qBAAqB;QACrB,OAAO;QACP,SAAS;QACT,GAAG;QACH,UAAU;QACV,GAAG;QACH,OAAO;QACP,OAAO;KACR,CAAC;IACF,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,mBAAmB,EAAE,GAAG;QACxB,mBAAmB,EAAE,GAAG;KACzB,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC1E,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE;YAClF,GAAG;YACH,OAAO,EAAE,KAAM;SAChB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,IAAI,iBAAiB,CAAC,6DAA6D,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,iBAAiB,CACzB,wDAAwD,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAC/F,CAAC;QACJ,CAAC;QACD,IACE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;YACzC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAC3C,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YACrC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EACxC,CAAC;YACD,MAAM,IAAI,iBAAiB,CAAC,4DAA4D,OAAO,EAAE,CAAC,CAAC;QACrG,CAAC;QACD,MAAM,IAAI,iBAAiB,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,MAM/B;IACC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IACrD,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,qBAAqB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;IACzG,IAAI,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,iBAAiB,CACzB,2CAA2C,CAAC,GAAG,IAAI,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5F,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,iBAAiB,CAAC,8DAA8D,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE;QACjD,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,iBAAiB,CAAC,gDAAgD,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QACnG,CAAC;QACD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,YAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;YACvE,MAAM,IAAI,iBAAiB,CAAC,8CAA8C,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QACjG,CAAC;QACD,MAAM,WAAW,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,iBAAiB,CAAC,sCAAsC,YAAY,CAAC,IAAI,WAAW,CAAC,CAAC;QAClG,CAAC;QACD,MAAM,WAAW,GAAG,qBAAqB,CAAC,YAAY,CAAC,IAAI,EAAE,YAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;QACnG,OAAO;YACL,IAAI,EAAE,WAAW,CAAC,IAAI;YACtB,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,eAAe,EAAE,YAAY,CAAC,eAAe;YAC7C,SAAS;SACV,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK;QACL,IAAI;QACJ,GAAG;QACH,MAAM;QACN,OAAO;QACP,UAAU;QACV,MAAM;QACN,OAAO,EAAE,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC;KAC7C,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,gBAAgB,CAAC,UAAmC,EAAE;IAC1E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,4BAAoB,CAAC;IACpD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,2BAAmB,CAAC;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,0BAAkB,CAAC;IAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,eAAe,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,OAAO,sBAAsB,CAAC;YAC5B,KAAK;YACL,IAAI;YACJ,GAAG;YACH,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAEY,QAAA,uBAAuB,GAAG;IACrC,oBAAoB;IACpB,sBAAsB;CACvB,CAAC"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/install.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAsR7C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAC,OAAO,SAAgD;IAC9D,MAAM,CAAC,WAAW,SAC0K;IAC5L,MAAM,CAAC,QAAQ,WAKb;IACF,MAAM,CAAC,KAAK;;;;;;;MA2BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAWZ,QAAQ;IA8HtB,OAAO,CAAC,UAAU;CAwCnB"} | ||
| {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/install.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAyS7C,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,OAAO;IAChD,MAAM,CAAC,OAAO,SAAgD;IAC9D,MAAM,CAAC,WAAW,SACsN;IACxO,MAAM,CAAC,QAAQ,WAKb;IACF,MAAM,CAAC,KAAK;;;;;;;MA2BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAWZ,QAAQ;IA6JtB,OAAO,CAAC,UAAU;CA8CnB"} |
+282
-248
@@ -11,27 +11,12 @@ "use strict"; | ||
| const skills_1 = require("../../lib/skills"); | ||
| const SKILL_CATALOG = [ | ||
| { | ||
| name: 'limrun-ios', | ||
| description: 'Build, launch, and control iOS apps with remote Xcode and Simulators', | ||
| defaultSelected: true, | ||
| }, | ||
| { | ||
| name: 'limrun-detox', | ||
| description: 'Run Detox tests on Limrun iOS with remote simulator launch and networking', | ||
| defaultSelected: false, | ||
| }, | ||
| ]; | ||
| const SKILL_NAMES = SKILL_CATALOG.map((skill) => skill.name); | ||
| const DEFAULT_SKILL_NAMES = SKILL_CATALOG.filter((skill) => skill.defaultSelected).map((skill) => skill.name); | ||
| const SKIPPED_REASON_CONFLICT = 'existing content differs; re-run with --force to overwrite'; | ||
| const remote_skills_1 = require("../../lib/remote-skills"); | ||
| const SKIPPED_REASON_CONFLICT = 'existing skill directory differs; re-run with --force to overwrite'; | ||
| const SKIPPED_REASON_BLOCKED = 'blocked: another target requires --force to proceed'; | ||
| const SKIPPED_REASON_DECLINED = 'user declined overwrite confirmation'; | ||
| function isSkillName(value) { | ||
| return SKILL_NAMES.includes(value); | ||
| } | ||
| function uniqueSkillNames(values) { | ||
| function uniqueSkillNames(values, availableSkills) { | ||
| const validNames = availableSkills.map((skill) => skill.name); | ||
| const skills = []; | ||
| for (const value of values) { | ||
| if (!isSkillName(value)) { | ||
| throw new Error(`Unknown skill "${value}". Valid skills: ${SKILL_NAMES.join(', ')}`); | ||
| if (!validNames.includes(value)) { | ||
| throw new Error(`Unknown skill "${value}". Valid skills: ${validNames.join(', ')}`); | ||
| } | ||
@@ -44,41 +29,12 @@ if (!skills.includes(value)) { | ||
| } | ||
| class PromptCancelled extends Error { | ||
| constructor() { | ||
| super('cancelled'); | ||
| this.name = 'PromptCancelled'; | ||
| } | ||
| } | ||
| function detectAgentsForScope(scope) { | ||
| const detected = new Set(); | ||
| for (const id of skills_1.AGENT_IDS) { | ||
| const agent = skills_1.AGENTS[id]; | ||
| for (const p of agent.detectionPaths(scope)) { | ||
| if (fs_1.default.existsSync(p)) { | ||
| detected.add(id); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| return detected; | ||
| } | ||
| async function promptAgents(preselected) { | ||
| // Loop to enforce "at least one agent" without crashing. | ||
| while (true) { | ||
| // `prompts` does not expose the multiselect cursor in onState - the state | ||
| // event only carries {value, aborted, exited}. Track cursor ourselves by | ||
| // listening to keypress events on stdin and mirror prompts' own dispatch | ||
| // (see prompts/lib/util/action.js and multiselect.js): | ||
| // - up / k : wrap (cursor === 0 ? last : cursor - 1) | ||
| // - down / j / tab : wrap (cursor === last ? 0 : cursor + 1) | ||
| // - ctrl+a : first | ||
| // - ctrl+e : last | ||
| // Anything else (page nav, home/end) is rare for a 3-row list and not | ||
| // tracked here; the worst case is the same as the previous clamp bug. | ||
| let cursor = 0; | ||
| const onKeypress = (_str, key) => { | ||
| if (!key || !key.name) | ||
| function createPromptCursorTracker(itemCount) { | ||
| let cursor = 0; | ||
| return { | ||
| current: () => cursor, | ||
| onKeypress: (_str, key) => { | ||
| if (!key || !key.name || itemCount === 0) | ||
| return; | ||
| if (key.meta && key.name !== 'escape') | ||
| return; | ||
| const last = skills_1.AGENT_IDS.length - 1; | ||
| const last = itemCount - 1; | ||
| if (key.ctrl) { | ||
@@ -97,97 +53,142 @@ if (key.name === 'a') | ||
| } | ||
| }; | ||
| process.stdin.on('keypress', onKeypress); | ||
| let response; | ||
| try { | ||
| response = await (0, prompts_1.default)({ | ||
| type: 'multiselect', | ||
| name: 'agents', | ||
| message: 'Which agents do you want to set up?', | ||
| instructions: false, | ||
| choices: skills_1.AGENT_IDS.map((id) => ({ | ||
| title: skills_1.AGENTS[id].displayName, | ||
| value: id, | ||
| selected: preselected.has(id), | ||
| })), | ||
| hint: 'Space to toggle, Enter to confirm (Enter alone picks the highlighted agent)', | ||
| }, { | ||
| onCancel: () => { | ||
| throw new PromptCancelled(); | ||
| }, | ||
| }); | ||
| }, | ||
| }; | ||
| } | ||
| function wrapDescription(value, width, indentSize = 2) { | ||
| const indent = ' '.repeat(indentSize); | ||
| const words = value.replace(/\s+/g, ' ').trim().split(' ').filter(Boolean); | ||
| const lines = []; | ||
| let line = indent; | ||
| for (const word of words) { | ||
| if (line === indent) { | ||
| line += word; | ||
| } | ||
| finally { | ||
| process.stdin.off('keypress', onKeypress); | ||
| else if (line.length + 1 + word.length <= width) { | ||
| line += ` ${word}`; | ||
| } | ||
| let picked = (response.agents ?? []); | ||
| // If the user hit Enter without toggling anything, treat the highlighted | ||
| // row as their pick. Saves a Space keystroke for the common single-agent case. | ||
| if (picked.length === 0 && cursor >= 0 && cursor < skills_1.AGENT_IDS.length) { | ||
| picked = [skills_1.AGENT_IDS[cursor]]; | ||
| else { | ||
| lines.push(line); | ||
| line = `${indent}${word}`; | ||
| } | ||
| if (picked.length > 0) { | ||
| process.stderr.write(` Selected: ${picked.map((id) => skills_1.AGENTS[id].displayName).join(', ')}\n`); | ||
| return picked; | ||
| } | ||
| if (line !== indent) { | ||
| lines.push(line); | ||
| } | ||
| return lines.join('\n'); | ||
| } | ||
| function installCompactMultiselectDescriptionRenderer() { | ||
| // prompts only exposes description text through its default renderer, whose | ||
| // wrap indent is too deep for long skill descriptions. Patch just this prompt | ||
| // and restore immediately after it completes. | ||
| const MultiselectPrompt = require('prompts/lib/elements/multiselect'); | ||
| const color = require('kleur'); | ||
| const { figures } = require('prompts/lib/util'); | ||
| const originalRenderOption = MultiselectPrompt.prototype.renderOption; | ||
| MultiselectPrompt.prototype.renderOption = function renderOption(cursor, choice, index, arrowIndicator) { | ||
| const prefix = (choice.selected ? color.green(figures.radioOn) : figures.radioOff) + ' ' + arrowIndicator + ' '; | ||
| let title; | ||
| if (choice.disabled) { | ||
| title = | ||
| cursor === index ? color.gray().underline(choice.title) : color.strikethrough().gray(choice.title); | ||
| } | ||
| // Re-prompt with a visible inline warning (should not be reachable now). | ||
| process.stderr.write('Select at least one agent.\n'); | ||
| else { | ||
| title = cursor === index ? color.cyan().underline(choice.title) : choice.title; | ||
| } | ||
| const description = !choice.disabled && cursor === index && choice.description ? | ||
| `\n${wrapDescription(choice.description, this.out.columns ?? 100, 4)}` | ||
| : ''; | ||
| return prefix + title + color.gray(description); | ||
| }; | ||
| return () => { | ||
| MultiselectPrompt.prototype.renderOption = originalRenderOption; | ||
| }; | ||
| } | ||
| class PromptCancelled extends Error { | ||
| constructor() { | ||
| super('cancelled'); | ||
| this.name = 'PromptCancelled'; | ||
| } | ||
| } | ||
| async function promptSkills() { | ||
| while (true) { | ||
| let cursor = 0; | ||
| const onKeypress = (_str, key) => { | ||
| if (!key || !key.name) | ||
| return; | ||
| if (key.meta && key.name !== 'escape') | ||
| return; | ||
| const last = SKILL_CATALOG.length - 1; | ||
| if (key.ctrl) { | ||
| if (key.name === 'a') | ||
| cursor = 0; | ||
| else if (key.name === 'e') | ||
| cursor = last; | ||
| return; | ||
| function detectAgentsForScope(scope) { | ||
| const detected = new Set(); | ||
| for (const id of skills_1.AGENT_IDS) { | ||
| const agent = skills_1.AGENTS[id]; | ||
| for (const p of agent.detectionPaths(scope)) { | ||
| if (fs_1.default.existsSync(p)) { | ||
| detected.add(id); | ||
| break; | ||
| } | ||
| if (key.name === 'up' || key.name === 'k') { | ||
| cursor = cursor === 0 ? last : cursor - 1; | ||
| } | ||
| else if (key.name === 'down' || key.name === 'j' || key.name === 'tab') { | ||
| cursor = cursor === last ? 0 : cursor + 1; | ||
| } | ||
| }; | ||
| process.stdin.on('keypress', onKeypress); | ||
| let response; | ||
| try { | ||
| response = await (0, prompts_1.default)({ | ||
| type: 'multiselect', | ||
| name: 'skills', | ||
| message: 'Which Limrun skills do you want to install?', | ||
| instructions: false, | ||
| choices: SKILL_CATALOG.map((skill) => ({ | ||
| title: `${skill.name} (${skill.description})`, | ||
| value: skill.name, | ||
| selected: skill.defaultSelected, | ||
| })), | ||
| hint: 'Space to toggle, Enter to confirm (Enter alone picks the highlighted skill)', | ||
| }, { | ||
| onCancel: () => { | ||
| throw new PromptCancelled(); | ||
| }, | ||
| }); | ||
| } | ||
| finally { | ||
| process.stdin.off('keypress', onKeypress); | ||
| } | ||
| let picked = uniqueSkillNames((response.skills ?? [])); | ||
| if (picked.length === 0 && cursor >= 0 && cursor < SKILL_CATALOG.length) { | ||
| picked = [SKILL_CATALOG[cursor].name]; | ||
| } | ||
| if (picked.length > 0) { | ||
| process.stderr.write(` Selected skills: ${picked.join(', ')}\n`); | ||
| return picked; | ||
| } | ||
| process.stderr.write('Select at least one skill.\n'); | ||
| } | ||
| return detected; | ||
| } | ||
| async function promptAgents(preselected) { | ||
| const cursor = createPromptCursorTracker(skills_1.AGENT_IDS.length); | ||
| process.stdin.on('keypress', cursor.onKeypress); | ||
| let response; | ||
| try { | ||
| response = await (0, prompts_1.default)({ | ||
| type: 'multiselect', | ||
| name: 'agents', | ||
| message: 'Which agents do you want to set up?', | ||
| instructions: false, | ||
| choices: skills_1.AGENT_IDS.map((id) => ({ | ||
| title: skills_1.AGENTS[id].displayName, | ||
| value: id, | ||
| selected: preselected.has(id), | ||
| })), | ||
| hint: 'Space to toggle, Enter to confirm (Enter alone picks the highlighted agent)', | ||
| }, { | ||
| onCancel: () => { | ||
| throw new PromptCancelled(); | ||
| }, | ||
| }); | ||
| } | ||
| finally { | ||
| process.stdin.off('keypress', cursor.onKeypress); | ||
| } | ||
| let picked = (response.agents ?? []); | ||
| const highlightedAgent = skills_1.AGENT_IDS[cursor.current()]; | ||
| if (picked.length === 0 && highlightedAgent) { | ||
| picked = [highlightedAgent]; | ||
| } | ||
| process.stderr.write(` Selected: ${picked.map((id) => skills_1.AGENTS[id].displayName).join(', ')}\n`); | ||
| return picked; | ||
| } | ||
| async function promptSkills(availableSkills) { | ||
| const cursor = createPromptCursorTracker(availableSkills.length); | ||
| let response; | ||
| const restoreMultiselectRenderer = installCompactMultiselectDescriptionRenderer(); | ||
| process.stdin.on('keypress', cursor.onKeypress); | ||
| try { | ||
| response = await (0, prompts_1.default)({ | ||
| type: 'multiselect', | ||
| name: 'skills', | ||
| message: 'Which Limrun skills do you want to install?', | ||
| instructions: false, | ||
| choices: availableSkills.map((skill) => ({ | ||
| title: skill.name, | ||
| description: skill.description.replace(/\s+/g, ' ').trim(), | ||
| value: skill.name, | ||
| selected: skill.defaultSelected, | ||
| })), | ||
| hint: 'Catalog defaults selected. Space toggles, Enter confirms.', | ||
| }, { | ||
| onCancel: () => { | ||
| throw new PromptCancelled(); | ||
| }, | ||
| }); | ||
| } | ||
| finally { | ||
| restoreMultiselectRenderer(); | ||
| process.stdin.off('keypress', cursor.onKeypress); | ||
| } | ||
| let picked = uniqueSkillNames((response.skills ?? []), availableSkills); | ||
| const highlightedSkill = availableSkills[cursor.current()]; | ||
| if (picked.length === 0 && highlightedSkill) { | ||
| picked = [highlightedSkill.name]; | ||
| } | ||
| process.stderr.write(` Selected skills: ${picked.join(', ')}\n`); | ||
| return picked; | ||
| } | ||
| async function promptScope() { | ||
@@ -261,120 +262,149 @@ const response = await (0, prompts_1.default)({ | ||
| let agents; | ||
| let skills; | ||
| let skills = []; | ||
| let scope; | ||
| if (flags.agents && flags.agents.length > 0) { | ||
| agents = Array.from(new Set(flags.agents)); | ||
| } | ||
| else if (interactive) { | ||
| // Pre-check based on project-local presence only. Global installs of | ||
| // agents (e.g. ~/.claude on a dev machine) are too weak a signal to | ||
| // auto-select them for this specific project's install. | ||
| agents = await promptAgents(detectAgentsForScope('project')); | ||
| } | ||
| else { | ||
| this.error('--agents requires at least one of: claude, cursor, codex.', { exit: 2 }); | ||
| } | ||
| if (flags.skills && flags.skills.length > 0) { | ||
| skills = uniqueSkillNames(flags.skills); | ||
| } | ||
| else if (interactive) { | ||
| skills = await promptSkills(); | ||
| } | ||
| else { | ||
| skills = [...DEFAULT_SKILL_NAMES]; | ||
| } | ||
| if (flags.scope) { | ||
| scope = flags.scope; | ||
| } | ||
| else if (interactive) { | ||
| scope = await promptScope(); | ||
| } | ||
| else { | ||
| this.error('Specify --agents and --scope in non-interactive mode.', { exit: 2 }); | ||
| } | ||
| const sources = new Map(); | ||
| for (const skill of skills) { | ||
| const source = (0, skills_1.sourceSkillMd)(this.config, skill); | ||
| if (!fs_1.default.existsSync(source)) { | ||
| this.error(`Bundled skill source missing at ${source}.`, { exit: 1 }); | ||
| let source; | ||
| try { | ||
| if (!interactive) { | ||
| if (!flags.agents || flags.agents.length === 0) { | ||
| this.error(`--agents requires at least one of: ${skills_1.AGENT_IDS.join(', ')}.`, { exit: 2 }); | ||
| } | ||
| if (!flags.scope) { | ||
| this.error('Specify --agents and --scope in non-interactive mode.', { exit: 2 }); | ||
| } | ||
| } | ||
| sources.set(skill, source); | ||
| } | ||
| // Phase 1: Plan. | ||
| const planned = []; | ||
| for (const skill of skills) { | ||
| const source = sources.get(skill); | ||
| for (const id of agents) { | ||
| const agent = skills_1.AGENTS[id]; | ||
| const target = (0, skills_1.targetSkillMd)(agent, scope, skill); | ||
| const { kind } = (0, skills_1.planSkillFileCopy)(source, target); | ||
| planned.push({ skill, agent, scope, source, target, kind }); | ||
| if (interactive) { | ||
| process.stderr.write('Fetching latest Limrun skills...\n'); | ||
| } | ||
| } | ||
| // Phase 2: Confirm. | ||
| const results = []; | ||
| const anyConflict = planned.some((t) => t.kind === 'conflict'); | ||
| if (anyConflict && !flags.force && !interactive) { | ||
| // Non-interactive + conflict + no force: all-or-nothing. Skip all targets. | ||
| for (const t of planned) { | ||
| results.push({ | ||
| skill: t.skill, | ||
| agent: t.agent.id, | ||
| scope: t.scope, | ||
| path: t.target, | ||
| status: 'skipped', | ||
| reason: t.kind === 'conflict' ? SKIPPED_REASON_CONFLICT : SKIPPED_REASON_BLOCKED, | ||
| source = await (0, remote_skills_1.loadRemoteSkills)(); | ||
| const availableSkills = source.skills; | ||
| if (availableSkills.length === 0) { | ||
| this.error(`No Limrun skills found in ${source.owner}/${source.repo}@${source.commit}.`, { | ||
| exit: 1, | ||
| }); | ||
| } | ||
| if (!flags.json) { | ||
| // --quiet still suppresses the human summary, but a hard refusal needs to be visible. | ||
| process.stderr.write('Existing skill files would be overwritten. Re-run with --force, or run interactively to confirm per target.\n'); | ||
| if (flags.skills && flags.skills.length > 0) { | ||
| skills = uniqueSkillNames(flags.skills, availableSkills); | ||
| } | ||
| this.emitOutput(results, flags, skills); | ||
| this.exit(1); | ||
| } | ||
| // Decide final status per target (no writes yet). | ||
| const finalDecisions = []; | ||
| for (const t of planned) { | ||
| if (t.kind === 'install') { | ||
| finalDecisions.push({ target: t, status: 'installed' }); | ||
| else if (interactive) { | ||
| skills = await promptSkills(availableSkills); | ||
| } | ||
| else if (t.kind === 'unchanged') { | ||
| finalDecisions.push({ target: t, status: 'unchanged' }); | ||
| else { | ||
| skills = availableSkills.filter((skill) => skill.defaultSelected).map((skill) => skill.name); | ||
| } | ||
| else if (flags.force) { | ||
| finalDecisions.push({ target: t, status: 'updated' }); | ||
| if (skills.length === 0) { | ||
| this.error(`No default Limrun skills found in ${source.owner}/${source.repo}@${source.commit}.`, { | ||
| exit: 1, | ||
| }); | ||
| } | ||
| if (flags.agents && flags.agents.length > 0) { | ||
| agents = Array.from(new Set(flags.agents)); | ||
| } | ||
| else if (interactive) { | ||
| // Pre-check based on project-local presence only. Global installs of | ||
| // agents (e.g. ~/.claude on a dev machine) are too weak a signal to | ||
| // auto-select them for this specific project's install. | ||
| agents = await promptAgents(detectAgentsForScope('project')); | ||
| } | ||
| else { | ||
| // Interactive conflict without --force: prompt per target. | ||
| const displayPath = humanPath(t.target, t.scope); | ||
| const ok = await promptOverwrite(displayPath); | ||
| if (ok) { | ||
| finalDecisions.push({ target: t, status: 'updated' }); | ||
| this.error(`--agents requires at least one of: ${skills_1.AGENT_IDS.join(', ')}.`, { exit: 2 }); | ||
| } | ||
| if (flags.scope) { | ||
| scope = flags.scope; | ||
| } | ||
| else if (interactive) { | ||
| scope = await promptScope(); | ||
| } | ||
| else { | ||
| this.error('Specify --agents and --scope in non-interactive mode.', { exit: 2 }); | ||
| } | ||
| const sources = new Map(); | ||
| for (const skill of skills) { | ||
| const sourceSkill = availableSkills.find((availableSkill) => availableSkill.name === skill); | ||
| if (!sourceSkill || !fs_1.default.existsSync(sourceSkill.sourceDir)) { | ||
| this.error(`Fetched skill source missing for "${skill}".`, { exit: 1 }); | ||
| } | ||
| else { | ||
| finalDecisions.push({ | ||
| target: t, | ||
| sources.set(skill, sourceSkill.sourceDir); | ||
| } | ||
| // Phase 1: Plan. | ||
| const planned = []; | ||
| for (const skill of skills) { | ||
| const sourceDir = sources.get(skill); | ||
| for (const id of agents) { | ||
| const agent = skills_1.AGENTS[id]; | ||
| const target = (0, skills_1.targetSkillDir)(agent, scope, skill); | ||
| const { kind } = (0, skills_1.planSkillDirectoryCopy)(sourceDir, target); | ||
| planned.push({ skill, agent, scope, source: sourceDir, target, kind }); | ||
| } | ||
| } | ||
| // Phase 2: Confirm. | ||
| const results = []; | ||
| const anyConflict = planned.some((t) => t.kind === 'conflict'); | ||
| if (anyConflict && !flags.force && !interactive) { | ||
| // Non-interactive + conflict + no force: all-or-nothing. Skip all targets. | ||
| for (const t of planned) { | ||
| results.push({ | ||
| skill: t.skill, | ||
| agent: t.agent.id, | ||
| scope: t.scope, | ||
| path: t.target, | ||
| status: 'skipped', | ||
| reason: SKIPPED_REASON_DECLINED, | ||
| reason: t.kind === 'conflict' ? SKIPPED_REASON_CONFLICT : SKIPPED_REASON_BLOCKED, | ||
| }); | ||
| } | ||
| if (!flags.json) { | ||
| // --quiet still suppresses the human summary, but a hard refusal needs to be visible. | ||
| process.stderr.write('Existing skill directories would be overwritten. Re-run with --force, or run interactively to confirm per target.\n'); | ||
| } | ||
| this.emitOutput(results, flags, skills, source); | ||
| this.exit(1); | ||
| } | ||
| } | ||
| // Phase 3: Apply. | ||
| for (const decision of finalDecisions) { | ||
| if (decision.status === 'installed' || decision.status === 'updated') { | ||
| (0, skills_1.applySkillFileCopy)(decision.target.source, decision.target.target); | ||
| // Decide final status per target (no writes yet). | ||
| const finalDecisions = []; | ||
| for (const t of planned) { | ||
| if (t.kind === 'install') { | ||
| finalDecisions.push({ target: t, status: 'installed' }); | ||
| } | ||
| else if (t.kind === 'unchanged') { | ||
| finalDecisions.push({ target: t, status: 'unchanged' }); | ||
| } | ||
| else if (flags.force) { | ||
| finalDecisions.push({ target: t, status: 'updated' }); | ||
| } | ||
| else { | ||
| // Interactive conflict without --force: prompt per target. | ||
| const displayPath = humanPath(t.target, t.scope); | ||
| const ok = await promptOverwrite(displayPath); | ||
| if (ok) { | ||
| finalDecisions.push({ target: t, status: 'updated' }); | ||
| } | ||
| else { | ||
| finalDecisions.push({ | ||
| target: t, | ||
| status: 'skipped', | ||
| reason: SKIPPED_REASON_DECLINED, | ||
| }); | ||
| } | ||
| } | ||
| } | ||
| results.push({ | ||
| skill: decision.target.skill, | ||
| agent: decision.target.agent.id, | ||
| scope: decision.target.scope, | ||
| path: decision.target.target, | ||
| status: decision.status, | ||
| ...(decision.reason ? { reason: decision.reason } : {}), | ||
| }); | ||
| // Phase 3: Apply. | ||
| for (const decision of finalDecisions) { | ||
| if (decision.status === 'installed' || decision.status === 'updated') { | ||
| (0, skills_1.applySkillDirectoryCopy)(decision.target.source, decision.target.target); | ||
| } | ||
| results.push({ | ||
| skill: decision.target.skill, | ||
| agent: decision.target.agent.id, | ||
| scope: decision.target.scope, | ||
| path: decision.target.target, | ||
| status: decision.status, | ||
| ...(decision.reason ? { reason: decision.reason } : {}), | ||
| }); | ||
| } | ||
| this.emitOutput(results, flags, skills, source); | ||
| } | ||
| this.emitOutput(results, flags, skills); | ||
| finally { | ||
| source?.cleanup(); | ||
| } | ||
| } | ||
| emitOutput(results, flags, skills) { | ||
| emitOutput(results, flags, skills, source) { | ||
| if (flags.json) { | ||
@@ -384,2 +414,7 @@ this.log(JSON.stringify({ | ||
| skills, | ||
| source: { | ||
| repository: `${source.owner}/${source.repo}`, | ||
| ref: source.ref, | ||
| commit: source.commit, | ||
| }, | ||
| results, | ||
@@ -408,7 +443,7 @@ }, null, 2)); | ||
| SkillsInstall.summary = 'Install Limrun skills for AI coding agents'; | ||
| SkillsInstall.description = 'Copy bundled Limrun skills into the native skills directory for each selected agent (Claude Code, Cursor, Codex). Pre-checks detected agents and lets you pick project or global scope.'; | ||
| SkillsInstall.description = 'Fetch the latest Limrun skills from limrun-inc/skills and install them into the native skills directory for each selected agent (Claude Code, Cursor, Codex). Pre-checks detected agents and lets you pick project or global scope.'; | ||
| SkillsInstall.examples = [ | ||
| '<%= config.bin %> skills install', | ||
| '<%= config.bin %> skills install --agents claude --agents cursor --scope project', | ||
| '<%= config.bin %> skills install --agents cursor --scope project --skills limrun-ios --skills limrun-detox', | ||
| '<%= config.bin %> skills install --agents cursor --scope project --skills limrun-xcode-and-ios-simulator --skills limrun-detox-testing', | ||
| '<%= config.bin %> skills install --agents codex --scope global --force', | ||
@@ -420,8 +455,7 @@ ]; | ||
| multiple: true, | ||
| options: ['claude', 'cursor', 'codex'], | ||
| options: skills_1.AGENT_IDS, | ||
| }), | ||
| skills: core_1.Flags.string({ | ||
| description: 'Limrun skill to install. Repeat to pick multiple. Defaults to limrun-ios.', | ||
| description: 'Limrun skill to install. Repeat to pick multiple. Defaults to the remote catalog default.', | ||
| multiple: true, | ||
| options: [...SKILL_NAMES], | ||
| }), | ||
@@ -433,3 +467,3 @@ scope: core_1.Flags.string({ | ||
| force: core_1.Flags.boolean({ | ||
| description: 'Overwrite existing skill files without confirmation.', | ||
| description: 'Overwrite existing skill directories without confirmation.', | ||
| default: false, | ||
@@ -436,0 +470,0 @@ }), |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/commands/skills/install.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,sDAA8B;AAC9B,sCAA6C;AAC7C,6CAU0B;AAE1B,MAAM,aAAa,GAAG;IACpB;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,sEAAsE;QACnF,eAAe,EAAE,IAAI;KACtB;IACD;QACE,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,2EAA2E;QACxF,eAAe,EAAE,KAAK;KACvB;CACO,CAAC;AAEX,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;AAC5E,MAAM,mBAAmB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CACpF,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CACP,CAAC;AACjB,MAAM,uBAAuB,GAAG,4DAA4D,CAAC;AAC7F,MAAM,sBAAsB,GAAG,qDAAqD,CAAC;AACrF,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AAsBvE,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,WAAW,CAAC,QAAQ,CAAC,KAAkB,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAgB;IACxC,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,oBAAoB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,eAAgB,SAAQ,KAAK;IACjC;QACE,KAAK,CAAC,WAAW,CAAC,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,SAAS,oBAAoB,CAAC,KAAY;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;IACpC,KAAK,MAAM,EAAE,IAAI,kBAAS,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,eAAM,CAAC,EAAE,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,YAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,WAAyB;IACnD,yDAAyD;IACzD,OAAO,IAAI,EAAE,CAAC;QACZ,0EAA0E;QAC1E,yEAAyE;QACzE,yEAAyE;QACzE,uDAAuD;QACvD,wDAAwD;QACxD,+DAA+D;QAC/D,sBAAsB;QACtB,qBAAqB;QACrB,sEAAsE;QACtE,sEAAsE;QACtE,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,GAAsD,EAAE,EAAE;YAC1F,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI;gBAAE,OAAO;YAC9B,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAC9C,MAAM,IAAI,GAAG,kBAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YAClC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBACb,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;oBAAE,MAAM,GAAG,CAAC,CAAC;qBAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;oBAAE,MAAM,GAAG,IAAI,CAAC;gBACzC,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBAC1C,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACzE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAA,iBAAO,EACtB;gBACE,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,qCAAqC;gBAC9C,YAAY,EAAE,KAAK;gBACnB,OAAO,EAAE,kBAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC9B,KAAK,EAAE,eAAM,CAAC,EAAE,CAAC,CAAC,WAAW;oBAC7B,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;iBAC9B,CAAC,CAAC;gBACH,IAAI,EAAE,6EAA6E;aACpF,EACD;gBACE,QAAQ,EAAE,GAAG,EAAE;oBACb,MAAM,IAAI,eAAe,EAAE,CAAC;gBAC9B,CAAC;aACF,CACF,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAc,CAAC;QAClD,yEAAyE;QACzE,+EAA+E;QAC/E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,GAAG,kBAAS,CAAC,MAAM,EAAE,CAAC;YACpE,MAAM,GAAG,CAAC,kBAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAM,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/F,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,yEAAyE;QACzE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,GAAsD,EAAE,EAAE;YAC1F,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI;gBAAE,OAAO;YAC9B,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAC9C,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;YACtC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBACb,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;oBAAE,MAAM,GAAG,CAAC,CAAC;qBAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;oBAAE,MAAM,GAAG,IAAI,CAAC;gBACzC,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBAC1C,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACzE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAA,iBAAO,EACtB;gBACE,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,6CAA6C;gBACtD,YAAY,EAAE,KAAK;gBACnB,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACrC,KAAK,EAAE,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,WAAW,GAAG;oBAC7C,KAAK,EAAE,KAAK,CAAC,IAAI;oBACjB,QAAQ,EAAE,KAAK,CAAC,eAAe;iBAChC,CAAC,CAAC;gBACH,IAAI,EAAE,6EAA6E;aACpF,EACD;gBACE,QAAQ,EAAE,GAAG,EAAE;oBACb,MAAM,IAAI,eAAe,EAAE,CAAC;gBAC9B,CAAC;aACF,CACF,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,MAAM,GAAG,gBAAgB,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAa,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;YACxE,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClE,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAO,EAC5B;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,mBAAmB;QAC5B,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,oCAAoC,EAAE;YACzF,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;SACtF;QACD,OAAO,EAAE,CAAC;KACX,EACD;QACE,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC;KACF,CACF,CAAC;IACF,OAAO,QAAQ,CAAC,KAAc,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,UAAkB;IAC/C,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAO,EAC5B;QACE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,sBAAsB,UAAU,GAAG;QAC5C,OAAO,EAAE,KAAK;KACf,EACD;QACE,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC;KACF,CACF,CAAC;IACF,OAAO,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,YAAoB,EAAE,KAAY;IACnD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,cAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAqB,aAAc,SAAQ,cAAO;IAuChD,KAAK,CAAC,GAAG;QACP,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAElD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAEhF,IAAI,MAAiB,CAAC;QACtB,IAAI,MAAmB,CAAC;QACxB,IAAI,KAAY,CAAC;QAEjB,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAc,CAAC;QAC1D,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,qEAAqE;YACrE,oEAAoE;YACpE,wDAAwD;YACxD,MAAM,GAAG,MAAM,YAAY,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,2DAA2D,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC,GAAG,mBAAmB,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,KAAK,GAAG,KAAK,CAAC,KAAc,CAAC;QAC/B,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,KAAK,CAAC,uDAAuD,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,KAAK,CAAC,mCAAmC,MAAM,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAED,iBAAiB;QACjB,MAAM,OAAO,GAAoB,EAAE,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YACnC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,eAAM,CAAC,EAAE,CAAC,CAAC;gBACzB,MAAM,MAAM,GAAG,IAAA,sBAAa,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;gBAClD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,0BAAiB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACnD,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,MAAM,OAAO,GAAgB,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAE/D,IAAI,WAAW,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;YAChD,2EAA2E;YAC3E,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC;oBACX,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;oBACjB,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,IAAI,EAAE,CAAC,CAAC,MAAM;oBACd,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB;iBACjF,CAAC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAChB,sFAAsF;gBACtF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,+GAA+G,CAChH,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;QAED,kDAAkD;QAClD,MAAM,cAAc,GAAsE,EAAE,CAAC;QAC7F,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACzB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;YAC1D,CAAC;iBAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAClC,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;YAC1D,CAAC;iBAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBACvB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,2DAA2D;gBAC3D,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;gBACjD,MAAM,EAAE,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;gBAC9C,IAAI,EAAE,EAAE,CAAC;oBACP,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACxD,CAAC;qBAAM,CAAC;oBACN,cAAc,CAAC,IAAI,CAAC;wBAClB,MAAM,EAAE,CAAC;wBACT,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,uBAAuB;qBAChC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;YACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACrE,IAAA,2BAAkB,EAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACrE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;gBAC5B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAC/B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;gBAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;gBAC5B,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAEO,UAAU,CAChB,OAAoB,EACpB,KAAwC,EACxC,MAAmB;QAEnB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,SAAS,CACZ;gBACE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpD,MAAM;gBACN,OAAO;aACR,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,iBAAiB;QACjB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtF,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC5B,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EACzD,aAAa,CAAC,MAAM,CACrB,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACjD,MAAM,UAAU,GAAG,eAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,OAAO,UAAU,KAAK,UAAU,SAAS,WAAW,OAAO,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;QACxG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;;AAtNM,qBAAO,GAAG,4CAA4C,CAAC;AACvD,yBAAW,GAChB,yLAAyL,CAAC;AACrL,sBAAQ,GAAG;IAChB,kCAAkC;IAClC,kFAAkF;IAClF,4GAA4G;IAC5G,wEAAwE;CACzE,CAAC;AACK,mBAAK,GAAG;IACb,MAAM,EAAE,YAAK,CAAC,MAAM,CAAC;QACnB,WAAW,EAAE,wCAAwC;QACrD,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC;KACvC,CAAC;IACF,MAAM,EAAE,YAAK,CAAC,MAAM,CAAC;QACnB,WAAW,EAAE,2EAA2E;QACxF,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,CAAC,GAAG,WAAW,CAAC;KAC1B,CAAC;IACF,KAAK,EAAE,YAAK,CAAC,MAAM,CAAC;QAClB,WAAW,EAAE,gBAAgB;QAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;KAC/B,CAAC;IACF,KAAK,EAAE,YAAK,CAAC,OAAO,CAAC;QACnB,WAAW,EAAE,sDAAsD;QACnE,OAAO,EAAE,KAAK;KACf,CAAC;IACF,IAAI,EAAE,YAAK,CAAC,OAAO,CAAC;QAClB,WAAW,EAAE,8BAA8B;QAC3C,OAAO,EAAE,KAAK;KACf,CAAC;IACF,KAAK,EAAE,YAAK,CAAC,OAAO,CAAC;QACnB,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,KAAK;KACf,CAAC;CACH,CAAC;kBArCiB,aAAa"} | ||
| {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/commands/skills/install.ts"],"names":[],"mappings":";;;;;AAAA,4CAAoB;AACpB,gDAAwB;AACxB,sDAA8B;AAC9B,sCAA6C;AAC7C,6CAS0B;AAC1B,2DAAsG;AAGtG,MAAM,uBAAuB,GAAG,oEAAoE,CAAC;AACrG,MAAM,sBAAsB,GAAG,qDAAqD,CAAC;AACrF,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AAsBvE,SAAS,gBAAgB,CAAC,MAAgB,EAAE,eAA8B;IACxE,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,oBAAoB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,yBAAyB,CAAC,SAAiB;IAIlD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM;QACrB,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACxB,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS,KAAK,CAAC;gBAAE,OAAO;YACjD,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,OAAO;YAC9C,MAAM,IAAI,GAAG,SAAS,GAAG,CAAC,CAAC;YAC3B,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBACb,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;oBAAE,MAAM,GAAG,CAAC,CAAC;qBAC5B,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG;oBAAE,MAAM,GAAG,IAAI,CAAC;gBACzC,OAAO;YACT,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,CAAC;gBAC1C,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACzE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa,EAAE,KAAa,EAAE,UAAU,GAAG,CAAC;IACnE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,GAAG,MAAM,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,IAAI,IAAI,IAAI,CAAC;QACf,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;YAClD,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,IAAI,GAAG,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,4CAA4C;IACnD,4EAA4E;IAC5E,8EAA8E;IAC9E,8CAA8C;IAC9C,MAAM,iBAAiB,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;IACtE,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChD,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC;IAEtE,iBAAiB,CAAC,SAAS,CAAC,YAAY,GAAG,SAAS,YAAY,CAE9D,MAAc,EACd,MAAuF,EACvF,KAAa,EACb,cAAsB;QAEtB,MAAM,MAAM,GACV,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,cAAc,GAAG,GAAG,CAAC;QACnG,IAAI,KAAa,CAAC;QAElB,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,KAAK;gBACH,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvG,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QACjF,CAAC;QAED,MAAM,WAAW,GACf,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;YAC1D,KAAK,eAAe,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC,EAAE;YACxE,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC,CAAC;IAEF,OAAO,GAAG,EAAE;QACV,iBAAiB,CAAC,SAAS,CAAC,YAAY,GAAG,oBAAoB,CAAC;IAClE,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,eAAgB,SAAQ,KAAK;IACjC;QACE,KAAK,CAAC,WAAW,CAAC,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,SAAS,oBAAoB,CAAC,KAAY;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;IACpC,KAAK,MAAM,EAAE,IAAI,kBAAS,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,eAAM,CAAC,EAAE,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,IAAI,YAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACjB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,WAAyB;IACnD,MAAM,MAAM,GAAG,yBAAyB,CAAC,kBAAS,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,QAAQ,CAAC;IACb,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,IAAA,iBAAO,EACtB;YACE,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,qCAAqC;YAC9C,YAAY,EAAE,KAAK;YACnB,OAAO,EAAE,kBAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC9B,KAAK,EAAE,eAAM,CAAC,EAAE,CAAC,CAAC,WAAW;gBAC7B,KAAK,EAAE,EAAE;gBACT,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;aAC9B,CAAC,CAAC;YACH,IAAI,EAAE,6EAA6E;SACpF,EACD;YACE,QAAQ,EAAE,GAAG,EAAE;gBACb,MAAM,IAAI,eAAe,EAAE,CAAC;YAC9B,CAAC;SACF,CACF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAc,CAAC;IAClD,MAAM,gBAAgB,GAAG,kBAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC5C,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,eAAM,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/F,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,eAA8B;IACxD,MAAM,MAAM,GAAG,yBAAyB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACjE,IAAI,QAAQ,CAAC;IACb,MAAM,0BAA0B,GAAG,4CAA4C,EAAE,CAAC;IAClF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,IAAA,iBAAO,EACtB;YACE,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,6CAA6C;YACtD,YAAY,EAAE,KAAK;YACnB,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACvC,KAAK,EAAE,KAAK,CAAC,IAAI;gBACjB,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE;gBAC1D,KAAK,EAAE,KAAK,CAAC,IAAI;gBACjB,QAAQ,EAAE,KAAK,CAAC,eAAe;aAChC,CAAC,CAAC;YACH,IAAI,EAAE,2DAA2D;SAClE,EACD;YACE,QAAQ,EAAE,GAAG,EAAE;gBACb,MAAM,IAAI,eAAe,EAAE,CAAC;YAC9B,CAAC;SACF,CACF,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,0BAA0B,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,MAAM,GAAG,gBAAgB,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAa,EAAE,eAAe,CAAC,CAAC;IACpF,MAAM,gBAAgB,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC5C,MAAM,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAO,EAC5B;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,mBAAmB;QAC5B,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,oCAAoC,EAAE;YACzF,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;SACtF;QACD,OAAO,EAAE,CAAC;KACX,EACD;QACE,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC;KACF,CACF,CAAC;IACF,OAAO,QAAQ,CAAC,KAAc,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,UAAkB;IAC/C,MAAM,QAAQ,GAAG,MAAM,IAAA,iBAAO,EAC5B;QACE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,sBAAsB,UAAU,GAAG;QAC5C,OAAO,EAAE,KAAK;KACf,EACD;QACE,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC;KACF,CACF,CAAC;IACF,OAAO,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,YAAoB,EAAE,KAAY;IACnD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,cAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,WAAW,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAqB,aAAc,SAAQ,cAAO;IAuChD,KAAK,CAAC,GAAG;QACP,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ;QACpB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAElD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAEhF,IAAI,MAAiB,CAAC;QACtB,IAAI,MAAM,GAAgB,EAAE,CAAC;QAC7B,IAAI,KAAY,CAAC;QACjB,IAAI,MAAsC,CAAC;QAE3C,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/C,IAAI,CAAC,KAAK,CAAC,sCAAsC,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBACzF,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBACjB,IAAI,CAAC,KAAK,CAAC,uDAAuD,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBACnF,CAAC;YACH,CAAC;YAED,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,GAAG,MAAM,IAAA,gCAAgB,GAAE,CAAC;YAClC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;YACtC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,KAAK,CAAC,6BAA6B,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;oBACvF,IAAI,EAAE,CAAC;iBACR,CAAC,CAAC;YACL,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAC3D,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,MAAM,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/F,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,KAAK,CAAC,qCAAqC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;oBAC/F,IAAI,EAAE,CAAC;iBACR,CAAC,CAAC;YACL,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5C,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAc,CAAC;YAC1D,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,qEAAqE;gBACrE,oEAAoE;gBACpE,wDAAwD;gBACxD,MAAM,GAAG,MAAM,YAAY,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,sCAAsC,kBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACzF,CAAC;YAED,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,KAAK,GAAG,KAAK,CAAC,KAAc,CAAC;YAC/B,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,uDAAuD,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YACnF,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;YAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;gBAC5F,IAAI,CAAC,WAAW,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC1D,IAAI,CAAC,KAAK,CAAC,qCAAqC,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC1E,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;YAC5C,CAAC;YAED,iBAAiB;YACjB,MAAM,OAAO,GAAoB,EAAE,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;gBACtC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;oBACxB,MAAM,KAAK,GAAG,eAAM,CAAC,EAAE,CAAC,CAAC;oBACzB,MAAM,MAAM,GAAG,IAAA,uBAAc,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;oBACnD,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,+BAAsB,EAAC,SAAS,EAAE,MAAM,CAAC,CAAC;oBAC3D,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBACzE,CAAC;YACH,CAAC;YAED,oBAAoB;YACpB,MAAM,OAAO,GAAgB,EAAE,CAAC;YAChC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAE/D,IAAI,WAAW,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;gBAChD,2EAA2E;gBAC3E,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACxB,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,CAAC,CAAC,KAAK;wBACd,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;wBACjB,KAAK,EAAE,CAAC,CAAC,KAAK;wBACd,IAAI,EAAE,CAAC,CAAC,MAAM;wBACd,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,sBAAsB;qBACjF,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBAChB,sFAAsF;oBACtF,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qHAAqH,CACtH,CAAC;gBACJ,CAAC;gBACD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;gBAChD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;YAED,kDAAkD;YAClD,MAAM,cAAc,GAAsE,EAAE,CAAC;YAC7F,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBACzB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC1D,CAAC;qBAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBAClC,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;gBAC1D,CAAC;qBAAM,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oBACvB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBACxD,CAAC;qBAAM,CAAC;oBACN,2DAA2D;oBAC3D,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;oBACjD,MAAM,EAAE,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;oBAC9C,IAAI,EAAE,EAAE,CAAC;wBACP,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;oBACxD,CAAC;yBAAM,CAAC;wBACN,cAAc,CAAC,IAAI,CAAC;4BAClB,MAAM,EAAE,CAAC;4BACT,MAAM,EAAE,SAAS;4BACjB,MAAM,EAAE,uBAAuB;yBAChC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,kBAAkB;YAClB,KAAK,MAAM,QAAQ,IAAI,cAAc,EAAE,CAAC;gBACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACrE,IAAA,gCAAuB,EAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1E,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC;oBACX,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;oBAC5B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;oBAC/B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;oBAC5B,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;oBAC5B,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxD,CAAC,CAAC;YACL,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAClD,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,OAAO,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAEO,UAAU,CAChB,OAAoB,EACpB,KAAwC,EACxC,MAAmB,EACnB,MAA0B;QAE1B,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,SAAS,CACZ;gBACE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpD,MAAM;gBACN,MAAM,EAAE;oBACN,UAAU,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE;oBAC5C,GAAG,EAAE,MAAM,CAAC,GAAG;oBACf,MAAM,EAAE,MAAM,CAAC,MAAM;iBACtB;gBACD,OAAO;aACR,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,iBAAiB;QACjB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC5B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACtF,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC5B,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,EACzD,aAAa,CAAC,MAAM,CACrB,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACjD,MAAM,UAAU,GAAG,eAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,OAAO,UAAU,KAAK,UAAU,SAAS,WAAW,OAAO,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;QACxG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;;AA3PM,qBAAO,GAAG,4CAA4C,CAAC;AACvD,yBAAW,GAChB,qOAAqO,CAAC;AACjO,sBAAQ,GAAG;IAChB,kCAAkC;IAClC,kFAAkF;IAClF,wIAAwI;IACxI,wEAAwE;CACzE,CAAC;AACK,mBAAK,GAAG;IACb,MAAM,EAAE,YAAK,CAAC,MAAM,CAAC;QACnB,WAAW,EAAE,wCAAwC;QACrD,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,kBAAS;KACnB,CAAC;IACF,MAAM,EAAE,YAAK,CAAC,MAAM,CAAC;QACnB,WAAW,EACT,2FAA2F;QAC7F,QAAQ,EAAE,IAAI;KACf,CAAC;IACF,KAAK,EAAE,YAAK,CAAC,MAAM,CAAC;QAClB,WAAW,EAAE,gBAAgB;QAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;KAC/B,CAAC;IACF,KAAK,EAAE,YAAK,CAAC,OAAO,CAAC;QACnB,WAAW,EAAE,4DAA4D;QACzE,OAAO,EAAE,KAAK;KACf,CAAC;IACF,IAAI,EAAE,YAAK,CAAC,OAAO,CAAC;QAClB,WAAW,EAAE,8BAA8B;QAC3C,OAAO,EAAE,KAAK;KACf,CAAC;IACF,KAAK,EAAE,YAAK,CAAC,OAAO,CAAC;QACnB,WAAW,EAAE,6BAA6B;QAC1C,OAAO,EAAE,KAAK;KACf,CAAC;CACH,CAAC;kBArCiB,aAAa"} |
@@ -1,2 +0,1 @@ | ||
| import { type Config } from '@oclif/core'; | ||
| export type AgentId = 'claude' | 'cursor' | 'codex'; | ||
@@ -12,10 +11,8 @@ export type Scope = 'project' | 'global'; | ||
| export declare const AGENTS: Record<AgentId, AgentSpec>; | ||
| export declare function skillsRoot(config: Config): string; | ||
| export declare function sourceSkillMd(config: Config, skillName: string): string; | ||
| export declare function targetSkillMd(agent: AgentSpec, scope: Scope, skillName: string): string; | ||
| export declare function targetSkillDir(agent: AgentSpec, scope: Scope, skillName: string): string; | ||
| export type PlanKind = 'install' | 'unchanged' | 'conflict'; | ||
| export declare function planSkillFileCopy(sourceFile: string, targetFile: string): { | ||
| export declare function planSkillDirectoryCopy(sourceDir: string, targetDir: string): { | ||
| kind: PlanKind; | ||
| }; | ||
| export declare function applySkillFileCopy(sourceFile: string, targetFile: string): void; | ||
| export declare function applySkillDirectoryCopy(sourceDir: string, targetDir: string): void; | ||
| //# sourceMappingURL=skills.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AACpD,MAAM,MAAM,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,OAAO,EAAkC,CAAC;AAElE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;IAChC,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;CACxC;AAcD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,CAsC7C,CAAC;AAEF,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvF;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAE5D,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAO5F;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAG/E"} | ||
| {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AACpD,MAAM,MAAM,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEzC,eAAO,MAAM,SAAS,EAAE,OAAO,EAAkC,CAAC;AAElE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;IAChC,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;CACxC;AAcD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,CAsC7C,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAExF;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAgD5D,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAQ/F;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAqClF"} |
+92
-21
@@ -7,7 +7,5 @@ "use strict"; | ||
| exports.AGENTS = exports.AGENT_IDS = void 0; | ||
| exports.skillsRoot = skillsRoot; | ||
| exports.sourceSkillMd = sourceSkillMd; | ||
| exports.targetSkillMd = targetSkillMd; | ||
| exports.planSkillFileCopy = planSkillFileCopy; | ||
| exports.applySkillFileCopy = applySkillFileCopy; | ||
| exports.targetSkillDir = targetSkillDir; | ||
| exports.planSkillDirectoryCopy = planSkillDirectoryCopy; | ||
| exports.applySkillDirectoryCopy = applySkillDirectoryCopy; | ||
| const fs_1 = __importDefault(require("fs")); | ||
@@ -18,3 +16,3 @@ const path_1 = __importDefault(require("path")); | ||
| function claudeGlobalRoot() { | ||
| const override = process.env.CLAUDE_CONFIG_DIR; | ||
| const override = process.env['CLAUDE_CONFIG_DIR']; | ||
| if (override) | ||
@@ -25,3 +23,3 @@ return path_1.default.resolve(override); | ||
| function codexGlobalRoot() { | ||
| const override = process.env.CODEX_HOME; | ||
| const override = process.env['CODEX_HOME']; | ||
| if (override) | ||
@@ -64,23 +62,96 @@ return path_1.default.resolve(override); | ||
| }; | ||
| function skillsRoot(config) { | ||
| return path_1.default.join(config.root, 'skills'); | ||
| function targetSkillDir(agent, scope, skillName) { | ||
| return path_1.default.join(agent.skillsDir(scope), skillName); | ||
| } | ||
| function sourceSkillMd(config, skillName) { | ||
| return path_1.default.join(skillsRoot(config), skillName, 'SKILL.md'); | ||
| function listRelativeFiles(root) { | ||
| const files = []; | ||
| function walk(current, relativePrefix) { | ||
| for (const entry of fs_1.default.readdirSync(current, { withFileTypes: true })) { | ||
| const relativePath = path_1.default.join(relativePrefix, entry.name); | ||
| const fullPath = path_1.default.join(current, entry.name); | ||
| if (entry.isDirectory()) { | ||
| walk(fullPath, relativePath); | ||
| } | ||
| else if (entry.isFile()) { | ||
| files.push(relativePath); | ||
| } | ||
| else { | ||
| files.push(relativePath); | ||
| } | ||
| } | ||
| } | ||
| walk(root, ''); | ||
| return files.sort(); | ||
| } | ||
| function targetSkillMd(agent, scope, skillName) { | ||
| return path_1.default.join(agent.skillsDir(scope), skillName, 'SKILL.md'); | ||
| function directoriesEqual(sourceDir, targetDir) { | ||
| const sourceFiles = listRelativeFiles(sourceDir); | ||
| const targetFiles = listRelativeFiles(targetDir); | ||
| if (sourceFiles.length !== targetFiles.length) | ||
| return false; | ||
| for (let i = 0; i < sourceFiles.length; i += 1) { | ||
| const sourceFile = sourceFiles[i]; | ||
| const targetFile = targetFiles[i]; | ||
| if (sourceFile === undefined || targetFile === undefined || sourceFile !== targetFile) | ||
| return false; | ||
| const sourcePath = path_1.default.join(sourceDir, sourceFile); | ||
| const targetPath = path_1.default.join(targetDir, targetFile); | ||
| const sourceStat = fs_1.default.lstatSync(sourcePath); | ||
| const targetStat = fs_1.default.lstatSync(targetPath); | ||
| if (!sourceStat.isFile() || !targetStat.isFile()) | ||
| return false; | ||
| if (sourceStat.size !== targetStat.size) | ||
| return false; | ||
| const sourceBuf = fs_1.default.readFileSync(sourcePath); | ||
| const targetBuf = fs_1.default.readFileSync(targetPath); | ||
| if (!sourceBuf.equals(targetBuf)) | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| function planSkillFileCopy(sourceFile, targetFile) { | ||
| if (!fs_1.default.existsSync(targetFile)) { | ||
| function planSkillDirectoryCopy(sourceDir, targetDir) { | ||
| if (!fs_1.default.existsSync(targetDir)) { | ||
| return { kind: 'install' }; | ||
| } | ||
| const sourceBuf = fs_1.default.readFileSync(sourceFile); | ||
| const targetBuf = fs_1.default.readFileSync(targetFile); | ||
| return { kind: sourceBuf.equals(targetBuf) ? 'unchanged' : 'conflict' }; | ||
| if (!fs_1.default.lstatSync(targetDir).isDirectory()) { | ||
| return { kind: 'conflict' }; | ||
| } | ||
| return { kind: directoriesEqual(sourceDir, targetDir) ? 'unchanged' : 'conflict' }; | ||
| } | ||
| function applySkillFileCopy(sourceFile, targetFile) { | ||
| fs_1.default.mkdirSync(path_1.default.dirname(targetFile), { recursive: true }); | ||
| fs_1.default.copyFileSync(sourceFile, targetFile); | ||
| function applySkillDirectoryCopy(sourceDir, targetDir) { | ||
| const parentDir = path_1.default.dirname(targetDir); | ||
| const baseName = path_1.default.basename(targetDir); | ||
| const suffix = `${process.pid}-${Date.now()}`; | ||
| const tempDir = path_1.default.join(parentDir, `.${baseName}.tmp-${suffix}`); | ||
| const backupDir = path_1.default.join(parentDir, `.${baseName}.backup-${suffix}`); | ||
| let backedUp = false; | ||
| let installed = false; | ||
| fs_1.default.mkdirSync(parentDir, { recursive: true }); | ||
| try { | ||
| fs_1.default.cpSync(sourceDir, tempDir, { recursive: true }); | ||
| if (fs_1.default.existsSync(targetDir)) { | ||
| fs_1.default.renameSync(targetDir, backupDir); | ||
| backedUp = true; | ||
| } | ||
| fs_1.default.renameSync(tempDir, targetDir); | ||
| installed = true; | ||
| } | ||
| catch (err) { | ||
| if (backedUp && !installed && !fs_1.default.existsSync(targetDir) && fs_1.default.existsSync(backupDir)) { | ||
| try { | ||
| fs_1.default.renameSync(backupDir, targetDir); | ||
| backedUp = false; | ||
| } | ||
| catch { | ||
| // Preserve the original error; rollback failure leaves the backup for manual recovery. | ||
| } | ||
| } | ||
| throw err; | ||
| } | ||
| finally { | ||
| fs_1.default.rmSync(tempDir, { recursive: true, force: true }); | ||
| if (installed || !backedUp) { | ||
| fs_1.default.rmSync(backupDir, { recursive: true, force: true }); | ||
| } | ||
| } | ||
| } | ||
| //# sourceMappingURL=skills.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"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"} |
+1
-2
| { | ||
| "name": "@limrun/cli", | ||
| "version": "0.8.6", | ||
| "version": "0.9.0", | ||
| "description": "Use remote XCode, iOS Simulator, Android Emulator and more to build and test apps from Linux, Windows or macOS.", | ||
@@ -76,5 +76,4 @@ "bin": { | ||
| "bin", | ||
| "skills", | ||
| "README.md" | ||
| ] | ||
| } |
+13
-4
@@ -619,3 +619,3 @@ # @limrun/cli | ||
| Install Limrun skills into the native skills directory of AI coding agents (Claude Code, Cursor, Codex). After installation, the agent auto-discovers the skill and triggers it when you ask things like "build the iOS app" or "show me a screenshot." | ||
| Fetch the latest Limrun skills from `limrun-inc/skills@main` and install them into the native skills directory of AI coding agents (Claude Code, Cursor, Codex). After installation, the agent auto-discovers the skill and triggers it when you ask things like "build the iOS app" or "show me a screenshot." | ||
@@ -630,4 +630,5 @@ ```bash | ||
| lim skills install --agents codex --scope global | ||
| lim skills install --agents cursor --scope project --skills limrun-expo-development | ||
| # Overwrite existing skill files (otherwise the command refuses on non-interactive runs) | ||
| # Overwrite existing skill directories (otherwise the command refuses on non-interactive runs) | ||
| lim skills install --agents claude --scope project --force | ||
@@ -644,7 +645,14 @@ | ||
| | `--agents <id>` | Target agent. Repeat to select multiple. One of: `claude`, `cursor`, `codex`. | | ||
| | `--skills <name>` | Limrun skill to install. Repeat to select multiple. Defaults to the remote catalog default. | | ||
| | `--scope <project\|global>` | `project` writes into the current directory; `global` writes into the user's home directory. | | ||
| | `--force` | Overwrite existing skill files without confirmation. | | ||
| | `--force` | Overwrite existing skill directories without confirmation. | | ||
| | `--json` | Emit structured JSON instead of the human summary. | | ||
| | `--quiet` | Suppress non-result output. | | ||
| **Available skills:** | ||
| - `limrun-xcode-and-ios-simulator` (default): Build, launch, and control iOS apps with remote XCode and Simulators. | ||
| - `limrun-expo-development`: Iterate on Expo / React Native apps with remote iOS dev-client workflows. | ||
| - `limrun-detox-testing`: Configure, run, and debug Detox against Limrun iOS simulators. | ||
| **Install paths:** | ||
@@ -660,3 +668,4 @@ | ||
| - The command compares bundled vs existing content byte-for-byte. Identical content is reported as `Unchanged` (no writes). | ||
| - The command fetches `limrun-inc/skills@main` at runtime, so skill updates do not require a new `@limrun/cli` release. | ||
| - The command compares fetched vs existing skill directories byte-for-byte. Identical content is reported as `Unchanged` (no writes). | ||
| - Different content: in interactive mode you are asked to confirm each overwrite; in non-interactive mode the command refuses unless `--force` is passed. | ||
@@ -663,0 +672,0 @@ - Non-interactive runs are all-or-nothing: if any selected target conflicts and `--force` is not set, no files are written for any target, and the command exits with status 1. |
| --- | ||
| name: limrun-detox | ||
| description: Configure, run, or debug Detox on Limrun iOS simulators. Use when attaching the Limrun Detox runtime to an app, wiring Detox mediator connectivity, or validating app/tester connections over reverse tunnels. | ||
| --- | ||
| # Limrun Detox | ||
| Use this for Detox runtime work on Limrun iOS. Keep build concerns separate unless the user explicitly asks for a native build. | ||
| ## Components | ||
| - Tester: local Node/Jest/Detox process. | ||
| - Mediator: `detox run-server`, usually local to the agent machine. | ||
| - App client: injected by limulator through `lim ios launch-app --runtime detox`. | ||
| ## CLI Flow | ||
| Check current help before running commands you have not used in this session: | ||
| ```bash | ||
| lim ios reverse --help | ||
| lim ios launch-app --help | ||
| ``` | ||
| Typical sequence: | ||
| ```bash | ||
| # Start the Detox mediator locally. | ||
| npx detox run-server -p 8099 -l verbose | ||
| # Expose the mediator to the simulator. | ||
| lim ios reverse 57091:8099 --id <ios-id> | ||
| # Relaunch the app with the managed Detox runtime. Use the remote endpoint | ||
| # printed by `lim ios reverse`, not 127.0.0.1 on the user machine. | ||
| # --detox-version is optional when running from the project with node_modules/detox. | ||
| lim ios launch-app <bundle-id> \ | ||
| --id <ios-id> \ | ||
| --runtime detox \ | ||
| --detox-server-url ws://<reverse-remote-host>:57091 \ | ||
| --detox-session-id <session-id> \ | ||
| --detox-version <detox-version> | ||
| # Run the tester with the same server/session. | ||
| npx detox test --no-start | ||
| ``` | ||
| Prefer starting the tester before the app connects, or use the maintained orchestration in `examples/detox-ios`, to avoid benign mediator "cannot forward" noise. | ||
| If you manually launch the app before `npx detox test --no-start`, that mediator message is expected until the tester connects. | ||
| ## Detox Test Setup | ||
| `npx detox test --no-start` still needs the normal Detox project configuration: | ||
| - Pass the Detox config file and configuration name from your project (see `examples/detox-ios/.detoxrc.cjs` for a reference layout). | ||
| - Use the Limrun third-party driver: `type: '@limrun/detox/driver'`. | ||
| - Keep `DETOX_SERVER` and `DETOX_SESSION_ID` aligned with the mediator and launch command. | ||
| - Provide Limrun driver env such as `LIMRUN_IOS_ID`, `LIMRUN_IOS_API_URL`, and `LIMRUN_IOS_TOKEN` when screenshots or driver calls need the instance API. | ||
| Use `examples/detox-ios` as the maintained happy path for exact config/env wiring. Use `-l trace` on `detox run-server` only when verbose logs are not enough. | ||
| For native SwiftUI apps, a minimal Detox configuration usually looks like: | ||
| ```js | ||
| module.exports = { | ||
| testRunner: { args: { $0: 'jest' }, jest: { setupTimeout: 120000 } }, | ||
| apps: { ios: { type: 'ios.app', binaryPath: 'unused-by-limrun' } }, | ||
| devices: { | ||
| limrun: { | ||
| type: '@limrun/detox/driver', | ||
| device: { id: process.env.LIMRUN_IOS_ID }, | ||
| }, | ||
| }, | ||
| configurations: { | ||
| 'ios.limrun': { | ||
| device: 'limrun', | ||
| app: 'ios', | ||
| behavior: { init: { reinstallApp: false }, cleanup: { shutdownDevice: false } }, | ||
| }, | ||
| }, | ||
| }; | ||
| ``` | ||
| Then launch with `lim ios launch-app <bundle-id> --runtime detox ...` and run `npx detox test --no-start`. | ||
| ## Validation Signals | ||
| - App connected: `detox run-server` logs `role:"app"` and `appConnected:true`. | ||
| - Tester connected: the same session reaches `testerConnected:true, appConnected:true`. | ||
| - Runtime loaded: the app connects to the mediator after the `--runtime detox` launch. | ||
| - UI visible: `lim ios element-tree --id <ios-id>` shows the expected app screen. | ||
| ## Gotchas | ||
| - Do not pass arbitrary env vars, app args, or injectable paths. Use `--runtime detox`. | ||
| - `--detox-version` should match the local `detox` package version used by the tester. If omitted, `lim ios launch-app` resolves it from the current working directory; pass it explicitly when running outside the Detox project. | ||
| - Unsupported bundled Detox versions should fail with a clear supported-version list. | ||
| - `Cannot forward the message to the Detox client` can simply mean the app connected before the tester did. | ||
| - For SwiftUI, prefer stable accessibility identifiers, e.g. `.accessibilityIdentifier("greetingText")` with `by.id('greetingText')`; `by.text(...)` can miss labels that appear in `lim ios element-tree`. | ||
| - Debug failures by checking `lim ios element-tree --id <ios-id>` first, then mediator logs for app/tester connection state. | ||
| - Cleanup manual runs by stopping `detox run-server`, stopping `lim ios reverse`, and deleting the instance with `lim ios delete <ios-id>` (`--id` is not valid for delete). | ||
| - This does not make Detox own the iOS lifecycle; prepare or reuse the Limrun instance separately. |
| --- | ||
| name: limrun-skill | ||
| description: "Replaces xcodebuild with remote XCode and Simulators. Use when the user wants to build or run an iOS app, test iOS UI, see their app on a simulator, or says 'run it', 'build it', 'test it', 'show me a screenshot', or 'launch on simulator'." | ||
| user-invocable: true | ||
| effort: high | ||
| --- | ||
| # Remote XCode & iOS Simulator | ||
| You are an iOS build-and-test operator. Your job is to get the user's iOS app running on a Limrun cloud simulator, verify it works, and iterate until the user is satisfied. | ||
| All builds and simulator operations run on Limrun and that's why you can build iOS | ||
| apps from any environments; linux, windows, macos, VM, container etc. Never try to | ||
| use local Xcode, local simulators, or local macOS build tools. | ||
| If `lim` CLI is not installed, you can install it with the following: | ||
| ```bash | ||
| npm install --global @limrun/cli | ||
| ``` | ||
| ## Check the CLI for current commands and flags | ||
| The CLI is the source of truth for command names, flags, and behavior. Before invoking any `lim` command you have not already used in this session, MUST run its `--help` first. Use: | ||
| ```bash | ||
| lim ios --help # list all iOS subcommands | ||
| lim ios <subcommand> --help # flags and examples for one iOS subcommand | ||
| lim xcode --help # list all xcode subcommands | ||
| lim xcode <subcommand> --help # flags and examples for one xcode subcommand | ||
| lim session --help # list all session subcommands | ||
| lim session <subcommand> --help # flags and examples for one session subcommand | ||
| ``` | ||
| ## Build and Reload | ||
| First, create an XCode & iOS Simulator pair: | ||
| ```bash | ||
| # Add label selector depending on your identifiers. For example, Linear issue, repo name etc. | ||
| lim ios create --xcode \ | ||
| --reuse-if-exists \ | ||
| --label issue=<ISSUE ID> \ | ||
| --label repo=<Repo Name> \ | ||
| --label agent=<Your Agent Name> | ||
| # Example call: lim xcode create --reuse-if-exists --label issue=LIM-34 --label repo=sample-native-app --label agent=cursor | ||
| ``` | ||
| In the command output, there will be a signed stream URL. Share that with user so that they can watch the simulator while you are working. | ||
| If you have a browser that user can see, open the signed stream URL in that browser and notify the user. | ||
| ### Build | ||
| Instead of `xcodebuild` command, you MUST use the following to build the iOS app. | ||
| ```bash | ||
| lim xcode build . | ||
| ``` | ||
| Use `--scheme` and `--workspace` flags if the project has multiple schemes or uses a workspace file. This makes sure the files are synced with the remote xcode and triggers | ||
| a build where the build logs are streamed through stdout and stderr. | ||
| Use `--configuration Debug` or `--configuration Release` when the app needs a specific Xcode build configuration: | ||
| ```bash | ||
| lim xcode build . --configuration Debug | ||
| ``` | ||
| If omitted, Limrun uses limbuild's project-type default: `Debug` for native Xcode builds and `Release` for React Native / Expo builds. `--dev-server-url` is only supported with `--configuration Debug` for React Native / Expo builds. It is a post-install launch URL: limbuild validates that it is a parseable absolute URL, then opens it unchanged after installing on the attached simulator. | ||
| For Expo dev-client builds, do not use plain `exp://`; Expo Go may intercept it. Use the app scheme: `expo.scheme` from `app.json` when present, otherwise Expo dev-client's generated default `exp+{expo.slug}`. | ||
| When Metro runs locally, prefer a same-port reverse tunnel. Expo dev-client can derive or rediscover Metro URLs, so matching the remote tunnel port and local Metro port avoids stale or unreachable advertised ports. Use the simulator-facing host printed by `lim ios reverse` in both `REACT_NATIVE_PACKAGER_HOSTNAME` and the encoded dev-client URL. | ||
| ```bash | ||
| # app.json: "scheme": "myapp" or fallback "slug": "myapp" -> exp+myapp | ||
| lim ios reverse 57090:57090 --id <ios-instance-id> | ||
| REACT_NATIVE_PACKAGER_HOSTNAME=<reverse-host> \ | ||
| npx expo start --dev-client --host lan --port 57090 | ||
| lim xcode build . --configuration Debug \ | ||
| --dev-server-url 'myapp://expo-development-client/?url=http%3A%2F%2F<reverse-host>%3A57090' | ||
| ``` | ||
| If the app launches without connecting to Metro, open the same URL explicitly to separate build/install issues from dev-client URL issues: | ||
| ```bash | ||
| lim ios open-url --id <ios-instance-id> \ | ||
| 'myapp://expo-development-client/?url=http%3A%2F%2F<reverse-host>%3A57090' | ||
| ``` | ||
| Mismatched tunnels such as `57090:8081` can work for plain TCP, but Expo dev-client is stricter because multiple URLs may be derived or advertised. Only use mismatched ports after verifying every dev-client URL points to the remote tunnel port, not the local Metro port. | ||
| Every successful build will automatically re-install the app in iOS Simulator and re-launch it. | ||
| ## Interacting with the App | ||
| Prefer tapping by accessibility identifier, then by label, then by coordinates as a last resort: | ||
| ```bash | ||
| lim ios tap-element --ax-unique-id startButton | ||
| lim ios tap-element --ax-label "Save" | ||
| lim ios tap 201 450 | ||
| ``` | ||
| After every interaction, re-run `element-tree` to confirm the UI transitioned correctly. No sleep is needed between a tap and element-tree. | ||
| For text input: | ||
| ```bash | ||
| lim ios type "hello world" | ||
| ``` | ||
| ## Testing Changes | ||
| After every build, test new or changed functionality by using interaction commands. Focus on what changed plus a quick smoke test of core flows. | ||
| Use element tree for functional assertions (element existence, labels, state changes). Use screenshots only for visual-only properties. | ||
| Use video recording for most accurate interaction tests such as animations, gameplay, | ||
| real experience etc. | ||
| Generally, start with getting an element tree: | ||
| ```bash | ||
| lim ios element-tree | ||
| ``` | ||
| Then if a single action will be taken, just call it. For example: | ||
| ```bash | ||
| lim ios tap-element --ax-label Continue | ||
| ``` | ||
| If you will take multiple actions, you can create a chain of actions to be executed | ||
| with precise timing. | ||
| Some examples: | ||
| ```bash | ||
| lim ios perform --action type=tap,x=100,y=200 --action "type=typeText,text=Hello World" | ||
| lim ios perform --action type=wait,durationMs=1000 --action type=pressKey,key=enter | ||
| ``` | ||
| You can write to a file and execute that too: | ||
| ```bash | ||
| lim ios perform --file ./actions.yaml | ||
| ``` | ||
| Use `lim ios perform --help` for more details on how to use it. | ||
| Video recording is available so you can review what the user sees while you are taking actions. For | ||
| any testing involving motion prefer video over screenshots for review. | ||
| Always include a demo video in the pull request so that user can see how it works. | ||
| Start recording (non-blocking): | ||
| ```bash | ||
| lim ios record start | ||
| ``` | ||
| Stop and save recording: | ||
| ```bash | ||
| lim ios record stop -o /tmp/recording.mp4 | ||
| ``` | ||
| ## Finalize | ||
| When you are done with the changes and present to the user, you should provide a | ||
| preview link to the user so they can test it. | ||
| If you will open a PR, make sure to do this and add the preview link to PR. | ||
| First build and make remote xcode upload the build: | ||
| ``` | ||
| ASSET_NAME="<bundle id/pr number/ or any session identifier>.zip" | ||
| lim xcode build . --upload ${ASSET_NAME} | ||
| # For a debug preview build: | ||
| lim xcode build . --configuration Debug --upload ${ASSET_NAME} | ||
| ``` | ||
| And construct this link for preview: | ||
| ``` | ||
| # Change ${ASSET_NAME} with asset name given above | ||
| https://console.limrun.com/preview?asset=${ASSET_NAME}&platform=ios | ||
| ``` | ||
| Always provide this in your last message. | ||
| ## Cleanup | ||
| When the user is satisfied or the conversation is ending, always clean up: | ||
| ```bash | ||
| lim ios delete | ||
| ``` | ||
| ## Gotchas | ||
| These are common failure points. Check here first when something goes wrong. | ||
| - **Instance ID is optional.** The CLI remembers the last created instance. You only need to pass an ID explicitly when controlling multiple instances. | ||
| - **No sleep needed between `tap-element` and `element-tree`.** The tap blocks until complete. | ||
| - **`element-tree` can be large.** Pipe through `grep` or `jq` to extract what you need rather than dumping the full tree into context. | ||
| - **Build errors are your job to fix.** If a build fails, read the error output, fix the code, and rebuild. Do not ask the user to fix build errors. | ||
| - **Bundle ID discovery.** If you don't know the bundle ID, check the Xcode project files or run `lim ios list-apps` after a successful build. | ||
| - **Expo dev-client redbox `Operation not permitted` usually means the simulator cannot reach the advertised Metro URL.** First use same-port reverse mapping such as `57090:57090`; do not add iOS ATS/local-network Info.plist exceptions unless a same-port tunnel still fails. | ||
| - **Monorepos need the workspace root.** Build from the repo root and pass `--expo-app-dir <app-path>` so the remote resolver sees the lockfile and workspace metadata. |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
690168
2.82%320
0.63%8638
4.7%822
1.11%26
13.04%6
20%