sortie-dogs 0.12.5 → 0.12.6

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.
@@ -7,7 +7,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
7
7
  return path;
8
8
  };
9
9
  import { createHash, randomUUID } from "node:crypto";
10
- import { lstat, mkdir, open, readFile, readdir, realpath, rm, stat, writeFile } from "node:fs/promises";
10
+ import { lstat, mkdir, open, readFile, readdir, readlink, realpath, rm, stat, writeFile } from "node:fs/promises";
11
11
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
12
12
  import { RUNTIME_ASSET_VERSION } from "../asset-version.js";
13
13
  import { GOAL_DECLARATION_FORMAT, GOAL_DELIVERY_INTENTS, GOAL_DELIVERY_MODES, GOAL_CRITERION_ENUMS, expandGoalDeclaration } from "../core/goal-declaration-format.js";
@@ -235,6 +235,7 @@ async function durableScopeRoot(projectRoot) {
235
235
  }
236
236
  async function protectedScopeDigest(projectRoot, paths, manifestHash) {
237
237
  const entries = [];
238
+ const canonicalRoot = await realpath(projectRoot);
238
239
  const visit = async (absolute) => {
239
240
  const scoped = relative(projectRoot, absolute).replaceAll("\\", "/");
240
241
  if (scoped === ".." || scoped.startsWith("../") || isAbsolute(scoped))
@@ -248,8 +249,22 @@ async function protectedScopeDigest(projectRoot, paths, manifestHash) {
248
249
  entries.push([scoped, "missing"]);
249
250
  return true;
250
251
  }
251
- if (metadata.isSymbolicLink())
252
- return false;
252
+ if (metadata.isSymbolicLink()) {
253
+ // Package managers place executable links under node_modules/.bin. Record
254
+ // both the link and its target bytes, but never follow a link out of the
255
+ // project or recurse through a linked directory (which may form a cycle).
256
+ const target = await realpath(absolute).catch(() => undefined);
257
+ if (target === undefined)
258
+ return false;
259
+ const relativeTarget = relative(canonicalRoot, target);
260
+ if (relativeTarget === ".." || relativeTarget.startsWith("../") || isAbsolute(relativeTarget) ||
261
+ !(await stat(target)).isFile())
262
+ return false;
263
+ const link = await readlink(absolute);
264
+ const contents = await readFile(target);
265
+ entries.push([scoped, `symlink:${link}`, createHash("sha256").update(contents).digest("hex")]);
266
+ return true;
267
+ }
253
268
  if (metadata.isDirectory()) {
254
269
  entries.push([scoped, "directory"]);
255
270
  const children = await readdir(absolute);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sortie-dogs",
3
- "version": "0.12.5",
3
+ "version": "0.12.6",
4
4
  "description": "Bounded agent harness and validated orchestration loop plugin for OpenCode",
5
5
  "keywords": [
6
6
  "opencode",