@annals/agent-mesh 0.13.0 → 0.14.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.
Files changed (2) hide show
  1. package/dist/index.js +117 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -555,8 +555,14 @@ var AgentAdapter = class {
555
555
  };
556
556
 
557
557
  // src/utils/client-workspace.ts
558
- import { mkdirSync, readdirSync, symlinkSync, existsSync } from "fs";
558
+ import { mkdirSync, readdirSync, symlinkSync, existsSync, lstatSync } from "fs";
559
559
  import { join, relative } from "path";
560
+ var SYMLINK_ALLOW = /* @__PURE__ */ new Set([
561
+ "CLAUDE.md",
562
+ ".claude",
563
+ ".agents",
564
+ "src"
565
+ ]);
560
566
  var SYMLINK_EXCLUDE = /* @__PURE__ */ new Set([
561
567
  ".bridge-clients",
562
568
  ".git",
@@ -567,20 +573,31 @@ var SYMLINK_EXCLUDE = /* @__PURE__ */ new Set([
567
573
  "build",
568
574
  "coverage",
569
575
  ".turbo",
570
- ".env"
576
+ ".env",
577
+ "connect.log",
578
+ "skills",
579
+ "skills-lock.json"
571
580
  ]);
572
- function shouldExclude(name) {
573
- return SYMLINK_EXCLUDE.has(name) || name.startsWith(".env.");
581
+ function shouldInclude(name) {
582
+ if (SYMLINK_ALLOW.has(name)) return true;
583
+ if (SYMLINK_EXCLUDE.has(name) || name.startsWith(".env.")) return false;
584
+ if (!name.startsWith(".")) return true;
585
+ return false;
574
586
  }
575
587
  function createClientWorkspace(projectPath, clientId) {
576
588
  const wsDir = join(projectPath, ".bridge-clients", clientId);
577
- if (existsSync(wsDir)) return wsDir;
589
+ const isNew = !existsSync(wsDir);
578
590
  mkdirSync(wsDir, { recursive: true });
579
591
  const entries = readdirSync(projectPath, { withFileTypes: true });
580
592
  for (const entry of entries) {
581
- if (shouldExclude(entry.name)) continue;
582
- const target = join(projectPath, entry.name);
593
+ if (!shouldInclude(entry.name)) continue;
583
594
  const link = join(wsDir, entry.name);
595
+ try {
596
+ lstatSync(link);
597
+ continue;
598
+ } catch {
599
+ }
600
+ const target = join(projectPath, entry.name);
584
601
  const relTarget = relative(wsDir, target);
585
602
  try {
586
603
  symlinkSync(relTarget, link);
@@ -588,7 +605,9 @@ function createClientWorkspace(projectPath, clientId) {
588
605
  log.warn(`Failed to create symlink ${link} \u2192 ${relTarget}: ${err}`);
589
606
  }
590
607
  }
591
- log.info(`Client workspace created: ${wsDir}`);
608
+ if (isNew) {
609
+ log.info(`Client workspace created: ${wsDir}`);
610
+ }
592
611
  return wsDir;
593
612
  }
594
613
 
@@ -2592,7 +2611,8 @@ var ERROR_HINTS = {
2592
2611
  github_required: "GitHub account required. Visit https://agents.hot/settings to link one.",
2593
2612
  validation_error: "Invalid input. Check your skill.json or command flags.",
2594
2613
  permission_denied: "You don't have permission to modify this skill.",
2595
- file_too_large: "Package file exceeds the 50MB limit."
2614
+ file_too_large: "Package file exceeds the 50MB limit.",
2615
+ subscription_required: "This is a private agent. Subscribe first: agent-mesh subscribe <author-login>"
2596
2616
  };
2597
2617
  var PlatformClient = class {
2598
2618
  token;
@@ -3788,7 +3808,10 @@ function registerDiscoverCommand(program2) {
3788
3808
  params.set("limit", opts.limit);
3789
3809
  params.set("offset", opts.offset);
3790
3810
  const url = `${BASE_URL}/api/agents/discover?${params}`;
3791
- const res = await fetch(url);
3811
+ const token = loadToken();
3812
+ const headers = {};
3813
+ if (token) headers["Authorization"] = `Bearer ${token}`;
3814
+ const res = await fetch(url, { headers });
3792
3815
  if (!res.ok) {
3793
3816
  const body = await res.json().catch(() => ({}));
3794
3817
  console.error(` Error: ${body.message ?? `HTTP ${res.status}`}`);
@@ -3875,12 +3898,20 @@ ${content}`;
3875
3898
  clearTimeout(timer);
3876
3899
  if (!res.ok) {
3877
3900
  let msg = `HTTP ${res.status}`;
3901
+ let errorCode = "";
3878
3902
  try {
3879
3903
  const body = await res.json();
3904
+ errorCode = body.error || "";
3880
3905
  msg = body.message || body.error || msg;
3881
3906
  } catch {
3882
3907
  }
3883
- log.error(msg);
3908
+ if (errorCode === "subscription_required") {
3909
+ log.error("This is a private agent.");
3910
+ console.error(` Subscribe first: agent-mesh subscribe <author-login>`);
3911
+ console.error(` Then retry: agent-mesh call ${agentInput} --task "..."`);
3912
+ } else {
3913
+ log.error(msg);
3914
+ }
3884
3915
  process.exit(1);
3885
3916
  }
3886
3917
  const contentType = res.headers.get("Content-Type") || "";
@@ -4145,6 +4176,80 @@ function printAgentStats(name, stats) {
4145
4176
  console.log("");
4146
4177
  }
4147
4178
 
4179
+ // src/commands/subscribe.ts
4180
+ var BASE_URL2 = "https://agents.hot";
4181
+ function handleError5(err) {
4182
+ if (err instanceof PlatformApiError) {
4183
+ log.error(err.message);
4184
+ } else {
4185
+ log.error(err.message);
4186
+ }
4187
+ process.exit(1);
4188
+ }
4189
+ async function resolveAuthorLogin(login) {
4190
+ const res = await fetch(`${BASE_URL2}/api/authors/resolve?login=${encodeURIComponent(login)}`);
4191
+ if (!res.ok) {
4192
+ if (res.status === 404) {
4193
+ throw new PlatformApiError(404, "not_found", `Author not found: ${login}`);
4194
+ }
4195
+ throw new PlatformApiError(res.status, "unknown", `Failed to resolve author: HTTP ${res.status}`);
4196
+ }
4197
+ return res.json();
4198
+ }
4199
+ function registerSubscribeCommand(program2) {
4200
+ program2.command("subscribe <author-login>").description("Subscribe to an author to access their private agents").action(async (authorLogin) => {
4201
+ try {
4202
+ const client = createClient();
4203
+ const author = await resolveAuthorLogin(authorLogin);
4204
+ await client.post(`/api/authors/${author.id}/subscribe`);
4205
+ log.success(`Subscribed to ${author.github_login}${author.name ? ` (${author.name})` : ""}`);
4206
+ } catch (err) {
4207
+ handleError5(err);
4208
+ }
4209
+ });
4210
+ program2.command("unsubscribe <author-login>").description("Unsubscribe from an author").action(async (authorLogin) => {
4211
+ try {
4212
+ const client = createClient();
4213
+ const author = await resolveAuthorLogin(authorLogin);
4214
+ await client.del(`/api/authors/${author.id}/subscribe`);
4215
+ log.success(`Unsubscribed from ${author.github_login}`);
4216
+ } catch (err) {
4217
+ handleError5(err);
4218
+ }
4219
+ });
4220
+ program2.command("subscriptions").description("List your author subscriptions").option("--json", "Output raw JSON").action(async (opts) => {
4221
+ try {
4222
+ const client = createClient();
4223
+ const data = await client.get("/api/user/subscriptions");
4224
+ if (opts.json) {
4225
+ console.log(JSON.stringify(data, null, 2));
4226
+ return;
4227
+ }
4228
+ if (data.subscriptions.length === 0) {
4229
+ console.log(" No subscriptions yet.");
4230
+ return;
4231
+ }
4232
+ const table = renderTable(
4233
+ [
4234
+ { key: "login", label: "AUTHOR", width: 24 },
4235
+ { key: "name", label: "NAME", width: 24 },
4236
+ { key: "since", label: "SINCE", width: 20 }
4237
+ ],
4238
+ data.subscriptions.map((s) => ({
4239
+ login: s.author.github_login,
4240
+ name: s.author.name || `${GRAY}\u2014${RESET}`,
4241
+ since: new Date(s.created_at).toLocaleDateString()
4242
+ }))
4243
+ );
4244
+ console.log(table);
4245
+ console.log(`
4246
+ ${GRAY}${data.subscriptions.length} subscription(s)${RESET}`);
4247
+ } catch (err) {
4248
+ handleError5(err);
4249
+ }
4250
+ });
4251
+ }
4252
+
4148
4253
  // src/index.ts
4149
4254
  var require2 = createRequire(import.meta.url);
4150
4255
  var { version } = require2("../package.json");
@@ -4171,4 +4276,5 @@ registerDiscoverCommand(program);
4171
4276
  registerCallCommand(program);
4172
4277
  registerConfigCommand(program);
4173
4278
  registerStatsCommand(program);
4279
+ registerSubscribeCommand(program);
4174
4280
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@annals/agent-mesh",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "CLI bridge connecting local AI agents to the Agents.Hot platform",
5
5
  "type": "module",
6
6
  "bin": {