@harperfast/agent 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +396 -289
- package/package.json +4 -3
package/dist/agent.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// agent.ts
|
|
4
4
|
import "dotenv/config";
|
|
5
|
-
import { Agent as
|
|
5
|
+
import { Agent as Agent2, run as run2 } from "@openai/agents";
|
|
6
6
|
import chalk13 from "chalk";
|
|
7
7
|
|
|
8
8
|
// lifecycle/cleanUpAndSayBye.ts
|
|
@@ -302,7 +302,6 @@ function harperResponse(text) {
|
|
|
302
302
|
import process2 from "process";
|
|
303
303
|
|
|
304
304
|
// lifecycle/trackedState.ts
|
|
305
|
-
import "@openai/agents";
|
|
306
305
|
var trackedState = {
|
|
307
306
|
agent: null,
|
|
308
307
|
cwd: process.cwd(),
|
|
@@ -315,7 +314,8 @@ var trackedState = {
|
|
|
315
314
|
sessionPath: null,
|
|
316
315
|
useFlexTier: false,
|
|
317
316
|
disableSpinner: false,
|
|
318
|
-
enableInterruptions: true
|
|
317
|
+
enableInterruptions: true,
|
|
318
|
+
session: null
|
|
319
319
|
};
|
|
320
320
|
|
|
321
321
|
// utils/shell/spinner.ts
|
|
@@ -469,6 +469,9 @@ function normalizeOllamaBaseUrl(baseUrl) {
|
|
|
469
469
|
return urlObj.toString().replace(/\/$/, "");
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
+
// lifecycle/parseArgs.ts
|
|
473
|
+
import path from "path";
|
|
474
|
+
|
|
472
475
|
// utils/shell/cli.ts
|
|
473
476
|
import chalk3 from "chalk";
|
|
474
477
|
|
|
@@ -628,6 +631,10 @@ function parseArgs() {
|
|
|
628
631
|
if (!trackedState.sessionPath && process.env.HARPER_AGENT_SESSION) {
|
|
629
632
|
trackedState.sessionPath = process.env.HARPER_AGENT_SESSION;
|
|
630
633
|
}
|
|
634
|
+
const sp = trackedState.sessionPath;
|
|
635
|
+
if (sp) {
|
|
636
|
+
trackedState.sessionPath = sp && !sp.startsWith("~") && !path.isAbsolute(sp) ? path.resolve(process.cwd(), sp) : sp;
|
|
637
|
+
}
|
|
631
638
|
if (!trackedState.useFlexTier && isTrue(process.env.HARPER_AGENT_FLEX_TIER)) {
|
|
632
639
|
trackedState.useFlexTier = true;
|
|
633
640
|
}
|
|
@@ -696,9 +703,9 @@ function sayHi() {
|
|
|
696
703
|
}
|
|
697
704
|
|
|
698
705
|
// tools/files/applyPatchTool.ts
|
|
699
|
-
import { tool } from "@openai/agents";
|
|
706
|
+
import { tool as tool2 } from "@openai/agents";
|
|
700
707
|
import chalk7 from "chalk";
|
|
701
|
-
import { z } from "zod";
|
|
708
|
+
import { z as z2 } from "zod";
|
|
702
709
|
|
|
703
710
|
// utils/files/printDiff.ts
|
|
704
711
|
import chalk5 from "chalk";
|
|
@@ -738,11 +745,68 @@ function getEnv(newKey, oldKey) {
|
|
|
738
745
|
return void 0;
|
|
739
746
|
}
|
|
740
747
|
|
|
748
|
+
// tools/harper/getHarperSkillTool.ts
|
|
749
|
+
import { tool } from "@openai/agents";
|
|
750
|
+
import { readdirSync, readFileSync as readFileSync3 } from "fs";
|
|
751
|
+
import { createRequire } from "module";
|
|
752
|
+
import { dirname, join as join6 } from "path";
|
|
753
|
+
import { z } from "zod";
|
|
754
|
+
var createHarper = dirname(createRequire(import.meta.url).resolve("create-harper"));
|
|
755
|
+
var agentsMarkdown = join6(
|
|
756
|
+
createHarper,
|
|
757
|
+
"AGENTS.md"
|
|
758
|
+
);
|
|
759
|
+
var skillsDir = join6(
|
|
760
|
+
createHarper,
|
|
761
|
+
"template-vanilla",
|
|
762
|
+
"skills"
|
|
763
|
+
);
|
|
764
|
+
var skillLinkRegex = /\[[^\]]+]\(skills\/([^)]+)\.md\)/g;
|
|
765
|
+
var skills = getSkills();
|
|
766
|
+
var ToolParameters = z.object({
|
|
767
|
+
skill: z.enum(skills.length > 0 ? skills : ["none"]).describe(
|
|
768
|
+
"The name of the skill to retrieve."
|
|
769
|
+
)
|
|
770
|
+
});
|
|
771
|
+
var getHarperSkillTool = tool({
|
|
772
|
+
name: "getHarperSkill",
|
|
773
|
+
description: getSkillsDescription(),
|
|
774
|
+
parameters: ToolParameters,
|
|
775
|
+
execute
|
|
776
|
+
});
|
|
777
|
+
function getSkillsDescription() {
|
|
778
|
+
try {
|
|
779
|
+
return readFileSync3(agentsMarkdown, "utf8").replace("This repository contains", "This tool describes").replace(skillLinkRegex, "$1");
|
|
780
|
+
} catch {
|
|
781
|
+
return "Returns the contents of a Harper skill markdown file. Skills provide guidance on developing Harper applications.";
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
function getSkills() {
|
|
785
|
+
try {
|
|
786
|
+
return readdirSync(skillsDir).filter((file) => file.endsWith(".md")).map((file) => file.replace(".md", ""));
|
|
787
|
+
} catch {
|
|
788
|
+
return [];
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
async function execute({ skill }) {
|
|
792
|
+
if (skill === "none") {
|
|
793
|
+
return "No skills found.";
|
|
794
|
+
}
|
|
795
|
+
try {
|
|
796
|
+
const filePath = join6(skillsDir, `${skill}.md`);
|
|
797
|
+
const content = readFileSync3(filePath, "utf8");
|
|
798
|
+
trackedState.session?.addSkillRead?.(skill);
|
|
799
|
+
return content;
|
|
800
|
+
} catch (error) {
|
|
801
|
+
return `Error reading Harper skill "${skill}": ${error}`;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
|
|
741
805
|
// tools/files/workspaceEditor.ts
|
|
742
806
|
import { applyDiff } from "@openai/agents";
|
|
743
|
-
import { existsSync as existsSync5, readFileSync as
|
|
807
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
744
808
|
import { mkdir, rm, writeFile } from "fs/promises";
|
|
745
|
-
import
|
|
809
|
+
import path4 from "path";
|
|
746
810
|
|
|
747
811
|
// utils/files/normalizeDiff.ts
|
|
748
812
|
function normalizeDiff(diff) {
|
|
@@ -759,17 +823,17 @@ function normalizeDiff(diff) {
|
|
|
759
823
|
}
|
|
760
824
|
|
|
761
825
|
// utils/files/paths.ts
|
|
762
|
-
import
|
|
826
|
+
import path3 from "path";
|
|
763
827
|
|
|
764
828
|
// utils/files/aiignore.ts
|
|
765
|
-
import { existsSync as existsSync4, readFileSync as
|
|
766
|
-
import
|
|
829
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
830
|
+
import path2 from "path";
|
|
767
831
|
var ignorePatterns = [];
|
|
768
832
|
function loadAiIgnore() {
|
|
769
|
-
const ignorePath =
|
|
833
|
+
const ignorePath = path2.join(trackedState.cwd, ".aiignore");
|
|
770
834
|
if (existsSync4(ignorePath)) {
|
|
771
835
|
try {
|
|
772
|
-
const content =
|
|
836
|
+
const content = readFileSync4(ignorePath, "utf8");
|
|
773
837
|
ignorePatterns = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((pattern) => pattern.endsWith("/") || pattern.endsWith("\\") ? pattern.slice(0, -1) : pattern);
|
|
774
838
|
} catch (error) {
|
|
775
839
|
console.error(`Error reading .aiignore: ${error}`);
|
|
@@ -780,39 +844,39 @@ function loadAiIgnore() {
|
|
|
780
844
|
}
|
|
781
845
|
}
|
|
782
846
|
function isIgnored(filePath) {
|
|
783
|
-
const directParts =
|
|
847
|
+
const directParts = path2.normalize(filePath).split(path2.sep);
|
|
784
848
|
if (directParts.includes(".aiignore")) {
|
|
785
849
|
return true;
|
|
786
850
|
}
|
|
787
|
-
const absolutePath =
|
|
788
|
-
const relativePath =
|
|
789
|
-
if (relativePath.startsWith("..") ||
|
|
851
|
+
const absolutePath = path2.resolve(trackedState.cwd, filePath);
|
|
852
|
+
const relativePath = path2.relative(trackedState.cwd, absolutePath);
|
|
853
|
+
if (relativePath.startsWith("..") || path2.isAbsolute(relativePath)) {
|
|
790
854
|
return false;
|
|
791
855
|
}
|
|
792
|
-
const
|
|
793
|
-
const parts =
|
|
856
|
+
const normalizedPath2 = path2.normalize(relativePath);
|
|
857
|
+
const parts = normalizedPath2.split(path2.sep);
|
|
794
858
|
loadAiIgnore();
|
|
795
859
|
if (ignorePatterns.length === 0) {
|
|
796
860
|
return false;
|
|
797
861
|
}
|
|
798
862
|
return ignorePatterns.some((pattern) => {
|
|
799
863
|
if (pattern.startsWith("/")) {
|
|
800
|
-
const normalizedPattern =
|
|
801
|
-
return
|
|
864
|
+
const normalizedPattern = path2.normalize(pattern.substring(1));
|
|
865
|
+
return normalizedPath2 === normalizedPattern || normalizedPath2.startsWith(normalizedPattern + path2.sep);
|
|
802
866
|
}
|
|
803
867
|
return parts.some((part, index) => {
|
|
804
|
-
const subPath = parts.slice(index).join(
|
|
805
|
-
const normalizedPattern =
|
|
806
|
-
return subPath === normalizedPattern || subPath.startsWith(normalizedPattern +
|
|
868
|
+
const subPath = parts.slice(index).join(path2.sep);
|
|
869
|
+
const normalizedPattern = path2.normalize(pattern);
|
|
870
|
+
return subPath === normalizedPattern || subPath.startsWith(normalizedPattern + path2.sep);
|
|
807
871
|
});
|
|
808
872
|
});
|
|
809
873
|
}
|
|
810
874
|
|
|
811
875
|
// utils/files/paths.ts
|
|
812
876
|
function resolvePath(root, relativePath) {
|
|
813
|
-
const resolved =
|
|
814
|
-
const relative =
|
|
815
|
-
if (relative.startsWith("..") ||
|
|
877
|
+
const resolved = path3.resolve(root, relativePath);
|
|
878
|
+
const relative = path3.relative(root, resolved);
|
|
879
|
+
if (relative.startsWith("..") || path3.isAbsolute(relative)) {
|
|
816
880
|
throw new Error(`Operation outside workspace: ${relativePath}`);
|
|
817
881
|
}
|
|
818
882
|
if (isIgnored(resolved)) {
|
|
@@ -830,7 +894,7 @@ var WorkspaceEditor = class {
|
|
|
830
894
|
async createFile(operation) {
|
|
831
895
|
try {
|
|
832
896
|
const targetPath = resolvePath(this.root(), operation.path);
|
|
833
|
-
await mkdir(
|
|
897
|
+
await mkdir(path4.dirname(targetPath), { recursive: true });
|
|
834
898
|
const normalizedDiff = normalizeDiff(operation.diff);
|
|
835
899
|
const content = applyDiff("", normalizedDiff, "create");
|
|
836
900
|
await writeFile(targetPath, content, "utf8");
|
|
@@ -845,7 +909,7 @@ var WorkspaceEditor = class {
|
|
|
845
909
|
if (!existsSync5(targetPath)) {
|
|
846
910
|
return { status: "failed", output: "Error: file not found at path " + targetPath };
|
|
847
911
|
}
|
|
848
|
-
const original =
|
|
912
|
+
const original = readFileSync5(targetPath, "utf8");
|
|
849
913
|
const normalizedDiff = normalizeDiff(operation.diff);
|
|
850
914
|
const patched = applyDiff(original, normalizedDiff);
|
|
851
915
|
await writeFile(targetPath, patched, "utf8");
|
|
@@ -869,48 +933,96 @@ var WorkspaceEditor = class {
|
|
|
869
933
|
};
|
|
870
934
|
|
|
871
935
|
// tools/files/applyPatchTool.ts
|
|
872
|
-
var ApplyPatchParameters =
|
|
873
|
-
type:
|
|
874
|
-
path:
|
|
875
|
-
diff:
|
|
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(
|
|
876
940
|
'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:".'
|
|
877
941
|
)
|
|
878
942
|
});
|
|
943
|
+
function normalizedPath(p) {
|
|
944
|
+
return p.replace(/\\/g, "/").replace(/^\.\/?/, "");
|
|
945
|
+
}
|
|
946
|
+
async function getSkillsRead() {
|
|
947
|
+
try {
|
|
948
|
+
const s = trackedState.session;
|
|
949
|
+
const arr = await Promise.resolve(s?.getSkillsRead?.());
|
|
950
|
+
return Array.isArray(arr) ? arr : [];
|
|
951
|
+
} catch {
|
|
952
|
+
return [];
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
function pickExistingSkill(candidates) {
|
|
956
|
+
for (const c of candidates) {
|
|
957
|
+
if (skills.includes(c)) {
|
|
958
|
+
return c;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
async function requiredSkillForOperation(path8, type) {
|
|
964
|
+
if (type === "delete_file") {
|
|
965
|
+
return null;
|
|
966
|
+
}
|
|
967
|
+
const p = normalizedPath(path8);
|
|
968
|
+
const read = await getSkillsRead();
|
|
969
|
+
if (p.includes("/resources/") || p.startsWith("resources/")) {
|
|
970
|
+
if (!read.includes("custom-resources") && !read.includes("extending-tables")) {
|
|
971
|
+
return pickExistingSkill(["custom-resources", "extending-tables"]);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
if (p.includes("/schemas/") || p.startsWith("schemas/") || p.includes("/schema/") || p.startsWith("schema/")) {
|
|
975
|
+
if (!read.includes("adding-tables-with-schemas")) {
|
|
976
|
+
return pickExistingSkill(["adding-tables-with-schemas"]);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return null;
|
|
980
|
+
}
|
|
981
|
+
var editor = new WorkspaceEditor(() => trackedState.cwd);
|
|
982
|
+
async function needsApproval(runContext, operation, callId) {
|
|
983
|
+
try {
|
|
984
|
+
const needed = await requiredSkillForOperation(operation.path, operation.type);
|
|
985
|
+
if (needed) {
|
|
986
|
+
return false;
|
|
987
|
+
}
|
|
988
|
+
if (callId && runContext.isToolApproved({ toolName: "apply_patch", callId })) {
|
|
989
|
+
return false;
|
|
990
|
+
}
|
|
991
|
+
const autoApproved = getEnv("HARPER_AGENT_AUTO_APPROVE_PATCHES", "APPLY_PATCH_AUTO_APPROVE") === "1";
|
|
992
|
+
spinner.stop();
|
|
993
|
+
if (autoApproved) {
|
|
994
|
+
console.log(`
|
|
995
|
+
${chalk7.bold.bgGreen.black(" Apply patch (auto-approved): ")}`);
|
|
996
|
+
} else {
|
|
997
|
+
console.log(`
|
|
998
|
+
${chalk7.bold.bgYellow.black(" Apply patch approval required: ")}`);
|
|
999
|
+
}
|
|
1000
|
+
console.log(`${chalk7.bold(operation.type)}: ${operation.path}`);
|
|
1001
|
+
if (operation.diff) {
|
|
1002
|
+
printDiff(operation.diff);
|
|
1003
|
+
}
|
|
1004
|
+
if (autoApproved) {
|
|
1005
|
+
spinner.start();
|
|
1006
|
+
}
|
|
1007
|
+
return !autoApproved;
|
|
1008
|
+
} catch (err) {
|
|
1009
|
+
console.error("apply_patch approval step failed:", err);
|
|
1010
|
+
return false;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
879
1013
|
function createApplyPatchTool() {
|
|
880
|
-
|
|
881
|
-
return tool({
|
|
1014
|
+
return tool2({
|
|
882
1015
|
name: "apply_patch",
|
|
883
1016
|
description: "Applies a patch (create, update, or delete a file) to the workspace.",
|
|
884
1017
|
parameters: ApplyPatchParameters,
|
|
885
|
-
needsApproval
|
|
886
|
-
try {
|
|
887
|
-
if (callId && runContext.isToolApproved({ toolName: "apply_patch", callId })) {
|
|
888
|
-
return false;
|
|
889
|
-
}
|
|
890
|
-
const autoApproved = getEnv("HARPER_AGENT_AUTO_APPROVE_PATCHES", "APPLY_PATCH_AUTO_APPROVE") === "1";
|
|
891
|
-
spinner.stop();
|
|
892
|
-
if (autoApproved) {
|
|
893
|
-
console.log(`
|
|
894
|
-
${chalk7.bold.bgGreen.black(" Apply patch (auto-approved): ")}`);
|
|
895
|
-
} else {
|
|
896
|
-
console.log(`
|
|
897
|
-
${chalk7.bold.bgYellow.black(" Apply patch approval required: ")}`);
|
|
898
|
-
}
|
|
899
|
-
console.log(`${chalk7.bold(operation.type)}: ${operation.path}`);
|
|
900
|
-
if (operation.diff) {
|
|
901
|
-
printDiff(operation.diff);
|
|
902
|
-
}
|
|
903
|
-
if (autoApproved) {
|
|
904
|
-
spinner.start();
|
|
905
|
-
}
|
|
906
|
-
return !autoApproved;
|
|
907
|
-
} catch (err) {
|
|
908
|
-
console.error("apply_patch approval step failed:", err);
|
|
909
|
-
return false;
|
|
910
|
-
}
|
|
911
|
-
},
|
|
1018
|
+
needsApproval,
|
|
912
1019
|
execute: async (operation) => {
|
|
913
1020
|
try {
|
|
1021
|
+
const needed = await requiredSkillForOperation(operation.path, operation.type);
|
|
1022
|
+
if (needed) {
|
|
1023
|
+
const content = await execute({ skill: needed });
|
|
1024
|
+
return { status: "completed", output: content };
|
|
1025
|
+
}
|
|
914
1026
|
switch (operation.type) {
|
|
915
1027
|
case "create_file":
|
|
916
1028
|
if (!operation.diff) {
|
|
@@ -936,15 +1048,15 @@ ${chalk7.bold.bgYellow.black(" Apply patch approval required: ")}`);
|
|
|
936
1048
|
}
|
|
937
1049
|
|
|
938
1050
|
// tools/files/changeCwdTool.ts
|
|
939
|
-
import { tool as
|
|
1051
|
+
import { tool as tool3 } from "@openai/agents";
|
|
940
1052
|
import { statSync } from "fs";
|
|
941
|
-
import { z as
|
|
942
|
-
var
|
|
943
|
-
path:
|
|
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.")
|
|
944
1056
|
});
|
|
945
|
-
async function
|
|
1057
|
+
async function execute2({ path: path8 }) {
|
|
946
1058
|
try {
|
|
947
|
-
const target = resolvePath(trackedState.cwd,
|
|
1059
|
+
const target = resolvePath(trackedState.cwd, path8);
|
|
948
1060
|
const stat = statSync(target);
|
|
949
1061
|
if (!stat.isDirectory()) {
|
|
950
1062
|
console.log(`Path is not a directory: ${target}`);
|
|
@@ -958,7 +1070,7 @@ async function execute({ path: path7 }) {
|
|
|
958
1070
|
if (trackedState.agent) {
|
|
959
1071
|
trackedState.agent.instructions = agentsMDContents;
|
|
960
1072
|
}
|
|
961
|
-
console.log("Detected AGENTS.md, reading its contents
|
|
1073
|
+
console.log("Detected AGENTS.md, reading its contents.");
|
|
962
1074
|
return `Switched current working directory to ${trackedState.cwd}, with a AGENTS.md file containing:
|
|
963
1075
|
${agentsMDContents}
|
|
964
1076
|
I strongly suggest you use these newfound skills!`;
|
|
@@ -969,27 +1081,27 @@ I strongly suggest you use these newfound skills!`;
|
|
|
969
1081
|
return `Failed to change directory: ${err.message}`;
|
|
970
1082
|
}
|
|
971
1083
|
}
|
|
972
|
-
var changeCwdTool =
|
|
1084
|
+
var changeCwdTool = tool3({
|
|
973
1085
|
name: "changeCwd",
|
|
974
1086
|
description: "Changes the current working directory for subsequent tools. Accepts absolute or relative paths.",
|
|
975
|
-
parameters:
|
|
976
|
-
execute
|
|
1087
|
+
parameters: ToolParameters2,
|
|
1088
|
+
execute: execute2
|
|
977
1089
|
});
|
|
978
1090
|
|
|
979
1091
|
// tools/files/egrepTool.ts
|
|
980
|
-
import { tool as
|
|
1092
|
+
import { tool as tool4 } from "@openai/agents";
|
|
981
1093
|
import { execFile } from "child_process";
|
|
982
1094
|
import { promisify } from "util";
|
|
983
|
-
import { z as
|
|
1095
|
+
import { z as z4 } from "zod";
|
|
984
1096
|
var execFileAsync = promisify(execFile);
|
|
985
|
-
var
|
|
986
|
-
path:
|
|
987
|
-
pattern:
|
|
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")
|
|
988
1100
|
});
|
|
989
|
-
var egrepTool =
|
|
1101
|
+
var egrepTool = tool4({
|
|
990
1102
|
name: "egrep",
|
|
991
1103
|
description: "File pattern searcher.",
|
|
992
|
-
parameters:
|
|
1104
|
+
parameters: ToolParameters3,
|
|
993
1105
|
async execute({ path: searchPath, pattern }) {
|
|
994
1106
|
try {
|
|
995
1107
|
const resolvedPath = resolvePath(trackedState.cwd, searchPath);
|
|
@@ -1015,21 +1127,21 @@ var egrepTool = tool3({
|
|
|
1015
1127
|
});
|
|
1016
1128
|
|
|
1017
1129
|
// tools/files/findTool.ts
|
|
1018
|
-
import { tool as
|
|
1130
|
+
import { tool as tool5 } from "@openai/agents";
|
|
1019
1131
|
import { execFile as execFile2 } from "child_process";
|
|
1020
1132
|
import { promisify as promisify2 } from "util";
|
|
1021
|
-
import { z as
|
|
1133
|
+
import { z as z5 } from "zod";
|
|
1022
1134
|
var execFileAsync2 = promisify2(execFile2);
|
|
1023
|
-
var
|
|
1024
|
-
path:
|
|
1025
|
-
iname:
|
|
1135
|
+
var ToolParameters4 = z5.object({
|
|
1136
|
+
path: z5.string().describe("The path to start the search from."),
|
|
1137
|
+
iname: z5.string().describe(
|
|
1026
1138
|
"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)."
|
|
1027
1139
|
)
|
|
1028
1140
|
});
|
|
1029
|
-
var findTool =
|
|
1141
|
+
var findTool = tool5({
|
|
1030
1142
|
name: "find",
|
|
1031
1143
|
description: "Walk a file hierarchy.",
|
|
1032
|
-
parameters:
|
|
1144
|
+
parameters: ToolParameters4,
|
|
1033
1145
|
async execute({ path: searchPath, iname }) {
|
|
1034
1146
|
try {
|
|
1035
1147
|
const resolvedPath = resolvePath(trackedState.cwd, searchPath);
|
|
@@ -1042,22 +1154,22 @@ var findTool = tool4({
|
|
|
1042
1154
|
});
|
|
1043
1155
|
|
|
1044
1156
|
// tools/files/readDirTool.ts
|
|
1045
|
-
import { tool as
|
|
1157
|
+
import { tool as tool6 } from "@openai/agents";
|
|
1046
1158
|
import { readdir } from "fs/promises";
|
|
1047
|
-
import
|
|
1048
|
-
import { z as
|
|
1049
|
-
var
|
|
1050
|
-
directoryName:
|
|
1159
|
+
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.")
|
|
1051
1163
|
});
|
|
1052
|
-
var readDirTool =
|
|
1164
|
+
var readDirTool = tool6({
|
|
1053
1165
|
name: "readDir",
|
|
1054
1166
|
description: "Lists the files in a directory.",
|
|
1055
|
-
parameters:
|
|
1167
|
+
parameters: ToolParameters5,
|
|
1056
1168
|
async execute({ directoryName }) {
|
|
1057
1169
|
try {
|
|
1058
1170
|
const resolvedPath = resolvePath(trackedState.cwd, directoryName);
|
|
1059
1171
|
const files = await readdir(resolvedPath, "utf8");
|
|
1060
|
-
return files.filter((file) => !isIgnored(
|
|
1172
|
+
return files.filter((file) => !isIgnored(path5.join(resolvedPath, file)));
|
|
1061
1173
|
} catch (error) {
|
|
1062
1174
|
return `Error reading directory: ${error}`;
|
|
1063
1175
|
}
|
|
@@ -1065,18 +1177,23 @@ var readDirTool = tool5({
|
|
|
1065
1177
|
});
|
|
1066
1178
|
|
|
1067
1179
|
// tools/files/readFileTool.ts
|
|
1068
|
-
import { tool as
|
|
1180
|
+
import { tool as tool7 } from "@openai/agents";
|
|
1069
1181
|
import { readFile } from "fs/promises";
|
|
1070
|
-
import { z as
|
|
1071
|
-
var
|
|
1072
|
-
fileName:
|
|
1182
|
+
import { z as z7 } from "zod";
|
|
1183
|
+
var ToolParameters6 = z7.object({
|
|
1184
|
+
fileName: z7.string().describe("The name of the file to read.")
|
|
1073
1185
|
});
|
|
1074
|
-
var readFileTool =
|
|
1186
|
+
var readFileTool = tool7({
|
|
1075
1187
|
name: "readFile",
|
|
1076
1188
|
description: "Reads the contents of a specified file.",
|
|
1077
|
-
parameters:
|
|
1189
|
+
parameters: ToolParameters6,
|
|
1078
1190
|
async execute({ fileName }) {
|
|
1079
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
|
+
}
|
|
1080
1197
|
const resolvedPath = resolvePath(trackedState.cwd, fileName);
|
|
1081
1198
|
return readFile(resolvedPath, "utf8");
|
|
1082
1199
|
} catch (error) {
|
|
@@ -1086,28 +1203,28 @@ var readFileTool = tool6({
|
|
|
1086
1203
|
});
|
|
1087
1204
|
|
|
1088
1205
|
// tools/general/codeInterpreterTool.ts
|
|
1089
|
-
import { tool as
|
|
1206
|
+
import { tool as tool8 } from "@openai/agents";
|
|
1090
1207
|
import chalk8 from "chalk";
|
|
1091
1208
|
import { exec } from "child_process";
|
|
1092
1209
|
import { unlink, writeFile as writeFile2 } from "fs/promises";
|
|
1093
|
-
import
|
|
1210
|
+
import path6 from "path";
|
|
1094
1211
|
import { promisify as promisify3 } from "util";
|
|
1095
|
-
import { z as
|
|
1212
|
+
import { z as z8 } from "zod";
|
|
1096
1213
|
var execAsync = promisify3(exec);
|
|
1097
|
-
var CodeInterpreterParameters =
|
|
1098
|
-
code:
|
|
1099
|
-
language:
|
|
1214
|
+
var CodeInterpreterParameters = z8.object({
|
|
1215
|
+
code: z8.string().describe("The code to execute."),
|
|
1216
|
+
language: z8.enum(["python", "javascript"]).optional().default("python").describe(
|
|
1100
1217
|
"The programming language of the code."
|
|
1101
1218
|
)
|
|
1102
1219
|
});
|
|
1103
|
-
var codeInterpreterTool =
|
|
1220
|
+
var codeInterpreterTool = tool8({
|
|
1104
1221
|
name: "code_interpreter",
|
|
1105
1222
|
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.",
|
|
1106
1223
|
parameters: CodeInterpreterParameters,
|
|
1107
|
-
execute:
|
|
1108
|
-
needsApproval
|
|
1224
|
+
execute: execute3,
|
|
1225
|
+
needsApproval: needsApproval2
|
|
1109
1226
|
});
|
|
1110
|
-
async function
|
|
1227
|
+
async function needsApproval2(runContext, { code, language }, callId) {
|
|
1111
1228
|
if (callId && runContext.isToolApproved({ toolName: "code_interpreter", callId })) {
|
|
1112
1229
|
return false;
|
|
1113
1230
|
}
|
|
@@ -1126,10 +1243,10 @@ ${chalk8.bold.bgYellow.black(` Code interpreter (${language}) approval required:
|
|
|
1126
1243
|
}
|
|
1127
1244
|
return !autoApproved;
|
|
1128
1245
|
}
|
|
1129
|
-
async function
|
|
1246
|
+
async function execute3({ code, language }) {
|
|
1130
1247
|
const extension = language === "javascript" ? "js" : "py";
|
|
1131
1248
|
const interpreter = language === "javascript" ? "node" : "python3";
|
|
1132
|
-
const tempFile =
|
|
1249
|
+
const tempFile = path6.join(trackedState.cwd, `.temp_code_${Date.now()}.${extension}`);
|
|
1133
1250
|
try {
|
|
1134
1251
|
await writeFile2(tempFile, code, "utf8");
|
|
1135
1252
|
const { stdout, stderr } = await execAsync(`${interpreter} ${tempFile}`);
|
|
@@ -1148,16 +1265,16 @@ STDERR: ${error.stderr || ""}`;
|
|
|
1148
1265
|
}
|
|
1149
1266
|
|
|
1150
1267
|
// tools/general/setInterpreterAutoApproveTool.ts
|
|
1151
|
-
import { tool as
|
|
1152
|
-
import { z as
|
|
1268
|
+
import { tool as tool9 } from "@openai/agents";
|
|
1269
|
+
import { z as z9 } from "zod";
|
|
1153
1270
|
|
|
1154
1271
|
// utils/files/updateEnv.ts
|
|
1155
1272
|
import { existsSync as existsSync6 } from "fs";
|
|
1156
1273
|
import { readFile as readFile2, writeFile as writeFile3 } from "fs/promises";
|
|
1157
|
-
import { join as
|
|
1274
|
+
import { join as join7 } from "path";
|
|
1158
1275
|
async function updateEnv(key, value) {
|
|
1159
1276
|
process.env[key] = value;
|
|
1160
|
-
const envPath =
|
|
1277
|
+
const envPath = join7(trackedState.cwd, ".env");
|
|
1161
1278
|
let envContent = "";
|
|
1162
1279
|
if (existsSync6(envPath)) {
|
|
1163
1280
|
envContent = await readFile2(envPath, "utf8");
|
|
@@ -1176,10 +1293,10 @@ async function updateEnv(key, value) {
|
|
|
1176
1293
|
}
|
|
1177
1294
|
|
|
1178
1295
|
// tools/general/setInterpreterAutoApproveTool.ts
|
|
1179
|
-
var SetInterpreterAutoApproveParameters =
|
|
1180
|
-
autoApprove:
|
|
1296
|
+
var SetInterpreterAutoApproveParameters = z9.object({
|
|
1297
|
+
autoApprove: z9.boolean()
|
|
1181
1298
|
});
|
|
1182
|
-
var setInterpreterAutoApproveTool =
|
|
1299
|
+
var setInterpreterAutoApproveTool = tool9({
|
|
1183
1300
|
name: "setInterpreterAutoApproveTool",
|
|
1184
1301
|
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.",
|
|
1185
1302
|
parameters: SetInterpreterAutoApproveParameters,
|
|
@@ -1202,12 +1319,12 @@ var setInterpreterAutoApproveTool = tool8({
|
|
|
1202
1319
|
});
|
|
1203
1320
|
|
|
1204
1321
|
// tools/general/setPatchAutoApproveTool.ts
|
|
1205
|
-
import { tool as
|
|
1206
|
-
import { z as
|
|
1207
|
-
var SetPatchAutoApproveParameters =
|
|
1208
|
-
autoApprove:
|
|
1322
|
+
import { tool as tool10 } from "@openai/agents";
|
|
1323
|
+
import { z as z10 } from "zod";
|
|
1324
|
+
var SetPatchAutoApproveParameters = z10.object({
|
|
1325
|
+
autoApprove: z10.boolean()
|
|
1209
1326
|
});
|
|
1210
|
-
var setPatchAutoApproveTool =
|
|
1327
|
+
var setPatchAutoApproveTool = tool10({
|
|
1211
1328
|
name: "setPatchAutoApproveTool",
|
|
1212
1329
|
description: "Enable or disable automatic approval for patch commands by setting HARPER_AGENT_AUTO_APPROVE_PATCHES=1 or 0 in .env and current process.",
|
|
1213
1330
|
parameters: SetPatchAutoApproveParameters,
|
|
@@ -1230,12 +1347,12 @@ var setPatchAutoApproveTool = tool9({
|
|
|
1230
1347
|
});
|
|
1231
1348
|
|
|
1232
1349
|
// tools/general/setShellAutoApproveTool.ts
|
|
1233
|
-
import { tool as
|
|
1234
|
-
import { z as
|
|
1235
|
-
var SetShellAutoApproveParameters =
|
|
1236
|
-
autoApprove:
|
|
1350
|
+
import { tool as tool11 } from "@openai/agents";
|
|
1351
|
+
import { z as z11 } from "zod";
|
|
1352
|
+
var SetShellAutoApproveParameters = z11.object({
|
|
1353
|
+
autoApprove: z11.boolean()
|
|
1237
1354
|
});
|
|
1238
|
-
var setShellAutoApproveTool =
|
|
1355
|
+
var setShellAutoApproveTool = tool11({
|
|
1239
1356
|
name: "setShellAutoApproveTool",
|
|
1240
1357
|
description: "Enable or disable automatic approval for shell commands by setting HARPER_AGENT_AUTO_APPROVE_SHELL=1 or 0 in .env and current process.",
|
|
1241
1358
|
parameters: SetShellAutoApproveParameters,
|
|
@@ -1258,9 +1375,9 @@ var setShellAutoApproveTool = tool10({
|
|
|
1258
1375
|
});
|
|
1259
1376
|
|
|
1260
1377
|
// tools/general/shellTool.ts
|
|
1261
|
-
import { tool as
|
|
1378
|
+
import { tool as tool12 } from "@openai/agents";
|
|
1262
1379
|
import chalk9 from "chalk";
|
|
1263
|
-
import { z as
|
|
1380
|
+
import { z as z12 } from "zod";
|
|
1264
1381
|
|
|
1265
1382
|
// utils/files/mentionsIgnoredPath.ts
|
|
1266
1383
|
function mentionsIgnoredPath(command) {
|
|
@@ -1372,11 +1489,11 @@ var LocalShell = class {
|
|
|
1372
1489
|
};
|
|
1373
1490
|
|
|
1374
1491
|
// tools/general/shellTool.ts
|
|
1375
|
-
var ShellParameters =
|
|
1376
|
-
commands:
|
|
1492
|
+
var ShellParameters = z12.object({
|
|
1493
|
+
commands: z12.array(z12.string()).describe("The commands to execute.")
|
|
1377
1494
|
});
|
|
1378
1495
|
var shell = new LocalShell();
|
|
1379
|
-
var shellTool =
|
|
1496
|
+
var shellTool = tool12({
|
|
1380
1497
|
name: "shellToolForCommandsWithoutABetterTool",
|
|
1381
1498
|
description: "Executes shell commands.",
|
|
1382
1499
|
parameters: ShellParameters,
|
|
@@ -1433,15 +1550,15 @@ TIMEOUT`;
|
|
|
1433
1550
|
});
|
|
1434
1551
|
|
|
1435
1552
|
// tools/git/gitAddTool.ts
|
|
1436
|
-
import { tool as
|
|
1553
|
+
import { tool as tool13 } from "@openai/agents";
|
|
1437
1554
|
import { execFile as execFile3 } from "child_process";
|
|
1438
1555
|
import { promisify as promisify5 } from "util";
|
|
1439
|
-
import { z as
|
|
1556
|
+
import { z as z13 } from "zod";
|
|
1440
1557
|
var execFileAsync3 = promisify5(execFile3);
|
|
1441
|
-
var GitAddParameters =
|
|
1442
|
-
files:
|
|
1558
|
+
var GitAddParameters = z13.object({
|
|
1559
|
+
files: z13.array(z13.string()).describe("The files to add. If not provided, all changes will be added.")
|
|
1443
1560
|
});
|
|
1444
|
-
var gitAddTool =
|
|
1561
|
+
var gitAddTool = tool13({
|
|
1445
1562
|
name: "gitAddTool",
|
|
1446
1563
|
description: "Add file contents to the index.",
|
|
1447
1564
|
parameters: GitAddParameters,
|
|
@@ -1462,16 +1579,16 @@ var gitAddTool = tool12({
|
|
|
1462
1579
|
});
|
|
1463
1580
|
|
|
1464
1581
|
// tools/git/gitBranchTool.ts
|
|
1465
|
-
import { tool as
|
|
1582
|
+
import { tool as tool14 } from "@openai/agents";
|
|
1466
1583
|
import { execFile as execFile4 } from "child_process";
|
|
1467
1584
|
import { promisify as promisify6 } from "util";
|
|
1468
|
-
import { z as
|
|
1585
|
+
import { z as z14 } from "zod";
|
|
1469
1586
|
var execFileAsync4 = promisify6(execFile4);
|
|
1470
|
-
var GitBranchParameters =
|
|
1471
|
-
branchName:
|
|
1472
|
-
create:
|
|
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.")
|
|
1473
1590
|
});
|
|
1474
|
-
var gitBranchTool =
|
|
1591
|
+
var gitBranchTool = tool14({
|
|
1475
1592
|
name: "gitBranchTool",
|
|
1476
1593
|
description: "Create or switch to a git branch.",
|
|
1477
1594
|
parameters: GitBranchParameters,
|
|
@@ -1488,18 +1605,18 @@ var gitBranchTool = tool13({
|
|
|
1488
1605
|
});
|
|
1489
1606
|
|
|
1490
1607
|
// tools/git/gitCommitTool.ts
|
|
1491
|
-
import { tool as
|
|
1608
|
+
import { tool as tool15 } from "@openai/agents";
|
|
1492
1609
|
import { execFile as execFile5 } from "child_process";
|
|
1493
1610
|
import { promisify as promisify7 } from "util";
|
|
1494
|
-
import { z as
|
|
1611
|
+
import { z as z15 } from "zod";
|
|
1495
1612
|
var execFileAsync5 = promisify7(execFile5);
|
|
1496
|
-
var GitCommitParameters =
|
|
1497
|
-
message:
|
|
1498
|
-
addAll:
|
|
1613
|
+
var GitCommitParameters = z15.object({
|
|
1614
|
+
message: z15.string().describe("The commit message."),
|
|
1615
|
+
addAll: z15.boolean().optional().default(false).describe(
|
|
1499
1616
|
"Whether to add all changes before committing (git commit -am)."
|
|
1500
1617
|
)
|
|
1501
1618
|
});
|
|
1502
|
-
var gitCommitTool =
|
|
1619
|
+
var gitCommitTool = tool15({
|
|
1503
1620
|
name: "gitCommitTool",
|
|
1504
1621
|
description: "Commit changes to the repository.",
|
|
1505
1622
|
parameters: GitCommitParameters,
|
|
@@ -1515,16 +1632,16 @@ var gitCommitTool = tool14({
|
|
|
1515
1632
|
});
|
|
1516
1633
|
|
|
1517
1634
|
// tools/git/gitLogTool.ts
|
|
1518
|
-
import { tool as
|
|
1635
|
+
import { tool as tool16 } from "@openai/agents";
|
|
1519
1636
|
import { execFile as execFile6 } from "child_process";
|
|
1520
1637
|
import { promisify as promisify8 } from "util";
|
|
1521
|
-
import { z as
|
|
1638
|
+
import { z as z16 } from "zod";
|
|
1522
1639
|
var execFileAsync6 = promisify8(execFile6);
|
|
1523
|
-
var GitLogParameters =
|
|
1524
|
-
count:
|
|
1525
|
-
oneline:
|
|
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.")
|
|
1526
1643
|
});
|
|
1527
|
-
var gitLogTool =
|
|
1644
|
+
var gitLogTool = tool16({
|
|
1528
1645
|
name: "gitLogTool",
|
|
1529
1646
|
description: "Show commit logs.",
|
|
1530
1647
|
parameters: GitLogParameters,
|
|
@@ -1543,17 +1660,17 @@ var gitLogTool = tool15({
|
|
|
1543
1660
|
});
|
|
1544
1661
|
|
|
1545
1662
|
// tools/git/gitStashTool.ts
|
|
1546
|
-
import { tool as
|
|
1663
|
+
import { tool as tool17 } from "@openai/agents";
|
|
1547
1664
|
import { execFile as execFile7 } from "child_process";
|
|
1548
1665
|
import { promisify as promisify9 } from "util";
|
|
1549
|
-
import { z as
|
|
1666
|
+
import { z as z17 } from "zod";
|
|
1550
1667
|
var execFileAsync7 = promisify9(execFile7);
|
|
1551
1668
|
var allowedActions = ["push", "pop", "apply", "list"];
|
|
1552
|
-
var GitStashParameters =
|
|
1553
|
-
action:
|
|
1554
|
-
message:
|
|
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.")
|
|
1555
1672
|
});
|
|
1556
|
-
var gitStashTool =
|
|
1673
|
+
var gitStashTool = tool17({
|
|
1557
1674
|
name: "gitStashTool",
|
|
1558
1675
|
description: "Stash changes or apply a stash.",
|
|
1559
1676
|
parameters: GitStashParameters,
|
|
@@ -1575,15 +1692,15 @@ var gitStashTool = tool16({
|
|
|
1575
1692
|
});
|
|
1576
1693
|
|
|
1577
1694
|
// tools/git/gitStatusTool.ts
|
|
1578
|
-
import { tool as
|
|
1695
|
+
import { tool as tool18 } from "@openai/agents";
|
|
1579
1696
|
import { execFile as execFile8 } from "child_process";
|
|
1580
1697
|
import { promisify as promisify10 } from "util";
|
|
1581
|
-
import { z as
|
|
1698
|
+
import { z as z18 } from "zod";
|
|
1582
1699
|
var execFileAsync8 = promisify10(execFile8);
|
|
1583
|
-
var GitStatusParameters =
|
|
1584
|
-
short:
|
|
1700
|
+
var GitStatusParameters = z18.object({
|
|
1701
|
+
short: z18.boolean().optional().default(false).describe("Whether to show the status in short format.")
|
|
1585
1702
|
});
|
|
1586
|
-
var gitStatusTool =
|
|
1703
|
+
var gitStatusTool = tool18({
|
|
1587
1704
|
name: "gitStatusTool",
|
|
1588
1705
|
description: "Show the working tree status.",
|
|
1589
1706
|
parameters: GitStatusParameters,
|
|
@@ -1602,17 +1719,17 @@ var gitStatusTool = tool17({
|
|
|
1602
1719
|
});
|
|
1603
1720
|
|
|
1604
1721
|
// tools/git/gitWorkspaceTool.ts
|
|
1605
|
-
import { tool as
|
|
1722
|
+
import { tool as tool19 } from "@openai/agents";
|
|
1606
1723
|
import { execFile as execFile9 } from "child_process";
|
|
1607
1724
|
import { promisify as promisify11 } from "util";
|
|
1608
|
-
import { z as
|
|
1725
|
+
import { z as z19 } from "zod";
|
|
1609
1726
|
var execFileAsync9 = promisify11(execFile9);
|
|
1610
|
-
var GitWorkspaceParameters =
|
|
1611
|
-
path:
|
|
1612
|
-
branchName:
|
|
1613
|
-
createBranch:
|
|
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.")
|
|
1614
1731
|
});
|
|
1615
|
-
var gitWorkspaceTool =
|
|
1732
|
+
var gitWorkspaceTool = tool19({
|
|
1616
1733
|
name: "gitWorkspaceTool",
|
|
1617
1734
|
description: "Create a new workspace (git worktree) for parallel work.",
|
|
1618
1735
|
parameters: GitWorkspaceParameters,
|
|
@@ -1629,13 +1746,13 @@ var gitWorkspaceTool = tool18({
|
|
|
1629
1746
|
});
|
|
1630
1747
|
|
|
1631
1748
|
// tools/harper/checkHarperStatusTool.ts
|
|
1632
|
-
import { tool as
|
|
1633
|
-
import { z as
|
|
1634
|
-
var
|
|
1635
|
-
var checkHarperStatusTool =
|
|
1749
|
+
import { tool as tool20 } from "@openai/agents";
|
|
1750
|
+
import { z as z20 } from "zod";
|
|
1751
|
+
var ToolParameters7 = z20.object({});
|
|
1752
|
+
var checkHarperStatusTool = tool20({
|
|
1636
1753
|
name: "checkHarperStatusTool",
|
|
1637
1754
|
description: "Checks if a Harper application is currently running.",
|
|
1638
|
-
parameters:
|
|
1755
|
+
parameters: ToolParameters7,
|
|
1639
1756
|
async execute() {
|
|
1640
1757
|
if (harperProcess.running) {
|
|
1641
1758
|
return "A Harper application is currently running.";
|
|
@@ -1646,10 +1763,10 @@ var checkHarperStatusTool = tool19({
|
|
|
1646
1763
|
});
|
|
1647
1764
|
|
|
1648
1765
|
// tools/harper/createNewHarperApplicationTool.ts
|
|
1649
|
-
import { tool as
|
|
1766
|
+
import { tool as tool21 } from "@openai/agents";
|
|
1650
1767
|
import { execSync as execSync3 } from "child_process";
|
|
1651
|
-
import
|
|
1652
|
-
import { z as
|
|
1768
|
+
import path7 from "path";
|
|
1769
|
+
import { z as z21 } from "zod";
|
|
1653
1770
|
|
|
1654
1771
|
// utils/package/buildHarperCreateCommand.ts
|
|
1655
1772
|
function buildCreateCommand(pm, appName, template) {
|
|
@@ -1699,16 +1816,16 @@ var PM_DISPLAY = {
|
|
|
1699
1816
|
};
|
|
1700
1817
|
|
|
1701
1818
|
// tools/harper/createNewHarperApplicationTool.ts
|
|
1702
|
-
var
|
|
1703
|
-
directoryName:
|
|
1704
|
-
template:
|
|
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")
|
|
1705
1822
|
});
|
|
1706
|
-
async function
|
|
1823
|
+
async function execute4({ directoryName, template }) {
|
|
1707
1824
|
const currentCwd = trackedState.cwd;
|
|
1708
1825
|
const resolvedPath = resolvePath(currentCwd, directoryName);
|
|
1709
1826
|
const isCurrentDir = resolvedPath === currentCwd;
|
|
1710
|
-
const executionCwd = isCurrentDir ? resolvedPath :
|
|
1711
|
-
const appName = isCurrentDir ? "." :
|
|
1827
|
+
const executionCwd = isCurrentDir ? resolvedPath : path7.dirname(resolvedPath);
|
|
1828
|
+
const appName = isCurrentDir ? "." : path7.basename(resolvedPath);
|
|
1712
1829
|
try {
|
|
1713
1830
|
console.log(`Creating new Harper application in ${resolvedPath} using template ${template}...`);
|
|
1714
1831
|
const pm = pickPreferredPackageManager();
|
|
@@ -1720,7 +1837,7 @@ async function execute3({ directoryName, template }) {
|
|
|
1720
1837
|
});
|
|
1721
1838
|
console.log(`Initializing new Git repository in ${resolvedPath}...`);
|
|
1722
1839
|
execSync3("git init", { cwd: resolvedPath, stdio: "ignore" });
|
|
1723
|
-
const switchedDir = await
|
|
1840
|
+
const switchedDir = await execute2({ path: resolvedPath });
|
|
1724
1841
|
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}.`;
|
|
1725
1842
|
} catch (error) {
|
|
1726
1843
|
let errorMsg = `Error creating new Harper application: ${error.message}`;
|
|
@@ -1733,33 +1850,33 @@ ${error.stdout}`;
|
|
|
1733
1850
|
return errorMsg;
|
|
1734
1851
|
}
|
|
1735
1852
|
}
|
|
1736
|
-
var createNewHarperApplicationTool =
|
|
1853
|
+
var createNewHarperApplicationTool = tool21({
|
|
1737
1854
|
name: "createNewHarperApplicationTool",
|
|
1738
1855
|
description: "Creates a new Harper application using the best available package manager (yarn/pnpm/bun/deno, falling back to npm).",
|
|
1739
|
-
parameters:
|
|
1740
|
-
execute:
|
|
1856
|
+
parameters: ToolParameters8,
|
|
1857
|
+
execute: execute4
|
|
1741
1858
|
});
|
|
1742
1859
|
|
|
1743
1860
|
// tools/harper/getHarperConfigSchemaTool.ts
|
|
1744
|
-
import { tool as
|
|
1861
|
+
import { tool as tool22 } from "@openai/agents";
|
|
1745
1862
|
import { readFile as readFile3 } from "fs/promises";
|
|
1746
|
-
import { createRequire } from "module";
|
|
1747
|
-
import { dirname, join as
|
|
1748
|
-
import { z as
|
|
1749
|
-
var
|
|
1750
|
-
schemaType:
|
|
1863
|
+
import { createRequire as createRequire2 } from "module";
|
|
1864
|
+
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(
|
|
1751
1868
|
'The type of configuration schema to retrieve: "app" for application configuration or "root" for root Harper configuration.'
|
|
1752
1869
|
)
|
|
1753
1870
|
});
|
|
1754
|
-
var getHarperConfigSchemaTool =
|
|
1871
|
+
var getHarperConfigSchemaTool = tool22({
|
|
1755
1872
|
name: "getHarperConfigSchemaTool",
|
|
1756
1873
|
description: "Returns the JSON schema for HarperDB configuration files (either app or root), which describes the config.yaml or harperdb-config.yaml files.",
|
|
1757
|
-
parameters:
|
|
1874
|
+
parameters: ToolParameters9,
|
|
1758
1875
|
async execute({ schemaType }) {
|
|
1759
1876
|
try {
|
|
1760
1877
|
return await readFile3(
|
|
1761
|
-
|
|
1762
|
-
|
|
1878
|
+
join8(
|
|
1879
|
+
dirname2(createRequire2(import.meta.url).resolve("harperdb")),
|
|
1763
1880
|
`config-${schemaType}.schema.json`
|
|
1764
1881
|
),
|
|
1765
1882
|
"utf8"
|
|
@@ -1771,13 +1888,13 @@ var getHarperConfigSchemaTool = tool21({
|
|
|
1771
1888
|
});
|
|
1772
1889
|
|
|
1773
1890
|
// tools/harper/getHarperResourceInterfaceTool.ts
|
|
1774
|
-
import { tool as
|
|
1891
|
+
import { tool as tool23 } from "@openai/agents";
|
|
1775
1892
|
import { readFile as readFile4 } from "fs/promises";
|
|
1776
|
-
import { createRequire as
|
|
1777
|
-
import { dirname as
|
|
1778
|
-
import { z as
|
|
1779
|
-
var
|
|
1780
|
-
resourceFile:
|
|
1893
|
+
import { createRequire as createRequire3 } from "module";
|
|
1894
|
+
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([
|
|
1781
1898
|
"ResourceInterfaceV2",
|
|
1782
1899
|
"ResourceInterface",
|
|
1783
1900
|
"Table",
|
|
@@ -1787,15 +1904,15 @@ var ToolParameters9 = z22.object({
|
|
|
1787
1904
|
"The resource-related definition file to read. Defaults to ResourceInterfaceV2."
|
|
1788
1905
|
).default("ResourceInterfaceV2")
|
|
1789
1906
|
});
|
|
1790
|
-
var getHarperResourceInterfaceTool =
|
|
1907
|
+
var getHarperResourceInterfaceTool = tool23({
|
|
1791
1908
|
name: "getHarperResourceInterfaceTool",
|
|
1792
1909
|
description: "Reads HarperDB resource interface and class definitions (like ResourceInterfaceV2.d.ts) to understand how resources and tables are structured.",
|
|
1793
|
-
parameters:
|
|
1910
|
+
parameters: ToolParameters10,
|
|
1794
1911
|
async execute({ resourceFile }) {
|
|
1795
1912
|
try {
|
|
1796
1913
|
return await readFile4(
|
|
1797
|
-
|
|
1798
|
-
|
|
1914
|
+
join9(
|
|
1915
|
+
dirname3(createRequire3(import.meta.url).resolve("harperdb")),
|
|
1799
1916
|
"resources",
|
|
1800
1917
|
`${resourceFile}.d.ts`
|
|
1801
1918
|
),
|
|
@@ -1808,21 +1925,21 @@ var getHarperResourceInterfaceTool = tool22({
|
|
|
1808
1925
|
});
|
|
1809
1926
|
|
|
1810
1927
|
// tools/harper/getHarperSchemaGraphQLTool.ts
|
|
1811
|
-
import { tool as
|
|
1928
|
+
import { tool as tool24 } from "@openai/agents";
|
|
1812
1929
|
import { readFile as readFile5 } from "fs/promises";
|
|
1813
|
-
import { createRequire as
|
|
1814
|
-
import { dirname as
|
|
1815
|
-
import { z as
|
|
1816
|
-
var
|
|
1817
|
-
var getHarperSchemaGraphQLTool =
|
|
1930
|
+
import { createRequire as createRequire4 } from "module";
|
|
1931
|
+
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({
|
|
1818
1935
|
name: "getHarperSchemaGraphQLTool",
|
|
1819
1936
|
description: "Returns the GraphQL schema for HarperDB schema files, which define the structure of HarperDB database tables.",
|
|
1820
|
-
parameters:
|
|
1937
|
+
parameters: ToolParameters11,
|
|
1821
1938
|
async execute() {
|
|
1822
1939
|
try {
|
|
1823
1940
|
return await readFile5(
|
|
1824
|
-
|
|
1825
|
-
|
|
1941
|
+
join10(
|
|
1942
|
+
dirname4(createRequire4(import.meta.url).resolve("harperdb")),
|
|
1826
1943
|
`schema.graphql`
|
|
1827
1944
|
),
|
|
1828
1945
|
"utf8"
|
|
@@ -1833,61 +1950,6 @@ var getHarperSchemaGraphQLTool = tool23({
|
|
|
1833
1950
|
}
|
|
1834
1951
|
});
|
|
1835
1952
|
|
|
1836
|
-
// tools/harper/getHarperSkillTool.ts
|
|
1837
|
-
import { tool as tool24 } from "@openai/agents";
|
|
1838
|
-
import { readdirSync, readFileSync as readFileSync5 } from "fs";
|
|
1839
|
-
import { createRequire as createRequire4 } from "module";
|
|
1840
|
-
import { dirname as dirname4, join as join10 } from "path";
|
|
1841
|
-
import { z as z24 } from "zod";
|
|
1842
|
-
var createHarper = dirname4(createRequire4(import.meta.url).resolve("create-harper"));
|
|
1843
|
-
var agentsMarkdown = join10(
|
|
1844
|
-
createHarper,
|
|
1845
|
-
"AGENTS.md"
|
|
1846
|
-
);
|
|
1847
|
-
var skillsDir = join10(
|
|
1848
|
-
createHarper,
|
|
1849
|
-
"template-vanilla",
|
|
1850
|
-
"skills"
|
|
1851
|
-
);
|
|
1852
|
-
var skillLinkRegex = /\[[^\]]+]\(skills\/([^)]+)\.md\)/g;
|
|
1853
|
-
var skills = getSkills();
|
|
1854
|
-
var ToolParameters11 = z24.object({
|
|
1855
|
-
skill: z24.enum(skills.length > 0 ? skills : ["none"]).describe(
|
|
1856
|
-
"The name of the skill to retrieve."
|
|
1857
|
-
)
|
|
1858
|
-
});
|
|
1859
|
-
var getHarperSkillTool = tool24({
|
|
1860
|
-
name: "getHarperSkill",
|
|
1861
|
-
description: getSkillsDescription(),
|
|
1862
|
-
parameters: ToolParameters11,
|
|
1863
|
-
execute: execute4
|
|
1864
|
-
});
|
|
1865
|
-
function getSkillsDescription() {
|
|
1866
|
-
try {
|
|
1867
|
-
return readFileSync5(agentsMarkdown, "utf8").replace("This repository contains", "This tool describes").replace(skillLinkRegex, "$1");
|
|
1868
|
-
} catch {
|
|
1869
|
-
return "Returns the contents of a Harper skill markdown file. Skills provide guidance on developing Harper applications.";
|
|
1870
|
-
}
|
|
1871
|
-
}
|
|
1872
|
-
function getSkills() {
|
|
1873
|
-
try {
|
|
1874
|
-
return readdirSync(skillsDir).filter((file) => file.endsWith(".md")).map((file) => file.replace(".md", ""));
|
|
1875
|
-
} catch {
|
|
1876
|
-
return [];
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
async function execute4({ skill }) {
|
|
1880
|
-
if (skill === "none") {
|
|
1881
|
-
return "No skills found.";
|
|
1882
|
-
}
|
|
1883
|
-
try {
|
|
1884
|
-
const filePath = join10(skillsDir, `${skill}.md`);
|
|
1885
|
-
return readFileSync5(filePath, "utf8");
|
|
1886
|
-
} catch (error) {
|
|
1887
|
-
return `Error reading Harper skill "${skill}": ${error}`;
|
|
1888
|
-
}
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
1953
|
// tools/harper/hitHarperAPITool.ts
|
|
1892
1954
|
import { tool as tool25 } from "@openai/agents";
|
|
1893
1955
|
import { z as z25 } from "zod";
|
|
@@ -1917,14 +1979,14 @@ var hitHarperAPITool = tool25({
|
|
|
1917
1979
|
}
|
|
1918
1980
|
return false;
|
|
1919
1981
|
},
|
|
1920
|
-
async execute({ path:
|
|
1982
|
+
async execute({ path: path8 = "/openapi", port, method = "GET", body }) {
|
|
1921
1983
|
try {
|
|
1922
1984
|
const effectivePort = port ?? (harperProcess.running ? harperProcess.httpPort : void 0);
|
|
1923
1985
|
if (!effectivePort) {
|
|
1924
1986
|
return `Error: No Harper application is currently running and no port was specified.`;
|
|
1925
1987
|
}
|
|
1926
1988
|
const response = await fetch(
|
|
1927
|
-
`http://localhost:${effectivePort}${
|
|
1989
|
+
`http://localhost:${effectivePort}${path8.startsWith("/") ? "" : "/"}${path8}`,
|
|
1928
1990
|
{
|
|
1929
1991
|
method,
|
|
1930
1992
|
headers: body ? { "Content-Type": "application/json" } : {},
|
|
@@ -2475,12 +2537,15 @@ var DiskSession = class extends MemorySession {
|
|
|
2475
2537
|
if (existsSync8(this.filePath)) {
|
|
2476
2538
|
try {
|
|
2477
2539
|
const data = await readFile6(this.filePath, "utf-8");
|
|
2478
|
-
|
|
2540
|
+
const parsed = JSON.parse(data);
|
|
2541
|
+
parsed.sessions = parsed.sessions || {};
|
|
2542
|
+
parsed.skillsRead = parsed.skillsRead || {};
|
|
2543
|
+
return parsed;
|
|
2479
2544
|
} catch (e) {
|
|
2480
2545
|
console.error(`Failed to read session file ${this.filePath}:`, e);
|
|
2481
2546
|
}
|
|
2482
2547
|
}
|
|
2483
|
-
return { sessions: {} };
|
|
2548
|
+
return { sessions: {}, skillsRead: {} };
|
|
2484
2549
|
}
|
|
2485
2550
|
async updateStorage(update) {
|
|
2486
2551
|
const storage = await this.loadStorage();
|
|
@@ -2532,8 +2597,30 @@ var DiskSession = class extends MemorySession {
|
|
|
2532
2597
|
const sessionId = await this.getSessionId();
|
|
2533
2598
|
await this.updateStorage((storage) => {
|
|
2534
2599
|
delete storage.sessions[sessionId];
|
|
2600
|
+
if (storage.skillsRead) {
|
|
2601
|
+
delete storage.skillsRead[sessionId];
|
|
2602
|
+
}
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
async addSkillRead(skill) {
|
|
2606
|
+
await this.ready;
|
|
2607
|
+
const sessionId = await this.getSessionId();
|
|
2608
|
+
await this.updateStorage((storage) => {
|
|
2609
|
+
if (!storage.skillsRead) {
|
|
2610
|
+
storage.skillsRead = {};
|
|
2611
|
+
}
|
|
2612
|
+
const arr = storage.skillsRead[sessionId] ?? (storage.skillsRead[sessionId] = []);
|
|
2613
|
+
if (!arr.includes(skill)) {
|
|
2614
|
+
arr.push(skill);
|
|
2615
|
+
}
|
|
2535
2616
|
});
|
|
2536
2617
|
}
|
|
2618
|
+
async getSkillsRead() {
|
|
2619
|
+
await this.ready;
|
|
2620
|
+
const sessionId = await this.getSessionId();
|
|
2621
|
+
const storage = await this.loadStorage();
|
|
2622
|
+
return storage.skillsRead?.[sessionId] ?? [];
|
|
2623
|
+
}
|
|
2537
2624
|
};
|
|
2538
2625
|
|
|
2539
2626
|
// utils/sessions/MemoryCompactionSession.ts
|
|
@@ -2542,19 +2629,18 @@ import {
|
|
|
2542
2629
|
} from "@openai/agents";
|
|
2543
2630
|
|
|
2544
2631
|
// utils/sessions/compactConversation.ts
|
|
2545
|
-
import { Agent
|
|
2632
|
+
import { Agent, run, system } from "@openai/agents";
|
|
2546
2633
|
async function compactConversation(items) {
|
|
2547
|
-
const firstItem = items[0];
|
|
2548
2634
|
const recentItems = items.slice(-3);
|
|
2549
|
-
const itemsToCompact = items.slice(
|
|
2635
|
+
const itemsToCompact = items.slice(0, -3);
|
|
2550
2636
|
let noticeContent = "... conversation history compacted ...";
|
|
2551
2637
|
if (trackedState.compactionModel && itemsToCompact.length > 0) {
|
|
2552
2638
|
try {
|
|
2553
|
-
const agent = new
|
|
2639
|
+
const agent = new Agent({
|
|
2554
2640
|
name: "History Compactor",
|
|
2555
2641
|
model: isOpenAIModel(trackedState.compactionModel) ? trackedState.compactionModel : getModel(trackedState.compactionModel),
|
|
2556
2642
|
modelSettings: compactionModelSettings,
|
|
2557
|
-
instructions: "
|
|
2643
|
+
instructions: "Compact the provided conversation history into key observations. Focus on what seems likely to be needed later. Be concise and avoid repeating information."
|
|
2558
2644
|
});
|
|
2559
2645
|
const result = await run(
|
|
2560
2646
|
agent,
|
|
@@ -2563,7 +2649,8 @@ async function compactConversation(items) {
|
|
|
2563
2649
|
const summary = result.finalOutput;
|
|
2564
2650
|
if (summary && summary.trim().length > 0) {
|
|
2565
2651
|
const s = summary.replace(/\s+/g, " ").trim();
|
|
2566
|
-
noticeContent =
|
|
2652
|
+
noticeContent = `Key observations from earlier:
|
|
2653
|
+
${s}`;
|
|
2567
2654
|
}
|
|
2568
2655
|
} catch (err) {
|
|
2569
2656
|
const msg = String(err?.message || err || "");
|
|
@@ -2573,7 +2660,7 @@ async function compactConversation(items) {
|
|
|
2573
2660
|
}
|
|
2574
2661
|
}
|
|
2575
2662
|
}
|
|
2576
|
-
const itemsToAdd = [
|
|
2663
|
+
const itemsToAdd = [system(noticeContent), ...recentItems].filter(excludeFalsy);
|
|
2577
2664
|
return { noticeContent, itemsToAdd };
|
|
2578
2665
|
}
|
|
2579
2666
|
|
|
@@ -2615,6 +2702,7 @@ var MemoryCompactionSession = class {
|
|
|
2615
2702
|
underlyingSession;
|
|
2616
2703
|
triggerTokens;
|
|
2617
2704
|
itemsAddedSinceLastCompaction = 0;
|
|
2705
|
+
skillsReadLocal = /* @__PURE__ */ new Set();
|
|
2618
2706
|
constructor(options) {
|
|
2619
2707
|
this.underlyingSession = options.underlyingSession ?? new MemorySession2();
|
|
2620
2708
|
if (trackedState.compactionModel) {
|
|
@@ -2625,6 +2713,25 @@ var MemoryCompactionSession = class {
|
|
|
2625
2713
|
async getSessionId() {
|
|
2626
2714
|
return this.underlyingSession.getSessionId();
|
|
2627
2715
|
}
|
|
2716
|
+
async addSkillRead(skill) {
|
|
2717
|
+
const u = this.underlyingSession;
|
|
2718
|
+
if (u && typeof u.addSkillRead === "function") {
|
|
2719
|
+
return u.addSkillRead(skill);
|
|
2720
|
+
}
|
|
2721
|
+
this.skillsReadLocal.add(skill);
|
|
2722
|
+
}
|
|
2723
|
+
async getSkillsRead() {
|
|
2724
|
+
const u = this.underlyingSession;
|
|
2725
|
+
let base = [];
|
|
2726
|
+
if (u && typeof u.getSkillsRead === "function") {
|
|
2727
|
+
try {
|
|
2728
|
+
base = await Promise.resolve(u.getSkillsRead());
|
|
2729
|
+
} catch {
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
const merged = /* @__PURE__ */ new Set([...base, ...this.skillsReadLocal]);
|
|
2733
|
+
return Array.from(merged);
|
|
2734
|
+
}
|
|
2628
2735
|
async getItems(limit) {
|
|
2629
2736
|
return this.underlyingSession.getItems(limit);
|
|
2630
2737
|
}
|
|
@@ -2729,14 +2836,14 @@ async function main() {
|
|
|
2729
2836
|
parseArgs();
|
|
2730
2837
|
await ensureApiKey();
|
|
2731
2838
|
sayHi();
|
|
2732
|
-
const agent = trackedState.agent = new
|
|
2839
|
+
const agent = trackedState.agent = new Agent2({
|
|
2733
2840
|
name: "Harper App Development Assistant",
|
|
2734
2841
|
model: isOpenAIModel(trackedState.model) ? trackedState.model : getModel(trackedState.model),
|
|
2735
2842
|
modelSettings,
|
|
2736
2843
|
instructions: readAgentsMD() || defaultInstructions(),
|
|
2737
2844
|
tools: createTools()
|
|
2738
2845
|
});
|
|
2739
|
-
const session = createSession(trackedState.sessionPath);
|
|
2846
|
+
const session = trackedState.session = createSession(trackedState.sessionPath);
|
|
2740
2847
|
while (true) {
|
|
2741
2848
|
let task = "";
|
|
2742
2849
|
let lastToolCallInfo = null;
|
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.
|
|
4
|
+
"version": "0.12.0",
|
|
5
5
|
"main": "dist/agent.js",
|
|
6
6
|
"repository": "github:HarperFast/harper-agent",
|
|
7
7
|
"bugs": {
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
"homepage": "https://github.com/harperfast",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"dev": "tsup agent.ts --format esm --clean --dts --watch",
|
|
13
|
+
"link": "npm run build && npm link",
|
|
13
14
|
"build": "tsup agent.ts --format esm --clean --dts",
|
|
14
15
|
"commitlint": "commitlint --edit",
|
|
15
16
|
"start": "node ./dist/agent.js",
|
|
16
|
-
"lint": "oxlint .",
|
|
17
|
-
"lint:fix": "oxlint . --fix",
|
|
17
|
+
"lint": "oxlint --format stylish .",
|
|
18
|
+
"lint:fix": "oxlint --format stylish . --fix",
|
|
18
19
|
"prepare": "husky",
|
|
19
20
|
"format": "dprint check",
|
|
20
21
|
"format:fix": "dprint fmt",
|