superskill 0.2.5 → 0.2.7

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.
@@ -0,0 +1,167 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later OR Commercial
2
+ import { readFile, writeFile, mkdir, rename } from "fs/promises";
3
+ import { resolve, dirname } from "path";
4
+ import { tmpdir } from "os";
5
+ import { randomBytes } from "crypto";
6
+ // ── Constants ────────────────────────────────────────
7
+ const MAX_ACTIVATIONS = 1000;
8
+ const MAX_FAILED_SEARCHES = 1000;
9
+ const ANALYTICS_DIR = resolve(process.env.HOME ?? process.env.USERPROFILE ?? tmpdir(), ".superskill");
10
+ const ANALYTICS_PATH = resolve(ANALYTICS_DIR, "analytics.json");
11
+ /** Override path for testing. */
12
+ let analyticsPathOverride = null;
13
+ export function setAnalyticsPath(path) {
14
+ analyticsPathOverride = path;
15
+ }
16
+ function getAnalyticsPath() {
17
+ return analyticsPathOverride ?? ANALYTICS_PATH;
18
+ }
19
+ // ── Storage ──────────────────────────────────────────
20
+ function emptyData() {
21
+ return {
22
+ activations: [],
23
+ failed_searches: [],
24
+ summary: {
25
+ total_activations: 0,
26
+ total_failed_searches: 0,
27
+ most_used_skills: [],
28
+ first_seen: null,
29
+ last_seen: null,
30
+ },
31
+ };
32
+ }
33
+ async function readAnalytics() {
34
+ try {
35
+ const raw = await readFile(getAnalyticsPath(), "utf-8");
36
+ const data = JSON.parse(raw);
37
+ return {
38
+ activations: Array.isArray(data.activations) ? data.activations : [],
39
+ failed_searches: Array.isArray(data.failed_searches) ? data.failed_searches : [],
40
+ summary: data.summary ?? emptyData().summary,
41
+ };
42
+ }
43
+ catch {
44
+ return emptyData();
45
+ }
46
+ }
47
+ function computeSummary(data) {
48
+ const counts = new Map();
49
+ for (const a of data.activations) {
50
+ counts.set(a.skill_id, (counts.get(a.skill_id) ?? 0) + 1);
51
+ }
52
+ const most_used_skills = Array.from(counts.entries())
53
+ .map(([id, count]) => ({ id, count }))
54
+ .sort((a, b) => b.count - a.count)
55
+ .slice(0, 20);
56
+ const allTimestamps = [
57
+ ...data.activations.map((a) => a.timestamp),
58
+ ...data.failed_searches.map((f) => f.timestamp),
59
+ ].filter(Boolean).sort();
60
+ return {
61
+ total_activations: data.activations.length,
62
+ total_failed_searches: data.failed_searches.length,
63
+ most_used_skills,
64
+ first_seen: allTimestamps[0] ?? null,
65
+ last_seen: allTimestamps[allTimestamps.length - 1] ?? null,
66
+ };
67
+ }
68
+ function rotateIfNeeded(data) {
69
+ if (data.activations.length > MAX_ACTIVATIONS) {
70
+ data.activations = data.activations.slice(-MAX_ACTIVATIONS);
71
+ }
72
+ if (data.failed_searches.length > MAX_FAILED_SEARCHES) {
73
+ data.failed_searches = data.failed_searches.slice(-MAX_FAILED_SEARCHES);
74
+ }
75
+ }
76
+ async function writeAnalytics(data) {
77
+ const filePath = getAnalyticsPath();
78
+ await mkdir(dirname(filePath), { recursive: true });
79
+ // Atomic write: write to temp file, then rename
80
+ const tempPath = filePath + "." + randomBytes(6).toString("hex") + ".tmp";
81
+ const json = JSON.stringify(data, null, 2);
82
+ await writeFile(tempPath, json, "utf-8");
83
+ await rename(tempPath, filePath);
84
+ }
85
+ // ── Public API ───────────────────────────────────────
86
+ /**
87
+ * Track a skill activation event.
88
+ * Never throws — analytics failures must not block skill activation.
89
+ */
90
+ export async function trackActivation(activation) {
91
+ try {
92
+ const data = await readAnalytics();
93
+ data.activations.push({
94
+ ...activation,
95
+ timestamp: new Date().toISOString(),
96
+ });
97
+ rotateIfNeeded(data);
98
+ data.summary = computeSummary(data);
99
+ await writeAnalytics(data);
100
+ }
101
+ catch {
102
+ // Never crash — analytics failure must never block skill activation
103
+ }
104
+ }
105
+ /**
106
+ * Track a failed search event.
107
+ * Never throws — analytics failures must not block skill activation.
108
+ */
109
+ export async function trackFailedSearch(query, resultCount = 0) {
110
+ try {
111
+ const data = await readAnalytics();
112
+ data.failed_searches.push({
113
+ query,
114
+ timestamp: new Date().toISOString(),
115
+ result_count: resultCount,
116
+ });
117
+ rotateIfNeeded(data);
118
+ data.summary = computeSummary(data);
119
+ await writeAnalytics(data);
120
+ }
121
+ catch {
122
+ // Never crash — analytics failure must never block skill activation
123
+ }
124
+ }
125
+ /**
126
+ * Track a web discovery activation (convenience wrapper).
127
+ * Never throws.
128
+ */
129
+ export async function trackWebDiscovery(taskQuery, matched) {
130
+ try {
131
+ await trackActivation({
132
+ skill_id: "web_discovery",
133
+ match_method: "web_discovery",
134
+ task_query: taskQuery,
135
+ matched,
136
+ });
137
+ }
138
+ catch {
139
+ // Never crash
140
+ }
141
+ }
142
+ /**
143
+ * Get the current analytics summary.
144
+ * Never throws — returns empty summary on failure.
145
+ */
146
+ export async function getAnalyticsSummary() {
147
+ try {
148
+ const data = await readAnalytics();
149
+ return computeSummary(data);
150
+ }
151
+ catch {
152
+ return emptyData().summary;
153
+ }
154
+ }
155
+ /**
156
+ * Get the full analytics data (for debugging / display).
157
+ * Never throws — returns empty data on failure.
158
+ */
159
+ export async function getAnalyticsData() {
160
+ try {
161
+ return await readAnalytics();
162
+ }
163
+ catch {
164
+ return emptyData();
165
+ }
166
+ }
167
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/lib/analytics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /** The 8 core skills that are prefetched on install */
2
+ export declare const PREFETCH_SKILL_IDS: string[];
3
+ export declare function setCacheDir(dir: string): void;
4
+ export declare function getCacheDir(): string;
5
+ /**
6
+ * Get cached skill content. Returns null if not cached.
7
+ */
8
+ export declare function getCachedSkill(skillId: string): Promise<string | null>;
9
+ /**
10
+ * Write skill content to cache. Uses atomic write (temp + rename).
11
+ */
12
+ export declare function cacheSkill(skillId: string, content: string): Promise<void>;
13
+ /**
14
+ * Check if a skill is cached.
15
+ */
16
+ export declare function isSkillCached(skillId: string): Promise<boolean>;
17
+ /**
18
+ * Prefetch core skills from their source repos.
19
+ * Called during postinstall. Non-fatal — warns on failure, never blocks install.
20
+ * Returns count of successfully cached skills.
21
+ */
22
+ export declare function prefetchCoreSkills(options?: {
23
+ concurrency?: number;
24
+ onProgress?: (skill: string, status: "cached" | "fetched" | "failed") => void;
25
+ }): Promise<{
26
+ fetched: number;
27
+ cached: number;
28
+ failed: number;
29
+ errors: string[];
30
+ }>;
31
+ /**
32
+ * List all cached skills.
33
+ */
34
+ export declare function listCachedSkills(): Promise<string[]>;
@@ -0,0 +1,150 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later OR Commercial
2
+ /**
3
+ * Skill cache — local disk cache for fetched skill content.
4
+ * Skills are cached at ~/.superskill/cache/{source}/{name}@{version}.md
5
+ * Prefetched skills are downloaded on install for offline availability.
6
+ */
7
+ import { readFile, writeFile, mkdir, rename, readdir } from "fs/promises";
8
+ import { resolve, dirname, join } from "path";
9
+ import { homedir, tmpdir } from "os";
10
+ import { randomBytes } from "crypto";
11
+ import { CATALOG } from "../commands/skill/catalog.js";
12
+ // ── Configuration ────────────────────────────────────
13
+ const CACHE_DIR = resolve(homedir(), ".superskill", "cache");
14
+ /** The 8 core skills that are prefetched on install */
15
+ export const PREFETCH_SKILL_IDS = [
16
+ "superpowers/brainstorming",
17
+ "ecc/plan",
18
+ "ecc/tdd-workflow",
19
+ "ecc/go-review",
20
+ "superpowers/systematic-debugging",
21
+ "ecc/security-review",
22
+ "ecc/verification-loop",
23
+ "ecc/deployment-patterns",
24
+ ];
25
+ // Allow tests to override the cache dir
26
+ let cacheDir = CACHE_DIR;
27
+ export function setCacheDir(dir) { cacheDir = dir; }
28
+ export function getCacheDir() { return cacheDir; }
29
+ // ── Cache Operations ─────────────────────────────────
30
+ /**
31
+ * Get cached skill content. Returns null if not cached.
32
+ */
33
+ export async function getCachedSkill(skillId) {
34
+ try {
35
+ const path = skillCachePath(skillId);
36
+ return await readFile(path, "utf-8");
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ /**
43
+ * Write skill content to cache. Uses atomic write (temp + rename).
44
+ */
45
+ export async function cacheSkill(skillId, content) {
46
+ try {
47
+ const path = skillCachePath(skillId);
48
+ await mkdir(dirname(path), { recursive: true });
49
+ const tmp = join(tmpdir(), `superskill-cache-${randomBytes(8).toString("hex")}`);
50
+ await writeFile(tmp, content, "utf-8");
51
+ await rename(tmp, path);
52
+ }
53
+ catch {
54
+ // Cache write failure is non-fatal
55
+ }
56
+ }
57
+ /**
58
+ * Check if a skill is cached.
59
+ */
60
+ export async function isSkillCached(skillId) {
61
+ try {
62
+ await readFile(skillCachePath(skillId), "utf-8");
63
+ return true;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }
69
+ /**
70
+ * Prefetch core skills from their source repos.
71
+ * Called during postinstall. Non-fatal — warns on failure, never blocks install.
72
+ * Returns count of successfully cached skills.
73
+ */
74
+ export async function prefetchCoreSkills(options) {
75
+ const concurrency = options?.concurrency ?? 4;
76
+ const onProgress = options?.onProgress;
77
+ const results = { fetched: 0, cached: 0, failed: 0, errors: [] };
78
+ // Resolve skill IDs to catalog entries
79
+ const skills = PREFETCH_SKILL_IDS
80
+ .map((id) => CATALOG.find((s) => s.id === id))
81
+ .filter((s) => s !== undefined);
82
+ // Process in batches for bounded concurrency
83
+ for (let i = 0; i < skills.length; i += concurrency) {
84
+ const batch = skills.slice(i, i + concurrency);
85
+ const batchResults = await Promise.allSettled(batch.map(async (skill) => {
86
+ // Check if already cached
87
+ if (await isSkillCached(skill.id)) {
88
+ onProgress?.(skill.id, "cached");
89
+ results.cached++;
90
+ return;
91
+ }
92
+ // Fetch from source
93
+ const content = await fetchSkillFromSource(skill.source);
94
+ await cacheSkill(skill.id, content);
95
+ onProgress?.(skill.id, "fetched");
96
+ results.fetched++;
97
+ }));
98
+ for (let j = 0; j < batchResults.length; j++) {
99
+ const result = batchResults[j];
100
+ if (result.status === "rejected") {
101
+ const skillId = batch[j].id;
102
+ const error = result.reason instanceof Error ? result.reason.message : String(result.reason);
103
+ results.errors.push(`${skillId}: ${error}`);
104
+ results.failed++;
105
+ onProgress?.(skillId, "failed");
106
+ }
107
+ }
108
+ }
109
+ return results;
110
+ }
111
+ /**
112
+ * List all cached skills.
113
+ */
114
+ export async function listCachedSkills() {
115
+ try {
116
+ const cached = [];
117
+ const repos = await readdir(cacheDir).catch(() => []);
118
+ for (const repo of repos) {
119
+ const repoDir = join(cacheDir, repo);
120
+ const files = await readdir(repoDir).catch(() => []);
121
+ for (const file of files) {
122
+ if (file.endsWith(".md")) {
123
+ const name = file.replace(".md", "");
124
+ cached.push(`${repo}/${name}`);
125
+ }
126
+ }
127
+ }
128
+ return cached;
129
+ }
130
+ catch {
131
+ return [];
132
+ }
133
+ }
134
+ // ── Helpers ──────────────────────────────────────────
135
+ function skillCachePath(skillId) {
136
+ // "ecc/tdd-workflow" → ~/.superskill/cache/ecc/tdd-workflow.md
137
+ const [repo, ...rest] = skillId.split("/");
138
+ const name = rest.join("/");
139
+ return resolve(cacheDir, repo, `${name}.md`);
140
+ }
141
+ async function fetchSkillFromSource(source) {
142
+ if (source.startsWith("http://") || source.startsWith("https://")) {
143
+ const res = await fetch(source);
144
+ if (!res.ok)
145
+ throw new Error(`HTTP ${res.status} ${res.statusText}`);
146
+ return res.text();
147
+ }
148
+ return readFile(source, "utf-8");
149
+ }
150
+ //# sourceMappingURL=skill-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-cache.js","sourceRoot":"","sources":["../../src/lib/skill-cache.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@
2
2
  // SPDX-License-Identifier: AGPL-3.0-or-later OR Commercial
3
3
  try {
4
4
  const { detectClients } = await import("./detect.js");
5
+ const { prefetchCoreSkills, PREFETCH_SKILL_IDS } = await import("../lib/skill-cache.js");
5
6
  if (!process.stdout.isTTY)
6
7
  process.exit(0);
7
8
  const detected = detectClients();
@@ -14,8 +15,28 @@ try {
14
15
  console.log(" No AI clients detected.");
15
16
  }
16
17
  console.log(' Run "superskill-cli setup --all" to configure all 8 supported clients.\n');
18
+ // Prefetch core skills for offline availability
19
+ console.log(` Prefetching ${PREFETCH_SKILL_IDS.length} core skills...`);
20
+ const result = await prefetchCoreSkills({
21
+ onProgress: (skill, status) => {
22
+ const icon = status === "fetched" ? "+" : status === "cached" ? "=" : "x";
23
+ console.log(` [${icon}] ${skill}`);
24
+ },
25
+ });
26
+ const parts = [];
27
+ if (result.fetched > 0)
28
+ parts.push(`${result.fetched} fetched`);
29
+ if (result.cached > 0)
30
+ parts.push(`${result.cached} already cached`);
31
+ if (result.failed > 0)
32
+ parts.push(`${result.failed} failed`);
33
+ console.log(` Done: ${parts.join(", ")}.\n`);
34
+ if (result.failed > 0) {
35
+ console.log(" Some skills could not be prefetched. They will be fetched on first use.\n");
36
+ }
17
37
  }
18
38
  catch {
39
+ // Postinstall must never fail the install
19
40
  process.exit(0);
20
41
  }
21
42
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../../src/setup/postinstall.ts"],"names":[],"mappings":";AACA,2DAA2D;AAC3D,IAAI,CAAC;IACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IAEtD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IAEjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;IAC7F,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;AAC5F,CAAC;AAAC,MAAM,CAAC;IACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"postinstall.js","sourceRoot":"","sources":["../../src/setup/postinstall.ts"],"names":[],"mappings":";AACA,2DAA2D;AAC3D,IAAI,CAAC;IACH,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACtD,MAAM,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAEzF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IAEjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;IAC7F,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;IAE1F,gDAAgD;IAChD,OAAO,CAAC,GAAG,CAAC,iBAAiB,kBAAkB,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAEzE,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC;QACtC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;QACxC,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;IAChE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,iBAAiB,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE9C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAAC,MAAM,CAAC;IACP,0CAA0C;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superskill",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Universal agentic knowledge base + context optimizer + skill marketplace for AI tools",
5
5
  "type": "module",
6
6
  "main": "dist/mcp-server.js",