@corenel/harness 0.1.0
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/compression.d.ts +11 -0
- package/dist/compression.d.ts.map +1 -0
- package/dist/compression.js +27 -0
- package/dist/compression.js.map +1 -0
- package/dist/conversation.d.ts +29 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/conversation.js +25 -0
- package/dist/conversation.js.map +1 -0
- package/dist/core/loop.d.ts +31 -0
- package/dist/core/loop.d.ts.map +1 -0
- package/dist/core/loop.js +237 -0
- package/dist/core/loop.js.map +1 -0
- package/dist/dag/executeNode.d.ts +41 -0
- package/dist/dag/executeNode.d.ts.map +1 -0
- package/dist/dag/executeNode.js +81 -0
- package/dist/dag/executeNode.js.map +1 -0
- package/dist/fileSchema.d.ts +7 -0
- package/dist/fileSchema.d.ts.map +1 -0
- package/dist/fileSchema.js +40 -0
- package/dist/fileSchema.js.map +1 -0
- package/dist/guardrail/builtins.d.ts +9 -0
- package/dist/guardrail/builtins.d.ts.map +1 -0
- package/dist/guardrail/builtins.js +61 -0
- package/dist/guardrail/builtins.js.map +1 -0
- package/dist/guardrail/glob.d.ts +3 -0
- package/dist/guardrail/glob.d.ts.map +1 -0
- package/dist/guardrail/glob.js +33 -0
- package/dist/guardrail/glob.js.map +1 -0
- package/dist/guardrail/guardrail.d.ts +25 -0
- package/dist/guardrail/guardrail.d.ts.map +1 -0
- package/dist/guardrail/guardrail.js +67 -0
- package/dist/guardrail/guardrail.js.map +1 -0
- package/dist/guardrail/index.d.ts +9 -0
- package/dist/guardrail/index.d.ts.map +1 -0
- package/dist/guardrail/index.js +11 -0
- package/dist/guardrail/index.js.map +1 -0
- package/dist/guardrail/permission-service.d.ts +53 -0
- package/dist/guardrail/permission-service.d.ts.map +1 -0
- package/dist/guardrail/permission-service.js +147 -0
- package/dist/guardrail/permission-service.js.map +1 -0
- package/dist/guardrail/serialize.d.ts +9 -0
- package/dist/guardrail/serialize.d.ts.map +1 -0
- package/dist/guardrail/serialize.js +53 -0
- package/dist/guardrail/serialize.js.map +1 -0
- package/dist/guardrail/store.d.ts +26 -0
- package/dist/guardrail/store.d.ts.map +1 -0
- package/dist/guardrail/store.js +109 -0
- package/dist/guardrail/store.js.map +1 -0
- package/dist/guardrail/validate.d.ts +8 -0
- package/dist/guardrail/validate.d.ts.map +1 -0
- package/dist/guardrail/validate.js +105 -0
- package/dist/guardrail/validate.js.map +1 -0
- package/dist/guards.d.ts +37 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +45 -0
- package/dist/guards.js.map +1 -0
- package/dist/log.d.ts +4 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +22 -0
- package/dist/log.js.map +1 -0
- package/dist/promptCompiler.d.ts +18 -0
- package/dist/promptCompiler.d.ts.map +1 -0
- package/dist/promptCompiler.js +11 -0
- package/dist/promptCompiler.js.map +1 -0
- package/dist/prompts/config.d.ts +63 -0
- package/dist/prompts/config.d.ts.map +1 -0
- package/dist/prompts/config.js +268 -0
- package/dist/prompts/config.js.map +1 -0
- package/dist/prompts/host.d.ts +30 -0
- package/dist/prompts/host.d.ts.map +1 -0
- package/dist/prompts/host.js +11 -0
- package/dist/prompts/host.js.map +1 -0
- package/dist/prompts/index.d.ts +50 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +105 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/library/defaults.generated.d.ts +2 -0
- package/dist/prompts/library/defaults.generated.d.ts.map +1 -0
- package/dist/prompts/library/defaults.generated.js +31 -0
- package/dist/prompts/library/defaults.generated.js.map +1 -0
- package/dist/prompts/library/index.d.ts +8 -0
- package/dist/prompts/library/index.d.ts.map +1 -0
- package/dist/prompts/library/index.js +28 -0
- package/dist/prompts/library/index.js.map +1 -0
- package/dist/providers/gateway.d.ts +58 -0
- package/dist/providers/gateway.d.ts.map +1 -0
- package/dist/providers/gateway.js +145 -0
- package/dist/providers/gateway.js.map +1 -0
- package/dist/services.d.ts +29 -0
- package/dist/services.d.ts.map +1 -0
- package/dist/services.js +22 -0
- package/dist/services.js.map +1 -0
- package/dist/sidecar/host.d.ts +69 -0
- package/dist/sidecar/host.d.ts.map +1 -0
- package/dist/sidecar/host.js +228 -0
- package/dist/sidecar/host.js.map +1 -0
- package/dist/sidecar/server.d.ts +42 -0
- package/dist/sidecar/server.d.ts.map +1 -0
- package/dist/sidecar/server.js +267 -0
- package/dist/sidecar/server.js.map +1 -0
- package/dist/skills.d.ts +39 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +216 -0
- package/dist/skills.js.map +1 -0
- package/dist/systemParts.d.ts +10 -0
- package/dist/systemParts.d.ts.map +1 -0
- package/dist/systemParts.js +21 -0
- package/dist/systemParts.js.map +1 -0
- package/dist/todos.d.ts +34 -0
- package/dist/todos.d.ts.map +1 -0
- package/dist/todos.js +112 -0
- package/dist/todos.js.map +1 -0
- package/dist/tools/builtins.d.ts +20 -0
- package/dist/tools/builtins.d.ts.map +1 -0
- package/dist/tools/builtins.js +335 -0
- package/dist/tools/builtins.js.map +1 -0
- package/dist/tools/files.d.ts +11 -0
- package/dist/tools/files.d.ts.map +1 -0
- package/dist/tools/files.js +161 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/http.d.ts +3 -0
- package/dist/tools/http.d.ts.map +1 -0
- package/dist/tools/http.js +71 -0
- package/dist/tools/http.js.map +1 -0
- package/dist/tools/namespaces.d.ts +27 -0
- package/dist/tools/namespaces.d.ts.map +1 -0
- package/dist/tools/namespaces.js +83 -0
- package/dist/tools/namespaces.js.map +1 -0
- package/dist/tools/registry.d.ts +8 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +14 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/sessions.d.ts +3 -0
- package/dist/tools/sessions.d.ts.map +1 -0
- package/dist/tools/sessions.js +149 -0
- package/dist/tools/sessions.js.map +1 -0
- package/dist/tools/todo.d.ts +3 -0
- package/dist/tools/todo.d.ts.map +1 -0
- package/dist/tools/todo.js +38 -0
- package/dist/tools/todo.js.map +1 -0
- package/dist/tools/urlGuard.d.ts +9 -0
- package/dist/tools/urlGuard.d.ts.map +1 -0
- package/dist/tools/urlGuard.js +80 -0
- package/dist/tools/urlGuard.js.map +1 -0
- package/dist/tools/web.d.ts +3 -0
- package/dist/tools/web.d.ts.map +1 -0
- package/dist/tools/web.js +35 -0
- package/dist/tools/web.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
function str(args, key) {
|
|
2
|
+
const v = args[key];
|
|
3
|
+
return typeof v === 'string' ? v : v == null ? '' : String(v);
|
|
4
|
+
}
|
|
5
|
+
function requireFiles(ctx) {
|
|
6
|
+
if (!ctx.files)
|
|
7
|
+
throw new Error('No file workspace is connected.');
|
|
8
|
+
return ctx.files;
|
|
9
|
+
}
|
|
10
|
+
function flatten(nodes, out = []) {
|
|
11
|
+
for (const n of nodes) {
|
|
12
|
+
out.push(`${n.kind === 'directory' ? '[dir] ' : ''}${n.path}${n.kind === 'file' && n.size != null ? ` (${n.size}b)` : ''}`);
|
|
13
|
+
if (n.children?.length)
|
|
14
|
+
flatten(n.children, out);
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
export const listFilesTool = {
|
|
19
|
+
name: 'list_files',
|
|
20
|
+
description: 'List files and directories in the workspace (the open folder or the virtual workspace). ' +
|
|
21
|
+
'Optionally pass `dir` to list a subdirectory. Returns paths relative to the workspace root.',
|
|
22
|
+
parameters: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: { dir: { type: 'string', description: 'Subdirectory to list (optional; omit for the root).' } },
|
|
25
|
+
},
|
|
26
|
+
async run(args, ctx) {
|
|
27
|
+
const files = requireFiles(ctx);
|
|
28
|
+
const nodes = await files.list(str(args, 'dir') || undefined);
|
|
29
|
+
const lines = flatten(nodes);
|
|
30
|
+
return lines.length ? lines.join('\n') : '(empty)';
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
export const readFileTool = {
|
|
34
|
+
name: 'read_file',
|
|
35
|
+
description: 'Read a file from the workspace and return its UTF-8 text. Pass `path` relative to the workspace root.',
|
|
36
|
+
parameters: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
properties: { path: { type: 'string', description: 'File path, e.g. "prompts/base.prmd".' } },
|
|
39
|
+
required: ['path'],
|
|
40
|
+
},
|
|
41
|
+
async run(args, ctx) {
|
|
42
|
+
const files = requireFiles(ctx);
|
|
43
|
+
return files.read(str(args, 'path'));
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export const statFileTool = {
|
|
47
|
+
name: 'stat_file',
|
|
48
|
+
description: 'Check whether a path exists in the workspace and whether it is a file or directory.',
|
|
49
|
+
parameters: {
|
|
50
|
+
type: 'object',
|
|
51
|
+
properties: { path: { type: 'string', description: 'Path to check.' } },
|
|
52
|
+
required: ['path'],
|
|
53
|
+
},
|
|
54
|
+
async run(args, ctx) {
|
|
55
|
+
const files = requireFiles(ctx);
|
|
56
|
+
const s = await files.stat(str(args, 'path'));
|
|
57
|
+
if (!s)
|
|
58
|
+
return `Not found: ${str(args, 'path')}`;
|
|
59
|
+
return `${s.kind} — ${s.path}${s.kind === 'file' ? ` (${s.size}b)` : ''}`;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
export const searchFilesTool = {
|
|
63
|
+
name: 'search_files',
|
|
64
|
+
description: 'Find files in the workspace whose path or contents contain a query (case-insensitive).',
|
|
65
|
+
parameters: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: { query: { type: 'string', description: 'Text to search for.' } },
|
|
68
|
+
required: ['query'],
|
|
69
|
+
},
|
|
70
|
+
async run(args, ctx) {
|
|
71
|
+
const files = requireFiles(ctx);
|
|
72
|
+
const hits = await files.search(str(args, 'query'));
|
|
73
|
+
return hits.length ? hits.join('\n') : 'No matches.';
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
export const writeFileTool = {
|
|
77
|
+
name: 'write_file',
|
|
78
|
+
mutates: true,
|
|
79
|
+
description: 'Overwrite (or create) a file in the workspace with the given full content. ' +
|
|
80
|
+
'Provide the COMPLETE new content, not a patch. Use `path` relative to the workspace root.',
|
|
81
|
+
parameters: {
|
|
82
|
+
type: 'object',
|
|
83
|
+
properties: {
|
|
84
|
+
path: { type: 'string', description: 'File path to write.' },
|
|
85
|
+
content: { type: 'string', description: 'The full file content.' },
|
|
86
|
+
},
|
|
87
|
+
required: ['path', 'content'],
|
|
88
|
+
},
|
|
89
|
+
async run(args, ctx) {
|
|
90
|
+
const files = requireFiles(ctx);
|
|
91
|
+
const path = str(args, 'path');
|
|
92
|
+
await files.write(path, str(args, 'content'));
|
|
93
|
+
return `Wrote ${path}.`;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
export const createFileTool = {
|
|
97
|
+
name: 'create_file',
|
|
98
|
+
mutates: true,
|
|
99
|
+
description: 'Create a new file in the workspace. Fails if it already exists (use write_file to overwrite).',
|
|
100
|
+
parameters: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
path: { type: 'string', description: 'New file path.' },
|
|
104
|
+
content: { type: 'string', description: 'Initial content (optional).' },
|
|
105
|
+
},
|
|
106
|
+
required: ['path'],
|
|
107
|
+
},
|
|
108
|
+
async run(args, ctx) {
|
|
109
|
+
const files = requireFiles(ctx);
|
|
110
|
+
const path = str(args, 'path');
|
|
111
|
+
await files.create(path, str(args, 'content'));
|
|
112
|
+
return `Created ${path}.`;
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
export const deleteFileTool = {
|
|
116
|
+
name: 'delete_file',
|
|
117
|
+
mutates: true,
|
|
118
|
+
description: 'Delete a file or directory (recursive) from the workspace.',
|
|
119
|
+
parameters: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
properties: { path: { type: 'string', description: 'Path to delete.' } },
|
|
122
|
+
required: ['path'],
|
|
123
|
+
},
|
|
124
|
+
async run(args, ctx) {
|
|
125
|
+
const files = requireFiles(ctx);
|
|
126
|
+
const path = str(args, 'path');
|
|
127
|
+
await files.remove(path);
|
|
128
|
+
return `Deleted ${path}.`;
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
export const renameFileTool = {
|
|
132
|
+
name: 'rename_file',
|
|
133
|
+
mutates: true,
|
|
134
|
+
description: 'Move or rename a file (or directory) within the workspace.',
|
|
135
|
+
parameters: {
|
|
136
|
+
type: 'object',
|
|
137
|
+
properties: {
|
|
138
|
+
from: { type: 'string', description: 'Current path.' },
|
|
139
|
+
to: { type: 'string', description: 'New path.' },
|
|
140
|
+
},
|
|
141
|
+
required: ['from', 'to'],
|
|
142
|
+
},
|
|
143
|
+
async run(args, ctx) {
|
|
144
|
+
const files = requireFiles(ctx);
|
|
145
|
+
const from = str(args, 'from');
|
|
146
|
+
const to = str(args, 'to');
|
|
147
|
+
await files.rename(from, to);
|
|
148
|
+
return `Renamed ${from} -> ${to}.`;
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
export const fileTools = [
|
|
152
|
+
listFilesTool,
|
|
153
|
+
readFileTool,
|
|
154
|
+
statFileTool,
|
|
155
|
+
searchFilesTool,
|
|
156
|
+
writeFileTool,
|
|
157
|
+
createFileTool,
|
|
158
|
+
deleteFileTool,
|
|
159
|
+
renameFileTool,
|
|
160
|
+
];
|
|
161
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../tools/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../tools/http.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAYnD,eAAO,MAAM,cAAc,EAAE,SA0D5B,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { outboundUrlError, safeFetch } from './urlGuard';
|
|
2
|
+
function str(args, key) {
|
|
3
|
+
const v = args[key];
|
|
4
|
+
return typeof v === 'string' ? v : v == null ? '' : String(v);
|
|
5
|
+
}
|
|
6
|
+
const METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD']);
|
|
7
|
+
/** Cap the body we feed back to the model so a large response can't blow context. */
|
|
8
|
+
const MAX_BODY = 16000;
|
|
9
|
+
export const apiRequestTool = {
|
|
10
|
+
name: 'api_request',
|
|
11
|
+
mutates: true,
|
|
12
|
+
description: 'Make an HTTP request to a URL and return the status and response body. Supply `url` (required), ' +
|
|
13
|
+
'optional `method` (GET by default), `headers` (object), and `body` (a string, or an object that is ' +
|
|
14
|
+
'JSON-encoded). Use for calling REST APIs and webhooks. NOTE: in the browser this is subject to CORS — ' +
|
|
15
|
+
'cross-origin endpoints without permissive CORS headers will fail.',
|
|
16
|
+
parameters: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
url: { type: 'string', description: 'The full request URL (https://…).' },
|
|
20
|
+
method: { type: 'string', description: 'HTTP method: GET (default), POST, PUT, PATCH, DELETE, HEAD.' },
|
|
21
|
+
headers: { type: 'object', description: 'Request headers as a flat string map.', additionalProperties: { type: 'string' } },
|
|
22
|
+
body: { type: 'string', description: 'Request body. A string is sent verbatim; an object is JSON-encoded (with a JSON content-type).' },
|
|
23
|
+
},
|
|
24
|
+
required: ['url'],
|
|
25
|
+
},
|
|
26
|
+
async run(args, ctx) {
|
|
27
|
+
const url = str(args, 'url').trim();
|
|
28
|
+
if (!url)
|
|
29
|
+
return 'Error: `url` is required.';
|
|
30
|
+
// SSRF guard: http(s) only, and never an internal/loopback/metadata host. The
|
|
31
|
+
// same check re-runs on every redirect hop inside safeFetch.
|
|
32
|
+
const bad = outboundUrlError(url);
|
|
33
|
+
if (bad)
|
|
34
|
+
return `Error: ${bad}.`;
|
|
35
|
+
const method = (str(args, 'method').toUpperCase() || 'GET');
|
|
36
|
+
if (!METHODS.has(method))
|
|
37
|
+
return `Error: unsupported method "${method}".`;
|
|
38
|
+
const headers = {};
|
|
39
|
+
if (args.headers && typeof args.headers === 'object') {
|
|
40
|
+
for (const [k, v] of Object.entries(args.headers))
|
|
41
|
+
headers[k] = v == null ? '' : String(v);
|
|
42
|
+
}
|
|
43
|
+
// body: a string is sent as-is; an object is JSON-encoded. GET/HEAD carry none.
|
|
44
|
+
let body;
|
|
45
|
+
if (method !== 'GET' && method !== 'HEAD' && args.body != null) {
|
|
46
|
+
if (typeof args.body === 'string') {
|
|
47
|
+
body = args.body;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
body = JSON.stringify(args.body);
|
|
51
|
+
if (!Object.keys(headers).some((h) => h.toLowerCase() === 'content-type'))
|
|
52
|
+
headers['Content-Type'] = 'application/json';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const res = await safeFetch(url, { method, headers, body, signal: ctx.signal });
|
|
57
|
+
const text = await res.text();
|
|
58
|
+
const clipped = text.length > MAX_BODY ? `${text.slice(0, MAX_BODY)}\n…[truncated ${text.length - MAX_BODY} chars]` : text;
|
|
59
|
+
return `HTTP ${res.status} ${res.statusText}\n\n${clipped || '(empty body)'}`;
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
const msg = String(e?.message || e);
|
|
63
|
+
// The browser reports a CORS/network failure as an opaque "Failed to fetch" —
|
|
64
|
+
// name the likely cause so the user isn't left guessing.
|
|
65
|
+
return /failed to fetch|networkerror/i.test(msg)
|
|
66
|
+
? `Request failed: ${msg}. In the browser this is usually CORS or an unreachable host.`
|
|
67
|
+
: `Request failed: ${msg}`;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../tools/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type ToolNamespace = 'fs' | 'prompd' | 'web' | 'memory' | 'agent' | 'shell' | 'system' | 'mcp' | 'skill' | 'other';
|
|
2
|
+
/** Display order + labels for the namespaces (capabilities panel grouping). */
|
|
3
|
+
export declare const NAMESPACE_LABELS: {
|
|
4
|
+
ns: ToolNamespace;
|
|
5
|
+
label: string;
|
|
6
|
+
}[];
|
|
7
|
+
/** Minimal shape needed to namespace a tool — a subset of AgentTool. */
|
|
8
|
+
export interface NamespacedTool {
|
|
9
|
+
name: string;
|
|
10
|
+
/** Explicit override (dynamic tools set this); otherwise resolved by name. */
|
|
11
|
+
namespace?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Resolve a tool's namespace: explicit field > built-in table > wire prefix > 'other'. */
|
|
14
|
+
export declare function resolveNamespace(tool: NamespacedTool): ToolNamespace;
|
|
15
|
+
/** The policy-facing address `namespace:leaf`. For mcp/skill the redundant wire
|
|
16
|
+
* prefix is stripped — both the `mcp__server__x` convention and the actual
|
|
17
|
+
* `mcp_x` wire names loadMcpTools produces (mcp__github__x -> mcp:github__x,
|
|
18
|
+
* mcp_create_issue -> mcp:create_issue). */
|
|
19
|
+
export declare function toolAddress(tool: NamespacedTool): string;
|
|
20
|
+
/** Candidate strings a policy glob may target for this tool: its address and its
|
|
21
|
+
* bare wire name (so both `fs:write_file` and legacy `write_file` match). */
|
|
22
|
+
export declare function toolGlobTargets(tool: NamespacedTool): string[];
|
|
23
|
+
/** True if any glob matches the tool by address or bare name. */
|
|
24
|
+
export declare function toolMatchesAnyGlob(tool: NamespacedTool, globs: readonly string[]): boolean;
|
|
25
|
+
/** Namespace-wildcard address (`fs:*`) — the "whole namespace" policy target. */
|
|
26
|
+
export declare function namespaceGlob(ns: ToolNamespace): string;
|
|
27
|
+
//# sourceMappingURL=namespaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespaces.d.ts","sourceRoot":"","sources":["../../tools/namespaces.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,aAAa,GACrB,IAAI,GACJ,QAAQ,GACR,KAAK,GACL,QAAQ,GACR,OAAO,GACP,OAAO,GACP,QAAQ,GACR,KAAK,GACL,OAAO,GACP,OAAO,CAAC;AAEZ,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAWlE,CAAC;AAcF,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,aAAa,CAUpE;AAED;;;4CAG4C;AAC5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAQxD;AAED;6EAC6E;AAC7E,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAE9D;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAI1F;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAEvD"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* Tool namespacing — the single source of truth for which namespace a tool
|
|
2
|
+
* belongs to, and the policy-addressing scheme built on top of it.
|
|
3
|
+
*
|
|
4
|
+
* Wire names (what the model calls) must match /^[a-zA-Z0-9_-]{1,64}$/, so the
|
|
5
|
+
* namespace is NOT part of the wire name — it is a policy/UI/authoring address:
|
|
6
|
+
* wire name write_file (sent to the model)
|
|
7
|
+
* address fs:write_file (used in policy globs + completions)
|
|
8
|
+
* Dynamic tools carry a wire prefix instead (mcp__server__tool, skill__name);
|
|
9
|
+
* their address strips the prefix to read mcp:server__tool / skill:name.
|
|
10
|
+
*
|
|
11
|
+
* Policy globs may target a whole namespace (fs:*) or one tool (fs:write_file),
|
|
12
|
+
* and legacy bare-name globs (write_file) still match for back-compat. */
|
|
13
|
+
import { matchesAnyGlob } from '../guardrail/glob';
|
|
14
|
+
/** Display order + labels for the namespaces (capabilities panel grouping). */
|
|
15
|
+
export const NAMESPACE_LABELS = [
|
|
16
|
+
{ ns: 'fs', label: 'Files' },
|
|
17
|
+
{ ns: 'prompd', label: 'Prompd' },
|
|
18
|
+
{ ns: 'web', label: 'Web' },
|
|
19
|
+
{ ns: 'memory', label: 'Memory' },
|
|
20
|
+
{ ns: 'agent', label: 'Agent' },
|
|
21
|
+
{ ns: 'shell', label: 'Shell' },
|
|
22
|
+
{ ns: 'system', label: 'System' },
|
|
23
|
+
{ ns: 'mcp', label: 'MCP' },
|
|
24
|
+
{ ns: 'skill', label: 'Skills' },
|
|
25
|
+
{ ns: 'other', label: 'Other' },
|
|
26
|
+
];
|
|
27
|
+
/** Canonical namespace for every built-in tool. Dynamic tools (mcp/skill) are
|
|
28
|
+
* resolved from their wire prefix, not this table. */
|
|
29
|
+
const BUILTIN_NAMESPACES = {
|
|
30
|
+
list_files: 'fs', read_file: 'fs', stat_file: 'fs', search_files: 'fs',
|
|
31
|
+
write_file: 'fs', create_file: 'fs', delete_file: 'fs', rename_file: 'fs',
|
|
32
|
+
compile_prompd: 'prompd', propose_edit: 'prompd', search_packages: 'prompd',
|
|
33
|
+
web_search: 'web',
|
|
34
|
+
save_memory: 'memory', recall_memory: 'memory', recall_result: 'memory',
|
|
35
|
+
kv_get: 'memory', kv_set: 'memory', search_sessions: 'memory',
|
|
36
|
+
ask_user: 'agent', spawn_agent: 'agent', spawn_agents: 'agent', todo_write: 'agent',
|
|
37
|
+
};
|
|
38
|
+
/** Resolve a tool's namespace: explicit field > built-in table > wire prefix > 'other'. */
|
|
39
|
+
export function resolveNamespace(tool) {
|
|
40
|
+
if (tool.namespace)
|
|
41
|
+
return tool.namespace;
|
|
42
|
+
const known = BUILTIN_NAMESPACES[tool.name];
|
|
43
|
+
if (known)
|
|
44
|
+
return known;
|
|
45
|
+
const i = tool.name.indexOf('__');
|
|
46
|
+
if (i > 0) {
|
|
47
|
+
const head = tool.name.slice(0, i);
|
|
48
|
+
if (head === 'mcp' || head === 'skill')
|
|
49
|
+
return head;
|
|
50
|
+
}
|
|
51
|
+
return 'other';
|
|
52
|
+
}
|
|
53
|
+
/** The policy-facing address `namespace:leaf`. For mcp/skill the redundant wire
|
|
54
|
+
* prefix is stripped — both the `mcp__server__x` convention and the actual
|
|
55
|
+
* `mcp_x` wire names loadMcpTools produces (mcp__github__x -> mcp:github__x,
|
|
56
|
+
* mcp_create_issue -> mcp:create_issue). */
|
|
57
|
+
export function toolAddress(tool) {
|
|
58
|
+
const ns = resolveNamespace(tool);
|
|
59
|
+
let leaf = tool.name;
|
|
60
|
+
if (ns === 'mcp' || ns === 'skill') {
|
|
61
|
+
const m = new RegExp(`^${ns}__?`).exec(leaf); // `mcp__` or `mcp_`
|
|
62
|
+
if (m)
|
|
63
|
+
leaf = leaf.slice(m[0].length);
|
|
64
|
+
}
|
|
65
|
+
return `${ns}:${leaf}`;
|
|
66
|
+
}
|
|
67
|
+
/** Candidate strings a policy glob may target for this tool: its address and its
|
|
68
|
+
* bare wire name (so both `fs:write_file` and legacy `write_file` match). */
|
|
69
|
+
export function toolGlobTargets(tool) {
|
|
70
|
+
return [toolAddress(tool), tool.name];
|
|
71
|
+
}
|
|
72
|
+
/** True if any glob matches the tool by address or bare name. */
|
|
73
|
+
export function toolMatchesAnyGlob(tool, globs) {
|
|
74
|
+
if (!globs.length)
|
|
75
|
+
return false;
|
|
76
|
+
const targets = toolGlobTargets(tool);
|
|
77
|
+
return globs.some((g) => matchesAnyGlob(targets[0], [g]) || matchesAnyGlob(targets[1], [g]));
|
|
78
|
+
}
|
|
79
|
+
/** Namespace-wildcard address (`fs:*`) — the "whole namespace" policy target. */
|
|
80
|
+
export function namespaceGlob(ns) {
|
|
81
|
+
return `${ns}:*`;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=namespaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"namespaces.js","sourceRoot":"","sources":["../../tools/namespaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentTool } from '@corenel/protocol';
|
|
2
|
+
/** Register (or replace) an extension tool by name. */
|
|
3
|
+
export declare function registerTool(tool: AgentTool): void;
|
|
4
|
+
/** Remove an extension tool (used by tests and dynamic providers). */
|
|
5
|
+
export declare function unregisterTool(name: string): void;
|
|
6
|
+
/** Host-registered extension tools, in registration order. */
|
|
7
|
+
export declare function extensionTools(): AgentTool[];
|
|
8
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../tools/registry.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAInD,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAElD;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,8DAA8D;AAC9D,wBAAgB,cAAc,IAAI,SAAS,EAAE,CAE5C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const registry = new Map();
|
|
2
|
+
/** Register (or replace) an extension tool by name. */
|
|
3
|
+
export function registerTool(tool) {
|
|
4
|
+
registry.set(tool.name, tool);
|
|
5
|
+
}
|
|
6
|
+
/** Remove an extension tool (used by tests and dynamic providers). */
|
|
7
|
+
export function unregisterTool(name) {
|
|
8
|
+
registry.delete(name);
|
|
9
|
+
}
|
|
10
|
+
/** Host-registered extension tools, in registration order. */
|
|
11
|
+
export function extensionTools() {
|
|
12
|
+
return [...registry.values()];
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../tools/registry.ts"],"names":[],"mappings":"AAYA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE9C,uDAAuD;AACvD,MAAM,UAAU,YAAY,CAAC,IAAe;IAC1C,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../tools/sessions.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AA2EnD,eAAO,MAAM,kBAAkB,EAAE,SA0DhC,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
function str(args, key) {
|
|
2
|
+
const v = args[key];
|
|
3
|
+
return typeof v === 'string' ? v : v == null ? '' : String(v);
|
|
4
|
+
}
|
|
5
|
+
function clamp(n, lo, hi) {
|
|
6
|
+
return Number.isFinite(n) ? Math.min(hi, Math.max(lo, Math.round(n))) : lo;
|
|
7
|
+
}
|
|
8
|
+
/** Text of one (possibly multimodal) message content. */
|
|
9
|
+
function messageText(content) {
|
|
10
|
+
if (typeof content === 'string')
|
|
11
|
+
return content;
|
|
12
|
+
if (Array.isArray(content)) {
|
|
13
|
+
return content
|
|
14
|
+
.map((p) => (p && typeof p === 'object' && p.type === 'text' && typeof p.text === 'string' ? p.text : ''))
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.join(' ');
|
|
17
|
+
}
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
/** Flatten a session's stored messages to {role,text}. Sessions persist as
|
|
21
|
+
* ConversationTurn[] (each turn wraps `messages`); older/other shapes may be a
|
|
22
|
+
* flat ChatCompletionMessageParam[] — handle both. Only user/assistant text. */
|
|
23
|
+
function extractMessages(raw) {
|
|
24
|
+
const out = [];
|
|
25
|
+
const walk = (items) => {
|
|
26
|
+
if (!Array.isArray(items))
|
|
27
|
+
return;
|
|
28
|
+
for (const item of items) {
|
|
29
|
+
if (!item || typeof item !== 'object')
|
|
30
|
+
continue;
|
|
31
|
+
const o = item;
|
|
32
|
+
if (Array.isArray(o.messages)) {
|
|
33
|
+
walk(o.messages);
|
|
34
|
+
continue;
|
|
35
|
+
} // ConversationTurn
|
|
36
|
+
const role = typeof o.role === 'string' ? o.role : '';
|
|
37
|
+
if (role !== 'user' && role !== 'assistant')
|
|
38
|
+
continue;
|
|
39
|
+
const text = messageText(o.content).trim();
|
|
40
|
+
if (text)
|
|
41
|
+
out.push({ role, text });
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
walk(raw);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
function occurrences(haystack, needle) {
|
|
48
|
+
if (!needle)
|
|
49
|
+
return 0;
|
|
50
|
+
return haystack.split(needle).length - 1;
|
|
51
|
+
}
|
|
52
|
+
/** A ~160-char window around the first matching term. */
|
|
53
|
+
function snippet(text, terms) {
|
|
54
|
+
const lower = text.toLowerCase();
|
|
55
|
+
let idx = -1;
|
|
56
|
+
for (const t of terms) {
|
|
57
|
+
const i = lower.indexOf(t);
|
|
58
|
+
if (i >= 0 && (idx < 0 || i < idx))
|
|
59
|
+
idx = i;
|
|
60
|
+
}
|
|
61
|
+
if (idx < 0)
|
|
62
|
+
idx = 0;
|
|
63
|
+
const start = Math.max(0, idx - 60);
|
|
64
|
+
const end = Math.min(text.length, idx + 100);
|
|
65
|
+
let s = text.slice(start, end).replace(/\s+/g, ' ').trim();
|
|
66
|
+
if (start > 0)
|
|
67
|
+
s = `…${s}`;
|
|
68
|
+
if (end < text.length)
|
|
69
|
+
s = `${s}…`;
|
|
70
|
+
return s;
|
|
71
|
+
}
|
|
72
|
+
function relTime(ts, now) {
|
|
73
|
+
const s = Math.max(0, Math.floor((now - ts) / 1000));
|
|
74
|
+
if (s < 60)
|
|
75
|
+
return 'just now';
|
|
76
|
+
const m = Math.floor(s / 60);
|
|
77
|
+
if (m < 60)
|
|
78
|
+
return `${m} minute${m > 1 ? 's' : ''} ago`;
|
|
79
|
+
const h = Math.floor(m / 60);
|
|
80
|
+
if (h < 24)
|
|
81
|
+
return `${h} hour${h > 1 ? 's' : ''} ago`;
|
|
82
|
+
const d = Math.floor(h / 24);
|
|
83
|
+
if (d < 30)
|
|
84
|
+
return `${d} day${d > 1 ? 's' : ''} ago`;
|
|
85
|
+
const mo = Math.floor(d / 30);
|
|
86
|
+
if (mo < 12)
|
|
87
|
+
return `${mo} month${mo > 1 ? 's' : ''} ago`;
|
|
88
|
+
const y = Math.floor(mo / 12);
|
|
89
|
+
return `${y} year${y > 1 ? 's' : ''} ago`;
|
|
90
|
+
}
|
|
91
|
+
export const searchSessionsTool = {
|
|
92
|
+
name: 'search_sessions',
|
|
93
|
+
noOffload: true, // results are short snippets the user asked to recall — keep inline
|
|
94
|
+
description: "Search the user's previous chat sessions (this app's saved conversations, for the signed-in user) by keyword. " +
|
|
95
|
+
'Use it to recall what was discussed or decided in an earlier chat — when the user says things like "like we ' +
|
|
96
|
+
'set up before", "what did we decide about X", or "continue from yesterday". Returns the best-matching sessions ' +
|
|
97
|
+
'with their title, how long ago, and short snippets showing where the words appear, plus a session id. ' +
|
|
98
|
+
'It does NOT search the workspace files (use search_files) or saved memory notes (use recall_memory).',
|
|
99
|
+
parameters: {
|
|
100
|
+
type: 'object',
|
|
101
|
+
properties: {
|
|
102
|
+
query: { type: 'string', description: 'Keywords to look for across past session titles and messages.' },
|
|
103
|
+
limit: { type: 'number', description: 'Max sessions to return (default 5, max 15).' },
|
|
104
|
+
},
|
|
105
|
+
required: ['query'],
|
|
106
|
+
},
|
|
107
|
+
async run(args, ctx) {
|
|
108
|
+
if (!ctx.sessions)
|
|
109
|
+
return 'Session history is unavailable in this environment.';
|
|
110
|
+
const query = str(args, 'query').trim();
|
|
111
|
+
if (!query)
|
|
112
|
+
return 'Provide a non-empty `query`.';
|
|
113
|
+
const limit = clamp(Number(args.limit) || 5, 1, 15);
|
|
114
|
+
const terms = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
115
|
+
const all = await ctx.sessions.list();
|
|
116
|
+
const now = Date.now();
|
|
117
|
+
const scored = all
|
|
118
|
+
.map((s) => {
|
|
119
|
+
const msgs = extractMessages(s.messages);
|
|
120
|
+
if (!msgs.length)
|
|
121
|
+
return null; // skip empty/placeholder chats
|
|
122
|
+
const title = s.title || 'Untitled';
|
|
123
|
+
const titleLower = title.toLowerCase();
|
|
124
|
+
const hay = `${title} ${msgs.map((m) => m.text).join(' ')}`.toLowerCase();
|
|
125
|
+
let score = 0;
|
|
126
|
+
for (const t of terms) {
|
|
127
|
+
if (titleLower.includes(t))
|
|
128
|
+
score += 3;
|
|
129
|
+
score += occurrences(hay, t);
|
|
130
|
+
}
|
|
131
|
+
return score > 0 ? { s, title, msgs, score } : null;
|
|
132
|
+
})
|
|
133
|
+
.filter((x) => x !== null)
|
|
134
|
+
.sort((a, b) => b.score - a.score || b.s.updatedAt - a.s.updatedAt)
|
|
135
|
+
.slice(0, limit);
|
|
136
|
+
if (!scored.length)
|
|
137
|
+
return `No previous sessions match "${query}".`;
|
|
138
|
+
const blocks = scored.map(({ s, title, msgs }, i) => {
|
|
139
|
+
const surface = s.surface || 'agent';
|
|
140
|
+
const when = relTime(s.updatedAt || s.createdAt || now, now);
|
|
141
|
+
const hits = msgs.filter((m) => terms.some((t) => m.text.toLowerCase().includes(t))).slice(0, 2);
|
|
142
|
+
const shown = hits.length ? hits : msgs.slice(0, 1); // title-only match -> show the opener
|
|
143
|
+
const lines = shown.map((m) => ` ${m.role}: "${snippet(m.text, terms)}"`);
|
|
144
|
+
return [`${i + 1}. "${title}" · ${surface} · ${when}`, ` id: ${s.id}`, ...lines].join('\n');
|
|
145
|
+
});
|
|
146
|
+
return `Found ${scored.length} previous session${scored.length > 1 ? 's' : ''} matching "${query}":\n\n${blocks.join('\n\n')}`;
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../tools/sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo.d.ts","sourceRoot":"","sources":["../../tools/todo.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,eAAO,MAAM,aAAa,EAAE,SAqC3B,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const todoWriteTool = {
|
|
2
|
+
name: 'todo_write',
|
|
3
|
+
noOffload: true, // the task list is what the user wants to see — keep it inline
|
|
4
|
+
description: 'Maintain a visible task list for a multi-step job. Pass the COMPLETE list each time (a rewrite). ' +
|
|
5
|
+
'Keep exactly one task "in_progress" while you work it; mark tasks "completed" as you finish; use ' +
|
|
6
|
+
'"blocked" + blockedBy for tasks waiting on others; nest a subtask one level with parentId. Reuse a ' +
|
|
7
|
+
'short stable id per task across updates so its progress and activity persist. Call it when you start ' +
|
|
8
|
+
'a multi-step task and after each meaningful step.',
|
|
9
|
+
parameters: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
todos: {
|
|
13
|
+
type: 'array',
|
|
14
|
+
description: 'The complete task list, in execution order.',
|
|
15
|
+
items: {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
id: { type: 'string', description: 'Stable short id, reused across updates (e.g. "auth").' },
|
|
19
|
+
title: { type: 'string', description: 'Concise, imperative (e.g. "Wire the routes").' },
|
|
20
|
+
status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'blocked'] },
|
|
21
|
+
note: { type: 'string', description: 'Optional one-line detail.' },
|
|
22
|
+
blockedBy: { type: 'array', items: { type: 'string' }, description: 'Task ids this one waits on.' },
|
|
23
|
+
parentId: { type: 'string', description: 'Parent task id for a subtask (one level deep).' },
|
|
24
|
+
},
|
|
25
|
+
required: ['id', 'title', 'status'],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
required: ['todos'],
|
|
30
|
+
},
|
|
31
|
+
async run(args) {
|
|
32
|
+
const todos = Array.isArray(args.todos) ? args.todos : [];
|
|
33
|
+
const done = todos.filter((t) => String(t?.status) === 'completed').length;
|
|
34
|
+
const active = todos.find((t) => String(t?.status) === 'in_progress');
|
|
35
|
+
return `Task list updated (${done}/${todos.length} done${active ? `, now: ${active.title}` : ''}).`;
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=todo.js.map
|