@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/server.js CHANGED
@@ -42,6 +42,90 @@ var init_esm_shims = __esm({
42
42
  }
43
43
  });
44
44
 
45
+ // src/infra/paths.ts
46
+ import { join } from "path";
47
+ import { homedir } from "os";
48
+ import { readFileSync } from "fs";
49
+ function isRoot() {
50
+ const getuid = process.getuid;
51
+ return typeof getuid === "function" && getuid() === 0;
52
+ }
53
+ function resolveOwnerHome() {
54
+ for (const name of [process.env.SUDO_USER, process.env.LOGNAME, process.env.USER]) {
55
+ if (name && name !== "root" && name !== "") {
56
+ const home = homeOf(name);
57
+ if (home) return home;
58
+ }
59
+ }
60
+ try {
61
+ const passwd = readFileSync("/etc/passwd", "utf-8");
62
+ for (const line of passwd.split("\n")) {
63
+ if (!line || line.startsWith("#")) continue;
64
+ const parts = line.split(":");
65
+ if (parts.length < 6) continue;
66
+ const uid = parseInt(parts[2], 10);
67
+ const name = parts[0];
68
+ if (uid >= 1e3 && name && !name.startsWith("_")) {
69
+ return parts[5];
70
+ }
71
+ }
72
+ } catch {
73
+ }
74
+ return null;
75
+ }
76
+ function homeOf(name) {
77
+ try {
78
+ const passwd = readFileSync("/etc/passwd", "utf-8");
79
+ for (const line of passwd.split("\n")) {
80
+ if (!line || line.startsWith("#")) continue;
81
+ const parts = line.split(":");
82
+ if (parts.length >= 6 && parts[0] === name) {
83
+ return parts[5];
84
+ }
85
+ }
86
+ } catch {
87
+ }
88
+ return null;
89
+ }
90
+ function getDataRoot() {
91
+ const envPath = process.env[ENV_DATA_ROOT];
92
+ if (envPath) return envPath;
93
+ if (isRoot()) {
94
+ const ownerHome = resolveOwnerHome();
95
+ if (ownerHome) {
96
+ return join(ownerHome, ".config", "agentmoss");
97
+ }
98
+ }
99
+ return DEFAULT_DATA_ROOT;
100
+ }
101
+ function getInstance() {
102
+ const v = process.env[ENV_INSTANCE] || "";
103
+ return v.trim().replace(/^[/\\]+|[/\\]+$/g, "");
104
+ }
105
+ function getConfigDir() {
106
+ return getDataRoot();
107
+ }
108
+ function getRuntimeConfigDir() {
109
+ return getDataRoot();
110
+ }
111
+ function getTokenStatsPath() {
112
+ const instance = getInstance();
113
+ if (instance) {
114
+ return join(getDataRoot(), instance, "agent_moss_token_stats.json");
115
+ }
116
+ return join(getDataRoot(), "agent_moss_token_stats.json");
117
+ }
118
+ var ENV_DATA_ROOT, ENV_INSTANCE, DEFAULT_DATA_ROOT;
119
+ var init_paths = __esm({
120
+ "src/infra/paths.ts"() {
121
+ "use strict";
122
+ init_esm_shims();
123
+ ENV_DATA_ROOT = "AGENT_MOSS_DATA_DIR";
124
+ ENV_INSTANCE = "AGENT_MOSS_INSTANCE";
125
+ DEFAULT_DATA_ROOT = join(homedir(), ".config", "agentmoss");
126
+ }
127
+ });
128
+
45
129
  // src/config.ts
46
130
  var config_exports = {};
47
131
  __export(config_exports, {
@@ -60,7 +144,6 @@ __export(config_exports, {
60
144
  });
61
145
  import fs from "fs";
62
146
  import path2 from "path";
63
- import os from "os";
64
147
  import { fileURLToPath as fileURLToPath2 } from "url";
65
148
  function loadConfigFile(filePath) {
66
149
  try {
@@ -73,7 +156,7 @@ function loadConfigFile(filePath) {
73
156
  function resolveConfigPath() {
74
157
  const envPath = process.env.AGENT_MOSS_CONFIG_PATH;
75
158
  if (envPath) return envPath;
76
- const userConfig = path2.join(os.homedir(), ".config", "agentmoss", "config.json");
159
+ const userConfig = path2.join(getConfigDir(), "config.json");
77
160
  if (fs.existsSync(userConfig)) return userConfig;
78
161
  const defaultConfig = path2.join(__dirname, "..", "..", "agent_moss", "infra", "config.json.example");
79
162
  if (fs.existsSync(defaultConfig)) {
@@ -242,6 +325,7 @@ var init_config = __esm({
242
325
  "src/config.ts"() {
243
326
  "use strict";
244
327
  init_esm_shims();
328
+ init_paths();
245
329
  llmConfig = (() => {
246
330
  const configPath = resolveConfigPath();
247
331
  const fileConfig = fs.existsSync(configPath) ? loadLLMConfigFromFile(configPath) : {};
@@ -1072,7 +1156,7 @@ var init_logic_rules = __esm({
1072
1156
  });
1073
1157
 
1074
1158
  // src/engine/skill-loader.ts
1075
- import { readFileSync, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
1159
+ import { readFileSync as readFileSync2, readdirSync as readdirSync2, existsSync as existsSync2 } from "fs";
1076
1160
  import { resolve, dirname } from "path";
1077
1161
  import { fileURLToPath as fileURLToPath3 } from "url";
1078
1162
  function loadAllSkills() {
@@ -1086,7 +1170,7 @@ function loadAllSkills() {
1086
1170
  const files = readdirSync2(dir).filter((f) => f.endsWith(".md"));
1087
1171
  for (const f of files) {
1088
1172
  const name = f.replace(".md", "");
1089
- cachedSkills[name] = readFileSync(resolve(dir, f), "utf-8");
1173
+ cachedSkills[name] = readFileSync2(resolve(dir, f), "utf-8");
1090
1174
  }
1091
1175
  console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);
1092
1176
  return cachedSkills;
@@ -1217,11 +1301,13 @@ __export(runtime_config_exports, {
1217
1301
  updateSkillCategoryEnabled: () => updateSkillCategoryEnabled,
1218
1302
  updateSkillEnabled: () => updateSkillEnabled
1219
1303
  });
1220
- import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync3, mkdirSync, unlinkSync, readdirSync as readdirSync3 } from "fs";
1221
- import { join } from "path";
1222
- import { homedir } from "os";
1304
+ import { readFileSync as readFileSync3, writeFileSync, existsSync as existsSync3, mkdirSync, unlinkSync, readdirSync as readdirSync3 } from "fs";
1305
+ import { join as join2 } from "path";
1223
1306
  import { fileURLToPath as fileURLToPath4 } from "url";
1224
1307
  import { dirname as dirname2 } from "path";
1308
+ function runtimeDir() {
1309
+ return getRuntimeConfigDir();
1310
+ }
1225
1311
  function getRuntimeConfigPath() {
1226
1312
  const envPath = process.env[ENV_RUNTIME_CONFIG_PATH];
1227
1313
  if (envPath) return envPath;
@@ -1254,7 +1340,7 @@ function loadRuntimeConfig() {
1254
1340
  return seeded;
1255
1341
  }
1256
1342
  try {
1257
- const data = JSON.parse(readFileSync2(p, "utf-8"));
1343
+ const data = JSON.parse(readFileSync3(p, "utf-8"));
1258
1344
  const merged = mergeConfig(data, generateSourceDefaults());
1259
1345
  return {
1260
1346
  version: data.version || 1,
@@ -1324,7 +1410,7 @@ function hasRuntimeConfig() {
1324
1410
  const p = getRuntimeConfigPath();
1325
1411
  if (!existsSync3(p)) return false;
1326
1412
  try {
1327
- JSON.parse(readFileSync2(p, "utf-8"));
1413
+ JSON.parse(readFileSync3(p, "utf-8"));
1328
1414
  return true;
1329
1415
  } catch {
1330
1416
  return false;
@@ -1512,11 +1598,11 @@ function _agentRulesToDefaults() {
1512
1598
  return out;
1513
1599
  }
1514
1600
  for (const agentId of entries) {
1515
- const rulesFile = join(agentsDir, agentId, "rules.json");
1601
+ const rulesFile = join2(agentsDir, agentId, "rules.json");
1516
1602
  if (!existsSync3(rulesFile)) continue;
1517
1603
  let data;
1518
1604
  try {
1519
- data = JSON.parse(readFileSync2(rulesFile, "utf-8"));
1605
+ data = JSON.parse(readFileSync3(rulesFile, "utf-8"));
1520
1606
  } catch {
1521
1607
  continue;
1522
1608
  }
@@ -1932,12 +2018,12 @@ function deleteCustomRule(layer, category, ruleId) {
1932
2018
  function addCustomSkill(skillId, category, keywords, content) {
1933
2019
  _validateSkillId(skillId);
1934
2020
  const runtime = loadRuntimeConfig();
1935
- const skillsDir = join(RUNTIME_CONFIG_DIR, "agent_moss_skills");
2021
+ const skillsDir = join2(RUNTIME_CONFIG_DIR, "agent_moss_skills");
1936
2022
  try {
1937
2023
  mkdirSync(skillsDir, { recursive: true });
1938
2024
  } catch {
1939
2025
  }
1940
- writeFileSync(join(skillsDir, `${skillId}.md`), content, "utf-8");
2026
+ writeFileSync(join2(skillsDir, `${skillId}.md`), content, "utf-8");
1941
2027
  const l3 = runtime.L3_skills || (runtime.L3_skills = {});
1942
2028
  const cat = l3[category] || (l3[category] = { category_enabled: true, category_desc: "", skills: [] });
1943
2029
  (cat.skills || (cat.skills = [])).push({ id: skillId, keywords, enabled: true, builtin: false });
@@ -1952,7 +2038,7 @@ function deleteCustomSkill(skillId, category) {
1952
2038
  if (idx >= 0) {
1953
2039
  if (skills[idx].builtin) return null;
1954
2040
  skills.splice(idx, 1);
1955
- const skillPath = join(RUNTIME_CONFIG_DIR, "agent_moss_skills", `${skillId}.md`);
2041
+ const skillPath = join2(RUNTIME_CONFIG_DIR, "agent_moss_skills", `${skillId}.md`);
1956
2042
  try {
1957
2043
  if (existsSync3(skillPath)) unlinkSync(skillPath);
1958
2044
  } catch {
@@ -2068,18 +2154,19 @@ function updateAgentCategoryEnabled(agentId, category, enabled) {
2068
2154
  saveRuntimeConfig(runtime);
2069
2155
  return runtime;
2070
2156
  }
2071
- var __dirname3, RUNTIME_CONFIG_DIR, RUNTIME_CONFIG_PATH, ENV_RUNTIME_CONFIG_PATH, LAYER_DISABLE_ENV, DENY_MODE_LABELS, _AGENTS_DIR_PROD, _AGENTS_DIR_DEV, SKILL_ID_RE;
2157
+ 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;
2072
2158
  var init_runtime_config = __esm({
2073
2159
  "src/infra/runtime-config.ts"() {
2074
2160
  "use strict";
2075
2161
  init_esm_shims();
2162
+ init_paths();
2076
2163
  init_heuristic();
2077
2164
  init_logic_rules();
2078
2165
  init_skill_loader();
2079
2166
  __dirname3 = dirname2(fileURLToPath4(import.meta.url));
2080
- RUNTIME_CONFIG_DIR = join(homedir(), ".config", "agentmoss");
2081
- RUNTIME_CONFIG_PATH = join(RUNTIME_CONFIG_DIR, "agent_moss_runtime.json");
2082
2167
  ENV_RUNTIME_CONFIG_PATH = "AGENT_MOSS_RUNTIME_CONFIG_PATH";
2168
+ RUNTIME_CONFIG_DIR = runtimeDir();
2169
+ RUNTIME_CONFIG_PATH = join2(RUNTIME_CONFIG_DIR, "agent_moss_runtime.json");
2083
2170
  LAYER_DISABLE_ENV = {
2084
2171
  L1_heuristic: "AGENT_MOSS_DISABLE_HEURISTIC",
2085
2172
  L2_logic_rules: "AGENT_MOSS_DISABLE_LOGIC_RULES",
@@ -2090,14 +2177,14 @@ var init_runtime_config = __esm({
2090
2177
  deny_read: "\u4EC5\u62E6\u622A\u8BFB\u53D6",
2091
2178
  deny_both: "\u8BFB\u5199\u5747\u62E6\u622A"
2092
2179
  };
2093
- _AGENTS_DIR_PROD = join(__dirname3, "agents");
2094
- _AGENTS_DIR_DEV = join(__dirname3, "..", "..", "..", "agent_moss", "agents");
2180
+ _AGENTS_DIR_PROD = join2(__dirname3, "agents");
2181
+ _AGENTS_DIR_DEV = join2(__dirname3, "..", "..", "..", "agent_moss", "agents");
2095
2182
  SKILL_ID_RE = /^[A-Za-z0-9_-]+$/;
2096
2183
  }
2097
2184
  });
2098
2185
 
2099
2186
  // src/agents/index.ts
2100
- import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
2187
+ import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
2101
2188
  import { resolve as resolve2, dirname as dirname3 } from "path";
2102
2189
  import { fileURLToPath as fileURLToPath5 } from "url";
2103
2190
  function resolveAgentsDir() {
@@ -2124,7 +2211,7 @@ function getAgentExtensions(agentId) {
2124
2211
  return null;
2125
2212
  }
2126
2213
  try {
2127
- const raw = readFileSync3(rulesFile, "utf-8");
2214
+ const raw = readFileSync4(rulesFile, "utf-8");
2128
2215
  ext = JSON.parse(raw);
2129
2216
  if (!ext.agent_id) {
2130
2217
  console.warn(`[AgentMoss agents] rules.json \u7F3A\u5C11 agent_id \u5B57\u6BB5: ${rulesFile}`);
@@ -2772,17 +2859,16 @@ __export(token_stats_exports, {
2772
2859
  recordTokenUsage: () => recordTokenUsage,
2773
2860
  resetTokenStats: () => resetTokenStats
2774
2861
  });
2775
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "fs";
2776
- import { join as join4 } from "path";
2777
- import { homedir as homedir3 } from "os";
2862
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync2, unlinkSync as unlinkSync2 } from "fs";
2778
2863
  function getStatsPath() {
2779
2864
  const envPath = process.env[ENV_STATS_PATH];
2780
- return envPath || STATS_FILE;
2865
+ if (envPath) return envPath;
2866
+ return getTokenStatsPath();
2781
2867
  }
2782
2868
  function loadAllRecords(statsPath) {
2783
2869
  if (!existsSync7(statsPath)) return [];
2784
2870
  try {
2785
- const data = JSON.parse(readFileSync7(statsPath, "utf-8"));
2871
+ const data = JSON.parse(readFileSync8(statsPath, "utf-8"));
2786
2872
  if (Array.isArray(data)) return data;
2787
2873
  if (data && Array.isArray(data.records)) return data.records;
2788
2874
  return [];
@@ -2922,13 +3008,12 @@ function resetTokenStats() {
2922
3008
  }
2923
3009
  }
2924
3010
  }
2925
- var STATS_DIR, STATS_FILE, ENV_STATS_PATH, MAX_RECORDS;
3011
+ var ENV_STATS_PATH, MAX_RECORDS;
2926
3012
  var init_token_stats = __esm({
2927
3013
  "src/engine/token-stats.ts"() {
2928
3014
  "use strict";
2929
3015
  init_esm_shims();
2930
- STATS_DIR = join4(homedir3(), ".config", "agentmoss");
2931
- STATS_FILE = join4(STATS_DIR, "agent_moss_token_stats.json");
3016
+ init_paths();
2932
3017
  ENV_STATS_PATH = "AGENT_MOSS_TOKEN_STATS_PATH";
2933
3018
  MAX_RECORDS = 1e4;
2934
3019
  }
@@ -3793,7 +3878,7 @@ init_skill_loader();
3793
3878
 
3794
3879
  // src/engine/template-loader.ts
3795
3880
  init_esm_shims();
3796
- import { readFileSync as readFileSync4, existsSync as existsSync5 } from "fs";
3881
+ import { readFileSync as readFileSync5, existsSync as existsSync5 } from "fs";
3797
3882
  import { resolve as resolve3, dirname as dirname4 } from "path";
3798
3883
  import { fileURLToPath as fileURLToPath6 } from "url";
3799
3884
  var __filename4 = fileURLToPath6(import.meta.url);
@@ -3814,7 +3899,7 @@ function loadTemplates() {
3814
3899
  const filePath = resolve3(dir, file);
3815
3900
  if (existsSync5(filePath)) {
3816
3901
  const key = file.replace(".txt", "").replace("_template", "");
3817
- cachedTemplates[key] = readFileSync4(filePath, "utf-8");
3902
+ cachedTemplates[key] = readFileSync5(filePath, "utf-8");
3818
3903
  }
3819
3904
  }
3820
3905
  console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates from ${dir}`);
@@ -3823,8 +3908,8 @@ function loadTemplates() {
3823
3908
 
3824
3909
  // src/engine/script-analyzer.ts
3825
3910
  init_esm_shims();
3826
- import { readFileSync as readFileSync5 } from "fs";
3827
- import { resolve as resolve4, join as join2 } from "path";
3911
+ import { readFileSync as readFileSync6 } from "fs";
3912
+ import { resolve as resolve4, join as join3 } from "path";
3828
3913
  var SUSPICIOUS_PATTERNS = [
3829
3914
  // Network exfiltration (curl/wget POST in scripts is almost never legitimate)
3830
3915
  { name: "curl POST", pattern: /curl\s+(.*\s)?-X\s+POST/i },
@@ -3957,8 +4042,8 @@ function assessKeywordCombinationRisk(matchedKeywords, scriptContent) {
3957
4042
  }
3958
4043
  function readScriptContent(scriptPath, maxLines = 500) {
3959
4044
  try {
3960
- const expandedPath = scriptPath.startsWith("~") ? join2(process.env.HOME || "/home/user", scriptPath.slice(2)) : resolve4(scriptPath);
3961
- const raw = readFileSync5(expandedPath, "utf-8");
4045
+ const expandedPath = scriptPath.startsWith("~") ? join3(process.env.HOME || "/home/user", scriptPath.slice(2)) : resolve4(scriptPath);
4046
+ const raw = readFileSync6(expandedPath, "utf-8");
3962
4047
  const lines = raw.split("\n").slice(0, maxLines);
3963
4048
  return { content: lines.join("\n"), lineCount: lines.length, error: "" };
3964
4049
  } catch (e) {
@@ -4012,8 +4097,8 @@ ${result.scriptContent}
4012
4097
  init_esm_shims();
4013
4098
  init_heuristic();
4014
4099
  init_logic_rules();
4015
- import { readFileSync as readFileSync6, statSync, existsSync as existsSync6 } from "fs";
4016
- import { resolve as resolve5, join as join3, isAbsolute, dirname as dirname5 } from "path";
4100
+ import { readFileSync as readFileSync7, statSync, existsSync as existsSync6 } from "fs";
4101
+ import { resolve as resolve5, join as join4, isAbsolute, dirname as dirname5 } from "path";
4017
4102
  import { homedir as homedir2 } from "os";
4018
4103
  function emptyChain() {
4019
4104
  return {
@@ -4254,7 +4339,7 @@ function extractInlineScriptPath(actionDetail) {
4254
4339
  function resolvePath(p) {
4255
4340
  let expanded = p;
4256
4341
  if (expanded.startsWith("~/") || expanded === "~") {
4257
- expanded = join3(homedir2(), expanded.slice(1));
4342
+ expanded = join4(homedir2(), expanded.slice(1));
4258
4343
  }
4259
4344
  return resolve5(expanded);
4260
4345
  }
@@ -4267,7 +4352,7 @@ function readScriptContent2(scriptPath, maxFileSize = 2 * 1024 * 1024) {
4267
4352
  if (stat.size > maxFileSize) {
4268
4353
  return { content: "", lineCount: 0, fileSize: stat.size, error: `\u811A\u672C\u6587\u4EF6\u8FC7\u5927 (${stat.size} bytes)\uFF0C\u8DF3\u8FC7\u8BFB\u53D6` };
4269
4354
  }
4270
- const content = readFileSync6(path3, "utf-8");
4355
+ const content = readFileSync7(path3, "utf-8");
4271
4356
  const lineCount = content ? content.split("\n").length : 0;
4272
4357
  return { content, lineCount, fileSize: stat.size, error: "" };
4273
4358
  } catch (e) {
@@ -4284,7 +4369,7 @@ function extractChildScriptPaths(content, baseDir) {
4284
4369
  const pathStr = m[1];
4285
4370
  if (pathStr.startsWith("-") || pathStr.startsWith("$")) continue;
4286
4371
  if (pathStr.includes("/dev/") || pathStr.startsWith("|") || pathStr.startsWith(";")) continue;
4287
- const full = isAbsolute(pathStr) ? pathStr : join3(baseDir, pathStr);
4372
+ const full = isAbsolute(pathStr) ? pathStr : join4(baseDir, pathStr);
4288
4373
  const resolved = resolvePath(full);
4289
4374
  if (existsSync6(resolved)) {
4290
4375
  try {
@@ -5242,7 +5327,7 @@ init_esm_shims();
5242
5327
  init_runtime_config();
5243
5328
  init_token_stats();
5244
5329
  import { Hono } from "hono";
5245
- import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
5330
+ import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
5246
5331
  import { join as join5, dirname as dirname6 } from "path";
5247
5332
  import { fileURLToPath as fileURLToPath7 } from "url";
5248
5333
  var __dirname6 = dirname6(fileURLToPath7(import.meta.url));
@@ -5272,7 +5357,7 @@ function createConsoleRouter() {
5272
5357
  const serveIndex = (c) => {
5273
5358
  const indexFile = join5(STATIC_DIR, "index.html");
5274
5359
  if (existsSync9(indexFile)) {
5275
- return c.html(readFileSync8(indexFile, "utf-8"));
5360
+ return c.html(readFileSync9(indexFile, "utf-8"));
5276
5361
  }
5277
5362
  return c.html("<h1>AgentMoss Policy Console</h1><p>Frontend not built. Use /console/api/* endpoints.</p>");
5278
5363
  };
@@ -5280,12 +5365,12 @@ function createConsoleRouter() {
5280
5365
  console2.get("", serveIndex);
5281
5366
  console2.get("/api/layers", (c) => {
5282
5367
  const rc = loadRuntimeConfig();
5283
- return c.json({ layers: rc.layers });
5368
+ return c.json({ layers: rc.layers, env_overrides: getEnvOverrides() });
5284
5369
  });
5285
5370
  console2.put("/api/layers", async (c) => {
5286
5371
  const body = await c.req.json();
5287
5372
  const rc = updateLayerEnabled(body.layer_key, body.enabled);
5288
- return c.json({ layers: rc.layers });
5373
+ return c.json({ layers: rc.layers, env_overrides: getEnvOverrides() });
5289
5374
  });
5290
5375
  console2.get("/api/rules", (c) => {
5291
5376
  const rc = loadRuntimeConfig();
@@ -5294,22 +5379,22 @@ function createConsoleRouter() {
5294
5379
  console2.put("/api/rules/enabled", async (c) => {
5295
5380
  const b = await c.req.json();
5296
5381
  const rc = updateRuleEnabled(b.layer, b.category, b.rule_id, b.enabled);
5297
- return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });
5382
+ return c.json(rc);
5298
5383
  });
5299
5384
  console2.put("/api/rules/deny_mode", async (c) => {
5300
5385
  const b = await c.req.json();
5301
5386
  const rc = updateRuleDenyMode(b.layer, b.category, b.rule_id, b.deny_mode);
5302
- return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });
5387
+ return c.json(rc);
5303
5388
  });
5304
5389
  console2.put("/api/rules/skip_l3", async (c) => {
5305
5390
  const b = await c.req.json();
5306
5391
  const rc = updateRuleSkipL3(b.layer, b.category, b.rule_id, b.skip_l3_on_disabled);
5307
- return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });
5392
+ return c.json(rc);
5308
5393
  });
5309
5394
  console2.put("/api/categories/enabled", async (c) => {
5310
5395
  const b = await c.req.json();
5311
5396
  const rc = updateCategoryEnabled(b.layer, b.category, b.enabled);
5312
- return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });
5397
+ return c.json(rc);
5313
5398
  });
5314
5399
  console2.post("/api/rules", async (c) => {
5315
5400
  const b = await c.req.json();
@@ -5325,38 +5410,38 @@ function createConsoleRouter() {
5325
5410
  credential: b.credential,
5326
5411
  deny_mode: b.deny_mode
5327
5412
  });
5328
- return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });
5413
+ return c.json(rc);
5329
5414
  });
5330
5415
  console2.delete("/api/rules", async (c) => {
5331
5416
  const b = await c.req.json();
5332
5417
  deleteCustomRule(b.layer, b.category, b.rule_id);
5333
5418
  const rc = loadRuntimeConfig();
5334
- return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });
5419
+ return c.json(rc);
5335
5420
  });
5336
5421
  console2.get("/api/skills", (c) => {
5337
5422
  const rc = loadRuntimeConfig();
5338
- return c.json({ L3_skills: rc.L3_skills });
5423
+ return c.json(rc.L3_skills);
5339
5424
  });
5340
5425
  console2.put("/api/skills/enabled", async (c) => {
5341
5426
  const b = await c.req.json();
5342
5427
  const rc = updateSkillEnabled(b.skill_id, b.enabled);
5343
- return c.json({ L3_skills: rc.L3_skills });
5428
+ return c.json(rc);
5344
5429
  });
5345
5430
  console2.put("/api/skill-categories/enabled", async (c) => {
5346
5431
  const b = await c.req.json();
5347
5432
  const rc = updateSkillCategoryEnabled(b.category, b.enabled);
5348
- return c.json({ L3_skills: rc.L3_skills });
5433
+ return c.json(rc);
5349
5434
  });
5350
5435
  console2.post("/api/skills", async (c) => {
5351
5436
  const b = await c.req.json();
5352
5437
  const rc = addCustomSkill(b.skill_id, b.category || "user_custom", b.keywords || [], b.content);
5353
- return c.json({ L3_skills: rc.L3_skills });
5438
+ return c.json(rc);
5354
5439
  });
5355
5440
  console2.delete("/api/skills", async (c) => {
5356
5441
  const b = await c.req.json();
5357
5442
  deleteCustomSkill(b.skill_id, b.category);
5358
5443
  const rc = loadRuntimeConfig();
5359
- return c.json({ L3_skills: rc.L3_skills });
5444
+ return c.json(rc);
5360
5445
  });
5361
5446
  console2.get("/api/skills/:skill_id/content", async (c) => {
5362
5447
  const skillId = c.req.param("skill_id");
@@ -5366,10 +5451,10 @@ function createConsoleRouter() {
5366
5451
  const skillPath = join5(dirname6(getRuntimeConfigPath()), "agent_moss_skills", `${skillId}.md`);
5367
5452
  if (!existsSync9(skillPath)) {
5368
5453
  const builtinPath = join5(__dirname6, "..", "..", "agent_moss", "skills", `${skillId}.md`);
5369
- if (existsSync9(builtinPath)) return c.text(readFileSync8(builtinPath, "utf-8"));
5454
+ if (existsSync9(builtinPath)) return c.text(readFileSync9(builtinPath, "utf-8"));
5370
5455
  return c.json({ error: "skill not found" }, 404);
5371
5456
  }
5372
- return c.text(readFileSync8(skillPath, "utf-8"));
5457
+ return c.text(readFileSync9(skillPath, "utf-8"));
5373
5458
  });
5374
5459
  console2.get("/api/agents", (c) => {
5375
5460
  const rc = loadRuntimeConfig();
@@ -5411,7 +5496,7 @@ function createConsoleRouter() {
5411
5496
  });
5412
5497
  console2.get("/api/config", (c) => {
5413
5498
  const rc = loadRuntimeConfig();
5414
- return c.json({ config: rc, config_path: getRuntimeConfigPath() });
5499
+ return c.json(rc);
5415
5500
  });
5416
5501
  console2.get("/api/env-overrides", (c) => {
5417
5502
  return c.json({ overrides: getEnvOverrides() });
@@ -5419,7 +5504,7 @@ function createConsoleRouter() {
5419
5504
  console2.post("/api/reset", (c) => {
5420
5505
  const defaults = generateSourceDefaults();
5421
5506
  saveRuntimeConfig(defaults);
5422
- return c.json({ config: defaults });
5507
+ return c.json(defaults);
5423
5508
  });
5424
5509
  console2.get("/api/token-stats", (c) => {
5425
5510
  const days = parseInt(c.req.query("days") || "7", 10);
@@ -5427,7 +5512,7 @@ function createConsoleRouter() {
5427
5512
  });
5428
5513
  console2.get("/api/token-stats/recent", (c) => {
5429
5514
  const limit = parseInt(c.req.query("limit") || "20", 10);
5430
- return c.json({ records: getRecentRecords(limit) });
5515
+ return c.json(getRecentRecords(limit));
5431
5516
  });
5432
5517
  console2.get("/api/token-stats/trend", (c) => {
5433
5518
  const days = parseInt(c.req.query("days") || "7", 10);