Skip to content
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ec7b5c7
feat(plugin): 插件版本目录布局与版本解析
Aqr-K Sep 2, 2026
abf9a4d
fix(plugin): 按版本目录导入插件模块失败时清除半成品缓存
Aqr-K Sep 2, 2026
382c0b3
feat(plugin): 插件版本注册、存量布局迁移与安装期多版本并存拒绝
Aqr-K Sep 2, 2026
5e6d5e5
feat(plugin): 安装流水线暂存内容后原子落盘版本目录
Aqr-K Sep 2, 2026
69311fd
test(plugin): 覆盖安装落盘版本目录、迁移、拒绝与暂存回滚
Aqr-K Sep 2, 2026
509f73c
feat(plugin): 实例绑定插件版本,多实例并行运行不同版本
Aqr-K Sep 2, 2026
0005e96
feat(plugin): 前端与静态资源按实例版本绑定解析目录
Aqr-K Sep 2, 2026
b1c12c7
feat(plugin): 插件版本回收与手动触发端点
Aqr-K Sep 2, 2026
dbd1f88
feat(plugin): 插件实例描述符迁入独立表
Aqr-K Sep 2, 2026
8a41a3e
feat(plugin): 插件实例描述符运行期接线与兜底导入
Aqr-K Sep 2, 2026
42d2381
feat(plugin): 源插件本体绑定运行版本
Aqr-K Sep 2, 2026
dbe778a
chore(architecture): 刷新插件实例描述符表的架构与启动性能基线
Aqr-K Sep 2, 2026
5888384
fix(plugin): 插件实例表统一去下划线命名并补全数据库技能文档
Aqr-K Sep 2, 2026
04f9878
feat(plugin): 插件实例描述符增加日志等级覆盖列
Aqr-K Sep 2, 2026
f0389d6
feat(plugin): 插件实例日志等级运行期解析与四类入口绑定
Aqr-K Sep 2, 2026
47293fb
feat(plugin): 插件实例日志等级查询与设置端点
Aqr-K Sep 2, 2026
241ad27
chore(architecture): 同步日志等级端点的 Agent 契约与架构基线
Aqr-K Sep 2, 2026
a1ed863
feat(plugin): 插件实例描述符增加默认调用目标标记列
Aqr-K Sep 3, 2026
f01bc6b
feat(plugin): 插件实例默认调用目标运行期裁决与工作流调用点接入
Aqr-K Sep 3, 2026
3007ba1
feat(plugin): 插件实例默认调用目标设置与清除端点
Aqr-K Sep 3, 2026
8445feb
chore(architecture): 同步默认调用目标端点的 Agent 契约与架构基线
Aqr-K Sep 3, 2026
3adefe7
fix(plugin): 迁移链重接到官方新基线头
Aqr-K Sep 3, 2026
b4813bc
chore(architecture): 变基后重新生成架构基线、Agent 契约与技能文档
Aqr-K Sep 3, 2026
a5d9560
chore(db): 插件实例迁移文件版本号顺延到官方之后
Aqr-K Sep 3, 2026
e60bca1
fix(plugin): 插件换入失败时正确回滚未完成的目标目录
Aqr-K Sep 3, 2026
505cfb3
fix(plugin): 插件安装失败清理收敛到单个版本目录
Aqr-K Sep 3, 2026
2c5110f
chore(architecture): 刷新插件安装失败清理改动后的依赖基线与文档指标
Aqr-K Sep 3, 2026
2253826
refactor(db): 插件实例模型改名为 PluginInstance 并去除显式表名
Aqr-K Sep 3, 2026
49b3006
feat(plugin): 插件列表投影补钉版本、默认目标与生效日志等级只读字段
Aqr-K Sep 3, 2026
73adfca
chore(architecture): 同步插件目录读日志等级新增依赖边的架构基线
Aqr-K Sep 3, 2026
b3059d1
docs(db): 插件实例模型 docstring 只描述当前形态
Aqr-K Sep 3, 2026
0719e62
fix(plugin): 换入未提交时不清理已恢复的旧内容
Aqr-K Sep 3, 2026
145aede
chore(architecture): 固化插件版本安装并发基线并复用启动收尾线程池出口
Aqr-K Sep 3, 2026
a3f80e9
fix(plugin): 版本安装失败回滚精确复原登记前的当前版本
Aqr-K Sep 3, 2026
c6dd865
fix(plugin): 修复多版本适配扫描器的共享基类漏检与类型检查误拦
Aqr-K Sep 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
514 changes: 421 additions & 93 deletions app/adapters/system/plugin/package.py

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions app/agent/policy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,26 @@ def _user_write(
_write("plugin.folder.create", recovery=RecoveryMode.TRANSACTION),
_write("plugin.folder.delete", effect=ActionEffect.DESTRUCTIVE_WRITE, recovery=_DELETE_RECOVERABLE),
_write("plugin.folder.plugins.update", recovery=RecoveryMode.TRANSACTION),
_admin_read("plugin.versions.get", sensitivity=ResultSensitivity.PRIVATE),
_spec(
"plugin.versions.set_instance",
effect=ActionEffect.EXTERNAL_SIDE_EFFECT,
required_role=_ADMIN,
confirmation=_CONFIRM,
recovery=RecoveryMode.RECONCILE,
),
_spec(
"plugin.versions.recycle",
effect=ActionEffect.EXTERNAL_SIDE_EFFECT,
required_role=_ADMIN,
confirmation=_CONFIRM,
recovery=RecoveryMode.RECONCILE,
),
_admin_read("plugin.loglevel.get", sensitivity=ResultSensitivity.PRIVATE),
_write("plugin.loglevel.set"),
_write("plugin.loglevel.clear"),
_write("plugin.default_target.set"),
_write("plugin.default_target.clear"),
)


Expand Down Expand Up @@ -755,6 +775,26 @@ def _user_write(
"plugin.folder.create": ApiOperationRoute("POST", "/api/v1/plugin/folders/{folder_name}"),
"plugin.folder.delete": ApiOperationRoute("DELETE", "/api/v1/plugin/folders/{folder_name}"),
"plugin.folder.plugins.update": ApiOperationRoute("PUT", "/api/v1/plugin/folders/{folder_name}/plugins"),
"plugin.versions.get": ApiOperationRoute("GET", "/api/v1/plugin/versions/{plugin_id}"),
"plugin.versions.set_instance": ApiOperationRoute(
"PUT", "/api/v1/plugin/versions/{plugin_id}/{instance_id}"
),
"plugin.versions.recycle": ApiOperationRoute(
"POST", "/api/v1/plugin/versions/{plugin_id}/recycle"
),
"plugin.loglevel.get": ApiOperationRoute("GET", "/api/v1/plugin/loglevel/{plugin_id}"),
"plugin.loglevel.set": ApiOperationRoute(
"PUT", "/api/v1/plugin/loglevel/{plugin_id}/{instance_id}"
),
"plugin.loglevel.clear": ApiOperationRoute(
"DELETE", "/api/v1/plugin/loglevel/{plugin_id}/{instance_id}"
),
"plugin.default_target.set": ApiOperationRoute(
"PUT", "/api/v1/plugin/instances/{plugin_id}/{instance_id}/default_target"
),
"plugin.default_target.clear": ApiOperationRoute(
"DELETE", "/api/v1/plugin/instances/{plugin_id}/{instance_id}/default_target"
),
}


Expand Down
18 changes: 18 additions & 0 deletions app/agent/policy/mcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@
"plugin.folder.create": "Create one named plugin folder.",
"plugin.folder.delete": "Delete one named plugin folder without uninstalling its plugins.",
"plugin.folder.plugins.update": "Replace the ordered plugin IDs assigned to one named plugin folder.",
"plugin.versions.get": "List one plugin's installed source versions and each instance's version binding.",
"plugin.versions.set_instance": "Set one plugin instance's version binding and restart it to apply the change.",
"plugin.versions.recycle": "Delete one plugin's installed source versions that are unreferenced and outside the retention window.",
"plugin.loglevel.get": "List one plugin's instances, including its host binding, with each instance's configured and effective log level.",
"plugin.loglevel.set": "Set one plugin instance's log-level override, taking effect immediately without following the global log level.",
"plugin.loglevel.clear": "Clear one plugin instance's log-level override so it immediately follows the global log level again.",
"plugin.default_target.set": "Set one plugin instance as the plugin's default call target, automatically clearing any previous default.",
"plugin.default_target.clear": "Clear one plugin instance's default-call-target flag, only if it is the plugin's current default.",
}


Expand Down Expand Up @@ -245,6 +253,7 @@
"completed_episode": "Highest episode number already completed for the subscription.",
"current_site_id": "Configured site ID currently handling the subscription execution.",
"cookie": "Site authentication cookie. Treat this value as a secret.",
"configured_level": "Plugin instance's own configured log-level override, null when unset or expired.",
"count": "Maximum number of records to return on the requested page.",
"current_audio_format": "Audio format of the best version currently held.",
"current_bit_depth": "Bit depth of the best version currently held.",
Expand Down Expand Up @@ -272,6 +281,7 @@
"douban_sort": "Douban Music category order: U for comprehensive, S for rating, R for newest, or O for hottest.",
"drive_id": "Provider-native storage drive identifier.",
"effect": "Video or release-effect filter expression used by the subscription.",
"effective_level": "Plugin instance's actual log level after resolving its override and expiry against the global log level.",
"error": "Human-readable workflow, provider, or execution error message.",
"entity": "Music exploration entity: recording for tracks or album for release groups.",
"enclosure": "Torrent download URL or enclosure supplied by the indexer result.",
Expand All @@ -284,6 +294,7 @@
"episodes": "Episode-number expression recorded in history, such as E01-E03.",
"errmsg": "Error message recorded for a failed transfer.",
"expected_revision": "Exact current plugin source-identity revision returned by plugin.source.options.",
"expires_at": "Expiry timestamp for a plugin instance's log-level override; null means it never expires.",
"exclude": "Regular expression or filter expression that rejects matching releases.",
"extension": "Filename extension, including or excluding the leading dot as returned by storage.",
"fileid": "Provider-native storage item identifier.",
Expand All @@ -292,6 +303,7 @@
"files": "Serialized list of files recorded by the history item.",
"filter": "Named filter rule or rule expression applied to this site or subscription.",
"filter_groups": "Ordered filter-rule group names applied to the subscription.",
"follow_current_version": "Follow the plugin's currently installed version instead of a pinned one.",
"force": "Force a marketplace refresh or plugin installation when true.",
"freedate": "Torrent freeleech expiration timestamp reported by the site.",
"freedate_diff": "Seconds remaining until the torrent freeleech period ends.",
Expand All @@ -310,13 +322,16 @@
"include_group_refs": "Include custom rules referenced only through rule groups.",
"include_usage": "Include the subscriptions or defaults that reference each rule group.",
"include_values": "Return complete setting values instead of discovery summaries.",
"instance_id": "Exact plugin instance ID returned by plugin.versions.get.",
"is_active": "Whether the configured site is enabled.",
"is_default_target": "Whether this plugin instance is the plugin's default call target, used when a caller does not specify an instance.",
"jobid": "Exact scheduler job ID returned by scheduler.list.",
"key": "Optional exact plugin data key used to narrow the returned preview.",
"keyword": "Case-insensitive substring used to discover settings or filter storage entries.",
"labels": "Torrent labels supplied by the site result.",
"lack_episode": "Number of episodes still missing from the subscription.",
"last_update": "Timestamp of the subscription's most recent update.",
"level": "Target log level, one of DEBUG, INFO, WARNING, ERROR, or CRITICAL.",
"library_category_folder": "Create or use a category-level folder in the target library.",
"library_type_folder": "Create or use a media-type folder in the target library.",
"limit_count": "Maximum number of site requests allowed in one rate-limit interval.",
Expand Down Expand Up @@ -365,6 +380,7 @@
"person_id": "Source-native person ID returned by person search.",
"pickcode": "115 storage pickcode associated with the item.",
"plugin_id": "Exact installed or marketplace plugin ID.",
"plugin_version": "Exact installed plugin version; required only when not following the current version.",
"poster": "Poster image URL stored with the media or subscription.",
"preview": "Validate and preview manual-transfer output without committing file changes.",
"pri": "Site search priority; lower or higher ordering follows the existing site API convention.",
Expand Down Expand Up @@ -567,6 +583,8 @@
"MediaSource": "Canonical metadata source identifier paired with a source-native media ID.",
"MediaType": "MoviePilot media type.",
"MusicRecognizeRequest": "Exact source-native recording or album identity to resolve into canonical music metadata.",
"PluginInstanceLogLevelUpdateRequest": "One plugin instance's log-level override update request.",
"PluginInstanceVersionUpdateRequest": "One plugin instance's version-binding update request.",
"PluginSourceChangeRequest": "Explicit online-source change request guarded by the current identity revision.",
"PluginSourceInstallRequest": "Explicit online-source installation request for an unbound plugin.",
"Site-Input": "Complete site configuration and runtime state.",
Expand Down
Loading
Loading