@oh-my-pi/pi-coding-agent 13.1.0 → 13.1.1

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
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [13.1.1] - 2026-02-23
6
+
7
+ ### Fixed
8
+
9
+ - Fixed bash internal URL expansion to resolve `local://` targets to concrete filesystem paths, including newly created destination files for commands like `mv src.json local://dest.json`
10
+ - Fixed bash local URL resolution to create missing parent directories under the session local root before command execution, preventing `mv` destination failures for new paths
5
11
  ## [13.1.0] - 2026-02-23
6
12
  ### Breaking Changes
7
13
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "13.1.0",
4
+ "version": "13.1.1",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/can1357/oh-my-pi",
7
7
  "author": "Can Boluk",
@@ -41,12 +41,12 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@mozilla/readability": "^0.6",
44
- "@oh-my-pi/omp-stats": "13.1.0",
45
- "@oh-my-pi/pi-agent-core": "13.1.0",
46
- "@oh-my-pi/pi-ai": "13.1.0",
47
- "@oh-my-pi/pi-natives": "13.1.0",
48
- "@oh-my-pi/pi-tui": "13.1.0",
49
- "@oh-my-pi/pi-utils": "13.1.0",
44
+ "@oh-my-pi/omp-stats": "13.1.1",
45
+ "@oh-my-pi/pi-agent-core": "13.1.1",
46
+ "@oh-my-pi/pi-ai": "13.1.1",
47
+ "@oh-my-pi/pi-natives": "13.1.1",
48
+ "@oh-my-pi/pi-tui": "13.1.1",
49
+ "@oh-my-pi/pi-utils": "13.1.1",
50
50
  "@sinclair/typebox": "^0.34",
51
51
  "@xterm/headless": "^6.0",
52
52
  "ajv": "^8.18",
@@ -1,5 +1,7 @@
1
+ import * as fs from "node:fs/promises";
1
2
  import * as path from "node:path";
2
3
  import type { Skill } from "../extensibility/skills";
4
+ import { type LocalProtocolOptions, resolveLocalUrlToPath } from "../internal-urls";
3
5
  import { validateRelativePath } from "../internal-urls/skill-protocol";
4
6
  import type { InternalResource } from "../internal-urls/types";
5
7
  import { ToolError } from "./tool-errors";
@@ -9,9 +11,9 @@ const SKILL_URL_PATTERN = /'skill:\/\/[^'\s")`\\]+'|"skill:\/\/[^"\s')`\\]+"|ski
9
11
 
10
12
  /** Regex to find supported internal URL tokens in command text. */
11
13
  const INTERNAL_URL_PATTERN =
12
- /'(?:skill|agent|artifact|plan|memory|rule):\/\/[^'\s")`\\]+'|"(?:skill|agent|artifact|plan|memory|rule):\/\/[^"\s')`\\]+"|(?:skill|agent|artifact|plan|memory|rule):\/\/[^\s'")`\\]+/g;
14
+ /'(?:skill|agent|artifact|plan|memory|rule|local):\/\/[^'\s")`\\]+'|"(?:skill|agent|artifact|plan|memory|rule|local):\/\/[^"\s')`\\]+"|(?:skill|agent|artifact|plan|memory|rule|local):\/\/[^\s'")`\\]+/g;
13
15
 
14
- const SUPPORTED_INTERNAL_SCHEMES = ["skill", "agent", "artifact", "plan", "memory", "rule"] as const;
16
+ const SUPPORTED_INTERNAL_SCHEMES = ["skill", "agent", "artifact", "plan", "memory", "rule", "local"] as const;
15
17
 
16
18
  type SupportedInternalScheme = (typeof SUPPORTED_INTERNAL_SCHEMES)[number];
17
19
 
@@ -24,6 +26,8 @@ export interface InternalUrlExpansionOptions {
24
26
  skills: readonly Skill[];
25
27
  noEscape?: boolean;
26
28
  internalRouter?: InternalUrlResolver;
29
+ localOptions?: LocalProtocolOptions;
30
+ ensureLocalParentDirs?: boolean;
27
31
  }
28
32
 
29
33
  /**
@@ -102,6 +106,8 @@ async function resolveInternalUrlToPath(
102
106
  url: string,
103
107
  skills: readonly Skill[],
104
108
  internalRouter?: InternalUrlResolver,
109
+ localOptions?: LocalProtocolOptions,
110
+ ensureLocalParentDirs?: boolean,
105
111
  ): Promise<string> {
106
112
  const scheme = extractScheme(url);
107
113
  if (!scheme) {
@@ -112,6 +118,19 @@ async function resolveInternalUrlToPath(
112
118
  return resolveSkillUrlToPath(url, skills);
113
119
  }
114
120
 
121
+ if (scheme === "local") {
122
+ if (!localOptions) {
123
+ throw new ToolError(
124
+ "Cannot resolve local:// URL in bash command: local protocol options are unavailable for this session.",
125
+ );
126
+ }
127
+ const resolvedLocalPath = resolveLocalUrlToPath(url, localOptions);
128
+ if (ensureLocalParentDirs) {
129
+ await fs.mkdir(path.dirname(resolvedLocalPath), { recursive: true });
130
+ }
131
+ return resolvedLocalPath;
132
+ }
133
+
115
134
  if (!internalRouter || !internalRouter.canHandle(url)) {
116
135
  throw new ToolError(
117
136
  `Cannot resolve ${scheme}:// URL in bash command: ${url}\n` +
@@ -169,7 +188,13 @@ export async function expandInternalUrls(command: string, options: InternalUrlEx
169
188
  if (index === undefined) continue;
170
189
 
171
190
  const url = unquoteToken(token);
172
- const resolvedPath = await resolveInternalUrlToPath(url, options.skills, options.internalRouter);
191
+ const resolvedPath = await resolveInternalUrlToPath(
192
+ url,
193
+ options.skills,
194
+ options.internalRouter,
195
+ options.localOptions,
196
+ options.ensureLocalParentDirs,
197
+ );
173
198
  const replacement = options.noEscape ? resolvedPath : shellEscape(resolvedPath);
174
199
  expanded = `${expanded.slice(0, index)}${replacement}${expanded.slice(index + token.length)}`;
175
200
  }
package/src/tools/bash.ts CHANGED
@@ -173,8 +173,12 @@ export class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
173
173
  const internalUrlOptions: InternalUrlExpansionOptions = {
174
174
  skills: this.session.skills ?? [],
175
175
  internalRouter: this.session.internalRouter,
176
+ localOptions: {
177
+ getArtifactsDir: this.session.getArtifactsDir,
178
+ getSessionId: this.session.getSessionId,
179
+ },
176
180
  };
177
- command = await expandInternalUrls(command, internalUrlOptions);
181
+ command = await expandInternalUrls(command, { ...internalUrlOptions, ensureLocalParentDirs: true });
178
182
 
179
183
  // Resolve protocol URLs (skill://, agent://, etc.) in extracted cwd.
180
184
  if (cwd?.includes("://")) {