@prompd/core 0.5.0-beta.17 → 0.5.0-beta.18

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.d.cts CHANGED
@@ -694,6 +694,8 @@ interface PackageStore {
694
694
  removeFile?(path: string): void | Promise<void>;
695
695
  /** Read a UTF-8 file, or null if absent — used to merge the workspace prompd.json. */
696
696
  readFile?(path: string): Promise<string | null> | string | null;
697
+ /** Read raw bytes — used to match a node-template .pdpkg by its manifest on uninstall. */
698
+ readBytes?(path: string): Promise<Uint8Array> | Uint8Array;
697
699
  /** List a directory's entry names — used to find a node-template .pdpkg to uninstall. */
698
700
  readdir?(path: string): Promise<string[]> | string[];
699
701
  }
package/dist/index.d.ts CHANGED
@@ -694,6 +694,8 @@ interface PackageStore {
694
694
  removeFile?(path: string): void | Promise<void>;
695
695
  /** Read a UTF-8 file, or null if absent — used to merge the workspace prompd.json. */
696
696
  readFile?(path: string): Promise<string | null> | string | null;
697
+ /** Read raw bytes — used to match a node-template .pdpkg by its manifest on uninstall. */
698
+ readBytes?(path: string): Promise<Uint8Array> | Uint8Array;
697
699
  /** List a directory's entry names — used to find a node-template .pdpkg to uninstall. */
698
700
  readdir?(path: string): Promise<string[]> | string[];
699
701
  }
package/dist/index.js CHANGED
@@ -3114,6 +3114,7 @@ var MAX_TOTAL_EXTRACTED_SIZE = 500 * 1024 * 1024;
3114
3114
  function isSymlinkEntry(perms) {
3115
3115
  return typeof perms === "number" && (perms & 61440) === 40960;
3116
3116
  }
3117
+ var pdpkgDecoder = new TextDecoder();
3117
3118
  async function extractPdpkg(buffer) {
3118
3119
  const zip = await JSZip.loadAsync(buffer);
3119
3120
  const out = /* @__PURE__ */ new Map();
@@ -3137,7 +3138,7 @@ async function extractPdpkg(buffer) {
3137
3138
  if (total > MAX_TOTAL_EXTRACTED_SIZE) {
3138
3139
  throw new Error(`Package total decompressed size exceeds limit (${MAX_TOTAL_EXTRACTED_SIZE} bytes). Possible decompression bomb.`);
3139
3140
  }
3140
- out.set(entry.name, new TextDecoder().decode(bytes));
3141
+ out.set(entry.name, pdpkgDecoder.decode(bytes));
3141
3142
  }
3142
3143
  return out;
3143
3144
  }
@@ -3364,34 +3365,18 @@ var HybridFileSystem = class {
3364
3365
 
3365
3366
  // src/lib/compiler/install.ts
3366
3367
  var MAX_PACKAGE_SIZE = 50 * 1024 * 1024;
3367
- function joinPosix3(...parts) {
3368
- const joined = parts.filter((p) => p && p !== ".").join("/").replace(/\/{2,}/g, "/");
3369
- return joined.replace(/\/+$/, "") || "/";
3370
- }
3371
- function normalizeSegments(p) {
3372
- const out = [];
3373
- for (const seg of p.split("/")) {
3374
- if (!seg || seg === ".") continue;
3375
- if (seg === "..") {
3376
- out.pop();
3377
- continue;
3378
- }
3379
- out.push(seg);
3380
- }
3381
- return out.join("/");
3382
- }
3383
3368
  function slugify(name) {
3384
3369
  return name.toLowerCase().replace(/[@/]+/g, "-").replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
3385
3370
  }
3386
3371
  function resolvePackageDir(root, type, name) {
3387
- return joinPosix3(root, ".prompd", getInstallDirForType(type), name);
3372
+ return joinPosix(root, ".prompd", getInstallDirForType(type), name);
3388
3373
  }
3389
3374
  function resolveInstallDir(root, type, name, version) {
3390
- return joinPosix3(resolvePackageDir(root, type, name), version);
3375
+ return joinPosix(resolvePackageDir(root, type, name), version);
3391
3376
  }
3392
3377
  async function addWorkspaceDependency(store, root, name, version) {
3393
3378
  if (!store.readFile) return;
3394
- const manifestPath = joinPosix3(root, "prompd.json");
3379
+ const manifestPath = joinPosix(root, "prompd.json");
3395
3380
  try {
3396
3381
  const existing = await store.readFile(manifestPath);
3397
3382
  const manifest = existing && existing.trim() ? JSON.parse(existing) : {};
@@ -3403,7 +3388,7 @@ async function addWorkspaceDependency(store, root, name, version) {
3403
3388
  }
3404
3389
  async function removeWorkspaceDependency(store, root, name) {
3405
3390
  if (!store.readFile) return;
3406
- const manifestPath = joinPosix3(root, "prompd.json");
3391
+ const manifestPath = joinPosix(root, "prompd.json");
3407
3392
  try {
3408
3393
  const existing = await store.readFile(manifestPath);
3409
3394
  if (!existing || !existing.trim()) return;
@@ -3455,22 +3440,22 @@ async function installInternal(opts, visited) {
3455
3440
  if (!store.writeBytes) {
3456
3441
  throw new Error("Installing a node-template requires a PackageStore with writeBytes (binary). This host does not support it.");
3457
3442
  }
3458
- const dir = joinPosix3(root, ".prompd", getInstallDirForType("node-template"));
3459
- installedPath = joinPosix3(dir, `${slugify(name)}-${version}.pdpkg`);
3443
+ const dir = joinPosix(root, ".prompd", getInstallDirForType("node-template"));
3444
+ installedPath = joinPosix(dir, `${slugify(name)}-${version}.pdpkg`);
3460
3445
  await store.writeBytes(installedPath, bytes);
3461
3446
  } else {
3462
3447
  installedPath = resolveInstallDir(root, type, name, version);
3463
- const base = normalizeSegments(installedPath);
3448
+ const base = normalizePosix(installedPath);
3464
3449
  await store.removeDir?.(installedPath);
3465
3450
  for (const [rel, content] of files) {
3466
- const dest = joinPosix3(installedPath, rel);
3467
- if (normalizeSegments(dest) !== base && !normalizeSegments(dest).startsWith(base + "/")) {
3451
+ const dest = joinPosix(installedPath, rel);
3452
+ if (dest !== base && !dest.startsWith(base + "/")) {
3468
3453
  throw new Error(`Security violation: extracted path escapes install directory: ${rel}`);
3469
3454
  }
3470
3455
  await store.writeFile(dest, content);
3471
3456
  written.push(rel);
3472
3457
  }
3473
- await store.writeFile(joinPosix3(installedPath, ".prmdmeta"), JSON.stringify(m, null, 2) + "\n");
3458
+ await store.writeFile(joinPosix(installedPath, ".prmdmeta"), JSON.stringify(m, null, 2) + "\n");
3474
3459
  if (tools && tools.length > 0) {
3475
3460
  if (type !== "skill") throw new Error(`Tool deploy is only valid for skills, but '${name}' is a ${type}.`);
3476
3461
  if (!deployTool) throw new Error("tools were requested but no deployTool hook was provided.");
@@ -3488,15 +3473,19 @@ async function uninstallPackage(opts) {
3488
3473
  const removed = [];
3489
3474
  for (const type of ["package", "workflow", "skill", "node-template"]) {
3490
3475
  if (type === "node-template") {
3491
- const dir = joinPosix3(root, ".prompd", getInstallDirForType("node-template"));
3492
- if (!store.readdir || !store.removeFile) continue;
3476
+ const dir = joinPosix(root, ".prompd", getInstallDirForType("node-template"));
3477
+ if (!store.readdir || !store.removeFile || !store.readBytes) continue;
3493
3478
  try {
3494
- const prefix = `${slugify(name)}-`;
3495
3479
  for (const entry of await store.readdir(dir)) {
3496
- if (entry.startsWith(prefix) && entry.endsWith(".pdpkg")) {
3497
- const p = joinPosix3(dir, entry);
3498
- await store.removeFile(p);
3499
- removed.push(p);
3480
+ if (!entry.endsWith(".pdpkg")) continue;
3481
+ const p = joinPosix(dir, entry);
3482
+ try {
3483
+ const m = readManifest(await extractPdpkg(await store.readBytes(p)));
3484
+ if (m.name === name) {
3485
+ await store.removeFile(p);
3486
+ removed.push(p);
3487
+ }
3488
+ } catch {
3500
3489
  }
3501
3490
  }
3502
3491
  } catch {