(srcPath: string, originalSource: string, opts: { force?: boolean })
| 61 | } |
| 62 | |
| 63 | async function installFromLocal(srcPath: string, originalSource: string, opts: { force?: boolean }): Promise<InstallResult> { |
| 64 | const stat = await fs.stat(srcPath); |
| 65 | if (stat.isFile()) { |
| 66 | if (/\.tgz$|\.tar\.gz$|\.tar$/i.test(srcPath)) { |
| 67 | const tmp = await mkdtempIn(os.tmpdir(), 'qodex-skill-tgz-'); |
| 68 | runOrThrow('tar', ['-xzf', srcPath, '-C', tmp], 'extract tarball'); |
| 69 | const extracted = await findSkillRoot(tmp); |
| 70 | return copyInto(extracted, originalSource, opts); |
| 71 | } |
| 72 | throw new Error(`Expected a directory, .tgz, or .tar.gz — got: ${srcPath}`); |
| 73 | } |
| 74 | if (!stat.isDirectory()) throw new Error(`Source is not a file or directory: ${srcPath}`); |
| 75 | const root = await findSkillRoot(srcPath); |
| 76 | return copyInto(root, originalSource, opts); |
| 77 | } |
| 78 | |
| 79 | async function installFromGithub(spec: string, originalSource: string, opts: { force?: boolean }): Promise<InstallResult> { |
| 80 | // spec is like "user/repo" or "user/repo@ref" |
no test coverage detected