🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@agent-pattern-labs/iso-context

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agent-pattern-labs/iso-context - npm Package Compare versions

Comparing version
0.1.1
to
0.1.2
+36
-14
dist/context.js

@@ -1,3 +0,3 @@

import { existsSync, readFileSync, statSync } from "node:fs";
import { resolve } from "node:path";
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
import { isAbsolute, relative, resolve, sep } from "node:path";
import { isJsonObject } from "./json.js";

@@ -116,2 +116,16 @@ const DEFAULT_CHARS_PER_TOKEN = 4;

}
const realRoot = realpathSync(root);
const realFile = realpathSync(absolutePath);
const relativeRealPath = relative(realRoot, realFile);
if (relativeRealPath === ".."
|| relativeRealPath.startsWith(`..${sep}`)
|| isAbsolute(relativeRealPath)) {
issues.push({
kind: "path-outside-root",
severity: "error",
path: file.path,
message: `context path "${file.path}" resolves outside the context root`,
});
return { ...base, exists: true };
}
const stat = statSync(absolutePath);

@@ -188,7 +202,7 @@ if (!stat.isFile()) {

...base,
description: base.description ?? parent.description,
files: mergeFiles(parent.files, base.files),
tokenBudget: parent.tokenBudget,
charsPerToken: parent.charsPerToken,
notes: unique([...parent.notes, ...base.notes]),
description: parent.description ?? base.description,
files: mergeFiles(base.files, parent.files),
tokenBudget: parent.tokenBudget ?? base.tokenBudget,
charsPerToken: parent.charsPerToken ?? base.charsPerToken,
notes: unique([...base.notes, ...parent.notes]),
};

@@ -259,5 +273,3 @@ }

if (typeof value === "string") {
if (!value.trim())
throw new Error(`${path} must not be empty`);
return value.trim();
return safeRelativePath(value, path);
}

@@ -268,3 +280,3 @@ return normalizeFileSpec(value, path);

if (typeof value === "string") {
return { path: value, required: true, notes: [] };
return { path: safeRelativePath(value, path), required: true, notes: [] };
}

@@ -276,5 +288,3 @@ return normalizeFileSpec(value, path);

throw new Error(`${path} must be a string or JSON object`);
const rawPath = requireString(value.path, `${path}.path`);
if (!rawPath)
throw new Error(`${path}.path must not be empty`);
const rawPath = safeRelativePath(requireString(value.path, `${path}.path`), `${path}.path`);
const spec = {

@@ -293,2 +303,14 @@ path: rawPath,

}
function safeRelativePath(value, label) {
const path = value.trim();
const portable = path.replace(/\\/g, "/");
if (!path
|| isAbsolute(path)
|| portable.startsWith("/")
|| /^[A-Za-z]:\//.test(portable)
|| portable.split("/").some((part) => part === "..")) {
throw new Error(`${label} must be a relative path inside the context root`);
}
return path;
}
function isContextPolicy(input) {

@@ -295,0 +317,0 @@ return isJsonObject(input) && Array.isArray(input.bundles);

@@ -70,3 +70,3 @@ export type JsonPrimitive = string | number | boolean | null;

}
export type ContextIssueKind = "missing-required-file" | "not-a-file" | "read-error" | "file-over-budget" | "bundle-over-budget";
export type ContextIssueKind = "missing-required-file" | "path-outside-root" | "not-a-file" | "read-error" | "file-over-budget" | "bundle-over-budget";
export interface ContextIssue {

@@ -73,0 +73,0 @@ kind: ContextIssueKind;

{
"name": "@agent-pattern-labs/iso-context",
"version": "0.1.1",
"version": "0.1.2",
"description": "Deterministic context bundle planning for AI-agent workflows: select files, estimate tokens, check budgets, and render prompt context without model calls.",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -82,3 +82,7 @@ # @agent-pattern-labs/iso-context

- `extends` supports one parent or an array of parents.
- Parent files and notes are inherited before child values.
- Parents are applied in declared order: a later parent overrides an earlier
parent's description, budgets, and fields on duplicate file paths when it
explicitly defines them. Omitted values do not erase earlier values.
- Parent files and notes are inherited before child values, and the child has
final precedence over every parent.
- Re-declaring the same file path in a child overrides scalar file fields while

@@ -91,2 +95,4 @@ preserving the original file order.

with `charsPerToken` defaulting to `4`.
- Context file paths must remain relative to the configured root, including
after resolving symlinks.

@@ -93,0 +99,0 @@ ## Library API