@morehao/dsh-github-trending 0.6.0 → 0.7.0
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/CHANGELOG.md +11 -0
- package/README.md +3 -1
- package/client.js +56 -14
- package/lib/{chunk-WDBZAMWN.js → chunk-VF6DOIQQ.js} +60 -9
- package/lib/index.js +1 -1
- package/lib/internal.d.ts +60 -50
- package/lib/internal.js +5 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v0.6.1] - 2026-11-01
|
|
4
|
+
|
|
5
|
+
### 变更
|
|
6
|
+
|
|
7
|
+
- 契约依赖 `@morehao/trendradar-contract` 0.3.0 → 0.4.0:`SubscriptionStatus` / `SubscriptionItem` /
|
|
8
|
+
`SubscriptionVolume` / `SubscriptionDoc` 改为从契约包 `import type`,删除 `src/ipc.ts` 与
|
|
9
|
+
`client/api.ts` 里的本地兜底声明(0.6.0 的临时载体)。
|
|
10
|
+
- **无行为变化**:wire 仍 `ipcSchema=2` / `digestSchema=2`,`dsh.core.version` 仍为 `0.7.0`;
|
|
11
|
+
运行时守卫与错误文案保持原样(契约包的 `subscriptionDoc` 校验比本地守卫更严,换用会改变对旧核心
|
|
12
|
+
的接受范围,故不动)。
|
|
13
|
+
|
|
3
14
|
## [v0.6.0] - 2026-11-01
|
|
4
15
|
|
|
5
16
|
> **发版顺序**:先发布核心 `0.7.0`(含契约 0.4.0 的字段),再发布本插件——本版
|
package/README.md
CHANGED
|
@@ -31,6 +31,8 @@ dsh plugin --profile <profile> add @morehao/dsh-github-trending
|
|
|
31
31
|
2. **填模型**:点「沿用 DSH 配置」从宿主 provider 目录里挑 provider 与模型;可导出密钥的直接传给核心,OAuth 类凭据走本机回环代理。
|
|
32
32
|
3. **试跑一次**:「试跑(不提交)」只抓取与渲染,不写文件、不提交。
|
|
33
33
|
|
|
34
|
+
> **重新生成(忽略缓存)**:手动「重新生成」会忽略核心持久化的摘要缓存,强制重新抓取与总结,并让榜单页以本次结果为准。若重新生成后内容与分支上已有产物逐字节相同,核心仍按 append-only 语义**不新增提交**(面板提示「内容无变化,未新增提交」);内容有变化才追加一个提交。定时运行永不强制重跑。
|
|
35
|
+
|
|
34
36
|
> 设置页分「内容来源 / 模型 / 仓库 / 认证 / 榜单 / 调度」六个 tab;**除「内容来源」(只有状态与核心操作,没有可保存字段)外,每个 tab 独立保存与校验**;某个 tab 有未保存改动时,左侧对应 tab 会显示黄点。
|
|
35
37
|
|
|
36
38
|
## 榜单预览与按周期回看
|
|
@@ -133,7 +135,7 @@ dsh plugin --profile <profile> add @morehao/dsh-github-trending
|
|
|
133
135
|
|
|
134
136
|
| 工具 | 参数 | 返回 |
|
|
135
137
|
|---|---|---|
|
|
136
|
-
| `trending_run` | `{ dryRun?: boolean, date?: string, period?: 'daily'\|'weekly'\|'monthly' }` | 结构化摘要:文件数、commit/分支、PR、内容哈希、错误码与下一步 |
|
|
138
|
+
| `trending_run` | `{ dryRun?: boolean, date?: string, period?: 'daily'\|'weekly'\|'monthly', force?: boolean }` | 结构化摘要:文件数、commit/分支、PR、内容哈希、错误码与下一步 |
|
|
137
139
|
| `trending_history` | `{ limit?: number }` | 上次/下次运行、最近 N 条记录、核心版本、模型、未合并 PR |
|
|
138
140
|
|
|
139
141
|
工具名是稳定对外接口:**只新增不改名**。
|
package/client.js
CHANGED
|
@@ -294,6 +294,10 @@ var DICT = {
|
|
|
294
294
|
"overview.live.note": "核心一次完成抓取、总结、渲染与提交,结束前没有分段进度;这里只显示已用时间和粗阶段。",
|
|
295
295
|
"overview.live.started": "开始于",
|
|
296
296
|
"run.dryRunShort": "试跑",
|
|
297
|
+
"run.force": "重新生成",
|
|
298
|
+
"run.force.hint": "忽略摘要缓存,强制重新抓取与总结",
|
|
299
|
+
"run.force.noChange": "内容无变化,未新增提交",
|
|
300
|
+
"run.forced.tag": "强制重跑",
|
|
297
301
|
"run.usage.commit": "提交",
|
|
298
302
|
"runs.count": "最近 {count} 次,超出即裁剪",
|
|
299
303
|
"runs.files": "{count} 个文件",
|
|
@@ -352,6 +356,7 @@ var DICT = {
|
|
|
352
356
|
"digest.select": "选择日报日期",
|
|
353
357
|
"digest.render": "渲染",
|
|
354
358
|
"digest.raw": "原文",
|
|
359
|
+
"digest.regenerate": "重新生成这一期",
|
|
355
360
|
"digest.mode": "预览方式",
|
|
356
361
|
"digest.copyPath": "复制路径",
|
|
357
362
|
"digest.copied": "已复制",
|
|
@@ -801,6 +806,10 @@ var DICT = {
|
|
|
801
806
|
"overview.live.note": "The core fetches, summarizes, renders and commits in one run; there is no per-step progress before it finishes. Only elapsed time and a coarse phase are shown here.",
|
|
802
807
|
"overview.live.started": "Started",
|
|
803
808
|
"run.dryRunShort": "Dry run",
|
|
809
|
+
"run.force": "Regenerate",
|
|
810
|
+
"run.force.hint": "Ignore the summary cache and re-fetch and re-summarize",
|
|
811
|
+
"run.force.noChange": "No content change; no new commit",
|
|
812
|
+
"run.forced.tag": "Forced",
|
|
804
813
|
"run.usage.commit": "Commit",
|
|
805
814
|
"runs.count": "Last {count} runs; older ones are trimmed",
|
|
806
815
|
"runs.files": "{count} files",
|
|
@@ -859,6 +868,7 @@ var DICT = {
|
|
|
859
868
|
"digest.select": "Choose a digest date",
|
|
860
869
|
"digest.render": "Rendered",
|
|
861
870
|
"digest.raw": "Raw",
|
|
871
|
+
"digest.regenerate": "Regenerate this period",
|
|
862
872
|
"digest.mode": "Preview mode",
|
|
863
873
|
"digest.copyPath": "Copy path",
|
|
864
874
|
"digest.copied": "Copied",
|
|
@@ -2740,14 +2750,18 @@ function useRunController(store) {
|
|
|
2740
2750
|
const [dryRun, setDryRun] = import_react.default.useState(false);
|
|
2741
2751
|
const [localStartedAt, setLocalStartedAt] = import_react.default.useState(null);
|
|
2742
2752
|
const run = import_react.default.useCallback(
|
|
2743
|
-
async (overrideDry) => {
|
|
2753
|
+
async (overrideDry, options) => {
|
|
2744
2754
|
const dry = overrideDry ?? dryRun;
|
|
2745
2755
|
setBusy(true);
|
|
2746
2756
|
setError(null);
|
|
2747
2757
|
setSummary(null);
|
|
2748
2758
|
setLocalStartedAt((/* @__PURE__ */ new Date()).toISOString());
|
|
2749
2759
|
try {
|
|
2750
|
-
const
|
|
2760
|
+
const body = { dryRun: dry };
|
|
2761
|
+
if (options?.force === true) body.force = true;
|
|
2762
|
+
if (options?.date !== void 0 && options.date !== "") body.date = options.date;
|
|
2763
|
+
if (options?.period !== void 0) body.period = options.period;
|
|
2764
|
+
const result = await apiCall("POST", "/run", body);
|
|
2751
2765
|
setSummary(result.summary);
|
|
2752
2766
|
await refresh({ quiet: true });
|
|
2753
2767
|
} catch (failure) {
|
|
@@ -2936,6 +2950,9 @@ function digestTarget(record, timeZone) {
|
|
|
2936
2950
|
const period = recordPeriod(record);
|
|
2937
2951
|
return { period, bucket: periodBucket(period, info.date) };
|
|
2938
2952
|
}
|
|
2953
|
+
function regenTarget(day) {
|
|
2954
|
+
return { period: day.period, date: day.date };
|
|
2955
|
+
}
|
|
2939
2956
|
function buildPeriodGroups(records, options) {
|
|
2940
2957
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
2941
2958
|
const today = zonedDateString(now, options.timeZone);
|
|
@@ -3325,7 +3342,10 @@ function recordSummary(t, record) {
|
|
|
3325
3342
|
if (!record.ok) {
|
|
3326
3343
|
return [record.errorCode, record.errorMessage].filter((item) => item !== void 0 && item !== "").join(" · ") || t("state.failed");
|
|
3327
3344
|
}
|
|
3328
|
-
if (record.skipped)
|
|
3345
|
+
if (record.skipped) {
|
|
3346
|
+
if (record.forced === true && record.skipReason === "unchanged") return t("run.force.noChange");
|
|
3347
|
+
return skipHint(t, record.skipReason, t("runs.noChange"));
|
|
3348
|
+
}
|
|
3329
3349
|
if (record.kind === "dry-run") return t("runs.dryHint");
|
|
3330
3350
|
if (record.branch !== void 0) return record.branch;
|
|
3331
3351
|
if (record.commit !== void 0) return record.commit;
|
|
@@ -3459,7 +3479,8 @@ function RunsView(props) {
|
|
|
3459
3479
|
{ className: "dshgt-run-what" },
|
|
3460
3480
|
record.kind === "dry-run" ? t("state.dry") : record.skipped ? t("state.skipped") : record.ok ? t("state.ok") : t("state.failed"),
|
|
3461
3481
|
h("span", { className: "dshgt-run-muted" }, recordSummary(t, record)),
|
|
3462
|
-
record.legacy === true ? h("span", { className: "dshgt-tag dshgt-inline-tag" }, t("runs.legacy")) : null
|
|
3482
|
+
record.legacy === true ? h("span", { className: "dshgt-tag dshgt-inline-tag" }, t("runs.legacy")) : null,
|
|
3483
|
+
record.forced === true ? h("span", { className: "dshgt-tag dshgt-inline-tag" }, t("run.forced.tag")) : null
|
|
3463
3484
|
),
|
|
3464
3485
|
h("span", { className: "dshgt-run-files" }, t("runs.files", { count: record.files })),
|
|
3465
3486
|
record.tokens === void 0 ? null : h("span", { className: "dshgt-run-tokens dshgt-mono", title: t("run.usage.tokens") }, `${formatTokens(record.tokens)} tok`),
|
|
@@ -4074,6 +4095,7 @@ function EmptyDigest(props) {
|
|
|
4074
4095
|
"div",
|
|
4075
4096
|
{ className: "dshgt-actions" },
|
|
4076
4097
|
h(Btn, { small: true, onClick: props.onOpenRuns }, t("digest.empty.viewRuns")),
|
|
4098
|
+
props.onRegenerate === void 0 ? null : h(Btn, { small: true, onClick: props.onRegenerate, disabled: props.regenDisabled === true }, t("digest.regenerate")),
|
|
4077
4099
|
nearest === void 0 ? null : h(
|
|
4078
4100
|
Btn,
|
|
4079
4101
|
{ small: true, onClick: () => props.onSelect({ period: nearest.period, bucket: nearest.bucket }) },
|
|
@@ -4083,7 +4105,7 @@ function EmptyDigest(props) {
|
|
|
4083
4105
|
);
|
|
4084
4106
|
}
|
|
4085
4107
|
function DigestView(props) {
|
|
4086
|
-
const { t, lang, store, selected } = props;
|
|
4108
|
+
const { t, lang, store, selected, controller } = props;
|
|
4087
4109
|
const [mode, setMode] = import_react.default.useState("render");
|
|
4088
4110
|
const [payload, setPayload] = import_react.default.useState(null);
|
|
4089
4111
|
const [loading, setLoading] = import_react.default.useState(false);
|
|
@@ -4119,20 +4141,20 @@ function DigestView(props) {
|
|
|
4119
4141
|
setLoading(false);
|
|
4120
4142
|
return () => void 0;
|
|
4121
4143
|
}
|
|
4122
|
-
const
|
|
4144
|
+
const controller2 = new AbortController();
|
|
4123
4145
|
setLoading(true);
|
|
4124
4146
|
setError(null);
|
|
4125
4147
|
setPayload(null);
|
|
4126
|
-
getPreview(previewRunId,
|
|
4127
|
-
if (
|
|
4148
|
+
getPreview(previewRunId, controller2.signal).then((result) => {
|
|
4149
|
+
if (controller2.signal.aborted) return;
|
|
4128
4150
|
setPayload(result);
|
|
4129
4151
|
setLoading(false);
|
|
4130
4152
|
}).catch((failure) => {
|
|
4131
|
-
if (
|
|
4153
|
+
if (controller2.signal.aborted) return;
|
|
4132
4154
|
setError(failure instanceof Error ? failure.message : String(failure));
|
|
4133
4155
|
setLoading(false);
|
|
4134
4156
|
});
|
|
4135
|
-
return () =>
|
|
4157
|
+
return () => controller2.abort();
|
|
4136
4158
|
}, [previewRunId]);
|
|
4137
4159
|
if (state === null) {
|
|
4138
4160
|
return h("div", { className: "dshgt-empty" }, store.error ?? t("quickfill.loading"));
|
|
@@ -4253,6 +4275,12 @@ function DigestView(props) {
|
|
|
4253
4275
|
}
|
|
4254
4276
|
const showEmpty = day.status !== "preview" || error !== null;
|
|
4255
4277
|
const record = day.record;
|
|
4278
|
+
const regenerate = () => {
|
|
4279
|
+
const target = regenTarget(day);
|
|
4280
|
+
props.onSelect({ period: target.period, bucket: day.bucket });
|
|
4281
|
+
void controller.run(false, { force: true, date: target.date, period: target.period });
|
|
4282
|
+
};
|
|
4283
|
+
const regenerateDisabled = controller.running || controller.busy;
|
|
4256
4284
|
return h(
|
|
4257
4285
|
"div",
|
|
4258
4286
|
{ className: "dshgt-view dshgt-digest" },
|
|
@@ -4268,7 +4296,9 @@ function DigestView(props) {
|
|
|
4268
4296
|
...nearest === void 0 ? {} : { nearest },
|
|
4269
4297
|
...error === null ? {} : { error },
|
|
4270
4298
|
onOpenRuns: props.onOpenRuns,
|
|
4271
|
-
onSelect: props.onSelect
|
|
4299
|
+
onSelect: props.onSelect,
|
|
4300
|
+
onRegenerate: regenerate,
|
|
4301
|
+
regenDisabled: regenerateDisabled
|
|
4272
4302
|
}) : h(
|
|
4273
4303
|
"div",
|
|
4274
4304
|
{ className: "dshgt-digest-body" },
|
|
@@ -4284,6 +4314,7 @@ function DigestView(props) {
|
|
|
4284
4314
|
h("span", { className: "dshgt-dim" }, record.preview === void 0 ? "—" : formatBytes(record.preview.bytes)),
|
|
4285
4315
|
payload?.preview.truncated === true ? h("span", { className: "dshgt-tag" }, t("digest.truncated")) : null,
|
|
4286
4316
|
h("span", { className: "dshgt-grow" }),
|
|
4317
|
+
h(Btn, { small: true, onClick: regenerate, disabled: regenerateDisabled }, t("digest.regenerate")),
|
|
4287
4318
|
h(
|
|
4288
4319
|
"div",
|
|
4289
4320
|
{ className: "dshgt-seg", role: "group", "aria-label": t("digest.mode") },
|
|
@@ -4391,9 +4422,10 @@ function statusLabel(t, status) {
|
|
|
4391
4422
|
function mergeRows(list) {
|
|
4392
4423
|
if (list === null) return [];
|
|
4393
4424
|
const byName = /* @__PURE__ */ new Map();
|
|
4394
|
-
|
|
4425
|
+
const items = list.items ?? [];
|
|
4426
|
+
for (const item of items) byName.set(item.fullName, item);
|
|
4395
4427
|
const names = [...list.repos];
|
|
4396
|
-
for (const item of
|
|
4428
|
+
for (const item of items) {
|
|
4397
4429
|
if (!names.includes(item.fullName)) names.push(item.fullName);
|
|
4398
4430
|
}
|
|
4399
4431
|
return names.map((name) => {
|
|
@@ -5549,7 +5581,7 @@ function apply(ctx) {
|
|
|
5549
5581
|
state.github.configured
|
|
5550
5582
|
].filter(Boolean).length;
|
|
5551
5583
|
const digestTail = state?.status.lastResult?.date ?? state?.status.history[0]?.date;
|
|
5552
|
-
const showActions = view === "overview" || view === "runs";
|
|
5584
|
+
const showActions = view === "overview" || view === "runs" || view === "digest";
|
|
5553
5585
|
const nextRun = schedule === void 0 || !schedule.enabled ? t("shell.scheduleOff") : schedule.nextRunAt === void 0 ? `${schedule.time} · ${schedule.timezone}` : nextRunText(schedule.nextRunAt);
|
|
5554
5586
|
const relNext = schedule !== void 0 && schedule.enabled && schedule.nextRunAt !== void 0 ? relativeFuture(schedule.nextRunAt, t) : void 0;
|
|
5555
5587
|
const viewNode = view === "overview" ? h(OverviewView, {
|
|
@@ -5564,6 +5596,7 @@ function apply(ctx) {
|
|
|
5564
5596
|
t,
|
|
5565
5597
|
lang,
|
|
5566
5598
|
store: value,
|
|
5599
|
+
controller,
|
|
5567
5600
|
...digestTarget2 === void 0 ? {} : { selected: digestTarget2 },
|
|
5568
5601
|
onSelect: setDigestTarget,
|
|
5569
5602
|
onOpenRuns: openRuns
|
|
@@ -5640,6 +5673,15 @@ function apply(ctx) {
|
|
|
5640
5673
|
},
|
|
5641
5674
|
t("run.dryRunShort")
|
|
5642
5675
|
),
|
|
5676
|
+
h(
|
|
5677
|
+
Btn,
|
|
5678
|
+
{
|
|
5679
|
+
key: "force",
|
|
5680
|
+
onClick: () => void controller.run(false, { force: true }),
|
|
5681
|
+
disabled: controller.running || controller.busy
|
|
5682
|
+
},
|
|
5683
|
+
t("run.force")
|
|
5684
|
+
),
|
|
5643
5685
|
h(
|
|
5644
5686
|
Btn,
|
|
5645
5687
|
{
|
|
@@ -1611,6 +1611,7 @@ function buildCoreArgs(channelPath, options) {
|
|
|
1611
1611
|
if (options.date !== void 0 && options.date !== "") args.push("--date", options.date);
|
|
1612
1612
|
if (options.period !== void 0) args.push("--period", options.period);
|
|
1613
1613
|
if (options.stages !== void 0 && options.stages.length > 0) args.push("--stages", options.stages.join(","));
|
|
1614
|
+
if (options.force === true) args.push("--force");
|
|
1614
1615
|
return args;
|
|
1615
1616
|
}
|
|
1616
1617
|
async function runCore(options) {
|
|
@@ -1625,7 +1626,8 @@ async function runCore(options) {
|
|
|
1625
1626
|
dryRun: options.dryRun,
|
|
1626
1627
|
date: options.date,
|
|
1627
1628
|
period: options.period,
|
|
1628
|
-
stages: options.stages
|
|
1629
|
+
stages: options.stages,
|
|
1630
|
+
force: options.force
|
|
1629
1631
|
});
|
|
1630
1632
|
const child = spawn2(options.core.path, args, {
|
|
1631
1633
|
env: sanitizedEnv(process.env, {
|
|
@@ -2722,9 +2724,33 @@ async function runSubscribe(input, deps) {
|
|
|
2722
2724
|
}
|
|
2723
2725
|
}
|
|
2724
2726
|
|
|
2727
|
+
// src/host/version.ts
|
|
2728
|
+
var version_exports = {};
|
|
2729
|
+
__export(version_exports, {
|
|
2730
|
+
versionAtLeast: () => versionAtLeast
|
|
2731
|
+
});
|
|
2732
|
+
function parseTriplet(value) {
|
|
2733
|
+
const match = /^v?(\d+)\.(\d+)\.(\d+)/.exec(value.trim());
|
|
2734
|
+
if (match === null) return void 0;
|
|
2735
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
2736
|
+
}
|
|
2737
|
+
function versionAtLeast(a, b) {
|
|
2738
|
+
const left = parseTriplet(a);
|
|
2739
|
+
const right = parseTriplet(b);
|
|
2740
|
+
if (left === void 0 || right === void 0) return false;
|
|
2741
|
+
for (let i = 0; i < 3; i += 1) {
|
|
2742
|
+
const l = left[i];
|
|
2743
|
+
const r = right[i];
|
|
2744
|
+
if (l > r) return true;
|
|
2745
|
+
if (l < r) return false;
|
|
2746
|
+
}
|
|
2747
|
+
return true;
|
|
2748
|
+
}
|
|
2749
|
+
|
|
2725
2750
|
// src/host/runner.ts
|
|
2726
2751
|
var runner_exports = {};
|
|
2727
2752
|
__export(runner_exports, {
|
|
2753
|
+
FORCE_MIN_CORE_VERSION: () => FORCE_MIN_CORE_VERSION,
|
|
2728
2754
|
Runner: () => Runner,
|
|
2729
2755
|
isoWeekName: () => isoWeekName,
|
|
2730
2756
|
periodFileBase: () => periodFileBase,
|
|
@@ -2733,6 +2759,7 @@ __export(runner_exports, {
|
|
|
2733
2759
|
import { createHash as createHash2 } from "crypto";
|
|
2734
2760
|
import { existsSync as existsSync4, readFileSync as readFileSync3, realpathSync, statSync as statSync5 } from "fs";
|
|
2735
2761
|
import path9 from "path";
|
|
2762
|
+
var FORCE_MIN_CORE_VERSION = "0.7.1";
|
|
2736
2763
|
function repoProblem(repoPath) {
|
|
2737
2764
|
if (repoPath.trim() === "") return { code: "CONFIG_INVALID", message: "\u8FD8\u6CA1\u6709\u9009\u62E9\u5F52\u6863\u4ED3\u5E93" };
|
|
2738
2765
|
if (!existsSync4(repoPath)) return { code: "REPO_NOT_GIT", message: `\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${repoPath}` };
|
|
@@ -2851,6 +2878,15 @@ var Runner = class {
|
|
|
2851
2878
|
`\u6838\u5FC3\u4E0D\u652F\u6301 provider\u300C${settings.model.provider}\u300D\uFF1B\u53EF\u7528\uFF1A${handshakeResult.supportedProviders.join(" / ")}`
|
|
2852
2879
|
);
|
|
2853
2880
|
}
|
|
2881
|
+
const forceRequested = options.force === true;
|
|
2882
|
+
const forceSupported = versionAtLeast(handshakeResult.version.version, FORCE_MIN_CORE_VERSION);
|
|
2883
|
+
const effectiveForce = forceRequested && forceSupported;
|
|
2884
|
+
if (forceRequested && !forceSupported) {
|
|
2885
|
+
store.appendLog(
|
|
2886
|
+
logFile,
|
|
2887
|
+
`[force] \u6838\u5FC3 ${handshakeResult.version.version} \u4F4E\u4E8E ${FORCE_MIN_CORE_VERSION}\uFF0C\u4E0D\u652F\u6301 --force\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u666E\u901A\u91CD\u8DD1`
|
|
2888
|
+
);
|
|
2889
|
+
}
|
|
2854
2890
|
const model = await this.openModelChannel({ settings, credentials, env, logFile });
|
|
2855
2891
|
const apiKey = model.apiKey;
|
|
2856
2892
|
proxy = model.proxy;
|
|
@@ -2868,6 +2904,7 @@ var Runner = class {
|
|
|
2868
2904
|
period,
|
|
2869
2905
|
dryRun,
|
|
2870
2906
|
trigger: options.trigger === "schedule" ? "schedule" : "manual",
|
|
2907
|
+
...effectiveForce ? { force: true } : {},
|
|
2871
2908
|
...model.baseURLOverride === void 0 ? {} : { baseURLOverride: model.baseURLOverride },
|
|
2872
2909
|
signal: controller.signal,
|
|
2873
2910
|
secrets: [apiKey, github.token],
|
|
@@ -2884,7 +2921,8 @@ var Runner = class {
|
|
|
2884
2921
|
channel: result.channelKind,
|
|
2885
2922
|
proxy: proxy !== void 0,
|
|
2886
2923
|
coreSource: core.source,
|
|
2887
|
-
...core.tag === void 0 ? {} : { coreTag: core.tag }
|
|
2924
|
+
...core.tag === void 0 ? {} : { coreTag: core.tag },
|
|
2925
|
+
...effectiveForce ? { forced: true } : {}
|
|
2888
2926
|
});
|
|
2889
2927
|
const preview = this.capturePreview({
|
|
2890
2928
|
id,
|
|
@@ -2892,7 +2930,8 @@ var Runner = class {
|
|
|
2892
2930
|
period,
|
|
2893
2931
|
settings,
|
|
2894
2932
|
outcome,
|
|
2895
|
-
secrets: [apiKey, github.token]
|
|
2933
|
+
secrets: [apiKey, github.token],
|
|
2934
|
+
...effectiveForce ? { force: true } : {}
|
|
2896
2935
|
});
|
|
2897
2936
|
if (preview !== void 0) summary.preview = preview;
|
|
2898
2937
|
this.record(summary, settings);
|
|
@@ -3192,7 +3231,8 @@ var Runner = class {
|
|
|
3192
3231
|
...input.channel === void 0 ? {} : { channel: input.channel },
|
|
3193
3232
|
proxy: input.proxy,
|
|
3194
3233
|
...input.coreSource === void 0 ? {} : { coreSource: input.coreSource },
|
|
3195
|
-
...input.coreTag === void 0 ? {} : { coreTag: input.coreTag }
|
|
3234
|
+
...input.coreTag === void 0 ? {} : { coreTag: input.coreTag },
|
|
3235
|
+
...input.forced === true ? { forced: true } : {}
|
|
3196
3236
|
};
|
|
3197
3237
|
}
|
|
3198
3238
|
failureSummary(input) {
|
|
@@ -3223,7 +3263,8 @@ var Runner = class {
|
|
|
3223
3263
|
*/
|
|
3224
3264
|
capturePreview(input) {
|
|
3225
3265
|
const { outcome, settings, date, period, id } = input;
|
|
3226
|
-
if (!outcome.ok || outcome.dryRun ||
|
|
3266
|
+
if (!outcome.ok || outcome.dryRun || date === void 0) return void 0;
|
|
3267
|
+
if (outcome.skipped && input.force !== true) return void 0;
|
|
3227
3268
|
const skip = (reason, extra = {}) => {
|
|
3228
3269
|
this.deps.logger?.("preview.skip", { id, reason, ...extra });
|
|
3229
3270
|
return void 0;
|
|
@@ -3294,6 +3335,7 @@ var Runner = class {
|
|
|
3294
3335
|
...summary.error.reason === void 0 ? {} : { errorReason: summary.error.reason }
|
|
3295
3336
|
},
|
|
3296
3337
|
...summary.skipReason === void 0 ? {} : { skipReason: summary.skipReason },
|
|
3338
|
+
...summary.forced === true ? { forced: true } : {},
|
|
3297
3339
|
durationMs: summary.durationMs,
|
|
3298
3340
|
files: summary.files,
|
|
3299
3341
|
...summary.date === void 0 ? {} : { date: summary.date },
|
|
@@ -3319,7 +3361,9 @@ var Runner = class {
|
|
|
3319
3361
|
...summary.ok ? { lastSuccessAt: record.at } : {},
|
|
3320
3362
|
...summary.ok && summary.period !== void 0 ? { periodSuccess } : {},
|
|
3321
3363
|
...summary.ok && summary.prUrl !== void 0 ? { pendingPr: { url: summary.prUrl, createdAt: record.at, ...summary.date === void 0 ? {} : { date: summary.date } } } : {},
|
|
3322
|
-
|
|
3364
|
+
// 幂等:内容未变(skipped)通常不刷新 lastDigest;但显式 force 时即便 core 判定
|
|
3365
|
+
// unchanged,也要把本次作为最新展示(contentHash 仍是真实 hash,不伪造)。
|
|
3366
|
+
...summary.ok && summary.contentHash !== void 0 && (!summary.skipped || summary.forced === true) ? {
|
|
3323
3367
|
lastDigest: {
|
|
3324
3368
|
date: summary.date ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
|
|
3325
3369
|
contentHash: summary.contentHash,
|
|
@@ -4060,6 +4104,7 @@ async function dispatch(method, pathname, url, request, deps) {
|
|
|
4060
4104
|
const base = {
|
|
4061
4105
|
dryRun: body.dryRun === true,
|
|
4062
4106
|
...typeof body.date === "string" && body.date !== "" ? { date: body.date } : {},
|
|
4107
|
+
...body.force === true ? { force: true } : {},
|
|
4063
4108
|
trigger: "manual"
|
|
4064
4109
|
};
|
|
4065
4110
|
if (isPeriod(body.period)) {
|
|
@@ -4333,6 +4378,7 @@ var RUN_OUTPUT_SCHEMA = {
|
|
|
4333
4378
|
ok: { type: "boolean" },
|
|
4334
4379
|
skipped: { type: "boolean" },
|
|
4335
4380
|
dryRun: { type: "boolean" },
|
|
4381
|
+
forced: { type: "boolean" },
|
|
4336
4382
|
durationMs: { type: "number" },
|
|
4337
4383
|
coreVersion: { type: "string" },
|
|
4338
4384
|
files: { type: "number" },
|
|
@@ -4393,11 +4439,12 @@ function describeRecord(record) {
|
|
|
4393
4439
|
function createTrendingRunTool(runner) {
|
|
4394
4440
|
return {
|
|
4395
4441
|
name: "trending_run",
|
|
4396
|
-
description: "\u6267\u884C GitHub \u8D8B\u52BF\u699C\u5355\uFF1A\u5B9A\u4F4D\u5E76\u63E1\u624B\u672C\u5730\u6838\u5FC3\uFF0Cspawn \u6838\u5FC3 run\uFF0C\u8FD4\u56DE\u7ED3\u6784\u5316\u6458\u8981\uFF08\u6587\u4EF6\u6570\u3001commit\u3001PR\u3001\u9519\u8BEF\u7801\uFF09\u3002\u7701\u7565 period \u65F6\u9ED8\u8BA4\u4EA7\u51FA\u65E5/\u5468/\u6708\u4E09\u699C\uFF08\u4F9D\u6B21\u8FD0\u884C\u4E09\u6B21\uFF0C\u8FD4\u56DE summaries\uFF09\u3002dryRun=true \u53EA\u6293\u53D6\u4E0E\u6E32\u67D3\u3001\u4E0D\u5199\u6587\u4EF6\u4E5F\u4E0D\u63D0\u4EA4\u3002\u540C\u65E5\u540C\u5185\u5BB9\u91CD\u8DD1\u4F1A\u8FD4\u56DE skipped=true\uFF08\u96F6\u65B0\u589E commit\uFF09\u3002",
|
|
4442
|
+
description: "\u6267\u884C GitHub \u8D8B\u52BF\u699C\u5355\uFF1A\u5B9A\u4F4D\u5E76\u63E1\u624B\u672C\u5730\u6838\u5FC3\uFF0Cspawn \u6838\u5FC3 run\uFF0C\u8FD4\u56DE\u7ED3\u6784\u5316\u6458\u8981\uFF08\u6587\u4EF6\u6570\u3001commit\u3001PR\u3001\u9519\u8BEF\u7801\uFF09\u3002\u7701\u7565 period \u65F6\u9ED8\u8BA4\u4EA7\u51FA\u65E5/\u5468/\u6708\u4E09\u699C\uFF08\u4F9D\u6B21\u8FD0\u884C\u4E09\u6B21\uFF0C\u8FD4\u56DE summaries\uFF09\u3002dryRun=true \u53EA\u6293\u53D6\u4E0E\u6E32\u67D3\u3001\u4E0D\u5199\u6587\u4EF6\u4E5F\u4E0D\u63D0\u4EA4\u3002force=true \u5FFD\u7565\u6458\u8981\u7F13\u5B58\u3001\u5F3A\u5236\u91CD\u65B0\u751F\u6210\uFF08\u5185\u5BB9\u65E0\u53D8\u5316\u65F6\u4E0D\u65B0\u589E\u63D0\u4EA4\uFF0C\u4F46\u4F1A\u5237\u65B0\u9884\u89C8\uFF09\u3002\u540C\u65E5\u540C\u5185\u5BB9\u91CD\u8DD1\u4F1A\u8FD4\u56DE skipped=true\uFF08\u96F6\u65B0\u589E commit\uFF09\u3002",
|
|
4397
4443
|
parameters: {
|
|
4398
4444
|
dryRun: { type: "boolean", description: "\u53EA\u8BD5\u8DD1\uFF1A\u4E0D\u5199\u6587\u4EF6\u3001\u4E0D\u63D0\u4EA4\u3001\u4E0D\u5F00 PR" },
|
|
4399
4445
|
date: { type: "string", description: "\u6307\u5B9A\u65E5\u671F\uFF08YYYY-MM-DD\uFF09\uFF1B\u7701\u7565\u5219\u7528\u8C03\u5EA6\u65F6\u533A\u7684\u4ECA\u5929" },
|
|
4400
|
-
period: { type: "string", enum: ["daily", "weekly", "monthly"], description: "\u53EA\u8DD1\u6307\u5B9A\u5468\u671F\uFF1B\u7701\u7565\u5219\u9ED8\u8BA4\u4EA7\u51FA\u65E5/\u5468/\u6708\u4E09\u699C" }
|
|
4446
|
+
period: { type: "string", enum: ["daily", "weekly", "monthly"], description: "\u53EA\u8DD1\u6307\u5B9A\u5468\u671F\uFF1B\u7701\u7565\u5219\u9ED8\u8BA4\u4EA7\u51FA\u65E5/\u5468/\u6708\u4E09\u699C" },
|
|
4447
|
+
force: { type: "boolean", description: "\u5FFD\u7565\u6458\u8981\u7F13\u5B58\u3001\u5F3A\u5236\u91CD\u65B0\u751F\u6210\uFF08\u5185\u5BB9\u65E0\u53D8\u5316\u65F6\u4E0D\u65B0\u589E\u63D0\u4EA4\uFF0C\u4F46\u4F1A\u5237\u65B0\u9884\u89C8\uFF09" }
|
|
4401
4448
|
},
|
|
4402
4449
|
output: {
|
|
4403
4450
|
schema: RUN_OUTPUT_SCHEMA,
|
|
@@ -4408,13 +4455,14 @@ function createTrendingRunTool(runner) {
|
|
|
4408
4455
|
const base = {
|
|
4409
4456
|
dryRun: args.dryRun === true,
|
|
4410
4457
|
...typeof args.date === "string" && args.date !== "" ? { date: args.date } : {},
|
|
4458
|
+
...args.force === true ? { force: true } : {},
|
|
4411
4459
|
trigger: "tool"
|
|
4412
4460
|
};
|
|
4413
4461
|
const summaries = isPeriod(args.period) ? [await runner.run({ ...base, period: args.period })] : await runner.runMany(base);
|
|
4414
4462
|
const lines = [];
|
|
4415
4463
|
for (const summary of summaries) {
|
|
4416
4464
|
const periodLabel = summary.period ?? "\u2014";
|
|
4417
|
-
const head = summary.ok ? summary.skipped ? "\u65E0\u53D8\u66F4\uFF08skipped\uFF09" : summary.dryRun ? "\u8BD5\u8DD1\u5B8C\u6210" : "\u8FD0\u884C\u6210\u529F" : `\u8FD0\u884C\u5931\u8D25\uFF1A${summary.error?.code ?? "INTERNAL"}`;
|
|
4465
|
+
const head = summary.ok ? summary.skipped ? summary.forced ? "\u65E0\u53D8\u5316\uFF08\u5F3A\u5236\u91CD\u8DD1\uFF0C\u672A\u65B0\u589E\u63D0\u4EA4\uFF09" : "\u65E0\u53D8\u66F4\uFF08skipped\uFF09" : summary.dryRun ? "\u8BD5\u8DD1\u5B8C\u6210" : "\u8FD0\u884C\u6210\u529F" : `\u8FD0\u884C\u5931\u8D25\uFF1A${summary.error?.code ?? "INTERNAL"}`;
|
|
4418
4466
|
lines.push(`${summary.ok ? "\u2713" : "\u2717"} [${periodLabel}] ${head}`);
|
|
4419
4467
|
lines.push(`\xB7 \u6838\u5FC3 ${summary.coreVersion || "(\u672A\u77E5)"} \xB7 ${formatDuration(summary.durationMs)} \xB7 ${summary.files} \u4E2A\u6587\u4EF6`);
|
|
4420
4468
|
if (summary.tokens !== void 0) {
|
|
@@ -4444,6 +4492,7 @@ function createTrendingRunTool(runner) {
|
|
|
4444
4492
|
ok: summary.ok,
|
|
4445
4493
|
skipped: summary.skipped,
|
|
4446
4494
|
dryRun: summary.dryRun,
|
|
4495
|
+
...summary.forced === true ? { forced: true } : {},
|
|
4447
4496
|
durationMs: summary.durationMs,
|
|
4448
4497
|
files: summary.files,
|
|
4449
4498
|
...summary.tokens === void 0 ? {} : { tokens: summary.tokens },
|
|
@@ -4455,6 +4504,7 @@ function createTrendingRunTool(runner) {
|
|
|
4455
4504
|
id: primary?.id,
|
|
4456
4505
|
skipped: summaries.every((summary) => summary.skipped),
|
|
4457
4506
|
dryRun: base.dryRun,
|
|
4507
|
+
...base.force === true ? { forced: true } : {},
|
|
4458
4508
|
durationMs: summaries.reduce((sum, summary) => sum + summary.durationMs, 0),
|
|
4459
4509
|
files: summaries.reduce((sum, summary) => sum + summary.files, 0),
|
|
4460
4510
|
...(() => {
|
|
@@ -4530,6 +4580,7 @@ export {
|
|
|
4530
4580
|
Scheduler,
|
|
4531
4581
|
schedule_exports,
|
|
4532
4582
|
subscribe_exports,
|
|
4583
|
+
version_exports,
|
|
4533
4584
|
Runner,
|
|
4534
4585
|
runner_exports,
|
|
4535
4586
|
readPluginInfo,
|
package/lib/index.js
CHANGED
package/lib/internal.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ErrorCode, FileArtifact, Usage, ReleasesReport, ErrorInfo, RunRequest, RunResult, State, StateRun, SubscriptionList } from '@morehao/trendradar-contract';
|
|
1
|
+
import { ErrorCode, FileArtifact, Usage, ReleasesReport, SubscriptionItem, SubscriptionDoc, SubscriptionStatus, ErrorInfo, RunRequest, RunResult, State, StateRun, SubscriptionList, SubscriptionVolume } from '@morehao/trendradar-contract';
|
|
2
2
|
import http from 'node:http';
|
|
3
3
|
import { Updater, PluginMeta, Logger } from '@morehao/dsh-plugin-kit/update';
|
|
4
4
|
|
|
@@ -112,40 +112,6 @@ interface RunOutcome {
|
|
|
112
112
|
durationMs: number;
|
|
113
113
|
coreVersion: string;
|
|
114
114
|
}
|
|
115
|
-
/**
|
|
116
|
-
* 契约 0.4.0(核心 0.7.0)新增的 wire 类型。
|
|
117
|
-
*
|
|
118
|
-
* 契约包尚未发布:npm 上的 `@morehao/trendradar-contract` 还停在 0.3.0,
|
|
119
|
-
* 因此这三块按 `contract/schema/releases.v2.json` 原样在本地声明,等 0.4.0 发布后
|
|
120
|
-
* 改回 `@morehao/trendradar-contract` 的 `import type`。除这里列出的字段外,
|
|
121
|
-
* 不补任何契约里没有的东西——本地声明只是「包还没发」的临时载体,不是第二份契约。
|
|
122
|
-
*/
|
|
123
|
-
type SubscriptionStatus = 'baseline' | 'ok' | 'no_change' | 'rate_limited' | 'failed';
|
|
124
|
-
/** 订阅表的一行:只放列表展示需要的字段,正文在 `SubscriptionDoc` 里(首屏体积预算)。 */
|
|
125
|
-
interface SubscriptionItem {
|
|
126
|
-
fullName: string;
|
|
127
|
-
url?: string;
|
|
128
|
-
latestTag?: string;
|
|
129
|
-
latestSummaryAt?: string;
|
|
130
|
-
lastCheckedAt?: string;
|
|
131
|
-
status: SubscriptionStatus;
|
|
132
|
-
}
|
|
133
|
-
/** 发版文档的一卷:每册都带两位序号,index N 是 `<repo>-0N.md`(第 1 册是 `-01`)。 */
|
|
134
|
-
interface SubscriptionVolume {
|
|
135
|
-
index: number;
|
|
136
|
-
file: string;
|
|
137
|
-
from?: string;
|
|
138
|
-
to?: string;
|
|
139
|
-
lines?: number;
|
|
140
|
-
}
|
|
141
|
-
/** 一个仓库某卷的发版文档;`markdown` 是文件原文,面板逐字渲染、不再二次摘要。 */
|
|
142
|
-
interface SubscriptionDoc {
|
|
143
|
-
fullName: string;
|
|
144
|
-
volume: number;
|
|
145
|
-
volumes?: SubscriptionVolume[];
|
|
146
|
-
updatedAt?: string;
|
|
147
|
-
markdown: string;
|
|
148
|
-
}
|
|
149
115
|
declare function isSubscriptionStatus(value: unknown): value is SubscriptionStatus;
|
|
150
116
|
/**
|
|
151
117
|
* `SubscriptionDoc` 的运行时守卫:缺 fullName/volume/markdown 的负载宁可抛
|
|
@@ -221,11 +187,11 @@ declare const ipc_State: typeof State;
|
|
|
221
187
|
declare const ipc_StateRun: typeof StateRun;
|
|
222
188
|
type ipc_SubscribeAction = SubscribeAction;
|
|
223
189
|
type ipc_SubscribeOutcome = SubscribeOutcome;
|
|
224
|
-
|
|
225
|
-
|
|
190
|
+
declare const ipc_SubscriptionDoc: typeof SubscriptionDoc;
|
|
191
|
+
declare const ipc_SubscriptionItem: typeof SubscriptionItem;
|
|
226
192
|
declare const ipc_SubscriptionList: typeof SubscriptionList;
|
|
227
|
-
|
|
228
|
-
|
|
193
|
+
declare const ipc_SubscriptionStatus: typeof SubscriptionStatus;
|
|
194
|
+
declare const ipc_SubscriptionVolume: typeof SubscriptionVolume;
|
|
229
195
|
declare const ipc_Usage: typeof Usage;
|
|
230
196
|
type ipc_VersionInfo = VersionInfo;
|
|
231
197
|
declare const ipc_isSubscriptionDoc: typeof isSubscriptionDoc;
|
|
@@ -236,7 +202,7 @@ declare const ipc_parseRunResult: typeof parseRunResult;
|
|
|
236
202
|
declare const ipc_parseSubscribeResult: typeof parseSubscribeResult;
|
|
237
203
|
declare const ipc_parseVersionInfo: typeof parseVersionInfo;
|
|
238
204
|
declare namespace ipc {
|
|
239
|
-
export { ipc_ErrorCode as ErrorCode, ipc_ErrorInfo as ErrorInfo, ipc_FileArtifact as FileArtifact, ipc_IPC_SCHEMA_VERSION as IPC_SCHEMA_VERSION, ipc_IpcError as IpcError, type ipc_ParseRunOptions as ParseRunOptions, ipc_ReleasesReport as ReleasesReport, type ipc_RunError as RunError, type ipc_RunOutcome as RunOutcome, ipc_RunRequest as RunRequest, ipc_RunResult as RunResult, ipc_SUPPORTED_CONTRACT_MAJOR as SUPPORTED_CONTRACT_MAJOR, ipc_SUPPORTED_DIGEST_SCHEMA as SUPPORTED_DIGEST_SCHEMA, ipc_State as State, ipc_StateRun as StateRun, type ipc_SubscribeAction as SubscribeAction, type ipc_SubscribeOutcome as SubscribeOutcome,
|
|
205
|
+
export { ipc_ErrorCode as ErrorCode, ipc_ErrorInfo as ErrorInfo, ipc_FileArtifact as FileArtifact, ipc_IPC_SCHEMA_VERSION as IPC_SCHEMA_VERSION, ipc_IpcError as IpcError, type ipc_ParseRunOptions as ParseRunOptions, ipc_ReleasesReport as ReleasesReport, type ipc_RunError as RunError, type ipc_RunOutcome as RunOutcome, ipc_RunRequest as RunRequest, ipc_RunResult as RunResult, ipc_SUPPORTED_CONTRACT_MAJOR as SUPPORTED_CONTRACT_MAJOR, ipc_SUPPORTED_DIGEST_SCHEMA as SUPPORTED_DIGEST_SCHEMA, ipc_State as State, ipc_StateRun as StateRun, type ipc_SubscribeAction as SubscribeAction, type ipc_SubscribeOutcome as SubscribeOutcome, ipc_SubscriptionDoc as SubscriptionDoc, ipc_SubscriptionItem as SubscriptionItem, ipc_SubscriptionList as SubscriptionList, ipc_SubscriptionStatus as SubscriptionStatus, ipc_SubscriptionVolume as SubscriptionVolume, ipc_Usage as Usage, type ipc_VersionInfo as VersionInfo, ipc_isSubscriptionDoc as isSubscriptionDoc, ipc_isSubscriptionStatus as isSubscriptionStatus, ipc_isVersionInfo as isVersionInfo, ipc_parseJsonObject as parseJsonObject, ipc_parseRunResult as parseRunResult, ipc_parseSubscribeResult as parseSubscribeResult, ipc_parseVersionInfo as parseVersionInfo };
|
|
240
206
|
}
|
|
241
207
|
|
|
242
208
|
type Provider = string;
|
|
@@ -589,6 +555,8 @@ interface RunRecord {
|
|
|
589
555
|
errorReason?: string;
|
|
590
556
|
/** 跳过原因:merged / pr-closed / unchanged。 */
|
|
591
557
|
skipReason?: string;
|
|
558
|
+
/** 本次是显式「强制重跑(忽略缓存)」;调度永不置位。仅用于展示与区分幂等。 */
|
|
559
|
+
forced?: boolean;
|
|
592
560
|
durationMs: number;
|
|
593
561
|
files: number;
|
|
594
562
|
/** 运行所属的调度时区日期(YYYY-MM-DD);旧记录可能没有。 */
|
|
@@ -1007,6 +975,8 @@ interface RunCoreOptions {
|
|
|
1007
975
|
dryRun: boolean;
|
|
1008
976
|
/** 谁触发的运行:核心用它在定时运行时尊重「人工关闭的 PR」。 */
|
|
1009
977
|
trigger?: 'manual' | 'schedule';
|
|
978
|
+
/** 忽略摘要缓存、强制重新生成(核心 `run --force`);不影响 append-only 提交判断。 */
|
|
979
|
+
force?: boolean;
|
|
1010
980
|
/** 回环代理地址:覆盖配置里的 model.baseURL(代理模式专用)。 */
|
|
1011
981
|
baseURLOverride?: string;
|
|
1012
982
|
/**
|
|
@@ -1033,6 +1003,7 @@ declare function buildCoreArgs(channelPath: string, options: {
|
|
|
1033
1003
|
date?: string;
|
|
1034
1004
|
period?: Period;
|
|
1035
1005
|
stages?: string[];
|
|
1006
|
+
force?: boolean;
|
|
1036
1007
|
}): string[];
|
|
1037
1008
|
declare function runCore(options: RunCoreOptions): Promise<RunCoreResult>;
|
|
1038
1009
|
|
|
@@ -1470,6 +1441,11 @@ declare namespace pendingPr {
|
|
|
1470
1441
|
export { type pendingPr_CheckPendingPrOptions as CheckPendingPrOptions, type pendingPr_ParsedPullUrl as ParsedPullUrl, type pendingPr_PendingPrStatus as PendingPrStatus, type pendingPr_PullState as PullState, pendingPr_checkPendingPr as checkPendingPr, pendingPr_clearPendingPrCache as clearPendingPrCache, pendingPr_parsePullUrl as parsePullUrl };
|
|
1471
1442
|
}
|
|
1472
1443
|
|
|
1444
|
+
/**
|
|
1445
|
+
* 支持 `run --force`(忽略摘要缓存重新生成)的最低核心版本。
|
|
1446
|
+
* 与 core patch 发版 `0.7.1` 对齐;`dsh.core.version` 应 >= 它,dev override 指向更旧核心时靠闸门降级。
|
|
1447
|
+
*/
|
|
1448
|
+
declare const FORCE_MIN_CORE_VERSION = "0.7.1";
|
|
1473
1449
|
interface RunSummary {
|
|
1474
1450
|
id: string;
|
|
1475
1451
|
ok: boolean;
|
|
@@ -1488,6 +1464,8 @@ interface RunSummary {
|
|
|
1488
1464
|
preview?: PreviewMeta;
|
|
1489
1465
|
/** 核心给出的跳过原因(merged / pr-closed / unchanged)。 */
|
|
1490
1466
|
skipReason?: string;
|
|
1467
|
+
/** 本次是显式「强制重跑(忽略缓存)」;调度永不置位。 */
|
|
1468
|
+
forced?: boolean;
|
|
1491
1469
|
error?: {
|
|
1492
1470
|
code: string;
|
|
1493
1471
|
message: string;
|
|
@@ -1515,6 +1493,8 @@ interface RunRequestOptions {
|
|
|
1515
1493
|
date?: string;
|
|
1516
1494
|
/** 标的周期;缺省取 settings.trending.since(手动/工具运行)。 */
|
|
1517
1495
|
period?: Period;
|
|
1496
|
+
/** 强制重跑:忽略摘要缓存、重新生成(核心 `run --force`);仅手动/工具触发,调度永不设置。 */
|
|
1497
|
+
force?: boolean;
|
|
1518
1498
|
trigger: 'manual' | 'schedule' | 'tool';
|
|
1519
1499
|
}
|
|
1520
1500
|
interface RunnerDeps {
|
|
@@ -1611,6 +1591,7 @@ declare class Runner {
|
|
|
1611
1591
|
coreStatus(fresh?: boolean): Promise<CoreStatus>;
|
|
1612
1592
|
}
|
|
1613
1593
|
|
|
1594
|
+
declare const runner_FORCE_MIN_CORE_VERSION: typeof FORCE_MIN_CORE_VERSION;
|
|
1614
1595
|
type runner_RunRequestOptions = RunRequestOptions;
|
|
1615
1596
|
type runner_RunSummary = RunSummary;
|
|
1616
1597
|
type runner_Runner = Runner;
|
|
@@ -1620,7 +1601,7 @@ declare const runner_isoWeekName: typeof isoWeekName;
|
|
|
1620
1601
|
declare const runner_periodFileBase: typeof periodFileBase;
|
|
1621
1602
|
declare const runner_projectUsage: typeof projectUsage;
|
|
1622
1603
|
declare namespace runner {
|
|
1623
|
-
export { type runner_RunRequestOptions as RunRequestOptions, type runner_RunSummary as RunSummary, runner_Runner as Runner, type runner_RunnerDeps as RunnerDeps, runner_isoWeekName as isoWeekName, runner_periodFileBase as periodFileBase, runner_projectUsage as projectUsage };
|
|
1604
|
+
export { runner_FORCE_MIN_CORE_VERSION as FORCE_MIN_CORE_VERSION, type runner_RunRequestOptions as RunRequestOptions, type runner_RunSummary as RunSummary, runner_Runner as Runner, type runner_RunnerDeps as RunnerDeps, runner_isoWeekName as isoWeekName, runner_periodFileBase as periodFileBase, runner_projectUsage as projectUsage };
|
|
1624
1605
|
}
|
|
1625
1606
|
|
|
1626
1607
|
/** 订阅命令超时:核心只做一次 GitHub 请求/本地文件读写,8 s 足够。 */
|
|
@@ -1803,6 +1784,23 @@ declare namespace schedule {
|
|
|
1803
1784
|
export { schedule_RELEASE_CATCH_UP_MINUTES as RELEASE_CATCH_UP_MINUTES, type schedule_ReleaseScheduleConfig as ReleaseScheduleConfig, type schedule_ScheduleConfig as ScheduleConfig, schedule_Scheduler as Scheduler, type schedule_SchedulerDeps as SchedulerDeps, schedule_daysInMonth as daysInMonth, schedule_isDue as isDue, schedule_isPeriodTriggerDay as isPeriodTriggerDay, schedule_isReleaseDue as isReleaseDue, schedule_isoWeekKey as isoWeekKey, schedule_nextOccurrence as nextOccurrence, schedule_nextOccurrenceFor as nextOccurrenceFor, schedule_nextReleaseOccurrence as nextReleaseOccurrence, schedule_parseClock as parseClock, schedule_zonedDateString as zonedDateString, schedule_zonedTimeToUtc as zonedTimeToUtc };
|
|
1804
1785
|
}
|
|
1805
1786
|
|
|
1787
|
+
/**
|
|
1788
|
+
* 版本比较:只用于「核心是否足够新到支持某个 CLI flag」这类能力闸门。
|
|
1789
|
+
*
|
|
1790
|
+
* 核心的 `version --json` 只给 `x.y.z`(偶带预发布后缀),这里按三段数字比较,
|
|
1791
|
+
* 后缀忽略。不做完整 semver 区间——项目只需要「>= 阈值」这一种判断,够用且不易错。
|
|
1792
|
+
*/
|
|
1793
|
+
/**
|
|
1794
|
+
* `a >= b` 时返回 true。任一方不可解析时返回 false(保守:当作「不满足」,
|
|
1795
|
+
* 让调用方降级为不带新 flag 的行为,避免向旧核心传未知参数)。
|
|
1796
|
+
*/
|
|
1797
|
+
declare function versionAtLeast(a: string, b: string): boolean;
|
|
1798
|
+
|
|
1799
|
+
declare const version_versionAtLeast: typeof versionAtLeast;
|
|
1800
|
+
declare namespace version {
|
|
1801
|
+
export { version_versionAtLeast as versionAtLeast };
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1806
1804
|
/**
|
|
1807
1805
|
* Host HTTP 面:`/api/morehao/github-trending/*`。
|
|
1808
1806
|
*
|
|
@@ -1909,6 +1907,10 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
1909
1907
|
enum: string[];
|
|
1910
1908
|
description: string;
|
|
1911
1909
|
};
|
|
1910
|
+
force: {
|
|
1911
|
+
type: string;
|
|
1912
|
+
description: string;
|
|
1913
|
+
};
|
|
1912
1914
|
};
|
|
1913
1915
|
output: {
|
|
1914
1916
|
schema: {
|
|
@@ -1927,6 +1929,9 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
1927
1929
|
readonly dryRun: {
|
|
1928
1930
|
readonly type: "boolean";
|
|
1929
1931
|
};
|
|
1932
|
+
readonly forced: {
|
|
1933
|
+
readonly type: "boolean";
|
|
1934
|
+
};
|
|
1930
1935
|
readonly durationMs: {
|
|
1931
1936
|
readonly type: "number";
|
|
1932
1937
|
};
|
|
@@ -1977,6 +1982,7 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
1977
1982
|
dryRun?: boolean;
|
|
1978
1983
|
date?: string;
|
|
1979
1984
|
period?: string;
|
|
1985
|
+
force?: boolean;
|
|
1980
1986
|
}, exec?: {
|
|
1981
1987
|
signal?: AbortSignal;
|
|
1982
1988
|
}): Promise<{
|
|
@@ -1986,6 +1992,9 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
1986
1992
|
errorHint?: string | undefined;
|
|
1987
1993
|
warnings: string[];
|
|
1988
1994
|
tokens: number;
|
|
1995
|
+
durationMs: number;
|
|
1996
|
+
files: number;
|
|
1997
|
+
forced?: boolean | undefined;
|
|
1989
1998
|
ok: boolean;
|
|
1990
1999
|
summaries: {
|
|
1991
2000
|
errorCode?: string | undefined;
|
|
@@ -1994,19 +2003,18 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
1994
2003
|
branch?: string | undefined;
|
|
1995
2004
|
releases?: ReleasesSummary | undefined;
|
|
1996
2005
|
tokens?: number | undefined;
|
|
2006
|
+
durationMs: number;
|
|
2007
|
+
files: number;
|
|
2008
|
+
forced?: boolean | undefined;
|
|
1997
2009
|
id: string;
|
|
1998
2010
|
period: Period | undefined;
|
|
1999
2011
|
ok: boolean;
|
|
2000
2012
|
skipped: boolean;
|
|
2001
2013
|
dryRun: boolean;
|
|
2002
|
-
durationMs: number;
|
|
2003
|
-
files: number;
|
|
2004
2014
|
}[];
|
|
2005
2015
|
id: string | undefined;
|
|
2006
2016
|
skipped: boolean;
|
|
2007
2017
|
dryRun: boolean;
|
|
2008
|
-
durationMs: number;
|
|
2009
|
-
files: number;
|
|
2010
2018
|
} | {
|
|
2011
2019
|
markdown: string;
|
|
2012
2020
|
errorCode?: string | undefined;
|
|
@@ -2014,6 +2022,9 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
2014
2022
|
errorHint?: string | undefined;
|
|
2015
2023
|
warnings: string[];
|
|
2016
2024
|
tokens?: undefined;
|
|
2025
|
+
durationMs: number;
|
|
2026
|
+
files: number;
|
|
2027
|
+
forced?: boolean | undefined;
|
|
2017
2028
|
ok: boolean;
|
|
2018
2029
|
summaries: {
|
|
2019
2030
|
errorCode?: string | undefined;
|
|
@@ -2022,19 +2033,18 @@ declare function createTrendingRunTool(runner: Runner): {
|
|
|
2022
2033
|
branch?: string | undefined;
|
|
2023
2034
|
releases?: ReleasesSummary | undefined;
|
|
2024
2035
|
tokens?: number | undefined;
|
|
2036
|
+
durationMs: number;
|
|
2037
|
+
files: number;
|
|
2038
|
+
forced?: boolean | undefined;
|
|
2025
2039
|
id: string;
|
|
2026
2040
|
period: Period | undefined;
|
|
2027
2041
|
ok: boolean;
|
|
2028
2042
|
skipped: boolean;
|
|
2029
2043
|
dryRun: boolean;
|
|
2030
|
-
durationMs: number;
|
|
2031
|
-
files: number;
|
|
2032
2044
|
}[];
|
|
2033
2045
|
id: string | undefined;
|
|
2034
2046
|
skipped: boolean;
|
|
2035
2047
|
dryRun: boolean;
|
|
2036
|
-
durationMs: number;
|
|
2037
|
-
files: number;
|
|
2038
2048
|
}>;
|
|
2039
2049
|
};
|
|
2040
2050
|
declare function createTrendingHistoryTool(store: Store, scheduler: Scheduler): {
|
|
@@ -2138,4 +2148,4 @@ declare namespace tools {
|
|
|
2138
2148
|
export { tools_createTrendingHistoryTool as createTrendingHistoryTool, tools_createTrendingRunTool as createTrendingRunTool };
|
|
2139
2149
|
}
|
|
2140
2150
|
|
|
2141
|
-
export { channel, config, core, credentials, errors, exec, github, handshake$1 as handshake, importCli, ipc, locate, paths, pendingPr, pluginInfo, preflight, proxy, quickfill, release, repo, routes, run, runner, schedule, state, subscribe, tools, update as updateService };
|
|
2151
|
+
export { channel, config, core, credentials, errors, exec, github, handshake$1 as handshake, importCli, ipc, locate, paths, pendingPr, pluginInfo, preflight, proxy, quickfill, release, repo, routes, run, runner, schedule, state, subscribe, tools, update as updateService, version };
|
package/lib/internal.js
CHANGED
|
@@ -24,8 +24,9 @@ import {
|
|
|
24
24
|
state_exports,
|
|
25
25
|
subscribe_exports,
|
|
26
26
|
tools_exports,
|
|
27
|
-
update_exports
|
|
28
|
-
|
|
27
|
+
update_exports,
|
|
28
|
+
version_exports
|
|
29
|
+
} from "./chunk-VF6DOIQQ.js";
|
|
29
30
|
import {
|
|
30
31
|
exec_exports
|
|
31
32
|
} from "./chunk-R7BK7SJK.js";
|
|
@@ -56,5 +57,6 @@ export {
|
|
|
56
57
|
state_exports as state,
|
|
57
58
|
subscribe_exports as subscribe,
|
|
58
59
|
tools_exports as tools,
|
|
59
|
-
update_exports as updateService
|
|
60
|
+
update_exports as updateService,
|
|
61
|
+
version_exports as version
|
|
60
62
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morehao/dsh-github-trending",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "GitHub 趋势日报插件:每天定时 spawn 本地 trendradar 核心,抓取 Trending、生成中文简介与总结,提交到你的仓库并自动合并 PR。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@morehao/dsh-plugin-kit": "0.1.0",
|
|
54
|
-
"@morehao/trendradar-contract": "0.
|
|
54
|
+
"@morehao/trendradar-contract": "0.4.0"
|
|
55
55
|
},
|
|
56
56
|
"dsh": {
|
|
57
57
|
"bundle": {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
"core": {
|
|
61
61
|
"repo": "morehao/trendradar",
|
|
62
|
-
"version": "0.7.
|
|
62
|
+
"version": "0.7.1"
|
|
63
63
|
},
|
|
64
64
|
"client": {
|
|
65
65
|
"platform": "web",
|