v2.4.0
This commit is contained in:
@@ -17,6 +17,8 @@ export async function executeMemoryFileSearch(args: {
|
||||
keywords: string | string[];
|
||||
scope?: string;
|
||||
context_lines?: number;
|
||||
_workspacePath?: string;
|
||||
_workspace?: string;
|
||||
}): Promise<ToolResult> {
|
||||
// Parse keywords
|
||||
let keywords: string[] = [];
|
||||
@@ -36,7 +38,7 @@ export async function executeMemoryFileSearch(args: {
|
||||
const scope = String(args?.scope || 'both').toLowerCase().trim();
|
||||
const contextLines = Math.max(0, Math.min(3, Number(args?.context_lines ?? 1)));
|
||||
|
||||
const workspacePath = getConfig().getWorkspacePath();
|
||||
const workspacePath = args?._workspacePath || args?._workspace || getConfig().getWorkspacePath();
|
||||
|
||||
// Determine which files to search
|
||||
const filesToSearch: Array<{ label: string; path: string }> = [];
|
||||
|
||||
@@ -17,7 +17,9 @@ const FILE_MAP: Record<string, string> = {
|
||||
memory: 'MEMORY.md',
|
||||
};
|
||||
|
||||
export async function executeMemoryRead(args: { target: string }): Promise<ToolResult> {
|
||||
export async function executeMemoryRead(
|
||||
args: { target: string; _workspacePath?: string; _workspace?: string },
|
||||
): Promise<ToolResult> {
|
||||
const target = String(args?.target || '').toLowerCase().trim();
|
||||
const filename = FILE_MAP[target];
|
||||
|
||||
@@ -29,7 +31,7 @@ export async function executeMemoryRead(args: { target: string }): Promise<ToolR
|
||||
}
|
||||
|
||||
try {
|
||||
const workspacePath = getConfig().getWorkspacePath();
|
||||
const workspacePath = args?._workspacePath || args?._workspace || getConfig().getWorkspacePath();
|
||||
const filePath = path.join(workspacePath, filename);
|
||||
|
||||
if (!fs.existsSync(filePath)) {
|
||||
|
||||
+15
-6
@@ -26,27 +26,33 @@ const ALLOWED_PERSONA_FILES = new Set([
|
||||
'TOOLS.md',
|
||||
]);
|
||||
|
||||
function getWorkspacePath(): string {
|
||||
function resolveWorkspacePath(args: { _workspacePath?: string; _workspace?: string } | undefined | null): string {
|
||||
// Caller (executeTool) injects _workspacePath / _workspace with the user-scoped
|
||||
// workspace. Fall back to global only if neither was provided (CLI/legacy paths).
|
||||
const fromArgs = args?._workspacePath || args?._workspace;
|
||||
if (fromArgs && typeof fromArgs === 'string') return fromArgs;
|
||||
return getConfig().getWorkspacePath();
|
||||
}
|
||||
|
||||
function resolvePersonaFile(filename: string): string | null {
|
||||
function resolvePersonaFile(filename: string, workspacePath: string): string | null {
|
||||
const clean = path.basename(filename.trim());
|
||||
if (!ALLOWED_PERSONA_FILES.has(clean)) return null;
|
||||
return path.join(getWorkspacePath(), clean);
|
||||
return path.join(workspacePath, clean);
|
||||
}
|
||||
|
||||
// ─── persona_read ─────────────────────────────────────────────────────────────
|
||||
|
||||
export interface PersonaReadArgs {
|
||||
file: string; // one of SOUL.md, USER.md, IDENTITY.md, MEMORY.md, etc.
|
||||
_workspacePath?: string;
|
||||
_workspace?: string;
|
||||
}
|
||||
|
||||
export async function executePersonaRead(args: PersonaReadArgs): Promise<ToolResult> {
|
||||
if (!args?.file?.trim()) {
|
||||
return { success: false, error: `file is required. Allowed: ${[...ALLOWED_PERSONA_FILES].join(', ')}` };
|
||||
}
|
||||
const absPath = resolvePersonaFile(args.file);
|
||||
const absPath = resolvePersonaFile(args.file, resolveWorkspacePath(args));
|
||||
if (!absPath) {
|
||||
return { success: false, error: `Not an editable persona file: "${args.file}". Allowed: ${[...ALLOWED_PERSONA_FILES].join(', ')}` };
|
||||
}
|
||||
@@ -96,6 +102,8 @@ export interface PersonaUpdateArgs {
|
||||
section_heading?: string; // for replace_section: heading to target (e.g. "## Notes")
|
||||
key?: string; // for upsert_line: substring to match existing line
|
||||
reason?: string; // why this update (logged to daily memory)
|
||||
_workspacePath?: string;
|
||||
_workspace?: string;
|
||||
}
|
||||
|
||||
export async function executePersonaUpdate(args: PersonaUpdateArgs): Promise<ToolResult> {
|
||||
@@ -109,7 +117,8 @@ export async function executePersonaUpdate(args: PersonaUpdateArgs): Promise<Too
|
||||
return { success: false, error: 'content is required' };
|
||||
}
|
||||
|
||||
const absPath = resolvePersonaFile(args.file);
|
||||
const workspacePath = resolveWorkspacePath(args);
|
||||
const absPath = resolvePersonaFile(args.file, workspacePath);
|
||||
if (!absPath) {
|
||||
return { success: false, error: `Not an editable persona file: "${args.file}". Allowed: ${[...ALLOWED_PERSONA_FILES].join(', ')}` };
|
||||
}
|
||||
@@ -195,7 +204,7 @@ export async function executePersonaUpdate(args: PersonaUpdateArgs): Promise<Too
|
||||
// Log the update to today's daily memory
|
||||
try {
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
const memDir = path.join(getWorkspacePath(), 'memory');
|
||||
const memDir = path.join(workspacePath, 'memory');
|
||||
fs.mkdirSync(memDir, { recursive: true });
|
||||
const logPath = path.join(memDir, `${today}.md`);
|
||||
const ts = new Date().toLocaleTimeString('en-US', { hour12: false });
|
||||
|
||||
Reference in New Issue
Block a user