@nameczz/skill-sync 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +246 -0
  3. package/dist/src/autoSync.d.ts +36 -0
  4. package/dist/src/autoSync.js +235 -0
  5. package/dist/src/autoSync.js.map +1 -0
  6. package/dist/src/cli.d.ts +2 -0
  7. package/dist/src/cli.js +211 -0
  8. package/dist/src/cli.js.map +1 -0
  9. package/dist/src/codexArchive.d.ts +38 -0
  10. package/dist/src/codexArchive.js +340 -0
  11. package/dist/src/codexArchive.js.map +1 -0
  12. package/dist/src/config.d.ts +12 -0
  13. package/dist/src/config.js +78 -0
  14. package/dist/src/config.js.map +1 -0
  15. package/dist/src/copy.d.ts +1 -0
  16. package/dist/src/copy.js +42 -0
  17. package/dist/src/copy.js.map +1 -0
  18. package/dist/src/directoryPicker.d.ts +8 -0
  19. package/dist/src/directoryPicker.js +49 -0
  20. package/dist/src/directoryPicker.js.map +1 -0
  21. package/dist/src/format.d.ts +2 -0
  22. package/dist/src/format.js +27 -0
  23. package/dist/src/format.js.map +1 -0
  24. package/dist/src/frontmatter.d.ts +5 -0
  25. package/dist/src/frontmatter.js +36 -0
  26. package/dist/src/frontmatter.js.map +1 -0
  27. package/dist/src/git.d.ts +25 -0
  28. package/dist/src/git.js +227 -0
  29. package/dist/src/git.js.map +1 -0
  30. package/dist/src/hash.d.ts +1 -0
  31. package/dist/src/hash.js +34 -0
  32. package/dist/src/hash.js.map +1 -0
  33. package/dist/src/importSkill.d.ts +6 -0
  34. package/dist/src/importSkill.js +58 -0
  35. package/dist/src/importSkill.js.map +1 -0
  36. package/dist/src/init.d.ts +5 -0
  37. package/dist/src/init.js +13 -0
  38. package/dist/src/init.js.map +1 -0
  39. package/dist/src/installSkill.d.ts +6 -0
  40. package/dist/src/installSkill.js +62 -0
  41. package/dist/src/installSkill.js.map +1 -0
  42. package/dist/src/json.d.ts +2 -0
  43. package/dist/src/json.js +11 -0
  44. package/dist/src/json.js.map +1 -0
  45. package/dist/src/metadata.d.ts +11 -0
  46. package/dist/src/metadata.js +115 -0
  47. package/dist/src/metadata.js.map +1 -0
  48. package/dist/src/paths.d.ts +22 -0
  49. package/dist/src/paths.js +103 -0
  50. package/dist/src/paths.js.map +1 -0
  51. package/dist/src/removeLocalSkill.d.ts +5 -0
  52. package/dist/src/removeLocalSkill.js +79 -0
  53. package/dist/src/removeLocalSkill.js.map +1 -0
  54. package/dist/src/resolveConflict.d.ts +10 -0
  55. package/dist/src/resolveConflict.js +146 -0
  56. package/dist/src/resolveConflict.js.map +1 -0
  57. package/dist/src/scanner.d.ts +5 -0
  58. package/dist/src/scanner.js +57 -0
  59. package/dist/src/scanner.js.map +1 -0
  60. package/dist/src/server.d.ts +10 -0
  61. package/dist/src/server.js +494 -0
  62. package/dist/src/server.js.map +1 -0
  63. package/dist/src/sessionUsage.d.ts +14 -0
  64. package/dist/src/sessionUsage.js +180 -0
  65. package/dist/src/sessionUsage.js.map +1 -0
  66. package/dist/src/skillDependencies.d.ts +2 -0
  67. package/dist/src/skillDependencies.js +56 -0
  68. package/dist/src/skillDependencies.js.map +1 -0
  69. package/dist/src/skillMentions.d.ts +3 -0
  70. package/dist/src/skillMentions.js +111 -0
  71. package/dist/src/skillMentions.js.map +1 -0
  72. package/dist/src/status.d.ts +3 -0
  73. package/dist/src/status.js +134 -0
  74. package/dist/src/status.js.map +1 -0
  75. package/dist/src/stopSyncingSkill.d.ts +2 -0
  76. package/dist/src/stopSyncingSkill.js +31 -0
  77. package/dist/src/stopSyncingSkill.js.map +1 -0
  78. package/dist/src/sync.d.ts +48 -0
  79. package/dist/src/sync.js +741 -0
  80. package/dist/src/sync.js.map +1 -0
  81. package/dist/src/types.d.ts +84 -0
  82. package/dist/src/types.js +2 -0
  83. package/dist/src/types.js.map +1 -0
  84. package/dist/src/updateLocalSkill.d.ts +6 -0
  85. package/dist/src/updateLocalSkill.js +19 -0
  86. package/dist/src/updateLocalSkill.js.map +1 -0
  87. package/dist/src/usage.d.ts +6 -0
  88. package/dist/src/usage.js +84 -0
  89. package/dist/src/usage.js.map +1 -0
  90. package/dist/src/usageMonitor.d.ts +17 -0
  91. package/dist/src/usageMonitor.js +90 -0
  92. package/dist/src/usageMonitor.js.map +1 -0
  93. package/dist/web/assets/index-CPJdd8n0.js +59 -0
  94. package/dist/web/assets/index-T4bm09OX.css +2 -0
  95. package/dist/web/index.html +13 -0
  96. package/dist/web/style-options/common.css +515 -0
  97. package/dist/web/style-options/console.html +143 -0
  98. package/dist/web/style-options/desktop.html +144 -0
  99. package/dist/web/style-options/index.html +36 -0
  100. package/dist/web/style-options/workbench.html +112 -0
  101. package/package.json +84 -0
@@ -0,0 +1,78 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { configFilePath, expandHome, getDefaultCacheDir, getDefaultAgentsSkillsDir, getDefaultCodexSkillsDir, getDefaultConfigDir, getDefaultSyncRepo, getLegacyConfigDir } from "./paths.js";
5
+ import { readJsonFile, writeJsonFile } from "./json.js";
6
+ export async function createLocalConfig(options = {}) {
7
+ const configDir = resolveConfigDirForWrite(options);
8
+ const now = new Date().toISOString();
9
+ const filePath = configFilePath(configDir);
10
+ const existing = existsSync(filePath) ? await loadLocalConfig(options) : null;
11
+ if (existsSync(filePath) && !options.force) {
12
+ return existing;
13
+ }
14
+ const config = {
15
+ schemaVersion: 1,
16
+ syncRepo: resolveUserPath(options.syncRepo ?? getDefaultSyncRepo(options), options),
17
+ codexSkillsDir: resolveUserPath(options.codexSkillsDir ?? getDefaultCodexSkillsDir(options), options),
18
+ agentsSkillsDir: resolveUserPath(options.agentsSkillsDir ?? existing?.agentsSkillsDir ?? getDefaultAgentsSkillsDir(options), options),
19
+ cacheDir: resolveUserPath(options.cacheDir ?? getDefaultCacheDir(options), options),
20
+ createdAt: existing?.createdAt ?? now,
21
+ updatedAt: now
22
+ };
23
+ await mkdir(config.cacheDir, { recursive: true });
24
+ await writeJsonFile(filePath, config);
25
+ return config;
26
+ }
27
+ export async function loadLocalConfig(options = {}) {
28
+ const filePath = resolveConfigFileForRead(options);
29
+ if (!existsSync(filePath)) {
30
+ throw new Error(`No config found at ${filePath}. Run "skill-sync init" first.`);
31
+ }
32
+ const config = await readJsonFile(filePath);
33
+ if (config.schemaVersion !== 1) {
34
+ throw new Error(`Unsupported config schema version in ${filePath}.`);
35
+ }
36
+ return {
37
+ ...config,
38
+ agentsSkillsDir: config.agentsSkillsDir ?? getDefaultAgentsSkillsDir(options)
39
+ };
40
+ }
41
+ export async function tryLoadLocalConfig(options = {}) {
42
+ const filePath = resolveConfigFileForRead(options);
43
+ if (!existsSync(filePath)) {
44
+ return null;
45
+ }
46
+ return loadLocalConfig(options);
47
+ }
48
+ function resolveConfigDirForWrite(options = {}) {
49
+ const primary = getDefaultConfigDir(options);
50
+ const legacy = getLegacyConfigDir(options);
51
+ const primaryFile = configFilePath(primary);
52
+ if (existsSync(primaryFile) || primary === legacy) {
53
+ return primary;
54
+ }
55
+ const env = options.env ?? process.env;
56
+ const hasExplicitConfigDir = Boolean(env.SKILL_SYNC_CONFIG_DIR || env.CSM_CONFIG_DIR);
57
+ if (!hasExplicitConfigDir && existsSync(configFilePath(legacy))) {
58
+ return legacy;
59
+ }
60
+ return primary;
61
+ }
62
+ function resolveConfigFileForRead(options = {}) {
63
+ const primary = configFilePath(getDefaultConfigDir(options));
64
+ if (existsSync(primary)) {
65
+ return primary;
66
+ }
67
+ const legacy = configFilePath(getLegacyConfigDir(options));
68
+ const env = options.env ?? process.env;
69
+ const hasExplicitConfigDir = Boolean(env.SKILL_SYNC_CONFIG_DIR || env.CSM_CONFIG_DIR);
70
+ if (!hasExplicitConfigDir && legacy !== primary && existsSync(legacy)) {
71
+ return legacy;
72
+ }
73
+ return primary;
74
+ }
75
+ function resolveUserPath(input, options) {
76
+ return path.resolve(expandHome(input, options.homeDir));
77
+ }
78
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function copySkillDirectory(sourceRoot: string, targetRoot: string): Promise<void>;
@@ -0,0 +1,42 @@
1
+ import { lstat, mkdir, readdir, readlink, copyFile, symlink } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { assertInside } from "./paths.js";
4
+ export async function copySkillDirectory(sourceRoot, targetRoot) {
5
+ assertInside(sourceRoot, path.dirname(sourceRoot));
6
+ await mkdir(targetRoot, { recursive: true });
7
+ await copyDirectory(sourceRoot, targetRoot, sourceRoot);
8
+ }
9
+ async function copyDirectory(source, target, sourceRoot) {
10
+ const stat = await lstat(source);
11
+ if (stat.isSymbolicLink()) {
12
+ const linkTarget = await readlink(source);
13
+ assertSafeLinkTarget(sourceRoot, source, linkTarget);
14
+ await symlink(linkTarget, target);
15
+ return;
16
+ }
17
+ if (stat.isDirectory()) {
18
+ await mkdir(target, { recursive: true });
19
+ const entries = await readdir(source);
20
+ entries.sort((a, b) => a.localeCompare(b));
21
+ for (const entry of entries) {
22
+ if (entry === ".git" || entry === "node_modules") {
23
+ continue;
24
+ }
25
+ await copyDirectory(path.join(source, entry), path.join(target, entry), sourceRoot);
26
+ }
27
+ return;
28
+ }
29
+ if (stat.isFile()) {
30
+ await copyFile(source, target);
31
+ }
32
+ }
33
+ function assertSafeLinkTarget(sourceRoot, source, linkTarget) {
34
+ const resolvedTarget = path.resolve(path.dirname(source), linkTarget);
35
+ try {
36
+ assertInside(resolvedTarget, sourceRoot);
37
+ }
38
+ catch {
39
+ throw new Error(`Refusing to copy symbolic link that escapes skill directory: ${source} -> ${linkTarget}`);
40
+ }
41
+ }
42
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAkB,EAAE,UAAkB;IAC7E,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACnD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,MAAc,EAAE,UAAkB;IAC7E,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;IAEjC,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1C,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACrD,MAAM,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACvB,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;gBACjD,SAAS;YACX,CAAC;YAED,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;QACtF,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClB,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,UAAkB,EAAE,MAAc,EAAE,UAAkB;IAClF,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;IACtE,IAAI,CAAC;QACH,YAAY,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gEAAgE,MAAM,OAAO,UAAU,EAAE,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export type DirectoryPickerResult = {
2
+ canceled: true;
3
+ } | {
4
+ canceled: false;
5
+ path: string;
6
+ };
7
+ export type DirectoryPicker = (title?: string) => Promise<DirectoryPickerResult>;
8
+ export declare const selectDirectory: DirectoryPicker;
@@ -0,0 +1,49 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ export const selectDirectory = async (title = "Choose a folder") => {
5
+ if (process.platform !== "darwin") {
6
+ const error = new Error("Directory picker is only supported on macOS for now. Paste a path instead.");
7
+ error.statusCode = 501;
8
+ throw error;
9
+ }
10
+ const script = `POSIX path of (choose folder with prompt ${toAppleScriptString(title)})`;
11
+ try {
12
+ const { stdout } = await execFileAsync("osascript", ["-e", script]);
13
+ const selectedPath = stripTrailingSlash(stdout.trim());
14
+ if (!selectedPath) {
15
+ return { canceled: true };
16
+ }
17
+ return {
18
+ canceled: false,
19
+ path: selectedPath
20
+ };
21
+ }
22
+ catch (err) {
23
+ if (isCanceledSelection(err)) {
24
+ return { canceled: true };
25
+ }
26
+ const message = err instanceof Error ? err.message : String(err);
27
+ const stderr = typeof err.stderr === "string" ? err.stderr.trim() : "";
28
+ const error = new Error(`Unable to open directory picker: ${stderr || message}`);
29
+ error.statusCode = 500;
30
+ throw error;
31
+ }
32
+ };
33
+ function toAppleScriptString(value) {
34
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
35
+ }
36
+ function stripTrailingSlash(value) {
37
+ if (value.length > 1 && value.endsWith("/")) {
38
+ return value.slice(0, -1);
39
+ }
40
+ return value;
41
+ }
42
+ function isCanceledSelection(err) {
43
+ const details = [
44
+ err instanceof Error ? err.message : "",
45
+ typeof err.stderr === "string" ? err.stderr : ""
46
+ ].join("\n");
47
+ return details.includes("User canceled") || details.includes("(-128)");
48
+ }
49
+ //# sourceMappingURL=directoryPicker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directoryPicker.js","sourceRoot":"","sources":["../../src/directoryPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAa1C,MAAM,CAAC,MAAM,eAAe,GAAoB,KAAK,EAAE,KAAK,GAAG,iBAAiB,EAAE,EAAE;IAClF,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QACrG,KAAwC,CAAC,UAAU,GAAG,GAAG,CAAC;QAC3D,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,4CAA4C,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC;IAEzF,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QACpE,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAEvD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC5B,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,YAAY;SACnB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC5B,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,OAAQ,GAA4B,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAE,GAA0B,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzH,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,oCAAoC,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;QAChF,KAAwC,CAAC,UAAU,GAAG,GAAG,CAAC;QAC3D,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AAClE,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa;IACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,GAAY;IACvC,MAAM,OAAO,GAAG;QACd,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACvC,OAAQ,GAA4B,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAE,GAA0B,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;KACnG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { StatusReport } from "./types.js";
2
+ export declare function formatStatus(report: StatusReport): string;
@@ -0,0 +1,27 @@
1
+ export function formatStatus(report) {
2
+ const lines = [];
3
+ lines.push(`Sync repo: ${report.syncRepo}`);
4
+ lines.push(`Codex skills: ${report.codexSkillsDir}`);
5
+ lines.push(`Agents skills: ${report.agentsSkillsDir}`);
6
+ lines.push("");
7
+ lines.push(`Managed skills: ${report.managed.length}`);
8
+ for (const skill of report.managed) {
9
+ lines.push(` - ${skill.id} [${skill.syncState}] source=${skill.localSource ?? "unknown"} installed=${skill.installed ? "yes" : "no"}`);
10
+ }
11
+ lines.push(`Unmanaged local skills: ${report.unmanagedLocal.length}`);
12
+ for (const skill of report.unmanagedLocal.slice(0, 20)) {
13
+ lines.push(` - ${skill.id} source=${skill.source}`);
14
+ }
15
+ if (report.unmanagedLocal.length > 20) {
16
+ lines.push(` ... ${report.unmanagedLocal.length - 20} more`);
17
+ }
18
+ lines.push(`Repo skills not in metadata: ${report.repoOnly.length}`);
19
+ for (const skill of report.repoOnly.slice(0, 20)) {
20
+ lines.push(` - ${skill.id}`);
21
+ }
22
+ if (report.repoOnly.length > 20) {
23
+ lines.push(` ... ${report.repoOnly.length - 20} more`);
24
+ }
25
+ return lines.join("\n");
26
+ }
27
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/format.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC;IACvD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEvD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,SAAS,YAAY,KAAK,CAAC,WAAW,IAAI,SAAS,cAAc,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1I,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,2BAA2B,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,WAAW,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,gCAAgC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACrE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export type SkillFrontmatter = {
2
+ name: string;
3
+ description: string;
4
+ };
5
+ export declare function readSkillFrontmatter(skillDir: string): Promise<SkillFrontmatter>;
@@ -0,0 +1,36 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function readSkillFrontmatter(skillDir) {
4
+ const skillFile = path.join(skillDir, "SKILL.md");
5
+ const raw = await readFile(skillFile, "utf8");
6
+ if (!raw.startsWith("---")) {
7
+ return { name: path.basename(skillDir), description: "" };
8
+ }
9
+ const end = raw.indexOf("\n---", 3);
10
+ if (end === -1) {
11
+ return { name: path.basename(skillDir), description: "" };
12
+ }
13
+ const block = raw.slice(3, end).trim();
14
+ const result = {};
15
+ for (const line of block.split(/\r?\n/)) {
16
+ const match = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
17
+ if (!match) {
18
+ continue;
19
+ }
20
+ const [, key, value] = match;
21
+ result[key] = stripYamlString(value);
22
+ }
23
+ return {
24
+ name: result.name ?? path.basename(skillDir),
25
+ description: result.description ?? ""
26
+ };
27
+ }
28
+ function stripYamlString(value) {
29
+ const trimmed = value.trim();
30
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
31
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
32
+ return trimmed.slice(1, -1);
33
+ }
34
+ return trimmed;
35
+ }
36
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAO7B,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAAgB;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAE9C,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,SAAS;QACX,CAAC;QAED,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;QAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC5C,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IACE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAClD,CAAC;QACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,25 @@
1
+ export type GitCommandResult = {
2
+ stdout: string;
3
+ stderr: string;
4
+ };
5
+ export type GitBranchSyncStatus = {
6
+ upstream: string | null;
7
+ ahead: number;
8
+ behind: number;
9
+ state: "up-to-date" | "ahead" | "behind" | "diverged" | "no-upstream" | "unknown";
10
+ };
11
+ export type GitBranchSyncStatusOptions = {
12
+ fetch?: boolean;
13
+ };
14
+ export declare function ensureGitRepository(syncRepo: string): Promise<boolean>;
15
+ export declare function gitStatus(syncRepo: string): Promise<string>;
16
+ export declare function gitBranchSyncStatus(syncRepo: string, options?: GitBranchSyncStatusOptions): Promise<GitBranchSyncStatus>;
17
+ export declare function gitAdd(syncRepo: string, paths: string[]): Promise<void>;
18
+ export declare function gitHasStagedChanges(syncRepo: string): Promise<boolean>;
19
+ export declare function gitCommit(syncRepo: string, message: string): Promise<string>;
20
+ export declare function gitPush(syncRepo: string): Promise<void>;
21
+ export declare function gitPull(syncRepo: string): Promise<void>;
22
+ export declare function gitHasUncommittedChanges(syncRepo: string): Promise<boolean>;
23
+ export declare function gitRemotes(syncRepo: string): Promise<string[]>;
24
+ export declare function hasUpstream(syncRepo: string): Promise<boolean>;
25
+ export declare function runGit(syncRepo: string, args: string[]): Promise<GitCommandResult>;
@@ -0,0 +1,227 @@
1
+ import { existsSync } from "node:fs";
2
+ import { execFile } from "node:child_process";
3
+ import { promisify } from "node:util";
4
+ import path from "node:path";
5
+ const execFileAsync = promisify(execFile);
6
+ export async function ensureGitRepository(syncRepo) {
7
+ if (existsSync(path.join(syncRepo, ".git"))) {
8
+ return false;
9
+ }
10
+ await execFileAsync("git", ["init"], { cwd: syncRepo });
11
+ return true;
12
+ }
13
+ export async function gitStatus(syncRepo) {
14
+ if (!existsSync(path.join(syncRepo, ".git"))) {
15
+ return "not a git repository";
16
+ }
17
+ const { stdout } = await runGit(syncRepo, ["status", "--short"]);
18
+ return stdout.trim();
19
+ }
20
+ export async function gitBranchSyncStatus(syncRepo, options = {}) {
21
+ if (!existsSync(path.join(syncRepo, ".git"))) {
22
+ return { upstream: null, ahead: 0, behind: 0, state: "unknown" };
23
+ }
24
+ const branch = await currentBranch(syncRepo);
25
+ const upstream = await branchUpstream(syncRepo);
26
+ if (!upstream) {
27
+ return { upstream: null, ahead: 0, behind: 0, state: "no-upstream" };
28
+ }
29
+ const remote = remoteFromUpstream(upstream);
30
+ if (!remote) {
31
+ return { upstream, ahead: 0, behind: 0, state: "unknown" };
32
+ }
33
+ try {
34
+ if (options.fetch) {
35
+ await runGit(syncRepo, ["fetch", "--prune", remote]);
36
+ }
37
+ const branchStatus = await runGit(syncRepo, ["rev-list", "--left-right", "--count", `${upstream}...${branch}`]);
38
+ const [rawBehind, rawAhead] = branchStatus.stdout.trim().split(/\s+/);
39
+ const behind = Number.parseInt(rawBehind ?? "", 10);
40
+ const ahead = Number.parseInt(rawAhead ?? "", 10);
41
+ if (!Number.isFinite(ahead) || !Number.isFinite(behind) || Number.isNaN(ahead) || Number.isNaN(behind)) {
42
+ return { upstream, ahead: 0, behind: 0, state: "unknown" };
43
+ }
44
+ return {
45
+ upstream,
46
+ ahead,
47
+ behind,
48
+ state: ahead === 0 && behind === 0
49
+ ? "up-to-date"
50
+ : ahead > 0 && behind > 0
51
+ ? "diverged"
52
+ : ahead > 0
53
+ ? "ahead"
54
+ : "behind"
55
+ };
56
+ }
57
+ catch {
58
+ return {
59
+ upstream,
60
+ ahead: 0,
61
+ behind: 0,
62
+ state: "unknown"
63
+ };
64
+ }
65
+ }
66
+ export async function gitAdd(syncRepo, paths) {
67
+ if (paths.length === 0) {
68
+ return;
69
+ }
70
+ await runGit(syncRepo, ["add", "-A", "--", ...paths]);
71
+ }
72
+ export async function gitHasStagedChanges(syncRepo) {
73
+ try {
74
+ await runGit(syncRepo, ["diff", "--cached", "--quiet"]);
75
+ return false;
76
+ }
77
+ catch (error) {
78
+ if (isGitExitCode(error, 1)) {
79
+ return true;
80
+ }
81
+ throw error;
82
+ }
83
+ }
84
+ export async function gitCommit(syncRepo, message) {
85
+ await runGit(syncRepo, [
86
+ "-c",
87
+ "user.name=Skill Sync",
88
+ "-c",
89
+ "user.email=skill-sync@local",
90
+ "commit",
91
+ "-m",
92
+ message
93
+ ]);
94
+ const { stdout } = await runGit(syncRepo, ["rev-parse", "--short", "HEAD"]);
95
+ return stdout.trim();
96
+ }
97
+ export async function gitPush(syncRepo) {
98
+ const remotes = await gitRemotes(syncRepo);
99
+ if (remotes.length === 0) {
100
+ throw new Error("No Git remote is configured for the sync repository.");
101
+ }
102
+ const branch = await currentBranch(syncRepo);
103
+ const remote = remotes.includes("origin") ? "origin" : remotes[0];
104
+ const shouldUseUpstream = await hasUpstream(syncRepo);
105
+ const pushArgs = shouldUseUpstream ? ["push"] : ["push", "-u", remote, branch];
106
+ try {
107
+ await runGit(syncRepo, pushArgs);
108
+ return;
109
+ }
110
+ catch (error) {
111
+ if (!isNonFastForwardPushError(error)) {
112
+ throw error;
113
+ }
114
+ await runGit(syncRepo, ["fetch", "--prune", remote]);
115
+ try {
116
+ await runGit(syncRepo, ["rebase", `${remote}/${branch}`]);
117
+ }
118
+ catch (rebaseError) {
119
+ await safeAbortRebase(syncRepo);
120
+ throw new Error(`Cannot push because ${branch} on ${remote} has diverged and remote changes could not be replayed cleanly. ` +
121
+ `Resolve the conflict and re-run sync.\n${rebaseError.message}`);
122
+ }
123
+ await runGit(syncRepo, pushArgs);
124
+ }
125
+ }
126
+ export async function gitPull(syncRepo) {
127
+ const status = await gitStatus(syncRepo);
128
+ if (status.trim()) {
129
+ throw new Error(`Cannot pull: sync repo has local uncommitted changes.\n${status}`);
130
+ }
131
+ const remotes = await gitRemotes(syncRepo);
132
+ if (remotes.length === 0) {
133
+ throw new Error("No Git remote is configured for the sync repository.");
134
+ }
135
+ const branch = await currentBranch(syncRepo);
136
+ const remote = remotes.includes("origin") ? "origin" : remotes[0];
137
+ if (await hasUpstream(syncRepo)) {
138
+ await runGit(syncRepo, ["pull", "--ff-only"]);
139
+ }
140
+ else {
141
+ await runGit(syncRepo, ["pull", "--ff-only", remote, branch]);
142
+ }
143
+ }
144
+ export async function gitHasUncommittedChanges(syncRepo) {
145
+ return (await gitStatus(syncRepo)).trim().length > 0;
146
+ }
147
+ export async function gitRemotes(syncRepo) {
148
+ const { stdout } = await runGit(syncRepo, ["remote"]);
149
+ return stdout
150
+ .split(/\r?\n/)
151
+ .map((line) => line.trim())
152
+ .filter(Boolean);
153
+ }
154
+ async function currentBranch(syncRepo) {
155
+ const { stdout } = await runGit(syncRepo, ["branch", "--show-current"]);
156
+ const branch = stdout.trim();
157
+ if (!branch) {
158
+ throw new Error("Cannot push from a detached HEAD.");
159
+ }
160
+ return branch;
161
+ }
162
+ async function branchUpstream(syncRepo) {
163
+ try {
164
+ const { stdout } = await runGit(syncRepo, ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]);
165
+ const upstream = stdout.trim();
166
+ return upstream || null;
167
+ }
168
+ catch (error) {
169
+ if (isGitExitCode(error, 128)) {
170
+ return null;
171
+ }
172
+ throw error;
173
+ }
174
+ }
175
+ function remoteFromUpstream(upstream) {
176
+ const slash = upstream.indexOf("/");
177
+ return slash > 0 ? upstream.substring(0, slash) : null;
178
+ }
179
+ export async function hasUpstream(syncRepo) {
180
+ try {
181
+ await runGit(syncRepo, ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]);
182
+ return true;
183
+ }
184
+ catch (error) {
185
+ if (isGitExitCode(error, 128)) {
186
+ return false;
187
+ }
188
+ throw error;
189
+ }
190
+ }
191
+ function isNonFastForwardPushError(error) {
192
+ const message = error instanceof Error ? error.message.toLowerCase() : "";
193
+ return message.includes("non-fast-forward") || message.includes("fetch first") || message.includes("not a fast-forward");
194
+ }
195
+ async function safeAbortRebase(syncRepo) {
196
+ try {
197
+ await runGit(syncRepo, ["rebase", "--abort"]);
198
+ }
199
+ catch {
200
+ // ignore any best-effort failure from aborting a non-rebase state
201
+ }
202
+ }
203
+ export async function runGit(syncRepo, args) {
204
+ try {
205
+ const { stdout, stderr } = await execFileAsync("git", args, { cwd: syncRepo });
206
+ return { stdout, stderr };
207
+ }
208
+ catch (error) {
209
+ throw normalizeGitError(error);
210
+ }
211
+ }
212
+ function isGitExitCode(error, code) {
213
+ return typeof error === "object" && error !== null && error.code === code;
214
+ }
215
+ function normalizeGitError(error) {
216
+ if (error instanceof Error) {
217
+ const stderr = error.stderr;
218
+ const stdout = error.stdout;
219
+ const details = typeof stderr === "string" && stderr.trim() ? stderr.trim() : typeof stdout === "string" ? stdout.trim() : "";
220
+ if (details) {
221
+ error.message = details;
222
+ }
223
+ return error;
224
+ }
225
+ return new Error(String(error));
226
+ }
227
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function hashDirectory(root: string): Promise<string>;
@@ -0,0 +1,34 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstat, readFile, readdir, readlink } from "node:fs/promises";
3
+ import path from "node:path";
4
+ export async function hashDirectory(root) {
5
+ const hash = createHash("sha256");
6
+ await addPathToHash(root, root, hash);
7
+ return hash.digest("hex");
8
+ }
9
+ async function addPathToHash(root, current, hash) {
10
+ const stat = await lstat(current);
11
+ const relative = path.relative(root, current).split(path.sep).join("/") || ".";
12
+ if (stat.isSymbolicLink()) {
13
+ const target = await readlink(current);
14
+ hash.update(`link:${relative}:${target}\n`);
15
+ return;
16
+ }
17
+ if (stat.isDirectory()) {
18
+ hash.update(`dir:${relative}\n`);
19
+ const entries = await readdir(current);
20
+ entries.sort((a, b) => a.localeCompare(b));
21
+ for (const entry of entries) {
22
+ if (entry === ".git" || entry === "node_modules") {
23
+ continue;
24
+ }
25
+ await addPathToHash(root, path.join(current, entry), hash);
26
+ }
27
+ return;
28
+ }
29
+ if (stat.isFile()) {
30
+ hash.update(`file:${relative}:${stat.size}\n`);
31
+ hash.update(await readFile(current));
32
+ }
33
+ }
34
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,OAAe,EAAE,IAAmC;IAC7F,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IAE/E,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,QAAQ,IAAI,MAAM,IAAI,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,OAAO,QAAQ,IAAI,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAE3C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;gBACjD,SAAS;YACX,CAAC;YACD,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,QAAQ,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { LocalConfig, LocalSkillSource, SkillRecord } from "./types.js";
2
+ export type ImportOptions = {
3
+ force?: boolean;
4
+ source?: LocalSkillSource;
5
+ };
6
+ export declare function importLocalSkill(config: LocalConfig, skillId: string, options?: ImportOptions): Promise<SkillRecord>;