vskill 1.0.3 → 1.0.5
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/agents.json +1 -1
- package/dist/commands/add.js +10 -3
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/outdated.d.ts +1 -0
- package/dist/commands/outdated.js +63 -25
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/plugin.js +39 -7
- package/dist/commands/plugin.js.map +1 -1
- package/dist/commands/repair-skills.d.ts +27 -0
- package/dist/commands/repair-skills.js +190 -0
- package/dist/commands/repair-skills.js.map +1 -0
- package/dist/commands/submit.js +61 -1
- package/dist/commands/submit.js.map +1 -1
- package/dist/eval-server/authoring-routes.js +90 -17
- package/dist/eval-server/authoring-routes.js.map +1 -1
- package/dist/eval-server/plugin-cli-routes.js +20 -13
- package/dist/eval-server/plugin-cli-routes.js.map +1 -1
- package/dist/eval-server/plugin-discovery.d.ts +17 -0
- package/dist/eval-server/plugin-discovery.js +183 -0
- package/dist/eval-server/plugin-discovery.js.map +1 -0
- package/dist/eval-ui/assets/{CreateSkillPage-B9MwTYPn.js → CreateSkillPage-D9ZsmNub.js} +1 -1
- package/dist/eval-ui/assets/{FindSkillsPalette-DSW-Zyl_.js → FindSkillsPalette-BBj-hoqE.js} +2 -2
- package/dist/eval-ui/assets/{SearchPaletteCore-91Jq-ilw.js → SearchPaletteCore-Ddcfdn9a.js} +1 -1
- package/dist/eval-ui/assets/{SkillDetailPanel-CPhEDst2.js → SkillDetailPanel-Xymi4aZg.js} +1 -1
- package/dist/eval-ui/assets/{UpdateDropdown-OxJwLHid.js → UpdateDropdown-DTP2sv27.js} +1 -1
- package/dist/eval-ui/assets/{index-DnXSuywx.js → index-BmriQsHr.js} +4 -4
- package/dist/eval-ui/index.html +1 -1
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -1
- package/dist/installer/frontmatter.js +24 -8
- package/dist/installer/frontmatter.js.map +1 -1
- package/dist/lib/frontmatter.d.ts +33 -0
- package/dist/lib/frontmatter.js +85 -0
- package/dist/lib/frontmatter.js.map +1 -0
- package/dist/lockfile/authored.d.ts +35 -0
- package/dist/lockfile/authored.js +82 -0
- package/dist/lockfile/authored.js.map +1 -0
- package/package.json +1 -1
|
@@ -10,11 +10,14 @@
|
|
|
10
10
|
// the platform returns `latest`, we compare semver — if disk >= latest
|
|
11
11
|
// the entry is NOT outdated (don't tell the user to "update" backwards).
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { isAbsolute, join } from "node:path";
|
|
13
15
|
import { checkUpdates } from "../api/client.js";
|
|
14
16
|
import { readLockfile, writeLockfile } from "../lockfile/lockfile.js";
|
|
15
17
|
import { getProjectRoot } from "../lockfile/project-root.js";
|
|
16
18
|
import { parseSource } from "../resolvers/source-resolver.js";
|
|
17
|
-
import { reconcileLockfileVersion, resolveInstallPath, compareSemver, } from "../eval/disk-version.js";
|
|
19
|
+
import { reconcileLockfileVersion, resolveInstallPath, compareSemver, readDiskVersion, } from "../eval/disk-version.js";
|
|
20
|
+
import { readAuthored, removeAuthoredSkill } from "../lockfile/authored.js";
|
|
18
21
|
import { bold, dim, green, red, yellow, cyan, table } from "../utils/output.js";
|
|
19
22
|
const TWENTY_FOUR_HOURS = 86_400_000;
|
|
20
23
|
/**
|
|
@@ -42,27 +45,60 @@ function resolveFullName(name, source) {
|
|
|
42
45
|
export async function getOutdatedJson() {
|
|
43
46
|
const lock = readLockfile();
|
|
44
47
|
const lockDir = getProjectRoot();
|
|
45
|
-
|
|
48
|
+
const authored = readAuthored(lockDir);
|
|
49
|
+
const lockSkillCount = lock ? Object.keys(lock.skills).length : 0;
|
|
50
|
+
if (lockSkillCount === 0 && authored.length === 0)
|
|
46
51
|
return null;
|
|
47
52
|
const diskVersions = new Map();
|
|
48
53
|
const reconcileWarnings = new Map();
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
const authoredNames = new Set();
|
|
55
|
+
const items = lock
|
|
56
|
+
? Object.entries(lock.skills).map(([name, entry]) => {
|
|
57
|
+
const resolvedName = resolveFullName(name, entry.source);
|
|
58
|
+
const skillMdPath = resolveInstallPath({ name, entry, lockDir });
|
|
59
|
+
const reconciled = reconcileLockfileVersion({
|
|
60
|
+
lockfileVersion: entry.version,
|
|
61
|
+
skillMdPath,
|
|
62
|
+
});
|
|
63
|
+
diskVersions.set(resolvedName, reconciled.version);
|
|
64
|
+
if (reconciled.warning) {
|
|
65
|
+
reconcileWarnings.set(resolvedName, reconciled.warning);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
name: resolvedName,
|
|
69
|
+
currentVersion: reconciled.version,
|
|
70
|
+
sha: entry.sha,
|
|
71
|
+
};
|
|
72
|
+
})
|
|
73
|
+
: [];
|
|
74
|
+
// 0794 / T-007 — append authored (source-origin) skills to the poll set.
|
|
75
|
+
// Skills the user has published themselves don't appear in vskill.lock
|
|
76
|
+
// (only installs do), so they were silently skipped before. Read disk
|
|
77
|
+
// version from the source SKILL.md and include them in the upstream
|
|
78
|
+
// check. Skip silently if the file disappeared (and clean up tracking)
|
|
79
|
+
// or if the local version cannot be read.
|
|
80
|
+
for (const a of authored) {
|
|
81
|
+
if (lock?.skills[a.name]) {
|
|
82
|
+
// Already tracked via lockfile — avoid duplicate poll entries.
|
|
83
|
+
continue;
|
|
59
84
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
85
|
+
const absSourcePath = isAbsolute(a.sourcePath)
|
|
86
|
+
? a.sourcePath
|
|
87
|
+
: join(lockDir, a.sourcePath);
|
|
88
|
+
if (!existsSync(absSourcePath)) {
|
|
89
|
+
removeAuthoredSkill(lockDir, a.name);
|
|
90
|
+
console.error(dim(`${a.name}: source path no longer exists, removed from authored tracking`));
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const v = readDiskVersion(absSourcePath);
|
|
94
|
+
if (!v)
|
|
95
|
+
continue; // never published or unreadable — skip silently (AC-US6-05)
|
|
96
|
+
diskVersions.set(a.name, v);
|
|
97
|
+
items.push({ name: a.name, currentVersion: v });
|
|
98
|
+
authoredNames.add(a.name);
|
|
99
|
+
}
|
|
100
|
+
if (items.length === 0)
|
|
101
|
+
return null;
|
|
66
102
|
const rawResults = await checkUpdates(items);
|
|
67
103
|
const results = rawResults.map((r) => {
|
|
68
104
|
const disk = diskVersions.get(r.name) ?? r.installed;
|
|
@@ -79,15 +115,17 @@ export async function getOutdatedJson() {
|
|
|
79
115
|
};
|
|
80
116
|
});
|
|
81
117
|
const pinMap = new Map();
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
118
|
+
if (lock) {
|
|
119
|
+
for (const [name, entry] of Object.entries(lock.skills)) {
|
|
120
|
+
if (entry.pinnedVersion) {
|
|
121
|
+
pinMap.set(name, entry.pinnedVersion);
|
|
122
|
+
const resolved = resolveFullName(name, entry.source);
|
|
123
|
+
if (resolved !== name)
|
|
124
|
+
pinMap.set(resolved, entry.pinnedVersion);
|
|
125
|
+
}
|
|
88
126
|
}
|
|
89
127
|
}
|
|
90
|
-
return { results, pinMap };
|
|
128
|
+
return { results, pinMap, authoredNames };
|
|
91
129
|
}
|
|
92
130
|
export async function outdatedCommand(opts) {
|
|
93
131
|
const programmatic = await getOutdatedJson().catch((err) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outdated.js","sourceRoot":"","sources":["../../src/commands/outdated.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kEAAkE;AAClE,8EAA8E;AAC9E,oEAAoE;AACpE,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,wEAAwE;AACxE,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,aAAa,
|
|
1
|
+
{"version":3,"file":"outdated.js","sourceRoot":"","sources":["../../src/commands/outdated.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/plugin.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// This command exists because Claude Code's `claude plugin` CLI has no
|
|
11
11
|
// `new`/`create`/`init` subcommand — plugin authoring is otherwise unowned.
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
-
import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
13
|
+
import { existsSync, mkdirSync, rmdirSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
14
14
|
import { resolve, join } from "node:path";
|
|
15
15
|
import { pluginJsonScaffold, skillMdScaffold, validateKebabName, } from "../eval-server/authoring-routes.js";
|
|
16
16
|
import { validateClaudePlugin } from "../core/plugin-validator.js";
|
|
@@ -52,10 +52,12 @@ export async function pluginNewCommand(pluginName, opts) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
const description = (opts.description ?? "").trim() || `Plugin: ${pluginName}`;
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
55
|
+
// All-or-nothing scaffolding: track what we create so we can roll the whole
|
|
56
|
+
// tree back on validator failure. If we wrote both a manifest AND a first
|
|
57
|
+
// skill, leaving the skill behind on rollback creates a phantom skill that
|
|
58
|
+
// would surprise the user (they ran one command, saw an error, and now the
|
|
59
|
+
// workspace has files they didn't ask for).
|
|
60
|
+
const created = {};
|
|
59
61
|
try {
|
|
60
62
|
mkdirSync(manifestDir, { recursive: true });
|
|
61
63
|
writeFileSync(manifestPath, pluginJsonScaffold(pluginName, description), "utf8");
|
|
@@ -63,6 +65,7 @@ export async function pluginNewCommand(pluginName, opts) {
|
|
|
63
65
|
const skillDir = join(pluginDir, "skills", withSkill);
|
|
64
66
|
mkdirSync(skillDir, { recursive: true });
|
|
65
67
|
writeFileSync(join(skillDir, "SKILL.md"), skillMdScaffold(withSkill, description), "utf8");
|
|
68
|
+
created.skillDir = skillDir;
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
catch (err) {
|
|
@@ -74,15 +77,44 @@ export async function pluginNewCommand(pluginName, opts) {
|
|
|
74
77
|
// for the plugin schema.
|
|
75
78
|
const validation = validateClaudePlugin(pluginDir);
|
|
76
79
|
if (!validation.ok) {
|
|
80
|
+
// Roll back EVERYTHING this command created. The manifest first (cheap),
|
|
81
|
+
// then the skill folder if we wrote one. After the artifact removals,
|
|
82
|
+
// best-effort `rmdirSync` walks up the tree (skills/ → pluginDir/) and
|
|
83
|
+
// removes each level only if it became empty — so we never delete user
|
|
84
|
+
// files that were already there.
|
|
77
85
|
try {
|
|
78
86
|
unlinkSync(manifestPath);
|
|
87
|
+
rmSync(manifestDir, { recursive: true, force: true });
|
|
79
88
|
}
|
|
80
89
|
catch {
|
|
81
|
-
/* best-effort
|
|
90
|
+
/* best-effort */
|
|
91
|
+
}
|
|
92
|
+
if (created.skillDir) {
|
|
93
|
+
try {
|
|
94
|
+
rmSync(created.skillDir, { recursive: true, force: true });
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
/* best-effort */
|
|
98
|
+
}
|
|
99
|
+
// rmdirSync only removes empty dirs (vs rmSync without `recursive`,
|
|
100
|
+
// which throws ENOTEMPTY on non-empty AND on empty dirs in some Node
|
|
101
|
+
// versions). Wrapping in try/catch lets us safely walk up.
|
|
102
|
+
try {
|
|
103
|
+
rmdirSync(join(pluginDir, "skills"));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
/* skills/ has other content the user owns — leave it */
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
rmdirSync(pluginDir);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
/* pluginDir not empty (other files we didn't create) — leave it */
|
|
82
114
|
}
|
|
83
115
|
console.error(red("Error: ") + dim("claude plugin validate rejected the generated manifest:"));
|
|
84
116
|
console.error(validation.stderr || "(no stderr captured)");
|
|
85
|
-
console.error(dim(" The
|
|
117
|
+
console.error(dim(" The plugin scaffold has been rolled back. Please file an issue if this is unexpected."));
|
|
86
118
|
exit(1);
|
|
87
119
|
}
|
|
88
120
|
if (validation.skipped) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/commands/plugin.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8CAA8C;AAC9C,EAAE;AACF,oFAAoF;AACpF,wEAAwE;AACxE,2EAA2E;AAC3E,wEAAwE;AACxE,0DAA0D;AAC1D,EAAE;AACF,uEAAuE;AACvE,4EAA4E;AAC5E,8EAA8E;AAE9E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/commands/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface RepairOptions {
|
|
2
|
+
/** Roots to walk. When omitted, defaults to all known cross-tool skill dirs. */
|
|
3
|
+
root?: string[];
|
|
4
|
+
/** Where to look for pristine sources. Defaults to ~/.claude/plugins/marketplaces. */
|
|
5
|
+
sourceRoot?: string;
|
|
6
|
+
/** When true, write restored content to disk; otherwise dry-run (report only). */
|
|
7
|
+
write?: boolean;
|
|
8
|
+
/** When true, emit JSON instead of human report. */
|
|
9
|
+
json?: boolean;
|
|
10
|
+
}
|
|
11
|
+
type Action = "restored" | "would-restore" | "corrupted-no-source" | "ok";
|
|
12
|
+
interface FileResult {
|
|
13
|
+
path: string;
|
|
14
|
+
action: Action;
|
|
15
|
+
reasons: string[];
|
|
16
|
+
source?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Detects the two corruption patterns. Returns reasons when corrupt, [] when clean. */
|
|
19
|
+
export declare function detectCorruption(content: string): string[];
|
|
20
|
+
export declare function repairSkillsCommand(opts?: RepairOptions): Promise<{
|
|
21
|
+
scanned: number;
|
|
22
|
+
corrupted: number;
|
|
23
|
+
restored: number;
|
|
24
|
+
unresolvable: number;
|
|
25
|
+
results: FileResult[];
|
|
26
|
+
}>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// `vskill repair-skills` — detects and restores corrupted SKILL.md files in
|
|
3
|
+
// local skill installations.
|
|
4
|
+
//
|
|
5
|
+
// Background: a bug in `ensureFrontmatter(forceName=true)` produced two
|
|
6
|
+
// corruption patterns when installing skills via `vskill add`:
|
|
7
|
+
// 1. Duplicated name token → `name: foo foo`
|
|
8
|
+
// 2. Duplicated description → two `^description:` lines in the same block
|
|
9
|
+
// The frontend-design Anthropic skill was the canonical reproducer.
|
|
10
|
+
//
|
|
11
|
+
// This command:
|
|
12
|
+
// - Walks the known cross-tool skill install dirs.
|
|
13
|
+
// - Flags any SKILL.md with the corruption signatures above.
|
|
14
|
+
// - Looks for a pristine source in ~/.claude/plugins/marketplaces/**/SKILL.md.
|
|
15
|
+
// - Restores from source when --write is passed; otherwise reports only.
|
|
16
|
+
//
|
|
17
|
+
// Conservative by default: dry-run, only restores when an exact-name match is
|
|
18
|
+
// found in a marketplace cache. Never touches files outside the user's $HOME.
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
import { promises as fs } from "node:fs";
|
|
21
|
+
import { homedir } from "node:os";
|
|
22
|
+
import { basename, join, resolve, sep } from "node:path";
|
|
23
|
+
const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---/;
|
|
24
|
+
const NAME_LINE_RE = /^name:\s*(.*)$/m;
|
|
25
|
+
const DESCRIPTION_LINE_RE = /^description:.*$/gm;
|
|
26
|
+
function defaultInstallRoots(home) {
|
|
27
|
+
return [
|
|
28
|
+
join(home, ".claude", "skills"),
|
|
29
|
+
join(home, ".cursor", "skills"),
|
|
30
|
+
join(home, ".config", "opencode", "skills"),
|
|
31
|
+
join(home, ".codex", "skills"),
|
|
32
|
+
join(home, ".config", "codex", "skills"),
|
|
33
|
+
join(home, ".aider", "skills"),
|
|
34
|
+
join(home, ".config", "aider", "skills"),
|
|
35
|
+
join(home, ".continue", "skills"),
|
|
36
|
+
join(home, ".junie", "skills"),
|
|
37
|
+
join(home, ".trae", "skills"),
|
|
38
|
+
join(home, ".windsurf", "skills"),
|
|
39
|
+
join(home, ".config", "windsurf", "skills"),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
async function walk(dir, out) {
|
|
43
|
+
let entries;
|
|
44
|
+
try {
|
|
45
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
const full = join(dir, entry.name);
|
|
52
|
+
if (entry.isSymbolicLink())
|
|
53
|
+
continue;
|
|
54
|
+
if (entry.isDirectory()) {
|
|
55
|
+
await walk(full, out);
|
|
56
|
+
}
|
|
57
|
+
else if (entry.isFile() && entry.name === "SKILL.md") {
|
|
58
|
+
out.push(full);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Detects the two corruption patterns. Returns reasons when corrupt, [] when clean. */
|
|
63
|
+
export function detectCorruption(content) {
|
|
64
|
+
const normalized = content.replace(/^/, "").replace(/\r\n/g, "\n");
|
|
65
|
+
const fm = normalized.match(FRONTMATTER_RE);
|
|
66
|
+
if (!fm)
|
|
67
|
+
return [];
|
|
68
|
+
const block = fm[1];
|
|
69
|
+
const reasons = [];
|
|
70
|
+
const nameMatch = block.match(NAME_LINE_RE);
|
|
71
|
+
if (nameMatch) {
|
|
72
|
+
const value = nameMatch[1].trim();
|
|
73
|
+
const tokens = value.split(/\s+/);
|
|
74
|
+
if (tokens.length >= 2 && tokens[0] === tokens[1]) {
|
|
75
|
+
reasons.push(`duplicated-name-value: ${JSON.stringify(value)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const descLines = block.match(DESCRIPTION_LINE_RE) ?? [];
|
|
79
|
+
if (descLines.length > 1) {
|
|
80
|
+
reasons.push(`${descLines.length}× description: lines`);
|
|
81
|
+
}
|
|
82
|
+
return reasons;
|
|
83
|
+
}
|
|
84
|
+
/** Find a pristine SKILL.md whose containing dir matches the given skill name. */
|
|
85
|
+
async function findPristineSource(sourceRoot, skillName) {
|
|
86
|
+
const candidates = [];
|
|
87
|
+
await walk(sourceRoot, candidates);
|
|
88
|
+
// Prefer paths whose immediate parent dir name equals the skill name.
|
|
89
|
+
for (const c of candidates) {
|
|
90
|
+
const parent = basename(c.slice(0, c.length - "/SKILL.md".length));
|
|
91
|
+
if (parent === skillName) {
|
|
92
|
+
// Skip self-references (e.g. if user pointed sourceRoot to an install dir).
|
|
93
|
+
// Rough heuristic: require the path to contain `marketplaces` or `plugins`.
|
|
94
|
+
if (/\b(marketplaces|plugins)\b/.test(c)) {
|
|
95
|
+
return c;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
export async function repairSkillsCommand(opts = {}) {
|
|
102
|
+
const home = homedir();
|
|
103
|
+
const roots = (opts.root && opts.root.length > 0
|
|
104
|
+
? opts.root
|
|
105
|
+
: defaultInstallRoots(home)).map((r) => resolve(r));
|
|
106
|
+
const sourceRoot = resolve(opts.sourceRoot ?? join(home, ".claude", "plugins", "marketplaces"));
|
|
107
|
+
const write = !!opts.write;
|
|
108
|
+
// Safety: refuse to walk roots outside $HOME.
|
|
109
|
+
const safeRoots = [];
|
|
110
|
+
for (const r of roots) {
|
|
111
|
+
if (r === home || !r.startsWith(home + sep)) {
|
|
112
|
+
console.error(`vskill repair-skills: refusing to walk outside $HOME: ${r}`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
safeRoots.push(r);
|
|
116
|
+
}
|
|
117
|
+
const files = [];
|
|
118
|
+
for (const r of safeRoots) {
|
|
119
|
+
await walk(r, files);
|
|
120
|
+
}
|
|
121
|
+
const results = [];
|
|
122
|
+
let corrupted = 0;
|
|
123
|
+
let restored = 0;
|
|
124
|
+
let unresolvable = 0;
|
|
125
|
+
for (const path of files) {
|
|
126
|
+
let content;
|
|
127
|
+
try {
|
|
128
|
+
content = await fs.readFile(path, "utf8");
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
const reasons = detectCorruption(content);
|
|
134
|
+
if (reasons.length === 0) {
|
|
135
|
+
results.push({ path, action: "ok", reasons: [] });
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
corrupted++;
|
|
139
|
+
const skillDirName = basename(path.slice(0, path.length - "/SKILL.md".length));
|
|
140
|
+
const source = await findPristineSource(sourceRoot, skillDirName);
|
|
141
|
+
if (!source) {
|
|
142
|
+
unresolvable++;
|
|
143
|
+
results.push({ path, action: "corrupted-no-source", reasons });
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (write) {
|
|
147
|
+
const pristine = await fs.readFile(source, "utf8");
|
|
148
|
+
await fs.writeFile(path, pristine, "utf8");
|
|
149
|
+
restored++;
|
|
150
|
+
results.push({ path, action: "restored", reasons, source });
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
results.push({ path, action: "would-restore", reasons, source });
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (opts.json) {
|
|
157
|
+
process.stdout.write(JSON.stringify({ scanned: files.length, corrupted, restored, unresolvable, dryRun: !write, results }, null, 2) + "\n");
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
const dryNote = write ? "(applied)" : "(dry-run — pass --write to apply)";
|
|
161
|
+
process.stdout.write(`vskill repair-skills ${dryNote}\n`);
|
|
162
|
+
process.stdout.write(` scanned: ${files.length}\n`);
|
|
163
|
+
process.stdout.write(` corrupted: ${corrupted}\n`);
|
|
164
|
+
process.stdout.write(` ${write ? "restored" : "would restore"}: ${write ? restored : corrupted - unresolvable}\n`);
|
|
165
|
+
process.stdout.write(` corrupted but no pristine source: ${unresolvable}\n`);
|
|
166
|
+
if (corrupted > 0) {
|
|
167
|
+
process.stdout.write(`\nCorrupted files:\n`);
|
|
168
|
+
for (const r of results.filter((r) => r.action !== "ok")) {
|
|
169
|
+
process.stdout.write(` ! ${r.path}\n`);
|
|
170
|
+
for (const reason of r.reasons) {
|
|
171
|
+
process.stdout.write(` ${reason}\n`);
|
|
172
|
+
}
|
|
173
|
+
if (r.source) {
|
|
174
|
+
process.stdout.write(` source: ${r.source}\n`);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
process.stdout.write(` source: <not found in ${sourceRoot}>\n`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
scanned: files.length,
|
|
184
|
+
corrupted,
|
|
185
|
+
restored,
|
|
186
|
+
unresolvable,
|
|
187
|
+
results,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=repair-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-skills.js","sourceRoot":"","sources":["../../src/commands/repair-skills.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/submit.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
2
|
// vskill submit -- submit skill for verification via API or browser fallback
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
|
+
import * as fs from "node:fs/promises";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
4
7
|
import { openBrowser } from "../utils/browser.js";
|
|
5
|
-
import { submitSkill } from "../api/client.js";
|
|
8
|
+
import { submitSkill, getVersions } from "../api/client.js";
|
|
6
9
|
import { bold, green, red, dim, cyan, yellow } from "../utils/output.js";
|
|
7
10
|
import { parseGitHubSource, validateSkillName } from "../utils/validation.js";
|
|
11
|
+
import { upsertFrontmatterVersion, validatesAsYamlFrontmatter } from "../lib/frontmatter.js";
|
|
12
|
+
import { addAuthoredSkill } from "../lockfile/authored.js";
|
|
13
|
+
import { getProjectRoot } from "../lockfile/project-root.js";
|
|
8
14
|
export async function submitCommand(source, opts) {
|
|
9
15
|
if (opts.skill && !validateSkillName(opts.skill)) {
|
|
10
16
|
console.error(red("Invalid skill name. ") + dim("Path traversal patterns are not allowed."));
|
|
@@ -58,6 +64,12 @@ export async function submitCommand(source, opts) {
|
|
|
58
64
|
console.log(green("Already verified! ") + dim("Skill is up-to-date in the registry."));
|
|
59
65
|
if (response.id)
|
|
60
66
|
console.log(dim(`Submission: ${response.id}`));
|
|
67
|
+
// 0794 / T-005 — write registry version back to local SKILL.md frontmatter.
|
|
68
|
+
// Only fires when the user has a local source path: prevents phantom
|
|
69
|
+
// "update available" right after submit (project_skill_version_publish_desync.md).
|
|
70
|
+
if (response.skillName && opts.path) {
|
|
71
|
+
await tryWriteBackVersion(response.skillName, opts.path);
|
|
72
|
+
}
|
|
61
73
|
return;
|
|
62
74
|
}
|
|
63
75
|
if (response.duplicate) {
|
|
@@ -70,6 +82,12 @@ export async function submitCommand(source, opts) {
|
|
|
70
82
|
console.log(dim(`State: ${response.state}`));
|
|
71
83
|
console.log(dim("\nThe skill will go through tier-1 and tier-2 scanning."));
|
|
72
84
|
console.log(dim(`Check status: vskill info ${opts.skill || repo}`));
|
|
85
|
+
// 0794 / T-005 — when state is already 'completed' (rare fast-path),
|
|
86
|
+
// attempt write-back. For pending state the user should re-run after
|
|
87
|
+
// scan completes (or use vskill outdated which will pick up the new version).
|
|
88
|
+
if (response.state === "completed" && response.skillName && opts.path) {
|
|
89
|
+
await tryWriteBackVersion(response.skillName, opts.path);
|
|
90
|
+
}
|
|
73
91
|
}
|
|
74
92
|
catch (err) {
|
|
75
93
|
const msg = err.message;
|
|
@@ -83,4 +101,46 @@ export async function submitCommand(source, opts) {
|
|
|
83
101
|
process.exit(1);
|
|
84
102
|
}
|
|
85
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* 0794 / T-005 — write the registry's latest version back to the user's
|
|
106
|
+
* local SKILL.md frontmatter. Looks up the latest published version via
|
|
107
|
+
* the registry's `/skills/<name>/versions` endpoint and uses
|
|
108
|
+
* upsertFrontmatterVersion to update only the top-level `version:` field.
|
|
109
|
+
*
|
|
110
|
+
* Best-effort: any failure is logged as dim text and never throws —
|
|
111
|
+
* write-back is a UX nicety, not a correctness requirement.
|
|
112
|
+
*/
|
|
113
|
+
async function tryWriteBackVersion(skillName, sourcePath) {
|
|
114
|
+
try {
|
|
115
|
+
const resolved = path.resolve(sourcePath);
|
|
116
|
+
if (!existsSync(resolved))
|
|
117
|
+
return;
|
|
118
|
+
const versions = await getVersions(skillName);
|
|
119
|
+
if (!versions || versions.length === 0)
|
|
120
|
+
return;
|
|
121
|
+
const latest = versions[0]; // API returns versions newest-first
|
|
122
|
+
if (!latest?.version)
|
|
123
|
+
return;
|
|
124
|
+
const before = await fs.readFile(resolved, "utf8");
|
|
125
|
+
const after = upsertFrontmatterVersion(before, latest.version);
|
|
126
|
+
if (after === before)
|
|
127
|
+
return; // already up to date
|
|
128
|
+
if (!validatesAsYamlFrontmatter(after)) {
|
|
129
|
+
console.log(dim(`(skipped writeback: result would not be valid YAML frontmatter)`));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
await fs.writeFile(resolved, after);
|
|
133
|
+
console.log(dim(`Wrote version ${latest.version} to ${path.relative(process.cwd(), resolved)}`));
|
|
134
|
+
// 0794 / T-006 — track this skill for source-origin update polling.
|
|
135
|
+
try {
|
|
136
|
+
addAuthoredSkill(getProjectRoot(), skillName, resolved);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Authored tracking is best-effort; never block writeback.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
console.log(dim(`(version writeback skipped: ${err.message})`));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
86
146
|
//# sourceMappingURL=submit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../../src/commands/submit.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAE9E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAiB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../../src/commands/submit.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAE9E,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAiB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAQ7D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAA0B,EAC1B,IAAmB;IAEnB,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,KAAK,CACX,GAAG,CAAC,sBAAsB,CAAC,GAAG,GAAG,CAAC,0CAA0C,CAAC,CAC9E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC,4CAA4C,CAAC,CAAC,CAAC;QAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,GAAG,CAAC,uBAAuB,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,+BAA+B,CAAC,CACxG,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IAC/B,MAAM,OAAO,GAAG,sBAAsB,KAAK,IAAI,IAAI,EAAE,CAAC;IAEtD,+CAA+C;IAC/C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAC/D,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,KAAK;YAAE,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAChE,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;QAEjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAChG,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7E,OAAO,CAAC,GAAG,CAAC,8BAA8B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,OAAO;IACT,CAAC;IAED,2DAA2D;IAC3D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC;IAEtF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC;YACjC,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,KAAK;YACrB,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,MAAM,EAAE,YAAY;SACrB,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,GAAG,GAAG,CAAC,sCAAsC,CAAC,CAAC,CAAC;YACvF,IAAI,QAAQ,CAAC,EAAE;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAChE,4EAA4E;YAC5E,qEAAqE;YACrE,mFAAmF;YACnF,IAAI,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACpC,MAAM,mBAAmB,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;YACxF,IAAI,QAAQ,CAAC,YAAY;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;YAC7F,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,OAAO,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QACpE,qEAAqE;QACrE,qEAAqE;QACrE,8EAA8E;QAC9E,IAAI,QAAQ,CAAC,KAAK,KAAK,WAAW,IAAI,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACtE,MAAM,mBAAmB,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,CAAC;QACnC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAChD,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;QACxG,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,mBAAmB,CAAC,SAAiB,EAAE,UAAkB;IACtE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO;QAClC,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,oCAAoC;QAChE,IAAI,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO;QAC7B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,KAAK,KAAK,MAAM;YAAE,OAAO,CAAC,qBAAqB;QACnD,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC,CAAC;YACpF,OAAO;QACT,CAAC;QACD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,OAAO,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QACjG,oEAAoE;QACpE,IAAI,CAAC;YACH,gBAAgB,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;QAAC,MAAM,CAAC;YACP,2DAA2D;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,+BAAgC,GAAa,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
|