skilld 1.7.3 → 2.0.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/dist/_chunks/add.mjs +66 -0
- package/dist/_chunks/add.mjs.map +1 -0
- package/dist/_chunks/agent-prompt.mjs +88 -0
- package/dist/_chunks/agent-prompt.mjs.map +1 -0
- package/dist/_chunks/agent.mjs +737 -619
- package/dist/_chunks/agent.mjs.map +1 -1
- package/dist/_chunks/args.mjs +42 -0
- package/dist/_chunks/args.mjs.map +1 -0
- package/dist/_chunks/assemble.mjs +11 -8
- package/dist/_chunks/assemble.mjs.map +1 -1
- package/dist/_chunks/author.mjs +77 -131
- package/dist/_chunks/author.mjs.map +1 -1
- package/dist/_chunks/cache.mjs +320 -54
- package/dist/_chunks/cache.mjs.map +1 -1
- package/dist/_chunks/cache2.mjs +7 -6
- package/dist/_chunks/cache2.mjs.map +1 -1
- package/dist/_chunks/client.mjs +117 -0
- package/dist/_chunks/client.mjs.map +1 -0
- package/dist/_chunks/core.mjs +7 -4
- package/dist/_chunks/detect.mjs +54 -44
- package/dist/_chunks/detect.mjs.map +1 -1
- package/dist/_chunks/eject.mjs +69 -0
- package/dist/_chunks/eject.mjs.map +1 -0
- package/dist/_chunks/embedding-cache2.mjs +2 -2
- package/dist/_chunks/env.mjs +19 -0
- package/dist/_chunks/env.mjs.map +1 -0
- package/dist/_chunks/install-many.mjs +376 -0
- package/dist/_chunks/install-many.mjs.map +1 -0
- package/dist/_chunks/install.mjs +86 -371
- package/dist/_chunks/install.mjs.map +1 -1
- package/dist/_chunks/intro.mjs +63 -0
- package/dist/_chunks/intro.mjs.map +1 -0
- package/dist/_chunks/list.mjs +2 -2
- package/dist/_chunks/list.mjs.map +1 -1
- package/dist/_chunks/lockfile.mjs +31 -7
- package/dist/_chunks/lockfile.mjs.map +1 -1
- package/dist/_chunks/login.mjs +233 -0
- package/dist/_chunks/login.mjs.map +1 -0
- package/dist/_chunks/logout.mjs +27 -0
- package/dist/_chunks/logout.mjs.map +1 -0
- package/dist/_chunks/map.mjs +11 -0
- package/dist/_chunks/map.mjs.map +1 -0
- package/dist/_chunks/markdown.mjs +79 -54
- package/dist/_chunks/markdown.mjs.map +1 -1
- package/dist/_chunks/menu.mjs +33 -0
- package/dist/_chunks/menu.mjs.map +1 -0
- package/dist/_chunks/model-picker.mjs +61 -0
- package/dist/_chunks/model-picker.mjs.map +1 -0
- package/dist/_chunks/monorepo.mjs +73 -0
- package/dist/_chunks/monorepo.mjs.map +1 -0
- package/dist/_chunks/package-json.mjs.map +1 -1
- package/dist/_chunks/paths.mjs +47 -0
- package/dist/_chunks/paths.mjs.map +1 -0
- package/dist/_chunks/pipeline.mjs +985 -0
- package/dist/_chunks/pipeline.mjs.map +1 -0
- package/dist/_chunks/pool2.mjs +2 -2
- package/dist/_chunks/portable.mjs +151 -0
- package/dist/_chunks/portable.mjs.map +1 -0
- package/dist/_chunks/prepare-hook.mjs +2 -0
- package/dist/_chunks/prepare-hook2.mjs +61 -0
- package/dist/_chunks/prepare-hook2.mjs.map +1 -0
- package/dist/_chunks/prepare.mjs +47 -3
- package/dist/_chunks/prepare.mjs.map +1 -1
- package/dist/_chunks/prepare2.mjs +9 -8
- package/dist/_chunks/prepare2.mjs.map +1 -1
- package/dist/_chunks/prompts.mjs +784 -26
- package/dist/_chunks/prompts.mjs.map +1 -1
- package/dist/_chunks/pull.mjs +219 -0
- package/dist/_chunks/pull.mjs.map +1 -0
- package/dist/_chunks/regex.mjs +19 -0
- package/dist/_chunks/regex.mjs.map +1 -0
- package/dist/_chunks/retriv.mjs +2 -171
- package/dist/_chunks/retriv2.mjs +159 -0
- package/dist/_chunks/retriv2.mjs.map +1 -0
- package/dist/_chunks/sanitize.mjs +12 -9
- package/dist/_chunks/sanitize.mjs.map +1 -1
- package/dist/_chunks/search-helpers.mjs +9 -8
- package/dist/_chunks/search-helpers.mjs.map +1 -1
- package/dist/_chunks/search-interactive.mjs +23 -20
- package/dist/_chunks/search-interactive.mjs.map +1 -1
- package/dist/_chunks/search.mjs +3 -4
- package/dist/_chunks/search.mjs.map +1 -1
- package/dist/_chunks/{sources.mjs → semver.mjs} +1128 -838
- package/dist/_chunks/semver.mjs.map +1 -0
- package/dist/_chunks/skill-installer.mjs +2 -0
- package/dist/_chunks/skill-installer2.mjs +154 -0
- package/dist/_chunks/skill-installer2.mjs.map +1 -0
- package/dist/_chunks/skills.mjs +12 -12
- package/dist/_chunks/skills.mjs.map +1 -1
- package/dist/_chunks/store.mjs +107 -0
- package/dist/_chunks/store.mjs.map +1 -0
- package/dist/_chunks/sync.mjs +761 -1349
- package/dist/_chunks/sync.mjs.map +1 -1
- package/dist/_chunks/sync2.mjs +2 -3
- package/dist/_chunks/telemetry.mjs +26 -0
- package/dist/_chunks/telemetry.mjs.map +1 -0
- package/dist/_chunks/uninstall.mjs +15 -13
- package/dist/_chunks/uninstall.mjs.map +1 -1
- package/dist/_chunks/update.mjs +171 -0
- package/dist/_chunks/update.mjs.map +1 -0
- package/dist/_chunks/upload.mjs +4 -4
- package/dist/_chunks/validate.mjs +1 -1
- package/dist/_chunks/version.mjs +16 -27
- package/dist/_chunks/version.mjs.map +1 -1
- package/dist/_chunks/whoami.mjs +21 -0
- package/dist/_chunks/whoami.mjs.map +1 -0
- package/dist/_chunks/wizard.mjs +2 -190
- package/dist/_chunks/wizard2.mjs +200 -0
- package/dist/_chunks/wizard2.mjs.map +1 -0
- package/dist/cli.mjs +77 -59
- package/dist/cli.mjs.map +1 -1
- package/dist/prepare.mjs +5 -4
- package/dist/prepare.mjs.map +1 -1
- package/dist/retriv/worker.d.mts +5 -1
- package/dist/retriv/worker.d.mts.map +1 -1
- package/dist/retriv/worker.mjs +1 -1
- package/package.json +20 -29
- package/dist/_chunks/author-group.mjs +0 -17
- package/dist/_chunks/author-group.mjs.map +0 -1
- package/dist/_chunks/cli-helpers.mjs +0 -335
- package/dist/_chunks/cli-helpers.mjs.map +0 -1
- package/dist/_chunks/cli-helpers2.mjs +0 -2
- package/dist/_chunks/config.mjs +0 -122
- package/dist/_chunks/config.mjs.map +0 -1
- package/dist/_chunks/index.d.mts +0 -151
- package/dist/_chunks/index.d.mts.map +0 -1
- package/dist/_chunks/index2.d.mts +0 -44
- package/dist/_chunks/index2.d.mts.map +0 -1
- package/dist/_chunks/index3.d.mts +0 -589
- package/dist/_chunks/index3.d.mts.map +0 -1
- package/dist/_chunks/prefix.mjs +0 -108
- package/dist/_chunks/prefix.mjs.map +0 -1
- package/dist/_chunks/retriv.mjs.map +0 -1
- package/dist/_chunks/setup.mjs +0 -17
- package/dist/_chunks/setup.mjs.map +0 -1
- package/dist/_chunks/shared.mjs +0 -503
- package/dist/_chunks/shared.mjs.map +0 -1
- package/dist/_chunks/skill.mjs +0 -329
- package/dist/_chunks/skill.mjs.map +0 -1
- package/dist/_chunks/sources.mjs.map +0 -1
- package/dist/_chunks/sync-registry.mjs +0 -59
- package/dist/_chunks/sync-registry.mjs.map +0 -1
- package/dist/_chunks/sync-shared.mjs +0 -2
- package/dist/_chunks/sync-shared2.mjs +0 -1020
- package/dist/_chunks/sync-shared2.mjs.map +0 -1
- package/dist/_chunks/types.d.mts +0 -88
- package/dist/_chunks/types.d.mts.map +0 -1
- package/dist/_chunks/wizard.mjs.map +0 -1
- package/dist/agent/index.d.mts +0 -346
- package/dist/agent/index.d.mts.map +0 -1
- package/dist/agent/index.mjs +0 -5
- package/dist/cache/index.d.mts +0 -2
- package/dist/cache/index.mjs +0 -4
- package/dist/index.d.mts +0 -5
- package/dist/index.mjs +0 -5
- package/dist/retriv/index.d.mts +0 -3
- package/dist/retriv/index.mjs +0 -2
- package/dist/sources/index.d.mts +0 -2
- package/dist/sources/index.mjs +0 -3
- package/dist/types.d.mts +0 -4
- package/dist/types.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-picker.mjs","names":[],"sources":["../../src/cli/model-picker.ts"],"sourcesContent":["import { styleText } from 'node:util'\nimport * as p from '@clack/prompts'\n\nexport const OAUTH_NOTE\n = `${styleText('yellow', '⚠')} OAuth providers are disabled.\\n`\n + `\\n`\n + `Consumer subscription OAuth impersonates official CLI clients and\\n`\n + `violates provider Terms of Service, risking account bans.\\n`\n + `\\n`\n + `Use API keys or native CLI tools instead:\\n`\n + ` ${styleText('cyan', 'ANTHROPIC_API_KEY')} / ${styleText('cyan', 'claude')} CLI\\n`\n + ` ${styleText('cyan', 'OPENAI_API_KEY')} / ${styleText('cyan', 'codex')} CLI\\n`\n + ` ${styleText('cyan', 'GEMINI_API_KEY')} / ${styleText('cyan', 'gemini')} CLI`\n\nexport const NO_MODELS_MESSAGE = `No enhancement models detected.\\n`\n + ` ${styleText('gray', 'Skills work fine without this, you get raw docs, issues, and types.\\n Enhancement compresses them into a concise cheat sheet with gotchas.')}\\n`\n + `\\n`\n + ` To connect a model (optional):\\n`\n + ` 1. Set an env var: ANTHROPIC_API_KEY, GEMINI_API_KEY, or OPENAI_API_KEY\\n`\n + ` 2. Install a CLI tool: ${styleText('cyan', 'claude')}, ${styleText('cyan', 'gemini')}, or ${styleText('cyan', 'codex')} (restart wizard after)`\n\nexport function groupModelsByProvider<T extends { provider: string, providerName: string, vendorGroup?: string }>(models: T[]): Map<string, { name: string, models: T[] }> {\n const byVendor = new Map<string, { name: string, models: T[] }>()\n for (const m of models) {\n const key = m.vendorGroup ?? m.provider\n if (!byVendor.has(key))\n byVendor.set(key, { name: key, models: [] })\n byVendor.get(key)!.models.push(m)\n }\n return byVendor\n}\n\nexport interface ModelPickerOptions {\n before?: Array<{ label: string, value: string, hint?: string }>\n after?: Array<{ label: string, value: string, hint?: string }>\n}\n\nexport async function pickModel<T extends { provider: string, providerName: string, name: string, id: string, hint: string, recommended?: boolean }>(\n models: T[],\n opts: ModelPickerOptions = {},\n): Promise<string | null> {\n const byProvider = groupModelsByProvider(models)\n const before = opts.before ?? []\n const after = opts.after ?? []\n\n if (byProvider.size === 1 && before.length === 0) {\n const [, group] = [...byProvider.entries()][0]!\n const choice = await p.select({\n message: `${group.name}`,\n options: [\n ...group.models.map(m => ({\n label: m.recommended ? `${m.name} (recommended - fast and cheap)` : m.name,\n value: m.id,\n hint: m.hint,\n })),\n ...after,\n ],\n })\n return p.isCancel(choice) ? null : choice as string\n }\n\n const providerChoice = await p.select({\n message: 'Select provider',\n options: [\n ...before,\n ...Array.from(byProvider.entries(), ([key, { name, models: ms }]) => ({\n label: name,\n value: key,\n hint: `${ms.length} models`,\n })),\n ...after,\n ],\n })\n\n if (p.isCancel(providerChoice))\n return null\n\n const providerStr = providerChoice as string\n if (before.some(o => o.value === providerStr) || after.some(o => o.value === providerStr))\n return providerStr\n\n const group = byProvider.get(providerStr)!\n const modelChoice = await p.select({\n message: `Select model (${group.name})`,\n options: group.models.map(m => ({\n label: m.recommended ? `${m.name} (recommended - fast and cheap)` : m.name,\n value: m.id,\n hint: m.hint,\n })),\n })\n\n return p.isCancel(modelChoice) ? null : modelChoice as string\n}\n"],"mappings":";;AAGA,MAAa,aACT,GAAG,UAAU,UAAU,IAAI,CAAC,kNAMrB,UAAU,QAAQ,oBAAoB,CAAC,KAAK,UAAU,QAAQ,SAAS,CAAC,UACxE,UAAU,QAAQ,iBAAiB,CAAC,OAAO,UAAU,QAAQ,QAAQ,CAAC,UACtE,UAAU,QAAQ,iBAAiB,CAAC,OAAO,UAAU,QAAQ,SAAS,CAAC;AAElF,MAAa,oBAAoB,sCACxB,UAAU,QAAQ,8IAA8I,CAAC,4IAI1I,UAAU,QAAQ,SAAS,CAAC,IAAI,UAAU,QAAQ,SAAS,CAAC,OAAO,UAAU,QAAQ,QAAQ,CAAC;AAE9H,SAAgB,sBAAkG,QAAyD;CACzK,MAAM,2BAAW,IAAI,KAA4C;CACjE,KAAK,MAAM,KAAK,QAAQ;EACtB,MAAM,MAAM,EAAE,eAAe,EAAE;EAC/B,IAAI,CAAC,SAAS,IAAI,IAAI,EACpB,SAAS,IAAI,KAAK;GAAE,MAAM;GAAK,QAAQ,EAAE;GAAE,CAAC;EAC9C,SAAS,IAAI,IAAI,CAAE,OAAO,KAAK,EAAE;;CAEnC,OAAO;;AAQT,eAAsB,UACpB,QACA,OAA2B,EAAE,EACL;CACxB,MAAM,aAAa,sBAAsB,OAAO;CAChD,MAAM,SAAS,KAAK,UAAU,EAAE;CAChC,MAAM,QAAQ,KAAK,SAAS,EAAE;CAE9B,IAAI,WAAW,SAAS,KAAK,OAAO,WAAW,GAAG;EAChD,MAAM,GAAG,SAAS,CAAC,GAAG,WAAW,SAAS,CAAC,CAAC;EAC5C,MAAM,SAAS,MAAM,EAAE,OAAO;GAC5B,SAAS,GAAG,MAAM;GAClB,SAAS,CACP,GAAG,MAAM,OAAO,KAAI,OAAM;IACxB,OAAO,EAAE,cAAc,GAAG,EAAE,KAAK,mCAAmC,EAAE;IACtE,OAAO,EAAE;IACT,MAAM,EAAE;IACT,EAAE,EACH,GAAG,MACJ;GACF,CAAC;EACF,OAAO,EAAE,SAAS,OAAO,GAAG,OAAO;;CAGrC,MAAM,iBAAiB,MAAM,EAAE,OAAO;EACpC,SAAS;EACT,SAAS;GACP,GAAG;GACH,GAAG,MAAM,KAAK,WAAW,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,QAAQ,WAAW;IACpE,OAAO;IACP,OAAO;IACP,MAAM,GAAG,GAAG,OAAO;IACpB,EAAE;GACH,GAAG;GACJ;EACF,CAAC;CAEF,IAAI,EAAE,SAAS,eAAe,EAC5B,OAAO;CAET,MAAM,cAAc;CACpB,IAAI,OAAO,MAAK,MAAK,EAAE,UAAU,YAAY,IAAI,MAAM,MAAK,MAAK,EAAE,UAAU,YAAY,EACvF,OAAO;CAET,MAAM,QAAQ,WAAW,IAAI,YAAY;CACzC,MAAM,cAAc,MAAM,EAAE,OAAO;EACjC,SAAS,iBAAiB,MAAM,KAAK;EACrC,SAAS,MAAM,OAAO,KAAI,OAAM;GAC9B,OAAO,EAAE,cAAc,GAAG,EAAE,KAAK,mCAAmC,EAAE;GACtE,OAAO,EAAE;GACT,MAAM,EAAE;GACT,EAAE;EACJ,CAAC;CAEF,OAAO,EAAE,SAAS,YAAY,GAAG,OAAO"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { i as GIT_PLUS_PREFIX_RE, o as GIT_SUFFIX_RE } from "./regex.mjs";
|
|
2
|
+
import { i as readPackageJsonSafe } from "./package-json.mjs";
|
|
3
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
4
|
+
import { join, resolve } from "pathe";
|
|
5
|
+
const STATIC_REGEX_3 = /\/?\*+$/;
|
|
6
|
+
const QUOTE_PREFIX_RE = /^['"]/;
|
|
7
|
+
const QUOTE_SUFFIX_RE = /['"]$/;
|
|
8
|
+
function readRepoUrl(pkg) {
|
|
9
|
+
return typeof pkg.repository === "string" ? pkg.repository : pkg.repository?.url?.replace(GIT_PLUS_PREFIX_RE, "").replace(GIT_SUFFIX_RE, "");
|
|
10
|
+
}
|
|
11
|
+
function readWorkspacePatterns(cwd, pkg) {
|
|
12
|
+
let patterns = [];
|
|
13
|
+
if (Array.isArray(pkg.workspaces)) patterns = pkg.workspaces;
|
|
14
|
+
else if (pkg.workspaces?.packages) patterns = pkg.workspaces.packages;
|
|
15
|
+
if (patterns.length === 0) {
|
|
16
|
+
const pnpmWs = join(cwd, "pnpm-workspace.yaml");
|
|
17
|
+
if (existsSync(pnpmWs)) {
|
|
18
|
+
const lines = readFileSync(pnpmWs, "utf-8").split("\n");
|
|
19
|
+
for (const line of lines) {
|
|
20
|
+
const trimmed = line.trim();
|
|
21
|
+
if (!trimmed.startsWith("-")) continue;
|
|
22
|
+
const value = trimmed.slice(1).trim().replace(QUOTE_PREFIX_RE, "").replace(QUOTE_SUFFIX_RE, "");
|
|
23
|
+
if (value) patterns.push(value);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return patterns;
|
|
28
|
+
}
|
|
29
|
+
function detectMonorepoPackages(cwd) {
|
|
30
|
+
const rootResult = readPackageJsonSafe(join(cwd, "package.json"));
|
|
31
|
+
if (!rootResult) return null;
|
|
32
|
+
const pkg = rootResult.parsed;
|
|
33
|
+
if (!pkg.private) return null;
|
|
34
|
+
const patterns = readWorkspacePatterns(cwd, pkg);
|
|
35
|
+
if (patterns.length === 0) return null;
|
|
36
|
+
const packages = [];
|
|
37
|
+
for (const pattern of patterns) {
|
|
38
|
+
const scanDir = resolve(cwd, pattern.replace(STATIC_REGEX_3, ""));
|
|
39
|
+
if (!existsSync(scanDir)) continue;
|
|
40
|
+
const directResult = readPackageJsonSafe(join(scanDir, "package.json"));
|
|
41
|
+
if (directResult) {
|
|
42
|
+
const directPkg = directResult.parsed;
|
|
43
|
+
if (!directPkg.private && directPkg.name) {
|
|
44
|
+
packages.push({
|
|
45
|
+
name: directPkg.name,
|
|
46
|
+
version: directPkg.version || "0.0.0",
|
|
47
|
+
description: directPkg.description,
|
|
48
|
+
repoUrl: readRepoUrl(directPkg),
|
|
49
|
+
dir: scanDir
|
|
50
|
+
});
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (const entry of readdirSync(scanDir, { withFileTypes: true })) {
|
|
55
|
+
if (!entry.isDirectory()) continue;
|
|
56
|
+
const childResult = readPackageJsonSafe(join(scanDir, entry.name, "package.json"));
|
|
57
|
+
if (!childResult) continue;
|
|
58
|
+
const childPkg = childResult.parsed;
|
|
59
|
+
if (childPkg.private || !childPkg.name) continue;
|
|
60
|
+
packages.push({
|
|
61
|
+
name: childPkg.name,
|
|
62
|
+
version: childPkg.version || "0.0.0",
|
|
63
|
+
description: childPkg.description,
|
|
64
|
+
repoUrl: readRepoUrl(childPkg),
|
|
65
|
+
dir: join(scanDir, entry.name)
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return packages.length > 0 ? packages : null;
|
|
70
|
+
}
|
|
71
|
+
export { detectMonorepoPackages as t };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=monorepo.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monorepo.mjs","names":[],"sources":["../../src/core/monorepo.ts"],"sourcesContent":["/**\n * Monorepo detection — discovers public packages in a workspace root.\n * Used by author flow to drive multi-package skill generation.\n */\n\nimport { existsSync, readdirSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'pathe'\nimport { readPackageJsonSafe } from './package-json.ts'\nimport { GIT_PLUS_PREFIX_RE, GIT_SUFFIX_RE } from './regex.ts'\n\nconst STATIC_REGEX_3 = /\\/?\\*+$/\n\nconst QUOTE_PREFIX_RE = /^['\"]/\nconst QUOTE_SUFFIX_RE = /['\"]$/\n\nexport interface MonorepoPackage {\n name: string\n version: string\n description?: string\n repoUrl?: string\n dir: string\n}\n\nfunction readRepoUrl(pkg: Record<string, any>): string | undefined {\n return typeof pkg.repository === 'string'\n ? pkg.repository\n : pkg.repository?.url?.replace(GIT_PLUS_PREFIX_RE, '').replace(GIT_SUFFIX_RE, '')\n}\n\nfunction readWorkspacePatterns(cwd: string, pkg: Record<string, any>): string[] {\n let patterns: string[] = []\n\n if (Array.isArray(pkg.workspaces))\n patterns = pkg.workspaces\n else if (pkg.workspaces?.packages)\n patterns = pkg.workspaces.packages\n\n if (patterns.length === 0) {\n const pnpmWs = join(cwd, 'pnpm-workspace.yaml')\n if (existsSync(pnpmWs)) {\n const lines = readFileSync(pnpmWs, 'utf-8').split('\\n')\n for (const line of lines) {\n const trimmed = line.trim()\n if (!trimmed.startsWith('-'))\n continue\n const value = trimmed.slice(1).trim().replace(QUOTE_PREFIX_RE, '').replace(QUOTE_SUFFIX_RE, '')\n if (value)\n patterns.push(value)\n }\n }\n }\n\n return patterns\n}\n\n/**\n * Detect public (non-private) packages declared by a workspace root.\n * Returns null if `cwd` is not a private workspace root or has no public\n * packages. Supports `package.json#workspaces` (array or `{ packages }`)\n * and `pnpm-workspace.yaml`.\n */\nexport function detectMonorepoPackages(cwd: string): MonorepoPackage[] | null {\n const rootResult = readPackageJsonSafe(join(cwd, 'package.json'))\n if (!rootResult)\n return null\n\n const pkg = rootResult.parsed as Record<string, any>\n if (!pkg.private)\n return null\n\n const patterns = readWorkspacePatterns(cwd, pkg)\n if (patterns.length === 0)\n return null\n\n const packages: MonorepoPackage[] = []\n\n for (const pattern of patterns) {\n const base = pattern.replace(STATIC_REGEX_3, '')\n const scanDir = resolve(cwd, base)\n if (!existsSync(scanDir))\n continue\n\n const directResult = readPackageJsonSafe(join(scanDir, 'package.json'))\n if (directResult) {\n const directPkg = directResult.parsed as Record<string, any>\n if (!directPkg.private && directPkg.name) {\n packages.push({\n name: directPkg.name,\n version: directPkg.version || '0.0.0',\n description: directPkg.description,\n repoUrl: readRepoUrl(directPkg),\n dir: scanDir,\n })\n continue\n }\n }\n\n for (const entry of readdirSync(scanDir, { withFileTypes: true })) {\n if (!entry.isDirectory())\n continue\n const childResult = readPackageJsonSafe(join(scanDir, entry.name, 'package.json'))\n if (!childResult)\n continue\n\n const childPkg = childResult.parsed as Record<string, any>\n if (childPkg.private || !childPkg.name)\n continue\n\n packages.push({\n name: childPkg.name,\n version: childPkg.version || '0.0.0',\n description: childPkg.description,\n repoUrl: readRepoUrl(childPkg),\n dir: join(scanDir, entry.name),\n })\n }\n }\n\n return packages.length > 0 ? packages : null\n}\n"],"mappings":";;;;;;;AAUA,SAAM,YAAA,KAAiB;CAEvB,OAAM,OAAA,IAAA,eAAkB,WAAA,IAAA,aAAA,IAAA,YAAA,KAAA,QAAA,oBAAA,GAAA,CAAA,QAAA,eAAA,GAAA;;AAWxB,SAAS,sBAA0D,KAAA,KAAA;CACjE,IAAA,WAAc,EAAA;;MAKhB,IAAS,IAAA,YAAA,UAAmC,WAAoC,IAAA,WAAA;CAC9E,IAAI,SAAA,WAAuB,GAAA;EAE3B,MAAI,SAAM,KAAQ,KAAI,sBACT;MACR,WAAQ,OAAA,EAAY;GAGzB,MAAI,QAAS,aAAc,QAAA,QAAA,CAAA,MAAA,KAAA;GACzB,KAAM,MAAA,QAAc,OAAK;IACzB,MAAI,UAAW,KAAO,MAAE;IACtB,IAAA,CAAM,QAAQ,WAAA,IAAa,EAAA;IAC3B,MAAK,QAAM,QAAQ,MAAO,EAAA,CAAA,MAAA,CAAA,QAAA,iBAAA,GAAA,CAAA,QAAA,iBAAA,GAAA;IACxB,IAAA,OAAM,SAAU,KAAK,MAAM;;;;;;SAU1B,uBAAA,KAAA;;;;;;;;CAST,KAAA,MAAgB,WAAA,UAAuB;EACrC,MAAM,UAAA,QAAa,KAAA,QAAA,QAAyB,gBAAK,GAAgB,CAAA;EACjE,IAAK,CAAA,WACH,QAAO,EAAA;EAET,MAAM,eAAM,oBAAW,KAAA,SAAA,eAAA,CAAA;EACvB,IAAK,cACH;GAEF,MAAM,YAAW,aAAA;GACjB,IAAI,CAAA,UAAS,WACX,UAAO,MAAA;IAET,SAAM,KAA8B;KAEpC,MAAK,UAAM;KAET,SAAM,UAAU,WADH;KAEb,aAAgB,UACd;KAEF,SAAM,YAAe,UAAA;KACrB,KAAI;KACF,CAAA;IACA;;;OAGI,MAAA,SAAS,YAAU,SAAW,EAAA,eAAA,MAAA,CAAA,EAAA;OAC9B,CAAA,MAAA,aAAa,EAAU;SACvB,cAAS,oBAAsB,KAAA,SAAA,MAAA,MAAA,eAAA,CAAA;OAC/B,CAAA,aAAK;SACL,WAAA,YAAA;OACF,SAAA,WAAA,CAAA,SAAA,MAAA;;;IAIJ,SAAW,SAAS,WAAA;IAClB,aAAW,SAAA;IAEX,SAAM,YAAc,SAAA;IACpB,KAAK,KAAA,SACH,MAAA,KAAA;IAEF,CAAA;;;QAKE,SAAM,SAAS,IAAA,WAAA;;SAGf,0BAA8B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-json.mjs","names":[],"sources":["../../src/core/package-json.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { applyEdits, modify, parseTree } from 'jsonc-parser'\n\nexport interface EditOptions {\n /** Formatting options for inserted content */\n tabSize?: number\n insertSpaces?: boolean\n}\n\nconst defaultEditOptions: EditOptions = { tabSize: 2, insertSpaces: true }\n\n// ── Cached reader ──────────────────────────────────────────────\n\nconst cache = new Map<string, { raw: string, parsed: Record<string, unknown> }>()\n\n/**\n * Read and parse a package.json, returning cached result on repeat calls.\n * Throws if the file does not exist.\n */\nexport function readPackageJson(pkgPath: string): { raw: string, parsed: Record<string, unknown> } {\n const hit = cache.get(pkgPath)\n if (hit)\n return hit\n const raw = readFileSync(pkgPath, 'utf-8')\n const parsed = JSON.parse(raw) as Record<string, unknown>\n const entry = { raw, parsed }\n cache.set(pkgPath, entry)\n return entry\n}\n\n/**\n * Same as readPackageJson but returns null when the file is missing or unparseable.\n */\nexport function readPackageJsonSafe(pkgPath: string): { raw: string, parsed: Record<string, unknown> } | null {\n if (cache.has(pkgPath))\n return cache.get(pkgPath)!\n if (!existsSync(pkgPath))\n return null\n try {\n return readPackageJson(pkgPath)\n }\n catch {\n return null\n }\n}\n\n/**\n * Drop any cached entry so the next read hits disk.\n */\nexport function invalidatePackageJson(pkgPath: string): void {\n cache.delete(pkgPath)\n}\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"package-json.mjs","names":[],"sources":["../../src/core/package-json.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { applyEdits, modify, parseTree } from 'jsonc-parser'\n\nexport interface EditOptions {\n /** Formatting options for inserted content */\n tabSize?: number\n insertSpaces?: boolean\n}\n\nconst defaultEditOptions: EditOptions = { tabSize: 2, insertSpaces: true }\n\n// ── Cached reader ──────────────────────────────────────────────\n\nconst cache = new Map<string, { raw: string, parsed: Record<string, unknown> }>()\n\n/**\n * Read and parse a package.json, returning cached result on repeat calls.\n * Throws if the file does not exist.\n */\nexport function readPackageJson(pkgPath: string): { raw: string, parsed: Record<string, unknown> } {\n const hit = cache.get(pkgPath)\n if (hit)\n return hit\n const raw = readFileSync(pkgPath, 'utf-8')\n const parsed = JSON.parse(raw) as Record<string, unknown>\n const entry = { raw, parsed }\n cache.set(pkgPath, entry)\n return entry\n}\n\n/**\n * Same as readPackageJson but returns null when the file is missing or unparseable.\n */\nexport function readPackageJsonSafe(pkgPath: string): { raw: string, parsed: Record<string, unknown> } | null {\n if (cache.has(pkgPath))\n return cache.get(pkgPath)!\n if (!existsSync(pkgPath))\n return null\n try {\n return readPackageJson(pkgPath)\n }\n catch {\n return null\n }\n}\n\n/**\n * Drop any cached entry so the next read hits disk.\n */\nexport function invalidatePackageJson(pkgPath: string): void {\n cache.delete(pkgPath)\n}\n\n/**\n * Drop all cached entries. Useful for tests.\n */\nexport function clearPackageJsonCache(): void {\n cache.clear()\n}\n\n// ── JSON editing helpers ───────────────────────────────────────\n\n/**\n * Set a value at a JSON path, preserving all surrounding formatting.\n * Returns the modified file content as a string.\n */\nexport function editJsonProperty(raw: string, path: (string | number)[], value: unknown, options?: EditOptions): string {\n const opts = { ...defaultEditOptions, ...options }\n const edits = modify(raw, path, value, {\n formattingOptions: { tabSize: opts.tabSize!, insertSpaces: opts.insertSpaces! },\n })\n return applyEdits(raw, edits)\n}\n\n/**\n * Read a package.json, apply an edit function, write it back, and invalidate the cache.\n * The edit function receives the raw text and parsed object,\n * and returns the new raw text (or null to skip writing).\n */\nexport function patchPackageJson(\n pkgPath: string,\n editFn: (raw: string, pkg: Record<string, unknown>) => string | null,\n): boolean {\n const { raw, parsed } = readPackageJson(pkgPath)\n const result = editFn(raw, parsed)\n if (result === null)\n return false\n writeFileSync(pkgPath, result)\n invalidatePackageJson(pkgPath)\n return true\n}\n\n/**\n * Append a value to a JSON array at the given path, preserving formatting.\n * Inserts in sorted order if the array contains strings.\n */\nexport function appendToJsonArray(raw: string, path: string[], value: string, options?: EditOptions): string {\n const opts = { ...defaultEditOptions, ...options }\n const tree = parseTree(raw)\n if (!tree)\n return editJsonProperty(raw, path, [value], opts)\n\n // Walk to the target array node\n let node = tree\n for (const key of path) {\n const child = node.children?.find(c =>\n c.type === 'property' && c.children?.[0]?.value === key,\n )\n if (!child?.children?.[1])\n return editJsonProperty(raw, path, [value], opts)\n node = child.children[1]\n }\n\n if (node.type !== 'array' || !node.children)\n return editJsonProperty(raw, path, [value], opts)\n\n // Find sorted insertion index (only for string-only arrays)\n const allStrings = node.children.every(c => typeof c.value === 'string')\n let idx = node.children.length\n if (allStrings) {\n const items = node.children.map(c => c.value as string)\n for (let i = 0; i < items.length; i++) {\n if (value.localeCompare(items[i]!) < 0) {\n idx = i\n break\n }\n }\n }\n\n const edits = modify(raw, [...path, idx], value, {\n formattingOptions: { tabSize: opts.tabSize!, insertSpaces: opts.insertSpaces! },\n isArrayInsertion: true,\n })\n return applyEdits(raw, edits)\n}\n"],"mappings":";;AASA,MAAM,qBAAkC;CAAE,SAAS;CAAG,cAAc;CAAM;AAI1E,MAAM,wBAAQ,IAAI,KAA+D;;;;CAMjF,MAAA,MAAgB,aAAgB,SAAmE,QAAA;CACjG,MAAM,QAAM;EACZ;EAEA,QAAM,KAAM,MAAA,IAAA;EAEZ;OAAgB,IAAA,SAAA,MAAA;QAAK;;SAEd,oBAAA,SAAA;;;;;SAMO;EACd,OAAI;;;SAOE,sBAAA,SAAA;OACJ,OAAO,QAAA;;;;;EAOX,GAAA;EACE;;;;;;SAiBM,iBAAO,SAAA,QAAA;OAAK,EAAA,KAAA,WAAA,gBAAA,QAAA;OAAuB,SAAA,OAAA,KAAA,OAAA;KAAS,WAAA,MAAA,OAAA;CAIlD,cAAO,SAHO,OAAO;uBACgB,QAAA;QAAU;;;;;;;CAUjD,MAAA,OAAgB,UAAA,IACd;CAGA,IAAA,CAAA,MAAQ,OAAK,iBAAW,KAAgB,MAAA,CAAA,MAAQ,EAAA,KAAA;CAChD,IAAA,OAAM;CACN,KAAI,MAAA,OAAW,MACb;EACF,MAAA,QAAc,KAAA,UAAgB,MAAA,MAAA,EAAA,SAAA,cAAA,EAAA,WAAA,IAAA,UAAA,IAAA;EAC9B,IAAA,CAAA,OAAA,WAAsB,IAAA,OAAQ,iBAAA,KAAA,MAAA,CAAA,MAAA,EAAA,KAAA;EAC9B,OAAO,MAAA,SAAA;;;;;;EAOT,MAAA,QAAgB,KAAA,SAAkB,KAAa,MAAgB,EAAA,MAAe;EAC5E,KAAM,IAAA,IAAO,GAAA,IAAA,MAAA,QAAA,KAAA,IAAA,MAAA,cAAA,MAAA,GAAA,GAAA,GAAA;GAAE,MAAG;GAAoB;;;CAEtC,OAAK,WACI,KAAA,OAAA,KAAiB,CAAA,GAAA,MAAK,IAAO,EAAA,OAAQ;EAG9C,mBAAW;GACX,SAAW,KAAA;GACT,cAAc,KAAK;GAGnB;EAEA,kBAAa;;;SAQX,uBAAoB,GAAA,oBAAA,GAAA,oBAAA,GAAA,qBAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "pathe";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
const SHARED_SKILLS_DIR = ".skills";
|
|
5
|
+
const SKILL_INTERNAL_DIRNAME = ".skilld";
|
|
6
|
+
const SKILL_INTERNAL_FILENAME = "_SKILL.md";
|
|
7
|
+
const LOCK_FILENAME = "skilld-lock.yaml";
|
|
8
|
+
const CONFIG_FILENAME = "config.yaml";
|
|
9
|
+
const CACHE_DIR = join(homedir(), ".skilld");
|
|
10
|
+
const REFERENCES_DIR = join(CACHE_DIR, "references");
|
|
11
|
+
const REPOS_DIR = join(CACHE_DIR, "repos");
|
|
12
|
+
const LLM_CACHE_DIR = join(CACHE_DIR, "llm-cache");
|
|
13
|
+
const CONFIG_PATH = join(CACHE_DIR, CONFIG_FILENAME);
|
|
14
|
+
const PI_AI_AUTH_PATH = join(CACHE_DIR, "pi-ai-auth.json");
|
|
15
|
+
const AUTH_PATH = join(CACHE_DIR, "auth.json");
|
|
16
|
+
function getSharedSkillsDir(cwd = process.cwd()) {
|
|
17
|
+
const dir = join(cwd, SHARED_SKILLS_DIR);
|
|
18
|
+
return existsSync(dir) ? dir : null;
|
|
19
|
+
}
|
|
20
|
+
function lockfilePath(skillsDir) {
|
|
21
|
+
return join(skillsDir, LOCK_FILENAME);
|
|
22
|
+
}
|
|
23
|
+
function skillInternalDir(skillDir) {
|
|
24
|
+
return join(skillDir, SKILL_INTERNAL_DIRNAME);
|
|
25
|
+
}
|
|
26
|
+
function skillInternalFile(skillDir) {
|
|
27
|
+
return join(skillDir, SKILL_INTERNAL_DIRNAME, SKILL_INTERNAL_FILENAME);
|
|
28
|
+
}
|
|
29
|
+
function skillLogDir(skillDir) {
|
|
30
|
+
return join(skillDir, SKILL_INTERNAL_DIRNAME, "logs");
|
|
31
|
+
}
|
|
32
|
+
function skillRefsSection(skillDir, section) {
|
|
33
|
+
return join(skillDir, SKILL_INTERNAL_DIRNAME, section);
|
|
34
|
+
}
|
|
35
|
+
function getReferencesDir(name, version) {
|
|
36
|
+
return join(REFERENCES_DIR, `${name}@${version}`);
|
|
37
|
+
}
|
|
38
|
+
function getRepoCacheDir(owner, repo) {
|
|
39
|
+
if (owner.includes("..") || repo.includes("..") || owner.includes("/") || repo.includes("/")) throw new Error(`Invalid repo path: ${owner}/${repo}`);
|
|
40
|
+
return join(REPOS_DIR, owner, repo);
|
|
41
|
+
}
|
|
42
|
+
function getPackageDbPath(name, version) {
|
|
43
|
+
return join(getReferencesDir(name, version), "search.db");
|
|
44
|
+
}
|
|
45
|
+
export { skillRefsSection as _, LOCK_FILENAME as a, REPOS_DIR as c, getRepoCacheDir as d, getSharedSkillsDir as f, skillLogDir as g, skillInternalFile as h, LLM_CACHE_DIR as i, SHARED_SKILLS_DIR as l, skillInternalDir as m, CACHE_DIR as n, PI_AI_AUTH_PATH as o, lockfilePath as p, CONFIG_PATH as r, REFERENCES_DIR as s, AUTH_PATH as t, getPackageDbPath as u };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=paths.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.mjs","names":[],"sources":["../../src/core/paths.ts"],"sourcesContent":["/**\n * Project layout: every `~/.skilld/...` and `.claude/skills/...` path lives here.\n *\n * Two layers:\n * 1. Global cache under `~/.skilld/` (references, repos, llm-cache, etc.)\n * 2. Per-skill internals: `<skillDir>/.skilld/` holds reference symlinks,\n * logs, and the canonical `_SKILL.md`. The lockfile sits as a sibling\n * of skill dirs as `skilld-lock.yaml`.\n *\n * Per-agent target dirs (`.claude/skills/`, `.cursor/skills/`, ...) are owned\n * by the agent registry (`src/agent/registry.ts`); this module exposes the\n * agent-agnostic `.skills/` shared dir and helpers that compose with target dirs.\n */\n\nimport { existsSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'pathe'\n\n// ── Project-relative names ──\n\n/** Shared, agent-agnostic skills directory at project root */\nexport const SHARED_SKILLS_DIR = '.skills'\n\n/** Per-skill internals directory (cache symlinks, logs, prompts, _SKILL.md) */\nexport const SKILL_INTERNAL_DIRNAME = '.skilld'\n\n/** Canonical SKILL.md copy inside the per-skill internals dir (frontmatter source of truth) */\nexport const SKILL_INTERNAL_FILENAME = '_SKILL.md'\n\n/** Lockfile sibling of skill directories */\nexport const LOCK_FILENAME = 'skilld-lock.yaml'\n\n/** Config filename inside the global cache */\nexport const CONFIG_FILENAME = 'config.yaml'\n\n// ── Global cache layout (~/.skilld/) ──\n\n/** Root of the global cache */\nexport const CACHE_DIR: string = join(homedir(), '.skilld')\n\n/** References subdirectory: `~/.skilld/references/<pkg>@<version>/` */\nexport const REFERENCES_DIR: string = join(CACHE_DIR, 'references')\n\n/** Repo-level cache (issues, discussions, releases shared across monorepo packages) */\nexport const REPOS_DIR: string = join(CACHE_DIR, 'repos')\n\n/** LLM output cache: `~/.skilld/llm-cache/<sha256>.json` */\nexport const LLM_CACHE_DIR: string = join(CACHE_DIR, 'llm-cache')\n\n/** Global config file */\nexport const CONFIG_PATH: string = join(CACHE_DIR, CONFIG_FILENAME)\n\n/** pi-ai auth credentials */\nexport const PI_AI_AUTH_PATH: string = join(CACHE_DIR, 'pi-ai-auth.json')\n\n/** CLI auth marker (`~/.skilld/auth.json`, 0600). Stores tokens directly only when keychain unavailable. */\nexport const AUTH_PATH: string = join(CACHE_DIR, 'auth.json')\n\n// ── Helpers ──\n\n/** Returns the shared skills directory path if `.skills/` exists at project root, else null */\nexport function getSharedSkillsDir(cwd: string = process.cwd()): string | null {\n const dir = join(cwd, SHARED_SKILLS_DIR)\n return existsSync(dir) ? dir : null\n}\n\n/** Path to the lockfile inside a skills directory */\nexport function lockfilePath(skillsDir: string): string {\n return join(skillsDir, LOCK_FILENAME)\n}\n\n/** Per-skill internals dir (`<skillDir>/.skilld`) */\nexport function skillInternalDir(skillDir: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME)\n}\n\n/** Per-skill canonical SKILL.md (`<skillDir>/.skilld/_SKILL.md`) */\nexport function skillInternalFile(skillDir: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME, SKILL_INTERNAL_FILENAME)\n}\n\n/** Per-skill log dir (`<skillDir>/.skilld/logs`) */\nexport function skillLogDir(skillDir: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME, 'logs')\n}\n\n/** Per-skill section dir (`<skillDir>/.skilld/<section>`), e.g. issues/discussions/releases/docs */\nexport function skillRefsSection(skillDir: string, section: string): string {\n return join(skillDir, SKILL_INTERNAL_DIRNAME, section)\n}\n\n/** References cache dir for a `name@version` */\nexport function getReferencesDir(name: string, version: string): string {\n return join(REFERENCES_DIR, `${name}@${version}`)\n}\n\n/** Repo cache dir with path-traversal validation */\nexport function getRepoCacheDir(owner: string, repo: string): string {\n if (owner.includes('..') || repo.includes('..') || owner.includes('/') || repo.includes('/'))\n throw new Error(`Invalid repo path: ${owner}/${repo}`)\n return join(REPOS_DIR, owner, repo)\n}\n\n/** search.db path for a `name@version` */\nexport function getPackageDbPath(name: string, version: string): string {\n return join(getReferencesDir(name, version), 'search.db')\n}\n"],"mappings":";;;;;;;;;AAqBA,MAAa,iBAAA,KAAoB,WAAA,aAAA;AAGjC,MAAa,YAAA,KAAA,WAAyB,QAAA;AAGtC,MAAa,gBAAA,KAAA,WAA0B,YAAA;AAGvC,MAAa,cAAA,KAAgB,WAAA,gBAAA;AAG7B,MAAa,kBAAkB,KAAA,WAAA,kBAAA;AAK/B,MAAa,YAAoB,KAAK,WAAW,YAAU;AAG3D,SAAa,mBAA8B,MAAA,QAAW,KAAA,EAAA;;CAGtD,OAAa,WAAoB,IAAK,GAAA,MAAA;;;CAMtC,OAAa,KAAA,WAAsB,cAAgB;;;CAMnD,OAAa,KAAA,UAAyB,uBAAuB;;SAMrD,kBAAgB,UAAA;CACtB,OAAO,KAAA,UAAe,wBAAS,wBAAA;;AAIjC,SAAgB,YAAA,UAAa;CAC3B,OAAO,KAAK,UAAA,wBAAyB,OAAA;;AAIvC,SAAgB,iBAAiB,UAA0B,SAAA;CACzD,OAAO,KAAK,UAAU,wBAAuB,QAAA;;AAI/C,SAAgB,iBAAA,MAAkB,SAA0B;CAC1D,OAAO,KAAK,gBAAU,GAAA,KAAA,GAAA,UAAwB;;AAIhD,SAAgB,gBAAY,OAA0B,MAAA;CACpD,IAAA,MAAO,SAAK,KAAU,IAAA,KAAA,SAAA,KAAwB,IAAA,MAAO,SAAA,IAAA,IAAA,KAAA,SAAA,IAAA,EAAA,MAAA,IAAA,MAAA,sBAAA,MAAA,GAAA,OAAA;;;SAK9C,iBAAe,MAAA,SAAA;;;SAKf,oBAAqB,GAAG,iBAAQ,GAAU,aAAA,GAAA,mBAAA,GAAA,sBAAA,GAAA,eAAA,GAAA,qBAAA,GAAA,iBAAA,GAAA,qBAAA,GAAA,oBAAA,GAAA,aAAA,GAAA,mBAAA,GAAA,gBAAA,GAAA,eAAA,GAAA,kBAAA,GAAA,aAAA,GAAA,oBAAA"}
|