vskill 1.0.13 → 1.0.15
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/README.md +63 -2
- package/agents.json +1 -1
- package/dist/bin.js +0 -0
- package/dist/clone/github-scaffold.d.ts +38 -0
- package/dist/clone/github-scaffold.js +108 -0
- package/dist/clone/github-scaffold.js.map +1 -0
- package/dist/clone/provenance-fork.d.ts +34 -0
- package/dist/clone/provenance-fork.js +97 -0
- package/dist/clone/provenance-fork.js.map +1 -0
- package/dist/clone/reference-scanner.d.ts +19 -0
- package/dist/clone/reference-scanner.js +144 -0
- package/dist/clone/reference-scanner.js.map +1 -0
- package/dist/clone/skill-locator.d.ts +26 -0
- package/dist/clone/skill-locator.js +248 -0
- package/dist/clone/skill-locator.js.map +1 -0
- package/dist/clone/target-router.d.ts +73 -0
- package/dist/clone/target-router.js +200 -0
- package/dist/clone/target-router.js.map +1 -0
- package/dist/clone/types.d.ts +82 -0
- package/dist/clone/types.js +11 -0
- package/dist/clone/types.js.map +1 -0
- package/dist/commands/add.js +96 -32
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/auth.d.ts +23 -0
- package/dist/commands/auth.js +273 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/check.d.ts +55 -0
- package/dist/commands/check.js +279 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/clone-prompts.d.ts +13 -0
- package/dist/commands/clone-prompts.js +67 -0
- package/dist/commands/clone-prompts.js.map +1 -0
- package/dist/commands/clone.d.ts +70 -0
- package/dist/commands/clone.js +649 -0
- package/dist/commands/clone.js.map +1 -0
- package/dist/commands/eval/serve.js +8 -1
- package/dist/commands/eval/serve.js.map +1 -1
- package/dist/commands/keys.js +54 -2
- package/dist/commands/keys.js.map +1 -1
- package/dist/core/agent-prompts.d.ts +35 -0
- package/dist/core/agent-prompts.js +201 -0
- package/dist/core/agent-prompts.js.map +1 -0
- package/dist/core/skill-generator.d.ts +25 -3
- package/dist/core/skill-generator.js +131 -0
- package/dist/core/skill-generator.js.map +1 -1
- package/dist/eval/skill-scanner.d.ts +2 -12
- package/dist/eval/skill-scanner.js +27 -5
- package/dist/eval/skill-scanner.js.map +1 -1
- package/dist/eval-server/api-routes.d.ts +14 -0
- package/dist/eval-server/api-routes.js +376 -31
- package/dist/eval-server/api-routes.js.map +1 -1
- package/dist/eval-server/data-events.d.ts +1 -1
- package/dist/eval-server/data-events.js.map +1 -1
- package/dist/eval-server/install-engine-routes-helpers.d.ts +1 -3
- package/dist/eval-server/install-engine-routes-helpers.js +6 -14
- package/dist/eval-server/install-engine-routes-helpers.js.map +1 -1
- package/dist/eval-server/origin-resolver.d.ts +42 -0
- package/dist/eval-server/origin-resolver.js +168 -0
- package/dist/eval-server/origin-resolver.js.map +1 -0
- package/dist/eval-server/platform-proxy.d.ts +10 -0
- package/dist/eval-server/platform-proxy.js +58 -2
- package/dist/eval-server/platform-proxy.js.map +1 -1
- package/dist/eval-server/skill-create-routes.d.ts +8 -0
- package/dist/eval-server/skill-create-routes.js +96 -0
- package/dist/eval-server/skill-create-routes.js.map +1 -1
- package/dist/eval-server/skill-resolver.js +40 -0
- package/dist/eval-server/skill-resolver.js.map +1 -1
- package/dist/eval-server/utils/resolve-editor.d.ts +18 -0
- package/dist/eval-server/utils/resolve-editor.js +77 -0
- package/dist/eval-server/utils/resolve-editor.js.map +1 -0
- package/dist/eval-server/utils/scan-install-locations.d.ts +7 -0
- package/dist/eval-server/utils/scan-install-locations.js +20 -0
- package/dist/eval-server/utils/scan-install-locations.js.map +1 -1
- package/dist/eval-server/utils/which.d.ts +15 -0
- package/dist/eval-server/utils/which.js +76 -0
- package/dist/eval-server/utils/which.js.map +1 -0
- package/dist/eval-ui/assets/{CreateSkillPage-T0YWZWw-.js → CreateSkillPage-BmbvQEzE.js} +1 -1
- package/dist/eval-ui/assets/{FindSkillsPalette-KcFM32hZ.js → FindSkillsPalette-D0Zjhm31.js} +2 -2
- package/dist/eval-ui/assets/{SearchPaletteCore-EhBtr4Xx.js → SearchPaletteCore-EhcN1xEa.js} +1 -1
- package/dist/eval-ui/assets/SkillDetailPanel-B5J60ffv.js +1 -0
- package/dist/eval-ui/assets/{UpdateDropdown-pjFhHTi6.js → UpdateDropdown-Celf0_Cr.js} +1 -1
- package/dist/eval-ui/assets/index-BV7k6fdk.js +124 -0
- package/dist/eval-ui/assets/{index-BKAvJDDF.css → index-CKLqBL52.css} +1 -1
- package/dist/eval-ui/index.html +2 -2
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -1
- package/dist/installer/frontmatter.d.ts +26 -0
- package/dist/installer/frontmatter.js +90 -0
- package/dist/installer/frontmatter.js.map +1 -1
- package/dist/lib/github-fetch.d.ts +22 -0
- package/dist/lib/github-fetch.js +152 -0
- package/dist/lib/github-fetch.js.map +1 -0
- package/dist/lib/keychain.d.ts +41 -0
- package/dist/lib/keychain.js +232 -0
- package/dist/lib/keychain.js.map +1 -0
- package/dist/studio/types.d.ts +13 -0
- package/dist/utils/claude-plugin.d.ts +26 -0
- package/dist/utils/claude-plugin.js +60 -0
- package/dist/utils/claude-plugin.js.map +1 -1
- package/package.json +2 -1
- package/dist/eval-ui/assets/SkillDetailPanel-cyzLsLcK.js +0 -1
- package/dist/eval-ui/assets/index-C3S9iHnq.js +0 -122
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// vskill clone — skill-locator
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Discover a source skill across the three supported locations, in deterministic
|
|
5
|
+
// order. The caller (orchestrator in src/commands/clone.ts) decides what to do
|
|
6
|
+
// with multiple matches (interactive disambiguation or honor --source override).
|
|
7
|
+
//
|
|
8
|
+
// Search order:
|
|
9
|
+
// 1. project → <cwd>/.claude/skills/<skill>/SKILL.md
|
|
10
|
+
// 2. personal → <home>/.claude/skills/<skill>/SKILL.md
|
|
11
|
+
// 3. cache → <home>/.claude/plugins/cache/<org>/<plugin>/<version>/skills/<skill>/SKILL.md
|
|
12
|
+
//
|
|
13
|
+
// Source identifiers may be passed as:
|
|
14
|
+
// - "ado-mapper" (bare skill name)
|
|
15
|
+
// - "sw/ado-mapper" (namespace/skill — namespace is treated informationally)
|
|
16
|
+
//
|
|
17
|
+
// See spec.md AC-US1-01 and plan.md §4.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
import { promises as fs } from "node:fs";
|
|
20
|
+
import { join, basename } from "node:path";
|
|
21
|
+
import { readProvenance } from "../studio/lib/provenance.js";
|
|
22
|
+
const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---/;
|
|
23
|
+
const NAME_LINE_RE = /^name:\s*(.+?)\s*$/m;
|
|
24
|
+
const VERSION_LINE_RE = /^version:\s*(.+?)\s*$/m;
|
|
25
|
+
function unquote(value) {
|
|
26
|
+
const trimmed = value.trim();
|
|
27
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
28
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
29
|
+
return trimmed.slice(1, -1);
|
|
30
|
+
}
|
|
31
|
+
return trimmed;
|
|
32
|
+
}
|
|
33
|
+
async function parseSkillMd(skillMdPath) {
|
|
34
|
+
try {
|
|
35
|
+
const raw = await fs.readFile(skillMdPath, "utf-8");
|
|
36
|
+
const normalized = raw.replace(/^/, "").replace(/\r\n/g, "\n");
|
|
37
|
+
const fmMatch = normalized.match(FRONTMATTER_RE);
|
|
38
|
+
if (!fmMatch)
|
|
39
|
+
return {};
|
|
40
|
+
const block = fmMatch[1];
|
|
41
|
+
const nameMatch = block.match(NAME_LINE_RE);
|
|
42
|
+
const versionMatch = block.match(VERSION_LINE_RE);
|
|
43
|
+
return {
|
|
44
|
+
name: nameMatch ? unquote(nameMatch[1]) : undefined,
|
|
45
|
+
version: versionMatch ? unquote(versionMatch[1]) : undefined,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Split a source identifier like "sw/ado-mapper" into namespace + skill, or
|
|
54
|
+
* return only the skill when no namespace is present.
|
|
55
|
+
*/
|
|
56
|
+
export function parseSourceIdent(source) {
|
|
57
|
+
const idx = source.indexOf("/");
|
|
58
|
+
if (idx === -1)
|
|
59
|
+
return { skill: source };
|
|
60
|
+
return { namespace: source.slice(0, idx), skill: source.slice(idx + 1) };
|
|
61
|
+
}
|
|
62
|
+
async function exists(path) {
|
|
63
|
+
try {
|
|
64
|
+
await fs.access(path);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function dirExists(path) {
|
|
72
|
+
try {
|
|
73
|
+
const st = await fs.stat(path);
|
|
74
|
+
return st.isDirectory();
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function buildSource(location, skillDir, fallbackSkillName, pluginCtx) {
|
|
81
|
+
const skillMd = join(skillDir, "SKILL.md");
|
|
82
|
+
if (!(await exists(skillMd)))
|
|
83
|
+
return null;
|
|
84
|
+
const fm = await parseSkillMd(skillMd);
|
|
85
|
+
const fullName = fm.name ?? fallbackSkillName;
|
|
86
|
+
const slashIdx = fullName.indexOf("/");
|
|
87
|
+
const namespace = slashIdx >= 0 ? fullName.slice(0, slashIdx) : undefined;
|
|
88
|
+
let existingProvenance = null;
|
|
89
|
+
try {
|
|
90
|
+
existingProvenance = await readProvenance(skillDir);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
existingProvenance = null;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
location,
|
|
97
|
+
skillDir,
|
|
98
|
+
skillName: fullName,
|
|
99
|
+
namespace,
|
|
100
|
+
version: fm.version ?? "0.0.0",
|
|
101
|
+
plugin: pluginCtx,
|
|
102
|
+
existingProvenance,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async function locateInProject(cwd, skill) {
|
|
106
|
+
const dir = join(cwd, ".claude", "skills", skill);
|
|
107
|
+
if (!(await dirExists(dir)))
|
|
108
|
+
return null;
|
|
109
|
+
return buildSource("project", dir, skill);
|
|
110
|
+
}
|
|
111
|
+
async function locateInPersonal(home, skill) {
|
|
112
|
+
const dir = join(home, ".claude", "skills", skill);
|
|
113
|
+
if (!(await dirExists(dir)))
|
|
114
|
+
return null;
|
|
115
|
+
return buildSource("personal", dir, skill);
|
|
116
|
+
}
|
|
117
|
+
async function locateInCache(home, skill, preferredNamespace) {
|
|
118
|
+
const cacheRoot = join(home, ".claude", "plugins", "cache");
|
|
119
|
+
if (!(await dirExists(cacheRoot)))
|
|
120
|
+
return [];
|
|
121
|
+
const matches = [];
|
|
122
|
+
let orgs;
|
|
123
|
+
try {
|
|
124
|
+
orgs = await fs.readdir(cacheRoot);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
for (const org of orgs) {
|
|
130
|
+
const orgDir = join(cacheRoot, org);
|
|
131
|
+
if (!(await dirExists(orgDir)))
|
|
132
|
+
continue;
|
|
133
|
+
let plugins;
|
|
134
|
+
try {
|
|
135
|
+
plugins = await fs.readdir(orgDir);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
for (const pluginName of plugins) {
|
|
141
|
+
const pluginRoot = join(orgDir, pluginName);
|
|
142
|
+
if (!(await dirExists(pluginRoot)))
|
|
143
|
+
continue;
|
|
144
|
+
let versions;
|
|
145
|
+
try {
|
|
146
|
+
versions = await fs.readdir(pluginRoot);
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
for (const version of versions) {
|
|
152
|
+
const skillDir = join(pluginRoot, version, "skills", skill);
|
|
153
|
+
if (!(await dirExists(skillDir)))
|
|
154
|
+
continue;
|
|
155
|
+
const built = await buildSource("cache", skillDir, skill, {
|
|
156
|
+
pluginNamespace: org,
|
|
157
|
+
pluginName,
|
|
158
|
+
pluginVersion: version,
|
|
159
|
+
pluginRoot: join(pluginRoot, version),
|
|
160
|
+
});
|
|
161
|
+
if (!built)
|
|
162
|
+
continue;
|
|
163
|
+
if (preferredNamespace && built.namespace && built.namespace !== preferredNamespace) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
matches.push(built);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return matches;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Discover a skill across project / personal / cache. Returns every match in
|
|
174
|
+
* search order — the orchestrator handles disambiguation when there is more
|
|
175
|
+
* than one and `--source` was not explicitly provided.
|
|
176
|
+
*/
|
|
177
|
+
export async function locateSkill(source, opts) {
|
|
178
|
+
const { skill, namespace } = parseSourceIdent(source);
|
|
179
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
180
|
+
const matches = [];
|
|
181
|
+
const project = await locateInProject(cwd, skill);
|
|
182
|
+
if (project && (!namespace || project.namespace === namespace || !project.namespace)) {
|
|
183
|
+
matches.push(project);
|
|
184
|
+
}
|
|
185
|
+
const personal = await locateInPersonal(opts.home, skill);
|
|
186
|
+
if (personal && (!namespace || personal.namespace === namespace || !personal.namespace)) {
|
|
187
|
+
matches.push(personal);
|
|
188
|
+
}
|
|
189
|
+
const cache = await locateInCache(opts.home, skill, namespace);
|
|
190
|
+
matches.push(...cache);
|
|
191
|
+
return matches;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Enumerate every skill inside a cached plugin. Used by the whole-plugin
|
|
195
|
+
* clone path (T-010). Returns a list of SkillSource entries (one per skill).
|
|
196
|
+
*/
|
|
197
|
+
export async function enumeratePluginSkills(pluginName, opts) {
|
|
198
|
+
const cacheRoot = join(opts.home, ".claude", "plugins", "cache");
|
|
199
|
+
if (!(await dirExists(cacheRoot)))
|
|
200
|
+
return [];
|
|
201
|
+
const results = [];
|
|
202
|
+
let orgs;
|
|
203
|
+
try {
|
|
204
|
+
orgs = await fs.readdir(cacheRoot);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
return [];
|
|
208
|
+
}
|
|
209
|
+
for (const org of orgs) {
|
|
210
|
+
const pluginRoot = join(cacheRoot, org, pluginName);
|
|
211
|
+
if (!(await dirExists(pluginRoot)))
|
|
212
|
+
continue;
|
|
213
|
+
let versions;
|
|
214
|
+
try {
|
|
215
|
+
versions = await fs.readdir(pluginRoot);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
for (const version of versions) {
|
|
221
|
+
const skillsDir = join(pluginRoot, version, "skills");
|
|
222
|
+
if (!(await dirExists(skillsDir)))
|
|
223
|
+
continue;
|
|
224
|
+
let skillEntries;
|
|
225
|
+
try {
|
|
226
|
+
skillEntries = await fs.readdir(skillsDir);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
for (const skillEntry of skillEntries) {
|
|
232
|
+
const skillDir = join(skillsDir, skillEntry);
|
|
233
|
+
if (!(await dirExists(skillDir)))
|
|
234
|
+
continue;
|
|
235
|
+
const built = await buildSource("cache", skillDir, basename(skillDir), {
|
|
236
|
+
pluginNamespace: org,
|
|
237
|
+
pluginName,
|
|
238
|
+
pluginVersion: version,
|
|
239
|
+
pluginRoot: join(pluginRoot, version),
|
|
240
|
+
});
|
|
241
|
+
if (built)
|
|
242
|
+
results.push(built);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return results;
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=skill-locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-locator.js","sourceRoot":"","sources":["../../src/clone/skill-locator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
export interface CopyResult {
|
|
3
|
+
/** Absolute path of the `.tmp` staging directory. Caller renames into place. */
|
|
4
|
+
stagingDir: string;
|
|
5
|
+
/** Number of files written under `stagingDir`. */
|
|
6
|
+
filesCopied: number;
|
|
7
|
+
/** Final destination path (where `stagingDir` should be renamed to). */
|
|
8
|
+
finalDir: string;
|
|
9
|
+
}
|
|
10
|
+
export interface PluginCopyResult extends CopyResult {
|
|
11
|
+
/** Absolute path of the `.tmp` staged plugin manifest (sibling of the live manifest). */
|
|
12
|
+
manifestTmpPath: string;
|
|
13
|
+
/** Absolute path of the live plugin manifest (final rename target). */
|
|
14
|
+
manifestFinalPath: string;
|
|
15
|
+
}
|
|
16
|
+
/** Compute the `.tmp` sibling of a final destination path. */
|
|
17
|
+
export declare function tmpSibling(finalPath: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Best-effort cleanup of a `.tmp` path. Mirrors the rollback shape used by
|
|
20
|
+
* src/commands/add.ts:rollbackInstall — swallows per-call errors so a partial
|
|
21
|
+
* filesystem state doesn't suppress the underlying diagnostic the orchestrator
|
|
22
|
+
* is about to surface to the user.
|
|
23
|
+
*/
|
|
24
|
+
export declare function bestEffortRm(path: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Copy a source skill into a fresh standalone target dir, staged at
|
|
27
|
+
* `<finalDir>.tmp`. The orchestrator is responsible for the atomic
|
|
28
|
+
* rename and any pre-checks for collisions / `--force`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function writeStandalone(args: {
|
|
31
|
+
sourceSkillDir: string;
|
|
32
|
+
finalDir: string;
|
|
33
|
+
}): Promise<CopyResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Copy a source skill into an existing user-owned plugin's skills/ directory
|
|
36
|
+
* AND stage an updated `plugin.json` at `<plugin.json>.tmp` so the
|
|
37
|
+
* orchestrator can rename both in sequence (two-phase commit).
|
|
38
|
+
*
|
|
39
|
+
* Pre-flight: detects malformed plugin.json BEFORE any copy is staged
|
|
40
|
+
* (AC-US2-03). Caller aborts on the thrown error; no skill files are written.
|
|
41
|
+
*/
|
|
42
|
+
export declare function writeToPlugin(args: {
|
|
43
|
+
sourceSkillDir: string;
|
|
44
|
+
pluginRoot: string;
|
|
45
|
+
newSkillName: string;
|
|
46
|
+
}): Promise<PluginCopyResult>;
|
|
47
|
+
/**
|
|
48
|
+
* Scaffold a fresh new plugin at `<pluginRoot>` containing
|
|
49
|
+
* `.claude-plugin/plugin.json` (with the requested name) plus
|
|
50
|
+
* `skills/<skill>/` subtree containing the cloned skill.
|
|
51
|
+
*
|
|
52
|
+
* The whole plugin tree is staged at `<pluginRoot>.tmp` and atomically
|
|
53
|
+
* renamed by the caller — there is no two-phase commit because the manifest
|
|
54
|
+
* and the skill files live under a common root (one `rename` is enough).
|
|
55
|
+
*/
|
|
56
|
+
export declare function writeNewPlugin(args: {
|
|
57
|
+
sourceSkillDir: string;
|
|
58
|
+
pluginRoot: string;
|
|
59
|
+
pluginName: string;
|
|
60
|
+
newSkillName: string;
|
|
61
|
+
/** Optional plugin description; defaults to a generic forked-skills line. */
|
|
62
|
+
description?: string;
|
|
63
|
+
/** Optional plugin author; recorded in plugin.json. */
|
|
64
|
+
author?: string;
|
|
65
|
+
}): Promise<CopyResult>;
|
|
66
|
+
/**
|
|
67
|
+
* The `bareSkillName` helper extracts the unqualified skill name from a
|
|
68
|
+
* fully-qualified name like `anton/ado-mapper` → `ado-mapper`. Used by the
|
|
69
|
+
* orchestrator and by callers that need the directory-safe segment.
|
|
70
|
+
*/
|
|
71
|
+
export declare function bareSkillName(fullyQualified: string): string;
|
|
72
|
+
/** Re-export for callers that want to validate basenames. */
|
|
73
|
+
export { basename };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// vskill clone — target-router
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Three target writers, all `.tmp`-staged so the orchestrator can atomically
|
|
5
|
+
// rename the staged copy into place once every other step (frontmatter
|
|
6
|
+
// rewrite, provenance write, validation) has succeeded.
|
|
7
|
+
//
|
|
8
|
+
// writeStandalone → drop the cloned skill at <dir>
|
|
9
|
+
// writeToPlugin → drop into <plugin>/skills/<skill> and append to manifest
|
|
10
|
+
// writeNewPlugin → scaffold a fresh plugin with .claude-plugin/plugin.json + skills/<skill>
|
|
11
|
+
//
|
|
12
|
+
// All three return the absolute path of the *staging* `.tmp` directory so the
|
|
13
|
+
// orchestrator can run subsequent in-place edits (frontmatter, sidecar) before
|
|
14
|
+
// committing with `fs.rename`. The ONLY exception is `writeToPlugin` which
|
|
15
|
+
// also returns a separate `manifestTmpPath` so the orchestrator can rename
|
|
16
|
+
// both `.tmp` paths in sequence (two-phase commit).
|
|
17
|
+
//
|
|
18
|
+
// Filtering: the recursive copy reuses the public `shouldSkipFromCommands`
|
|
19
|
+
// helper from src/shared/copy-plugin-filtered.ts plus a root-level filter for
|
|
20
|
+
// the vskill-internal sidecars `.vskill-meta.json` and `.vskill-source.json`
|
|
21
|
+
// (matching the OWN-scope copy semantics in src/studio/lib/scope-transfer.ts).
|
|
22
|
+
//
|
|
23
|
+
// See spec.md AC-US1-03 / AC-US2-01..03 / AC-US3-01, plan.md §5–§6.
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
import { promises as fs, existsSync, readdirSync, statSync, copyFileSync, mkdirSync, rmSync, } from "node:fs";
|
|
26
|
+
import { join, dirname, basename } from "node:path";
|
|
27
|
+
import { shouldSkipFromCommands } from "../shared/copy-plugin-filtered.js";
|
|
28
|
+
/**
|
|
29
|
+
* Recursive skill-dir copy with sidecar filtering at the root and
|
|
30
|
+
* shouldSkipFromCommands filtering at every depth. Mirrors the OWN-scope
|
|
31
|
+
* helper in src/studio/lib/scope-transfer.ts (lines 101–119) — that helper is
|
|
32
|
+
* not exported, so we re-implement the same behavior rather than duplicate
|
|
33
|
+
* its file.
|
|
34
|
+
*/
|
|
35
|
+
function copySkillDirFiltered(sourceDir, targetDir, relBase = "") {
|
|
36
|
+
mkdirSync(targetDir, { recursive: true });
|
|
37
|
+
let filesCopied = 0;
|
|
38
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
39
|
+
// Filter vskill internal sidecars at the skill root only — same asymmetric
|
|
40
|
+
// contract as scope-transfer.ts: OWN scope is a single skill dir, so
|
|
41
|
+
// sidecars only ever exist at the root.
|
|
42
|
+
if (!relBase && (entry === ".vskill-meta.json" || entry === ".vskill-source.json"))
|
|
43
|
+
continue;
|
|
44
|
+
const relPath = relBase ? `${relBase}/${entry}` : entry;
|
|
45
|
+
const sourcePath = join(sourceDir, entry);
|
|
46
|
+
const st = statSync(sourcePath);
|
|
47
|
+
if (st.isDirectory()) {
|
|
48
|
+
filesCopied += copySkillDirFiltered(sourcePath, join(targetDir, entry), relPath);
|
|
49
|
+
}
|
|
50
|
+
else if (st.isFile() && !shouldSkipFromCommands(relPath)) {
|
|
51
|
+
copyFileSync(sourcePath, join(targetDir, entry));
|
|
52
|
+
filesCopied += 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return filesCopied;
|
|
56
|
+
}
|
|
57
|
+
/** Compute the `.tmp` sibling of a final destination path. */
|
|
58
|
+
export function tmpSibling(finalPath) {
|
|
59
|
+
return `${finalPath}.tmp`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Best-effort cleanup of a `.tmp` path. Mirrors the rollback shape used by
|
|
63
|
+
* src/commands/add.ts:rollbackInstall — swallows per-call errors so a partial
|
|
64
|
+
* filesystem state doesn't suppress the underlying diagnostic the orchestrator
|
|
65
|
+
* is about to surface to the user.
|
|
66
|
+
*/
|
|
67
|
+
export function bestEffortRm(path) {
|
|
68
|
+
try {
|
|
69
|
+
if (existsSync(path))
|
|
70
|
+
rmSync(path, { recursive: true, force: true });
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// best-effort
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Copy a source skill into a fresh standalone target dir, staged at
|
|
78
|
+
* `<finalDir>.tmp`. The orchestrator is responsible for the atomic
|
|
79
|
+
* rename and any pre-checks for collisions / `--force`.
|
|
80
|
+
*/
|
|
81
|
+
export async function writeStandalone(args) {
|
|
82
|
+
const stagingDir = tmpSibling(args.finalDir);
|
|
83
|
+
// Clear any leftover staging directory from a prior failed run before copying.
|
|
84
|
+
bestEffortRm(stagingDir);
|
|
85
|
+
await fs.mkdir(dirname(args.finalDir), { recursive: true });
|
|
86
|
+
const filesCopied = copySkillDirFiltered(args.sourceSkillDir, stagingDir);
|
|
87
|
+
return { stagingDir, filesCopied, finalDir: args.finalDir };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Copy a source skill into an existing user-owned plugin's skills/ directory
|
|
91
|
+
* AND stage an updated `plugin.json` at `<plugin.json>.tmp` so the
|
|
92
|
+
* orchestrator can rename both in sequence (two-phase commit).
|
|
93
|
+
*
|
|
94
|
+
* Pre-flight: detects malformed plugin.json BEFORE any copy is staged
|
|
95
|
+
* (AC-US2-03). Caller aborts on the thrown error; no skill files are written.
|
|
96
|
+
*/
|
|
97
|
+
export async function writeToPlugin(args) {
|
|
98
|
+
const manifestFinalPath = join(args.pluginRoot, ".claude-plugin", "plugin.json");
|
|
99
|
+
if (!existsSync(manifestFinalPath)) {
|
|
100
|
+
throw new Error(`target plugin manifest not found at ${manifestFinalPath} — pass a plugin root that contains .claude-plugin/plugin.json`);
|
|
101
|
+
}
|
|
102
|
+
// Pre-flight: parse the manifest BEFORE any copy is staged.
|
|
103
|
+
let manifestRaw;
|
|
104
|
+
try {
|
|
105
|
+
manifestRaw = await fs.readFile(manifestFinalPath, "utf-8");
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
throw new Error(`failed to read plugin manifest: ${err.message}`);
|
|
109
|
+
}
|
|
110
|
+
let manifest;
|
|
111
|
+
try {
|
|
112
|
+
manifest = JSON.parse(manifestRaw);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
throw new Error(`target plugin manifest is malformed JSON (${err.message}) — refusing to clone into ${args.pluginRoot}`);
|
|
116
|
+
}
|
|
117
|
+
// The "register the new skill" step appends to a `skills` array (creating
|
|
118
|
+
// one if absent). Existing entries are preserved; duplicate entries are
|
|
119
|
+
// collapsed.
|
|
120
|
+
const skills = Array.isArray(manifest.skills) ? [...manifest.skills] : [];
|
|
121
|
+
if (!skills.includes(args.newSkillName))
|
|
122
|
+
skills.push(args.newSkillName);
|
|
123
|
+
const updatedManifest = { ...manifest, skills };
|
|
124
|
+
const finalDir = join(args.pluginRoot, "skills", args.newSkillName);
|
|
125
|
+
const stagingDir = tmpSibling(finalDir);
|
|
126
|
+
bestEffortRm(stagingDir);
|
|
127
|
+
await fs.mkdir(dirname(finalDir), { recursive: true });
|
|
128
|
+
let filesCopied = 0;
|
|
129
|
+
try {
|
|
130
|
+
filesCopied = copySkillDirFiltered(args.sourceSkillDir, stagingDir);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
bestEffortRm(stagingDir);
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
// Stage the updated manifest. The orchestrator commits both renames.
|
|
137
|
+
const manifestTmpPath = `${manifestFinalPath}.tmp`;
|
|
138
|
+
try {
|
|
139
|
+
await fs.writeFile(manifestTmpPath, JSON.stringify(updatedManifest, null, 2) + "\n", "utf-8");
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
bestEffortRm(stagingDir);
|
|
143
|
+
bestEffortRm(manifestTmpPath);
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
stagingDir,
|
|
148
|
+
filesCopied,
|
|
149
|
+
finalDir,
|
|
150
|
+
manifestTmpPath,
|
|
151
|
+
manifestFinalPath,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Scaffold a fresh new plugin at `<pluginRoot>` containing
|
|
156
|
+
* `.claude-plugin/plugin.json` (with the requested name) plus
|
|
157
|
+
* `skills/<skill>/` subtree containing the cloned skill.
|
|
158
|
+
*
|
|
159
|
+
* The whole plugin tree is staged at `<pluginRoot>.tmp` and atomically
|
|
160
|
+
* renamed by the caller — there is no two-phase commit because the manifest
|
|
161
|
+
* and the skill files live under a common root (one `rename` is enough).
|
|
162
|
+
*/
|
|
163
|
+
export async function writeNewPlugin(args) {
|
|
164
|
+
const stagingDir = tmpSibling(args.pluginRoot);
|
|
165
|
+
bestEffortRm(stagingDir);
|
|
166
|
+
// Build the new plugin's manifest.
|
|
167
|
+
await fs.mkdir(join(stagingDir, ".claude-plugin"), { recursive: true });
|
|
168
|
+
const manifest = {
|
|
169
|
+
name: args.pluginName,
|
|
170
|
+
description: args.description ?? `Plugin scaffolded by 'vskill clone' containing forked skills.`,
|
|
171
|
+
skills: [args.newSkillName],
|
|
172
|
+
};
|
|
173
|
+
if (args.author) {
|
|
174
|
+
manifest.author = { name: args.author };
|
|
175
|
+
}
|
|
176
|
+
await fs.writeFile(join(stagingDir, ".claude-plugin", "plugin.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
177
|
+
// Copy the skill into <stagingDir>/skills/<newSkillName>/.
|
|
178
|
+
const skillTargetDir = join(stagingDir, "skills", args.newSkillName);
|
|
179
|
+
let filesCopied = 0;
|
|
180
|
+
try {
|
|
181
|
+
filesCopied = copySkillDirFiltered(args.sourceSkillDir, skillTargetDir);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
bestEffortRm(stagingDir);
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
return { stagingDir, filesCopied, finalDir: args.pluginRoot };
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The `bareSkillName` helper extracts the unqualified skill name from a
|
|
191
|
+
* fully-qualified name like `anton/ado-mapper` → `ado-mapper`. Used by the
|
|
192
|
+
* orchestrator and by callers that need the directory-safe segment.
|
|
193
|
+
*/
|
|
194
|
+
export function bareSkillName(fullyQualified) {
|
|
195
|
+
const idx = fullyQualified.indexOf("/");
|
|
196
|
+
return idx >= 0 ? fullyQualified.slice(idx + 1) : fullyQualified;
|
|
197
|
+
}
|
|
198
|
+
/** Re-export for callers that want to validate basenames. */
|
|
199
|
+
export { basename };
|
|
200
|
+
//# sourceMappingURL=target-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target-router.js","sourceRoot":"","sources":["../../src/clone/target-router.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+BAA+B;AAC/B,8EAA8E;AAC9E,6EAA6E;AAC7E,uEAAuE;AACvE,wDAAwD;AACxD,EAAE;AACF,sDAAsD;AACtD,gFAAgF;AAChF,gGAAgG;AAChG,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,2EAA2E;AAC3E,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,8EAA8E;AAC9E,6EAA6E;AAC7E,+EAA+E;AAC/E,EAAE;AACF,oEAAoE;AACpE,8EAA8E;AAE9E,OAAO,EACL,QAAQ,IAAI,EAAE,EACd,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,MAAM,GACP,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAkB3E;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,SAAiB,EAAE,SAAiB,EAAE,OAAO,GAAG,EAAE;IAC9E,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3C,2EAA2E;QAC3E,qEAAqE;QACrE,wCAAwC;QACxC,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,mBAAmB,IAAI,KAAK,KAAK,qBAAqB,CAAC;YAAE,SAAS;QAC7F,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QACxD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,EAAE,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,WAAW,IAAI,oBAAoB,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;QACnF,CAAC;aAAM,IAAI,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3D,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YACjD,WAAW,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,GAAG,SAAS,MAAM,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAGrC;IACC,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,YAAY,CAAC,UAAU,CAAC,CAAC;IACzB,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAC1E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAInC;IACC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;IACjF,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,uCAAuC,iBAAiB,gEAAgE,CACzH,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACH,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mCAAoC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,6CAA8C,GAAa,CAAC,OAAO,8BAA8B,IAAI,CAAC,UAAU,EAAE,CACnH,CAAC;IACJ,CAAC;IAED,0EAA0E;IAC1E,wEAAwE;IACxE,aAAa;IACb,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAI,QAAQ,CAAC,MAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACxE,MAAM,eAAe,GAAG,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEhD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACxC,YAAY,CAAC,UAAU,CAAC,CAAC;IAEzB,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC;QACH,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACtE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,qEAAqE;IACrE,MAAM,eAAe,GAAG,GAAG,iBAAiB,MAAM,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,SAAS,CAChB,eAAe,EACf,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAC/C,OAAO,CACR,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,YAAY,CAAC,eAAe,CAAC,CAAC;QAC9B,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO;QACL,UAAU;QACV,WAAW;QACX,QAAQ;QACR,eAAe;QACf,iBAAiB;KAClB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IASpC;IACC,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,YAAY,CAAC,UAAU,CAAC,CAAC;IAEzB,mCAAmC;IACnC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,MAAM,QAAQ,GAA4B;QACxC,IAAI,EAAE,IAAI,CAAC,UAAU;QACrB,WAAW,EACT,IAAI,CAAC,WAAW,IAAI,+DAA+D;QACrF,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;KAC5B,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC1C,CAAC;IACD,MAAM,EAAE,CAAC,SAAS,CAChB,IAAI,CAAC,UAAU,EAAE,gBAAgB,EAAE,aAAa,CAAC,EACjD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EACxC,OAAO,CACR,CAAC;IAEF,2DAA2D;IAC3D,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACrE,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,CAAC;QACH,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,cAAsB;IAClD,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AACnE,CAAC;AAED,6DAA6D;AAC7D,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Provenance } from "../studio/types.js";
|
|
2
|
+
/** Where a skill lives on disk. */
|
|
3
|
+
export type SkillSourceLocation = "project" | "personal" | "cache";
|
|
4
|
+
/** A discovered source skill, with absolute path and parsed identity. */
|
|
5
|
+
export interface SkillSource {
|
|
6
|
+
location: SkillSourceLocation;
|
|
7
|
+
/** Absolute path to the skill directory (the dir containing SKILL.md). */
|
|
8
|
+
skillDir: string;
|
|
9
|
+
/** Skill name as parsed from frontmatter (or directory basename if frontmatter lacks `name`). */
|
|
10
|
+
skillName: string;
|
|
11
|
+
/** Original namespace if discoverable (e.g., "sw" for plugin-cache sources). undefined for personal/project. */
|
|
12
|
+
namespace?: string;
|
|
13
|
+
/** Original version from frontmatter (or "0.0.0" if absent). */
|
|
14
|
+
version: string;
|
|
15
|
+
/** Plugin context — present only for cache-located skills. */
|
|
16
|
+
plugin?: {
|
|
17
|
+
pluginNamespace: string;
|
|
18
|
+
pluginName: string;
|
|
19
|
+
pluginVersion: string;
|
|
20
|
+
pluginRoot: string;
|
|
21
|
+
};
|
|
22
|
+
/** Existing provenance read from .vskill-meta.json (null if no sidecar). */
|
|
23
|
+
existingProvenance: Provenance | null;
|
|
24
|
+
}
|
|
25
|
+
/** Where the cloned skill should be written. */
|
|
26
|
+
export type CloneTargetKind = "standalone" | "plugin" | "new-plugin";
|
|
27
|
+
export interface CloneTarget {
|
|
28
|
+
kind: CloneTargetKind;
|
|
29
|
+
/** Absolute path to the final skill directory (where files end up after atomic rename). */
|
|
30
|
+
targetSkillDir: string;
|
|
31
|
+
/** For "plugin" kind: absolute path to the existing plugin's .claude-plugin/plugin.json. */
|
|
32
|
+
existingPluginManifestPath?: string;
|
|
33
|
+
/** For "new-plugin" kind: absolute path to the plugin root being scaffolded. */
|
|
34
|
+
newPluginRoot?: string;
|
|
35
|
+
/** For "new-plugin" kind: name to use in the new plugin manifest. */
|
|
36
|
+
newPluginName?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface CloneOptions {
|
|
39
|
+
/** New namespace for the cloned skill (e.g., "anton"). Required. */
|
|
40
|
+
namespace: string;
|
|
41
|
+
/** New author name. Required. */
|
|
42
|
+
author: string;
|
|
43
|
+
/** When true, overwrite existing target without confirmation. */
|
|
44
|
+
force: boolean;
|
|
45
|
+
/** When true, after files land, scaffold a GitHub repo via gh. */
|
|
46
|
+
github: boolean;
|
|
47
|
+
/** When true, do not write any files — just print the planned actions. */
|
|
48
|
+
dryRun: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** Result returned by the clone orchestrator. */
|
|
51
|
+
export interface CloneResult {
|
|
52
|
+
source: SkillSource;
|
|
53
|
+
target: CloneTarget;
|
|
54
|
+
/** Final skill name written (e.g., "anton/ado-mapper"). */
|
|
55
|
+
finalSkillName: string;
|
|
56
|
+
/** Number of files copied. */
|
|
57
|
+
filesCopied: number;
|
|
58
|
+
/** Cross-skill references found in the body (informational, not auto-rewritten). */
|
|
59
|
+
referenceReport: ReferenceMatch[];
|
|
60
|
+
/** Self-name occurrences in prose (informational). */
|
|
61
|
+
selfNameMatches: ReferenceMatch[];
|
|
62
|
+
/** GitHub repo URL if --github was used and succeeded; null if skipped. */
|
|
63
|
+
githubRepoUrl: string | null;
|
|
64
|
+
/** Provenance written to the cloned skill. */
|
|
65
|
+
provenance: Provenance;
|
|
66
|
+
}
|
|
67
|
+
export interface ReferenceMatch {
|
|
68
|
+
/** Path of the file the match was found in (relative to skill root). */
|
|
69
|
+
file: string;
|
|
70
|
+
/** Line number (1-indexed). */
|
|
71
|
+
line: number;
|
|
72
|
+
/** The matched text (e.g., "sw:ado-mapper"). */
|
|
73
|
+
match: string;
|
|
74
|
+
/** Pattern category. */
|
|
75
|
+
kind: "backtick" | "skill-call" | "slash-command" | "self-name";
|
|
76
|
+
}
|
|
77
|
+
/** Fork provenance metadata written to the cloned skill's .vskill-meta.json. */
|
|
78
|
+
export interface ForkProvenance {
|
|
79
|
+
source: string;
|
|
80
|
+
version: string;
|
|
81
|
+
clonedAt: string;
|
|
82
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// vskill clone — shared type contracts
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Source of truth for the `vskill clone` command. Consumed by skill-locator,
|
|
5
|
+
// frontmatter rewriter, provenance-fork, target-router, github-scaffold, and
|
|
6
|
+
// the orchestrator in src/commands/clone.ts.
|
|
7
|
+
//
|
|
8
|
+
// See .specweave/increments/0822-vskill-clone-skill-fork/spec.md and plan.md.
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/clone/types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAC9E,6EAA6E;AAC7E,6EAA6E;AAC7E,6CAA6C;AAC7C,EAAE;AACF,8EAA8E;AAC9E,8EAA8E"}
|