llmstxt-cli 0.2.0 → 0.3.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/index.js +399 -810
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,23 +23,23 @@ function error(message) {
|
|
|
23
23
|
function spinner2(_text) {
|
|
24
24
|
const s = p.spinner();
|
|
25
25
|
return {
|
|
26
|
-
start(
|
|
27
|
-
s.start(
|
|
26
|
+
start(text2) {
|
|
27
|
+
s.start(text2 || _text || "");
|
|
28
28
|
},
|
|
29
|
-
stop(
|
|
30
|
-
s.stop(
|
|
29
|
+
stop(text2) {
|
|
30
|
+
s.stop(text2 || "");
|
|
31
31
|
},
|
|
32
|
-
succeed(
|
|
33
|
-
s.stop(`${pc.green("\u2713")} ${
|
|
32
|
+
succeed(text2) {
|
|
33
|
+
s.stop(`${pc.green("\u2713")} ${text2}`);
|
|
34
34
|
},
|
|
35
|
-
fail(
|
|
36
|
-
s.stop(`${pc.red("\u2717")} ${
|
|
35
|
+
fail(text2) {
|
|
36
|
+
s.stop(`${pc.red("\u2717")} ${text2}`);
|
|
37
37
|
},
|
|
38
|
-
info(
|
|
39
|
-
s.stop(`${pc.blue("\u2139")} ${
|
|
38
|
+
info(text2) {
|
|
39
|
+
s.stop(`${pc.blue("\u2139")} ${text2}`);
|
|
40
40
|
},
|
|
41
|
-
warn(
|
|
42
|
-
s.stop(`${pc.yellow("\u26A0")} ${
|
|
41
|
+
warn(text2) {
|
|
42
|
+
s.stop(`${pc.yellow("\u26A0")} ${text2}`);
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
}
|
|
@@ -6390,6 +6390,9 @@ function searchRegistry(query, categories) {
|
|
|
6390
6390
|
function getEntry2(slug) {
|
|
6391
6391
|
return entries.find((e) => e.slug === slug);
|
|
6392
6392
|
}
|
|
6393
|
+
function getAllEntries(categories) {
|
|
6394
|
+
return categories ? filterByCategories(entries, categories) : entries;
|
|
6395
|
+
}
|
|
6393
6396
|
function resolveSlug(nameOrSlug) {
|
|
6394
6397
|
const exact = entries.find((e) => e.slug === nameOrSlug);
|
|
6395
6398
|
if (exact) return exact;
|
|
@@ -6457,7 +6460,7 @@ var agents = [
|
|
|
6457
6460
|
displayName: "Antigravity",
|
|
6458
6461
|
skillsDir: ".agent/skills",
|
|
6459
6462
|
isUniversal: false,
|
|
6460
|
-
detectInstalled: () => existsSync2(join3(
|
|
6463
|
+
detectInstalled: () => existsSync2(join3(home, ".gemini/antigravity"))
|
|
6461
6464
|
},
|
|
6462
6465
|
{
|
|
6463
6466
|
name: "augment",
|
|
@@ -6485,7 +6488,7 @@ var agents = [
|
|
|
6485
6488
|
displayName: "CodeBuddy",
|
|
6486
6489
|
skillsDir: ".codebuddy/skills",
|
|
6487
6490
|
isUniversal: false,
|
|
6488
|
-
detectInstalled: () => existsSync2(join3(
|
|
6491
|
+
detectInstalled: () => existsSync2(join3(home, ".codebuddy"))
|
|
6489
6492
|
},
|
|
6490
6493
|
{
|
|
6491
6494
|
name: "codex",
|
|
@@ -6506,7 +6509,7 @@ var agents = [
|
|
|
6506
6509
|
displayName: "Continue",
|
|
6507
6510
|
skillsDir: ".continue/skills",
|
|
6508
6511
|
isUniversal: false,
|
|
6509
|
-
detectInstalled: () => existsSync2(join3(
|
|
6512
|
+
detectInstalled: () => existsSync2(join3(home, ".continue"))
|
|
6510
6513
|
},
|
|
6511
6514
|
{
|
|
6512
6515
|
name: "crush",
|
|
@@ -6541,7 +6544,7 @@ var agents = [
|
|
|
6541
6544
|
displayName: "GitHub Copilot",
|
|
6542
6545
|
skillsDir: ".agents/skills",
|
|
6543
6546
|
isUniversal: true,
|
|
6544
|
-
detectInstalled: () => existsSync2(join3(
|
|
6547
|
+
detectInstalled: () => existsSync2(join3(home, ".copilot"))
|
|
6545
6548
|
},
|
|
6546
6549
|
{
|
|
6547
6550
|
name: "goose",
|
|
@@ -6632,7 +6635,7 @@ var agents = [
|
|
|
6632
6635
|
displayName: "OpenCode",
|
|
6633
6636
|
skillsDir: ".agents/skills",
|
|
6634
6637
|
isUniversal: true,
|
|
6635
|
-
detectInstalled: () => existsSync2(join3(configHome, "opencode"))
|
|
6638
|
+
detectInstalled: () => existsSync2(join3(configHome, "opencode"))
|
|
6636
6639
|
},
|
|
6637
6640
|
{
|
|
6638
6641
|
name: "openhands",
|
|
@@ -6812,7 +6815,8 @@ function installToAgents({
|
|
|
6812
6815
|
slug,
|
|
6813
6816
|
entry,
|
|
6814
6817
|
content,
|
|
6815
|
-
format
|
|
6818
|
+
format,
|
|
6819
|
+
targetAgents
|
|
6816
6820
|
}) {
|
|
6817
6821
|
const checksum = createHash("sha256").update(content).digest("hex");
|
|
6818
6822
|
const size = Buffer.byteLength(content, "utf-8");
|
|
@@ -6827,8 +6831,8 @@ function installToAgents({
|
|
|
6827
6831
|
writeFileSync3(join4(canonicalDir, "reference.md"), referenceMd, "utf-8");
|
|
6828
6832
|
}
|
|
6829
6833
|
installedAgents.push("universal");
|
|
6830
|
-
const
|
|
6831
|
-
for (const agent of
|
|
6834
|
+
const agentsToLink = targetAgents ?? detectInstalledAgents();
|
|
6835
|
+
for (const agent of agentsToLink) {
|
|
6832
6836
|
if (agent.isUniversal) {
|
|
6833
6837
|
if (!installedAgents.includes(agent.name)) {
|
|
6834
6838
|
installedAgents.push(agent.name);
|
|
@@ -6934,6 +6938,68 @@ ${pc2.dim("Full:")} ${entry.llmsFullTxtUrl}` : ""}`
|
|
|
6934
6938
|
import * as p3 from "@clack/prompts";
|
|
6935
6939
|
import pc4 from "picocolors";
|
|
6936
6940
|
|
|
6941
|
+
// src/lib/agent-selection.ts
|
|
6942
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
6943
|
+
import { join as join5 } from "path";
|
|
6944
|
+
var PREFS_DIR = ".llms";
|
|
6945
|
+
var PREFS_FILE = "agent-prefs.json";
|
|
6946
|
+
var DEFAULT_AGENTS = ["claude-code", "cursor", "codex"];
|
|
6947
|
+
function detectProjectAgents(opts) {
|
|
6948
|
+
const detected = [];
|
|
6949
|
+
for (const agent of opts.allAgents) {
|
|
6950
|
+
if (agent.isUniversal) continue;
|
|
6951
|
+
const configDir = agent.skillsDir.split("/")[0];
|
|
6952
|
+
if (configDir && configDir !== "skills" && existsSync4(join5(opts.projectDir, configDir))) {
|
|
6953
|
+
detected.push(agent.name);
|
|
6954
|
+
}
|
|
6955
|
+
}
|
|
6956
|
+
return detected;
|
|
6957
|
+
}
|
|
6958
|
+
function getInitialAgents(opts) {
|
|
6959
|
+
const validNames = new Set(opts.allAgents.map((a) => a.name));
|
|
6960
|
+
if (opts.savedPrefs && opts.savedPrefs.length > 0) {
|
|
6961
|
+
const filtered = opts.savedPrefs.filter((name) => validNames.has(name));
|
|
6962
|
+
if (filtered.length > 0) return filtered;
|
|
6963
|
+
}
|
|
6964
|
+
if (opts.projectDir) {
|
|
6965
|
+
const detected = detectProjectAgents({ projectDir: opts.projectDir, allAgents: opts.allAgents });
|
|
6966
|
+
if (detected.length > 0) return detected;
|
|
6967
|
+
}
|
|
6968
|
+
return DEFAULT_AGENTS.filter((name) => validNames.has(name));
|
|
6969
|
+
}
|
|
6970
|
+
function ensureUniversalAgents(opts) {
|
|
6971
|
+
const result = [...opts.selected];
|
|
6972
|
+
for (const agent of opts.allAgents) {
|
|
6973
|
+
if (agent.isUniversal && !result.includes(agent.name)) {
|
|
6974
|
+
result.push(agent.name);
|
|
6975
|
+
}
|
|
6976
|
+
}
|
|
6977
|
+
return result;
|
|
6978
|
+
}
|
|
6979
|
+
function loadSavedAgentPrefs(projectDir) {
|
|
6980
|
+
try {
|
|
6981
|
+
const filePath = join5(projectDir, PREFS_DIR, PREFS_FILE);
|
|
6982
|
+
if (!existsSync4(filePath)) return null;
|
|
6983
|
+
const data = JSON.parse(readFileSync4(filePath, "utf-8"));
|
|
6984
|
+
if (Array.isArray(data.agents)) return data.agents;
|
|
6985
|
+
return null;
|
|
6986
|
+
} catch {
|
|
6987
|
+
return null;
|
|
6988
|
+
}
|
|
6989
|
+
}
|
|
6990
|
+
function saveAgentPrefs(projectDir, agentNames) {
|
|
6991
|
+
try {
|
|
6992
|
+
const dir = join5(projectDir, PREFS_DIR);
|
|
6993
|
+
mkdirSync5(dir, { recursive: true });
|
|
6994
|
+
writeFileSync4(
|
|
6995
|
+
join5(dir, PREFS_FILE),
|
|
6996
|
+
JSON.stringify({ agents: agentNames }, null, 2) + "\n",
|
|
6997
|
+
"utf-8"
|
|
6998
|
+
);
|
|
6999
|
+
} catch {
|
|
7000
|
+
}
|
|
7001
|
+
}
|
|
7002
|
+
|
|
6937
7003
|
// src/lib/banner.ts
|
|
6938
7004
|
import pc3 from "picocolors";
|
|
6939
7005
|
var BANNER_LINES = [
|
|
@@ -6959,18 +7025,18 @@ ${pc3.dim(` v${version} \xB7 Install llms.txt documentation for AI coding tools
|
|
|
6959
7025
|
}
|
|
6960
7026
|
|
|
6961
7027
|
// src/lib/context.ts
|
|
6962
|
-
import { existsSync as
|
|
6963
|
-
import { join as
|
|
7028
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
7029
|
+
import { join as join6 } from "path";
|
|
6964
7030
|
var START_MARKER = "<!-- llmstxt:start -->";
|
|
6965
7031
|
var END_MARKER = "<!-- llmstxt:end -->";
|
|
6966
7032
|
function syncClaudeMd(projectDir) {
|
|
6967
7033
|
try {
|
|
6968
7034
|
const lockfile = readLockfile(projectDir);
|
|
6969
7035
|
const entries2 = Object.values(lockfile.entries);
|
|
6970
|
-
const claudeMdPath =
|
|
7036
|
+
const claudeMdPath = join6(projectDir, "CLAUDE.md");
|
|
6971
7037
|
let content = "";
|
|
6972
|
-
if (
|
|
6973
|
-
content =
|
|
7038
|
+
if (existsSync5(claudeMdPath)) {
|
|
7039
|
+
content = readFileSync5(claudeMdPath, "utf-8");
|
|
6974
7040
|
}
|
|
6975
7041
|
const section = buildSection(entries2);
|
|
6976
7042
|
if (content.includes(START_MARKER)) {
|
|
@@ -6993,12 +7059,12 @@ function syncClaudeMd(projectDir) {
|
|
|
6993
7059
|
new RegExp(`\\n?${escapeRegex(START_MARKER)}[\\s\\S]*?${escapeRegex(END_MARKER)}\\n?`),
|
|
6994
7060
|
""
|
|
6995
7061
|
).trim();
|
|
6996
|
-
if (content.length === 0 && !
|
|
7062
|
+
if (content.length === 0 && !existsSync5(claudeMdPath)) {
|
|
6997
7063
|
return;
|
|
6998
7064
|
}
|
|
6999
7065
|
}
|
|
7000
|
-
if (content.length > 0 ||
|
|
7001
|
-
|
|
7066
|
+
if (content.length > 0 || existsSync5(claudeMdPath)) {
|
|
7067
|
+
writeFileSync5(claudeMdPath, content.endsWith("\n") ? content : `${content}
|
|
7002
7068
|
`, "utf-8");
|
|
7003
7069
|
}
|
|
7004
7070
|
} catch (err) {
|
|
@@ -7026,701 +7092,76 @@ function escapeRegex(s) {
|
|
|
7026
7092
|
}
|
|
7027
7093
|
|
|
7028
7094
|
// src/lib/detector.ts
|
|
7029
|
-
import { existsSync as
|
|
7030
|
-
import { join as
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
|
|
7037
|
-
|
|
7038
|
-
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7042
|
-
|
|
7043
|
-
|
|
7044
|
-
adx: "adx",
|
|
7045
|
-
"affordable-nvme-ssd-web-hosting-pakistan": "affordable-nvme-ssd-web-hosting-pakistan",
|
|
7046
|
-
aftermath: "aftermath",
|
|
7047
|
-
agentai: "agentai",
|
|
7048
|
-
agentlayer: "agentlayer",
|
|
7049
|
-
agentql: "agentql",
|
|
7050
|
-
agno: "agno",
|
|
7051
|
-
"ai-consulting": "ai-consulting",
|
|
7052
|
-
"ai-dream-scope": "ai-dream-scope",
|
|
7053
|
-
"ai-predict-stock": "ai-predict-stock",
|
|
7054
|
-
"ai-sdk": "ai-sdk",
|
|
7055
|
-
"ai-squared": "ai-squared",
|
|
7056
|
-
aicryptocore: "aicryptocore",
|
|
7057
|
-
akool: "akool",
|
|
7058
|
-
alexopdev: "alexopdev",
|
|
7059
|
-
"all-in": "all-in",
|
|
7060
|
-
"alpha-fi": "alpha-fi",
|
|
7061
|
-
alphagate: "alphagate",
|
|
7062
|
-
altostrat: "altostrat",
|
|
7063
|
-
alva: "alva",
|
|
7064
|
-
amema: "amema",
|
|
7065
|
-
amplemarket: "amplemarket",
|
|
7066
|
-
analog: "analog",
|
|
7067
|
-
annoto: "annoto",
|
|
7068
|
-
answerai: "answerai",
|
|
7069
|
-
"ant-design": "ant-design",
|
|
7070
|
-
anthropic: "anthropic",
|
|
7071
|
-
anytrack: "anytrack",
|
|
7072
|
-
anytype: "anytype",
|
|
7073
|
-
"apex-protocol": "apex-protocol",
|
|
7074
|
-
apibara: "apibara",
|
|
7075
|
-
apify: "apify",
|
|
7076
|
-
aporia: "aporia",
|
|
7077
|
-
appointo: "appointo",
|
|
7078
|
-
appzung: "appzung",
|
|
7079
|
-
"aps-sdks-openapi-specification-aps": "aps-sdks-openapi-specification-aps",
|
|
7080
|
-
aptible: "aptible",
|
|
7081
|
-
arbiscan: "arbiscan",
|
|
7082
|
-
arcade: "arcade",
|
|
7083
|
-
"argil-ai": "argil-ai",
|
|
7084
|
-
"ark-ui": "ark-ui",
|
|
7085
|
-
arpeggi: "arpeggi",
|
|
7086
|
-
artzero: "artzero",
|
|
7087
|
-
asapp: "asapp",
|
|
7088
|
-
"asposewords-product-family": "asposewords-product-family",
|
|
7089
|
-
"ast-grep": "ast-grep",
|
|
7090
|
-
astro: "astro",
|
|
7091
|
-
"augment-code": "augment-code",
|
|
7092
|
-
autentique: "autentique",
|
|
7093
|
-
avaamo: "avaamo",
|
|
7094
|
-
avacloud: "avacloud",
|
|
7095
|
-
"avada-seo-suite": "avada-seo-suite",
|
|
7096
|
-
"avalanche-hvac-services-heating-air": "avalanche-hvac-services-heating-air",
|
|
7097
|
-
avo: "avo",
|
|
7098
|
-
awesomeapi: "awesomeapi",
|
|
7099
|
-
axiom: "axiom",
|
|
7100
|
-
axle: "axle",
|
|
7101
|
-
azumuta: "azumuta",
|
|
7102
|
-
basehub: "basehub",
|
|
7103
|
-
beacon: "beacon",
|
|
7104
|
-
"best-app-development-company": "best-app-development-company",
|
|
7105
|
-
"best-boat-lifts": "best-boat-lifts",
|
|
7106
|
-
"beta-three-professional-audio": "beta-three-professional-audio",
|
|
7107
|
-
"better-auth": "better-auth",
|
|
7108
|
-
beyondwords: "beyondwords",
|
|
7109
|
-
bika: "bika",
|
|
7110
|
-
birdie: "birdie",
|
|
7111
|
-
"bitcoin-cold-storage-tools": "bitcoin-cold-storage-tools",
|
|
7112
|
-
bito: "bito",
|
|
7113
|
-
"bits-ui": "bits-ui",
|
|
7114
|
-
bixgrow: "bixgrow",
|
|
7115
|
-
blacknet: "blacknet",
|
|
7116
|
-
"blue-media-services": "blue-media-services",
|
|
7117
|
-
blueshift: "blueshift",
|
|
7118
|
-
booqable: "booqable",
|
|
7119
|
-
bottalk: "bottalk",
|
|
7120
|
-
braintrust: "braintrust",
|
|
7121
|
-
brandfetch: "brandfetch",
|
|
7122
|
-
"bright-data": "bright-data",
|
|
7123
|
-
browsee: "browsee",
|
|
7124
|
-
bucket: "bucket",
|
|
7125
|
-
bugsplat: "bugsplat",
|
|
7126
|
-
builtwith: "builtwith",
|
|
7127
|
-
bun: "bun",
|
|
7128
|
-
bunny: "bunny",
|
|
7129
|
-
butlr: "butlr",
|
|
7130
|
-
caf: "caf",
|
|
7131
|
-
calcom: "calcom",
|
|
7132
|
-
calendarscripts: "calendarscripts",
|
|
7133
|
-
"callback-technologies": "callback-technologies",
|
|
7134
|
-
campsite: "campsite",
|
|
7135
|
-
captivaterecipes: "captivaterecipes",
|
|
7136
|
-
"car-rental-in-airports-ofgeorgia": "car-rental-in-airports-ofgeorgia",
|
|
7137
|
-
cardknox: "cardknox",
|
|
7138
|
-
carto: "carto",
|
|
7139
|
-
carv: "carv",
|
|
7140
|
-
catizen: "catizen",
|
|
7141
|
-
"cdata-software": "cdata-software",
|
|
7142
|
-
"chakra-ui": "chakra-ui",
|
|
7143
|
-
chargeblast: "chargeblast",
|
|
7144
|
-
chartbeat: "chartbeat",
|
|
7145
|
-
chatbase: "chatbase",
|
|
7146
|
-
chatknow: "chatknow",
|
|
7147
|
-
chatling: "chatling",
|
|
7148
|
-
"checkmate-live": "checkmate-live",
|
|
7149
|
-
"chic-room": "chic-room",
|
|
7150
|
-
"chirp-wireless": "chirp-wireless",
|
|
7151
|
-
"cid-contact": "cid-contact",
|
|
7152
|
-
cipherstash: "cipherstash",
|
|
7153
|
-
circleci: "circleci",
|
|
7154
|
-
citizenshipper: "citizenshipper",
|
|
7155
|
-
citrusad: "citrusad",
|
|
7156
|
-
civic: "civic",
|
|
7157
|
-
"claude-mcp-community": "claude-mcp-community",
|
|
7158
|
-
clerk: "clerk",
|
|
7159
|
-
"clever-cloud": "clever-cloud",
|
|
7160
|
-
cloreai: "cloreai",
|
|
7161
|
-
cloudfix: "cloudfix",
|
|
7162
|
-
cloudflare: "cloudflare",
|
|
7163
|
-
clouve: "clouve",
|
|
7164
|
-
cloverspace: "cloverspace",
|
|
7165
|
-
"cnpjws-api": "cnpjws-api",
|
|
7166
|
-
cobo: "cobo",
|
|
7167
|
-
cobrowse: "cobrowse",
|
|
7168
|
-
codecrafters: "codecrafters",
|
|
7169
|
-
codeium: "codeium",
|
|
7170
|
-
coefont: "coefont",
|
|
7171
|
-
coframe: "coframe",
|
|
7172
|
-
cog: "cog",
|
|
7173
|
-
cohere: "cohere",
|
|
7174
|
-
comforterp: "comforterp",
|
|
7175
|
-
comforthrm: "comforthrm",
|
|
7176
|
-
comfy: "comfy",
|
|
7177
|
-
"commerce-layer": "commerce-layer",
|
|
7178
|
-
"common-ninja": "common-ninja",
|
|
7179
|
-
"community-helm-charts": "community-helm-charts",
|
|
7180
|
-
comparisonator: "comparisonator",
|
|
7181
|
-
"concept-designs-marketing": "concept-designs-marketing",
|
|
7182
|
-
conductor: "conductor",
|
|
7183
|
-
configcat: "configcat",
|
|
7184
|
-
consentik: "consentik",
|
|
7185
|
-
contentsquare: "contentsquare",
|
|
7186
|
-
"contractor-marketing-agency": "contractor-marketing-agency",
|
|
7187
|
-
contravault: "contravault",
|
|
7188
|
-
convex: "convex",
|
|
7189
|
-
coolify: "coolify",
|
|
7190
|
-
coollabs: "coollabs",
|
|
7191
|
-
"copenhagen-art-and-photography": "copenhagen-art-and-photography",
|
|
7192
|
-
"corso-seo-online-certificato": "corso-seo-online-certificato",
|
|
7193
|
-
cosmic: "cosmic",
|
|
7194
|
-
couchdrop: "couchdrop",
|
|
7195
|
-
count: "count",
|
|
7196
|
-
courier: "courier",
|
|
7197
|
-
craftco: "craftco",
|
|
7198
|
-
"cre-data-and-location-intelligence-app": "cre-data-and-location-intelligence-app",
|
|
7199
|
-
"creative-handbook-production-resource-directory": "creative-handbook-production-resource-directory",
|
|
7200
|
-
creatopy: "creatopy",
|
|
7201
|
-
crewai: "crewai",
|
|
7202
|
-
"cross-browser-mobile-app-testing": "cross-browser-mobile-app-testing",
|
|
7203
|
-
cryptlex: "cryptlex",
|
|
7204
|
-
"curling-io": "curling-io",
|
|
7205
|
-
cursor: "cursor",
|
|
7206
|
-
"customer-service-ai-platform": "customer-service-ai-platform",
|
|
7207
|
-
"cyber-security-news": "cyber-security-news",
|
|
7208
|
-
daisyui: "daisyui",
|
|
7209
|
-
dappier: "dappier",
|
|
7210
|
-
dat1co: "dat1co",
|
|
7211
|
-
"data-surfer": "data-surfer",
|
|
7212
|
-
"databuddy-analytics": "databuddy-analytics",
|
|
7213
|
-
datacamp: "datacamp",
|
|
7214
|
-
datafold: "datafold",
|
|
7215
|
-
dataimpulse: "dataimpulse",
|
|
7216
|
-
"datastax-astra-db": "datastax-astra-db",
|
|
7217
|
-
daytona: "daytona",
|
|
7218
|
-
decocx: "decocx",
|
|
7219
|
-
deepconverse: "deepconverse",
|
|
7220
|
-
"demo-time": "demo-time",
|
|
7221
|
-
"deno-documentation": "deno-documentation",
|
|
7222
|
-
deployhq: "deployhq",
|
|
7223
|
-
designmodo: "designmodo",
|
|
7224
|
-
devhub: "devhub",
|
|
7225
|
-
devunus: "devunus",
|
|
7226
|
-
"dexpaprika-api-live-crypto-pool-data": "dexpaprika-api-live-crypto-pool-data",
|
|
7227
|
-
dns0eu: "dns0eu",
|
|
7228
|
-
docetl: "docetl",
|
|
7229
|
-
"docker-docs": "docker-docs",
|
|
7230
|
-
docspring: "docspring",
|
|
7231
|
-
"document-file-translation-powered-by-ai": "document-file-translation-powered-by-ai",
|
|
7232
|
-
donobu: "donobu",
|
|
7233
|
-
"dopp-finance": "dopp-finance",
|
|
7234
|
-
dotenvx: "dotenvx",
|
|
7235
|
-
"drizzle-orm": "drizzle-orm",
|
|
7236
|
-
dub: "dub",
|
|
7237
|
-
duckdb: "duckdb",
|
|
7238
|
-
"duende-software": "duende-software",
|
|
7239
|
-
dynamic: "dynamic",
|
|
7240
|
-
e6data: "e6data",
|
|
7241
|
-
effect: "effect",
|
|
7242
|
-
elevenlabs: "elevenlabs",
|
|
7243
|
-
elysia: "elysia",
|
|
7244
|
-
emailgic: "emailgic",
|
|
7245
|
-
"embed-notion-pages-into-your-website": "embed-notion-pages-into-your-website",
|
|
7246
|
-
embedchain: "embedchain",
|
|
7247
|
-
envoyer: "envoyer",
|
|
7248
|
-
equipment: "equipment",
|
|
7249
|
-
essio: "essio",
|
|
7250
|
-
"expo-documentation": "expo-documentation",
|
|
7251
|
-
fabric: "fabric",
|
|
7252
|
-
facets: "facets",
|
|
7253
|
-
"fantasy-sports-app-development-company": "fantasy-sports-app-development-company",
|
|
7254
|
-
"farcaster-miniapps": "farcaster-miniapps",
|
|
7255
|
-
"feedback-sync": "feedback-sync",
|
|
7256
|
-
fern: "fern",
|
|
7257
|
-
fibery: "fibery",
|
|
7258
|
-
"film-and-screenwriter-school": "film-and-screenwriter-school",
|
|
7259
|
-
finch: "finch",
|
|
7260
|
-
fireproof: "fireproof",
|
|
7261
|
-
"fireworks-ai": "fireworks-ai",
|
|
7262
|
-
firmly: "firmly",
|
|
7263
|
-
flatfile: "flatfile",
|
|
7264
|
-
flipto: "flipto",
|
|
7265
|
-
flows: "flows",
|
|
7266
|
-
flowx: "flowx",
|
|
7267
|
-
"fork-force-australia": "fork-force-australia",
|
|
7268
|
-
formo: "formo",
|
|
7269
|
-
formwerk: "formwerk",
|
|
7270
|
-
fractalpay: "fractalpay",
|
|
7271
|
-
"fraction-ai": "fraction-ai",
|
|
7272
|
-
fragbin: "fragbin",
|
|
7273
|
-
"frank-krav-maga-self-defense-bengaluru": "frank-krav-maga-self-defense-bengaluru",
|
|
7274
|
-
"free-ai-image-generator-maker": "free-ai-image-generator-maker",
|
|
7275
|
-
frigade: "frigade",
|
|
7276
|
-
"front-matter-cms-a-cms-in-your-vs-code-editor": "front-matter-cms-a-cms-in-your-vs-code-editor",
|
|
7277
|
-
"funny-stories-of-horrible-stories": "funny-stories-of-horrible-stories",
|
|
7278
|
-
galileo: "galileo",
|
|
7279
|
-
"game-development-hub": "game-development-hub",
|
|
7280
|
-
gaminator: "gaminator",
|
|
7281
|
-
"gaslighting-check": "gaslighting-check",
|
|
7282
|
-
genaiscript: "genaiscript",
|
|
7283
|
-
"generate-ai-ugc-videos-for-ads": "generate-ai-ugc-videos-for-ads",
|
|
7284
|
-
getinbox: "getinbox",
|
|
7285
|
-
getmarked: "getmarked",
|
|
7286
|
-
giselle: "giselle",
|
|
7287
|
-
glama: "glama",
|
|
7288
|
-
gloodai: "gloodai",
|
|
7289
|
-
glucncom: "glucncom",
|
|
7290
|
-
"gnosis-chain": "gnosis-chain",
|
|
7291
|
-
goody: "goody",
|
|
7292
|
-
gradio: "gradio",
|
|
7293
|
-
"graphite-note": "graphite-note",
|
|
7294
|
-
"greece-vacation-search": "greece-vacation-search",
|
|
7295
|
-
"green-apple-travel-tourism": "green-apple-travel-tourism",
|
|
7296
|
-
groqcloud: "groqcloud",
|
|
7297
|
-
gumlet: "gumlet",
|
|
7298
|
-
helicone: "helicone",
|
|
7299
|
-
"help-for-erectile-dysfunction": "help-for-erectile-dysfunction",
|
|
7300
|
-
"henan-pengfei-pvp-k30-povidone": "henan-pengfei-pvp-k30-povidone",
|
|
7301
|
-
herd: "herd",
|
|
7302
|
-
"heritage-collection": "heritage-collection",
|
|
7303
|
-
heyflow: "heyflow",
|
|
7304
|
-
hola: "hola",
|
|
7305
|
-
home: "home",
|
|
7306
|
-
"home-llms-txt": "home-llms-txt",
|
|
7307
|
-
"home-tz": "home-tz",
|
|
7308
|
-
"home-angular": "home-angular",
|
|
7309
|
-
hono: "hono",
|
|
7310
|
-
hub88: "hub88",
|
|
7311
|
-
hubspot: "hubspot",
|
|
7312
|
-
"hugging-face-accelerate": "hugging-face-accelerate",
|
|
7313
|
-
"hugging-face-diffusers": "hugging-face-diffusers",
|
|
7314
|
-
"hugging-face-hub": "hugging-face-hub",
|
|
7315
|
-
"hugging-face-hub-python-library": "hugging-face-hub-python-library",
|
|
7316
|
-
"hugging-face-transformers": "hugging-face-transformers",
|
|
7317
|
-
"humanity-protocol": "humanity-protocol",
|
|
7318
|
-
hybridai: "hybridai",
|
|
7319
|
-
hyperbeam: "hyperbeam",
|
|
7320
|
-
hyperline: "hyperline",
|
|
7321
|
-
hypermode: "hypermode",
|
|
7322
|
-
hypertune: "hypertune",
|
|
7323
|
-
i3dnet: "i3dnet",
|
|
7324
|
-
"iagent-protocol": "iagent-protocol",
|
|
7325
|
-
icepanel: "icepanel",
|
|
7326
|
-
id21: "id21",
|
|
7327
|
-
ideogram: "ideogram",
|
|
7328
|
-
"ig-exporter": "ig-exporter",
|
|
7329
|
-
illuvium: "illuvium",
|
|
7330
|
-
imaginstudio: "imaginstudio",
|
|
7331
|
-
imagineart: "imagineart",
|
|
7332
|
-
"img-arena": "img-arena",
|
|
7333
|
-
"immortal-rising-2": "immortal-rising-2",
|
|
7334
|
-
infera: "infera",
|
|
7335
|
-
infisical: "infisical",
|
|
7336
|
-
inkeep: "inkeep",
|
|
7337
|
-
inngest: "inngest",
|
|
7338
|
-
inspector: "inspector",
|
|
7339
|
-
"inspira-ui-build-beautiful-websites-using-vue-nuxt": "inspira-ui-build-beautiful-websites-using-vue-nuxt",
|
|
7340
|
-
instant: "instant",
|
|
7341
|
-
instruqt: "instruqt",
|
|
7342
|
-
intelligems: "intelligems",
|
|
7343
|
-
intract: "intract",
|
|
7344
|
-
intuned: "intuned",
|
|
7345
|
-
ionos: "ionos",
|
|
7346
|
-
ionq: "ionq",
|
|
7347
|
-
ipaper: "ipaper",
|
|
7348
|
-
iproyalcom: "iproyalcom",
|
|
7349
|
-
irev: "irev",
|
|
7350
|
-
"island-router": "island-router",
|
|
7351
|
-
jam: "jam",
|
|
7352
|
-
jazztools: "jazztools",
|
|
7353
|
-
journeyapps: "journeyapps",
|
|
7354
|
-
journify: "journify",
|
|
7355
|
-
jsfiddle: "jsfiddle",
|
|
7356
|
-
jumptask: "jumptask",
|
|
7357
|
-
"juniper-creates": "juniper-creates",
|
|
7358
|
-
juno: "juno",
|
|
7359
|
-
"kaisar-network": "kaisar-network",
|
|
7360
|
-
"karrier-one": "karrier-one",
|
|
7361
|
-
keeper: "keeper",
|
|
7362
|
-
ketch: "ketch",
|
|
7363
|
-
kick: "kick",
|
|
7364
|
-
koala: "koala",
|
|
7365
|
-
kruzty: "kruzty",
|
|
7366
|
-
lacremeai: "lacremeai",
|
|
7367
|
-
lago: "lago",
|
|
7368
|
-
lambdatest: "lambdatest",
|
|
7369
|
-
"langchain-javascript-docs": "langchain-javascript-docs",
|
|
7370
|
-
"langchain-python-docs": "langchain-python-docs",
|
|
7371
|
-
langflow: "langflow",
|
|
7372
|
-
langfuse: "langfuse",
|
|
7373
|
-
"langgraph-javascript-docs": "langgraph-javascript-docs",
|
|
7374
|
-
"langgraph-python-docs": "langgraph-python-docs",
|
|
7375
|
-
launchfast: "launchfast",
|
|
7376
|
-
lavita: "lavita",
|
|
7377
|
-
"law-firm-digital-marketing-agency": "law-firm-digital-marketing-agency",
|
|
7378
|
-
layouthub: "layouthub",
|
|
7379
|
-
"leather-jackets-coats-for-men-women": "leather-jackets-coats-for-men-women",
|
|
7380
|
-
legend: "legend",
|
|
7381
|
-
"legend-state": "legend-state",
|
|
7382
|
-
"legends-of-learning": "legends-of-learning",
|
|
7383
|
-
legitt: "legitt",
|
|
7384
|
-
lettermint: "lettermint",
|
|
7385
|
-
"liam-erd": "liam-erd",
|
|
7386
|
-
liblab: "liblab",
|
|
7387
|
-
libmodulor: "libmodulor",
|
|
7388
|
-
likec4: "likec4",
|
|
7389
|
-
linktree: "linktree",
|
|
7390
|
-
litdb: "litdb",
|
|
7391
|
-
liveblocks: "liveblocks",
|
|
7392
|
-
livecaller: "livecaller",
|
|
7393
|
-
livecodes: "livecodes",
|
|
7394
|
-
livespotting: "livespotting",
|
|
7395
|
-
"llms-txtio": "llms-txtio",
|
|
7396
|
-
llmstxt: "llmstxt",
|
|
7397
|
-
llmvo: "llmvo",
|
|
7398
|
-
"lm-studio": "lm-studio",
|
|
7399
|
-
lobehub: "lobehub",
|
|
7400
|
-
loglayer: "loglayer",
|
|
7401
|
-
loops: "loops",
|
|
7402
|
-
"lots-of-csvs": "lots-of-csvs",
|
|
7403
|
-
lottielab: "lottielab",
|
|
7404
|
-
lunacy: "lunacy",
|
|
7405
|
-
luxalgo: "luxalgo",
|
|
7406
|
-
luxid: "luxid",
|
|
7407
|
-
lynx: "lynx",
|
|
7408
|
-
mailmodo: "mailmodo",
|
|
7409
|
-
mako: "mako",
|
|
7410
|
-
mangopay: "mangopay",
|
|
7411
|
-
"manifestly-checklists": "manifestly-checklists",
|
|
7412
|
-
"marco-ronco-seo-specialist": "marco-ronco-seo-specialist",
|
|
7413
|
-
marimo: "marimo",
|
|
7414
|
-
"marketing-doctors": "marketing-doctors",
|
|
7415
|
-
"marketing-integration-and-automation": "marketing-integration-and-automation",
|
|
7416
|
-
massive: "massive",
|
|
7417
|
-
mastory: "mastory",
|
|
7418
|
-
mastra: "mastra",
|
|
7419
|
-
"material-ui-aka-mui": "material-ui-aka-mui",
|
|
7420
|
-
"maxim-ai": "maxim-ai",
|
|
7421
|
-
"mdutil-free-markdown-tools": "mdutil-free-markdown-tools",
|
|
7422
|
-
mealbymeal: "mealbymeal",
|
|
7423
|
-
"meds-canada": "meds-canada",
|
|
7424
|
-
medusa: "medusa",
|
|
7425
|
-
meilisearch: "meilisearch",
|
|
7426
|
-
"mekalite-cnc-machining-services": "mekalite-cnc-machining-services",
|
|
7427
|
-
meshconnect: "meshconnect",
|
|
7428
|
-
"method-financial": "method-financial",
|
|
7429
|
-
micro1: "micro1",
|
|
7430
|
-
mintlify: "mintlify",
|
|
7431
|
-
mixo: "mixo",
|
|
7432
|
-
"model-context-protocol-mcp": "model-context-protocol-mcp",
|
|
7433
|
-
"monster-ui": "monster-ui",
|
|
7434
|
-
moondream: "moondream",
|
|
7435
|
-
"morphic-solutions": "morphic-solutions",
|
|
7436
|
-
movehealth: "movehealth",
|
|
7437
|
-
"mubashir-hassan": "mubashir-hassan",
|
|
7438
|
-
"mui-x-advanced-react-components-for-complex-use-cases": "mui-x-advanced-react-components-for-complex-use-cases",
|
|
7439
|
-
multiplier: "multiplier",
|
|
7440
|
-
multisynq: "multisynq",
|
|
7441
|
-
mux: "mux",
|
|
7442
|
-
"mystery-o-matic": "mystery-o-matic",
|
|
7443
|
-
nash: "nash",
|
|
7444
|
-
nativescript: "nativescript",
|
|
7445
|
-
navi: "navi",
|
|
7446
|
-
"naviga-global": "naviga-global",
|
|
7447
|
-
"needle-cloud": "needle-cloud",
|
|
7448
|
-
netlify: "netlify",
|
|
7449
|
-
nextevo: "nextevo",
|
|
7450
|
-
nextevogroup: "nextevogroup",
|
|
7451
|
-
"nile-postgres": "nile-postgres",
|
|
7452
|
-
nomadhelperai: "nomadhelperai",
|
|
7453
|
-
"nonprofit-management-consulting": "nonprofit-management-consulting",
|
|
7454
|
-
"novi-labs": "novi-labs",
|
|
7455
|
-
nsoftware: "nsoftware",
|
|
7456
|
-
nuxt: "nuxt",
|
|
7457
|
-
"omnimind-docs-oss-mcp-client": "omnimind-docs-oss-mcp-client",
|
|
7458
|
-
onagentsorg: "onagentsorg",
|
|
7459
|
-
"once-ui": "once-ui",
|
|
7460
|
-
onetrust: "onetrust",
|
|
7461
|
-
openfort: "openfort",
|
|
7462
|
-
openphone: "openphone",
|
|
7463
|
-
openpipe: "openpipe",
|
|
7464
|
-
openrouter: "openrouter",
|
|
7465
|
-
"openvpn-zero-trust-vpn": "openvpn-zero-trust-vpn",
|
|
7466
|
-
"opik-by-comet": "opik-by-comet",
|
|
7467
|
-
"optimajet-form-builder": "optimajet-form-builder",
|
|
7468
|
-
oxla: "oxla",
|
|
7469
|
-
papergraderpro: "papergraderpro",
|
|
7470
|
-
paragon: "paragon",
|
|
7471
|
-
"parcelcube-static-dimensioning-systems": "parcelcube-static-dimensioning-systems",
|
|
7472
|
-
parseable: "parseable",
|
|
7473
|
-
pastaclean: "pastaclean",
|
|
7474
|
-
payperfax: "payperfax",
|
|
7475
|
-
payrollrabbit: "payrollrabbit",
|
|
7476
|
-
"pentesting-red-teaming-company": "pentesting-red-teaming-company",
|
|
7477
|
-
perplexity: "perplexity",
|
|
7478
|
-
"personal-page": "personal-page",
|
|
7479
|
-
"petite-box": "petite-box",
|
|
7480
|
-
pgflow: "pgflow",
|
|
7481
|
-
phare: "phare",
|
|
7482
|
-
pikaicons: "pikaicons",
|
|
7483
|
-
pinata: "pinata",
|
|
7484
|
-
pinecone: "pinecone",
|
|
7485
|
-
plain: "plain",
|
|
7486
|
-
"plan-harmony-travel-planning": "plan-harmony-travel-planning",
|
|
7487
|
-
platformsh: "platformsh",
|
|
7488
|
-
playai: "playai",
|
|
7489
|
-
popsmash: "popsmash",
|
|
7490
|
-
postfast: "postfast",
|
|
7491
|
-
preact: "preact",
|
|
7492
|
-
prettier: "prettier",
|
|
7493
|
-
primev: "primev",
|
|
7494
|
-
prisma: "prisma",
|
|
7495
|
-
profound: "profound",
|
|
7496
|
-
progressrocks: "progressrocks",
|
|
7497
|
-
"proguard-pest-control": "proguard-pest-control",
|
|
7498
|
-
projectdiscovery: "projectdiscovery",
|
|
7499
|
-
"prompt-kit": "prompt-kit",
|
|
7500
|
-
promptfoo: "promptfoo",
|
|
7501
|
-
pydantic: "pydantic",
|
|
7502
|
-
pydanticai: "pydanticai",
|
|
7503
|
-
qrcoau: "qrcoau",
|
|
7504
|
-
quill: "quill",
|
|
7505
|
-
qwikrank: "qwikrank",
|
|
7506
|
-
rainbowkit: "rainbowkit",
|
|
7507
|
-
raincamp: "raincamp",
|
|
7508
|
-
rankscaleai: "rankscaleai",
|
|
7509
|
-
rapidtextai: "rapidtextai",
|
|
7510
|
-
raycast: "raycast",
|
|
7511
|
-
rcponline: "rcponline",
|
|
7512
|
-
redpanda: "redpanda",
|
|
7513
|
-
rememberizer: "rememberizer",
|
|
7514
|
-
remotion: "remotion",
|
|
7515
|
-
remult: "remult",
|
|
7516
|
-
render: "render",
|
|
7517
|
-
reown: "reown",
|
|
7518
|
-
replit: "replit",
|
|
7519
|
-
resend: "resend",
|
|
7520
|
-
respondio: "respondio",
|
|
7521
|
-
retainful: "retainful",
|
|
7522
|
-
"ri-xu-online": "ri-xu-online",
|
|
7523
|
-
"rims-tires-for-cars-and-trucks": "rims-tires-for-cars-and-trucks",
|
|
7524
|
-
roc: "roc",
|
|
7525
|
-
rsbuild: "rsbuild",
|
|
7526
|
-
rsdoctor: "rsdoctor",
|
|
7527
|
-
rslib: "rslib",
|
|
7528
|
-
rspack: "rspack",
|
|
7529
|
-
rubric: "rubric",
|
|
7530
|
-
"ruleta-aleatoria-online-gratis": "ruleta-aleatoria-online-gratis",
|
|
7531
|
-
rushdb: "rushdb",
|
|
7532
|
-
saev: "saev",
|
|
7533
|
-
salesbricks: "salesbricks",
|
|
7534
|
-
"salesforce-marketing-cloud-consultants": "salesforce-marketing-cloud-consultants",
|
|
7535
|
-
"samsung-food": "samsung-food",
|
|
7536
|
-
sandisk: "sandisk",
|
|
7537
|
-
sardine: "sardine",
|
|
7538
|
-
"scottish-art-prints-by-carol-mcewan": "scottish-art-prints-by-carol-mcewan",
|
|
7539
|
-
"scraping-proxies": "scraping-proxies",
|
|
7540
|
-
screenshotone: "screenshotone",
|
|
7541
|
-
sealos: "sealos",
|
|
7542
|
-
"secure-fast-online-money-transfers": "secure-fast-online-money-transfers",
|
|
7543
|
-
sekhlopk: "sekhlopk",
|
|
7544
|
-
self: "self",
|
|
7545
|
-
sellersprite: "sellersprite",
|
|
7546
|
-
semgrep: "semgrep",
|
|
7547
|
-
seo2llm: "seo2llm",
|
|
7548
|
-
servicestack: "servicestack",
|
|
7549
|
-
sgnlai: "sgnlai",
|
|
7550
|
-
sherlock: "sherlock",
|
|
7551
|
-
"shop-positioner-llc": "shop-positioner-llc",
|
|
7552
|
-
"side-space": "side-space",
|
|
7553
|
-
simplepdf: "simplepdf",
|
|
7554
|
-
sinch: "sinch",
|
|
7555
|
-
"singing-carrots": "singing-carrots",
|
|
7556
|
-
sitespeakai: "sitespeakai",
|
|
7557
|
-
skipgo: "skipgo",
|
|
7558
|
-
"sky-follower-bridge": "sky-follower-bridge",
|
|
7559
|
-
skydeckai: "skydeckai",
|
|
7560
|
-
"skyworkthe-ai-workspace-agents": "skyworkthe-ai-workspace-agents",
|
|
7561
|
-
smartcar: "smartcar",
|
|
7562
|
-
social: "social",
|
|
7563
|
-
socialityio: "socialityio",
|
|
7564
|
-
solid: "solid",
|
|
7565
|
-
sourcegraph: "sourcegraph",
|
|
7566
|
-
spacetimedb: "spacetimedb",
|
|
7567
|
-
speakeasy: "speakeasy",
|
|
7568
|
-
starwind: "starwind",
|
|
7569
|
-
statusfield: "statusfield",
|
|
7570
|
-
stedi: "stedi",
|
|
7571
|
-
"stephanie-kabi": "stephanie-kabi",
|
|
7572
|
-
"stock-trading-investment-app": "stock-trading-investment-app",
|
|
7573
|
-
stripe: "stripe",
|
|
7574
|
-
"study-fetch": "study-fetch",
|
|
7575
|
-
"sunra-ai": "sunra-ai",
|
|
7576
|
-
supabase: "supabase",
|
|
7577
|
-
supadata: "supadata",
|
|
7578
|
-
superwall: "superwall",
|
|
7579
|
-
svelte: "svelte",
|
|
7580
|
-
"svg-viewer": "svg-viewer",
|
|
7581
|
-
"swipe-simple-invoicing-and-payments-app": "swipe-simple-invoicing-and-payments-app",
|
|
7582
|
-
tamagui: "tamagui",
|
|
7583
|
-
"taskade-ai": "taskade-ai",
|
|
7584
|
-
tavus: "tavus",
|
|
7585
|
-
"tlassistance-snior": "tlassistance-snior",
|
|
7586
|
-
televisionai: "televisionai",
|
|
7587
|
-
tensorzero: "tensorzero",
|
|
7588
|
-
"the-ai-engineers-handbook": "the-ai-engineers-handbook",
|
|
7589
|
-
"the-bucket-hat": "the-bucket-hat",
|
|
7590
|
-
"the-crawl-tool": "the-crawl-tool",
|
|
7591
|
-
"the-data-driven-marketer": "the-data-driven-marketer",
|
|
7592
|
-
"the-dinner-detective-murder-mystery-show": "the-dinner-detective-murder-mystery-show",
|
|
7593
|
-
theirstack: "theirstack",
|
|
7594
|
-
"therapydave-dave-lechnyr-lcsw": "therapydave-dave-lechnyr-lcsw",
|
|
7595
|
-
tidb: "tidb",
|
|
7596
|
-
tidio: "tidio",
|
|
7597
|
-
tinybird: "tinybird",
|
|
7598
|
-
tiptap: "tiptap",
|
|
7599
|
-
toriut: "toriut",
|
|
7600
|
-
trackingplan: "trackingplan",
|
|
7601
|
-
trackvia: "trackvia",
|
|
7602
|
-
"trail-of-bits": "trail-of-bits",
|
|
7603
|
-
transloadit: "transloadit",
|
|
7604
|
-
"travel-nepal": "travel-nepal",
|
|
7605
|
-
triggerdev: "triggerdev",
|
|
7606
|
-
triplit: "triplit",
|
|
7607
|
-
trueprofit: "trueprofit",
|
|
7608
|
-
truffle: "truffle",
|
|
7609
|
-
turbo: "turbo",
|
|
7610
|
-
turbodocx: "turbodocx",
|
|
7611
|
-
turso: "turso",
|
|
7612
|
-
"twicpics-by-frontify": "twicpics-by-frontify",
|
|
7613
|
-
twoshoes: "twoshoes",
|
|
7614
|
-
"ufc-velvet": "ufc-velvet",
|
|
7615
|
-
"uminai-mcp": "uminai-mcp",
|
|
7616
|
-
underrunio: "underrunio",
|
|
7617
|
-
unifygtm: "unifygtm",
|
|
7618
|
-
unistyles: "unistyles",
|
|
7619
|
-
uniwebview: "uniwebview",
|
|
7620
|
-
unkey: "unkey",
|
|
7621
|
-
unstructured: "unstructured",
|
|
7622
|
-
upstash: "upstash",
|
|
7623
|
-
"upstreet-ai": "upstreet-ai",
|
|
7624
|
-
upsun: "upsun",
|
|
7625
|
-
useapinet: "useapinet",
|
|
7626
|
-
"utrecht-golf-instructor-marina-romanik": "utrecht-golf-instructor-marina-romanik",
|
|
7627
|
-
"ux-patterns-for-devs": "ux-patterns-for-devs",
|
|
7628
|
-
vald: "vald",
|
|
7629
|
-
"vald-health": "vald-health",
|
|
7630
|
-
vapi: "vapi",
|
|
7631
|
-
vdoninja: "vdoninja",
|
|
7632
|
-
velt: "velt",
|
|
7633
|
-
vendure: "vendure",
|
|
7634
|
-
veniceai: "veniceai",
|
|
7635
|
-
ventrata: "ventrata",
|
|
7636
|
-
"vercel-ai-sdk": "vercel-ai-sdk",
|
|
7637
|
-
verdn: "verdn",
|
|
7638
|
-
"video-and-audio-frameworks-for-net": "video-and-audio-frameworks-for-net",
|
|
7639
|
-
videosdklive: "videosdklive",
|
|
7640
|
-
videowise: "videowise",
|
|
7641
|
-
viem: "viem",
|
|
7642
|
-
"vignette-id": "vignette-id",
|
|
7643
|
-
vital: "vital",
|
|
7644
|
-
"voxel-busters": "voxel-busters",
|
|
7645
|
-
"voyager-shuffle": "voyager-shuffle",
|
|
7646
|
-
vplayed: "vplayed",
|
|
7647
|
-
"vue-macros": "vue-macros",
|
|
7648
|
-
vuejs: "vuejs",
|
|
7649
|
-
wandio: "wandio",
|
|
7650
|
-
warp: "warp",
|
|
7651
|
-
weathercom: "weathercom",
|
|
7652
|
-
"web-design-company-qatar": "web-design-company-qatar",
|
|
7653
|
-
"web-development-wordpress-maintenance": "web-development-wordpress-maintenance",
|
|
7654
|
-
webrecorder: "webrecorder",
|
|
7655
|
-
"wedgwood-insurance": "wedgwood-insurance",
|
|
7656
|
-
weka: "weka",
|
|
7657
|
-
"welcome-to-bunny": "welcome-to-bunny",
|
|
7658
|
-
"welcome-to-htmlhint": "welcome-to-htmlhint",
|
|
7659
|
-
"wf-content-creator-platform": "wf-content-creator-platform",
|
|
7660
|
-
whereby: "whereby",
|
|
7661
|
-
"wild-in-africa": "wild-in-africa",
|
|
7662
|
-
wized: "wized",
|
|
7663
|
-
wonderchat: "wonderchat",
|
|
7664
|
-
woowup: "woowup",
|
|
7665
|
-
wordlift: "wordlift",
|
|
7666
|
-
workbookly: "workbookly",
|
|
7667
|
-
workflow: "workflow",
|
|
7668
|
-
"wot-design-uni": "wot-design-uni",
|
|
7669
|
-
writer: "writer",
|
|
7670
|
-
wxt: "wxt",
|
|
7671
|
-
x: "x",
|
|
7672
|
-
"x-cmd": "x-cmd",
|
|
7673
|
-
xmcp: "xmcp",
|
|
7674
|
-
xomatic: "xomatic",
|
|
7675
|
-
yamlresume: "yamlresume",
|
|
7676
|
-
youform: "youform",
|
|
7677
|
-
zag: "zag",
|
|
7678
|
-
zapts: "zapts",
|
|
7679
|
-
"zaphyr-php-framework": "zaphyr-php-framework",
|
|
7680
|
-
zapier: "zapier",
|
|
7681
|
-
zeffy: "zeffy",
|
|
7682
|
-
zenml: "zenml",
|
|
7683
|
-
zep: "zep",
|
|
7684
|
-
zigpoll: "zigpoll",
|
|
7685
|
-
zipchat: "zipchat",
|
|
7686
|
-
zipy: "zipy",
|
|
7687
|
-
zodori: "zodori",
|
|
7688
|
-
zoko: "zoko",
|
|
7689
|
-
"zoomryconveyorshiploader-manufacturer": "zoomryconveyorshiploader-manufacturer"
|
|
7095
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
7096
|
+
import { join as join7 } from "path";
|
|
7097
|
+
function normalize(name) {
|
|
7098
|
+
return name.toLowerCase().replace(/[-_./]/g, "");
|
|
7099
|
+
}
|
|
7100
|
+
function extractTokens(dep) {
|
|
7101
|
+
const tokens = [];
|
|
7102
|
+
const unscoped = dep.startsWith("@") ? dep.slice(1) : dep;
|
|
7103
|
+
tokens.push(unscoped);
|
|
7104
|
+
if (dep.startsWith("@") && unscoped.includes("/")) {
|
|
7105
|
+
const [scope, pkg] = unscoped.split("/");
|
|
7106
|
+
tokens.push(pkg);
|
|
7107
|
+
tokens.push(scope);
|
|
7108
|
+
const cleanScope = scope.replace(/js$/, "").replace(/-ai$/, "");
|
|
7109
|
+
if (cleanScope !== scope) tokens.push(cleanScope);
|
|
7690
7110
|
}
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7111
|
+
for (const suffix of ["-js", "-sdk", "-client", "-core", "-cli", "-types"]) {
|
|
7112
|
+
if (dep.endsWith(suffix)) {
|
|
7113
|
+
tokens.push(dep.slice(0, -suffix.length));
|
|
7114
|
+
}
|
|
7115
|
+
}
|
|
7116
|
+
return tokens;
|
|
7117
|
+
}
|
|
7118
|
+
function matchesEntry(dep, entry) {
|
|
7119
|
+
const tokens = extractTokens(dep);
|
|
7120
|
+
const entrySlug = entry.slug.toLowerCase();
|
|
7121
|
+
const entryName = normalize(entry.name);
|
|
7122
|
+
for (const token of tokens) {
|
|
7123
|
+
const norm = normalize(token);
|
|
7124
|
+
if (norm === entrySlug) return true;
|
|
7125
|
+
if (norm === entryName) return true;
|
|
7126
|
+
if (entrySlug === norm) return true;
|
|
7127
|
+
if (entryName.startsWith(norm) && norm.length >= 3) return true;
|
|
7128
|
+
}
|
|
7129
|
+
return false;
|
|
7130
|
+
}
|
|
7694
7131
|
function detectFromPackageJson(projectDir) {
|
|
7695
|
-
const pkgPath =
|
|
7696
|
-
if (!
|
|
7132
|
+
const pkgPath = join7(projectDir, "package.json");
|
|
7133
|
+
if (!existsSync6(pkgPath)) return [];
|
|
7697
7134
|
let pkg;
|
|
7698
7135
|
try {
|
|
7699
|
-
pkg = JSON.parse(
|
|
7136
|
+
pkg = JSON.parse(readFileSync6(pkgPath, "utf-8"));
|
|
7700
7137
|
} catch {
|
|
7701
7138
|
return [];
|
|
7702
7139
|
}
|
|
7703
|
-
const
|
|
7140
|
+
const depNames = Object.keys({
|
|
7704
7141
|
...pkg.dependencies,
|
|
7705
7142
|
...pkg.devDependencies
|
|
7706
|
-
};
|
|
7707
|
-
|
|
7143
|
+
});
|
|
7144
|
+
if (depNames.length === 0) return [];
|
|
7145
|
+
const entries2 = getAllEntries();
|
|
7708
7146
|
const matchesBySlug = /* @__PURE__ */ new Map();
|
|
7709
|
-
for (const
|
|
7710
|
-
const
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
results.push({ slug, matchedPackages, registryEntry });
|
|
7147
|
+
for (const dep of depNames) {
|
|
7148
|
+
for (const entry of entries2) {
|
|
7149
|
+
if (matchesEntry(dep, entry)) {
|
|
7150
|
+
const existing = matchesBySlug.get(entry.slug);
|
|
7151
|
+
if (existing) {
|
|
7152
|
+
existing.deps.push(dep);
|
|
7153
|
+
} else {
|
|
7154
|
+
matchesBySlug.set(entry.slug, { deps: [dep], entry });
|
|
7155
|
+
}
|
|
7156
|
+
break;
|
|
7157
|
+
}
|
|
7721
7158
|
}
|
|
7722
7159
|
}
|
|
7723
|
-
return
|
|
7160
|
+
return [...matchesBySlug.values()].map(({ deps, entry }) => ({
|
|
7161
|
+
slug: entry.slug,
|
|
7162
|
+
matchedPackages: deps,
|
|
7163
|
+
registryEntry: entry
|
|
7164
|
+
}));
|
|
7724
7165
|
}
|
|
7725
7166
|
function filterMatchesByCategories(matches, categories) {
|
|
7726
7167
|
if (categories.length === 0) return matches;
|
|
@@ -7832,12 +7273,12 @@ async function fetchLlmsTxt({ url, existingEtag }) {
|
|
|
7832
7273
|
if (contentLength && Number.parseInt(contentLength, 10) > MAX_SIZE) {
|
|
7833
7274
|
throw new Error(`Response too large (${contentLength} bytes, max ${MAX_SIZE})`);
|
|
7834
7275
|
}
|
|
7835
|
-
const
|
|
7836
|
-
if (
|
|
7837
|
-
throw new Error(`Response too large (${
|
|
7276
|
+
const text2 = await response.text();
|
|
7277
|
+
if (text2.length > MAX_SIZE) {
|
|
7278
|
+
throw new Error(`Response too large (${text2.length} bytes, max ${MAX_SIZE})`);
|
|
7838
7279
|
}
|
|
7839
7280
|
return {
|
|
7840
|
-
content:
|
|
7281
|
+
content: text2,
|
|
7841
7282
|
etag: response.headers.get("etag"),
|
|
7842
7283
|
lastModified: response.headers.get("last-modified"),
|
|
7843
7284
|
notModified: false
|
|
@@ -7849,7 +7290,7 @@ async function fetchLlmsTxt({ url, existingEtag }) {
|
|
|
7849
7290
|
|
|
7850
7291
|
// src/lib/telemetry.ts
|
|
7851
7292
|
var TELEMETRY_ENDPOINT = "https://llmstxt.directory/api/cli/telemetry";
|
|
7852
|
-
var CLI_VERSION = "0.
|
|
7293
|
+
var CLI_VERSION = "0.3.0";
|
|
7853
7294
|
var CI_ENV_VARS = ["CI", "GITHUB_ACTIONS", "GITLAB_CI", "CIRCLECI", "TRAVIS"];
|
|
7854
7295
|
function isDisabled() {
|
|
7855
7296
|
return process.env.DO_NOT_TRACK === "1" || process.env.LLMSTXT_TELEMETRY_DISABLED === "1";
|
|
@@ -7876,27 +7317,13 @@ function track(params) {
|
|
|
7876
7317
|
async function init(options) {
|
|
7877
7318
|
const projectDir = process.cwd();
|
|
7878
7319
|
const isInteractive = process.stdin.isTTY && !options.yes;
|
|
7879
|
-
printBanner("0.
|
|
7320
|
+
printBanner("0.3.0");
|
|
7880
7321
|
p3.intro("Install llms.txt documentation for your project");
|
|
7881
7322
|
const spin = spinner2("Loading registry...");
|
|
7882
7323
|
spin.start();
|
|
7883
7324
|
await loadRegistry();
|
|
7884
7325
|
spin.succeed("Registry loaded");
|
|
7885
7326
|
const agents2 = detectInstalledAgents();
|
|
7886
|
-
if (agents2.length > 0) {
|
|
7887
|
-
p3.log.info(`Detected agents: ${agents2.map((a) => pc4.cyan(a.displayName)).join(", ")}`);
|
|
7888
|
-
} else {
|
|
7889
|
-
p3.log.warn("No AI coding tools detected \u2014 files will be installed to .agents/skills/ only");
|
|
7890
|
-
}
|
|
7891
|
-
const spin2 = spinner2("Detecting project dependencies...");
|
|
7892
|
-
spin2.start();
|
|
7893
|
-
let matches = detectFromPackageJson(projectDir);
|
|
7894
|
-
if (matches.length === 0) {
|
|
7895
|
-
spin2.info("No matching llms.txt entries found for your dependencies");
|
|
7896
|
-
p3.log.message(pc4.dim("Try `llmstxt search <query>` to find entries manually"));
|
|
7897
|
-
p3.outro("No skills to install.");
|
|
7898
|
-
return;
|
|
7899
|
-
}
|
|
7900
7327
|
let activeCategories;
|
|
7901
7328
|
if (options.allCategories) {
|
|
7902
7329
|
activeCategories = [];
|
|
@@ -7905,95 +7332,223 @@ async function init(options) {
|
|
|
7905
7332
|
} else {
|
|
7906
7333
|
activeCategories = [...PRIMARY_CATEGORIES];
|
|
7907
7334
|
}
|
|
7335
|
+
let depMatches = detectFromPackageJson(projectDir);
|
|
7908
7336
|
if (activeCategories.length > 0) {
|
|
7909
|
-
|
|
7337
|
+
depMatches = filterMatchesByCategories(depMatches, activeCategories);
|
|
7338
|
+
}
|
|
7339
|
+
const depSlugs = new Set(depMatches.map((m) => m.slug));
|
|
7340
|
+
if (depMatches.length > 0) {
|
|
7341
|
+
p3.log.info(
|
|
7342
|
+
`Found ${depMatches.length} matching your dependencies: ${depMatches.map((m) => pc4.cyan(m.registryEntry.name)).join(", ")}`
|
|
7343
|
+
);
|
|
7910
7344
|
}
|
|
7911
|
-
if (
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7345
|
+
if (!isInteractive) {
|
|
7346
|
+
return installEntries({
|
|
7347
|
+
projectDir,
|
|
7348
|
+
entries: depMatches.map((m) => m.registryEntry),
|
|
7349
|
+
options,
|
|
7350
|
+
agents: agents2,
|
|
7351
|
+
targetAgents: agents2
|
|
7352
|
+
});
|
|
7353
|
+
}
|
|
7354
|
+
const selectedEntries = await browseAndSelect({ projectDir, depMatches, depSlugs });
|
|
7355
|
+
if (selectedEntries.length === 0) {
|
|
7356
|
+
p3.outro("No skills selected.");
|
|
7915
7357
|
return;
|
|
7916
7358
|
}
|
|
7917
|
-
|
|
7918
|
-
if (
|
|
7919
|
-
|
|
7920
|
-
const already = isInstalled({ projectDir, slug: match.slug });
|
|
7921
|
-
const status = already ? pc4.dim(" (already installed)") : "";
|
|
7922
|
-
p3.log.message(` ${pc4.cyan(match.registryEntry.name)}${status}`);
|
|
7923
|
-
}
|
|
7924
|
-
p3.outro("Dry run \u2014 no files were written");
|
|
7359
|
+
const targetAgents = await pickAgents(projectDir);
|
|
7360
|
+
if (!targetAgents) {
|
|
7361
|
+
p3.cancel("Installation cancelled.");
|
|
7925
7362
|
return;
|
|
7926
7363
|
}
|
|
7927
|
-
|
|
7928
|
-
if (
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
}
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
const
|
|
7948
|
-
message: "
|
|
7949
|
-
options:
|
|
7950
|
-
|
|
7951
|
-
|
|
7364
|
+
const format = await pickFormat(selectedEntries, options);
|
|
7365
|
+
if (!format) {
|
|
7366
|
+
p3.cancel("Installation cancelled.");
|
|
7367
|
+
return;
|
|
7368
|
+
}
|
|
7369
|
+
return installEntries({
|
|
7370
|
+
projectDir,
|
|
7371
|
+
entries: selectedEntries,
|
|
7372
|
+
options: { ...options, full: format === "llms-full.txt" },
|
|
7373
|
+
agents: agents2,
|
|
7374
|
+
targetAgents
|
|
7375
|
+
});
|
|
7376
|
+
}
|
|
7377
|
+
async function browseAndSelect({
|
|
7378
|
+
projectDir,
|
|
7379
|
+
depMatches,
|
|
7380
|
+
depSlugs
|
|
7381
|
+
}) {
|
|
7382
|
+
const selectedEntries = [];
|
|
7383
|
+
while (true) {
|
|
7384
|
+
const action = await p3.select({
|
|
7385
|
+
message: selectedEntries.length === 0 ? "How would you like to find llms.txt documentation?" : `${selectedEntries.length} selected. Add more or install?`,
|
|
7386
|
+
options: [
|
|
7387
|
+
...depMatches.length > 0 && selectedEntries.length === 0 ? [
|
|
7388
|
+
{
|
|
7389
|
+
value: "suggestions",
|
|
7390
|
+
label: `Suggested from dependencies (${depMatches.length} found)`,
|
|
7391
|
+
hint: depMatches.map((m) => m.registryEntry.name).join(", ")
|
|
7392
|
+
}
|
|
7393
|
+
] : [],
|
|
7394
|
+
{ value: "browse", label: "Browse by category" },
|
|
7395
|
+
{ value: "search", label: "Search by name" },
|
|
7396
|
+
...selectedEntries.length > 0 ? [{ value: "install", label: `Install ${selectedEntries.length} selected` }] : [],
|
|
7397
|
+
{ value: "done", label: selectedEntries.length > 0 ? "Cancel" : "Exit" }
|
|
7398
|
+
]
|
|
7952
7399
|
});
|
|
7953
|
-
if (p3.isCancel(
|
|
7954
|
-
p3.cancel("Installation cancelled.");
|
|
7955
|
-
|
|
7956
|
-
return;
|
|
7400
|
+
if (p3.isCancel(action) || action === "done") {
|
|
7401
|
+
if (selectedEntries.length > 0) p3.cancel("Installation cancelled.");
|
|
7402
|
+
else p3.outro("No skills selected.");
|
|
7403
|
+
return [];
|
|
7957
7404
|
}
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7405
|
+
if (action === "install") break;
|
|
7406
|
+
let picked = [];
|
|
7407
|
+
if (action === "suggestions") {
|
|
7408
|
+
picked = await pickFromList(
|
|
7409
|
+
depMatches.map((m) => m.registryEntry),
|
|
7410
|
+
projectDir,
|
|
7411
|
+
depSlugs
|
|
7412
|
+
);
|
|
7413
|
+
} else if (action === "browse") {
|
|
7414
|
+
picked = await browseByCategory(projectDir, depSlugs);
|
|
7415
|
+
} else if (action === "search") {
|
|
7416
|
+
picked = await searchByName(projectDir, depSlugs);
|
|
7962
7417
|
}
|
|
7963
|
-
const
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
p3.cancel("Installation cancelled.");
|
|
7968
|
-
process.exitCode = 0;
|
|
7969
|
-
return;
|
|
7418
|
+
for (const entry of picked) {
|
|
7419
|
+
if (!selectedEntries.some((e) => e.slug === entry.slug)) {
|
|
7420
|
+
selectedEntries.push(entry);
|
|
7421
|
+
}
|
|
7970
7422
|
}
|
|
7971
|
-
}
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7423
|
+
}
|
|
7424
|
+
return selectedEntries;
|
|
7425
|
+
}
|
|
7426
|
+
async function browseByCategory(projectDir, depSlugs) {
|
|
7427
|
+
const allEntries = getAllEntries();
|
|
7428
|
+
const categoryMap = /* @__PURE__ */ new Map();
|
|
7429
|
+
for (const entry of allEntries) {
|
|
7430
|
+
categoryMap.set(entry.category, (categoryMap.get(entry.category) || 0) + 1);
|
|
7431
|
+
}
|
|
7432
|
+
const categoryChoice = await p3.select({
|
|
7433
|
+
message: "Select a category:",
|
|
7434
|
+
options: [...categoryMap.entries()].sort((a, b) => b[1] - a[1]).map(([cat, count]) => ({
|
|
7435
|
+
value: cat,
|
|
7436
|
+
label: cat,
|
|
7437
|
+
hint: `${count} entries`
|
|
7438
|
+
}))
|
|
7439
|
+
});
|
|
7440
|
+
if (p3.isCancel(categoryChoice)) return [];
|
|
7441
|
+
const categoryEntries = allEntries.filter((e) => e.category === categoryChoice);
|
|
7442
|
+
return pickFromList(categoryEntries, projectDir, depSlugs);
|
|
7443
|
+
}
|
|
7444
|
+
async function searchByName(projectDir, depSlugs) {
|
|
7445
|
+
const query = await p3.text({
|
|
7446
|
+
message: "Search for:",
|
|
7447
|
+
placeholder: "e.g. react, stripe, prisma..."
|
|
7448
|
+
});
|
|
7449
|
+
if (p3.isCancel(query) || !query) return [];
|
|
7450
|
+
const results = searchRegistry(query).slice(0, 20);
|
|
7451
|
+
if (results.length === 0) {
|
|
7452
|
+
p3.log.warn(`No results for "${query}"`);
|
|
7453
|
+
return [];
|
|
7454
|
+
}
|
|
7455
|
+
return pickFromList(results, projectDir, depSlugs);
|
|
7456
|
+
}
|
|
7457
|
+
async function pickFromList(entries2, projectDir, depSlugs) {
|
|
7458
|
+
const optionsList = entries2.map((entry) => {
|
|
7459
|
+
const already = isInstalled({ projectDir, slug: entry.slug });
|
|
7460
|
+
const isDep = depSlugs.has(entry.slug);
|
|
7461
|
+
const hints = [];
|
|
7462
|
+
if (already) hints.push("installed");
|
|
7463
|
+
if (isDep) hints.push("in your deps");
|
|
7464
|
+
hints.push(entry.category);
|
|
7465
|
+
return {
|
|
7466
|
+
value: entry.slug,
|
|
7467
|
+
label: entry.name,
|
|
7468
|
+
hint: hints.join(" \xB7 ")
|
|
7469
|
+
};
|
|
7470
|
+
});
|
|
7471
|
+
const selected = await p3.multiselect({
|
|
7472
|
+
message: `Select entries (${entries2.length} available):`,
|
|
7473
|
+
options: optionsList,
|
|
7474
|
+
required: false
|
|
7475
|
+
});
|
|
7476
|
+
if (p3.isCancel(selected)) return [];
|
|
7477
|
+
const slugSet = new Set(selected);
|
|
7478
|
+
return entries2.filter((e) => slugSet.has(e.slug));
|
|
7479
|
+
}
|
|
7480
|
+
async function pickFormat(entries2, options) {
|
|
7481
|
+
if (options.full) return "llms-full.txt";
|
|
7482
|
+
const hasFullAvailable = entries2.some((e) => e.llmsFullTxtUrl);
|
|
7483
|
+
if (!hasFullAvailable) return "llms.txt";
|
|
7484
|
+
const fullCount = entries2.filter((e) => e.llmsFullTxtUrl).length;
|
|
7485
|
+
const choice = await p3.select({
|
|
7486
|
+
message: "Which documentation format?",
|
|
7487
|
+
options: [
|
|
7488
|
+
{
|
|
7489
|
+
value: "llms.txt",
|
|
7490
|
+
label: "llms.txt",
|
|
7491
|
+
hint: "concise \u2014 smaller, faster to load"
|
|
7492
|
+
},
|
|
7493
|
+
{
|
|
7494
|
+
value: "llms-full.txt",
|
|
7495
|
+
label: "llms-full.txt",
|
|
7496
|
+
hint: `comprehensive \u2014 ${fullCount}/${entries2.length} selected have full version`
|
|
7497
|
+
}
|
|
7498
|
+
]
|
|
7499
|
+
});
|
|
7500
|
+
if (p3.isCancel(choice)) return null;
|
|
7501
|
+
return choice;
|
|
7502
|
+
}
|
|
7503
|
+
async function pickAgents(projectDir) {
|
|
7504
|
+
const savedPrefs = loadSavedAgentPrefs(projectDir);
|
|
7505
|
+
const initialValues = getInitialAgents({ allAgents: agents, savedPrefs, projectDir });
|
|
7506
|
+
const selected = await p3.multiselect({
|
|
7507
|
+
message: "Which agents should receive the skills?",
|
|
7508
|
+
options: agents.map((a) => ({
|
|
7509
|
+
value: a.name,
|
|
7510
|
+
label: a.displayName,
|
|
7511
|
+
hint: a.isUniversal ? "always included" : a.skillsDir
|
|
7512
|
+
})),
|
|
7513
|
+
initialValues,
|
|
7514
|
+
required: true
|
|
7515
|
+
});
|
|
7516
|
+
if (p3.isCancel(selected)) return null;
|
|
7517
|
+
const finalNames = ensureUniversalAgents({ selected, allAgents: agents });
|
|
7518
|
+
saveAgentPrefs(projectDir, selected);
|
|
7519
|
+
const nameSet = new Set(finalNames);
|
|
7520
|
+
return agents.filter((a) => nameSet.has(a.name));
|
|
7521
|
+
}
|
|
7522
|
+
async function installEntries({
|
|
7523
|
+
projectDir,
|
|
7524
|
+
entries: entries2,
|
|
7525
|
+
options,
|
|
7526
|
+
agents: agents2,
|
|
7527
|
+
targetAgents
|
|
7528
|
+
}) {
|
|
7529
|
+
if (options.dryRun) {
|
|
7530
|
+
for (const entry of entries2) {
|
|
7531
|
+
const already = isInstalled({ projectDir, slug: entry.slug });
|
|
7532
|
+
const status = already ? pc4.dim(" (already installed)") : "";
|
|
7533
|
+
p3.log.message(` ${pc4.cyan(entry.name)}${status}`);
|
|
7977
7534
|
}
|
|
7535
|
+
p3.outro("Dry run \u2014 no files were written");
|
|
7536
|
+
return;
|
|
7978
7537
|
}
|
|
7979
7538
|
const format = options.full ? "llms-full.txt" : "llms.txt";
|
|
7980
7539
|
let installed = 0;
|
|
7981
7540
|
let skipped = 0;
|
|
7982
7541
|
let failed = 0;
|
|
7983
7542
|
const installedSlugs = [];
|
|
7984
|
-
for (const
|
|
7985
|
-
if (!selectedSlugs.has(match.slug)) {
|
|
7986
|
-
continue;
|
|
7987
|
-
}
|
|
7988
|
-
const entry = match.registryEntry;
|
|
7543
|
+
for (const entry of entries2) {
|
|
7989
7544
|
const actualFormat = format === "llms-full.txt" && entry.llmsFullTxtUrl ? "llms-full.txt" : "llms.txt";
|
|
7990
7545
|
const url = actualFormat === "llms-full.txt" ? entry.llmsFullTxtUrl : entry.llmsTxtUrl;
|
|
7991
|
-
if (isInstalled({ projectDir, slug:
|
|
7546
|
+
if (isInstalled({ projectDir, slug: entry.slug })) {
|
|
7992
7547
|
skipped++;
|
|
7993
7548
|
continue;
|
|
7994
7549
|
}
|
|
7995
|
-
const
|
|
7996
|
-
|
|
7550
|
+
const spin = spinner2(`Fetching ${entry.name}...`);
|
|
7551
|
+
spin.start();
|
|
7997
7552
|
try {
|
|
7998
7553
|
const result = await fetchLlmsTxt({ url });
|
|
7999
7554
|
const {
|
|
@@ -8002,15 +7557,16 @@ async function init(options) {
|
|
|
8002
7557
|
agents: installedTo
|
|
8003
7558
|
} = installToAgents({
|
|
8004
7559
|
projectDir,
|
|
8005
|
-
slug:
|
|
7560
|
+
slug: entry.slug,
|
|
8006
7561
|
entry,
|
|
8007
7562
|
content: result.content,
|
|
8008
|
-
format: actualFormat
|
|
7563
|
+
format: actualFormat,
|
|
7564
|
+
targetAgents
|
|
8009
7565
|
});
|
|
8010
7566
|
addEntry({
|
|
8011
7567
|
projectDir,
|
|
8012
7568
|
entry: {
|
|
8013
|
-
slug:
|
|
7569
|
+
slug: entry.slug,
|
|
8014
7570
|
format: actualFormat,
|
|
8015
7571
|
sourceUrl: url,
|
|
8016
7572
|
etag: result.etag,
|
|
@@ -8021,12 +7577,12 @@ async function init(options) {
|
|
|
8021
7577
|
name: entry.name
|
|
8022
7578
|
}
|
|
8023
7579
|
});
|
|
8024
|
-
|
|
7580
|
+
spin.succeed(`${entry.name} ${pc4.dim(`\u2192 ${installedTo.join(", ")}`)}`);
|
|
8025
7581
|
installed++;
|
|
8026
|
-
installedSlugs.push(
|
|
7582
|
+
installedSlugs.push(entry.slug);
|
|
8027
7583
|
} catch (err) {
|
|
8028
7584
|
const msg = err instanceof Error ? err.message : String(err);
|
|
8029
|
-
|
|
7585
|
+
spin.fail(`${entry.name}: ${msg}`);
|
|
8030
7586
|
failed++;
|
|
8031
7587
|
}
|
|
8032
7588
|
}
|
|
@@ -8038,7 +7594,7 @@ async function init(options) {
|
|
|
8038
7594
|
p3.note(summaryLines.join("\n"), "Summary");
|
|
8039
7595
|
}
|
|
8040
7596
|
if (addToGitignore(projectDir)) {
|
|
8041
|
-
p3.log.success("Added
|
|
7597
|
+
p3.log.success("Added skill directories to .gitignore");
|
|
8042
7598
|
}
|
|
8043
7599
|
if (installed > 0) {
|
|
8044
7600
|
syncClaudeMd(projectDir);
|
|
@@ -8068,8 +7624,34 @@ async function install({ names, options }) {
|
|
|
8068
7624
|
await loadRegistry();
|
|
8069
7625
|
spin.succeed("Registry loaded");
|
|
8070
7626
|
const agents2 = detectInstalledAgents();
|
|
8071
|
-
|
|
8072
|
-
|
|
7627
|
+
let targetAgents;
|
|
7628
|
+
if (!process.stdin.isTTY) {
|
|
7629
|
+
targetAgents = agents2;
|
|
7630
|
+
if (agents2.length > 0) {
|
|
7631
|
+
const display = agents2.map((a) => a.displayName).join(", ");
|
|
7632
|
+
p4.log.message(pc5.dim(`Installing to: ${display}`));
|
|
7633
|
+
}
|
|
7634
|
+
} else {
|
|
7635
|
+
const savedPrefs = loadSavedAgentPrefs(projectDir);
|
|
7636
|
+
const initialValues = getInitialAgents({ allAgents: agents, savedPrefs, projectDir });
|
|
7637
|
+
const selected = await p4.multiselect({
|
|
7638
|
+
message: "Which agents should receive the skills?",
|
|
7639
|
+
options: agents.map((a) => ({
|
|
7640
|
+
value: a.name,
|
|
7641
|
+
label: a.displayName,
|
|
7642
|
+
hint: a.isUniversal ? "always included" : a.skillsDir
|
|
7643
|
+
})),
|
|
7644
|
+
initialValues,
|
|
7645
|
+
required: true
|
|
7646
|
+
});
|
|
7647
|
+
if (p4.isCancel(selected)) {
|
|
7648
|
+
p4.cancel("Installation cancelled.");
|
|
7649
|
+
return;
|
|
7650
|
+
}
|
|
7651
|
+
const finalNames = ensureUniversalAgents({ selected, allAgents: agents });
|
|
7652
|
+
saveAgentPrefs(projectDir, selected);
|
|
7653
|
+
const nameSet = new Set(finalNames);
|
|
7654
|
+
targetAgents = agents.filter((a) => nameSet.has(a.name));
|
|
8073
7655
|
}
|
|
8074
7656
|
let installed = 0;
|
|
8075
7657
|
let failed = 0;
|
|
@@ -8122,7 +7704,14 @@ async function install({ names, options }) {
|
|
|
8122
7704
|
checksum,
|
|
8123
7705
|
size,
|
|
8124
7706
|
agents: installedTo
|
|
8125
|
-
} = installToAgents({
|
|
7707
|
+
} = installToAgents({
|
|
7708
|
+
projectDir,
|
|
7709
|
+
slug: entry.slug,
|
|
7710
|
+
entry,
|
|
7711
|
+
content: result.content,
|
|
7712
|
+
format,
|
|
7713
|
+
targetAgents
|
|
7714
|
+
});
|
|
8126
7715
|
addEntry({
|
|
8127
7716
|
projectDir,
|
|
8128
7717
|
entry: {
|
|
@@ -8378,8 +7967,8 @@ async function update(name, options) {
|
|
|
8378
7967
|
|
|
8379
7968
|
// src/index.ts
|
|
8380
7969
|
var program = new Command();
|
|
8381
|
-
program.name("llmstxt").description("Install llms.txt files from the llms-txt-hub registry into your AI coding tools").version("0.
|
|
8382
|
-
printBanner("0.
|
|
7970
|
+
program.name("llmstxt").description("Install llms.txt files from the llms-txt-hub registry into your AI coding tools").version("0.3.0").action(() => {
|
|
7971
|
+
printBanner("0.3.0");
|
|
8383
7972
|
program.outputHelp();
|
|
8384
7973
|
});
|
|
8385
7974
|
program.command("init").description("Auto-detect dependencies and install matching llms.txt files").option("--category <categories>", "Filter by categories (comma-separated)").option("--all-categories", "Include all categories").option("--dry-run", "Preview without installing").option("--full", "Prefer llms-full.txt when available").option("-y, --yes", "Skip confirmation prompts").action(init);
|