@miruzero/zero-agent 0.3.2 → 0.3.4
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/package.json +1 -1
- package/src/autostart.js +3 -1
- package/src/capabilities.js +14 -3
- package/src/local-tools.js +29 -3
package/package.json
CHANGED
package/src/autostart.js
CHANGED
|
@@ -35,10 +35,12 @@ const paths = (env = process.env) => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
const packageSpec = () => pkg.name + '@' + pkg.version;
|
|
38
|
+
const packageBin = () => path.join(__dirname, '..', 'bin', 'zero-agent.js');
|
|
38
39
|
|
|
39
40
|
const launcherContent = ({ interval = DEFAULT_INTERVAL, roots, logFile }, env = process.env) => {
|
|
40
41
|
const home = config.agentHome(env);
|
|
41
42
|
const spec = packageSpec();
|
|
43
|
+
const bin = packageBin();
|
|
42
44
|
return [
|
|
43
45
|
'@echo off',
|
|
44
46
|
'setlocal',
|
|
@@ -49,7 +51,7 @@ const launcherContent = ({ interval = DEFAULT_INTERVAL, roots, logFile }, env =
|
|
|
49
51
|
'rem interval=' + Number(interval || DEFAULT_INTERVAL) + 'ms',
|
|
50
52
|
'if not exist ' + q(winPath(path.dirname(logFile))) + ' mkdir ' + q(winPath(path.dirname(logFile))),
|
|
51
53
|
'echo [%date% %time%] starting ' + spec + ' >> ' + q(winPath(logFile)),
|
|
52
|
-
'
|
|
54
|
+
'node ' + q(winPath(bin)) + ' start --interval %ZERO_AGENT_INTERVAL% >> ' + q(winPath(logFile)) + ' 2>&1',
|
|
53
55
|
''
|
|
54
56
|
].join('\r\n');
|
|
55
57
|
};
|
package/src/capabilities.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const crypto = require('node:crypto');
|
|
4
4
|
const fs = require('node:fs');
|
|
5
5
|
const path = require('node:path');
|
|
6
|
+
const localTools = require('./local-tools');
|
|
6
7
|
|
|
7
8
|
const defaultMcpRoot = () => path.resolve(__dirname, '../..');
|
|
8
9
|
const mcpRoot = (env = process.env) => path.resolve(env.ZERO_MCP_ROOT || defaultMcpRoot());
|
|
@@ -55,8 +56,17 @@ const safeInternalTools = (provider) => {
|
|
|
55
56
|
return [{ name: '__scan_error__', description: error.message, inputSchema: null }];
|
|
56
57
|
}
|
|
57
58
|
};
|
|
59
|
+
const builtInLocalProvider = () => ({
|
|
60
|
+
name: 'zero-agent-local',
|
|
61
|
+
type: 'internal',
|
|
62
|
+
description: 'Built-in safe local filesystem tools exposed by zero-agent.',
|
|
63
|
+
status: 'present',
|
|
64
|
+
tools: localTools.listTools(),
|
|
65
|
+
tool_count: localTools.listTools().length
|
|
66
|
+
});
|
|
67
|
+
|
|
58
68
|
const buildCapabilities = (env = process.env) => {
|
|
59
|
-
const providers = manifestProviders(env).map((provider) => {
|
|
69
|
+
const providers = [builtInLocalProvider(), ...manifestProviders(env).map((provider) => {
|
|
60
70
|
const tools = provider.type === 'internal' ? safeInternalTools(provider) : [];
|
|
61
71
|
return {
|
|
62
72
|
name: provider.name,
|
|
@@ -67,7 +77,7 @@ const buildCapabilities = (env = process.env) => {
|
|
|
67
77
|
tool_count: tools.length,
|
|
68
78
|
mcp_stdio_live_scan: provider.type === 'mcp-stdio' ? false : undefined
|
|
69
79
|
};
|
|
70
|
-
});
|
|
80
|
+
})];
|
|
71
81
|
const payload = {
|
|
72
82
|
agent_version: require('../package.json').version,
|
|
73
83
|
mcp_root: mcpRoot(env),
|
|
@@ -80,4 +90,5 @@ const buildCapabilities = (env = process.env) => {
|
|
|
80
90
|
return payload;
|
|
81
91
|
};
|
|
82
92
|
|
|
83
|
-
|
|
93
|
+
const capabilities = { mcpRoot, providersDir, manifestProviders, buildCapabilities };
|
|
94
|
+
Object.assign(exports, capabilities);
|
package/src/local-tools.js
CHANGED
|
@@ -101,6 +101,20 @@ const readFile = (args, env) => {
|
|
|
101
101
|
return { ok: true, path: file, totalLines: lines.length, offset: start, length: slice.length, content: numbered(slice, start) };
|
|
102
102
|
};
|
|
103
103
|
|
|
104
|
+
const readFiles = (args = {}, env) => {
|
|
105
|
+
const requests = Array.isArray(args.files) && args.files.length
|
|
106
|
+
? args.files.map((item) => ({ path: item.path, offset: item.offset, length: item.length }))
|
|
107
|
+
: (Array.isArray(args.paths) ? args.paths : []).map((inputPath) => ({ path: inputPath, offset: args.offset, length: args.length }));
|
|
108
|
+
if (!requests.length) throw err('INVALID_PATHS', 'paths or files must contain at least one file');
|
|
109
|
+
if (requests.length > 50) throw err('TOO_MANY_PATHS', 'readFiles supports up to 50 files');
|
|
110
|
+
const files = requests.map((request) => {
|
|
111
|
+
try { return readFile(request, env); }
|
|
112
|
+
catch (error) { return { ok: false, path: String(request.path), error: { code: error.code || 'READ_FAILED', message: error.message || String(error) } }; }
|
|
113
|
+
});
|
|
114
|
+
const succeeded = files.filter((item) => item.ok).length;
|
|
115
|
+
return { ok: succeeded === files.length, count: files.length, succeeded, failed: files.length - succeeded, files };
|
|
116
|
+
};
|
|
117
|
+
|
|
104
118
|
const globFiles = (args, env) => {
|
|
105
119
|
const root = resolveAllowed(args.path, env);
|
|
106
120
|
const rx = wildcard(args.pattern || '*');
|
|
@@ -133,13 +147,25 @@ const grepFiles = (args, env) => {
|
|
|
133
147
|
return { ok: true, path: root, pattern: args.pattern, matches };
|
|
134
148
|
};
|
|
135
149
|
|
|
136
|
-
const handlers = { listDirectory, getFileInfo, readFile, globFiles, grepFiles };
|
|
150
|
+
const handlers = { listDirectory, getFileInfo, readFile, readFiles, globFiles, grepFiles };
|
|
151
|
+
|
|
152
|
+
const schemaObject = (properties, required = []) => ({ type: 'object', properties, required });
|
|
153
|
+
const toolSchemas = [
|
|
154
|
+
{ name: 'listDirectory', description: 'List files and folders inside ZERO_AGENT_ROOTS.', inputSchema: schemaObject({ path: { type: 'string' }, depth: { type: 'number' } }, ['path']) },
|
|
155
|
+
{ name: 'getFileInfo', description: 'Get metadata for a file or directory inside ZERO_AGENT_ROOTS.', inputSchema: schemaObject({ path: { type: 'string' } }, ['path']) },
|
|
156
|
+
{ name: 'readFile', description: 'Read a UTF-8 text file inside ZERO_AGENT_ROOTS with line pagination.', inputSchema: schemaObject({ path: { type: 'string' }, offset: { type: 'number' }, length: { type: 'number' } }, ['path']) },
|
|
157
|
+
{ name: 'readFiles', description: 'Read multiple UTF-8 text files inside ZERO_AGENT_ROOTS. Accept paths[] or files[].', inputSchema: schemaObject({ paths: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 50 }, files: { type: 'array', minItems: 1, maxItems: 50, items: schemaObject({ path: { type: 'string' }, offset: { type: 'number' }, length: { type: 'number' } }, ['path']) }, offset: { type: 'number' }, length: { type: 'number' } }) },
|
|
158
|
+
{ name: 'globFiles', description: 'Find files by wildcard pattern inside ZERO_AGENT_ROOTS.', inputSchema: schemaObject({ path: { type: 'string' }, pattern: { type: 'string' }, maxResults: { type: 'number' } }, ['path']) },
|
|
159
|
+
{ name: 'grepFiles', description: 'Search text files inside ZERO_AGENT_ROOTS.', inputSchema: schemaObject({ path: { type: 'string' }, pattern: { type: 'string' }, literal: { type: 'boolean' }, filePattern: { type: 'string' }, maxResults: { type: 'number' } }, ['path', 'pattern']) }
|
|
160
|
+
];
|
|
137
161
|
|
|
138
|
-
|
|
162
|
+
const execute = (tool, args = {}, env = process.env) => {
|
|
139
163
|
const cleanTool = String(tool || '').replace(/^command\./, '');
|
|
140
164
|
const handler = handlers[cleanTool];
|
|
141
165
|
if (!handler) throw err('UNKNOWN_AGENT_TOOL', 'unknown or unsafe agent tool: ' + tool);
|
|
142
166
|
return handler(args, env);
|
|
143
167
|
};
|
|
168
|
+
const listTools = () => toolSchemas.map((tool) => ({ ...tool }));
|
|
144
169
|
|
|
145
|
-
|
|
170
|
+
const localTools = { execute, listTools, _private: { rootsFor, resolveAllowed, wildcard } };
|
|
171
|
+
Object.assign(exports, localTools);
|