@skild/core 0.10.22 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ declare class SkildError extends Error {
5
5
  constructor(code: SkildErrorCode, message: string, details?: Record<string, unknown>);
6
6
  }
7
7
 
8
- declare const PLATFORMS: readonly ["claude", "codex", "copilot", "antigravity", "opencode", "cursor", "windsurf"];
8
+ declare const PLATFORMS: readonly ["claude", "codex", "copilot", "antigravity", "opencode", "cursor", "windsurf", "agents"];
9
9
  type Platform = (typeof PLATFORMS)[number];
10
10
  type InstallScope = 'global' | 'project';
11
11
  type SourceType = 'local' | 'github-url' | 'degit-shorthand' | 'registry';
@@ -112,6 +112,9 @@ interface GlobalConfig {
112
112
  schemaVersion: 1;
113
113
  defaultPlatform: Platform;
114
114
  defaultScope: InstallScope;
115
+ push?: {
116
+ defaultRepo?: string;
117
+ };
115
118
  }
116
119
  interface RegistryAuth {
117
120
  schemaVersion: 1;
@@ -126,6 +129,7 @@ interface RegistryAuth {
126
129
  }
127
130
 
128
131
  declare function loadOrCreateGlobalConfig(): GlobalConfig;
132
+ declare function saveGlobalConfig(config: GlobalConfig): void;
129
133
  declare function loadRegistryAuth(): RegistryAuth | null;
130
134
  declare function saveRegistryAuth(auth: RegistryAuth): void;
131
135
  declare function clearRegistryAuth(): void;
@@ -251,4 +255,4 @@ declare function uninstallSkill(name: string, options?: InstallOptions & {
251
255
  }): void;
252
256
  declare function updateSkill(name?: string, options?: UpdateOptions): Promise<InstallRecord[]>;
253
257
 
254
- export { DEFAULT_REGISTRY_URL, type DependencySourceType, type GlobalConfig, type InstallOptions, type InstallRecord, type InstallScope, type InstalledDependency, type ListOptions, type Lockfile, PLATFORMS, type Platform, type RegistryAuth, SkildError, type SkillFrontmatter, type SkillValidationIssue, type SkillValidationResult, type UpdateOptions, assertValidAlias, canonicalNameToInstallDirName, clearRegistryAuth, deriveChildSource, downloadAndExtractTarball, fetchWithTimeout, getSkillInfo, getSkillInstallDir, getSkillsDir, initSkill, installRegistrySkill, installSkill, isValidAlias, listAllSkills, listSkills, loadOrCreateGlobalConfig, loadRegistryAuth, materializeSourceToDir, materializeSourceToTemp, normalizeAlias, parseRegistrySpecifier, parseSkillFrontmatter, readSkillMd, resolveRegistryAlias, resolveRegistryUrl, resolveRegistryVersion, saveRegistryAuth, searchRegistrySkills, splitCanonicalName, stripSourceRef, toDegitPath, uninstallSkill, updateSkill, validateSkill, validateSkillDir };
258
+ export { DEFAULT_REGISTRY_URL, type DependencySourceType, type GlobalConfig, type InstallOptions, type InstallRecord, type InstallScope, type InstalledDependency, type ListOptions, type Lockfile, PLATFORMS, type Platform, type RegistryAuth, SkildError, type SkillFrontmatter, type SkillValidationIssue, type SkillValidationResult, type UpdateOptions, assertValidAlias, canonicalNameToInstallDirName, clearRegistryAuth, deriveChildSource, downloadAndExtractTarball, fetchWithTimeout, getSkillInfo, getSkillInstallDir, getSkillsDir, initSkill, installRegistrySkill, installSkill, isValidAlias, listAllSkills, listSkills, loadOrCreateGlobalConfig, loadRegistryAuth, materializeSourceToDir, materializeSourceToTemp, normalizeAlias, parseRegistrySpecifier, parseSkillFrontmatter, readSkillMd, resolveRegistryAlias, resolveRegistryUrl, resolveRegistryVersion, saveGlobalConfig, saveRegistryAuth, searchRegistrySkills, splitCanonicalName, stripSourceRef, toDegitPath, uninstallSkill, updateSkill, validateSkill, validateSkillDir };
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ var SkildError = class extends Error {
10
10
  };
11
11
 
12
12
  // src/types.ts
13
- var PLATFORMS = ["claude", "codex", "copilot", "antigravity", "opencode", "cursor", "windsurf"];
13
+ var PLATFORMS = ["claude", "codex", "copilot", "antigravity", "opencode", "cursor", "windsurf", "agents"];
14
14
 
15
15
  // src/storage.ts
16
16
  import fs2 from "fs";
@@ -51,6 +51,8 @@ function getSkillsDir(platform, scope) {
51
51
  return scope === "project" ? path.join(getProjectDir(), ".cursor", "skills") : path.join(getHomeDir(), ".cursor", "skills");
52
52
  case "windsurf":
53
53
  return scope === "project" ? path.join(getProjectDir(), ".windsurf", "skills") : path.join(getHomeDir(), ".windsurf", "skills");
54
+ case "agents":
55
+ return scope === "project" ? path.join(getProjectDir(), ".agents", "skills") : path.join(getHomeDir(), ".agents", "skills");
54
56
  }
55
57
  }
56
58
  function getProjectSkildDir() {
@@ -124,18 +126,30 @@ function sanitizeLockfile(lockfile) {
124
126
  );
125
127
  return { ...lockfile, entries };
126
128
  }
129
+ var GLOBAL_CONFIG_DEFAULTS = {
130
+ schemaVersion: 1,
131
+ defaultPlatform: PLATFORMS[0],
132
+ defaultScope: "global"
133
+ };
134
+ function applyGlobalConfigDefaults(existing) {
135
+ if (!existing) return { ...GLOBAL_CONFIG_DEFAULTS };
136
+ return {
137
+ ...GLOBAL_CONFIG_DEFAULTS,
138
+ ...existing,
139
+ push: existing.push ? { ...existing.push } : void 0
140
+ };
141
+ }
127
142
  function loadOrCreateGlobalConfig() {
128
143
  const filePath = getGlobalConfigPath();
129
144
  const existing = readJsonFile(filePath);
130
- if (existing) return existing;
131
- const created = {
132
- schemaVersion: 1,
133
- defaultPlatform: PLATFORMS[0],
134
- defaultScope: "global"
135
- };
145
+ if (existing) return applyGlobalConfigDefaults(existing);
146
+ const created = applyGlobalConfigDefaults();
136
147
  writeJsonFile(filePath, created);
137
148
  return created;
138
149
  }
150
+ function saveGlobalConfig(config) {
151
+ writeJsonFile(getGlobalConfigPath(), applyGlobalConfigDefaults(config));
152
+ }
139
153
  function loadRegistryAuth() {
140
154
  return readJsonFile(getGlobalRegistryAuthPath());
141
155
  }
@@ -331,6 +345,7 @@ import fs6 from "fs";
331
345
  import os2 from "os";
332
346
  import path7 from "path";
333
347
  import degit from "degit";
348
+ import simpleGit from "simple-git";
334
349
 
335
350
  // src/source.ts
336
351
  import path6 from "path";
@@ -491,6 +506,81 @@ function resetTargetDir(targetPath) {
491
506
  removeDir(targetPath);
492
507
  fs6.mkdirSync(targetPath, { recursive: true });
493
508
  }
509
+ function splitSourceRef(source) {
510
+ const [base, ref] = source.split("#", 2);
511
+ return { base, ref: ref?.trim() || void 0 };
512
+ }
513
+ function parseGitCloneSpec(source) {
514
+ const trimmed = source.trim();
515
+ if (!trimmed) return null;
516
+ if (resolveLocalPath(trimmed)) return null;
517
+ const { base, ref } = splitSourceRef(trimmed);
518
+ const githubTreeWithPathMatch = base.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)/);
519
+ if (githubTreeWithPathMatch) {
520
+ const [, owner, repo, branch, subpath] = githubTreeWithPathMatch;
521
+ return { url: `https://github.com/${owner}/${repo}.git`, ref: branch, subpath };
522
+ }
523
+ const githubTreeMatch = base.match(/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)$/);
524
+ if (githubTreeMatch) {
525
+ const [, owner, repo, branch] = githubTreeMatch;
526
+ return { url: `https://github.com/${owner}/${repo}.git`, ref: branch };
527
+ }
528
+ const githubRepoMatch = base.match(/github\.com\/([^/]+)\/([^/]+)/);
529
+ if (githubRepoMatch) {
530
+ const [, owner, repoRaw] = githubRepoMatch;
531
+ const repo = repoRaw.replace(/\.git$/, "");
532
+ return { url: `https://github.com/${owner}/${repo}.git`, ref };
533
+ }
534
+ const gitlabTreeWithPathMatch = base.match(/gitlab\.com\/([^/]+)\/([^/]+)\/-\/tree\/([^/]+)\/(.+)/);
535
+ if (gitlabTreeWithPathMatch) {
536
+ const [, owner, repo, branch, subpath] = gitlabTreeWithPathMatch;
537
+ return { url: `https://gitlab.com/${owner}/${repo}.git`, ref: branch, subpath };
538
+ }
539
+ const gitlabTreeMatch = base.match(/gitlab\.com\/([^/]+)\/([^/]+)\/-\/tree\/([^/]+)$/);
540
+ if (gitlabTreeMatch) {
541
+ const [, owner, repo, branch] = gitlabTreeMatch;
542
+ return { url: `https://gitlab.com/${owner}/${repo}.git`, ref: branch };
543
+ }
544
+ const gitlabRepoMatch = base.match(/gitlab\.com\/([^/]+)\/([^/]+)/);
545
+ if (gitlabRepoMatch) {
546
+ const [, owner, repoRaw] = gitlabRepoMatch;
547
+ const repo = repoRaw.replace(/\.git$/, "");
548
+ return { url: `https://gitlab.com/${owner}/${repo}.git`, ref };
549
+ }
550
+ const shorthandMatch = base.match(/^([^/]+)\/([^/]+)(?:\/(.+))?$/);
551
+ if (shorthandMatch && !base.includes(":") && !base.startsWith(".") && !base.startsWith("/")) {
552
+ const [, owner, repo, subpath] = shorthandMatch;
553
+ return { url: `https://github.com/${owner}/${repo}.git`, ref, subpath };
554
+ }
555
+ if (/^(https?:|git@|ssh:)/i.test(base)) {
556
+ return { url: base, ref };
557
+ }
558
+ return null;
559
+ }
560
+ async function cloneWithGit(spec, targetPath) {
561
+ const cloneOptions = spec.ref ? ["--depth", "1", "--branch", spec.ref] : ["--depth", "1"];
562
+ const git = simpleGit();
563
+ if (!spec.subpath) {
564
+ resetTargetDir(targetPath);
565
+ await git.clone(spec.url, targetPath, cloneOptions);
566
+ return spec.url;
567
+ }
568
+ const tempRoot = createTempDir(path7.join(os2.tmpdir(), "skild-git"), extractSkillName(spec.url));
569
+ try {
570
+ await git.clone(spec.url, tempRoot, cloneOptions);
571
+ const resolvedSubpath = path7.resolve(tempRoot, spec.subpath);
572
+ const resolvedRoot = path7.resolve(tempRoot);
573
+ if (!resolvedSubpath.startsWith(`${resolvedRoot}${path7.sep}`)) {
574
+ throw new SkildError("INVALID_SOURCE", `Subpath escapes repository root: ${spec.subpath}`, { subpath: spec.subpath });
575
+ }
576
+ ensureInstallableDir(resolvedSubpath);
577
+ resetTargetDir(targetPath);
578
+ copyDir(resolvedSubpath, targetPath);
579
+ return spec.url;
580
+ } finally {
581
+ removeDir(tempRoot);
582
+ }
583
+ }
494
584
  async function cloneRemote(degitSrc, targetPath, mode) {
495
585
  const emitter = degit(degitSrc, { force: true, verbose: false, mode });
496
586
  await emitter.clone(targetPath);
@@ -543,6 +633,14 @@ async function materializeSourceToDir(input) {
543
633
  copyDir(localPath, targetDir);
544
634
  return { sourceType: "local", materializedFrom: localPath };
545
635
  }
636
+ const gitSpec = parseGitCloneSpec(input.source);
637
+ if (gitSpec) {
638
+ try {
639
+ const materializedFrom2 = await cloneWithGit(gitSpec, targetDir);
640
+ return { sourceType, materializedFrom: materializedFrom2 };
641
+ } catch {
642
+ }
643
+ }
546
644
  const degitPath = toDegitPath(input.source);
547
645
  const materializedFrom = await cloneRemoteWithFallback(degitPath, targetDir);
548
646
  return { sourceType, materializedFrom };
@@ -1287,6 +1385,7 @@ export {
1287
1385
  resolveRegistryAlias,
1288
1386
  resolveRegistryUrl,
1289
1387
  resolveRegistryVersion,
1388
+ saveGlobalConfig,
1290
1389
  saveRegistryAuth,
1291
1390
  searchRegistrySkills,
1292
1391
  splitCanonicalName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skild/core",
3
- "version": "0.10.22",
3
+ "version": "0.13.0",
4
4
  "description": "Skild core library (headless) for installing, validating, and managing Agent Skills locally.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,6 +20,7 @@
20
20
  "degit": "^2.8.4",
21
21
  "js-yaml": "^4.1.0",
22
22
  "semver": "^7.6.3",
23
+ "simple-git": "^3.27.0",
23
24
  "tar": "^7.4.3"
24
25
  },
25
26
  "devDependencies": {