@push.rocks/smartagent 1.7.0 → 3.0.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.
Files changed (81) hide show
  1. package/dist_ts/00_commitinfo_data.js +3 -3
  2. package/dist_ts/index.d.ts +9 -12
  3. package/dist_ts/index.js +9 -20
  4. package/dist_ts/plugins.d.ts +8 -9
  5. package/dist_ts/plugins.js +10 -12
  6. package/dist_ts/smartagent.classes.agent.d.ts +2 -0
  7. package/dist_ts/smartagent.classes.agent.js +173 -0
  8. package/dist_ts/smartagent.classes.toolregistry.d.ts +12 -0
  9. package/dist_ts/smartagent.classes.toolregistry.js +17 -0
  10. package/dist_ts/smartagent.interfaces.d.ts +47 -231
  11. package/dist_ts/smartagent.interfaces.js +6 -7
  12. package/dist_ts/smartagent.utils.truncation.d.ts +10 -0
  13. package/dist_ts/smartagent.utils.truncation.js +26 -0
  14. package/dist_ts_compaction/index.d.ts +1 -0
  15. package/dist_ts_compaction/index.js +2 -0
  16. package/dist_ts_compaction/plugins.d.ts +4 -0
  17. package/dist_ts_compaction/plugins.js +3 -0
  18. package/dist_ts_compaction/smartagent.compaction.d.ts +10 -0
  19. package/dist_ts_compaction/smartagent.compaction.js +46 -0
  20. package/dist_ts_tools/index.d.ts +8 -0
  21. package/dist_ts_tools/index.js +6 -0
  22. package/dist_ts_tools/plugins.d.ts +15 -0
  23. package/dist_ts_tools/plugins.js +19 -0
  24. package/dist_ts_tools/tool.filesystem.d.ts +6 -0
  25. package/dist_ts_tools/tool.filesystem.js +102 -0
  26. package/dist_ts_tools/tool.http.d.ts +2 -0
  27. package/dist_ts_tools/tool.http.js +65 -0
  28. package/dist_ts_tools/tool.json.d.ts +2 -0
  29. package/dist_ts_tools/tool.json.js +47 -0
  30. package/dist_ts_tools/tool.shell.d.ts +8 -0
  31. package/dist_ts_tools/tool.shell.js +40 -0
  32. package/npmextra.json +1 -1
  33. package/package.json +30 -18
  34. package/readme.hints.md +43 -42
  35. package/readme.md +257 -526
  36. package/ts/00_commitinfo_data.ts +2 -2
  37. package/ts/index.ts +11 -31
  38. package/ts/plugins.ts +22 -21
  39. package/ts/smartagent.classes.agent.ts +198 -0
  40. package/ts/smartagent.classes.toolregistry.ts +20 -0
  41. package/ts/smartagent.interfaces.ts +51 -303
  42. package/ts/smartagent.utils.truncation.ts +39 -0
  43. package/ts_compaction/index.ts +1 -0
  44. package/ts_compaction/plugins.ts +6 -0
  45. package/ts_compaction/smartagent.compaction.ts +51 -0
  46. package/ts_tools/index.ts +8 -0
  47. package/ts_tools/plugins.ts +30 -0
  48. package/ts_tools/tool.filesystem.ts +131 -0
  49. package/ts_tools/tool.http.ts +78 -0
  50. package/ts_tools/tool.json.ts +53 -0
  51. package/ts_tools/tool.shell.ts +62 -0
  52. package/dist_ts/smartagent.classes.driveragent.d.ts +0 -134
  53. package/dist_ts/smartagent.classes.driveragent.js +0 -671
  54. package/dist_ts/smartagent.classes.dualagent.d.ts +0 -79
  55. package/dist_ts/smartagent.classes.dualagent.js +0 -583
  56. package/dist_ts/smartagent.classes.guardianagent.d.ts +0 -46
  57. package/dist_ts/smartagent.classes.guardianagent.js +0 -201
  58. package/dist_ts/smartagent.tools.base.d.ts +0 -52
  59. package/dist_ts/smartagent.tools.base.js +0 -42
  60. package/dist_ts/smartagent.tools.browser.d.ts +0 -17
  61. package/dist_ts/smartagent.tools.browser.js +0 -229
  62. package/dist_ts/smartagent.tools.deno.d.ts +0 -21
  63. package/dist_ts/smartagent.tools.deno.js +0 -191
  64. package/dist_ts/smartagent.tools.filesystem.d.ts +0 -40
  65. package/dist_ts/smartagent.tools.filesystem.js +0 -801
  66. package/dist_ts/smartagent.tools.http.d.ts +0 -16
  67. package/dist_ts/smartagent.tools.http.js +0 -264
  68. package/dist_ts/smartagent.tools.json.d.ts +0 -24
  69. package/dist_ts/smartagent.tools.json.js +0 -202
  70. package/dist_ts/smartagent.tools.shell.d.ts +0 -17
  71. package/dist_ts/smartagent.tools.shell.js +0 -202
  72. package/ts/smartagent.classes.driveragent.ts +0 -775
  73. package/ts/smartagent.classes.dualagent.ts +0 -657
  74. package/ts/smartagent.classes.guardianagent.ts +0 -241
  75. package/ts/smartagent.tools.base.ts +0 -83
  76. package/ts/smartagent.tools.browser.ts +0 -253
  77. package/ts/smartagent.tools.deno.ts +0 -230
  78. package/ts/smartagent.tools.filesystem.ts +0 -885
  79. package/ts/smartagent.tools.http.ts +0 -283
  80. package/ts/smartagent.tools.json.ts +0 -224
  81. package/ts/smartagent.tools.shell.ts +0 -230
@@ -0,0 +1,10 @@
1
+ export interface ITruncateResult {
2
+ content: string;
3
+ truncated: boolean;
4
+ /** Set when truncated: describes what was dropped */
5
+ notice?: string;
6
+ }
7
+ export declare function truncateOutput(text: string, options?: {
8
+ maxLines?: number;
9
+ maxBytes?: number;
10
+ }): ITruncateResult;
@@ -0,0 +1,26 @@
1
+ // Truncation logic derived from opencode (MIT) — https://github.com/sst/opencode
2
+ const MAX_LINES = 2000;
3
+ const MAX_BYTES = 50 * 1024; // 50 KB
4
+ export function truncateOutput(text, options) {
5
+ const maxLines = options?.maxLines ?? MAX_LINES;
6
+ const maxBytes = options?.maxBytes ?? MAX_BYTES;
7
+ const lines = text.split('\n');
8
+ const totalBytes = Buffer.byteLength(text, 'utf-8');
9
+ if (lines.length <= maxLines && totalBytes <= maxBytes) {
10
+ return { content: text, truncated: false };
11
+ }
12
+ const out = [];
13
+ let bytes = 0;
14
+ for (let i = 0; i < lines.length && i < maxLines; i++) {
15
+ const size = Buffer.byteLength(lines[i], 'utf-8') + (i > 0 ? 1 : 0);
16
+ if (bytes + size > maxBytes)
17
+ break;
18
+ out.push(lines[i]);
19
+ bytes += size;
20
+ }
21
+ const kept = out.length;
22
+ const dropped = lines.length - kept;
23
+ const notice = `\n[Output truncated: showing ${kept}/${lines.length} lines. ${dropped} lines omitted.]`;
24
+ return { content: out.join('\n') + notice, truncated: true, notice };
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhZ2VudC51dGlscy50cnVuY2F0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhZ2VudC51dGlscy50cnVuY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlGQUFpRjtBQUVqRixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUM7QUFDdkIsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLFFBQVE7QUFTckMsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsSUFBWSxFQUNaLE9BQWtEO0lBRWxELE1BQU0sUUFBUSxHQUFHLE9BQU8sRUFBRSxRQUFRLElBQUksU0FBUyxDQUFDO0lBQ2hELE1BQU0sUUFBUSxHQUFHLE9BQU8sRUFBRSxRQUFRLElBQUksU0FBUyxDQUFDO0lBQ2hELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDL0IsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFFcEQsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLFFBQVEsSUFBSSxVQUFVLElBQUksUUFBUSxFQUFFLENBQUM7UUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQzdDLENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7SUFDekIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3RELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwRSxJQUFJLEtBQUssR0FBRyxJQUFJLEdBQUcsUUFBUTtZQUFFLE1BQU07UUFDbkMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQixLQUFLLElBQUksSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO0lBQ3hCLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3BDLE1BQU0sTUFBTSxHQUFHLGdDQUFnQyxJQUFJLElBQUksS0FBSyxDQUFDLE1BQU0sV0FBVyxPQUFPLGtCQUFrQixDQUFDO0lBQ3hHLE9BQU8sRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztBQUN2RSxDQUFDIn0=
@@ -0,0 +1 @@
1
+ export { compactMessages } from './smartagent.compaction.js';
@@ -0,0 +1,2 @@
1
+ export { compactMessages } from './smartagent.compaction.js';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19jb21wYWN0aW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQyJ9
@@ -0,0 +1,4 @@
1
+ import { generateText } from 'ai';
2
+ export { generateText };
3
+ export type { ModelMessage } from 'ai';
4
+ export type { LanguageModelV3 } from '@push.rocks/smartai';
@@ -0,0 +1,3 @@
1
+ import { generateText } from 'ai';
2
+ export { generateText };
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2NvbXBhY3Rpb24vcGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBRWxDLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQyJ9
@@ -0,0 +1,10 @@
1
+ import * as plugins from './plugins.js';
2
+ /**
3
+ * Compacts a message history into a summary.
4
+ * Pass this as the onContextOverflow handler in IAgentRunOptions.
5
+ *
6
+ * @param model The same model used by runAgent, or a cheaper small model
7
+ * @param messages The full message history that overflowed
8
+ * @returns A minimal ModelMessage[] containing the summary as context
9
+ */
10
+ export declare function compactMessages(model: plugins.LanguageModelV3, messages: plugins.ModelMessage[]): Promise<plugins.ModelMessage[]>;
@@ -0,0 +1,46 @@
1
+ import * as plugins from './plugins.js';
2
+ const COMPACTION_PROMPT = `Provide a detailed prompt for continuing our conversation above.
3
+ Focus on information that would be helpful for continuing the conversation, including what we did, what we're doing, which files we're working on, and what we're going to do next.
4
+ The summary that you construct will be used so that another agent can read it and continue the work.
5
+
6
+ When constructing the summary, try to stick to this template:
7
+ ---
8
+ ## Goal
9
+ [What goal(s) is the user trying to accomplish?]
10
+
11
+ ## Instructions
12
+ - [What important instructions did the user give you that are relevant]
13
+
14
+ ## Discoveries
15
+ [What notable things were learned during this conversation that would be useful for the next agent to know]
16
+
17
+ ## Accomplished
18
+ [What work has been completed, what work is still in progress, and what work is left?]
19
+
20
+ ## Relevant files / directories
21
+ [A structured list of relevant files that have been read, edited, or created]
22
+ ---`;
23
+ /**
24
+ * Compacts a message history into a summary.
25
+ * Pass this as the onContextOverflow handler in IAgentRunOptions.
26
+ *
27
+ * @param model The same model used by runAgent, or a cheaper small model
28
+ * @param messages The full message history that overflowed
29
+ * @returns A minimal ModelMessage[] containing the summary as context
30
+ */
31
+ export async function compactMessages(model, messages) {
32
+ const result = await plugins.generateText({
33
+ model,
34
+ messages: [
35
+ ...messages,
36
+ { role: 'user', content: COMPACTION_PROMPT },
37
+ ],
38
+ });
39
+ return [
40
+ {
41
+ role: 'user',
42
+ content: `[Previous conversation summary]\n\n${result.text}\n\n[End of summary. Continue from here.]`,
43
+ },
44
+ ];
45
+ }
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhZ2VudC5jb21wYWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfY29tcGFjdGlvbi9zbWFydGFnZW50LmNvbXBhY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFFeEMsTUFBTSxpQkFBaUIsR0FBRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFvQnRCLENBQUM7QUFFTDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxlQUFlLENBQ25DLEtBQThCLEVBQzlCLFFBQWdDO0lBRWhDLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLFlBQVksQ0FBQztRQUN4QyxLQUFLO1FBQ0wsUUFBUSxFQUFFO1lBQ1IsR0FBRyxRQUFRO1lBQ1gsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRTtTQUM3QztLQUNGLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTDtZQUNFLElBQUksRUFBRSxNQUFNO1lBQ1osT0FBTyxFQUFFLHNDQUFzQyxNQUFNLENBQUMsSUFBSSwyQ0FBMkM7U0FDdEc7S0FDRixDQUFDO0FBQ0osQ0FBQyJ9
@@ -0,0 +1,8 @@
1
+ export { filesystemTool } from './tool.filesystem.js';
2
+ export type { IFilesystemToolOptions } from './tool.filesystem.js';
3
+ export { shellTool } from './tool.shell.js';
4
+ export type { IShellToolOptions } from './tool.shell.js';
5
+ export { httpTool } from './tool.http.js';
6
+ export { jsonTool } from './tool.json.js';
7
+ export { truncateOutput } from './plugins.js';
8
+ export type { ITruncateResult } from './plugins.js';
@@ -0,0 +1,6 @@
1
+ export { filesystemTool } from './tool.filesystem.js';
2
+ export { shellTool } from './tool.shell.js';
3
+ export { httpTool } from './tool.http.js';
4
+ export { jsonTool } from './tool.json.js';
5
+ export { truncateOutput } from './plugins.js';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c190b29scy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFdEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGNBQWMsQ0FBQyJ9
@@ -0,0 +1,15 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs';
3
+ export { path, fs };
4
+ import { z } from 'zod';
5
+ export { z };
6
+ import { tool } from '@push.rocks/smartai';
7
+ export { tool };
8
+ export type { ToolSet } from 'ai';
9
+ import * as smartfs from '@push.rocks/smartfs';
10
+ import * as smartshell from '@push.rocks/smartshell';
11
+ import * as smartrequest from '@push.rocks/smartrequest';
12
+ export { smartfs, smartshell, smartrequest };
13
+ import { truncateOutput } from '../dist_ts/smartagent.utils.truncation.js';
14
+ export { truncateOutput };
15
+ export type { ITruncateResult } from '../dist_ts/smartagent.utils.truncation.js';
@@ -0,0 +1,19 @@
1
+ // node native
2
+ import * as path from 'path';
3
+ import * as fs from 'fs';
4
+ export { path, fs };
5
+ // zod
6
+ import { z } from 'zod';
7
+ export { z };
8
+ // ai-sdk
9
+ import { tool } from '@push.rocks/smartai';
10
+ export { tool };
11
+ // @push.rocks scope
12
+ import * as smartfs from '@push.rocks/smartfs';
13
+ import * as smartshell from '@push.rocks/smartshell';
14
+ import * as smartrequest from '@push.rocks/smartrequest';
15
+ export { smartfs, smartshell, smartrequest };
16
+ // cross-folder import
17
+ import { truncateOutput } from '../dist_ts/smartagent.utils.truncation.js';
18
+ export { truncateOutput };
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3Rvb2xzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYztBQUNkLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBRXpCLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFFcEIsTUFBTTtBQUNOLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFFeEIsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO0FBRWIsU0FBUztBQUNULE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFJaEIsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBRXpELE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxDQUFDO0FBRTdDLHNCQUFzQjtBQUN0QixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFFdEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxDQUFDIn0=
@@ -0,0 +1,6 @@
1
+ import * as plugins from './plugins.js';
2
+ export interface IFilesystemToolOptions {
3
+ /** Restrict file access to this directory. Default: process.cwd() */
4
+ rootDir?: string;
5
+ }
6
+ export declare function filesystemTool(options?: IFilesystemToolOptions): plugins.ToolSet;
@@ -0,0 +1,102 @@
1
+ import * as plugins from './plugins.js';
2
+ function validatePath(filePath, rootDir) {
3
+ const resolved = plugins.path.resolve(filePath);
4
+ if (rootDir) {
5
+ const resolvedRoot = plugins.path.resolve(rootDir);
6
+ if (!resolved.startsWith(resolvedRoot + plugins.path.sep) && resolved !== resolvedRoot) {
7
+ throw new Error(`Access denied: "${filePath}" is outside allowed root "${rootDir}"`);
8
+ }
9
+ }
10
+ return resolved;
11
+ }
12
+ export function filesystemTool(options) {
13
+ const rootDir = options?.rootDir;
14
+ return {
15
+ read_file: plugins.tool({
16
+ description: 'Read file contents. Returns the full text or a specified line range.',
17
+ inputSchema: plugins.z.object({
18
+ path: plugins.z.string().describe('Absolute path to the file'),
19
+ startLine: plugins.z
20
+ .number()
21
+ .optional()
22
+ .describe('First line (1-indexed, inclusive)'),
23
+ endLine: plugins.z
24
+ .number()
25
+ .optional()
26
+ .describe('Last line (1-indexed, inclusive)'),
27
+ }),
28
+ execute: async ({ path: filePath, startLine, endLine, }) => {
29
+ const resolved = validatePath(filePath, rootDir);
30
+ const content = plugins.fs.readFileSync(resolved, 'utf-8');
31
+ if (startLine !== undefined || endLine !== undefined) {
32
+ const lines = content.split('\n');
33
+ const start = (startLine ?? 1) - 1;
34
+ const end = endLine ?? lines.length;
35
+ const sliced = lines.slice(start, end).join('\n');
36
+ return plugins.truncateOutput(sliced).content;
37
+ }
38
+ return plugins.truncateOutput(content).content;
39
+ },
40
+ }),
41
+ write_file: plugins.tool({
42
+ description: 'Write content to a file (creates parent dirs if needed, overwrites existing).',
43
+ inputSchema: plugins.z.object({
44
+ path: plugins.z.string().describe('Absolute path to the file'),
45
+ content: plugins.z.string().describe('Content to write'),
46
+ }),
47
+ execute: async ({ path: filePath, content }) => {
48
+ const resolved = validatePath(filePath, rootDir);
49
+ const dir = plugins.path.dirname(resolved);
50
+ plugins.fs.mkdirSync(dir, { recursive: true });
51
+ plugins.fs.writeFileSync(resolved, content, 'utf-8');
52
+ return `Written ${content.length} characters to ${filePath}`;
53
+ },
54
+ }),
55
+ list_directory: plugins.tool({
56
+ description: 'List files and directories at the given path.',
57
+ inputSchema: plugins.z.object({
58
+ path: plugins.z.string().describe('Directory path to list'),
59
+ recursive: plugins.z
60
+ .boolean()
61
+ .optional()
62
+ .describe('List recursively (default: false)'),
63
+ }),
64
+ execute: async ({ path: dirPath, recursive, }) => {
65
+ const resolved = validatePath(dirPath, rootDir);
66
+ function listDir(dir, prefix = '') {
67
+ const entries = plugins.fs.readdirSync(dir, { withFileTypes: true });
68
+ const result = [];
69
+ for (const entry of entries) {
70
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
71
+ const indicator = entry.isDirectory() ? '/' : '';
72
+ result.push(`${rel}${indicator}`);
73
+ if (recursive && entry.isDirectory()) {
74
+ result.push(...listDir(plugins.path.join(dir, entry.name), rel));
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ const entries = listDir(resolved);
80
+ return plugins.truncateOutput(entries.join('\n')).content;
81
+ },
82
+ }),
83
+ delete_file: plugins.tool({
84
+ description: 'Delete a file or empty directory.',
85
+ inputSchema: plugins.z.object({
86
+ path: plugins.z.string().describe('Path to delete'),
87
+ }),
88
+ execute: async ({ path: filePath }) => {
89
+ const resolved = validatePath(filePath, rootDir);
90
+ const stat = plugins.fs.statSync(resolved);
91
+ if (stat.isDirectory()) {
92
+ plugins.fs.rmdirSync(resolved);
93
+ }
94
+ else {
95
+ plugins.fs.unlinkSync(resolved);
96
+ }
97
+ return `Deleted ${filePath}`;
98
+ },
99
+ }),
100
+ };
101
+ }
102
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5maWxlc3lzdGVtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfdG9vbHMvdG9vbC5maWxlc3lzdGVtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBT3hDLFNBQVMsWUFBWSxDQUFDLFFBQWdCLEVBQUUsT0FBZ0I7SUFDdEQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDaEQsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNaLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFFBQVEsS0FBSyxZQUFZLEVBQUUsQ0FBQztZQUN2RixNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixRQUFRLDhCQUE4QixPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZGLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVELE1BQU0sVUFBVSxjQUFjLENBQUMsT0FBZ0M7SUFDN0QsTUFBTSxPQUFPLEdBQUcsT0FBTyxFQUFFLE9BQU8sQ0FBQztJQUVqQyxPQUFPO1FBQ0wsU0FBUyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDdEIsV0FBVyxFQUNULHNFQUFzRTtZQUN4RSxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQzVCLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQztnQkFDOUQsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3FCQUNqQixNQUFNLEVBQUU7cUJBQ1IsUUFB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
@@ -0,0 +1,2 @@
1
+ import * as plugins from './plugins.js';
2
+ export declare function httpTool(): plugins.ToolSet;
@@ -0,0 +1,65 @@
1
+ import * as plugins from './plugins.js';
2
+ export function httpTool() {
3
+ return {
4
+ http_get: plugins.tool({
5
+ description: 'Make an HTTP GET request and return the response.',
6
+ inputSchema: plugins.z.object({
7
+ url: plugins.z.string().describe('URL to request'),
8
+ headers: plugins.z
9
+ .record(plugins.z.string())
10
+ .optional()
11
+ .describe('Request headers'),
12
+ }),
13
+ execute: async ({ url, headers, }) => {
14
+ let req = plugins.smartrequest.default.create().url(url);
15
+ if (headers) {
16
+ req = req.headers(headers);
17
+ }
18
+ const response = await req.get();
19
+ let body;
20
+ try {
21
+ const json = await response.json();
22
+ body = JSON.stringify(json, null, 2);
23
+ }
24
+ catch {
25
+ body = await response.text();
26
+ }
27
+ return plugins.truncateOutput(`HTTP ${response.status}\n${body}`).content;
28
+ },
29
+ }),
30
+ http_post: plugins.tool({
31
+ description: 'Make an HTTP POST request with a JSON body.',
32
+ inputSchema: plugins.z.object({
33
+ url: plugins.z.string().describe('URL to request'),
34
+ body: plugins.z
35
+ .record(plugins.z.unknown())
36
+ .optional()
37
+ .describe('JSON body to send'),
38
+ headers: plugins.z
39
+ .record(plugins.z.string())
40
+ .optional()
41
+ .describe('Request headers'),
42
+ }),
43
+ execute: async ({ url, body, headers, }) => {
44
+ let req = plugins.smartrequest.default.create().url(url);
45
+ if (headers) {
46
+ req = req.headers(headers);
47
+ }
48
+ if (body) {
49
+ req = req.json(body);
50
+ }
51
+ const response = await req.post();
52
+ let responseBody;
53
+ try {
54
+ const json = await response.json();
55
+ responseBody = JSON.stringify(json, null, 2);
56
+ }
57
+ catch {
58
+ responseBody = await response.text();
59
+ }
60
+ return plugins.truncateOutput(`HTTP ${response.status}\n${responseBody}`).content;
61
+ },
62
+ }),
63
+ };
64
+ }
65
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5odHRwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfdG9vbHMvdG9vbC5odHRwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE1BQU0sVUFBVSxRQUFRO0lBQ3RCLE9BQU87UUFDTCxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNyQixXQUFXLEVBQUUsbURBQW1EO1lBQ2hFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDNUIsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDO2dCQUNsRCxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQ2YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7cUJBQzFCLFFBQVEsRUFBRTtxQkFDVixRQUFRLENBQUMsaUJBQWlCLENBQUM7YUFDL0IsQ0FBQztZQUNGLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFDZCxHQUFHLEVBQ0gsT0FBTyxHQUlSLEVBQUUsRUFBRTtnQkFDSCxJQUFJLEdBQUcsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3pELElBQUksT0FBTyxFQUFFLENBQUM7b0JBQ1osR0FBRyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzdCLENBQUM7Z0JBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQ2pDLElBQUksSUFBWSxDQUFDO2dCQUNqQixJQUFJLENBQUM7b0JBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ25DLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZDLENBQUM7Z0JBQUMsTUFBTSxDQUFDO29CQUNQLElBQUksR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDL0IsQ0FBQztnQkFDRCxPQUFPLE9BQU8sQ0FBQyxjQUFjLENBQUMsUUFBUSxRQUFRLENBQUMsTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzVFLENBQUM7U0FDRixDQUFDO1FBRUYsU0FBUyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDdEIsV0FBVyxFQUFFLDZDQUE2QztZQUMxRCxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQzVCLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDbEQsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO3FCQUNaLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO3FCQUMzQixRQUFRLEVBQUU7cUJBQ1YsUUFBUSxDQUFDLG1CQUFtQixDQUFDO2dCQUNoQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQ2YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7cUJBQzFCLFFBQVEsRUFBRTtxQkFDVixRQUFRLENBQUMsaUJBQWlCLENBQUM7YUFDL0IsQ0FBQztZQUNGLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFDZCxHQUFHLEVBQ0gsSUFBSSxFQUNKLE9BQU8sR0FLUixFQUFFLEVBQUU7Z0JBQ0gsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN6RCxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM3QixDQUFDO2dCQUNELElBQUksSUFBSSxFQUFFLENBQUM7b0JBQ1QsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3ZCLENBQUM7Z0JBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2xDLElBQUksWUFBb0IsQ0FBQztnQkFDekIsSUFBSSxDQUFDO29CQUNILE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNuQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUMvQyxDQUFDO2dCQUFDLE1BQU0sQ0FBQztvQkFDUCxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3ZDLENBQUM7Z0JBQ0QsT0FBTyxPQUFPLENBQUMsY0FBYyxDQUFDLFFBQVEsUUFBUSxDQUFDLE1BQU0sS0FBSyxZQUFZLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNwRixDQUFDO1NBQ0YsQ0FBQztLQUNILENBQUM7QUFDSixDQUFDIn0=
@@ -0,0 +1,2 @@
1
+ import * as plugins from './plugins.js';
2
+ export declare function jsonTool(): plugins.ToolSet;
@@ -0,0 +1,47 @@
1
+ import * as plugins from './plugins.js';
2
+ export function jsonTool() {
3
+ return {
4
+ json_validate: plugins.tool({
5
+ description: 'Validate a JSON string and optionally check for required fields.',
6
+ inputSchema: plugins.z.object({
7
+ jsonString: plugins.z.string().describe('JSON string to validate'),
8
+ requiredFields: plugins.z
9
+ .array(plugins.z.string())
10
+ .optional()
11
+ .describe('Fields that must exist at the top level'),
12
+ }),
13
+ execute: async ({ jsonString, requiredFields, }) => {
14
+ try {
15
+ const parsed = JSON.parse(jsonString);
16
+ if (requiredFields?.length) {
17
+ const missing = requiredFields.filter((f) => !(f in parsed));
18
+ if (missing.length) {
19
+ return `Invalid: missing required fields: ${missing.join(', ')}`;
20
+ }
21
+ }
22
+ const type = Array.isArray(parsed) ? 'array' : typeof parsed;
23
+ return `Valid JSON (${type})`;
24
+ }
25
+ catch (e) {
26
+ return `Invalid JSON: ${e.message}`;
27
+ }
28
+ },
29
+ }),
30
+ json_transform: plugins.tool({
31
+ description: 'Parse a JSON string and return it pretty-printed.',
32
+ inputSchema: plugins.z.object({
33
+ jsonString: plugins.z.string().describe('JSON string to format'),
34
+ }),
35
+ execute: async ({ jsonString }) => {
36
+ try {
37
+ const parsed = JSON.parse(jsonString);
38
+ return JSON.stringify(parsed, null, 2);
39
+ }
40
+ catch (e) {
41
+ return `Error parsing JSON: ${e.message}`;
42
+ }
43
+ },
44
+ }),
45
+ };
46
+ }
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfdG9vbHMvdG9vbC5qc29uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE1BQU0sVUFBVSxRQUFRO0lBQ3RCLE9BQU87UUFDTCxhQUFhLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQztZQUMxQixXQUFXLEVBQ1Qsa0VBQWtFO1lBQ3BFLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztnQkFDNUIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLHlCQUF5QixDQUFDO2dCQUNsRSxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQ3RCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUN6QixRQUFRLEVBQUU7cUJBQ1YsUUFBUSxDQUFDLHlDQUF5QyxDQUFDO2FBQ3ZELENBQUM7WUFDRixPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQ2QsVUFBVSxFQUNWLGNBQWMsR0FJZixFQUFFLEVBQUU7Z0JBQ0gsSUFBSSxDQUFDO29CQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3RDLElBQUksY0FBYyxFQUFFLE1BQU0sRUFBRSxDQUFDO3dCQUMzQixNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUM7d0JBQzdELElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDOzRCQUNuQixPQUFPLHFDQUFxQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7d0JBQ25FLENBQUM7b0JBQ0gsQ0FBQztvQkFDRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sTUFBTSxDQUFDO29CQUM3RCxPQUFPLGVBQWUsSUFBSSxHQUFHLENBQUM7Z0JBQ2hDLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCxPQUFPLGlCQUFrQixDQUFXLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2pELENBQUM7WUFDSCxDQUFDO1NBQ0YsQ0FBQztRQUVGLGNBQWMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzNCLFdBQVcsRUFBRSxtREFBbUQ7WUFDaEUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUM1QixVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsdUJBQXVCLENBQUM7YUFDakUsQ0FBQztZQUNGLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxVQUFVLEVBQTBCLEVBQUUsRUFBRTtnQkFDeEQsSUFBSSxDQUFDO29CQUNILE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ3RDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7b0JBQ1gsT0FBTyx1QkFBd0IsQ0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN2RCxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyJ9
@@ -0,0 +1,8 @@
1
+ import * as plugins from './plugins.js';
2
+ export interface IShellToolOptions {
3
+ /** Allowed commands whitelist. If empty, all commands are allowed. */
4
+ allowedCommands?: string[];
5
+ /** Working directory for shell execution */
6
+ cwd?: string;
7
+ }
8
+ export declare function shellTool(options?: IShellToolOptions): plugins.ToolSet;
@@ -0,0 +1,40 @@
1
+ import * as plugins from './plugins.js';
2
+ export function shellTool(options) {
3
+ const smartshell = new plugins.smartshell.Smartshell({ executor: 'bash' });
4
+ return {
5
+ run_command: plugins.tool({
6
+ description: 'Execute a shell command. Provide the full command string. stdout and stderr are returned.',
7
+ inputSchema: plugins.z.object({
8
+ command: plugins.z.string().describe('The shell command to execute'),
9
+ cwd: plugins.z
10
+ .string()
11
+ .optional()
12
+ .describe('Working directory for the command'),
13
+ timeout: plugins.z
14
+ .number()
15
+ .optional()
16
+ .describe('Timeout in milliseconds'),
17
+ }),
18
+ execute: async ({ command, cwd, timeout, }) => {
19
+ // Validate against allowed commands whitelist
20
+ if (options?.allowedCommands?.length) {
21
+ const baseCommand = command.split(/\s+/)[0];
22
+ if (!options.allowedCommands.includes(baseCommand)) {
23
+ return `Command "${baseCommand}" is not in the allowed commands list: ${options.allowedCommands.join(', ')}`;
24
+ }
25
+ }
26
+ // Build full command string with cd prefix if cwd specified
27
+ const effectiveCwd = cwd ?? options?.cwd;
28
+ const fullCommand = effectiveCwd
29
+ ? `cd ${JSON.stringify(effectiveCwd)} && ${command}`
30
+ : command;
31
+ const execResult = await smartshell.exec(fullCommand);
32
+ const output = execResult.exitCode === 0
33
+ ? execResult.stdout
34
+ : `Exit code: ${execResult.exitCode}\nstdout:\n${execResult.stdout}\nstderr:\n${execResult.stderr ?? ''}`;
35
+ return plugins.truncateOutput(output).content;
36
+ },
37
+ }),
38
+ };
39
+ }
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5zaGVsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX3Rvb2xzL3Rvb2wuc2hlbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFTeEMsTUFBTSxVQUFVLFNBQVMsQ0FBQyxPQUEyQjtJQUNuRCxNQUFNLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFFM0UsT0FBTztRQUNMLFdBQVcsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ3hCLFdBQVcsRUFDVCwyRkFBMkY7WUFDN0YsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO2dCQUM1QixPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsOEJBQThCLENBQUM7Z0JBQ3BFLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztxQkFDWCxNQUFNLEVBQUU7cUJBQ1IsUUFBUSxFQUFFO3FCQUNWLFFBQVEsQ0FBQyxtQ0FBbUMsQ0FBQztnQkFDaEQsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO3FCQUNmLE1BQU0sRUFBRTtxQkFDUixRQUFRLEVBQUU7cUJBQ1YsUUFBUSxDQUFDLHlCQUF5QixDQUFDO2FBQ3ZDLENBQUM7WUFDRixPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQ2QsT0FBTyxFQUNQLEdBQUcsRUFDSCxPQUFPLEdBS1IsRUFBRSxFQUFFO2dCQUNILDhDQUE4QztnQkFDOUMsSUFBSSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxDQUFDO29CQUNyQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQzt3QkFDbkQsT0FBTyxZQUFZLFdBQVcsMENBQTBDLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQy9HLENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCw0REFBNEQ7Z0JBQzVELE1BQU0sWUFBWSxHQUFHLEdBQUcsSUFBSSxPQUFPLEVBQUUsR0FBRyxDQUFDO2dCQUN6QyxNQUFNLFdBQVcsR0FBRyxZQUFZO29CQUM5QixDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxPQUFPLE9BQU8sRUFBRTtvQkFDcEQsQ0FBQyxDQUFDLE9BQU8sQ0FBQztnQkFFWixNQUFNLFVBQVUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBRXRELE1BQU0sTUFBTSxHQUNWLFVBQVUsQ0FBQyxRQUFRLEtBQUssQ0FBQztvQkFDdkIsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNO29CQUNuQixDQUFDLENBQUMsY0FBYyxVQUFVLENBQUMsUUFBUSxjQUFjLFVBQVUsQ0FBQyxNQUFNLGNBQWMsVUFBVSxDQUFDLE1BQU0sSUFBSSxFQUFFLEVBQUUsQ0FBQztnQkFFOUcsT0FBTyxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNoRCxDQUFDO1NBQ0YsQ0FBQztLQUNILENBQUM7QUFDSixDQUFDIn0=
package/npmextra.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "githost": "code.foss.global",
6
6
  "gitscope": "push.rocks",
7
7
  "gitrepo": "smartagent",
8
- "description": "an agentic framework built on top of @push.rocks/smartai",
8
+ "description": "Agentic loop for ai-sdk (Vercel AI SDK). Wraps streamText with stopWhen for parallel multi-step tool execution. Built on @push.rocks/smartai.",
9
9
  "npmPackagename": "@push.rocks/smartagent",
10
10
  "license": "MIT",
11
11
  "projectDomain": "push.rocks"
package/package.json CHANGED
@@ -1,33 +1,47 @@
1
1
  {
2
2
  "name": "@push.rocks/smartagent",
3
- "version": "1.7.0",
3
+ "version": "3.0.0",
4
4
  "private": false,
5
- "description": "an agentic framework built on top of @push.rocks/smartai",
5
+ "description": "Agentic loop for ai-sdk (Vercel AI SDK). Wraps streamText with stopWhen for parallel multi-step tool execution. Built on @push.rocks/smartai.",
6
6
  "main": "dist_ts/index.js",
7
7
  "typings": "dist_ts/index.d.ts",
8
8
  "type": "module",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist_ts/index.js",
12
+ "types": "./dist_ts/index.d.ts"
13
+ },
14
+ "./tools": {
15
+ "import": "./dist_ts_tools/index.js",
16
+ "types": "./dist_ts_tools/index.d.ts"
17
+ },
18
+ "./compaction": {
19
+ "import": "./dist_ts_compaction/index.js",
20
+ "types": "./dist_ts_compaction/index.d.ts"
21
+ }
22
+ },
9
23
  "author": "Task Venture Capital GmbH",
10
24
  "license": "MIT",
11
25
  "scripts": {
12
- "test": "(tstest test/ --verbose)",
13
- "build": "(tsbuild --web --allowimplicitany)",
26
+ "test": "(tstest test/ --verbose --logfile --timeout 120)",
27
+ "build": "(tsbuild tsfolders --allowimplicitany)",
14
28
  "buildDocs": "(tsdoc)"
15
29
  },
16
30
  "devDependencies": {
17
- "@git.zone/tsbuild": "^4.0.2",
18
- "@git.zone/tsbundle": "^2.6.3",
31
+ "@git.zone/tsbuild": "^4.3.0",
32
+ "@git.zone/tsbundle": "^2.9.1",
19
33
  "@git.zone/tsrun": "^2.0.1",
20
- "@git.zone/tstest": "^3.1.3",
21
- "@types/node": "^25.0.2"
34
+ "@git.zone/tstest": "^3.3.0",
35
+ "@push.rocks/qenv": "^6.1.3",
36
+ "@types/node": "^25.3.5"
22
37
  },
23
38
  "dependencies": {
24
- "@push.rocks/smartai": "^0.13.3",
25
- "@push.rocks/smartbrowser": "^2.0.8",
26
- "@push.rocks/smartdeno": "^1.2.0",
27
- "@push.rocks/smartfs": "^1.2.0",
39
+ "@push.rocks/smartai": "^2.0.0",
40
+ "@push.rocks/smartfs": "^1.4.0",
28
41
  "@push.rocks/smartrequest": "^5.0.1",
29
- "@push.rocks/smartshell": "^3.3.0",
30
- "minimatch": "^10.1.1"
42
+ "@push.rocks/smartshell": "^3.3.7",
43
+ "ai": "^6.0.0",
44
+ "zod": "^3.25.0"
31
45
  },
32
46
  "packageManager": "pnpm@10.18.1+sha512.77a884a165cbba2d8d1c19e3b4880eee6d2fcabd0d879121e282196b80042351d5eb3ca0935fa599da1dc51265cc68816ad2bddd2a2de5ea9fdf92adbec7cd34",
33
47
  "repository": {
@@ -40,13 +54,11 @@
40
54
  "homepage": "https://code.foss.global/push.rocks/smartagent#readme",
41
55
  "files": [
42
56
  "ts/**/*",
43
- "ts_web/**/*",
57
+ "ts_tools/**/*",
58
+ "ts_compaction/**/*",
44
59
  "dist/**/*",
45
60
  "dist_*/**/*",
46
- "dist_ts/**/*",
47
- "dist_ts_web/**/*",
48
61
  "assets/**/*",
49
- "cli.js",
50
62
  "npmextra.json",
51
63
  "readme.md"
52
64
  ],