@annals/agent-mesh 0.12.1 → 0.13.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 +100 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -410,7 +410,9 @@ var BridgeManager = class {
410
410
  }
411
411
  }
412
412
  wireSession(handle, sessionId, requestRef) {
413
+ let fullResponseBuffer = "";
413
414
  handle.onChunk((delta) => {
415
+ fullResponseBuffer += delta;
414
416
  const chunk = {
415
417
  type: "chunk",
416
418
  session_id: sessionId,
@@ -438,10 +440,12 @@ var BridgeManager = class {
438
440
  type: "done",
439
441
  session_id: sessionId,
440
442
  request_id: requestRef.requestId,
441
- ...attachments && attachments.length > 0 && { attachments }
443
+ ...attachments && attachments.length > 0 && { attachments },
444
+ ...fullResponseBuffer && { result: fullResponseBuffer }
442
445
  };
443
446
  this.trackRequest(sessionId, requestRef.requestId, "done");
444
447
  this.wsClient.send(done);
448
+ fullResponseBuffer = "";
445
449
  this.sessionLastSeenAt.set(sessionId, Date.now());
446
450
  const fileInfo = attachments && attachments.length > 0 ? ` (${attachments.length} files)` : "";
447
451
  log.info(`Request done: session=${sessionId.slice(0, 8)}... request=${requestRef.requestId.slice(0, 8)}...${fileInfo}`);
@@ -551,8 +555,14 @@ var AgentAdapter = class {
551
555
  };
552
556
 
553
557
  // src/utils/client-workspace.ts
554
- import { mkdirSync, readdirSync, symlinkSync, existsSync } from "fs";
558
+ import { mkdirSync, readdirSync, symlinkSync, existsSync, lstatSync } from "fs";
555
559
  import { join, relative } from "path";
560
+ var SYMLINK_ALLOW = /* @__PURE__ */ new Set([
561
+ "CLAUDE.md",
562
+ ".claude",
563
+ ".agents",
564
+ "src"
565
+ ]);
556
566
  var SYMLINK_EXCLUDE = /* @__PURE__ */ new Set([
557
567
  ".bridge-clients",
558
568
  ".git",
@@ -563,20 +573,31 @@ var SYMLINK_EXCLUDE = /* @__PURE__ */ new Set([
563
573
  "build",
564
574
  "coverage",
565
575
  ".turbo",
566
- ".env"
576
+ ".env",
577
+ "connect.log",
578
+ "skills",
579
+ "skills-lock.json"
567
580
  ]);
568
- function shouldExclude(name) {
569
- 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;
570
586
  }
571
587
  function createClientWorkspace(projectPath, clientId) {
572
588
  const wsDir = join(projectPath, ".bridge-clients", clientId);
573
- if (existsSync(wsDir)) return wsDir;
589
+ const isNew = !existsSync(wsDir);
574
590
  mkdirSync(wsDir, { recursive: true });
575
591
  const entries = readdirSync(projectPath, { withFileTypes: true });
576
592
  for (const entry of entries) {
577
- if (shouldExclude(entry.name)) continue;
578
- const target = join(projectPath, entry.name);
593
+ if (!shouldInclude(entry.name)) continue;
579
594
  const link = join(wsDir, entry.name);
595
+ try {
596
+ lstatSync(link);
597
+ continue;
598
+ } catch {
599
+ }
600
+ const target = join(projectPath, entry.name);
580
601
  const relTarget = relative(wsDir, target);
581
602
  try {
582
603
  symlinkSync(relTarget, link);
@@ -584,7 +605,9 @@ function createClientWorkspace(projectPath, clientId) {
584
605
  log.warn(`Failed to create symlink ${link} \u2192 ${relTarget}: ${err}`);
585
606
  }
586
607
  }
587
- log.info(`Client workspace created: ${wsDir}`);
608
+ if (isNew) {
609
+ log.info(`Client workspace created: ${wsDir}`);
610
+ }
588
611
  return wsDir;
589
612
  }
590
613
 
@@ -2897,7 +2920,68 @@ function parseSseChunk(raw, carry) {
2897
2920
 
2898
2921
  // src/commands/chat.ts
2899
2922
  var DEFAULT_BASE_URL3 = "https://agents.hot";
2923
+ function sleep4(ms) {
2924
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
2925
+ }
2926
+ async function asyncChat(opts) {
2927
+ const res = await fetch(`${opts.baseUrl}/api/agents/${opts.agentId}/chat`, {
2928
+ method: "POST",
2929
+ headers: {
2930
+ Authorization: `Bearer ${opts.token}`,
2931
+ "Content-Type": "application/json"
2932
+ },
2933
+ body: JSON.stringify({ message: opts.message, mode: "async" }),
2934
+ signal: opts.signal
2935
+ });
2936
+ if (!res.ok) {
2937
+ let msg = `HTTP ${res.status}`;
2938
+ try {
2939
+ const body = await res.json();
2940
+ msg = body.message || body.error || msg;
2941
+ } catch {
2942
+ }
2943
+ throw new Error(msg);
2944
+ }
2945
+ const { task_id, status, error_message, error_code } = await res.json();
2946
+ if (status === "failed") {
2947
+ throw new Error(`Task failed: ${error_message || error_code}`);
2948
+ }
2949
+ process.stderr.write(`${GRAY}[async] task=${task_id.slice(0, 8)}... polling${RESET}`);
2950
+ const maxWait = 5 * 60 * 1e3;
2951
+ const pollInterval = 2e3;
2952
+ const startTime = Date.now();
2953
+ while (Date.now() - startTime < maxWait) {
2954
+ if (opts.signal?.aborted) throw new Error("Aborted");
2955
+ await sleep4(pollInterval);
2956
+ const pollRes = await fetch(`${opts.baseUrl}/api/tasks/${task_id}`, {
2957
+ headers: { Authorization: `Bearer ${opts.token}` },
2958
+ signal: opts.signal
2959
+ });
2960
+ if (!pollRes.ok) {
2961
+ throw new Error(`Poll failed: HTTP ${pollRes.status}`);
2962
+ }
2963
+ const task = await pollRes.json();
2964
+ if (task.status === "completed") {
2965
+ process.stderr.write(` done
2966
+ `);
2967
+ process.stdout.write((task.result || "") + "\n");
2968
+ return;
2969
+ }
2970
+ if (task.status === "failed") {
2971
+ process.stderr.write(` failed
2972
+ `);
2973
+ throw new Error(`Task failed: ${task.error_message || task.error_code}`);
2974
+ }
2975
+ process.stderr.write(".");
2976
+ }
2977
+ process.stderr.write(` timeout
2978
+ `);
2979
+ throw new Error("Task timed out waiting for result");
2980
+ }
2900
2981
  async function streamChat(opts) {
2982
+ if ((opts.mode ?? "async") === "async") {
2983
+ return asyncChat(opts);
2984
+ }
2901
2985
  const res = await fetch(`${opts.baseUrl}/api/agents/${opts.agentId}/chat`, {
2902
2986
  method: "POST",
2903
2987
  headers: {
@@ -2998,7 +3082,7 @@ ${"\x1B[31m"}Error: ${event.errorText}${RESET}
2998
3082
  }
2999
3083
  }
3000
3084
  function registerChatCommand(program2) {
3001
- program2.command("chat <agent> [message]").description("Chat with an agent through the platform (for debugging)").option("--no-thinking", "Hide thinking/reasoning output").option("--base-url <url>", "Platform base URL", DEFAULT_BASE_URL3).action(async (agentInput, inlineMessage, opts) => {
3085
+ program2.command("chat <agent> [message]").description("Chat with an agent through the platform (for debugging)").option("--no-thinking", "Hide thinking/reasoning output").option("--stream", "Force SSE streaming mode (default is async)").option("--base-url <url>", "Platform base URL", DEFAULT_BASE_URL3).action(async (agentInput, inlineMessage, opts) => {
3002
3086
  const token = loadToken();
3003
3087
  if (!token) {
3004
3088
  log.error("Not authenticated. Run `agent-mesh login` first.");
@@ -3015,15 +3099,17 @@ function registerChatCommand(program2) {
3015
3099
  log.error(err.message);
3016
3100
  process.exit(1);
3017
3101
  }
3102
+ const mode = opts.stream ? "stream" : "async";
3018
3103
  if (inlineMessage) {
3019
- log.info(`Chatting with ${BOLD}${agentName}${RESET}`);
3104
+ log.info(`Chatting with ${BOLD}${agentName}${RESET} (${mode})`);
3020
3105
  try {
3021
3106
  await streamChat({
3022
3107
  agentId,
3023
3108
  message: inlineMessage,
3024
3109
  token,
3025
3110
  baseUrl: opts.baseUrl,
3026
- showThinking: opts.thinking
3111
+ showThinking: opts.thinking,
3112
+ mode
3027
3113
  });
3028
3114
  } catch (err) {
3029
3115
  log.error(err.message);
@@ -3067,7 +3153,8 @@ function registerChatCommand(program2) {
3067
3153
  message: trimmed,
3068
3154
  token,
3069
3155
  baseUrl: opts.baseUrl,
3070
- showThinking: opts.thinking
3156
+ showThinking: opts.thinking,
3157
+ mode
3071
3158
  });
3072
3159
  } catch (err) {
3073
3160
  if (abortController.signal.aborted) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@annals/agent-mesh",
3
- "version": "0.12.1",
3
+ "version": "0.13.1",
4
4
  "description": "CLI bridge connecting local AI agents to the Agents.Hot platform",
5
5
  "type": "module",
6
6
  "bin": {