@ash-cloud/ash-ai 0.1.12 → 0.1.13

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/index.d.cts CHANGED
@@ -1331,8 +1331,21 @@ interface FileSyncEventData {
1331
1331
  operation: FileSyncOperation;
1332
1332
  /** Who initiated this operation */
1333
1333
  source: FileSyncSource;
1334
- /** Path of the file */
1335
- filePath: string;
1334
+ /**
1335
+ * Canonical file path - the logical path used as S3 key
1336
+ * Example: "src/Root.tsx"
1337
+ */
1338
+ canonicalPath: string;
1339
+ /**
1340
+ * Base path / target path prefix used in the sandbox
1341
+ * Example: "." (root), ".claude/files" (default), "my-project"
1342
+ */
1343
+ basePath: string;
1344
+ /**
1345
+ * Full computed path in the sandbox
1346
+ * Example: "src/Root.tsx" (if basePath=".") or ".claude/files/src/Root.tsx" (if basePath=".claude/files")
1347
+ */
1348
+ sandboxPath: string;
1336
1349
  /** Size of the file in bytes */
1337
1350
  fileSize?: number;
1338
1351
  /** Whether the operation succeeded */
@@ -4530,14 +4543,31 @@ declare function createMinioFileStore(config: {
4530
4543
  type FileChangeType = 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir';
4531
4544
  /**
4532
4545
  * Event emitted when a file changes in the watched directory
4546
+ *
4547
+ * Path terminology:
4548
+ * - relativePath: Path relative to the watch directory (e.g., "src/Root.tsx")
4549
+ * - absolutePath: Full filesystem path (e.g., "/workspace/src/Root.tsx")
4550
+ * - basePath: The watch directory path (e.g., ".", ".claude/files")
4533
4551
  */
4534
4552
  interface FileChangeEvent {
4535
4553
  /** Type of change */
4536
4554
  type: FileChangeType;
4537
- /** Relative path from the watched directory */
4555
+ /**
4556
+ * Relative path from the watched directory
4557
+ * This is the canonical path for storage purposes
4558
+ * Example: "src/Root.tsx"
4559
+ */
4538
4560
  relativePath: string;
4539
- /** Absolute path to the file */
4561
+ /**
4562
+ * Absolute filesystem path to the file
4563
+ * Example: "/workspace/src/Root.tsx" or "/vercel/sandbox/.claude/files/src/Root.tsx"
4564
+ */
4540
4565
  absolutePath: string;
4566
+ /**
4567
+ * The base path being watched (the watch directory)
4568
+ * Example: "." (root), ".claude/files" (default)
4569
+ */
4570
+ basePath: string;
4541
4571
  /** Session ID this watch is associated with */
4542
4572
  sessionId: string;
4543
4573
  /** File size (only for add/change events) */
@@ -4969,8 +4999,16 @@ interface FilePushResult {
4969
4999
  interface PushOptions {
4970
5000
  /**
4971
5001
  * Override the sandbox target path for these files.
4972
- * Default uses sandboxBasePath (.claude/files).
4973
- * Use '.' to write to sandbox working directory root.
5002
+ * This REPLACES the default sandboxBasePath - it does NOT nest under it.
5003
+ *
5004
+ * Path resolution (for file path 'src/Root.tsx'):
5005
+ * - undefined (default) → .claude/files/src/Root.tsx
5006
+ * - '.' → src/Root.tsx (working dir root)
5007
+ * - 'my-project' → my-project/src/Root.tsx
5008
+ * - '.claude/files' → .claude/files/src/Root.tsx (same as undefined)
5009
+ *
5010
+ * Note: There is NO double-nesting. targetPath: '.claude/files' does NOT
5011
+ * result in .claude/files/.claude/files/path.
4974
5012
  */
4975
5013
  targetPath?: string;
4976
5014
  /**
@@ -4996,8 +5034,12 @@ interface FilePullResult {
4996
5034
  interface PullOptions {
4997
5035
  /**
4998
5036
  * Override the sandbox source path for reading files.
4999
- * Default uses sandboxBasePath (.claude/files).
5000
- * Use '.' to read from sandbox working directory root.
5037
+ * This REPLACES the default sandboxBasePath - it does NOT nest under it.
5038
+ *
5039
+ * Path resolution (for file path 'src/Root.tsx'):
5040
+ * - undefined (default) → reads from .claude/files/src/Root.tsx
5041
+ * - '.' → reads from src/Root.tsx (working dir root)
5042
+ * - 'my-project' → reads from my-project/src/Root.tsx
5001
5043
  *
5002
5044
  * This is useful when watching files edited by the agent,
5003
5045
  * which are at the sandbox root rather than in sandboxBasePath.
@@ -5017,12 +5059,31 @@ interface SyncResult {
5017
5059
  /**
5018
5060
  * Event emitted during file sync operations
5019
5061
  * Operation names are fully explicit about source and destination
5062
+ *
5063
+ * Path terminology:
5064
+ * - canonicalPath: The logical file path (e.g., "src/Root.tsx") - used as S3 key
5065
+ * - basePath: The target prefix in sandbox (e.g., ".", ".claude/files", "my-project")
5066
+ * - sandboxPath: The computed path in sandbox (e.g., "src/Root.tsx" or ".claude/files/src/Root.tsx")
5020
5067
  */
5021
5068
  interface FileSyncEvent {
5022
5069
  operation: 'client_uploaded_to_ash_storage' | 'agent_sandbox_saved_to_ash_storage' | 'ash_storage_synced_to_agent_sandbox' | 'read_from_agent_sandbox' | 'deleted_from_ash_storage' | 'deleted_from_agent_sandbox';
5023
5070
  /** Who initiated this operation */
5024
5071
  source: 'client_api' | 'ash_file_sync';
5025
- filePath: string;
5072
+ /**
5073
+ * Canonical file path - the logical path used as S3 key
5074
+ * Example: "src/Root.tsx"
5075
+ */
5076
+ canonicalPath: string;
5077
+ /**
5078
+ * Base path / target path prefix used in the sandbox
5079
+ * Example: "." (root), ".claude/files" (default), "my-project"
5080
+ */
5081
+ basePath: string;
5082
+ /**
5083
+ * Full computed path in the sandbox
5084
+ * Example: "src/Root.tsx" (if basePath=".") or ".claude/files/src/Root.tsx" (if basePath=".claude/files")
5085
+ */
5086
+ sandboxPath: string;
5026
5087
  fileSize?: number;
5027
5088
  success: boolean;
5028
5089
  error?: string;
@@ -5197,12 +5258,23 @@ declare class SandboxFileSync {
5197
5258
  * This is called by the cloud layer after creating the sync service
5198
5259
  */
5199
5260
  setSandboxOperations(ops: SandboxFileOperations): void;
5261
+ /**
5262
+ * Get the effective base path for sandbox operations
5263
+ * @param targetPath - Optional override for the base path
5264
+ */
5265
+ private getBasePath;
5200
5266
  /**
5201
5267
  * Get the full sandbox path for a file
5202
5268
  * @param path - The relative file path
5203
5269
  * @param targetPath - Optional override for the base path
5204
5270
  */
5205
5271
  private getSandboxPath;
5272
+ /**
5273
+ * Build all path fields for a FileSyncEvent
5274
+ * @param path - The canonical file path (used as S3 key)
5275
+ * @param targetPath - Optional override for the base path
5276
+ */
5277
+ private buildPathFields;
5206
5278
  /**
5207
5279
  * Push a file: writes to S3, then to sandbox if running
5208
5280
  * @param sessionId - Session ID
package/dist/index.d.ts CHANGED
@@ -1331,8 +1331,21 @@ interface FileSyncEventData {
1331
1331
  operation: FileSyncOperation;
1332
1332
  /** Who initiated this operation */
1333
1333
  source: FileSyncSource;
1334
- /** Path of the file */
1335
- filePath: string;
1334
+ /**
1335
+ * Canonical file path - the logical path used as S3 key
1336
+ * Example: "src/Root.tsx"
1337
+ */
1338
+ canonicalPath: string;
1339
+ /**
1340
+ * Base path / target path prefix used in the sandbox
1341
+ * Example: "." (root), ".claude/files" (default), "my-project"
1342
+ */
1343
+ basePath: string;
1344
+ /**
1345
+ * Full computed path in the sandbox
1346
+ * Example: "src/Root.tsx" (if basePath=".") or ".claude/files/src/Root.tsx" (if basePath=".claude/files")
1347
+ */
1348
+ sandboxPath: string;
1336
1349
  /** Size of the file in bytes */
1337
1350
  fileSize?: number;
1338
1351
  /** Whether the operation succeeded */
@@ -4530,14 +4543,31 @@ declare function createMinioFileStore(config: {
4530
4543
  type FileChangeType = 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir';
4531
4544
  /**
4532
4545
  * Event emitted when a file changes in the watched directory
4546
+ *
4547
+ * Path terminology:
4548
+ * - relativePath: Path relative to the watch directory (e.g., "src/Root.tsx")
4549
+ * - absolutePath: Full filesystem path (e.g., "/workspace/src/Root.tsx")
4550
+ * - basePath: The watch directory path (e.g., ".", ".claude/files")
4533
4551
  */
4534
4552
  interface FileChangeEvent {
4535
4553
  /** Type of change */
4536
4554
  type: FileChangeType;
4537
- /** Relative path from the watched directory */
4555
+ /**
4556
+ * Relative path from the watched directory
4557
+ * This is the canonical path for storage purposes
4558
+ * Example: "src/Root.tsx"
4559
+ */
4538
4560
  relativePath: string;
4539
- /** Absolute path to the file */
4561
+ /**
4562
+ * Absolute filesystem path to the file
4563
+ * Example: "/workspace/src/Root.tsx" or "/vercel/sandbox/.claude/files/src/Root.tsx"
4564
+ */
4540
4565
  absolutePath: string;
4566
+ /**
4567
+ * The base path being watched (the watch directory)
4568
+ * Example: "." (root), ".claude/files" (default)
4569
+ */
4570
+ basePath: string;
4541
4571
  /** Session ID this watch is associated with */
4542
4572
  sessionId: string;
4543
4573
  /** File size (only for add/change events) */
@@ -4969,8 +4999,16 @@ interface FilePushResult {
4969
4999
  interface PushOptions {
4970
5000
  /**
4971
5001
  * Override the sandbox target path for these files.
4972
- * Default uses sandboxBasePath (.claude/files).
4973
- * Use '.' to write to sandbox working directory root.
5002
+ * This REPLACES the default sandboxBasePath - it does NOT nest under it.
5003
+ *
5004
+ * Path resolution (for file path 'src/Root.tsx'):
5005
+ * - undefined (default) → .claude/files/src/Root.tsx
5006
+ * - '.' → src/Root.tsx (working dir root)
5007
+ * - 'my-project' → my-project/src/Root.tsx
5008
+ * - '.claude/files' → .claude/files/src/Root.tsx (same as undefined)
5009
+ *
5010
+ * Note: There is NO double-nesting. targetPath: '.claude/files' does NOT
5011
+ * result in .claude/files/.claude/files/path.
4974
5012
  */
4975
5013
  targetPath?: string;
4976
5014
  /**
@@ -4996,8 +5034,12 @@ interface FilePullResult {
4996
5034
  interface PullOptions {
4997
5035
  /**
4998
5036
  * Override the sandbox source path for reading files.
4999
- * Default uses sandboxBasePath (.claude/files).
5000
- * Use '.' to read from sandbox working directory root.
5037
+ * This REPLACES the default sandboxBasePath - it does NOT nest under it.
5038
+ *
5039
+ * Path resolution (for file path 'src/Root.tsx'):
5040
+ * - undefined (default) → reads from .claude/files/src/Root.tsx
5041
+ * - '.' → reads from src/Root.tsx (working dir root)
5042
+ * - 'my-project' → reads from my-project/src/Root.tsx
5001
5043
  *
5002
5044
  * This is useful when watching files edited by the agent,
5003
5045
  * which are at the sandbox root rather than in sandboxBasePath.
@@ -5017,12 +5059,31 @@ interface SyncResult {
5017
5059
  /**
5018
5060
  * Event emitted during file sync operations
5019
5061
  * Operation names are fully explicit about source and destination
5062
+ *
5063
+ * Path terminology:
5064
+ * - canonicalPath: The logical file path (e.g., "src/Root.tsx") - used as S3 key
5065
+ * - basePath: The target prefix in sandbox (e.g., ".", ".claude/files", "my-project")
5066
+ * - sandboxPath: The computed path in sandbox (e.g., "src/Root.tsx" or ".claude/files/src/Root.tsx")
5020
5067
  */
5021
5068
  interface FileSyncEvent {
5022
5069
  operation: 'client_uploaded_to_ash_storage' | 'agent_sandbox_saved_to_ash_storage' | 'ash_storage_synced_to_agent_sandbox' | 'read_from_agent_sandbox' | 'deleted_from_ash_storage' | 'deleted_from_agent_sandbox';
5023
5070
  /** Who initiated this operation */
5024
5071
  source: 'client_api' | 'ash_file_sync';
5025
- filePath: string;
5072
+ /**
5073
+ * Canonical file path - the logical path used as S3 key
5074
+ * Example: "src/Root.tsx"
5075
+ */
5076
+ canonicalPath: string;
5077
+ /**
5078
+ * Base path / target path prefix used in the sandbox
5079
+ * Example: "." (root), ".claude/files" (default), "my-project"
5080
+ */
5081
+ basePath: string;
5082
+ /**
5083
+ * Full computed path in the sandbox
5084
+ * Example: "src/Root.tsx" (if basePath=".") or ".claude/files/src/Root.tsx" (if basePath=".claude/files")
5085
+ */
5086
+ sandboxPath: string;
5026
5087
  fileSize?: number;
5027
5088
  success: boolean;
5028
5089
  error?: string;
@@ -5197,12 +5258,23 @@ declare class SandboxFileSync {
5197
5258
  * This is called by the cloud layer after creating the sync service
5198
5259
  */
5199
5260
  setSandboxOperations(ops: SandboxFileOperations): void;
5261
+ /**
5262
+ * Get the effective base path for sandbox operations
5263
+ * @param targetPath - Optional override for the base path
5264
+ */
5265
+ private getBasePath;
5200
5266
  /**
5201
5267
  * Get the full sandbox path for a file
5202
5268
  * @param path - The relative file path
5203
5269
  * @param targetPath - Optional override for the base path
5204
5270
  */
5205
5271
  private getSandboxPath;
5272
+ /**
5273
+ * Build all path fields for a FileSyncEvent
5274
+ * @param path - The canonical file path (used as S3 key)
5275
+ * @param targetPath - Optional override for the base path
5276
+ */
5277
+ private buildPathFields;
5206
5278
  /**
5207
5279
  * Push a file: writes to S3, then to sandbox if running
5208
5280
  * @param sessionId - Session ID
package/dist/index.js CHANGED
@@ -5993,6 +5993,7 @@ var init_sandbox_file_watcher = __esm({
5993
5993
  type,
5994
5994
  relativePath,
5995
5995
  absolutePath,
5996
+ basePath: this.watchPath,
5996
5997
  sessionId: this.sessionId,
5997
5998
  fileSize,
5998
5999
  timestamp: /* @__PURE__ */ new Date()
@@ -6201,6 +6202,7 @@ var init_sandbox_file_watcher = __esm({
6201
6202
  type: "add",
6202
6203
  relativePath: filePath,
6203
6204
  absolutePath: `${this.basePath}/${filePath}`,
6205
+ basePath: this.basePath,
6204
6206
  sessionId: this.sessionId,
6205
6207
  fileSize: info.size,
6206
6208
  timestamp: /* @__PURE__ */ new Date()
@@ -6213,6 +6215,7 @@ var init_sandbox_file_watcher = __esm({
6213
6215
  type: "unlink",
6214
6216
  relativePath: filePath,
6215
6217
  absolutePath: `${this.basePath}/${filePath}`,
6218
+ basePath: this.basePath,
6216
6219
  sessionId: this.sessionId,
6217
6220
  timestamp: /* @__PURE__ */ new Date()
6218
6221
  });
@@ -6517,7 +6520,7 @@ var init_sandbox_file_sync = __esm({
6517
6520
  }
6518
6521
  };
6519
6522
  const webhookType = payload.event === "file_sync" ? "file_sync" : "file_change";
6520
- const filePath = payload.fileSyncEvent?.filePath ?? payload.fileChangeEvent?.relativePath;
6523
+ const filePath = payload.fileSyncEvent?.canonicalPath ?? payload.fileChangeEvent?.relativePath;
6521
6524
  const operation = payload.fileSyncEvent?.operation ?? payload.fileChangeEvent?.type;
6522
6525
  if (isAsync) {
6523
6526
  sendWithRetry(0).then(async (result) => {
@@ -6647,7 +6650,9 @@ var init_sandbox_file_sync = __esm({
6647
6650
  const eventData = {
6648
6651
  operation: event.operation,
6649
6652
  source: event.source,
6650
- filePath: event.filePath,
6653
+ canonicalPath: event.canonicalPath,
6654
+ basePath: event.basePath,
6655
+ sandboxPath: event.sandboxPath,
6651
6656
  fileSize: event.fileSize,
6652
6657
  success: event.success,
6653
6658
  error: event.error,
@@ -6678,6 +6683,13 @@ var init_sandbox_file_sync = __esm({
6678
6683
  setSandboxOperations(ops) {
6679
6684
  this.sandboxOps = ops;
6680
6685
  }
6686
+ /**
6687
+ * Get the effective base path for sandbox operations
6688
+ * @param targetPath - Optional override for the base path
6689
+ */
6690
+ getBasePath(targetPath) {
6691
+ return targetPath ?? this.sandboxBasePath;
6692
+ }
6681
6693
  /**
6682
6694
  * Get the full sandbox path for a file
6683
6695
  * @param path - The relative file path
@@ -6685,12 +6697,30 @@ var init_sandbox_file_sync = __esm({
6685
6697
  */
6686
6698
  getSandboxPath(path15, targetPath) {
6687
6699
  const normalizedPath = path15.replace(/^\/+/, "");
6688
- const basePath = targetPath ?? this.sandboxBasePath;
6700
+ const basePath = this.getBasePath(targetPath);
6689
6701
  if (basePath === ".") {
6690
6702
  return normalizedPath;
6691
6703
  }
6692
6704
  return `${basePath}/${normalizedPath}`;
6693
6705
  }
6706
+ /**
6707
+ * Build all path fields for a FileSyncEvent
6708
+ * @param path - The canonical file path (used as S3 key)
6709
+ * @param targetPath - Optional override for the base path
6710
+ */
6711
+ buildPathFields(path15, targetPath) {
6712
+ const normalizedPath = path15.replace(/^\/+/, "");
6713
+ const basePath = this.getBasePath(targetPath);
6714
+ const sandboxPath = this.getSandboxPath(path15, targetPath);
6715
+ return {
6716
+ canonicalPath: normalizedPath,
6717
+ // The logical path (S3 key)
6718
+ basePath,
6719
+ // The prefix used in sandbox
6720
+ sandboxPath
6721
+ // Full computed path in sandbox
6722
+ };
6723
+ }
6694
6724
  /**
6695
6725
  * Push a file: writes to S3, then to sandbox if running
6696
6726
  * @param sessionId - Session ID
@@ -6707,13 +6737,14 @@ var init_sandbox_file_sync = __esm({
6707
6737
  };
6708
6738
  const source = options?.source ?? "client_api";
6709
6739
  const uploadToStorageOp = source === "client_api" ? "client_uploaded_to_ash_storage" : "agent_sandbox_saved_to_ash_storage";
6740
+ const pathFields = this.buildPathFields(path15, options?.targetPath);
6710
6741
  try {
6711
6742
  await this.fileStore.writeFile(sessionId, path15, content);
6712
6743
  result.s3Written = true;
6713
6744
  await this.emitFileEvent(sessionId, {
6714
6745
  operation: uploadToStorageOp,
6715
6746
  source,
6716
- filePath: path15,
6747
+ ...pathFields,
6717
6748
  fileSize: content.length,
6718
6749
  success: true,
6719
6750
  previousContent,
@@ -6726,7 +6757,7 @@ var init_sandbox_file_sync = __esm({
6726
6757
  await this.emitFileEvent(sessionId, {
6727
6758
  operation: uploadToStorageOp,
6728
6759
  source,
6729
- filePath: path15,
6760
+ ...pathFields,
6730
6761
  fileSize: content.length,
6731
6762
  success: false,
6732
6763
  error: errorMessage
@@ -6735,13 +6766,12 @@ var init_sandbox_file_sync = __esm({
6735
6766
  }
6736
6767
  if (this.sandboxOps?.isSandboxRunning(sessionId)) {
6737
6768
  try {
6738
- const sandboxPath = this.getSandboxPath(path15, options?.targetPath);
6739
- const writeResult = await this.sandboxOps.writeFile(sessionId, sandboxPath, content);
6769
+ const writeResult = await this.sandboxOps.writeFile(sessionId, pathFields.sandboxPath, content);
6740
6770
  result.sandboxWritten = writeResult.success;
6741
6771
  await this.emitFileEvent(sessionId, {
6742
6772
  operation: "ash_storage_synced_to_agent_sandbox",
6743
6773
  source,
6744
- filePath: path15,
6774
+ ...pathFields,
6745
6775
  fileSize: content.length,
6746
6776
  success: writeResult.success,
6747
6777
  error: writeResult.error
@@ -6755,7 +6785,7 @@ var init_sandbox_file_sync = __esm({
6755
6785
  await this.emitFileEvent(sessionId, {
6756
6786
  operation: "ash_storage_synced_to_agent_sandbox",
6757
6787
  source,
6758
- filePath: path15,
6788
+ ...pathFields,
6759
6789
  fileSize: content.length,
6760
6790
  success: false,
6761
6791
  error: errorMessage
@@ -6798,15 +6828,15 @@ var init_sandbox_file_sync = __esm({
6798
6828
  result.error = "Sandbox is not running";
6799
6829
  return result;
6800
6830
  }
6831
+ const pathFields = this.buildPathFields(path15, options?.targetPath);
6801
6832
  try {
6802
- const sandboxPath = this.getSandboxPath(path15, options?.targetPath);
6803
- const readResult = await this.sandboxOps.readFile(sessionId, sandboxPath);
6833
+ const readResult = await this.sandboxOps.readFile(sessionId, pathFields.sandboxPath);
6804
6834
  if (!readResult.success || !readResult.content) {
6805
6835
  result.error = readResult.error ?? "File not found in sandbox";
6806
6836
  await this.emitFileEvent(sessionId, {
6807
6837
  operation: "read_from_agent_sandbox",
6808
6838
  source: "ash_file_sync",
6809
- filePath: path15,
6839
+ ...pathFields,
6810
6840
  success: false,
6811
6841
  error: result.error
6812
6842
  });
@@ -6816,7 +6846,7 @@ var init_sandbox_file_sync = __esm({
6816
6846
  await this.emitFileEvent(sessionId, {
6817
6847
  operation: "read_from_agent_sandbox",
6818
6848
  source: "ash_file_sync",
6819
- filePath: path15,
6849
+ ...pathFields,
6820
6850
  fileSize: readResult.content.length,
6821
6851
  success: true,
6822
6852
  newContent: readResult.content
@@ -6827,7 +6857,7 @@ var init_sandbox_file_sync = __esm({
6827
6857
  await this.emitFileEvent(sessionId, {
6828
6858
  operation: "read_from_agent_sandbox",
6829
6859
  source: "ash_file_sync",
6830
- filePath: path15,
6860
+ ...pathFields,
6831
6861
  success: false,
6832
6862
  error: errorMessage
6833
6863
  });
@@ -6839,7 +6869,7 @@ var init_sandbox_file_sync = __esm({
6839
6869
  await this.emitFileEvent(sessionId, {
6840
6870
  operation: "agent_sandbox_saved_to_ash_storage",
6841
6871
  source: "ash_file_sync",
6842
- filePath: path15,
6872
+ ...pathFields,
6843
6873
  fileSize: result.content.length,
6844
6874
  success: true,
6845
6875
  newContent: result.content
@@ -6851,7 +6881,7 @@ var init_sandbox_file_sync = __esm({
6851
6881
  await this.emitFileEvent(sessionId, {
6852
6882
  operation: "agent_sandbox_saved_to_ash_storage",
6853
6883
  source: "ash_file_sync",
6854
- filePath: path15,
6884
+ ...pathFields,
6855
6885
  fileSize: result.content?.length,
6856
6886
  success: false,
6857
6887
  error: errorMessage
@@ -6893,13 +6923,14 @@ var init_sandbox_file_sync = __esm({
6893
6923
  */
6894
6924
  async deleteFile(sessionId, path15) {
6895
6925
  const result = { s3Deleted: false, sandboxDeleted: false };
6926
+ const pathFields = this.buildPathFields(path15);
6896
6927
  try {
6897
6928
  await this.fileStore.deleteFile(sessionId, path15);
6898
6929
  result.s3Deleted = true;
6899
6930
  await this.emitFileEvent(sessionId, {
6900
6931
  operation: "deleted_from_ash_storage",
6901
6932
  source: "ash_file_sync",
6902
- filePath: path15,
6933
+ ...pathFields,
6903
6934
  success: true
6904
6935
  });
6905
6936
  } catch (error) {
@@ -6908,20 +6939,19 @@ var init_sandbox_file_sync = __esm({
6908
6939
  await this.emitFileEvent(sessionId, {
6909
6940
  operation: "deleted_from_ash_storage",
6910
6941
  source: "ash_file_sync",
6911
- filePath: path15,
6942
+ ...pathFields,
6912
6943
  success: false,
6913
6944
  error: errorMessage
6914
6945
  });
6915
6946
  }
6916
6947
  if (this.sandboxOps?.isSandboxRunning(sessionId)) {
6917
6948
  try {
6918
- const sandboxPath = this.getSandboxPath(path15);
6919
- console.log(`[FILE_SYNC] Would delete ${sandboxPath} from sandbox`);
6949
+ console.log(`[FILE_SYNC] Would delete ${pathFields.sandboxPath} from sandbox`);
6920
6950
  result.sandboxDeleted = true;
6921
6951
  await this.emitFileEvent(sessionId, {
6922
6952
  operation: "deleted_from_agent_sandbox",
6923
6953
  source: "ash_file_sync",
6924
- filePath: path15,
6954
+ ...pathFields,
6925
6955
  success: true
6926
6956
  });
6927
6957
  } catch (error) {
@@ -6929,7 +6959,7 @@ var init_sandbox_file_sync = __esm({
6929
6959
  await this.emitFileEvent(sessionId, {
6930
6960
  operation: "deleted_from_agent_sandbox",
6931
6961
  source: "ash_file_sync",
6932
- filePath: path15,
6962
+ ...pathFields,
6933
6963
  success: false,
6934
6964
  error: errorMessage
6935
6965
  });
@@ -6949,6 +6979,7 @@ var init_sandbox_file_sync = __esm({
6949
6979
  }
6950
6980
  const files = await this.fileStore.listFiles(sessionId);
6951
6981
  for (const file of files) {
6982
+ const pathFields = this.buildPathFields(file.path);
6952
6983
  try {
6953
6984
  const content = await this.fileStore.readFile(sessionId, file.path);
6954
6985
  if (!content) {
@@ -6956,20 +6987,19 @@ var init_sandbox_file_sync = __esm({
6956
6987
  await this.emitFileEvent(sessionId, {
6957
6988
  operation: "ash_storage_synced_to_agent_sandbox",
6958
6989
  source: "ash_file_sync",
6959
- filePath: file.path,
6990
+ ...pathFields,
6960
6991
  success: false,
6961
6992
  error: "File not found in Ash storage"
6962
6993
  });
6963
6994
  continue;
6964
6995
  }
6965
- const sandboxPath = this.getSandboxPath(file.path);
6966
- const writeResult = await this.sandboxOps.writeFile(sessionId, sandboxPath, content);
6996
+ const writeResult = await this.sandboxOps.writeFile(sessionId, pathFields.sandboxPath, content);
6967
6997
  if (writeResult.success) {
6968
6998
  result.fileCount++;
6969
6999
  await this.emitFileEvent(sessionId, {
6970
7000
  operation: "ash_storage_synced_to_agent_sandbox",
6971
7001
  source: "ash_file_sync",
6972
- filePath: file.path,
7002
+ ...pathFields,
6973
7003
  fileSize: content.length,
6974
7004
  success: true
6975
7005
  });
@@ -6978,7 +7008,7 @@ var init_sandbox_file_sync = __esm({
6978
7008
  await this.emitFileEvent(sessionId, {
6979
7009
  operation: "ash_storage_synced_to_agent_sandbox",
6980
7010
  source: "ash_file_sync",
6981
- filePath: file.path,
7011
+ ...pathFields,
6982
7012
  fileSize: content.length,
6983
7013
  success: false,
6984
7014
  error: writeResult.error
@@ -6993,7 +7023,7 @@ var init_sandbox_file_sync = __esm({
6993
7023
  await this.emitFileEvent(sessionId, {
6994
7024
  operation: "ash_storage_synced_to_agent_sandbox",
6995
7025
  source: "ash_file_sync",
6996
- filePath: file.path,
7026
+ ...pathFields,
6997
7027
  success: false,
6998
7028
  error: errorMessage
6999
7029
  });
@@ -7024,24 +7054,25 @@ var init_sandbox_file_sync = __esm({
7024
7054
  return result;
7025
7055
  }
7026
7056
  }
7027
- for (const filePath of filesToSync) {
7057
+ for (const file of filesToSync) {
7058
+ const pathFields = this.buildPathFields(file);
7028
7059
  try {
7029
- const pullResult = await this.pullFile(sessionId, filePath);
7060
+ const pullResult = await this.pullFile(sessionId, file);
7030
7061
  if (pullResult.s3Written) {
7031
7062
  result.fileCount++;
7032
7063
  } else if (pullResult.error) {
7033
- result.errors.push({ path: filePath, error: pullResult.error });
7064
+ result.errors.push({ path: file, error: pullResult.error });
7034
7065
  }
7035
7066
  } catch (error) {
7036
7067
  const errorMessage = extractErrorMessage(error);
7037
7068
  result.errors.push({
7038
- path: filePath,
7069
+ path: file,
7039
7070
  error: errorMessage
7040
7071
  });
7041
7072
  await this.emitFileEvent(sessionId, {
7042
7073
  operation: "agent_sandbox_saved_to_ash_storage",
7043
7074
  source: "ash_file_sync",
7044
- filePath,
7075
+ ...pathFields,
7045
7076
  success: false,
7046
7077
  error: errorMessage
7047
7078
  });
@@ -7455,6 +7486,7 @@ WATCHER_EOF`;
7455
7486
  type: data.type,
7456
7487
  relativePath: data.path.replace(/^\.\//, ""),
7457
7488
  absolutePath: data.path,
7489
+ basePath: this.watchPath,
7458
7490
  sessionId: this.sessionId,
7459
7491
  timestamp: new Date(data.timestamp)
7460
7492
  });