@ai-studio-3d/vyasa 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.
- package/README.md +69 -0
- package/data/common-kit.json +34 -0
- package/data/pricing.json +119 -0
- package/data/schema/AnalyticsData.json +214 -0
- package/data/schema/FoundationData.json +42 -0
- package/data/schema/KitData.json +321 -0
- package/data/schema/SearchData.json +173 -0
- package/data/schema/SessionDetailData.json +231 -0
- package/data/schema/SessionsListData.json +115 -0
- package/data/schema/WasteData.json +95 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +343 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/billing/index.d.ts +4 -0
- package/dist/core/billing/index.d.ts.map +1 -0
- package/dist/core/billing/index.js +43 -0
- package/dist/core/billing/index.js.map +1 -0
- package/dist/core/budget/index.d.ts +30 -0
- package/dist/core/budget/index.d.ts.map +1 -0
- package/dist/core/budget/index.js +61 -0
- package/dist/core/budget/index.js.map +1 -0
- package/dist/core/codex/index.d.ts +3 -0
- package/dist/core/codex/index.d.ts.map +1 -0
- package/dist/core/codex/index.js +212 -0
- package/dist/core/codex/index.js.map +1 -0
- package/dist/core/cursor/index.d.ts +3 -0
- package/dist/core/cursor/index.d.ts.map +1 -0
- package/dist/core/cursor/index.js +304 -0
- package/dist/core/cursor/index.js.map +1 -0
- package/dist/core/cursor/scan.d.ts +28 -0
- package/dist/core/cursor/scan.d.ts.map +1 -0
- package/dist/core/cursor/scan.js +79 -0
- package/dist/core/cursor/scan.js.map +1 -0
- package/dist/core/decisions/index.d.ts +21 -0
- package/dist/core/decisions/index.d.ts.map +1 -0
- package/dist/core/decisions/index.js +133 -0
- package/dist/core/decisions/index.js.map +1 -0
- package/dist/core/dlp/index.d.ts +7 -0
- package/dist/core/dlp/index.d.ts.map +1 -0
- package/dist/core/dlp/index.js +115 -0
- package/dist/core/dlp/index.js.map +1 -0
- package/dist/core/health/index.d.ts +10 -0
- package/dist/core/health/index.d.ts.map +1 -0
- package/dist/core/health/index.js +21 -0
- package/dist/core/health/index.js.map +1 -0
- package/dist/core/index/index.d.ts +9 -0
- package/dist/core/index/index.d.ts.map +1 -0
- package/dist/core/index/index.js +103 -0
- package/dist/core/index/index.js.map +1 -0
- package/dist/core/index/ingest.d.ts +16 -0
- package/dist/core/index/ingest.d.ts.map +1 -0
- package/dist/core/index/ingest.js +184 -0
- package/dist/core/index/ingest.js.map +1 -0
- package/dist/core/index/platforms.d.ts +21 -0
- package/dist/core/index/platforms.d.ts.map +1 -0
- package/dist/core/index/platforms.js +44 -0
- package/dist/core/index/platforms.js.map +1 -0
- package/dist/core/index/pricing-map.d.ts +10 -0
- package/dist/core/index/pricing-map.d.ts.map +1 -0
- package/dist/core/index/pricing-map.js +16 -0
- package/dist/core/index/pricing-map.js.map +1 -0
- package/dist/core/index/progress.d.ts +26 -0
- package/dist/core/index/progress.d.ts.map +1 -0
- package/dist/core/index/progress.js +59 -0
- package/dist/core/index/progress.js.map +1 -0
- package/dist/core/index/scan.d.ts +9 -0
- package/dist/core/index/scan.d.ts.map +1 -0
- package/dist/core/index/scan.js +42 -0
- package/dist/core/index/scan.js.map +1 -0
- package/dist/core/index/statements.d.ts +18 -0
- package/dist/core/index/statements.d.ts.map +1 -0
- package/dist/core/index/statements.js +82 -0
- package/dist/core/index/statements.js.map +1 -0
- package/dist/core/index/tail.d.ts +42 -0
- package/dist/core/index/tail.d.ts.map +1 -0
- package/dist/core/index/tail.js +123 -0
- package/dist/core/index/tail.js.map +1 -0
- package/dist/core/jsonl/index.d.ts +3 -0
- package/dist/core/jsonl/index.d.ts.map +1 -0
- package/dist/core/jsonl/index.js +106 -0
- package/dist/core/jsonl/index.js.map +1 -0
- package/dist/core/jsonl-validate/index.d.ts +10 -0
- package/dist/core/jsonl-validate/index.d.ts.map +1 -0
- package/dist/core/jsonl-validate/index.js +40 -0
- package/dist/core/jsonl-validate/index.js.map +1 -0
- package/dist/core/kit/detection.d.ts +94 -0
- package/dist/core/kit/detection.d.ts.map +1 -0
- package/dist/core/kit/detection.js +312 -0
- package/dist/core/kit/detection.js.map +1 -0
- package/dist/core/kit/index.d.ts +12 -0
- package/dist/core/kit/index.d.ts.map +1 -0
- package/dist/core/kit/index.js +131 -0
- package/dist/core/kit/index.js.map +1 -0
- package/dist/core/kit/scan.d.ts +28 -0
- package/dist/core/kit/scan.d.ts.map +1 -0
- package/dist/core/kit/scan.js +432 -0
- package/dist/core/kit/scan.js.map +1 -0
- package/dist/core/recap/index.d.ts +18 -0
- package/dist/core/recap/index.d.ts.map +1 -0
- package/dist/core/recap/index.js +88 -0
- package/dist/core/recap/index.js.map +1 -0
- package/dist/core/repetition/index.d.ts +5 -0
- package/dist/core/repetition/index.d.ts.map +1 -0
- package/dist/core/repetition/index.js +0 -0
- package/dist/core/repetition/index.js.map +1 -0
- package/dist/core/schema/index.d.ts +514 -0
- package/dist/core/schema/index.d.ts.map +1 -0
- package/dist/core/schema/index.js +2 -0
- package/dist/core/schema/index.js.map +1 -0
- package/dist/core/schema-watch/index.d.ts +34 -0
- package/dist/core/schema-watch/index.d.ts.map +1 -0
- package/dist/core/schema-watch/index.js +87 -0
- package/dist/core/schema-watch/index.js.map +1 -0
- package/dist/core/search/index.d.ts +44 -0
- package/dist/core/search/index.d.ts.map +1 -0
- package/dist/core/search/index.js +641 -0
- package/dist/core/search/index.js.map +1 -0
- package/dist/core/settings/index.d.ts +24 -0
- package/dist/core/settings/index.d.ts.map +1 -0
- package/dist/core/settings/index.js +76 -0
- package/dist/core/settings/index.js.map +1 -0
- package/dist/core/share/bundle.d.ts +40 -0
- package/dist/core/share/bundle.d.ts.map +1 -0
- package/dist/core/share/bundle.js +158 -0
- package/dist/core/share/bundle.js.map +1 -0
- package/dist/core/share/canonical/from-claude.d.ts +13 -0
- package/dist/core/share/canonical/from-claude.d.ts.map +1 -0
- package/dist/core/share/canonical/from-claude.js +129 -0
- package/dist/core/share/canonical/from-claude.js.map +1 -0
- package/dist/core/share/canonical/from-codex.d.ts +18 -0
- package/dist/core/share/canonical/from-codex.d.ts.map +1 -0
- package/dist/core/share/canonical/from-codex.js +183 -0
- package/dist/core/share/canonical/from-codex.js.map +1 -0
- package/dist/core/share/canonical/to-claude.d.ts +15 -0
- package/dist/core/share/canonical/to-claude.d.ts.map +1 -0
- package/dist/core/share/canonical/to-claude.js +146 -0
- package/dist/core/share/canonical/to-claude.js.map +1 -0
- package/dist/core/share/canonical/to-codex.d.ts +21 -0
- package/dist/core/share/canonical/to-codex.d.ts.map +1 -0
- package/dist/core/share/canonical/to-codex.js +124 -0
- package/dist/core/share/canonical/to-codex.js.map +1 -0
- package/dist/core/share/canonical/tool-map.d.ts +61 -0
- package/dist/core/share/canonical/tool-map.d.ts.map +1 -0
- package/dist/core/share/canonical/tool-map.js +299 -0
- package/dist/core/share/canonical/tool-map.js.map +1 -0
- package/dist/core/share/canonical/types.d.ts +57 -0
- package/dist/core/share/canonical/types.d.ts.map +1 -0
- package/dist/core/share/canonical/types.js +9 -0
- package/dist/core/share/canonical/types.js.map +1 -0
- package/dist/core/share/import.d.ts +28 -0
- package/dist/core/share/import.d.ts.map +1 -0
- package/dist/core/share/import.js +174 -0
- package/dist/core/share/import.js.map +1 -0
- package/dist/core/share/manifest.d.ts +37 -0
- package/dist/core/share/manifest.d.ts.map +1 -0
- package/dist/core/share/manifest.js +31 -0
- package/dist/core/share/manifest.js.map +1 -0
- package/dist/core/share/preview.d.ts +4 -0
- package/dist/core/share/preview.d.ts.map +1 -0
- package/dist/core/share/preview.js +153 -0
- package/dist/core/share/preview.js.map +1 -0
- package/dist/core/share/primer.d.ts +19 -0
- package/dist/core/share/primer.d.ts.map +1 -0
- package/dist/core/share/primer.js +196 -0
- package/dist/core/share/primer.js.map +1 -0
- package/dist/core/share/resume.d.ts +10 -0
- package/dist/core/share/resume.d.ts.map +1 -0
- package/dist/core/share/resume.js +58 -0
- package/dist/core/share/resume.js.map +1 -0
- package/dist/core/share/scrub.d.ts +10 -0
- package/dist/core/share/scrub.d.ts.map +1 -0
- package/dist/core/share/scrub.js +198 -0
- package/dist/core/share/scrub.js.map +1 -0
- package/dist/core/share/tar.d.ts +12 -0
- package/dist/core/share/tar.d.ts.map +1 -0
- package/dist/core/share/tar.js +78 -0
- package/dist/core/share/tar.js.map +1 -0
- package/dist/core/tags/index.d.ts +48 -0
- package/dist/core/tags/index.d.ts.map +1 -0
- package/dist/core/tags/index.js +113 -0
- package/dist/core/tags/index.js.map +1 -0
- package/dist/core/today/index.d.ts +25 -0
- package/dist/core/today/index.d.ts.map +1 -0
- package/dist/core/today/index.js +42 -0
- package/dist/core/today/index.js.map +1 -0
- package/dist/core/waste/abandoned.d.ts +12 -0
- package/dist/core/waste/abandoned.d.ts.map +1 -0
- package/dist/core/waste/abandoned.js +127 -0
- package/dist/core/waste/abandoned.js.map +1 -0
- package/dist/core/waste/cache-miss.d.ts +9 -0
- package/dist/core/waste/cache-miss.d.ts.map +1 -0
- package/dist/core/waste/cache-miss.js +84 -0
- package/dist/core/waste/cache-miss.js.map +1 -0
- package/dist/core/waste/index.d.ts +12 -0
- package/dist/core/waste/index.d.ts.map +1 -0
- package/dist/core/waste/index.js +45 -0
- package/dist/core/waste/index.js.map +1 -0
- package/dist/core/waste/wrong-model.d.ts +11 -0
- package/dist/core/waste/wrong-model.d.ts.map +1 -0
- package/dist/core/waste/wrong-model.js +104 -0
- package/dist/core/waste/wrong-model.js.map +1 -0
- package/dist/db/index.d.ts +10 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +29 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrate.d.ts +8 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +282 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/server/events.d.ts +4 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/events.js +54 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +238 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/routes/foundation.d.ts +2 -0
- package/dist/server/routes/foundation.d.ts.map +1 -0
- package/dist/server/routes/foundation.js +2 -0
- package/dist/server/routes/foundation.js.map +1 -0
- package/dist/server/routes/search.d.ts +2 -0
- package/dist/server/routes/search.d.ts.map +1 -0
- package/dist/server/routes/search.js +2 -0
- package/dist/server/routes/search.js.map +1 -0
- package/dist/server/routes/sessions.d.ts +2 -0
- package/dist/server/routes/sessions.d.ts.map +1 -0
- package/dist/server/routes/sessions.js +2 -0
- package/dist/server/routes/sessions.js.map +1 -0
- package/dist/server/routes/waste.d.ts +2 -0
- package/dist/server/routes/waste.d.ts.map +1 -0
- package/dist/server/routes/waste.js +2 -0
- package/dist/server/routes/waste.js.map +1 -0
- package/dist/web/assets/index-Ba1VvTj0.js +37 -0
- package/dist/web/index.html +12 -0
- package/package.json +76 -0
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { homedir, platform } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { indexProgress } from '../index/progress.js';
|
|
6
|
+
/** Parse `---\nkey: value\n---` YAML frontmatter, just enough to grab name/description.
|
|
7
|
+
* Quietly returns {} on any oddity — frontmatter is best-effort metadata. */
|
|
8
|
+
function parseFrontmatter(text) {
|
|
9
|
+
if (!text.startsWith('---'))
|
|
10
|
+
return {};
|
|
11
|
+
const end = text.indexOf('\n---', 3);
|
|
12
|
+
if (end < 0)
|
|
13
|
+
return {};
|
|
14
|
+
const block = text.slice(3, end).trim();
|
|
15
|
+
const out = {};
|
|
16
|
+
// Track multi-line YAML scalar continuations (lines indented past their key).
|
|
17
|
+
let currentKey = null;
|
|
18
|
+
let currentVal = '';
|
|
19
|
+
const flush = () => {
|
|
20
|
+
if (currentKey != null) {
|
|
21
|
+
const v = currentVal.trim().replace(/^["']|["']$/g, '');
|
|
22
|
+
if (currentKey === 'name')
|
|
23
|
+
out.name = v;
|
|
24
|
+
else if (currentKey === 'description')
|
|
25
|
+
out.description = v;
|
|
26
|
+
}
|
|
27
|
+
currentKey = null;
|
|
28
|
+
currentVal = '';
|
|
29
|
+
};
|
|
30
|
+
for (const line of block.split('\n')) {
|
|
31
|
+
const m = /^([a-zA-Z_-]+)\s*:\s*(.*)$/.exec(line);
|
|
32
|
+
if (m && /^(name|description)$/.test(m[1])) {
|
|
33
|
+
flush();
|
|
34
|
+
currentKey = m[1];
|
|
35
|
+
currentVal = m[2];
|
|
36
|
+
}
|
|
37
|
+
else if (m) {
|
|
38
|
+
// Different key — flush any in-progress value, ignore this key
|
|
39
|
+
flush();
|
|
40
|
+
}
|
|
41
|
+
else if (currentKey != null && line.trim().length > 0) {
|
|
42
|
+
// Continuation line for a folded scalar
|
|
43
|
+
currentVal += ' ' + line.trim();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
flush();
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
async function readSkillMeta(skillMdPath) {
|
|
50
|
+
try {
|
|
51
|
+
const [text, s] = await Promise.all([readFile(skillMdPath, 'utf8'), stat(skillMdPath)]);
|
|
52
|
+
const fm = parseFrontmatter(text);
|
|
53
|
+
return {
|
|
54
|
+
description: fm.description ?? null,
|
|
55
|
+
installedAtMs: s.mtimeMs,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.error(`[vyasa] kit: failed to read skill ${skillMdPath}:`, err);
|
|
60
|
+
indexProgress.recordError();
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ─── Skill scanners ──────────────────────────────────────────────────────────
|
|
65
|
+
/**
|
|
66
|
+
* Walks a `<root>/<skill>/SKILL.md` layout. Each child directory is treated as
|
|
67
|
+
* a skill named after the directory. Returns an empty array when root does not
|
|
68
|
+
* exist or is not readable.
|
|
69
|
+
*/
|
|
70
|
+
async function scanSkillRoot(root, opts) {
|
|
71
|
+
if (!existsSync(root))
|
|
72
|
+
return [];
|
|
73
|
+
let entries;
|
|
74
|
+
try {
|
|
75
|
+
entries = await readdir(root);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
// Parallel per-skill read — each iteration is `readFile + stat`, was serial
|
|
81
|
+
// before. With 70+ plugin-cached skills, this is the dominant cost of a refresh.
|
|
82
|
+
const visible = entries.filter((n) => !n.startsWith('.')); // hide .system, .git, etc.
|
|
83
|
+
const items = await Promise.all(visible.map(async (name) => {
|
|
84
|
+
const skillMd = join(root, name, 'SKILL.md');
|
|
85
|
+
if (!existsSync(skillMd))
|
|
86
|
+
return null;
|
|
87
|
+
const meta = await readSkillMeta(skillMd);
|
|
88
|
+
if (!meta)
|
|
89
|
+
return null;
|
|
90
|
+
return { name, skillMd, meta };
|
|
91
|
+
}));
|
|
92
|
+
const results = [];
|
|
93
|
+
for (const item of items) {
|
|
94
|
+
if (!item)
|
|
95
|
+
continue;
|
|
96
|
+
const id = opts.plugin ? `${opts.plugin}:${item.name}` : item.name;
|
|
97
|
+
results.push({
|
|
98
|
+
id,
|
|
99
|
+
name: item.name,
|
|
100
|
+
plugin: opts.plugin,
|
|
101
|
+
platform: opts.platform,
|
|
102
|
+
scope: opts.scope,
|
|
103
|
+
projectPath: opts.projectPath,
|
|
104
|
+
sourcePath: item.skillMd,
|
|
105
|
+
description: item.meta.description,
|
|
106
|
+
installedAtMs: item.meta.installedAtMs,
|
|
107
|
+
lastUsedMs: null, // hydrated later in detection.ts
|
|
108
|
+
usageCount: 0,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return results;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Walks `<pluginCacheRoot>/<marketplace>/<plugin>/<version>/skills/<skill>/SKILL.md`.
|
|
115
|
+
* The marketplace dir holds one or more plugins; each plugin has versioned subdirs.
|
|
116
|
+
* We pick the lexicographically highest version (semver-ish) to avoid surfacing
|
|
117
|
+
* superseded copies that bloat the inventory.
|
|
118
|
+
*/
|
|
119
|
+
async function scanPluginCacheRoot(pluginCacheRoot, platform) {
|
|
120
|
+
if (!existsSync(pluginCacheRoot))
|
|
121
|
+
return [];
|
|
122
|
+
let marketplaces;
|
|
123
|
+
try {
|
|
124
|
+
marketplaces = await readdir(pluginCacheRoot);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
const results = [];
|
|
130
|
+
for (const mkt of marketplaces) {
|
|
131
|
+
const mktDir = join(pluginCacheRoot, mkt);
|
|
132
|
+
let plugins;
|
|
133
|
+
try {
|
|
134
|
+
plugins = await readdir(mktDir);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
for (const plug of plugins) {
|
|
140
|
+
const plugDir = join(mktDir, plug);
|
|
141
|
+
let versions;
|
|
142
|
+
try {
|
|
143
|
+
versions = await readdir(plugDir);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (versions.length === 0)
|
|
149
|
+
continue;
|
|
150
|
+
// Pick highest version (string sort is fine for both semver and 'unknown')
|
|
151
|
+
versions.sort();
|
|
152
|
+
const chosen = versions[versions.length - 1];
|
|
153
|
+
const skillsRoot = join(plugDir, chosen, 'skills');
|
|
154
|
+
const found = await scanSkillRoot(skillsRoot, {
|
|
155
|
+
platform,
|
|
156
|
+
scope: 'global',
|
|
157
|
+
plugin: plug,
|
|
158
|
+
projectPath: null,
|
|
159
|
+
});
|
|
160
|
+
results.push(...found);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return results;
|
|
164
|
+
}
|
|
165
|
+
export async function scanGlobalSkills() {
|
|
166
|
+
const home = homedir();
|
|
167
|
+
const results = [];
|
|
168
|
+
// Claude: loose skills + plugin cache
|
|
169
|
+
results.push(...(await scanSkillRoot(join(home, '.claude', 'skills'), {
|
|
170
|
+
platform: 'claude-code',
|
|
171
|
+
scope: 'global',
|
|
172
|
+
plugin: null,
|
|
173
|
+
projectPath: null,
|
|
174
|
+
})));
|
|
175
|
+
results.push(...(await scanPluginCacheRoot(join(home, '.claude', 'plugins', 'cache'), 'claude-code')));
|
|
176
|
+
// Codex: loose skills (skip .system) + plugin cache
|
|
177
|
+
results.push(...(await scanSkillRoot(join(home, '.codex', 'skills'), {
|
|
178
|
+
platform: 'codex',
|
|
179
|
+
scope: 'global',
|
|
180
|
+
plugin: null,
|
|
181
|
+
projectPath: null,
|
|
182
|
+
})));
|
|
183
|
+
// Codex .system skills live one level deeper; surface as plugin='.system' for clarity
|
|
184
|
+
const codexSystemRoot = join(home, '.codex', 'skills', '.system');
|
|
185
|
+
if (existsSync(codexSystemRoot)) {
|
|
186
|
+
results.push(...(await scanSkillRoot(codexSystemRoot, {
|
|
187
|
+
platform: 'codex',
|
|
188
|
+
scope: 'global',
|
|
189
|
+
plugin: 'system',
|
|
190
|
+
projectPath: null,
|
|
191
|
+
})));
|
|
192
|
+
}
|
|
193
|
+
results.push(...(await scanPluginCacheRoot(join(home, '.codex', 'plugins', 'cache'), 'codex')));
|
|
194
|
+
// Cursor: managed skills directory. Cursor uses 'skills-cursor' (not just 'skills')
|
|
195
|
+
// — verified locally; the plain `skills/` slot is unused in current Cursor builds.
|
|
196
|
+
results.push(...(await scanSkillRoot(join(home, '.cursor', 'skills-cursor'), {
|
|
197
|
+
platform: 'cursor',
|
|
198
|
+
scope: 'global',
|
|
199
|
+
plugin: null,
|
|
200
|
+
projectPath: null,
|
|
201
|
+
})));
|
|
202
|
+
return results;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Scans likely project-scoped skill dirs under each given project root.
|
|
206
|
+
* `projectRoots` should be absolute paths that look like project working
|
|
207
|
+
* directories (decoded from session.project where possible).
|
|
208
|
+
*/
|
|
209
|
+
export async function scanProjectSkills(projectRoots) {
|
|
210
|
+
const results = [];
|
|
211
|
+
for (const root of projectRoots) {
|
|
212
|
+
if (!root || !existsSync(root))
|
|
213
|
+
continue;
|
|
214
|
+
// Claude project skills
|
|
215
|
+
results.push(...(await scanSkillRoot(join(root, '.claude', 'skills'), {
|
|
216
|
+
platform: 'claude-code',
|
|
217
|
+
scope: 'project',
|
|
218
|
+
plugin: null,
|
|
219
|
+
projectPath: root,
|
|
220
|
+
})));
|
|
221
|
+
// Codex project skills (canonical .agents/skills + alt skills/ for repos that pre-date the move)
|
|
222
|
+
results.push(...(await scanSkillRoot(join(root, '.agents', 'skills'), {
|
|
223
|
+
platform: 'codex',
|
|
224
|
+
scope: 'project',
|
|
225
|
+
plugin: null,
|
|
226
|
+
projectPath: root,
|
|
227
|
+
})));
|
|
228
|
+
// Only fall back to bare skills/ when .agents/ is absent — otherwise it'd
|
|
229
|
+
// surface the plugin's *.md test fixtures as skills.
|
|
230
|
+
if (!existsSync(join(root, '.agents'))) {
|
|
231
|
+
results.push(...(await scanSkillRoot(join(root, 'skills'), {
|
|
232
|
+
platform: 'codex',
|
|
233
|
+
scope: 'project',
|
|
234
|
+
plugin: null,
|
|
235
|
+
projectPath: root,
|
|
236
|
+
})));
|
|
237
|
+
}
|
|
238
|
+
// Cursor project skills
|
|
239
|
+
results.push(...(await scanSkillRoot(join(root, '.cursor', 'skills'), {
|
|
240
|
+
platform: 'cursor',
|
|
241
|
+
scope: 'project',
|
|
242
|
+
plugin: null,
|
|
243
|
+
projectPath: root,
|
|
244
|
+
})));
|
|
245
|
+
}
|
|
246
|
+
return results;
|
|
247
|
+
}
|
|
248
|
+
/** Read a JSON file with an mcpServers block. Returns null on any I/O or
|
|
249
|
+
* parse failure — MCP configs are user-managed and we'd rather skip than crash. */
|
|
250
|
+
async function readJsonMcpConfig(path) {
|
|
251
|
+
if (!existsSync(path))
|
|
252
|
+
return null;
|
|
253
|
+
try {
|
|
254
|
+
const [text, s] = await Promise.all([readFile(path, 'utf8'), stat(path)]);
|
|
255
|
+
const trimmed = text.trim();
|
|
256
|
+
// Cursor's mcp.json is a 0-byte file out of the box; treat empty as no config
|
|
257
|
+
if (trimmed.length === 0)
|
|
258
|
+
return { data: {}, mtimeMs: s.mtimeMs };
|
|
259
|
+
const parsed = JSON.parse(trimmed);
|
|
260
|
+
return { data: parsed, mtimeMs: s.mtimeMs };
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
console.error(`[vyasa] kit: failed to read MCP config ${path}:`, err);
|
|
264
|
+
indexProgress.recordError();
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export async function scanGlobalMcp() {
|
|
269
|
+
const home = homedir();
|
|
270
|
+
const results = [];
|
|
271
|
+
// Claude Code — ~/.claude.json holds both top-level mcpServers and per-project
|
|
272
|
+
// mcpServers (keyed by absolute project path). We split top-level → global,
|
|
273
|
+
// per-project → project-scope.
|
|
274
|
+
const claudePath = join(home, '.claude.json');
|
|
275
|
+
const claudeCfg = await readJsonMcpConfig(claudePath);
|
|
276
|
+
if (claudeCfg) {
|
|
277
|
+
const top = claudeCfg.data.mcpServers;
|
|
278
|
+
if (top && typeof top === 'object') {
|
|
279
|
+
for (const name of Object.keys(top)) {
|
|
280
|
+
results.push({
|
|
281
|
+
id: name,
|
|
282
|
+
platform: 'claude-code',
|
|
283
|
+
scope: 'global',
|
|
284
|
+
projectPath: null,
|
|
285
|
+
sourcePath: claudePath,
|
|
286
|
+
installedAtMs: claudeCfg.mtimeMs,
|
|
287
|
+
lastUsedMs: null,
|
|
288
|
+
usageCount: 0,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Cursor — ~/.cursor/mcp.json
|
|
294
|
+
const cursorPath = join(home, '.cursor', 'mcp.json');
|
|
295
|
+
const cursorCfg = await readJsonMcpConfig(cursorPath);
|
|
296
|
+
if (cursorCfg) {
|
|
297
|
+
const top = cursorCfg.data.mcpServers;
|
|
298
|
+
if (top && typeof top === 'object') {
|
|
299
|
+
for (const name of Object.keys(top)) {
|
|
300
|
+
results.push({
|
|
301
|
+
id: name,
|
|
302
|
+
platform: 'cursor',
|
|
303
|
+
scope: 'global',
|
|
304
|
+
projectPath: null,
|
|
305
|
+
sourcePath: cursorPath,
|
|
306
|
+
installedAtMs: cursorCfg.mtimeMs,
|
|
307
|
+
lastUsedMs: null,
|
|
308
|
+
usageCount: 0,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// Codex — no documented global JSON MCP config in observed installs. Skip
|
|
314
|
+
// silently. (If Codex adds one, this is the place to wire it in.)
|
|
315
|
+
return results;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Returns MCP servers declared at project-scope for the given roots:
|
|
319
|
+
* • Claude: ~/.claude.json's projects[<root>].mcpServers
|
|
320
|
+
* • Cursor: <root>/.cursor/mcp.json
|
|
321
|
+
*/
|
|
322
|
+
export async function scanProjectMcp(projectRoots) {
|
|
323
|
+
const home = homedir();
|
|
324
|
+
const results = [];
|
|
325
|
+
// Pull the Claude projects block once (don't re-read for every root)
|
|
326
|
+
const claudePath = join(home, '.claude.json');
|
|
327
|
+
const claudeCfg = await readJsonMcpConfig(claudePath);
|
|
328
|
+
const claudeProjects = claudeCfg?.data.projects ?? {};
|
|
329
|
+
for (const root of projectRoots) {
|
|
330
|
+
if (!root)
|
|
331
|
+
continue;
|
|
332
|
+
// Claude project MCPs
|
|
333
|
+
const projBlock = claudeProjects[root];
|
|
334
|
+
if (projBlock?.mcpServers && typeof projBlock.mcpServers === 'object') {
|
|
335
|
+
for (const name of Object.keys(projBlock.mcpServers)) {
|
|
336
|
+
results.push({
|
|
337
|
+
id: name,
|
|
338
|
+
platform: 'claude-code',
|
|
339
|
+
scope: 'project',
|
|
340
|
+
projectPath: root,
|
|
341
|
+
sourcePath: claudePath,
|
|
342
|
+
installedAtMs: claudeCfg.mtimeMs,
|
|
343
|
+
lastUsedMs: null,
|
|
344
|
+
usageCount: 0,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// Cursor per-project mcp.json
|
|
349
|
+
const cursorProjPath = join(root, '.cursor', 'mcp.json');
|
|
350
|
+
const cursorProjCfg = await readJsonMcpConfig(cursorProjPath);
|
|
351
|
+
if (cursorProjCfg) {
|
|
352
|
+
const top = cursorProjCfg.data.mcpServers;
|
|
353
|
+
if (top && typeof top === 'object') {
|
|
354
|
+
for (const name of Object.keys(top)) {
|
|
355
|
+
results.push({
|
|
356
|
+
id: name,
|
|
357
|
+
platform: 'cursor',
|
|
358
|
+
scope: 'project',
|
|
359
|
+
projectPath: root,
|
|
360
|
+
sourcePath: cursorProjPath,
|
|
361
|
+
installedAtMs: cursorProjCfg.mtimeMs,
|
|
362
|
+
lastUsedMs: null,
|
|
363
|
+
usageCount: 0,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return results;
|
|
370
|
+
}
|
|
371
|
+
// ─── Project-path decoder ─────────────────────────────────────────────────────
|
|
372
|
+
// POSIX-only — Claude Code's slug encoding (and thus this decoder) doesn't
|
|
373
|
+
// apply on Windows. Memoized per-slug: each decode does O(N²) stat() calls so
|
|
374
|
+
// repeated calls (one per project per Kit refresh) add up fast without a cache.
|
|
375
|
+
const _slugCache = new Map();
|
|
376
|
+
/**
|
|
377
|
+
* Claude encodes the project working dir as a slug — `/Users/abhinav/foo` becomes
|
|
378
|
+
* `-Users-abhinav-foo`. The encoding is lossy: literal dashes inside path
|
|
379
|
+
* components (e.g. `claude-tool`) get merged with the separator dashes. We
|
|
380
|
+
* recover the true path by probing the filesystem — try the naive split first,
|
|
381
|
+
* then merge adjacent segments left-to-right until we find a directory that
|
|
382
|
+
* exists. Longest matching prefix wins. Falls back to the naive split (which
|
|
383
|
+
* won't `existsSync`, so callers harmlessly skip it) when no resolution is possible.
|
|
384
|
+
*/
|
|
385
|
+
export function decodeClaudeProjectSlug(slug) {
|
|
386
|
+
const cached = _slugCache.get(slug);
|
|
387
|
+
if (cached !== undefined)
|
|
388
|
+
return cached;
|
|
389
|
+
const result = _decodeSlugUncached(slug);
|
|
390
|
+
_slugCache.set(slug, result);
|
|
391
|
+
return result;
|
|
392
|
+
}
|
|
393
|
+
function _decodeSlugUncached(slug) {
|
|
394
|
+
if (!slug.startsWith('-'))
|
|
395
|
+
return slug;
|
|
396
|
+
const segments = slug.slice(1).split('-');
|
|
397
|
+
if (segments.length === 0)
|
|
398
|
+
return slug;
|
|
399
|
+
// Greedy walk: start at '/', try each segment as a directory component; if it
|
|
400
|
+
// doesn't exist, glue it onto the previous component with '-' (claude-tool case).
|
|
401
|
+
let current = '/';
|
|
402
|
+
let i = 0;
|
|
403
|
+
while (i < segments.length) {
|
|
404
|
+
let attempt = segments[i];
|
|
405
|
+
let consumed = 1;
|
|
406
|
+
// Look ahead and try longest matching prefix first
|
|
407
|
+
let bestPath = '';
|
|
408
|
+
let bestConsumed = 0;
|
|
409
|
+
while (i + consumed <= segments.length) {
|
|
410
|
+
const candidate = join(current, attempt);
|
|
411
|
+
if (existsSync(candidate)) {
|
|
412
|
+
bestPath = candidate;
|
|
413
|
+
bestConsumed = consumed;
|
|
414
|
+
}
|
|
415
|
+
if (i + consumed >= segments.length)
|
|
416
|
+
break;
|
|
417
|
+
attempt = attempt + '-' + segments[i + consumed];
|
|
418
|
+
consumed++;
|
|
419
|
+
}
|
|
420
|
+
if (bestConsumed === 0) {
|
|
421
|
+
// Nothing matched — fall back to the naive replacement so the caller
|
|
422
|
+
// at least has a parseable shape.
|
|
423
|
+
return '/' + segments.join('/');
|
|
424
|
+
}
|
|
425
|
+
current = bestPath;
|
|
426
|
+
i += bestConsumed;
|
|
427
|
+
}
|
|
428
|
+
return current;
|
|
429
|
+
}
|
|
430
|
+
// Re-export os.platform for tests that need the same OS check shape
|
|
431
|
+
export { platform as osPlatform };
|
|
432
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/core/kit/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { RecapData } from '../schema/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* "This Week" recap — the single blessed weekly digest.
|
|
5
|
+
*
|
|
6
|
+
* Aggregates, all over the current ISO week (Monday-anchored, reusing budget.weekKey):
|
|
7
|
+
* - burn — rolling 7-day token burn vs the user-entered cap (silent when no cap set)
|
|
8
|
+
* - wasteCents— this week's attributed waste (summed from waste_attributions)
|
|
9
|
+
* - thrash — top sessions by run-health errorCount (errorCount > 0 only)
|
|
10
|
+
* - drift — sessions whose plans were reopened (plan_reopened decision events)
|
|
11
|
+
* - repetition— near-duplicate user instructions worth extracting to CLAUDE.md
|
|
12
|
+
* - secrets — DLP findings in this week's content
|
|
13
|
+
*
|
|
14
|
+
* Bounded/fast: every sub-query is capped, and the per-session decision walk only
|
|
15
|
+
* runs over the (already capped) week's session list.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getRecap(db: Database.Database, nowMs?: number): RecapData;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/recap/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAUnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,GAAE,MAAmB,GAAG,SAAS,CA0ErF"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { weekKey, weeklyBurn, capStatus } from '../budget/index.js';
|
|
2
|
+
import { getSessions } from '../search/index.js';
|
|
3
|
+
import { getDecisions } from '../decisions/index.js';
|
|
4
|
+
import { scanRecent } from '../dlp/index.js';
|
|
5
|
+
import { mineRepetition } from '../repetition/index.js';
|
|
6
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
7
|
+
const WEEK_MS = 7 * DAY_MS;
|
|
8
|
+
/**
|
|
9
|
+
* "This Week" recap — the single blessed weekly digest.
|
|
10
|
+
*
|
|
11
|
+
* Aggregates, all over the current ISO week (Monday-anchored, reusing budget.weekKey):
|
|
12
|
+
* - burn — rolling 7-day token burn vs the user-entered cap (silent when no cap set)
|
|
13
|
+
* - wasteCents— this week's attributed waste (summed from waste_attributions)
|
|
14
|
+
* - thrash — top sessions by run-health errorCount (errorCount > 0 only)
|
|
15
|
+
* - drift — sessions whose plans were reopened (plan_reopened decision events)
|
|
16
|
+
* - repetition— near-duplicate user instructions worth extracting to CLAUDE.md
|
|
17
|
+
* - secrets — DLP findings in this week's content
|
|
18
|
+
*
|
|
19
|
+
* Bounded/fast: every sub-query is capped, and the per-session decision walk only
|
|
20
|
+
* runs over the (already capped) week's session list.
|
|
21
|
+
*/
|
|
22
|
+
export function getRecap(db, nowMs = Date.now()) {
|
|
23
|
+
const weekStart = weekKey(nowMs);
|
|
24
|
+
const weekStartMs = Date.parse(weekStart + 'T00:00:00.000Z');
|
|
25
|
+
const weekEndMs = weekStartMs + WEEK_MS;
|
|
26
|
+
const weekStartIso = new Date(weekStartMs).toISOString();
|
|
27
|
+
const weekEndIso = new Date(weekEndMs).toISOString();
|
|
28
|
+
// ── burn (rolling 7-day, from budget) ──────────────────────────────────────
|
|
29
|
+
const burnRollup = weeklyBurn(db, nowMs);
|
|
30
|
+
const cap = capStatus(db, nowMs);
|
|
31
|
+
const burn = {
|
|
32
|
+
used: burnRollup.tokensLast7d,
|
|
33
|
+
cap: cap.capSet ? cap.cap : null,
|
|
34
|
+
pct: cap.capSet ? cap.pct : null,
|
|
35
|
+
projectedWeekEnd: burnRollup.projectedWeekEnd,
|
|
36
|
+
daysToExhaust: cap.capSet ? cap.daysToExhaust : null,
|
|
37
|
+
};
|
|
38
|
+
// ── sessions active this week ───────────────────────────────────────────────
|
|
39
|
+
// Pull a bounded slice of this week's sessions; reused for sessionCount, thrash, drift.
|
|
40
|
+
const { sessions } = getSessions(db, {
|
|
41
|
+
dateFrom: weekStartIso,
|
|
42
|
+
dateTo: weekEndIso,
|
|
43
|
+
limit: 200,
|
|
44
|
+
});
|
|
45
|
+
const sessionCount = sessions.length;
|
|
46
|
+
// ── wasteCents (this week's attributed waste) ───────────────────────────────
|
|
47
|
+
const wasteRow = db
|
|
48
|
+
.prepare(`SELECT COALESCE(SUM(wa.amount_cents), 0) AS cents
|
|
49
|
+
FROM waste_attributions wa
|
|
50
|
+
JOIN sessions s ON s.id = wa.session_id
|
|
51
|
+
WHERE s.started_at >= ? AND s.started_at < ?`)
|
|
52
|
+
.get(weekStartIso, weekEndIso);
|
|
53
|
+
const wasteCents = Math.round(wasteRow.cents ?? 0);
|
|
54
|
+
// ── thrash (top error sessions) ─────────────────────────────────────────────
|
|
55
|
+
const thrash = sessions
|
|
56
|
+
.filter((s) => s.errorCount > 0)
|
|
57
|
+
.sort((a, b) => b.errorCount - a.errorCount)
|
|
58
|
+
.slice(0, 5)
|
|
59
|
+
.map((s) => ({ sessionId: s.id, name: s.name, errorCount: s.errorCount }));
|
|
60
|
+
// ── drift (plan_reopened) ───────────────────────────────────────────────────
|
|
61
|
+
const drift = sessions
|
|
62
|
+
.map((s) => {
|
|
63
|
+
const events = getDecisions(db, s.id);
|
|
64
|
+
const reopens = events.filter((e) => e.kind === 'plan_reopened');
|
|
65
|
+
if (reopens.length === 0)
|
|
66
|
+
return null;
|
|
67
|
+
const tokensInReopens = reopens.reduce((acc, e) => acc + (e.tokensInSpan ?? 0), 0);
|
|
68
|
+
return { sessionId: s.id, name: s.name, reopens: reopens.length, tokensInReopens };
|
|
69
|
+
})
|
|
70
|
+
.filter((d) => d !== null)
|
|
71
|
+
.sort((a, b) => b.reopens - a.reopens || b.tokensInReopens - a.tokensInReopens)
|
|
72
|
+
.slice(0, 5);
|
|
73
|
+
// ── repetition (near-duplicate instructions) ────────────────────────────────
|
|
74
|
+
const repetition = mineRepetition(db, weekStartMs).slice(0, 5);
|
|
75
|
+
// ── secrets (DLP findings) ──────────────────────────────────────────────────
|
|
76
|
+
const secrets = scanRecent(db, weekStartMs).slice(0, 10);
|
|
77
|
+
return {
|
|
78
|
+
weekStart,
|
|
79
|
+
sessionCount,
|
|
80
|
+
burn,
|
|
81
|
+
wasteCents,
|
|
82
|
+
thrash,
|
|
83
|
+
drift,
|
|
84
|
+
repetition,
|
|
85
|
+
secrets,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/recap/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import type { RepetitionCluster } from '../schema/index.js';
|
|
3
|
+
/** Cluster near-duplicate user instructions across sessions active since `sinceMs`. */
|
|
4
|
+
export declare function mineRepetition(db: Database.Database, sinceMs: number): RepetitionCluster[];
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/repetition/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AA+F3D,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE,CA2G1F"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/repetition/index.ts"],"names":[],"mappings":"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"}
|