This document defines the intended behavior for rewriting the native find function in src/gio.cc.
Implement find so that it uses GNOME's file search mechanism used by Nautilus, and returns result objects that match the same shape and semantics as ls.
- Platform: Linux GNOME environments.
- Runtime: Node native addon exported from this repository.
- Function under spec:
find. - This is a functional specification, not an implementation note.
find must use the GNOME/Nautilus search backend rather than manual recursive filesystem traversal or shelling out to Tracker CLI commands.
In practice, this means:
- Use the GNOME desktop search/indexing mechanism that Nautilus relies on.
- Prefer native library/API access over spawning shell commands.
- Do not construct shell commands from user input.
- Do not use
popen,system, or equivalent shell-based fallbacks for search execution.
The public JavaScript API should remain:
find(query, callback)find(query, sourcePath, callback)find(query, options, callback)find(query, sourcePath, options, callback)
- Type:
string - Required.
- Represents a user-entered search term.
- Matching should be case-insensitive.
- Matching behavior should align with Nautilus-style filename/title search as closely as practical.
- Type:
string - Optional.
- When provided, search should be scoped to that directory subtree or search root if the GNOME search backend supports scoped search.
- If the underlying GNOME search API cannot restrict results directly, implementation may post-filter results, but must still use the GNOME/Nautilus search source as the data origin.
- Type:
function - Required.
- Callback style should remain:
- success:
callback(null, results) - failure:
callback(errorMessageString, null)
- Type:
object - Optional.
- Supported fields:
dateFrom:Date | string | number, compared against resultmtimedateTo:Date | string | number, compared against resultmtimeminSize:number, minimum result size in bytesmaxSize:number, maximum result size in bytes
Filtering may be applied after GNOME-backed search results are resolved, but the search origin must remain GNOME/Nautilus-backed.
The native function should return undefined and deliver results through the callback.
Each result item must match the same object shape returned by ls, not the reduced shape currently returned by find.
Each result object should include the same fields ls currently emits when available:
name: stringdisplay_name: stringhref: stringlocation: stringis_dir: booleanis_hidden: booleanis_readable: booleanis_writable: booleanis_symlink: booleanfilesystem: stringcontent_type: stringwhen availablesize: numberwhen availablemtime: numberwhen availableatime: numberwhen availablectime: numberwhen available
hrefmust represent the matched file path in the same style asls.locationmust represent the parent directory path in the same style asls.- Metadata should be gathered using the same or equivalent GIO file info attributes used by
ls. - Missing metadata should be handled the same way as
lshandles it now.
The rewritten find should behave like a user-facing desktop search rather than a raw filesystem grep.
Required matching characteristics:
- Case-insensitive matching.
- Partial substring matching.
- Search should primarily target file display names / titles / names in a way consistent with Nautilus search.
- Results should include files and directories.
Preferred behavior:
- Returned order should reflect GNOME search backend ordering if available.
- Duplicate logical results should be removed.
- Hidden files should be included or excluded according to what the GNOME search backend returns by default, unless the implementation explicitly defines a repo-wide policy.
- Search across the default GNOME/Nautilus searchable scope available to the current user session.
- Results may reflect what the desktop indexer currently knows about.
- Search should be restricted to
sourcePathwhen possible. - If the GNOME search backend cannot natively scope the query, the implementation may:
- run the GNOME-backed search first
- filter results so only items under
sourcePathremain
- If the GNOME backend is unavailable or returns no matches, a recursive GIO filesystem fallback may be used.
The rewritten function must validate arguments before invoking any search backend.
Use JavaScript exceptions for invalid arguments, consistent with the rest of the addon:
- missing query
- non-string query
- missing callback
- non-function callback
- if provided, non-string
sourcePath
Use callback errors for runtime search failures:
- backend unavailable
- query execution failure
- metadata resolution failure that prevents result construction
- scope restriction failure when it makes the final result unusable
Runtime failure callback format:
callback(errorMessageString, null)
The rewrite must satisfy these constraints:
- No shell command construction from user input.
- No
popen,system, or shell-based Tracker wrappers. - No command-line fallback that interpolates raw query text.
- No use-after-free of search strings or URI buffers.
- No leaking per-result allocations when producing large result sets.
- The function should use indexed desktop search rather than recursive full-tree traversal as the primary search mechanism.
- Metadata collection should avoid unnecessary duplicate lookups when possible.
- The function should remain responsive for large result sets.
- If the backend can return more results than desired, the implementation may impose a limit, but that limit must be explicit and documented.
- Filesystem fallback is acceptable only as a secondary path when the GNOME backend is unavailable, fails, or returns no matches.
The rewrite should preserve these external behaviors:
- Same exported function name:
find - Same callback-based API
- Same optional
sourcePathoverload - Same Linux/GIO-oriented code style as the rest of the addon
The rewrite should remove these current behaviors:
- manual recursive traversal as the primary search mechanism
- shell-based Tracker fallback
- reduced result shape compared with
ls
The rewrite is complete when all of the following are true:
find("report", cb)performs GNOME/Nautilus-backed search.find("report", "/home/user/Documents", cb)returns only results under that scope.- Every returned result includes the same metadata fields that
lsreturns. - Callback success uses
callback(null, results). - Runtime failures use
callback(errorMessageString, null). - No shell command execution is used in the search path.
- The implementation does not rely on recursive directory walking as its main search engine.
- Duplicate results are not returned.
- If Tracker is unavailable or yields no matches, the implementation may return results from a GIO-based filesystem fallback.
- Search for an existing filename fragment and verify non-empty results.
- Search with mixed case and verify case-insensitive matching.
- Search with
sourcePathand verify everyhrefstays under that path. - Compare one returned result against
ls(parentDir, cb)and confirm matching object shape. - Search for a nonexistent term and verify
callback(null, []). - Pass invalid argument types and verify JavaScript exceptions are thrown.
- Run search with filenames containing spaces, quotes, and shell metacharacters and verify safe handling.
The rewrite should treat ls as the canonical metadata formatter for result objects. If practical, the implementation should share metadata construction logic with ls rather than maintaining a second partially overlapping formatter.