codex/bound-transcode-segments
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4504d7c68e |
fix(autoscan): read descriptors from installed metadata, tighten source config
Second Codex review pass. Two P1s meant the descriptor mechanism was dead for every real plugin; both are verified against the pinned SDK's converter. Backend: - The SDK's CapabilityRecordsFromManifest nests a capability's arbitrary metadata struct under "metadata" rather than flattening it, so an installed plugin's contract lives at metadata.metadata.scan_source. The top-level lookup never matched, silently resolving every plugin to host defaults. Look in the nested location first, keeping the flat path for host-built descriptors. - The same converter persists config_schema without admin_form, so a plugin's form could never reach the UI through that route. The canonical location is now config_form inside the typed block, which survives installation; the config_schema path is retained only as a fallback. - Compatibility merging now tracks which fields the manifest actually declared instead of comparing against defaults. A plugin explicitly declaring a default-valued field was previously indistinguishable from silence and got overwritten, contradicting the stated manifest-wins contract. - Dynamic-option fields are dropped from source config forms: their options come from a connection-aware probe only the plugin-config page performs, so a required one could never be satisfied and would block creation permanently. Frontend: - The mapping editor asked for "the path your download manager reports" and suggested /downloads/tv. arrwebhook.Parse consumes episodeFile.path / movieFile.path — the arr's imported library paths, not the download client's working directory — so following the example produced rewrites that never matched. Relabelled to the Sonarr/Radarr root folder. - Full-state saves no longer carry an invalid config draft. Enabling, renaming, or editing an interval serialized the in-progress draft, bypassing the validity gate; unrelated mutations now send the persisted config instead. - Legacy movie_nested_paths/tv_nested_paths migration is scoped to the CephFS identity. Applied globally it would rename an unrelated plugin's identically-named key on first save, losing its configuration. - Rows re-parse when the descriptor arrives after /sources. Mounting with the default descriptor left stored switch values as strings, so "false" rendered as an enabled switch. Done during render rather than in an effect, and skipped once the row is dirty so an in-progress edit survives. - Values hidden by an unsatisfied show_when are no longer persisted, and displayed defaults are. Both come from reusing buildSchemaValues, the same helper the plugin-config page uses. - The manual connection form asks which service it is when a descriptor accepts several, instead of always recording the first kind. - The inline connection picker remounts per source, so a half-entered server is not carried into a different plugin's descriptor. - emits_native_paths sources report unknown targets rather than "can't match anything": they discover Silo-native paths at poll time and need no configured root. |
||
|
|
bcea996172 |
fix(autoscan): address PR review findings
Codex and CodeRabbit review of #515. Each finding verified against the code before acting; two were declined with reasons recorded below. Correctness: - source_config is plaintext JSONB returned verbatim by the source API, unlike connection keys which take the repository's encrypted path. Drop secret and PASSWORD fields from scan-source config forms rather than rendering a masked input over a value stored in the clear. Plugins needing a credential should take a connection. - Plugin-declared webhook delivery is dropped at parse time. resolveDeliveryMode accepts webhook only for the built-in ARR identity, so honouring the claim offered a setup path whose every submission ended in HTTP 400. The built-in supplies its descriptor directly, so it is unaffected. - Compat lookup now requires plugin id AND capability id. Capability ids are author-chosen and not unique, so an OR handed CephFS's path/exclusion form to any plugin naming a capability "cephfs". - Config values stay typed until submit. Stringifying every change turned a false switch into the truthy "false" (re-rendering it enabled) and a multi-select array into a join the renderer read back as no selection. - Creation is gated on config-form validity. The host stores source_config without interpreting it, so required and validated fields are only enforced client-side; the dialog previously ignored the renderer's verdict. - Row editing now honours the descriptor it was already given: a `required` source cannot be unbound, a `none` source shows no picker, and only compatible connection kinds are offered. - sourceTargets skips disabled libraries. The scanner rejects them, so counting one as a target showed a source as wired while its deliveries were dropped. - Inline reuse compares request_integration_id, not connection id — different identifier spaces, so the dedupe matched nothing and could create a second connection to the same server. Disabled integrations are also excluded, since they are rejected at poll time. - Webhook setup instructions follow the operator's chosen provider rather than the descriptor, which advertises both kinds and so always resolved to "auto". - Webhook rows render their plugin-declared config form (the built-in's provider field stays with the endpoint section, not duplicated). Declined: - Collapsing sibling paths to a common ancestor is kept. It is what takes a real install's 96 library paths to 2 rows. The reviewer is right that one rule cannot serve branches the arr exposes under different roots, so the editor now offers to split a collapsed row into one row per branch (expandedRootsFor) instead of forcing the operator to retype paths. - Legacy source_config keys are still migrated away on first save; the comment claiming both keys are written was wrong and has been corrected to match. Also: stable ids on mapping rows so removing one does not throw focus into a neighbouring field, memoized config fields, and descriptor marked optional in the TS type to match descriptorFor's documented fallback. |
||
|
|
251282186e |
feat(autoscan): make source setup descriptor-driven and self-contained
Autoscan setup asked operators to hold five concepts — plugin, capability, source, connection, delivery mode — before anything scanned, spread across four tabs. Sources never stated which library they fed, so a misconfigured one ran cleanly and silently did nothing. The admin UI also hardcoded two plugin identities: SourcesPanel.tsx carried 33 references to silo.autoscan.cephfs / silo.autoscan.arr-webhook plus a bespoke CephFS config editor. A third-party scan-source plugin could render no configuration UI at all without patching silo-server. Host side, add a ScanSourceDescriptor read from capability manifest metadata: delivery modes, connection requirement, connection kinds, and the per-source config form. Capabilities that declare nothing resolve to poll + optional connection — exactly the pre-descriptor behavior, so existing installs are unaffected. Compatibility descriptors for the two first-party plugins live in one file with a clear exit: the manifest always wins, so a plugin takes ownership by publishing its own. UI side, the Add-source flow builds its steps from the descriptor rather than from plugin ids, so a single-mode source is never asked how changes arrive and a credential-free one never sees the connection step. Connections are created inline (previously a dead end that forced cancelling out of the dialog), and webhook setup finishes in one place: mappings, then the URL with the exact Sonarr/Radarr triggers the host actually parses. Mapping rows seed from library paths collapsed to their common ancestor per mount point. Verified against a real install: 96 library paths become 2 rows. Rewrites match by longest prefix at a segment boundary, so one row per mount covers everything beneath it. Fold the Connections and Settings tabs into an Advanced section (4 tabs -> 2); old ?tab= links land on Sources with it expanded. Source rows now name the libraries they feed and warn when a source can never resolve one. API changes are additive within /api/v1: new optional fields on /autoscan/scan-source-plugins only. |