@kenhkl/agent-moss 0.11.0 → 0.11.3
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/cli.js +157 -72
- package/dist/cli.js.map +1 -1
- package/dist/engine/coordinator.js +125 -40
- package/dist/engine/coordinator.js.map +1 -1
- package/dist/server.js +145 -60
- package/dist/server.js.map +1 -1
- package/dist/static/index.html +21 -5
- package/package.json +1 -1
|
@@ -32,6 +32,90 @@ var init_esm_shims = __esm({
|
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
+
// src/infra/paths.ts
|
|
36
|
+
import { join } from "path";
|
|
37
|
+
import { homedir } from "os";
|
|
38
|
+
import { readFileSync } from "fs";
|
|
39
|
+
function isRoot() {
|
|
40
|
+
const getuid = process.getuid;
|
|
41
|
+
return typeof getuid === "function" && getuid() === 0;
|
|
42
|
+
}
|
|
43
|
+
function resolveOwnerHome() {
|
|
44
|
+
for (const name of [process.env.SUDO_USER, process.env.LOGNAME, process.env.USER]) {
|
|
45
|
+
if (name && name !== "root" && name !== "") {
|
|
46
|
+
const home = homeOf(name);
|
|
47
|
+
if (home) return home;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const passwd = readFileSync("/etc/passwd", "utf-8");
|
|
52
|
+
for (const line of passwd.split("\n")) {
|
|
53
|
+
if (!line || line.startsWith("#")) continue;
|
|
54
|
+
const parts = line.split(":");
|
|
55
|
+
if (parts.length < 6) continue;
|
|
56
|
+
const uid = parseInt(parts[2], 10);
|
|
57
|
+
const name = parts[0];
|
|
58
|
+
if (uid >= 1e3 && name && !name.startsWith("_")) {
|
|
59
|
+
return parts[5];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function homeOf(name) {
|
|
67
|
+
try {
|
|
68
|
+
const passwd = readFileSync("/etc/passwd", "utf-8");
|
|
69
|
+
for (const line of passwd.split("\n")) {
|
|
70
|
+
if (!line || line.startsWith("#")) continue;
|
|
71
|
+
const parts = line.split(":");
|
|
72
|
+
if (parts.length >= 6 && parts[0] === name) {
|
|
73
|
+
return parts[5];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
function getDataRoot() {
|
|
81
|
+
const envPath = process.env[ENV_DATA_ROOT];
|
|
82
|
+
if (envPath) return envPath;
|
|
83
|
+
if (isRoot()) {
|
|
84
|
+
const ownerHome = resolveOwnerHome();
|
|
85
|
+
if (ownerHome) {
|
|
86
|
+
return join(ownerHome, ".config", "agentmoss");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return DEFAULT_DATA_ROOT;
|
|
90
|
+
}
|
|
91
|
+
function getInstance() {
|
|
92
|
+
const v = process.env[ENV_INSTANCE] || "";
|
|
93
|
+
return v.trim().replace(/^[/\\]+|[/\\]+$/g, "");
|
|
94
|
+
}
|
|
95
|
+
function getConfigDir() {
|
|
96
|
+
return getDataRoot();
|
|
97
|
+
}
|
|
98
|
+
function getRuntimeConfigDir() {
|
|
99
|
+
return getDataRoot();
|
|
100
|
+
}
|
|
101
|
+
function getTokenStatsPath() {
|
|
102
|
+
const instance = getInstance();
|
|
103
|
+
if (instance) {
|
|
104
|
+
return join(getDataRoot(), instance, "agent_moss_token_stats.json");
|
|
105
|
+
}
|
|
106
|
+
return join(getDataRoot(), "agent_moss_token_stats.json");
|
|
107
|
+
}
|
|
108
|
+
var ENV_DATA_ROOT, ENV_INSTANCE, DEFAULT_DATA_ROOT;
|
|
109
|
+
var init_paths = __esm({
|
|
110
|
+
"src/infra/paths.ts"() {
|
|
111
|
+
"use strict";
|
|
112
|
+
init_esm_shims();
|
|
113
|
+
ENV_DATA_ROOT = "AGENT_MOSS_DATA_DIR";
|
|
114
|
+
ENV_INSTANCE = "AGENT_MOSS_INSTANCE";
|
|
115
|
+
DEFAULT_DATA_ROOT = join(homedir(), ".config", "agentmoss");
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
35
119
|
// src/config.ts
|
|
36
120
|
var config_exports = {};
|
|
37
121
|
__export(config_exports, {
|
|
@@ -50,7 +134,6 @@ __export(config_exports, {
|
|
|
50
134
|
});
|
|
51
135
|
import fs from "fs";
|
|
52
136
|
import path2 from "path";
|
|
53
|
-
import os from "os";
|
|
54
137
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
55
138
|
function loadConfigFile(filePath) {
|
|
56
139
|
try {
|
|
@@ -63,7 +146,7 @@ function loadConfigFile(filePath) {
|
|
|
63
146
|
function resolveConfigPath() {
|
|
64
147
|
const envPath = process.env.AGENT_MOSS_CONFIG_PATH;
|
|
65
148
|
if (envPath) return envPath;
|
|
66
|
-
const userConfig = path2.join(
|
|
149
|
+
const userConfig = path2.join(getConfigDir(), "config.json");
|
|
67
150
|
if (fs.existsSync(userConfig)) return userConfig;
|
|
68
151
|
const defaultConfig = path2.join(__dirname, "..", "..", "agent_moss", "infra", "config.json.example");
|
|
69
152
|
if (fs.existsSync(defaultConfig)) {
|
|
@@ -232,6 +315,7 @@ var init_config = __esm({
|
|
|
232
315
|
"src/config.ts"() {
|
|
233
316
|
"use strict";
|
|
234
317
|
init_esm_shims();
|
|
318
|
+
init_paths();
|
|
235
319
|
llmConfig = (() => {
|
|
236
320
|
const configPath = resolveConfigPath();
|
|
237
321
|
const fileConfig = fs.existsSync(configPath) ? loadLLMConfigFromFile(configPath) : {};
|
|
@@ -1062,7 +1146,7 @@ var init_logic_rules = __esm({
|
|
|
1062
1146
|
});
|
|
1063
1147
|
|
|
1064
1148
|
// src/engine/skill-loader.ts
|
|
1065
|
-
import { readFileSync, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
|
|
1149
|
+
import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
|
|
1066
1150
|
import { resolve, dirname } from "path";
|
|
1067
1151
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1068
1152
|
function loadAllSkills() {
|
|
@@ -1076,7 +1160,7 @@ function loadAllSkills() {
|
|
|
1076
1160
|
const files = readdirSync2(dir).filter((f) => f.endsWith(".md"));
|
|
1077
1161
|
for (const f of files) {
|
|
1078
1162
|
const name = f.replace(".md", "");
|
|
1079
|
-
cachedSkills[name] =
|
|
1163
|
+
cachedSkills[name] = readFileSync2(resolve(dir, f), "utf-8");
|
|
1080
1164
|
}
|
|
1081
1165
|
console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);
|
|
1082
1166
|
return cachedSkills;
|
|
@@ -1207,11 +1291,13 @@ __export(runtime_config_exports, {
|
|
|
1207
1291
|
updateSkillCategoryEnabled: () => updateSkillCategoryEnabled,
|
|
1208
1292
|
updateSkillEnabled: () => updateSkillEnabled
|
|
1209
1293
|
});
|
|
1210
|
-
import { readFileSync as
|
|
1211
|
-
import { join } from "path";
|
|
1212
|
-
import { homedir } from "os";
|
|
1294
|
+
import { readFileSync as readFileSync3, writeFileSync, existsSync as existsSync3, mkdirSync, unlinkSync, readdirSync as readdirSync3 } from "fs";
|
|
1295
|
+
import { join as join2 } from "path";
|
|
1213
1296
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
1214
1297
|
import { dirname as dirname2 } from "path";
|
|
1298
|
+
function runtimeDir() {
|
|
1299
|
+
return getRuntimeConfigDir();
|
|
1300
|
+
}
|
|
1215
1301
|
function getRuntimeConfigPath() {
|
|
1216
1302
|
const envPath = process.env[ENV_RUNTIME_CONFIG_PATH];
|
|
1217
1303
|
if (envPath) return envPath;
|
|
@@ -1244,7 +1330,7 @@ function loadRuntimeConfig() {
|
|
|
1244
1330
|
return seeded;
|
|
1245
1331
|
}
|
|
1246
1332
|
try {
|
|
1247
|
-
const data = JSON.parse(
|
|
1333
|
+
const data = JSON.parse(readFileSync3(p, "utf-8"));
|
|
1248
1334
|
const merged = mergeConfig(data, generateSourceDefaults());
|
|
1249
1335
|
return {
|
|
1250
1336
|
version: data.version || 1,
|
|
@@ -1314,7 +1400,7 @@ function hasRuntimeConfig() {
|
|
|
1314
1400
|
const p = getRuntimeConfigPath();
|
|
1315
1401
|
if (!existsSync3(p)) return false;
|
|
1316
1402
|
try {
|
|
1317
|
-
JSON.parse(
|
|
1403
|
+
JSON.parse(readFileSync3(p, "utf-8"));
|
|
1318
1404
|
return true;
|
|
1319
1405
|
} catch {
|
|
1320
1406
|
return false;
|
|
@@ -1502,11 +1588,11 @@ function _agentRulesToDefaults() {
|
|
|
1502
1588
|
return out;
|
|
1503
1589
|
}
|
|
1504
1590
|
for (const agentId of entries) {
|
|
1505
|
-
const rulesFile =
|
|
1591
|
+
const rulesFile = join2(agentsDir, agentId, "rules.json");
|
|
1506
1592
|
if (!existsSync3(rulesFile)) continue;
|
|
1507
1593
|
let data;
|
|
1508
1594
|
try {
|
|
1509
|
-
data = JSON.parse(
|
|
1595
|
+
data = JSON.parse(readFileSync3(rulesFile, "utf-8"));
|
|
1510
1596
|
} catch {
|
|
1511
1597
|
continue;
|
|
1512
1598
|
}
|
|
@@ -1922,12 +2008,12 @@ function deleteCustomRule(layer, category, ruleId) {
|
|
|
1922
2008
|
function addCustomSkill(skillId, category, keywords, content) {
|
|
1923
2009
|
_validateSkillId(skillId);
|
|
1924
2010
|
const runtime = loadRuntimeConfig();
|
|
1925
|
-
const skillsDir =
|
|
2011
|
+
const skillsDir = join2(RUNTIME_CONFIG_DIR, "agent_moss_skills");
|
|
1926
2012
|
try {
|
|
1927
2013
|
mkdirSync(skillsDir, { recursive: true });
|
|
1928
2014
|
} catch {
|
|
1929
2015
|
}
|
|
1930
|
-
writeFileSync(
|
|
2016
|
+
writeFileSync(join2(skillsDir, `${skillId}.md`), content, "utf-8");
|
|
1931
2017
|
const l3 = runtime.L3_skills || (runtime.L3_skills = {});
|
|
1932
2018
|
const cat = l3[category] || (l3[category] = { category_enabled: true, category_desc: "", skills: [] });
|
|
1933
2019
|
(cat.skills || (cat.skills = [])).push({ id: skillId, keywords, enabled: true, builtin: false });
|
|
@@ -1942,7 +2028,7 @@ function deleteCustomSkill(skillId, category) {
|
|
|
1942
2028
|
if (idx >= 0) {
|
|
1943
2029
|
if (skills[idx].builtin) return null;
|
|
1944
2030
|
skills.splice(idx, 1);
|
|
1945
|
-
const skillPath =
|
|
2031
|
+
const skillPath = join2(RUNTIME_CONFIG_DIR, "agent_moss_skills", `${skillId}.md`);
|
|
1946
2032
|
try {
|
|
1947
2033
|
if (existsSync3(skillPath)) unlinkSync(skillPath);
|
|
1948
2034
|
} catch {
|
|
@@ -2058,18 +2144,19 @@ function updateAgentCategoryEnabled(agentId, category, enabled) {
|
|
|
2058
2144
|
saveRuntimeConfig(runtime);
|
|
2059
2145
|
return runtime;
|
|
2060
2146
|
}
|
|
2061
|
-
var __dirname3, RUNTIME_CONFIG_DIR, RUNTIME_CONFIG_PATH,
|
|
2147
|
+
var __dirname3, ENV_RUNTIME_CONFIG_PATH, RUNTIME_CONFIG_DIR, RUNTIME_CONFIG_PATH, LAYER_DISABLE_ENV, DENY_MODE_LABELS, _AGENTS_DIR_PROD, _AGENTS_DIR_DEV, SKILL_ID_RE;
|
|
2062
2148
|
var init_runtime_config = __esm({
|
|
2063
2149
|
"src/infra/runtime-config.ts"() {
|
|
2064
2150
|
"use strict";
|
|
2065
2151
|
init_esm_shims();
|
|
2152
|
+
init_paths();
|
|
2066
2153
|
init_heuristic();
|
|
2067
2154
|
init_logic_rules();
|
|
2068
2155
|
init_skill_loader();
|
|
2069
2156
|
__dirname3 = dirname2(fileURLToPath4(import.meta.url));
|
|
2070
|
-
RUNTIME_CONFIG_DIR = join(homedir(), ".config", "agentmoss");
|
|
2071
|
-
RUNTIME_CONFIG_PATH = join(RUNTIME_CONFIG_DIR, "agent_moss_runtime.json");
|
|
2072
2157
|
ENV_RUNTIME_CONFIG_PATH = "AGENT_MOSS_RUNTIME_CONFIG_PATH";
|
|
2158
|
+
RUNTIME_CONFIG_DIR = runtimeDir();
|
|
2159
|
+
RUNTIME_CONFIG_PATH = join2(RUNTIME_CONFIG_DIR, "agent_moss_runtime.json");
|
|
2073
2160
|
LAYER_DISABLE_ENV = {
|
|
2074
2161
|
L1_heuristic: "AGENT_MOSS_DISABLE_HEURISTIC",
|
|
2075
2162
|
L2_logic_rules: "AGENT_MOSS_DISABLE_LOGIC_RULES",
|
|
@@ -2080,14 +2167,14 @@ var init_runtime_config = __esm({
|
|
|
2080
2167
|
deny_read: "\u4EC5\u62E6\u622A\u8BFB\u53D6",
|
|
2081
2168
|
deny_both: "\u8BFB\u5199\u5747\u62E6\u622A"
|
|
2082
2169
|
};
|
|
2083
|
-
_AGENTS_DIR_PROD =
|
|
2084
|
-
_AGENTS_DIR_DEV =
|
|
2170
|
+
_AGENTS_DIR_PROD = join2(__dirname3, "agents");
|
|
2171
|
+
_AGENTS_DIR_DEV = join2(__dirname3, "..", "..", "..", "agent_moss", "agents");
|
|
2085
2172
|
SKILL_ID_RE = /^[A-Za-z0-9_-]+$/;
|
|
2086
2173
|
}
|
|
2087
2174
|
});
|
|
2088
2175
|
|
|
2089
2176
|
// src/agents/index.ts
|
|
2090
|
-
import { readFileSync as
|
|
2177
|
+
import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
|
|
2091
2178
|
import { resolve as resolve2, dirname as dirname3 } from "path";
|
|
2092
2179
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
2093
2180
|
function resolveAgentsDir() {
|
|
@@ -2114,7 +2201,7 @@ function getAgentExtensions(agentId) {
|
|
|
2114
2201
|
return null;
|
|
2115
2202
|
}
|
|
2116
2203
|
try {
|
|
2117
|
-
const raw =
|
|
2204
|
+
const raw = readFileSync4(rulesFile, "utf-8");
|
|
2118
2205
|
ext = JSON.parse(raw);
|
|
2119
2206
|
if (!ext.agent_id) {
|
|
2120
2207
|
console.warn(`[AgentMoss agents] rules.json \u7F3A\u5C11 agent_id \u5B57\u6BB5: ${rulesFile}`);
|
|
@@ -2762,17 +2849,16 @@ __export(token_stats_exports, {
|
|
|
2762
2849
|
recordTokenUsage: () => recordTokenUsage,
|
|
2763
2850
|
resetTokenStats: () => resetTokenStats
|
|
2764
2851
|
});
|
|
2765
|
-
import { readFileSync as
|
|
2766
|
-
import { join as join4 } from "path";
|
|
2767
|
-
import { homedir as homedir3 } from "os";
|
|
2852
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "fs";
|
|
2768
2853
|
function getStatsPath() {
|
|
2769
2854
|
const envPath = process.env[ENV_STATS_PATH];
|
|
2770
|
-
|
|
2855
|
+
if (envPath) return envPath;
|
|
2856
|
+
return getTokenStatsPath();
|
|
2771
2857
|
}
|
|
2772
2858
|
function loadAllRecords(statsPath) {
|
|
2773
2859
|
if (!existsSync7(statsPath)) return [];
|
|
2774
2860
|
try {
|
|
2775
|
-
const data = JSON.parse(
|
|
2861
|
+
const data = JSON.parse(readFileSync8(statsPath, "utf-8"));
|
|
2776
2862
|
if (Array.isArray(data)) return data;
|
|
2777
2863
|
if (data && Array.isArray(data.records)) return data.records;
|
|
2778
2864
|
return [];
|
|
@@ -2912,13 +2998,12 @@ function resetTokenStats() {
|
|
|
2912
2998
|
}
|
|
2913
2999
|
}
|
|
2914
3000
|
}
|
|
2915
|
-
var
|
|
3001
|
+
var ENV_STATS_PATH, MAX_RECORDS;
|
|
2916
3002
|
var init_token_stats = __esm({
|
|
2917
3003
|
"src/engine/token-stats.ts"() {
|
|
2918
3004
|
"use strict";
|
|
2919
3005
|
init_esm_shims();
|
|
2920
|
-
|
|
2921
|
-
STATS_FILE = join4(STATS_DIR, "agent_moss_token_stats.json");
|
|
3006
|
+
init_paths();
|
|
2922
3007
|
ENV_STATS_PATH = "AGENT_MOSS_TOKEN_STATS_PATH";
|
|
2923
3008
|
MAX_RECORDS = 1e4;
|
|
2924
3009
|
}
|
|
@@ -2937,7 +3022,7 @@ init_skill_loader();
|
|
|
2937
3022
|
|
|
2938
3023
|
// src/engine/template-loader.ts
|
|
2939
3024
|
init_esm_shims();
|
|
2940
|
-
import { readFileSync as
|
|
3025
|
+
import { readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
|
|
2941
3026
|
import { resolve as resolve3, dirname as dirname4 } from "path";
|
|
2942
3027
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
2943
3028
|
var __filename4 = fileURLToPath6(import.meta.url);
|
|
@@ -2958,7 +3043,7 @@ function loadTemplates() {
|
|
|
2958
3043
|
const filePath = resolve3(dir, file);
|
|
2959
3044
|
if (existsSync5(filePath)) {
|
|
2960
3045
|
const key = file.replace(".txt", "").replace("_template", "");
|
|
2961
|
-
cachedTemplates[key] =
|
|
3046
|
+
cachedTemplates[key] = readFileSync5(filePath, "utf-8");
|
|
2962
3047
|
}
|
|
2963
3048
|
}
|
|
2964
3049
|
console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates from ${dir}`);
|
|
@@ -2967,8 +3052,8 @@ function loadTemplates() {
|
|
|
2967
3052
|
|
|
2968
3053
|
// src/engine/script-analyzer.ts
|
|
2969
3054
|
init_esm_shims();
|
|
2970
|
-
import { readFileSync as
|
|
2971
|
-
import { resolve as resolve4, join as
|
|
3055
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
3056
|
+
import { resolve as resolve4, join as join3 } from "path";
|
|
2972
3057
|
var SUSPICIOUS_PATTERNS = [
|
|
2973
3058
|
// Network exfiltration (curl/wget POST in scripts is almost never legitimate)
|
|
2974
3059
|
{ name: "curl POST", pattern: /curl\s+(.*\s)?-X\s+POST/i },
|
|
@@ -3101,8 +3186,8 @@ function assessKeywordCombinationRisk(matchedKeywords, scriptContent) {
|
|
|
3101
3186
|
}
|
|
3102
3187
|
function readScriptContent(scriptPath, maxLines = 500) {
|
|
3103
3188
|
try {
|
|
3104
|
-
const expandedPath = scriptPath.startsWith("~") ?
|
|
3105
|
-
const raw =
|
|
3189
|
+
const expandedPath = scriptPath.startsWith("~") ? join3(process.env.HOME || "/home/user", scriptPath.slice(2)) : resolve4(scriptPath);
|
|
3190
|
+
const raw = readFileSync6(expandedPath, "utf-8");
|
|
3106
3191
|
const lines = raw.split("\n").slice(0, maxLines);
|
|
3107
3192
|
return { content: lines.join("\n"), lineCount: lines.length, error: "" };
|
|
3108
3193
|
} catch (e) {
|
|
@@ -3156,8 +3241,8 @@ ${result.scriptContent}
|
|
|
3156
3241
|
init_esm_shims();
|
|
3157
3242
|
init_heuristic();
|
|
3158
3243
|
init_logic_rules();
|
|
3159
|
-
import { readFileSync as
|
|
3160
|
-
import { resolve as resolve5, join as
|
|
3244
|
+
import { readFileSync as readFileSync7, statSync, existsSync as existsSync6 } from "fs";
|
|
3245
|
+
import { resolve as resolve5, join as join4, isAbsolute, dirname as dirname5 } from "path";
|
|
3161
3246
|
import { homedir as homedir2 } from "os";
|
|
3162
3247
|
function emptyChain() {
|
|
3163
3248
|
return {
|
|
@@ -3398,7 +3483,7 @@ function extractInlineScriptPath(actionDetail) {
|
|
|
3398
3483
|
function resolvePath(p) {
|
|
3399
3484
|
let expanded = p;
|
|
3400
3485
|
if (expanded.startsWith("~/") || expanded === "~") {
|
|
3401
|
-
expanded =
|
|
3486
|
+
expanded = join4(homedir2(), expanded.slice(1));
|
|
3402
3487
|
}
|
|
3403
3488
|
return resolve5(expanded);
|
|
3404
3489
|
}
|
|
@@ -3411,7 +3496,7 @@ function readScriptContent2(scriptPath, maxFileSize = 2 * 1024 * 1024) {
|
|
|
3411
3496
|
if (stat.size > maxFileSize) {
|
|
3412
3497
|
return { content: "", lineCount: 0, fileSize: stat.size, error: `\u811A\u672C\u6587\u4EF6\u8FC7\u5927 (${stat.size} bytes)\uFF0C\u8DF3\u8FC7\u8BFB\u53D6` };
|
|
3413
3498
|
}
|
|
3414
|
-
const content =
|
|
3499
|
+
const content = readFileSync7(path3, "utf-8");
|
|
3415
3500
|
const lineCount = content ? content.split("\n").length : 0;
|
|
3416
3501
|
return { content, lineCount, fileSize: stat.size, error: "" };
|
|
3417
3502
|
} catch (e) {
|
|
@@ -3428,7 +3513,7 @@ function extractChildScriptPaths(content, baseDir) {
|
|
|
3428
3513
|
const pathStr = m[1];
|
|
3429
3514
|
if (pathStr.startsWith("-") || pathStr.startsWith("$")) continue;
|
|
3430
3515
|
if (pathStr.includes("/dev/") || pathStr.startsWith("|") || pathStr.startsWith(";")) continue;
|
|
3431
|
-
const full = isAbsolute(pathStr) ? pathStr :
|
|
3516
|
+
const full = isAbsolute(pathStr) ? pathStr : join4(baseDir, pathStr);
|
|
3432
3517
|
const resolved = resolvePath(full);
|
|
3433
3518
|
if (existsSync6(resolved)) {
|
|
3434
3519
|
try {
|