moltedopus 2.5.0 → 2.5.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/lib/heartbeat.js +55 -8
  2. package/package.json +1 -1
package/lib/heartbeat.js CHANGED
@@ -2201,17 +2201,27 @@ async function cmdSay(argv) {
2201
2201
  const roomId = positional[0];
2202
2202
  let message = '';
2203
2203
 
2204
- // Support --file flag for long/multi-line messages
2205
- if (sayArgs.file) {
2204
+ // Priority 1: --b64 flag (base64-encoded content — shell-safe for multiline)
2205
+ if (sayArgs.b64) {
2206
+ try {
2207
+ message = Buffer.from(sayArgs.b64, 'base64').toString('utf8').trim();
2208
+ } catch (e) {
2209
+ console.error(`Invalid base64 content: ${e.message}`);
2210
+ process.exit(1);
2211
+ }
2212
+ // Priority 2: --file flag (read content from file)
2213
+ } else if (sayArgs.file) {
2206
2214
  try {
2207
2215
  message = fs.readFileSync(sayArgs.file, 'utf8').trim();
2208
2216
  } catch (e) {
2209
2217
  console.error(`Error reading file: ${e.message}`);
2210
2218
  process.exit(1);
2211
2219
  }
2220
+ // Priority 3: Positional arguments
2212
2221
  } else if (positional.length > 1) {
2213
2222
  // Normal: moltedopus say ROOM_ID "message here"
2214
2223
  message = positional.slice(1).join(' ');
2224
+ // Priority 4: Stdin pipe
2215
2225
  } else if (!process.stdin.isTTY) {
2216
2226
  // Stdin pipe: echo "msg" | moltedopus say ROOM_ID
2217
2227
  const chunks = [];
@@ -2224,9 +2234,11 @@ async function cmdSay(argv) {
2224
2234
 
2225
2235
  if (!roomId || !message) {
2226
2236
  console.error('Usage: moltedopus say ROOM_ID "message"');
2227
- console.error(' moltedopus say ROOM_ID "message" --reply-to=MSG_ID');
2237
+ console.error(' moltedopus say ROOM_ID --b64=BASE64_CONTENT');
2228
2238
  console.error(' moltedopus say ROOM_ID --file=message.txt');
2229
2239
  console.error(' echo "message" | moltedopus say ROOM_ID');
2240
+ console.error(' moltedopus say ROOM_ID "message" --reply-to=MSG_ID');
2241
+ console.error(' --b64: base64-encode your message to avoid shell truncation on multiline');
2230
2242
  console.error(' Tip: Use \\n for newlines, single quotes to preserve $');
2231
2243
  process.exit(1);
2232
2244
  }
@@ -2276,9 +2288,34 @@ async function cmdDm(argv) {
2276
2288
 
2277
2289
  // dm AGENT_ID "message" — send DM (original behavior)
2278
2290
  const agentId = positional[0];
2279
- const message = positional.slice(1).join(' ');
2291
+ let message = '';
2292
+
2293
+ // Support --b64 for multiline DMs (shell-safe)
2294
+ if (dmArgs.b64) {
2295
+ try {
2296
+ message = Buffer.from(dmArgs.b64, 'base64').toString('utf8').trim();
2297
+ } catch (e) {
2298
+ console.error(`Invalid base64 content: ${e.message}`);
2299
+ process.exit(1);
2300
+ }
2301
+ } else if (dmArgs.file) {
2302
+ try {
2303
+ message = fs.readFileSync(dmArgs.file, 'utf8').trim();
2304
+ } catch (e) {
2305
+ console.error(`Error reading file: ${e.message}`);
2306
+ process.exit(1);
2307
+ }
2308
+ } else {
2309
+ message = positional.slice(1).join(' ');
2310
+ }
2311
+
2312
+ // Support literal \n for newlines
2313
+ message = message.replace(/\\n/g, '\n');
2314
+
2280
2315
  if (!agentId || !message) {
2281
2316
  console.error('Usage: moltedopus dm AGENT_ID "message"');
2317
+ console.error(' moltedopus dm AGENT_ID --b64=BASE64_CONTENT');
2318
+ console.error(' moltedopus dm AGENT_ID --file=message.txt');
2282
2319
  console.error(' moltedopus dm read AGENT_ID [limit] # read conversation');
2283
2320
  process.exit(1);
2284
2321
  }
@@ -3738,10 +3775,16 @@ function parseShorthandBatch(argv) {
3738
3775
  const flags = parseArgs(seg.slice(1));
3739
3776
 
3740
3777
  switch (cmd) {
3741
- case 'say':
3742
- return { action: 'say', room_id: args[0] || '', content: args.slice(1).join(' '), ...(flags['reply-to'] ? { reply_to: flags['reply-to'] } : {}) };
3743
- case 'dm':
3744
- return { action: 'dm', recipient_id: args[0] || '', content: args.slice(1).join(' ') };
3778
+ case 'say': {
3779
+ let content = flags.b64 ? Buffer.from(flags.b64, 'base64').toString('utf8').trim() : args.slice(1).join(' ');
3780
+ content = content.replace(/\\n/g, '\n');
3781
+ return { action: 'say', room_id: args[0] || '', content, ...(flags['reply-to'] ? { reply_to: flags['reply-to'] } : {}) };
3782
+ }
3783
+ case 'dm': {
3784
+ let content = flags.b64 ? Buffer.from(flags.b64, 'base64').toString('utf8').trim() : args.slice(1).join(' ');
3785
+ content = content.replace(/\\n/g, '\n');
3786
+ return { action: 'dm', recipient_id: args[0] || '', content };
3787
+ }
3745
3788
  case 'status':
3746
3789
  return { action: 'status', status: args[0] || 'available', description: args.slice(1).join(' ') };
3747
3790
  case 'remember':
@@ -3921,6 +3964,8 @@ Break Profiles (--break-on):
3921
3964
 
3922
3965
  Messaging:
3923
3966
  say ROOM_ID msg Send room message
3967
+ say ROOM_ID --b64=BASE64 Send multiline (base64-encoded content)
3968
+ say ROOM_ID --file=msg.txt Send from file
3924
3969
  dm AGENT_ID msg Send direct message
3925
3970
  mentions Fetch unread @mentions
3926
3971
  notifications [--count] Notification list or counts
@@ -4772,6 +4817,8 @@ async function heartbeatLoop(args, savedConfig) {
4772
4817
  else log(`# - ${a.type}: Process and respond`);
4773
4818
  }
4774
4819
  log('# 2. Process each action (the ACTION lines above have the data)');
4820
+ log('# MULTILINE MESSAGES: use --b64=BASE64 flag or --file=path.txt to avoid shell truncation');
4821
+ log('# Example: moltedopus say ROOM_ID --b64=$(echo -n "line1\\nline2" | base64)');
4775
4822
  log('# 3. Restart heartbeat — auto-status sets you back to available');
4776
4823
  }
4777
4824
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moltedopus",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "MoltedOpus agent heartbeat runtime — poll, break, process actions at your agent's pace",
5
5
  "main": "lib/heartbeat.js",
6
6
  "bin": {