tokrepo 3.3.0 → 3.3.1
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/bin/tokrepo.js +55 -23
- package/package.json +1 -1
package/bin/tokrepo.js
CHANGED
|
@@ -517,7 +517,7 @@ async function cmdPush() {
|
|
|
517
517
|
// Flags override config
|
|
518
518
|
title = args.flags.title || title || guessTitle(filesToPush, baseDir);
|
|
519
519
|
description = args.flags.desc || description || '';
|
|
520
|
-
visibility = args.flags.public ? 1 : (args.flags.private ? 0 : (projectConfig?.visibility ??
|
|
520
|
+
visibility = args.flags.public ? 1 : (args.flags.private ? 0 : (projectConfig?.visibility ?? 0));
|
|
521
521
|
tags = args.flags.tags || tags || [];
|
|
522
522
|
|
|
523
523
|
// Read files and detect types
|
|
@@ -553,8 +553,8 @@ async function cmdPush() {
|
|
|
553
553
|
// Show summary
|
|
554
554
|
log(`\n${C.bold}tokrepo push${C.reset}\n`);
|
|
555
555
|
log(` ${C.bold}Title:${C.reset} ${title}`);
|
|
556
|
-
log(` ${C.bold}Visibility:${C.reset} ${visibility === 1 ? `${C.green}public${C.reset}` : `${C.yellow}private${C.reset}`}`);
|
|
557
|
-
log(` ${C.bold}Files:${C.reset} ${pushFiles.length}`);
|
|
556
|
+
log(` ${C.bold}Visibility:${C.reset} ${visibility === 1 ? `${C.green}public${C.reset} (visible to everyone)` : `${C.yellow}private${C.reset} (only you can see)`}`);
|
|
557
|
+
log(` ${C.bold}Files:${C.reset} ${pushFiles.length} (only these files will be uploaded)`);
|
|
558
558
|
if (detectedTags.size > 0) {
|
|
559
559
|
log(` ${C.bold}Tags:${C.reset} ${Array.from(detectedTags).join(', ')}`);
|
|
560
560
|
}
|
|
@@ -614,7 +614,7 @@ async function cmdInit() {
|
|
|
614
614
|
title: title || dirName,
|
|
615
615
|
description: description || '',
|
|
616
616
|
files: ['*.md', '*.sh', '*.py', '*.js', '*.mjs', '*.ts', '*.json', '*.yaml'],
|
|
617
|
-
visibility:
|
|
617
|
+
visibility: 0,
|
|
618
618
|
tags: [],
|
|
619
619
|
};
|
|
620
620
|
|
|
@@ -663,6 +663,11 @@ async function cmdPull() {
|
|
|
663
663
|
}
|
|
664
664
|
}
|
|
665
665
|
|
|
666
|
+
// Normalize query: replace hyphens/underscores/dots with spaces for better matching
|
|
667
|
+
function normalizeQuery(q) {
|
|
668
|
+
return q.replace(/[-_.]/g, ' ').replace(/\s+/g, ' ').trim();
|
|
669
|
+
}
|
|
670
|
+
|
|
666
671
|
// Resolve various input formats to a UUID:
|
|
667
672
|
// - UUID directly: "ca000374-f5d8-..."
|
|
668
673
|
// - Full URL: "https://tokrepo.com/en/workflows/ca000374-f5d8-..."
|
|
@@ -680,9 +685,10 @@ async function resolveAssetId(input, config, apiBase) {
|
|
|
680
685
|
const atMatch = input.match(/^@([^/]+)\/(.+)$/);
|
|
681
686
|
if (atMatch) {
|
|
682
687
|
const [, username, assetName] = atMatch;
|
|
683
|
-
|
|
688
|
+
const normalizedName = normalizeQuery(assetName);
|
|
689
|
+
info(`Searching for "${normalizedName}" by @${username}...`);
|
|
684
690
|
// Search by keyword, then filter by author nickname
|
|
685
|
-
const encoded = encodeURIComponent(
|
|
691
|
+
const encoded = encodeURIComponent(normalizedName);
|
|
686
692
|
try {
|
|
687
693
|
const data = await apiRequest('GET', `/api/v1/tokenboard/workflows/list?keyword=${encoded}&page=1&page_size=20&sort_by=views`, null, config?.token, apiBase);
|
|
688
694
|
const items = data.list || data.items || [];
|
|
@@ -700,9 +706,10 @@ async function resolveAssetId(input, config, apiBase) {
|
|
|
700
706
|
error(`Asset not found: ${input}`);
|
|
701
707
|
}
|
|
702
708
|
|
|
703
|
-
// Plain name: search by keyword
|
|
704
|
-
|
|
705
|
-
|
|
709
|
+
// Plain name: search by keyword (normalize separators)
|
|
710
|
+
const normalizedInput = normalizeQuery(input);
|
|
711
|
+
info(`Searching for "${normalizedInput}"...`);
|
|
712
|
+
const encoded = encodeURIComponent(normalizedInput);
|
|
706
713
|
try {
|
|
707
714
|
const data = await apiRequest('GET', `/api/v1/tokenboard/workflows/list?keyword=${encoded}&page=1&page_size=5&sort_by=views`, null, config?.token, apiBase);
|
|
708
715
|
const items = data.list || data.items || [];
|
|
@@ -714,10 +721,12 @@ async function resolveAssetId(input, config, apiBase) {
|
|
|
714
721
|
// ─── Search ───
|
|
715
722
|
|
|
716
723
|
async function cmdSearch() {
|
|
717
|
-
const
|
|
718
|
-
if (!
|
|
724
|
+
const rawQuery = process.argv.slice(3).join(' ');
|
|
725
|
+
if (!rawQuery) error('Usage: tokrepo search <keyword>');
|
|
719
726
|
|
|
720
|
-
|
|
727
|
+
const query = normalizeQuery(rawQuery);
|
|
728
|
+
const displayQuery = query !== rawQuery ? `"${rawQuery}" → "${query}"` : `"${query}"`;
|
|
729
|
+
log(`\n${C.bold}tokrepo search${C.reset} ${displayQuery}\n`);
|
|
721
730
|
|
|
722
731
|
const config = readConfig();
|
|
723
732
|
const apiBase = config?.api || DEFAULT_API;
|
|
@@ -728,7 +737,14 @@ async function cmdSearch() {
|
|
|
728
737
|
|
|
729
738
|
if (!data.list || data.list.length === 0) {
|
|
730
739
|
info('No assets found.');
|
|
731
|
-
|
|
740
|
+
// Suggest broader search terms
|
|
741
|
+
const words = query.split(' ');
|
|
742
|
+
if (words.length > 1) {
|
|
743
|
+
log(`\n ${C.dim}Try fewer keywords:${C.reset}`);
|
|
744
|
+
log(` ${C.cyan}tokrepo search ${words[0]}${C.reset}`);
|
|
745
|
+
log(` ${C.cyan}tokrepo search ${words.slice(0, 2).join(' ')}${C.reset}`);
|
|
746
|
+
}
|
|
747
|
+
log(`\n ${C.dim}Browse all: https://tokrepo.com/en/featured${C.reset}\n`);
|
|
732
748
|
return;
|
|
733
749
|
}
|
|
734
750
|
|
|
@@ -739,8 +755,13 @@ async function cmdSearch() {
|
|
|
739
755
|
const tags = (wf.tags || []).map(t => t.name).join(', ');
|
|
740
756
|
const views = wf.view_count || 0;
|
|
741
757
|
const votes = wf.vote_count || 0;
|
|
758
|
+
// Truncate long descriptions for readability
|
|
759
|
+
const desc = (wf.description || '').length > 80
|
|
760
|
+
? wf.description.substring(0, 77) + '...'
|
|
761
|
+
: (wf.description || '');
|
|
742
762
|
|
|
743
763
|
log(` ${C.dim}${String(i + 1).padStart(2)}.${C.reset} ${C.bold}${wf.title}${C.reset}`);
|
|
764
|
+
if (desc) log(` ${desc}`);
|
|
744
765
|
if (tags) log(` ${C.cyan}${tags}${C.reset} ${C.dim}★${votes} 👁${views}${C.reset}`);
|
|
745
766
|
log(` ${C.dim}tokrepo install ${wf.uuid}${C.reset}`);
|
|
746
767
|
log('');
|
|
@@ -778,18 +799,23 @@ Examples:
|
|
|
778
799
|
}
|
|
779
800
|
// UUID format check
|
|
780
801
|
else if (!/^[a-f0-9-]{36}$/.test(target)) {
|
|
781
|
-
// Search by name
|
|
782
|
-
|
|
802
|
+
// Search by name (normalize separators for better matching)
|
|
803
|
+
const normalizedTarget = normalizeQuery(target);
|
|
804
|
+
info(`Searching for "${normalizedTarget}"...`);
|
|
783
805
|
try {
|
|
784
|
-
const encoded = encodeURIComponent(
|
|
806
|
+
const encoded = encodeURIComponent(normalizedTarget);
|
|
785
807
|
const searchData = await apiRequest('GET', `/api/v1/tokenboard/workflows/list?keyword=${encoded}&page=1&page_size=5&sort_by=views`, null, config?.token, apiBase);
|
|
786
808
|
|
|
787
809
|
if (!searchData.list || searchData.list.length === 0) {
|
|
788
810
|
error(`No asset found matching "${target}". Try: tokrepo search ${target}`);
|
|
789
811
|
}
|
|
790
812
|
|
|
791
|
-
// If
|
|
792
|
-
const
|
|
813
|
+
// If title contains all query words, prefer it
|
|
814
|
+
const queryWords = normalizedTarget.toLowerCase().split(' ');
|
|
815
|
+
const exact = searchData.list.find(w => {
|
|
816
|
+
const title = w.title.toLowerCase();
|
|
817
|
+
return queryWords.every(word => title.includes(word));
|
|
818
|
+
});
|
|
793
819
|
const chosen = exact || searchData.list[0];
|
|
794
820
|
|
|
795
821
|
uuid = chosen.uuid;
|
|
@@ -1241,10 +1267,14 @@ function showHelp() {
|
|
|
1241
1267
|
log(`
|
|
1242
1268
|
${C.bold}tokrepo${C.reset} — AI assets for humans and agents. Like GitHub, for AI experience.
|
|
1243
1269
|
|
|
1270
|
+
${C.dim}You control what gets pushed. Each push uploads only the files you specify.
|
|
1271
|
+
Nothing is shared without your explicit action. Private by default.${C.reset}
|
|
1272
|
+
|
|
1244
1273
|
${C.bold}QUICK START${C.reset}
|
|
1245
1274
|
${C.cyan}tokrepo search cursor rules${C.reset} # find assets
|
|
1246
1275
|
${C.cyan}tokrepo install awesome-cursor-rules${C.reset} # install to your project
|
|
1247
|
-
${C.cyan}tokrepo push --
|
|
1276
|
+
${C.cyan}tokrepo push --private my-skill.md${C.reset} # save privately (only you can see)
|
|
1277
|
+
${C.cyan}tokrepo push --public my-skill.md${C.reset} # share publicly
|
|
1248
1278
|
|
|
1249
1279
|
${C.bold}USAGE${C.reset}
|
|
1250
1280
|
tokrepo <command> [args] [options]
|
|
@@ -1270,8 +1300,8 @@ ${C.bold}ACCOUNT${C.reset}
|
|
|
1270
1300
|
${C.cyan}help${C.reset} Show this help
|
|
1271
1301
|
|
|
1272
1302
|
${C.bold}PUSH OPTIONS${C.reset}
|
|
1273
|
-
${C.cyan}--
|
|
1274
|
-
${C.cyan}--
|
|
1303
|
+
${C.cyan}--private${C.reset} Keep asset private — only you can see it (recommended for personal assets)
|
|
1304
|
+
${C.cyan}--public${C.reset} Share asset publicly with the community
|
|
1275
1305
|
${C.cyan}--title${C.reset} "..." Set title (auto-detected from README or dir name)
|
|
1276
1306
|
${C.cyan}--desc${C.reset} "..." Set description
|
|
1277
1307
|
${C.cyan}--tag${C.reset} Skills Add tag (repeatable)
|
|
@@ -1286,8 +1316,10 @@ ${C.bold}INSTALL BEHAVIOR${C.reset}
|
|
|
1286
1316
|
${C.bold}EXAMPLES${C.reset}
|
|
1287
1317
|
tokrepo search "mcp server" # Find MCP configs
|
|
1288
1318
|
tokrepo install ca000374-f5d8-... # Install by UUID
|
|
1289
|
-
tokrepo push --
|
|
1290
|
-
tokrepo push --public
|
|
1319
|
+
tokrepo push --private my-rules.md # Save one file privately
|
|
1320
|
+
tokrepo push --public skill.md # Share one file publicly
|
|
1321
|
+
tokrepo push --private . # Push current dir as private
|
|
1322
|
+
tokrepo push --public --title "My MCP" . # Push dir publicly with title
|
|
1291
1323
|
|
|
1292
1324
|
${C.bold}FILE TYPE AUTO-DETECTION${C.reset}
|
|
1293
1325
|
.sh .py .js .ts .mjs .go .rs → script
|