agentdev 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BasicAgent-UWXLSZP2.js → BasicAgent-R7DYGTHF.js} +3 -3
- package/dist/{ExplorerAgent-LCM3JQS4.js → ExplorerAgent-DXY3OQ5U.js} +3 -3
- package/dist/{chunk-A354ZCZF.js → chunk-3AR3JBW6.js} +209 -151
- package/dist/chunk-3AR3JBW6.js.map +1 -0
- package/dist/{chunk-QFHPUAUQ.js → chunk-72H6A6NB.js} +3 -3
- package/dist/{chunk-5T4C2XRT.js → chunk-REOJZCSZ.js} +3 -3
- package/dist/create-feature-cli.js +26 -7
- package/dist/index.d.ts +27 -2
- package/dist/index.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-A354ZCZF.js.map +0 -1
- /package/dist/{BasicAgent-UWXLSZP2.js.map → BasicAgent-R7DYGTHF.js.map} +0 -0
- /package/dist/{ExplorerAgent-LCM3JQS4.js.map → ExplorerAgent-DXY3OQ5U.js.map} +0 -0
- /package/dist/{chunk-QFHPUAUQ.js.map → chunk-72H6A6NB.js.map} +0 -0
- /package/dist/{chunk-5T4C2XRT.js.map → chunk-REOJZCSZ.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BasicAgent
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-REOJZCSZ.js";
|
|
4
|
+
import "./chunk-3AR3JBW6.js";
|
|
5
5
|
import "./chunk-BVF7RUXV.js";
|
|
6
6
|
import "./chunk-EECW6PYP.js";
|
|
7
7
|
import "./chunk-G5ECPY4K.js";
|
|
@@ -10,4 +10,4 @@ import "./chunk-BDS2QGZ5.js";
|
|
|
10
10
|
export {
|
|
11
11
|
BasicAgent
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=BasicAgent-
|
|
13
|
+
//# sourceMappingURL=BasicAgent-R7DYGTHF.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExplorerAgent
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-72H6A6NB.js";
|
|
4
|
+
import "./chunk-3AR3JBW6.js";
|
|
5
5
|
import "./chunk-BVF7RUXV.js";
|
|
6
6
|
import "./chunk-EECW6PYP.js";
|
|
7
7
|
import "./chunk-G5ECPY4K.js";
|
|
@@ -10,4 +10,4 @@ import "./chunk-BDS2QGZ5.js";
|
|
|
10
10
|
export {
|
|
11
11
|
ExplorerAgent
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=ExplorerAgent-
|
|
13
|
+
//# sourceMappingURL=ExplorerAgent-DXY3OQ5U.js.map
|
|
@@ -1208,6 +1208,107 @@ var TemplateComposer = class _TemplateComposer {
|
|
|
1208
1208
|
}
|
|
1209
1209
|
};
|
|
1210
1210
|
|
|
1211
|
+
// src/skills/loader.ts
|
|
1212
|
+
import { readdir as readdir2, readFile as readFile3 } from "fs/promises";
|
|
1213
|
+
import { resolve as resolve3, isAbsolute, join as join2, normalize } from "path";
|
|
1214
|
+
import { existsSync as existsSync2 } from "fs";
|
|
1215
|
+
function parseSkillFrontmatter(content, path2) {
|
|
1216
|
+
if (!content.trimStart().startsWith("---")) {
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
const frontmatterEnd = content.indexOf("---", 3);
|
|
1220
|
+
if (frontmatterEnd === -1) {
|
|
1221
|
+
return null;
|
|
1222
|
+
}
|
|
1223
|
+
const frontmatterStr = content.slice(3, frontmatterEnd).trim();
|
|
1224
|
+
const nameMatch = frontmatterStr.match(/^name:\s*(.+)$/m);
|
|
1225
|
+
const descriptionMatch = frontmatterStr.match(/^description:\s*(.+)$/m);
|
|
1226
|
+
if (!nameMatch || !descriptionMatch) {
|
|
1227
|
+
return null;
|
|
1228
|
+
}
|
|
1229
|
+
const name = nameMatch[1].trim();
|
|
1230
|
+
const description = descriptionMatch[1].trim();
|
|
1231
|
+
const cleanValue = (value) => {
|
|
1232
|
+
value = value.trim();
|
|
1233
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1234
|
+
return value.slice(1, -1);
|
|
1235
|
+
}
|
|
1236
|
+
return value;
|
|
1237
|
+
};
|
|
1238
|
+
return {
|
|
1239
|
+
name: cleanValue(name),
|
|
1240
|
+
description: cleanValue(description),
|
|
1241
|
+
path: path2
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
async function collectSkillFiles(dir, skillsDir) {
|
|
1245
|
+
const skillFiles = [];
|
|
1246
|
+
try {
|
|
1247
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
1248
|
+
for (const entry of entries) {
|
|
1249
|
+
const fullPath = join2(dir, entry.name);
|
|
1250
|
+
if (entry.isFile() && entry.name === "SKILL.md") {
|
|
1251
|
+
skillFiles.push(normalize(fullPath));
|
|
1252
|
+
} else if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
1253
|
+
let isLinkToDir = false;
|
|
1254
|
+
if (entry.isSymbolicLink()) {
|
|
1255
|
+
try {
|
|
1256
|
+
const stats = await readFileStats(fullPath);
|
|
1257
|
+
isLinkToDir = stats.isDirectory();
|
|
1258
|
+
} catch {
|
|
1259
|
+
continue;
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
if (isLinkToDir || entry.isDirectory()) {
|
|
1263
|
+
const subFiles = await collectSkillFiles(fullPath, skillsDir);
|
|
1264
|
+
skillFiles.push(...subFiles);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
} catch {
|
|
1269
|
+
}
|
|
1270
|
+
return skillFiles;
|
|
1271
|
+
}
|
|
1272
|
+
async function readFileStats(path2) {
|
|
1273
|
+
const { stat: stat4 } = await import("fs/promises");
|
|
1274
|
+
return stat4(path2);
|
|
1275
|
+
}
|
|
1276
|
+
async function discover(options = {}) {
|
|
1277
|
+
const { dir } = options;
|
|
1278
|
+
const skillsDir = resolveSkillsDir(dir);
|
|
1279
|
+
if (!existsSync2(skillsDir)) {
|
|
1280
|
+
return [];
|
|
1281
|
+
}
|
|
1282
|
+
const skills = [];
|
|
1283
|
+
try {
|
|
1284
|
+
const skillFiles = await collectSkillFiles(skillsDir, skillsDir);
|
|
1285
|
+
for (const fullPath of skillFiles) {
|
|
1286
|
+
try {
|
|
1287
|
+
const content = await readFile3(fullPath, "utf-8");
|
|
1288
|
+
const metadata = parseSkillFrontmatter(content, fullPath);
|
|
1289
|
+
if (metadata) {
|
|
1290
|
+
skills.push(metadata);
|
|
1291
|
+
}
|
|
1292
|
+
} catch {
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
} catch {
|
|
1296
|
+
return [];
|
|
1297
|
+
}
|
|
1298
|
+
return skills;
|
|
1299
|
+
}
|
|
1300
|
+
function resolveSkillsDir(dir) {
|
|
1301
|
+
const cwd6 = process.cwd();
|
|
1302
|
+
if (dir) {
|
|
1303
|
+
if (isAbsolute(dir)) {
|
|
1304
|
+
return dir;
|
|
1305
|
+
}
|
|
1306
|
+
const resolved = resolve3(cwd6, dir);
|
|
1307
|
+
return resolved;
|
|
1308
|
+
}
|
|
1309
|
+
return resolve3(cwd6, ".agentdev", "skills");
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1211
1312
|
// src/core/lifecycle.ts
|
|
1212
1313
|
var CoreLifecycle = /* @__PURE__ */ ((CoreLifecycle2) => {
|
|
1213
1314
|
CoreLifecycle2["AgentInitiate"] = "AgentInitiate";
|
|
@@ -1364,21 +1465,21 @@ function getDecoratorMetadata(target) {
|
|
|
1364
1465
|
|
|
1365
1466
|
// src/core/feature.ts
|
|
1366
1467
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1367
|
-
import { dirname as
|
|
1368
|
-
import { existsSync as
|
|
1468
|
+
import { dirname as dirname3, join as join3 } from "path";
|
|
1469
|
+
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
1369
1470
|
function getPackageInfoFromSource(source) {
|
|
1370
1471
|
if (!source) {
|
|
1371
1472
|
return null;
|
|
1372
1473
|
}
|
|
1373
1474
|
try {
|
|
1374
1475
|
const filePath = source.startsWith("file://") ? fileURLToPath2(source) : source;
|
|
1375
|
-
const featureDir =
|
|
1476
|
+
const featureDir = dirname3(filePath);
|
|
1376
1477
|
let currentDir = featureDir;
|
|
1377
1478
|
const root = process.platform === "win32" ? currentDir.split(/[/\\]/)[0] : "";
|
|
1378
1479
|
while (currentDir && currentDir !== root) {
|
|
1379
1480
|
try {
|
|
1380
|
-
const packageJsonPath =
|
|
1381
|
-
if (!
|
|
1481
|
+
const packageJsonPath = join3(currentDir, "package.json");
|
|
1482
|
+
if (!existsSync3(packageJsonPath)) {
|
|
1382
1483
|
throw new Error("Not found");
|
|
1383
1484
|
}
|
|
1384
1485
|
const content = readFileSync(packageJsonPath, "utf-8");
|
|
@@ -1389,7 +1490,7 @@ function getPackageInfoFromSource(source) {
|
|
|
1389
1490
|
root: currentDir
|
|
1390
1491
|
};
|
|
1391
1492
|
} catch {
|
|
1392
|
-
const parentDir =
|
|
1493
|
+
const parentDir = dirname3(currentDir);
|
|
1393
1494
|
if (parentDir === currentDir) {
|
|
1394
1495
|
break;
|
|
1395
1496
|
}
|
|
@@ -1403,13 +1504,13 @@ function getPackageInfoFromSource(source) {
|
|
|
1403
1504
|
}
|
|
1404
1505
|
|
|
1405
1506
|
// src/mcp/config.ts
|
|
1406
|
-
import { existsSync as
|
|
1507
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, readdirSync } from "fs";
|
|
1407
1508
|
import { basename } from "path";
|
|
1408
1509
|
import { cwd as cwd2 } from "process";
|
|
1409
|
-
import { isAbsolute, join as
|
|
1510
|
+
import { isAbsolute as isAbsolute2, join as join4, resolve as resolve4 } from "path";
|
|
1410
1511
|
function readConfigFile(configPath) {
|
|
1411
1512
|
try {
|
|
1412
|
-
if (!
|
|
1513
|
+
if (!existsSync4(configPath)) {
|
|
1413
1514
|
return void 0;
|
|
1414
1515
|
}
|
|
1415
1516
|
const content = readFileSync2(configPath, "utf-8");
|
|
@@ -1464,21 +1565,21 @@ function normalizeToMCPConfig(value, fallbackServerId) {
|
|
|
1464
1565
|
return void 0;
|
|
1465
1566
|
}
|
|
1466
1567
|
function getDefaultMCPConfigDir(rootDir = cwd2()) {
|
|
1467
|
-
return
|
|
1568
|
+
return join4(rootDir, ".agentdev", "mcps");
|
|
1468
1569
|
}
|
|
1469
1570
|
function loadMCPConfigFromInput(input, rootDir = cwd2()) {
|
|
1470
1571
|
let configPath;
|
|
1471
1572
|
let fallbackServerId = "default";
|
|
1472
|
-
if (
|
|
1573
|
+
if (isAbsolute2(input)) {
|
|
1473
1574
|
configPath = input;
|
|
1474
1575
|
} else if (input.includes("/") || input.includes("\\")) {
|
|
1475
|
-
configPath =
|
|
1576
|
+
configPath = resolve4(rootDir, input);
|
|
1476
1577
|
fallbackServerId = basename(configPath, ".json");
|
|
1477
1578
|
} else {
|
|
1478
|
-
configPath =
|
|
1579
|
+
configPath = join4(getDefaultMCPConfigDir(rootDir), `${input}.json`);
|
|
1479
1580
|
fallbackServerId = input;
|
|
1480
1581
|
}
|
|
1481
|
-
if (!
|
|
1582
|
+
if (!existsSync4(configPath)) {
|
|
1482
1583
|
console.warn(`[MCP] Config file does not exist: ${configPath}`);
|
|
1483
1584
|
return void 0;
|
|
1484
1585
|
}
|
|
@@ -1486,7 +1587,7 @@ function loadMCPConfigFromInput(input, rootDir = cwd2()) {
|
|
|
1486
1587
|
}
|
|
1487
1588
|
function loadAllMCPConfigs(rootDir = cwd2(), options = {}) {
|
|
1488
1589
|
const configDir = getDefaultMCPConfigDir(rootDir);
|
|
1489
|
-
if (!
|
|
1590
|
+
if (!existsSync4(configDir)) {
|
|
1490
1591
|
return void 0;
|
|
1491
1592
|
}
|
|
1492
1593
|
const excludedServers = new Set(options.excludeServers ?? []);
|
|
@@ -1496,7 +1597,7 @@ function loadAllMCPConfigs(rootDir = cwd2(), options = {}) {
|
|
|
1496
1597
|
if (!entry.isFile() || !entry.name.endsWith(".json")) {
|
|
1497
1598
|
continue;
|
|
1498
1599
|
}
|
|
1499
|
-
const configPath =
|
|
1600
|
+
const configPath = join4(configDir, entry.name);
|
|
1500
1601
|
const config = readConfigFile(configPath);
|
|
1501
1602
|
if (!config) {
|
|
1502
1603
|
continue;
|
|
@@ -2248,9 +2349,9 @@ async function mountMCPToolsFromConfig(config, options = {}) {
|
|
|
2248
2349
|
|
|
2249
2350
|
// src/features/mcp/index.ts
|
|
2250
2351
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2251
|
-
import { dirname as
|
|
2352
|
+
import { dirname as dirname4 } from "path";
|
|
2252
2353
|
var __filename2 = fileURLToPath3(import.meta.url);
|
|
2253
|
-
var __dirname =
|
|
2354
|
+
var __dirname = dirname4(__filename2);
|
|
2254
2355
|
var MCPFeature = class {
|
|
2255
2356
|
name = "mcp";
|
|
2256
2357
|
dependencies = [];
|
|
@@ -2348,8 +2449,8 @@ var MCPFeature = class {
|
|
|
2348
2449
|
|
|
2349
2450
|
// src/features/audit/index.ts
|
|
2350
2451
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
2351
|
-
import { existsSync as
|
|
2352
|
-
import { resolve as
|
|
2452
|
+
import { existsSync as existsSync5 } from "fs";
|
|
2453
|
+
import { resolve as resolve5, dirname as dirname5 } from "path";
|
|
2353
2454
|
import OpenAI from "openai";
|
|
2354
2455
|
import Database from "better-sqlite3";
|
|
2355
2456
|
import { mkdir as mkdirAsync } from "fs/promises";
|
|
@@ -2402,7 +2503,7 @@ var AuditFeature = class {
|
|
|
2402
2503
|
dbPath: config.dbPath ?? ".agentdev/audit/audit.db",
|
|
2403
2504
|
cacheTtlDays: config.cacheTtlDays ?? 0
|
|
2404
2505
|
};
|
|
2405
|
-
this.dbPath =
|
|
2506
|
+
this.dbPath = resolve5(config.workspaceDir ?? process.cwd(), this.config.dbPath);
|
|
2406
2507
|
this.client = new OpenAI({
|
|
2407
2508
|
baseURL: `${this.config.baseUrl}/v1`,
|
|
2408
2509
|
apiKey: "audit-key"
|
|
@@ -2543,8 +2644,8 @@ ${command}
|
|
|
2543
2644
|
*/
|
|
2544
2645
|
async initDatabase() {
|
|
2545
2646
|
try {
|
|
2546
|
-
const dbDir =
|
|
2547
|
-
if (!
|
|
2647
|
+
const dbDir = dirname5(this.dbPath);
|
|
2648
|
+
if (!existsSync5(dbDir)) {
|
|
2548
2649
|
await mkdirAsync(dbDir, { recursive: true });
|
|
2549
2650
|
this.logger?.info("[AuditFeature] Created database directory", { dbDir });
|
|
2550
2651
|
}
|
|
@@ -2694,10 +2795,10 @@ __decorateClass([
|
|
|
2694
2795
|
|
|
2695
2796
|
// src/features/audio-feedback/index.ts
|
|
2696
2797
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
2697
|
-
import { dirname as
|
|
2798
|
+
import { dirname as dirname6, join as join6 } from "path";
|
|
2698
2799
|
import soundPlay from "sound-play";
|
|
2699
2800
|
var __filename3 = fileURLToPath5(import.meta.url);
|
|
2700
|
-
var __dirname2 =
|
|
2801
|
+
var __dirname2 = dirname6(__filename3);
|
|
2701
2802
|
var AudioFeedbackFeature = class {
|
|
2702
2803
|
name = "audio-feedback";
|
|
2703
2804
|
dependencies = [];
|
|
@@ -2713,7 +2814,7 @@ var AudioFeedbackFeature = class {
|
|
|
2713
2814
|
logger;
|
|
2714
2815
|
constructor(config = {}) {
|
|
2715
2816
|
this.config = {
|
|
2716
|
-
audioPath: config.audioPath ??
|
|
2817
|
+
audioPath: config.audioPath ?? join6(__dirname2, "media", "success.mp3"),
|
|
2717
2818
|
enabled: config.enabled ?? true,
|
|
2718
2819
|
volume: config.volume ?? 0.5
|
|
2719
2820
|
};
|
|
@@ -2793,19 +2894,19 @@ __decorateClass([
|
|
|
2793
2894
|
|
|
2794
2895
|
// src/features/memory/index.ts
|
|
2795
2896
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
2796
|
-
import { readFileSync as readFileSync3, existsSync as
|
|
2797
|
-
import { resolve as
|
|
2897
|
+
import { readFileSync as readFileSync3, existsSync as existsSync6 } from "fs";
|
|
2898
|
+
import { resolve as resolve6 } from "path";
|
|
2798
2899
|
var MemoryFeature = class {
|
|
2799
2900
|
name = "memory";
|
|
2800
2901
|
dependencies = [];
|
|
2801
2902
|
source = fileURLToPath6(import.meta.url).replace(/\\\\/g, "/");
|
|
2802
2903
|
description = "\u81EA\u52A8\u8BFB\u53D6\u5E76\u6CE8\u5165\u9879\u76EE CLAUDE.md \u6587\u4EF6\u4F5C\u4E3A\u7CFB\u7EDF\u63D0\u793A\u8BCD\u3002";
|
|
2803
2904
|
filename;
|
|
2804
|
-
|
|
2905
|
+
sourceRoot;
|
|
2805
2906
|
_packageInfo = null;
|
|
2806
2907
|
constructor(config = {}) {
|
|
2807
2908
|
this.filename = config.filename ?? "CLAUDE.md";
|
|
2808
|
-
this.
|
|
2909
|
+
this.sourceRoot = config.resourceRoot ?? config.workspaceDir ?? process.cwd();
|
|
2809
2910
|
}
|
|
2810
2911
|
/**
|
|
2811
2912
|
* 获取包信息(统一打包方案)
|
|
@@ -2827,9 +2928,9 @@ var MemoryFeature = class {
|
|
|
2827
2928
|
if (!ctx.isFirstCall) {
|
|
2828
2929
|
return;
|
|
2829
2930
|
}
|
|
2830
|
-
const cwd6 = this.
|
|
2831
|
-
const filePath =
|
|
2832
|
-
if (!
|
|
2931
|
+
const cwd6 = this.sourceRoot;
|
|
2932
|
+
const filePath = resolve6(cwd6, this.filename);
|
|
2933
|
+
if (!existsSync6(filePath)) {
|
|
2833
2934
|
return;
|
|
2834
2935
|
}
|
|
2835
2936
|
const content = readFileSync3(filePath, "utf-8");
|
|
@@ -2852,107 +2953,6 @@ __decorateClass([
|
|
|
2852
2953
|
CallStart
|
|
2853
2954
|
], MemoryFeature.prototype, "injectCLAUDEContent", 1);
|
|
2854
2955
|
|
|
2855
|
-
// src/skills/loader.ts
|
|
2856
|
-
import { readdir as readdir2, readFile as readFile3 } from "fs/promises";
|
|
2857
|
-
import { resolve as resolve6, isAbsolute as isAbsolute2, join as join6, normalize } from "path";
|
|
2858
|
-
import { existsSync as existsSync6 } from "fs";
|
|
2859
|
-
function parseSkillFrontmatter(content, path2) {
|
|
2860
|
-
if (!content.trimStart().startsWith("---")) {
|
|
2861
|
-
return null;
|
|
2862
|
-
}
|
|
2863
|
-
const frontmatterEnd = content.indexOf("---", 3);
|
|
2864
|
-
if (frontmatterEnd === -1) {
|
|
2865
|
-
return null;
|
|
2866
|
-
}
|
|
2867
|
-
const frontmatterStr = content.slice(3, frontmatterEnd).trim();
|
|
2868
|
-
const nameMatch = frontmatterStr.match(/^name:\s*(.+)$/m);
|
|
2869
|
-
const descriptionMatch = frontmatterStr.match(/^description:\s*(.+)$/m);
|
|
2870
|
-
if (!nameMatch || !descriptionMatch) {
|
|
2871
|
-
return null;
|
|
2872
|
-
}
|
|
2873
|
-
const name = nameMatch[1].trim();
|
|
2874
|
-
const description = descriptionMatch[1].trim();
|
|
2875
|
-
const cleanValue = (value) => {
|
|
2876
|
-
value = value.trim();
|
|
2877
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2878
|
-
return value.slice(1, -1);
|
|
2879
|
-
}
|
|
2880
|
-
return value;
|
|
2881
|
-
};
|
|
2882
|
-
return {
|
|
2883
|
-
name: cleanValue(name),
|
|
2884
|
-
description: cleanValue(description),
|
|
2885
|
-
path: path2
|
|
2886
|
-
};
|
|
2887
|
-
}
|
|
2888
|
-
async function collectSkillFiles(dir, skillsDir) {
|
|
2889
|
-
const skillFiles = [];
|
|
2890
|
-
try {
|
|
2891
|
-
const entries = await readdir2(dir, { withFileTypes: true });
|
|
2892
|
-
for (const entry of entries) {
|
|
2893
|
-
const fullPath = join6(dir, entry.name);
|
|
2894
|
-
if (entry.isFile() && entry.name === "SKILL.md") {
|
|
2895
|
-
skillFiles.push(normalize(fullPath));
|
|
2896
|
-
} else if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
2897
|
-
let isLinkToDir = false;
|
|
2898
|
-
if (entry.isSymbolicLink()) {
|
|
2899
|
-
try {
|
|
2900
|
-
const stats = await readFileStats(fullPath);
|
|
2901
|
-
isLinkToDir = stats.isDirectory();
|
|
2902
|
-
} catch {
|
|
2903
|
-
continue;
|
|
2904
|
-
}
|
|
2905
|
-
}
|
|
2906
|
-
if (isLinkToDir || entry.isDirectory()) {
|
|
2907
|
-
const subFiles = await collectSkillFiles(fullPath, skillsDir);
|
|
2908
|
-
skillFiles.push(...subFiles);
|
|
2909
|
-
}
|
|
2910
|
-
}
|
|
2911
|
-
}
|
|
2912
|
-
} catch {
|
|
2913
|
-
}
|
|
2914
|
-
return skillFiles;
|
|
2915
|
-
}
|
|
2916
|
-
async function readFileStats(path2) {
|
|
2917
|
-
const { stat: stat4 } = await import("fs/promises");
|
|
2918
|
-
return stat4(path2);
|
|
2919
|
-
}
|
|
2920
|
-
async function discover(options = {}) {
|
|
2921
|
-
const { dir } = options;
|
|
2922
|
-
const skillsDir = resolveSkillsDir(dir);
|
|
2923
|
-
if (!existsSync6(skillsDir)) {
|
|
2924
|
-
return [];
|
|
2925
|
-
}
|
|
2926
|
-
const skills = [];
|
|
2927
|
-
try {
|
|
2928
|
-
const skillFiles = await collectSkillFiles(skillsDir, skillsDir);
|
|
2929
|
-
for (const fullPath of skillFiles) {
|
|
2930
|
-
try {
|
|
2931
|
-
const content = await readFile3(fullPath, "utf-8");
|
|
2932
|
-
const metadata = parseSkillFrontmatter(content, fullPath);
|
|
2933
|
-
if (metadata) {
|
|
2934
|
-
skills.push(metadata);
|
|
2935
|
-
}
|
|
2936
|
-
} catch {
|
|
2937
|
-
}
|
|
2938
|
-
}
|
|
2939
|
-
} catch {
|
|
2940
|
-
return [];
|
|
2941
|
-
}
|
|
2942
|
-
return skills;
|
|
2943
|
-
}
|
|
2944
|
-
function resolveSkillsDir(dir) {
|
|
2945
|
-
const cwd6 = process.cwd();
|
|
2946
|
-
if (dir) {
|
|
2947
|
-
if (isAbsolute2(dir)) {
|
|
2948
|
-
return dir;
|
|
2949
|
-
}
|
|
2950
|
-
const resolved = resolve6(cwd6, dir);
|
|
2951
|
-
return resolved;
|
|
2952
|
-
}
|
|
2953
|
-
return resolve6(cwd6, ".agentdev", "skills");
|
|
2954
|
-
}
|
|
2955
|
-
|
|
2956
2956
|
// src/features/skill/index.ts
|
|
2957
2957
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
2958
2958
|
import { dirname as dirname8 } from "path";
|
|
@@ -3021,6 +3021,7 @@ var SkillFeature = class {
|
|
|
3021
3021
|
description = "\u53D1\u73B0\u672C\u5730 skills\uFF0C\u5E76\u63D0\u4F9B invoke_skill \u5DE5\u5177\u4E0E\u6280\u80FD\u6570\u636E\u6E90\u3002";
|
|
3022
3022
|
skillsDir;
|
|
3023
3023
|
skills = [];
|
|
3024
|
+
featureSkills = [];
|
|
3024
3025
|
/**
|
|
3025
3026
|
* 缓存包信息
|
|
3026
3027
|
*/
|
|
@@ -3072,6 +3073,14 @@ var SkillFeature = class {
|
|
|
3072
3073
|
if (this.skillsDir) {
|
|
3073
3074
|
this.skills = await discover({ dir: this.skillsDir });
|
|
3074
3075
|
}
|
|
3076
|
+
if (this.featureSkills.length > 0) {
|
|
3077
|
+
const userSkillNames = new Set(this.skills.map((s) => s.name));
|
|
3078
|
+
for (const s of this.featureSkills) {
|
|
3079
|
+
if (!userSkillNames.has(s.name)) {
|
|
3080
|
+
this.skills.push(s);
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3075
3084
|
DataSourceRegistry.register({
|
|
3076
3085
|
name: "skills",
|
|
3077
3086
|
getData: () => this.skills,
|
|
@@ -3086,6 +3095,13 @@ var SkillFeature = class {
|
|
|
3086
3095
|
}
|
|
3087
3096
|
});
|
|
3088
3097
|
}
|
|
3098
|
+
/**
|
|
3099
|
+
* 注入来自其他 Feature 的 skills
|
|
3100
|
+
* 由 Agent 在 onInitiate 之前调用
|
|
3101
|
+
*/
|
|
3102
|
+
addFeatureSkills(skills) {
|
|
3103
|
+
this.featureSkills = skills;
|
|
3104
|
+
}
|
|
3089
3105
|
/**
|
|
3090
3106
|
* 获取已加载的 Skills
|
|
3091
3107
|
*/
|
|
@@ -3616,7 +3632,8 @@ var PluginCompatFeature = class {
|
|
|
3616
3632
|
if (!this.enabled) {
|
|
3617
3633
|
return;
|
|
3618
3634
|
}
|
|
3619
|
-
|
|
3635
|
+
const resourceRoot = config?.resourceRoot ?? ctx.config?.projectRoot ?? ctx.config?.workspaceDir ?? process.cwd();
|
|
3636
|
+
this.pluginRoots = config?.pluginRoots ?? [resolve9(resourceRoot, ".agentdev/plugins")];
|
|
3620
3637
|
await this.loadPlugins();
|
|
3621
3638
|
this.diagnostics.printReport();
|
|
3622
3639
|
}
|
|
@@ -3903,7 +3920,8 @@ var QQBotFeature = class {
|
|
|
3903
3920
|
clientSecret: this.config.clientSecret
|
|
3904
3921
|
};
|
|
3905
3922
|
}
|
|
3906
|
-
const
|
|
3923
|
+
const configRoot = this.config.resourceRoot ?? this.config.workspaceDir ?? process.cwd();
|
|
3924
|
+
const defaultConfigPath = join9(configRoot, ".agentdev", "qqbot.config.json");
|
|
3907
3925
|
const configPath = this.config.configPath || defaultConfigPath;
|
|
3908
3926
|
const fileConfig = loadConfigFromFile(configPath);
|
|
3909
3927
|
if (!fileConfig || !fileConfig.appId || !fileConfig.clientSecret) {
|
|
@@ -3970,12 +3988,13 @@ var execAsync = promisify(exec);
|
|
|
3970
3988
|
var GIT_BASH = "C:/Program Files/Git/bin/bash.exe";
|
|
3971
3989
|
async function runShellCommand(command, options = {}) {
|
|
3972
3990
|
const workspaceDir = options.workspaceDir || process.cwd();
|
|
3991
|
+
const workdir = options.workdir || workspaceDir;
|
|
3973
3992
|
const resourceRoot = options.resourceRoot || process.cwd();
|
|
3974
3993
|
const bashrcPath = resolve10(resourceRoot, ".agentdev/bashrc");
|
|
3975
3994
|
console.log(`[shell] ${command}`);
|
|
3976
3995
|
try {
|
|
3977
3996
|
const bashCommand = `"${GIT_BASH}" --rcfile "${bashrcPath}" -i -c "${command.replace(/"/g, '\\"')}"`;
|
|
3978
|
-
const { stdout, stderr } = await execAsync(bashCommand, { cwd:
|
|
3997
|
+
const { stdout, stderr } = await execAsync(bashCommand, { cwd: workdir });
|
|
3979
3998
|
const cleanStderr = stderr?.split("\n").filter((line) => !line.includes("process group") && !line.includes("job control")).join("\n") || "";
|
|
3980
3999
|
return {
|
|
3981
4000
|
stdout: stdout || "",
|
|
@@ -5140,14 +5159,17 @@ var ShellFeature = class {
|
|
|
5140
5159
|
bashDescription;
|
|
5141
5160
|
_packageInfo = null;
|
|
5142
5161
|
workspaceDir;
|
|
5162
|
+
workdir;
|
|
5143
5163
|
resourceRoot;
|
|
5144
5164
|
constructor(config = {}) {
|
|
5145
5165
|
this.workspaceDir = config.workspaceDir || process.cwd();
|
|
5166
|
+
this.workdir = config.workdir || this.workspaceDir;
|
|
5146
5167
|
this.resourceRoot = config.resourceRoot || process.cwd();
|
|
5147
5168
|
}
|
|
5148
5169
|
async run(command) {
|
|
5149
5170
|
return runShellCommand(command, {
|
|
5150
5171
|
workspaceDir: this.workspaceDir,
|
|
5172
|
+
workdir: this.workdir,
|
|
5151
5173
|
resourceRoot: this.resourceRoot
|
|
5152
5174
|
});
|
|
5153
5175
|
}
|
|
@@ -5176,9 +5198,9 @@ var ShellFeature = class {
|
|
|
5176
5198
|
*/
|
|
5177
5199
|
getTools() {
|
|
5178
5200
|
return [
|
|
5179
|
-
createSafeTrashDeleteTool(this.
|
|
5180
|
-
createSafeTrashListTool(this.
|
|
5181
|
-
createSafeTrashRestoreTool(this.
|
|
5201
|
+
createSafeTrashDeleteTool(this.workdir),
|
|
5202
|
+
createSafeTrashListTool(this.workdir),
|
|
5203
|
+
createSafeTrashRestoreTool(this.workdir)
|
|
5182
5204
|
];
|
|
5183
5205
|
}
|
|
5184
5206
|
/**
|
|
@@ -5195,6 +5217,7 @@ var ShellFeature = class {
|
|
|
5195
5217
|
}
|
|
5196
5218
|
return [createShellCommandTool(this.bashDescription, {
|
|
5197
5219
|
workspaceDir: this.workspaceDir,
|
|
5220
|
+
workdir: this.workdir,
|
|
5198
5221
|
resourceRoot: this.resourceRoot
|
|
5199
5222
|
})];
|
|
5200
5223
|
}
|
|
@@ -6393,8 +6416,8 @@ var __dirname6 = dirname15(fileURLToPath13(import.meta.url));
|
|
|
6393
6416
|
var DEFAULT_VOICE = "zf_xiaobei";
|
|
6394
6417
|
var DEFAULT_LANG = "zh";
|
|
6395
6418
|
var DEFAULT_SPEED = 1.2;
|
|
6396
|
-
function getDefaultPythonPath() {
|
|
6397
|
-
const projectRoot2 = process.cwd();
|
|
6419
|
+
function getDefaultPythonPath(workspaceDir) {
|
|
6420
|
+
const projectRoot2 = workspaceDir ?? process.cwd();
|
|
6398
6421
|
const venvPython = process.platform === "win32" ? join17(projectRoot2, ".venv", "Scripts", "python.exe") : join17(projectRoot2, ".venv", "bin", "python");
|
|
6399
6422
|
if (existsSync9(venvPython)) {
|
|
6400
6423
|
console.log(`[TTSFeature] Using project Python: ${venvPython}`);
|
|
@@ -6418,14 +6441,14 @@ var TTSFeature = class {
|
|
|
6418
6441
|
lastUtteranceId: null,
|
|
6419
6442
|
totalUtterances: 0
|
|
6420
6443
|
};
|
|
6421
|
-
const projectRoot2 = process.cwd();
|
|
6444
|
+
const projectRoot2 = config.workspaceDir ?? process.cwd();
|
|
6422
6445
|
const defaultOutputDir = join17(projectRoot2, ".agentdev", "tts");
|
|
6423
6446
|
const outputDir = config.output?.outputDir || defaultOutputDir;
|
|
6424
6447
|
if (!existsSync9(outputDir)) {
|
|
6425
6448
|
mkdirSync2(outputDir, { recursive: true });
|
|
6426
6449
|
}
|
|
6427
6450
|
this.config = {
|
|
6428
|
-
pythonPath: config.pythonPath ?? getDefaultPythonPath(),
|
|
6451
|
+
pythonPath: config.pythonPath ?? getDefaultPythonPath(config.workspaceDir),
|
|
6429
6452
|
pythonArgs: config.pythonArgs,
|
|
6430
6453
|
checkPythonEnv: config.checkPythonEnv ?? true,
|
|
6431
6454
|
outputDir,
|
|
@@ -7964,8 +7987,8 @@ var DEFAULT_BASE_URL2 = "http://localhost:7575";
|
|
|
7964
7987
|
var DEFAULT_MODEL2 = "Qwen3.5-4B-Q5_K_M";
|
|
7965
7988
|
var DEFAULT_ADVANCED_BASE_URL = "http://localhost:7577";
|
|
7966
7989
|
var DEFAULT_ADVANCED_MODEL = "Qwen3.5-9B-Q4_K_M";
|
|
7967
|
-
function getDefaultPythonPath2() {
|
|
7968
|
-
const projectRoot2 = process.cwd();
|
|
7990
|
+
function getDefaultPythonPath2(workspaceDir) {
|
|
7991
|
+
const projectRoot2 = workspaceDir ?? process.cwd();
|
|
7969
7992
|
const venvPython = process.platform === "win32" ? join20(projectRoot2, ".venv", "Scripts", "python.exe") : join20(projectRoot2, ".venv", "bin", "python");
|
|
7970
7993
|
if (existsSync11(venvPython)) {
|
|
7971
7994
|
console.log(`[VisualFeature] Using project Python: ${venvPython}`);
|
|
@@ -8005,7 +8028,7 @@ var VisualFeature = class {
|
|
|
8005
8028
|
model: config.model ?? DEFAULT_MODEL2,
|
|
8006
8029
|
advancedBaseUrl: config.advancedVision?.baseUrl ?? DEFAULT_ADVANCED_BASE_URL,
|
|
8007
8030
|
advancedModel: config.advancedVision?.model ?? DEFAULT_ADVANCED_MODEL,
|
|
8008
|
-
pythonPath: config.pythonPath ?? getDefaultPythonPath2(),
|
|
8031
|
+
pythonPath: config.pythonPath ?? getDefaultPythonPath2(config.workspaceDir),
|
|
8009
8032
|
pythonArgs: config.pythonArgs,
|
|
8010
8033
|
enableWindowInfo: config.enableWindowInfo ?? true,
|
|
8011
8034
|
checkPythonEnv: config.checkPythonEnv ?? true
|
|
@@ -10919,6 +10942,11 @@ var UsageStats = class {
|
|
|
10919
10942
|
}
|
|
10920
10943
|
};
|
|
10921
10944
|
|
|
10945
|
+
// src/core/agent.ts
|
|
10946
|
+
import { existsSync as existsSync13 } from "fs";
|
|
10947
|
+
import { dirname as dirname21, join as join24 } from "path";
|
|
10948
|
+
import { fileURLToPath as fileURLToPath20 } from "url";
|
|
10949
|
+
|
|
10922
10950
|
// src/core/agent/hooks-executor.ts
|
|
10923
10951
|
var hookLogger = createLogger("agent.forward-hook");
|
|
10924
10952
|
async function executeHook(agent, hookFn, options) {
|
|
@@ -12047,14 +12075,14 @@ var AgentBase = class {
|
|
|
12047
12075
|
if (factory) return factory();
|
|
12048
12076
|
switch (type) {
|
|
12049
12077
|
case "ExplorerAgent": {
|
|
12050
|
-
const { ExplorerAgent } = await import("./ExplorerAgent-
|
|
12078
|
+
const { ExplorerAgent } = await import("./ExplorerAgent-DXY3OQ5U.js");
|
|
12051
12079
|
return new ExplorerAgent({
|
|
12052
12080
|
llm: this.llm
|
|
12053
12081
|
});
|
|
12054
12082
|
}
|
|
12055
12083
|
case "BasicAgent":
|
|
12056
12084
|
default: {
|
|
12057
|
-
const { BasicAgent } = await import("./BasicAgent-
|
|
12085
|
+
const { BasicAgent } = await import("./BasicAgent-R7DYGTHF.js");
|
|
12058
12086
|
return new BasicAgent({
|
|
12059
12087
|
llm: this.llm,
|
|
12060
12088
|
tools: this.tools.getAll().slice(0, 3)
|
|
@@ -12191,6 +12219,13 @@ var AgentBase = class {
|
|
|
12191
12219
|
*/
|
|
12192
12220
|
async ensureFeatureTools() {
|
|
12193
12221
|
if (this.featureToolsReady) return;
|
|
12222
|
+
const featureSkills = await this.collectFeatureSkills();
|
|
12223
|
+
if (featureSkills.length > 0) {
|
|
12224
|
+
const skillFeature = this.features.get("skill");
|
|
12225
|
+
if (skillFeature?.addFeatureSkills) {
|
|
12226
|
+
skillFeature.addFeatureSkills(featureSkills);
|
|
12227
|
+
}
|
|
12228
|
+
}
|
|
12194
12229
|
for (const [name, feature] of this.features) {
|
|
12195
12230
|
const featureLogger = createLogger(`feature.${name}`, {
|
|
12196
12231
|
agentId: this.agentId,
|
|
@@ -12245,6 +12280,29 @@ var AgentBase = class {
|
|
|
12245
12280
|
this.featureToolsReady = true;
|
|
12246
12281
|
this.pushInspectorSnapshot();
|
|
12247
12282
|
}
|
|
12283
|
+
/**
|
|
12284
|
+
* 收集所有 Feature 自带的 skills
|
|
12285
|
+
* 约定:Feature 目录下存在 skills/ 目录则自动发现
|
|
12286
|
+
*/
|
|
12287
|
+
async collectFeatureSkills() {
|
|
12288
|
+
const collected = [];
|
|
12289
|
+
for (const [name, feature] of this.features) {
|
|
12290
|
+
if (name === "skill") continue;
|
|
12291
|
+
if (!feature.source) continue;
|
|
12292
|
+
const filePath = feature.source.startsWith("file://") ? fileURLToPath20(feature.source) : feature.source;
|
|
12293
|
+
const featureDir = dirname21(filePath);
|
|
12294
|
+
const candidate1 = join24(featureDir, "skills");
|
|
12295
|
+
const pkgInfo = feature.getPackageInfo?.();
|
|
12296
|
+
const candidate2 = pkgInfo ? join24(pkgInfo.root, "skills") : null;
|
|
12297
|
+
const skillsDir = existsSync13(candidate1) ? candidate1 : candidate2 && existsSync13(candidate2) ? candidate2 : null;
|
|
12298
|
+
if (!skillsDir) continue;
|
|
12299
|
+
const found = await discover({ dir: skillsDir });
|
|
12300
|
+
if (found.length > 0) {
|
|
12301
|
+
collected.push(...found);
|
|
12302
|
+
}
|
|
12303
|
+
}
|
|
12304
|
+
return collected;
|
|
12305
|
+
}
|
|
12248
12306
|
// ========== 内部方法 ==========
|
|
12249
12307
|
/**
|
|
12250
12308
|
* 解析相对路径(处理 ./ 和 ../)
|
|
@@ -12523,6 +12581,7 @@ export {
|
|
|
12523
12581
|
DataSourceRegistry,
|
|
12524
12582
|
createListRenderer,
|
|
12525
12583
|
TemplateComposer,
|
|
12584
|
+
discover,
|
|
12526
12585
|
Decision,
|
|
12527
12586
|
CallStart,
|
|
12528
12587
|
CallFinish,
|
|
@@ -12550,7 +12609,6 @@ export {
|
|
|
12550
12609
|
AuditFeature,
|
|
12551
12610
|
AudioFeedbackFeature,
|
|
12552
12611
|
MemoryFeature,
|
|
12553
|
-
discover,
|
|
12554
12612
|
SkillFeature,
|
|
12555
12613
|
PluginCompatFeature,
|
|
12556
12614
|
QQBotFeature,
|
|
@@ -12575,4 +12633,4 @@ export {
|
|
|
12575
12633
|
createLLM,
|
|
12576
12634
|
AgentBase
|
|
12577
12635
|
};
|
|
12578
|
-
//# sourceMappingURL=chunk-
|
|
12636
|
+
//# sourceMappingURL=chunk-3AR3JBW6.js.map
|