zhitalk 0.0.5 → 0.0.7

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.
Files changed (47) hide show
  1. package/README.md +2 -2
  2. package/dist/agent/agent.js +86 -63
  3. package/dist/agent/cli.js +39 -73
  4. package/dist/agent/colors.js +6 -44
  5. package/dist/agent/commands.js +22 -28
  6. package/dist/agent/config.js +20 -62
  7. package/dist/agent/context.js +14 -12
  8. package/dist/agent/db.js +17 -27
  9. package/dist/agent/hooks.d.ts +1 -1
  10. package/dist/agent/hooks.js +13 -22
  11. package/dist/agent/mcp/client.js +25 -29
  12. package/dist/agent/mcp/index.d.ts +1 -1
  13. package/dist/agent/mcp/index.js +8 -13
  14. package/dist/agent/mcp/wrapper.d.ts +2 -2
  15. package/dist/agent/mcp/wrapper.js +5 -8
  16. package/dist/agent/model.js +6 -10
  17. package/dist/agent/permission/exec.js +8 -11
  18. package/dist/agent/permission/is-dangerous-path.js +126 -18
  19. package/dist/agent/permission/is-safe-domains.js +1 -4
  20. package/dist/agent/permission/network.js +3 -6
  21. package/dist/agent/permission/read.js +3 -6
  22. package/dist/agent/permission/util.js +16 -26
  23. package/dist/agent/permission/write.js +5 -8
  24. package/dist/agent/prompt.js +9 -15
  25. package/dist/agent/skills.js +19 -24
  26. package/dist/agent/tools/agent_tool.js +2 -38
  27. package/dist/agent/tools/exec_tool.js +4 -7
  28. package/dist/agent/tools/load_skill_tool.js +3 -6
  29. package/dist/agent/tools/memory_create_tool.js +4 -10
  30. package/dist/agent/tools/memory_delete_tool.js +4 -10
  31. package/dist/agent/tools/memory_retrieve_tool.js +3 -6
  32. package/dist/agent/tools/profile_update_tool.js +11 -14
  33. package/dist/agent/tools/read_file_tool.js +4 -6
  34. package/dist/agent/tools/run_js_tool.js +3 -6
  35. package/dist/agent/tools/run_py_tool.js +4 -7
  36. package/dist/agent/tools/search.js +1 -4
  37. package/dist/agent/tools/web_fetch_tool.js +1 -4
  38. package/dist/agent/tools/web_search_tool.js +5 -8
  39. package/dist/agent/tools/write_file_tool.js +8 -9
  40. package/dist/agent/tools.js +76 -81
  41. package/dist/agent/utils.d.ts +1 -0
  42. package/dist/agent/utils.js +13 -6
  43. package/dist/index.js +23 -49
  44. package/dist/install.js +14 -50
  45. package/jest.config.js +11 -0
  46. package/package.json +8 -7
  47. package/dist/agent/permission/dangerous-path.json +0 -115
@@ -1,34 +1,31 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkExecPermission = checkExecPermission;
4
- const util_1 = require("./util");
5
- function checkExecPermission(toolCall) {
1
+ import { isSafeCommand, isChangingDirectory, isScriptExecution, isDangerousOperation } from './util.js';
2
+ export function checkExecPermission(toolCall) {
6
3
  const command = toolCall.args?.command;
7
4
  if (typeof command !== 'string') {
8
- return { action: 'confirm' };
5
+ return { action: 'allow' };
9
6
  }
10
- if ((0, util_1.isSafeCommand)(command)) {
7
+ if (isSafeCommand(command)) {
11
8
  return { action: 'allow' };
12
9
  }
13
- if ((0, util_1.isChangingDirectory)(command)) {
10
+ if (isChangingDirectory(command)) {
14
11
  return {
15
12
  action: 'block',
16
13
  reason: `命令包含切换目录操作,为防止目录逃逸,禁止执行。如有需要请手动操作。`,
17
14
  };
18
15
  }
19
- const scriptCheck = (0, util_1.isScriptExecution)(command);
16
+ const scriptCheck = isScriptExecution(command);
20
17
  if (scriptCheck.blocked) {
21
18
  return {
22
19
  action: 'block',
23
20
  reason: scriptCheck.reason,
24
21
  };
25
22
  }
26
- const dangerCheck = (0, util_1.isDangerousOperation)(command);
23
+ const dangerCheck = isDangerousOperation(command);
27
24
  if (dangerCheck.blocked) {
28
25
  return {
29
26
  action: 'block',
30
27
  reason: dangerCheck.reason,
31
28
  };
32
29
  }
33
- return { action: 'confirm' };
30
+ return { action: 'allow' };
34
31
  }
@@ -1,24 +1,132 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
1
+ import path from 'path';
2
+ import os from 'os';
3
+ const dangerousPaths = {
4
+ macos: [
5
+ '~/.ssh',
6
+ '~/.gnupg',
7
+ '~/.aws',
8
+ '~/.azure',
9
+ '~/.config/gcloud',
10
+ '~/.kube',
11
+ '~/.docker',
12
+ '~/.netrc',
13
+ '~/Library/Keychains',
14
+ '~/Library/Application Support/Google/Chrome',
15
+ '~/Library/Application Support/Chromium',
16
+ '~/Library/Application Support/Firefox',
17
+ '~/Library/Application Support/Slack',
18
+ '~/Library/Application Support/Discord',
19
+ '~/Library/Application Support/Telegram',
20
+ '~/Library/Application Support/Signal',
21
+ '~/.zshrc',
22
+ '~/.bashrc',
23
+ '~/.bash_profile',
24
+ '~/.profile',
25
+ '~/.env',
26
+ '~/.env.*',
27
+ '~/.gitconfig',
28
+ '~/.git-credentials',
29
+ '~/.npmrc',
30
+ '~/.pnpmrc',
31
+ '~/.yarnrc',
32
+ '~/.pypirc',
33
+ '~/.m2',
34
+ '~/.gradle',
35
+ '~/.terraform',
36
+ '~/.config/gh',
37
+ '~/.config/gitlab',
38
+ '~/.circleci',
39
+ '~/.vercel',
40
+ '~/.netlify',
41
+ '~/Library/Containers',
42
+ '/private',
43
+ '/etc',
44
+ '/var',
45
+ ],
46
+ linux: [
47
+ '~/.ssh',
48
+ '~/.gnupg',
49
+ '~/.pki',
50
+ '~/.aws',
51
+ '~/.azure',
52
+ '~/.config/gcloud',
53
+ '~/.kube',
54
+ '~/.docker',
55
+ '~/.netrc',
56
+ '~/.local/share/keyrings',
57
+ '~/.config/google-chrome',
58
+ '~/.config/chromium',
59
+ '~/.mozilla/firefox',
60
+ '~/.config/Slack',
61
+ '~/.config/discord',
62
+ '~/.local/share/TelegramDesktop',
63
+ '~/.zshrc',
64
+ '~/.bashrc',
65
+ '~/.bash_profile',
66
+ '~/.profile',
67
+ '~/.env',
68
+ '~/.env.*',
69
+ '~/.gitconfig',
70
+ '~/.git-credentials',
71
+ '~/.npmrc',
72
+ '~/.pnpmrc',
73
+ '~/.yarnrc',
74
+ '~/.pypirc',
75
+ '~/.m2',
76
+ '~/.gradle',
77
+ '~/.terraform',
78
+ '~/.config/gh',
79
+ '~/.config/gitlab',
80
+ '~/.circleci',
81
+ '~/.vercel',
82
+ '~/.netlify',
83
+ '/etc/shadow',
84
+ '/etc/sudoers',
85
+ '/proc',
86
+ '/sys',
87
+ '/var/lib',
88
+ '/root',
89
+ ],
90
+ windows: [
91
+ '%USERPROFILE%\\.ssh',
92
+ '%USERPROFILE%\\.gnupg',
93
+ '%USERPROFILE%\\.aws',
94
+ '%USERPROFILE%\\.azure',
95
+ '%USERPROFILE%\\.kube',
96
+ '%USERPROFILE%\\.docker',
97
+ '%LOCALAPPDATA%\\Google\\Chrome\\User Data',
98
+ '%LOCALAPPDATA%\\Chromium\\User Data',
99
+ '%APPDATA%\\Mozilla\\Firefox',
100
+ '%APPDATA%\\Slack',
101
+ '%APPDATA%\\Discord',
102
+ '%APPDATA%\\Telegram Desktop',
103
+ '%USERPROFILE%\\.gitconfig',
104
+ '%USERPROFILE%\\.git-credentials',
105
+ '%USERPROFILE%\\.npmrc',
106
+ '%USERPROFILE%\\.pnpmrc',
107
+ '%USERPROFILE%\\.yarnrc',
108
+ '%USERPROFILE%\\.m2',
109
+ '%USERPROFILE%\\.gradle',
110
+ '%APPDATA%',
111
+ '%LOCALAPPDATA%',
112
+ 'C:\\Windows\\System32',
113
+ 'C:\\Windows\\System32\\config\\SAM',
114
+ 'C:\\Windows\\System32\\config\\SECURITY',
115
+ 'C:\\Windows\\System32\\config\\SYSTEM',
116
+ ],
4
117
  };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isDangerousPath = isDangerousPath;
7
- const path_1 = __importDefault(require("path"));
8
- const os_1 = __importDefault(require("os"));
9
- const dangerous_path_json_1 = __importDefault(require("./dangerous-path.json"));
10
118
  function expandPath(filepath) {
11
119
  let expanded = filepath;
12
120
  if (expanded.startsWith('~')) {
13
- expanded = path_1.default.join(os_1.default.homedir(), expanded.slice(1));
121
+ expanded = path.join(os.homedir(), expanded.slice(1));
14
122
  }
15
- expanded = expanded.replace(/%USERPROFILE%/gi, os_1.default.homedir());
16
- expanded = expanded.replace(/%APPDATA%/gi, process.env.APPDATA || path_1.default.join(os_1.default.homedir(), 'AppData', 'Roaming'));
17
- expanded = expanded.replace(/%LOCALAPPDATA%/gi, process.env.LOCALAPPDATA || path_1.default.join(os_1.default.homedir(), 'AppData', 'Local'));
18
- if (!path_1.default.isAbsolute(expanded)) {
19
- expanded = path_1.default.resolve(expanded);
123
+ expanded = expanded.replace(/%USERPROFILE%/gi, os.homedir());
124
+ expanded = expanded.replace(/%APPDATA%/gi, process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming'));
125
+ expanded = expanded.replace(/%LOCALAPPDATA%/gi, process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'));
126
+ if (!path.isAbsolute(expanded)) {
127
+ expanded = path.resolve(expanded);
20
128
  }
21
- expanded = path_1.default.normalize(expanded);
129
+ expanded = path.normalize(expanded);
22
130
  return expanded;
23
131
  }
24
132
  function globToRegex(pattern) {
@@ -27,13 +135,13 @@ function globToRegex(pattern) {
27
135
  .replace(/\*/g, '[^\\\\/]*');
28
136
  return new RegExp(`^${escaped}(?:[\\\\/].*)?$`);
29
137
  }
30
- function isDangerousPath(filepath) {
138
+ export function isDangerousPath(filepath) {
31
139
  const platform = process.platform === 'win32'
32
140
  ? 'windows'
33
141
  : process.platform === 'darwin'
34
142
  ? 'macos'
35
143
  : 'linux';
36
- const dangerousList = dangerous_path_json_1.default[platform];
144
+ const dangerousList = dangerousPaths[platform];
37
145
  const expandedInput = expandPath(filepath);
38
146
  for (const dangerous of dangerousList) {
39
147
  const expandedDangerous = expandPath(dangerous);
@@ -45,7 +153,7 @@ function isDangerousPath(filepath) {
45
153
  else {
46
154
  if (expandedInput === expandedDangerous)
47
155
  return true;
48
- if (expandedInput.startsWith(expandedDangerous + path_1.default.sep))
156
+ if (expandedInput.startsWith(expandedDangerous + path.sep))
49
157
  return true;
50
158
  }
51
159
  }
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isSafeDomain = isSafeDomain;
4
1
  const commonDomainsCNForDevelopers = [
5
2
  // 搜索 / AI
6
3
  'google.com',
@@ -127,7 +124,7 @@ const commonDomainsCNForDevelopers = [
127
124
  'tavily.com',
128
125
  'smith.langchain.com',
129
126
  ];
130
- function isSafeDomain(url) {
127
+ export function isSafeDomain(url) {
131
128
  let hostname;
132
129
  try {
133
130
  hostname = new URL(url).hostname.toLowerCase();
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkNetworkPermission = checkNetworkPermission;
4
- const is_safe_domains_1 = require("./is-safe-domains");
5
- function checkNetworkPermission(toolCall) {
1
+ import { isSafeDomain } from './is-safe-domains.js';
2
+ export function checkNetworkPermission(toolCall) {
6
3
  const url = toolCall.args?.url;
7
4
  if (typeof url !== 'string') {
8
5
  return { action: 'allow' };
9
6
  }
10
- if ((0, is_safe_domains_1.isSafeDomain)(url)) {
7
+ if (isSafeDomain(url)) {
11
8
  return { action: 'allow' };
12
9
  }
13
10
  return { action: 'confirm' };
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkReadPermission = checkReadPermission;
4
- const is_dangerous_path_1 = require("./is-dangerous-path");
5
- function checkReadPermission(toolCall) {
1
+ import { isDangerousPath } from './is-dangerous-path.js';
2
+ export function checkReadPermission(toolCall) {
6
3
  const filepath = toolCall.args?.filepath;
7
4
  if (filepath == null) {
8
5
  return { action: 'allow' };
9
6
  }
10
- if ((0, is_dangerous_path_1.isDangerousPath)(filepath)) {
7
+ if (isDangerousPath(filepath)) {
11
8
  return {
12
9
  action: 'block',
13
10
  reason: `路径 "${filepath}" 是系统敏感目录,为保护系统安全,禁止访问。如有需要请手动操作。`,
@@ -1,25 +1,15 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isInProjectDir = isInProjectDir;
7
- exports.isChangingDirectory = isChangingDirectory;
8
- exports.isScriptExecution = isScriptExecution;
9
- exports.isSafeCommand = isSafeCommand;
10
- exports.isDangerousOperation = isDangerousOperation;
11
- const path_1 = __importDefault(require("path"));
12
- const config_1 = require("../config");
13
- function isInProjectDir(filepath) {
14
- const resolved = path_1.default.resolve(filepath);
15
- const cwd = path_1.default.resolve(process.cwd());
16
- if (resolved === cwd || resolved.startsWith(cwd + path_1.default.sep)) {
1
+ import path from 'path';
2
+ import { WORKSPACE_DIR } from '../config.js';
3
+ export function isInProjectDir(filepath) {
4
+ const resolved = path.resolve(filepath);
5
+ const cwd = path.resolve(process.cwd());
6
+ if (resolved === cwd || resolved.startsWith(cwd + path.sep)) {
17
7
  return true;
18
8
  }
19
- const zhitalkDir = config_1.WORKSPACE_DIR;
20
- return resolved === zhitalkDir || resolved.startsWith(zhitalkDir + path_1.default.sep);
9
+ const zhitalkDir = WORKSPACE_DIR;
10
+ return resolved === zhitalkDir || resolved.startsWith(zhitalkDir + path.sep);
21
11
  }
22
- function isChangingDirectory(command) {
12
+ export function isChangingDirectory(command) {
23
13
  return /(?:^|[\s;|&])(?:cd|chdir|pushd|popd)(?:\s|$)/i.test(command);
24
14
  }
25
15
  const PYTHON_TOOLS = ['python', 'python3', 'python2'];
@@ -37,12 +27,12 @@ function getFirstToken(command) {
37
27
  const match = trimmed.match(/^([^\s]+)/);
38
28
  return match ? match[1] : trimmed;
39
29
  }
40
- function isScriptExecution(command) {
30
+ export function isScriptExecution(command) {
41
31
  const subCommands = command.split(/[;|&]+/).filter(Boolean);
42
32
  for (const sub of subCommands) {
43
33
  const token = getFirstToken(sub);
44
- const tool = path_1.default.basename(token).toLowerCase();
45
- const ext = path_1.default.extname(token).toLowerCase();
34
+ const tool = path.basename(token).toLowerCase();
35
+ const ext = path.extname(token).toLowerCase();
46
36
  if (PYTHON_TOOLS.includes(tool) || ext === '.py') {
47
37
  return { blocked: true, reason: '检测到 Python 脚本执行,请使用 run_py tool 执行 Python 代码。' };
48
38
  }
@@ -118,13 +108,13 @@ function getSecondToken(command) {
118
108
  const tokens = command.trim().split(/\s+/);
119
109
  return tokens[1] || null;
120
110
  }
121
- function isSafeCommand(command) {
111
+ export function isSafeCommand(command) {
122
112
  if (hasOutputRedirect(command))
123
113
  return false;
124
114
  const subCommands = command.split(/[;|&]+/).filter(Boolean);
125
115
  for (const sub of subCommands) {
126
116
  const token = getFirstToken(sub);
127
- const tool = path_1.default.basename(token).toLowerCase();
117
+ const tool = path.basename(token).toLowerCase();
128
118
  if (SAFE_COMMANDS.includes(tool)) {
129
119
  continue;
130
120
  }
@@ -138,7 +128,7 @@ function isSafeCommand(command) {
138
128
  }
139
129
  return true;
140
130
  }
141
- function isDangerousOperation(command) {
131
+ export function isDangerousOperation(command) {
142
132
  const subCommand = extractShellSubCommand(command);
143
133
  if (subCommand) {
144
134
  const result = isDangerousOperation(subCommand);
@@ -148,7 +138,7 @@ function isDangerousOperation(command) {
148
138
  const subCommands = command.split(/[;|&]+/).filter(Boolean);
149
139
  for (const sub of subCommands) {
150
140
  const token = getFirstToken(sub);
151
- const tool = path_1.default.basename(token).toLowerCase();
141
+ const tool = path.basename(token).toLowerCase();
152
142
  if (DANGEROUS_COMMANDS.includes(tool)) {
153
143
  return { blocked: true, reason: `检测到危险操作 "${tool}",exec tool 禁止执行该命令。如有需要请手动操作。` };
154
144
  }
@@ -1,20 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkWritePermission = checkWritePermission;
4
- const is_dangerous_path_1 = require("./is-dangerous-path");
5
- const util_1 = require("./util");
6
- function checkWritePermission(toolCall) {
1
+ import { isDangerousPath } from './is-dangerous-path.js';
2
+ import { isInProjectDir } from './util.js';
3
+ export function checkWritePermission(toolCall) {
7
4
  const filepath = toolCall.args?.filepath;
8
5
  if (filepath == null) {
9
6
  return { action: 'allow' };
10
7
  }
11
- if ((0, is_dangerous_path_1.isDangerousPath)(filepath)) {
8
+ if (isDangerousPath(filepath)) {
12
9
  return {
13
10
  action: 'block',
14
11
  reason: `路径 "${filepath}" 是系统敏感目录,为保护系统安全,禁止访问。如有需要请手动操作。`,
15
12
  };
16
13
  }
17
- if ((0, util_1.isInProjectDir)(filepath)) {
14
+ if (isInProjectDir(filepath)) {
18
15
  return { action: 'allow' };
19
16
  }
20
17
  return { action: 'confirm' };
@@ -1,21 +1,15 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.systemPrompt = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const skills_1 = require("./skills");
10
- const config_1 = require("./config");
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { discoverSkills, getSkillsListText } from './skills.js';
4
+ import { WORKSPACE_DIR } from './config.js';
11
5
  // ── Skills ────────────────────────────────────────────────
12
- (0, skills_1.discoverSkills)();
13
- const skillsText = (0, skills_1.getSkillsListText)();
6
+ discoverSkills();
7
+ const skillsText = getSkillsListText();
14
8
  const basePrompt = 'You are zhitalk, 中文名字叫智语, a personal AI Agent like OpenClaw, including tools, skills, memory, hook, sub-agent, MCP server, etc. Run in the terminal.';
15
9
  function readProfile() {
16
10
  try {
17
- const filePath = path_1.default.join(config_1.WORKSPACE_DIR, '.data', 'profile.md');
18
- const content = fs_1.default.readFileSync(filePath, 'utf-8').trim();
11
+ const filePath = path.join(WORKSPACE_DIR, '.data', 'profile.md');
12
+ const content = fs.readFileSync(filePath, 'utf-8').trim();
19
13
  return `<profile_info>${content}</profile_info>`;
20
14
  }
21
15
  catch {
@@ -45,6 +39,6 @@ const memoryPrompt = `## Memory Management Rules
45
39
  const dateTimePrompt = `## Current DateTime
46
40
 
47
41
  ${new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}`;
48
- exports.systemPrompt = skillsText
42
+ export const systemPrompt = skillsText
49
43
  ? `${basePrompt}\n\n${profilePrompt}\n\n${memoryPrompt}\n\n## Available Skills\n\nYou have access to the following skills. When a user's request matches a skill's description, you MUST call the \`load_skill\` tool to load that skill's full instructions, then follow them.\n\n${skillsText}\n\n${dateTimePrompt}`
50
44
  : `${basePrompt}\n\n${profilePrompt}\n\n${memoryPrompt}\n\n${dateTimePrompt}`;
@@ -1,12 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.discoverSkills = discoverSkills;
4
- exports.loadSkill = loadSkill;
5
- exports.getSkillsListText = getSkillsListText;
6
- const fs_1 = require("fs");
7
- const path_1 = require("path");
8
- const os_1 = require("os");
9
- const config_1 = require("./config");
1
+ import { readdirSync, readFileSync, statSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { WORKSPACE_DIR } from './config.js';
10
5
  const skills = [];
11
6
  const skillContentMap = new Map();
12
7
  function parseFrontmatter(content) {
@@ -30,30 +25,30 @@ function parseFrontmatter(content) {
30
25
  }
31
26
  return { name: result.name || '', description: result.description || '' };
32
27
  }
33
- function discoverSkills() {
28
+ export function discoverSkills() {
34
29
  skills.length = 0;
35
30
  skillContentMap.clear();
36
31
  const skillDirs = [
37
- (0, path_1.join)((0, os_1.homedir)(), '.agents', 'skills'),
38
- (0, path_1.join)(config_1.WORKSPACE_DIR, '.agents', 'skills'),
39
- (0, path_1.join)(config_1.WORKSPACE_DIR, 'skills'),
32
+ join(homedir(), '.agents', 'skills'),
33
+ join(WORKSPACE_DIR, '.agents', 'skills'),
34
+ join(WORKSPACE_DIR, 'skills'),
40
35
  ];
41
36
  for (const skillsDir of skillDirs) {
42
37
  let entries;
43
38
  try {
44
- entries = (0, fs_1.readdirSync)(skillsDir);
39
+ entries = readdirSync(skillsDir);
45
40
  }
46
41
  catch {
47
42
  continue;
48
43
  }
49
44
  for (const entry of entries) {
50
- const entryPath = (0, path_1.join)(skillsDir, entry);
45
+ const entryPath = join(skillsDir, entry);
51
46
  try {
52
- const entryStat = (0, fs_1.statSync)(entryPath);
47
+ const entryStat = statSync(entryPath);
53
48
  if (!entryStat.isDirectory())
54
49
  continue;
55
- const skillMdPath = (0, path_1.join)(entryPath, 'SKILL.md');
56
- const content = (0, fs_1.readFileSync)(skillMdPath, 'utf-8');
50
+ const skillMdPath = join(entryPath, 'SKILL.md');
51
+ const content = readFileSync(skillMdPath, 'utf-8');
57
52
  const { name, description } = parseFrontmatter(content);
58
53
  if (name && description) {
59
54
  const existing = skills.find((s) => s.name === name);
@@ -74,18 +69,18 @@ function discoverSkills() {
74
69
  }
75
70
  return skills;
76
71
  }
77
- function loadSkill(name) {
72
+ export function loadSkill(name) {
78
73
  return skillContentMap.get(name) ?? null;
79
74
  }
80
- function getSkillsListText() {
75
+ export function getSkillsListText() {
81
76
  const lines = skills.map((s) => `- **${s.name}**: ${s.description}`);
82
77
  if (skills.length > 0) {
83
78
  lines.push('');
84
79
  lines.push('skills 的目录:');
85
- lines.push((0, path_1.join)((0, os_1.homedir)(), '.agents', 'skills'));
86
- lines.push((0, path_1.join)(config_1.WORKSPACE_DIR, '.agents', 'skills'));
87
- lines.push((0, path_1.join)(config_1.WORKSPACE_DIR, 'skills'));
88
- lines.push(`如果增加新 skill,必须放在 ${(0, path_1.join)(config_1.WORKSPACE_DIR, 'skills')} 目录下`);
80
+ lines.push(join(homedir(), '.agents', 'skills'));
81
+ lines.push(join(WORKSPACE_DIR, '.agents', 'skills'));
82
+ lines.push(join(WORKSPACE_DIR, 'skills'));
83
+ lines.push(`如果增加新 skill,必须放在 ${join(WORKSPACE_DIR, 'skills')} 目录下`);
89
84
  }
90
85
  return lines.join('\n');
91
86
  }
@@ -1,44 +1,8 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.agentTool = agentTool;
37
- async function agentTool({ prompt }) {
1
+ export async function agentTool({ prompt }) {
38
2
  if (!prompt || !prompt.trim()) {
39
3
  return 'Error: prompt is empty.';
40
4
  }
41
5
  // 动态 import 避免循环依赖:agent.ts -> tools.ts -> agent_tool.ts -> agent.ts
42
- const { runSubAgent } = await Promise.resolve().then(() => __importStar(require('../agent')));
6
+ const { runSubAgent } = await import('../agent.js');
43
7
  return runSubAgent(prompt.trim());
44
8
  }
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.execTool = execTool;
4
- const child_process_1 = require("child_process");
5
- const util_1 = require("util");
6
- const execAsync = (0, util_1.promisify)(child_process_1.exec);
7
- async function execTool({ command }) {
1
+ import { exec } from 'child_process';
2
+ import { promisify } from 'util';
3
+ const execAsync = promisify(exec);
4
+ export async function execTool({ command }) {
8
5
  const trimmed = command.trim();
9
6
  if (!trimmed) {
10
7
  return 'Error: command is empty.';
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadSkillTool = loadSkillTool;
4
- const skills_1 = require("../skills");
5
- async function loadSkillTool({ name }) {
1
+ import { loadSkill } from '../skills.js';
2
+ export async function loadSkillTool({ name }) {
6
3
  const trimmed = name.trim();
7
4
  if (!trimmed) {
8
5
  return 'Error: skill name is empty.';
9
6
  }
10
- const content = (0, skills_1.loadSkill)(trimmed);
7
+ const content = loadSkill(trimmed);
11
8
  if (!content) {
12
9
  return `Error: skill "${trimmed}" not found.`;
13
10
  }
@@ -1,13 +1,7 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.memoryCreateTool = memoryCreateTool;
7
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
- const db_1 = require("../db");
1
+ import Database from 'better-sqlite3';
2
+ import { DB_PATH } from '../db.js';
9
3
  const VALID_TYPES = ['fact', 'event', 'preference', 'skill'];
10
- async function memoryCreateTool({ type, content, keywords, importance, }, config) {
4
+ export async function memoryCreateTool({ type, content, keywords, importance, }, config) {
11
5
  if (!VALID_TYPES.includes(type)) {
12
6
  return `Error: type must be one of ${VALID_TYPES.join(', ')}.`;
13
7
  }
@@ -21,7 +15,7 @@ async function memoryCreateTool({ type, content, keywords, importance, }, config
21
15
  }
22
16
  const sessionId = config?.configurable?.thread_id ?? 'default-session';
23
17
  const keywordsJson = keywords && keywords.length > 0 ? JSON.stringify(keywords) : null;
24
- const db = new better_sqlite3_1.default(db_1.DB_PATH);
18
+ const db = new Database(DB_PATH);
25
19
  try {
26
20
  const stmt = db.prepare(`INSERT INTO memory (type, content, keywords, importance, session_id)
27
21
  VALUES (?, ?, ?, ?, ?)`);
@@ -1,16 +1,10 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.memoryDeleteTool = memoryDeleteTool;
7
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
- const db_1 = require("../db");
9
- async function memoryDeleteTool({ id, }, _config) {
1
+ import Database from 'better-sqlite3';
2
+ import { DB_PATH } from '../db.js';
3
+ export async function memoryDeleteTool({ id, }, _config) {
10
4
  if (!Number.isFinite(id) || id <= 0) {
11
5
  return 'Error: id must be a positive integer.';
12
6
  }
13
- const db = new better_sqlite3_1.default(db_1.DB_PATH);
7
+ const db = new Database(DB_PATH);
14
8
  try {
15
9
  const existing = db.prepare('SELECT 1 FROM memory WHERE id = ?').get(id);
16
10
  if (!existing) {
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.memoryRetrieveTool = memoryRetrieveTool;
4
- const db_1 = require("../db");
5
- async function memoryRetrieveTool({ query, limit, }, config) {
1
+ import { searchMemories } from '../db.js';
2
+ export async function memoryRetrieveTool({ query, limit, }, config) {
6
3
  const trimmedQueries = query?.map((q) => q.trim()).filter((q) => q.length > 0);
7
4
  if (!trimmedQueries || trimmedQueries.length === 0) {
8
5
  return 'Error: query is required.';
@@ -12,7 +9,7 @@ async function memoryRetrieveTool({ query, limit, }, config) {
12
9
  return 'Error: limit must be between 1 and 50.';
13
10
  }
14
11
  try {
15
- const results = (0, db_1.searchMemories)(trimmedQueries, limitValue);
12
+ const results = searchMemories(trimmedQueries, limitValue);
16
13
  if (results.length === 0) {
17
14
  return 'No relevant memories found.';
18
15
  }