@@ -417,6 +417,113 @@ VXCORE_API VxCoreError vxcore_buffer_auto_save_tick(VxCoreContextHandle context)
417417VXCORE_API VxCoreError vxcore_buffer_set_auto_save_interval (VxCoreContextHandle context ,
418418 int64_t interval_ms );
419419
420+ // ============ Buffer Asset Operations (Filesystem Only) ============
421+ // Asset operations only touch the filesystem, they do NOT modify attachment metadata.
422+ // Use these for embedding inline content (images, diagrams) that don't need tracking.
423+
424+ // Insert binary data as an asset file (NO attachment tracking).
425+ // Creates assets folder lazily if it doesn't exist.
426+ // If asset_name already exists, a unique name is generated (e.g., image_1.png).
427+ //
428+ // buffer_id: ID of an open buffer
429+ // asset_name: Desired filename (e.g., "screenshot.png")
430+ // data: Binary content to write
431+ // data_size: Size of data in bytes
432+ // out_relative_path: Receives the relative path for embedding in content
433+ // (e.g., "vx_assets/<uuid>/screenshot.png" for notebook files,
434+ // or "<filename>_assets/screenshot.png" for external files)
435+ // Caller must free with vxcore_string_free.
436+ // Returns VXCORE_ERR_BUFFER_NOT_FOUND if buffer doesn't exist.
437+ // Returns VXCORE_ERR_UNSUPPORTED for raw notebooks.
438+ // Returns VXCORE_ERR_IO on filesystem error.
439+ VXCORE_API VxCoreError vxcore_buffer_insert_asset_raw (VxCoreContextHandle context ,
440+ const char * buffer_id , const char * asset_name ,
441+ const void * data , size_t data_size ,
442+ char * * out_relative_path );
443+
444+ // Copy a file to assets folder (NO attachment tracking).
445+ // Creates assets folder lazily if it doesn't exist.
446+ // If filename already exists, a unique name is generated.
447+ //
448+ // source_path: Absolute path to source file
449+ // out_relative_path: Receives the relative path for embedding in content
450+ // Caller must free with vxcore_string_free.
451+ VXCORE_API VxCoreError vxcore_buffer_insert_asset (VxCoreContextHandle context ,
452+ const char * buffer_id , const char * source_path ,
453+ char * * out_relative_path );
454+
455+ // Delete an asset file from the buffer's assets folder (NO attachment tracking).
456+ // Does NOT touch attachment metadata.
457+ //
458+ // relative_path: Path as returned by vxcore_buffer_insert_asset*
459+ // Returns VXCORE_ERR_NOT_FOUND if asset doesn't exist.
460+ VXCORE_API VxCoreError vxcore_buffer_delete_asset (VxCoreContextHandle context ,
461+ const char * buffer_id , const char * relative_path );
462+
463+ // Get absolute path to the buffer's assets folder.
464+ // Creates folder lazily if it doesn't exist.
465+ //
466+ // out_path: Receives absolute filesystem path.
467+ // Caller must free with vxcore_string_free.
468+ VXCORE_API VxCoreError vxcore_buffer_get_assets_folder (VxCoreContextHandle context ,
469+ const char * buffer_id , char * * out_path );
470+
471+ // ============ Buffer Attachment Operations (Filesystem + Metadata) ============
472+ // Attachment operations modify both filesystem and attachment metadata.
473+ // Use these for files that need to be tracked (downloadable attachments).
474+
475+ // Copy a file to attachments folder and add to attachment list.
476+ // For notebook files: copies file + adds to FileRecord.attachments
477+ // For external files: copies file only (no metadata tracking available)
478+ //
479+ // source_path: Absolute path to source file
480+ // out_filename: Receives just the filename (not full path)
481+ // Caller must free with vxcore_string_free.
482+ VXCORE_API VxCoreError vxcore_buffer_insert_attachment (VxCoreContextHandle context ,
483+ const char * buffer_id ,
484+ const char * source_path ,
485+ char * * out_filename );
486+
487+ // Delete an attachment file and remove from attachment list.
488+ //
489+ // filename: Just the filename (not full path)
490+ // Returns VXCORE_ERR_NOT_FOUND if attachment doesn't exist.
491+ VXCORE_API VxCoreError vxcore_buffer_delete_attachment (VxCoreContextHandle context ,
492+ const char * buffer_id , const char * filename );
493+
494+ // Rename an attachment file and update attachment list.
495+ // If new_filename already exists, a unique name is generated.
496+ //
497+ // old_filename: Current filename
498+ // new_filename: New filename
499+ // out_new_filename: Receives the actual new filename (may differ if collision)
500+ // Caller must free with vxcore_string_free.
501+ VXCORE_API VxCoreError vxcore_buffer_rename_attachment (VxCoreContextHandle context ,
502+ const char * buffer_id ,
503+ const char * old_filename ,
504+ const char * new_filename ,
505+ char * * out_new_filename );
506+
507+ // List all attachments (from metadata, not filesystem scan).
508+ // For notebook files: returns FileRecord.attachments
509+ // For external files: returns filesystem listing (no metadata)
510+ // Returns JSON array of filenames (not full paths).
511+ //
512+ // out_attachments_json: Receives JSON array (e.g., ["doc.pdf", "data.zip", ...])
513+ // Caller must free with vxcore_string_free.
514+ VXCORE_API VxCoreError vxcore_buffer_list_attachments (VxCoreContextHandle context ,
515+ const char * buffer_id ,
516+ char * * out_attachments_json );
517+
518+ // Get absolute path to the buffer's attachments folder.
519+ // Creates folder lazily if it doesn't exist.
520+ // (Same folder as assets folder - attachments and assets share location)
521+ //
522+ // out_path: Receives absolute filesystem path.
523+ // Caller must free with vxcore_string_free.
524+ VXCORE_API VxCoreError vxcore_buffer_get_attachments_folder (VxCoreContextHandle context ,
525+ const char * buffer_id , char * * out_path );
526+
420527VXCORE_API void vxcore_string_free (char * str );
421528
422529#ifdef __cplusplus
0 commit comments