vskill 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 (59) hide show
  1. package/README.md +49 -0
  2. package/dist/agents/agents-registry.d.ts +57 -0
  3. package/dist/agents/agents-registry.js +511 -0
  4. package/dist/agents/agents-registry.js.map +1 -0
  5. package/dist/api/client.d.ts +50 -0
  6. package/dist/api/client.js +50 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/commands/add.d.ts +7 -0
  9. package/dist/commands/add.js +126 -0
  10. package/dist/commands/add.js.map +1 -0
  11. package/dist/commands/find.d.ts +1 -0
  12. package/dist/commands/find.js +42 -0
  13. package/dist/commands/find.js.map +1 -0
  14. package/dist/commands/init.d.ts +1 -0
  15. package/dist/commands/init.js +39 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/list.d.ts +6 -0
  18. package/dist/commands/list.js +79 -0
  19. package/dist/commands/list.js.map +1 -0
  20. package/dist/commands/scan.d.ts +1 -0
  21. package/dist/commands/scan.js +99 -0
  22. package/dist/commands/scan.js.map +1 -0
  23. package/dist/commands/submit.d.ts +5 -0
  24. package/dist/commands/submit.js +34 -0
  25. package/dist/commands/submit.js.map +1 -0
  26. package/dist/commands/update.d.ts +5 -0
  27. package/dist/commands/update.js +114 -0
  28. package/dist/commands/update.js.map +1 -0
  29. package/dist/commands/version.d.ts +1 -0
  30. package/dist/commands/version.js +11 -0
  31. package/dist/commands/version.js.map +1 -0
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.js +68 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/lockfile/index.d.ts +2 -0
  36. package/dist/lockfile/index.js +2 -0
  37. package/dist/lockfile/index.js.map +1 -0
  38. package/dist/lockfile/lockfile.d.ts +23 -0
  39. package/dist/lockfile/lockfile.js +70 -0
  40. package/dist/lockfile/lockfile.js.map +1 -0
  41. package/dist/lockfile/types.d.ts +14 -0
  42. package/dist/lockfile/types.js +5 -0
  43. package/dist/lockfile/types.js.map +1 -0
  44. package/dist/scanner/index.d.ts +4 -0
  45. package/dist/scanner/index.js +3 -0
  46. package/dist/scanner/index.js.map +1 -0
  47. package/dist/scanner/patterns.d.ts +25 -0
  48. package/dist/scanner/patterns.js +347 -0
  49. package/dist/scanner/patterns.js.map +1 -0
  50. package/dist/scanner/pipeline/submission-pipeline.d.ts +100 -0
  51. package/dist/scanner/pipeline/submission-pipeline.js +173 -0
  52. package/dist/scanner/pipeline/submission-pipeline.js.map +1 -0
  53. package/dist/scanner/tier1.d.ts +23 -0
  54. package/dist/scanner/tier1.js +83 -0
  55. package/dist/scanner/tier1.js.map +1 -0
  56. package/dist/utils/output.d.ts +15 -0
  57. package/dist/utils/output.js +87 -0
  58. package/dist/utils/output.js.map +1 -0
  59. package/package.json +51 -0
@@ -0,0 +1,114 @@
1
+ // ---------------------------------------------------------------------------
2
+ // vskill update -- update installed skills
3
+ // ---------------------------------------------------------------------------
4
+ import { mkdirSync, writeFileSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { createHash } from "node:crypto";
7
+ import { readLockfile, writeLockfile } from "../lockfile/index.js";
8
+ import { getSkill } from "../api/client.js";
9
+ import { detectInstalledAgents } from "../agents/agents-registry.js";
10
+ import { runTier1Scan } from "../scanner/index.js";
11
+ import { bold, green, red, yellow, dim, cyan, spinner, } from "../utils/output.js";
12
+ export async function updateCommand(skill, opts) {
13
+ const lock = readLockfile();
14
+ if (!lock) {
15
+ console.error(yellow("No vskill.lock found. Run ") +
16
+ cyan("vskill init") +
17
+ yellow(" first."));
18
+ process.exit(1);
19
+ return; // unreachable but satisfies TS
20
+ }
21
+ const skillNames = Object.keys(lock.skills);
22
+ if (skillNames.length === 0) {
23
+ console.log(dim("No skills installed. Nothing to update."));
24
+ return;
25
+ }
26
+ // Determine which skills to update
27
+ let toUpdate;
28
+ if (skill) {
29
+ if (!lock.skills[skill]) {
30
+ console.error(red(`Skill "${skill}" is not installed.`));
31
+ process.exit(1);
32
+ return;
33
+ }
34
+ toUpdate = [skill];
35
+ }
36
+ else if (opts.all) {
37
+ toUpdate = skillNames;
38
+ }
39
+ else {
40
+ console.log(yellow("Specify a skill name or use --all to update everything."));
41
+ console.log(dim(`Installed: ${skillNames.join(", ")}`));
42
+ return;
43
+ }
44
+ const agents = await detectInstalledAgents();
45
+ if (agents.length === 0) {
46
+ console.error(red("No agents detected. Cannot update."));
47
+ process.exit(1);
48
+ return;
49
+ }
50
+ let updated = 0;
51
+ for (const name of toUpdate) {
52
+ const entry = lock.skills[name];
53
+ const spin = spinner(`Checking ${name}`);
54
+ try {
55
+ const remote = await getSkill(name);
56
+ spin.stop();
57
+ // Compare versions
58
+ if (remote.sha && remote.sha === entry.sha) {
59
+ console.log(dim(`${name}: already up to date`));
60
+ continue;
61
+ }
62
+ console.log(`${bold(name)}: ${dim(entry.sha?.slice(0, 8) || "unknown")} -> ${green(remote.sha?.slice(0, 8) || "new")}`);
63
+ // Fetch new content
64
+ if (!remote.content) {
65
+ console.log(yellow(` No content available from registry for ${name}. Skipping.`));
66
+ continue;
67
+ }
68
+ // Run scan on new version
69
+ const scanResult = runTier1Scan(remote.content);
70
+ const verdictColor = scanResult.verdict === "PASS"
71
+ ? green
72
+ : scanResult.verdict === "CONCERNS"
73
+ ? yellow
74
+ : red;
75
+ console.log(` Scan: ${verdictColor(scanResult.verdict)} (${scanResult.score}/100)`);
76
+ if (scanResult.verdict === "FAIL") {
77
+ console.log(red(` Refusing to update ${name}: scan FAILED`));
78
+ continue;
79
+ }
80
+ // Install to each agent
81
+ const sha = createHash("sha256")
82
+ .update(remote.content)
83
+ .digest("hex")
84
+ .slice(0, 12);
85
+ for (const agent of agents) {
86
+ const skillDir = join(process.cwd(), agent.localSkillsDir, name);
87
+ try {
88
+ mkdirSync(skillDir, { recursive: true });
89
+ writeFileSync(join(skillDir, "SKILL.md"), remote.content, "utf-8");
90
+ }
91
+ catch {
92
+ // Silently skip write failures for update
93
+ }
94
+ }
95
+ // Update lockfile entry
96
+ lock.skills[name] = {
97
+ ...entry,
98
+ version: remote.version || entry.version,
99
+ sha,
100
+ tier: remote.tier || entry.tier,
101
+ installedAt: new Date().toISOString(),
102
+ };
103
+ updated++;
104
+ }
105
+ catch (err) {
106
+ spin.stop();
107
+ console.log(yellow(` ${name}: `) +
108
+ dim(`could not fetch from registry (${err.message})`));
109
+ }
110
+ }
111
+ writeLockfile(lock);
112
+ console.log(`\n${updated > 0 ? green(`${updated} skill${updated === 1 ? "" : "s"} updated`) : dim("No updates available")}`);
113
+ }
114
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function versionCommand(): Promise<void>;
@@ -0,0 +1,11 @@
1
+ // ---------------------------------------------------------------------------
2
+ // vskill version
3
+ // ---------------------------------------------------------------------------
4
+ import { createRequire } from "node:module";
5
+ import { bold, cyan } from "../utils/output.js";
6
+ const require = createRequire(import.meta.url);
7
+ const pkg = require("../../package.json");
8
+ export async function versionCommand() {
9
+ console.log(`${bold("vskill")} ${cyan(`v${pkg.version}`)}`);
10
+ }
11
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { createRequire } from "node:module";
4
+ const require = createRequire(import.meta.url);
5
+ const pkg = require("../package.json");
6
+ const program = new Command();
7
+ program
8
+ .name("vskill")
9
+ .description("Secure multi-platform AI skill installer -- scan before you install")
10
+ .version(pkg.version, "-v, --version");
11
+ program
12
+ .command("init")
13
+ .description("Initialize vskill and detect installed AI agents")
14
+ .action(async () => {
15
+ const { initCommand } = await import("./commands/init.js");
16
+ await initCommand();
17
+ });
18
+ program
19
+ .command("add <source>")
20
+ .description("Install a skill from GitHub with security scanning")
21
+ .option("--skill <name>", "Skill name within a multi-skill repo")
22
+ .option("--global", "Install to global agent directories")
23
+ .option("--force", "Install even if scan finds issues")
24
+ .action(async (source, opts) => {
25
+ const { addCommand } = await import("./commands/add.js");
26
+ await addCommand(source, opts);
27
+ });
28
+ program
29
+ .command("scan <path>")
30
+ .description("Run tier-1 security scan on a SKILL.md file")
31
+ .action(async (path) => {
32
+ const { scanCommand } = await import("./commands/scan.js");
33
+ await scanCommand(path);
34
+ });
35
+ program
36
+ .command("list")
37
+ .description("List installed skills or detected agents")
38
+ .option("--agents", "Show all 39 known agents with installed status")
39
+ .option("--json", "Output as JSON")
40
+ .action(async (opts) => {
41
+ const { listCommand } = await import("./commands/list.js");
42
+ await listCommand(opts);
43
+ });
44
+ program
45
+ .command("find <query>")
46
+ .description("Search the verified-skill.com registry")
47
+ .action(async (query) => {
48
+ const { findCommand } = await import("./commands/find.js");
49
+ await findCommand(query);
50
+ });
51
+ program
52
+ .command("update [skill]")
53
+ .description("Update installed skills from the registry")
54
+ .option("--all", "Update all installed skills")
55
+ .action(async (skill, opts) => {
56
+ const { updateCommand } = await import("./commands/update.js");
57
+ await updateCommand(skill, opts);
58
+ });
59
+ program
60
+ .command("submit <source>")
61
+ .description("Submit a skill for verification on verified-skill.com")
62
+ .option("--email <email>", "Email for submission updates")
63
+ .action(async (source, opts) => {
64
+ const { submitCommand } = await import("./commands/submit.js");
65
+ await submitCommand(source, opts);
66
+ });
67
+ program.parse();
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,qEAAqE,CAAC;KAClF,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;AAEzC,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,WAAW,EAAE,CAAC;AACtB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,oDAAoD,CAAC;KACjE,MAAM,CAAC,gBAAgB,EAAE,sCAAsC,CAAC;KAChE,MAAM,CAAC,UAAU,EAAE,qCAAqC,CAAC;KACzD,MAAM,CAAC,SAAS,EAAE,mCAAmC,CAAC;KACtD,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;IACrC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACzD,MAAM,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,UAAU,EAAE,gDAAgD,CAAC;KACpE,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;IAC9B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,OAAO,EAAE,6BAA6B,CAAC;KAC9C,MAAM,CAAC,KAAK,EAAE,KAAyB,EAAE,IAAI,EAAE,EAAE;IAChD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAC/D,MAAM,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,uDAAuD,CAAC;KACpE,MAAM,CAAC,iBAAiB,EAAE,8BAA8B,CAAC;KACzD,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,IAAI,EAAE,EAAE;IACrC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAC/D,MAAM,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type { VskillLock, SkillLockEntry } from "./types.js";
2
+ export { readLockfile, writeLockfile, ensureLockfile, addSkillToLock, removeSkillFromLock, } from "./lockfile.js";
@@ -0,0 +1,2 @@
1
+ export { readLockfile, writeLockfile, ensureLockfile, addSkillToLock, removeSkillFromLock, } from "./lockfile.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lockfile/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,cAAc,EACd,mBAAmB,GACpB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { VskillLock, SkillLockEntry } from "./types.js";
2
+ /**
3
+ * Read vskill.lock from cwd or specified directory.
4
+ * Returns null if the lockfile does not exist.
5
+ */
6
+ export declare function readLockfile(dir?: string): VskillLock | null;
7
+ /**
8
+ * Write a VskillLock object to disk.
9
+ */
10
+ export declare function writeLockfile(lock: VskillLock, dir?: string): void;
11
+ /**
12
+ * Create a lockfile if one does not already exist.
13
+ * Returns the existing or newly created lock.
14
+ */
15
+ export declare function ensureLockfile(dir?: string): VskillLock;
16
+ /**
17
+ * Add or update a skill entry in the lockfile.
18
+ */
19
+ export declare function addSkillToLock(name: string, info: SkillLockEntry, dir?: string): void;
20
+ /**
21
+ * Remove a skill entry from the lockfile.
22
+ */
23
+ export declare function removeSkillFromLock(name: string, dir?: string): void;
@@ -0,0 +1,70 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Read/write vskill.lock
3
+ // ---------------------------------------------------------------------------
4
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ const LOCKFILE_NAME = "vskill.lock";
7
+ function lockPath(dir) {
8
+ return join(dir || process.cwd(), LOCKFILE_NAME);
9
+ }
10
+ /**
11
+ * Read vskill.lock from cwd or specified directory.
12
+ * Returns null if the lockfile does not exist.
13
+ */
14
+ export function readLockfile(dir) {
15
+ const p = lockPath(dir);
16
+ if (!existsSync(p))
17
+ return null;
18
+ try {
19
+ const raw = readFileSync(p, "utf-8");
20
+ return JSON.parse(raw);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /**
27
+ * Write a VskillLock object to disk.
28
+ */
29
+ export function writeLockfile(lock, dir) {
30
+ lock.updatedAt = new Date().toISOString();
31
+ const p = lockPath(dir);
32
+ writeFileSync(p, JSON.stringify(lock, null, 2) + "\n", "utf-8");
33
+ }
34
+ /**
35
+ * Create a lockfile if one does not already exist.
36
+ * Returns the existing or newly created lock.
37
+ */
38
+ export function ensureLockfile(dir) {
39
+ const existing = readLockfile(dir);
40
+ if (existing)
41
+ return existing;
42
+ const lock = {
43
+ version: 1,
44
+ agents: [],
45
+ skills: {},
46
+ createdAt: new Date().toISOString(),
47
+ updatedAt: new Date().toISOString(),
48
+ };
49
+ writeLockfile(lock, dir);
50
+ return lock;
51
+ }
52
+ /**
53
+ * Add or update a skill entry in the lockfile.
54
+ */
55
+ export function addSkillToLock(name, info, dir) {
56
+ const lock = ensureLockfile(dir);
57
+ lock.skills[name] = info;
58
+ writeLockfile(lock, dir);
59
+ }
60
+ /**
61
+ * Remove a skill entry from the lockfile.
62
+ */
63
+ export function removeSkillFromLock(name, dir) {
64
+ const lock = readLockfile(dir);
65
+ if (!lock)
66
+ return;
67
+ delete lock.skills[name];
68
+ writeLockfile(lock, dir);
69
+ }
70
+ //# sourceMappingURL=lockfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../../src/lockfile/lockfile.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,aAAa,GAAG,aAAa,CAAC;AAEpC,SAAS,QAAQ,CAAC,GAAY;IAC5B,OAAO,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAgB,EAAE,GAAY;IAC1D,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,IAAI,GAAe;QACvB,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IACF,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,IAAoB,EACpB,GAAY;IAEZ,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,GAAY;IAC5D,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,aAAa,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface SkillLockEntry {
2
+ version: string;
3
+ sha: string;
4
+ tier: string;
5
+ installedAt: string;
6
+ source: string;
7
+ }
8
+ export interface VskillLock {
9
+ version: 1;
10
+ agents: string[];
11
+ skills: Record<string, SkillLockEntry>;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ }
@@ -0,0 +1,5 @@
1
+ // ---------------------------------------------------------------------------
2
+ // vskill.lock schema
3
+ // ---------------------------------------------------------------------------
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lockfile/types.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E"}
@@ -0,0 +1,4 @@
1
+ export { scanContent, SCAN_PATTERNS } from "./patterns.js";
2
+ export type { ScanPattern, ScanFinding, ScanVerdict, PatternSeverity, PatternCategory, } from "./patterns.js";
3
+ export { runTier1Scan } from "./tier1.js";
4
+ export type { Tier1Result } from "./tier1.js";
@@ -0,0 +1,3 @@
1
+ export { scanContent, SCAN_PATTERNS } from "./patterns.js";
2
+ export { runTier1Scan } from "./tier1.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAS3D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,25 @@
1
+ export type PatternSeverity = "critical" | "high" | "medium" | "low" | "info";
2
+ export type PatternCategory = "command-injection" | "data-exfiltration" | "privilege-escalation" | "credential-theft" | "prompt-injection" | "filesystem-access" | "network-access" | "code-execution";
3
+ export type ScanVerdict = "PASS" | "CONCERNS" | "FAIL";
4
+ export interface ScanPattern {
5
+ id: string;
6
+ name: string;
7
+ severity: PatternSeverity;
8
+ description: string;
9
+ pattern: RegExp;
10
+ category: PatternCategory;
11
+ }
12
+ export interface ScanFinding {
13
+ patternId: string;
14
+ patternName: string;
15
+ severity: PatternSeverity;
16
+ category: PatternCategory;
17
+ match: string;
18
+ lineNumber: number;
19
+ context: string;
20
+ }
21
+ export declare const SCAN_PATTERNS: ScanPattern[];
22
+ /**
23
+ * Scan content against all 37 patterns, returning every match found.
24
+ */
25
+ export declare function scanContent(content: string): ScanFinding[];