@a2f0/agent-tool 0.1.39 → 0.1.40
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/package.json +1 -1
- package/src/bun/dependencies.ts +25 -3
package/package.json
CHANGED
package/src/bun/dependencies.ts
CHANGED
|
@@ -143,10 +143,32 @@ function runBun(bun: BunExecutable, directory: string, args: string[]) {
|
|
|
143
143
|
|
|
144
144
|
function resolvedPlan(root: string, version: string, requested: Requested[], workspaceNames: Set<string>) {
|
|
145
145
|
assert(Bun.semver.satisfies(version, ">=1.4.4"), `Resolved-only updates require the owning Bun 1.4.4 or newer (found ${version}); older Bun can add a direct declaration. Upgrade the project's pin through its normal approval workflow first.`);
|
|
146
|
+
const object = (value: unknown): value is Record<string, unknown> => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
147
|
+
const strings = (value: unknown) => object(value) && Object.values(value).every(item => typeof item === "string");
|
|
148
|
+
const info = (value: unknown) => object(value) && SECTIONS.every(section => value[section] === undefined || strings(value[section]));
|
|
149
|
+
const overrides = (value: unknown): boolean => object(value) && Object.values(value).every(item => typeof item === "string" || overrides(item));
|
|
150
|
+
const tuple = (value: unknown): boolean => {
|
|
151
|
+
if (!Array.isArray(value) || typeof value[0] !== "string") return false;
|
|
152
|
+
const at = value[0].indexOf("@", value[0].startsWith("@") ? 1 : 0);
|
|
153
|
+
// Bun explicitly accepts @root: for an anonymous root referenced by file:.
|
|
154
|
+
if (at < 1 && !value[0].startsWith("@root:")) return false;
|
|
155
|
+
const resolution = value[0].slice(at + 1);
|
|
156
|
+
// v1/v2/v3 share package tuples. v2 tightens Bun's semantic checks; v3
|
|
157
|
+
// adds scoped override objects, not a new npm tuple layout.
|
|
158
|
+
if (EXACT.test(resolution)) return value.length === 4 && typeof value[1] === "string" && info(value[2]) && typeof value[3] === "string";
|
|
159
|
+
if (resolution.startsWith("workspace:")) return value.length === 1;
|
|
160
|
+
// Non-registry entries can coexist, but cannot be selected for refresh.
|
|
161
|
+
return (value.length === 2 || value.length === 3) && info(value[1]) && (value.length === 2 || typeof value[2] === "string");
|
|
162
|
+
};
|
|
146
163
|
const readLock = () => {
|
|
147
|
-
const lock = Bun.JSONC.parse(readFileSync(path.join(root, "bun.lock"), "utf8"))
|
|
148
|
-
assert(lock &&
|
|
149
|
-
|
|
164
|
+
const lock = Bun.JSONC.parse(readFileSync(path.join(root, "bun.lock"), "utf8"));
|
|
165
|
+
assert(object(lock) && [1, 2, 3].includes(lock.lockfileVersion as number)
|
|
166
|
+
&& object(lock.workspaces) && info(lock.workspaces[""]) && Object.values(lock.workspaces).every(info)
|
|
167
|
+
&& object(lock.packages) && Object.values(lock.packages).every(tuple)
|
|
168
|
+
&& (lock.overrides === undefined || overrides(lock.overrides)), "Resolved-only updates need a supported text bun.lock (versions 1, 2, or 3) with valid workspaces, packages, and overrides.");
|
|
169
|
+
// Bun's frozen preflight remains the authority for resolution, integrity,
|
|
170
|
+
// and configuration semantics after this fail-closed structural check.
|
|
171
|
+
return lock as Record<string, unknown> & { packages: Record<string, unknown[]> };
|
|
150
172
|
};
|
|
151
173
|
const keyName = (key: string) => { const parts = key.split("/"); return parts.at(-2)?.startsWith("@") ? parts.slice(-2).join("/") : parts.at(-1)!; };
|
|
152
174
|
const registry = (tuple: unknown, name: string) => Array.isArray(tuple) && typeof tuple[0] === "string" && tuple[0].startsWith(`${name}@`) && EXACT.test(tuple[0].slice(name.length + 1));
|