@jcheesepkg/nanobot 0.6.96 → 0.6.98
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.d.mts","names":[],"sources":["../../../src/agent/tools/shell.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"shell.d.mts","names":[],"sources":["../../../src/agent/tools/shell.ts"],"mappings":";;;cAuEa,QAAA,SAAiB,IAAA;EAAA,SACnB,IAAA;EAAA,SACA,WAAA;EAAA,SAEA,UAAA;;;;;;;;;;;;;;UAYD,UAAA;EAAA,QACA,cAAA;EAAA,QACA,mBAAA;cAEI,MAAA;IACV,UAAA;IACA,OAAA;IACA,mBAAA;EAAA;EAQI,OAAA,CAAQ,IAAA,EAAM,MAAA,oBAA0B,OAAA;AAAA"}
|
|
@@ -11,6 +11,7 @@ const SENSITIVE_ENV_PATTERNS = [
|
|
|
11
11
|
/token/i,
|
|
12
12
|
/password/i,
|
|
13
13
|
/credential/i,
|
|
14
|
+
/^LLM_/i,
|
|
14
15
|
/^OPENROUTER_/i,
|
|
15
16
|
/^OPENAI_/i,
|
|
16
17
|
/^ANTHROPIC_/i,
|
|
@@ -21,9 +22,23 @@ const SENSITIVE_ENV_PATTERNS = [
|
|
|
21
22
|
/^BRAVE_/i,
|
|
22
23
|
/^AWS_/i,
|
|
23
24
|
/^GOOGLE_/i,
|
|
24
|
-
/^AZURE_/i
|
|
25
|
+
/^AZURE_/i,
|
|
26
|
+
/^NANOBOT_/i
|
|
25
27
|
];
|
|
26
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Trusted commands that receive skill-specific env vars.
|
|
30
|
+
* Only the first word (binary name) of the command is matched.
|
|
31
|
+
* These commands still do NOT get the core LLM/channel secrets.
|
|
32
|
+
*/
|
|
33
|
+
const TRUSTED_COMMANDS = ["summarize"];
|
|
34
|
+
/** Env vars injected for trusted commands only. */
|
|
35
|
+
const SKILL_ENV_KEYS = [
|
|
36
|
+
"Z_AI_API_KEY",
|
|
37
|
+
"Z_AI_BASE_URL",
|
|
38
|
+
"APIFY_API_TOKEN",
|
|
39
|
+
"BRAVE_API_KEY"
|
|
40
|
+
];
|
|
41
|
+
/** Build a sanitized env for child processes — strips all secrets. */
|
|
27
42
|
function buildSafeEnv() {
|
|
28
43
|
const safe = {};
|
|
29
44
|
for (const [key, value] of Object.entries(process.env)) {
|
|
@@ -33,6 +48,20 @@ function buildSafeEnv() {
|
|
|
33
48
|
}
|
|
34
49
|
return safe;
|
|
35
50
|
}
|
|
51
|
+
/** Build env for trusted skill commands — safe env + skill-specific keys. */
|
|
52
|
+
function buildSkillEnv() {
|
|
53
|
+
const env = buildSafeEnv();
|
|
54
|
+
for (const key of SKILL_ENV_KEYS) {
|
|
55
|
+
const value = process.env[key];
|
|
56
|
+
if (value) env[key] = value;
|
|
57
|
+
}
|
|
58
|
+
return env;
|
|
59
|
+
}
|
|
60
|
+
/** Check if a command starts with a trusted binary. */
|
|
61
|
+
function isTrustedCommand(command) {
|
|
62
|
+
const firstWord = command.replace(/^\s*(timeout\s+\d+\s+|env\s+\S+=\S+\s+)*/, "").trim().split(/\s+/)[0];
|
|
63
|
+
return TRUSTED_COMMANDS.includes(firstWord);
|
|
64
|
+
}
|
|
36
65
|
var ExecTool = class extends Tool {
|
|
37
66
|
name = "exec";
|
|
38
67
|
description = "Execute a shell command and return its output. Use for running programs, scripts, git, etc.";
|
|
@@ -71,10 +100,15 @@ var ExecTool = class extends Tool {
|
|
|
71
100
|
"> /dev/"
|
|
72
101
|
]) if (command.includes(pattern)) return `Error: Command blocked for safety: ${pattern}`;
|
|
73
102
|
}
|
|
74
|
-
|
|
103
|
+
let env;
|
|
104
|
+
if (!this.restrictToWorkspace) env = {
|
|
75
105
|
...process.env,
|
|
76
106
|
HOME: process.env.HOME ?? ""
|
|
77
107
|
};
|
|
108
|
+
else if (isTrustedCommand(command)) {
|
|
109
|
+
env = buildSkillEnv();
|
|
110
|
+
console.log(`Exec: trusted command detected, injecting skill env keys`, env);
|
|
111
|
+
} else env = buildSafeEnv();
|
|
78
112
|
return new Promise((resolve) => {
|
|
79
113
|
exec(command, {
|
|
80
114
|
cwd: this.workingDir,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell.mjs","names":[],"sources":["../../../src/agent/tools/shell.ts"],"sourcesContent":["import { exec, spawn } from \"node:child_process\";\nimport { Tool } from \"./base.js\";\n\n/** Env var patterns that should never leak to user-invoked commands. */\nconst SENSITIVE_ENV_PATTERNS = [\n /api[_-]?key/i,\n /api[_-]?token/i,\n /api[_-]?secret/i,\n /secret/i,\n /token/i,\n /password/i,\n /credential/i,\n /^OPENROUTER_/i,\n /^OPENAI_/i,\n /^ANTHROPIC_/i,\n /^STRIPE_/i,\n /^LINE_CHANNEL/i,\n /^APIFY_/i,\n /^Z_AI_/i,\n /^BRAVE_/i,\n /^AWS_/i,\n /^GOOGLE_/i,\n /^AZURE_/i,\n];\n\n/** Build a sanitized env for child processes — strips secrets
|
|
1
|
+
{"version":3,"file":"shell.mjs","names":[],"sources":["../../../src/agent/tools/shell.ts"],"sourcesContent":["import { exec, spawn } from \"node:child_process\";\nimport { Tool } from \"./base.js\";\n\n/** Env var patterns that should never leak to user-invoked commands. */\nconst SENSITIVE_ENV_PATTERNS = [\n /api[_-]?key/i,\n /api[_-]?token/i,\n /api[_-]?secret/i,\n /secret/i,\n /token/i,\n /password/i,\n /credential/i,\n /^LLM_/i,\n /^OPENROUTER_/i,\n /^OPENAI_/i,\n /^ANTHROPIC_/i,\n /^STRIPE_/i,\n /^LINE_CHANNEL/i,\n /^APIFY_/i,\n /^Z_AI_/i,\n /^BRAVE_/i,\n /^AWS_/i,\n /^GOOGLE_/i,\n /^AZURE_/i,\n /^NANOBOT_/i,\n];\n\n/**\n * Trusted commands that receive skill-specific env vars.\n * Only the first word (binary name) of the command is matched.\n * These commands still do NOT get the core LLM/channel secrets.\n */\nconst TRUSTED_COMMANDS = [\"summarize\"];\n\n/** Env vars injected for trusted commands only. */\nconst SKILL_ENV_KEYS = [\n \"Z_AI_API_KEY\",\n \"Z_AI_BASE_URL\",\n \"APIFY_API_TOKEN\",\n \"BRAVE_API_KEY\",\n];\n\n/** Build a sanitized env for child processes — strips all secrets. */\nfunction buildSafeEnv(): Record<string, string> {\n const safe: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (!value) continue;\n if (SENSITIVE_ENV_PATTERNS.some((re) => re.test(key))) continue;\n safe[key] = value;\n }\n return safe;\n}\n\n/** Build env for trusted skill commands — safe env + skill-specific keys. */\nfunction buildSkillEnv(): Record<string, string> {\n const env = buildSafeEnv();\n for (const key of SKILL_ENV_KEYS) {\n const value = process.env[key];\n if (value) env[key] = value;\n }\n return env;\n}\n\n/** Check if a command starts with a trusted binary. */\nfunction isTrustedCommand(command: string): boolean {\n // Extract the first word, stripping common prefixes like timeout, env, etc.\n const stripped = command.replace(/^\\s*(timeout\\s+\\d+\\s+|env\\s+\\S+=\\S+\\s+)*/, \"\");\n const firstWord = stripped.trim().split(/\\s+/)[0];\n return TRUSTED_COMMANDS.includes(firstWord);\n}\n\nexport class ExecTool extends Tool {\n readonly name = \"exec\";\n readonly description =\n \"Execute a shell command and return its output. Use for running programs, scripts, git, etc.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n command: { type: \"string\", description: \"Shell command to execute\" },\n timeout: {\n type: \"integer\",\n description: \"Timeout in seconds (default: 60)\",\n },\n },\n required: [\"command\"],\n };\n\n private workingDir: string;\n private defaultTimeout: number;\n private restrictToWorkspace: boolean;\n\n constructor(params?: {\n workingDir?: string;\n timeout?: number;\n restrictToWorkspace?: boolean;\n }) {\n super();\n this.workingDir = params?.workingDir ?? process.cwd();\n this.defaultTimeout = params?.timeout ?? 60;\n this.restrictToWorkspace = params?.restrictToWorkspace ?? false;\n }\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const command = String(args.command);\n const timeout = args.timeout ? Number(args.timeout) : this.defaultTimeout;\n\n if (!command.trim()) {\n return \"Error: Empty command\";\n }\n\n // Safety checks when restricted to workspace\n if (this.restrictToWorkspace) {\n const dangerous = [\"rm -rf /\", \"mkfs\", \"dd if=\", \"> /dev/\"];\n for (const pattern of dangerous) {\n if (command.includes(pattern)) {\n return `Error: Command blocked for safety: ${pattern}`;\n }\n }\n }\n\n // Build env: scrub secrets when restricted, pass through when unrestricted\n let env: Record<string, string>;\n if (!this.restrictToWorkspace) {\n env = { ...process.env, HOME: process.env.HOME ?? \"\" } as Record<string, string>;\n } else if (isTrustedCommand(command)) {\n env = buildSkillEnv();\n console.log(`Exec: trusted command detected, injecting skill env keys`, env);\n } else {\n env = buildSafeEnv();\n }\n\n return new Promise<string>((resolve) => {\n exec(\n command,\n {\n cwd: this.workingDir,\n timeout: timeout * 1000,\n maxBuffer: 1024 * 1024, // 1MB\n env,\n },\n (error, stdout, stderr) => {\n const parts: string[] = [];\n\n if (stdout) parts.push(stdout);\n if (stderr) parts.push(`[stderr]\\n${stderr}`);\n\n if (error) {\n if (error.killed) {\n parts.push(`\\n[Timed out after ${timeout}s]`);\n } else if (error.code !== undefined) {\n parts.push(`\\n[Exit code: ${error.code}]`);\n }\n }\n\n const output = parts.join(\"\\n\").trim();\n // Truncate large output\n if (output.length > 50000) {\n resolve(\n output.slice(0, 50000) + \"\\n... (truncated, output too large)\",\n );\n } else {\n resolve(output || \"(no output)\");\n }\n },\n );\n\n });\n }\n}\n"],"mappings":";;;;;AAIA,MAAM,yBAAyB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;AAOD,MAAM,mBAAmB,CAAC,YAAY;;AAGtC,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACD;;AAGD,SAAS,eAAuC;CAC9C,MAAM,OAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,IAAI,EAAE;AACtD,MAAI,CAAC,MAAO;AACZ,MAAI,uBAAuB,MAAM,OAAO,GAAG,KAAK,IAAI,CAAC,CAAE;AACvD,OAAK,OAAO;;AAEd,QAAO;;;AAIT,SAAS,gBAAwC;CAC/C,MAAM,MAAM,cAAc;AAC1B,MAAK,MAAM,OAAO,gBAAgB;EAChC,MAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,MAAO,KAAI,OAAO;;AAExB,QAAO;;;AAIT,SAAS,iBAAiB,SAA0B;CAGlD,MAAM,YADW,QAAQ,QAAQ,4CAA4C,GAAG,CACrD,MAAM,CAAC,MAAM,MAAM,CAAC;AAC/C,QAAO,iBAAiB,SAAS,UAAU;;AAG7C,IAAa,WAAb,cAA8B,KAAK;CACjC,AAAS,OAAO;CAChB,AAAS,cACP;CACF,AAAS,aAAa;EACpB,MAAM;EACN,YAAY;GACV,SAAS;IAAE,MAAM;IAAU,aAAa;IAA4B;GACpE,SAAS;IACP,MAAM;IACN,aAAa;IACd;GACF;EACD,UAAU,CAAC,UAAU;EACtB;CAED,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,QAIT;AACD,SAAO;AACP,OAAK,aAAa,QAAQ,cAAc,QAAQ,KAAK;AACrD,OAAK,iBAAiB,QAAQ,WAAW;AACzC,OAAK,sBAAsB,QAAQ,uBAAuB;;CAG5D,MAAM,QAAQ,MAAgD;EAC5D,MAAM,UAAU,OAAO,KAAK,QAAQ;EACpC,MAAM,UAAU,KAAK,UAAU,OAAO,KAAK,QAAQ,GAAG,KAAK;AAE3D,MAAI,CAAC,QAAQ,MAAM,CACjB,QAAO;AAIT,MAAI,KAAK,qBAEP;QAAK,MAAM,WADO;IAAC;IAAY;IAAQ;IAAU;IAAU,CAEzD,KAAI,QAAQ,SAAS,QAAQ,CAC3B,QAAO,sCAAsC;;EAMnD,IAAI;AACJ,MAAI,CAAC,KAAK,oBACR,OAAM;GAAE,GAAG,QAAQ;GAAK,MAAM,QAAQ,IAAI,QAAQ;GAAI;WAC7C,iBAAiB,QAAQ,EAAE;AACpC,SAAM,eAAe;AACrB,WAAQ,IAAI,4DAA4D,IAAI;QAE5E,OAAM,cAAc;AAGtB,SAAO,IAAI,SAAiB,YAAY;AACtC,QACE,SACA;IACE,KAAK,KAAK;IACV,SAAS,UAAU;IACnB,WAAW,OAAO;IAClB;IACD,GACA,OAAO,QAAQ,WAAW;IACzB,MAAM,QAAkB,EAAE;AAE1B,QAAI,OAAQ,OAAM,KAAK,OAAO;AAC9B,QAAI,OAAQ,OAAM,KAAK,aAAa,SAAS;AAE7C,QAAI,OACF;SAAI,MAAM,OACR,OAAM,KAAK,sBAAsB,QAAQ,IAAI;cACpC,MAAM,SAAS,OACxB,OAAM,KAAK,iBAAiB,MAAM,KAAK,GAAG;;IAI9C,MAAM,SAAS,MAAM,KAAK,KAAK,CAAC,MAAM;AAEtC,QAAI,OAAO,SAAS,IAClB,SACE,OAAO,MAAM,GAAG,IAAM,GAAG,sCAC1B;QAED,SAAQ,UAAU,cAAc;KAGrC;IAED"}
|
package/dist/config/schema.d.mts
CHANGED
|
@@ -539,15 +539,15 @@ declare const ToolsConfigSchema: z.ZodObject<{
|
|
|
539
539
|
export?: string | undefined;
|
|
540
540
|
}>, "many">>;
|
|
541
541
|
}, "strip", z.ZodTypeAny, {
|
|
542
|
+
exec: {
|
|
543
|
+
timeout: number;
|
|
544
|
+
};
|
|
542
545
|
web: {
|
|
543
546
|
search: {
|
|
544
547
|
apiKey: string;
|
|
545
548
|
maxResults: number;
|
|
546
549
|
};
|
|
547
550
|
};
|
|
548
|
-
exec: {
|
|
549
|
-
timeout: number;
|
|
550
|
-
};
|
|
551
551
|
restrictToWorkspace: boolean;
|
|
552
552
|
enabled?: string[] | undefined;
|
|
553
553
|
disabled?: string[] | undefined;
|
|
@@ -557,6 +557,9 @@ declare const ToolsConfigSchema: z.ZodObject<{
|
|
|
557
557
|
export?: string | undefined;
|
|
558
558
|
}[] | undefined;
|
|
559
559
|
}, {
|
|
560
|
+
exec?: {
|
|
561
|
+
timeout?: number | undefined;
|
|
562
|
+
} | undefined;
|
|
560
563
|
enabled?: string[] | undefined;
|
|
561
564
|
web?: {
|
|
562
565
|
search?: {
|
|
@@ -564,9 +567,6 @@ declare const ToolsConfigSchema: z.ZodObject<{
|
|
|
564
567
|
maxResults?: number | undefined;
|
|
565
568
|
} | undefined;
|
|
566
569
|
} | undefined;
|
|
567
|
-
exec?: {
|
|
568
|
-
timeout?: number | undefined;
|
|
569
|
-
} | undefined;
|
|
570
570
|
restrictToWorkspace?: boolean | undefined;
|
|
571
571
|
disabled?: string[] | undefined;
|
|
572
572
|
custom?: {
|
|
@@ -988,15 +988,15 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
988
988
|
export?: string | undefined;
|
|
989
989
|
}>, "many">>;
|
|
990
990
|
}, "strip", z.ZodTypeAny, {
|
|
991
|
+
exec: {
|
|
992
|
+
timeout: number;
|
|
993
|
+
};
|
|
991
994
|
web: {
|
|
992
995
|
search: {
|
|
993
996
|
apiKey: string;
|
|
994
997
|
maxResults: number;
|
|
995
998
|
};
|
|
996
999
|
};
|
|
997
|
-
exec: {
|
|
998
|
-
timeout: number;
|
|
999
|
-
};
|
|
1000
1000
|
restrictToWorkspace: boolean;
|
|
1001
1001
|
enabled?: string[] | undefined;
|
|
1002
1002
|
disabled?: string[] | undefined;
|
|
@@ -1006,6 +1006,9 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1006
1006
|
export?: string | undefined;
|
|
1007
1007
|
}[] | undefined;
|
|
1008
1008
|
}, {
|
|
1009
|
+
exec?: {
|
|
1010
|
+
timeout?: number | undefined;
|
|
1011
|
+
} | undefined;
|
|
1009
1012
|
enabled?: string[] | undefined;
|
|
1010
1013
|
web?: {
|
|
1011
1014
|
search?: {
|
|
@@ -1013,9 +1016,6 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1013
1016
|
maxResults?: number | undefined;
|
|
1014
1017
|
} | undefined;
|
|
1015
1018
|
} | undefined;
|
|
1016
|
-
exec?: {
|
|
1017
|
-
timeout?: number | undefined;
|
|
1018
|
-
} | undefined;
|
|
1019
1019
|
restrictToWorkspace?: boolean | undefined;
|
|
1020
1020
|
disabled?: string[] | undefined;
|
|
1021
1021
|
custom?: {
|
|
@@ -1110,15 +1110,15 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1110
1110
|
port: number;
|
|
1111
1111
|
};
|
|
1112
1112
|
tools: {
|
|
1113
|
+
exec: {
|
|
1114
|
+
timeout: number;
|
|
1115
|
+
};
|
|
1113
1116
|
web: {
|
|
1114
1117
|
search: {
|
|
1115
1118
|
apiKey: string;
|
|
1116
1119
|
maxResults: number;
|
|
1117
1120
|
};
|
|
1118
1121
|
};
|
|
1119
|
-
exec: {
|
|
1120
|
-
timeout: number;
|
|
1121
|
-
};
|
|
1122
1122
|
restrictToWorkspace: boolean;
|
|
1123
1123
|
enabled?: string[] | undefined;
|
|
1124
1124
|
disabled?: string[] | undefined;
|
|
@@ -1214,6 +1214,9 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1214
1214
|
port?: number | undefined;
|
|
1215
1215
|
} | undefined;
|
|
1216
1216
|
tools?: {
|
|
1217
|
+
exec?: {
|
|
1218
|
+
timeout?: number | undefined;
|
|
1219
|
+
} | undefined;
|
|
1217
1220
|
enabled?: string[] | undefined;
|
|
1218
1221
|
web?: {
|
|
1219
1222
|
search?: {
|
|
@@ -1221,9 +1224,6 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
1221
1224
|
maxResults?: number | undefined;
|
|
1222
1225
|
} | undefined;
|
|
1223
1226
|
} | undefined;
|
|
1224
|
-
exec?: {
|
|
1225
|
-
timeout?: number | undefined;
|
|
1226
|
-
} | undefined;
|
|
1227
1227
|
restrictToWorkspace?: boolean | undefined;
|
|
1228
1228
|
disabled?: string[] | undefined;
|
|
1229
1229
|
custom?: {
|