@chainlesschain/personal-data-hub 0.4.29 → 0.4.30
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/lib/prompt-builder.js +15 -1
- package/package.json +4 -1
- package/__tests__/adapter-guide.test.js +0 -47
- package/__tests__/adapter-spec.test.js +0 -78
- package/__tests__/adapters/ai-chat-cookie-capture-spec.test.js +0 -211
- package/__tests__/adapters/ai-chat-health-checker.test.js +0 -262
- package/__tests__/adapters/ai-chat-history.test.js +0 -396
- package/__tests__/adapters/ai-chat-http-client.test.js +0 -242
- package/__tests__/adapters/ai-chat-vendors.test.js +0 -874
- package/__tests__/adapters/alipay-bill-adapter.test.js +0 -538
- package/__tests__/adapters/apple-health.test.js +0 -95
- package/__tests__/adapters/bank-family.test.js +0 -125
- package/__tests__/adapters/biz-tianyancha.test.js +0 -159
- package/__tests__/adapters/browser-history-chrome.test.js +0 -377
- package/__tests__/adapters/browser-history-edge.test.js +0 -159
- package/__tests__/adapters/car-mercedesme.test.js +0 -74
- package/__tests__/adapters/doc-baidu-netdisk.test.js +0 -102
- package/__tests__/adapters/doc-camscanner.test.js +0 -147
- package/__tests__/adapters/doc-platforms.test.js +0 -177
- package/__tests__/adapters/edu-huawei-learning-live.test.js +0 -198
- package/__tests__/adapters/edu-zuoyebang-live.test.js +0 -226
- package/__tests__/adapters/email-adapter-snapshot.test.js +0 -237
- package/__tests__/adapters/email-adapter.test.js +0 -742
- package/__tests__/adapters/email-classifier.test.js +0 -347
- package/__tests__/adapters/email-imap-session.test.js +0 -334
- package/__tests__/adapters/email-parser.test.js +0 -244
- package/__tests__/adapters/email-pdf-extractor.test.js +0 -529
- package/__tests__/adapters/email-providers.test.js +0 -84
- package/__tests__/adapters/email-retry-progress.test.js +0 -294
- package/__tests__/adapters/email-templates.test.js +0 -822
- package/__tests__/adapters/family-23-collectors-scaffold.test.js +0 -182
- package/__tests__/adapters/finance-alipay-live.test.js +0 -258
- package/__tests__/adapters/finance-dcep.test.js +0 -74
- package/__tests__/adapters/fitness-joyrun.test.js +0 -82
- package/__tests__/adapters/game-genshin-live.test.js +0 -238
- package/__tests__/adapters/game-genshin-scaffold.test.js +0 -108
- package/__tests__/adapters/game-honor-of-kings-live.test.js +0 -230
- package/__tests__/adapters/git-activity.test.js +0 -222
- package/__tests__/adapters/gov-12123.test.js +0 -103
- package/__tests__/adapters/gov-ixiamen.test.js +0 -150
- package/__tests__/adapters/gov-tax.test.js +0 -135
- package/__tests__/adapters/health-meiyou.test.js +0 -125
- package/__tests__/adapters/local-files.test.js +0 -264
- package/__tests__/adapters/local-im-pc.test.js +0 -154
- package/__tests__/adapters/messaging-whatsapp.test.js +0 -289
- package/__tests__/adapters/music-kugou.test.js +0 -187
- package/__tests__/adapters/music-qq.test.js +0 -112
- package/__tests__/adapters/netease-music-live.test.js +0 -244
- package/__tests__/adapters/netease-music.test.js +0 -74
- package/__tests__/adapters/pc-local-discovery.test.js +0 -141
- package/__tests__/adapters/qq-pc-direct-read.test.js +0 -227
- package/__tests__/adapters/reading-family.test.js +0 -108
- package/__tests__/adapters/recruit-boss.test.js +0 -180
- package/__tests__/adapters/shell-history.test.js +0 -180
- package/__tests__/adapters/shopping-base.test.js +0 -179
- package/__tests__/adapters/shopping-dianping.test.js +0 -239
- package/__tests__/adapters/social-bilibili-adb-api-client.test.js +0 -721
- package/__tests__/adapters/social-bilibili-adb-chromium-cookies-reader.test.js +0 -346
- package/__tests__/adapters/social-bilibili-adb-collector.test.js +0 -284
- package/__tests__/adapters/social-bilibili-adb-cookies-extension.test.js +0 -343
- package/__tests__/adapters/social-bilibili-adb-snapshot-builder.test.js +0 -296
- package/__tests__/adapters/social-csdn.test.js +0 -175
- package/__tests__/adapters/social-dongchedi.test.js +0 -165
- package/__tests__/adapters/social-douyin-adb-aweme-detail.test.js +0 -165
- package/__tests__/adapters/social-douyin-adb-collector.test.js +0 -254
- package/__tests__/adapters/social-douyin-adb-db-extension.test.js +0 -114
- package/__tests__/adapters/social-douyin-adb-im-db-parser.test.js +0 -304
- package/__tests__/adapters/social-douyin-adb-snapshot-builder.test.js +0 -216
- package/__tests__/adapters/social-douyin-adb-usage-profile.test.js +0 -229
- package/__tests__/adapters/social-douyin-adb-watch-history.test.js +0 -269
- package/__tests__/adapters/social-kuaishou-adb-api-client.test.js +0 -496
- package/__tests__/adapters/social-kuaishou-adb-collector.test.js +0 -276
- package/__tests__/adapters/social-kuaishou-adb-cookies-extension.test.js +0 -152
- package/__tests__/adapters/social-kuaishou-adb-snapshot-builder.test.js +0 -178
- package/__tests__/adapters/social-toutiao-adb-account-reader.test.js +0 -135
- package/__tests__/adapters/social-toutiao-adb-api-client.test.js +0 -626
- package/__tests__/adapters/social-toutiao-adb-article.test.js +0 -155
- package/__tests__/adapters/social-toutiao-adb-collector.test.js +0 -378
- package/__tests__/adapters/social-toutiao-adb-cookies-extension.test.js +0 -193
- package/__tests__/adapters/social-toutiao-adb-snapshot-builder.test.js +0 -196
- package/__tests__/adapters/social-toutiao-kuaishou-scaffold.test.js +0 -311
- package/__tests__/adapters/social-weibo-adb-api-client.test.js +0 -362
- package/__tests__/adapters/social-weibo-adb-collector.test.js +0 -201
- package/__tests__/adapters/social-weibo-adb-cookies-extension.test.js +0 -167
- package/__tests__/adapters/social-weibo-adb-snapshot-builder.test.js +0 -189
- package/__tests__/adapters/social-xiaohongshu-adb-api-client.test.js +0 -431
- package/__tests__/adapters/social-xiaohongshu-adb-collector.test.js +0 -207
- package/__tests__/adapters/social-xiaohongshu-adb-cookies-extension.test.js +0 -0
- package/__tests__/adapters/social-xiaohongshu-adb-sign-provider-injection.test.js +0 -351
- package/__tests__/adapters/social-xiaohongshu-adb-sign.test.js +0 -130
- package/__tests__/adapters/social-xiaohongshu-adb-snapshot-builder.test.js +0 -200
- package/__tests__/adapters/social-zhihu.test.js +0 -246
- package/__tests__/adapters/system-data-adapter.test.js +0 -443
- package/__tests__/adapters/system-data-android-ingest.test.js +0 -144
- package/__tests__/adapters/system-data-android.test.js +0 -519
- package/__tests__/adapters/system-data-disclosure.test.js +0 -153
- package/__tests__/adapters/travel-12306.test.js +0 -512
- package/__tests__/adapters/travel-amap.test.js +0 -219
- package/__tests__/adapters/travel-baidu-map.test.js +0 -305
- package/__tests__/adapters/travel-base.test.js +0 -205
- package/__tests__/adapters/travel-ctrip.test.js +0 -377
- package/__tests__/adapters/travel-didi-consumer.test.js +0 -66
- package/__tests__/adapters/travel-didi.test.js +0 -204
- package/__tests__/adapters/travel-tencent-map.test.js +0 -207
- package/__tests__/adapters/travel-tongcheng.test.js +0 -289
- package/__tests__/adapters/video-platforms.test.js +0 -152
- package/__tests__/adapters/video-xigua.test.js +0 -106
- package/__tests__/adapters/vscode.test.js +0 -299
- package/__tests__/adapters/wechat-bootstrap.test.js +0 -240
- package/__tests__/adapters/wechat-env-probe.test.js +0 -162
- package/__tests__/adapters/wechat-frida-agent.test.js +0 -322
- package/__tests__/adapters/wechat-frida-integration.test.js +0 -149
- package/__tests__/adapters/wechat-frida-key-provider.test.js +0 -188
- package/__tests__/adapters/wechat-md5-key-provider.test.js +0 -101
- package/__tests__/adapters/wechat-pc-direct-read.test.js +0 -365
- package/__tests__/adapters/wechat-pc-group-topic.test.js +0 -63
- package/__tests__/adapters/wechat-pc-v4-sidecar.test.js +0 -72
- package/__tests__/adapters/weread.test.js +0 -123
- package/__tests__/adapters/wework-pc.test.js +0 -124
- package/__tests__/adapters/win-recent.test.js +0 -192
- package/__tests__/analysis-skills.test.js +0 -754
- package/__tests__/analysis.test.js +0 -1845
- package/__tests__/audio-ximalaya-snapshot.test.js +0 -279
- package/__tests__/batch.test.js +0 -133
- package/__tests__/bridges-cc-kg.test.js +0 -231
- package/__tests__/bridges-cc-llm.test.js +0 -191
- package/__tests__/bridges-cc-rag.test.js +0 -162
- package/__tests__/categories.test.js +0 -92
- package/__tests__/e2e/ai-chat-cross-source-journey.test.js +0 -213
- package/__tests__/e2e/full-user-journey.test.js +0 -188
- package/__tests__/e2e/local-data-adapters-cli.e2e.test.js +0 -146
- package/__tests__/entity-resolver-ingest-hook.test.js +0 -177
- package/__tests__/entity-resolver-stages.test.js +0 -411
- package/__tests__/entity-resolver-vault.test.js +0 -249
- package/__tests__/entity-resolver.test.js +0 -526
- package/__tests__/fitness-keep-snapshot.test.js +0 -224
- package/__tests__/fixtures/entity-resolver-200-mock.json +0 -96
- package/__tests__/ids.test.js +0 -45
- package/__tests__/integration/ai-chat-history-registry.test.js +0 -228
- package/__tests__/integration/aichat-wizard-end-to-end.test.js +0 -282
- package/__tests__/integration/cross-adapter-pipelines.test.js +0 -396
- package/__tests__/integration/local-data-adapters-pipeline.test.js +0 -373
- package/__tests__/integration/social-bilibili-pipeline.test.js +0 -261
- package/__tests__/integration/wechat-bootstrap-end-to-end.test.js +0 -390
- package/__tests__/key-providers.test.js +0 -126
- package/__tests__/kg-derive.test.js +0 -219
- package/__tests__/llm-client.test.js +0 -122
- package/__tests__/longtail-adapters.test.js +0 -281
- package/__tests__/messaging-qq-snapshot.test.js +0 -294
- package/__tests__/mobile-extractor-encrypted.test.js +0 -460
- package/__tests__/mobile-extractor.test.js +0 -288
- package/__tests__/mock-adapter.test.js +0 -93
- package/__tests__/prompt-builder.test.js +0 -249
- package/__tests__/query-parser.test.js +0 -365
- package/__tests__/rag-derive.test.js +0 -169
- package/__tests__/registry-readiness.test.js +0 -292
- package/__tests__/registry.test.js +0 -420
- package/__tests__/salvage-ingest.test.js +0 -97
- package/__tests__/schemas.test.js +0 -331
- package/__tests__/shopping-adapters.test.js +0 -392
- package/__tests__/shopping-eleme-snapshot.test.js +0 -454
- package/__tests__/shopping-pinduoduo-snapshot.test.js +0 -484
- package/__tests__/shopping-snapshot.test.js +0 -438
- package/__tests__/shopping-vipshop-snapshot.test.js +0 -425
- package/__tests__/shopping-xianyu-snapshot.test.js +0 -451
- package/__tests__/sidecar-contacts-cross-validate.test.js +0 -186
- package/__tests__/sidecar-supervisor.test.js +0 -128
- package/__tests__/sign-providers.test.js +0 -62
- package/__tests__/social-adapters.test.js +0 -280
- package/__tests__/social-bilibili-snapshot.test.js +0 -278
- package/__tests__/social-douban-snapshot.test.js +0 -351
- package/__tests__/social-douyin-im-direct-read.test.js +0 -377
- package/__tests__/social-douyin-salvage-collector.test.js +0 -98
- package/__tests__/social-douyin-salvage-mapper.test.js +0 -90
- package/__tests__/social-douyin-snapshot.test.js +0 -256
- package/__tests__/social-kuaishou-snapshot.test.js +0 -362
- package/__tests__/social-toutiao-snapshot.test.js +0 -366
- package/__tests__/social-weibo-snapshot.test.js +0 -234
- package/__tests__/social-weibo-sqlite-device.test.js +0 -174
- package/__tests__/social-xiaohongshu-snapshot.test.js +0 -232
- package/__tests__/sqlite-leaf-salvage.test.js +0 -97
- package/__tests__/travel-adapters.test.js +0 -483
- package/__tests__/travel-maps-snapshot.test.js +0 -426
- package/__tests__/vault-driver-error.test.js +0 -74
- package/__tests__/vault-search-helpers.test.js +0 -104
- package/__tests__/vault-search.test.js +0 -423
- package/__tests__/vault.test.js +0 -767
- package/__tests__/wechat-adapter.test.js +0 -594
- package/__tests__/whatsapp-adapter.test.js +0 -138
- package/scripts/_make-fixture-all.js +0 -126
- package/scripts/_make-fixture-contacts.js +0 -84
- package/scripts/evaluate-entity-resolver.js +0 -213
- package/scripts/run-native-tests-sandbox.sh +0 -55
- package/scripts/smoke-phase-5-5.js +0 -196
- package/scripts/smoke-phase-5-7.js +0 -181
- package/scripts/smoke-system-data-contacts.js +0 -309
- package/scripts/smoke-system-data.js +0 -312
- package/vitest.config.js +0 -88
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Full system-data smoke / real-device runner — Phase 4.5.7.
|
|
4
|
-
*
|
|
5
|
-
* Drives the full SystemDataAdapter end-to-end across all 4 sources
|
|
6
|
-
* (contacts / calllog / sms / wifi), exercising:
|
|
7
|
-
*
|
|
8
|
-
* - PythonSidecarAdapter base class
|
|
9
|
-
* - SidecarSupervisor lifecycle
|
|
10
|
-
* - SystemDataAdapter.authenticate
|
|
11
|
-
* - 4 sidecar parse_* methods
|
|
12
|
-
* - per-entity hub-side UnifiedSchema validation
|
|
13
|
-
* - dataDisclosure metadata sanitization
|
|
14
|
-
*
|
|
15
|
-
* Replaces the contacts-only `smoke-system-data-contacts.js`. The older
|
|
16
|
-
* script remains for users who only want to exercise the Phase 4.5.2 slice.
|
|
17
|
-
*
|
|
18
|
-
* Usage:
|
|
19
|
-
*
|
|
20
|
-
* # Offline mode — pre-extracted host files (no ADB)
|
|
21
|
-
* node scripts/smoke-system-data.js \
|
|
22
|
-
* --contacts-db ./fixtures/contacts2.db \
|
|
23
|
-
* --calllog-db ./fixtures/contacts2.db \
|
|
24
|
-
* --wifi-dir ./fixtures/wifi/
|
|
25
|
-
*
|
|
26
|
-
* # Live device, /sdcard workaround (non-root)
|
|
27
|
-
* node scripts/smoke-system-data.js \
|
|
28
|
-
* --serial 24115RA8ECabc123 --extract-mode sdcard
|
|
29
|
-
*
|
|
30
|
-
* # Live device with adb root
|
|
31
|
-
* node scripts/smoke-system-data.js --serial 24115RA8ECabc123
|
|
32
|
-
*
|
|
33
|
-
* # Include SMS (default off — explicit opt-in for legality)
|
|
34
|
-
* node scripts/smoke-system-data.js --serial XYZ --extract-mode sdcard --include sms
|
|
35
|
-
*
|
|
36
|
-
* # Disable contacts but include sms
|
|
37
|
-
* node scripts/smoke-system-data.js --db ... --include sms --exclude contacts
|
|
38
|
-
*
|
|
39
|
-
* Exit codes:
|
|
40
|
-
* 0 success
|
|
41
|
-
* 1 sidecar / hub error
|
|
42
|
-
* 2 invalid entities (schema validation failed)
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
"use strict";
|
|
46
|
-
|
|
47
|
-
const path = require("node:path");
|
|
48
|
-
const fs = require("node:fs");
|
|
49
|
-
const os = require("node:os");
|
|
50
|
-
|
|
51
|
-
const { SidecarSupervisor } = require("../lib/sidecar");
|
|
52
|
-
const {
|
|
53
|
-
SystemDataAdapter,
|
|
54
|
-
sanitizeInclude,
|
|
55
|
-
DEFAULT_INCLUDE,
|
|
56
|
-
} = require("../lib/adapters/system-data");
|
|
57
|
-
const { validate } = require("../lib/schemas");
|
|
58
|
-
|
|
59
|
-
const SIDECAR_ROOT = path.resolve(__dirname, "..", "..", "personal-data-hub-bridge");
|
|
60
|
-
const PYTHON = process.env.FORENSICS_BRIDGE_PYTHON || "python";
|
|
61
|
-
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
|
|
64
|
-
function parseArgs(argv) {
|
|
65
|
-
const out = {
|
|
66
|
-
serial: null,
|
|
67
|
-
extractMode: "normal",
|
|
68
|
-
dataPaths: {},
|
|
69
|
-
include: [],
|
|
70
|
-
exclude: [],
|
|
71
|
-
list: false,
|
|
72
|
-
outDir: null,
|
|
73
|
-
help: false,
|
|
74
|
-
};
|
|
75
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
76
|
-
const a = argv[i];
|
|
77
|
-
switch (a) {
|
|
78
|
-
case "--serial": out.serial = argv[++i]; break;
|
|
79
|
-
case "--extract-mode": out.extractMode = argv[++i]; break;
|
|
80
|
-
case "--contacts-db": out.dataPaths.contacts = path.resolve(argv[++i]); break;
|
|
81
|
-
case "--calllog-db": out.dataPaths.calllog = path.resolve(argv[++i]); break;
|
|
82
|
-
case "--sms-db": out.dataPaths.sms = path.resolve(argv[++i]); break;
|
|
83
|
-
case "--wifi-dir": out.dataPaths.wifi = path.resolve(argv[++i]); break;
|
|
84
|
-
case "--include": out.include.push(argv[++i]); break;
|
|
85
|
-
case "--exclude": out.exclude.push(argv[++i]); break;
|
|
86
|
-
case "--list": out.list = true; break;
|
|
87
|
-
case "--out": out.outDir = argv[++i]; break;
|
|
88
|
-
case "-h": case "--help": out.help = true; break;
|
|
89
|
-
default:
|
|
90
|
-
if (a.startsWith("--")) throw new Error(`unknown flag: ${a}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return out;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function printHelp() {
|
|
97
|
-
process.stdout.write(`
|
|
98
|
-
smoke-system-data — drive SystemDataAdapter end-to-end for all 4 sources.
|
|
99
|
-
|
|
100
|
-
Modes (mutually exclusive):
|
|
101
|
-
Pre-extracted (offline):
|
|
102
|
-
--contacts-db <path> contacts2.db on disk
|
|
103
|
-
--calllog-db <path> calls db on disk (may be same as --contacts-db)
|
|
104
|
-
--sms-db <path> mmssms.db on disk
|
|
105
|
-
--wifi-dir <path> directory with WifiConfigStore.xml / wpa_supplicant.conf
|
|
106
|
-
|
|
107
|
-
Live device (ADB):
|
|
108
|
-
--serial <serial> target device
|
|
109
|
-
--extract-mode normal pull from /data/data (requires adb root)
|
|
110
|
-
--extract-mode sdcard pull from /sdcard/Download/ (Termux+tsu workaround)
|
|
111
|
-
|
|
112
|
-
Source gating:
|
|
113
|
-
--include <key> force-enable a source (key: contacts/calllog/sms/wifi)
|
|
114
|
-
--exclude <key> force-disable a source
|
|
115
|
-
(defaults per adapter.dataDisclosure: contacts=on / calllog=on / sms=OFF / wifi=on)
|
|
116
|
-
|
|
117
|
-
Misc:
|
|
118
|
-
--list list ADB devices and exit
|
|
119
|
-
--out <dir> output directory (default: ./out/<timestamp>)
|
|
120
|
-
-h, --help show this help
|
|
121
|
-
|
|
122
|
-
Env:
|
|
123
|
-
FORENSICS_BRIDGE_PYTHON python interpreter (default: python)
|
|
124
|
-
`);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function timestampSlug() {
|
|
128
|
-
const d = new Date();
|
|
129
|
-
const z = (n) => String(n).padStart(2, "0");
|
|
130
|
-
return `${d.getFullYear()}${z(d.getMonth() + 1)}${z(d.getDate())}-${z(d.getHours())}${z(d.getMinutes())}${z(d.getSeconds())}`;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function log(level, msg, extra = {}) {
|
|
134
|
-
const line = JSON.stringify({ ts: new Date().toISOString(), level, msg, ...extra });
|
|
135
|
-
if (level === "error") process.stderr.write(line + "\n");
|
|
136
|
-
else process.stdout.write(line + "\n");
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function resolveInclude(args) {
|
|
140
|
-
const include = { ...DEFAULT_INCLUDE };
|
|
141
|
-
for (const k of args.include) {
|
|
142
|
-
if (!Object.prototype.hasOwnProperty.call(include, k)) {
|
|
143
|
-
throw new Error(`unknown source for --include: ${k}`);
|
|
144
|
-
}
|
|
145
|
-
include[k] = true;
|
|
146
|
-
}
|
|
147
|
-
for (const k of args.exclude) {
|
|
148
|
-
if (!Object.prototype.hasOwnProperty.call(include, k)) {
|
|
149
|
-
throw new Error(`unknown source for --exclude: ${k}`);
|
|
150
|
-
}
|
|
151
|
-
include[k] = false;
|
|
152
|
-
}
|
|
153
|
-
return sanitizeInclude(include);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
|
|
158
|
-
async function main(rawArgs) {
|
|
159
|
-
let args;
|
|
160
|
-
try {
|
|
161
|
-
args = parseArgs(rawArgs);
|
|
162
|
-
} catch (err) {
|
|
163
|
-
console.error(err.message);
|
|
164
|
-
printHelp();
|
|
165
|
-
process.exit(2);
|
|
166
|
-
}
|
|
167
|
-
if (args.help) { printHelp(); return; }
|
|
168
|
-
|
|
169
|
-
const outDir = path.resolve(args.outDir || path.join(process.cwd(), "out", timestampSlug()));
|
|
170
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
171
|
-
log("info", "output directory ready", { outDir });
|
|
172
|
-
|
|
173
|
-
const supervisor = new SidecarSupervisor({
|
|
174
|
-
command: PYTHON,
|
|
175
|
-
args: ["-u", "-m", "forensics_bridge.ipc_server"],
|
|
176
|
-
cwd: SIDECAR_ROOT,
|
|
177
|
-
healthCheckIntervalMs: 0,
|
|
178
|
-
env: { PYTHONPATH: SIDECAR_ROOT },
|
|
179
|
-
});
|
|
180
|
-
supervisor.on("log", (line) => process.stderr.write(`[sidecar] ${line}\n`));
|
|
181
|
-
|
|
182
|
-
await supervisor.start({ readyTimeoutMs: 10_000 });
|
|
183
|
-
log("info", "sidecar ready");
|
|
184
|
-
|
|
185
|
-
const adapter = new SystemDataAdapter({ supervisor });
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
if (args.list) {
|
|
189
|
-
const devices = await supervisor.invoke("android.list_devices");
|
|
190
|
-
console.log(JSON.stringify(devices, null, 2));
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const include = resolveInclude(args);
|
|
195
|
-
log("info", "include resolved", include);
|
|
196
|
-
|
|
197
|
-
// 1. authenticate
|
|
198
|
-
const auth = await adapter.authenticate({
|
|
199
|
-
dataPaths: Object.keys(args.dataPaths).length ? args.dataPaths : undefined,
|
|
200
|
-
serial: args.serial || undefined,
|
|
201
|
-
});
|
|
202
|
-
log("info", "authenticated", auth);
|
|
203
|
-
if (!auth.ok) {
|
|
204
|
-
log("error", "authentication failed", auth);
|
|
205
|
-
process.exit(1);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// 2. drain sync stream + validate every entity
|
|
209
|
-
const entitiesByType = { person: [], event: [], place: [], item: [], topic: [] };
|
|
210
|
-
const invalid = [];
|
|
211
|
-
let total = 0;
|
|
212
|
-
const t0 = Date.now();
|
|
213
|
-
|
|
214
|
-
const scratchDir = path.join(outDir, "scratch");
|
|
215
|
-
fs.mkdirSync(scratchDir, { recursive: true });
|
|
216
|
-
|
|
217
|
-
const progressEvents = [];
|
|
218
|
-
for await (const raw of adapter.sync({
|
|
219
|
-
include,
|
|
220
|
-
serial: args.serial || undefined,
|
|
221
|
-
extractMode: args.extractMode,
|
|
222
|
-
dataPaths: Object.keys(args.dataPaths).length ? args.dataPaths : undefined,
|
|
223
|
-
scratchDir,
|
|
224
|
-
onProgress: (msg) => {
|
|
225
|
-
progressEvents.push(msg);
|
|
226
|
-
if (msg.phase === "progress") return; // too chatty
|
|
227
|
-
log("info", `adapter:${msg.source}`, msg);
|
|
228
|
-
},
|
|
229
|
-
})) {
|
|
230
|
-
total += 1;
|
|
231
|
-
const bucket = entitiesByType[raw.entityType];
|
|
232
|
-
if (bucket) bucket.push(raw.payload);
|
|
233
|
-
|
|
234
|
-
// Cross-source schema validation
|
|
235
|
-
const v = validate(raw.payload);
|
|
236
|
-
if (!v.valid) {
|
|
237
|
-
invalid.push({
|
|
238
|
-
id: raw.payload && raw.payload.id,
|
|
239
|
-
entityType: raw.entityType,
|
|
240
|
-
errors: v.errors,
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
const wallMs = Date.now() - t0;
|
|
245
|
-
|
|
246
|
-
log("info", "sync drained", {
|
|
247
|
-
wallMs,
|
|
248
|
-
total,
|
|
249
|
-
persons: entitiesByType.person.length,
|
|
250
|
-
events: entitiesByType.event.length,
|
|
251
|
-
places: entitiesByType.place.length,
|
|
252
|
-
invalidCount: invalid.length,
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
if (invalid.length) {
|
|
256
|
-
log("error", "validation failed", { count: invalid.length });
|
|
257
|
-
fs.writeFileSync(
|
|
258
|
-
path.join(outDir, "validation-errors.json"),
|
|
259
|
-
JSON.stringify(invalid, null, 2),
|
|
260
|
-
);
|
|
261
|
-
process.exitCode = 2;
|
|
262
|
-
} else {
|
|
263
|
-
log("info", "all entities passed UnifiedSchema validation");
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// 3. write per-source NormalizedBatch JSON dumps for inspection
|
|
267
|
-
const dump = {
|
|
268
|
-
schemaVersion: "0.1.0",
|
|
269
|
-
generatedAt: new Date().toISOString(),
|
|
270
|
-
adapter: "system-data",
|
|
271
|
-
adapterVersion: adapter.version,
|
|
272
|
-
include,
|
|
273
|
-
input: {
|
|
274
|
-
serial: args.serial || null,
|
|
275
|
-
extractMode: args.extractMode,
|
|
276
|
-
dataPaths: args.dataPaths,
|
|
277
|
-
},
|
|
278
|
-
wallMs,
|
|
279
|
-
totals: {
|
|
280
|
-
persons: entitiesByType.person.length,
|
|
281
|
-
events: entitiesByType.event.length,
|
|
282
|
-
places: entitiesByType.place.length,
|
|
283
|
-
invalid: invalid.length,
|
|
284
|
-
},
|
|
285
|
-
progressEvents,
|
|
286
|
-
persons: entitiesByType.person,
|
|
287
|
-
events: entitiesByType.event,
|
|
288
|
-
places: entitiesByType.place,
|
|
289
|
-
};
|
|
290
|
-
const dumpPath = path.join(outDir, "system-data-batch.json");
|
|
291
|
-
fs.writeFileSync(dumpPath, JSON.stringify(dump, null, 2));
|
|
292
|
-
log("info", "wrote dump", { dumpPath, bytes: fs.statSync(dumpPath).size });
|
|
293
|
-
|
|
294
|
-
log("info", "summary", {
|
|
295
|
-
total,
|
|
296
|
-
persons: entitiesByType.person.length,
|
|
297
|
-
events: entitiesByType.event.length,
|
|
298
|
-
places: entitiesByType.place.length,
|
|
299
|
-
invalid: invalid.length,
|
|
300
|
-
wallMs,
|
|
301
|
-
outDir,
|
|
302
|
-
});
|
|
303
|
-
} finally {
|
|
304
|
-
await supervisor.stop({ graceMs: 2000 });
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
main(process.argv.slice(2)).catch((err) => {
|
|
309
|
-
log("error", "fatal", { name: err.name, message: err.message, code: err.code });
|
|
310
|
-
if (err.stack) process.stderr.write(err.stack + "\n");
|
|
311
|
-
process.exit(1);
|
|
312
|
-
});
|
package/vitest.config.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
import { defineConfig, configDefaults } from "vitest/config";
|
|
3
|
-
|
|
4
|
-
const require = createRequire(import.meta.url);
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Probe once at config load whether the native SQLCipher driver
|
|
8
|
-
* (better-sqlite3-multiple-ciphers / "bs3mc") loads on the *host* Node.
|
|
9
|
-
*
|
|
10
|
-
* Why this matters locally: the root node_modules bs3mc binding is built for
|
|
11
|
-
* Electron (NODE_MODULE_VERSION 140) and does NOT match a plain host Node
|
|
12
|
-
* (e.g. ABI 127). Any test that opens a LocalVault then throws an ABI-mismatch
|
|
13
|
-
* error at construction time, which surfaces as a cascade of ~228 cryptic
|
|
14
|
-
* red failures (most as `Cannot destructure property 'vault' of undefined`,
|
|
15
|
-
* because per-file setup helpers swallow the throw and return undefined).
|
|
16
|
-
*
|
|
17
|
-
* That noise drowns out any *real* regression locally. So: when the host
|
|
18
|
-
* binding doesn't load, we EXCLUDE the vault-dependent test files and print a
|
|
19
|
-
* banner pointing at the sandbox runner that installs a host-ABI bs3mc.
|
|
20
|
-
*
|
|
21
|
-
* CI is unaffected — it rebuilds node_modules fresh for the host Node, the
|
|
22
|
-
* probe succeeds, nothing is excluded, and the full suite runs.
|
|
23
|
-
*
|
|
24
|
-
* See: scripts/run-native-tests-sandbox.sh, memory `bs3mc_electron_abi_sandbox_workaround`.
|
|
25
|
-
*/
|
|
26
|
-
function probeNativeVault() {
|
|
27
|
-
try {
|
|
28
|
-
const Database = require("better-sqlite3-multiple-ciphers");
|
|
29
|
-
const db = new Database(":memory:");
|
|
30
|
-
db.close();
|
|
31
|
-
return { available: true, reason: null };
|
|
32
|
-
} catch (err) {
|
|
33
|
-
return { available: false, reason: (err && err.message ? err.message : String(err)).split("\n")[0] };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Tests that open a LocalVault (directly or transitively via registry /
|
|
39
|
-
* entity-resolver / analysis / e2e / integration pipelines). Empirically the
|
|
40
|
-
* exact set that fails when bs3mc can't load on the host. Skipped locally,
|
|
41
|
-
* always run in CI. Keep in sync if you add a new vault-touching test file.
|
|
42
|
-
*/
|
|
43
|
-
const NATIVE_DEPENDENT_TESTS = [
|
|
44
|
-
"__tests__/vault.test.js",
|
|
45
|
-
"__tests__/vault-search.test.js",
|
|
46
|
-
"__tests__/registry.test.js",
|
|
47
|
-
"__tests__/analysis.test.js",
|
|
48
|
-
"__tests__/analysis-skills.test.js",
|
|
49
|
-
"__tests__/entity-resolver.test.js",
|
|
50
|
-
"__tests__/entity-resolver-stages.test.js",
|
|
51
|
-
"__tests__/entity-resolver-vault.test.js",
|
|
52
|
-
"__tests__/entity-resolver-ingest-hook.test.js",
|
|
53
|
-
"__tests__/e2e/full-user-journey.test.js",
|
|
54
|
-
"__tests__/e2e/ai-chat-cross-source-journey.test.js",
|
|
55
|
-
"__tests__/integration/cross-adapter-pipelines.test.js",
|
|
56
|
-
"__tests__/integration/ai-chat-history-registry.test.js",
|
|
57
|
-
"__tests__/integration/social-bilibili-pipeline.test.js",
|
|
58
|
-
"__tests__/integration/wechat-bootstrap-end-to-end.test.js",
|
|
59
|
-
];
|
|
60
|
-
|
|
61
|
-
const native = probeNativeVault();
|
|
62
|
-
const exclude = [...configDefaults.exclude];
|
|
63
|
-
|
|
64
|
-
if (!native.available) {
|
|
65
|
-
exclude.push(...NATIVE_DEPENDENT_TESTS);
|
|
66
|
-
// eslint-disable-next-line no-console
|
|
67
|
-
console.warn(
|
|
68
|
-
[
|
|
69
|
-
"",
|
|
70
|
-
"⚠️ PDH: native SQLCipher driver (bs3mc) does not load on this host Node —",
|
|
71
|
-
" " + (native.reason || "unknown load failure"),
|
|
72
|
-
" Skipping " + NATIVE_DEPENDENT_TESTS.length + " vault-dependent test file(s) so the rest stay green.",
|
|
73
|
-
" For full native coverage run: bash scripts/run-native-tests-sandbox.sh",
|
|
74
|
-
" (CI rebuilds bs3mc for the host ABI and runs the full suite.)",
|
|
75
|
-
"",
|
|
76
|
-
].join("\n"),
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export default defineConfig({
|
|
81
|
-
test: {
|
|
82
|
-
globals: false,
|
|
83
|
-
environment: "node",
|
|
84
|
-
include: ["__tests__/**/*.test.js"],
|
|
85
|
-
exclude,
|
|
86
|
-
testTimeout: 10000,
|
|
87
|
-
},
|
|
88
|
-
});
|