@elizaos/plugin-code 2.0.0-alpha.1 → 2.0.0-alpha.3

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/index.js CHANGED
@@ -962,6 +962,37 @@ class CoderService extends Service {
962
962
  executedIn: this.getCurrentDirectory(conversationId)
963
963
  };
964
964
  }
965
+ const cwd = this.getCurrentDirectory(conversationId);
966
+ const shellService = typeof this.runtime?.getService === "function" ? this.runtime.getService("shell") : null;
967
+ if (shellService) {
968
+ const execResult = await shellService.exec(trimmed, {
969
+ workdir: cwd,
970
+ timeout: Math.floor(this.coderConfig.timeoutMs / 1000),
971
+ conversationId
972
+ });
973
+ if (execResult.status === "running") {
974
+ const result2 = {
975
+ success: true,
976
+ stdout: `Command running in background (session: ${execResult.sessionId})`,
977
+ stderr: "",
978
+ exitCode: 0,
979
+ executedIn: cwd
980
+ };
981
+ this.addToHistory(conversationId, trimmed, result2);
982
+ return result2;
983
+ }
984
+ const success = execResult.status === "completed" && execResult.exitCode === 0;
985
+ const result = {
986
+ success,
987
+ stdout: execResult.aggregated ?? "",
988
+ stderr: execResult.reason ?? "",
989
+ exitCode: execResult.exitCode ?? (success ? 0 : 1),
990
+ error: success ? undefined : "Command failed",
991
+ executedIn: cwd
992
+ };
993
+ this.addToHistory(conversationId, trimmed, result);
994
+ return result;
995
+ }
965
996
  if (!isSafeCommand(trimmed)) {
966
997
  return {
967
998
  success: false,
@@ -969,7 +1000,7 @@ class CoderService extends Service {
969
1000
  stderr: "Command contains forbidden patterns",
970
1001
  exitCode: 1,
971
1002
  error: "Security policy violation",
972
- executedIn: this.getCurrentDirectory(conversationId)
1003
+ executedIn: cwd
973
1004
  };
974
1005
  }
975
1006
  if (isForbiddenCommand(trimmed, this.coderConfig.forbiddenCommands)) {
@@ -979,10 +1010,9 @@ class CoderService extends Service {
979
1010
  stderr: "Command is forbidden by security policy",
980
1011
  exitCode: 1,
981
1012
  error: "Forbidden command",
982
- executedIn: this.getCurrentDirectory(conversationId)
1013
+ executedIn: cwd
983
1014
  };
984
1015
  }
985
- const cwd = this.getCurrentDirectory(conversationId);
986
1016
  try {
987
1017
  const stdout = execSync(trimmed, {
988
1018
  cwd,
@@ -1021,6 +1051,413 @@ class CoderService extends Service {
1021
1051
  return this.executeShell(`git ${args}`, conversationId);
1022
1052
  }
1023
1053
  }
1054
+ // configureCodingTools.ts
1055
+ function configureCodingTools(runtime, options) {
1056
+ const shellService = runtime.getService("shell");
1057
+ const coderService = runtime.getService("coder");
1058
+ const defaultCwd = options?.cwd ?? process.cwd();
1059
+ const scopeKey = options?.scopeKey;
1060
+ const sessionKey = options?.sessionKey;
1061
+ const notifyOnExit = options?.notifyOnExit ?? false;
1062
+ const defaultBackgroundMs = options?.backgroundMs ?? 1e4;
1063
+ const defaultTimeoutSec = options?.timeoutSec ?? 1800;
1064
+ const conversationId = options?.conversationId ?? "default";
1065
+ const actions = [];
1066
+ if (shellService) {
1067
+ const execAction = {
1068
+ name: "exec",
1069
+ label: "exec",
1070
+ description: "Execute a shell command. Returns output when complete or session info if backgrounded.",
1071
+ parameters: {
1072
+ type: "object",
1073
+ properties: {
1074
+ command: { type: "string", description: "Shell command to execute" },
1075
+ workdir: {
1076
+ type: "string",
1077
+ description: "Working directory (optional)"
1078
+ },
1079
+ env: {
1080
+ type: "object",
1081
+ additionalProperties: { type: "string" },
1082
+ description: "Environment variables (optional)"
1083
+ },
1084
+ yieldMs: {
1085
+ type: "number",
1086
+ description: "Milliseconds to wait before backgrounding (default 10000)"
1087
+ },
1088
+ background: {
1089
+ type: "boolean",
1090
+ description: "Run in background immediately"
1091
+ },
1092
+ timeout: { type: "number", description: "Timeout in seconds" },
1093
+ pty: {
1094
+ type: "boolean",
1095
+ description: "Use PTY for interactive commands"
1096
+ }
1097
+ },
1098
+ required: ["command"]
1099
+ },
1100
+ execute: async (context) => {
1101
+ const params = context.args;
1102
+ if (!params.command) {
1103
+ throw new Error("Provide a command to execute.");
1104
+ }
1105
+ const result = await shellService.exec(params.command, {
1106
+ workdir: params.workdir?.trim() || defaultCwd,
1107
+ env: params.env,
1108
+ yieldMs: params.yieldMs ?? defaultBackgroundMs,
1109
+ background: params.background,
1110
+ timeout: params.timeout ?? defaultTimeoutSec,
1111
+ pty: params.pty,
1112
+ scopeKey,
1113
+ sessionKey,
1114
+ notifyOnExit,
1115
+ conversationId: context.conversationId ?? conversationId,
1116
+ onUpdate: context.onUpdate ? (session) => {
1117
+ context.onUpdate?.({
1118
+ content: [
1119
+ {
1120
+ type: "text",
1121
+ text: session.tail || session.aggregated || ""
1122
+ }
1123
+ ],
1124
+ details: {
1125
+ status: "running",
1126
+ sessionId: session.id,
1127
+ pid: session.pid ?? undefined,
1128
+ startedAt: session.startedAt,
1129
+ cwd: session.cwd,
1130
+ tail: session.tail
1131
+ }
1132
+ });
1133
+ } : undefined
1134
+ });
1135
+ if (result.status === "running") {
1136
+ return {
1137
+ content: [
1138
+ {
1139
+ type: "text",
1140
+ text: `Command still running (session ${result.sessionId}, pid ${result.pid ?? "n/a"}). Use process action (list/poll/log/write/kill) for follow-up.`
1141
+ }
1142
+ ],
1143
+ details: {
1144
+ status: "running",
1145
+ sessionId: result.sessionId,
1146
+ pid: result.pid ?? undefined,
1147
+ startedAt: result.startedAt,
1148
+ cwd: result.cwd,
1149
+ tail: result.tail
1150
+ }
1151
+ };
1152
+ }
1153
+ if (result.status === "failed") {
1154
+ return {
1155
+ content: [
1156
+ {
1157
+ type: "text",
1158
+ text: result.aggregated || result.reason || "Command failed."
1159
+ }
1160
+ ],
1161
+ details: {
1162
+ status: "failed",
1163
+ exitCode: result.exitCode ?? 1,
1164
+ durationMs: result.durationMs,
1165
+ reason: result.reason
1166
+ }
1167
+ };
1168
+ }
1169
+ return {
1170
+ content: [
1171
+ {
1172
+ type: "text",
1173
+ text: result.aggregated || "(no output)"
1174
+ }
1175
+ ],
1176
+ details: {
1177
+ status: "completed",
1178
+ exitCode: result.exitCode ?? 0,
1179
+ durationMs: result.durationMs,
1180
+ aggregated: result.aggregated,
1181
+ cwd: result.cwd
1182
+ }
1183
+ };
1184
+ }
1185
+ };
1186
+ actions.push(execAction);
1187
+ const processAction = {
1188
+ name: "process",
1189
+ label: "process",
1190
+ description: "Manage running exec sessions: list, poll, log, write, send-keys, submit, paste, kill.",
1191
+ parameters: {
1192
+ type: "object",
1193
+ properties: {
1194
+ action: {
1195
+ type: "string",
1196
+ description: "Process action (list, poll, log, write, send-keys, submit, paste, kill, clear, remove)"
1197
+ },
1198
+ sessionId: {
1199
+ type: "string",
1200
+ description: "Session id for actions other than list"
1201
+ },
1202
+ data: {
1203
+ type: "string",
1204
+ description: "Data to write for write action"
1205
+ },
1206
+ keys: {
1207
+ type: "array",
1208
+ items: { type: "string" },
1209
+ description: "Key tokens to send for send-keys"
1210
+ },
1211
+ hex: {
1212
+ type: "array",
1213
+ items: { type: "string" },
1214
+ description: "Hex bytes to send for send-keys"
1215
+ },
1216
+ literal: {
1217
+ type: "string",
1218
+ description: "Literal string for send-keys"
1219
+ },
1220
+ text: {
1221
+ type: "string",
1222
+ description: "Text to paste for paste action"
1223
+ },
1224
+ bracketed: {
1225
+ type: "boolean",
1226
+ description: "Wrap paste in bracketed mode"
1227
+ },
1228
+ eof: { type: "boolean", description: "Close stdin after write" },
1229
+ offset: { type: "number", description: "Log offset" },
1230
+ limit: { type: "number", description: "Log length" }
1231
+ },
1232
+ required: ["action"]
1233
+ },
1234
+ execute: async (context) => {
1235
+ const params = context.args;
1236
+ const result = await shellService.processAction({
1237
+ action: params.action,
1238
+ sessionId: params.sessionId,
1239
+ data: params.data,
1240
+ keys: params.keys,
1241
+ hex: params.hex,
1242
+ literal: params.literal,
1243
+ text: params.text,
1244
+ bracketed: params.bracketed,
1245
+ eof: params.eof,
1246
+ offset: params.offset,
1247
+ limit: params.limit
1248
+ });
1249
+ return {
1250
+ content: [
1251
+ {
1252
+ type: "text",
1253
+ text: result.message
1254
+ }
1255
+ ],
1256
+ details: result.data
1257
+ };
1258
+ }
1259
+ };
1260
+ actions.push(processAction);
1261
+ }
1262
+ if (coderService) {
1263
+ const readFileAction = {
1264
+ name: "read_file",
1265
+ label: "read_file",
1266
+ description: "Read the contents of a file.",
1267
+ parameters: {
1268
+ type: "object",
1269
+ properties: {
1270
+ path: { type: "string", description: "Path to the file to read" }
1271
+ },
1272
+ required: ["path"]
1273
+ },
1274
+ execute: async (context) => {
1275
+ const params = context.args;
1276
+ const convId = context.conversationId ?? conversationId;
1277
+ const result = await coderService.readFile(convId, params.path);
1278
+ if (!result.ok) {
1279
+ return {
1280
+ content: [{ type: "text", text: `Error: ${result.error}` }],
1281
+ details: { success: false, error: result.error }
1282
+ };
1283
+ }
1284
+ return {
1285
+ content: [{ type: "text", text: result.content }],
1286
+ details: { success: true }
1287
+ };
1288
+ }
1289
+ };
1290
+ actions.push(readFileAction);
1291
+ const writeFileAction = {
1292
+ name: "write_file",
1293
+ label: "write_file",
1294
+ description: "Write content to a file. Creates the file if it doesn't exist.",
1295
+ parameters: {
1296
+ type: "object",
1297
+ properties: {
1298
+ path: { type: "string", description: "Path to the file to write" },
1299
+ content: {
1300
+ type: "string",
1301
+ description: "Content to write to the file"
1302
+ }
1303
+ },
1304
+ required: ["path", "content"]
1305
+ },
1306
+ execute: async (context) => {
1307
+ const params = context.args;
1308
+ const convId = context.conversationId ?? conversationId;
1309
+ const result = await coderService.writeFile(convId, params.path, params.content);
1310
+ if (!result.ok) {
1311
+ return {
1312
+ content: [{ type: "text", text: `Error: ${result.error}` }],
1313
+ details: { success: false, error: result.error }
1314
+ };
1315
+ }
1316
+ return {
1317
+ content: [{ type: "text", text: `File written: ${params.path}` }],
1318
+ details: { success: true }
1319
+ };
1320
+ }
1321
+ };
1322
+ actions.push(writeFileAction);
1323
+ const editFileAction = {
1324
+ name: "edit_file",
1325
+ label: "edit_file",
1326
+ description: "Edit a file by replacing text. Finds old_str and replaces with new_str.",
1327
+ parameters: {
1328
+ type: "object",
1329
+ properties: {
1330
+ path: { type: "string", description: "Path to the file to edit" },
1331
+ old_str: { type: "string", description: "Text to find and replace" },
1332
+ new_str: { type: "string", description: "Text to replace with" }
1333
+ },
1334
+ required: ["path", "old_str", "new_str"]
1335
+ },
1336
+ execute: async (context) => {
1337
+ const params = context.args;
1338
+ const convId = context.conversationId ?? conversationId;
1339
+ const result = await coderService.editFile(convId, params.path, params.old_str, params.new_str);
1340
+ if (!result.ok) {
1341
+ return {
1342
+ content: [{ type: "text", text: `Error: ${result.error}` }],
1343
+ details: { success: false, error: result.error }
1344
+ };
1345
+ }
1346
+ return {
1347
+ content: [{ type: "text", text: `File edited: ${params.path}` }],
1348
+ details: { success: true }
1349
+ };
1350
+ }
1351
+ };
1352
+ actions.push(editFileAction);
1353
+ const listFilesAction = {
1354
+ name: "list_files",
1355
+ label: "list_files",
1356
+ description: "List files and directories in a path.",
1357
+ parameters: {
1358
+ type: "object",
1359
+ properties: {
1360
+ path: {
1361
+ type: "string",
1362
+ description: "Directory path to list (defaults to current directory)"
1363
+ }
1364
+ },
1365
+ required: []
1366
+ },
1367
+ execute: async (context) => {
1368
+ const params = context.args;
1369
+ const convId = context.conversationId ?? conversationId;
1370
+ const result = await coderService.listFiles(convId, params.path ?? ".");
1371
+ if (!result.ok) {
1372
+ return {
1373
+ content: [{ type: "text", text: `Error: ${result.error}` }],
1374
+ details: { success: false, error: result.error }
1375
+ };
1376
+ }
1377
+ return {
1378
+ content: [{ type: "text", text: result.items.join(`
1379
+ `) }],
1380
+ details: { success: true, items: result.items }
1381
+ };
1382
+ }
1383
+ };
1384
+ actions.push(listFilesAction);
1385
+ const searchFilesAction = {
1386
+ name: "search_files",
1387
+ label: "search_files",
1388
+ description: "Search for a pattern in files within a directory.",
1389
+ parameters: {
1390
+ type: "object",
1391
+ properties: {
1392
+ pattern: { type: "string", description: "Pattern to search for" },
1393
+ path: {
1394
+ type: "string",
1395
+ description: "Directory path to search in (defaults to current directory)"
1396
+ },
1397
+ max_matches: {
1398
+ type: "number",
1399
+ description: "Maximum matches to return (default 50)"
1400
+ }
1401
+ },
1402
+ required: ["pattern"]
1403
+ },
1404
+ execute: async (context) => {
1405
+ const params = context.args;
1406
+ const convId = context.conversationId ?? conversationId;
1407
+ const result = await coderService.searchFiles(convId, params.pattern, params.path ?? ".", params.max_matches ?? 50);
1408
+ if (!result.ok) {
1409
+ return {
1410
+ content: [{ type: "text", text: `Error: ${result.error}` }],
1411
+ details: { success: false, error: result.error }
1412
+ };
1413
+ }
1414
+ const formatted = result.matches.map((m) => `${m.file}:${m.line}: ${m.content}`).join(`
1415
+ `);
1416
+ return {
1417
+ content: [{ type: "text", text: formatted || "No matches found" }],
1418
+ details: { success: true, matches: result.matches }
1419
+ };
1420
+ }
1421
+ };
1422
+ actions.push(searchFilesAction);
1423
+ const gitAction = {
1424
+ name: "git",
1425
+ label: "git",
1426
+ description: "Execute a git command.",
1427
+ parameters: {
1428
+ type: "object",
1429
+ properties: {
1430
+ args: {
1431
+ type: "string",
1432
+ description: "Git command arguments (e.g., 'status', 'diff', 'log --oneline -5')"
1433
+ }
1434
+ },
1435
+ required: ["args"]
1436
+ },
1437
+ execute: async (context) => {
1438
+ const params = context.args;
1439
+ const convId = context.conversationId ?? conversationId;
1440
+ const result = await coderService.git(params.args, convId);
1441
+ return {
1442
+ content: [
1443
+ {
1444
+ type: "text",
1445
+ text: result.success ? result.stdout : result.stderr
1446
+ }
1447
+ ],
1448
+ details: {
1449
+ success: result.success,
1450
+ exitCode: result.exitCode,
1451
+ stdout: result.stdout,
1452
+ stderr: result.stderr
1453
+ }
1454
+ };
1455
+ }
1456
+ };
1457
+ actions.push(gitAction);
1458
+ }
1459
+ return actions;
1460
+ }
1024
1461
 
1025
1462
  // index.ts
1026
1463
  var coderPlugin = {
@@ -1054,6 +1491,7 @@ export {
1054
1491
  executeShell,
1055
1492
  editFile,
1056
1493
  typescript_default as default,
1494
+ configureCodingTools,
1057
1495
  coderStatusProvider,
1058
1496
  coderPlugin,
1059
1497
  changeDirectory,
@@ -1061,4 +1499,4 @@ export {
1061
1499
  CoderService
1062
1500
  };
1063
1501
 
1064
- //# debugId=11D69657230A26B464756E2164756E21
1502
+ //# debugId=30DB4D8CA69EB24D64756E2164756E21