@siftd/connect-agent 0.2.54 → 0.2.56

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.
package/dist/agent.js CHANGED
@@ -415,8 +415,15 @@ export async function runAgent(pollInterval = 2000) {
415
415
  });
416
416
  // Worker results - send to user when workers complete
417
417
  orchestrator.setWorkerResultCallback((workerId, result) => {
418
- console.log(`[WORKER DONE] ${workerId}: ${result.slice(0, 100)}...`);
419
- if (wsClient?.connected()) {
418
+ const trimmed = result.trim();
419
+ const lower = trimmed.toLowerCase();
420
+ const shouldSuppress = !trimmed ||
421
+ trimmed === '(No output)' ||
422
+ lower.startsWith('worker timed out') ||
423
+ lower.startsWith('worker error') ||
424
+ lower.includes('partial output: none');
425
+ console.log(`[WORKER DONE] ${workerId}: ${trimmed.slice(0, 100)}${shouldSuppress ? ' (suppressed)' : ''}`);
426
+ if (!shouldSuppress && wsClient?.connected()) {
420
427
  // Send as response with worker ID as message ID
421
428
  wsClient.sendResponse(workerId, `**Worker completed:**\n\n${result}`);
422
429
  }
@@ -721,9 +721,14 @@ export class MasterOrchestrator {
721
721
  return lines.join('\n');
722
722
  }
723
723
  stripTodoSnapshot(message) {
724
- const marker = '\n\nTODO SNAPSHOT';
725
- const index = message.indexOf(marker);
726
- return index === -1 ? message : message.slice(0, index);
724
+ const markers = ['\n\nTODO SNAPSHOT', '\n\nRECENT CONVERSATION'];
725
+ const indices = markers
726
+ .map((marker) => message.indexOf(marker))
727
+ .filter((index) => index !== -1);
728
+ if (indices.length === 0)
729
+ return message;
730
+ const earliest = Math.min(...indices);
731
+ return message.slice(0, earliest);
727
732
  }
728
733
  hasTodoMutation(message) {
729
734
  const lower = this.stripTodoSnapshot(message).toLowerCase();
@@ -736,13 +741,16 @@ export class MasterOrchestrator {
736
741
  const lower = this.stripTodoSnapshot(message).toLowerCase();
737
742
  const target = /(^|\s)\/cal\b|\/calendar\b|\bcalendar\b|\bcal\b|\bschedule\b|\bagenda\b/.test(lower);
738
743
  const action = /\b(add|create|schedule|book|move|reschedule|update|change|cancel|delete|remove|set|put|place|remind)\b/.test(lower);
744
+ const dateCue = /\b(today|tomorrow|tonight|next|this\s+(week|month|year)|mon(day)?|tue(sday)?|wed(nesday)?|thu(rsday)?|fri(day)?|sat(urday)?|sun(day)?|\b\d{1,2}(:\d{2})?\s?(am|pm)\b|\b\d{1,2}\/\d{1,2}\b|\b\d{4}-\d{2}-\d{2}\b)\b/.test(lower);
745
+ const eventCue = /\b(meeting|call|appointment|event|reminder|session|class|lecture|review|deadline)\b/.test(lower);
746
+ const implicitTarget = eventCue && dateCue;
739
747
  const query = /\b(what|show|list|open|view|see)\b/.test(lower);
740
- return target && action && !query;
748
+ return (target || implicitTarget) && action && !query;
741
749
  }
742
750
  hasFileMutation(message) {
743
751
  const lower = this.stripTodoSnapshot(message).toLowerCase();
744
752
  const target = /(^|\s)\/files\b|\bfiles?\b/.test(lower);
745
- const action = /\b(create|make|write|save|generate|export|upload|attach|produce|edit|update|modify|delete|remove)\b/.test(lower);
753
+ const action = /\b(create|make|write|save|generate|export|upload|attach|produce|edit|update|modify|delete|remove|add|append|insert|include)\b/.test(lower);
746
754
  const query = /\b(what|show|list|open|view|see|browse|find)\b/.test(lower);
747
755
  return target && action && !query;
748
756
  }
@@ -947,14 +955,15 @@ export class MasterOrchestrator {
947
955
  * Process a user message
948
956
  */
949
957
  async processMessage(message, conversationHistory = [], sendMessage) {
950
- this.lastUserMessage = message;
958
+ const cleanMessage = this.stripTodoSnapshot(message);
959
+ this.lastUserMessage = cleanMessage;
951
960
  // Handle slash commands first
952
- const slashResponse = this.handleSlashCommand(message);
961
+ const slashResponse = this.handleSlashCommand(cleanMessage);
953
962
  if (slashResponse) {
954
963
  return slashResponse;
955
964
  }
956
- this.updateFileScope(message);
957
- const wantsTodoOrCal = this.hasTodoMutation(message) || this.hasCalendarMutation(message);
965
+ this.updateFileScope(cleanMessage);
966
+ const wantsTodoOrCal = this.hasTodoMutation(cleanMessage) || this.hasCalendarMutation(cleanMessage);
958
967
  if (wantsTodoOrCal) {
959
968
  this.attachmentContext = this.extractAttachmentContext(message);
960
969
  const toolMessages = [{ role: 'user', content: message }];
@@ -976,11 +985,11 @@ export class MasterOrchestrator {
976
985
  // return quickWrite;
977
986
  // }
978
987
  // Load hub context (AGENTS.md identity, LANDMARKS.md state, project bio if relevant)
979
- const hubContext = loadHubContext(message);
988
+ const hubContext = loadHubContext(cleanMessage);
980
989
  const hubContextStr = formatHubContext(hubContext);
981
990
  this.attachmentContext = this.extractAttachmentContext(message);
982
991
  // Build context from memory
983
- const memoryContext = await this.getMemoryContext(message);
992
+ const memoryContext = await this.getMemoryContext(cleanMessage);
984
993
  // Build system prompt with hub context, genesis knowledge, and memory context
985
994
  const genesisKnowledge = getKnowledgeForPrompt();
986
995
  let systemWithContext = SYSTEM_PROMPT;
@@ -1018,11 +1027,11 @@ ${hubContextStr}
1018
1027
  try {
1019
1028
  const response = await this.runAgentLoop(messages, systemWithContext, sendMessage);
1020
1029
  // Auto-remember important things from the conversation
1021
- await this.autoRemember(message, response);
1022
- void this.autoCaptureContext(message);
1030
+ await this.autoRemember(cleanMessage, response);
1031
+ void this.autoCaptureContext(cleanMessage);
1023
1032
  // Log significant actions to hub
1024
1033
  if (response.length > 100) {
1025
- const action = message.length > 50 ? message.slice(0, 50) + '...' : message;
1034
+ const action = cleanMessage.length > 50 ? cleanMessage.slice(0, 50) + '...' : cleanMessage;
1026
1035
  logAction(action, hubContext.projectName || undefined, `Response: ${response.length} chars`);
1027
1036
  }
1028
1037
  return response;
@@ -2241,6 +2250,11 @@ Unlike lia_plan (internal only), this creates a VISIBLE todo list that appears i
2241
2250
  try {
2242
2251
  const pathValue = String(input.path || '').trim();
2243
2252
  const content = String(input.content || '');
2253
+ const allowEmpty = /\b(empty|blank|placeholder)\b/i.test(this.lastUserMessage || '');
2254
+ if (!content.trim() && !allowEmpty) {
2255
+ result = { success: false, output: '', error: 'Refusing to write empty file content.' };
2256
+ break;
2257
+ }
2244
2258
  const targetPath = this.resolveFilesWritePath(pathValue);
2245
2259
  mkdirSync(dirname(targetPath), { recursive: true });
2246
2260
  writeFileSync(targetPath, content, 'utf8');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siftd/connect-agent",
3
- "version": "0.2.54",
3
+ "version": "0.2.56",
4
4
  "description": "Master orchestrator agent - control Claude Code remotely via web",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",