Conversation
Users can now add their own scripts to the file and folder context menus. Definitions are portable TOML directories under `$XDG_CONFIG_HOME/strata/actions/<id>/`, holding `action.toml` plus an optional script. `model::action` owns the pure contract (parsing, validation, matching, token expansion, shebang handling), `services::actions` owns the cached catalog and matching, `adapters::local_actions` owns the filesystem, and `adapters::local_jobs` runs one invocation as a child process. `services::jobs` owns the queue, per-item iteration, progress, cancellation, bounded logs, and history, which the footer's Jobs dashboard observes. Boundaries that keep this safe to ship: - No shell. Programs receive argv entries directly, argument tokens expand only to absolute paths, and a token inside a larger string is rejected, so a selected file name can never be read as a command or an option. - Paths travel as bytes (NUL-delimited file plus environment variables) so names that are not valid UTF-8 survive, and matching is byte-exact. - Opening a menu only evaluates declarative rules; user code runs on invocation. - Manifests, scripts, action directories, entrypoints, and the scratch base are read as regular files and refused when they are links; generated files are owner-only inside an owner-only directory. - Output, progress events, and history are bounded, and progress lines are validated before they reach the UI. - Imported actions arrive disabled and copy only the manifest and its entrypoint. Settings gains an Actions page with a manager and an editor for the same files, and the footer gains a Jobs indicator that stays reachable when keybinding hints are off. Dismissing the dashboard never cancels work.
Records the manifest schema, matching rules, execution modes, environment and progress contract, the bundled Python helper, the Jobs dashboard behaviour, and the trust model, plus where the new boundary sits in the architecture notes.
|
Validation notes from building this out:
|
|
Review of 1. Duplicate of a max-length action id overwrites the original
2. Test quality: tautological / duplicate testsDrop these. Do not add more coverage in the same change.
CI is green on this SHA; local suite was not re-run. |
The test asked the waiter to wait for pid `u32::MAX`, which is not a portable way to describe an already-exited process. bash, which Arch installs as `/bin/sh`, wraps that value so `kill -0` reports every process as alive and the waiter loop never exits, hanging the suite on those hosts. Waiting for a reaped pid expresses the same intent and terminates on every shell.
|
Merged the latest Two notes from the merge:
Local gate after the merge: |
|
Review of 1. Duplicate of a max-length action id overwrites the original
2. Test quality: tautological / duplicate testsDrop these. Do not add more coverage in the same change.
|
Keeps the Actions page nav entry, the action search targets, the footer's `set_activity` hook, and the single `storage::config_directory` helper while taking main's preference split: `bind_preferences` now accepts a `PreferenceManager`, and `ui::preferences` owns the settings file store while delegating the config path to `storage::config_directory`.
|
Review of 1. Duplicate of a max-length action id overwrites the original
2. Test quality: tautological / duplicate testsDrop these. Do not add more coverage in the same change.
|
Two presentation defects in the new surfaces: - The empty manager message lives inside a `settings-group`, where rows supply their own padding, so a lone label sat against the group border. It now pads itself the same way a row does. - `GtkSwitch` fills whatever allocation it is given, so the editor's stacked Confirm and Enabled fields rendered as full-width ovals. Both switches now keep their natural size under their label.
|
Review of 1. Duplicate of a max-length action id overwrites the original
2. Test quality: tautological / duplicate testsDrop these. Do not add more coverage in the same change.
|
Action-editor UI follow-up —
|
|
Found 1 test failure on Blacksmith runners: Failure
|
Description
Adds the custom actions and background Jobs workflow agreed in #36. Actions are portable folders under
$XDG_CONFIG_HOME/strata/actions/<id>/, containingaction.tomland an optional Python/Bash script. Command actions use an installed program with explicit arguments. Settings manages the same files users can edit by hand.The action editor now follows the supplied three-tab design:
The active-tab underline sits above the divider; the header and footer stay outside the scrolling pages. Validation selects the relevant tab without losing edits. Existing modal, form, settings, segmented-control, icon, and source-theme components are reused.
The execution contract is unchanged: trusted local programs run with the user's permissions, without shell interpolation; paths remain byte-exact, links are refused, imported actions start disabled, and progress/log/history storage is bounded. Jobs can run in the background or be explicitly cancelled. Parameter forms, parallel per-item execution, remote inputs, restart/resume, sandboxing, and migration of built-in transfer jobs remain deferred. See
docs/custom-actions.md.Visual evidence
Pending owner upload through GitHub's description/comment editor. No supported authenticated attachment-upload route is available here; local captures are retained, not committed or presented as attached evidence.
Editor captures are in
/home/l0gicgate/Documents/github/strata/target/1085-ui/evidence/:before.png— previous long, scrolling action form (native GTK).general.png— new General tab and inline icons.script.png— new Script tab with line numbers and syntax colors.behavior.png— new Behavior tab with per-item failure policy disabled by default.command.png— program and multiline arguments.light-general.png,light-script.png,light-behavior.png— light-theme equivalents.After captures use the pinned GTK 4.14 environment on private Xvfb/D-Bus. Earlier context-menu, Actions Settings, and Jobs captures remain in
/home/l0gicgate/Documents/github/strata-worktrees/36-custom-actions/target/36-captures/.How to test
Checksums, leave the suggested id, and choose an icon.sha256sumwith{paths}on its own argument line.bin, check the run/placement controls, and choose Create action. Invalid fields should return you to the appropriate tab without saving.*.binfile and choose Actions → Checksums, then open the footer's Jobs indicator.Expected result:
Three tabs retain edits, the active indicator is above the divider, and the action saves once across all tabs. Only matching entries offer it. The Jobs dashboard reports execution and progress; hiding it leaves work running, while Cancel stops the job. Missing programs remain visible but unavailable; invalid manifests appear under Problems.
Related issue
Refs #36. Implements the agreed first-release scope; deferred items remain open.