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.
Files changed (2) hide show
  1. package/bin/tokrepo.js +55 -23
  2. 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 ?? 1));
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: 1,
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
- info(`Searching for "${assetName}" by @${username}...`);
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(assetName);
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
- info(`Searching for "${input}"...`);
705
- const encoded = encodeURIComponent(input);
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 query = process.argv.slice(3).join(' ');
718
- if (!query) error('Usage: tokrepo search <keyword>');
724
+ const rawQuery = process.argv.slice(3).join(' ');
725
+ if (!rawQuery) error('Usage: tokrepo search <keyword>');
719
726
 
720
- log(`\n${C.bold}tokrepo search${C.reset} "${query}"\n`);
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
- log(`\n ${C.dim}Try different keywords or browse: https://tokrepo.com/en/featured${C.reset}\n`);
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
- info(`Searching for "${target}"...`);
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(target);
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 exact title match, use it directly
792
- const exact = searchData.list.find(w => w.title.toLowerCase().includes(target.toLowerCase()));
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 --public .${C.reset} # share your own assets
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}--public${C.reset} Make asset publicly visible (default)
1274
- ${C.cyan}--private${C.reset} Make asset private
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 --public . # Push current directory
1290
- tokrepo push --public --title "My MCP" . # Push with custom title
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokrepo",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "description": "AI assets for humans and agents — search, install, push. Like GitHub, for AI experience.",
5
5
  "bin": {
6
6
  "tokrepo": "bin/tokrepo.js"