@vietor/easy-agent 0.4.4 → 0.4.5

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/main.js CHANGED
@@ -1,41 +1,26 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
+ import { Command } from "commander";
4
5
  import { loadConfig } from "./config.js";
5
- import { tryLoadSkills, tryReadFileText, createSession, } from "@vietor/easy-agent-core";
6
+ import { tryLoadSkills, tryReadFileText, createSession } from "@vietor/easy-agent-core";
6
7
  import { builtinCommands } from "./cmds/builtin.js";
7
8
  import { startApp } from "./tui/App.js";
9
+ import { getPackageInfo } from "./util/package.js";
8
10
  import { FileSessionPersistence } from "./util/sessionStore.js";
9
- const SYSTEM_PROMPT_BASE = [
10
- "You are Easy Agent, an autonomous assistant. You complete tasks by calling tools, inspecting their results, and iterating until the work is done.",
11
- `Output:
11
+ function buildSystemPromptBase(cwd) {
12
+ return [
13
+ "You are Easy Agent, an autonomous assistant. You complete tasks by calling tools, inspecting their results, and iterating until the work is done.",
14
+ `Output:
12
15
  - Be concise and use GitHub-flavored markdown.
13
16
  - State what you did and stop once the task is complete; report outcomes faithfully.
14
17
  - Reference code as file_path:line_number.`,
15
- `Environment:
18
+ `Environment:
16
19
  - Platform: ${process.platform}
17
- - Working directory: ${process.cwd()}`,
18
- `Decision making:
20
+ - Working directory: ${cwd}`,
21
+ `Decision making:
19
22
  - When a decision belongs to the user, call AskUser and wait for the answer rather than listing options in prose. Ask when there are multiple reasonable approaches, an irreversible or consequential action, or the request is ambiguous; when you have enough to proceed, act without asking.`,
20
- ].join("\n\n");
21
- function parseArgs(argv) {
22
- let mode = "new";
23
- let id;
24
- for (let i = 0; i < argv.length; i++) {
25
- const a = argv[i];
26
- if (a === "-c" || a === "--continue") {
27
- mode = "continue";
28
- }
29
- else if (a === "-r" || a === "--resume") {
30
- mode = "resume";
31
- const next = argv[i + 1];
32
- if (next && !next.startsWith("-")) {
33
- id = next;
34
- i++;
35
- }
36
- }
37
- }
38
- return { mode, id };
23
+ ].join("\n\n");
39
24
  }
40
25
  async function listSessions(store) {
41
26
  const sessions = await store.listSessions();
@@ -51,35 +36,43 @@ async function listSessions(store) {
51
36
  console.log("\nResume with: easy-agent --resume <id>");
52
37
  }
53
38
  export async function main(argv = []) {
54
- const { mode, id } = parseArgs(argv);
55
- const store = new FileSessionPersistence(process.cwd());
56
- if (mode === "resume" && !id) {
39
+ const pkg = getPackageInfo();
40
+ const program = new Command();
41
+ program
42
+ .name("easy-agent")
43
+ .version(pkg.version)
44
+ .description("Terminal-based AI agent CLI with conversational TUI")
45
+ .option("-c, --continue", "Continue the most recent session")
46
+ .option("-r, --resume [id]", "Resume a session by ID (omit to list sessions)")
47
+ .parse(argv, { from: "user" });
48
+ const opts = program.opts();
49
+ const cwd = process.cwd();
50
+ const store = new FileSessionPersistence(cwd);
51
+ if (opts.resume !== undefined && typeof opts.resume !== "string") {
57
52
  await listSessions(store);
58
53
  return;
59
54
  }
60
55
  const config = loadConfig();
61
56
  let sessionId;
62
57
  let resume = false;
63
- if (mode === "continue") {
58
+ if (opts.continue) {
64
59
  const sessions = await store.listSessions();
65
60
  if (sessions.length) {
66
61
  sessionId = sessions[0].id;
67
62
  resume = true;
68
63
  }
69
64
  }
70
- else if (mode === "resume" && id) {
71
- sessionId = id;
65
+ else if (opts.resume && typeof opts.resume === "string") {
66
+ sessionId = opts.resume;
72
67
  resume = true;
73
68
  }
74
69
  if (!sessionId)
75
70
  sessionId = randomUUID();
76
- const globalSkills = tryLoadSkills(join(homedir(), ".easy-agent", "skills"))
77
- ?? tryLoadSkills(join(homedir(), ".claude", "skills"));
78
- const globalPrompt = tryReadFileText(join(homedir(), ".easy-agent", "AGENTS.md"))
79
- ?? tryReadFileText(join(homedir(), ".claude", "CLAUDE.md"));
80
- const projectPrompt = tryReadFileText(join(process.cwd(), "AGENTS.md"))
81
- ?? tryReadFileText(join(process.cwd(), "CLAUDE.md"));
82
- const systemPrompt = [SYSTEM_PROMPT_BASE, globalPrompt, projectPrompt]
71
+ const globalSkills = tryLoadSkills(join(homedir(), ".easy-agent", "skills")) ?? tryLoadSkills(join(homedir(), ".claude", "skills"));
72
+ const globalPrompt = tryReadFileText(join(homedir(), ".easy-agent", "AGENTS.md")) ??
73
+ tryReadFileText(join(homedir(), ".claude", "CLAUDE.md"));
74
+ const projectPrompt = tryReadFileText(join(cwd, "AGENTS.md")) ?? tryReadFileText(join(cwd, "CLAUDE.md"));
75
+ const systemPrompt = [buildSystemPromptBase(cwd), globalPrompt, projectPrompt]
83
76
  .filter(Boolean)
84
77
  .join("\n\n=================\n\n");
85
78
  const session = await createSession({
@@ -90,13 +83,17 @@ export async function main(argv = []) {
90
83
  commands: builtinCommands,
91
84
  builtinTools: {
92
85
  askUser: true,
93
- todoWrite: true
86
+ todoWrite: true,
94
87
  },
88
+ cwd: cwd,
95
89
  sessionId,
96
90
  persistence: store,
97
91
  });
98
92
  if (resume)
99
93
  await session.restore();
100
94
  const app = startApp(session);
101
- await app.waitUntilExit().finally(() => session.dispose());
95
+ await app.waitUntilExit().finally(() => {
96
+ session.dispose();
97
+ console.log(["Resume this session with:", `easy-agent --resume ${sessionId}`].join("\n"));
98
+ });
102
99
  }
package/dist/tui/App.js CHANGED
@@ -89,7 +89,7 @@ export function App({ session }) {
89
89
  runningView = (_jsx(Box, { marginTop: 1, paddingLeft: 1, children: _jsx(Spinner, { label: "thinking", elapsed: runState.elapsed, promptTokens: runState.promptTokens, completionTokens: runState.completionTokens }) }));
90
90
  }
91
91
  }
92
- return (_jsxs(Box, { width: columns, flexDirection: "column", children: [_jsx(AppHeader, {}), _jsx(TimelineList, { session: session }), view.todos.length > 0 ? _jsx(TodoView, { todos: view.todos }) : null, runningView, !runState.running ? (_jsxs(_Fragment, { children: [_jsx(StatusBar, { contextTokens: session.contextTokens }), _jsx(PromptOrCommandInput, { commands: allCmds, onCommand: handleCommand, onPrompt: handlePrompt })] })) : null] }));
92
+ return (_jsxs(Box, { width: columns, flexDirection: "column", children: [_jsx(AppHeader, { cwd: session.cwd }), _jsx(TimelineList, { session: session }), view.todos.length > 0 ? _jsx(TodoView, { todos: view.todos }) : null, runningView, !runState.running ? (_jsxs(_Fragment, { children: [_jsx(StatusBar, { contextTokens: session.contextTokens }), _jsx(PromptOrCommandInput, { commands: allCmds, onCommand: handleCommand, onPrompt: handlePrompt })] })) : null] }));
93
93
  }
94
94
  export function startApp(session) {
95
95
  process.stdout.write("");
@@ -2,8 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { memo } from "react";
3
3
  import { Box, Text, useWindowSize } from "ink";
4
4
  import { getPackageInfo } from "../util/package.js";
5
- export const AppHeader = memo(function AppHeader() {
5
+ export const AppHeader = memo(function AppHeader({ cwd }) {
6
6
  const { columns } = useWindowSize();
7
7
  const pkginfo = getPackageInfo();
8
- return (_jsxs(Box, { width: columns, paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Easy Agent" }), _jsxs(Text, { dimColor: true, children: [" v", pkginfo.version] })] }), _jsx(Text, { dimColor: true, children: process.cwd() })] }));
8
+ return (_jsxs(Box, { width: columns, paddingX: 1, flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { bold: true, children: "Easy Agent" }), _jsxs(Text, { dimColor: true, children: [" v", pkginfo.version] })] }), _jsx(Text, { dimColor: true, children: cwd })] }));
9
9
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vietor/easy-agent",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "type": "module",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
@@ -16,13 +16,14 @@
16
16
  "url": "https://github.com/vietor/easy-agent.git"
17
17
  },
18
18
  "dependencies": {
19
+ "commander": "^13.0.0",
19
20
  "ink": "^7.1.0",
20
21
  "ink-text-input": "^6.0.0",
21
22
  "marked": "^18.0.5",
22
23
  "react": "^19.2.7",
23
24
  "string-width": "^8.2.1",
24
25
  "zod": "^4.4.3",
25
- "@vietor/easy-agent-core": "0.4.4"
26
+ "@vietor/easy-agent-core": "0.4.5"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/node": "^22.0.0",