jinzd-ai-cli 0.4.235 → 0.4.236
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/README.md +5 -5
- package/dist/{batch-Y7MHXVR7.js → batch-HZI7QAE7.js} +2 -2
- package/dist/{chunk-Q5GVANMH.js → chunk-7VAE3I3D.js} +1 -1
- package/dist/{chunk-GDXKFWFL.js → chunk-CGQARJMP.js} +1 -1
- package/dist/{chunk-HHYMSEWS.js → chunk-MFWAL5S2.js} +1 -1
- package/dist/{chunk-CDOQNIVV.js → chunk-O4QYY6SF.js} +3 -3
- package/dist/{chunk-7D5EJBHO.js → chunk-QDP3NUPX.js} +3 -3
- package/dist/{chunk-FYJGVFXL.js → chunk-SBSWH2EG.js} +7 -7
- package/dist/{chunk-WXFQ6LYN.js → chunk-SCFGLRB3.js} +1 -1
- package/dist/{chunk-GFDRC2JZ.js → chunk-T6EIBUKW.js} +115 -18
- package/dist/{chunk-DHNYGJYB.js → chunk-TT7YURG3.js} +3 -3
- package/dist/{chunk-BFTTW5LS.js → chunk-VBAW4ZPY.js} +1 -1
- package/dist/{ci-OAFNH3MA.js → ci-FYLCHRN3.js} +4 -4
- package/dist/{ci-format-4LSXJNND.js → ci-format-TH2ZTFKU.js} +2 -2
- package/dist/{constants-ERIAS7GV.js → constants-BF6YNKRW.js} +1 -1
- package/dist/{doctor-cli-VFSVWZU6.js → doctor-cli-B6GE4BYJ.js} +4 -4
- package/dist/electron-server.js +164 -67
- package/dist/{hub-X4EUYRIN.js → hub-QBQCKEPE.js} +1 -1
- package/dist/index.js +2438 -2436
- package/dist/{pr-2CZN5JLE.js → pr-KV2WK7SU.js} +4 -4
- package/dist/{run-tests-YSRET52H.js → run-tests-DI6WEYHX.js} +1 -1
- package/dist/{run-tests-DXRJDPFF.js → run-tests-MEHC73SQ.js} +2 -2
- package/dist/{server-FGJGXHZD.js → server-ETIGAZX5.js} +4 -4
- package/dist/{server-5ZAXMKRI.js → server-KZAP5JN3.js} +28 -28
- package/dist/{task-orchestrator-QMERCD77.js → task-orchestrator-WS724BUX.js} +4 -4
- package/dist/{usage-633DUDNT.js → usage-DHZR5PG7.js} +2 -2
- package/package.json +1 -1
package/dist/electron-server.js
CHANGED
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
VERSION,
|
|
39
39
|
buildUserIdentityPrompt,
|
|
40
40
|
runTestsTool
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-MFWAL5S2.js";
|
|
42
42
|
import {
|
|
43
43
|
hasSemanticIndex,
|
|
44
44
|
semanticSearch
|
|
@@ -70,8 +70,8 @@ import {
|
|
|
70
70
|
import express from "express";
|
|
71
71
|
import { createServer } from "http";
|
|
72
72
|
import { WebSocketServer } from "ws";
|
|
73
|
-
import { join as join28, dirname as
|
|
74
|
-
import { existsSync as
|
|
73
|
+
import { join as join28, dirname as dirname11, resolve as resolve13, relative as relative6, sep as sep4 } from "path";
|
|
74
|
+
import { existsSync as existsSync33, readFileSync as readFileSync25, readdirSync as readdirSync16, statSync as statSync14, realpathSync as realpathSync3 } from "fs";
|
|
75
75
|
import { networkInterfaces } from "os";
|
|
76
76
|
|
|
77
77
|
// src/config/config-manager.ts
|
|
@@ -10146,8 +10146,8 @@ import { join as join14 } from "path";
|
|
|
10146
10146
|
import { homedir as homedir6 } from "os";
|
|
10147
10147
|
|
|
10148
10148
|
// src/plugins/plugin-manager.ts
|
|
10149
|
-
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync13, cpSync, rmSync, statSync as statSync7 } from "fs";
|
|
10150
|
-
import { basename as basename6, dirname as dirname8, join as join13, resolve as resolve7 } from "path";
|
|
10149
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync9, readdirSync as readdirSync7, readFileSync as readFileSync13, realpathSync as realpathSync2, cpSync, rmSync, statSync as statSync7 } from "fs";
|
|
10150
|
+
import { basename as basename6, dirname as dirname8, join as join13, relative as relative3, resolve as resolve7, sep as sep3 } from "path";
|
|
10151
10151
|
import { createHash as createHash3 } from "crypto";
|
|
10152
10152
|
import { z as z2 } from "zod";
|
|
10153
10153
|
var MANIFEST_RELATIVE = ".aicli-plugin/plugin.json";
|
|
@@ -10217,20 +10217,117 @@ function statePath(configDir) {
|
|
|
10217
10217
|
}
|
|
10218
10218
|
function loadState(configDir) {
|
|
10219
10219
|
const file = statePath(configDir);
|
|
10220
|
-
if (!existsSync18(file)) return { version:
|
|
10220
|
+
if (!existsSync18(file)) return { version: 2, plugins: [] };
|
|
10221
10221
|
try {
|
|
10222
10222
|
const parsed = JSON.parse(readFileSync13(file, "utf-8"));
|
|
10223
|
-
|
|
10223
|
+
const rawPlugins = Array.isArray(parsed.plugins) ? parsed.plugins : [];
|
|
10224
|
+
return { version: 2, plugins: rawPlugins.map((p) => migrateEntry(p)) };
|
|
10224
10225
|
} catch {
|
|
10225
|
-
return { version:
|
|
10226
|
+
return { version: 2, plugins: [] };
|
|
10226
10227
|
}
|
|
10227
10228
|
}
|
|
10229
|
+
function migrateEntry(entry) {
|
|
10230
|
+
const name = String(entry.name ?? "");
|
|
10231
|
+
const contentHash = typeof entry.contentHash === "string" ? entry.contentHash : void 0;
|
|
10232
|
+
const legacyHash = typeof entry.hash === "string" ? entry.hash : void 0;
|
|
10233
|
+
const trusted = contentHash ? entry.trusted === true : false;
|
|
10234
|
+
return {
|
|
10235
|
+
name,
|
|
10236
|
+
enabled: entry.enabled === true,
|
|
10237
|
+
trusted,
|
|
10238
|
+
contentHash: contentHash ?? legacyHash,
|
|
10239
|
+
installedAt: String(entry.installedAt ?? (/* @__PURE__ */ new Date(0)).toISOString()),
|
|
10240
|
+
trustedAt: trusted && entry.trustedAt ? String(entry.trustedAt) : void 0,
|
|
10241
|
+
enabledAt: entry.enabledAt ? String(entry.enabledAt) : void 0
|
|
10242
|
+
};
|
|
10243
|
+
}
|
|
10228
10244
|
function saveState(configDir, state2) {
|
|
10229
10245
|
mkdirSync9(pluginRoot(configDir), { recursive: true });
|
|
10230
10246
|
atomicWriteFileSync(statePath(configDir), JSON.stringify(state2, null, 2));
|
|
10231
10247
|
}
|
|
10232
|
-
function
|
|
10233
|
-
|
|
10248
|
+
function normalizeForHash(buf) {
|
|
10249
|
+
const str = buf.toString("utf-8").replaceAll("\r\n", "\n");
|
|
10250
|
+
return Buffer.from(str, "utf-8");
|
|
10251
|
+
}
|
|
10252
|
+
function extractCommandPaths(command, pluginDir) {
|
|
10253
|
+
const resolvedDir = resolve7(pluginDir);
|
|
10254
|
+
const refs = [];
|
|
10255
|
+
for (const m of command.matchAll(/\$PLUGIN_DIR[\\/]([^"'\s]+)/g)) {
|
|
10256
|
+
refs.push(m[1]);
|
|
10257
|
+
}
|
|
10258
|
+
for (const m of command.matchAll(/\$\{pluginDir\}[\\/]([^"'\s}]+)/g)) {
|
|
10259
|
+
refs.push(m[1]);
|
|
10260
|
+
}
|
|
10261
|
+
for (const m of command.matchAll(/(?<=["'\s])(\.?[.\\/][^"'\s]+)/g)) {
|
|
10262
|
+
refs.push(m[0]);
|
|
10263
|
+
}
|
|
10264
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10265
|
+
const valid = [];
|
|
10266
|
+
for (const ref of refs) {
|
|
10267
|
+
if (seen.has(ref)) continue;
|
|
10268
|
+
seen.add(ref);
|
|
10269
|
+
try {
|
|
10270
|
+
const abs = resolve7(resolvedDir, ref);
|
|
10271
|
+
if (!abs.startsWith(resolvedDir + sep3)) continue;
|
|
10272
|
+
if (existsSync18(abs)) {
|
|
10273
|
+
const real = realpathSync2(abs);
|
|
10274
|
+
if (!real.startsWith(resolvedDir + sep3)) continue;
|
|
10275
|
+
valid.push(relative3(resolvedDir, real));
|
|
10276
|
+
}
|
|
10277
|
+
} catch {
|
|
10278
|
+
}
|
|
10279
|
+
}
|
|
10280
|
+
return valid;
|
|
10281
|
+
}
|
|
10282
|
+
function hashPluginContent(pluginDir, manifest) {
|
|
10283
|
+
const resolvedDir = resolve7(pluginDir);
|
|
10284
|
+
const assetRels = /* @__PURE__ */ new Set(
|
|
10285
|
+
[...manifest.skills, ...manifest.commands, ...manifest.agents]
|
|
10286
|
+
);
|
|
10287
|
+
for (const raw of Object.values(manifest.hooks?.events ?? {})) {
|
|
10288
|
+
const items = Array.isArray(raw) ? raw : [raw];
|
|
10289
|
+
for (const item of items) {
|
|
10290
|
+
const cmd = typeof item === "string" ? item : item.command;
|
|
10291
|
+
if (cmd) {
|
|
10292
|
+
for (const p of extractCommandPaths(cmd, pluginDir)) assetRels.add(p);
|
|
10293
|
+
}
|
|
10294
|
+
}
|
|
10295
|
+
}
|
|
10296
|
+
for (const server of Object.values(manifest.mcpServers ?? {})) {
|
|
10297
|
+
for (const p of extractCommandPaths(server.command, pluginDir)) assetRels.add(p);
|
|
10298
|
+
for (const arg of server.args ?? []) {
|
|
10299
|
+
for (const p of extractCommandPaths(arg, pluginDir)) assetRels.add(p);
|
|
10300
|
+
}
|
|
10301
|
+
}
|
|
10302
|
+
const sorted = [...assetRels].sort();
|
|
10303
|
+
const hasher = createHash3("sha256");
|
|
10304
|
+
const manifestPath = join13(resolvedDir, MANIFEST_RELATIVE);
|
|
10305
|
+
hasher.update(normalizeForHash(readFileSync13(manifestPath)));
|
|
10306
|
+
for (const rel of sorted) {
|
|
10307
|
+
const abs = resolve7(resolvedDir, rel);
|
|
10308
|
+
if (!abs.startsWith(resolvedDir + sep3)) {
|
|
10309
|
+
throw new Error(`plugin asset escapes plugin dir: ${rel}`);
|
|
10310
|
+
}
|
|
10311
|
+
let realPath;
|
|
10312
|
+
try {
|
|
10313
|
+
realPath = realpathSync2(abs);
|
|
10314
|
+
} catch {
|
|
10315
|
+
continue;
|
|
10316
|
+
}
|
|
10317
|
+
try {
|
|
10318
|
+
if (statSync7(realPath).isDirectory()) continue;
|
|
10319
|
+
} catch {
|
|
10320
|
+
continue;
|
|
10321
|
+
}
|
|
10322
|
+
if (!realPath.startsWith(resolvedDir + sep3)) {
|
|
10323
|
+
throw new Error(`plugin asset symlink escapes plugin dir: ${rel} \u2192 ${realPath}`);
|
|
10324
|
+
}
|
|
10325
|
+
hasher.update(normalizeForHash(readFileSync13(abs)));
|
|
10326
|
+
}
|
|
10327
|
+
return hasher.digest("hex");
|
|
10328
|
+
}
|
|
10329
|
+
function effectiveHash(entry) {
|
|
10330
|
+
return entry.contentHash ?? entry.hash ?? "";
|
|
10234
10331
|
}
|
|
10235
10332
|
function readPluginManifest(manifestPath) {
|
|
10236
10333
|
return PluginManifestSchema.parse(JSON.parse(readFileSync13(manifestPath, "utf-8")));
|
|
@@ -10251,19 +10348,19 @@ function installPlugin(configDir, inputPath) {
|
|
|
10251
10348
|
if (existsSync18(targetDir)) rmSync(targetDir, { recursive: true, force: true });
|
|
10252
10349
|
cpSync(sourceDir, targetDir, { recursive: true });
|
|
10253
10350
|
const manifestPath = pluginManifestPath(targetDir);
|
|
10254
|
-
const
|
|
10351
|
+
const contentHash = hashPluginContent(targetDir, manifest);
|
|
10255
10352
|
const state2 = loadState(configDir);
|
|
10256
10353
|
const previous = state2.plugins.find((p) => p.name === manifest.name);
|
|
10257
10354
|
const next = {
|
|
10258
10355
|
name: manifest.name,
|
|
10259
10356
|
enabled: previous?.enabled ?? false,
|
|
10260
10357
|
trusted: false,
|
|
10261
|
-
|
|
10358
|
+
contentHash,
|
|
10262
10359
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10263
10360
|
};
|
|
10264
10361
|
state2.plugins = [...state2.plugins.filter((p) => p.name !== manifest.name), next];
|
|
10265
10362
|
saveState(configDir, state2);
|
|
10266
|
-
return { name: manifest.name, dir: targetDir, manifestPath, manifest, hash, enabled: next.enabled, trusted: false, valid: true };
|
|
10363
|
+
return { name: manifest.name, dir: targetDir, manifestPath, manifest, hash: contentHash, enabled: next.enabled, trusted: false, valid: true };
|
|
10267
10364
|
}
|
|
10268
10365
|
function setPluginEnabled(configDir, name, enabled) {
|
|
10269
10366
|
const plugin = getInstalledPlugin(configDir, name);
|
|
@@ -10273,10 +10370,10 @@ function setPluginEnabled(configDir, name, enabled) {
|
|
|
10273
10370
|
name: plugin.name,
|
|
10274
10371
|
enabled: false,
|
|
10275
10372
|
trusted: false,
|
|
10276
|
-
|
|
10373
|
+
contentHash: plugin.hash,
|
|
10277
10374
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10278
10375
|
};
|
|
10279
|
-
const next = { ...current, enabled,
|
|
10376
|
+
const next = { ...current, enabled, contentHash: plugin.hash, enabledAt: enabled ? (/* @__PURE__ */ new Date()).toISOString() : current.enabledAt };
|
|
10280
10377
|
state2.plugins = [...state2.plugins.filter((p) => p.name !== plugin.name), next];
|
|
10281
10378
|
saveState(configDir, state2);
|
|
10282
10379
|
return next;
|
|
@@ -10289,10 +10386,10 @@ function trustPlugin(configDir, name) {
|
|
|
10289
10386
|
name: plugin.name,
|
|
10290
10387
|
enabled: false,
|
|
10291
10388
|
trusted: false,
|
|
10292
|
-
|
|
10389
|
+
contentHash: plugin.hash,
|
|
10293
10390
|
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10294
10391
|
};
|
|
10295
|
-
const next = { ...current, trusted: true,
|
|
10392
|
+
const next = { ...current, trusted: true, contentHash: plugin.hash, trustedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
10296
10393
|
state2.plugins = [...state2.plugins.filter((p) => p.name !== plugin.name), next];
|
|
10297
10394
|
saveState(configDir, state2);
|
|
10298
10395
|
return next;
|
|
@@ -10320,15 +10417,15 @@ function listInstalledPlugins(configDir) {
|
|
|
10320
10417
|
if (!existsSync18(manifestPath)) continue;
|
|
10321
10418
|
try {
|
|
10322
10419
|
const manifest = readPluginManifest(manifestPath);
|
|
10323
|
-
const
|
|
10420
|
+
const contentHash = hashPluginContent(dir, manifest);
|
|
10324
10421
|
const st = state2.plugins.find((p) => p.name === manifest.name);
|
|
10325
|
-
const trusted = st?.trusted === true && st
|
|
10422
|
+
const trusted = st?.trusted === true && effectiveHash(st) === contentHash;
|
|
10326
10423
|
out.push({
|
|
10327
10424
|
name: manifest.name,
|
|
10328
10425
|
dir,
|
|
10329
10426
|
manifestPath,
|
|
10330
10427
|
manifest,
|
|
10331
|
-
hash,
|
|
10428
|
+
hash: contentHash,
|
|
10332
10429
|
enabled: st?.enabled === true,
|
|
10333
10430
|
trusted,
|
|
10334
10431
|
valid: true
|
|
@@ -13607,7 +13704,7 @@ function autoTrimSessionIfNeeded(session, sizeLimit = SESSION_SIZE_LIMIT) {
|
|
|
13607
13704
|
|
|
13608
13705
|
// src/core/context-files.ts
|
|
13609
13706
|
import { existsSync as existsSync26, readFileSync as readFileSync19 } from "fs";
|
|
13610
|
-
import { join as join19, relative as
|
|
13707
|
+
import { join as join19, relative as relative4, resolve as resolve9 } from "path";
|
|
13611
13708
|
function uniqueNonEmpty(values) {
|
|
13612
13709
|
const seen = /* @__PURE__ */ new Set();
|
|
13613
13710
|
const out = [];
|
|
@@ -13623,14 +13720,14 @@ function buildContextFileCandidates(fallbackFilenames = []) {
|
|
|
13623
13720
|
return uniqueNonEmpty([...CONTEXT_FILE_CANDIDATES, ...fallbackFilenames]);
|
|
13624
13721
|
}
|
|
13625
13722
|
function displayPath(filePath, cwd) {
|
|
13626
|
-
const rel =
|
|
13723
|
+
const rel = relative4(cwd, filePath);
|
|
13627
13724
|
if (rel && !rel.startsWith("..") && !rel.startsWith("/") && !rel.startsWith("\\")) {
|
|
13628
13725
|
return rel;
|
|
13629
13726
|
}
|
|
13630
13727
|
return filePath;
|
|
13631
13728
|
}
|
|
13632
13729
|
function isInsideOrEqual(parent, child) {
|
|
13633
|
-
const rel =
|
|
13730
|
+
const rel = relative4(resolve9(parent), resolve9(child));
|
|
13634
13731
|
return rel === "" || !!rel && !rel.startsWith("..") && !rel.startsWith("/") && !rel.startsWith("\\");
|
|
13635
13732
|
}
|
|
13636
13733
|
function readContextFile(level, filePath, cwd, maxBytes) {
|
|
@@ -13763,8 +13860,8 @@ function loadContextFiles(options) {
|
|
|
13763
13860
|
}
|
|
13764
13861
|
|
|
13765
13862
|
// src/web/session-handler.ts
|
|
13766
|
-
import { mkdirSync as
|
|
13767
|
-
import { join as join26, dirname as
|
|
13863
|
+
import { mkdirSync as mkdirSync15, createWriteStream as createWriteStream2 } from "fs";
|
|
13864
|
+
import { join as join26, dirname as dirname10 } from "path";
|
|
13768
13865
|
|
|
13769
13866
|
// src/repl/commands/project-init.ts
|
|
13770
13867
|
import { existsSync as existsSync27, readFileSync as readFileSync20, readdirSync as readdirSync11, statSync as statSync9 } from "fs";
|
|
@@ -15889,7 +15986,7 @@ async function handleSecurityReview(args, ctx) {
|
|
|
15889
15986
|
async function handleTest(args, ctx) {
|
|
15890
15987
|
ctx.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
15891
15988
|
try {
|
|
15892
|
-
const { executeTests } = await import("./run-tests-
|
|
15989
|
+
const { executeTests } = await import("./run-tests-DI6WEYHX.js");
|
|
15893
15990
|
const argStr = args.join(" ").trim();
|
|
15894
15991
|
let testArgs = {};
|
|
15895
15992
|
if (argStr) {
|
|
@@ -17217,7 +17314,7 @@ Try: /compact to reduce context, /clear to reset, or switch to a larger-context
|
|
|
17217
17314
|
this.send({ type: "response_done", content, usage });
|
|
17218
17315
|
if (pendingTeeSave && isCleanDocumentBody(content)) {
|
|
17219
17316
|
try {
|
|
17220
|
-
|
|
17317
|
+
mkdirSync15(dirname10(pendingTeeSave), { recursive: true });
|
|
17221
17318
|
const bodyToSave = stripOuterCodeFence(content);
|
|
17222
17319
|
atomicWriteFileSync(pendingTeeSave, bodyToSave);
|
|
17223
17320
|
undoStack.push(pendingTeeSave, `save_last_response (deferred): ${pendingTeeSave}`);
|
|
@@ -17393,8 +17490,8 @@ ${summaryContent}`,
|
|
|
17393
17490
|
let isError = false;
|
|
17394
17491
|
let summary;
|
|
17395
17492
|
try {
|
|
17396
|
-
|
|
17397
|
-
fileStream =
|
|
17493
|
+
mkdirSync15(dirname10(saveToFile), { recursive: true });
|
|
17494
|
+
fileStream = createWriteStream2(saveToFile);
|
|
17398
17495
|
const teeSystemPrompt = stripToolCallReminder(systemPrompt ?? "") + CONTENT_ONLY_STREAM_REMINDER;
|
|
17399
17496
|
const teeExtraMessages = extraMessages.length > 0 ? [...extraMessages, { role: "user", content: TEE_FINAL_USER_NUDGE }] : [{ role: "user", content: TEE_FINAL_USER_NUDGE }];
|
|
17400
17497
|
const chatRequest = {
|
|
@@ -17968,8 +18065,8 @@ async function setupProxy(configProxy) {
|
|
|
17968
18065
|
}
|
|
17969
18066
|
|
|
17970
18067
|
// src/web/auth.ts
|
|
17971
|
-
import { existsSync as
|
|
17972
|
-
import { isAbsolute as isAbsolute3, join as join27, relative as
|
|
18068
|
+
import { existsSync as existsSync32, readFileSync as readFileSync24, writeFileSync as writeFileSync5, mkdirSync as mkdirSync16, readdirSync as readdirSync15, copyFileSync } from "fs";
|
|
18069
|
+
import { isAbsolute as isAbsolute3, join as join27, relative as relative5 } from "path";
|
|
17973
18070
|
import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
|
|
17974
18071
|
var USERS_FILE = "users.json";
|
|
17975
18072
|
var TOKEN_EXPIRY_HOURS = 24;
|
|
@@ -18015,7 +18112,7 @@ var AuthManager = class {
|
|
|
18015
18112
|
const passwordHash = this.hashPassword(password, salt);
|
|
18016
18113
|
const dataDir = join27(USERS_DIR, username);
|
|
18017
18114
|
const fullDataDir = join27(this.baseDir, dataDir);
|
|
18018
|
-
|
|
18115
|
+
mkdirSync16(join27(fullDataDir, "history"), { recursive: true });
|
|
18019
18116
|
const user = {
|
|
18020
18117
|
username,
|
|
18021
18118
|
passwordHash,
|
|
@@ -18167,25 +18264,25 @@ var AuthManager = class {
|
|
|
18167
18264
|
if (err) return err;
|
|
18168
18265
|
const userDir = this.getUserDataDir(username);
|
|
18169
18266
|
const globalConfig = join27(this.baseDir, "config.json");
|
|
18170
|
-
if (
|
|
18267
|
+
if (existsSync32(globalConfig)) {
|
|
18171
18268
|
try {
|
|
18172
|
-
const content =
|
|
18173
|
-
|
|
18269
|
+
const content = readFileSync24(globalConfig, "utf-8");
|
|
18270
|
+
writeFileSync5(join27(userDir, "config.json"), content, "utf-8");
|
|
18174
18271
|
} catch {
|
|
18175
18272
|
}
|
|
18176
18273
|
}
|
|
18177
18274
|
const globalMemory = join27(this.baseDir, "memory.md");
|
|
18178
|
-
if (
|
|
18275
|
+
if (existsSync32(globalMemory)) {
|
|
18179
18276
|
try {
|
|
18180
|
-
const content =
|
|
18181
|
-
|
|
18277
|
+
const content = readFileSync24(globalMemory, "utf-8");
|
|
18278
|
+
writeFileSync5(join27(userDir, "memory.md"), content, "utf-8");
|
|
18182
18279
|
} catch {
|
|
18183
18280
|
}
|
|
18184
18281
|
}
|
|
18185
18282
|
const globalHistory = join27(this.baseDir, "history");
|
|
18186
|
-
if (
|
|
18283
|
+
if (existsSync32(globalHistory)) {
|
|
18187
18284
|
try {
|
|
18188
|
-
const files =
|
|
18285
|
+
const files = readdirSync15(globalHistory).filter((f) => f.endsWith(".json"));
|
|
18189
18286
|
const userHistory = join27(userDir, "history");
|
|
18190
18287
|
for (const f of files) {
|
|
18191
18288
|
try {
|
|
@@ -18200,9 +18297,9 @@ var AuthManager = class {
|
|
|
18200
18297
|
}
|
|
18201
18298
|
// ── Private methods ────────────────────────────────────────────
|
|
18202
18299
|
loadOrCreate() {
|
|
18203
|
-
if (
|
|
18300
|
+
if (existsSync32(this.usersFile)) {
|
|
18204
18301
|
try {
|
|
18205
|
-
const parsed = JSON.parse(
|
|
18302
|
+
const parsed = JSON.parse(readFileSync24(this.usersFile, "utf-8"));
|
|
18206
18303
|
if (!this.isValidUsersDB(parsed)) {
|
|
18207
18304
|
throw new Error("database structure is invalid");
|
|
18208
18305
|
}
|
|
@@ -18236,7 +18333,7 @@ var AuthManager = class {
|
|
|
18236
18333
|
if (typeof record.username !== "string" || !/^[a-z0-9_-]{2,32}$/.test(record.username) || usernames.has(record.username) || typeof record.passwordHash !== "string" || record.passwordHash.length === 0 || typeof record.salt !== "string" || record.salt.length === 0 || typeof record.createdAt !== "string" || typeof record.dataDir !== "string" || record.dataDir.length === 0 || isAbsolute3(record.dataDir)) {
|
|
18237
18334
|
return false;
|
|
18238
18335
|
}
|
|
18239
|
-
const dataDirFromBase =
|
|
18336
|
+
const dataDirFromBase = relative5(this.baseDir, join27(this.baseDir, record.dataDir));
|
|
18240
18337
|
if (dataDirFromBase.startsWith("..") || isAbsolute3(dataDirFromBase)) return false;
|
|
18241
18338
|
if (record.hashVersion !== void 0 && record.hashVersion !== 1 && record.hashVersion !== 2) return false;
|
|
18242
18339
|
if (record.tokensRevokedBefore !== void 0 && !Number.isFinite(record.tokensRevokedBefore)) return false;
|
|
@@ -18248,7 +18345,7 @@ var AuthManager = class {
|
|
|
18248
18345
|
this.saveDB(this.db);
|
|
18249
18346
|
}
|
|
18250
18347
|
saveDB(db) {
|
|
18251
|
-
|
|
18348
|
+
mkdirSync16(this.baseDir, { recursive: true });
|
|
18252
18349
|
atomicWriteFileSync(this.usersFile, JSON.stringify(db, null, 2));
|
|
18253
18350
|
}
|
|
18254
18351
|
/** Legacy hash — kept only for migrating old users (v0.2.x) */
|
|
@@ -18280,7 +18377,7 @@ function getModuleDir() {
|
|
|
18280
18377
|
if (typeof import.meta?.url === "string") {
|
|
18281
18378
|
const url = new URL(import.meta.url);
|
|
18282
18379
|
const filePath = url.pathname.replace(/^\/([A-Z]:)/i, "$1");
|
|
18283
|
-
return
|
|
18380
|
+
return dirname11(filePath);
|
|
18284
18381
|
}
|
|
18285
18382
|
} catch {
|
|
18286
18383
|
}
|
|
@@ -18353,7 +18450,7 @@ async function startWebServer(options = {}) {
|
|
|
18353
18450
|
}
|
|
18354
18451
|
let skillManager = null;
|
|
18355
18452
|
const skillsDir = join28(config.getConfigDir(), SKILLS_DIR_NAME);
|
|
18356
|
-
if (
|
|
18453
|
+
if (existsSync33(skillsDir)) {
|
|
18357
18454
|
skillManager = new SkillManager(skillsDir, config.get("ui").skillSizeWarn);
|
|
18358
18455
|
skillManager.loadSkills(pluginAssets.skillDirs);
|
|
18359
18456
|
const count = skillManager.listSkills().length;
|
|
@@ -18425,13 +18522,13 @@ async function startWebServer(options = {}) {
|
|
|
18425
18522
|
};
|
|
18426
18523
|
const moduleDir = getModuleDir();
|
|
18427
18524
|
let clientDir = join28(moduleDir, "web", "client");
|
|
18428
|
-
if (!
|
|
18525
|
+
if (!existsSync33(clientDir)) {
|
|
18429
18526
|
clientDir = join28(moduleDir, "client");
|
|
18430
18527
|
}
|
|
18431
|
-
if (!
|
|
18528
|
+
if (!existsSync33(clientDir)) {
|
|
18432
18529
|
clientDir = join28(moduleDir, "..", "..", "src", "web", "client");
|
|
18433
18530
|
}
|
|
18434
|
-
if (!
|
|
18531
|
+
if (!existsSync33(clientDir)) {
|
|
18435
18532
|
clientDir = join28(process.cwd(), "src", "web", "client");
|
|
18436
18533
|
}
|
|
18437
18534
|
console.log(` Static files: ${clientDir}`);
|
|
@@ -18504,9 +18601,9 @@ async function startWebServer(options = {}) {
|
|
|
18504
18601
|
const prefix = req.query.prefix || "";
|
|
18505
18602
|
const targetDir = join28(cwd, prefix);
|
|
18506
18603
|
try {
|
|
18507
|
-
const canonicalTarget =
|
|
18508
|
-
const canonicalCwd =
|
|
18509
|
-
if (!canonicalTarget.startsWith(canonicalCwd +
|
|
18604
|
+
const canonicalTarget = realpathSync3(resolve13(targetDir));
|
|
18605
|
+
const canonicalCwd = realpathSync3(resolve13(cwd));
|
|
18606
|
+
if (!canonicalTarget.startsWith(canonicalCwd + sep4) && canonicalTarget !== canonicalCwd) {
|
|
18510
18607
|
res.json({ files: [] });
|
|
18511
18608
|
return;
|
|
18512
18609
|
}
|
|
@@ -18516,10 +18613,10 @@ async function startWebServer(options = {}) {
|
|
|
18516
18613
|
}
|
|
18517
18614
|
try {
|
|
18518
18615
|
const SKIP = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", "dist-cjs", "release", "__pycache__", ".next", ".nuxt", "coverage", ".cache"]);
|
|
18519
|
-
const entries =
|
|
18616
|
+
const entries = readdirSync16(targetDir, { withFileTypes: true });
|
|
18520
18617
|
const files = entries.filter((e) => !SKIP.has(e.name) && !e.name.startsWith(".")).slice(0, 50).map((e) => ({
|
|
18521
18618
|
name: e.name,
|
|
18522
|
-
path:
|
|
18619
|
+
path: relative6(cwd, join28(targetDir, e.name)).replace(/\\/g, "/"),
|
|
18523
18620
|
isDir: e.isDirectory()
|
|
18524
18621
|
}));
|
|
18525
18622
|
res.json({ files });
|
|
@@ -18560,14 +18657,14 @@ async function startWebServer(options = {}) {
|
|
|
18560
18657
|
const authUser = req._authUser;
|
|
18561
18658
|
const histDir = authUser ? getUserShared(authUser).config.getHistoryDir() : config.getHistoryDir();
|
|
18562
18659
|
const filePath = join28(histDir, `${id}.json`);
|
|
18563
|
-
if (!
|
|
18660
|
+
if (!existsSync33(filePath)) {
|
|
18564
18661
|
res.status(404).json({ error: "Session not found" });
|
|
18565
18662
|
return;
|
|
18566
18663
|
}
|
|
18567
18664
|
try {
|
|
18568
|
-
const canonicalFile =
|
|
18569
|
-
const canonicalDir =
|
|
18570
|
-
if (!canonicalFile.startsWith(canonicalDir +
|
|
18665
|
+
const canonicalFile = realpathSync3(filePath);
|
|
18666
|
+
const canonicalDir = realpathSync3(histDir);
|
|
18667
|
+
if (!canonicalFile.startsWith(canonicalDir + sep4)) {
|
|
18571
18668
|
res.status(404).json({ error: "Session not found" });
|
|
18572
18669
|
return;
|
|
18573
18670
|
}
|
|
@@ -18575,7 +18672,7 @@ async function startWebServer(options = {}) {
|
|
|
18575
18672
|
res.status(404).json({ error: "Session not found" });
|
|
18576
18673
|
return;
|
|
18577
18674
|
}
|
|
18578
|
-
const data = JSON.parse(
|
|
18675
|
+
const data = JSON.parse(readFileSync25(filePath, "utf-8"));
|
|
18579
18676
|
res.json({ session: data });
|
|
18580
18677
|
} catch (err) {
|
|
18581
18678
|
res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
|
|
@@ -18590,9 +18687,9 @@ async function startWebServer(options = {}) {
|
|
|
18590
18687
|
const cwd = process.cwd();
|
|
18591
18688
|
const fullPath = resolve13(join28(cwd, filePath));
|
|
18592
18689
|
try {
|
|
18593
|
-
const canonicalFull =
|
|
18594
|
-
const canonicalCwd =
|
|
18595
|
-
if (!canonicalFull.startsWith(canonicalCwd +
|
|
18690
|
+
const canonicalFull = realpathSync3(fullPath);
|
|
18691
|
+
const canonicalCwd = realpathSync3(resolve13(cwd));
|
|
18692
|
+
if (!canonicalFull.startsWith(canonicalCwd + sep4) && canonicalFull !== canonicalCwd) {
|
|
18596
18693
|
res.json({ error: "Access denied" });
|
|
18597
18694
|
return;
|
|
18598
18695
|
}
|
|
@@ -18601,12 +18698,12 @@ async function startWebServer(options = {}) {
|
|
|
18601
18698
|
return;
|
|
18602
18699
|
}
|
|
18603
18700
|
try {
|
|
18604
|
-
const stat =
|
|
18701
|
+
const stat = statSync14(fullPath);
|
|
18605
18702
|
if (stat.size > 512 * 1024) {
|
|
18606
18703
|
res.json({ error: `File too large (${(stat.size / 1024).toFixed(0)} KB, max 512 KB)` });
|
|
18607
18704
|
return;
|
|
18608
18705
|
}
|
|
18609
|
-
const content =
|
|
18706
|
+
const content = readFileSync25(fullPath, "utf-8");
|
|
18610
18707
|
res.json({ content, size: stat.size });
|
|
18611
18708
|
} catch {
|
|
18612
18709
|
res.json({ error: "Cannot read file" });
|
|
@@ -18862,16 +18959,16 @@ function resolveProjectMcpPath() {
|
|
|
18862
18959
|
const gitRoot = getGitRoot(cwd);
|
|
18863
18960
|
const projectRoot = gitRoot ?? cwd;
|
|
18864
18961
|
const configPath = join28(projectRoot, MCP_PROJECT_CONFIG_NAME);
|
|
18865
|
-
return
|
|
18962
|
+
return existsSync33(configPath) ? configPath : null;
|
|
18866
18963
|
}
|
|
18867
18964
|
function loadProjectMcpConfig() {
|
|
18868
18965
|
const cwd = process.cwd();
|
|
18869
18966
|
const gitRoot = getGitRoot(cwd);
|
|
18870
18967
|
const projectRoot = gitRoot ?? cwd;
|
|
18871
18968
|
const configPath = join28(projectRoot, MCP_PROJECT_CONFIG_NAME);
|
|
18872
|
-
if (!
|
|
18969
|
+
if (!existsSync33(configPath)) return null;
|
|
18873
18970
|
try {
|
|
18874
|
-
const raw = JSON.parse(
|
|
18971
|
+
const raw = JSON.parse(readFileSync25(configPath, "utf-8"));
|
|
18875
18972
|
return raw.mcpServers ?? raw;
|
|
18876
18973
|
} catch {
|
|
18877
18974
|
return null;
|
|
@@ -154,7 +154,7 @@ ${content}`);
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
157
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
157
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-WS724BUX.js");
|
|
158
158
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
159
159
|
let interrupted = false;
|
|
160
160
|
const onSigint = () => {
|