@harperfast/agent 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/agent.js +74 -54
  2. package/package.json +3 -2
package/dist/agent.js CHANGED
@@ -243,30 +243,36 @@ function resolveSessionPathConsideringHarper(raw, cwd, originalCwd) {
243
243
  }
244
244
 
245
245
  // lifecycle/trackedState.ts
246
- var trackedState = {
247
- originalCwd: process.cwd(),
248
- cwd: process.cwd(),
249
- model: "",
250
- compactionModel: "",
251
- originalSessionPath: null,
252
- get sessionPath() {
253
- return resolveSessionPathConsideringHarper(trackedState.originalSessionPath, this.cwd, this.originalCwd);
254
- },
255
- set sessionPath(value) {
256
- trackedState.originalSessionPath = value;
257
- },
258
- useFlexTier: false,
259
- currentTurn: 0,
260
- maxTurns: 30,
261
- maxCost: null,
262
- autoApproveCodeInterpreter: false,
263
- autoApprovePatches: false,
264
- autoApproveShell: false,
265
- monitorRateLimits: true,
266
- rateLimitThreshold: 80,
267
- autonomous: false,
268
- prompt: null
269
- };
246
+ var trackedState = bootstrapTrackedState();
247
+ function resetTrackedState() {
248
+ trackedState = bootstrapTrackedState();
249
+ }
250
+ function bootstrapTrackedState() {
251
+ return {
252
+ originalCwd: process.cwd(),
253
+ cwd: process.cwd(),
254
+ model: "",
255
+ compactionModel: "",
256
+ originalSessionPath: null,
257
+ get sessionPath() {
258
+ return resolveSessionPathConsideringHarper(trackedState.originalSessionPath, this.cwd, this.originalCwd);
259
+ },
260
+ set sessionPath(value) {
261
+ trackedState.originalSessionPath = value;
262
+ },
263
+ useFlexTier: false,
264
+ currentTurn: 0,
265
+ maxTurns: 30,
266
+ maxCost: null,
267
+ autoApproveCodeInterpreter: false,
268
+ autoApprovePatches: false,
269
+ autoApproveShell: false,
270
+ monitorRateLimits: true,
271
+ rateLimitThreshold: 80,
272
+ autonomous: false,
273
+ prompt: null
274
+ };
275
+ }
270
276
 
271
277
  // lifecycle/defaultInstructions.ts
272
278
  function defaultInstructions() {
@@ -482,13 +488,20 @@ async function handleExit() {
482
488
  process.exit(0);
483
489
  }
484
490
 
485
- // lifecycle/readAgentsMD.ts
491
+ // lifecycle/readAgentSkillsRoot.ts
486
492
  import { existsSync as existsSync3, readFileSync } from "fs";
487
493
  import { join as join4 } from "path";
488
- function readAgentsMD() {
489
- const agentsMdExists = existsSync3(join4(trackedState.cwd, "AGENTS.md"));
494
+
495
+ // lifecycle/agentsSkillReference.ts
496
+ var agentsSkillDir = ".agents/skills/harper-best-practices";
497
+ var agentsSkillReference = `${agentsSkillDir}/SKILL.md`;
498
+
499
+ // lifecycle/readAgentSkillsRoot.ts
500
+ function readAgentSkillsRoot() {
501
+ const agentsFile = join4(trackedState.cwd, agentsSkillReference);
502
+ const agentsMdExists = existsSync3(agentsFile);
490
503
  if (agentsMdExists) {
491
- return readFileSync(join4(trackedState.cwd, "AGENTS.md"), "utf8");
504
+ return readFileSync(agentsFile, "utf8");
492
505
  }
493
506
  }
494
507
 
@@ -790,17 +803,23 @@ import { readdirSync, readFileSync as readFileSync2 } from "fs";
790
803
  import { createRequire } from "module";
791
804
  import { dirname as dirname2, join as join5 } from "path";
792
805
  import { z as z10 } from "zod";
793
- var createHarper = dirname2(createRequire(import.meta.url).resolve("create-harper"));
794
- var agentsMarkdown = join5(
795
- createHarper,
796
- "AGENTS.md"
806
+ var require2 = createRequire(import.meta.url);
807
+ var harperSkillsModuleDir = dirname2(
808
+ require2.resolve("@harperfast/skills/package.json")
809
+ );
810
+ var harperBestPracticesDir = join5(
811
+ harperSkillsModuleDir,
812
+ "harper-best-practices"
797
813
  );
798
- var skillsDir = join5(
799
- createHarper,
800
- "template-vanilla",
801
- "skills"
814
+ var skillRootFile = join5(
815
+ harperBestPracticesDir,
816
+ "SKILL.md"
802
817
  );
803
- var skillLinkRegex = /\[[^\]]+]\(skills\/([^)]+)\.md\)/g;
818
+ var rulesDir = join5(
819
+ harperBestPracticesDir,
820
+ "rules"
821
+ );
822
+ var skillLinkRegex = /\[[^\]]+]\((?:rules|skills)\/([^)]+)\.md\)/g;
804
823
  var skills = getSkills();
805
824
  var ToolParameters10 = z10.object({
806
825
  skill: z10.enum(skills.length > 0 ? skills : ["none"]).describe(
@@ -815,24 +834,24 @@ var getHarperSkillTool = tool10({
815
834
  });
816
835
  function getSkillsDescription() {
817
836
  try {
818
- return readFileSync2(agentsMarkdown, "utf8").replace("This repository contains", "This tool describes").replace(skillLinkRegex, "$1");
837
+ return readFileSync2(skillRootFile, "utf8").replace("This repository contains", "This tool describes").replace(skillLinkRegex, "$1");
819
838
  } catch {
820
839
  return "Returns the contents of a Harper skill markdown file. Skills provide guidance on developing Harper applications.";
821
840
  }
822
841
  }
823
842
  function getSkills() {
824
843
  try {
825
- return readdirSync(skillsDir).filter((file) => file.endsWith(".md")).map((file) => file.replace(".md", ""));
844
+ return readdirSync(rulesDir).filter((file) => file.endsWith(".md")).map((file) => file.replace(".md", ""));
826
845
  } catch {
827
846
  return [];
828
847
  }
829
848
  }
830
849
  async function execute10({ skill }) {
831
850
  if (skill === "none") {
832
- return "No skills found.";
851
+ return "No skill requested.";
833
852
  }
834
853
  try {
835
- const filePath = join5(skillsDir, `${skill}.md`);
854
+ const filePath = join5(rulesDir, `${skill}.md`);
836
855
  const content = readFileSync2(filePath, "utf8");
837
856
  agentManager.session?.addSkillRead?.(skill);
838
857
  return content;
@@ -1170,18 +1189,18 @@ async function execute12({ path: path9 }) {
1170
1189
  }
1171
1190
  process.chdir(target);
1172
1191
  trackedState.cwd = process.cwd();
1173
- const agentsMDContents = readAgentsMD();
1174
- if (agentsMDContents) {
1192
+ const agentSkillsRoot = readAgentSkillsRoot();
1193
+ if (agentSkillsRoot) {
1175
1194
  if (agentManager.agent) {
1176
- agentManager.agent.instructions = agentsMDContents;
1195
+ agentManager.agent.instructions = agentSkillsRoot;
1177
1196
  }
1178
1197
  emitToListeners("PushNewMessages", [{
1179
1198
  type: "agent",
1180
- text: "Detected AGENTS.md, reading its contents.",
1199
+ text: "Detected agent skills, reading its contents.",
1181
1200
  version: 1
1182
1201
  }]);
1183
- return `Switched current working directory to ${trackedState.cwd}, with a AGENTS.md file containing:
1184
- ${agentsMDContents}
1202
+ return `Switched current working directory to ${trackedState.cwd}, with ${agentsSkillReference} file containing:
1203
+ ${agentSkillsRoot}
1185
1204
  I strongly suggest you use these newfound skills!`;
1186
1205
  }
1187
1206
  return `Switched current working directory to ${trackedState.cwd}`;
@@ -3722,7 +3741,7 @@ var AgentManager = class {
3722
3741
  name: "Harper Agent",
3723
3742
  model: isOpenAIModel(trackedState.model) ? trackedState.model : getModel(trackedState.model),
3724
3743
  modelSettings: getModelSettings(trackedState.model),
3725
- instructions: readAgentsMD() || defaultInstructions(),
3744
+ instructions: readAgentSkillsRoot() || defaultInstructions(),
3726
3745
  tools: createTools()
3727
3746
  });
3728
3747
  this.session = createSession(trackedState.sessionPath);
@@ -5980,7 +5999,7 @@ var compactorModelsByProvider = {
5980
5999
  OpenAI: modelsByProvider.OpenAI.slice().reverse(),
5981
6000
  Anthropic: modelsByProvider.Anthropic.slice().reverse(),
5982
6001
  Google: modelsByProvider.Google.slice().reverse(),
5983
- Ollama: modelsByProvider.Ollama.slice()
6002
+ Ollama: modelsByProvider.Ollama.slice().reverse()
5984
6003
  };
5985
6004
 
5986
6005
  // ink/configurationWizard/ModelSelectionStep.tsx
@@ -6213,8 +6232,10 @@ function ConfigurationWizard({ onComplete }) {
6213
6232
 
6214
6233
  // ink/main.tsx
6215
6234
  import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
6216
- function bootstrapConfig(onComplete) {
6217
- render(/* @__PURE__ */ jsx26(MainConfig, { onComplete }));
6235
+ function bootstrapConfig() {
6236
+ return new Promise((resolve2) => {
6237
+ render(/* @__PURE__ */ jsx26(MainConfig, { onComplete: resolve2 }));
6238
+ });
6218
6239
  }
6219
6240
  function MainConfig({ onComplete }) {
6220
6241
  const { exit } = useApp();
@@ -6663,9 +6684,8 @@ function ensureApiKey() {
6663
6684
  await checkForUpdate();
6664
6685
  parseArgs();
6665
6686
  if (!ensureApiKey()) {
6666
- await new Promise((resolve2) => {
6667
- bootstrapConfig(resolve2);
6668
- });
6687
+ resetTrackedState();
6688
+ await bootstrapConfig();
6669
6689
  emitToListeners("ExitUI", void 0);
6670
6690
  parseArgs();
6671
6691
  if (!ensureApiKey()) {
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.14.0",
4
+ "version": "0.15.0",
5
5
  "main": "dist/agent.js",
6
6
  "repository": "github:HarperFast/harper-agent",
7
7
  "bugs": {
@@ -46,12 +46,12 @@
46
46
  "@ai-sdk/anthropic": "^3.0.41",
47
47
  "@ai-sdk/google": "^3.0.24",
48
48
  "@ai-sdk/openai": "^3.0.26",
49
+ "@harperfast/skills": "^1.0.0",
49
50
  "@inkjs/ui": "^2.0.0",
50
51
  "@openai/agents": "^0.4.6",
51
52
  "@openai/agents-extensions": "^0.4.6",
52
53
  "ai": "^6.0.79",
53
54
  "chalk": "^5.6.2",
54
- "create-harper": "^1.0.0",
55
55
  "cross-spawn": "^7.0.6",
56
56
  "dotenv": "^17.2.4",
57
57
  "ink": "^6.7.0",
@@ -83,6 +83,7 @@
83
83
  "harperdb": "^4.7.19",
84
84
  "hono": "^4.11.9",
85
85
  "husky": "^9.1.7",
86
+ "ink-testing-library": "^4.0.0",
86
87
  "oxlint": "^1.43.0",
87
88
  "semantic-release": "^25.0.3",
88
89
  "tsup": "^8.5.1",