chainlesschain 0.157.2 → 0.157.4
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/package.json +2 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CNyKzbBw.js → ActionButton-CwL5V4rk.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BZUBYH80.js → Analytics-BlsG3Nvq.js} +1 -1
- package/src/assets/web-panel/assets/AppLayout-CDW-fEBB.css +1 -0
- package/src/assets/web-panel/assets/AppLayout-bQJ6NJkS.js +1 -0
- package/src/assets/web-panel/assets/Backup-CKjf2R2f.js +1 -0
- package/src/assets/web-panel/assets/{BaseInput-Ck9Kjams.js → BaseInput-nL30Uqw9.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DyoI0cWX.js → Chat-CArgL-BR.js} +2 -2
- package/src/assets/web-panel/assets/{Checkbox-yEvLzLd8.js → Checkbox-C2UDDSs8.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CQ11Dnmt.js → Col-B7ocl9Ww.js} +1 -1
- package/src/assets/web-panel/assets/Community-BRYhwndT.js +1 -0
- package/src/assets/web-panel/assets/{Compact-Bmf5Cuzh.js → Compact-Dya_aHuV.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CbAGA5A5.js → Cowork-Jz5Q55Gv.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CwbLFJdF.js → Cron-DbD6XGF3.js} +2 -2
- package/src/assets/web-panel/assets/Crosschain-DThGgQk8.css +1 -0
- package/src/assets/web-panel/assets/Crosschain-Dtu8IMai.js +1 -0
- package/src/assets/web-panel/assets/{DID-Bz-Q7RAn.js → DID-BxckhNcy.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DxyAGNxR.js → Dashboard-C8vWq_IC.js} +1 -1
- package/src/assets/web-panel/assets/{Dropdown-B3gLO6AH.js → Dropdown-Bjndts_O.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DR8WMkWL.js → FormItemContext-bOF0FL5N.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Bo6SJajL.js → Git-BtH4vugY.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Dr7X3CJz.js → KnowledgeGraph-CauuWTCg.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BNA4XGT-.js → Logs-DCfoGLWg.js} +1 -1
- package/src/assets/web-panel/assets/Marketplace-B-4uYu_j.css +1 -0
- package/src/assets/web-panel/assets/Marketplace-BNv5w-8n.js +1 -0
- package/src/assets/web-panel/assets/{McpTools-D10LT5nQ.js → McpTools-vh8oeQ_N.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-BpGVVsGn.js → Memory-B-BtLRWD.js} +2 -2
- package/src/assets/web-panel/assets/{Notes-DRwg9537.js → Notes-D-V-KW8L.js} +2 -2
- package/src/assets/web-panel/assets/{Organization-DcyIwloj.js → Organization-DE_QjJF0.js} +3 -3
- package/src/assets/web-panel/assets/{Overflow-MuWktKcP.js → Overflow-CvGooyM4.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-Ci1QXDFH.js → P2P-bmQWjcTu.js} +2 -2
- package/src/assets/web-panel/assets/{Permissions-Rdt6O8t8.js → Permissions-C0kqPJfm.js} +3 -3
- package/src/assets/web-panel/assets/{ProjectSettings-DhYrRsiw.js → ProjectSettings-DRqY-cna.js} +1 -1
- package/src/assets/web-panel/assets/{Projects-BHSVUn-P.js → Projects-C9N8_IbI.js} +2 -2
- package/src/assets/web-panel/assets/{Providers-D7Yf3Eh5.js → Providers-D_UuBLoY.js} +1 -1
- package/src/assets/web-panel/assets/{Row-C4W6kn-O.js → Row-B_nOQOCt.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BRRNqE6z.js → RssFeed-C7pFhGvD.js} +3 -3
- package/src/assets/web-panel/assets/{Security-yVk1t4NG.js → Security-C81wAGw7.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DqtefZh8.js → Services-CXO09HRi.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-B8DP7HAQ.js → Skeleton-pzCg9Pnc.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Dm_T9KJy.js → Skills-0AKMVnae.js} +1 -1
- package/src/assets/web-panel/assets/{Tasks-C66psb8Z.js → Tasks-BobOO2E9.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BEnkhJFe.js → Templates-CDjBR3fZ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BHYwMCjE.js → Trigger-Bvwds95J.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DucGsoXn.js → VideoEditing-DF_v4mGP.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BEnL0gxM.js → Wallet-By5UwKVh.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BZ3njvle.js → WebAuthn-BwVVXAv2.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-DNG6cJRJ.js → WorkflowEditor-5U7bQ2W8.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CruxFUlV.js → colors-umO_4d2G.js} +1 -1
- package/src/assets/web-panel/assets/community-parser-CO25nZFt.js +3 -0
- package/src/assets/web-panel/assets/{compact-item-DGL0Q_YX.js → compact-item-DQizAYSA.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-Z0XEM4Cq.js → createContext-B4cgNOPl.js} +1 -1
- package/src/assets/web-panel/assets/{hasIn-Km8uZit7.js → hasIn-BlpjKJek.js} +1 -1
- package/src/assets/web-panel/assets/icons-C0xSkzug.js +57 -0
- package/src/assets/web-panel/assets/{index-DuQBpo_N.js → index-0Kan5LKq.js} +2 -2
- package/src/assets/web-panel/assets/{index-D7hqt7jp.js → index-8iWNplHD.js} +1 -1
- package/src/assets/web-panel/assets/{index-C6qy-Zu-.js → index-BBXgHH-n.js} +1 -1
- package/src/assets/web-panel/assets/{index-BO1I7Jar.js → index-BFCm-ez3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDw_V2Ts.js → index-BLSfu07o.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2IHkqnY.js → index-BWQQnruX.js} +2 -2
- package/src/assets/web-panel/assets/{index-3KWzfh6j.js → index-BjshxRqs.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0iFuZHn.js → index-Bpn272aB.js} +1 -1
- package/src/assets/web-panel/assets/index-BqEMjyrg.js +1 -0
- package/src/assets/web-panel/assets/{index-C0ngZOEr.js → index-BrLgYcYw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGvUENNM.js → index-Bxa12jHB.js} +1 -1
- package/src/assets/web-panel/assets/{index-CR7JroGW.js → index-BxkDaXvc.js} +1 -1
- package/src/assets/web-panel/assets/{index-But1z4eV.js → index-BzatTiIv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqOFRJpD.js → index-C-24swjx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFJYxODK.js → index-C-ri0NGO.js} +1 -1
- package/src/assets/web-panel/assets/index-C1kMaz6E.js +1 -0
- package/src/assets/web-panel/assets/{index-DoHOmopo.js → index-CHFoDNQ0.js} +2 -2
- package/src/assets/web-panel/assets/{index-Crtf8JqT.js → index-CUBfNblp.js} +2 -2
- package/src/assets/web-panel/assets/{index--i0DkVXq.js → index-CUqnZufL.js} +1 -1
- package/src/assets/web-panel/assets/{index-5Jby7AnF.js → index-CbEcq7vH.js} +1 -1
- package/src/assets/web-panel/assets/{index-g30p4eci.js → index-Cf_9fnbE.js} +1 -1
- package/src/assets/web-panel/assets/{index-N7lOpMHe.js → index-CmnzbK4b.js} +1 -1
- package/src/assets/web-panel/assets/{index-bUf23fPj.js → index-CqwDvOkw.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7vymjCu.js → index-Cqykb9ZW.js} +1 -1
- package/src/assets/web-panel/assets/{index-pbblwkTP.js → index-DF_WAwo2.js} +1 -1
- package/src/assets/web-panel/assets/index-DKyOq7hH.js +36 -0
- package/src/assets/web-panel/assets/{index-BhFkrt3P.js → index-DXYL4L2w.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9UU-ZOL.js → index-DbN_ZPnl.js} +1 -1
- package/src/assets/web-panel/assets/{index-ROop7jDs.js → index-DtPNcQ4n.js} +1 -1
- package/src/assets/web-panel/assets/{index-vfJ5N9Wn.js → index-Ho9akU7U.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWvztGRz.js → index-LUf68SrL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DR4nFehS.js → index-ZPIbAiEU.js} +1 -1
- package/src/assets/web-panel/assets/{index-93dWGD7J.js → index-g91q-v6w.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWjdRkPO.js → index-lUKzY82L.js} +2 -2
- package/src/assets/web-panel/assets/{index-DHWpBglQ.js → index-mHBrdFck.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dgiq6kNf.js → index-oC0OINzs.js} +2 -2
- package/src/assets/web-panel/assets/{index-CoBBNzIM.js → index-ug3GpVu7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DApPTzuh.js → index-uzrAZgzY.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-eEPfzAfC.js → initDefaultProps-D7cer4hW.js} +1 -1
- package/src/assets/web-panel/assets/{motion-xnRaf7sL.js → motion-CnElQ3Xy.js} +1 -1
- package/src/assets/web-panel/assets/{move-CpDkwenV.js → move-dvqokDN1.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B7Nb8KI8.js → omit-DYHi-pbs.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BYHnT8J9.js → pickAttrs-DUC9etdU.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-lfdL5TRx.js → placementArrow-CZyEeX_l.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CMAMO-tl.js → responsiveObserve-CAycKNvy.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Dr-GHujf.js → slide-BAObbkl7.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CGJ1hNOe.js → statusUtils-Bu8BSzrG.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-jwEBpTKF.js → styleChecker-CnYmg0_G.js} +1 -1
- package/src/assets/web-panel/assets/{transition-gUK896vh.js → transition-8JSy_yCb.js} +1 -1
- package/src/assets/web-panel/assets/{useConfigInject-DBxKPWDc.js → useConfigInject-CypxEK_1.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CckP5k1m.js → useFlexGapSupport-Ckda3t4R.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Dcul1jVV.js → vnode-BE-GtqXI.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DaF2prgS.js → zoom-5CInnogB.js} +1 -1
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/db.js +324 -158
- package/src/assets/web-panel/assets/AppLayout-Cvl5XUEL.js +0 -1
- package/src/assets/web-panel/assets/AppLayout-DbK0-so_.css +0 -1
- package/src/assets/web-panel/assets/Backup-CyZlJ_l8.js +0 -1
- package/src/assets/web-panel/assets/Community-Ccn1BYio.js +0 -3
- package/src/assets/web-panel/assets/icons-C40taSZA.js +0 -57
- package/src/assets/web-panel/assets/index-BGsbbo5Y.js +0 -1
- package/src/assets/web-panel/assets/index-DoSx4Q_p.js +0 -1
- package/src/assets/web-panel/assets/index-xcQ2VcES.js +0 -36
package/src/commands/db.js
CHANGED
|
@@ -5,11 +5,286 @@
|
|
|
5
5
|
|
|
6
6
|
import ora from "ora";
|
|
7
7
|
import chalk from "chalk";
|
|
8
|
+
import { createRequire } from "module";
|
|
8
9
|
import { logger } from "../lib/logger.js";
|
|
9
10
|
import { bootstrap, shutdown } from "../runtime/bootstrap.js";
|
|
10
11
|
|
|
12
|
+
const requireCjs = createRequire(import.meta.url);
|
|
11
13
|
const quoteIdent = (name) => `"${String(name).replace(/"/g, '""')}"`;
|
|
12
14
|
|
|
15
|
+
// SQLite driver loader for db check/repair. Cascades: native → wasm.
|
|
16
|
+
// Native (better-sqlite3) is fast but needs prebuilt binaries — fails on
|
|
17
|
+
// Apple Silicon w/o prebuilds, musl Linux, and some Node-version drift.
|
|
18
|
+
// WASM (sql.js) is pure JS+WASM, slower but always loadable.
|
|
19
|
+
// Inlined here rather than imported from core-db because the published
|
|
20
|
+
// @chainlesschain/core-db@0.1.0 doesn't export its loader; bumping core-db
|
|
21
|
+
// would have wider ripple, so we duplicate the cascade locally.
|
|
22
|
+
async function loadAnyDriver() {
|
|
23
|
+
for (const pkg of ["better-sqlite3-multiple-ciphers", "better-sqlite3"]) {
|
|
24
|
+
try {
|
|
25
|
+
const Database = requireCjs(pkg);
|
|
26
|
+
const probe = new Database(":memory:");
|
|
27
|
+
probe.close();
|
|
28
|
+
return { kind: "native", name: pkg, Database };
|
|
29
|
+
} catch (_e) {
|
|
30
|
+
/* try next */
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const initSqlJs = requireCjs("sql.js");
|
|
35
|
+
const SQL = await initSqlJs();
|
|
36
|
+
return { kind: "wasm", name: "sql.js", SQL };
|
|
37
|
+
} catch (_e) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Run integrity check. Normalizes both driver shapes to { ok, diagnostics }.
|
|
43
|
+
// native: db.pragma("integrity_check") → [{integrity_check: "ok"}] or [{integrity_check: "*** in db ***\n..."}]
|
|
44
|
+
// wasm: db.exec("PRAGMA integrity_check") → [{columns: [...], values: [["ok"]]}]
|
|
45
|
+
async function runIntegrityCheck(driver, dbPath, checkName) {
|
|
46
|
+
const fs = requireCjs("fs");
|
|
47
|
+
if (driver.kind === "native") {
|
|
48
|
+
const conn = new driver.Database(dbPath, {
|
|
49
|
+
readonly: true,
|
|
50
|
+
fileMustExist: true,
|
|
51
|
+
});
|
|
52
|
+
const rows = conn.pragma(checkName);
|
|
53
|
+
conn.close();
|
|
54
|
+
const lines = rows.map((r) => (r && r[checkName]) || JSON.stringify(r));
|
|
55
|
+
return {
|
|
56
|
+
ok: lines.length === 1 && lines[0] === "ok",
|
|
57
|
+
diagnostics: lines,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const buf = fs.readFileSync(dbPath);
|
|
61
|
+
const conn = new driver.SQL.Database(buf);
|
|
62
|
+
let res;
|
|
63
|
+
try {
|
|
64
|
+
res = conn.exec(`PRAGMA ${checkName}`);
|
|
65
|
+
} finally {
|
|
66
|
+
conn.close();
|
|
67
|
+
}
|
|
68
|
+
const lines = (res[0]?.values || []).map((v) => String(v[0]));
|
|
69
|
+
return {
|
|
70
|
+
ok: lines.length === 1 && lines[0] === "ok",
|
|
71
|
+
diagnostics: lines,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Best-effort row salvage. Handles both native and wasm drivers.
|
|
76
|
+
// onTable(name, copied, lost, err?) is called for each table for live progress.
|
|
77
|
+
// Returns { stats: {tables, rowsCopied, rowsLost, schemasFailed} }.
|
|
78
|
+
async function salvageDatabase(driver, srcPath, dstPath, onTable) {
|
|
79
|
+
const fs = requireCjs("fs");
|
|
80
|
+
const stats = { tables: 0, rowsCopied: 0, rowsLost: 0, schemasFailed: 0 };
|
|
81
|
+
|
|
82
|
+
if (driver.kind === "native") {
|
|
83
|
+
const src = new driver.Database(srcPath, {
|
|
84
|
+
readonly: true,
|
|
85
|
+
fileMustExist: true,
|
|
86
|
+
});
|
|
87
|
+
const dst = new driver.Database(dstPath);
|
|
88
|
+
dst.pragma("journal_mode = WAL");
|
|
89
|
+
try {
|
|
90
|
+
const schemaRows = src
|
|
91
|
+
.prepare(
|
|
92
|
+
"SELECT type, name, sql FROM sqlite_master WHERE type IN ('table','index','view') AND sql IS NOT NULL AND name NOT LIKE 'sqlite_%' ORDER BY (type='table') DESC, name",
|
|
93
|
+
)
|
|
94
|
+
.all();
|
|
95
|
+
for (const r of schemaRows) {
|
|
96
|
+
try {
|
|
97
|
+
dst.exec(r.sql);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
stats.schemasFailed++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const tables = src
|
|
103
|
+
.prepare(
|
|
104
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name",
|
|
105
|
+
)
|
|
106
|
+
.all()
|
|
107
|
+
.map((t) => t.name);
|
|
108
|
+
for (const t of tables) {
|
|
109
|
+
let copied = 0;
|
|
110
|
+
let lost = 0;
|
|
111
|
+
let err = null;
|
|
112
|
+
try {
|
|
113
|
+
const cols = src
|
|
114
|
+
.prepare(`PRAGMA table_info(${quoteIdent(t)})`)
|
|
115
|
+
.all()
|
|
116
|
+
.map((c) => c.name);
|
|
117
|
+
if (cols.length === 0) {
|
|
118
|
+
stats.tables++;
|
|
119
|
+
onTable(t, 0, 0, "no columns");
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const colList = cols.map(quoteIdent).join(",");
|
|
123
|
+
const placeholders = cols.map(() => "?").join(",");
|
|
124
|
+
const insert = dst.prepare(
|
|
125
|
+
`INSERT OR IGNORE INTO ${quoteIdent(t)} (${colList}) VALUES (${placeholders})`,
|
|
126
|
+
);
|
|
127
|
+
const iter = src
|
|
128
|
+
.prepare(`SELECT ${colList} FROM ${quoteIdent(t)}`)
|
|
129
|
+
.iterate();
|
|
130
|
+
while (true) {
|
|
131
|
+
let next;
|
|
132
|
+
try {
|
|
133
|
+
next = iter.next();
|
|
134
|
+
} catch (_e) {
|
|
135
|
+
lost++;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
if (next.done) break;
|
|
139
|
+
try {
|
|
140
|
+
insert.run(...cols.map((c) => next.value[c]));
|
|
141
|
+
copied++;
|
|
142
|
+
} catch (_e) {
|
|
143
|
+
lost++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
iter.return && iter.return();
|
|
148
|
+
} catch (_e) {
|
|
149
|
+
/* swallow */
|
|
150
|
+
}
|
|
151
|
+
} catch (e) {
|
|
152
|
+
err = e.message;
|
|
153
|
+
}
|
|
154
|
+
stats.tables++;
|
|
155
|
+
stats.rowsCopied += copied;
|
|
156
|
+
stats.rowsLost += lost;
|
|
157
|
+
onTable(t, copied, lost, err);
|
|
158
|
+
}
|
|
159
|
+
} finally {
|
|
160
|
+
try {
|
|
161
|
+
src.close();
|
|
162
|
+
} catch (_e) {
|
|
163
|
+
/* swallow */
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
dst.close();
|
|
167
|
+
} catch (_e) {
|
|
168
|
+
/* swallow */
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return { stats };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// wasm path
|
|
175
|
+
const buf = fs.readFileSync(srcPath);
|
|
176
|
+
const src = new driver.SQL.Database(buf);
|
|
177
|
+
const dst = new driver.SQL.Database();
|
|
178
|
+
try {
|
|
179
|
+
let schemaRows = [];
|
|
180
|
+
try {
|
|
181
|
+
const r = src.exec(
|
|
182
|
+
"SELECT type, name, sql FROM sqlite_master WHERE type IN ('table','index','view') AND sql IS NOT NULL AND name NOT LIKE 'sqlite_%' ORDER BY (type='table') DESC, name",
|
|
183
|
+
);
|
|
184
|
+
schemaRows = (r[0]?.values || []).map((v) => ({
|
|
185
|
+
type: v[0],
|
|
186
|
+
name: v[1],
|
|
187
|
+
sql: v[2],
|
|
188
|
+
}));
|
|
189
|
+
} catch (_e) {
|
|
190
|
+
/* sqlite_master unreadable */
|
|
191
|
+
}
|
|
192
|
+
for (const r of schemaRows) {
|
|
193
|
+
try {
|
|
194
|
+
dst.exec(r.sql);
|
|
195
|
+
} catch (_e) {
|
|
196
|
+
stats.schemasFailed++;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
let tables = [];
|
|
200
|
+
try {
|
|
201
|
+
const r = src.exec(
|
|
202
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name",
|
|
203
|
+
);
|
|
204
|
+
tables = (r[0]?.values || []).map((v) => v[0]);
|
|
205
|
+
} catch (_e) {
|
|
206
|
+
/* tables unreadable */
|
|
207
|
+
}
|
|
208
|
+
for (const t of tables) {
|
|
209
|
+
let copied = 0;
|
|
210
|
+
let lost = 0;
|
|
211
|
+
let err = null;
|
|
212
|
+
try {
|
|
213
|
+
const ti = src.exec(`PRAGMA table_info(${quoteIdent(t)})`);
|
|
214
|
+
const cols = (ti[0]?.values || []).map((v) => v[1]);
|
|
215
|
+
if (cols.length === 0) {
|
|
216
|
+
stats.tables++;
|
|
217
|
+
onTable(t, 0, 0, "no columns");
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const colList = cols.map(quoteIdent).join(",");
|
|
221
|
+
const placeholders = cols.map(() => "?").join(",");
|
|
222
|
+
const insertSql = `INSERT OR IGNORE INTO ${quoteIdent(t)} (${colList}) VALUES (${placeholders})`;
|
|
223
|
+
const insertStmt = dst.prepare(insertSql);
|
|
224
|
+
const selectStmt = src.prepare(
|
|
225
|
+
`SELECT ${colList} FROM ${quoteIdent(t)}`,
|
|
226
|
+
);
|
|
227
|
+
try {
|
|
228
|
+
while (true) {
|
|
229
|
+
let stepped;
|
|
230
|
+
try {
|
|
231
|
+
stepped = selectStmt.step();
|
|
232
|
+
} catch (_e) {
|
|
233
|
+
lost++;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
if (!stepped) break;
|
|
237
|
+
let row;
|
|
238
|
+
try {
|
|
239
|
+
row = selectStmt.get();
|
|
240
|
+
} catch (_e) {
|
|
241
|
+
lost++;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
insertStmt.run(row);
|
|
246
|
+
} catch (_e) {
|
|
247
|
+
lost++;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
} finally {
|
|
251
|
+
try {
|
|
252
|
+
selectStmt.free();
|
|
253
|
+
} catch (_e) {
|
|
254
|
+
/* swallow */
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
insertStmt.free();
|
|
258
|
+
} catch (_e) {
|
|
259
|
+
/* swallow */
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
} catch (e) {
|
|
263
|
+
err = e.message;
|
|
264
|
+
}
|
|
265
|
+
stats.tables++;
|
|
266
|
+
stats.rowsCopied += copied;
|
|
267
|
+
stats.rowsLost += lost;
|
|
268
|
+
onTable(t, copied, lost, err);
|
|
269
|
+
}
|
|
270
|
+
// Persist wasm in-memory DB to disk.
|
|
271
|
+
const outBuf = dst.export();
|
|
272
|
+
fs.writeFileSync(dstPath, Buffer.from(outBuf));
|
|
273
|
+
} finally {
|
|
274
|
+
try {
|
|
275
|
+
src.close();
|
|
276
|
+
} catch (_e) {
|
|
277
|
+
/* swallow */
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
dst.close();
|
|
281
|
+
} catch (_e) {
|
|
282
|
+
/* swallow */
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return { stats };
|
|
286
|
+
}
|
|
287
|
+
|
|
13
288
|
export function registerDbCommand(program) {
|
|
14
289
|
const db = program.command("db").description("Database management");
|
|
15
290
|
|
|
@@ -171,48 +446,54 @@ export function registerDbCommand(program) {
|
|
|
171
446
|
await shutdown();
|
|
172
447
|
process.exit(1);
|
|
173
448
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
);
|
|
177
|
-
const driver = loadSQLiteDriver();
|
|
178
|
-
if (
|
|
179
|
-
!driver ||
|
|
180
|
-
(driver.type !== "native" && driver.type !== "native-cipher")
|
|
181
|
-
) {
|
|
449
|
+
const driver = await loadAnyDriver();
|
|
450
|
+
if (!driver) {
|
|
182
451
|
logger.error(
|
|
183
|
-
"
|
|
452
|
+
"No SQLite driver available. Install better-sqlite3 or sql.js.",
|
|
184
453
|
);
|
|
185
454
|
await shutdown();
|
|
186
455
|
process.exit(1);
|
|
187
456
|
}
|
|
188
|
-
const conn = new driver.Database(dbPath, {
|
|
189
|
-
readonly: true,
|
|
190
|
-
fileMustExist: true,
|
|
191
|
-
});
|
|
192
457
|
const checkName = options.quick ? "quick_check" : "integrity_check";
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
458
|
+
const { ok, diagnostics } = await runIntegrityCheck(
|
|
459
|
+
driver,
|
|
460
|
+
dbPath,
|
|
461
|
+
checkName,
|
|
462
|
+
);
|
|
197
463
|
if (options.json) {
|
|
198
464
|
console.log(
|
|
199
|
-
JSON.stringify(
|
|
465
|
+
JSON.stringify(
|
|
466
|
+
{
|
|
467
|
+
ok,
|
|
468
|
+
check: checkName,
|
|
469
|
+
path: dbPath,
|
|
470
|
+
driver: driver.name,
|
|
471
|
+
diagnostics,
|
|
472
|
+
},
|
|
473
|
+
null,
|
|
474
|
+
2,
|
|
475
|
+
),
|
|
200
476
|
);
|
|
201
477
|
} else if (ok) {
|
|
202
478
|
logger.success(
|
|
203
|
-
`Database integrity OK (${checkName}): ${chalk.cyan(dbPath)}`,
|
|
479
|
+
`Database integrity OK (${checkName} via ${driver.name}): ${chalk.cyan(dbPath)}`,
|
|
204
480
|
);
|
|
205
481
|
} else {
|
|
206
|
-
logger.error(
|
|
207
|
-
|
|
208
|
-
|
|
482
|
+
logger.error(
|
|
483
|
+
`Database is CORRUPT (${checkName} via ${driver.name}): ${chalk.cyan(dbPath)}`,
|
|
484
|
+
);
|
|
485
|
+
for (const msg of diagnostics) {
|
|
209
486
|
const lines = String(msg).split("\n").slice(0, 20);
|
|
210
487
|
for (const line of lines) console.log(" " + line);
|
|
211
488
|
}
|
|
212
489
|
console.log("");
|
|
213
490
|
logger.warn("Recovery options:");
|
|
214
|
-
console.log(
|
|
215
|
-
|
|
491
|
+
console.log(
|
|
492
|
+
" cc db repair – best-effort row salvage into a new file",
|
|
493
|
+
);
|
|
494
|
+
console.log(
|
|
495
|
+
" cc db reset – back up corrupt DB and start fresh",
|
|
496
|
+
);
|
|
216
497
|
}
|
|
217
498
|
exitCode = ok ? 0 : 2;
|
|
218
499
|
await shutdown();
|
|
@@ -297,16 +578,10 @@ export function registerDbCommand(program) {
|
|
|
297
578
|
await shutdown();
|
|
298
579
|
process.exit(1);
|
|
299
580
|
}
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
);
|
|
303
|
-
const driver = loadSQLiteDriver();
|
|
304
|
-
if (
|
|
305
|
-
!driver ||
|
|
306
|
-
(driver.type !== "native" && driver.type !== "native-cipher")
|
|
307
|
-
) {
|
|
581
|
+
const driver = await loadAnyDriver();
|
|
582
|
+
if (!driver) {
|
|
308
583
|
logger.error(
|
|
309
|
-
"
|
|
584
|
+
"No SQLite driver available. Install better-sqlite3 or sql.js.",
|
|
310
585
|
);
|
|
311
586
|
await shutdown();
|
|
312
587
|
process.exit(1);
|
|
@@ -319,133 +594,24 @@ export function registerDbCommand(program) {
|
|
|
319
594
|
process.exit(1);
|
|
320
595
|
}
|
|
321
596
|
logger.info(
|
|
322
|
-
`Salvaging ${chalk.cyan(dbPath)} → ${chalk.cyan(outPath)}`,
|
|
597
|
+
`Salvaging ${chalk.cyan(dbPath)} → ${chalk.cyan(outPath)} (driver: ${driver.name})`,
|
|
323
598
|
);
|
|
324
599
|
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
} catch (e) {
|
|
341
|
-
logger.error(`Cannot read sqlite_master: ${e.message}`);
|
|
342
|
-
src.close();
|
|
343
|
-
dst.close();
|
|
344
|
-
await shutdown();
|
|
345
|
-
process.exit(1);
|
|
346
|
-
}
|
|
347
|
-
const stats = {
|
|
348
|
-
tables: 0,
|
|
349
|
-
rowsCopied: 0,
|
|
350
|
-
rowsLost: 0,
|
|
351
|
-
schemasFailed: 0,
|
|
352
|
-
};
|
|
353
|
-
for (const r of schemaRows) {
|
|
354
|
-
try {
|
|
355
|
-
dst.exec(r.sql);
|
|
356
|
-
} catch (e) {
|
|
357
|
-
stats.schemasFailed++;
|
|
358
|
-
logger.warn(`schema replay failed for ${r.name}: ${e.message}`);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const tableRows = src
|
|
363
|
-
.prepare(
|
|
364
|
-
"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name",
|
|
365
|
-
)
|
|
366
|
-
.all();
|
|
367
|
-
const tables = tableRows.map((t) => t.name);
|
|
368
|
-
for (const t of tables) {
|
|
369
|
-
let copied = 0;
|
|
370
|
-
let lost = 0;
|
|
371
|
-
let cols = [];
|
|
372
|
-
try {
|
|
373
|
-
cols = src
|
|
374
|
-
.prepare(`PRAGMA table_info(${quoteIdent(t)})`)
|
|
375
|
-
.all()
|
|
376
|
-
.map((c) => c.name);
|
|
377
|
-
} catch (e) {
|
|
378
|
-
console.log(
|
|
379
|
-
` ${t.padEnd(28)} ${chalk.red("schema unreadable")}`,
|
|
380
|
-
);
|
|
381
|
-
stats.tables++;
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
if (cols.length === 0) {
|
|
385
|
-
console.log(` ${t.padEnd(28)} ${chalk.gray("no columns")}`);
|
|
386
|
-
stats.tables++;
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
const colList = cols.map(quoteIdent).join(",");
|
|
390
|
-
const placeholders = cols.map(() => "?").join(",");
|
|
391
|
-
let insert;
|
|
392
|
-
try {
|
|
393
|
-
insert = dst.prepare(
|
|
394
|
-
`INSERT OR IGNORE INTO ${quoteIdent(t)} (${colList}) VALUES (${placeholders})`,
|
|
395
|
-
);
|
|
396
|
-
} catch (e) {
|
|
397
|
-
console.log(
|
|
398
|
-
` ${t.padEnd(28)} ${chalk.red("dest insert prep failed")}`,
|
|
399
|
-
);
|
|
400
|
-
stats.tables++;
|
|
401
|
-
continue;
|
|
402
|
-
}
|
|
403
|
-
let iter;
|
|
404
|
-
try {
|
|
405
|
-
iter = src
|
|
406
|
-
.prepare(`SELECT ${colList} FROM ${quoteIdent(t)}`)
|
|
407
|
-
.iterate();
|
|
408
|
-
} catch (e) {
|
|
409
|
-
console.log(
|
|
410
|
-
` ${t.padEnd(28)} ${chalk.red("table read aborted: " + e.message.slice(0, 40))}`,
|
|
411
|
-
);
|
|
412
|
-
stats.tables++;
|
|
413
|
-
continue;
|
|
414
|
-
}
|
|
415
|
-
while (true) {
|
|
416
|
-
let next;
|
|
417
|
-
try {
|
|
418
|
-
next = iter.next();
|
|
419
|
-
} catch (e) {
|
|
420
|
-
lost++;
|
|
421
|
-
break;
|
|
422
|
-
}
|
|
423
|
-
if (next.done) break;
|
|
424
|
-
try {
|
|
425
|
-
insert.run(...cols.map((c) => next.value[c]));
|
|
426
|
-
copied++;
|
|
427
|
-
} catch (e) {
|
|
428
|
-
lost++;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
try {
|
|
432
|
-
iter.return && iter.return();
|
|
433
|
-
} catch (_e) {
|
|
434
|
-
/* swallow */
|
|
435
|
-
}
|
|
436
|
-
stats.tables++;
|
|
437
|
-
stats.rowsCopied += copied;
|
|
438
|
-
stats.rowsLost += lost;
|
|
439
|
-
const status =
|
|
440
|
-
lost > 0
|
|
441
|
-
? chalk.yellow(`${copied} copied, ${lost} lost`)
|
|
442
|
-
: copied === 0
|
|
443
|
-
? chalk.gray(`${copied} copied`)
|
|
444
|
-
: chalk.green(`${copied} copied`);
|
|
445
|
-
console.log(` ${t.padEnd(28)} ${status}`);
|
|
446
|
-
}
|
|
447
|
-
src.close();
|
|
448
|
-
dst.close();
|
|
600
|
+
const { stats } = await salvageDatabase(
|
|
601
|
+
driver,
|
|
602
|
+
dbPath,
|
|
603
|
+
outPath,
|
|
604
|
+
(name, copied, lost, err) => {
|
|
605
|
+
const tag = err
|
|
606
|
+
? chalk.red(err)
|
|
607
|
+
: lost > 0
|
|
608
|
+
? chalk.yellow(`${copied} copied, ${lost} lost`)
|
|
609
|
+
: copied === 0
|
|
610
|
+
? chalk.gray(`${copied} copied`)
|
|
611
|
+
: chalk.green(`${copied} copied`);
|
|
612
|
+
console.log(` ${name.padEnd(28)} ${tag}`);
|
|
613
|
+
},
|
|
614
|
+
);
|
|
449
615
|
|
|
450
616
|
logger.log("");
|
|
451
617
|
logger.success(`Recovered DB written to ${chalk.cyan(outPath)}`);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as we,m as v,x as t,q as d,B as je,C as Se,v as i,c as e,D as a,E as j,u as s,F as r,G as B,H as S,I as g,J as l,K as Te,L as Be,r as Re,j as y}from"./vendor-xFZ6Jlpw.js";import{u as Le}from"./ws-Dg01CdRG.js";import{u as xe,T as Ae}from"./index-xcQ2VcES.js";import{_ as De}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{F as b,G as R,D,M as I,R as N,C as U,a as P,A as K,b as M,c as V,B as F,d as E,S as G,e as W,f as z,h as q,i as H,I as $,L as J,W as Y,j as Q,k as X,P as Z,l as h,m as ee,n as te,o as oe,U as se,V as Ie,p as ne,K as le,q as Ne}from"./icons-C40taSZA.js";const Ue=["src"],Pe={key:0,class:"logo-text"},Ke={key:0,class:"mode-banner project"},Me={class:"banner-info"},Ve={class:"banner-name"},Fe={key:1,class:"mode-banner global"},Ee=["title"],Ge={key:0,class:"footer-text"},We={class:"header-left"},ze={class:"header-right"},qe={class:"theme-switcher"},He=["data-theme-key","onClick"],$e={class:"version-tag"},Je={__name:"AppLayout",setup(Ye){const ae=je(),ie=Se(),O=Le(),T=xe(),u=Re(!1),k=window.__CC_CONFIG__||{},m=y(()=>k.mode==="project"),de="v5.0.3.1",ue=new URL(""+new URL("logo-DBCYUiWP.png",import.meta.url).href,import.meta.url).href,re=y(()=>T.current),ce=y(()=>T.config.vars["--menu-mode"]),L=y(()=>{const c=ie.name?.toLowerCase()||"dashboard";return[{mcptools:"mcp"}[c]||c]}),C=y(()=>O.status),pe=y(()=>({connected:"success",connecting:"processing",error:"error",disconnected:"default"})[O.status]||"default"),me=y(()=>({connected:"已连接",connecting:"连接中...",error:"连接错误",disconnected:"未连接"})[O.status]||"未知");function ye(c){T.setTheme(c)}function ke({key:c}){ae.push({mcp:"/mcp"}[c]||`/${c}`)}return we(()=>O.connect()),(c,o)=>{const n=d("a-menu-item"),p=d("a-menu-item-group"),f=d("a-menu-divider"),fe=d("a-menu"),_e=d("a-badge"),ve=d("a-layout-sider"),x=d("a-tooltip"),ge=d("a-tag"),be=d("a-layout-header"),Oe=d("router-view"),Ce=d("a-layout-content"),A=d("a-layout");return i(),v(A,{class:"app-root"},{default:t(()=>[e(ve,{collapsed:u.value,"onUpdate:collapsed":o[1]||(o[1]=_=>u.value=_),collapsible:"","collapsed-width":56,width:216,class:"sidebar"},{default:t(()=>[a("div",{class:j(["logo",{collapsed:u.value}])},[a("img",{src:s(ue),alt:"ChainlessChain",class:"logo-icon"},null,8,Ue),u.value?B("",!0):(i(),r("span",Pe,"ChainlessChain"))],2),u.value?(i(),r("div",{key:1,class:"mode-icon-sm",title:m.value?s(k).projectName:"全局模式"},[m.value?(i(),v(s(b),{key:0,style:{color:"#1677ff"}})):(i(),v(s(R),{key:1,style:{color:"#722ed1"}}))],8,Ee)):(i(),r(S,{key:0},[m.value?(i(),r("div",Ke,[e(s(b),{class:"banner-icon"}),a("div",Me,[a("div",Ve,g(s(k).projectName||"项目"),1),o[2]||(o[2]=a("div",{class:"banner-sub"},"项目级面板",-1))])])):(i(),r("div",Fe,[e(s(R),{class:"banner-icon"}),o[3]||(o[3]=a("span",{class:"banner-name"},"全局模式",-1))]))],64)),e(fe,{selectedKeys:L.value,"onUpdate:selectedKeys":o[0]||(o[0]=_=>L.value=_),theme:ce.value,mode:"inline","inline-collapsed":u.value,class:"side-menu",onClick:ke},{default:t(()=>[u.value?(i(),r(S,{key:1},[e(n,{key:"dashboard"},{icon:t(()=>[e(s(D))]),_:1}),e(n,{key:"chat"},{icon:t(()=>[e(s(I))]),_:1}),e(n,{key:"cowork"},{icon:t(()=>[e(s(N))]),_:1}),e(n,{key:"services"},{icon:t(()=>[e(s(U))]),_:1}),e(n,{key:"logs"},{icon:t(()=>[e(s(P))]),_:1}),e(f,{class:"divider-sm"}),e(n,{key:"skills"},{icon:t(()=>[e(s(K))]),_:1}),e(n,{key:"providers"},{icon:t(()=>[e(s(M))]),_:1}),e(n,{key:"mcp"},{icon:t(()=>[e(s(V))]),_:1}),e(n,{key:"project-settings"},{icon:t(()=>[e(s(b))]),_:1}),e(f,{class:"divider-sm"}),e(n,{key:"notes"},{icon:t(()=>[e(s(F))]),_:1}),e(n,{key:"memory"},{icon:t(()=>[e(s(E))]),_:1}),e(n,{key:"knowledge"},{icon:t(()=>[e(s(G))]),_:1}),e(n,{key:"cron"},{icon:t(()=>[e(s(W))]),_:1}),e(n,{key:"workflow"},{icon:t(()=>[e(s(z))]),_:1}),e(n,{key:"tasks"},{icon:t(()=>[e(s(q))]),_:1}),e(f,{class:"divider-sm"}),e(n,{key:"security"},{icon:t(()=>[e(s(H))]),_:1}),e(n,{key:"did"},{icon:t(()=>[e(s($))]),_:1}),e(n,{key:"permissions"},{icon:t(()=>[e(s(J))]),_:1}),e(n,{key:"p2p"},{icon:t(()=>[e(s(Y))]),_:1}),e(n,{key:"backup"},{icon:t(()=>[e(s(Q))]),_:1}),e(n,{key:"git"},{icon:t(()=>[e(s(X))]),_:1}),e(n,{key:"projects"},{icon:t(()=>[e(s(Z))]),_:1}),e(f,{class:"divider-sm"}),e(n,{key:"wallet"},{icon:t(()=>[e(s(h))]),_:1}),e(n,{key:"organization"},{icon:t(()=>[e(s(ee))]),_:1}),e(n,{key:"analytics"},{icon:t(()=>[e(s(te))]),_:1}),e(n,{key:"templates"},{icon:t(()=>[e(s(oe))]),_:1}),e(f,{class:"divider-sm"}),e(n,{key:"community"},{icon:t(()=>[e(s(se))]),_:1}),e(f,{class:"divider-sm"}),e(n,{key:"rssfeed"},{icon:t(()=>[e(s(ne))]),_:1}),e(n,{key:"webauthn"},{icon:t(()=>[e(s(le))]),_:1})],64)):(i(),r(S,{key:0},[e(p,null,{title:t(()=>[...o[4]||(o[4]=[a("span",{class:"group-label"},"概 览",-1)])]),default:t(()=>[e(n,{key:"dashboard"},{icon:t(()=>[e(s(D))]),default:t(()=>[o[5]||(o[5]=l("仪表板",-1))]),_:1}),e(n,{key:"chat"},{icon:t(()=>[e(s(I))]),default:t(()=>[o[6]||(o[6]=l("AI 对话",-1))]),_:1}),e(n,{key:"cowork"},{icon:t(()=>[e(s(N))]),default:t(()=>[o[7]||(o[7]=l("日常协作",-1))]),_:1}),e(n,{key:"services"},{icon:t(()=>[e(s(U))]),default:t(()=>[o[8]||(o[8]=l("服务管理",-1))]),_:1}),e(n,{key:"logs"},{icon:t(()=>[e(s(P))]),default:t(()=>[o[9]||(o[9]=l("日志查看",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[10]||(o[10]=[a("span",{class:"group-label"},"配 置",-1)])]),default:t(()=>[e(n,{key:"skills"},{icon:t(()=>[e(s(K))]),default:t(()=>[o[11]||(o[11]=l("技能管理",-1))]),_:1}),e(n,{key:"providers"},{icon:t(()=>[e(s(M))]),default:t(()=>[o[12]||(o[12]=l("LLM 配置",-1))]),_:1}),e(n,{key:"mcp"},{icon:t(()=>[e(s(V))]),default:t(()=>[o[13]||(o[13]=l("MCP 工具",-1))]),_:1}),e(n,{key:"project-settings"},{icon:t(()=>[e(s(b))]),default:t(()=>[o[14]||(o[14]=l("项目存储",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[15]||(o[15]=[a("span",{class:"group-label"},"数 据",-1)])]),default:t(()=>[e(n,{key:"notes"},{icon:t(()=>[e(s(F))]),default:t(()=>[o[16]||(o[16]=l("笔记管理",-1))]),_:1}),e(n,{key:"memory"},{icon:t(()=>[e(s(E))]),default:t(()=>[o[17]||(o[17]=l("记忆文件",-1))]),_:1}),e(n,{key:"knowledge"},{icon:t(()=>[e(s(G))]),default:t(()=>[o[18]||(o[18]=l("知识图谱",-1))]),_:1}),e(n,{key:"cron"},{icon:t(()=>[e(s(W))]),default:t(()=>[o[19]||(o[19]=l("定时任务",-1))]),_:1}),e(n,{key:"workflow"},{icon:t(()=>[e(s(z))]),default:t(()=>[o[20]||(o[20]=l("工作流编辑",-1))]),_:1}),e(n,{key:"tasks"},{icon:t(()=>[e(s(q))]),default:t(()=>[o[21]||(o[21]=l("后台任务",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[22]||(o[22]=[a("span",{class:"group-label"},"高 级",-1)])]),default:t(()=>[e(n,{key:"security"},{icon:t(()=>[e(s(H))]),default:t(()=>[o[23]||(o[23]=l("安全中心",-1))]),_:1}),e(n,{key:"did"},{icon:t(()=>[e(s($))]),default:t(()=>[o[24]||(o[24]=l("DID 身份",-1))]),_:1}),e(n,{key:"permissions"},{icon:t(()=>[e(s(J))]),default:t(()=>[o[25]||(o[25]=l("权限管理",-1))]),_:1}),e(n,{key:"p2p"},{icon:t(()=>[e(s(Y))]),default:t(()=>[o[26]||(o[26]=l("P2P 网络",-1))]),_:1}),e(n,{key:"backup"},{icon:t(()=>[e(s(Q))]),default:t(()=>[o[27]||(o[27]=l("备份同步",-1))]),_:1}),e(n,{key:"git"},{icon:t(()=>[e(s(X))]),default:t(()=>[o[28]||(o[28]=l("Git 与数据",-1))]),_:1}),e(n,{key:"projects"},{icon:t(()=>[e(s(Z))]),default:t(()=>[o[29]||(o[29]=l("项目管理",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[30]||(o[30]=[a("span",{class:"group-label"},"企 业",-1)])]),default:t(()=>[e(n,{key:"wallet"},{icon:t(()=>[e(s(h))]),default:t(()=>[o[31]||(o[31]=l("钱包管理",-1))]),_:1}),e(n,{key:"organization"},{icon:t(()=>[e(s(ee))]),default:t(()=>[o[32]||(o[32]=l("组织管理",-1))]),_:1}),e(n,{key:"analytics"},{icon:t(()=>[e(s(te))]),default:t(()=>[o[33]||(o[33]=l("使用分析",-1))]),_:1}),e(n,{key:"templates"},{icon:t(()=>[e(s(oe))]),default:t(()=>[o[34]||(o[34]=l("模板中心",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[35]||(o[35]=[a("span",{class:"group-label"},"社 交",-1)])]),default:t(()=>[e(n,{key:"community"},{icon:t(()=>[e(s(se))]),default:t(()=>[o[36]||(o[36]=l("社区",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[37]||(o[37]=[a("span",{class:"group-label"},"媒 体",-1)])]),default:t(()=>[e(n,{key:"video"},{icon:t(()=>[e(s(Ie))]),default:t(()=>[o[38]||(o[38]=l("视频剪辑",-1))]),_:1})]),_:1}),e(p,null,{title:t(()=>[...o[39]||(o[39]=[a("span",{class:"group-label"},"扩 展",-1)])]),default:t(()=>[e(n,{key:"rssfeed"},{icon:t(()=>[e(s(ne))]),default:t(()=>[o[40]||(o[40]=l("RSS 订阅",-1))]),_:1}),e(n,{key:"webauthn"},{icon:t(()=>[e(s(le))]),default:t(()=>[o[41]||(o[41]=l("身份认证",-1))]),_:1})]),_:1})],64))]),_:1},8,["selectedKeys","theme","inline-collapsed"]),a("div",{class:j(["sidebar-footer",{collapsed:u.value}])},[e(_e,{status:pe.value},null,8,["status"]),u.value?B("",!0):(i(),r("span",Ge,g(me.value),1))],2)]),_:1},8,["collapsed"]),e(A,{class:"main-area"},{default:t(()=>[e(be,{class:"app-header"},{default:t(()=>[a("div",We,[a("div",{class:j(["scope-tag",m.value?"project":"global"])},[(i(),v(Te(m.value?s(b):s(R)))),a("span",null,g(m.value?s(k).projectName||"项目":"全局模式"),1),m.value&&s(k).projectRoot?(i(),v(x,{key:0,title:s(k).projectRoot},{default:t(()=>[e(s(Ne),{class:"info-icon"})]),_:1},8,["title"])):B("",!0)],2)]),a("div",ze,[a("div",qe,[(i(!0),r(S,null,Be(s(Ae),(_,w)=>(i(),v(x,{key:w,title:_.label},{default:t(()=>[a("button",{class:j(["theme-btn",{active:re.value===w}]),"data-theme-key":w,onClick:Qe=>ye(w)},g(_.icon),11,He)]),_:2},1032,["title"]))),128))]),a("span",$e,g(s(de)),1),e(ge,{color:C.value==="connected"?"green":C.value==="connecting"?"orange":"red",class:"ws-tag"},{default:t(()=>[l(g(C.value==="connected"?"已连接":C.value==="connecting"?"连接中":"断开"),1)]),_:1},8,["color"])])]),_:1}),e(Ce,{class:"page-content"},{default:t(()=>[e(Oe)]),_:1})]),_:1})]),_:1})}}},ot=De(Je,[["__scopeId","data-v-0cfe1e7d"]]);export{ot as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.app-root[data-v-0cfe1e7d]{min-height:100vh;background:var(--bg-base)}.sidebar[data-v-0cfe1e7d]{background:var(--bg-sidebar)!important;border-right:1px solid var(--border-color);transition:background .25s}[data-v-0cfe1e7d] .ant-layout-sider-children{display:flex;flex-direction:column;overflow:hidden}.main-area[data-v-0cfe1e7d]{background:var(--bg-base)}.logo[data-v-0cfe1e7d]{height:52px;display:flex;align-items:center;padding:0 18px;gap:10px;border-bottom:1px solid var(--border-color);overflow:hidden;white-space:nowrap;flex-shrink:0}.logo.collapsed[data-v-0cfe1e7d]{padding:0;justify-content:center}.logo-icon[data-v-0cfe1e7d]{width:24px;height:24px;flex-shrink:0;object-fit:contain}.logo-text[data-v-0cfe1e7d]{color:var(--logo-text);font-weight:700;font-size:14px;letter-spacing:.01em}.mode-banner[data-v-0cfe1e7d]{display:flex;align-items:center;gap:8px;padding:7px 10px;margin:8px 8px 4px;border-radius:7px;overflow:hidden}.mode-banner.project[data-v-0cfe1e7d]{background:#1677ff1a;border:1px solid rgba(22,119,255,.2)}.mode-banner.global[data-v-0cfe1e7d]{background:#722ed11a;border:1px solid rgba(114,46,209,.2)}.banner-icon[data-v-0cfe1e7d]{font-size:13px;flex-shrink:0;color:#1677ff}.mode-banner.global .banner-icon[data-v-0cfe1e7d]{color:#722ed1}.banner-info[data-v-0cfe1e7d]{flex:1;min-width:0}.banner-name[data-v-0cfe1e7d]{font-size:12px;font-weight:600;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.banner-sub[data-v-0cfe1e7d]{font-size:10px;color:#1677ff;margin-top:1px}.mode-banner.global .banner-name[data-v-0cfe1e7d]{color:#c084fc}.mode-icon-sm[data-v-0cfe1e7d]{display:flex;justify-content:center;padding:8px 0;font-size:14px}.side-menu[data-v-0cfe1e7d]{border:none!important;margin-top:2px;-webkit-user-select:none;user-select:none;background:transparent!important;flex:1;overflow-y:auto;overflow-x:hidden}.group-label[data-v-0cfe1e7d]{color:var(--group-title);font-size:10px;font-weight:700;letter-spacing:.12em;padding-left:6px}[data-v-0cfe1e7d] .ant-menu-item-group-title{padding:8px 16px 2px!important}[data-v-0cfe1e7d] .ant-menu-item{height:38px!important;line-height:38px!important;margin:1px 4px!important;border-radius:6px!important}.divider-sm[data-v-0cfe1e7d]{margin:4px 0!important}.sidebar-footer[data-v-0cfe1e7d]{flex-shrink:0;padding:8px 18px;display:flex;align-items:center;gap:8px;border-top:1px solid var(--border-color)}.sidebar-footer.collapsed[data-v-0cfe1e7d]{justify-content:center;padding:8px 0}.footer-text[data-v-0cfe1e7d]{color:var(--text-secondary);font-size:11px}.app-header[data-v-0cfe1e7d]{background:var(--bg-header)!important;padding:0 20px!important;border-bottom:1px solid var(--border-color);height:50px!important;line-height:50px!important;display:flex!important;align-items:center!important;justify-content:space-between!important;box-shadow:0 1px 4px #0000000f}.header-left[data-v-0cfe1e7d],.header-right[data-v-0cfe1e7d]{display:flex;align-items:center;gap:10px}.scope-tag[data-v-0cfe1e7d]{display:flex;align-items:center;gap:5px;padding:3px 10px;border-radius:5px;font-size:12px;font-weight:500}.scope-tag.project[data-v-0cfe1e7d]{background:#1677ff1a;color:#1677ff;border:1px solid rgba(22,119,255,.2)}.scope-tag.global[data-v-0cfe1e7d]{background:#722ed11a;color:#722ed1;border:1px solid rgba(114,46,209,.2)}.info-icon[data-v-0cfe1e7d]{opacity:.45;cursor:help;margin-left:2px}.theme-switcher[data-v-0cfe1e7d]{display:flex;align-items:center;gap:4px;background:var(--bg-card);border:1px solid var(--border-color);border-radius:20px;padding:3px 6px}.theme-btn[data-v-0cfe1e7d]{width:26px;height:26px;border:none;border-radius:50%;cursor:pointer;background:transparent;font-size:14px;line-height:1;display:flex;align-items:center;justify-content:center;transition:background .15s,transform .15s;opacity:.55}.theme-btn[data-v-0cfe1e7d]:hover{opacity:.9;transform:scale(1.15);background:var(--bg-card-hover)}.theme-btn.active[data-v-0cfe1e7d]{opacity:1;transform:scale(1.1);background:var(--bg-card-hover);outline:2px solid var(--text-secondary)}.version-tag[data-v-0cfe1e7d]{color:var(--text-muted);font-size:11px}.ws-tag[data-v-0cfe1e7d]{margin:0!important;font-size:11px}.page-content[data-v-0cfe1e7d]{padding:24px;overflow:auto;background:var(--bg-base);min-height:calc(100vh - 50px)}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as Me}from"./ws-Dg01CdRG.js";import{_ as Ne}from"./_plugin-vue_export-helper-DlAUqK2U.js";import{r as je,Z as me,j as re,$ as N,af as U,ad as Le}from"./icons-C40taSZA.js";import{l as Te,F as s,D as p,c as a,x as o,r as n,q as y,v as l,J as f,u as v,m as b,G as r,I as u,H as De}from"./vendor-xFZ6Jlpw.js";const Re={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Ee={key:0,style:{"text-align":"center",padding:"30px"}},Ue={key:0,style:{"font-family":"monospace",color:"var(--text-muted)","font-size":"12px"}},Je={key:1},Ke={key:2,style:{color:"var(--text-secondary)","font-size":"12px"}},Ve={key:3,style:{"margin-top":"16px"}},Ge={style:{background:"var(--bg-base)",border:"1px solid var(--border-color)","border-radius":"6px",padding:"12px",color:"#aaa","font-size":"12px","max-height":"200px","overflow-y":"auto","white-space":"pre-wrap"}},He={key:4,style:{"margin-top":"12px",color:"#ff4d4f","font-size":"12px"}},qe={key:0,style:{background:"var(--bg-base)",border:"1px solid var(--border-color)","border-radius":"6px",padding:"12px","margin-top":"8px"}},We={style:{"font-family":"monospace"}},Ze={key:0},Qe={key:1,style:{"margin-top":"12px"}},Xe={style:{background:"var(--bg-base)",border:"1px solid var(--border-color)","border-radius":"6px",padding:"12px",color:"#aaa","font-size":"12px","white-space":"pre-wrap"}},Ye={key:0,style:{"text-align":"center",padding:"30px"}},et={key:0,style:{"margin-bottom":"16px"}},tt={style:{background:"var(--bg-base)",border:"1px solid var(--border-color)","border-radius":"6px",padding:"12px",color:"#aaa","font-size":"12px","max-height":"200px","overflow-y":"auto","white-space":"pre-wrap"}},at={key:0,style:{"font-family":"monospace","font-size":"12px"}},ot={key:2,style:{"margin-top":"12px",color:"#ff4d4f","font-size":"12px"}},lt={key:0,style:{"text-align":"center",padding:"30px"}},nt={key:2,style:{"margin-top":"12px",color:"#ff4d4f","font-size":"12px"}},st={key:0,style:{"text-align":"center",padding:"30px"}},rt={key:0,style:{"font-family":"monospace",color:"var(--text-muted)","font-size":"12px"}},it={key:1},ut={key:2},ct={key:3,style:{color:"var(--text-secondary)","font-size":"12px"}},dt={key:3,style:{"margin-top":"12px",color:"#ff4d4f","font-size":"12px"}},pt={key:0,style:{"margin-top":"12px"}},vt={style:{background:"var(--bg-base)",border:"1px solid var(--border-color)","border-radius":"6px",padding:"12px",color:"#aaa","font-size":"12px","white-space":"pre-wrap"}},yt={__name:"Backup",setup(ft){const g=Me(),ie=n("backup"),J=n(!1),K=n(!1),V=n(!1),B=n(""),w=n([]),_=n(""),be=[{title:"备份 ID",key:"id"},{title:"大小",key:"size",width:120},{title:"创建时间",key:"createdAt"},{title:"操作",key:"action",width:100}];async function ue(){K.value=!0,B.value="";try{const{output:t}=await g.execute("backup list --json",15e3),e=M(t);Array.isArray(e)?w.value=e:e&&Array.isArray(e.backups)?w.value=e.backups:(w.value=[],t&&t.trim()&&(_.value=t))}catch(t){B.value=`加载备份列表失败: ${t.message}`}finally{K.value=!1}}async function xe(){V.value=!0,_.value="",B.value="";try{const{output:t}=await g.execute("backup create --json",3e4);_.value=t||"备份已创建",await ue()}catch(t){_.value=`创建备份失败: ${t.message}`}finally{V.value=!1}}const G=n(!1),H=n(!1),k=n(null),z=n("");function _e(t){k.value=t,z.value="",G.value=!0}async function ke(){if(k.value){H.value=!0,z.value="";try{const{output:t}=await g.execute(`backup restore ${k.value.id}`,6e4);z.value=t||"恢复完成"}catch(t){z.value=`恢复失败: ${t.message}`}finally{H.value=!1}}}const q=n(!1),j=n(""),I=n(!1),L=n("未知"),T=n(0),W=n(""),x=n(""),Z=n(!1),Q=n(!1),S=n([]),he=[{title:"文件路径",key:"path"},{title:"冲突类型",key:"type",width:120}];async function X(){q.value=!0,j.value="";try{const{output:t}=await g.execute("sync status --json",15e3),e=M(t);e?(I.value=e.online||e.synced||e.status==="online"||!1,L.value=I.value?"已同步":"未同步",T.value=e.pending??e.pendingChanges??0,W.value=e.lastSync||e.lastSyncTime||""):we(t)}catch(t){j.value=`加载同步状态失败: ${t.message}`}finally{q.value=!1}}function we(t){if(!t){L.value="未知";return}I.value=/synced|online|up.to.date/i.test(t),L.value=I.value?"已同步":"未同步";const e=t.match(/pending[:\s]+(\d+)/i);T.value=e?parseInt(e[1]):0;const c=t.match(/last[:\s]+(.+)/i);c&&(W.value=c[1].trim())}async function ze(){Z.value=!0,x.value="";try{const{output:t}=await g.execute("sync push",3e4);x.value=t||"推送完成",await X()}catch(t){x.value=`推送失败: ${t.message}`}finally{Z.value=!1}}async function Se(){Q.value=!0,x.value="";try{const{output:t}=await g.execute("sync pull",3e4);x.value=t||"拉取完成",await X()}catch(t){x.value=`拉取失败: ${t.message}`}finally{Q.value=!1}}async function Ce(){try{const{output:t}=await g.execute("sync conflicts --json",15e3),e=M(t);Array.isArray(e)?S.value=e:e&&Array.isArray(e.conflicts)?S.value=e.conflicts:S.value=[]}catch{S.value=[]}}const Y=n(!1),D=n(""),C=n(!1),ee=n(""),te=n(!1),O=n(""),A=n([]),Ae=[{title:"CID",key:"cid"},{title:"名称",key:"name"},{title:"大小",key:"size",width:120},{title:"固定时间",key:"pinnedAt"},{title:"操作",key:"action",width:120}];async function Pe(){Y.value=!0,D.value="";try{const{output:t}=await g.execute("ipfs status --json",15e3),e=M(t);if(e)C.value=e.online||e.status==="online"||e.connected||!1,ee.value=e.peerId||e.id||"";else{C.value=t?/online|connected|running/i.test(t):!1;const c=t?t.match(/(?:peer\s*id|id)[:\s]+(\S+)/i):null;ee.value=c?c[1]:""}}catch(t){D.value=`加载 IPFS 状态失败: ${t.message}`}finally{Y.value=!1}}async function ae(){te.value=!0,O.value="";try{const{output:t}=await g.execute("ipfs pins --json",15e3),e=M(t);Array.isArray(e)?A.value=e:e&&Array.isArray(e.pins)?A.value=e.pins:A.value=[]}catch(t){O.value=`加载固定列表失败: ${t.message}`}finally{te.value=!1}}const oe=n(!1),le=n(!1),R=n(""),F=n("");async function ce(){if(R.value.trim()){le.value=!0,F.value="";try{const{output:t}=await g.execute(`ipfs pin "${R.value.trim()}"`,3e4);F.value=t||"固定成功",await ae()}catch(t){F.value=`固定失败: ${t.message}`}finally{le.value=!1}}}async function $e(t){try{await g.execute(`ipfs unpin ${t.cid}`,15e3),await ae()}catch(e){O.value=`取消固定失败: ${e.message}`}}function M(t){if(!t||!t.trim())return null;try{return JSON.parse(t.trim())}catch{const c=t.match(/\{[\s\S]*\}|\[[\s\S]*\]/);if(c)try{return JSON.parse(c[0])}catch{}return null}}function de(t){if(t==null||isNaN(t))return"-";const e=Number(t);if(e===0)return"0 B";const c=["B","KB","MB","GB","TB"],h=Math.floor(Math.log(e)/Math.log(1024));return(e/Math.pow(1024,h)).toFixed(h>0?1:0)+" "+c[h]}async function pe(){J.value=!0;try{await Promise.all([ue(),X(),Ce(),Pe(),ae()])}finally{J.value=!1}}return Te(pe),(t,e)=>{const c=y("a-button"),h=y("a-space"),E=y("a-spin"),ve=y("a-empty"),ne=y("a-table"),m=y("a-card"),ye=y("a-modal"),se=y("a-tab-pane"),P=y("a-statistic"),$=y("a-col"),fe=y("a-row"),ge=y("a-tag"),Be=y("a-popconfirm"),Ie=y("a-input"),Oe=y("a-tabs");return l(),s("div",null,[p("div",Re,[e[6]||(e[6]=p("div",null,[p("h2",{class:"page-title"},"备份与同步"),p("p",{class:"page-sub"},"备份管理 / 数据同步 / IPFS")],-1)),a(c,{type:"primary",ghost:"",loading:J.value,onClick:pe},{icon:o(()=>[a(v(je))]),default:o(()=>[e[5]||(e[5]=f(" 刷新 ",-1))]),_:1},8,["loading"])]),a(Oe,{activeKey:ie.value,"onUpdate:activeKey":e[4]||(e[4]=i=>ie.value=i),type:"card"},{default:o(()=>[a(se,{key:"backup"},{tab:o(()=>[a(v(re)),e[7]||(e[7]=f(" 备份管理",-1))]),default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"20px"}},{title:o(()=>[a(h,null,{default:o(()=>[a(v(re)),e[8]||(e[8]=p("span",null,"备份操作",-1))]),_:1})]),extra:o(()=>[a(c,{type:"primary",loading:V.value,onClick:xe},{icon:o(()=>[a(v(me))]),default:o(()=>[e[9]||(e[9]=f(" 创建备份 ",-1))]),_:1},8,["loading"])]),default:o(()=>[K.value?(l(),s("div",Ee,[a(E)])):w.value.length===0&&!_.value?(l(),b(ve,{key:1,description:"暂无备份记录"})):r("",!0),w.value.length>0?(l(),b(ne,{key:2,columns:be,"data-source":w.value,pagination:!1,size:"small","row-key":"id"},{bodyCell:o(({column:i,record:d})=>[i.key==="id"?(l(),s("span",Ue,u(d.id.length>20?d.id.slice(0,20)+"...":d.id),1)):r("",!0),i.key==="size"?(l(),s("span",Je,u(de(d.size)),1)):r("",!0),i.key==="createdAt"?(l(),s("span",Ke,u(d.createdAt||"-"),1)):r("",!0),i.key==="action"?(l(),b(c,{key:3,size:"small",type:"link",onClick:Fe=>_e(d)},{default:o(()=>[...e[10]||(e[10]=[f(" 恢复 ",-1)])]),_:1},8,["onClick"])):r("",!0)]),_:1},8,["data-source"])):r("",!0),_.value?(l(),s("div",Ve,[e[11]||(e[11]=p("div",{style:{color:"var(--text-secondary)","font-size":"11px","margin-bottom":"6px"}},"最近操作结果",-1)),p("pre",Ge,u(_.value),1)])):r("",!0),B.value?(l(),s("div",He,u(B.value),1)):r("",!0)]),_:1}),a(ye,{open:G.value,"onUpdate:open":e[0]||(e[0]=i=>G.value=i),title:"确认恢复备份","ok-text":"确认恢复","cancel-text":"取消","confirm-loading":H.value,onOk:ke,"ok-type":"danger"},{default:o(()=>[e[15]||(e[15]=p("p",{style:{color:"var(--text-secondary)"}}," 确定要恢复以下备份吗?此操作将覆盖当前数据。 ",-1)),k.value?(l(),s("div",qe,[p("div",null,[e[12]||(e[12]=p("strong",null,"备份 ID:",-1)),e[13]||(e[13]=f()),p("span",We,u(k.value.id),1)]),k.value.createdAt?(l(),s("div",Ze,[e[14]||(e[14]=p("strong",null,"创建时间:",-1)),f(" "+u(k.value.createdAt),1)])):r("",!0)])):r("",!0),z.value?(l(),s("div",Qe,[p("pre",Xe,u(z.value),1)])):r("",!0)]),_:1},8,["open","confirm-loading"])]),_:1}),a(se,{key:"sync"},{tab:o(()=>[a(v(N)),e[16]||(e[16]=f(" 数据同步",-1))]),default:o(()=>[q.value?(l(),s("div",Ye,[a(E)])):(l(),s(De,{key:1},[a(fe,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:o(()=>[a($,{xs:24,sm:8},{default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(P,{title:"同步状态",value:L.value,"value-style":{color:I.value?"#52c41a":"#888",fontSize:"16px"}},{prefix:o(()=>[a(v(N))]),_:1},8,["value","value-style"])]),_:1})]),_:1}),a($,{xs:24,sm:8},{default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(P,{title:"待同步变更",value:T.value,"value-style":{color:T.value>0?"#faad14":"#52c41a",fontSize:"16px"}},{prefix:o(()=>[a(v(N))]),_:1},8,["value","value-style"])]),_:1})]),_:1}),a($,{xs:24,sm:8},{default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(P,{title:"最近同步",value:W.value||"无","value-style":{color:"var(--text-secondary)",fontSize:"16px"}},{prefix:o(()=>[a(v(N))]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),a(h,{style:{"margin-bottom":"16px"}},{default:o(()=>[a(c,{loading:Z.value,onClick:ze,style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{icon:o(()=>[a(v(re))]),default:o(()=>[e[17]||(e[17]=f(" 推送 ",-1))]),_:1},8,["loading"]),a(c,{loading:Q.value,onClick:Se,style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{icon:o(()=>[a(v(N))]),default:o(()=>[e[18]||(e[18]=f(" 拉取 ",-1))]),_:1},8,["loading"])]),_:1}),x.value?(l(),s("div",et,[e[19]||(e[19]=p("div",{style:{color:"var(--text-secondary)","font-size":"11px","margin-bottom":"6px"}},"操作结果",-1)),p("pre",tt,u(x.value),1)])):r("",!0),S.value.length>0?(l(),b(m,{key:1,title:"冲突列表",style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(ne,{columns:he,"data-source":S.value,pagination:!1,size:"small","row-key":"path"},{bodyCell:o(({column:i,record:d})=>[i.key==="path"?(l(),s("span",at,u(d.path),1)):r("",!0),i.key==="type"?(l(),b(ge,{key:1,color:"red"},{default:o(()=>[f(u(d.type||"冲突"),1)]),_:2},1024)):r("",!0)]),_:1},8,["data-source"])]),_:1})):r("",!0)],64)),j.value?(l(),s("div",ot,u(j.value),1)):r("",!0)]),_:1}),a(se,{key:"ipfs"},{tab:o(()=>[a(v(U)),e[20]||(e[20]=f(" IPFS 存储",-1))]),default:o(()=>[a(m,{title:"IPFS 状态",style:{background:"var(--bg-card)","border-color":"var(--border-color)","margin-bottom":"20px"}},{extra:o(()=>[a(ge,{color:C.value?"green":"default"},{default:o(()=>[f(u(C.value?"在线":"离线"),1)]),_:1},8,["color"])]),default:o(()=>[Y.value?(l(),s("div",lt,[a(E)])):(l(),b(fe,{key:1,gutter:[16,16]},{default:o(()=>[a($,{xs:24,sm:8},{default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(P,{title:"节点状态",value:C.value?"已连接":"未连接","value-style":{color:C.value?"#52c41a":"#888",fontSize:"16px"}},{prefix:o(()=>[a(v(U))]),_:1},8,["value","value-style"])]),_:1})]),_:1}),a($,{xs:24,sm:8},{default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(P,{title:"已固定文件",value:A.value.length,"value-style":{fontSize:"16px"}},{prefix:o(()=>[a(v(U))]),_:1},8,["value"])]),_:1})]),_:1}),a($,{xs:24,sm:8},{default:o(()=>[a(m,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:o(()=>[a(P,{title:"Peer ID",value:ee.value||"-","value-style":{color:"var(--text-muted)",fontSize:"12px",fontFamily:"monospace"}},{prefix:o(()=>[a(v(U))]),_:1},8,["value"])]),_:1})]),_:1})]),_:1})),D.value?(l(),s("div",nt,u(D.value),1)):r("",!0)]),_:1}),a(m,{title:"固定文件列表",style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{extra:o(()=>[a(c,{size:"small",onClick:e[1]||(e[1]=i=>oe.value=!0),style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{icon:o(()=>[a(v(me))]),default:o(()=>[e[21]||(e[21]=f(" 固定文件 ",-1))]),_:1})]),default:o(()=>[te.value?(l(),s("div",st,[a(E)])):A.value.length===0?(l(),b(ve,{key:1,description:"暂无固定文件"})):(l(),b(ne,{key:2,columns:Ae,"data-source":A.value,pagination:{pageSize:10},size:"small","row-key":"cid"},{bodyCell:o(({column:i,record:d})=>[i.key==="cid"?(l(),s("span",rt,u(d.cid.length>24?d.cid.slice(0,24)+"...":d.cid),1)):r("",!0),i.key==="name"?(l(),s("span",it,u(d.name||"-"),1)):r("",!0),i.key==="size"?(l(),s("span",ut,u(de(d.size)),1)):r("",!0),i.key==="pinnedAt"?(l(),s("span",ct,u(d.pinnedAt||"-"),1)):r("",!0),i.key==="action"?(l(),b(Be,{key:4,title:"确定取消固定?","ok-text":"确定","cancel-text":"取消",onConfirm:Fe=>$e(d)},{default:o(()=>[a(c,{size:"small",type:"link",danger:""},{default:o(()=>[a(v(Le)),e[22]||(e[22]=f(" 取消固定 ",-1))]),_:1})]),_:1},8,["onConfirm"])):r("",!0)]),_:1},8,["data-source"])),O.value?(l(),s("div",dt,u(O.value),1)):r("",!0)]),_:1}),a(ye,{open:oe.value,"onUpdate:open":e[3]||(e[3]=i=>oe.value=i),title:"固定文件到 IPFS","confirm-loading":le.value,onOk:ce,"ok-text":"固定","cancel-text":"取消"},{default:o(()=>[e[23]||(e[23]=p("div",{style:{"margin-bottom":"12px",color:"var(--text-secondary)"}},"请输入要固定的文件路径",-1)),a(Ie,{value:R.value,"onUpdate:value":e[2]||(e[2]=i=>R.value=i),placeholder:"文件路径,例如: /path/to/file.txt",onPressEnter:ce},null,8,["value"]),F.value?(l(),s("div",pt,[p("pre",vt,u(F.value),1)])):r("",!0)]),_:1},8,["open","confirm-loading"])]),_:1})]),_:1},8,["activeKey"])])}}},_t=Ne(yt,[["__scopeId","data-v-3d5d81e6"]]);export{_t as default};
|