@koishi-ce/plugin-market 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/style.css CHANGED
@@ -1,2 +1,2 @@
1
- .confirm-panel td.arrow{padding:0}.confirm-panel td.arrow span{justify-content:center;align-items:center;display:flex}.confirm-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.manual-panel .k-comment{margin-top:0}.dep-package-view[data-v-0fc4cb55]{height:3rem;position:relative}.dep-package-view .el-button[data-v-0fc4cb55]{width:4rem}.page-deps{flex-flow:column;display:flex}.page-deps .body-container{margin-top:-1px;transform:translateY(1px)}.page-deps table tr:first-child{border-top:none}.page-deps tbody tr{transition:all .3s}.page-deps tbody tr:hover{background-color:var(--k-side-bg)}@media (width<=768px){.page-deps td{padding:.5em}}.theme-color.primary{color:var(--primary)}.theme-color.success{color:var(--success)}.theme-color.warning{color:var(--warning)}.theme-color.danger{color:var(--danger)}.install-panel .el-dialog__header{align-items:center;gap:0 .5em;padding-bottom:4px;padding-right:36px;display:flex}.install-panel .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.install-panel .el-dialog__header .el-select{flex:auto;max-width:12.5rem;margin:-2px 0 -4px}.install-panel .warning{color:var(--k-color-warning)}.install-panel .danger{color:var(--k-color-danger)}.install-panel .version-badges{float:right;margin-right:-12px}.install-panel .el-dialog__body{min-height:40px;padding:0 20px}.install-panel .el-dialog__body>div{margin:1rem 0}.install-panel .el-dialog__body:last-child{padding-bottom:1rem}.install-panel table thead td,.install-panel table thead th,.install-panel table tbody td,.install-panel table tbody th{white-space:nowrap;padding:.5em .875em}.install-panel span.link:hover{cursor:pointer;text-decoration:underline}.install-panel .el-button+.el-button{margin-left:1rem}.install-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.install-panel .wrapper{display:inline-flex;position:relative}.install-panel .wrapper .shadow{letter-spacing:1px;visibility:hidden;padding-right:22px}.install-panel .wrapper .el-select{position:absolute;top:50%;left:0;right:0;transform:translateY(-50%)}.dot-hint:before{content:"";background-color:currentColor;border-radius:100%;width:.5rem;height:.5rem;transition:background-color .3s;position:absolute;top:50%;right:20px;transform:translateY(-50%);box-shadow:1px 1px 2px #3333}.k-schema-item p{margin:.25rem;font-size:.875rem;line-height:1.7}.k-schema-item .markdown p{margin:0}.k-schema-item ul{width:100%;padding-left:1rem;font-size:.875rem;list-style:none}.k-schema-item ul .el-radio,.k-schema-item ul .el-checkbox{height:1.375rem}.k-schema-item .el-button+.el-button{margin-left:0}.k-schema-item .k-schema-main{grid-template-columns:1fr auto 2rem;justify-content:space-between;align-items:center;gap:.25rem 1rem;min-height:3rem;display:grid}.k-schema-item h3{-webkit-user-select:none;user-select:none;align-items:center;margin:0;font-size:1rem;line-height:1.7;display:flex;position:relative}.k-schema-item h3>*{flex:none}.k-schema-item h3 .prefix{text-overflow:ellipsis;flex:0 auto;font-weight:400;overflow:hidden}.k-schema-item .k-schema-right{flex:1;justify-content:flex-end;gap:1rem;display:flex}.k-schema-item .el-button.ellipsis{padding:8px 9px}.k-schema-item .el-button.ellipsis .k-icon{width:12px}.k-schema-item .bottom{margin:.5rem 0 .25rem}.k-schema-item .actions{width:.5rem;height:100%;transition:var(--color-transition);border-left:2px solid #0000;position:absolute;top:0;left:0}.k-schema-item.changed .actions{border-left-color:var(--el-color-primary)}.k-schema-item.required .actions{border-left-color:var(--el-color-error)}.k-schema-item.invalid .actions{border-left-color:var(--el-color-warning)}.k-schema-item .el-input .suffix-icon{justify-content:center;align-items:center;width:1rem;margin-left:6px;display:flex}.k-schema-item .el-input .k-icon{color:var(--k-text-light);transition:var(--color-transition);cursor:pointer;height:.75rem}.k-schema-item .el-input .k-icon:hover{color:var(--k-text-dark)}.k-schema-item .el-input .k-icon.invalid{cursor:auto;color:var(--k-color-danger)}.k-schema-item .el-input.nullable:not(:focus-within) .el-input__prefix{border-top:var(--el-border);width:40%;transition:var(--color-transition);display:block;position:absolute;top:50%}.k-schema-item .el-input .el-input__wrapper{padding-right:9px}.k-schema-item .el-input:not(.minimal).invalid .el-input__wrapper:hover,.k-schema-item .el-input:not(.minimal).invalid .el-input__wrapper.is-focus{box-shadow:0 0 0 1px var(--k-color-danger) inset}.k-schema-item .el-input-number .el-input__wrapper{padding-right:42px}.k-schema-item .el-switch.nullable .el-switch__core{border:1px solid var(--el-border-color);background-color:#0000}.k-schema-item .el-switch.nullable .el-switch__action{background-color:var(--el-border-color);border-radius:0;width:16px;height:1px;left:11px}.k-schema-item .el-switch.nullable:hover .el-switch__core{border-color:var(--el-color-primary)}.entry-input[data-v-e26e0849]{position:relative}.entry-input .shadow[data-v-e26e0849]{visibility:hidden;white-space:pre}.entry-input .placeholder[data-v-e26e0849]{min-width:2rem;display:inline-block}.entry-input input[data-v-e26e0849]{font-size:1em;font-weight:inherit;border:none;border-radius:0;outline:none;margin:0;padding:0 .5em;font-family:inherit;position:absolute;left:-.5em;right:-.5em}.k-schema-table-container{position:relative}.k-schema-table-container .cell-outline{box-sizing:border-box;border:1px solid var(--k-color-active);pointer-events:none;position:absolute}.k-schema-table-container .cell-outline.invalid{border-color:var(--k-color-danger)}.k-schema-table td,.k-schema-table th{border:1px solid var(--el-border-color)}.k-schema-table th{padding:.5rem .75rem;line-height:1.25rem}.k-schema-table td{transition:var(--color-transition);padding:0}.k-schema-table td:hover{background-color:var(--k-button-hover-bg)}.k-schema-table td.k-schema-table-button{width:2rem;max-width:2rem;color:var(--k-text-light);cursor:pointer}.k-schema-table td.k-schema-table-button:hover{color:var(--k-color-active)}.k-schema-table td.k-schema-table-button .inner{box-sizing:border-box;justify-content:center;align-items:center;height:2rem;display:flex}.k-schema-table td.k-schema-table-button .k-icon{height:1rem}.k-schema-table td.k-schema-table-button.disabled{color:var(--k-color-disabled);pointer-events:none}.k-badge{color:#fff;white-space:nowrap;vertical-align:baseline;border-radius:4px;height:1.25rem;margin-left:.5rem;padding:0 6px;font-size:14px;font-weight:500;line-height:1.25rem;display:inline-block}.k-badge.primary{background-color:var(--k-color-primary)}.k-badge.warning{background-color:var(--k-color-warning)}.k-badge.success{background-color:var(--k-color-success)}.k-badge.danger{background-color:var(--k-color-danger)}.k-form:not(:first-child){margin-top:2rem}@media screen and (width<=480px){.k-form{margin:0 -1.5rem}.k-form .k-schema-header{padding:0 1.5rem}.k-form .k-schema-item{padding:.5rem 1.5rem}.k-form .k-schema-item .k-schema-main{min-height:unset;grid-template-rows:auto auto;grid-template-columns:auto 2rem}.k-form .k-schema-item .k-schema-right{grid-area:2/1/auto/2;display:block}.k-form .k-schema-item .k-schema-right>:first-child{margin-top:.25rem}.k-form .k-schema-item .k-schema-right>:last-child{margin-bottom:.25rem}}.k-menu,.k-menu.el-popper.is-light{z-index:1000;background-color:var(--el-bg-color-overlay);min-width:12rem;box-shadow:var(--k-menu-shadow);border-radius:6px;padding:.375rem 0;font-size:14px;position:fixed}.k-menu-separator{border-top:1px solid var(--el-border-color-light);margin:.375rem 0}.k-menu-separator:first-child,.k-menu-separator:last-child,.k-menu-separator+.k-menu-separator{display:none}.k-menu-item{-webkit-user-select:none;user-select:none;cursor:pointer;transition:var(--color-transition);border-radius:4px;margin:0 .375rem;padding:.375rem 0 .375rem 2.5rem;position:relative}.k-menu-item.disabled{color:var(--k-color-disabled);pointer-events:none}.k-menu-item:not(.disabled):hover{background-color:var(--k-hover-bg);color:inherit!important}.k-menu-item:not(.disabled).primary{color:var(--el-color-primary)}.k-menu-item:not(.disabled).primary:hover{background-color:var(--el-color-primary)}.k-menu-item:not(.disabled).danger{color:var(--el-color-error)}.k-menu-item:not(.disabled).danger:hover{background-color:var(--el-color-error)}.k-menu-item:not(.disabled).warning{color:var(--el-color-warning)}.k-menu-item:not(.disabled).warning:hover{background-color:var(--el-color-warning)}.k-menu-icon{justify-content:center;align-items:center;width:2.5rem;height:100%;display:flex;position:absolute;top:0;left:0}.k-menu-icon .k-icon{height:1rem}.k-schema-item{border-bottom:1px solid var(--el-border-color-light);transition:var(--color-transition);padding:.5rem 1rem;position:relative}.k-schema-item:first-child,:not(.k-schema-item):not(.k-schema-group)+.k-schema-item{border-top:1px solid var(--el-border-color-light)}.k-schema-item+h2{margin-top:2rem}.k-schema-item:hover{background-color:var(--el-fill-color)}.k-schema-item .k-schema-right .el-select{width:12rem}.k-schema-header{margin:1rem 0;font-size:1.25rem}.k-schema-header:not(:first-child){margin-top:2rem}.k-schema-group{position:relative}.k-schema-group:empty{border-bottom:none}.k-schema-group>:first-child{border-top:none}.k-schema-table .el-input,.k-schema-table .el-input-number{width:100%}.k-schema-table-cell-input,.k-schema-table-cell-input-number,.k-schema-table-cell-select{min-width:6rem}.k-schema-table .el-input__wrapper,.k-schema-table .el-select__wrapper{box-shadow:none!important}.el-input.invalid .el-input__wrapper,.el-textarea.invalid .el-textarea__inner{box-shadow:0 0 0 1px var(--el-color-danger) inset}.k-schema-edit-dialog .el-dialog__footer{justify-content:space-between;display:flex}.k-filter-expr{flex:1 0 auto;display:inline-flex}.k-filter-expr .entity,.k-filter-expr .operator{flex:none;width:7.5rem}.k-filter-expr .value{flex:1 0 auto;width:auto}.k-filter-item{display:flex}.overlay-enter-from,.overlay-leave-to{opacity:0}.overlay-enter,.overlay-leave{opacity:1}.image-viewer{position:absolute;inset:0}.image-viewer .button{cursor:pointer;-webkit-user-select:none;user-select:none;opacity:.5;background-color:#303133;border-radius:3rem;justify-content:space-evenly;align-items:center;height:3rem;font-size:1.5rem;transition:all .4s;display:flex;position:absolute}.image-viewer .button .k-icon{height:1.25rem;transition:all .4s}.image-viewer .button:not(.disabled):hover{opacity:.8}.image-viewer .button:not(.disabled) .k-icon:hover{color:#f4f4f5cc}.image-viewer .button.left{z-index:2000;width:3rem;top:50%;left:3rem;transform:translateY(-50%)}.image-viewer .button.left .k-icon{margin-left:-3px}.image-viewer .button.right{z-index:2000;width:3rem;top:50%;right:3rem;transform:translateY(-50%)}.image-viewer .button.right .k-icon{margin-right:-3px}.image-viewer .button.bottom{z-index:2000;width:18rem;bottom:3rem;left:50%;transform:translate(-50%)}.image-viewer .button.disabled{cursor:not-allowed}.image-viewer img{transition:all .3s;position:absolute}.k-link{cursor:pointer;text-decoration:underline}.k-link:hover{text-decoration:underline}.market-filter-item[data-v-542fc917]{box-sizing:border-box;color:var(--k-text-normal);z-index:2;cursor:pointer;border-radius:8px;align-items:center;height:28px;margin:2px 0;padding:0 .5rem;transition:color .2s,background-color .2s;display:flex}.market-filter-item[data-v-542fc917]:hover{color:var(--k-text-dark);background-color:var(--k-hover-bg)}.market-filter-item.active[data-v-542fc917]{color:var(--k-color-primary);background-color:color-mix(in srgb, var(--k-color-primary) 10%, transparent)}.market-filter-item.active .text[data-v-542fc917]{font-weight:600}.market-filter-item.active.verified[data-v-542fc917],.market-filter-item.active.newborn[data-v-542fc917]{color:var(--k-color-success);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent)}.market-filter-item.active.preview[data-v-542fc917],.market-filter-item.active.portable[data-v-542fc917]{color:var(--k-color-warning);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent)}.market-filter-item.active.insecure[data-v-542fc917]{color:var(--k-color-danger);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent)}.market-filter-item.disabled[data-v-542fc917]{opacity:.5;text-decoration:line-through;text-decoration-thickness:2px}.market-filter-item .icon[data-v-542fc917]{justify-content:center;align-items:center;width:1.75rem;margin-right:4px;display:inline-flex}.market-filter-item:not(.active) .order[data-v-542fc917]{display:none}.market-filter-item .order[data-v-542fc917]{justify-content:center;align-items:center;width:1.75rem;display:inline-flex}.market-filter-item svg[data-v-542fc917]{max-width:1.125rem;height:1rem}.market-filter-item .text[data-v-542fc917],.market-filter-item .count[data-v-542fc917]{font-size:14px;font-weight:500;line-height:20px}.market-filter-item .count[data-v-542fc917]{opacity:.7;margin-right:4px;font-size:12px}.market-filter-item .spacer[data-v-542fc917]{flex:1}.cat-adapter[data-v-0e838db4]{--c:#38bdf8}.cat-general[data-v-0e838db4]{--c:#4ade80}.cat-extension[data-v-0e838db4]{--c:#a78bfa}.cat-webui[data-v-0e838db4]{--c:#fb923c}.cat-manage[data-v-0e838db4]{--c:#facc15}.cat-preset[data-v-0e838db4]{--c:#60a5fa}.cat-image[data-v-0e838db4]{--c:#f472b6}.cat-media[data-v-0e838db4]{--c:#e879f9}.cat-tool[data-v-0e838db4]{--c:#94a3b8}.cat-life[data-v-0e838db4]{--c:#34d399}.cat-ai[data-v-0e838db4]{--c:#818cf8}.cat-meme[data-v-0e838db4]{--c:#fbbf24}.cat-game[data-v-0e838db4]{--c:#f87171}.cat-gametool[data-v-0e838db4]{--c:#c084fc}.cat-other[data-v-0e838db4]{--c:#64748b}.market-package[data-v-0e838db4]{box-sizing:border-box;background-color:var(--k-card-bg);border:1px solid var(--k-color-border);contain:layout paint style;border-radius:12px;width:100%;max-width:540px;height:calc(12.5rem + 2px);margin:0;padding:1rem 1.25rem;transition:border-color .18s,box-shadow .18s,background-color .18s;position:relative}.market-package[data-v-0e838db4]:hover{border-color:var(--k-color-primary);box-shadow:0 4px 12px #0000000f}.market-package .market-icon[data-v-0e838db4]{height:1em;display:inline}.market-package .header[data-v-0e838db4],.market-package .footer[data-v-0e838db4]{flex:none}.market-package .header[data-v-0e838db4]{position:relative}.market-package .header .left[data-v-0e838db4]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--c) 35%, var(--k-color-border));background:linear-gradient(135deg, color-mix(in srgb, var(--c) 18%, var(--k-card-bg)), color-mix(in srgb, var(--c) 10%, var(--k-card-bg)));width:3.5rem;height:3.5rem;transition:var(--color-transition);border-radius:10px}.market-package .header .left svg[data-v-0e838db4]{height:1.75rem;color:var(--c)}.market-package .header h2[data-v-0e838db4]{align-items:center;margin:0;font-size:1.125rem;font-weight:600;line-height:1.2;display:flex}.market-package .header h2 .title[data-v-0e838db4]{flex:0 auto;line-height:1.5rem;display:inline-block}.market-package .header .heartbeat[data-v-0e838db4]{height:1.5rem;color:var(--k-text-light);align-items:center;gap:5px;font-size:12px;display:inline-flex}.market-package .header .heartbeat .market-icon[data-v-0e838db4]{width:12px;height:12px;color:color-mix(in srgb, #eb4d55 var(--heart-mix,0%), var(--k-text-light));opacity:var(--heart-opacity,.5);filter:drop-shadow(0 0 calc(var(--heart-glow,0) * 4px) rgb(235, 77, 85, calc(var(--heart-glow,0) * .45)));flex:none;transition:color .3s,opacity .3s}.market-package .badge-float[data-v-0e838db4]{position:absolute;bottom:2.5rem;right:1.25rem}.market-package .badge-pill[data-v-0e838db4]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-success) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent);height:20px;color:var(--k-color-success);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:10px;align-items:center;gap:3px;padding:0 6px;font-size:12px;font-weight:500;line-height:20px;display:inline-flex}.market-package .badge-pill .market-icon[data-v-0e838db4]{width:12px;height:12px}.market-package .badge-pill.preview[data-v-0e838db4]{border-color:color-mix(in srgb, var(--k-color-warning) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent);color:var(--k-color-warning)}.market-package .badge-pill.insecure[data-v-0e838db4]{border-color:color-mix(in srgb, var(--k-color-danger) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent);color:var(--k-color-danger)}.market-package .desc[data-v-0e838db4]{color:var(--k-text-light);word-break:break-word;text-overflow:ellipsis;-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:auto;margin:0;font-size:14px;line-height:1.6;display:-webkit-box;overflow:hidden}.market-package .footer[data-v-0e838db4]{cursor:default;height:1.5rem;color:var(--k-text-light);align-items:center;gap:.5rem;margin-bottom:-.25rem;font-size:13px;transition:color .3s;display:flex;overflow:hidden}.market-package .footer[data-v-0e838db4]>*{flex:none}.market-package .footer .spacer[data-v-0e838db4]{flex:0 2 .5rem}.market-package .footer .long-spacer[data-v-0e838db4]{flex:auto}.market-package .footer .market-icon[data-v-0e838db4]{vertical-align:-1px;width:16px;height:12px;margin-right:6px}.market-package .footer .avatars[data-v-0e838db4]{gap:.25rem;display:flex}.market-package .footer .avatars .avatar[data-v-0e838db4]{cursor:pointer;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar img[data-v-0e838db4]{vertical-align:middle;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar.fallback[data-v-0e838db4]{box-sizing:border-box;background:linear-gradient(135deg, color-mix(in srgb, var(--c) 30%, var(--k-card-bg)), color-mix(in srgb, var(--c) 12%, var(--k-card-bg)));color:color-mix(in srgb, var(--c) 80%, var(--k-text-dark));justify-content:center;align-items:center;font-size:.68rem;font-weight:700;display:inline-flex}.market-package .footer .avatars .avatar.fallback[data-v-0e838db4]:before{content:attr(data-initial)}@media (width<=420px){.market-package[data-v-0e838db4]{height:auto;min-height:11rem;padding:.82rem .9rem}.market-package .header .left[data-v-0e838db4]{width:3rem;height:3rem}.market-package h2[data-v-0e838db4]{font-size:1rem}.market-package .badge-float[data-v-0e838db4]{bottom:2.3rem;right:.9rem}.market-package .footer[data-v-0e838db4]{flex-wrap:wrap;height:auto}.market-package .footer .long-spacer[data-v-0e838db4]{display:none}}.package-list[data-v-e3691166]{gap:var(--card-margin);flex:1 0 auto;grid-template-columns:repeat(auto-fill,minmax(336px,1fr));justify-items:center;display:grid}.pagination[data-v-e3691166]{margin:var(--card-margin) 0;justify-content:center}.k-empty[data-v-e3691166]{flex:1 0 auto}.search-box[data-v-ee66eeec]{border:1.5px solid var(--k-color-border);box-sizing:border-box;background-color:var(--k-card-bg);border-radius:2rem;align-items:center;width:100%;max-width:640px;margin:2rem auto 0;transition:border-color .2s,box-shadow .2s;display:flex;box-shadow:0 2px 12px #0000000f,0 1px 3px #0000000a}.search-box[data-v-ee66eeec]:focus-within{border-color:var(--k-color-primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--k-color-primary) 15%, transparent), 0 2px 12px #0000000f, 0 1px 3px #0000000a}.search-container[data-v-ee66eeec]{flex-wrap:wrap;flex:auto;align-items:center;gap:8px 6px;padding:.75rem 0 .75rem 1.25rem;display:flex}.search-container input[data-v-ee66eeec]{box-sizing:border-box;min-width:10rem;height:1.25rem;color:inherit;background-color:#0000;border:none;outline:none;flex:auto;padding:0;font-size:.925rem}.search-action[data-v-ee66eeec]{cursor:pointer;flex-direction:column;flex:none;justify-content:center;align-items:center;width:3rem;height:2.5rem;display:flex}.search-action .market-icon[data-v-ee66eeec]{opacity:.45;height:1rem;transition:opacity .2s}.search-action:hover .market-icon[data-v-ee66eeec]{opacity:.85}.search-action:hover .market-icon.search[data-v-ee66eeec],.search-action:not(:hover) .market-icon.close[data-v-ee66eeec]{display:none}.search-word[data-v-ee66eeec]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-primary) 25%, transparent);background-color:color-mix(in srgb, var(--k-color-primary) 12%, transparent);height:1.375rem;color:var(--k-color-primary);white-space:nowrap;vertical-align:baseline;cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;flex:none;padding:0 8px;font-size:12px;font-weight:500;line-height:calc(1.375rem - 2px);transition:opacity .3s,background-color .3s,border-color .3s;display:inline-block}.search-word.invalid[data-v-ee66eeec]{opacity:.5;text-decoration:line-through}.search-word.invalid[data-v-ee66eeec]:hover{opacity:1}@media (width<=420px){.search-box[data-v-ee66eeec]{border-radius:12px}}.page-market .layout-main .el-scrollbar__view{padding:0 var(--card-margin);flex-direction:column;min-height:100%;display:flex}.page-market .layout-left .market-filter-group{margin:1.5rem 0;padding:0 1rem}.page-market .layout-left h2{letter-spacing:.08em;text-transform:uppercase;color:var(--k-text-light);opacity:.7;margin:0;padding:6px .5rem;font-size:11px;font-weight:700}.market-loading{flex-direction:column;flex:1 0 auto;justify-content:center;align-items:center;gap:2rem;min-height:50vh;display:flex}.market-loading .el-loading-spinner{margin-top:0}.market-slow.k-comment{max-width:640px}.market-hint{width:100%;color:var(--el-text-color-regular);font-size:var(--el-font-size-base);font-weight:var(--el-font-weight-primary);margin:1rem 0 .75rem;transition:color .3s}.market-container .k-button{margin-left:1rem;padding:.35em .85em;transform:translateY(-1px)}.market-error.k-comment{margin-left:2rem;margin-right:2rem}.page-market .el-scrollbar__thumb{background-clip:content-box;background-color:color-mix(in srgb, var(--k-color-primary) 26%, var(--fg3));border:2px solid #0000;border-radius:999px;min-height:32px}.page-market .el-scrollbar__thumb:hover{background-color:color-mix(in srgb, var(--k-color-primary) 44%, var(--fg3))}.k-status .el-progress-bar{width:120px;margin-right:2px}.dialog-config-fork .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.dialog-config-fork .status-light{margin-right:.75rem}.dialog-config-fork .actions{justify-content:flex-end;align-items:center;gap:0 .5rem;display:flex}.dialog-config-fork .action{cursor:pointer;width:1.25rem;color:var(--fg2);transition:var(--color-transition);justify-content:center;display:inline-flex}.dialog-config-fork .action:hover{color:var(--fg1)}.dialog-config-fork .el-dialog__footer{justify-content:space-between;align-items:center;font-size:.9em;display:flex}.modifier,.plugin-view .markdown.usage{margin-bottom:2rem}.plugin-view .markdown.usage h2{font-size:1.25rem}.plugin-tree{width:100%;height:100%;overflow:auto}.plugin-tree .el-scrollbar__view{padding:1rem 0;line-height:2.25rem}.plugin-tree .search{padding:0 1.5rem}.plugin-tree .k-icon-filter{height:15px}.plugin-tree .el-tree-node.is-group>.el-tree-node__content{font-weight:700}.plugin-tree .el-tree-node__content .item{flex:1;justify-content:space-between;align-items:center;height:100%;display:flex;overflow:hidden}.plugin-tree .el-tree-node__content .label{text-overflow:ellipsis;transition:var(--color-transition);overflow:hidden}.plugin-tree .el-tree-node__content .right{height:100%;margin:0 1.5rem 0 .5rem}.end{margin-right:.5rem}.config-header{margin:0 0 2rem;font-size:1.375rem;line-height:2rem}.config-header .k-button{float:right}.plugin-view .k-content>:first-child{margin-top:0}.plugin-select .el-dialog__header{border-bottom:1px solid var(--k-color-divider);justify-content:space-between;align-items:center;margin-right:0;padding:12px 20px;display:flex}.plugin-select .el-dialog__header button{top:2px}.plugin-select .el-dialog__header .title{flex:none}.plugin-select .el-dialog__header .el-input{width:220px;height:2rem;display:inline-block}.plugin-select .el-dialog__body{height:50vh;padding:0;display:flex}.plugin-select .el-dialog__body .tabs{border-right:1px solid var(--k-color-divider);flex:none;width:7.5rem;font-size:15px}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs{width:3rem}}.plugin-select .el-dialog__body .tabs .el-scrollbar__view{padding:.5rem 0}.plugin-select .el-dialog__body .tabs .tab-item{cursor:pointer;height:2rem;transition:var(--color-transition);justify-content:center;align-items:center;padding:0 1rem;font-size:.875rem;display:flex}.plugin-select .el-dialog__body .tabs .tab-item:hover{background-color:var(--k-hover-bg)}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item{padding:0}}.plugin-select .el-dialog__body .tabs .tab-item .market-icon{width:1.25rem;height:1rem}.plugin-select .el-dialog__body .tabs .tab-item.active{color:var(--primary)}.plugin-select .el-dialog__body .tabs .tab-item .title{width:3.5rem;margin-left:.5rem}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item .title{display:none}}.plugin-select .el-dialog__body .content{flex:auto}.plugin-select .el-dialog__body .content .package{cursor:pointer;transition:var(--color-transition);padding:.5rem 1rem}.plugin-select .el-dialog__body .content .package h3{margin:0 0 .25rem;font-size:16px}.plugin-select .el-dialog__body .content .package p{margin:0;font-size:14px}.plugin-select .el-dialog__body .content .package:hover{background-color:var(--k-hover-bg)}.absolute{position:absolute}.relative{position:relative}.grid{display:grid}.my-8{margin-top:2rem;margin-bottom:2rem}.inline{display:inline}.block{display:block}.inline-block{display:inline-block}.hidden{display:none}.h2{height:.5rem}.h3{height:.75rem}.flex{display:flex}.inline-flex{display:inline-flex}.shrink-0{flex-shrink:0}.grow-1{flex-grow:1}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.transform{transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.items-center{align-items:center}.justify-center{justify-content:center}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{column-gap:1rem}.gap-y-2{row-gap:.5rem}.overflow-hidden{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.b,.border{border-width:1px}.px{padding-left:1rem;padding-right:1rem}.pl-8{padding-left:2rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color,#0000001a),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color,#0000001a);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow)}.outline{outline-style:solid}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease{transition-timing-function:cubic-bezier(.4,0,.2,1)}.dialog-config-fork .status-light,.plugin-tree .status-light{width:.625rem;height:.625rem;transition:var(--color-transition);border-radius:100%;display:inline-block}.dialog-config-fork .status-light.active,.plugin-tree .status-light.active{background-color:var(--k-color-success)}.dialog-config-fork .status-light.pending,.plugin-tree .status-light.pending{background-color:var(--k-color-warning)}.dialog-config-fork .status-light.loading,.plugin-tree .status-light.loading{background-color:var(--k-color-warning);animation:1s infinite status-flash}.dialog-config-fork .status-light.failed,.plugin-tree .status-light.failed{background-color:var(--k-color-danger)}.dialog-config-fork .status-light.disabled:not(.ignore-disabled),.plugin-tree .status-light.disabled:not(.ignore-disabled){opacity:.5;background-color:var(--k-color-disabled)}@keyframes status-flash{0%,to{opacity:0}50%{opacity:1}}
1
+ .confirm-panel td.arrow{padding:0}.confirm-panel td.arrow span{justify-content:center;align-items:center;display:flex}.confirm-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.manual-panel .k-comment{margin-top:0}.dep-package-view[data-v-0fc4cb55]{height:3rem;position:relative}.dep-package-view .el-button[data-v-0fc4cb55]{width:4rem}.page-deps{flex-flow:column;display:flex}.page-deps .body-container{margin-top:-1px;transform:translateY(1px)}.page-deps table tr:first-child{border-top:none}.page-deps tbody tr{transition:all .3s}.page-deps tbody tr:hover{background-color:var(--k-side-bg)}@media (width<=768px){.page-deps td{padding:.5em}}.theme-color.primary{color:var(--primary)}.theme-color.success{color:var(--success)}.theme-color.warning{color:var(--warning)}.theme-color.danger{color:var(--danger)}.install-panel .el-dialog__header{align-items:center;gap:0 .5em;padding-bottom:4px;padding-right:36px;display:flex}.install-panel .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.install-panel .el-dialog__header .el-select{flex:auto;max-width:12.5rem;margin:-2px 0 -4px}.install-panel .warning{color:var(--k-color-warning)}.install-panel .danger{color:var(--k-color-danger)}.install-panel .version-badges{float:right;margin-right:-12px}.install-panel .el-dialog__body{min-height:40px;padding:0 20px}.install-panel .el-dialog__body>div{margin:1rem 0}.install-panel .el-dialog__body:last-child{padding-bottom:1rem}.install-panel table thead td,.install-panel table thead th,.install-panel table tbody td,.install-panel table tbody th{white-space:nowrap;padding:.5em .875em}.install-panel span.link:hover{cursor:pointer;text-decoration:underline}.install-panel .el-button+.el-button{margin-left:1rem}.install-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.install-panel .wrapper{display:inline-flex;position:relative}.install-panel .wrapper .shadow{letter-spacing:1px;visibility:hidden;padding-right:22px}.install-panel .wrapper .el-select{position:absolute;top:50%;left:0;right:0;transform:translateY(-50%)}.dot-hint:before{content:"";background-color:currentColor;border-radius:100%;width:.5rem;height:.5rem;transition:background-color .3s;position:absolute;top:50%;right:20px;transform:translateY(-50%);box-shadow:1px 1px 2px #3333}.market-filter-item[data-v-23068a68]{box-sizing:border-box;color:var(--k-text-normal);z-index:2;cursor:pointer;border-radius:8px;align-items:center;height:28px;margin:2px 0;padding:0 .5rem;transition:color .2s,background-color .2s;display:flex}.market-filter-item[data-v-23068a68]:hover{color:var(--k-text-dark);background-color:var(--k-hover-bg)}.market-filter-item.active[data-v-23068a68]{color:var(--k-color-primary);background-color:color-mix(in srgb, var(--k-color-primary) 10%, transparent)}.market-filter-item.active .text[data-v-23068a68]{font-weight:600}.market-filter-item.active.verified[data-v-23068a68],.market-filter-item.active.newborn[data-v-23068a68]{color:var(--k-color-success);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent)}.market-filter-item.active.preview[data-v-23068a68],.market-filter-item.active.portable[data-v-23068a68]{color:var(--k-color-warning);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent)}.market-filter-item.active.insecure[data-v-23068a68]{color:var(--k-color-danger);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent)}.market-filter-item.disabled[data-v-23068a68]{opacity:.5;text-decoration:line-through;text-decoration-thickness:2px}.market-filter-item .icon[data-v-23068a68]{justify-content:center;align-items:center;width:1.75rem;margin-right:4px;display:inline-flex}.market-filter-item:not(.active) .order[data-v-23068a68]{display:none}.market-filter-item .order[data-v-23068a68]{justify-content:center;align-items:center;width:1.75rem;display:inline-flex}.market-filter-item svg[data-v-23068a68]{max-width:1.125rem;height:1rem}.market-filter-item .text[data-v-23068a68],.market-filter-item .count[data-v-23068a68]{font-size:14px;font-weight:500;line-height:20px}.market-filter-item .count[data-v-23068a68]{opacity:.7;margin-right:4px;font-size:12px}.market-filter-item .spacer[data-v-23068a68]{flex:1}.cat-adapter[data-v-715b4290]{--c:#38bdf8}.cat-general[data-v-715b4290]{--c:#4ade80}.cat-extension[data-v-715b4290]{--c:#a78bfa}.cat-webui[data-v-715b4290]{--c:#fb923c}.cat-manage[data-v-715b4290]{--c:#facc15}.cat-preset[data-v-715b4290]{--c:#60a5fa}.cat-image[data-v-715b4290]{--c:#f472b6}.cat-media[data-v-715b4290]{--c:#e879f9}.cat-tool[data-v-715b4290]{--c:#94a3b8}.cat-life[data-v-715b4290]{--c:#34d399}.cat-ai[data-v-715b4290]{--c:#818cf8}.cat-meme[data-v-715b4290]{--c:#fbbf24}.cat-game[data-v-715b4290]{--c:#f87171}.cat-gametool[data-v-715b4290]{--c:#c084fc}.cat-other[data-v-715b4290]{--c:#64748b}.market-package[data-v-715b4290]{box-sizing:border-box;background-color:var(--k-card-bg);border:1px solid var(--k-color-border);contain:layout paint style;border-radius:12px;width:100%;max-width:540px;height:calc(12.5rem + 2px);margin:0;padding:1rem 1.25rem;transition:border-color .18s,box-shadow .18s,background-color .18s;position:relative}.market-package[data-v-715b4290]:hover{border-color:var(--k-color-primary);box-shadow:0 4px 12px #0000000f}.market-package .market-icon[data-v-715b4290]{height:1em;display:inline}.market-package .header[data-v-715b4290],.market-package .footer[data-v-715b4290]{flex:none}.market-package .header[data-v-715b4290]{position:relative}.market-package .header .left[data-v-715b4290]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--c) 35%, var(--k-color-border));background:linear-gradient(135deg, color-mix(in srgb, var(--c) 18%, var(--k-card-bg)), color-mix(in srgb, var(--c) 10%, var(--k-card-bg)));width:3.5rem;height:3.5rem;transition:var(--color-transition);border-radius:10px}.market-package .header .left svg[data-v-715b4290]{height:1.75rem;color:var(--c)}.market-package .header h2[data-v-715b4290]{align-items:center;margin:0;font-size:1.125rem;font-weight:600;line-height:1.2;display:flex}.market-package .header h2 .title[data-v-715b4290]{flex:0 auto;line-height:1.5rem;display:inline-block}.market-package .header .heartbeat[data-v-715b4290]{height:1.5rem;color:var(--k-text-light);align-items:center;gap:5px;font-size:12px;display:inline-flex}.market-package .header .heartbeat .market-icon[data-v-715b4290]{width:12px;height:12px;color:color-mix(in srgb, #eb4d55 var(--heart-mix,0%), var(--k-text-light));opacity:var(--heart-opacity,.5);filter:drop-shadow(0 0 calc(var(--heart-glow,0) * 4px) rgb(235, 77, 85, calc(var(--heart-glow,0) * .45)));flex:none;transition:color .3s,opacity .3s}.market-package .badge-float[data-v-715b4290]{position:absolute;bottom:2.5rem;right:1.25rem}.market-package .badge-pill[data-v-715b4290]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-success) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent);height:20px;color:var(--k-color-success);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:10px;align-items:center;gap:3px;padding:0 6px;font-size:12px;font-weight:500;line-height:20px;display:inline-flex}.market-package .badge-pill .market-icon[data-v-715b4290]{width:12px;height:12px}.market-package .badge-pill.preview[data-v-715b4290]{border-color:color-mix(in srgb, var(--k-color-warning) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent);color:var(--k-color-warning)}.market-package .badge-pill.insecure[data-v-715b4290]{border-color:color-mix(in srgb, var(--k-color-danger) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent);color:var(--k-color-danger)}.market-package .desc[data-v-715b4290]{color:var(--k-text-light);word-break:break-word;text-overflow:ellipsis;-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:auto;margin:0;font-size:14px;line-height:1.6;display:-webkit-box;overflow:hidden}.market-package .footer[data-v-715b4290]{cursor:default;height:1.5rem;color:var(--k-text-light);align-items:center;gap:.5rem;margin-bottom:-.25rem;font-size:13px;transition:color .3s;display:flex;overflow:hidden}.market-package .footer[data-v-715b4290]>*{flex:none}.market-package .footer .spacer[data-v-715b4290]{flex:0 2 .5rem}.market-package .footer .long-spacer[data-v-715b4290]{flex:auto}.market-package .footer .market-icon[data-v-715b4290]{vertical-align:-1px;width:16px;height:12px;margin-right:6px}.market-package .footer .avatars[data-v-715b4290]{gap:.25rem;display:flex}.market-package .footer .avatars .avatar[data-v-715b4290]{cursor:pointer;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar img[data-v-715b4290]{vertical-align:middle;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar.fallback[data-v-715b4290]{box-sizing:border-box;background:linear-gradient(135deg, color-mix(in srgb, var(--c) 30%, var(--k-card-bg)), color-mix(in srgb, var(--c) 12%, var(--k-card-bg)));color:color-mix(in srgb, var(--c) 80%, var(--k-text-dark));justify-content:center;align-items:center;font-size:.68rem;font-weight:700;display:inline-flex}.market-package .footer .avatars .avatar.fallback[data-v-715b4290]:before{content:attr(data-initial)}@media (width<=420px){.market-package[data-v-715b4290]{height:auto;min-height:11rem;padding:.82rem .9rem}.market-package .header .left[data-v-715b4290]{width:3rem;height:3rem}.market-package h2[data-v-715b4290]{font-size:1rem}.market-package .badge-float[data-v-715b4290]{bottom:2.3rem;right:.9rem}.market-package .footer[data-v-715b4290]{flex-wrap:wrap;height:auto}.market-package .footer .long-spacer[data-v-715b4290]{display:none}}.package-list[data-v-7274b89c]{gap:var(--card-margin);flex:1 0 auto;grid-template-columns:repeat(auto-fill,minmax(336px,1fr));justify-items:center;display:grid}.pagination[data-v-7274b89c]{margin:var(--card-margin) 0;justify-content:center}.k-empty[data-v-7274b89c]{flex:1 0 auto}.search-box[data-v-98462ea9]{border:1.5px solid var(--k-color-border);box-sizing:border-box;background-color:var(--k-card-bg);border-radius:2rem;align-items:center;width:100%;max-width:640px;margin:2rem auto 0;transition:border-color .2s,box-shadow .2s;display:flex;box-shadow:0 2px 12px #0000000f,0 1px 3px #0000000a}.search-box[data-v-98462ea9]:focus-within{border-color:var(--k-color-primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--k-color-primary) 15%, transparent), 0 2px 12px #0000000f, 0 1px 3px #0000000a}.search-container[data-v-98462ea9]{flex-wrap:wrap;flex:auto;align-items:center;gap:8px 6px;padding:.75rem 0 .75rem 1.25rem;display:flex}.search-container input[data-v-98462ea9]{box-sizing:border-box;min-width:10rem;height:1.25rem;color:inherit;background-color:#0000;border:none;outline:none;flex:auto;padding:0;font-size:.925rem}.search-action[data-v-98462ea9]{cursor:pointer;flex-direction:column;flex:none;justify-content:center;align-items:center;width:3rem;height:2.5rem;display:flex}.search-action .market-icon[data-v-98462ea9]{opacity:.45;height:1rem;transition:opacity .2s}.search-action:hover .market-icon[data-v-98462ea9]{opacity:.85}.search-action:hover .market-icon.search[data-v-98462ea9],.search-action:not(:hover) .market-icon.close[data-v-98462ea9]{display:none}.search-word[data-v-98462ea9]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-primary) 25%, transparent);background-color:color-mix(in srgb, var(--k-color-primary) 12%, transparent);height:1.375rem;color:var(--k-color-primary);white-space:nowrap;vertical-align:baseline;cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;flex:none;padding:0 8px;font-size:12px;font-weight:500;line-height:calc(1.375rem - 2px);transition:opacity .3s,background-color .3s,border-color .3s;display:inline-block}.search-word.invalid[data-v-98462ea9]{opacity:.5;text-decoration:line-through}.search-word.invalid[data-v-98462ea9]:hover{opacity:1}@media (width<=420px){.search-box[data-v-98462ea9]{border-radius:12px}}.page-market .layout-main .el-scrollbar__view{padding:0 var(--card-margin);flex-direction:column;min-height:100%;display:flex}.page-market .layout-left .market-filter-group{margin:1.5rem 0;padding:0 1rem}.page-market .layout-left h2{letter-spacing:.08em;text-transform:uppercase;color:var(--k-text-light);opacity:.7;margin:0;padding:6px .5rem;font-size:11px;font-weight:700}.market-loading{flex-direction:column;flex:1 0 auto;justify-content:center;align-items:center;gap:2rem;min-height:50vh;display:flex}.market-loading .el-loading-spinner{margin-top:0}.market-slow.k-comment{max-width:640px}.market-hint{width:100%;color:var(--el-text-color-regular);font-size:var(--el-font-size-base);font-weight:var(--el-font-weight-primary);margin:1rem 0 .75rem;transition:color .3s}.market-container .k-button{margin-left:1rem;padding:.35em .85em;transform:translateY(-1px)}.market-error.k-comment{margin-left:2rem;margin-right:2rem}.page-market .el-scrollbar__thumb{background-clip:content-box;background-color:color-mix(in srgb, var(--k-color-primary) 26%, var(--fg3));border:2px solid #0000;border-radius:999px;min-height:32px}.page-market .el-scrollbar__thumb:hover{background-color:color-mix(in srgb, var(--k-color-primary) 44%, var(--fg3))}.k-status .el-progress-bar{width:120px;margin-right:2px}.dialog-config-fork .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.dialog-config-fork .status-light{margin-right:.75rem}.dialog-config-fork .actions{justify-content:flex-end;align-items:center;gap:0 .5rem;display:flex}.dialog-config-fork .action{cursor:pointer;width:1.25rem;color:var(--fg2);transition:var(--color-transition);justify-content:center;display:inline-flex}.dialog-config-fork .action:hover{color:var(--fg1)}.dialog-config-fork .el-dialog__footer{justify-content:space-between;align-items:center;font-size:.9em;display:flex}.modifier,.plugin-view .markdown.usage{margin-bottom:2rem}.plugin-view .markdown.usage h2{font-size:1.25rem}.plugin-tree{width:100%;height:100%;overflow:auto}.plugin-tree .el-scrollbar__view{padding:1rem 0;line-height:2.25rem}.plugin-tree .search{padding:0 1.5rem}.plugin-tree .k-icon-filter{height:15px}.plugin-tree .el-tree-node.is-group>.el-tree-node__content{font-weight:700}.plugin-tree .el-tree-node__content .item{flex:1;justify-content:space-between;align-items:center;height:100%;display:flex;overflow:hidden}.plugin-tree .el-tree-node__content .label{text-overflow:ellipsis;transition:var(--color-transition);overflow:hidden}.plugin-tree .el-tree-node__content .right{height:100%;margin:0 1.5rem 0 .5rem}.end{margin-right:.5rem}.config-header{margin:0 0 2rem;font-size:1.375rem;line-height:2rem}.config-header .k-button{float:right}.plugin-view .k-content>:first-child{margin-top:0}.plugin-select .el-dialog__header{border-bottom:1px solid var(--k-color-divider);justify-content:space-between;align-items:center;margin-right:0;padding:12px 20px;display:flex}.plugin-select .el-dialog__header button{top:2px}.plugin-select .el-dialog__header .title{flex:none}.plugin-select .el-dialog__header .el-input{width:220px;height:2rem;display:inline-block}.plugin-select .el-dialog__body{height:50vh;padding:0;display:flex}.plugin-select .el-dialog__body .tabs{border-right:1px solid var(--k-color-divider);flex:none;width:7.5rem;font-size:15px}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs{width:3rem}}.plugin-select .el-dialog__body .tabs .el-scrollbar__view{padding:.5rem 0}.plugin-select .el-dialog__body .tabs .tab-item{cursor:pointer;height:2rem;transition:var(--color-transition);justify-content:center;align-items:center;padding:0 1rem;font-size:.875rem;display:flex}.plugin-select .el-dialog__body .tabs .tab-item:hover{background-color:var(--k-hover-bg)}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item{padding:0}}.plugin-select .el-dialog__body .tabs .tab-item .market-icon{width:1.25rem;height:1rem}.plugin-select .el-dialog__body .tabs .tab-item.active{color:var(--primary)}.plugin-select .el-dialog__body .tabs .tab-item .title{width:3.5rem;margin-left:.5rem}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item .title{display:none}}.plugin-select .el-dialog__body .content{flex:auto}.plugin-select .el-dialog__body .content .package{cursor:pointer;transition:var(--color-transition);padding:.5rem 1rem}.plugin-select .el-dialog__body .content .package h3{margin:0 0 .25rem;font-size:16px}.plugin-select .el-dialog__body .content .package p{margin:0;font-size:14px}.plugin-select .el-dialog__body .content .package:hover{background-color:var(--k-hover-bg)}.absolute{position:absolute}.relative{position:relative}.grid{display:grid}.my-8{margin-top:2rem;margin-bottom:2rem}.inline{display:inline}.inline-block{display:inline-block}.hidden{display:none}.h2{height:.5rem}.h3{height:.75rem}.flex{display:flex}.inline-flex{display:inline-flex}.shrink-0{flex-shrink:0}.grow-1{flex-grow:1}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.transform{transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.items-center{align-items:center}.justify-center{justify-content:center}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{column-gap:1rem}.gap-y-2{row-gap:.5rem}.overflow-hidden{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.b,.border{border-width:1px}.pl-8{padding-left:2rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color,#0000001a),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color,#0000001a);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow)}.outline{outline-style:solid}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease{transition-timing-function:cubic-bezier(.4,0,.2,1)}.dialog-config-fork .status-light,.plugin-tree .status-light{width:.625rem;height:.625rem;transition:var(--color-transition);border-radius:100%;display:inline-block}.dialog-config-fork .status-light.active,.plugin-tree .status-light.active{background-color:var(--k-color-success)}.dialog-config-fork .status-light.pending,.plugin-tree .status-light.pending{background-color:var(--k-color-warning)}.dialog-config-fork .status-light.loading,.plugin-tree .status-light.loading{background-color:var(--k-color-warning);animation:1s infinite status-flash}.dialog-config-fork .status-light.failed,.plugin-tree .status-light.failed{background-color:var(--k-color-danger)}.dialog-config-fork .status-light.disabled:not(.ignore-disabled),.plugin-tree .status-light.disabled:not(.ignore-disabled){opacity:.5;background-color:var(--k-color-disabled)}@keyframes status-flash{0%,to{opacity:0}50%{opacity:1}}
2
2
  /*$vite$:1*/
package/lib/index.d.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import { Awaitable, Context, Dict, HTTP, Schema, Service } from "@koishi-ce/koishi";
2
2
  import { DataService } from "@koishi-ce/console";
3
3
  import { DependencyMetaKey, RemotePackage, SearchObject, SearchResult } from "@koishi-ce/registry";
4
- //#region src/node/installer.d.ts
4
+ //#region src/node/installer/versions.d.ts
5
+ /** 归一化后的版本表:版本号 → 依赖元信息(键序即降序,首项为最新版) */
6
+ type VersionMap = Dict<Pick<RemotePackage, DependencyMetaKey>>;
7
+ //#endregion
8
+ //#region src/node/installer/index.d.ts
5
9
  interface Dependency {
6
10
  /**
7
11
  * requested semver range
@@ -23,8 +27,8 @@ interface Dependency {
23
27
  declare class Installer extends Service {
24
28
  http: HTTP;
25
29
  endpoint: string | undefined;
26
- fullCache: Dict<Dict<Pick<RemotePackage, DependencyMetaKey>>>;
27
- tempCache: Dict<Dict<Pick<RemotePackage, DependencyMetaKey>>>;
30
+ fullCache: Dict<VersionMap>;
31
+ tempCache: Dict<VersionMap>;
28
32
  private pkgTasks;
29
33
  private manifest;
30
34
  private depTask;
@@ -37,7 +41,7 @@ declare class Installer extends Service {
37
41
  findVersion(names: string[]): Promise<Dict<string> | undefined>;
38
42
  private _getPackage;
39
43
  setPackage(name: string, versions: RemotePackage[]): void;
40
- getPackage(name: string): Promise<Dict<Pick<RemotePackage, DependencyMetaKey>>>;
44
+ getPackage(name: string): Promise<VersionMap>;
41
45
  private _getDeps;
42
46
  getDeps(): Promise<Dict<Dependency>>;
43
47
  refreshData(): void;
@@ -45,20 +49,6 @@ declare class Installer extends Service {
45
49
  exec(args: string[]): Promise<number>;
46
50
  override(deps: Dict<string | null>): Promise<void>;
47
51
  private _install;
48
- /**
49
- * 安装完整性校验:从本次安装的包出发递归纯 fs 探测依赖可达性,返回
50
- * 「包: 缺失依赖」描述列表。背景是 Bun isolated 布局的增量安装缺陷
51
- * (2026-09-07 实证):升级插件时包目录 hash 变化,而其依赖的解析
52
- * 结果未变,bun 的增量安装跳过新包目录内的依赖链接建立——插件入口
53
- * (顶层 symlink)可加载,内部依赖的 require 却炸 MODULE_NOT_FOUND;
54
- * 此时补跑一次普通 bun install,bun 按磁盘实际状态检测到包不完整
55
- * 即重建链接(秒级)。全程只走 existsSync / readFileSync /
56
- * realpathSync,不触碰解析 API(防父目录快照缓存,与
57
- * resolvePackageJson 同一纪律)。peer / optional 依赖由宿主或按需
58
- * 提供不入校验;workspace / alias 等非 semver 声明的落盘名与键名无
59
- * 直接映射,同样跳过。
60
- */
61
- private _findMissingDeps;
62
52
  private _getLocalDeps;
63
53
  install(deps: Dict<string | null>, forced?: boolean): Promise<number>;
64
54
  static Config: Schema<Installer.Config>;
@@ -77,7 +67,7 @@ declare class DependencyProvider extends DataService<Dict<Dependency>> {
77
67
  }
78
68
  declare class RegistryProvider extends DataService<Dict<Dict<Pick<RemotePackage, DependencyMetaKey>>>> {
79
69
  constructor(ctx: Context);
80
- get(): Promise<Dict<Dict<Pick<RemotePackage, DependencyMetaKey>>>>;
70
+ get(): Promise<Dict<VersionMap>>;
81
71
  }
82
72
  //#endregion
83
73
  //#region src/shared/index.d.ts
package/lib/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import { dirname, join, resolve } from "node:path";
2
2
  import { Logger, Schema, Service, Time, defineProperty, pick, sleep, valueMap } from "@koishi-ce/koishi";
3
3
  import { compare, gt, satisfies, valid } from "semver";
4
+ import messageZhCN from "./assets/message.zh-CN-D1DbsO3I.yml";
5
+ import schemaZhCN from "./assets/schema.zh-CN-Bj0_jaVr.yml";
4
6
  import { DataService } from "@koishi-ce/console";
5
- import { existsSync, readFileSync, realpathSync } from "node:fs";
6
- import { homedir } from "node:os";
7
7
  import Scanner, { isResidentInCache, mapLimit, resolvePackageJson } from "@koishi-ce/registry";
8
8
  import { spawn } from "node:child_process";
9
- import messageZhCN from "./assets/message.zh-CN-D1DbsO3I.yml";
10
- import schemaZhCN from "./assets/schema.zh-CN-Bj0_jaVr.yml";
9
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
10
+ import { NPM_OFFICIAL_REGISTRY, getLocalRegistry } from "@koishi-ce/utils";
11
11
  //#region src/node/deps.ts
12
12
  var DependencyProvider = class extends DataService {
13
13
  constructor(ctx) {
@@ -26,7 +26,7 @@ var RegistryProvider = class extends DataService {
26
26
  }
27
27
  };
28
28
  //#endregion
29
- //#region src/node/proc.ts
29
+ //#region src/node/installer/proc.ts
30
30
  /**
31
31
  * 安装子进程的创建封装(原依赖 execa)。
32
32
  *
@@ -47,21 +47,57 @@ function spawnBun(args, cwd) {
47
47
  return spawn(process.execPath, args, { cwd });
48
48
  }
49
49
  //#endregion
50
- //#region src/node/installer.ts
51
- const logger$2 = new Logger("market");
50
+ //#region src/node/installer/exec.ts
52
51
  /**
53
- * 判断依赖声明是否受护栏保护、不可被安装清单覆盖或删除。两类:
54
- * - `workspace:` 声明是本仓库(monorepo)对上游名的归属(如 koishi
55
- * 裸名 shim,见 packages/shim/koishi);
56
- * - `npm:@koishi-ce/...` alias 是下游脚手架生成项目对上游名的归属
57
- * (如 "koishi": "npm:@koishi-ce/koishi-shim@^4.18.11",见
58
- * packages/shim/koishi-shim)。
59
- * 两者被覆盖或删除都会让 peer 解析失去归属,重新拉下 npm 官方包形成
60
- * 第二份框架副本。
52
+ * bun 安装子进程的驱动与输出转发。
53
+ *
54
+ * Bun-first:CE 生态只存在 bun 这一种包管理器,直接驱动 bun 执行安装
55
+ * (上游经 which-pm-runs 探测 npm/yarn/bun,此处固定为 bun)。子进程本身的
56
+ * 创建见 ./proc.ts;本模块负责退出码归一化与日志转发,不持有任何服务状态。
61
57
  */
62
- function isGuardedRequest(request) {
63
- return request?.startsWith("workspace:") === true || request?.startsWith("npm:@koishi-ce") === true;
58
+ const logger$3 = new Logger("market");
59
+ /**
60
+ * 在 cwd 下执行 `bun <args>`,返回退出码(spawn 失败与异常退出统一为非 0,
61
+ * 由调用方按失败处理)。
62
+ *
63
+ * 输出按行转发到 market 日志:未成行的尾段暂存到下一次数据到来时补齐,
64
+ * 避免半行日志刷屏。
65
+ */
66
+ function runBun(args, cwd) {
67
+ return new Promise((resolve) => {
68
+ const child = spawnBun(args, cwd);
69
+ child.on("exit", (code) => resolve(code ?? -1));
70
+ child.on("error", () => resolve(-1));
71
+ let stderr = "";
72
+ child.stderr?.on("data", (data) => {
73
+ stderr += data.toString();
74
+ const lines = stderr.split("\n");
75
+ stderr = lines.pop() ?? "";
76
+ for (const line of lines) logger$3.warn(line);
77
+ });
78
+ let stdout = "";
79
+ child.stdout?.on("data", (data) => {
80
+ stdout += data.toString();
81
+ const lines = stdout.split("\n");
82
+ stdout = lines.pop() ?? "";
83
+ for (const line of lines) logger$3.info(line);
84
+ });
85
+ });
64
86
  }
87
+ //#endregion
88
+ //#region src/node/installer/integrity.ts
89
+ /**
90
+ * 安装完整性校验:Bun isolated 布局的增量安装缺陷防御。
91
+ *
92
+ * 背景(2026-09-07 实证):升级插件时包目录 hash 变化,而其依赖的解析
93
+ * 结果未变,bun 的增量安装跳过新包目录内的依赖链接建立——插件入口(顶层
94
+ * symlink)可加载,内部依赖的 require 却炸 MODULE_NOT_FOUND;此时补跑一次
95
+ * 普通 bun install,bun 按磁盘实际状态检测到包不完整即重建链接(秒级)。
96
+ * 本模块只负责「发现问题」,补救(补装、告警)由 installer 侧完成。
97
+ *
98
+ * 全程只走 existsSync / readFileSync / realpathSync,不触碰解析 API
99
+ * (防父目录快照缓存,与 registry 的 resolvePackageJson 同一纪律)。
100
+ */
65
101
  /**
66
102
  * 从 fromDir 沿 node_modules 链纯 fs 探测依赖包,命中返回其真实目录。
67
103
  * realpath 化是 isolated 布局的关键:顶层条目是 symlink,包的依赖链接
@@ -82,32 +118,66 @@ function probePackage(fromDir, name) {
82
118
  dir = parent;
83
119
  }
84
120
  }
85
- /** 从单个 .npmrc 文件提取 registry 配置项;文件不存在或读取出错一律视为未配置 */
86
- function readNpmrcRegistry(file) {
87
- try {
88
- for (const line of readFileSync(file, "utf8").split(/\r?\n/)) {
89
- const value = /^\s*registry\s*=\s*(\S+)\s*$/.exec(line)?.[1];
90
- if (value) return value;
121
+ /**
122
+ * 从本次安装的包出发递归纯 fs 探测依赖可达性,返回「包: 缺失依赖」描述
123
+ * 列表。peer / optional 依赖由宿主或按需提供不入校验;workspace / alias
124
+ * 等非 semver 声明的落盘名与键名无直接映射,同样跳过。
125
+ *
126
+ * @param root 项目根目录
127
+ * @param deps 依赖增删清单(值为 null 表示卸载该依赖)
128
+ */
129
+ function findMissingDeps(root, deps) {
130
+ const problems = [];
131
+ const visited = /* @__PURE__ */ new Set();
132
+ const walk = (dir, label) => {
133
+ if (visited.has(dir)) return;
134
+ visited.add(dir);
135
+ let manifest;
136
+ try {
137
+ manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
138
+ } catch {
139
+ return;
140
+ }
141
+ for (const [dep, request] of Object.entries(manifest.dependencies ?? {})) {
142
+ if (request.includes(":")) continue;
143
+ const depDir = probePackage(dir, dep);
144
+ if (!depDir) {
145
+ problems.push(`${label} 的依赖 ${dep} 未被链接`);
146
+ continue;
147
+ }
148
+ walk(depDir, `${label} → ${dep}`);
91
149
  }
92
- } catch {}
150
+ };
151
+ for (const name in deps) {
152
+ const request = deps[name];
153
+ if (!request || request.includes(":")) continue;
154
+ const dir = probePackage(root, name);
155
+ if (!dir) continue;
156
+ walk(dir, name);
157
+ }
158
+ return problems;
93
159
  }
160
+ //#endregion
161
+ //#region src/node/installer/manifest.ts
94
162
  /**
95
- * 读取本机 npm registry 配置(优先级对齐 npm 自身:环境变量 > 项目
96
- * .npmrc > 用户 ~/.npmrc)。刻意不 spawn 子进程探测——原依赖
97
- * get-registry 按 user-agent 选 `bun config get registry`,而 Bun 没有
98
- * config 子命令,Bun 运行时下子进程退出码 1 直接炸掉 market 服务启动;
99
- * 读 npmrc 是零子进程的等价路径。任何一步都拿不到时回落 npm 官方
100
- * 源(对齐被移除的 get-registry 的默认值),保证 http 恒有 endpoint
101
- * 可拼接相对 URL——缺省时相对请求会在 resolveURL 抛 Invalid URL。
163
+ * 项目根 package.json(安装清单)的读写与护栏判定。
164
+ *
165
+ * 只做纯 fs 的清单操作,与 registry 的交互(版本探测、http 缓存)无关,
166
+ * 故独立于 installer 服务;依赖链接的探测属安装完整性校验,见
167
+ * ./integrity.ts。
102
168
  */
103
- function getLocalRegistry(cwd, userHome = homedir()) {
104
- const candidates = [
105
- process.env["npm_config_registry"],
106
- readNpmrcRegistry(join(cwd, ".npmrc")),
107
- readNpmrcRegistry(join(userHome, ".npmrc"))
108
- ];
109
- for (const candidate of candidates) if (candidate?.startsWith("https://") || candidate?.startsWith("http://")) return candidate;
110
- return "https://registry.npmjs.org/";
169
+ /**
170
+ * 判断依赖声明是否受护栏保护、不可被安装清单覆盖或删除。两类:
171
+ * - `workspace:` 声明是本仓库(monorepo)对上游名的归属(如 koishi
172
+ * 裸名 shim,见 packages/shim/koishi);
173
+ * - `npm:@koishi-ce/...` alias 是下游脚手架生成项目对上游名的归属
174
+ * (如 "koishi": "npm:@koishi-ce/koishi-shim@^4.18.11",见
175
+ * packages/shim/koishi-shim)。
176
+ * 两者被覆盖或删除都会让 peer 解析失去归属,重新拉下 npm 官方包形成
177
+ * 第二份框架副本。
178
+ */
179
+ function isGuardedRequest(request) {
180
+ return request?.startsWith("workspace:") === true || request?.startsWith("npm:@koishi-ce") === true;
111
181
  }
112
182
  function loadManifest(name) {
113
183
  const filename = resolvePackageJson(name);
@@ -116,6 +186,38 @@ function loadManifest(name) {
116
186
  defineProperty(meta, "$workspace", !filename.includes("node_modules"));
117
187
  return meta;
118
188
  }
189
+ /**
190
+ * 把依赖增删写回项目根 package.json,返回写回后的清单。
191
+ *
192
+ * 现读现写:调用方持有的清单原为构造期的启动快照,运行期间根
193
+ * package.json 可能已被外部更新,基于快照整体重写会抹掉变更,故此处
194
+ * 重新读盘。受护栏保护的声明(见 isGuardedRequest)既不覆盖也不删除。
195
+ *
196
+ * @param cwd 项目根目录
197
+ * @param deps 依赖增删清单(值为 null 表示卸载该依赖)
198
+ */
199
+ async function writeManifest(cwd, deps) {
200
+ const filename = resolve(cwd, "package.json");
201
+ const manifest = JSON.parse(readFileSync(filename, "utf8"));
202
+ manifest.dependencies ||= {};
203
+ for (const key in deps) if (deps[key]) {
204
+ if (isGuardedRequest(manifest.dependencies[key])) continue;
205
+ manifest.dependencies[key] = deps[key];
206
+ } else if (!isGuardedRequest(manifest.dependencies[key])) delete manifest.dependencies[key];
207
+ manifest.dependencies = Object.fromEntries(Object.entries(manifest.dependencies).sort((a, b) => a[0].localeCompare(b[0])));
208
+ await Bun.write(filename, `${JSON.stringify(manifest, null, " ")}\n`);
209
+ return manifest;
210
+ }
211
+ //#endregion
212
+ //#region src/node/installer/versions.ts
213
+ /**
214
+ * 远端包版本探测与归一化。
215
+ *
216
+ * 从 registry 取回版本数组后,过滤掉与当前框架不兼容的版本,再归一化为
217
+ * 「版本号 → peer 依赖声明 / 弃用标记」的映射并按版本号降序排列(首项即
218
+ * 最新版)。纯 IO + 纯函数,不持有服务状态;缓存与去重由 installer 侧负责。
219
+ */
220
+ /** 把 registry 返回的版本数组归一化并降序排列 */
119
221
  function getVersions(versions) {
120
222
  return Object.fromEntries(versions.map((item) => [item.version, pick(item, [
121
223
  "peerDependencies",
@@ -123,6 +225,24 @@ function getVersions(versions) {
123
225
  "deprecated"
124
226
  ])]).sort(([a], [b]) => compare(b, a)));
125
227
  }
228
+ /**
229
+ * 取回单个包的可用版本表(已过滤不兼容版本)。
230
+ *
231
+ * 兼容性口径:`koishi` 本体按 4.x 判定;其余包若确认为插件则要求与
232
+ * 4.x 兼容(Scanner 的判定基于包名与 remote 元信息)。
233
+ *
234
+ * @throws 网络或 registry 响应异常时向上抛出,由调用方决定日志口径
235
+ */
236
+ async function fetchVersions(http, name) {
237
+ const registry = await http.get(`/${name}`);
238
+ return getVersions(Object.values(registry.versions).filter((remote) => {
239
+ if (name === "koishi") return satisfies(remote.version, "4");
240
+ return !Scanner.isPlugin(name) || Scanner.isCompatible("4", remote);
241
+ }));
242
+ }
243
+ //#endregion
244
+ //#region src/node/installer/index.ts
245
+ const logger$2 = new Logger("market");
126
246
  var Installer = class extends Service {
127
247
  fullCache = {};
128
248
  tempCache = {};
@@ -144,7 +264,7 @@ var Installer = class extends Service {
144
264
  }
145
265
  async start() {
146
266
  const { endpoint, timeout } = this.config;
147
- this.endpoint = endpoint ?? getLocalRegistry(this.cwd);
267
+ this.endpoint = endpoint ?? getLocalRegistry(this.cwd) ?? NPM_OFFICIAL_REGISTRY;
148
268
  const options = {};
149
269
  if (this.endpoint) options.endpoint = this.endpoint;
150
270
  if (timeout !== void 0) options.timeout = timeout;
@@ -171,11 +291,7 @@ var Installer = class extends Service {
171
291
  }
172
292
  async _getPackage(name) {
173
293
  try {
174
- const registry = await this.http.get(`/${name}`);
175
- const versions = getVersions(Object.values(registry.versions).filter((remote) => {
176
- if (name === "koishi") return satisfies(remote.version, "4");
177
- return !Scanner.isPlugin(name) || Scanner.isCompatible("4", remote);
178
- }));
294
+ const versions = await fetchVersions(this.http, name);
179
295
  this.fullCache[name] = this.tempCache[name] = versions;
180
296
  this.flushData();
181
297
  return versions;
@@ -228,86 +344,16 @@ var Installer = class extends Service {
228
344
  }
229
345
  async exec(args) {
230
346
  args.unshift("install");
231
- return new Promise((resolve) => {
232
- const child = spawnBun(args, this.cwd);
233
- child.on("exit", (code) => resolve(code ?? -1));
234
- child.on("error", () => resolve(-1));
235
- let stderr = "";
236
- child.stderr?.on("data", (data) => {
237
- stderr += data.toString();
238
- const lines = stderr.split("\n");
239
- stderr = lines.pop() ?? "";
240
- for (const line of lines) logger$2.warn(line);
241
- });
242
- let stdout = "";
243
- child.stdout?.on("data", (data) => {
244
- stdout += data.toString();
245
- const lines = stdout.split("\n");
246
- stdout = lines.pop() ?? "";
247
- for (const line of lines) logger$2.info(line);
248
- });
249
- });
347
+ return runBun(args, this.cwd);
250
348
  }
251
349
  async override(deps) {
252
- const filename = resolve(this.cwd, "package.json");
253
- this.manifest = JSON.parse(readFileSync(filename, "utf8"));
254
- this.manifest.dependencies ||= {};
255
- for (const key in deps) if (deps[key]) {
256
- if (isGuardedRequest(this.manifest.dependencies[key])) continue;
257
- this.manifest.dependencies[key] = deps[key];
258
- } else if (!isGuardedRequest(this.manifest.dependencies[key])) delete this.manifest.dependencies[key];
259
- this.manifest.dependencies = Object.fromEntries(Object.entries(this.manifest.dependencies).sort((a, b) => a[0].localeCompare(b[0])));
260
- await Bun.write(filename, `${JSON.stringify(this.manifest, null, " ")}\n`);
350
+ this.manifest = await writeManifest(this.cwd, deps);
261
351
  }
262
352
  _install() {
263
353
  const args = [];
264
354
  if (this.endpoint) args.push("--registry", this.endpoint);
265
355
  return this.exec(args);
266
356
  }
267
- /**
268
- * 安装完整性校验:从本次安装的包出发递归纯 fs 探测依赖可达性,返回
269
- * 「包: 缺失依赖」描述列表。背景是 Bun isolated 布局的增量安装缺陷
270
- * (2026-09-07 实证):升级插件时包目录 hash 变化,而其依赖的解析
271
- * 结果未变,bun 的增量安装跳过新包目录内的依赖链接建立——插件入口
272
- * (顶层 symlink)可加载,内部依赖的 require 却炸 MODULE_NOT_FOUND;
273
- * 此时补跑一次普通 bun install,bun 按磁盘实际状态检测到包不完整
274
- * 即重建链接(秒级)。全程只走 existsSync / readFileSync /
275
- * realpathSync,不触碰解析 API(防父目录快照缓存,与
276
- * resolvePackageJson 同一纪律)。peer / optional 依赖由宿主或按需
277
- * 提供不入校验;workspace / alias 等非 semver 声明的落盘名与键名无
278
- * 直接映射,同样跳过。
279
- */
280
- _findMissingDeps(deps) {
281
- const problems = [];
282
- const visited = /* @__PURE__ */ new Set();
283
- const walk = (dir, label) => {
284
- if (visited.has(dir)) return;
285
- visited.add(dir);
286
- let manifest;
287
- try {
288
- manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
289
- } catch {
290
- return;
291
- }
292
- for (const [dep, request] of Object.entries(manifest.dependencies ?? {})) {
293
- if (request.includes(":")) continue;
294
- const depDir = probePackage(dir, dep);
295
- if (!depDir) {
296
- problems.push(`${label} 的依赖 ${dep} 未被链接`);
297
- continue;
298
- }
299
- walk(depDir, `${label} → ${dep}`);
300
- }
301
- };
302
- for (const name in deps) {
303
- const request = deps[name];
304
- if (!request || request.includes(":")) continue;
305
- const dir = probePackage(this.cwd, name);
306
- if (!dir) continue;
307
- walk(dir, name);
308
- }
309
- return problems;
310
- }
311
357
  _getLocalDeps(override) {
312
358
  return valueMap(override, (request, name) => {
313
359
  const dep = { request };
@@ -333,12 +379,12 @@ var Installer = class extends Service {
333
379
  if (shouldInstall) {
334
380
  const code = await this._install();
335
381
  if (code) return code;
336
- const missing = this._findMissingDeps(deps);
382
+ const missing = findMissingDeps(this.cwd, deps);
337
383
  if (missing.length) {
338
384
  logger$2.warn(`检测到增量安装未建立部分依赖链接(isolated 布局已知缺陷),正在补装: ${missing.join("; ")}`);
339
385
  const retry = await this._install();
340
386
  if (retry) return retry;
341
- if (this._findMissingDeps(deps).length) logger$2.warn("自动补装后依赖链接仍不完整,请在项目根目录运行 bun install --force 并重启 koishi");
387
+ if (findMissingDeps(this.cwd, deps).length) logger$2.warn("自动补装后依赖链接仍不完整,请在项目根目录运行 bun install --force 并重启 koishi");
342
388
  }
343
389
  }
344
390
  this.refresh();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@koishi-ce/plugin-market",
3
3
  "description": "Manage your bots and plugins with console",
4
- "version": "1.1.0",
4
+ "version": "1.1.2",
5
5
  "type": "module",
6
6
  "main": "lib/index.mjs",
7
7
  "typings": "lib/index.d.ts",
@@ -61,19 +61,21 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@koishi-ce/plugin-database-memory": "^1.1.0",
64
- "@koishi-ce/client": "^1.2.3",
65
- "@koishi-ce/loader": "^1.0.8",
66
- "@koishi-ce/plugin-config": "^1.1.2",
67
- "@koishijs/market": "^4.2.10",
64
+ "@koishi-ce/client": "^1.3.0",
65
+ "@koishi-ce/loader": "^1.1.0",
66
+ "@koishi-ce/plugin-config": "^1.1.4",
67
+ "@koishi-ce/components": "^1.0.4",
68
68
  "@types/semver": "^7.5.8",
69
- "@types/spark-md5": "^3.0.4",
70
69
  "@vueuse/core": "^14.4.0",
70
+ "cosmokit": "^1.8.1",
71
71
  "spark-md5": "^3.0.2",
72
72
  "vue": "^3.5.12",
73
+ "vue-i18n": "^11.4.10",
73
74
  "vue-router": "^5.2.0"
74
75
  },
75
76
  "dependencies": {
76
- "@koishi-ce/console": "^1.0.0",
77
+ "@koishi-ce/console": "^1.1.0",
78
+ "@koishi-ce/utils": "^1.1.0",
77
79
  "@koishi-ce/registry": "^1.0.5",
78
80
  "semver": "^7.6.3"
79
81
  },
package/src/index.test.ts CHANGED
@@ -23,7 +23,7 @@ import memory from "@koishi-ce/plugin-database-memory";
23
23
 
24
24
  /**
25
25
  * market 插件测试:
26
- * - 子进程(bun 安装)经 mock.module 拦截本地 proc.ts(spawnBun 封装),不落盘不联网安装;
26
+ * - 子进程(bun 安装)经 mock.module 拦截 installer/proc.ts(spawnBun 封装),不落盘不联网安装;
27
27
  * - registry 网络请求由进程内 Bun.serve 提供(registry 协议的最小 JSON);
28
28
  * - 宿主环境(loader / cwd)使用 FakeLoader 与临时目录 + chdir,
29
29
  * Installer 的 override 写盘只会作用于临时 package.json。
@@ -64,7 +64,7 @@ const spawnBunMock = (_args: string[], _cwd: string) => {
64
64
  };
65
65
  };
66
66
 
67
- mock.module("../node/proc.ts", () => ({
67
+ mock.module("./node/installer/proc.ts", () => ({
68
68
  spawnBun: spawnBunMock,
69
69
  }));
70
70
 
@@ -84,7 +84,7 @@ const { isResidentInCache } = await import(
84
84
  );
85
85
  const market = await import("./node/index.ts");
86
86
  const { default: Installer } = await import(
87
- "./node/installer.ts"
87
+ "./node/installer/index.ts"
88
88
  );
89
89
  const mockPlugin = (await import("@koishi-ce/plugin-mock"))
90
90
  .default;
package/src/node/deps.ts CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  DependencyMetaKey,
9
9
  RemotePackage,
10
10
  } from "@koishi-ce/registry";
11
- import type { Dependency } from "./installer.ts";
11
+ import type { Dependency } from "./installer/index.ts";
12
12
 
13
13
  class DependencyProvider extends DataService<
14
14
  Dict<Dependency>
package/src/node/index.ts CHANGED
@@ -14,13 +14,13 @@ import type {
14
14
  RemotePackage,
15
15
  } from "@koishi-ce/registry";
16
16
  import { gt } from "semver";
17
+ import messageZhCN from "../../locales/message.zh-CN.yml";
18
+ import schemaZhCN from "../../locales/schema.zh-CN.yml";
17
19
  import {
18
20
  DependencyProvider,
19
21
  RegistryProvider,
20
22
  } from "./deps.ts";
21
- import Installer from "./installer.ts";
22
- import messageZhCN from "./locales/message.zh-CN.yml";
23
- import schemaZhCN from "./locales/schema.zh-CN.yml";
23
+ import Installer from "./installer/index.ts";
24
24
  import MarketProvider from "./market.ts";
25
25
 
26
26
  export * from "../shared/index.ts";