@siftd/connect-agent 0.2.44 → 0.2.46

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.
@@ -71,6 +71,8 @@ export declare class MasterOrchestrator {
71
71
  private workspaceDir;
72
72
  private claudePath;
73
73
  private initialized;
74
+ private currentFileScope;
75
+ private forceTeamWorkingDir;
74
76
  private bashTool;
75
77
  private webTools;
76
78
  private workerTools;
@@ -194,6 +196,10 @@ export declare class MasterOrchestrator {
194
196
  private hasExplicitDate;
195
197
  private getToolChoice;
196
198
  private withAttachments;
199
+ private updateFileScope;
200
+ private getTeamFilesDir;
201
+ private getFileScopeOverrides;
202
+ private getFileScopeSystemNote;
197
203
  /**
198
204
  * Check if verbose mode is enabled
199
205
  */
@@ -7,6 +7,7 @@
7
7
  import Anthropic from '@anthropic-ai/sdk';
8
8
  import { spawn, execSync } from 'child_process';
9
9
  import { existsSync, readFileSync } from 'fs';
10
+ import { join } from 'path';
10
11
  import { AdvancedMemoryStore } from './core/memory-advanced.js';
11
12
  import { PostgresMemoryStore, isPostgresConfigured } from './core/memory-postgres.js';
12
13
  import { TaskScheduler } from './core/scheduler.js';
@@ -146,6 +147,7 @@ FILES SCOPES:
146
147
  - "My Files" are private to the user (default /files view)
147
148
  - "Team Files" are shared across the org (use /files team or the Team Files location)
148
149
  - If a user asks to share with the team, store outputs in Team Files and mention that it is shared
150
+ - When a TEAM FILES DIRECTORY note is present, save shared outputs there
149
151
 
150
152
  CALENDAR + TODO (Lia-managed data):
151
153
  - /cal reads ~/Lia-Hub/shared/outputs/.lia/calendar.json
@@ -209,6 +211,8 @@ export class MasterOrchestrator {
209
211
  workspaceDir;
210
212
  claudePath;
211
213
  initialized = false;
214
+ currentFileScope = 'personal';
215
+ forceTeamWorkingDir = false;
212
216
  // New tools from whatsapp-claude
213
217
  bashTool;
214
218
  webTools;
@@ -716,6 +720,51 @@ export class MasterOrchestrator {
716
720
  }
717
721
  return { task: `${task}\n\n${attachmentNote}` };
718
722
  }
723
+ updateFileScope(message) {
724
+ const marker = '📎 Attached files:';
725
+ const base = message.split(marker)[0]?.trim() || message;
726
+ const lowered = base.toLowerCase();
727
+ const mentionsTeam = /\b(team files|shared files|share with team|team folder|team drive|org files|company files)\b/i.test(lowered);
728
+ const mentionsPersonal = /\b(my files|personal files|private files)\b/i.test(lowered);
729
+ let scope = this.instanceMode === 'team' ? 'team' : 'personal';
730
+ if (mentionsTeam)
731
+ scope = 'team';
732
+ if (mentionsPersonal)
733
+ scope = 'personal';
734
+ this.currentFileScope = scope;
735
+ this.forceTeamWorkingDir = mentionsTeam;
736
+ }
737
+ getTeamFilesDir() {
738
+ if (!this.orgId)
739
+ return null;
740
+ const envDir = process.env.LIA_TEAM_FILES_DIR || process.env.CONNECT_TEAM_FILES_DIR;
741
+ if (envDir && envDir.trim())
742
+ return envDir.trim();
743
+ const dataDir = process.env.DATA_DIR || '/data';
744
+ if (!existsSync(dataDir))
745
+ return null;
746
+ return join(dataDir, 'orgs', this.orgId, 'shared');
747
+ }
748
+ getFileScopeOverrides() {
749
+ if (this.currentFileScope !== 'team')
750
+ return {};
751
+ const teamDir = this.getTeamFilesDir();
752
+ if (!teamDir)
753
+ return {};
754
+ const hasTeamDir = existsSync(teamDir);
755
+ return {
756
+ workingDir: this.forceTeamWorkingDir && hasTeamDir ? teamDir : undefined,
757
+ instructions: `TEAM FILES DIRECTORY: ${teamDir}\nSave any requested files under this directory so they appear in /files (Team Files). Create the directory if needed.`,
758
+ };
759
+ }
760
+ getFileScopeSystemNote() {
761
+ if (this.currentFileScope !== 'team')
762
+ return null;
763
+ const teamDir = this.getTeamFilesDir();
764
+ if (!teamDir)
765
+ return null;
766
+ return `TEAM FILES DIRECTORY:\n- ${teamDir}\nUse this path for files meant to be shared with the team.`;
767
+ }
719
768
  /**
720
769
  * Check if verbose mode is enabled
721
770
  */
@@ -731,6 +780,7 @@ export class MasterOrchestrator {
731
780
  if (slashResponse) {
732
781
  return slashResponse;
733
782
  }
783
+ this.updateFileScope(message);
734
784
  // DISABLED: Dumb regex extraction was creating garbage todos
735
785
  // Let the AI use calendar_upsert_events and todo_upsert_items tools properly
736
786
  // const quickWrite = this.tryHandleCalendarTodo(message);
@@ -768,6 +818,10 @@ ${hubContextStr}
768
818
  if (memoryContext) {
769
819
  systemWithContext += `\n\nRELEVANT MEMORIES:\n${memoryContext}`;
770
820
  }
821
+ const fileScopeNote = this.getFileScopeSystemNote();
822
+ if (fileScopeNote) {
823
+ systemWithContext += `\n\n${fileScopeNote}`;
824
+ }
771
825
  // Add user message
772
826
  const messages = [
773
827
  ...conversationHistory,
@@ -1406,6 +1460,10 @@ and preserve explicit due dates and priority from the user.`,
1406
1460
  type: 'string',
1407
1461
  enum: ['low', 'normal', 'high', 'critical'],
1408
1462
  description: 'Task priority'
1463
+ },
1464
+ working_directory: {
1465
+ type: 'string',
1466
+ description: 'Directory to work in (defaults to user home)'
1409
1467
  }
1410
1468
  },
1411
1469
  required: ['task']
@@ -1852,9 +1910,12 @@ Unlike lia_plan (internal only), this creates a VISIBLE todo list that appears i
1852
1910
  // Worker tools
1853
1911
  case 'spawn_worker': {
1854
1912
  const { task } = this.withAttachments(input.task);
1855
- result = await this.workerTools.spawnWorker(task, {
1913
+ const fileScope = this.getFileScopeOverrides();
1914
+ const scopedTask = fileScope.instructions ? `${fileScope.instructions}\n\n${task}` : task;
1915
+ result = await this.workerTools.spawnWorker(scopedTask, {
1856
1916
  timeout: input.timeout,
1857
- priority: input.priority
1917
+ priority: input.priority,
1918
+ workingDirectory: input.working_directory || fileScope.workingDir
1858
1919
  });
1859
1920
  break;
1860
1921
  }
@@ -1873,7 +1934,8 @@ Unlike lia_plan (internal only), this creates a VISIBLE todo list that appears i
1873
1934
  // Legacy delegate tool
1874
1935
  case 'delegate_to_worker': {
1875
1936
  const { task, context } = this.withAttachments(input.task, input.context);
1876
- result = await this.delegateToWorker(task, context, input.working_directory);
1937
+ const fileScope = this.getFileScopeOverrides();
1938
+ result = await this.delegateToWorker(task, context, input.working_directory || fileScope.workingDir, fileScope.instructions);
1877
1939
  break;
1878
1940
  }
1879
1941
  case 'remember':
@@ -2004,13 +2066,14 @@ Unlike lia_plan (internal only), this creates a VISIBLE todo list that appears i
2004
2066
  * Delegate task to Claude Code CLI worker - NON-BLOCKING
2005
2067
  * Returns immediately, sends results via callback when done
2006
2068
  */
2007
- async delegateToWorker(task, context, workingDir) {
2069
+ async delegateToWorker(task, context, workingDir, customInstructions) {
2008
2070
  const id = `worker_${Date.now()}_${++this.jobCounter}`;
2009
2071
  const cwd = workingDir || this.workspaceDir;
2010
2072
  // Use standardized worker prompt from prompts module
2011
2073
  const prompt = buildWorkerPrompt(task, {
2012
2074
  jobId: id,
2013
- context
2075
+ context,
2076
+ customInstructions
2014
2077
  });
2015
2078
  // Log worker start to hub
2016
2079
  logWorker(id, task, 'started');
@@ -27,6 +27,7 @@ export declare class WorkerTools {
27
27
  spawnWorker(task: string, options?: {
28
28
  timeout?: number;
29
29
  priority?: 'low' | 'normal' | 'high' | 'critical';
30
+ workingDirectory?: string;
30
31
  }): Promise<ToolResult>;
31
32
  /**
32
33
  * Check worker status
@@ -33,7 +33,8 @@ export class WorkerTools {
33
33
  try {
34
34
  const jobId = await this.manager.spawn(task, {
35
35
  timeout: options?.timeout,
36
- priority: options?.priority
36
+ priority: options?.priority,
37
+ workspace: options?.workingDirectory
37
38
  });
38
39
  const job = this.manager.get(jobId);
39
40
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@siftd/connect-agent",
3
- "version": "0.2.44",
3
+ "version": "0.2.46",
4
4
  "description": "Master orchestrator agent - control Claude Code remotely via web",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",