From 7a9ef51c9b2efd25dae22bb646eca4bb526ffe25 Mon Sep 17 00:00:00 2001 From: Konrad Rokicki Date: Mon, 6 Jul 2026 14:27:55 -0400 Subject: [PATCH 1/4] Document file associations and the path parameter type Covers the new associations field on file/directory/path parameters: extension matching, capability manifest references (a separate standard resolved at manifest load), matching rules where capabilities are authoritative for Zarr datasets, and the Compatible apps panel in the file browser that prefills the launch form. Co-Authored-By: Claude Fable 5 --- src/content/docs/authoring/parameters.mdx | 56 ++++++++++++++++++-- src/content/docs/workflows/apps-and-jobs.mdx | 6 ++- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/content/docs/authoring/parameters.mdx b/src/content/docs/authoring/parameters.mdx index 02665d5..3577a18 100644 --- a/src/content/docs/authoring/parameters.mdx +++ b/src/content/docs/authoring/parameters.mdx @@ -27,7 +27,8 @@ Each parameter with a `flag` field becomes a CLI flag appended to the base comma | `raw` | boolean | no | If `true`, the value is appended to the command without shell quoting. Validated against shell metacharacters for safety. Default: `false` | | `value_separator` | string | no | How a flagged parameter is joined to its value: `"space"` emits `--flag 'value'`, `"equals"` emits `--flag='value'`. Use `equals` for tools (like Nextflow) that would otherwise misparse a value starting with `-` as another flag. Default: `"space"` | | `boolean_style` | string | no | Only valid on `boolean` parameters. `"flag"` emits the bare flag when true and omits it when false; `"value"` emits an explicit `--flag true` / `--flag false` (or `--flag=true` / `--flag=false` with `value_separator: equals`). Use `value` for tools where omitting a false switch would leave a default of true in effect. Default: `"flag"` | -| `exists` | boolean | no | Only valid on `file` and `directory` parameters. When `true` (the default), the path must exist and be readable before launch. Set `false` for outputs the job creates: the existence check is skipped, and `directory` parameters are created (as the user, within an allowed file share) before launch, so a home default like `~/.fileglancer/logs` works on first launch. Default: `true` | +| `exists` | boolean | no | Only valid on `file`, `directory`, and `path` parameters. When `true` (the default), the path must exist and be readable before launch. Set `false` for outputs the job creates: the existence check is skipped, and `directory` parameters are created (as the user, within an allowed file share) before launch, so a home default like `~/.fileglancer/logs` works on first launch. Default: `true` | +| `associations` | object | no | Only valid on `file`, `directory`, and `path` parameters. Declares which file types this parameter accepts, so the file browser can offer the app when the user navigates to a matching file or directory. See [File Associations](#file-associations) | ## Parameter Types @@ -39,17 +40,64 @@ Each parameter with a `flag` field becomes a CLI flag appended to the base comma | `boolean` | Checkbox | `--flag` (if true, omitted if false); `--flag true` / `--flag false` with `boolean_style: value` | N/A | Must be true/false | | `file` | Text input + file browser | `--flag '/path/to/file'` | `'/path/to/file'` | Must be an absolute path that exists, is readable, and points to a file on the server (unless `exists: false`) | | `directory` | Text input + directory browser | `--flag '/path/to/dir'` | `'/path/to/dir'` | Must be an absolute path that exists, is readable, and points to a directory on the server (unless `exists: false`) | +| `path` | Text input + file/directory browser | `--flag '/path/to/item'` | `'/path/to/item'` | Must be an absolute path that exists and is readable on the server (unless `exists: false`). Accepts either a file or a directory — no type check. Useful for inputs that take both, e.g. TIFF files and OME-Zarr directories | | `enum` | Dropdown select | `--flag 'chosen_value'` | `'chosen_value'` | Value must be one of the `options` list | -**Notes on `file` and `directory` types:** +**Notes on `file`, `directory`, and `path` types:** - The UI provides a browse button alongside the text input, so users can pick paths from the Fileglancer file browser instead of typing them. -- Paths are validated server-side before job submission (must exist, be accessible, and match the expected file/folder type, unless `exists: false`). +- Paths are validated server-side before job submission (must exist, be accessible, and match the expected file/folder type, unless `exists: false`; `path` parameters accept either kind). - Both absolute paths (`/data/images`) and home-relative paths (`~/output`) are accepted. - Shell metacharacters (`;`, `&`, `|`, `` ` ``, `$`, `(`, `)`, etc.) are rejected for safety. -- Set `exists: false` on paths the job creates, such as an output or logs directory. The path is still validated for file-share containment, but not for existence. If the path already exists, Fileglancer still checks that it matches the expected file/folder type. Fileglancer additionally creates `exists: false` directories (as the user, within an allowed file share) just before launch, so a default like `~/.fileglancer/logs` works out of the box and overrides that point at a new directory are created too. Overrides pointing at an existing directory are a no-op. This never creates anything outside a file share. `file` parameters with `exists: false` skip the existence check but nothing is created for them. +- Set `exists: false` on paths the job creates, such as an output or logs directory. The path is still validated for file-share containment, but not for existence. If the path already exists, Fileglancer still checks that it matches the expected file/folder type. Fileglancer additionally creates `exists: false` directories (as the user, within an allowed file share) just before launch, so a default like `~/.fileglancer/logs` works out of the box and overrides that point at a new directory are created too. Overrides pointing at an existing directory are a no-op. This never creates anything outside a file share. `file` and `path` parameters with `exists: false` skip the existence check but nothing is created for them (a `path` parameter's kind is ambiguous, so Fileglancer cannot know whether to create a directory). - Apps auto-detected from a Nextflow pipeline's `nextflow_schema.json` follow the same convention as [nf-schema](https://nextflow-io.github.io/nf-schema/): a path parameter only requires existence when the schema property sets `"exists": true`. +## File Associations + +`file`, `directory`, and `path` parameters can declare `associations`: the file types they accept. When a user navigates to a matching file or directory in the Fileglancer file browser, a **Compatible apps** panel appears above the listing. Clicking the app opens its launch form with the browsed path already filled into the associated parameter. + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `extensions` | list of strings | no | Name suffixes to match, e.g. `[.tif, .czi]`. Case-insensitive; a missing leading dot is added automatically. Multi-part suffixes match against the end of the name, so `.ome.zarr` works | +| `capabilities_manifest` | string | no | Repo-relative path to a [capability manifest](https://github.com/BioImageTools/capability-manifest) YAML file describing the OME-Zarr data the app supports — the same standard Fileglancer uses to pick compatible OME-Zarr web viewers. Accepts either a full manifest (`viewer:` + `capabilities:` sections) or a bare capabilities mapping. Resolved when the app manifest is loaded, so the pinned app snapshot carries its capabilities with it. Only valid on `directory` and `path` parameters | +| `label` | string | no | Display label shown in the file browser panel, e.g. `TIFF images`. Defaults to the parameter's `name` | + +At least one of `extensions` or `capabilities_manifest` must be declared. Capability manifests are a separate standard and always live in their own file — they cannot be inlined in `runnables.yaml`. + +### Matching Rules + +- A `file` parameter only matches files, a `directory` parameter only matches directories, and a `path` parameter matches both. +- For a Zarr dataset (detected by content, not by name), declared capabilities are **authoritative**: the app is offered only when the compatibility check passes, even if `.zarr` is also listed in `extensions`. Plain (non-OME) Zarr never matches a capabilities rule, since compatibility cannot be verified. +- Everything else matches by case-insensitive name suffix. + +This lets one input register many file types with different handling. For example, an image converter that accepts TIFF and CZI files by extension, plus the OME-Zarr datasets it can actually read: + +```yaml +# runnables.yaml +parameters: + - flag: --input + name: Input image + type: path + required: true + associations: + extensions: [.tiff, .czi, .zarr] + capabilities_manifest: capabilities.yaml + label: Convertible images +``` + +```yaml +# capabilities.yaml (next to runnables.yaml) +capabilities: + ome_zarr_versions: [0.4, 0.5] + compression_codecs: [blosc, zstd, gzip] +``` + +This app appears for every `.tiff` and `.czi` file. For Zarr datasets, the capability manifest decides: an OME-Zarr 0.4 dataset compressed with blosc matches, while an unsupported version or codec hides the app — even though `.zarr` is in the extensions list. + + + ## Flag Forms Parameters support three flag styles: diff --git a/src/content/docs/workflows/apps-and-jobs.mdx b/src/content/docs/workflows/apps-and-jobs.mdx index 135d44d..9a8a972 100644 --- a/src/content/docs/workflows/apps-and-jobs.mdx +++ b/src/content/docs/workflows/apps-and-jobs.mdx @@ -117,7 +117,7 @@ Once an app is added, you can launch it as a job on the compute cluster. 3. **Fill in parameters on the launch form**
- The form shows the app's parameters with their types, defaults, and descriptions. For `file` and `directory` parameters, a browse button lets you pick paths from the Fileglancer file browser. Required parameters are marked and validated before submission. + The form shows the app's parameters with their types, defaults, and descriptions. For `file`, `directory`, and `path` parameters, a browse button lets you pick paths from the Fileglancer file browser. Required parameters are marked and validated before submission. 4. **Review the cluster and environment settings (optional)**
Switch to the **Cluster** tab to adjust CPU, memory, walltime, and queue requests, along with any extra scheduler arguments. The **Environment** tab lets you set environment variables, pre/post-run scripts, and tool-specific options like Nextflow profiles. @@ -127,6 +127,10 @@ Once an app is added, you can launch it as a job on the compute cluster.
+### Launching from the File Browser + +Apps can register **file associations** — the file types they handle, declared in their manifest (see [File Associations](/authoring/parameters/#file-associations)). When you navigate to a matching file or directory in the file browser, a **Compatible apps** panel appears above the listing, next to any OME-Zarr viewer links. Clicking an app opens its launch form with the browsed path already filled into the matching parameter; review the remaining settings and submit as usual. For Zarr datasets, apps that declare OME-Zarr capabilities are shown only when the dataset is actually compatible, the same way viewer links are filtered. + ### Tips for Launching - **Running the latest code**: Each launch runs the exact commit the app is pinned to, so repeated runs are reproducible. If the app's code is actively developed, watch for the amber **Update available** tag on the app's card and use the **Update** button to move to the newest commit before launching (see [Updating an App](#updating-an-app)). From 00d241d86fe2e7467a6be61e0c75461e2e4bfdee Mon Sep 17 00:00:00 2001 From: Konrad Rokicki Date: Tue, 21 Jul 2026 14:11:41 -0400 Subject: [PATCH 2/4] Document repo_url same-repo behavior Clarify that repo_url only triggers separate-tool-repo handling when it names a different owner/repo; pointing it at the manifest's own repository is ignored and the job runs from the manifest's branch and pinned commit. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/content/docs/authoring/manifest-reference.mdx | 2 +- src/content/docs/authoring/overview.mdx | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/content/docs/authoring/manifest-reference.mdx b/src/content/docs/authoring/manifest-reference.mdx index 35cf7b4..9757863 100644 --- a/src/content/docs/authoring/manifest-reference.mdx +++ b/src/content/docs/authoring/manifest-reference.mdx @@ -13,7 +13,7 @@ The `runnables.yaml` manifest describes your app. This page documents its struct |-------|------|----------|-------------| | `name` | string | yes | Display name shown in the Fileglancer UI | | `description` | string | no | Short description of the app | -| `repo_url` | string | no | GitHub URL of a separate repository containing the tool code (see [Separate Tool Repo](/authoring/overview/#separate-tool-repo)). Must be a valid GitHub repository URL — the manifest is rejected at load time otherwise | +| `repo_url` | string | no | GitHub URL of a separate repository containing the tool code (see [Separate Tool Repo](/authoring/overview/#separate-tool-repo)). Only takes effect when it names a *different* repository (`owner/repo`); pointing it at the manifest's own repo is ignored, and the job runs from the manifest's branch and pinned commit. Must be a valid GitHub repository URL — the manifest is rejected at load time otherwise | | `requirements` | list of strings | no | Tools that must be available in the job environment (see [Requirements](#requirements)) | | `runnables` | list of objects | yes | One or more runnable definitions (see [Runnables](#runnables)). A manifest with an empty `runnables` list is rejected | diff --git a/src/content/docs/authoring/overview.mdx b/src/content/docs/authoring/overview.mdx index 08a17ec..8468be7 100644 --- a/src/content/docs/authoring/overview.mdx +++ b/src/content/docs/authoring/overview.mdx @@ -130,6 +130,8 @@ When `repo_url` is set: - The discovery repo (containing `runnables.yaml`) is used only for manifest metadata. - The tool repo (`repo_url`) is cloned separately and used as the working directory for the job. +`repo_url` only triggers this separate-repo behavior when it points to a *different* repository (a different `owner/repo`); the branch is ignored in that comparison. If `repo_url` names the **same** repository the manifest lives in, it is not treated as separate — the job runs from the manifest's own branch and pinned commit. So a manifest on a non-default branch does not need `repo_url` pointing back at itself; doing so with a bare URL (no `/tree/`) would otherwise imply the repo's default branch. Omit `repo_url` unless the code genuinely lives in another repository. + Repos are cloned into a per-user cache, and every app is **pinned to an exact commit** when it is added. Jobs run from an immutable per-commit checkout of the pinned code — they never pull automatically, and nothing can change a job's code while it runs. To get the newest code, use the **Update** action for the app in the UI, which pulls the latest commits on the app's revision, re-reads the manifest, and re-pins the app (both the manifest repo and the `repo_url` tool repo, when one is declared). Updates are per-app: other apps sharing the same repository keep their own pinned commits. ## Where to Go Next From a6849fcc6dca134deced497c923ffecbf9a75e3b Mon Sep 17 00:00:00 2001 From: Konrad Rokicki Date: Tue, 21 Jul 2026 14:17:27 -0400 Subject: [PATCH 3/4] Rename Job page commit label from Version to Commit Matches the UI rename of the Job page field from "Version" to "Commit". Co-Authored-By: Claude Opus 4.8 (1M context) --- src/content/docs/workflows/apps-and-jobs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/workflows/apps-and-jobs.mdx b/src/content/docs/workflows/apps-and-jobs.mdx index 9a8a972..a268e8b 100644 --- a/src/content/docs/workflows/apps-and-jobs.mdx +++ b/src/content/docs/workflows/apps-and-jobs.mdx @@ -170,7 +170,7 @@ The Jobs page displays a table with the following columns: Click an entry point name in the jobs table (or select **View Details** from the actions menu) to open the detail view. This page shows: - **Header** — app name, entry point, and status badge, with a back arrow that returns to the jobs list -- **Overview tab** — a summary of the job: its app (linked to the app's detail page), entry point, the exact commit the job executed (**Version**, linked to GitHub), status, timestamps (submitted, started, finished, exit code), and resource requests +- **Overview tab** — a summary of the job: its app (linked to the app's detail page), entry point, the exact commit the job executed (**Commit**, linked to GitHub), status, timestamps (submitted, started, finished, exit code), and resource requests - **Parameters tab** — the parameter values that were used for this job - **Script tab** — the generated shell script that was submitted to the cluster, with a link to the script file on disk - **Output Log tab** — the job's stdout, streamed in near-real-time while the job is running. Includes a download button From c30d6b275cdb07e6b8a77ed7b9f1fbf718e1d860 Mon Sep 17 00:00:00 2001 From: Konrad Rokicki Date: Tue, 21 Jul 2026 20:34:07 -0400 Subject: [PATCH 4/4] Document working_dir: manifest and repo Rename the old "repo" option (runs from the manifest's directory) to "manifest", and document the new "repo" option that always runs from the clone root. Update the default (now "manifest" for non-container runnables) and the bind-mount note. Co-Authored-By: Claude Opus 4.8 --- src/content/docs/authoring/execution.mdx | 7 ++++--- src/content/docs/authoring/manifest-reference.mdx | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/content/docs/authoring/execution.mdx b/src/content/docs/authoring/execution.mdx index f16b4cd..bf9385b 100644 --- a/src/content/docs/authoring/execution.mdx +++ b/src/content/docs/authoring/execution.mdx @@ -48,7 +48,8 @@ A requirement check (see [Requirements](/authoring/manifest-reference/#requireme Every job gets a private **work directory** (`$FG_WORK_DIR`), and a checkout of the project at the app's **pinned commit** is symlinked into it as `repo`. The `working_dir` runnable field controls which of these the command runs from: -- **`repo`** (default for most runnables) — the script `cd`s into `$FG_WORK_DIR/repo` (or the manifest's subdirectory within it). Use this when the command relies on the project being the current directory — for example Pixi tasks, or scripts that reference sibling files with relative paths. +- **`manifest`** (default for most runnables) — the script `cd`s into the manifest's directory within the checkout: `$FG_WORK_DIR/repo` when the manifest is at the repo root, or its subdirectory when the manifest lives deeper (e.g. a monorepo). Use this when the command relies on being run from beside the manifest — for example Pixi tasks, or scripts that reference sibling files with relative paths. +- **`repo`** — the script `cd`s into the checkout root (`$FG_WORK_DIR/repo`) regardless of where the manifest lives. Use this for a manifest in a subdirectory whose command still needs to run from the top of the project. - **`work`** (default for **container** runnables) — the script `cd`s into `$FG_WORK_DIR`. The project is still reachable via the `repo` symlink (e.g. `nextflow run repo`). Use this for tools that should write their outputs into a clean per-job directory rather than the project checkout (which is shared by every job running the same version of the app). The checkout is per-version: jobs of an app that hasn't been updated share one checkout (so e.g. a Pixi environment builds once and is reused), and updating the app gives subsequent jobs a fresh checkout of the new commit while running jobs keep the one they started with. @@ -61,7 +62,7 @@ runnables: working_dir: work ``` -Containers default to `work` because the project checkout is **not** bind-mounted into the container (only the work directory and your file/directory parameters are), so a container's current directory should be the work dir. A container runnable that genuinely needs the project can set `working_dir: repo` — Fileglancer then bind-mounts the checkout into the container automatically so the command can run from it and read the project's files. +Containers default to `work` because the project checkout is **not** bind-mounted into the container (only the work directory and your file/directory parameters are), so a container's current directory should be the work dir. A container runnable that genuinely needs the project can set `working_dir: manifest` or `working_dir: repo` — Fileglancer then bind-mounts the checkout into the container automatically so the command can run from it and read the project's files. ## Environment Variables @@ -202,7 +203,7 @@ apptainer exec --bind /home/user/.fileglancer/jobs/1-lolcow-say "$SIF_PATH" \ 'Hello from Fileglancer!' ``` -**Bind mounts** are auto-detected from `file` and `directory` parameters — the effective values the command is built from, so manifest defaults and parameters declared in `env_parameters` are bound too, not just values the user typed. The job's working directory is always bound, and when `working_dir: repo` is set, the cached repo clone is bound as well. Use `bind_paths` to add extra paths: +**Bind mounts** are auto-detected from `file` and `directory` parameters — the effective values the command is built from, so manifest defaults and parameters declared in `env_parameters` are bound too, not just values the user typed. The job's working directory is always bound, and when `working_dir` is `manifest` or `repo`, the cached repo clone is bound as well. Use `bind_paths` to add extra paths: ```yaml container: ghcr.io/org/image:tag diff --git a/src/content/docs/authoring/manifest-reference.mdx b/src/content/docs/authoring/manifest-reference.mdx index 9757863..148011b 100644 --- a/src/content/docs/authoring/manifest-reference.mdx +++ b/src/content/docs/authoring/manifest-reference.mdx @@ -38,7 +38,7 @@ Each runnable defines a single command that users can launch. If a manifest has | `container` | string | no | Container image URL for Apptainer (see [Containers](/authoring/execution/#containers-apptainer)) | | `bind_paths` | list of strings | no | Additional paths to bind-mount into the container (requires `container`) | | `container_args` | string | no | Default extra arguments for container exec (e.g. `--nv`), overridable at launch time | -| `working_dir` | string | no | Where the command runs: `repo` (the cloned project, optionally the manifest's subdirectory) or `work` (the job's work directory). Defaults to `work` for container runnables and `repo` otherwise (see [Execution Environment](/authoring/execution/#working-directory)) | +| `working_dir` | string | no | Where the command runs: `manifest` (the manifest's directory inside the cloned project), `repo` (the cloned project's root), or `work` (the job's work directory). Defaults to `work` for container runnables and `manifest` otherwise (see [Execution Environment](/authoring/execution/#working-directory)) | | `auto_url` | boolean | no | Service runnables only. When `true`, Fileglancer publishes the service URL for you once `$FG_SERVICE_PORT` is accepting connections — bind your service to `$FG_SERVICE_PORT` and you need no URL-writing code (see [Services](/authoring/services/)) | | `service_url_suffix` | string | no | Service runnables with `auto_url`. Text appended to `http://$FG_HOSTNAME:$FG_SERVICE_PORT` when publishing — a path and/or query, e.g. `/?access_token=${FG_SERVICE_TOKEN}` for one-click auth. May contain literal URL text and the placeholders `${FG_SERVICE_TOKEN}`, `${FG_SERVICE_PORT}`, `${FG_HOSTNAME}` (braces required); nothing else (see [Services](/authoring/services/)) | | `requirements` | list of strings | no | Additional tool requirements specific to this runnable, merged with manifest-level requirements |