dsh-config-manager 0.1.37 → 0.1.39

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.
Files changed (44) hide show
  1. package/lib/client.d.ts +173 -66
  2. package/lib/client.js +1643 -1115
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +175 -1
  5. package/lib/index.js.map +1 -1
  6. package/lib/market/git-file-writer.d.ts +86 -0
  7. package/lib/market/git-file-writer.js +269 -0
  8. package/lib/market/git-file-writer.js.map +1 -0
  9. package/lib/market/github-repos.d.ts +122 -0
  10. package/lib/market/github-repos.js +407 -0
  11. package/lib/market/github-repos.js.map +1 -0
  12. package/lib/market/my-repo.d.ts +131 -0
  13. package/lib/market/my-repo.js +389 -0
  14. package/lib/market/my-repo.js.map +1 -0
  15. package/lib/ui/i18n.d.ts +9 -10
  16. package/lib/ui/i18n.js +19 -21
  17. package/lib/ui/i18n.js.map +1 -1
  18. package/package.json +1 -1
  19. package/src/client/ConfigManagerSection.tsx +2 -2
  20. package/src/client/client-types.ts +2 -0
  21. package/src/client/index.ts +4 -2
  22. package/src/client/market/MarketPanel.tsx +64 -17
  23. package/src/client/market/MyConfigsView.tsx +745 -0
  24. package/src/client/market/market-api.test.ts +29 -0
  25. package/src/client/market/market-api.ts +5 -2
  26. package/src/client/market/market-locales.ts +118 -117
  27. package/src/client/market/my-configs-api.ts +163 -0
  28. package/src/client/market/my-configs-view.test.ts +289 -0
  29. package/src/client/market/my-configs-view.ts +304 -0
  30. package/src/client/run-store.ts +13 -0
  31. package/src/index.ts +163 -1
  32. package/src/market/git-file-writer.test.ts +249 -0
  33. package/src/market/git-file-writer.ts +336 -0
  34. package/src/market/github-repos.test.ts +400 -0
  35. package/src/market/github-repos.ts +481 -0
  36. package/src/market/my-repo.test.ts +472 -0
  37. package/src/market/my-repo.ts +516 -0
  38. package/src/ui/i18n.ts +19 -21
  39. package/lib/ui/market-publish.d.ts +0 -129
  40. package/lib/ui/market-publish.js +0 -168
  41. package/lib/ui/market-publish.js.map +0 -1
  42. package/src/client/market/PublishView.tsx +0 -388
  43. package/src/ui/market-publish.test.ts +0 -219
  44. package/src/ui/market-publish.ts +0 -256
package/lib/client.d.ts CHANGED
@@ -517,16 +517,15 @@ declare const uiZh: {
517
517
  readonly 'market.detail.sectionsEmpty': "未声明分区";
518
518
  readonly 'market.detail.statusValid': "校验通过";
519
519
  readonly 'market.detail.statusInvalid': "校验未通过";
520
- readonly 'marketPublish.stepSelect': "选择配置包";
521
- readonly 'marketPublish.stepValidate': "本地校验";
522
- readonly 'marketPublish.stepPrepare': "生成条目包";
523
- readonly 'marketPublish.stepPush': "推送作者仓库";
524
- readonly 'marketPublish.stepSubmit': "提交收录申请";
525
- readonly 'marketPublish.errorItemId': "条目 id 仅允许字母数字开头,字符限 . _ -(最长 128)";
526
- readonly 'marketPublish.errorName': "条目名称不能为空";
527
- readonly 'marketPublish.repoWhitespace': "仓库地址不能包含空白字符";
528
- readonly 'marketPublish.repoScheme': "仓库地址必须为 http(s) 链接";
529
- readonly 'marketPublish.repoUserinfo': "仓库地址不能包含用户名或密码(userinfo);凭据请通过 DSH credentials 提供";
520
+ readonly 'myConfigs.autoField': "系统自动";
521
+ readonly 'myConfigs.field.id': "条目 ID";
522
+ readonly 'myConfigs.field.author': "作者";
523
+ readonly 'myConfigs.field.version': "版本";
524
+ readonly 'myConfigs.field.updatedAt': "更新时间";
525
+ readonly 'myConfigs.status.notListed': "未收录";
526
+ readonly 'myConfigs.status.pendingPr': "PR 待审核";
527
+ readonly 'myConfigs.status.listed': "已收录";
528
+ readonly 'myConfigs.form.errorName': "名称不能为空";
530
529
  };
531
530
  type UiTextKey = keyof typeof uiZh;
532
531
  /** UI 翻译函数:key → 当前语言文案({param} 插值;未知键回退 zh/键名)。 */
@@ -1166,8 +1165,11 @@ declare class MarketApi {
1166
1165
  /** 浏览内置市场(合并 index + 本地缓存状态 → 条目列表带 cacheState) */
1167
1166
  browse(): Promise<MarketBrowseResponse>;
1168
1167
  /** 下载 + 校验单条目(dry-run 预览:拉取 → §6 校验 → analyzeImport → createImportPlan)。
1168
+ * repo 可选:条目来源仓库(作者自托管)。自托管条目(官方 index 带 repo 引用、或「我的配置」
1169
+ * 未收录条目)内容文件在作者自己的公开仓库,必须显式传 repo 才能从正确来源拉取;
1170
+ * 缺省 = 市场仓库(官方同仓条目)。
1169
1171
  * 真正落盘由用户对预览确认后走现有 executeImportPlan(confirm:true 安全阀 + 回滚)。 */
1170
- download(itemId: string): Promise<MarketDownloadResult>;
1172
+ download(itemId: string, repo?: string): Promise<MarketDownloadResult>;
1171
1173
  /** 发布向导:由「上传 zip + 用户填写元数据」生成市场条目包(L2 manifest + SHA-256 + sections),
1172
1174
  * 供 UI 展示/复制与引导推送。零写入配置(发布目录在受控临时区);不含任何凭据字段。 */
1173
1175
  prepare(payload: MarketPreparePayload): Promise<MarketPrepareResponse>;
@@ -1175,6 +1177,104 @@ declare class MarketApi {
1175
1177
  downloadPublishUrl(zipPath: string): string;
1176
1178
  }
1177
1179
  //#endregion
1180
+ //#region src/market/my-repo.d.ts
1181
+ /** 条目收录状态:未收录(本地独有)| PR 待审核(带 PR 链接)| 已收录(官方市场 index 含该 id) */
1182
+ type MyItemStatus = 'not-listed' | 'pr-pending' | 'listed';
1183
+ /** 上传表单:仅用户填写的描述性内容;id/author/version/updatedAt/repoUrl 全自动 */
1184
+ interface MyRepoForm {
1185
+ /** 配置名(预填 zip 文件名,可改);id 由其派生稳定 slug */
1186
+ name: string;
1187
+ description?: string;
1188
+ categories?: string[];
1189
+ }
1190
+ /** upload / update 返回(ok=false 时携带已脱敏 error + errorCode) */
1191
+ interface UploadResult {
1192
+ ok: boolean;
1193
+ itemId: string;
1194
+ version: string;
1195
+ sha256: string;
1196
+ sections: SectionId[];
1197
+ /** 用户公开仓库 URL(https://github.com/<login>/dsh-configs) */
1198
+ repoUrl: string;
1199
+ prNumber: number | null;
1200
+ prUrl: string | null;
1201
+ warnings: string[];
1202
+ /** ok=false 时:可展示错误(已脱敏,无 token 形态) */
1203
+ error?: string;
1204
+ /** ok=false 时:错误分类码(unauthorized/prepare_failed/...;无则 'internal') */
1205
+ errorCode?: string;
1206
+ }
1207
+ /** listItems 条目:用户仓库 index.json 条目 + 收录状态 */
1208
+ interface MyItemEntry {
1209
+ id: string;
1210
+ name: string;
1211
+ version?: string;
1212
+ description?: string;
1213
+ author?: string;
1214
+ updatedAt?: string;
1215
+ categories?: string[];
1216
+ status: MyItemStatus;
1217
+ /** status=pr-pending 时:PR 链接 */
1218
+ prUrl?: string;
1219
+ /** 用户公开仓库 URL */
1220
+ repoUrl: string;
1221
+ }
1222
+ //#endregion
1223
+ //#region src/client/market/my-configs-api.d.ts
1224
+ /**
1225
+ * POST /me/status 响应:登录态 + 用户配置仓库状态(设计文档 §4.2)。
1226
+ * 仅非敏感展示位:login 用户名可回显;token 值永不回传浏览器。
1227
+ */
1228
+ interface MyMeStatusResponse {
1229
+ loggedIn: boolean;
1230
+ /** GitHub 登录名(展示 @login 用) */
1231
+ login?: string;
1232
+ /** 用户自己的配置仓库 URL(无则尚未创建) */
1233
+ repoUrl?: string;
1234
+ /** 配置仓库是否已存在(false = 尚未创建过) */
1235
+ repoExists?: boolean;
1236
+ }
1237
+ /**
1238
+ * 一键上传/更新请求体中的表单(设计文档 §2.4 用户输入最小化):
1239
+ * 仅 name(必填,预填 zip 文件名可改)/ description(可选)/ categories(可选);
1240
+ * id / author / version / updatedAt 全部系统自动生成,不在表单里。
1241
+ * categories 为数组(UI 层先经 parseCategories 解析逗号分隔文本)。
1242
+ * **与 Host 半 my-repo.ts 的 MyRepoForm 同构**(对齐导出,避免漂移)。
1243
+ */
1244
+ type MyConfigsFormPayload = MyRepoForm;
1245
+ /**
1246
+ * POST /me/upload | /me/update 响应(**对齐 host 半 my-repo.ts 的 UploadResult**)。
1247
+ * ok=false 时 itemId/version/sha256 可为空串,warnings/error/errorCode 携带可展示信息(已脱敏)。
1248
+ */
1249
+ type MyUploadResult = UploadResult;
1250
+ /** POST /me/items 响应:用户仓库的全部条目(空仓库 → 空数组)。
1251
+ * 条目 = Host 侧 MyItemEntry(含收录状态 status + prUrl + repoUrl,§4.5 在 Host 判定)。 */
1252
+ interface MyItemsResponse {
1253
+ items: MyItemEntry[];
1254
+ }
1255
+ /**
1256
+ * 「我的配置」浏览器半数据入口(MarketPanel 的「我的配置」子视图注入业务面)。
1257
+ * 登录(GitHub device flow)不在此类 —— 复用 SyncApi.githubStart/githubPoll/githubCancel。
1258
+ */
1259
+ declare class MyConfigsApi {
1260
+ readonly t: UiT;
1261
+ constructor(t?: UiT);
1262
+ /** 读取登录态 + 用户配置仓库状态(token 失效 → Host 返回 401/未登录,UI 引导重新登录) */
1263
+ meStatus(): Promise<MyMeStatusResponse>;
1264
+ /** 一键上传:校验 → 建/复用仓库 → 写入用户仓库 → fork → 改官方 index → 提收录 PR */
1265
+ meUpload(payload: {
1266
+ zipPath: string;
1267
+ form: MyConfigsFormPayload;
1268
+ }): Promise<MyUploadResult>;
1269
+ /** 读取已上传条目列表(用户仓库 index.json;每条目含 Host 侧判定的收录状态) */
1270
+ meItems(): Promise<MyItemsResponse>;
1271
+ /** 一键更新:version 自动 +1,复用/重开收录 PR */
1272
+ meUpdate(payload: {
1273
+ zipPath: string;
1274
+ form: MyConfigsFormPayload;
1275
+ }): Promise<MyUploadResult>;
1276
+ }
1277
+ //#endregion
1178
1278
  //#region src/client/client-types.d.ts
1179
1279
  /** 本插件 Client 半的注入业务面:每个 settings.section 注册项都拿到同一个 api 实例 */
1180
1280
  interface ConfigManagerSectionInjected {
@@ -1185,6 +1285,8 @@ interface ConfigManagerSectionInjected {
1185
1285
  syncT: import('@deepseek-ai/dsh-client-ui-slots').TranslateNS<'config-manager-sync'>;
1186
1286
  /** 配置市场 API(备份与迁移页第 5 个 tab 使用,主 section 注册时注入) */
1187
1287
  marketApi: MarketApi;
1288
+ /** 「我的配置」API(MarketPanel 的「我的配置」子视图使用,主 section 注册时注入) */
1289
+ myConfigsApi: MyConfigsApi;
1188
1290
  /** 配置市场 locale(config-manager-market 命名空间,主 section 注册时注入) */
1189
1291
  marketT: import('@deepseek-ai/dsh-client-ui-slots').TranslateNS<'config-manager-market'>;
1190
1292
  }
@@ -1563,61 +1665,62 @@ declare const zh: {
1563
1665
  readonly 'detail.approval.safe': "可导入";
1564
1666
  readonly 'detail.approval.count': "已批准 {selected}/{total} 分区";
1565
1667
  readonly 'detail.noApproval': "未批准任何分区,无法导入";
1566
- readonly 'publish.title': "发布到市场";
1567
- readonly 'publish.subtitle': "把本地导出配置分享到社区:作者自托管公开仓库 + 官方收录引用(方案 B),官方市场只读、零凭据";
1568
- readonly 'publish.back': "返回市场";
1569
- readonly 'publish.stepIndicator': "步骤 {current}/{total}:{label}";
1570
- readonly 'publish.next': "下一步";
1571
- readonly 'publish.prev': "上一步";
1572
- readonly 'publish.step.select': "选择配置包";
1573
- readonly 'publish.step.validate': "本地校验";
1574
- readonly 'publish.step.prepare': "生成条目包";
1575
- readonly 'publish.step.push': "推送作者仓库";
1576
- readonly 'publish.step.submit': "提交收录申请";
1577
- readonly 'publish.select.hint': "发布内容来自你的导出 zip:先在「导出」tab 生成备份文件,再回到这里选择。市场通道永不携带秘密——包含密钥的备份将被拒绝。";
1578
- readonly 'publish.select.browse': "选择导出 ZIP…";
1579
- readonly 'publish.select.reselect': "重新选择";
1580
- readonly 'publish.select.file': "已选择:{name}";
1581
- readonly 'publish.select.uploading': "上传中…";
1582
- readonly 'publish.validate.hint': "本地 dry-run 校验(零写入):确认内容合法且不含密钥,之后才能生成条目包。";
1583
- readonly 'publish.validate.run': "开始校验";
1584
- readonly 'publish.validate.running': "校验中…";
1585
- readonly 'publish.validate.ok': "校验通过:内容合法、不含密钥";
1586
- readonly 'publish.validate.secrets': "包含密钥:市场通道永不携带秘密,拒绝发布";
1587
- readonly 'publish.validate.invalid': "内容校验未通过,无法发布";
1588
- readonly 'publish.validate.retry': "重新校验";
1589
- readonly 'publish.form.title': "条目元数据";
1590
- readonly 'publish.form.id': "条目 ID(必需)";
1591
- readonly 'publish.form.idHint': "字母数字开头,仅 . _ -,最长 128;将作为 items/<id>/ 目录名";
1592
- readonly 'publish.form.name': "条目名称(必需)";
1593
- readonly 'publish.form.description': "描述";
1594
- readonly 'publish.form.author': "作者";
1595
- readonly 'publish.form.version': "版本";
1596
- readonly 'publish.form.categories': "类别(逗号分隔)";
1597
- readonly 'publish.form.repoUrl': "托管仓库 URL(可选)";
1598
- readonly 'publish.form.repoUrlHint': "作者公开 Git 仓库地址(http(s),不含用户名/密码)。留空表示暂不关联仓库;推送指引与收录引用需要它。";
1599
- readonly 'publish.form.generate': "生成条目包";
1600
- readonly 'publish.form.generating': "生成中…";
1601
- readonly 'publish.prepare.title': "条目包已生成";
1602
- readonly 'publish.prepare.manifest': "items/<id>/manifest.json";
1603
- readonly 'publish.prepare.sha256': "SHA-256:{hash}";
1604
- readonly 'publish.prepare.sections': "包含分区:{sections}";
1605
- readonly 'publish.prepare.warnings': "发布即公开、未经官方审核;下载方导入前会逐项核对";
1606
- readonly 'publish.prepare.dirHint': "发布目录已在宿主受控临时区生成({dir}):items/<id>/manifest.json + config.zip";
1607
- readonly 'publish.prepare.copyManifest': "复制 manifest";
1608
- readonly 'publish.push.hint': "先下载「发布包」并解压为 dist/,然后在你自己的公开仓库中按序执行以下命令(插件不做任何 git 写操作、不持有凭据):";
1609
- readonly 'publish.push.commands': "git 命令";
1610
- readonly 'publish.push.download': "下载发布包";
1611
- readonly 'publish.push.copy': "复制命令";
1612
- readonly 'publish.push.repoMissing': "尚未填写托管仓库 URL——请在上一步「生成条目包」中填写,或手动把 items/{id}/ 目录推送到你的公开仓库。";
1613
- readonly 'publish.submit.hint': "把下面的片段追加到官方市场仓库 index.json 的 items[],然后提 PR。收录由创建者人工审核。";
1614
- readonly 'publish.submit.snippet': "index.json 追加片段(items[] 内新增一条)";
1615
- readonly 'publish.submit.copy': "复制片段";
1616
- readonly 'publish.submit.fork': "提交流程:fork 官方仓库({url})→ 在 index.json 的 items[] 追加上述片段 → 提交 PR。";
1617
- readonly 'publish.submit.manual': "也可把「条目 ID + 仓库地址」提交到项目 issue,由创建者人工收录。";
1618
- readonly 'publish.submit.repoMissing': "收录引用需要托管仓库 URL——请先在上一步「生成条目包」中填写。";
1619
- readonly 'publish.copied': "已复制";
1620
- readonly 'publish.copyFailed': "复制失败,请手动选择文本复制";
1668
+ readonly 'myconfigs.tab.browse': "浏览市场";
1669
+ readonly 'myconfigs.tab.myconfigs': "我的配置";
1670
+ readonly 'myconfigs.back': "返回市场";
1671
+ readonly 'myconfigs.login.title': "GitHub 登录";
1672
+ readonly 'myconfigs.login.hint': "登录后即可一键上传配置到你的公开仓库(自动创建 <login>/dsh-configs)并提交官方市场收录(目标仓库固定,不可修改)。";
1673
+ readonly 'myconfigs.login.checking': "正在检查登录状态…";
1674
+ readonly 'myconfigs.login.loggedInAs': "已登录:{login}";
1675
+ readonly 'myconfigs.login.targetRepo': "收录目标(固定):{repo}";
1676
+ readonly 'myconfigs.login.repoMissing': "配置仓库尚未创建,首次上传将自动创建(公开)";
1677
+ readonly 'myconfigs.login.repoReady': "配置仓库:{repo}";
1678
+ readonly 'myconfigs.login.start': "使用 GitHub 登录";
1679
+ readonly 'myconfigs.login.relogin': "重新登录";
1680
+ readonly 'myconfigs.login.cancel': "取消登录";
1681
+ readonly 'myconfigs.login.userCode': "一次性代码:{code}";
1682
+ readonly 'myconfigs.login.openAuth': "打开授权页";
1683
+ readonly 'myconfigs.upload.title': "一键上传";
1684
+ readonly 'myconfigs.upload.selectHint': "选择导出的配置 zip(先在「导出」tab 生成备份文件,再回到这里选择)。市场通道永不携带秘密——包含密钥的备份将被拒绝。";
1685
+ readonly 'myconfigs.upload.select': "选择 ZIP…";
1686
+ readonly 'myconfigs.upload.reselect': "重新选择";
1687
+ readonly 'myconfigs.upload.selected': "已选择:{name}";
1688
+ readonly 'myconfigs.upload.validate': "开始校验";
1689
+ readonly 'myconfigs.upload.validating': "校验中…";
1690
+ readonly 'myconfigs.upload.validateOk': "校验通过:内容合法、不含密钥";
1691
+ readonly 'myconfigs.upload.validateSecrets': "包含密钥:市场通道永不携带秘密,拒绝上传";
1692
+ readonly 'myconfigs.upload.validateInvalid': "内容校验未通过,无法上传";
1693
+ readonly 'myconfigs.upload.form.title': "条目信息";
1694
+ readonly 'myconfigs.upload.form.name': "名称";
1695
+ readonly 'myconfigs.upload.form.nameHint': "预填 zip 文件名,可修改";
1696
+ readonly 'myconfigs.upload.form.description': "描述(可选)";
1697
+ readonly 'myconfigs.upload.form.categories': "类别(可选,逗号分隔)";
1698
+ readonly 'myconfigs.upload.form.autoHint': "以下字段由系统自动生成:";
1699
+ readonly 'myconfigs.upload.run': "一键上传";
1700
+ readonly 'myconfigs.upload.running': "上传中…";
1701
+ readonly 'myconfigs.update.title': "更新配置";
1702
+ readonly 'myconfigs.update.hint': "版本将自动 +1,已预填原条目信息(名称可改)。";
1703
+ readonly 'myconfigs.update.run': "一键更新";
1704
+ readonly 'myconfigs.update.running': "更新中…";
1705
+ readonly 'myconfigs.result.title': "上传/更新完成";
1706
+ readonly 'myconfigs.result.version': "版本 {version}";
1707
+ readonly 'myconfigs.result.sha256': "SHA-256:{hash}";
1708
+ readonly 'myconfigs.result.sections': "分区:{sections}";
1709
+ readonly 'myconfigs.result.repo': "配置仓库";
1710
+ readonly 'myconfigs.result.openRepo': "打开仓库";
1711
+ readonly 'myconfigs.result.pr': "收录 PR #{number}";
1712
+ readonly 'myconfigs.result.openPr': "查看 PR";
1713
+ readonly 'myconfigs.list.title': "已上传";
1714
+ readonly 'myconfigs.list.empty': "尚未上传任何配置";
1715
+ readonly 'myconfigs.list.loading': "正在读取…";
1716
+ readonly 'myconfigs.list.refresh': "刷新";
1717
+ readonly 'myconfigs.list.summary': "共 {total} 条 · {listed} 已收录 · {pending} 待审核 · {none} 未收录";
1718
+ readonly 'myconfigs.list.openRepo': "打开仓库";
1719
+ readonly 'myconfigs.item.update': "更新";
1720
+ readonly 'myconfigs.item.install': "装回本地";
1721
+ readonly 'myconfigs.item.openPr': "查看收录 PR";
1722
+ readonly 'myconfigs.error.loadStatus': "登录状态读取失败";
1723
+ readonly 'myconfigs.error.loadItems': "已上传列表读取失败";
1621
1724
  readonly 'common.cancel': "取消";
1622
1725
  readonly 'common.close': "关闭";
1623
1726
  readonly 'common.retry': "重试";
@@ -1653,8 +1756,12 @@ interface SyncSettingsViewProps {
1653
1756
  //#region src/client/market/MarketPanel.d.ts
1654
1757
  interface MarketPanelProps {
1655
1758
  api: MarketApi;
1759
+ /** 「我的配置」API(/me/* 端点:登录态/一键上传/查看已上传/一键更新;登录复用 SyncApi.github*) */
1760
+ myConfigsApi: MyConfigsApi;
1656
1761
  /** 确认导入复用的主 ConfigManagerApi(executeImportPlan:安全阀 + 回滚) */
1657
1762
  importApi: ConfigManagerApi;
1763
+ /** GitHub 登录 API(「我的配置」登录卡复用 sync github device flow,同 token 槽) */
1764
+ syncApi: SyncApi;
1658
1765
  t: TranslateNS<'config-manager-market'>;
1659
1766
  }
1660
1767
  //#endregion