@particle-academy/agent-integrations 0.40.0 → 0.41.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/dist/index.cjs CHANGED
@@ -2800,6 +2800,13 @@ function registerGitBridge(host, options) {
2800
2800
  // src/bridges/files.ts
2801
2801
  var DEFAULT_AGENT10 = { id: "agent", name: "Agent", color: "#a855f7" };
2802
2802
  var MAX_SNAPSHOT_DEPTH = 8;
2803
+ function invalidFolderName(name) {
2804
+ const trimmed = name.trim();
2805
+ if (trimmed === "") return "A folder name is required.";
2806
+ if (trimmed.includes("/") || trimmed.includes("\\")) return "A folder name may not contain a path separator.";
2807
+ if (trimmed === "." || trimmed === "..") return "That folder name is reserved.";
2808
+ return null;
2809
+ }
2803
2810
  function assertPathWithinRoot(root, path) {
2804
2811
  const segments = path.replace(/[\\/]+/g, "/").split("/");
2805
2812
  if (segments.includes("..")) {
@@ -2829,6 +2836,7 @@ var asPaths = (v) => {
2829
2836
  function registerFilesBridge(host, options) {
2830
2837
  const { adapter } = options;
2831
2838
  const agent = { ...DEFAULT_AGENT10, ...options.agent ?? {} };
2839
+ const pendingMode = options.pendingMode ?? true;
2832
2840
  const disposers = [];
2833
2841
  const guard = (path) => {
2834
2842
  if (options.root !== void 0) assertPathWithinRoot(options.root, path);
@@ -2995,6 +3003,42 @@ function registerFilesBridge(host, options) {
2995
3003
  },
2996
3004
  fTarget
2997
3005
  );
3006
+ if (adapter.createFolder) {
3007
+ reg(
3008
+ "files_create_folder",
3009
+ "Create a folder inside `parentPath`. Staged for human confirmation unless the host disabled pendingMode.",
3010
+ {
3011
+ parentPath: { type: "string", description: "Directory to create in; defaults to the current directory." },
3012
+ name: { type: "string", description: "The new folder's name. A leaf name \u2014 no separators." },
3013
+ confirm: { type: "boolean", description: "Acknowledge a staged write when the host wired no confirm hook." }
3014
+ },
3015
+ ["name"],
3016
+ async (args) => {
3017
+ const parentPath = guard(args.parentPath !== void 0 ? str3(args.parentPath) : adapter.getPath());
3018
+ const name = str3(args.name).trim();
3019
+ const invalid = invalidFolderName(name);
3020
+ if (invalid) return errorResult(invalid);
3021
+ const label = `${parentPath}/${name}`;
3022
+ if (pendingMode) {
3023
+ if (options.confirm) {
3024
+ const ok = await options.confirm({ action: "files_create_folder", path: label, label });
3025
+ if (!ok) return errorResult(`Declined: create folder ${label} (human did not confirm).`);
3026
+ } else if (args.confirm !== true) {
3027
+ return errorResult(
3028
+ `Staged: create folder ${label}. Re-call with confirm:true to proceed.`
3029
+ );
3030
+ }
3031
+ }
3032
+ try {
3033
+ await adapter.createFolder({ parentPath, name });
3034
+ } catch (e) {
3035
+ return errorResult(e instanceof Error ? e.message : String(e));
3036
+ }
3037
+ return textResult(`Created folder ${label}.`, { parentPath, name, path: label });
3038
+ },
3039
+ (args) => ({ kind: "directory", path: `${str3(args.parentPath)}/${str3(args.name)}`, label: str3(args.name) })
3040
+ );
3041
+ }
2998
3042
  reg(
2999
3043
  "files_request_snapshot",
3000
3044
  "Request a fresh snapshot subtree rooted at `path` (snapshot mode) \u2014 e.g. to pull a remote machine's current tree. Requires the host to wire requestSnapshot.",