@harperfast/agent 0.12.1 → 0.13.1

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 (2) hide show
  1. package/dist/agent.js +521 -265
  2. package/package.json +16 -13
package/dist/agent.js CHANGED
@@ -282,9 +282,9 @@ var HarperProcess = class {
282
282
  this.stopTailingLogs();
283
283
  }
284
284
  getAndClearLogs() {
285
- const logs = this.logs;
285
+ const logs2 = this.logs;
286
286
  this.logs = [];
287
- return logs.join("");
287
+ return logs2.join("");
288
288
  }
289
289
  };
290
290
  var harperProcess = new HarperProcess();
@@ -702,10 +702,275 @@ function sayHi() {
702
702
  );
703
703
  }
704
704
 
705
- // tools/files/applyPatchTool.ts
705
+ // tools/browser/browserClickTool.ts
706
+ import { tool } from "@openai/agents";
707
+ import { z } from "zod";
708
+
709
+ // tools/browser/browserManager.ts
710
+ var browser = null;
711
+ var page = null;
712
+ var logs = [];
713
+ async function getBrowser() {
714
+ if (!browser) {
715
+ let puppeteer;
716
+ try {
717
+ puppeteer = await import("puppeteer");
718
+ } catch {
719
+ throw new Error(
720
+ "Puppeteer is not installed. Browser tools require puppeteer. Please install it with `npm install puppeteer`."
721
+ );
722
+ }
723
+ browser = await puppeteer.default.launch({
724
+ headless: false,
725
+ defaultViewport: null
726
+ });
727
+ }
728
+ return browser;
729
+ }
730
+ async function getPage() {
731
+ if (!page) {
732
+ const b = await getBrowser();
733
+ const pages = await b.pages();
734
+ if (pages.length > 0) {
735
+ page = pages[0];
736
+ } else {
737
+ page = await b.newPage();
738
+ }
739
+ page.on("console", (msg) => {
740
+ logs.push(`[${msg.type()}] ${msg.text()}`);
741
+ });
742
+ page.on("pageerror", (err) => {
743
+ logs.push(`[error] ${err.message || err}`);
744
+ });
745
+ }
746
+ return page;
747
+ }
748
+ function getBrowserLogs() {
749
+ return logs;
750
+ }
751
+ function clearBrowserLogs() {
752
+ logs.length = 0;
753
+ }
754
+ async function closeBrowser() {
755
+ if (browser) {
756
+ await browser.close();
757
+ browser = null;
758
+ page = null;
759
+ }
760
+ }
761
+
762
+ // tools/browser/browserClickTool.ts
763
+ var ToolParameters = z.object({
764
+ selector: z.string().describe("The CSS selector of the element to click."),
765
+ button: z.enum(["left", "right", "middle"]).default("left").describe("The button to use for the click."),
766
+ clickCount: z.number().default(1).describe("The number of times to click.")
767
+ });
768
+ async function execute({ selector, button, clickCount }) {
769
+ try {
770
+ const page2 = await getPage();
771
+ await page2.click(selector, { button, clickCount });
772
+ return `Successfully clicked on ${selector}`;
773
+ } catch (error) {
774
+ return `Error clicking on ${selector}: ${error}`;
775
+ }
776
+ }
777
+ var browserClickTool = tool({
778
+ name: "browser_click",
779
+ description: "Clicks on an element specified by a CSS selector.",
780
+ parameters: ToolParameters,
781
+ execute
782
+ });
783
+
784
+ // tools/browser/browserCloseTool.ts
706
785
  import { tool as tool2 } from "@openai/agents";
707
- import chalk7 from "chalk";
708
786
  import { z as z2 } from "zod";
787
+ var ToolParameters2 = z2.object({});
788
+ async function execute2() {
789
+ try {
790
+ await closeBrowser();
791
+ return "Browser closed successfully.";
792
+ } catch (error) {
793
+ return `Error closing browser: ${error}`;
794
+ }
795
+ }
796
+ var browserCloseTool = tool2({
797
+ name: "browser_close",
798
+ description: "Closes the browser instance.",
799
+ parameters: ToolParameters2,
800
+ execute: execute2
801
+ });
802
+
803
+ // tools/browser/browserEvaluateTool.ts
804
+ import { tool as tool3 } from "@openai/agents";
805
+ import { z as z3 } from "zod";
806
+ var ToolParameters3 = z3.object({
807
+ script: z3.string().describe("The JavaScript to evaluate in the context of the page.")
808
+ });
809
+ async function execute3({ script }) {
810
+ try {
811
+ const page2 = await getPage();
812
+ const result = await page2.evaluate(script);
813
+ return JSON.stringify(result, null, 2);
814
+ } catch (error) {
815
+ return `Error evaluating script: ${error}`;
816
+ }
817
+ }
818
+ var browserEvaluateTool = tool3({
819
+ name: "browser_evaluate",
820
+ description: "Evaluates JavaScript in the context of the current page.",
821
+ parameters: ToolParameters3,
822
+ execute: execute3
823
+ });
824
+
825
+ // tools/browser/browserGetContentTool.ts
826
+ import { tool as tool4 } from "@openai/agents";
827
+ import { z as z4 } from "zod";
828
+ var ToolParameters4 = z4.object({
829
+ type: z4.enum(["html", "text"]).default("html").describe("The type of content to retrieve (html or text).")
830
+ });
831
+ async function execute4({ type }) {
832
+ try {
833
+ const page2 = await getPage();
834
+ if (type === "text") {
835
+ return await page2.evaluate(() => document.body.innerText);
836
+ }
837
+ return await page2.content();
838
+ } catch (error) {
839
+ return `Error getting content: ${error}`;
840
+ }
841
+ }
842
+ var browserGetContentTool = tool4({
843
+ name: "browser_get_content",
844
+ description: "Gets the content (HTML or text) of the current page.",
845
+ parameters: ToolParameters4,
846
+ execute: execute4
847
+ });
848
+
849
+ // tools/browser/browserGetLogsTool.ts
850
+ import { tool as tool5 } from "@openai/agents";
851
+ import { z as z5 } from "zod";
852
+ var ToolParameters5 = z5.object({
853
+ clear: z5.boolean().default(false).describe("Whether to clear the logs after reading them.")
854
+ });
855
+ async function execute5({ clear }) {
856
+ const logs2 = getBrowserLogs();
857
+ const result = logs2.length > 0 ? logs2.join("\n") : "No logs found.";
858
+ if (clear) {
859
+ clearBrowserLogs();
860
+ }
861
+ return result;
862
+ }
863
+ var browserGetLogsTool = tool5({
864
+ name: "browser_get_logs",
865
+ description: "Returns the console logs from the browser.",
866
+ parameters: ToolParameters5,
867
+ execute: execute5
868
+ });
869
+
870
+ // tools/browser/browserIsElementPresentTool.ts
871
+ import { tool as tool6 } from "@openai/agents";
872
+ import { z as z6 } from "zod";
873
+ var ToolParameters6 = z6.object({
874
+ selector: z6.string().describe("The CSS selector of the element to check for presence.")
875
+ });
876
+ async function execute6({ selector }) {
877
+ try {
878
+ const page2 = await getPage();
879
+ const element = await page2.$(selector);
880
+ return element !== null ? `Element ${selector} is present.` : `Element ${selector} is not present.`;
881
+ } catch (error) {
882
+ return `Error checking for element ${selector}: ${error}`;
883
+ }
884
+ }
885
+ var browserIsElementPresentTool = tool6({
886
+ name: "browser_is_element_present",
887
+ description: "Checks if an element is present on the page.",
888
+ parameters: ToolParameters6,
889
+ execute: execute6
890
+ });
891
+
892
+ // tools/browser/browserNavigateTool.ts
893
+ import { tool as tool7 } from "@openai/agents";
894
+ import { z as z7 } from "zod";
895
+ var ToolParameters7 = z7.object({
896
+ url: z7.string().describe("The URL to navigate to."),
897
+ waitUntil: z7.enum(["load", "domcontentloaded", "networkidle0", "networkidle2"]).default("load").describe("When to consider navigation succeeded.")
898
+ });
899
+ async function execute7({ url, waitUntil }) {
900
+ try {
901
+ const page2 = await getPage();
902
+ await page2.goto(url, { waitUntil });
903
+ return `Successfully navigated to ${url}`;
904
+ } catch (error) {
905
+ return `Error navigating to ${url}: ${error}`;
906
+ }
907
+ }
908
+ var browserNavigateTool = tool7({
909
+ name: "browser_navigate",
910
+ description: "Navigates the browser to a specified URL.",
911
+ parameters: ToolParameters7,
912
+ execute: execute7
913
+ });
914
+
915
+ // tools/browser/browserScreenshotTool.ts
916
+ import { tool as tool8 } from "@openai/agents";
917
+ import { z as z8 } from "zod";
918
+ var ToolParameters8 = z8.object({
919
+ fullPage: z8.boolean().default(false).describe("Whether to take a screenshot of the full scrollable page.")
920
+ });
921
+ async function execute8({ fullPage }) {
922
+ try {
923
+ const page2 = await getPage();
924
+ const screenshot = await page2.screenshot({
925
+ encoding: "base64",
926
+ type: "jpeg",
927
+ quality: 80,
928
+ fullPage
929
+ });
930
+ return {
931
+ type: "image",
932
+ image: `data:image/jpeg;base64,${screenshot}`,
933
+ detail: "auto"
934
+ };
935
+ } catch (error) {
936
+ return `Error taking screenshot: ${error}`;
937
+ }
938
+ }
939
+ var browserScreenshotTool = tool8({
940
+ name: "browser_screenshot",
941
+ description: "Takes a screenshot of the current page.",
942
+ parameters: ToolParameters8,
943
+ execute: execute8
944
+ });
945
+
946
+ // tools/browser/browserTypeTool.ts
947
+ import { tool as tool9 } from "@openai/agents";
948
+ import { z as z9 } from "zod";
949
+ var ToolParameters9 = z9.object({
950
+ selector: z9.string().describe("The CSS selector of the element to type into."),
951
+ text: z9.string().describe("The text to type into the element."),
952
+ delay: z9.number().default(0).describe("Delay between key presses in milliseconds.")
953
+ });
954
+ async function execute9({ selector, text, delay }) {
955
+ try {
956
+ const page2 = await getPage();
957
+ await page2.type(selector, text, { delay });
958
+ return `Successfully typed into ${selector}`;
959
+ } catch (error) {
960
+ return `Error typing into ${selector}: ${error}`;
961
+ }
962
+ }
963
+ var browserTypeTool = tool9({
964
+ name: "browser_type",
965
+ description: "Types text into an element specified by a CSS selector.",
966
+ parameters: ToolParameters9,
967
+ execute: execute9
968
+ });
969
+
970
+ // tools/files/applyPatchTool.ts
971
+ import { tool as tool11 } from "@openai/agents";
972
+ import chalk7 from "chalk";
973
+ import { z as z11 } from "zod";
709
974
 
710
975
  // utils/files/printDiff.ts
711
976
  import chalk5 from "chalk";
@@ -746,11 +1011,11 @@ function getEnv(newKey, oldKey) {
746
1011
  }
747
1012
 
748
1013
  // tools/harper/getHarperSkillTool.ts
749
- import { tool } from "@openai/agents";
1014
+ import { tool as tool10 } from "@openai/agents";
750
1015
  import { readdirSync, readFileSync as readFileSync3 } from "fs";
751
1016
  import { createRequire } from "module";
752
1017
  import { dirname, join as join6 } from "path";
753
- import { z } from "zod";
1018
+ import { z as z10 } from "zod";
754
1019
  var createHarper = dirname(createRequire(import.meta.url).resolve("create-harper"));
755
1020
  var agentsMarkdown = join6(
756
1021
  createHarper,
@@ -763,16 +1028,16 @@ var skillsDir = join6(
763
1028
  );
764
1029
  var skillLinkRegex = /\[[^\]]+]\(skills\/([^)]+)\.md\)/g;
765
1030
  var skills = getSkills();
766
- var ToolParameters = z.object({
767
- skill: z.enum(skills.length > 0 ? skills : ["none"]).describe(
1031
+ var ToolParameters10 = z10.object({
1032
+ skill: z10.enum(skills.length > 0 ? skills : ["none"]).describe(
768
1033
  "The name of the skill to retrieve."
769
1034
  )
770
1035
  });
771
- var getHarperSkillTool = tool({
772
- name: "getHarperSkill",
1036
+ var getHarperSkillTool = tool10({
1037
+ name: "get_harper_skill",
773
1038
  description: getSkillsDescription(),
774
- parameters: ToolParameters,
775
- execute
1039
+ parameters: ToolParameters10,
1040
+ execute: execute10
776
1041
  });
777
1042
  function getSkillsDescription() {
778
1043
  try {
@@ -788,7 +1053,7 @@ function getSkills() {
788
1053
  return [];
789
1054
  }
790
1055
  }
791
- async function execute({ skill }) {
1056
+ async function execute10({ skill }) {
792
1057
  if (skill === "none") {
793
1058
  return "No skills found.";
794
1059
  }
@@ -933,10 +1198,10 @@ var WorkspaceEditor = class {
933
1198
  };
934
1199
 
935
1200
  // tools/files/applyPatchTool.ts
936
- var ApplyPatchParameters = z2.object({
937
- type: z2.enum(["create_file", "update_file", "delete_file"]).describe("The type of operation to perform."),
938
- path: z2.string().describe("The path to the file to operate on."),
939
- diff: z2.string().optional().default("").describe(
1201
+ var ApplyPatchParameters = z11.object({
1202
+ type: z11.enum(["create_file", "update_file", "delete_file"]).describe("The type of operation to perform."),
1203
+ path: z11.string().describe("The path to the file to operate on."),
1204
+ diff: z11.string().optional().default("").describe(
940
1205
  'The diff to apply. For create_file, every line must start with "+". For update_file, use a headerless unified diff format (start sections with "@@", and use "+", "-", or " " for lines). Do not include markers like "*** Begin Patch" or "*** Add File:".'
941
1206
  )
942
1207
  });
@@ -1011,7 +1276,7 @@ ${chalk7.bold.bgYellow.black(" Apply patch approval required: ")}`);
1011
1276
  }
1012
1277
  }
1013
1278
  function createApplyPatchTool() {
1014
- return tool2({
1279
+ return tool11({
1015
1280
  name: "apply_patch",
1016
1281
  description: "Applies a patch (create, update, or delete a file) to the workspace.",
1017
1282
  parameters: ApplyPatchParameters,
@@ -1020,7 +1285,7 @@ function createApplyPatchTool() {
1020
1285
  try {
1021
1286
  const needed = await requiredSkillForOperation(operation.path, operation.type);
1022
1287
  if (needed) {
1023
- const content = await execute({ skill: needed });
1288
+ const content = await execute10({ skill: needed });
1024
1289
  return { status: "completed", output: content };
1025
1290
  }
1026
1291
  switch (operation.type) {
@@ -1048,13 +1313,13 @@ function createApplyPatchTool() {
1048
1313
  }
1049
1314
 
1050
1315
  // tools/files/changeCwdTool.ts
1051
- import { tool as tool3 } from "@openai/agents";
1316
+ import { tool as tool12 } from "@openai/agents";
1052
1317
  import { statSync } from "fs";
1053
- import { z as z3 } from "zod";
1054
- var ToolParameters2 = z3.object({
1055
- path: z3.string().describe("Directory to switch into. Can be absolute or relative to current workspace.")
1318
+ import { z as z12 } from "zod";
1319
+ var ToolParameters11 = z12.object({
1320
+ path: z12.string().describe("Directory to switch into. Can be absolute or relative to current workspace.")
1056
1321
  });
1057
- async function execute2({ path: path8 }) {
1322
+ async function execute11({ path: path8 }) {
1058
1323
  try {
1059
1324
  const target = resolvePath(trackedState.cwd, path8);
1060
1325
  const stat = statSync(target);
@@ -1081,27 +1346,27 @@ I strongly suggest you use these newfound skills!`;
1081
1346
  return `Failed to change directory: ${err.message}`;
1082
1347
  }
1083
1348
  }
1084
- var changeCwdTool = tool3({
1085
- name: "changeCwd",
1349
+ var changeCwdTool = tool12({
1350
+ name: "change_cwd",
1086
1351
  description: "Changes the current working directory for subsequent tools. Accepts absolute or relative paths.",
1087
- parameters: ToolParameters2,
1088
- execute: execute2
1352
+ parameters: ToolParameters11,
1353
+ execute: execute11
1089
1354
  });
1090
1355
 
1091
1356
  // tools/files/egrepTool.ts
1092
- import { tool as tool4 } from "@openai/agents";
1357
+ import { tool as tool13 } from "@openai/agents";
1093
1358
  import { execFile } from "child_process";
1094
1359
  import { promisify } from "util";
1095
- import { z as z4 } from "zod";
1360
+ import { z as z13 } from "zod";
1096
1361
  var execFileAsync = promisify(execFile);
1097
- var ToolParameters3 = z4.object({
1098
- path: z4.string().describe("The path to start the search from."),
1099
- pattern: z4.string().describe("The pattern to search")
1362
+ var ToolParameters12 = z13.object({
1363
+ path: z13.string().describe("The path to start the search from."),
1364
+ pattern: z13.string().describe("The pattern to search")
1100
1365
  });
1101
- var egrepTool = tool4({
1366
+ var egrepTool = tool13({
1102
1367
  name: "egrep",
1103
1368
  description: "File pattern searcher.",
1104
- parameters: ToolParameters3,
1369
+ parameters: ToolParameters12,
1105
1370
  async execute({ path: searchPath, pattern }) {
1106
1371
  try {
1107
1372
  const resolvedPath = resolvePath(trackedState.cwd, searchPath);
@@ -1127,21 +1392,21 @@ var egrepTool = tool4({
1127
1392
  });
1128
1393
 
1129
1394
  // tools/files/findTool.ts
1130
- import { tool as tool5 } from "@openai/agents";
1395
+ import { tool as tool14 } from "@openai/agents";
1131
1396
  import { execFile as execFile2 } from "child_process";
1132
1397
  import { promisify as promisify2 } from "util";
1133
- import { z as z5 } from "zod";
1398
+ import { z as z14 } from "zod";
1134
1399
  var execFileAsync2 = promisify2(execFile2);
1135
- var ToolParameters4 = z5.object({
1136
- path: z5.string().describe("The path to start the search from."),
1137
- iname: z5.string().describe(
1400
+ var ToolParameters13 = z14.object({
1401
+ path: z14.string().describe("The path to start the search from."),
1402
+ iname: z14.string().describe(
1138
1403
  "Case insensitive, true if the last component of the pathname being examined matches pattern. Special shell pattern matching characters (\u201C[\u201D, \u201C]\u201D, \u201C*\u201D, and \u201C?\u201D) may be used as part of pattern. These characters may be matched explicitly by escaping them with a backslash (\u201C\\\u201D)."
1139
1404
  )
1140
1405
  });
1141
- var findTool = tool5({
1406
+ var findTool = tool14({
1142
1407
  name: "find",
1143
1408
  description: "Walk a file hierarchy.",
1144
- parameters: ToolParameters4,
1409
+ parameters: ToolParameters13,
1145
1410
  async execute({ path: searchPath, iname }) {
1146
1411
  try {
1147
1412
  const resolvedPath = resolvePath(trackedState.cwd, searchPath);
@@ -1154,17 +1419,17 @@ var findTool = tool5({
1154
1419
  });
1155
1420
 
1156
1421
  // tools/files/readDirTool.ts
1157
- import { tool as tool6 } from "@openai/agents";
1422
+ import { tool as tool15 } from "@openai/agents";
1158
1423
  import { readdir } from "fs/promises";
1159
1424
  import path5 from "path";
1160
- import { z as z6 } from "zod";
1161
- var ToolParameters5 = z6.object({
1162
- directoryName: z6.string().describe("The name of the directory to read.")
1425
+ import { z as z15 } from "zod";
1426
+ var ToolParameters14 = z15.object({
1427
+ directoryName: z15.string().describe("The name of the directory to read.")
1163
1428
  });
1164
- var readDirTool = tool6({
1165
- name: "readDir",
1429
+ var readDirTool = tool15({
1430
+ name: "read_dir",
1166
1431
  description: "Lists the files in a directory.",
1167
- parameters: ToolParameters5,
1432
+ parameters: ToolParameters14,
1168
1433
  async execute({ directoryName }) {
1169
1434
  try {
1170
1435
  const resolvedPath = resolvePath(trackedState.cwd, directoryName);
@@ -1177,51 +1442,70 @@ var readDirTool = tool6({
1177
1442
  });
1178
1443
 
1179
1444
  // tools/files/readFileTool.ts
1180
- import { tool as tool7 } from "@openai/agents";
1445
+ import { tool as tool16 } from "@openai/agents";
1181
1446
  import { readFile } from "fs/promises";
1182
- import { z as z7 } from "zod";
1183
- var ToolParameters6 = z7.object({
1184
- fileName: z7.string().describe("The name of the file to read.")
1447
+ import { extname } from "path";
1448
+ import { z as z16 } from "zod";
1449
+ var ToolParameters15 = z16.object({
1450
+ fileName: z16.string().describe("The name of the file to read.")
1185
1451
  });
1186
- var readFileTool = tool7({
1187
- name: "readFile",
1188
- description: "Reads the contents of a specified file.",
1189
- parameters: ToolParameters6,
1190
- async execute({ fileName }) {
1191
- try {
1192
- const normalized = String(fileName).replace(/\\/g, "/");
1193
- const m = normalized.match(/(?:^|\/)skills\/([A-Za-z0-9_-]+)\.md(?:$|[?#])/);
1194
- if (m && m[1]) {
1195
- trackedState.session?.addSkillRead?.(m[1]);
1196
- }
1197
- const resolvedPath = resolvePath(trackedState.cwd, fileName);
1198
- return readFile(resolvedPath, "utf8");
1199
- } catch (error) {
1200
- return `Error reading file: ${error}`;
1452
+ var IMAGE_EXTENSIONS = {
1453
+ ".png": "image/png",
1454
+ ".jpg": "image/jpeg",
1455
+ ".jpeg": "image/jpeg",
1456
+ ".gif": "image/gif",
1457
+ ".webp": "image/webp",
1458
+ ".bmp": "image/bmp"
1459
+ };
1460
+ async function execute12({ fileName }) {
1461
+ try {
1462
+ const normalized = String(fileName).replace(/\\/g, "/");
1463
+ const m = normalized.match(/(?:^|\/)skills\/([A-Za-z0-9_-]+)\.md(?:$|[?#])/);
1464
+ if (m && m[1]) {
1465
+ trackedState.session?.addSkillRead?.(m[1]);
1466
+ }
1467
+ const resolvedPath = resolvePath(trackedState.cwd, fileName);
1468
+ const ext = extname(resolvedPath).toLowerCase();
1469
+ if (IMAGE_EXTENSIONS[ext]) {
1470
+ const buffer = await readFile(resolvedPath);
1471
+ return {
1472
+ type: "image",
1473
+ image: `data:${IMAGE_EXTENSIONS[ext]};base64,${buffer.toString("base64")}`,
1474
+ detail: "auto"
1475
+ };
1201
1476
  }
1477
+ return await readFile(resolvedPath, "utf8");
1478
+ } catch (error) {
1479
+ return `Error reading file: ${error}`;
1202
1480
  }
1481
+ }
1482
+ var readFileTool = tool16({
1483
+ name: "read_file",
1484
+ description: "Reads the contents of a specified file. If the file is an image, it returns a structured image object.",
1485
+ parameters: ToolParameters15,
1486
+ execute: execute12
1203
1487
  });
1204
1488
 
1205
1489
  // tools/general/codeInterpreterTool.ts
1206
- import { tool as tool8 } from "@openai/agents";
1490
+ import { tool as tool17 } from "@openai/agents";
1207
1491
  import chalk8 from "chalk";
1208
1492
  import { exec } from "child_process";
1209
1493
  import { unlink, writeFile as writeFile2 } from "fs/promises";
1210
1494
  import path6 from "path";
1211
1495
  import { promisify as promisify3 } from "util";
1212
- import { z as z8 } from "zod";
1496
+ import { z as z17 } from "zod";
1213
1497
  var execAsync = promisify3(exec);
1214
- var CodeInterpreterParameters = z8.object({
1215
- code: z8.string().describe("The code to execute."),
1216
- language: z8.enum(["python", "javascript"]).optional().default("python").describe(
1498
+ var CodeInterpreterParameters = z17.object({
1499
+ code: z17.string().describe("The code to execute."),
1500
+ language: z17.enum(["python", "javascript"]).optional().default("python").describe(
1217
1501
  "The programming language of the code."
1218
1502
  )
1219
1503
  });
1220
- var codeInterpreterTool = tool8({
1504
+ var codeInterpreterTool = tool17({
1221
1505
  name: "code_interpreter",
1222
1506
  description: "Executes Python or JavaScript code in a local environment. This is useful for data analysis, complex calculations, and more. All code will be executed in the current workspace.",
1223
1507
  parameters: CodeInterpreterParameters,
1224
- execute: execute3,
1508
+ execute: execute13,
1225
1509
  needsApproval: needsApproval2
1226
1510
  });
1227
1511
  async function needsApproval2(runContext, { code, language }, callId) {
@@ -1243,7 +1527,7 @@ ${chalk8.bold.bgYellow.black(` Code interpreter (${language}) approval required:
1243
1527
  }
1244
1528
  return !autoApproved;
1245
1529
  }
1246
- async function execute3({ code, language }) {
1530
+ async function execute13({ code, language }) {
1247
1531
  const extension = language === "javascript" ? "js" : "py";
1248
1532
  const interpreter = language === "javascript" ? "node" : "python3";
1249
1533
  const tempFile = path6.join(trackedState.cwd, `.temp_code_${Date.now()}.${extension}`);
@@ -1265,8 +1549,8 @@ STDERR: ${error.stderr || ""}`;
1265
1549
  }
1266
1550
 
1267
1551
  // tools/general/setInterpreterAutoApproveTool.ts
1268
- import { tool as tool9 } from "@openai/agents";
1269
- import { z as z9 } from "zod";
1552
+ import { tool as tool18 } from "@openai/agents";
1553
+ import { z as z18 } from "zod";
1270
1554
 
1271
1555
  // utils/files/updateEnv.ts
1272
1556
  import { existsSync as existsSync6 } from "fs";
@@ -1293,11 +1577,11 @@ async function updateEnv(key, value) {
1293
1577
  }
1294
1578
 
1295
1579
  // tools/general/setInterpreterAutoApproveTool.ts
1296
- var SetInterpreterAutoApproveParameters = z9.object({
1297
- autoApprove: z9.boolean()
1580
+ var SetInterpreterAutoApproveParameters = z18.object({
1581
+ autoApprove: z18.boolean()
1298
1582
  });
1299
- var setInterpreterAutoApproveTool = tool9({
1300
- name: "setInterpreterAutoApproveTool",
1583
+ var setInterpreterAutoApproveTool = tool18({
1584
+ name: "set_interpreter_auto_approve",
1301
1585
  description: "Enable or disable automatic approval for code interpreter by setting HARPER_AGENT_AUTO_APPROVE_CODE_INTERPRETER=1 or 0 in .env and current process.",
1302
1586
  parameters: SetInterpreterAutoApproveParameters,
1303
1587
  needsApproval: async (_runContext, { autoApprove }) => {
@@ -1319,13 +1603,13 @@ var setInterpreterAutoApproveTool = tool9({
1319
1603
  });
1320
1604
 
1321
1605
  // tools/general/setPatchAutoApproveTool.ts
1322
- import { tool as tool10 } from "@openai/agents";
1323
- import { z as z10 } from "zod";
1324
- var SetPatchAutoApproveParameters = z10.object({
1325
- autoApprove: z10.boolean()
1606
+ import { tool as tool19 } from "@openai/agents";
1607
+ import { z as z19 } from "zod";
1608
+ var SetPatchAutoApproveParameters = z19.object({
1609
+ autoApprove: z19.boolean()
1326
1610
  });
1327
- var setPatchAutoApproveTool = tool10({
1328
- name: "setPatchAutoApproveTool",
1611
+ var setPatchAutoApproveTool = tool19({
1612
+ name: "set_patch_auto_approve",
1329
1613
  description: "Enable or disable automatic approval for patch commands by setting HARPER_AGENT_AUTO_APPROVE_PATCHES=1 or 0 in .env and current process.",
1330
1614
  parameters: SetPatchAutoApproveParameters,
1331
1615
  needsApproval: async (_runContext, { autoApprove }) => {
@@ -1347,13 +1631,13 @@ var setPatchAutoApproveTool = tool10({
1347
1631
  });
1348
1632
 
1349
1633
  // tools/general/setShellAutoApproveTool.ts
1350
- import { tool as tool11 } from "@openai/agents";
1351
- import { z as z11 } from "zod";
1352
- var SetShellAutoApproveParameters = z11.object({
1353
- autoApprove: z11.boolean()
1634
+ import { tool as tool20 } from "@openai/agents";
1635
+ import { z as z20 } from "zod";
1636
+ var SetShellAutoApproveParameters = z20.object({
1637
+ autoApprove: z20.boolean()
1354
1638
  });
1355
- var setShellAutoApproveTool = tool11({
1356
- name: "setShellAutoApproveTool",
1639
+ var setShellAutoApproveTool = tool20({
1640
+ name: "set_shell_auto_approve",
1357
1641
  description: "Enable or disable automatic approval for shell commands by setting HARPER_AGENT_AUTO_APPROVE_SHELL=1 or 0 in .env and current process.",
1358
1642
  parameters: SetShellAutoApproveParameters,
1359
1643
  needsApproval: async (_runContext, { autoApprove }) => {
@@ -1375,9 +1659,9 @@ var setShellAutoApproveTool = tool11({
1375
1659
  });
1376
1660
 
1377
1661
  // tools/general/shellTool.ts
1378
- import { tool as tool12 } from "@openai/agents";
1662
+ import { tool as tool21 } from "@openai/agents";
1379
1663
  import chalk9 from "chalk";
1380
- import { z as z12 } from "zod";
1664
+ import { z as z21 } from "zod";
1381
1665
 
1382
1666
  // utils/files/mentionsIgnoredPath.ts
1383
1667
  function mentionsIgnoredPath(command) {
@@ -1489,13 +1773,13 @@ var LocalShell = class {
1489
1773
  };
1490
1774
 
1491
1775
  // tools/general/shellTool.ts
1492
- var ShellParameters = z12.object({
1493
- commands: z12.array(z12.string()).describe("The commands to execute.")
1776
+ var ShellParameters = z21.object({
1777
+ commands: z21.array(z21.string()).describe("The commands to execute.")
1494
1778
  });
1495
1779
  var shell = new LocalShell();
1496
- var shellTool = tool12({
1497
- name: "shellToolForCommandsWithoutABetterTool",
1498
- description: "Executes shell commands.",
1780
+ var shellTool = tool21({
1781
+ name: "shell",
1782
+ description: "Executes shell commands. Only use when we do not have a better tool.",
1499
1783
  parameters: ShellParameters,
1500
1784
  execute: async ({ commands }) => {
1501
1785
  const result = await shell.run({ commands });
@@ -1550,16 +1834,16 @@ TIMEOUT`;
1550
1834
  });
1551
1835
 
1552
1836
  // tools/git/gitAddTool.ts
1553
- import { tool as tool13 } from "@openai/agents";
1837
+ import { tool as tool22 } from "@openai/agents";
1554
1838
  import { execFile as execFile3 } from "child_process";
1555
1839
  import { promisify as promisify5 } from "util";
1556
- import { z as z13 } from "zod";
1840
+ import { z as z22 } from "zod";
1557
1841
  var execFileAsync3 = promisify5(execFile3);
1558
- var GitAddParameters = z13.object({
1559
- files: z13.array(z13.string()).describe("The files to add. If not provided, all changes will be added.")
1842
+ var GitAddParameters = z22.object({
1843
+ files: z22.array(z22.string()).describe("The files to add. If not provided, all changes will be added.")
1560
1844
  });
1561
- var gitAddTool = tool13({
1562
- name: "gitAddTool",
1845
+ var gitAddTool = tool22({
1846
+ name: "git_add",
1563
1847
  description: "Add file contents to the index.",
1564
1848
  parameters: GitAddParameters,
1565
1849
  async execute({ files }) {
@@ -1579,17 +1863,17 @@ var gitAddTool = tool13({
1579
1863
  });
1580
1864
 
1581
1865
  // tools/git/gitBranchTool.ts
1582
- import { tool as tool14 } from "@openai/agents";
1866
+ import { tool as tool23 } from "@openai/agents";
1583
1867
  import { execFile as execFile4 } from "child_process";
1584
1868
  import { promisify as promisify6 } from "util";
1585
- import { z as z14 } from "zod";
1869
+ import { z as z23 } from "zod";
1586
1870
  var execFileAsync4 = promisify6(execFile4);
1587
- var GitBranchParameters = z14.object({
1588
- branchName: z14.string().describe("The name of the branch to create or switch to."),
1589
- create: z14.boolean().optional().default(false).describe("Whether to create a new branch.")
1871
+ var GitBranchParameters = z23.object({
1872
+ branchName: z23.string().describe("The name of the branch to create or switch to."),
1873
+ create: z23.boolean().optional().default(false).describe("Whether to create a new branch.")
1590
1874
  });
1591
- var gitBranchTool = tool14({
1592
- name: "gitBranchTool",
1875
+ var gitBranchTool = tool23({
1876
+ name: "git_branch",
1593
1877
  description: "Create or switch to a git branch.",
1594
1878
  parameters: GitBranchParameters,
1595
1879
  needsApproval: true,
@@ -1605,19 +1889,19 @@ var gitBranchTool = tool14({
1605
1889
  });
1606
1890
 
1607
1891
  // tools/git/gitCommitTool.ts
1608
- import { tool as tool15 } from "@openai/agents";
1892
+ import { tool as tool24 } from "@openai/agents";
1609
1893
  import { execFile as execFile5 } from "child_process";
1610
1894
  import { promisify as promisify7 } from "util";
1611
- import { z as z15 } from "zod";
1895
+ import { z as z24 } from "zod";
1612
1896
  var execFileAsync5 = promisify7(execFile5);
1613
- var GitCommitParameters = z15.object({
1614
- message: z15.string().describe("The commit message."),
1615
- addAll: z15.boolean().optional().default(false).describe(
1897
+ var GitCommitParameters = z24.object({
1898
+ message: z24.string().describe("The commit message."),
1899
+ addAll: z24.boolean().optional().default(false).describe(
1616
1900
  "Whether to add all changes before committing (git commit -am)."
1617
1901
  )
1618
1902
  });
1619
- var gitCommitTool = tool15({
1620
- name: "gitCommitTool",
1903
+ var gitCommitTool = tool24({
1904
+ name: "git_commit",
1621
1905
  description: "Commit changes to the repository.",
1622
1906
  parameters: GitCommitParameters,
1623
1907
  async execute({ message, addAll }) {
@@ -1632,17 +1916,17 @@ var gitCommitTool = tool15({
1632
1916
  });
1633
1917
 
1634
1918
  // tools/git/gitLogTool.ts
1635
- import { tool as tool16 } from "@openai/agents";
1919
+ import { tool as tool25 } from "@openai/agents";
1636
1920
  import { execFile as execFile6 } from "child_process";
1637
1921
  import { promisify as promisify8 } from "util";
1638
- import { z as z16 } from "zod";
1922
+ import { z as z25 } from "zod";
1639
1923
  var execFileAsync6 = promisify8(execFile6);
1640
- var GitLogParameters = z16.object({
1641
- count: z16.number().optional().default(10).describe("Number of commits to show."),
1642
- oneline: z16.boolean().optional().default(true).describe("Whether to show log in oneline format.")
1924
+ var GitLogParameters = z25.object({
1925
+ count: z25.number().optional().default(10).describe("Number of commits to show."),
1926
+ oneline: z25.boolean().optional().default(true).describe("Whether to show log in oneline format.")
1643
1927
  });
1644
- var gitLogTool = tool16({
1645
- name: "gitLogTool",
1928
+ var gitLogTool = tool25({
1929
+ name: "git_log",
1646
1930
  description: "Show commit logs.",
1647
1931
  parameters: GitLogParameters,
1648
1932
  async execute({ count, oneline }) {
@@ -1660,18 +1944,18 @@ var gitLogTool = tool16({
1660
1944
  });
1661
1945
 
1662
1946
  // tools/git/gitStashTool.ts
1663
- import { tool as tool17 } from "@openai/agents";
1947
+ import { tool as tool26 } from "@openai/agents";
1664
1948
  import { execFile as execFile7 } from "child_process";
1665
1949
  import { promisify as promisify9 } from "util";
1666
- import { z as z17 } from "zod";
1950
+ import { z as z26 } from "zod";
1667
1951
  var execFileAsync7 = promisify9(execFile7);
1668
1952
  var allowedActions = ["push", "pop", "apply", "list"];
1669
- var GitStashParameters = z17.object({
1670
- action: z17.string().describe("The stash action to perform: " + allowedActions.join(", ")),
1671
- message: z17.string().describe("A message for the stash change.")
1953
+ var GitStashParameters = z26.object({
1954
+ action: z26.string().describe("The stash action to perform: " + allowedActions.join(", ")),
1955
+ message: z26.string().describe("A message for the stash change.")
1672
1956
  });
1673
- var gitStashTool = tool17({
1674
- name: "gitStashTool",
1957
+ var gitStashTool = tool26({
1958
+ name: "git_stash",
1675
1959
  description: "Stash changes or apply a stash.",
1676
1960
  parameters: GitStashParameters,
1677
1961
  async execute({ action, message }) {
@@ -1692,16 +1976,16 @@ var gitStashTool = tool17({
1692
1976
  });
1693
1977
 
1694
1978
  // tools/git/gitStatusTool.ts
1695
- import { tool as tool18 } from "@openai/agents";
1979
+ import { tool as tool27 } from "@openai/agents";
1696
1980
  import { execFile as execFile8 } from "child_process";
1697
1981
  import { promisify as promisify10 } from "util";
1698
- import { z as z18 } from "zod";
1982
+ import { z as z27 } from "zod";
1699
1983
  var execFileAsync8 = promisify10(execFile8);
1700
- var GitStatusParameters = z18.object({
1701
- short: z18.boolean().optional().default(false).describe("Whether to show the status in short format.")
1984
+ var GitStatusParameters = z27.object({
1985
+ short: z27.boolean().optional().default(false).describe("Whether to show the status in short format.")
1702
1986
  });
1703
- var gitStatusTool = tool18({
1704
- name: "gitStatusTool",
1987
+ var gitStatusTool = tool27({
1988
+ name: "git_status",
1705
1989
  description: "Show the working tree status.",
1706
1990
  parameters: GitStatusParameters,
1707
1991
  async execute({ short }) {
@@ -1719,18 +2003,18 @@ var gitStatusTool = tool18({
1719
2003
  });
1720
2004
 
1721
2005
  // tools/git/gitWorkspaceTool.ts
1722
- import { tool as tool19 } from "@openai/agents";
2006
+ import { tool as tool28 } from "@openai/agents";
1723
2007
  import { execFile as execFile9 } from "child_process";
1724
2008
  import { promisify as promisify11 } from "util";
1725
- import { z as z19 } from "zod";
2009
+ import { z as z28 } from "zod";
1726
2010
  var execFileAsync9 = promisify11(execFile9);
1727
- var GitWorkspaceParameters = z19.object({
1728
- path: z19.string().describe("The path where the new workspace (worktree) should be created."),
1729
- branchName: z19.string().describe("The name of the branch to use in the new workspace."),
1730
- createBranch: z19.boolean().optional().default(false).describe("Whether to create a new branch for this workspace.")
2011
+ var GitWorkspaceParameters = z28.object({
2012
+ path: z28.string().describe("The path where the new workspace (worktree) should be created."),
2013
+ branchName: z28.string().describe("The name of the branch to use in the new workspace."),
2014
+ createBranch: z28.boolean().optional().default(false).describe("Whether to create a new branch for this workspace.")
1731
2015
  });
1732
- var gitWorkspaceTool = tool19({
1733
- name: "gitWorkspaceTool",
2016
+ var gitWorkspaceTool = tool28({
2017
+ name: "git_workspace",
1734
2018
  description: "Create a new workspace (git worktree) for parallel work.",
1735
2019
  parameters: GitWorkspaceParameters,
1736
2020
  async execute({ path: workspacePath, branchName, createBranch }) {
@@ -1746,13 +2030,13 @@ var gitWorkspaceTool = tool19({
1746
2030
  });
1747
2031
 
1748
2032
  // tools/harper/checkHarperStatusTool.ts
1749
- import { tool as tool20 } from "@openai/agents";
1750
- import { z as z20 } from "zod";
1751
- var ToolParameters7 = z20.object({});
1752
- var checkHarperStatusTool = tool20({
1753
- name: "checkHarperStatusTool",
2033
+ import { tool as tool29 } from "@openai/agents";
2034
+ import { z as z29 } from "zod";
2035
+ var ToolParameters16 = z29.object({});
2036
+ var checkHarperStatusTool = tool29({
2037
+ name: "check_harper_status",
1754
2038
  description: "Checks if a Harper application is currently running.",
1755
- parameters: ToolParameters7,
2039
+ parameters: ToolParameters16,
1756
2040
  async execute() {
1757
2041
  if (harperProcess.running) {
1758
2042
  return "A Harper application is currently running.";
@@ -1763,10 +2047,10 @@ var checkHarperStatusTool = tool20({
1763
2047
  });
1764
2048
 
1765
2049
  // tools/harper/createNewHarperApplicationTool.ts
1766
- import { tool as tool21 } from "@openai/agents";
2050
+ import { tool as tool30 } from "@openai/agents";
1767
2051
  import { execSync as execSync3 } from "child_process";
1768
2052
  import path7 from "path";
1769
- import { z as z21 } from "zod";
2053
+ import { z as z30 } from "zod";
1770
2054
 
1771
2055
  // utils/package/buildHarperCreateCommand.ts
1772
2056
  function buildCreateCommand(pm, appName, template) {
@@ -1816,11 +2100,11 @@ var PM_DISPLAY = {
1816
2100
  };
1817
2101
 
1818
2102
  // tools/harper/createNewHarperApplicationTool.ts
1819
- var ToolParameters8 = z21.object({
1820
- directoryName: z21.string().describe("The name of the directory to create the application in."),
1821
- template: z21.enum(["vanilla-ts", "vanilla", "react-ts", "react"]).optional().describe("The template to use for the new application. Defaults to vanilla-ts.").default("vanilla-ts")
2103
+ var ToolParameters17 = z30.object({
2104
+ directoryName: z30.string().describe("The name of the directory to create the application in."),
2105
+ template: z30.enum(["vanilla-ts", "vanilla", "react-ts", "react"]).optional().describe("The template to use for the new application. Defaults to vanilla-ts.").default("vanilla-ts")
1822
2106
  });
1823
- async function execute4({ directoryName, template }) {
2107
+ async function execute14({ directoryName, template }) {
1824
2108
  const currentCwd = trackedState.cwd;
1825
2109
  const resolvedPath = resolvePath(currentCwd, directoryName);
1826
2110
  const isCurrentDir = resolvedPath === currentCwd;
@@ -1837,7 +2121,7 @@ async function execute4({ directoryName, template }) {
1837
2121
  });
1838
2122
  console.log(`Initializing new Git repository in ${resolvedPath}...`);
1839
2123
  execSync3("git init", { cwd: resolvedPath, stdio: "ignore" });
1840
- const switchedDir = await execute2({ path: resolvedPath });
2124
+ const switchedDir = await execute11({ path: resolvedPath });
1841
2125
  return `Successfully created a new Harper application in '${resolvedPath}' using template '${template}' with a matching Git repository initialized. Use the readDir and readFile tools to inspect the contents of the application. ${switchedDir}.`;
1842
2126
  } catch (error) {
1843
2127
  let errorMsg = `Error creating new Harper application: ${error.message}`;
@@ -1850,28 +2134,28 @@ ${error.stdout}`;
1850
2134
  return errorMsg;
1851
2135
  }
1852
2136
  }
1853
- var createNewHarperApplicationTool = tool21({
1854
- name: "createNewHarperApplicationTool",
2137
+ var createNewHarperApplicationTool = tool30({
2138
+ name: "create_new_harper_application",
1855
2139
  description: "Creates a new Harper application using the best available package manager (yarn/pnpm/bun/deno, falling back to npm).",
1856
- parameters: ToolParameters8,
1857
- execute: execute4
2140
+ parameters: ToolParameters17,
2141
+ execute: execute14
1858
2142
  });
1859
2143
 
1860
2144
  // tools/harper/getHarperConfigSchemaTool.ts
1861
- import { tool as tool22 } from "@openai/agents";
2145
+ import { tool as tool31 } from "@openai/agents";
1862
2146
  import { readFile as readFile3 } from "fs/promises";
1863
2147
  import { createRequire as createRequire2 } from "module";
1864
2148
  import { dirname as dirname2, join as join8 } from "path";
1865
- import { z as z22 } from "zod";
1866
- var ToolParameters9 = z22.object({
1867
- schemaType: z22.enum(["app", "root"]).describe(
2149
+ import { z as z31 } from "zod";
2150
+ var ToolParameters18 = z31.object({
2151
+ schemaType: z31.enum(["app", "root"]).describe(
1868
2152
  'The type of configuration schema to retrieve: "app" for application configuration or "root" for root Harper configuration.'
1869
2153
  )
1870
2154
  });
1871
- var getHarperConfigSchemaTool = tool22({
1872
- name: "getHarperConfigSchemaTool",
2155
+ var getHarperConfigSchemaTool = tool31({
2156
+ name: "get_harper_config_schema",
1873
2157
  description: "Returns the JSON schema for HarperDB configuration files (either app or root), which describes the config.yaml or harperdb-config.yaml files.",
1874
- parameters: ToolParameters9,
2158
+ parameters: ToolParameters18,
1875
2159
  async execute({ schemaType }) {
1876
2160
  try {
1877
2161
  return await readFile3(
@@ -1888,13 +2172,13 @@ var getHarperConfigSchemaTool = tool22({
1888
2172
  });
1889
2173
 
1890
2174
  // tools/harper/getHarperResourceInterfaceTool.ts
1891
- import { tool as tool23 } from "@openai/agents";
2175
+ import { tool as tool32 } from "@openai/agents";
1892
2176
  import { readFile as readFile4 } from "fs/promises";
1893
2177
  import { createRequire as createRequire3 } from "module";
1894
2178
  import { dirname as dirname3, join as join9 } from "path";
1895
- import { z as z23 } from "zod";
1896
- var ToolParameters10 = z23.object({
1897
- resourceFile: z23.enum([
2179
+ import { z as z32 } from "zod";
2180
+ var ToolParameters19 = z32.object({
2181
+ resourceFile: z32.enum([
1898
2182
  "ResourceInterfaceV2",
1899
2183
  "ResourceInterface",
1900
2184
  "Table",
@@ -1904,10 +2188,10 @@ var ToolParameters10 = z23.object({
1904
2188
  "The resource-related definition file to read. Defaults to ResourceInterfaceV2."
1905
2189
  ).default("ResourceInterfaceV2")
1906
2190
  });
1907
- var getHarperResourceInterfaceTool = tool23({
1908
- name: "getHarperResourceInterfaceTool",
2191
+ var getHarperResourceInterfaceTool = tool32({
2192
+ name: "get_harper_resource_interface",
1909
2193
  description: "Reads HarperDB resource interface and class definitions (like ResourceInterfaceV2.d.ts) to understand how resources and tables are structured.",
1910
- parameters: ToolParameters10,
2194
+ parameters: ToolParameters19,
1911
2195
  async execute({ resourceFile }) {
1912
2196
  try {
1913
2197
  return await readFile4(
@@ -1925,16 +2209,16 @@ var getHarperResourceInterfaceTool = tool23({
1925
2209
  });
1926
2210
 
1927
2211
  // tools/harper/getHarperSchemaGraphQLTool.ts
1928
- import { tool as tool24 } from "@openai/agents";
2212
+ import { tool as tool33 } from "@openai/agents";
1929
2213
  import { readFile as readFile5 } from "fs/promises";
1930
2214
  import { createRequire as createRequire4 } from "module";
1931
2215
  import { dirname as dirname4, join as join10 } from "path";
1932
- import { z as z24 } from "zod";
1933
- var ToolParameters11 = z24.object({});
1934
- var getHarperSchemaGraphQLTool = tool24({
1935
- name: "getHarperSchemaGraphQLTool",
2216
+ import { z as z33 } from "zod";
2217
+ var ToolParameters20 = z33.object({});
2218
+ var getHarperSchemaGraphQLTool = tool33({
2219
+ name: "get_harper_schema_graphql",
1936
2220
  description: "Returns the GraphQL schema for HarperDB schema files, which define the structure of HarperDB database tables.",
1937
- parameters: ToolParameters11,
2221
+ parameters: ToolParameters20,
1938
2222
  async execute() {
1939
2223
  try {
1940
2224
  return await readFile5(
@@ -1951,24 +2235,24 @@ var getHarperSchemaGraphQLTool = tool24({
1951
2235
  });
1952
2236
 
1953
2237
  // tools/harper/hitHarperAPITool.ts
1954
- import { tool as tool25 } from "@openai/agents";
1955
- import { z as z25 } from "zod";
1956
- var ToolParameters12 = z25.object({
1957
- method: z25.enum(["POST", "GET", "PUT", "DELETE"]).optional().default("GET").describe(
2238
+ import { tool as tool34 } from "@openai/agents";
2239
+ import { z as z34 } from "zod";
2240
+ var ToolParameters21 = z34.object({
2241
+ method: z34.enum(["POST", "GET", "PUT", "DELETE"]).optional().default("GET").describe(
1958
2242
  'The HTTP method to use, defaults to "get". Notably, POST and PUT require the full body be sent.'
1959
2243
  ),
1960
- path: z25.string().optional().default("/openapi").describe("The path to fetch from localhost (defaults to /openapi)."),
1961
- port: z25.number().optional().default(harperProcess.httpPort).describe(
2244
+ path: z34.string().optional().default("/openapi").describe("The path to fetch from localhost (defaults to /openapi)."),
2245
+ port: z34.number().optional().default(harperProcess.httpPort).describe(
1962
2246
  "The port to fetch from localhost (defaults to the running Harper port)."
1963
2247
  ),
1964
- body: z25.string().optional().default("").describe("An optional JSON string body to send along with the request.")
2248
+ body: z34.string().optional().default("").describe("An optional JSON string body to send along with the request.")
1965
2249
  });
1966
- var hitHarperAPITool = tool25({
1967
- name: "hitHarperAPITool",
2250
+ var hitHarperAPITool = tool34({
2251
+ name: "hit_harper_api",
1968
2252
  description: "Performs a request against the running Harper API. Use /openapi to look up Harper APIs.",
1969
- parameters: ToolParameters12,
2253
+ parameters: ToolParameters21,
1970
2254
  needsApproval: async (runContext, input, callId) => {
1971
- if (callId && runContext.isToolApproved({ toolName: "hitHarperAPITool", callId })) {
2255
+ if (callId && runContext.isToolApproved({ toolName: "hit_harper_api", callId })) {
1972
2256
  return false;
1973
2257
  }
1974
2258
  if (input.method === "DELETE") {
@@ -2003,57 +2287,21 @@ var hitHarperAPITool = tool25({
2003
2287
  }
2004
2288
  });
2005
2289
 
2006
- // tools/harper/openHarperInBrowserTool.ts
2007
- import { tool as tool26 } from "@openai/agents";
2008
- import spawn2 from "cross-spawn";
2009
- import { platform } from "os";
2010
- import { z as z26 } from "zod";
2011
- var alreadyOpened = false;
2012
- var ToolParameters13 = z26.object({});
2013
- var openHarperInBrowserTool = tool26({
2014
- name: "openHarperInBrowserTool",
2015
- description: "Opens the running Harper app in the user's browser.",
2016
- parameters: ToolParameters13,
2017
- async execute() {
2018
- try {
2019
- if (alreadyOpened) {
2020
- return `Browser is already open.`;
2021
- }
2022
- if (!harperProcess.running) {
2023
- return `Error: No Harper application is currently running.`;
2024
- }
2025
- const url = `http://localhost:${harperProcess.httpPort}/`;
2026
- const p = platform();
2027
- if (p === "darwin") {
2028
- spawn2("open", [url]);
2029
- } else if (p === "win32") {
2030
- spawn2("start", ["", url]);
2031
- } else {
2032
- spawn2("xdg-open", [url]);
2033
- }
2034
- alreadyOpened = true;
2035
- return `Successfully opened '${url}' in the browser.`;
2036
- } catch (error) {
2037
- return `Error opening browser: ${error}`;
2038
- }
2039
- }
2040
- });
2041
-
2042
2290
  // tools/harper/readHarperLogsTool.ts
2043
- import { tool as tool27 } from "@openai/agents";
2044
- import { z as z27 } from "zod";
2045
- var ToolParameters14 = z27.object({});
2046
- var readHarperLogsTool = tool27({
2047
- name: "readHarperLogsTool",
2291
+ import { tool as tool35 } from "@openai/agents";
2292
+ import { z as z35 } from "zod";
2293
+ var ToolParameters22 = z35.object({});
2294
+ var readHarperLogsTool = tool35({
2295
+ name: "read_harper_logs",
2048
2296
  description: "Reads the most recent console logs of a started Harper app and clears them so that subsequent reads will only show new logs.",
2049
- parameters: ToolParameters14,
2297
+ parameters: ToolParameters22,
2050
2298
  async execute() {
2051
2299
  if (!harperProcess.running) {
2052
2300
  return `Error: No Harper application is currently running.`;
2053
2301
  }
2054
2302
  try {
2055
- const logs = harperProcess.getAndClearLogs();
2056
- return logs || "No logs available yet.";
2303
+ const logs2 = harperProcess.getAndClearLogs();
2304
+ return logs2 || "No logs available yet.";
2057
2305
  } catch (error) {
2058
2306
  return `Error reading Harper application logs: ${error}`;
2059
2307
  }
@@ -2061,10 +2309,10 @@ var readHarperLogsTool = tool27({
2061
2309
  });
2062
2310
 
2063
2311
  // tools/harper/startHarperTool.ts
2064
- import { tool as tool28 } from "@openai/agents";
2312
+ import { tool as tool36 } from "@openai/agents";
2065
2313
  import { existsSync as existsSync7 } from "fs";
2066
2314
  import { basename, resolve } from "path";
2067
- import { z as z28 } from "zod";
2315
+ import { z as z36 } from "zod";
2068
2316
 
2069
2317
  // utils/promises/sleep.ts
2070
2318
  function sleep(ms) {
@@ -2072,13 +2320,13 @@ function sleep(ms) {
2072
2320
  }
2073
2321
 
2074
2322
  // tools/harper/startHarperTool.ts
2075
- var ToolParameters15 = z28.object({
2076
- directoryName: z28.string().describe("The name of the directory that the Harper app is in.")
2323
+ var ToolParameters23 = z36.object({
2324
+ directoryName: z36.string().describe("The name of the directory that the Harper app is in.")
2077
2325
  });
2078
- var startHarperTool = tool28({
2079
- name: "startHarperTool",
2080
- description: "Starts a Harper app background process, allowing you to observe the app in action (by readHarperLogsTool, hitHarperAPITool, openHarperInBrowserTool, etc).",
2081
- parameters: ToolParameters15,
2326
+ var startHarperTool = tool36({
2327
+ name: "start_harper",
2328
+ description: "Starts a Harper app background process, allowing you to observe the app in action (by readHarperLogsTool, hitHarperAPITool, etc).",
2329
+ parameters: ToolParameters23,
2082
2330
  async execute({ directoryName }) {
2083
2331
  if (isIgnored(directoryName)) {
2084
2332
  return `Error: Target directory ${directoryName} is restricted by .aiignore`;
@@ -2097,9 +2345,9 @@ var startHarperTool = tool28({
2097
2345
  }
2098
2346
  harperProcess.start(effectiveDirectory);
2099
2347
  await sleep(5e3);
2100
- const logs = harperProcess.getAndClearLogs();
2348
+ const logs2 = harperProcess.getAndClearLogs();
2101
2349
  return `Successfully started Harper application with auto-reload in '${effectiveDirectory}' with initial logs:
2102
- ${logs}`;
2350
+ ${logs2}`;
2103
2351
  } catch (error) {
2104
2352
  return `Error: failed to start Harper application: ${error}`;
2105
2353
  }
@@ -2107,13 +2355,13 @@ ${logs}`;
2107
2355
  });
2108
2356
 
2109
2357
  // tools/harper/stopHarperTool.ts
2110
- import { tool as tool29 } from "@openai/agents";
2111
- import { z as z29 } from "zod";
2112
- var ToolParameters16 = z29.object({});
2113
- var stopHarperTool = tool29({
2114
- name: "stopHarperTool",
2358
+ import { tool as tool37 } from "@openai/agents";
2359
+ import { z as z37 } from "zod";
2360
+ var ToolParameters24 = z37.object({});
2361
+ var stopHarperTool = tool37({
2362
+ name: "stop_harper",
2115
2363
  description: "Stops all previously started Harper app background process.",
2116
- parameters: ToolParameters16,
2364
+ parameters: ToolParameters24,
2117
2365
  async execute() {
2118
2366
  if (!harperProcess.running) {
2119
2367
  return `Error: No Harper application is currently running.`;
@@ -2130,6 +2378,15 @@ var stopHarperTool = tool29({
2130
2378
  // tools/factory.ts
2131
2379
  function createTools() {
2132
2380
  return [
2381
+ browserClickTool,
2382
+ browserCloseTool,
2383
+ browserEvaluateTool,
2384
+ browserGetContentTool,
2385
+ browserGetLogsTool,
2386
+ browserIsElementPresentTool,
2387
+ browserNavigateTool,
2388
+ browserScreenshotTool,
2389
+ browserTypeTool,
2133
2390
  changeCwdTool,
2134
2391
  checkHarperStatusTool,
2135
2392
  codeInterpreterTool,
@@ -2149,7 +2406,6 @@ function createTools() {
2149
2406
  gitStatusTool,
2150
2407
  gitWorkspaceTool,
2151
2408
  hitHarperAPITool,
2152
- openHarperInBrowserTool,
2153
2409
  readDirTool,
2154
2410
  readFileTool,
2155
2411
  readHarperLogsTool,
@@ -2164,7 +2420,7 @@ function createTools() {
2164
2420
 
2165
2421
  // utils/package/checkForUpdate.ts
2166
2422
  import chalk10 from "chalk";
2167
- import spawn3 from "cross-spawn";
2423
+ import spawn2 from "cross-spawn";
2168
2424
 
2169
2425
  // utils/package/getLatestVersion.ts
2170
2426
  async function getLatestVersion(packageName) {
@@ -2224,7 +2480,7 @@ A new version of ${chalk10.bold(packageName)} is available! (${chalk10.dim(packa
2224
2480
  `);
2225
2481
  let isGlobal = false;
2226
2482
  try {
2227
- const globalRootResult = spawn3.sync("npm", ["root", "-g"], {
2483
+ const globalRootResult = spawn2.sync("npm", ["root", "-g"], {
2228
2484
  encoding: "utf8"
2229
2485
  });
2230
2486
  const globalRoot = globalRootResult.stdout?.trim();
@@ -2234,15 +2490,15 @@ A new version of ${chalk10.bold(packageName)} is available! (${chalk10.dim(packa
2234
2490
  } catch {
2235
2491
  }
2236
2492
  if (isGlobal) {
2237
- spawn3.sync("npm", ["install", "-g", `${packageName}@latest`], {
2493
+ spawn2.sync("npm", ["install", "-g", `${packageName}@latest`], {
2238
2494
  stdio: "inherit"
2239
2495
  });
2240
- const result2 = spawn3.sync("harper-agent", process.argv.slice(2), {
2496
+ const result2 = spawn2.sync("harper-agent", process.argv.slice(2), {
2241
2497
  stdio: "inherit"
2242
2498
  });
2243
2499
  process.exit(result2.status ?? 0);
2244
2500
  }
2245
- const lsResult = spawn3.sync("npm", ["cache", "npx", "ls", packageName], {
2501
+ const lsResult = spawn2.sync("npm", ["cache", "npx", "ls", packageName], {
2246
2502
  encoding: "utf8"
2247
2503
  });
2248
2504
  if (lsResult.stdout) {
@@ -2251,12 +2507,12 @@ A new version of ${chalk10.bold(packageName)} is available! (${chalk10.dim(packa
2251
2507
  return pkgPart && pkgPart.trim().startsWith(`${packageName}@`);
2252
2508
  }).map((line) => line.split(":")[0].trim());
2253
2509
  if (keys.length > 0) {
2254
- spawn3.sync("npm", ["cache", "npx", "rm", ...keys], {
2510
+ spawn2.sync("npm", ["cache", "npx", "rm", ...keys], {
2255
2511
  stdio: "inherit"
2256
2512
  });
2257
2513
  }
2258
2514
  }
2259
- const result = spawn3.sync("npx", ["-y", `${packageName}@latest`, ...process.argv.slice(2)], {
2515
+ const result = spawn2.sync("npx", ["-y", `${packageName}@latest`, ...process.argv.slice(2)], {
2260
2516
  stdio: "inherit"
2261
2517
  });
2262
2518
  process.exit(result.status ?? 0);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@harperfast/agent",
3
3
  "description": "AI to help you with Harper app management",
4
- "version": "0.12.1",
4
+ "version": "0.13.1",
5
5
  "main": "dist/agent.js",
6
6
  "repository": "github:HarperFast/harper-agent",
7
7
  "bugs": {
@@ -9,9 +9,9 @@
9
9
  },
10
10
  "homepage": "https://github.com/harperfast",
11
11
  "scripts": {
12
- "dev": "tsup agent.ts --format esm --clean --dts --watch",
12
+ "dev": "tsup agent.ts --format esm --clean --dts --watch --external puppeteer",
13
13
  "link": "npm run build && npm link",
14
- "build": "tsup agent.ts --format esm --clean --dts",
14
+ "build": "tsup agent.ts --format esm --clean --dts --external puppeteer",
15
15
  "commitlint": "commitlint --edit",
16
16
  "start": "node ./dist/agent.js",
17
17
  "lint": "oxlint --format stylish .",
@@ -42,19 +42,22 @@
42
42
  "license": "None",
43
43
  "type": "module",
44
44
  "dependencies": {
45
- "@ai-sdk/anthropic": "^3.0.36",
46
- "@ai-sdk/google": "^3.0.20",
47
- "@ai-sdk/openai": "^3.0.25",
48
- "@openai/agents": "^0.4.5",
49
- "@openai/agents-extensions": "^0.4.5",
50
- "ai": "^6.0.69",
45
+ "@ai-sdk/anthropic": "^3.0.41",
46
+ "@ai-sdk/google": "^3.0.24",
47
+ "@ai-sdk/openai": "^3.0.26",
48
+ "@openai/agents": "^0.4.6",
49
+ "@openai/agents-extensions": "^0.4.6",
50
+ "ai": "^6.0.79",
51
51
  "chalk": "^5.6.2",
52
- "create-harper": "^0.12.0",
52
+ "create-harper": "^0.12.4",
53
53
  "cross-spawn": "^7.0.6",
54
- "dotenv": "^17.2.3",
55
- "ollama-ai-provider-v2": "^3.0.3",
54
+ "dotenv": "^17.2.4",
55
+ "ollama-ai-provider-v2": "^3.3.0",
56
56
  "zod": "^4.3.6"
57
57
  },
58
+ "optionalDependencies": {
59
+ "puppeteer": "^24.37.2"
60
+ },
58
61
  "devDependencies": {
59
62
  "@commitlint/cli": "^20.4.1",
60
63
  "@commitlint/config-conventional": "^20.4.1",
@@ -69,7 +72,7 @@
69
72
  "conventional-changelog-conventionalcommits": "^9.1.0",
70
73
  "dprint": "^0.51.1",
71
74
  "express": "^5.2.1",
72
- "harperdb": "^4.7.17",
75
+ "harperdb": "^4.7.19",
73
76
  "hono": "^4.11.9",
74
77
  "husky": "^9.1.7",
75
78
  "oxlint": "^1.43.0",