@agentmeshhq/agent 0.1.11 → 0.1.12

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 (47) hide show
  1. package/dist/__tests__/injector.test.d.ts +1 -0
  2. package/dist/__tests__/injector.test.js +26 -0
  3. package/dist/__tests__/injector.test.js.map +1 -0
  4. package/dist/cli/build.d.ts +6 -0
  5. package/dist/cli/build.js +111 -0
  6. package/dist/cli/build.js.map +1 -0
  7. package/dist/cli/deploy.d.ts +9 -0
  8. package/dist/cli/deploy.js +130 -0
  9. package/dist/cli/deploy.js.map +1 -0
  10. package/dist/cli/index.js +155 -0
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/cli/local.d.ts +9 -0
  13. package/dist/cli/local.js +139 -0
  14. package/dist/cli/local.js.map +1 -0
  15. package/dist/cli/migrate.d.ts +8 -0
  16. package/dist/cli/migrate.js +167 -0
  17. package/dist/cli/migrate.js.map +1 -0
  18. package/dist/cli/slack.d.ts +3 -0
  19. package/dist/cli/slack.js +57 -0
  20. package/dist/cli/slack.js.map +1 -0
  21. package/dist/cli/start.d.ts +4 -0
  22. package/dist/cli/start.js +5 -0
  23. package/dist/cli/start.js.map +1 -1
  24. package/dist/cli/test.d.ts +8 -0
  25. package/dist/cli/test.js +110 -0
  26. package/dist/cli/test.js.map +1 -0
  27. package/dist/core/daemon.d.ts +12 -0
  28. package/dist/core/daemon.js +96 -27
  29. package/dist/core/daemon.js.map +1 -1
  30. package/dist/core/injector.d.ts +6 -1
  31. package/dist/core/injector.js +64 -1
  32. package/dist/core/injector.js.map +1 -1
  33. package/dist/core/tmux.js +8 -10
  34. package/dist/core/tmux.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/__tests__/injector.test.ts +29 -0
  37. package/src/cli/build.ts +137 -0
  38. package/src/cli/deploy.ts +153 -0
  39. package/src/cli/index.ts +156 -0
  40. package/src/cli/local.ts +174 -0
  41. package/src/cli/migrate.ts +210 -0
  42. package/src/cli/slack.ts +69 -0
  43. package/src/cli/start.ts +8 -0
  44. package/src/cli/test.ts +141 -0
  45. package/src/core/daemon.ts +118 -35
  46. package/src/core/injector.ts +98 -1
  47. package/src/core/tmux.ts +9 -11
@@ -1,3 +1,5 @@
1
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
1
3
  import { formatHandoffContextSummary, parseHandoffContext } from "../context/handoff.js";
2
4
  import type { AgentContext } from "../context/schema.js";
3
5
  import type { InboxItem } from "./registry.js";
@@ -65,6 +67,85 @@ You can now proceed with your work.`;
65
67
  sendKeys(agentName, message);
66
68
  }
67
69
 
70
+ export interface EventContext {
71
+ hubUrl?: string;
72
+ token?: string;
73
+ }
74
+
75
+ interface SlackFile {
76
+ name: string;
77
+ type: string;
78
+ url: string;
79
+ permalink: string;
80
+ base64?: string;
81
+ mediaType?: string;
82
+ }
83
+
84
+ export function injectSlackMessage(
85
+ agentName: string,
86
+ event: WebSocketEvent,
87
+ context?: EventContext,
88
+ ): void {
89
+ const user = (event.user as string) || "unknown";
90
+ const channel = (event.channel as string) || "unknown";
91
+ const text = (event.text as string) || "";
92
+ const files = (event.files as SlackFile[] | undefined) || [];
93
+
94
+ // Build message with file info
95
+ let message = `[Slack from ${user} in ${channel}] ${text}`;
96
+
97
+ if (files.length > 0) {
98
+ const savedImages: string[] = [];
99
+ const otherFiles: string[] = [];
100
+
101
+ // Save images with base64 data to disk
102
+ const attachmentsDir = join(process.env.HOME || "/tmp", ".agentmesh", "attachments");
103
+ if (!existsSync(attachmentsDir)) {
104
+ mkdirSync(attachmentsDir, { recursive: true });
105
+ }
106
+
107
+ for (const f of files) {
108
+ console.log(
109
+ `[Injector] File: ${f.name}, type: ${f.type}, mediaType: ${f.mediaType}, has base64: ${!!f.base64}`,
110
+ );
111
+ if (f.base64 && (f.mediaType?.startsWith("image/") || f.type?.startsWith("image/"))) {
112
+ // Save image to disk
113
+ const timestamp = Date.now();
114
+ const safeName = f.name.replace(/[^a-zA-Z0-9._-]/g, "_");
115
+ const filePath = join(attachmentsDir, `${timestamp}-${safeName}`);
116
+
117
+ try {
118
+ writeFileSync(filePath, Buffer.from(f.base64, "base64"));
119
+ savedImages.push(filePath);
120
+ console.log(`[Injector] Saved image to: ${filePath}`);
121
+ } catch (err) {
122
+ console.error(`[Injector] Failed to save image:`, err);
123
+ otherFiles.push(`${f.name} (failed to save)`);
124
+ }
125
+ } else {
126
+ // Just reference the URL for non-image files
127
+ otherFiles.push(`${f.name}: ${f.permalink}`);
128
+ }
129
+ }
130
+
131
+ // Add instruction to view images - OpenCode needs explicit instruction
132
+ if (savedImages.length > 0) {
133
+ message += `\n\nUser attached ${savedImages.length} image(s). Use the Read tool to view them:`;
134
+ for (const img of savedImages) {
135
+ message += `\n- ${img}`;
136
+ }
137
+ }
138
+
139
+ if (otherFiles.length > 0) {
140
+ message += ` [Other files: ${otherFiles.join(" | ")}]`;
141
+ }
142
+ }
143
+
144
+ console.log(`[Injector] Sending to tmux: ${message}`);
145
+ const result = sendKeys(agentName, message);
146
+ console.log(`[Injector] sendKeys result: ${result}`);
147
+ }
148
+
68
149
  export function injectInboxItems(agentName: string, items: InboxItem[]): void {
69
150
  if (items.length === 0) {
70
151
  sendKeys(agentName, "[AgentMesh] Your inbox is empty.");
@@ -85,7 +166,11 @@ export function injectInboxItems(agentName: string, items: InboxItem[]): void {
85
166
  sendKeys(agentName, message);
86
167
  }
87
168
 
88
- export function handleWebSocketEvent(agentName: string, event: WebSocketEvent): void {
169
+ export function handleWebSocketEvent(
170
+ agentName: string,
171
+ event: WebSocketEvent,
172
+ context?: EventContext,
173
+ ): void {
89
174
  switch (event.type) {
90
175
  case "handoff_received":
91
176
  case "handoff.received":
@@ -102,6 +187,18 @@ export function handleWebSocketEvent(agentName: string, event: WebSocketEvent):
102
187
  injectBlockerResolved(agentName, event);
103
188
  break;
104
189
 
190
+ case "slack.message":
191
+ console.log(`[Injector] Handling slack.message for ${agentName}`);
192
+ console.log(`[Injector] Event keys: ${Object.keys(event).join(", ")}`);
193
+ if (event.files) {
194
+ const files = event.files as Array<{ name: string; base64?: string }>;
195
+ console.log(
196
+ `[Injector] Files count: ${files.length}, has base64: ${files.some((f) => !!f.base64)}`,
197
+ );
198
+ }
199
+ injectSlackMessage(agentName, event, context);
200
+ break;
201
+
105
202
  default:
106
203
  // Unknown event type, ignore
107
204
  break;
package/src/core/tmux.ts CHANGED
@@ -56,7 +56,8 @@ export function createSession(
56
56
 
57
57
  const fullCommand = `${envPrefix}${command}`;
58
58
 
59
- const args = ["new-session", "-d", "-s", sessionName];
59
+ // Set reasonable terminal size for TUI applications
60
+ const args = ["new-session", "-d", "-s", sessionName, "-x", "200", "-y", "50"];
60
61
 
61
62
  if (workdir) {
62
63
  args.push("-c", workdir);
@@ -128,16 +129,13 @@ export function sendKeys(agentName: string, message: string): boolean {
128
129
  }
129
130
 
130
131
  try {
131
- // Escape special characters for tmux
132
- const escapedMessage = message
133
- .replace(/\\/g, "\\\\")
134
- .replace(/"/g, '\\"')
135
- .replace(/\$/g, "\\$")
136
- .replace(/`/g, "\\`");
137
-
138
- // Send the message, then press Enter separately to submit to the AI
139
- execSync(`tmux send-keys -t "${sessionName}" "${escapedMessage}"`);
140
- execSync(`tmux send-keys -t "${sessionName}" Enter`);
132
+ // Replace newlines with " | " to keep message on single line (newlines would act as Enter)
133
+ const cleanMessage = message.replace(/\n/g, " | ");
134
+
135
+ // Use execFileSync with array args to avoid shell escaping issues
136
+ // The -l flag sends keys literally
137
+ execFileSync("tmux", ["send-keys", "-t", sessionName, "-l", cleanMessage]);
138
+ execFileSync("tmux", ["send-keys", "-t", sessionName, "Enter"]);
141
139
  return true;
142
140
  } catch (error) {
143
141
  console.error(`Failed to send keys: ${error}`);