65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
|
// Licensed under the Apache License, Version 2.0
|
|
|
|
import path from "node:path";
|
|
|
|
import { formatError, type IToolError } from "@gadget/ai";
|
|
import type { AiToolbox } from "../toolbox.ts";
|
|
import { getProjectRoot, toolError } from "../system/common.ts";
|
|
|
|
export interface ResolvedPlanPath {
|
|
inputPath: string;
|
|
absolutePath: string;
|
|
displayPath: string;
|
|
}
|
|
|
|
export function getGadgetDir(toolbox: AiToolbox): string | undefined {
|
|
const projectRoot = getProjectRoot(toolbox);
|
|
if (!projectRoot) return undefined;
|
|
return path.resolve(projectRoot, ".gadget");
|
|
}
|
|
|
|
export function resolvePlanPath(
|
|
toolbox: AiToolbox,
|
|
inputPath: string,
|
|
): ResolvedPlanPath | string {
|
|
const gadgetDir = getGadgetDir(toolbox);
|
|
if (!gadgetDir) {
|
|
return toolError({
|
|
code: "OPERATION_NOT_ALLOWED",
|
|
message: "No active project workspace is configured for plan file tools.",
|
|
recoveryHint: "Run this tool during an active Agent work order in Plan mode.",
|
|
});
|
|
}
|
|
|
|
const trimmedPath = inputPath.trim();
|
|
if (!trimmedPath) {
|
|
return toolError({
|
|
code: "MISSING_PARAMETER",
|
|
message: "File path must not be empty.",
|
|
parameter: "path",
|
|
recoveryHint: "Provide a valid file path within the .gadget directory.",
|
|
});
|
|
}
|
|
|
|
const absolutePath = path.isAbsolute(trimmedPath)
|
|
? path.resolve(trimmedPath)
|
|
: path.resolve(gadgetDir, trimmedPath);
|
|
const relative = path.relative(gadgetDir, absolutePath);
|
|
|
|
if (relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative))) {
|
|
return {
|
|
inputPath: trimmedPath,
|
|
absolutePath,
|
|
displayPath: relative || ".",
|
|
};
|
|
}
|
|
|
|
return toolError({
|
|
code: "SECURITY_VIOLATION",
|
|
message: `Path is outside the .gadget directory: ${trimmedPath}`,
|
|
parameter: "path",
|
|
recoveryHint: "Use a relative path inside the project's .gadget directory.",
|
|
});
|
|
}
|