@xynogen/pix-skills 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.ts +26 -5
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
13
|
+
import { homedir } from "node:os";
|
|
13
14
|
import { join, resolve } from "node:path";
|
|
14
15
|
import { fileURLToPath } from "node:url";
|
|
15
16
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
@@ -18,12 +19,17 @@ import { Type } from "typebox";
|
|
|
18
19
|
|
|
19
20
|
// ─── Skill resolution ─────────────────────────────────────────────────────────
|
|
20
21
|
|
|
21
|
-
/** Absolute path to this package's skills/ directory. */
|
|
22
|
+
/** Absolute path to this package's bundled skills/ directory. */
|
|
22
23
|
function skillsRoot(): string {
|
|
23
24
|
const here = fileURLToPath(new URL(".", import.meta.url));
|
|
24
25
|
return resolve(here, "..", "skills");
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
/** Absolute path to the user-level skills directory (~/.pi/agent/skills). */
|
|
29
|
+
function userSkillsRoot(): string {
|
|
30
|
+
return join(homedir(), ".pi", "agent", "skills");
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
interface SkillEntry {
|
|
28
34
|
name: string;
|
|
29
35
|
/** Absolute path to the SKILL.md or flat .md file. */
|
|
@@ -31,13 +37,12 @@ interface SkillEntry {
|
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
/**
|
|
34
|
-
*
|
|
40
|
+
* Scan a single skills root directory.
|
|
35
41
|
* Supports two layouts:
|
|
36
42
|
* - flat: skills/commit.md
|
|
37
43
|
* - subdir: skills/commit/SKILL.md
|
|
38
44
|
*/
|
|
39
|
-
function
|
|
40
|
-
const root = skillsRoot();
|
|
45
|
+
function scanSkillsDir(root: string): SkillEntry[] {
|
|
41
46
|
if (!existsSync(root)) return [];
|
|
42
47
|
|
|
43
48
|
const entries: SkillEntry[] = [];
|
|
@@ -56,7 +61,23 @@ function discoverSkills(): SkillEntry[] {
|
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
63
|
|
|
59
|
-
return entries
|
|
64
|
+
return entries;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Discover all skills from bundled skills/ AND ~/.pi/agent/skills/.
|
|
69
|
+
* Bundled skills take precedence on name collision.
|
|
70
|
+
* Results sorted alphabetically by name.
|
|
71
|
+
*/
|
|
72
|
+
function discoverSkills(): SkillEntry[] {
|
|
73
|
+
const bundled = scanSkillsDir(skillsRoot());
|
|
74
|
+
const user = scanSkillsDir(userSkillsRoot());
|
|
75
|
+
|
|
76
|
+
// Merge: bundled wins on collision
|
|
77
|
+
const seen = new Set(bundled.map((s) => s.name));
|
|
78
|
+
const merged = [...bundled, ...user.filter((s) => !seen.has(s.name))];
|
|
79
|
+
|
|
80
|
+
return merged.sort((a, b) => a.name.localeCompare(b.name));
|
|
60
81
|
}
|
|
61
82
|
|
|
62
83
|
/** Extract the `description` from YAML frontmatter, or null. */
|