allagents 1.11.1-next.1 → 1.11.2-next.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/dist/index.js +145 -22
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -34731,7 +34731,7 @@ function buildSearchQueries(query, owner) {
34731
34731
  const userClause = owner ? `user:${owner}` : "";
34732
34732
  const join26 = (...parts) => parts.filter(Boolean).join(" ");
34733
34733
  const queries = [
34734
- { priority: 1, label: "path", q: join26("filename:SKILL.md", `in:path ${pathTerm}`, userClause) }
34734
+ { priority: 1, label: "path", q: join26("filename:SKILL.md", `path:${pathTerm}`, userClause) }
34735
34735
  ];
34736
34736
  if (pathTerm !== trimmed2) {
34737
34737
  queries.push({ priority: 2, label: "hyphen", q: join26("filename:SKILL.md", pathTerm, userClause) });
@@ -34778,7 +34778,7 @@ function parseSkillPath(path, repoFallback) {
34778
34778
  const skillsIdx = parts.lastIndexOf("skills");
34779
34779
  if (skillsIdx !== -1) {
34780
34780
  const afterSkills = parts.slice(skillsIdx + 1);
34781
- const meaningful = afterSkills[afterSkills.length - 1] === "SKILL.md" ? afterSkills.slice(0, -1) : afterSkills;
34781
+ const meaningful = afterSkills[afterSkills.length - 1]?.toLowerCase() === "skill.md" ? afterSkills.slice(0, -1) : afterSkills;
34782
34782
  if (meaningful.length >= 2) {
34783
34783
  const namespace = meaningful[0] ?? "";
34784
34784
  const name = meaningful[1] ?? "";
@@ -34786,11 +34786,14 @@ function parseSkillPath(path, repoFallback) {
34786
34786
  return { namespace, name };
34787
34787
  }
34788
34788
  if (meaningful.length === 1 && meaningful[0]) {
34789
- return { namespace: "", name: meaningful[0] };
34789
+ const nsFromPlugin = skillsIdx >= 2 && parts[skillsIdx - 2] === "plugins" ? parts[skillsIdx - 1] ?? "" : "";
34790
+ return { namespace: nsFromPlugin, name: meaningful[0] };
34790
34791
  }
34791
34792
  }
34792
- if (parts.length >= 2) {
34793
- const parent = parts[parts.length - 2];
34793
+ const lastPart = parts[parts.length - 1]?.toLowerCase() ?? "";
34794
+ const fileIdx = lastPart.endsWith(".md") ? parts.length - 2 : parts.length - 1;
34795
+ if (fileIdx >= 0) {
34796
+ const parent = parts[fileIdx];
34794
34797
  if (parent)
34795
34798
  return { namespace: "", name: parent };
34796
34799
  }
@@ -34828,7 +34831,8 @@ async function runOneQuery(q3, page, limit, token, fetchFn) {
34828
34831
  repo,
34829
34832
  path,
34830
34833
  description: item.repository?.description ?? "",
34831
- sha: item.sha ?? ""
34834
+ sha: item.sha ?? "",
34835
+ stars: item.repository?.stargazers_count ?? 0
34832
34836
  };
34833
34837
  });
34834
34838
  return {
@@ -34843,7 +34847,7 @@ async function searchSkills(query, options2 = {}, deps = {}) {
34843
34847
  const logger = deps.logger ?? ((msg) => process.stderr.write(`${msg}
34844
34848
  `));
34845
34849
  const page = options2.page ?? 1;
34846
- const limit = options2.limit ?? 30;
34850
+ const limit = options2.limit ?? 15;
34847
34851
  const token = await (deps.tokenResolver ?? resolveGhToken)();
34848
34852
  const queries = buildSearchQueries(query, options2.owner);
34849
34853
  const settled = await Promise.allSettled(queries.map((entry) => runOneQuery(entry.q, page, limit, token, fetchFn)));
@@ -34868,11 +34872,18 @@ async function searchSkills(query, options2 = {}, deps = {}) {
34868
34872
  buckets.sort((a, b) => a.priority - b.priority);
34869
34873
  const mergedItems = buckets.flatMap((b) => b.result.items);
34870
34874
  const deduped = dedupeItems(mergedItems);
34875
+ const visible = deduped.filter((item) => {
34876
+ const firstSegment = item.path.split("/")[0] ?? "";
34877
+ return !firstSegment.startsWith(".");
34878
+ });
34879
+ await fetchStarsForItems(visible, token, fetchFn);
34880
+ visible.sort((a, b) => b.stars - a.stars);
34881
+ const finalItems = visible.slice(0, limit);
34871
34882
  return {
34872
34883
  query,
34873
- items: deduped,
34874
- total: deduped.length,
34875
- truncated: buckets.some((b) => b.result.truncated)
34884
+ items: finalItems,
34885
+ total: finalItems.length,
34886
+ truncated: buckets.some((b) => b.result.truncated) || visible.length > limit
34876
34887
  };
34877
34888
  }
34878
34889
  function dedupeItems(items) {
@@ -34887,6 +34898,31 @@ function dedupeItems(items) {
34887
34898
  }
34888
34899
  return out;
34889
34900
  }
34901
+ async function fetchStarsForItems(items, token, fetchFn) {
34902
+ const uniqueRepos = [...new Set(items.map((i2) => i2.repo))];
34903
+ const headers = {
34904
+ Accept: "application/vnd.github+json",
34905
+ "X-GitHub-Api-Version": "2022-11-28",
34906
+ "User-Agent": "allagents-cli"
34907
+ };
34908
+ if (token)
34909
+ headers.Authorization = `token ${token}`;
34910
+ const starsMap = new Map;
34911
+ await Promise.allSettled(uniqueRepos.map(async (repo) => {
34912
+ try {
34913
+ const res = await fetchFn(`https://api.github.com/repos/${repo}`, { headers });
34914
+ if (!res.ok)
34915
+ return;
34916
+ const body = await res.json();
34917
+ starsMap.set(repo, body.stargazers_count ?? 0);
34918
+ } catch {}
34919
+ }));
34920
+ for (const item of items) {
34921
+ const s = starsMap.get(item.repo);
34922
+ if (s !== undefined)
34923
+ item.stars = s;
34924
+ }
34925
+ }
34890
34926
  var OWNER_REGEX, COULD_BE_OWNER_REGEX, SkillSearchError;
34891
34927
  var init_skill_search = __esm(() => {
34892
34928
  OWNER_REGEX = /^[A-Za-z0-9-]{1,39}$/;
@@ -41871,7 +41907,7 @@ var package_default;
41871
41907
  var init_package = __esm(() => {
41872
41908
  package_default = {
41873
41909
  name: "allagents",
41874
- version: "1.11.1-next.1",
41910
+ version: "1.11.2-next.1",
41875
41911
  packageManager: "bun@1.3.12",
41876
41912
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
41877
41913
  type: "module",
@@ -44718,7 +44754,7 @@ var skillsRemoveMeta = {
44718
44754
  };
44719
44755
  var skillsSearchMeta = {
44720
44756
  command: "skill search",
44721
- description: "Search GitHub for skills by querying SKILL.md files via the Code Search API",
44757
+ description: "Search GitHub for skills by querying SKILL.md files via the Code Search API. Results are sorted by star count. In TTY mode, shows a filter-as-you-type picker and offers to install the selected skill.",
44722
44758
  whenToUse: 'To discover available skills from public GitHub repositories without leaving the CLI. Bridges "I want a skill that does X" → install.',
44723
44759
  examples: [
44724
44760
  "allagents skill search terraform",
@@ -44726,18 +44762,18 @@ var skillsSearchMeta = {
44726
44762
  "allagents skill search docs --page 2 --limit 10",
44727
44763
  "allagents --json skill search docs --limit 5"
44728
44764
  ],
44729
- expectedOutput: "Ranked list of matching skills with repo, path, and description",
44765
+ expectedOutput: "Skills sorted by star count: repo, skill name, stars, description. In TTY mode, followed by a filter-as-you-type install prompt.",
44730
44766
  positionals: [
44731
44767
  { name: "query", type: "string", required: true, description: "Search query (≥2 characters)." }
44732
44768
  ],
44733
44769
  options: [
44734
44770
  { flag: "--owner", type: "string", description: "Scope to a single GitHub owner (org or user)." },
44735
44771
  { flag: "--page", type: "string", description: "Result page (1-indexed, default 1)." },
44736
- { flag: "--limit", type: "string", description: "Results per page (1–100, default 30)." }
44772
+ { flag: "--limit", type: "string", description: "Results per page (1–100, default 15)." }
44737
44773
  ],
44738
44774
  outputSchema: {
44739
44775
  query: "string",
44740
- items: [{ name: "string", repo: "string", path: "string", description: "string", sha: "string" }],
44776
+ items: [{ name: "string", namespace: "string", repo: "string", path: "string", description: "string", sha: "string", stars: "number" }],
44741
44777
  total: "number",
44742
44778
  truncated: "boolean"
44743
44779
  }
@@ -45754,6 +45790,78 @@ Use --plugin to specify: allagents skill add ${skill} --plugin <name>`;
45754
45790
  }
45755
45791
  }
45756
45792
  });
45793
+ function printSearchResults(items, query, truncated) {
45794
+ console.log(`
45795
+ Showing ${items.length} result${items.length !== 1 ? "s" : ""} for "${query}"${truncated ? " (truncated)" : ""}
45796
+ `);
45797
+ for (const item of items) {
45798
+ const repoCol = item.repo.padEnd(30);
45799
+ const nameCol = qualifiedName(item).padEnd(24);
45800
+ const stars = item.stars > 0 ? source_default.yellow(`★ ${item.stars}`) : "";
45801
+ const desc = item.description ? source_default.dim(item.description.length > 60 ? `${item.description.slice(0, 57)}...` : item.description) : "";
45802
+ const starsAndDesc = [stars, desc].filter(Boolean).join(" ");
45803
+ console.log(` ${source_default.cyan(repoCol)} ${source_default.bold(nameCol)} ${starsAndDesc}`);
45804
+ }
45805
+ console.log("");
45806
+ }
45807
+ async function installFromSearch(repo) {
45808
+ const p = await Promise.resolve().then(() => (init_dist2(), exports_dist));
45809
+ const workspacePath = process.cwd();
45810
+ const isInstalledProject = hasProjectConfig(workspacePath) ? await hasPlugin(repo, workspacePath) : false;
45811
+ const isInstalledUser = await hasUserPlugin(repo);
45812
+ if (isInstalledProject || isInstalledUser) {
45813
+ const scopeLabel = isInstalledUser ? "user" : "project";
45814
+ p.log.info(`Plugin ${source_default.bold(repo)} is already installed (${scopeLabel} scope).`);
45815
+ return false;
45816
+ }
45817
+ const scopeChoice = await p.select({
45818
+ message: "Install scope",
45819
+ options: [
45820
+ { label: "Project (this workspace)", value: "project" },
45821
+ { label: "User (global)", value: "user" }
45822
+ ]
45823
+ });
45824
+ if (p.isCancel(scopeChoice))
45825
+ return false;
45826
+ const s = p.spinner();
45827
+ s.start("Installing plugin...");
45828
+ try {
45829
+ if (scopeChoice === "project") {
45830
+ const result = await addPlugin(repo, workspacePath);
45831
+ if (!result.success) {
45832
+ s.stop("Installation failed");
45833
+ p.log.error(result.error ?? "Unknown error");
45834
+ return false;
45835
+ }
45836
+ s.message("Syncing...");
45837
+ const syncResult = await syncWorkspace(workspacePath);
45838
+ s.stop("Installed and synced");
45839
+ const lines = formatVerboseSyncLines(syncResult);
45840
+ if (lines.length > 0)
45841
+ p.note(lines.join(`
45842
+ `), `Installed: ${repo}`);
45843
+ } else {
45844
+ const result = await addUserPlugin(repo);
45845
+ if (!result.success) {
45846
+ s.stop("Installation failed");
45847
+ p.log.error(result.error ?? "Unknown error");
45848
+ return false;
45849
+ }
45850
+ s.message("Syncing...");
45851
+ const syncResult = await syncUserWorkspace();
45852
+ s.stop("Installed and synced");
45853
+ const lines = formatVerboseSyncLines(syncResult);
45854
+ if (lines.length > 0)
45855
+ p.note(lines.join(`
45856
+ `), `Installed: ${repo}`);
45857
+ }
45858
+ return true;
45859
+ } catch (err) {
45860
+ s.stop("Installation failed");
45861
+ p.log.error(err instanceof Error ? err.message : String(err));
45862
+ return false;
45863
+ }
45864
+ }
45757
45865
  var searchCmd = import_cmd_ts3.command({
45758
45866
  name: "search",
45759
45867
  description: buildDescription(skillsSearchMeta),
@@ -45772,7 +45880,7 @@ var searchCmd = import_cmd_ts3.command({
45772
45880
  limit: import_cmd_ts3.option({
45773
45881
  type: import_cmd_ts3.optional(import_cmd_ts3.string),
45774
45882
  long: "limit",
45775
- description: "Results per page (1–100, default 30)."
45883
+ description: "Results per page (1–100, default 15)."
45776
45884
  })
45777
45885
  },
45778
45886
  handler: async ({ query, owner, page, limit }) => {
@@ -45819,13 +45927,28 @@ var searchCmd = import_cmd_ts3.command({
45819
45927
  console.log(`No skills found for "${query}".`);
45820
45928
  return;
45821
45929
  }
45822
- console.log(`Found ${result.total} skill(s)${result.truncated ? " (results truncated)" : ""}:`);
45823
- for (const item of result.items) {
45824
- const repoCol = item.repo.padEnd(28);
45825
- const nameCol = item.name.padEnd(28);
45826
- const desc = item.description ? ` ${item.description}` : "";
45827
- console.log(` ${repoCol} ${nameCol}${desc}`);
45930
+ const isTTY = process.stdout.isTTY && process.stdin.isTTY;
45931
+ if (!isTTY) {
45932
+ printSearchResults(result.items, query, result.truncated);
45933
+ return;
45934
+ }
45935
+ const { autocomplete, isCancel } = await Promise.resolve().then(() => (init_dist2(), exports_dist));
45936
+ printSearchResults(result.items, query, result.truncated);
45937
+ const options2 = result.items.map((item) => ({
45938
+ label: `${qualifiedName(item)} ${source_default.dim(item.repo)}`,
45939
+ value: item.repo,
45940
+ hint: `${item.stars > 0 ? `★${item.stars} ` : ""}${item.description ?? ""}`
45941
+ }));
45942
+ options2.push({ label: "Cancel", value: "__cancel__", hint: "" });
45943
+ const selected = await autocomplete({
45944
+ message: `Select a skill to install (type to filter ${result.items.length} results)`,
45945
+ options: options2,
45946
+ placeholder: "Type to filter..."
45947
+ });
45948
+ if (isCancel(selected) || selected === "__cancel__") {
45949
+ return;
45828
45950
  }
45951
+ await installFromSearch(selected);
45829
45952
  } catch (error) {
45830
45953
  if (error instanceof SkillSearchError) {
45831
45954
  const exitCode = error.kind === "validation" ? 2 : 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allagents",
3
- "version": "1.11.1-next.1",
3
+ "version": "1.11.2-next.1",
4
4
  "packageManager": "bun@1.3.12",
5
5
  "description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
6
6
  "type": "module",