omp-fabric 1.3.1 → 1.3.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.2
4
+
5
+ ### Fixed
6
+
7
+ - **`omp.write` never resolved an internal URL, so `local://` writes landed in a literal `local:` directory.** Fabric replaces the host's write tool with its own implementation to attach diff previews, and that replacement carried no internal-URL handling: `resolve(cwd, "local://notes.md")` collapses the scheme into a path segment and produced `<cwd>/local:/notes.md`. Subagents are instructed to exchange findings through `local://` files, so a real project accumulated one of these directories with five files in it. Meanwhile `omp.read` resolves `local://` correctly, because Fabric binds the host's read tool unchanged, so a write and a read of the same URL disagreed about where the file was.
8
+
9
+ URI-like write targets are now delegated to the host's write tool, which resolves them: `local://round-trip.md` writes to the session's local root under `omp-local`, `xd://` reports that no device is mounted, `artifact://` reports that it is read-only for writes, and an unknown scheme keeps the host's own guidance. Ordinary filesystem writes keep the diff preview.
10
+
11
+ 1.3.0 turned the silent mis-write into a refusal, which stopped the stray directories but left agents unable to write `local://` at all under full code mode, since the top-level write tool only accepts `local://` during plan mode. This completes that fix.
12
+
13
+ ### Notes
14
+
15
+ - A directory literally named `local:` inside a project is the signature of this defect from any Fabric before 1.3.0. Its contents are real files and can be moved or deleted; nothing reads them at that path.
16
+
3
17
  ## 1.3.1
4
18
 
5
19
  ### Fixed
@@ -9761,6 +9761,7 @@ import { homedir } from "node:os";
9761
9761
  import { dirname, isAbsolute, resolve, win32 } from "node:path";
9762
9762
  import { mkdir, readFile as readFile2, stat, writeFile } from "node:fs/promises";
9763
9763
  import { Type as Type4 } from "@oh-my-pi/pi-coding-agent/extensibility/legacy-typebox";
9764
+ import { WriteTool } from "@oh-my-pi/pi-coding-agent/tools/write";
9764
9765
  var mutationQueues = /* @__PURE__ */ new Map();
9765
9766
  var withFileMutationQueue = async (path20, operation) => {
9766
9767
  const previous = mutationQueues.get(path20) ?? Promise.resolve();
@@ -9778,29 +9779,18 @@ var withFileMutationQueue = async (path20, operation) => {
9778
9779
  }
9779
9780
  };
9780
9781
  var URI_LIKE_WRITE_TARGET_RE = /^([a-z][a-z0-9+.-]*):\/{1,2}/i;
9781
- var OmpWriteUriTargetError = class extends Error {
9782
- path;
9783
- constructor(message2, path20) {
9784
- super(message2);
9785
- this.name = "OmpWriteUriTargetError";
9786
- this.path = path20;
9787
- }
9788
- };
9789
- var assertFilesystemWriteTarget = (candidate, reported) => {
9782
+ var uriLikeScheme = (candidate) => {
9790
9783
  const trimmed = candidate.trim();
9791
- if (win32.isAbsolute(trimmed)) return;
9792
- const scheme = URI_LIKE_WRITE_TARGET_RE.exec(trimmed)?.[1]?.toLowerCase();
9793
- if (scheme === void 0) return;
9794
- const guidance = scheme === "xd" ? "Tool devices are dispatched by the top-level `write` tool, which carries the xd:// transport; omp.write writes files." : "omp.write resolves filesystem paths only.";
9795
- throw new OmpWriteUriTargetError(
9796
- `Refusing to write '${reported}': '${scheme}://' is a URI scheme, not a directory. ${guidance} Prefix the path with './' to create a literal file by that name.`,
9797
- reported
9798
- );
9784
+ if (win32.isAbsolute(trimmed)) return void 0;
9785
+ return URI_LIKE_WRITE_TARGET_RE.exec(trimmed)?.[1]?.toLowerCase();
9786
+ };
9787
+ var isUriLikeWriteTarget = (filePath) => {
9788
+ const expanded = filePath.startsWith("@") ? filePath.slice(1) : filePath;
9789
+ return uriLikeScheme(expanded.replace(/[\u00a0\u2000-\u200a\u202f\u205f\u3000]/g, " ")) !== void 0;
9799
9790
  };
9800
9791
  var resolvePreviewPath = (filePath, cwd) => {
9801
9792
  let expanded = filePath.startsWith("@") ? filePath.slice(1) : filePath;
9802
9793
  expanded = expanded.replace(/[\u00a0\u2000-\u200a\u202f\u205f\u3000]/g, " ");
9803
- assertFilesystemWriteTarget(expanded, filePath);
9804
9794
  if (expanded === "~") expanded = homedir();
9805
9795
  else if (expanded.startsWith("~/")) expanded = homedir() + expanded.slice(1);
9806
9796
  return isAbsolute(expanded) ? expanded : resolve(cwd, expanded);
@@ -9837,7 +9827,7 @@ var readExistingFileForPreview = async (filePath, cwd, nextContent) => {
9837
9827
  return skipped("previous content unavailable", fileStat.size);
9838
9828
  }
9839
9829
  };
9840
- var createPreviewWriteToolDefinition = (cwd) => {
9830
+ var createPreviewWriteToolDefinition = (cwd, session) => {
9841
9831
  const original = {
9842
9832
  name: "write",
9843
9833
  label: "Write",
@@ -9849,6 +9839,21 @@ var createPreviewWriteToolDefinition = (cwd) => {
9849
9839
  ...original,
9850
9840
  async execute(_toolCallId, params, signal) {
9851
9841
  const { path: path20, content } = params;
9842
+ if (isUriLikeWriteTarget(path20)) {
9843
+ if (session === void 0) {
9844
+ throw new Error(
9845
+ `Refusing to write '${path20}': URI-like targets need a host session to resolve. Prefix the path with './' to create a literal file by that name.`
9846
+ );
9847
+ }
9848
+ return await new WriteTool(session).execute(
9849
+ _toolCallId,
9850
+ params,
9851
+ signal,
9852
+ (() => {
9853
+ }),
9854
+ { signal }
9855
+ );
9856
+ }
9852
9857
  const absolutePath = resolvePreviewPath(path20, cwd);
9853
9858
  return withFileMutationQueue(absolutePath, async () => {
9854
9859
  const throwIfAborted2 = () => {
@@ -10444,7 +10449,7 @@ var OmpToolsProvider = class _OmpToolsProvider {
10444
10449
  read: createNativeReadToolDefinition(cwd),
10445
10450
  bash: createNativeBashToolDefinition(cwd, this.#artifactPaths),
10446
10451
  edit: createNativeReplaceEditToolDefinition(cwd),
10447
- write: createPreviewWriteToolDefinition(cwd),
10452
+ write: createPreviewWriteToolDefinition(cwd, createNativeSession(cwd)),
10448
10453
  grep: createGrepDefinitionWithSkip(cwd),
10449
10454
  find: createFindDefinitionWithFilters(cwd),
10450
10455
  ls: createLsToolDefinition(cwd)