allagents 1.10.0-next.1 → 1.11.0-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 (3) hide show
  1. package/README.md +2 -2
  2. package/dist/index.js +263 -188
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -12,7 +12,7 @@ AllAgents keeps your AI tooling (skills, agents, hooks, MCP servers) in one work
12
12
 
13
13
  ```bash
14
14
  # Create a workspace from a shared template
15
- npx allagents workspace init my-workspace --from myorg/templates/nodejs
15
+ npx allagents init my-workspace --from myorg/templates/nodejs
16
16
  cd my-workspace
17
17
 
18
18
  # Install plugins
@@ -89,7 +89,7 @@ clients:
89
89
 
90
90
  | Command | Description |
91
91
  |---|---|
92
- | `allagents workspace init <path>` | Create a workspace (optionally `--from owner/repo`) |
92
+ | `allagents init <path>` | Create a workspace (optionally `--from owner/repo`) |
93
93
  | `allagents update` | Sync all plugins to workspace |
94
94
  | `allagents plugin install <spec>` | Install a plugin |
95
95
  | `allagents plugin uninstall <spec>` | Remove a plugin |
package/dist/index.js CHANGED
@@ -29053,6 +29053,15 @@ var init_sync_state2 = __esm(() => {
29053
29053
  // src/core/vscode-workspace.ts
29054
29054
  import { createHash as createHash2 } from "node:crypto";
29055
29055
  import { resolve as resolve9, basename as basename6, isAbsolute as isAbsolute3, relative as relative4 } from "node:path";
29056
+ function normalizeWorkspacePath(path) {
29057
+ return path.replace(/\\/g, "/");
29058
+ }
29059
+ function resolveFolderAbsolutePath(workspacePath, folderPath) {
29060
+ return (isAbsolute3(folderPath) ? folderPath : resolve9(workspacePath, folderPath)).replace(/\\/g, "/");
29061
+ }
29062
+ function resolveFolderDisplayPath(folderPath) {
29063
+ return normalizeWorkspacePath(folderPath);
29064
+ }
29056
29065
  function buildPathPlaceholderMap(repositories, workspacePath) {
29057
29066
  const map2 = new Map;
29058
29067
  for (const repo of repositories) {
@@ -29093,8 +29102,8 @@ function generateVscodeWorkspace(input) {
29093
29102
  folders.push({ path: "." });
29094
29103
  seenPaths.add(resolve9(workspacePath, "."));
29095
29104
  for (const repo of repositories) {
29096
- const absolutePath = resolve9(workspacePath, repo.path).replace(/\\/g, "/");
29097
- const entry = { path: absolutePath };
29105
+ const absolutePath = resolveFolderAbsolutePath(workspacePath, repo.path);
29106
+ const entry = { path: resolveFolderDisplayPath(repo.path) };
29098
29107
  if (repo.name)
29099
29108
  entry.name = repo.name;
29100
29109
  folders.push(entry);
@@ -29103,9 +29112,9 @@ function generateVscodeWorkspace(input) {
29103
29112
  if (resolvedTemplate && Array.isArray(resolvedTemplate.folders)) {
29104
29113
  for (const folder of resolvedTemplate.folders) {
29105
29114
  const rawPath = folder.path;
29106
- const normalizedPath = (typeof rawPath === "string" && !isAbsolute3(rawPath) ? resolve9(workspacePath, rawPath) : rawPath).replace(/\\/g, "/");
29115
+ const normalizedPath = resolveFolderAbsolutePath(workspacePath, rawPath);
29107
29116
  if (!seenPaths.has(normalizedPath)) {
29108
- const entry = { path: normalizedPath };
29117
+ const entry = { path: resolveFolderDisplayPath(rawPath) };
29109
29118
  if (folder.name)
29110
29119
  entry.name = folder.name;
29111
29120
  folders.push(entry);
@@ -34698,6 +34707,182 @@ var init_skills = __esm(() => {
34698
34707
  init_skill();
34699
34708
  });
34700
34709
 
34710
+ // src/core/skill-search.ts
34711
+ function validateSkillSearchArgs(query, options2) {
34712
+ if (query.trim().length < 2) {
34713
+ throw new SkillSearchError("Search query must be at least 2 characters.", "validation");
34714
+ }
34715
+ if (options2.page !== undefined && options2.page < 1) {
34716
+ throw new SkillSearchError("--page must be >= 1.", "validation");
34717
+ }
34718
+ if (options2.limit !== undefined && (options2.limit < 1 || options2.limit > 100)) {
34719
+ throw new SkillSearchError("--limit must be between 1 and 100.", "validation");
34720
+ }
34721
+ if (options2.owner !== undefined && !OWNER_REGEX.test(options2.owner)) {
34722
+ throw new SkillSearchError(`Invalid --owner "${options2.owner}": GitHub owners are alphanumeric + dashes, ≤ 39 chars.`, "validation");
34723
+ }
34724
+ }
34725
+ function couldBeOwner(query) {
34726
+ return COULD_BE_OWNER_REGEX.test(query);
34727
+ }
34728
+ function buildSearchQueries(query, owner) {
34729
+ const trimmed2 = query.trim();
34730
+ const pathTerm = trimmed2.replace(/ /g, "-");
34731
+ const userClause = owner ? `user:${owner}` : "";
34732
+ const join26 = (...parts) => parts.filter(Boolean).join(" ");
34733
+ const queries = [
34734
+ { priority: 1, label: "path", q: join26("filename:SKILL.md", `in:path ${pathTerm}`, userClause) }
34735
+ ];
34736
+ if (pathTerm !== trimmed2) {
34737
+ queries.push({ priority: 2, label: "hyphen", q: join26("filename:SKILL.md", pathTerm, userClause) });
34738
+ }
34739
+ if (!owner && couldBeOwner(trimmed2)) {
34740
+ queries.push({ priority: 3, label: "owner", q: `filename:SKILL.md user:${trimmed2}` });
34741
+ }
34742
+ queries.push({ priority: 4, label: "primary", q: join26("filename:SKILL.md", trimmed2, userClause) });
34743
+ return queries;
34744
+ }
34745
+ function classifyApiError(status, body) {
34746
+ const msg = typeof body === "object" && body !== null && "message" in body ? String(body.message ?? "") : "";
34747
+ if (status === 403 && /rate limit/i.test(msg)) {
34748
+ return new SkillSearchError("GitHub Code Search rate limit exceeded. Authenticate with `gh auth login` or set GITHUB_TOKEN to raise the quota.", "rate-limit");
34749
+ }
34750
+ if (status === 422) {
34751
+ return new SkillSearchError(`GitHub rejected the search query: ${msg || "unprocessable entity"}.`, "api");
34752
+ }
34753
+ return new SkillSearchError(`GitHub Code Search returned ${status}${msg ? `: ${msg}` : ""}.`, "api");
34754
+ }
34755
+ function qualifiedName(item) {
34756
+ return item.namespace ? `${item.namespace}/${item.name}` : item.name;
34757
+ }
34758
+ function parseSkillPath(path, repoFallback) {
34759
+ const parts = path.split("/").filter(Boolean);
34760
+ const skillsIdx = parts.lastIndexOf("skills");
34761
+ if (skillsIdx !== -1) {
34762
+ const afterSkills = parts.slice(skillsIdx + 1);
34763
+ const meaningful = afterSkills[afterSkills.length - 1] === "SKILL.md" ? afterSkills.slice(0, -1) : afterSkills;
34764
+ if (meaningful.length >= 2) {
34765
+ const namespace = meaningful[0] ?? "";
34766
+ const name = meaningful[1] ?? "";
34767
+ if (namespace && name)
34768
+ return { namespace, name };
34769
+ }
34770
+ if (meaningful.length === 1 && meaningful[0]) {
34771
+ return { namespace: "", name: meaningful[0] };
34772
+ }
34773
+ }
34774
+ if (parts.length >= 2) {
34775
+ const parent = parts[parts.length - 2];
34776
+ if (parent)
34777
+ return { namespace: "", name: parent };
34778
+ }
34779
+ return { namespace: "", name: repoFallback };
34780
+ }
34781
+ async function runOneQuery(q3, page, limit, token, fetchFn) {
34782
+ const url = new URL("https://api.github.com/search/code");
34783
+ url.searchParams.set("q", q3);
34784
+ url.searchParams.set("per_page", String(limit));
34785
+ url.searchParams.set("page", String(page));
34786
+ const headers = {
34787
+ Accept: "application/vnd.github+json",
34788
+ "X-GitHub-Api-Version": "2022-11-28",
34789
+ "User-Agent": "allagents-cli"
34790
+ };
34791
+ if (token)
34792
+ headers.Authorization = `token ${token}`;
34793
+ const response = await fetchFn(url.toString(), { headers });
34794
+ let body = null;
34795
+ try {
34796
+ body = await response.json();
34797
+ } catch {}
34798
+ if (!response.ok) {
34799
+ throw classifyApiError(response.status, body);
34800
+ }
34801
+ const parsed = body;
34802
+ const items = (parsed.items ?? []).map((item) => {
34803
+ const path = item.path ?? "";
34804
+ const repo = item.repository?.full_name ?? "";
34805
+ const repoFallback = repo.split("/").pop() ?? "";
34806
+ const { namespace, name } = parseSkillPath(path, repoFallback);
34807
+ return {
34808
+ name,
34809
+ namespace,
34810
+ repo,
34811
+ path,
34812
+ description: item.repository?.description ?? "",
34813
+ sha: item.sha ?? ""
34814
+ };
34815
+ });
34816
+ return {
34817
+ items,
34818
+ total: parsed.total_count ?? items.length,
34819
+ truncated: Boolean(parsed.incomplete_results)
34820
+ };
34821
+ }
34822
+ async function searchSkills(query, options2 = {}, deps = {}) {
34823
+ validateSkillSearchArgs(query, options2);
34824
+ const fetchFn = deps.fetch ?? fetch;
34825
+ const logger = deps.logger ?? ((msg) => process.stderr.write(`${msg}
34826
+ `));
34827
+ const page = options2.page ?? 1;
34828
+ const limit = options2.limit ?? 30;
34829
+ const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
34830
+ const queries = buildSearchQueries(query, options2.owner);
34831
+ const settled = await Promise.allSettled(queries.map((entry) => runOneQuery(entry.q, page, limit, token, fetchFn)));
34832
+ const primaryIdx = queries.findIndex((q3) => q3.priority === 4);
34833
+ const primarySettled = settled[primaryIdx];
34834
+ if (primarySettled?.status === "rejected") {
34835
+ throw primarySettled.reason;
34836
+ }
34837
+ const buckets = [];
34838
+ for (let i2 = 0;i2 < queries.length; i2++) {
34839
+ const entry = queries[i2];
34840
+ const outcome = settled[i2];
34841
+ if (!entry || !outcome)
34842
+ continue;
34843
+ if (outcome.status === "fulfilled") {
34844
+ buckets.push({ priority: entry.priority, result: outcome.value });
34845
+ } else {
34846
+ const reason = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
34847
+ logger(`Warning: skill search "${entry.label}" query failed: ${reason}`);
34848
+ }
34849
+ }
34850
+ buckets.sort((a, b) => a.priority - b.priority);
34851
+ const mergedItems = buckets.flatMap((b) => b.result.items);
34852
+ const deduped = dedupeItems(mergedItems);
34853
+ return {
34854
+ query,
34855
+ items: deduped,
34856
+ total: deduped.length,
34857
+ truncated: buckets.some((b) => b.result.truncated)
34858
+ };
34859
+ }
34860
+ function dedupeItems(items) {
34861
+ const seen = new Set;
34862
+ const out = [];
34863
+ for (const item of items) {
34864
+ const key = `${item.repo}#${qualifiedName(item)}`;
34865
+ if (seen.has(key))
34866
+ continue;
34867
+ seen.add(key);
34868
+ out.push(item);
34869
+ }
34870
+ return out;
34871
+ }
34872
+ var OWNER_REGEX, COULD_BE_OWNER_REGEX, SkillSearchError;
34873
+ var init_skill_search = __esm(() => {
34874
+ OWNER_REGEX = /^[A-Za-z0-9-]{1,39}$/;
34875
+ COULD_BE_OWNER_REGEX = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$/;
34876
+ SkillSearchError = class SkillSearchError extends Error {
34877
+ kind;
34878
+ constructor(message, kind) {
34879
+ super(message);
34880
+ this.kind = kind;
34881
+ this.name = "SkillSearchError";
34882
+ }
34883
+ };
34884
+ });
34885
+
34701
34886
  // node_modules/ajv/dist/compile/codegen/code.js
34702
34887
  var require_code = __commonJS((exports) => {
34703
34888
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -41668,7 +41853,7 @@ var package_default;
41668
41853
  var init_package = __esm(() => {
41669
41854
  package_default = {
41670
41855
  name: "allagents",
41671
- version: "1.10.0-next.1",
41856
+ version: "1.11.0-next.1",
41672
41857
  packageManager: "bun@1.3.12",
41673
41858
  description: "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
41674
41859
  type: "module",
@@ -42956,6 +43141,7 @@ async function runSkills(context, cache2) {
42956
43141
  options: [
42957
43142
  { label: "Toggle installed skills", value: "toggle" },
42958
43143
  { label: "Browse marketplace skills...", value: "browse" },
43144
+ { label: "Search online...", value: "search" },
42959
43145
  { label: "Back", value: "back" }
42960
43146
  ]
42961
43147
  });
@@ -42966,6 +43152,10 @@ async function runSkills(context, cache2) {
42966
43152
  await runBrowseMarketplaceSkills(context, cache2);
42967
43153
  continue;
42968
43154
  }
43155
+ if (action === "search") {
43156
+ await runSearchOnlineSkills(context, cache2);
43157
+ continue;
43158
+ }
42969
43159
  await runToggleSkills(skills, context, cache2);
42970
43160
  return;
42971
43161
  }
@@ -43122,7 +43312,60 @@ Use "Manage marketplaces" to add one first.`, "Skills");
43122
43312
  await runBrowsePluginSkills(selected, scope, context, cache2);
43123
43313
  }
43124
43314
  }
43125
- var multiselect2, select4, autocomplete2;
43315
+ async function runSearchOnlineSkills(context, cache2) {
43316
+ const query = await text3({
43317
+ message: "Search for skills on GitHub",
43318
+ placeholder: "e.g. commit, deploy, aws"
43319
+ });
43320
+ if (Ct(query) || !query || query.trim().length === 0) {
43321
+ return;
43322
+ }
43323
+ const s = Ie();
43324
+ s.start("Searching GitHub...");
43325
+ let items;
43326
+ try {
43327
+ const result = await searchSkills(query.trim());
43328
+ items = result.items;
43329
+ } catch (error2) {
43330
+ s.stop("Search failed");
43331
+ kt2(error2 instanceof Error ? error2.message : String(error2), "Search Error");
43332
+ return;
43333
+ }
43334
+ s.stop(`Found ${items.length} skill${items.length !== 1 ? "s" : ""}`);
43335
+ if (items.length === 0) {
43336
+ kt2(`No skills found for "${query.trim()}".`, "Search");
43337
+ return;
43338
+ }
43339
+ const options2 = items.map((item) => ({
43340
+ label: qualifiedName(item),
43341
+ value: item.repo,
43342
+ hint: item.repo + (item.description ? ` · ${item.description}` : "")
43343
+ }));
43344
+ options2.push({ label: "Back", value: "__back__" });
43345
+ const selected = await autocomplete2({
43346
+ message: `Results for "${query.trim()}"`,
43347
+ options: options2,
43348
+ placeholder: "Type to filter..."
43349
+ });
43350
+ if (Ct(selected) || selected === "__back__") {
43351
+ return;
43352
+ }
43353
+ const workspacePath = context.workspacePath ?? process.cwd();
43354
+ const isInstalledProject = context.workspacePath ? await hasPlugin(selected, workspacePath) : false;
43355
+ const isInstalledUser = await hasUserPlugin(selected);
43356
+ if (isInstalledProject || isInstalledUser) {
43357
+ const scope = isInstalledUser ? "user" : "project";
43358
+ await runBrowsePluginSkills(selected, scope, context, cache2);
43359
+ return;
43360
+ }
43361
+ const installed = await installSelectedPlugin(selected, context, cache2);
43362
+ if (installed) {
43363
+ const nowInstalledUser = await hasUserPlugin(selected);
43364
+ const scope = nowInstalledUser ? "user" : "project";
43365
+ await runBrowsePluginSkills(selected, scope, context, cache2);
43366
+ }
43367
+ }
43368
+ var multiselect2, select4, autocomplete2, text3;
43126
43369
  var init_skills2 = __esm(() => {
43127
43370
  init_dist2();
43128
43371
  init_skills();
@@ -43130,9 +43373,10 @@ var init_skills2 = __esm(() => {
43130
43373
  init_user_workspace();
43131
43374
  init_sync();
43132
43375
  init_marketplace();
43376
+ init_skill_search();
43133
43377
  init_constants();
43134
43378
  init_plugins();
43135
- ({ multiselect: multiselect2, select: select4, autocomplete: autocomplete2 } = exports_dist);
43379
+ ({ multiselect: multiselect2, select: select4, autocomplete: autocomplete2, text: text3 } = exports_dist);
43136
43380
  });
43137
43381
 
43138
43382
  // src/cli/tui/wizard.ts
@@ -43488,14 +43732,14 @@ function validateJsonFields(fields, meta) {
43488
43732
 
43489
43733
  // src/cli/metadata/workspace.ts
43490
43734
  var initMeta = {
43491
- command: "workspace init",
43735
+ command: "init",
43492
43736
  description: "Create new workspace and sync plugins",
43493
43737
  whenToUse: "When starting a new project or adding allagents to an existing repo for the first time",
43494
43738
  examples: [
43495
- "allagents workspace init",
43496
- "allagents workspace init ./my-project",
43497
- "allagents workspace init --from ../template-workspace/.allagents/workspace.yaml",
43498
- "allagents workspace init --client claude,copilot,cursor"
43739
+ "allagents init",
43740
+ "allagents init ./my-project",
43741
+ "allagents init --from ../template-workspace/.allagents/workspace.yaml",
43742
+ "allagents init --client claude,copilot,cursor"
43499
43743
  ],
43500
43744
  expectedOutput: "Creates .allagents/workspace.yaml and syncs plugins. Shows sync results per plugin. Exit 0 on success, exit 1 on failure.",
43501
43745
  positionals: [
@@ -44534,181 +44778,8 @@ var skillsAddMeta = {
44534
44778
  }
44535
44779
  };
44536
44780
 
44537
- // src/core/skill-search.ts
44538
- var OWNER_REGEX = /^[A-Za-z0-9-]{1,39}$/;
44539
- var COULD_BE_OWNER_REGEX = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$/;
44540
-
44541
- class SkillSearchError extends Error {
44542
- kind;
44543
- constructor(message, kind) {
44544
- super(message);
44545
- this.kind = kind;
44546
- this.name = "SkillSearchError";
44547
- }
44548
- }
44549
- function validateSkillSearchArgs(query, options2) {
44550
- if (query.trim().length < 2) {
44551
- throw new SkillSearchError("Search query must be at least 2 characters.", "validation");
44552
- }
44553
- if (options2.page !== undefined && options2.page < 1) {
44554
- throw new SkillSearchError("--page must be >= 1.", "validation");
44555
- }
44556
- if (options2.limit !== undefined && (options2.limit < 1 || options2.limit > 100)) {
44557
- throw new SkillSearchError("--limit must be between 1 and 100.", "validation");
44558
- }
44559
- if (options2.owner !== undefined && !OWNER_REGEX.test(options2.owner)) {
44560
- throw new SkillSearchError(`Invalid --owner "${options2.owner}": GitHub owners are alphanumeric + dashes, ≤ 39 chars.`, "validation");
44561
- }
44562
- }
44563
- function couldBeOwner(query) {
44564
- return COULD_BE_OWNER_REGEX.test(query);
44565
- }
44566
- function buildSearchQueries(query, owner) {
44567
- const trimmed2 = query.trim();
44568
- const pathTerm = trimmed2.replace(/ /g, "-");
44569
- const userClause = owner ? `user:${owner}` : "";
44570
- const join26 = (...parts) => parts.filter(Boolean).join(" ");
44571
- const queries = [
44572
- { priority: 1, label: "path", q: join26("filename:SKILL.md", `in:path ${pathTerm}`, userClause) }
44573
- ];
44574
- if (pathTerm !== trimmed2) {
44575
- queries.push({ priority: 2, label: "hyphen", q: join26("filename:SKILL.md", pathTerm, userClause) });
44576
- }
44577
- if (!owner && couldBeOwner(trimmed2)) {
44578
- queries.push({ priority: 3, label: "owner", q: `filename:SKILL.md user:${trimmed2}` });
44579
- }
44580
- queries.push({ priority: 4, label: "primary", q: join26("filename:SKILL.md", trimmed2, userClause) });
44581
- return queries;
44582
- }
44583
- function classifyApiError(status, body) {
44584
- const msg = typeof body === "object" && body !== null && "message" in body ? String(body.message ?? "") : "";
44585
- if (status === 403 && /rate limit/i.test(msg)) {
44586
- return new SkillSearchError("GitHub Code Search rate limit exceeded. Authenticate with `gh auth login` or set GITHUB_TOKEN to raise the quota.", "rate-limit");
44587
- }
44588
- if (status === 422) {
44589
- return new SkillSearchError(`GitHub rejected the search query: ${msg || "unprocessable entity"}.`, "api");
44590
- }
44591
- return new SkillSearchError(`GitHub Code Search returned ${status}${msg ? `: ${msg}` : ""}.`, "api");
44592
- }
44593
- function qualifiedName(item) {
44594
- return item.namespace ? `${item.namespace}/${item.name}` : item.name;
44595
- }
44596
- function parseSkillPath(path, repoFallback) {
44597
- const parts = path.split("/").filter(Boolean);
44598
- const skillsIdx = parts.lastIndexOf("skills");
44599
- if (skillsIdx !== -1) {
44600
- const afterSkills = parts.slice(skillsIdx + 1);
44601
- const meaningful = afterSkills[afterSkills.length - 1] === "SKILL.md" ? afterSkills.slice(0, -1) : afterSkills;
44602
- if (meaningful.length >= 2) {
44603
- const namespace = meaningful[0] ?? "";
44604
- const name = meaningful[1] ?? "";
44605
- if (namespace && name)
44606
- return { namespace, name };
44607
- }
44608
- if (meaningful.length === 1 && meaningful[0]) {
44609
- return { namespace: "", name: meaningful[0] };
44610
- }
44611
- }
44612
- if (parts.length >= 2) {
44613
- const parent = parts[parts.length - 2];
44614
- if (parent)
44615
- return { namespace: "", name: parent };
44616
- }
44617
- return { namespace: "", name: repoFallback };
44618
- }
44619
- async function runOneQuery(q3, page, limit, token, fetchFn) {
44620
- const url = new URL("https://api.github.com/search/code");
44621
- url.searchParams.set("q", q3);
44622
- url.searchParams.set("per_page", String(limit));
44623
- url.searchParams.set("page", String(page));
44624
- const headers = {
44625
- Accept: "application/vnd.github+json",
44626
- "X-GitHub-Api-Version": "2022-11-28",
44627
- "User-Agent": "allagents-cli"
44628
- };
44629
- if (token)
44630
- headers.Authorization = `token ${token}`;
44631
- const response = await fetchFn(url.toString(), { headers });
44632
- let body = null;
44633
- try {
44634
- body = await response.json();
44635
- } catch {}
44636
- if (!response.ok) {
44637
- throw classifyApiError(response.status, body);
44638
- }
44639
- const parsed = body;
44640
- const items = (parsed.items ?? []).map((item) => {
44641
- const path = item.path ?? "";
44642
- const repo = item.repository?.full_name ?? "";
44643
- const repoFallback = repo.split("/").pop() ?? "";
44644
- const { namespace, name } = parseSkillPath(path, repoFallback);
44645
- return {
44646
- name,
44647
- namespace,
44648
- repo,
44649
- path,
44650
- description: item.repository?.description ?? "",
44651
- sha: item.sha ?? ""
44652
- };
44653
- });
44654
- return {
44655
- items,
44656
- total: parsed.total_count ?? items.length,
44657
- truncated: Boolean(parsed.incomplete_results)
44658
- };
44659
- }
44660
- async function searchSkills(query, options2 = {}, deps = {}) {
44661
- validateSkillSearchArgs(query, options2);
44662
- const fetchFn = deps.fetch ?? fetch;
44663
- const logger = deps.logger ?? ((msg) => process.stderr.write(`${msg}
44664
- `));
44665
- const page = options2.page ?? 1;
44666
- const limit = options2.limit ?? 30;
44667
- const token = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
44668
- const queries = buildSearchQueries(query, options2.owner);
44669
- const settled = await Promise.allSettled(queries.map((entry) => runOneQuery(entry.q, page, limit, token, fetchFn)));
44670
- const primaryIdx = queries.findIndex((q3) => q3.priority === 4);
44671
- const primarySettled = settled[primaryIdx];
44672
- if (primarySettled?.status === "rejected") {
44673
- throw primarySettled.reason;
44674
- }
44675
- const buckets = [];
44676
- for (let i2 = 0;i2 < queries.length; i2++) {
44677
- const entry = queries[i2];
44678
- const outcome = settled[i2];
44679
- if (!entry || !outcome)
44680
- continue;
44681
- if (outcome.status === "fulfilled") {
44682
- buckets.push({ priority: entry.priority, result: outcome.value });
44683
- } else {
44684
- const reason = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
44685
- logger(`Warning: skill search "${entry.label}" query failed: ${reason}`);
44686
- }
44687
- }
44688
- buckets.sort((a, b) => a.priority - b.priority);
44689
- const mergedItems = buckets.flatMap((b) => b.result.items);
44690
- const deduped = dedupeItems(mergedItems);
44691
- return {
44692
- query,
44693
- items: deduped,
44694
- total: deduped.length,
44695
- truncated: buckets.some((b) => b.result.truncated)
44696
- };
44697
- }
44698
- function dedupeItems(items) {
44699
- const seen = new Set;
44700
- const out = [];
44701
- for (const item of items) {
44702
- const key = `${item.repo}#${qualifiedName(item)}`;
44703
- if (seen.has(key))
44704
- continue;
44705
- seen.add(key);
44706
- out.push(item);
44707
- }
44708
- return out;
44709
- }
44710
-
44711
44781
  // src/cli/commands/plugin-skills.ts
44782
+ init_skill_search();
44712
44783
  init_constants();
44713
44784
  init_plugin_path();
44714
44785
  init_plugin();
@@ -55416,11 +55487,14 @@ function findFreePort() {
55416
55487
  });
55417
55488
  });
55418
55489
  }
55419
- function tryOpenBrowser(url2) {
55420
- const commands = process.platform === "darwin" ? [{ command: "open", args: [url2] }] : process.platform === "win32" ? [{ command: "cmd", args: ["/c", "start", "", url2] }] : [
55490
+ function getBrowserOpenCommands(url2, platform2 = process.platform) {
55491
+ return platform2 === "darwin" ? [{ command: "open", args: [url2] }] : platform2 === "win32" ? [{ command: "explorer.exe", args: [url2] }] : [
55421
55492
  { command: "xdg-open", args: [url2] },
55422
55493
  { command: "gio", args: ["open", url2] }
55423
55494
  ];
55495
+ }
55496
+ function tryOpenBrowser(url2) {
55497
+ const commands = getBrowserOpenCommands(url2);
55424
55498
  return new Promise((resolve15) => {
55425
55499
  const tryCommand = (index) => {
55426
55500
  if (index >= commands.length) {
@@ -57923,6 +57997,7 @@ var app = conciseSubcommands({
57923
57997
  ` + "For AI agents: use --agent-help for machine-readable help, or --json for structured output",
57924
57998
  version: package_default.version,
57925
57999
  cmds: {
58000
+ init: initCmd,
57926
58001
  update: syncCmd,
57927
58002
  workspace: workspaceCmd,
57928
58003
  plugin: pluginCmd,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allagents",
3
- "version": "1.10.0-next.1",
3
+ "version": "1.11.0-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",