@bolloon/bolloon-agent 0.4.32 → 0.5.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/dist/agents/chain/explorer.js +52 -0
- package/dist/agents/chain/index.js +2 -0
- package/dist/agents/chain/onchain-trade.js +15 -1
- package/dist/agents/contacts/chain.js +27 -7
- package/dist/agents/execution-supervisor.js +493 -35
- package/dist/agents/external-events.js +35 -6
- package/dist/agents/gateway-group.js +100 -12
- package/dist/agents/goal-criteria.js +10 -3
- package/dist/agents/goal-flywheel/block-executor.js +346 -0
- package/dist/agents/goal-flywheel/continuation-decision.js +592 -0
- package/dist/agents/goal-flywheel/goal-change.js +754 -0
- package/dist/agents/goal-flywheel/index.js +26 -0
- package/dist/agents/goal-flywheel/memory-layers.js +227 -0
- package/dist/agents/goal-flywheel/run-closure.js +809 -0
- package/dist/agents/goal-flywheel/skill-candidate.js +628 -0
- package/dist/agents/goal-flywheel/types.js +329 -0
- package/dist/agents/goal-flywheel/wiring/change.js +288 -0
- package/dist/agents/goal-flywheel/wiring/closure.js +697 -0
- package/dist/agents/goal-flywheel/wiring/continuation.js +432 -0
- package/dist/agents/goal-flywheel/wiring/contract.js +270 -0
- package/dist/agents/goal-flywheel/wiring/index.js +26 -0
- package/dist/agents/goal-flywheel/wiring/monitor.js +254 -0
- package/dist/agents/goal-flywheel/wiring/seams.js +592 -0
- package/dist/agents/goal-flywheel/work-contract.js +478 -0
- package/dist/agents/goal-flywheel/work-monitor.js +488 -0
- package/dist/agents/goal-flywheel-wiring.js +1870 -0
- package/dist/agents/goal-state-reducer.js +406 -0
- package/dist/agents/goal-store.js +35 -1
- package/dist/agents/mobile-flywheel-view.js +144 -0
- package/dist/agents/mobile-task-actions-verify.js +74 -0
- package/dist/agents/mobile-task-actions.js +178 -0
- package/dist/agents/mobile-task-views.js +199 -0
- package/dist/agents/network-pulse.js +525 -27
- package/dist/agents/pi-sdk.js +75 -20
- package/dist/agents/run-store.js +18 -5
- package/dist/agents/skill-readiness.js +52 -10
- package/dist/agents/subagent-manager.js +209 -3
- package/dist/agents/task/task-onchain-runner.js +19 -1
- package/dist/agents/task/task-runner.js +36 -6
- package/dist/agents/task-board.js +702 -0
- package/dist/agents/task-group.js +524 -0
- package/dist/agents/task-public-text.js +89 -0
- package/dist/cli/commands/index.js +3 -0
- package/dist/cli/commands/tasks.js +977 -8
- package/dist/cli/identity-command.js +177 -0
- package/dist/cli/protocol-envelope.js +4 -0
- package/dist/cli/setup-wizard.js +71 -0
- package/dist/cli/update-commands.js +150 -24
- package/dist/cli-entry.js +12 -2
- package/dist/electron-build/agents/chain/explorer.js +59 -0
- package/dist/electron-build/agents/chain/explorer.js.map +1 -0
- package/dist/electron-build/agents/contacts/chain.js +26 -6
- package/dist/electron-build/agents/contacts/chain.js.map +1 -1
- package/dist/electron-build/agents/execution-supervisor.js +492 -34
- package/dist/electron-build/agents/execution-supervisor.js.map +1 -1
- package/dist/electron-build/agents/external-events.js +34 -5
- package/dist/electron-build/agents/external-events.js.map +1 -1
- package/dist/electron-build/agents/goal-criteria.js +10 -3
- package/dist/electron-build/agents/goal-criteria.js.map +1 -1
- package/dist/electron-build/agents/goal-flywheel/continuation-decision.js +598 -0
- package/dist/electron-build/agents/goal-flywheel/continuation-decision.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/goal-change.js +773 -0
- package/dist/electron-build/agents/goal-flywheel/goal-change.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/memory-layers.js +269 -0
- package/dist/electron-build/agents/goal-flywheel/memory-layers.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/run-closure.js +818 -0
- package/dist/electron-build/agents/goal-flywheel/run-closure.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/skill-candidate.js +642 -0
- package/dist/electron-build/agents/goal-flywheel/skill-candidate.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/types.js +333 -0
- package/dist/electron-build/agents/goal-flywheel/types.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/change.js +294 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/change.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/closure.js +742 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/closure.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/continuation.js +444 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/continuation.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/contract.js +279 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/contract.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/index.js +111 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/index.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/monitor.js +264 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/monitor.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/seams.js +612 -0
- package/dist/electron-build/agents/goal-flywheel/wiring/seams.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/work-contract.js +488 -0
- package/dist/electron-build/agents/goal-flywheel/work-contract.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel/work-monitor.js +501 -0
- package/dist/electron-build/agents/goal-flywheel/work-monitor.js.map +1 -0
- package/dist/electron-build/agents/goal-flywheel-wiring.js +1962 -0
- package/dist/electron-build/agents/goal-flywheel-wiring.js.map +1 -0
- package/dist/electron-build/agents/goal-state-reducer.js +414 -0
- package/dist/electron-build/agents/goal-state-reducer.js.map +1 -0
- package/dist/electron-build/agents/goal-store.js +35 -1
- package/dist/electron-build/agents/goal-store.js.map +1 -1
- package/dist/electron-build/agents/local-signer.js +101 -0
- package/dist/electron-build/agents/local-signer.js.map +1 -0
- package/dist/electron-build/agents/network-pulse.js +531 -28
- package/dist/electron-build/agents/network-pulse.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +74 -19
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/run-store.js +20 -5
- package/dist/electron-build/agents/run-store.js.map +1 -1
- package/dist/electron-build/agents/skill-readiness.js +52 -9
- package/dist/electron-build/agents/skill-readiness.js.map +1 -1
- package/dist/electron-build/agents/task/task-runner.js +35 -5
- package/dist/electron-build/agents/task/task-runner.js.map +1 -1
- package/dist/electron-build/agents/task-board.js +761 -0
- package/dist/electron-build/agents/task-board.js.map +1 -0
- package/dist/electron-build/agents/task-contract.js +382 -0
- package/dist/electron-build/agents/task-contract.js.map +1 -0
- package/dist/electron-build/orbitdb/cid-database.js +83 -17
- package/dist/electron-build/orbitdb/cid-database.js.map +1 -1
- package/dist/electron-build/orbitdb/ipfs-node.js +31 -2
- package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -1
- package/dist/electron-build/utils/dual-source.js +471 -0
- package/dist/electron-build/utils/dual-source.js.map +1 -0
- package/dist/electron-build/utils/update-manager.js +331 -57
- package/dist/electron-build/utils/update-manager.js.map +1 -1
- package/dist/electron-build/utils/update-state.js +16 -1
- package/dist/electron-build/utils/update-state.js.map +1 -1
- package/dist/electron-build/utils/version-info.js +82 -2
- package/dist/electron-build/utils/version-info.js.map +1 -1
- package/dist/index.js +103 -12
- package/dist/ios/chain-explorer.js +617 -0
- package/dist/ios/explorer.html +163 -0
- package/dist/ios/index.html +96 -0
- package/dist/ios/mobile-agent.js +2 -2
- package/dist/ios/mobile-contacts.js +329 -0
- package/dist/ios/mobile-core.js +1379 -226
- package/dist/ios/mobile-privacy.js +185 -0
- package/dist/ios/mobile.css +19 -0
- package/dist/ios/mobile.html +96 -0
- package/dist/ios/mobile.js +706 -7
- package/dist/ios/routes-chain-index.js +108 -0
- package/dist/ios/routes-contacts.js +420 -0
- package/dist/ios/routes-onchain-trade.js +99 -0
- package/dist/ios/routes-x402-info.js +1 -0
- package/dist/ios/server.js +762 -0
- package/dist/ios/task-frame-server.js +211 -0
- package/dist/orbitdb/cid-database.js +81 -16
- package/dist/orbitdb/ipfs-node.js +31 -2
- package/dist/utils/dual-source.js +426 -0
- package/dist/utils/update-cli.js +16 -21
- package/dist/utils/update-health.js +35 -5
- package/dist/utils/update-manager.js +329 -57
- package/dist/utils/update-state.js +16 -1
- package/dist/utils/version-info.js +75 -1
- package/dist/web/mobile-contacts.js +44 -11
- package/dist/web/mobile-core.js +1197 -513
- package/dist/web/mobile-tasks.js +339 -0
- package/dist/web/mobile.css +19 -0
- package/dist/web/mobile.html +64 -0
- package/dist/web/mobile.js +531 -1
- package/dist/web/routes-mobile-tasks.js +353 -0
- package/dist/web/server.js +163 -4
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cid-database.js","sourceRoot":"","sources":["../../../src/orbitdb/cid-database.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,0CAAuC;AACvC,MAAY,OAAO,2CAAuB;AAC1C,mDAAkD;AAClD,+CAA2D;AAC3D,wCAA2E;AAC3E,iDAAqE;AACrE,MAAY,IAAI,iCAAa;AAC7B,MAAY,EAAE,+BAAW;
|
|
1
|
+
{"version":3,"file":"cid-database.js","sourceRoot":"","sources":["../../../src/orbitdb/cid-database.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* ipfs-node.ts — Bolloon 的 OrbitDB 底层 IPFS 节点工厂 (2026-08-06)
|
|
3
|
+
* ipfs-node.ts — Bolloon 的 OrbitDB 底层 IPFS 节点工厂 (2026-08-06; 落盘 2026-09-24)
|
|
4
4
|
*
|
|
5
5
|
* 基于 helia 7:
|
|
6
6
|
* - createHelia() 内部已 withLibp2p 但**不传 opts** → 无法自定义 services
|
|
@@ -11,6 +11,20 @@
|
|
|
11
11
|
* 必须显式列出要保留的默认服务 (dht/identify/keychain/...)
|
|
12
12
|
* - withLibp2p().start() 之后 libp2p getter 才可用 (之前抛 NotStartedError)
|
|
13
13
|
*
|
|
14
|
+
* 2026-09-24 **区块/datastore 落盘修复** (跨进程可重开的根因):
|
|
15
|
+
* 原来 createHeliaLight 只传 codecs/hashers → helia 用默认 MemoryBlockstore / MemoryDatastore,
|
|
16
|
+
* 而 OrbitDB 的 manifest 与 oplog 条目都走 IPFSBlockStorage(ipfs.blockstore) 存
|
|
17
|
+
* (@orbitdb/core/src/storage/ipfs-block.js)。于是 `~/.bolloon/orbitdb/` 下只有 stores/
|
|
18
|
+
* (keystore + log/_heads 的 LevelDB), 没有 ipfs/ 块存储 —— store 只活在创建它的那个进程里。
|
|
19
|
+
* 新进程用地址重开必挂在 manifestStore.get():
|
|
20
|
+
* "No block brokers capable of retrieving blocks are configured, the CID bafyrei… cannot be fetched"
|
|
21
|
+
* 现在: FsBlockstore(dataDir/blocks) + FsDatastore(dataDir/datastore) 真落盘。
|
|
22
|
+
* · datastore 顺带持久化 pin (helia pins) 与 libp2p 私钥
|
|
23
|
+
* (@helia/libp2p: loadOrCreateSelfKey(helia.datastore) + opts.datastore ??= helia.datastore)
|
|
24
|
+
* → 同一 dataDir 的 peerId 跨进程稳定。
|
|
25
|
+
* · 这两个包是 Node 专用 (node:fs / node:path); 本文件只被 Node 侧 import,
|
|
26
|
+
* 浏览器入口 (client.ts / mobile-core.ts / a2ui-client.tsx) 到不了这里 —— 不伤 Web 包。
|
|
27
|
+
*
|
|
14
28
|
* 跑法: npx tsx scripts/smoke-orbitdb.ts
|
|
15
29
|
*/
|
|
16
30
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -51,6 +65,8 @@ exports.createBolloonIpfs = createBolloonIpfs;
|
|
|
51
65
|
exports.dbNameFromAddress = dbNameFromAddress;
|
|
52
66
|
const helia_1 = require("helia");
|
|
53
67
|
const libp2p_1 = require("@helia/libp2p");
|
|
68
|
+
const blockstore_fs_1 = require("blockstore-fs");
|
|
69
|
+
const datastore_fs_1 = require("datastore-fs");
|
|
54
70
|
const dagCbor = __importStar(require("@ipld/dag-cbor"));
|
|
55
71
|
const dagJson = __importStar(require("@ipld/dag-json"));
|
|
56
72
|
const json = __importStar(require("multiformats/codecs/json"));
|
|
@@ -74,13 +90,25 @@ const os = __importStar(require("os"));
|
|
|
74
90
|
/**
|
|
75
91
|
* 创建 Bolloon 用的 helia 节点 (libp2p 完整默认服务 + gossipsub pubsub)。
|
|
76
92
|
* dataDir 持久化节点身份/数据 (默认 ~/.bolloon/orbitdb-ipfs)。
|
|
93
|
+
*
|
|
94
|
+
* 2026-09-24: dataDir 下真落两个目录 —— `blocks/` (区块) 与 `datastore/` (pin + peerkey)。
|
|
95
|
+
* 目录不可写时**直接抛** (不退回内存: 静默退回正好是"新进程读不到群"的根因)。
|
|
77
96
|
*/
|
|
78
97
|
async function createBolloonIpfs(dataDir) {
|
|
79
|
-
const dir = dataDir ?? path.join(process.env.HOME || os.homedir() || '/tmp', '.bolloon', 'orbitdb-ipfs');
|
|
98
|
+
const dir = path.resolve(dataDir ?? path.join(process.env.HOME || os.homedir() || '/tmp', '.bolloon', 'orbitdb-ipfs'));
|
|
99
|
+
const blocksDir = path.join(dir, 'blocks');
|
|
100
|
+
const datastoreDir = path.join(dir, 'datastore');
|
|
101
|
+
// 落盘存储: 不传这两个, helia 默认 MemoryBlockstore/MemoryDatastore → 进程退出即丢区块
|
|
102
|
+
const blockstore = new blockstore_fs_1.FsBlockstore(blocksDir);
|
|
103
|
+
const datastore = new datastore_fs_1.FsDatastore(datastoreDir);
|
|
104
|
+
await blockstore.open(); // 建目录 + F_OK|W_OK 探测, 失败抛 OpenFailedError (不静默)
|
|
105
|
+
await datastore.open();
|
|
80
106
|
// createHeliaLight 无 libp2p → withLibp2p 手动装配 (可传 services)
|
|
81
107
|
// codecs/hashers 照抄 createHelia 默认: OrbitDB 的 log entry 用 dag-cbor (codec 113),
|
|
82
108
|
// 不注册会报 "Could not load codec for 113"
|
|
83
109
|
const helia = (0, libp2p_1.withLibp2p)((0, helia_1.createHeliaLight)({
|
|
110
|
+
blockstore,
|
|
111
|
+
datastore,
|
|
84
112
|
codecs: [dagCbor, dagJson, json],
|
|
85
113
|
hashers: [sha2_1.sha512],
|
|
86
114
|
}), {
|
|
@@ -108,6 +136,7 @@ async function createBolloonIpfs(dataDir) {
|
|
|
108
136
|
return {
|
|
109
137
|
helia,
|
|
110
138
|
peerId,
|
|
139
|
+
paths: { dataDir: dir, blocksDir, datastoreDir },
|
|
111
140
|
start: async () => { await helia.start(); },
|
|
112
141
|
stop: async () => { await helia.stop(); },
|
|
113
142
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ipfs-node.js","sourceRoot":"","sources":["../../../src/orbitdb/ipfs-node.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"ipfs-node.js","sourceRoot":"","sources":["../../../src/orbitdb/ipfs-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* dual-source.ts — 双源 (npm registry + GitHub) 的**源事实** (2026-09-25, update-protocol §12)
|
|
4
|
+
*
|
|
5
|
+
* 为什么单独一个模块: §1.4 冻结的是 "npm 是唯一稳定渠道", §12 把它改成**双源但权威顺序不变**。
|
|
6
|
+
* 这件事不该塞进 update-manager (那会让"唯一决策者"同时变成"网络客户端"), 也不该让
|
|
7
|
+
* CLI / 健康检查各自造一份 GitHub 事实。所以:
|
|
8
|
+
*
|
|
9
|
+
* - 源事实 (GitHub 可达性 / tag / Release / master HEAD) 只在本模块查
|
|
10
|
+
* - 错误分类 `classifyGithubError` 与 §3 的 `classifyRegistryError` **并列, 不合并**
|
|
11
|
+
* - dev 快照的**取源与构建**也在这里 (update-manager 只负责"切换 + 验证 + 回滚", 不另造一套)
|
|
12
|
+
*
|
|
13
|
+
* 硬口径 (§12.5, 验收核心):
|
|
14
|
+
* - 源不可达 / 版本不存在 → **拒绝并说清** (带具体分类), 绝不静默装回旧版
|
|
15
|
+
* - 不编造不存在的路径: 本仓 GitHub 上**真的没有 Release** (0 个), 所以 "Release 缺" 时
|
|
16
|
+
* 如实报 "发布记录缺 Tag / Release" (提醒级), **不是** fake 一个 Release 出来
|
|
17
|
+
*/
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
exports.DEV_CHANNEL_WARNING = void 0;
|
|
53
|
+
exports.toGithubReport = toGithubReport;
|
|
54
|
+
exports.renderGithubReportLine = renderGithubReportLine;
|
|
55
|
+
exports.classifyGithubError = classifyGithubError;
|
|
56
|
+
exports.fetchGithubFacts = fetchGithubFacts;
|
|
57
|
+
exports.newestGithubVersion = newestGithubVersion;
|
|
58
|
+
exports.crossCheckStable = crossCheckStable;
|
|
59
|
+
exports.compareDevSnapshots = compareDevSnapshots;
|
|
60
|
+
exports.prepareDevSnapshot = prepareDevSnapshot;
|
|
61
|
+
const fs = __importStar(require("fs"));
|
|
62
|
+
const fsp = __importStar(require("fs/promises"));
|
|
63
|
+
const path = __importStar(require("path"));
|
|
64
|
+
const http = __importStar(require("http"));
|
|
65
|
+
const https = __importStar(require("https"));
|
|
66
|
+
const child_process_1 = require("child_process");
|
|
67
|
+
const version_info_js_1 = require("./version-info.js");
|
|
68
|
+
Object.defineProperty(exports, "DEV_CHANNEL_WARNING", { enumerable: true, get: function () { return version_info_js_1.DEV_CHANNEL_WARNING; } });
|
|
69
|
+
function toGithubReport(r) {
|
|
70
|
+
if (!r.ok) {
|
|
71
|
+
return {
|
|
72
|
+
reachable: false, reason: r.reason, detail: r.detail, retryAt: r.retryAt,
|
|
73
|
+
headSha: r.facts?.headSha ?? null, ref: r.facts?.ref ?? `refs/heads/${version_info_js_1.DEV_BRANCH}`,
|
|
74
|
+
releases: r.facts?.releases.length, tags: r.facts?.tags.length,
|
|
75
|
+
newestVersion: r.facts ? newestGithubVersion(r.facts) : null,
|
|
76
|
+
partial: r.facts?.partial, fetchedAt: r.facts?.fetchedAt,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
reachable: true, headSha: r.facts.headSha, ref: r.facts.ref,
|
|
81
|
+
releases: r.facts.releases.length, tags: r.facts.tags.length,
|
|
82
|
+
newestVersion: newestGithubVersion(r.facts), partial: r.facts.partial, fetchedAt: r.facts.fetchedAt,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function renderGithubReportLine(g) {
|
|
86
|
+
if (!g)
|
|
87
|
+
return 'GitHub 源: 未查询';
|
|
88
|
+
if (!g.reachable) {
|
|
89
|
+
const retry = g.retryAt ? `, 限流重试时间 ${g.retryAt}` : '';
|
|
90
|
+
return `GitHub 源: 不可达 — github_unavailable(${g.reason}) ${g.detail || ''}${retry}`;
|
|
91
|
+
}
|
|
92
|
+
return `GitHub 源: 可达 · master HEAD ${g.headSha ? g.headSha.slice(0, 7) : '未知'} · Release ${g.releases ?? 0} 个 · Tag ${g.tags ?? 0} 个 · 最新版本标签 ${g.newestVersion || '无'}${g.partial ? ' (部分请求失败)' : ''}`;
|
|
93
|
+
}
|
|
94
|
+
// ── HTTP ────────────────────────────────────────────────────────────────────
|
|
95
|
+
const OFFLINE_CODES = new Set(['ENOTFOUND', 'EAI_AGAIN', 'ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'EHOSTUNREACH', 'ENETUNREACH', 'ENETDOWN', 'EAI_FAIL', 'UND_ERR_CONNECT_TIMEOUT', 'CERT_HAS_EXPIRED']);
|
|
96
|
+
/** 可选 GitHub token (只为提配额: 匿名 60 次/小时, 认证 5000 次/小时)。**永不打印、永不入库**。 */
|
|
97
|
+
function githubToken(env = process.env) {
|
|
98
|
+
const t = env.GITHUB_TOKEN || env.GH_TOKEN || env.BOLLOON_GITHUB_TOKEN;
|
|
99
|
+
return t && String(t).trim() ? String(t).trim() : null;
|
|
100
|
+
}
|
|
101
|
+
function httpGetRaw(url, timeoutMs, token) {
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
const client = url.startsWith('https') ? https : http;
|
|
104
|
+
const req = client.get(url, {
|
|
105
|
+
timeout: timeoutMs,
|
|
106
|
+
headers: {
|
|
107
|
+
Accept: 'application/vnd.github+json, application/json',
|
|
108
|
+
'User-Agent': 'bolloon-update',
|
|
109
|
+
// token 只进请求头, 不进日志/状态/输出 (凭证红线)
|
|
110
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
111
|
+
},
|
|
112
|
+
}, (res) => {
|
|
113
|
+
let data = '';
|
|
114
|
+
res.on('data', (c) => { data += c; });
|
|
115
|
+
res.on('end', () => resolve({ status: res.statusCode || 0, body: data, headers: (res.headers || {}) }));
|
|
116
|
+
});
|
|
117
|
+
req.on('error', reject);
|
|
118
|
+
req.on('timeout', () => { req.destroy(new Error('timeout')); });
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/** 网络类 → offline; 403/429 → rate_limited; 404 → not_found; 其它 → http_error。 */
|
|
122
|
+
function classifyGithubError(err, httpStatus, headers = {}) {
|
|
123
|
+
const retryAt = headers['x-ratelimit-reset']
|
|
124
|
+
? new Date(Number(headers['x-ratelimit-reset']) * 1000).toISOString()
|
|
125
|
+
: null;
|
|
126
|
+
const code = String(err?.code || '');
|
|
127
|
+
if (OFFLINE_CODES.has(code) || /timeout|timed out|ENOTFOUND|getaddrinfo|network|socket hang up|超时/i.test(String(err?.message || ''))) {
|
|
128
|
+
return { kind: 'github_unavailable', reason: 'offline', detail: `${code || err?.message || '网络不可达'}`, retryAt: null };
|
|
129
|
+
}
|
|
130
|
+
if (httpStatus === 403 || httpStatus === 429) {
|
|
131
|
+
return { kind: 'github_unavailable', reason: 'rate_limited', detail: `GitHub 返回 HTTP ${httpStatus} (限流/权限)`, retryAt };
|
|
132
|
+
}
|
|
133
|
+
if (httpStatus === 404) {
|
|
134
|
+
return { kind: 'github_unavailable', reason: 'not_found', detail: `GitHub 上没有 ${version_info_js_1.GITHUB_UPSTREAM_SLUG} 的该项记录 (HTTP 404)`, retryAt: null };
|
|
135
|
+
}
|
|
136
|
+
if (httpStatus && httpStatus >= 400) {
|
|
137
|
+
return { kind: 'github_unavailable', reason: 'http_error', detail: `GitHub 返回 HTTP ${httpStatus}`, retryAt };
|
|
138
|
+
}
|
|
139
|
+
return { kind: 'github_unavailable', reason: 'http_error', detail: code || err?.message || '未知错误', retryAt: null };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* 查 GitHub 的三个事实: Releases / Tags / master HEAD。
|
|
143
|
+
* **任何一个请求失败 → 整条 `github_unavailable`** (带分类), 但把已拿到的那部分 facts 一起带回去
|
|
144
|
+
* (上层因此能说清"哪些拿到了、哪些没拿到", 而不是一句"更新失败")。
|
|
145
|
+
*/
|
|
146
|
+
async function fetchGithubFacts(opts = {}) {
|
|
147
|
+
const base = (opts.apiBase || version_info_js_1.GITHUB_API_BASE).replace(/\/+$/, '');
|
|
148
|
+
const slug = opts.slug || version_info_js_1.GITHUB_UPSTREAM_SLUG;
|
|
149
|
+
const timeout = opts.timeoutMs ?? 10000;
|
|
150
|
+
// 有 token 就用 (配额 60/h → 5000/h); 没有也能跑, 只是可能 403 限流
|
|
151
|
+
const token = opts.token !== undefined ? opts.token : githubToken();
|
|
152
|
+
const missing = [];
|
|
153
|
+
let releases = [];
|
|
154
|
+
let tags = [];
|
|
155
|
+
let headSha = null;
|
|
156
|
+
/** 失败累积 (第一个失败决定分类, 但所有失败都记进 missing) */
|
|
157
|
+
const failures = [];
|
|
158
|
+
const note = (e, what) => {
|
|
159
|
+
missing.push(what);
|
|
160
|
+
failures.push({ reason: e.reason, detail: `${what}: ${e.detail}`, retryAt: e.retryAt });
|
|
161
|
+
};
|
|
162
|
+
// 1. Releases (本仓真的没有 → 200 + [] , 不是错误)
|
|
163
|
+
try {
|
|
164
|
+
const r = await httpGetRaw(`${base}/repos/${slug}/releases?per_page=100`, timeout, token);
|
|
165
|
+
if (r.status >= 200 && r.status < 300) {
|
|
166
|
+
const arr = JSON.parse(r.body);
|
|
167
|
+
releases = Array.isArray(arr) ? arr.map((x) => String(x?.tag_name || '')).filter(Boolean) : [];
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
note(classifyGithubError(null, r.status, r.headers), 'releases');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
note(classifyGithubError(e), 'releases');
|
|
175
|
+
}
|
|
176
|
+
// 2. Tags
|
|
177
|
+
try {
|
|
178
|
+
const r = await httpGetRaw(`${base}/repos/${slug}/tags?per_page=100`, timeout, token);
|
|
179
|
+
if (r.status >= 200 && r.status < 300) {
|
|
180
|
+
const arr = JSON.parse(r.body);
|
|
181
|
+
tags = Array.isArray(arr)
|
|
182
|
+
? arr.map((x) => ({ name: String(x?.name || ''), sha: x?.commit?.sha ? String(x.commit.sha) : null })).filter((t) => t.name)
|
|
183
|
+
: [];
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
note(classifyGithubError(null, r.status, r.headers), 'tags');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (e) {
|
|
190
|
+
note(classifyGithubError(e), 'tags');
|
|
191
|
+
}
|
|
192
|
+
// 3. master HEAD (dev 通道的身份来源)
|
|
193
|
+
try {
|
|
194
|
+
const r = await httpGetRaw(`${base}/repos/${slug}/commits/${version_info_js_1.DEV_BRANCH}`, timeout, token);
|
|
195
|
+
if (r.status >= 200 && r.status < 300) {
|
|
196
|
+
const j = JSON.parse(r.body);
|
|
197
|
+
headSha = j?.sha ? String(j.sha) : null;
|
|
198
|
+
if (!headSha)
|
|
199
|
+
note({ reason: 'parse_error', detail: 'commits/master 没有 sha 字段', retryAt: null }, 'head');
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// 404 在这里的语义就是"没有 master 分支"(§12.3)
|
|
203
|
+
note(classifyGithubError(null, r.status, r.headers), 'head');
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (e) {
|
|
207
|
+
note(classifyGithubError(e), 'head');
|
|
208
|
+
}
|
|
209
|
+
const facts = {
|
|
210
|
+
slug, ref: `refs/heads/${version_info_js_1.DEV_BRANCH}`, headSha, releases, tags,
|
|
211
|
+
fetchedAt: new Date().toISOString(), partial: missing.length > 0, missing,
|
|
212
|
+
};
|
|
213
|
+
if (failures.length > 0) {
|
|
214
|
+
const first = failures[0];
|
|
215
|
+
return { ok: false, kind: 'github_unavailable', reason: first.reason, detail: first.detail, retryAt: first.retryAt, facts };
|
|
216
|
+
}
|
|
217
|
+
return { ok: true, facts };
|
|
218
|
+
}
|
|
219
|
+
/** GitHub 上出现过的最高版本号 (Release ∪ Tag, 去掉 v 前缀)。没有 → null。 */
|
|
220
|
+
function newestGithubVersion(facts) {
|
|
221
|
+
const all = [...facts.releases, ...facts.tags.map((t) => t.name)]
|
|
222
|
+
.map((n) => String(n).trim().replace(/^v/, ''))
|
|
223
|
+
.filter((n) => /^\d+\.\d+\.\d+/.test(n));
|
|
224
|
+
if (all.length === 0)
|
|
225
|
+
return null;
|
|
226
|
+
return all.sort((a, b) => (numericCompare(a, b) < 0 ? 1 : -1))[0];
|
|
227
|
+
}
|
|
228
|
+
/** 只比数值段 (与 update-manager 的 compareVersions 同语义, 这里不反向依赖它)。 */
|
|
229
|
+
function numericCompare(a, b) {
|
|
230
|
+
const p = (v) => v.split('-')[0].split('.').map((x) => parseInt(x.replace(/\D.*$/, ''), 10) || 0);
|
|
231
|
+
const pa = p(a);
|
|
232
|
+
const pb = p(b);
|
|
233
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
234
|
+
const x = pa[i] ?? 0;
|
|
235
|
+
const y = pb[i] ?? 0;
|
|
236
|
+
if (x < y)
|
|
237
|
+
return -1;
|
|
238
|
+
if (x > y)
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
function hasName(names, v) {
|
|
244
|
+
const set = new Set(names.map((n) => String(n).trim().replace(/^v/, '')));
|
|
245
|
+
return set.has(v.replace(/^v/, ''));
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* stable 的交叉校验 (§12.1/§12.5): npm 仍是权威, GitHub 只回答"这次发布的记录在不在"。
|
|
249
|
+
*
|
|
250
|
+
* agree npm 的 latest 在 GitHub 上有同名 tag/Release → 两条记录指向同一版
|
|
251
|
+
* mismatch GitHub 记录了**更新的**版本而 registry 上没有 → 拒绝 (不许按 tag 去装)
|
|
252
|
+
* missing_record registry 有该版本但 GitHub 缺这条记录 → **提醒级, 不阻塞** (§12.5 原文:
|
|
253
|
+
* "报发布记录缺 Tag (提醒级, 不阻塞 stable 更新)")
|
|
254
|
+
* no_record_at_all GitHub 上一条版本记录都没有 → 如实报"暂无 tag 可交叉校验"(不编造路径)
|
|
255
|
+
*/
|
|
256
|
+
function crossCheckStable(registryLatest, facts) {
|
|
257
|
+
const common = {
|
|
258
|
+
registryLatest, githubVersion: newestGithubVersion(facts),
|
|
259
|
+
releases: facts.releases.length, tags: facts.tags.length,
|
|
260
|
+
};
|
|
261
|
+
if (!registryLatest) {
|
|
262
|
+
return { ...common, kind: 'no_record_at_all', hasTag: false, hasRelease: false, blocking: false, detail: 'npm 没有给出 latest, 无从交叉校验' };
|
|
263
|
+
}
|
|
264
|
+
const allNames = [...facts.releases, ...facts.tags.map((t) => t.name)];
|
|
265
|
+
const hasTag = hasName(facts.tags.map((t) => t.name), registryLatest);
|
|
266
|
+
const hasRelease = hasName(facts.releases, registryLatest);
|
|
267
|
+
const ghNewest = common.githubVersion;
|
|
268
|
+
/**
|
|
269
|
+
* **先判"GitHub 记录了比 registry 更新的发布"** —— 这是 §12.5 的 "Release 存在但 registry 上没有该版本 → cross_check_mismatch"。
|
|
270
|
+
* 放在 agree 之前: 即使 registry 的 latest 自己也有 tag, 只要 GitHub 上还多出一条更新的发布记录, 两个源对
|
|
271
|
+
* "当前最新是哪一版"就是不一致的 —— 这种不一致必须拦住, 不能因为"latest 有 tag"就宣布一致。
|
|
272
|
+
*/
|
|
273
|
+
if (ghNewest && numericCompare(ghNewest, registryLatest) > 0) {
|
|
274
|
+
return {
|
|
275
|
+
...common, kind: 'mismatch', hasTag, hasRelease, blocking: true,
|
|
276
|
+
detail: `GitHub 上有 ${ghNewest} 的发布记录, 但 npm registry 的 latest 还是 ${registryLatest} — 拒绝按 GitHub 的记录安装`,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
if (hasTag || hasRelease) {
|
|
280
|
+
return {
|
|
281
|
+
...common, kind: 'agree', hasTag, hasRelease, blocking: false,
|
|
282
|
+
detail: `npm latest=${registryLatest} 在 GitHub 上有同名记录 (${hasRelease ? `Release v${registryLatest}` : `Tag v${registryLatest}`}) — 两个源指向同一版`,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (allNames.length === 0) {
|
|
286
|
+
return {
|
|
287
|
+
...common, kind: 'no_record_at_all', hasTag: false, hasRelease: false, blocking: false,
|
|
288
|
+
detail: `GitHub 上暂无任何 tag / Release (0 个) — 暂无可交叉校验的记录, npm 仍是权威 (latest=${registryLatest})`,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
...common, kind: 'missing_record', hasTag, hasRelease, blocking: false,
|
|
293
|
+
detail: `npm latest=${registryLatest} 在 GitHub 上没有对应记录 (GitHub 最新版本标签 ${ghNewest || '无'}; Release ${facts.releases.length} 个 / Tag ${facts.tags.length} 个) — 发布记录缺 Tag, 不阻塞 stable 更新`,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function compareDevSnapshots(installedSha, headSha, ref = `refs/heads/${version_info_js_1.DEV_BRANCH}`) {
|
|
297
|
+
const short = (s) => (s ? s.slice(0, 7) : '未知');
|
|
298
|
+
if (!headSha) {
|
|
299
|
+
return { ref, headSha, installedSha, same: false, behind: false, detail: `${ref} 的 HEAD 读不到 — 无法判定 dev 快照新旧` };
|
|
300
|
+
}
|
|
301
|
+
if (!installedSha) {
|
|
302
|
+
return { ref, headSha, installedSha, same: false, behind: false, detail: `当前不是 dev 快照 (stable 安装) — 切到 dev 将得到 ${ref} @ ${short(headSha)}` };
|
|
303
|
+
}
|
|
304
|
+
const same = installedSha.slice(0, 7) === headSha.slice(0, 7);
|
|
305
|
+
return {
|
|
306
|
+
ref, headSha, installedSha, same, behind: !same,
|
|
307
|
+
detail: same
|
|
308
|
+
? `已是最新的 dev 快照 (${ref} @ ${short(headSha)}) — 同一个 commit`
|
|
309
|
+
: `dev 快照落后: 已装 ${short(installedSha)} → master HEAD ${short(headSha)} (按 commit sha 判定, 不看版本号)`,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function defaultRunNpm(args, cwd) {
|
|
313
|
+
const r = (0, child_process_1.spawnSync)('npm', args, { cwd, encoding: 'utf-8', timeout: 900_000, maxBuffer: 32 * 1024 * 1024 });
|
|
314
|
+
return { code: r.status ?? 1, stdout: r.stdout || '', stderr: r.stderr || '' };
|
|
315
|
+
}
|
|
316
|
+
/** 从 GitHub 取 master 的源码快照 (codeload tarball); 解到 destParent。 */
|
|
317
|
+
async function downloadGithubSnapshot(sha, destParent, env, timeoutMs) {
|
|
318
|
+
const template = env.BOLLOON_DEV_TARBALL_URL
|
|
319
|
+
|| `https://codeload.github.com/${version_info_js_1.GITHUB_UPSTREAM_SLUG}/tar.gz/{sha}`;
|
|
320
|
+
const url = template.replace('{sha}', sha).replace('{branch}', version_info_js_1.DEV_BRANCH);
|
|
321
|
+
await fsp.mkdir(destParent, { recursive: true });
|
|
322
|
+
const file = path.join(destParent, `dev-${sha.slice(0, 7)}.tar.gz`);
|
|
323
|
+
try {
|
|
324
|
+
const buf = await new Promise((resolve, reject) => {
|
|
325
|
+
const client = url.startsWith('https') ? https : http;
|
|
326
|
+
const tk = githubToken(env);
|
|
327
|
+
const req = client.get(url, { timeout: timeoutMs, headers: { 'User-Agent': 'bolloon-update', ...(tk ? { Authorization: `Bearer ${tk}` } : {}) } }, (res) => {
|
|
328
|
+
if ((res.statusCode || 0) >= 400) {
|
|
329
|
+
reject(classifyGithubError(null, res.statusCode, res.headers));
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const chunks = [];
|
|
333
|
+
res.on('data', (c) => chunks.push(c));
|
|
334
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
335
|
+
});
|
|
336
|
+
req.on('error', reject);
|
|
337
|
+
req.on('timeout', () => { req.destroy(new Error('timeout')); });
|
|
338
|
+
});
|
|
339
|
+
await fsp.writeFile(file, buf);
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
const cls = e?.kind === 'github_unavailable' ? e : classifyGithubError(e);
|
|
343
|
+
return { ok: false, kind: 'github_unavailable', reason: cls.reason, detail: `取 ${url} 失败: ${cls.detail}` };
|
|
344
|
+
}
|
|
345
|
+
const extract = path.join(destParent, 'src');
|
|
346
|
+
await fsp.mkdir(extract, { recursive: true });
|
|
347
|
+
const tar = (0, child_process_1.spawnSync)('tar', ['-xzf', file, '-C', extract], { encoding: 'utf-8', timeout: 300_000 });
|
|
348
|
+
if (tar.status !== 0)
|
|
349
|
+
return { ok: false, kind: 'github_unavailable', reason: 'http_error', detail: `解压快照失败: ${String(tar.stderr || '').slice(0, 200)}` };
|
|
350
|
+
const kids = (await fsp.readdir(extract)).filter((f) => !f.startsWith('.'));
|
|
351
|
+
if (kids.length !== 1)
|
|
352
|
+
return { ok: false, kind: 'github_unavailable', reason: 'http_error', detail: `快照解压后目录数不是 1 (${kids.length})` };
|
|
353
|
+
return { ok: true, dir: path.join(extract, kids[0]), source: 'github-tarball' };
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* 把 master HEAD 的一个 commit 变成**可安装的 dev 快照 tarball**:
|
|
357
|
+
* 取源码 → 校验 sha (本地源码树必须对得上) → 版本改成 `<base>+dev.<sha7>` → 需要时构建 → npm pack
|
|
358
|
+
*
|
|
359
|
+
* 复用原则 (§5 的刻意偏差): **不另造一套替换机制** —— 产物仍是 tarball, 仍交给 npm 替换,
|
|
360
|
+
* 仍然"切换后验证 + 失败回滚"。这里只负责"从哪个源取、装出来是什么身份"。
|
|
361
|
+
*/
|
|
362
|
+
async function prepareDevSnapshot(opts) {
|
|
363
|
+
const env = opts.env ?? process.env;
|
|
364
|
+
const runNpm = opts.runNpm || defaultRunNpm;
|
|
365
|
+
const stage = (s, d) => { try {
|
|
366
|
+
opts.onStage?.(s, d);
|
|
367
|
+
}
|
|
368
|
+
catch { /* 回调不许影响流程 */ } };
|
|
369
|
+
const sha = String(opts.sha || '').trim();
|
|
370
|
+
if (!/^[0-9a-f]{7,40}$/i.test(sha)) {
|
|
371
|
+
return { ok: false, kind: 'github_unavailable', reason: 'not_found', detail: `master HEAD 的 sha 不合法 (${sha || '空'}) — 拒绝按未知 commit 安装` };
|
|
372
|
+
}
|
|
373
|
+
let dir = '';
|
|
374
|
+
let source = '';
|
|
375
|
+
const envDir = env.BOLLOON_DEV_SOURCE_DIR;
|
|
376
|
+
if (envDir) {
|
|
377
|
+
if (!fs.existsSync(path.join(envDir, 'package.json'))) {
|
|
378
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'source_dir_missing', detail: `BOLLOON_DEV_SOURCE_DIR=${envDir} 下没有 package.json` };
|
|
379
|
+
}
|
|
380
|
+
// 本地源码树必须**真的**是这个 commit —— 否则不许把它当 master HEAD 的快照
|
|
381
|
+
const local = (0, child_process_1.spawnSync)('git', ['-C', envDir, 'rev-parse', 'HEAD'], { encoding: 'utf-8', timeout: 10_000, stdio: ['ignore', 'pipe', 'ignore'] });
|
|
382
|
+
const localSha = (local.stdout || '').trim();
|
|
383
|
+
if (local.status !== 0 || !localSha) {
|
|
384
|
+
if (env.BOLLOON_DEV_ALLOW_UNVERIFIED_SOURCE !== '1') {
|
|
385
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'sha_unverifiable', detail: `${envDir} 不是 git 检出, 无法核对 sha=${sha.slice(0, 7)} (要强制使用请设 BOLLOON_DEV_ALLOW_UNVERIFIED_SOURCE=1)` };
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else if (!localSha.startsWith(sha.slice(0, 7)) && !sha.startsWith(localSha.slice(0, 7))) {
|
|
389
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'sha_mismatch', detail: `${envDir} 的 HEAD 是 ${localSha.slice(0, 7)}, 与 master HEAD ${sha.slice(0, 7)} 不是同一个 commit — 拒绝用错的源码做 dev 快照` };
|
|
390
|
+
}
|
|
391
|
+
dir = envDir;
|
|
392
|
+
source = `local-tree@${(localSha || sha).slice(0, 7)}`;
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
stage('downloading', `取 GitHub master @ ${sha.slice(0, 7)}`);
|
|
396
|
+
const dl = await downloadGithubSnapshot(sha, opts.workDir, env, opts.timeoutMs ?? 120_000);
|
|
397
|
+
if (!dl.ok)
|
|
398
|
+
return dl;
|
|
399
|
+
dir = dl.dir;
|
|
400
|
+
source = dl.source;
|
|
401
|
+
}
|
|
402
|
+
// 身份 = 源码树自己的版本号 + dev.<sha>
|
|
403
|
+
const pkg = (0, version_info_js_1.readPackageAt)(dir);
|
|
404
|
+
if (!pkg?.version)
|
|
405
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'no_version', detail: `${dir}/package.json 读不到版本` };
|
|
406
|
+
const baseVersion = (0, version_info_js_1.baseVersionOf)(String(pkg.version));
|
|
407
|
+
const identity = (0, version_info_js_1.devIdentity)(baseVersion, sha);
|
|
408
|
+
stage('staged', `打上 dev 身份 ${identity}`);
|
|
409
|
+
// 需要时构建 (GitHub tarball 里没有 dist/; 本地树通常已构建)
|
|
410
|
+
let built = false;
|
|
411
|
+
if (!fs.existsSync(path.join(dir, 'dist', 'cli-entry.js'))) {
|
|
412
|
+
stage('staged', '源码树缺少 dist/, 先装依赖再构建 (npm run build:main)');
|
|
413
|
+
if (!fs.existsSync(path.join(dir, 'node_modules'))) {
|
|
414
|
+
/**
|
|
415
|
+
* 验收加速开关: 把已有 node_modules 直接软链进来, 跳过 `npm install` (本仓依赖 889MB)。
|
|
416
|
+
* **只省"装依赖"这一步**, 构建与打包仍然真跑 —— 刻意留给验收脚本用, 别在生产路径上设。
|
|
417
|
+
*/
|
|
418
|
+
const reuse = env.BOLLOON_DEV_REUSE_NODE_MODULES;
|
|
419
|
+
if (reuse && fs.existsSync(path.join(reuse, '.bin'))) {
|
|
420
|
+
stage('staged', `复用现成依赖 (${reuse}) 跳过 npm install`);
|
|
421
|
+
try {
|
|
422
|
+
fs.symlinkSync(reuse, path.join(dir, 'node_modules'), 'dir');
|
|
423
|
+
}
|
|
424
|
+
catch { /* 已存在就跳过 */ }
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
const inst = runNpm(['install', '--no-audit', '--no-fund', '--loglevel=error', '--fetch-retries=5'], dir);
|
|
428
|
+
if (inst.code !== 0) {
|
|
429
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'npm_install_failed', detail: `dev 快照装依赖失败: ${(inst.stderr || inst.stdout).slice(0, 400)}` };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* 从 git 源码树构建要**两步** (真跑踩到的坑):
|
|
435
|
+
* ① `npm run build --workspaces --if-present` —— 先建 workspace 依赖 (@bolloon/constraint-runtime),
|
|
436
|
+
* 否则根包 tsc 会因为 `../constraint-runtime/dist/tools/...` 不存在而直接报 TS2307;
|
|
437
|
+
* ② `npm run build:main` —— 再建根包 (tsc + copy-constraint-runtime)。
|
|
438
|
+
* 原来只跑 ②, 在**干净源码树**上必失败 —— 这个坑只有真从 git 建一次才会暴露。
|
|
439
|
+
*/
|
|
440
|
+
const buildWs = runNpm(['run', 'build', '--workspaces', '--if-present', '--loglevel=error'], dir);
|
|
441
|
+
if (buildWs.code !== 0) {
|
|
442
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'build_failed', detail: `dev 快照构建 workspace 依赖失败: ${(buildWs.stderr || buildWs.stdout).slice(0, 400)}` };
|
|
443
|
+
}
|
|
444
|
+
const build = runNpm(['run', 'build:main'], dir);
|
|
445
|
+
if (build.code !== 0) {
|
|
446
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'build_failed', detail: `dev 快照构建失败: ${(build.stderr || build.stdout).slice(0, 400)}` };
|
|
447
|
+
}
|
|
448
|
+
built = true;
|
|
449
|
+
}
|
|
450
|
+
// 写身份 (改 package.json 的版本身份 + 一个可核对的标记文件)
|
|
451
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
452
|
+
const raw = JSON.parse(await fsp.readFile(pkgPath, 'utf8'));
|
|
453
|
+
raw.version = identity;
|
|
454
|
+
await fsp.writeFile(pkgPath, JSON.stringify(raw, null, 2) + '\n', 'utf8');
|
|
455
|
+
await fsp.writeFile(path.join(dir, '.bolloon-dev-snapshot.json'), JSON.stringify({
|
|
456
|
+
channel: 'dev', ref: `refs/heads/${version_info_js_1.DEV_BRANCH}`, sha, identity, source, built,
|
|
457
|
+
builtAt: new Date().toISOString(),
|
|
458
|
+
warning: version_info_js_1.DEV_CHANNEL_WARNING,
|
|
459
|
+
}, null, 2) + '\n', 'utf8');
|
|
460
|
+
// 打包 (产物仍是 tarball → 交给 npm 替换, 不另造一套)
|
|
461
|
+
const pack = runNpm(['pack', dir, '--pack-destination', opts.workDir, '--loglevel=error'], opts.workDir);
|
|
462
|
+
if (pack.code !== 0) {
|
|
463
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'pack_failed', detail: `dev 快照打包失败: ${(pack.stderr || pack.stdout).slice(0, 400)}` };
|
|
464
|
+
}
|
|
465
|
+
const tgzs = (await fsp.readdir(opts.workDir)).filter((f) => f.endsWith('.tgz') && f.includes('bolloon-agent'));
|
|
466
|
+
if (tgzs.length === 0)
|
|
467
|
+
return { ok: false, kind: 'dev_source_failed', reason: 'no_tarball', detail: 'npm pack 没有产出 tarball' };
|
|
468
|
+
const tarball = path.join(opts.workDir, tgzs.sort()[tgzs.length - 1]);
|
|
469
|
+
return { ok: true, dir, tarball, identity, sha, baseVersion, source, built };
|
|
470
|
+
}
|
|
471
|
+
//# sourceMappingURL=dual-source.js.map
|