cmdr-agent 1.0.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/LICENSE +21 -0
- package/README.md +238 -0
- package/dist/bin/cmdr.d.ts +9 -0
- package/dist/bin/cmdr.d.ts.map +1 -0
- package/dist/bin/cmdr.js +49 -0
- package/dist/bin/cmdr.js.map +1 -0
- package/dist/src/cli/args.d.ts +19 -0
- package/dist/src/cli/args.d.ts.map +1 -0
- package/dist/src/cli/args.js +89 -0
- package/dist/src/cli/args.js.map +1 -0
- package/dist/src/cli/commands.d.ts +12 -0
- package/dist/src/cli/commands.d.ts.map +1 -0
- package/dist/src/cli/commands.js +400 -0
- package/dist/src/cli/commands.js.map +1 -0
- package/dist/src/cli/renderer.d.ts +8 -0
- package/dist/src/cli/renderer.d.ts.map +1 -0
- package/dist/src/cli/renderer.js +47 -0
- package/dist/src/cli/renderer.js.map +1 -0
- package/dist/src/cli/repl.d.ts +18 -0
- package/dist/src/cli/repl.d.ts.map +1 -0
- package/dist/src/cli/repl.js +751 -0
- package/dist/src/cli/repl.js.map +1 -0
- package/dist/src/cli/spinner.d.ts +16 -0
- package/dist/src/cli/spinner.d.ts.map +1 -0
- package/dist/src/cli/spinner.js +233 -0
- package/dist/src/cli/spinner.js.map +1 -0
- package/dist/src/cli/theme.d.ts +95 -0
- package/dist/src/cli/theme.d.ts.map +1 -0
- package/dist/src/cli/theme.js +178 -0
- package/dist/src/cli/theme.js.map +1 -0
- package/dist/src/communication/message-bus.d.ts +35 -0
- package/dist/src/communication/message-bus.d.ts.map +1 -0
- package/dist/src/communication/message-bus.js +60 -0
- package/dist/src/communication/message-bus.js.map +1 -0
- package/dist/src/communication/shared-memory.d.ts +19 -0
- package/dist/src/communication/shared-memory.d.ts.map +1 -0
- package/dist/src/communication/shared-memory.js +37 -0
- package/dist/src/communication/shared-memory.js.map +1 -0
- package/dist/src/communication/task-queue.d.ts +50 -0
- package/dist/src/communication/task-queue.d.ts.map +1 -0
- package/dist/src/communication/task-queue.js +158 -0
- package/dist/src/communication/task-queue.js.map +1 -0
- package/dist/src/config/config-loader.d.ts +23 -0
- package/dist/src/config/config-loader.d.ts.map +1 -0
- package/dist/src/config/config-loader.js +91 -0
- package/dist/src/config/config-loader.js.map +1 -0
- package/dist/src/config/defaults.d.ts +6 -0
- package/dist/src/config/defaults.d.ts.map +1 -0
- package/dist/src/config/defaults.js +21 -0
- package/dist/src/config/defaults.js.map +1 -0
- package/dist/src/config/schema.d.ts +135 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +35 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/config/telemetry.d.ts +41 -0
- package/dist/src/config/telemetry.d.ts.map +1 -0
- package/dist/src/config/telemetry.js +57 -0
- package/dist/src/config/telemetry.js.map +1 -0
- package/dist/src/core/agent-pool.d.ts +40 -0
- package/dist/src/core/agent-pool.d.ts.map +1 -0
- package/dist/src/core/agent-pool.js +66 -0
- package/dist/src/core/agent-pool.js.map +1 -0
- package/dist/src/core/agent-runner.d.ts +51 -0
- package/dist/src/core/agent-runner.d.ts.map +1 -0
- package/dist/src/core/agent-runner.js +251 -0
- package/dist/src/core/agent-runner.js.map +1 -0
- package/dist/src/core/agent.d.ts +34 -0
- package/dist/src/core/agent.d.ts.map +1 -0
- package/dist/src/core/agent.js +143 -0
- package/dist/src/core/agent.js.map +1 -0
- package/dist/src/core/intent.d.ts +33 -0
- package/dist/src/core/intent.d.ts.map +1 -0
- package/dist/src/core/intent.js +91 -0
- package/dist/src/core/intent.js.map +1 -0
- package/dist/src/core/orchestrator.d.ts +43 -0
- package/dist/src/core/orchestrator.d.ts.map +1 -0
- package/dist/src/core/orchestrator.js +115 -0
- package/dist/src/core/orchestrator.js.map +1 -0
- package/dist/src/core/permissions.d.ts +36 -0
- package/dist/src/core/permissions.d.ts.map +1 -0
- package/dist/src/core/permissions.js +129 -0
- package/dist/src/core/permissions.js.map +1 -0
- package/dist/src/core/presets.d.ts +12 -0
- package/dist/src/core/presets.d.ts.map +1 -0
- package/dist/src/core/presets.js +148 -0
- package/dist/src/core/presets.js.map +1 -0
- package/dist/src/core/team.d.ts +44 -0
- package/dist/src/core/team.d.ts.map +1 -0
- package/dist/src/core/team.js +156 -0
- package/dist/src/core/team.js.map +1 -0
- package/dist/src/core/types.d.ts +257 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +7 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/index.d.ts +44 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm/adapter.d.ts +5 -0
- package/dist/src/llm/adapter.d.ts.map +1 -0
- package/dist/src/llm/adapter.js +5 -0
- package/dist/src/llm/adapter.js.map +1 -0
- package/dist/src/llm/model-registry.d.ts +14 -0
- package/dist/src/llm/model-registry.d.ts.map +1 -0
- package/dist/src/llm/model-registry.js +30 -0
- package/dist/src/llm/model-registry.js.map +1 -0
- package/dist/src/llm/ollama.d.ts +26 -0
- package/dist/src/llm/ollama.d.ts.map +1 -0
- package/dist/src/llm/ollama.js +375 -0
- package/dist/src/llm/ollama.js.map +1 -0
- package/dist/src/llm/token-counter.d.ts +11 -0
- package/dist/src/llm/token-counter.d.ts.map +1 -0
- package/dist/src/llm/token-counter.js +35 -0
- package/dist/src/llm/token-counter.js.map +1 -0
- package/dist/src/plugins/mcp-client.d.ts +38 -0
- package/dist/src/plugins/mcp-client.d.ts.map +1 -0
- package/dist/src/plugins/mcp-client.js +113 -0
- package/dist/src/plugins/mcp-client.js.map +1 -0
- package/dist/src/plugins/plugin-manager.d.ts +37 -0
- package/dist/src/plugins/plugin-manager.d.ts.map +1 -0
- package/dist/src/plugins/plugin-manager.js +146 -0
- package/dist/src/plugins/plugin-manager.js.map +1 -0
- package/dist/src/scheduling/semaphore.d.ts +20 -0
- package/dist/src/scheduling/semaphore.d.ts.map +1 -0
- package/dist/src/scheduling/semaphore.js +52 -0
- package/dist/src/scheduling/semaphore.js.map +1 -0
- package/dist/src/scheduling/strategies.d.ts +39 -0
- package/dist/src/scheduling/strategies.d.ts.map +1 -0
- package/dist/src/scheduling/strategies.js +88 -0
- package/dist/src/scheduling/strategies.js.map +1 -0
- package/dist/src/session/compaction.d.ts +32 -0
- package/dist/src/session/compaction.d.ts.map +1 -0
- package/dist/src/session/compaction.js +172 -0
- package/dist/src/session/compaction.js.map +1 -0
- package/dist/src/session/cost-tracker.d.ts +41 -0
- package/dist/src/session/cost-tracker.d.ts.map +1 -0
- package/dist/src/session/cost-tracker.js +76 -0
- package/dist/src/session/cost-tracker.js.map +1 -0
- package/dist/src/session/project-context.d.ts +6 -0
- package/dist/src/session/project-context.d.ts.map +1 -0
- package/dist/src/session/project-context.js +147 -0
- package/dist/src/session/project-context.js.map +1 -0
- package/dist/src/session/prompt-builder.d.ts +11 -0
- package/dist/src/session/prompt-builder.d.ts.map +1 -0
- package/dist/src/session/prompt-builder.js +30 -0
- package/dist/src/session/prompt-builder.js.map +1 -0
- package/dist/src/session/session-manager.d.ts +32 -0
- package/dist/src/session/session-manager.d.ts.map +1 -0
- package/dist/src/session/session-manager.js +84 -0
- package/dist/src/session/session-manager.js.map +1 -0
- package/dist/src/session/session-persistence.d.ts +44 -0
- package/dist/src/session/session-persistence.d.ts.map +1 -0
- package/dist/src/session/session-persistence.js +150 -0
- package/dist/src/session/session-persistence.js.map +1 -0
- package/dist/src/session/undo-manager.d.ts +35 -0
- package/dist/src/session/undo-manager.d.ts.map +1 -0
- package/dist/src/session/undo-manager.js +79 -0
- package/dist/src/session/undo-manager.js.map +1 -0
- package/dist/src/tools/built-in/ask-user.d.ts +7 -0
- package/dist/src/tools/built-in/ask-user.d.ts.map +1 -0
- package/dist/src/tools/built-in/ask-user.js +28 -0
- package/dist/src/tools/built-in/ask-user.js.map +1 -0
- package/dist/src/tools/built-in/bash.d.ts +9 -0
- package/dist/src/tools/built-in/bash.d.ts.map +1 -0
- package/dist/src/tools/built-in/bash.js +67 -0
- package/dist/src/tools/built-in/bash.js.map +1 -0
- package/dist/src/tools/built-in/file-edit.d.ts +9 -0
- package/dist/src/tools/built-in/file-edit.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-edit.js +39 -0
- package/dist/src/tools/built-in/file-edit.js.map +1 -0
- package/dist/src/tools/built-in/file-read.d.ts +9 -0
- package/dist/src/tools/built-in/file-read.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-read.js +41 -0
- package/dist/src/tools/built-in/file-read.js.map +1 -0
- package/dist/src/tools/built-in/file-write.d.ts +8 -0
- package/dist/src/tools/built-in/file-write.d.ts.map +1 -0
- package/dist/src/tools/built-in/file-write.js +29 -0
- package/dist/src/tools/built-in/file-write.js.map +1 -0
- package/dist/src/tools/built-in/git-commit.d.ts +12 -0
- package/dist/src/tools/built-in/git-commit.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-commit.js +96 -0
- package/dist/src/tools/built-in/git-commit.js.map +1 -0
- package/dist/src/tools/built-in/git-diff.d.ts +8 -0
- package/dist/src/tools/built-in/git-diff.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-diff.js +43 -0
- package/dist/src/tools/built-in/git-diff.js.map +1 -0
- package/dist/src/tools/built-in/git-log.d.ts +8 -0
- package/dist/src/tools/built-in/git-log.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-log.js +39 -0
- package/dist/src/tools/built-in/git-log.js.map +1 -0
- package/dist/src/tools/built-in/glob.d.ts +8 -0
- package/dist/src/tools/built-in/glob.d.ts.map +1 -0
- package/dist/src/tools/built-in/glob.js +60 -0
- package/dist/src/tools/built-in/glob.js.map +1 -0
- package/dist/src/tools/built-in/grep.d.ts +9 -0
- package/dist/src/tools/built-in/grep.d.ts.map +1 -0
- package/dist/src/tools/built-in/grep.js +115 -0
- package/dist/src/tools/built-in/grep.js.map +1 -0
- package/dist/src/tools/built-in/index.d.ts +21 -0
- package/dist/src/tools/built-in/index.d.ts.map +1 -0
- package/dist/src/tools/built-in/index.js +30 -0
- package/dist/src/tools/built-in/index.js.map +1 -0
- package/dist/src/tools/built-in/think.d.ts +7 -0
- package/dist/src/tools/built-in/think.d.ts.map +1 -0
- package/dist/src/tools/built-in/think.js +18 -0
- package/dist/src/tools/built-in/think.js.map +1 -0
- package/dist/src/tools/built-in/web-fetch.d.ts +11 -0
- package/dist/src/tools/built-in/web-fetch.d.ts.map +1 -0
- package/dist/src/tools/built-in/web-fetch.js +70 -0
- package/dist/src/tools/built-in/web-fetch.js.map +1 -0
- package/dist/src/tools/executor.d.ts +25 -0
- package/dist/src/tools/executor.d.ts.map +1 -0
- package/dist/src/tools/executor.js +61 -0
- package/dist/src/tools/executor.js.map +1 -0
- package/dist/src/tools/registry.d.ts +25 -0
- package/dist/src/tools/registry.d.ts.map +1 -0
- package/dist/src/tools/registry.js +135 -0
- package/dist/src/tools/registry.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session persistence — save/load conversation sessions to ~/.cmdr/sessions/.
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { homedir } from 'os';
|
|
7
|
+
const CMDR_DIR = join(homedir(), '.cmdr');
|
|
8
|
+
const SESSIONS_DIR = join(CMDR_DIR, 'sessions');
|
|
9
|
+
async function ensureDir(dir) {
|
|
10
|
+
await mkdir(dir, { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
/** Extract list of unique tool names used in a conversation. */
|
|
13
|
+
function extractToolsUsed(messages) {
|
|
14
|
+
const tools = new Set();
|
|
15
|
+
for (const msg of messages) {
|
|
16
|
+
for (const block of msg.content) {
|
|
17
|
+
if (block.type === 'tool_use') {
|
|
18
|
+
tools.add(block.name);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return [...tools];
|
|
23
|
+
}
|
|
24
|
+
/** Generate a short summary from the first user message. */
|
|
25
|
+
function extractSummary(messages) {
|
|
26
|
+
for (const msg of messages) {
|
|
27
|
+
if (msg.role === 'user') {
|
|
28
|
+
const text = msg.content
|
|
29
|
+
.filter(b => b.type === 'text')
|
|
30
|
+
.map(b => b.text)
|
|
31
|
+
.join('')
|
|
32
|
+
.trim();
|
|
33
|
+
if (text) {
|
|
34
|
+
return text.length > 120 ? text.slice(0, 117) + '...' : text;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
export async function saveSession(sessionState, model) {
|
|
41
|
+
await ensureDir(SESSIONS_DIR);
|
|
42
|
+
const saved = {
|
|
43
|
+
id: sessionState.id,
|
|
44
|
+
messages: sessionState.messages,
|
|
45
|
+
projectRoot: sessionState.projectContext.rootDir,
|
|
46
|
+
model,
|
|
47
|
+
createdAt: sessionState.createdAt.toISOString(),
|
|
48
|
+
lastActivity: new Date().toISOString(),
|
|
49
|
+
toolsUsed: extractToolsUsed(sessionState.messages),
|
|
50
|
+
summary: extractSummary(sessionState.messages),
|
|
51
|
+
};
|
|
52
|
+
const filePath = join(SESSIONS_DIR, `${sessionState.id}.json`);
|
|
53
|
+
await writeFile(filePath, JSON.stringify(saved, null, 2), 'utf-8');
|
|
54
|
+
return sessionState.id;
|
|
55
|
+
}
|
|
56
|
+
export async function loadSession(sessionId) {
|
|
57
|
+
try {
|
|
58
|
+
const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
|
|
59
|
+
const data = await readFile(filePath, 'utf-8');
|
|
60
|
+
return JSON.parse(data);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** Find the most recent session for a given project directory. */
|
|
67
|
+
export async function findRecentSession(projectRoot) {
|
|
68
|
+
const sessions = await listSessions();
|
|
69
|
+
const match = sessions.find(s => s.projectRoot === projectRoot);
|
|
70
|
+
if (!match)
|
|
71
|
+
return null;
|
|
72
|
+
return loadSession(match.id);
|
|
73
|
+
}
|
|
74
|
+
export async function listSessions() {
|
|
75
|
+
try {
|
|
76
|
+
await ensureDir(SESSIONS_DIR);
|
|
77
|
+
const files = await readdir(SESSIONS_DIR);
|
|
78
|
+
const sessions = [];
|
|
79
|
+
for (const file of files) {
|
|
80
|
+
if (!file.endsWith('.json'))
|
|
81
|
+
continue;
|
|
82
|
+
try {
|
|
83
|
+
const data = await readFile(join(SESSIONS_DIR, file), 'utf-8');
|
|
84
|
+
const saved = JSON.parse(data);
|
|
85
|
+
sessions.push({
|
|
86
|
+
id: saved.id,
|
|
87
|
+
projectRoot: saved.projectRoot,
|
|
88
|
+
model: saved.model,
|
|
89
|
+
lastActivity: saved.lastActivity,
|
|
90
|
+
messageCount: saved.messages.length,
|
|
91
|
+
toolsUsed: saved.toolsUsed,
|
|
92
|
+
summary: saved.summary,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// skip corrupt files
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Most recent first
|
|
100
|
+
sessions.sort((a, b) => b.lastActivity.localeCompare(a.lastActivity));
|
|
101
|
+
return sessions;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Get the ~/.cmdr directory path. */
|
|
108
|
+
export function getCmdrDir() {
|
|
109
|
+
return CMDR_DIR;
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Debounced auto-save
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
export class DebouncedSaver {
|
|
115
|
+
timer = null;
|
|
116
|
+
intervalMs;
|
|
117
|
+
constructor(intervalMs = 5000) {
|
|
118
|
+
this.intervalMs = intervalMs;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Schedule a save. If one is already pending, it's a no-op (coalesce).
|
|
122
|
+
* Guaranteed at most once per intervalMs.
|
|
123
|
+
*/
|
|
124
|
+
schedule(fn) {
|
|
125
|
+
if (this.timer)
|
|
126
|
+
return; // already scheduled
|
|
127
|
+
this.timer = setTimeout(async () => {
|
|
128
|
+
this.timer = null;
|
|
129
|
+
try {
|
|
130
|
+
await fn();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// best effort
|
|
134
|
+
}
|
|
135
|
+
}, this.intervalMs);
|
|
136
|
+
}
|
|
137
|
+
/** Cancel any pending save. */
|
|
138
|
+
cancel() {
|
|
139
|
+
if (this.timer) {
|
|
140
|
+
clearTimeout(this.timer);
|
|
141
|
+
this.timer = null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Flush immediately (e.g., on exit). */
|
|
145
|
+
async flush(fn) {
|
|
146
|
+
this.cancel();
|
|
147
|
+
await fn();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=session-persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-persistence.js","sourceRoot":"","sources":["../../../src/session/session-persistence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UndoManager — tracks file changes made by the agent and supports reverting them.
|
|
3
|
+
*
|
|
4
|
+
* Stores snapshots of files before they are modified by file_write or file_edit tools.
|
|
5
|
+
*/
|
|
6
|
+
export interface FileChange {
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly type: 'create' | 'edit' | 'write';
|
|
9
|
+
readonly originalContent: string | null;
|
|
10
|
+
readonly timestamp: Date;
|
|
11
|
+
}
|
|
12
|
+
export declare class UndoManager {
|
|
13
|
+
private changes;
|
|
14
|
+
/**
|
|
15
|
+
* Record a file's state before modification.
|
|
16
|
+
* Call this BEFORE the tool writes to the file.
|
|
17
|
+
*/
|
|
18
|
+
recordBefore(filePath: string, type: 'create' | 'edit' | 'write'): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Undo the last file change.
|
|
21
|
+
* Returns the change that was undone, or null if nothing to undo.
|
|
22
|
+
*/
|
|
23
|
+
undoLast(): Promise<FileChange | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Undo ALL changes (most recent first).
|
|
26
|
+
*/
|
|
27
|
+
undoAll(): Promise<FileChange[]>;
|
|
28
|
+
/** Get the list of recorded changes (oldest first). */
|
|
29
|
+
getChanges(): FileChange[];
|
|
30
|
+
/** Number of undoable changes. */
|
|
31
|
+
get count(): number;
|
|
32
|
+
/** Clear change history without undoing. */
|
|
33
|
+
clear(): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=undo-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undo-manager.d.ts","sourceRoot":"","sources":["../../../src/session/undo-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;IAC1C,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IACvC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAA;CACzB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAmB;IAElC;;;OAGG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBtF;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAmB5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAStC,uDAAuD;IACvD,UAAU,IAAI,UAAU,EAAE;IAI1B,kCAAkC;IAClC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,4CAA4C;IAC5C,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UndoManager — tracks file changes made by the agent and supports reverting them.
|
|
3
|
+
*
|
|
4
|
+
* Stores snapshots of files before they are modified by file_write or file_edit tools.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile, writeFile, unlink } from 'fs/promises';
|
|
7
|
+
import { existsSync } from 'fs';
|
|
8
|
+
export class UndoManager {
|
|
9
|
+
changes = [];
|
|
10
|
+
/**
|
|
11
|
+
* Record a file's state before modification.
|
|
12
|
+
* Call this BEFORE the tool writes to the file.
|
|
13
|
+
*/
|
|
14
|
+
async recordBefore(filePath, type) {
|
|
15
|
+
let originalContent = null;
|
|
16
|
+
if (existsSync(filePath)) {
|
|
17
|
+
try {
|
|
18
|
+
originalContent = await readFile(filePath, 'utf-8');
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
originalContent = null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
this.changes.push({
|
|
25
|
+
path: filePath,
|
|
26
|
+
type,
|
|
27
|
+
originalContent,
|
|
28
|
+
timestamp: new Date(),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Undo the last file change.
|
|
33
|
+
* Returns the change that was undone, or null if nothing to undo.
|
|
34
|
+
*/
|
|
35
|
+
async undoLast() {
|
|
36
|
+
const change = this.changes.pop();
|
|
37
|
+
if (!change)
|
|
38
|
+
return null;
|
|
39
|
+
if (change.originalContent === null) {
|
|
40
|
+
// File was newly created — delete it
|
|
41
|
+
try {
|
|
42
|
+
await unlink(change.path);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// File may have been deleted already
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Restore original content
|
|
50
|
+
await writeFile(change.path, change.originalContent, 'utf-8');
|
|
51
|
+
}
|
|
52
|
+
return change;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Undo ALL changes (most recent first).
|
|
56
|
+
*/
|
|
57
|
+
async undoAll() {
|
|
58
|
+
const undone = [];
|
|
59
|
+
while (this.changes.length > 0) {
|
|
60
|
+
const change = await this.undoLast();
|
|
61
|
+
if (change)
|
|
62
|
+
undone.push(change);
|
|
63
|
+
}
|
|
64
|
+
return undone;
|
|
65
|
+
}
|
|
66
|
+
/** Get the list of recorded changes (oldest first). */
|
|
67
|
+
getChanges() {
|
|
68
|
+
return [...this.changes];
|
|
69
|
+
}
|
|
70
|
+
/** Number of undoable changes. */
|
|
71
|
+
get count() {
|
|
72
|
+
return this.changes.length;
|
|
73
|
+
}
|
|
74
|
+
/** Clear change history without undoing. */
|
|
75
|
+
clear() {
|
|
76
|
+
this.changes = [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=undo-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undo-manager.js","sourceRoot":"","sources":["../../../src/session/undo-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAS/B,MAAM,OAAO,WAAW;IACd,OAAO,GAAiB,EAAE,CAAA;IAElC;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,QAAgB,EAAE,IAAiC;QACpE,IAAI,eAAe,GAAkB,IAAI,CAAA;QAEzC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,eAAe,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YACrD,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe,GAAG,IAAI,CAAA;YACxB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,QAAQ;YACd,IAAI;YACJ,eAAe;YACf,SAAS,EAAE,IAAI,IAAI,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ;QACZ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAExB,IAAI,MAAM,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;YACpC,qCAAqC;YACrC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,2BAA2B;YAC3B,MAAM,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;QAC/D,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,MAAM,GAAiB,EAAE,CAAA;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAA;YACpC,IAAI,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,uDAAuD;IACvD,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;IAED,kCAAkC;IAClC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;IAC5B,CAAC;IAED,4CAA4C;IAC5C,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-user.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/ask-user.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,eAAO,MAAM,WAAW;;EAqBtB,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ask_user — prompt the user for input/confirmation mid-task.
|
|
3
|
+
*/
|
|
4
|
+
import * as readline from 'readline';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { defineTool } from '../registry.js';
|
|
7
|
+
export const askUserTool = defineTool({
|
|
8
|
+
name: 'ask_user',
|
|
9
|
+
description: 'Ask the user a question and get their response. Use when you need clarification or a decision.',
|
|
10
|
+
inputSchema: z.object({
|
|
11
|
+
question: z.string().describe('The question to ask the user'),
|
|
12
|
+
}),
|
|
13
|
+
execute: async (input) => {
|
|
14
|
+
return new Promise((resolve) => {
|
|
15
|
+
const rl = readline.createInterface({
|
|
16
|
+
input: process.stdin,
|
|
17
|
+
output: process.stdout,
|
|
18
|
+
terminal: true,
|
|
19
|
+
});
|
|
20
|
+
console.log('');
|
|
21
|
+
rl.question(` \u001b[35m?\u001b[0m ${input.question}\n \u001b[90m>\u001b[0m `, (answer) => {
|
|
22
|
+
rl.close();
|
|
23
|
+
resolve({ data: answer.trim() || '(no response)' });
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=ask-user.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-user.js","sourceRoot":"","sources":["../../../../src/tools/built-in/ask-user.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAA;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;IACpC,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,gGAAgG;IAC7G,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAC9D,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACvB,OAAO,IAAI,OAAO,CAAmB,CAAC,OAAO,EAAE,EAAE;YAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;gBAClC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAA;YAEF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACf,EAAE,CAAC,QAAQ,CAAC,0BAA0B,KAAK,CAAC,QAAQ,2BAA2B,EAAE,CAAC,MAAM,EAAE,EAAE;gBAC1F,EAAE,CAAC,KAAK,EAAE,CAAA;gBACV,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,eAAe,EAAE,CAAC,CAAA;YACrD,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/bash.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,eAAO,MAAM,QAAQ;;;;EA6BnB,CAAA"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in bash tool — execute shell commands.
|
|
3
|
+
*/
|
|
4
|
+
import { spawn } from 'child_process';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { defineTool } from '../registry.js';
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
8
|
+
export const bashTool = defineTool({
|
|
9
|
+
name: 'bash',
|
|
10
|
+
description: 'Execute a bash command and return stdout/stderr. ' +
|
|
11
|
+
'Use for file operations, running scripts, installing packages, etc. ' +
|
|
12
|
+
'The command runs in a non-interactive shell (bash -c).',
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
command: z.string().describe('The bash command to execute.'),
|
|
15
|
+
timeout: z.number().optional().describe(`Timeout in ms. Defaults to ${DEFAULT_TIMEOUT_MS}.`),
|
|
16
|
+
cwd: z.string().optional().describe('Working directory for the command.'),
|
|
17
|
+
}),
|
|
18
|
+
execute: async (input, context) => {
|
|
19
|
+
const timeoutMs = input.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
20
|
+
const cwd = input.cwd ?? context.cwd ?? process.cwd();
|
|
21
|
+
const { stdout, stderr, exitCode } = await runCommand(input.command, cwd, timeoutMs, context.abortSignal);
|
|
22
|
+
const parts = [];
|
|
23
|
+
if (stdout)
|
|
24
|
+
parts.push(stdout);
|
|
25
|
+
if (stderr)
|
|
26
|
+
parts.push(`[stderr]\n${stderr}`);
|
|
27
|
+
if (exitCode !== 0)
|
|
28
|
+
parts.push(`[exit code: ${exitCode}]`);
|
|
29
|
+
return {
|
|
30
|
+
data: parts.join('\n') || '(no output)',
|
|
31
|
+
isError: exitCode !== 0,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
function runCommand(command, cwd, timeoutMs, signal) {
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
const stdoutChunks = [];
|
|
38
|
+
const stderrChunks = [];
|
|
39
|
+
const child = spawn('bash', ['-c', command], {
|
|
40
|
+
cwd,
|
|
41
|
+
env: process.env,
|
|
42
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
43
|
+
});
|
|
44
|
+
child.stdout.on('data', (chunk) => stdoutChunks.push(chunk));
|
|
45
|
+
child.stderr.on('data', (chunk) => stderrChunks.push(chunk));
|
|
46
|
+
const timer = setTimeout(() => {
|
|
47
|
+
child.kill('SIGKILL');
|
|
48
|
+
}, timeoutMs);
|
|
49
|
+
const onAbort = () => child.kill('SIGKILL');
|
|
50
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
51
|
+
child.on('close', (code) => {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
signal?.removeEventListener('abort', onAbort);
|
|
54
|
+
resolve({
|
|
55
|
+
stdout: Buffer.concat(stdoutChunks).toString('utf-8'),
|
|
56
|
+
stderr: Buffer.concat(stderrChunks).toString('utf-8'),
|
|
57
|
+
exitCode: code ?? 1,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
child.on('error', (err) => {
|
|
61
|
+
clearTimeout(timer);
|
|
62
|
+
signal?.removeEventListener('abort', onAbort);
|
|
63
|
+
resolve({ stdout: '', stderr: err.message, exitCode: 1 });
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=bash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../../src/tools/built-in/bash.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,kBAAkB,GAAG,MAAM,CAAA;AAEjC,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IACjC,IAAI,EAAE,MAAM;IACZ,WAAW,EACT,mDAAmD;QACnD,sEAAsE;QACtE,wDAAwD;IAE1D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;QAC5D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,kBAAkB,GAAG,CAAC;QAC5F,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KAC1E,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,IAAI,kBAAkB,CAAA;QACrD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;QAErD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;QAEzG,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,IAAI,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC9B,IAAI,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,EAAE,CAAC,CAAA;QAC7C,IAAI,QAAQ,KAAK,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,eAAe,QAAQ,GAAG,CAAC,CAAA;QAE1D,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa;YACvC,OAAO,EAAE,QAAQ,KAAK,CAAC;SACxB,CAAA;IACH,CAAC;CACF,CAAC,CAAA;AAIF,SAAS,UAAU,CACjB,OAAe,EACf,GAAW,EACX,SAAiB,EACjB,MAAoB;IAEpB,OAAO,IAAI,OAAO,CAAY,CAAC,OAAO,EAAE,EAAE;QACxC,MAAM,YAAY,GAAa,EAAE,CAAA;QACjC,MAAM,YAAY,GAAa,EAAE,CAAA;QAEjC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;YAC3C,GAAG;YACH,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAA;QAEF,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QACpE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAEpE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACvB,CAAC,EAAE,SAAS,CAAC,CAAA;QAEb,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAC3C,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;QAE1D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC7C,OAAO,CAAC;gBACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACrD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACrD,QAAQ,EAAE,IAAI,IAAI,CAAC;aACpB,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACxB,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAA;QAC3D,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-edit.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/file-edit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,eAAO,MAAM,YAAY;;;;EAmCvB,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in file_edit tool — replace exact strings in files.
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
5
|
+
import { resolve } from 'path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { defineTool } from '../registry.js';
|
|
8
|
+
export const fileEditTool = defineTool({
|
|
9
|
+
name: 'file_edit',
|
|
10
|
+
description: 'Edit a file by replacing an exact string with a new string. ' +
|
|
11
|
+
'The old_string must appear exactly once in the file. ' +
|
|
12
|
+
'Use this for surgical edits instead of rewriting entire files.',
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
path: z.string().describe('Absolute or relative path to the file.'),
|
|
15
|
+
old_string: z.string().describe('The exact string to find and replace. Must appear exactly once.'),
|
|
16
|
+
new_string: z.string().describe('The replacement string.'),
|
|
17
|
+
}),
|
|
18
|
+
execute: async (input, context) => {
|
|
19
|
+
try {
|
|
20
|
+
const filePath = resolve(context.cwd ?? process.cwd(), input.path);
|
|
21
|
+
const content = await readFile(filePath, 'utf-8');
|
|
22
|
+
const occurrences = content.split(input.old_string).length - 1;
|
|
23
|
+
if (occurrences === 0) {
|
|
24
|
+
return { data: `old_string not found in ${input.path}`, isError: true };
|
|
25
|
+
}
|
|
26
|
+
if (occurrences > 1) {
|
|
27
|
+
return { data: `old_string found ${occurrences} times in ${input.path}. Must appear exactly once.`, isError: true };
|
|
28
|
+
}
|
|
29
|
+
const updated = content.replace(input.old_string, input.new_string);
|
|
30
|
+
await writeFile(filePath, updated, 'utf-8');
|
|
31
|
+
return { data: `Edited ${input.path}: replaced ${input.old_string.length} chars with ${input.new_string.length} chars.` };
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
35
|
+
return { data: msg, isError: true };
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=file-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-edit.js","sourceRoot":"","sources":["../../../../src/tools/built-in/file-edit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,WAAW;IACjB,WAAW,EACT,8DAA8D;QAC9D,uDAAuD;QACvD,gEAAgE;IAElE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iEAAiE,CAAC;QAClG,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;KAC3D,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YAClE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAEjD,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAA;YAC9D,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,IAAI,EAAE,2BAA2B,KAAK,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;YACzE,CAAC;YACD,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACpB,OAAO,EAAE,IAAI,EAAE,oBAAoB,WAAW,aAAa,KAAK,CAAC,IAAI,6BAA6B,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;YACrH,CAAC;YAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAA;YACnE,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;YAE3C,OAAO,EAAE,IAAI,EAAE,UAAU,KAAK,CAAC,IAAI,cAAc,KAAK,CAAC,UAAU,CAAC,MAAM,eAAe,KAAK,CAAC,UAAU,CAAC,MAAM,SAAS,EAAE,CAAA;QAC3H,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QACrC,CAAC;IACH,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in file_read tool — read file contents with offset/limit support.
|
|
3
|
+
*/
|
|
4
|
+
export declare const fileReadTool: import("../registry.js").ToolDefinition<{
|
|
5
|
+
path: string;
|
|
6
|
+
offset?: number | undefined;
|
|
7
|
+
limit?: number | undefined;
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=file-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-read.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/file-read.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,eAAO,MAAM,YAAY;;;;EAqCvB,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in file_read tool — read file contents with offset/limit support.
|
|
3
|
+
*/
|
|
4
|
+
import { readFile, stat } from 'fs/promises';
|
|
5
|
+
import { resolve } from 'path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { defineTool } from '../registry.js';
|
|
8
|
+
export const fileReadTool = defineTool({
|
|
9
|
+
name: 'file_read',
|
|
10
|
+
description: 'Read the contents of a file. Supports offset and limit for large files. ' +
|
|
11
|
+
'Returns the file text or an error if the file does not exist.',
|
|
12
|
+
inputSchema: z.object({
|
|
13
|
+
path: z.string().describe('Absolute or relative path to the file.'),
|
|
14
|
+
offset: z.number().optional().describe('Line number to start reading from (0-based).'),
|
|
15
|
+
limit: z.number().optional().describe('Maximum number of lines to return.'),
|
|
16
|
+
}),
|
|
17
|
+
execute: async (input, context) => {
|
|
18
|
+
try {
|
|
19
|
+
const filePath = resolve(context.cwd ?? process.cwd(), input.path);
|
|
20
|
+
const info = await stat(filePath);
|
|
21
|
+
if (!info.isFile()) {
|
|
22
|
+
return { data: `"${input.path}" is not a file.`, isError: true };
|
|
23
|
+
}
|
|
24
|
+
const content = await readFile(filePath, 'utf-8');
|
|
25
|
+
if (input.offset !== undefined || input.limit !== undefined) {
|
|
26
|
+
const lines = content.split('\n');
|
|
27
|
+
const start = input.offset ?? 0;
|
|
28
|
+
const end = input.limit !== undefined ? start + input.limit : lines.length;
|
|
29
|
+
const slice = lines.slice(start, end);
|
|
30
|
+
const header = `[Lines ${start}-${Math.min(end, lines.length)} of ${lines.length}]\n`;
|
|
31
|
+
return { data: header + slice.join('\n') };
|
|
32
|
+
}
|
|
33
|
+
return { data: content };
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
37
|
+
return { data: msg, isError: true };
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=file-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-read.js","sourceRoot":"","sources":["../../../../src/tools/built-in/file-read.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,WAAW;IACjB,WAAW,EACT,0EAA0E;QAC1E,+DAA+D;IAEjE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACnE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QACtF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;KAC5E,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YAClE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,OAAO,EAAE,IAAI,EAAE,IAAI,KAAK,CAAC,IAAI,kBAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;YAClE,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAEjD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC5D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACjC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAA;gBAC/B,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;gBAC1E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;gBACrC,MAAM,MAAM,GAAG,UAAU,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;gBACrF,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;YAC5C,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QACrC,CAAC;IACH,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-write.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/file-write.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,eAAO,MAAM,aAAa;;;EAsBxB,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in file_write tool — create or overwrite files.
|
|
3
|
+
*/
|
|
4
|
+
import { writeFile, mkdir } from 'fs/promises';
|
|
5
|
+
import { resolve, dirname } from 'path';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { defineTool } from '../registry.js';
|
|
8
|
+
export const fileWriteTool = defineTool({
|
|
9
|
+
name: 'file_write',
|
|
10
|
+
description: 'Write content to a file. Creates the file and parent directories if they do not exist. ' +
|
|
11
|
+
'Overwrites existing content. Use file_edit for surgical changes.',
|
|
12
|
+
inputSchema: z.object({
|
|
13
|
+
path: z.string().describe('Absolute or relative path to the file.'),
|
|
14
|
+
content: z.string().describe('The full content to write to the file.'),
|
|
15
|
+
}),
|
|
16
|
+
execute: async (input, context) => {
|
|
17
|
+
try {
|
|
18
|
+
const filePath = resolve(context.cwd ?? process.cwd(), input.path);
|
|
19
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
20
|
+
await writeFile(filePath, input.content, 'utf-8');
|
|
21
|
+
return { data: `Wrote ${input.content.length} bytes to ${input.path}` };
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
25
|
+
return { data: msg, isError: true };
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=file-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-write.js","sourceRoot":"","sources":["../../../../src/tools/built-in/file-write.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;IACtC,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,yFAAyF;QACzF,kEAAkE;IAEpE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACnE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;KACvE,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YAClE,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACnD,MAAM,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YACjD,OAAO,EAAE,IAAI,EAAE,SAAS,KAAK,CAAC,OAAO,CAAC,MAAM,aAAa,KAAK,CAAC,IAAI,EAAE,EAAE,CAAA;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QACrC,CAAC;IACH,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in git_commit tool — commit changes from the working tree.
|
|
3
|
+
*/
|
|
4
|
+
export declare const gitCommitTool: import("../registry.js").ToolDefinition<{
|
|
5
|
+
message: string;
|
|
6
|
+
files?: string[] | undefined;
|
|
7
|
+
}>;
|
|
8
|
+
export declare const gitBranchTool: import("../registry.js").ToolDefinition<{
|
|
9
|
+
action: "list" | "create" | "switch";
|
|
10
|
+
name?: string | undefined;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=git-commit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-commit.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/git-commit.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6BH,eAAO,MAAM,aAAa;;;EAyCxB,CAAA;AAEF,eAAO,MAAM,aAAa;;;EAoCxB,CAAA"}
|