@botharness/core 1.0.1 → 1.0.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/CHANGELOG.md +659 -0
- package/CHANGELOG.zh.md +659 -0
- package/dist/index.d.mts +47 -0
- package/dist/index.mjs +384 -7
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -10832,6 +10832,48 @@ interface MarketplaceClient {
|
|
|
10832
10832
|
}>>;
|
|
10833
10833
|
}
|
|
10834
10834
|
//#endregion
|
|
10835
|
+
//#region packages/core/src/release/notes.d.ts
|
|
10836
|
+
interface LocalizedText {
|
|
10837
|
+
en: string;
|
|
10838
|
+
zh: string;
|
|
10839
|
+
}
|
|
10840
|
+
interface ReleaseNoteSection {
|
|
10841
|
+
name: string;
|
|
10842
|
+
entries: LocalizedText[];
|
|
10843
|
+
}
|
|
10844
|
+
interface ReleaseNote {
|
|
10845
|
+
version: string;
|
|
10846
|
+
date: string;
|
|
10847
|
+
summary: LocalizedText;
|
|
10848
|
+
sections: ReleaseNoteSection[];
|
|
10849
|
+
}
|
|
10850
|
+
//#endregion
|
|
10851
|
+
//#region packages/core/src/release/service.d.ts
|
|
10852
|
+
interface ReleaseInfo {
|
|
10853
|
+
version: string;
|
|
10854
|
+
releases: ReleaseNote[];
|
|
10855
|
+
}
|
|
10856
|
+
type ReleaseUpdate = {
|
|
10857
|
+
status: 'development';
|
|
10858
|
+
current: string;
|
|
10859
|
+
} | {
|
|
10860
|
+
status: 'unavailable';
|
|
10861
|
+
current: string;
|
|
10862
|
+
} | {
|
|
10863
|
+
status: 'current';
|
|
10864
|
+
current: string;
|
|
10865
|
+
latest: string;
|
|
10866
|
+
} | {
|
|
10867
|
+
status: 'available';
|
|
10868
|
+
current: string;
|
|
10869
|
+
latest: string;
|
|
10870
|
+
releases: ReleaseNote[];
|
|
10871
|
+
};
|
|
10872
|
+
interface ReleaseService {
|
|
10873
|
+
info(since?: string): ReleaseInfo;
|
|
10874
|
+
update(): Promise<ReleaseUpdate>;
|
|
10875
|
+
}
|
|
10876
|
+
//#endregion
|
|
10835
10877
|
//#region packages/core/src/channels/profile-activity.d.ts
|
|
10836
10878
|
interface GroupProfileActivityDay {
|
|
10837
10879
|
day: string;
|
|
@@ -11363,6 +11405,8 @@ interface BridgeMethods {
|
|
|
11363
11405
|
marketplaceReport(payload: unknown): Promise<BridgeResult<{
|
|
11364
11406
|
received: true;
|
|
11365
11407
|
}>>;
|
|
11408
|
+
releaseInfo(payload: unknown): BridgeResult<ReleaseInfo>;
|
|
11409
|
+
releaseUpdate(): Promise<BridgeResult<ReleaseUpdate>>;
|
|
11366
11410
|
}
|
|
11367
11411
|
interface BridgeMethodsDeps {
|
|
11368
11412
|
warn?: (message: string) => void;
|
|
@@ -11403,6 +11447,7 @@ interface BridgeMethodsDeps {
|
|
|
11403
11447
|
};
|
|
11404
11448
|
createBotId?: () => string;
|
|
11405
11449
|
marketplace?: MarketplaceClient;
|
|
11450
|
+
release?: ReleaseService;
|
|
11406
11451
|
}
|
|
11407
11452
|
export declare function createBridgeMethods(deps: BridgeMethodsDeps): BridgeMethods;
|
|
11408
11453
|
//#endregion
|
|
@@ -11768,6 +11813,8 @@ export declare class BotharnessBridgeService extends TypertRemoteService {
|
|
|
11768
11813
|
}>;
|
|
11769
11814
|
marketplaceTopics(): Promise<MarketplaceTopic[]>;
|
|
11770
11815
|
marketplaceDetail(id: string): Promise<MarketplaceDetail>;
|
|
11816
|
+
releaseInfo(since?: string): Promise<ReleaseInfo>;
|
|
11817
|
+
releaseUpdate(): Promise<ReleaseUpdate>;
|
|
11771
11818
|
}
|
|
11772
11819
|
export declare function registerBridge(ctx: Context, methods: BridgeMethods): BotharnessBridgeService;
|
|
11773
11820
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -5045,7 +5045,7 @@ const initializer = (inst, issues) => {
|
|
|
5045
5045
|
const ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, void 0, { Parent: Error });
|
|
5046
5046
|
//#endregion
|
|
5047
5047
|
//#region node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/parse.js
|
|
5048
|
-
const parse$
|
|
5048
|
+
const parse$2 = /* @__PURE__ */ _parse(ZodRealError);
|
|
5049
5049
|
const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
5050
5050
|
const safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
5051
5051
|
const safeParseAsync = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
@@ -5177,7 +5177,7 @@ const ZodType = /*@__PURE__*/ $constructor("ZodType", (inst, def) => {
|
|
|
5177
5177
|
own(this, "~standard", value);
|
|
5178
5178
|
},
|
|
5179
5179
|
parse: function _parse(data, params) {
|
|
5180
|
-
return parse$
|
|
5180
|
+
return parse$2(this, data, params, { callee: _parse });
|
|
5181
5181
|
},
|
|
5182
5182
|
parseAsync: async function _parseAsync(data, params) {
|
|
5183
5183
|
return await parseAsync(this, data, params, { callee: _parseAsync });
|
|
@@ -7895,7 +7895,7 @@ function createInboundMessaging(options) {
|
|
|
7895
7895
|
const assertCurrent = () => {
|
|
7896
7896
|
if (!valid(grant(value.id)) || grant(value.id).revision !== value.revision || providers.get(value.providerId) !== entry) throw new MessagingError("source-unavailable");
|
|
7897
7897
|
};
|
|
7898
|
-
const audit = (record) =>
|
|
7898
|
+
const audit = (record) => transaction((db) => {
|
|
7899
7899
|
assertCurrent();
|
|
7900
7900
|
const row = db.prepare("SELECT payload_json FROM source_events WHERE source_event_id = ?").get(sourceEventId);
|
|
7901
7901
|
const payload = JSON.parse(row.payload_json);
|
|
@@ -8009,7 +8009,7 @@ function createInboundMessaging(options) {
|
|
|
8009
8009
|
});
|
|
8010
8010
|
result.nextCursor = key;
|
|
8011
8011
|
}
|
|
8012
|
-
|
|
8012
|
+
transaction((db) => {
|
|
8013
8013
|
signal.throwIfAborted();
|
|
8014
8014
|
assertCurrent();
|
|
8015
8015
|
for (const event of page.events.slice(cursor?.offset ?? 0, offset)) persistSource(db, value, event);
|
|
@@ -21754,6 +21754,15 @@ function parseStringArray(source, key) {
|
|
|
21754
21754
|
}
|
|
21755
21755
|
const parseRoles$1 = (source) => parseStringArray(source, "roles");
|
|
21756
21756
|
const parseWorkspaces = (source) => parseStringArray(source, "workspaces");
|
|
21757
|
+
function releaseUnavailable() {
|
|
21758
|
+
return {
|
|
21759
|
+
ok: false,
|
|
21760
|
+
error: {
|
|
21761
|
+
code: "release-unavailable",
|
|
21762
|
+
message: "Release information is unavailable"
|
|
21763
|
+
}
|
|
21764
|
+
};
|
|
21765
|
+
}
|
|
21757
21766
|
function invalidInput(message) {
|
|
21758
21767
|
return {
|
|
21759
21768
|
ok: false,
|
|
@@ -22597,6 +22606,22 @@ function createBridgeMethods(deps) {
|
|
|
22597
22606
|
marketplaceTopics() {
|
|
22598
22607
|
return marketplaceCall((client) => client.topics());
|
|
22599
22608
|
},
|
|
22609
|
+
releaseInfo(payload) {
|
|
22610
|
+
if (deps.release === void 0) return releaseUnavailable();
|
|
22611
|
+
const since = asObject(payload)["since"];
|
|
22612
|
+
if (since !== void 0 && typeof since !== "string") return invalidInput("invalid since");
|
|
22613
|
+
return {
|
|
22614
|
+
ok: true,
|
|
22615
|
+
value: deps.release.info(since)
|
|
22616
|
+
};
|
|
22617
|
+
},
|
|
22618
|
+
async releaseUpdate() {
|
|
22619
|
+
if (deps.release === void 0) return releaseUnavailable();
|
|
22620
|
+
return {
|
|
22621
|
+
ok: true,
|
|
22622
|
+
value: await deps.release.update()
|
|
22623
|
+
};
|
|
22624
|
+
},
|
|
22600
22625
|
marketplaceDetail(payload) {
|
|
22601
22626
|
const id = asObject(payload)["id"];
|
|
22602
22627
|
if (typeof id !== "string" || id.trim().length === 0) return Promise.resolve(invalidInput("id is required"));
|
|
@@ -25054,6 +25079,12 @@ var BotharnessBridgeService = class extends TypertRemoteService {
|
|
|
25054
25079
|
async marketplaceDetail(id) {
|
|
25055
25080
|
return unwrapAsync(this.methods.marketplaceDetail({ id }));
|
|
25056
25081
|
}
|
|
25082
|
+
async releaseInfo(since) {
|
|
25083
|
+
return unwrap(this.methods.releaseInfo(since === void 0 ? {} : { since }));
|
|
25084
|
+
}
|
|
25085
|
+
async releaseUpdate() {
|
|
25086
|
+
return unwrapAsync(this.methods.releaseUpdate());
|
|
25087
|
+
}
|
|
25057
25088
|
};
|
|
25058
25089
|
markRemoteMethods(BotharnessBridgeService.prototype, [
|
|
25059
25090
|
"messagingDefaults",
|
|
@@ -25178,7 +25209,9 @@ markRemoteMethods(BotharnessBridgeService.prototype, [
|
|
|
25178
25209
|
"marketplaceTopics",
|
|
25179
25210
|
"marketplaceDetail",
|
|
25180
25211
|
"marketplaceChallenge",
|
|
25181
|
-
"marketplaceReport"
|
|
25212
|
+
"marketplaceReport",
|
|
25213
|
+
"releaseInfo",
|
|
25214
|
+
"releaseUpdate"
|
|
25182
25215
|
]);
|
|
25183
25216
|
function registerBridge(ctx, methods) {
|
|
25184
25217
|
return new BotharnessBridgeService(ctx, methods);
|
|
@@ -25206,7 +25239,7 @@ function parseChallenge(value) {
|
|
|
25206
25239
|
}
|
|
25207
25240
|
//#endregion
|
|
25208
25241
|
//#region packages/core/src/marketplace/client.ts
|
|
25209
|
-
const REQUEST_TIMEOUT_MS = 15e3;
|
|
25242
|
+
const REQUEST_TIMEOUT_MS$1 = 15e3;
|
|
25210
25243
|
function record$2(value) {
|
|
25211
25244
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
25212
25245
|
}
|
|
@@ -25306,7 +25339,7 @@ function parseReceipt(value) {
|
|
|
25306
25339
|
function createMarketplaceClient(options) {
|
|
25307
25340
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
25308
25341
|
const baseUrl = options.baseUrl.replace(/\/+$/u, "");
|
|
25309
|
-
const timeoutMs = options.timeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
25342
|
+
const timeoutMs = options.timeoutMs ?? REQUEST_TIMEOUT_MS$1;
|
|
25310
25343
|
const request = async (path, init, parse) => {
|
|
25311
25344
|
let response;
|
|
25312
25345
|
try {
|
|
@@ -25384,6 +25417,349 @@ function createMarketplaceClient(options) {
|
|
|
25384
25417
|
};
|
|
25385
25418
|
}
|
|
25386
25419
|
//#endregion
|
|
25420
|
+
//#region scripts/release-ledger.mjs
|
|
25421
|
+
const RELEASE_HEADING = /^## \[([^\]]+)](?: - (\d{4}-\d{2}-\d{2}))?$/;
|
|
25422
|
+
const SECTION_HEADING = /^### (.+)$/;
|
|
25423
|
+
const MARKDOWN_LINK$1 = /\[[^\]]*]\(([^)]+)\)/g;
|
|
25424
|
+
const RELEASE_PROVENANCE = /^- \*\*(Skill version|Verified against DSH|Upstream revision|Skill 版本|核验的 DSH 版本|上游 revision)(?::|:)\*\*\s+(.+)$/;
|
|
25425
|
+
const RELEASE_ARTIFACT_EVIDENCE = /^- \*\*(Release tag|Installable artifact|发布 tag|可安装 artifact)(?::|:)\*\*\s+\[[^\]]+]\((https:\/\/[^)]+)\)$/;
|
|
25426
|
+
const PROVENANCE_KEYS = /* @__PURE__ */ new Map([
|
|
25427
|
+
["Skill version", "skillVersion"],
|
|
25428
|
+
["Skill 版本", "skillVersion"],
|
|
25429
|
+
["Verified against DSH", "verifiedAgainst"],
|
|
25430
|
+
["核验的 DSH 版本", "verifiedAgainst"],
|
|
25431
|
+
["Upstream revision", "upstreamSha"],
|
|
25432
|
+
["上游 revision", "upstreamSha"]
|
|
25433
|
+
]);
|
|
25434
|
+
const EVIDENCE_KEYS = /* @__PURE__ */ new Map([
|
|
25435
|
+
["Release tag", "tagUrl"],
|
|
25436
|
+
["发布 tag", "tagUrl"],
|
|
25437
|
+
["Installable artifact", "installUrl"],
|
|
25438
|
+
["可安装 artifact", "installUrl"]
|
|
25439
|
+
]);
|
|
25440
|
+
function linksIn(text) {
|
|
25441
|
+
return [...text.matchAll(MARKDOWN_LINK$1)].map((match) => match[1]);
|
|
25442
|
+
}
|
|
25443
|
+
function provenanceValue(text) {
|
|
25444
|
+
return text.match(/`([^`]+)`/)?.[1] ?? text.trim();
|
|
25445
|
+
}
|
|
25446
|
+
function parseReleaseLedgerDocument(markdown) {
|
|
25447
|
+
const lines = markdown.replaceAll("\r\n", "\n").split("\n");
|
|
25448
|
+
const releases = [];
|
|
25449
|
+
const unexpectedContent = [];
|
|
25450
|
+
let release;
|
|
25451
|
+
let section;
|
|
25452
|
+
for (const [index, line] of lines.entries()) {
|
|
25453
|
+
const releaseMatch = line.match(RELEASE_HEADING);
|
|
25454
|
+
if (releaseMatch) {
|
|
25455
|
+
release = {
|
|
25456
|
+
identity: releaseMatch[1],
|
|
25457
|
+
date: releaseMatch[2],
|
|
25458
|
+
summary: "",
|
|
25459
|
+
sections: []
|
|
25460
|
+
};
|
|
25461
|
+
releases.push(release);
|
|
25462
|
+
section = void 0;
|
|
25463
|
+
continue;
|
|
25464
|
+
}
|
|
25465
|
+
if (!release) continue;
|
|
25466
|
+
const sectionMatch = line.match(SECTION_HEADING);
|
|
25467
|
+
if (sectionMatch) {
|
|
25468
|
+
section = {
|
|
25469
|
+
name: sectionMatch[1],
|
|
25470
|
+
entries: []
|
|
25471
|
+
};
|
|
25472
|
+
release.sections.push(section);
|
|
25473
|
+
continue;
|
|
25474
|
+
}
|
|
25475
|
+
const provenanceMatch = line.match(RELEASE_PROVENANCE);
|
|
25476
|
+
if (provenanceMatch && !section) {
|
|
25477
|
+
release.provenance ??= {};
|
|
25478
|
+
const key = PROVENANCE_KEYS.get(provenanceMatch[1]);
|
|
25479
|
+
release.provenance[key] = provenanceValue(provenanceMatch[2]);
|
|
25480
|
+
if (key === "upstreamSha") release.provenance.upstreamUrl = linksIn(provenanceMatch[2])[0];
|
|
25481
|
+
continue;
|
|
25482
|
+
}
|
|
25483
|
+
const evidenceMatch = line.match(RELEASE_ARTIFACT_EVIDENCE);
|
|
25484
|
+
if (evidenceMatch && !section) {
|
|
25485
|
+
release.evidence ??= {};
|
|
25486
|
+
release.evidence[EVIDENCE_KEYS.get(evidenceMatch[1])] = evidenceMatch[2];
|
|
25487
|
+
continue;
|
|
25488
|
+
}
|
|
25489
|
+
if (line.startsWith("- ") && section) {
|
|
25490
|
+
const text = line.slice(2);
|
|
25491
|
+
section.entries.push({
|
|
25492
|
+
text,
|
|
25493
|
+
links: linksIn(text)
|
|
25494
|
+
});
|
|
25495
|
+
continue;
|
|
25496
|
+
}
|
|
25497
|
+
if (/^\s{2,}\S/.test(line) && section && section.entries.length > 0) {
|
|
25498
|
+
const entry = section.entries.at(-1);
|
|
25499
|
+
entry.text = `${entry.text} ${line.trim()}`;
|
|
25500
|
+
entry.links = linksIn(entry.text);
|
|
25501
|
+
continue;
|
|
25502
|
+
}
|
|
25503
|
+
if (!release.summary && !section && line.trim()) {
|
|
25504
|
+
release.summary = line.trim();
|
|
25505
|
+
continue;
|
|
25506
|
+
}
|
|
25507
|
+
if (section && line.trim()) unexpectedContent.push({
|
|
25508
|
+
releaseIdentity: release.identity,
|
|
25509
|
+
sectionName: section.name,
|
|
25510
|
+
line: index + 1
|
|
25511
|
+
});
|
|
25512
|
+
}
|
|
25513
|
+
return {
|
|
25514
|
+
releases,
|
|
25515
|
+
unexpectedContent
|
|
25516
|
+
};
|
|
25517
|
+
}
|
|
25518
|
+
function parseReleaseLedger(markdown) {
|
|
25519
|
+
const { releases } = parseReleaseLedgerDocument(markdown);
|
|
25520
|
+
return { releases };
|
|
25521
|
+
}
|
|
25522
|
+
//#endregion
|
|
25523
|
+
//#region packages/core/src/release/version.ts
|
|
25524
|
+
const RELEASE_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/u;
|
|
25525
|
+
function parse$1(version) {
|
|
25526
|
+
const match = RELEASE_VERSION.exec(version);
|
|
25527
|
+
if (match === null) return void 0;
|
|
25528
|
+
return {
|
|
25529
|
+
core: [
|
|
25530
|
+
Number(match[1]),
|
|
25531
|
+
Number(match[2]),
|
|
25532
|
+
Number(match[3])
|
|
25533
|
+
],
|
|
25534
|
+
prerelease: match[4] === void 0 ? [] : match[4].split(".")
|
|
25535
|
+
};
|
|
25536
|
+
}
|
|
25537
|
+
function compareIdentifier(left, right) {
|
|
25538
|
+
const leftNumeric = /^\d+$/u.test(left);
|
|
25539
|
+
const rightNumeric = /^\d+$/u.test(right);
|
|
25540
|
+
if (leftNumeric && rightNumeric) return Math.sign(Number(left) - Number(right));
|
|
25541
|
+
if (leftNumeric) return -1;
|
|
25542
|
+
if (rightNumeric) return 1;
|
|
25543
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
25544
|
+
}
|
|
25545
|
+
function isReleaseVersion(version) {
|
|
25546
|
+
const parsed = parse$1(version);
|
|
25547
|
+
return parsed !== void 0 && parsed.core.some((part) => part > 0);
|
|
25548
|
+
}
|
|
25549
|
+
function compareVersions(left, right) {
|
|
25550
|
+
const a = parse$1(left);
|
|
25551
|
+
const b = parse$1(right);
|
|
25552
|
+
if (a === void 0 || b === void 0) return 0;
|
|
25553
|
+
for (let index = 0; index < 3; index += 1) {
|
|
25554
|
+
const difference = a.core[index] - b.core[index];
|
|
25555
|
+
if (difference !== 0) return Math.sign(difference);
|
|
25556
|
+
}
|
|
25557
|
+
if (a.prerelease.length === 0 || b.prerelease.length === 0) return Math.sign(b.prerelease.length - a.prerelease.length);
|
|
25558
|
+
const length = Math.max(a.prerelease.length, b.prerelease.length);
|
|
25559
|
+
for (let index = 0; index < length; index += 1) {
|
|
25560
|
+
const left = a.prerelease[index];
|
|
25561
|
+
const right = b.prerelease[index];
|
|
25562
|
+
if (left === void 0) return -1;
|
|
25563
|
+
if (right === void 0) return 1;
|
|
25564
|
+
const order = compareIdentifier(left, right);
|
|
25565
|
+
if (order !== 0) return order;
|
|
25566
|
+
}
|
|
25567
|
+
return 0;
|
|
25568
|
+
}
|
|
25569
|
+
//#endregion
|
|
25570
|
+
//#region packages/core/src/release/notes.ts
|
|
25571
|
+
const RELEASE_REPOSITORY_URL = "https://github.com/BotHarness/BotHarness";
|
|
25572
|
+
const RELEASE_NOTE_SECTION_ORDER = [
|
|
25573
|
+
"Added",
|
|
25574
|
+
"Changed",
|
|
25575
|
+
"Fixed",
|
|
25576
|
+
"Security",
|
|
25577
|
+
"Documentation",
|
|
25578
|
+
"Breaking Changes",
|
|
25579
|
+
"Deprecated",
|
|
25580
|
+
"Removed"
|
|
25581
|
+
];
|
|
25582
|
+
function sectionRank(name) {
|
|
25583
|
+
const index = RELEASE_NOTE_SECTION_ORDER.indexOf(name);
|
|
25584
|
+
return index === -1 ? RELEASE_NOTE_SECTION_ORDER.length : index;
|
|
25585
|
+
}
|
|
25586
|
+
const MARKDOWN_LINK = /(\[[^\]]*\]\()([^)\s]+)(\))/gu;
|
|
25587
|
+
function absolutizeLedgerLinks(text) {
|
|
25588
|
+
return text.replace(MARKDOWN_LINK, (whole, open, target, close) => {
|
|
25589
|
+
if (/^[a-z][a-z0-9+.-]*:/iu.test(target) || target.startsWith("#")) return whole;
|
|
25590
|
+
const path = target.replace(/^\.?\//u, "");
|
|
25591
|
+
return `${open}${RELEASE_REPOSITORY_URL}/blob/main/${path}${close}`;
|
|
25592
|
+
});
|
|
25593
|
+
}
|
|
25594
|
+
function pairReleaseLedgers(english, chinese) {
|
|
25595
|
+
const translated = new Map(parseReleaseLedger(chinese).releases.map((release) => [release.identity, release]));
|
|
25596
|
+
const notes = [];
|
|
25597
|
+
for (const release of parseReleaseLedger(english).releases) {
|
|
25598
|
+
if (!isReleaseVersion(release.identity) || release.date === void 0) continue;
|
|
25599
|
+
const zh = translated.get(release.identity);
|
|
25600
|
+
notes.push({
|
|
25601
|
+
version: release.identity,
|
|
25602
|
+
date: release.date,
|
|
25603
|
+
summary: {
|
|
25604
|
+
en: absolutizeLedgerLinks(release.summary),
|
|
25605
|
+
zh: absolutizeLedgerLinks(zh?.summary || release.summary)
|
|
25606
|
+
},
|
|
25607
|
+
sections: release.sections.toSorted((left, right) => sectionRank(left.name) - sectionRank(right.name)).map((section) => {
|
|
25608
|
+
const zhEntries = zh?.sections.find((candidate) => candidate.name === section.name)?.entries;
|
|
25609
|
+
return {
|
|
25610
|
+
name: section.name,
|
|
25611
|
+
entries: section.entries.map((entry, index) => ({
|
|
25612
|
+
en: absolutizeLedgerLinks(entry.text),
|
|
25613
|
+
zh: absolutizeLedgerLinks(zhEntries?.[index]?.text ?? entry.text)
|
|
25614
|
+
}))
|
|
25615
|
+
};
|
|
25616
|
+
})
|
|
25617
|
+
});
|
|
25618
|
+
}
|
|
25619
|
+
return notes.sort((left, right) => compareVersions(right.version, left.version));
|
|
25620
|
+
}
|
|
25621
|
+
function selectReleaseNotes(notes, range) {
|
|
25622
|
+
return notes.filter((note) => compareVersions(note.version, range.through) <= 0 && (range.after === void 0 || !isReleaseVersion(range.after) || compareVersions(note.version, range.after) > 0));
|
|
25623
|
+
}
|
|
25624
|
+
//#endregion
|
|
25625
|
+
//#region packages/core/src/release/service.ts
|
|
25626
|
+
const RELEASE_PACKAGE = "deepseekbot";
|
|
25627
|
+
const RELEASE_NOTES_PACKAGE = "@botharness/core";
|
|
25628
|
+
const DEFAULT_RELEASE_REGISTRIES = ["https://registry.npmjs.org", "https://registry.npmmirror.com"];
|
|
25629
|
+
const DEFAULT_RELEASE_NOTE_SOURCES = [(version) => `https://cdn.jsdelivr.net/npm/${RELEASE_NOTES_PACKAGE}@${version}/`, (version) => `https://registry.npmmirror.com/${RELEASE_NOTES_PACKAGE}/${version}/files/`];
|
|
25630
|
+
const CHECK_CACHE_MS = 216e5;
|
|
25631
|
+
const FAILURE_CACHE_MS = 3e5;
|
|
25632
|
+
const REQUEST_TIMEOUT_MS = 8e3;
|
|
25633
|
+
function readFirst(candidates) {
|
|
25634
|
+
for (const candidate of candidates) try {
|
|
25635
|
+
return readFileSync(candidate, "utf8");
|
|
25636
|
+
} catch {
|
|
25637
|
+
continue;
|
|
25638
|
+
}
|
|
25639
|
+
}
|
|
25640
|
+
function installedRelease(moduleUrl) {
|
|
25641
|
+
const ledger = (name) => readFirst([new URL(`../${name}`, moduleUrl), new URL(`../../../${name}`, moduleUrl)]);
|
|
25642
|
+
return {
|
|
25643
|
+
version: () => {
|
|
25644
|
+
const manifest = readFirst([new URL("../package.json", moduleUrl)]);
|
|
25645
|
+
if (manifest === void 0) return "0.0.0";
|
|
25646
|
+
const version = JSON.parse(manifest).version;
|
|
25647
|
+
return typeof version === "string" ? version : "0.0.0";
|
|
25648
|
+
},
|
|
25649
|
+
ledgers: () => {
|
|
25650
|
+
const english = ledger("CHANGELOG.md");
|
|
25651
|
+
if (english === void 0) return void 0;
|
|
25652
|
+
return {
|
|
25653
|
+
english,
|
|
25654
|
+
chinese: ledger("CHANGELOG.zh.md") ?? english
|
|
25655
|
+
};
|
|
25656
|
+
}
|
|
25657
|
+
};
|
|
25658
|
+
}
|
|
25659
|
+
function newestTag(tags, current) {
|
|
25660
|
+
if (typeof tags !== "object" || tags === null) return void 0;
|
|
25661
|
+
const source = tags;
|
|
25662
|
+
return [source["latest"], current.includes("-") ? source["next"] : void 0].filter((value) => typeof value === "string" && isReleaseVersion(value)).sort(compareVersions).at(-1);
|
|
25663
|
+
}
|
|
25664
|
+
function createReleaseService(options) {
|
|
25665
|
+
const fetchImpl = options.fetchImpl ?? fetch;
|
|
25666
|
+
const now = options.now ?? Date.now;
|
|
25667
|
+
const registries = options.registries ?? DEFAULT_RELEASE_REGISTRIES;
|
|
25668
|
+
const noteSources = options.noteSources ?? DEFAULT_RELEASE_NOTE_SOURCES;
|
|
25669
|
+
const timeoutMs = options.timeoutMs ?? REQUEST_TIMEOUT_MS;
|
|
25670
|
+
let notes;
|
|
25671
|
+
let cached;
|
|
25672
|
+
let pending;
|
|
25673
|
+
const installedNotes = () => {
|
|
25674
|
+
if (notes !== void 0) return notes;
|
|
25675
|
+
const ledgers = options.ledgers();
|
|
25676
|
+
notes = ledgers === void 0 ? [] : pairReleaseLedgers(ledgers.english, ledgers.chinese);
|
|
25677
|
+
return notes;
|
|
25678
|
+
};
|
|
25679
|
+
const text = async (url) => {
|
|
25680
|
+
try {
|
|
25681
|
+
const response = await fetchImpl(url, { signal: AbortSignal.timeout(timeoutMs) });
|
|
25682
|
+
return response.ok ? await response.text() : void 0;
|
|
25683
|
+
} catch {
|
|
25684
|
+
return;
|
|
25685
|
+
}
|
|
25686
|
+
};
|
|
25687
|
+
const latestVersion = async (current) => {
|
|
25688
|
+
for (const registry of registries) {
|
|
25689
|
+
const body = await text(`${registry.replace(/\/+$/u, "")}/-/package/${RELEASE_PACKAGE}/dist-tags`);
|
|
25690
|
+
if (body === void 0) continue;
|
|
25691
|
+
try {
|
|
25692
|
+
const latest = newestTag(JSON.parse(body), current);
|
|
25693
|
+
if (latest !== void 0) return latest;
|
|
25694
|
+
} catch {
|
|
25695
|
+
continue;
|
|
25696
|
+
}
|
|
25697
|
+
}
|
|
25698
|
+
};
|
|
25699
|
+
const newerNotes = async (current, latest) => {
|
|
25700
|
+
for (const source of noteSources) {
|
|
25701
|
+
const base = source(latest);
|
|
25702
|
+
const english = await text(`${base}CHANGELOG.md`);
|
|
25703
|
+
if (english === void 0) continue;
|
|
25704
|
+
return selectReleaseNotes(pairReleaseLedgers(english, await text(`${base}CHANGELOG.zh.md`) ?? english), {
|
|
25705
|
+
after: current,
|
|
25706
|
+
through: latest
|
|
25707
|
+
});
|
|
25708
|
+
}
|
|
25709
|
+
return [];
|
|
25710
|
+
};
|
|
25711
|
+
const check = async () => {
|
|
25712
|
+
const current = options.version();
|
|
25713
|
+
if (!isReleaseVersion(current)) return {
|
|
25714
|
+
status: "development",
|
|
25715
|
+
current
|
|
25716
|
+
};
|
|
25717
|
+
const latest = await latestVersion(current);
|
|
25718
|
+
if (latest === void 0) return {
|
|
25719
|
+
status: "unavailable",
|
|
25720
|
+
current
|
|
25721
|
+
};
|
|
25722
|
+
if (compareVersions(latest, current) <= 0) return {
|
|
25723
|
+
status: "current",
|
|
25724
|
+
current,
|
|
25725
|
+
latest
|
|
25726
|
+
};
|
|
25727
|
+
return {
|
|
25728
|
+
status: "available",
|
|
25729
|
+
current,
|
|
25730
|
+
latest,
|
|
25731
|
+
releases: await newerNotes(current, latest)
|
|
25732
|
+
};
|
|
25733
|
+
};
|
|
25734
|
+
return {
|
|
25735
|
+
info(since) {
|
|
25736
|
+
const version = options.version();
|
|
25737
|
+
return {
|
|
25738
|
+
version,
|
|
25739
|
+
releases: !isReleaseVersion(version) ? [] : since === void 0 ? installedNotes().filter((note) => compareVersions(note.version, version) === 0) : selectReleaseNotes(installedNotes(), {
|
|
25740
|
+
after: since,
|
|
25741
|
+
through: version
|
|
25742
|
+
})
|
|
25743
|
+
};
|
|
25744
|
+
},
|
|
25745
|
+
update() {
|
|
25746
|
+
if (cached !== void 0) {
|
|
25747
|
+
if (now() - cached.at < (cached.result.status === "unavailable" ? FAILURE_CACHE_MS : CHECK_CACHE_MS)) return Promise.resolve(cached.result);
|
|
25748
|
+
}
|
|
25749
|
+
pending ??= check().then((result) => {
|
|
25750
|
+
cached = {
|
|
25751
|
+
at: now(),
|
|
25752
|
+
result
|
|
25753
|
+
};
|
|
25754
|
+
return result;
|
|
25755
|
+
}).finally(() => {
|
|
25756
|
+
pending = void 0;
|
|
25757
|
+
});
|
|
25758
|
+
return pending;
|
|
25759
|
+
}
|
|
25760
|
+
};
|
|
25761
|
+
}
|
|
25762
|
+
//#endregion
|
|
25387
25763
|
//#region packages/core/src/bots/avatar-snapshot.ts
|
|
25388
25764
|
function deriveAvatarAppearance(value) {
|
|
25389
25765
|
if (!isAvatarRecipe(value)) return void 0;
|
|
@@ -49675,6 +50051,7 @@ function apply(ctx, config) {
|
|
|
49675
50051
|
toolRules: core.toolRules,
|
|
49676
50052
|
assignmentAccess: core.assignmentAccess,
|
|
49677
50053
|
marketplace: createMarketplaceClient({ baseUrl: config.marketplaceUrl ?? "https://market.botharness.ai" }),
|
|
50054
|
+
release: createReleaseService(installedRelease(import.meta.url)),
|
|
49678
50055
|
developerMode: { set: (enabled) => developerModeTarget.gate?.set(enabled) },
|
|
49679
50056
|
computerAccess: { changed: (slug) => {
|
|
49680
50057
|
(ctx.get("botharnessComputerTools")?.reconcileBot?.(slug))?.catch((error) => {
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botharness/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "BotHarness core: PersonaBot registry, memory, and state",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"cordis.patch.yml",
|
|
8
|
+
"CHANGELOG.md",
|
|
9
|
+
"CHANGELOG.zh.md",
|
|
8
10
|
"LICENSE"
|
|
9
11
|
],
|
|
10
12
|
"type": "module",
|