@morehao/dsh-github-trending 0.8.20 → 0.8.21

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/README.md CHANGED
@@ -89,6 +89,8 @@ dsh plugin --profile <profile> add @morehao/dsh-github-trending
89
89
 
90
90
  环境要求:DSH `0.2.1-rc.3` 以上、Node.js `^22.20.0 || >=24.0.0`、本地 git ≥ 2.30 与可写远端、git/GitHub 凭据(仅 push 与开 PR 需要)。核心二进制首次运行从 GitHub Release 下载并按 sha256 校验,之后离线复用。
91
91
 
92
+ > **网络代理**:核心抓取 GitHub 需要联网。GUI 宿主(从 Finder 启动)通常**不继承** shell 的 `http(s)_proxy`,在国内直连会超时——现象是趋势页抓取失败、回退到 GitHub 搜索 API(无「今日新增」增量、按总 star 排序)。此时在**设置 → 核心 → 网络代理**填 `http://127.0.0.1:7890`(你的代理地址)即可,插件会把它注入核心子进程的 `HTTP(S)_PROXY/ALL_PROXY`。留空则不使用代理。
93
+
92
94
  ## 开发与发版
93
95
 
94
96
  ```bash
package/client.js CHANGED
@@ -78,6 +78,9 @@ var DICT = {
78
78
  "core.missing": "未安装",
79
79
  "core.override": "覆盖路径:{path}",
80
80
  "core.order": "解析顺序:TRENDING_DIGEST_CORE(仅开发/排障)→ Release 资产(缓存命中直接用,否则下载并校验);都不可用时报 CORE_UNAVAILABLE。",
81
+ "network.proxy": "网络代理",
82
+ "network.proxy.help": "核心进程出站代理(拉取 GitHub 趋势/推送用)。GUI 宿主常不继承 shell 的 http(s)_proxy,国内直连会超时;填如 http://127.0.0.1:7890,留空不用代理。",
83
+ "network.proxy.placeholder": "http://127.0.0.1:7890(留空不使用)",
81
84
  "coexist.title": "检测到本机另有 CLI",
82
85
  "coexist.hint": "插件仍使用自带核心,不切换、不接管它的定时。",
83
86
  "card.model.title": "模型",
@@ -631,6 +634,9 @@ var DICT = {
631
634
  "core.redownload": "Re-download",
632
635
  "core.downloaded": "Core downloaded and verified",
633
636
  "core.order": "Resolution order: TRENDING_DIGEST_CORE (dev/troubleshooting only) → Release asset (cache first, otherwise download and verify); otherwise CORE_UNAVAILABLE.",
637
+ "network.proxy": "Network proxy",
638
+ "network.proxy.help": "Outbound proxy for the core process (fetching GitHub Trending / pushing). GUI hosts often do not inherit the shell http(s)_proxy, so direct connections time out in some regions; e.g. http://127.0.0.1:7890. Leave empty for no proxy.",
639
+ "network.proxy.placeholder": "http://127.0.0.1:7890 (empty = no proxy)",
634
640
  "coexist.title": "Another CLI found on this machine",
635
641
  "coexist.hint": "The plugin still uses its bundled core; it never switches or takes over that CLI schedule.",
636
642
  "card.model.title": "Model",
@@ -2228,7 +2234,7 @@ function cloneSettings(settings) {
2228
2234
  function sectionSlice(settings, section) {
2229
2235
  switch (section) {
2230
2236
  case "source":
2231
- return { corePath: settings.corePath };
2237
+ return { corePath: settings.corePath, network: settings.network };
2232
2238
  case "model":
2233
2239
  return { model: settings.model };
2234
2240
  case "repo":
@@ -2272,7 +2278,7 @@ function SettingsView(props) {
2272
2278
  const [signIn, setSignIn] = import_react.default.useState({ phase: "idle" });
2273
2279
  const [signInModal, setSignInModal] = import_react.default.useState(false);
2274
2280
  const anyDirty = SECTIONS.some((id) => dirtySections[id]);
2275
- const sectionEditable = section !== "source";
2281
+ const sectionEditable = true;
2276
2282
  import_react.default.useEffect(() => {
2277
2283
  if (state !== null && !anyDirty) setDraft(state.settings);
2278
2284
  }, [state, anyDirty]);
@@ -2537,6 +2543,19 @@ function SettingsView(props) {
2537
2543
  state.core.release === void 0 ? null : h("p", { className: "dshgt-hint dshgt-mono", style: { fontSize: 11 } }, `${state.core.release.url} → ${state.core.release.binaryPath}`),
2538
2544
  state.core.state === "ready" ? null : h(Alert, { kind: "err", title: t("core.label") }, h("div", null, state.core.message ?? ""), h("div", { className: "dshgt-hint" }, t("core.order"))),
2539
2545
  h("p", { className: "dshgt-hint" }, t("core.order")),
2546
+ h(
2547
+ Row,
2548
+ { label: t("network.proxy"), help: t("network.proxy.help") },
2549
+ h(Input, {
2550
+ mono: true,
2551
+ width: 280,
2552
+ value: draft.network?.proxy ?? "",
2553
+ placeholder: t("network.proxy.placeholder"),
2554
+ onInput: (value) => update((next) => {
2555
+ next.network = { proxy: value };
2556
+ })
2557
+ })
2558
+ ),
2540
2559
  state.coexistence.found ? h(Alert, { kind: "warn", title: t("coexist.title") }, h("div", { className: "dshgt-mono", style: { fontSize: 12 } }, `${state.coexistence.path ?? ""} ${state.coexistence.version ?? ""}`), h("div", null, state.coexistence.message ?? ""), h("div", { className: "dshgt-hint" }, t("coexist.hint"))) : null
2541
2560
  );
2542
2561
  const modelCredential = credentialView({ mode: draft.model.mode, credential: state.model.credential }, t);
@@ -86,7 +86,8 @@ var DEFAULT_SETTINGS = {
86
86
  output: { dir: "trending" },
87
87
  schedule: { enabled: true, time: "08:30:00", timezone: "Asia/Shanghai", periods: ["daily", "weekly", "monthly"] },
88
88
  corePath: "",
89
- coreAutoDownload: true
89
+ coreAutoDownload: true,
90
+ network: { proxy: "" }
90
91
  };
91
92
  var PROVIDER_BASE_URLS = {
92
93
  deepseek: "https://api.deepseek.com/v1",
@@ -103,7 +104,7 @@ function sectionOfField(field) {
103
104
  if (field.startsWith("summarize.")) return "summarize";
104
105
  if (field.startsWith("releases.")) return "releases";
105
106
  if (field.startsWith("schedule.")) return "schedule";
106
- if (field === "corePath" || field === "coreAutoDownload") return "source";
107
+ if (field === "corePath" || field === "coreAutoDownload" || field === "network.proxy") return "source";
107
108
  return void 0;
108
109
  }
109
110
  function mergeSettingsSection(stored, incoming, section) {
@@ -112,6 +113,7 @@ function mergeSettingsSection(stored, incoming, section) {
112
113
  case "source":
113
114
  next.corePath = incoming.corePath;
114
115
  next.coreAutoDownload = incoming.coreAutoDownload;
116
+ next.network = incoming.network;
115
117
  break;
116
118
  case "model":
117
119
  next.model = incoming.model;
@@ -252,7 +254,10 @@ function normalizeSettings(input) {
252
254
  periods: periodList(schedule.periods, DEFAULT_SETTINGS.schedule.periods)
253
255
  },
254
256
  corePath: str(raw.corePath, DEFAULT_SETTINGS.corePath).trim(),
255
- coreAutoDownload: bool(raw.coreAutoDownload, DEFAULT_SETTINGS.coreAutoDownload)
257
+ coreAutoDownload: bool(raw.coreAutoDownload, DEFAULT_SETTINGS.coreAutoDownload),
258
+ network: {
259
+ proxy: str(raw.network?.proxy, DEFAULT_SETTINGS.network.proxy).trim()
260
+ }
256
261
  };
257
262
  }
258
263
  var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?$/;
@@ -272,6 +277,14 @@ function autoInRange(value, min, max) {
272
277
  function validateSettings(settings, providers = CORE_PROVIDERS) {
273
278
  const problems = [];
274
279
  const { model, repo, trending, summarize, releases, output, schedule } = settings;
280
+ const proxy = (settings.network?.proxy ?? "").trim();
281
+ if (proxy !== "" && !/^https?:\/\/[^\s]+$/.test(proxy)) {
282
+ problems.push({
283
+ field: "network.proxy",
284
+ code: "CONFIG_INVALID",
285
+ message: "\u4EE3\u7406\u5FC5\u987B\u662F http(s):// \u5730\u5740\uFF08\u5982 http://127.0.0.1:7890\uFF09\uFF0C\u7559\u7A7A\u5219\u4E0D\u4F7F\u7528\u4EE3\u7406"
286
+ });
287
+ }
275
288
  if (model.provider.trim() === "") {
276
289
  problems.push({ field: "model.provider", code: "CONFIG_INVALID", message: "\u7F3A\u5C11 provider" });
277
290
  } else if (!providers.includes(model.provider)) {
@@ -1601,6 +1614,7 @@ var run_exports = {};
1601
1614
  __export(run_exports, {
1602
1615
  DEFAULT_RUN_TIMEOUT_MS: () => DEFAULT_RUN_TIMEOUT_MS,
1603
1616
  buildCoreArgs: () => buildCoreArgs,
1617
+ proxyEnv: () => proxyEnv,
1604
1618
  runCore: () => runCore
1605
1619
  });
1606
1620
  import { spawn as spawn2 } from "child_process";
@@ -1631,6 +1645,18 @@ function buildCoreArgs(channelPath, options) {
1631
1645
  if (options.repo !== void 0 && options.repo !== "") args.push("--repo", options.repo);
1632
1646
  return args;
1633
1647
  }
1648
+ function proxyEnv(proxy) {
1649
+ const p = (proxy ?? "").trim();
1650
+ if (p === "") return {};
1651
+ return {
1652
+ HTTP_PROXY: p,
1653
+ HTTPS_PROXY: p,
1654
+ ALL_PROXY: p,
1655
+ http_proxy: p,
1656
+ https_proxy: p,
1657
+ all_proxy: p
1658
+ };
1659
+ }
1634
1660
  async function runCore(options) {
1635
1661
  const timeoutMs = options.timeoutMs ?? DEFAULT_RUN_TIMEOUT_MS;
1636
1662
  const startedAt = nowIso();
@@ -1652,7 +1678,11 @@ async function runCore(options) {
1652
1678
  GITHUB_TOKEN: options.token,
1653
1679
  GH_TOKEN: options.token,
1654
1680
  // 环境变量通道:旧核心会忽略它,不会因为多一个未知参数而失败。
1655
- TRENDRADAR_TRIGGER: options.trigger ?? "manual"
1681
+ TRENDRADAR_TRIGGER: options.trigger ?? "manual",
1682
+ // 出站代理:GUI 宿主往往不继承 shell 的 http(s)_proxy,国内直连 GitHub 会
1683
+ // 超时。设置里填了就显式注入(大小写两份,Go 的 ProxyFromEnvironment 与多数
1684
+ // 工具都能识别)。空/未设时不注入任何键,保持原有环境透传行为。
1685
+ ...proxyEnv(options.settings.network?.proxy)
1656
1686
  }),
1657
1687
  stdio: ["ignore", "pipe", "pipe"],
1658
1688
  windowsHide: true
package/lib/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  createUpdateService,
10
10
  ensureGithubFlow,
11
11
  readPluginInfo
12
- } from "./chunk-6YH4NOBR.js";
12
+ } from "./chunk-SLY2RKCZ.js";
13
13
 
14
14
  // src/index.ts
15
15
  var name = "dsh-github-trending";
package/lib/internal.d.ts CHANGED
@@ -352,6 +352,15 @@ interface Settings {
352
352
  corePath: string;
353
353
  /** 缓存缺失时是否自动从 Release 下载核心(首次运行需要联网)。 */
354
354
  coreAutoDownload: boolean;
355
+ /**
356
+ * 核心进程的出站网络代理(如 http://127.0.0.1:7890)。GUI 宿主往往不继承
357
+ * shell 的 http(s)_proxy,国内直连 GitHub 会超时;这里显式注入到核心子进程的
358
+ * HTTP_PROXY/HTTPS_PROXY/ALL_PROXY(含大小写两份)。空串 = 不使用代理。
359
+ */
360
+ network: NetworkSettings;
361
+ }
362
+ interface NetworkSettings {
363
+ proxy: string;
355
364
  }
356
365
  declare const DEFAULT_SETTINGS: Settings;
357
366
  /** 核心支持的 provider 默认端点(空字符串 = 必须由用户填)。 */
@@ -470,6 +479,7 @@ declare const config_DEFAULT_SETTINGS: typeof DEFAULT_SETTINGS;
470
479
  type config_Enrich = Enrich;
471
480
  type config_GithubSettings = GithubSettings;
472
481
  type config_ModelSettings = ModelSettings;
482
+ type config_NetworkSettings = NetworkSettings;
473
483
  type config_OutputSettings = OutputSettings;
474
484
  declare const config_PERIODS: typeof PERIODS;
475
485
  declare const config_PROVIDER_BASE_URLS: typeof PROVIDER_BASE_URLS;
@@ -498,7 +508,7 @@ declare const config_toCoreConfig: typeof toCoreConfig;
498
508
  declare const config_toYaml: typeof toYaml;
499
509
  declare const config_validateSettings: typeof validateSettings;
500
510
  declare namespace config {
501
- export { type config_AuthMode as AuthMode, config_CORE_PROVIDERS as CORE_PROVIDERS, type config_CommitMode as CommitMode, type config_CoreConfig as CoreConfig, config_DEFAULT_SETTINGS as DEFAULT_SETTINGS, type config_Enrich as Enrich, type config_GithubSettings as GithubSettings, type config_ModelSettings as ModelSettings, type config_OutputSettings as OutputSettings, config_PERIODS as PERIODS, config_PROVIDER_BASE_URLS as PROVIDER_BASE_URLS, type config_PRSettings as PRSettings, type config_Period as Period, type config_Problem as Problem, type config_Provider as Provider, type config_ReleaseScheduleSettings as ReleaseScheduleSettings, type config_ReleasesSettings as ReleasesSettings, type config_RepoSettings as RepoSettings, config_SETTINGS_SECTIONS as SETTINGS_SECTIONS, type config_ScheduleSettings as ScheduleSettings, type config_Settings as Settings, type config_SettingsSection as SettingsSection, type config_Since as Since, type config_SummarizeSettings as SummarizeSettings, type config_TrendingSettings as TrendingSettings, config_effectiveBaseURL as effectiveBaseURL, config_isEnrich as isEnrich, config_isPeriod as isPeriod, config_isValidTimezone as isValidTimezone, config_mergeSettingsSection as mergeSettingsSection, config_normalizeSettings as normalizeSettings, config_sectionOfField as sectionOfField, config_toCoreConfig as toCoreConfig, config_toYaml as toYaml, config_validateSettings as validateSettings };
511
+ export { type config_AuthMode as AuthMode, config_CORE_PROVIDERS as CORE_PROVIDERS, type config_CommitMode as CommitMode, type config_CoreConfig as CoreConfig, config_DEFAULT_SETTINGS as DEFAULT_SETTINGS, type config_Enrich as Enrich, type config_GithubSettings as GithubSettings, type config_ModelSettings as ModelSettings, type config_NetworkSettings as NetworkSettings, type config_OutputSettings as OutputSettings, config_PERIODS as PERIODS, config_PROVIDER_BASE_URLS as PROVIDER_BASE_URLS, type config_PRSettings as PRSettings, type config_Period as Period, type config_Problem as Problem, type config_Provider as Provider, type config_ReleaseScheduleSettings as ReleaseScheduleSettings, type config_ReleasesSettings as ReleasesSettings, type config_RepoSettings as RepoSettings, config_SETTINGS_SECTIONS as SETTINGS_SECTIONS, type config_ScheduleSettings as ScheduleSettings, type config_Settings as Settings, type config_SettingsSection as SettingsSection, type config_Since as Since, type config_SummarizeSettings as SummarizeSettings, type config_TrendingSettings as TrendingSettings, config_effectiveBaseURL as effectiveBaseURL, config_isEnrich as isEnrich, config_isPeriod as isPeriod, config_isValidTimezone as isValidTimezone, config_mergeSettingsSection as mergeSettingsSection, config_normalizeSettings as normalizeSettings, config_sectionOfField as sectionOfField, config_toCoreConfig as toCoreConfig, config_toYaml as toYaml, config_validateSettings as validateSettings };
502
512
  }
503
513
 
504
514
  declare const PLUGIN_DIR_NAME = "github-trending";
@@ -983,15 +993,22 @@ declare function buildCoreArgs(channelPath: string, options: {
983
993
  force?: boolean;
984
994
  repo?: string;
985
995
  }): string[];
996
+ /**
997
+ * 把设置里的代理地址展开成核心子进程需要的环境变量。返回空对象表示不注入代理。
998
+ * 同时给大小写两份:Go 的 `http.ProxyFromEnvironment` 等实现只认大写,不少工具
999
+ * 只认小写,两份都放最稳。
1000
+ */
1001
+ declare function proxyEnv(proxy: string | undefined): Record<string, string>;
986
1002
  declare function runCore(options: RunCoreOptions): Promise<RunCoreResult>;
987
1003
 
988
1004
  declare const run_DEFAULT_RUN_TIMEOUT_MS: typeof DEFAULT_RUN_TIMEOUT_MS;
989
1005
  type run_RunCoreOptions = RunCoreOptions;
990
1006
  type run_RunCoreResult = RunCoreResult;
991
1007
  declare const run_buildCoreArgs: typeof buildCoreArgs;
1008
+ declare const run_proxyEnv: typeof proxyEnv;
992
1009
  declare const run_runCore: typeof runCore;
993
1010
  declare namespace run {
994
- export { run_DEFAULT_RUN_TIMEOUT_MS as DEFAULT_RUN_TIMEOUT_MS, type run_RunCoreOptions as RunCoreOptions, type run_RunCoreResult as RunCoreResult, run_buildCoreArgs as buildCoreArgs, run_runCore as runCore };
1011
+ export { run_DEFAULT_RUN_TIMEOUT_MS as DEFAULT_RUN_TIMEOUT_MS, type run_RunCoreOptions as RunCoreOptions, type run_RunCoreResult as RunCoreResult, run_buildCoreArgs as buildCoreArgs, run_proxyEnv as proxyEnv, run_runCore as runCore };
995
1012
  }
996
1013
 
997
1014
  /** `owner/repo`(可选带前后 `v`)→ `https://github.com/owner/repo`;非 GitHub 形态返回 undefined。 */
package/lib/internal.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  tools_exports,
28
28
  update_exports,
29
29
  version_exports
30
- } from "./chunk-6YH4NOBR.js";
30
+ } from "./chunk-SLY2RKCZ.js";
31
31
 
32
32
  // src/internal.ts
33
33
  import * as exec from "@morehao/dsh-plugin-kit/exec";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morehao/dsh-github-trending",
3
- "version": "0.8.20",
3
+ "version": "0.8.21",
4
4
  "description": "GitHub 趋势日报的 DeepSeek Harness 插件:按日 / 周 / 月周期定时 spawn 本地 trendradar 核心,抓取 Trending、生成中文简介与周期总结,并可选把订阅仓库的新 Release 合成中文摘要,一起提交到你的仓库、自动开 PR 合并;内置概览 / 榜单 / 运行记录 / 订阅 / 设置工作台。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",