agent-contracts 0.11.2 → 0.11.3
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/README.md +39 -1
- package/dist/cli.js +70 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.js +72 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -136,6 +136,7 @@ declare const BindingOutputSchema: z.ZodObject<{
|
|
|
136
136
|
}>>;
|
|
137
137
|
group_by: z.ZodOptional<z.ZodString>;
|
|
138
138
|
executable: z.ZodOptional<z.ZodBoolean>;
|
|
139
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
139
140
|
}, z.core.$loose>;
|
|
140
141
|
type BindingOutput = z.infer<typeof BindingOutputSchema>;
|
|
141
142
|
declare const ReportingSchema: z.ZodObject<{
|
|
@@ -177,6 +178,7 @@ declare const SoftwareBindingSchema: z.ZodObject<{
|
|
|
177
178
|
}>>;
|
|
178
179
|
group_by: z.ZodOptional<z.ZodString>;
|
|
179
180
|
executable: z.ZodOptional<z.ZodBoolean>;
|
|
181
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
180
182
|
}, z.core.$loose>>>;
|
|
181
183
|
reporting: z.ZodOptional<z.ZodObject<{
|
|
182
184
|
commands: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -947,6 +949,7 @@ declare const RenderTargetSchema: z.ZodObject<{
|
|
|
947
949
|
output: z.ZodString;
|
|
948
950
|
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
949
951
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
952
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
950
953
|
}, z.core.$strip>;
|
|
951
954
|
type RenderTarget = z.infer<typeof RenderTargetSchema>;
|
|
952
955
|
declare const AgentContractsConfigSchema: z.ZodObject<{
|
|
@@ -970,6 +973,7 @@ declare const AgentContractsConfigSchema: z.ZodObject<{
|
|
|
970
973
|
output: z.ZodString;
|
|
971
974
|
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
972
975
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
976
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
973
977
|
}, z.core.$strip>>;
|
|
974
978
|
bindings: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
975
979
|
active_guardrail_policy: z.ZodOptional<z.ZodString>;
|
|
@@ -982,6 +986,7 @@ interface ResolvedRenderTarget {
|
|
|
982
986
|
output: string;
|
|
983
987
|
include?: string[];
|
|
984
988
|
exclude?: string[];
|
|
989
|
+
skip_empty?: boolean;
|
|
985
990
|
}
|
|
986
991
|
interface ResolvedConfig {
|
|
987
992
|
dsl: string;
|
package/dist/index.js
CHANGED
|
@@ -50513,7 +50513,8 @@ var BindingOutputSchema = z3.object({
|
|
|
50513
50513
|
inline_template: z3.string().optional(),
|
|
50514
50514
|
mode: z3.enum(["write", "patch"]).default("write"),
|
|
50515
50515
|
group_by: z3.string().optional(),
|
|
50516
|
-
executable: z3.boolean().optional()
|
|
50516
|
+
executable: z3.boolean().optional(),
|
|
50517
|
+
skip_empty: z3.boolean().optional()
|
|
50517
50518
|
}).passthrough().refine(
|
|
50518
50519
|
(data) => !(data.template && data.inline_template),
|
|
50519
50520
|
{ message: "template and inline_template are mutually exclusive" }
|
|
@@ -52828,7 +52829,7 @@ async function spectralLint(dslObject) {
|
|
|
52828
52829
|
}
|
|
52829
52830
|
|
|
52830
52831
|
// src/renderer/renderer.ts
|
|
52831
|
-
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
52832
|
+
import { readFile as readFile2, writeFile, mkdir, unlink } from "fs/promises";
|
|
52832
52833
|
import { dirname as dirname3 } from "path";
|
|
52833
52834
|
import Handlebars from "handlebars";
|
|
52834
52835
|
|
|
@@ -53959,6 +53960,15 @@ function buildEntityContext(dsl, context, entityId) {
|
|
|
53959
53960
|
async function loadTemplate(templatePath) {
|
|
53960
53961
|
return readFile2(templatePath, "utf8");
|
|
53961
53962
|
}
|
|
53963
|
+
function isEffectivelyEmpty(output) {
|
|
53964
|
+
return output.trim().length === 0;
|
|
53965
|
+
}
|
|
53966
|
+
async function removeIfExists(filePath) {
|
|
53967
|
+
try {
|
|
53968
|
+
await unlink(filePath);
|
|
53969
|
+
} catch {
|
|
53970
|
+
}
|
|
53971
|
+
}
|
|
53962
53972
|
async function renderFromConfig(dsl, renderTargets) {
|
|
53963
53973
|
const outputFiles = [];
|
|
53964
53974
|
for (const target of renderTargets) {
|
|
@@ -53967,6 +53977,10 @@ async function renderFromConfig(dsl, renderTargets) {
|
|
|
53967
53977
|
if (target.context === "system") {
|
|
53968
53978
|
const ctx = buildSystemContext(dsl);
|
|
53969
53979
|
const output = compiled(ctx);
|
|
53980
|
+
if (target.skip_empty && isEffectivelyEmpty(output)) {
|
|
53981
|
+
await removeIfExists(target.output);
|
|
53982
|
+
continue;
|
|
53983
|
+
}
|
|
53970
53984
|
await mkdir(dirname3(target.output), { recursive: true });
|
|
53971
53985
|
await writeFile(target.output, output, "utf8");
|
|
53972
53986
|
outputFiles.push(target.output);
|
|
@@ -53978,6 +53992,10 @@ async function renderFromConfig(dsl, renderTargets) {
|
|
|
53978
53992
|
const ctx = buildEntityContext(dsl, target.context, entityId);
|
|
53979
53993
|
const output = compiled(ctx);
|
|
53980
53994
|
const outputPath = expandOutputPath(target.output, target.context, entityId);
|
|
53995
|
+
if (target.skip_empty && isEffectivelyEmpty(output)) {
|
|
53996
|
+
await removeIfExists(outputPath);
|
|
53997
|
+
continue;
|
|
53998
|
+
}
|
|
53981
53999
|
await mkdir(dirname3(outputPath), { recursive: true });
|
|
53982
54000
|
await writeFile(outputPath, output, "utf8");
|
|
53983
54001
|
outputFiles.push(outputPath);
|
|
@@ -53986,6 +54004,26 @@ async function renderFromConfig(dsl, renderTargets) {
|
|
|
53986
54004
|
}
|
|
53987
54005
|
return outputFiles;
|
|
53988
54006
|
}
|
|
54007
|
+
async function fileExists(filePath) {
|
|
54008
|
+
try {
|
|
54009
|
+
await readFile2(filePath);
|
|
54010
|
+
return true;
|
|
54011
|
+
} catch {
|
|
54012
|
+
return false;
|
|
54013
|
+
}
|
|
54014
|
+
}
|
|
54015
|
+
function checkExpectedVsExisting(expected, outputPath, skipEmpty, diffs) {
|
|
54016
|
+
if (skipEmpty && isEffectivelyEmpty(expected)) {
|
|
54017
|
+
return fileExists(outputPath).then((exists) => {
|
|
54018
|
+
if (exists) diffs.push(outputPath);
|
|
54019
|
+
});
|
|
54020
|
+
}
|
|
54021
|
+
return readFile2(outputPath, "utf8").then((existing) => {
|
|
54022
|
+
if (existing !== expected) diffs.push(outputPath);
|
|
54023
|
+
}).catch(() => {
|
|
54024
|
+
diffs.push(outputPath);
|
|
54025
|
+
});
|
|
54026
|
+
}
|
|
53989
54027
|
async function checkDriftFromConfig(dsl, renderTargets) {
|
|
53990
54028
|
const diffs = [];
|
|
53991
54029
|
for (const target of renderTargets) {
|
|
@@ -53994,12 +54032,7 @@ async function checkDriftFromConfig(dsl, renderTargets) {
|
|
|
53994
54032
|
if (target.context === "system") {
|
|
53995
54033
|
const ctx = buildSystemContext(dsl);
|
|
53996
54034
|
const expected = compiled(ctx);
|
|
53997
|
-
|
|
53998
|
-
const existing = await readFile2(target.output, "utf8");
|
|
53999
|
-
if (existing !== expected) diffs.push(target.output);
|
|
54000
|
-
} catch {
|
|
54001
|
-
diffs.push(target.output);
|
|
54002
|
-
}
|
|
54035
|
+
await checkExpectedVsExisting(expected, target.output, target.skip_empty, diffs);
|
|
54003
54036
|
} else {
|
|
54004
54037
|
const section = getDslSection(dsl, target.context);
|
|
54005
54038
|
const allIds = Object.keys(section);
|
|
@@ -54008,12 +54041,7 @@ async function checkDriftFromConfig(dsl, renderTargets) {
|
|
|
54008
54041
|
const ctx = buildEntityContext(dsl, target.context, entityId);
|
|
54009
54042
|
const expected = compiled(ctx);
|
|
54010
54043
|
const outputPath = expandOutputPath(target.output, target.context, entityId);
|
|
54011
|
-
|
|
54012
|
-
const existing = await readFile2(outputPath, "utf8");
|
|
54013
|
-
if (existing !== expected) diffs.push(outputPath);
|
|
54014
|
-
} catch {
|
|
54015
|
-
diffs.push(outputPath);
|
|
54016
|
-
}
|
|
54044
|
+
await checkExpectedVsExisting(expected, outputPath, target.skip_empty, diffs);
|
|
54017
54045
|
}
|
|
54018
54046
|
}
|
|
54019
54047
|
}
|
|
@@ -54055,7 +54083,8 @@ var RenderTargetSchema = z16.object({
|
|
|
54055
54083
|
context: ContextTypeSchema,
|
|
54056
54084
|
output: z16.string(),
|
|
54057
54085
|
include: z16.array(z16.string()).optional(),
|
|
54058
|
-
exclude: z16.array(z16.string()).optional()
|
|
54086
|
+
exclude: z16.array(z16.string()).optional(),
|
|
54087
|
+
skip_empty: z16.boolean().optional()
|
|
54059
54088
|
}).refine(
|
|
54060
54089
|
(data) => !(data.include && data.exclude),
|
|
54061
54090
|
{ message: "include and exclude are mutually exclusive" }
|
|
@@ -54087,7 +54116,7 @@ var ConfigLoadError = class extends Error {
|
|
|
54087
54116
|
}
|
|
54088
54117
|
filePath;
|
|
54089
54118
|
};
|
|
54090
|
-
async function
|
|
54119
|
+
async function fileExists2(filePath) {
|
|
54091
54120
|
try {
|
|
54092
54121
|
await access(filePath);
|
|
54093
54122
|
return true;
|
|
@@ -54098,7 +54127,7 @@ async function fileExists(filePath) {
|
|
|
54098
54127
|
async function loadConfig(configPath) {
|
|
54099
54128
|
const isExplicit = configPath !== void 0;
|
|
54100
54129
|
const targetPath = resolve4(configPath ?? DEFAULT_CONFIG_NAME);
|
|
54101
|
-
if (!await
|
|
54130
|
+
if (!await fileExists2(targetPath)) {
|
|
54102
54131
|
if (isExplicit) {
|
|
54103
54132
|
throw new ConfigLoadError(
|
|
54104
54133
|
`Config file not found: ${targetPath}`,
|
|
@@ -54299,7 +54328,7 @@ ${issues}`,
|
|
|
54299
54328
|
}
|
|
54300
54329
|
|
|
54301
54330
|
// src/guardrail-generator/generator.ts
|
|
54302
|
-
import { readFile as readFile5, writeFile as writeFile2, mkdir as mkdir2, chmod } from "fs/promises";
|
|
54331
|
+
import { readFile as readFile5, writeFile as writeFile2, mkdir as mkdir2, chmod, unlink as unlink2 } from "fs/promises";
|
|
54303
54332
|
import { resolve as resolve6, dirname as dirname6 } from "path";
|
|
54304
54333
|
import Handlebars2 from "handlebars";
|
|
54305
54334
|
|
|
@@ -54473,6 +54502,7 @@ async function generateGuardrails(options) {
|
|
|
54473
54502
|
});
|
|
54474
54503
|
continue;
|
|
54475
54504
|
}
|
|
54505
|
+
const shouldSkipEmpty = outputDef.skip_empty === true;
|
|
54476
54506
|
if (outputDef.group_by) {
|
|
54477
54507
|
const groupField = outputDef.group_by;
|
|
54478
54508
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -54492,6 +54522,15 @@ async function generateGuardrails(options) {
|
|
|
54492
54522
|
const compiled = Handlebars2.compile(templateContent, { noEscape: true });
|
|
54493
54523
|
const output = compiled(groupCtx);
|
|
54494
54524
|
const groupTarget = resolve6(targetPath, groupKey);
|
|
54525
|
+
if (shouldSkipEmpty && output.trim().length === 0) {
|
|
54526
|
+
if (!dryRun) {
|
|
54527
|
+
try {
|
|
54528
|
+
await unlink2(groupTarget);
|
|
54529
|
+
} catch {
|
|
54530
|
+
}
|
|
54531
|
+
}
|
|
54532
|
+
continue;
|
|
54533
|
+
}
|
|
54495
54534
|
if (!dryRun) {
|
|
54496
54535
|
await mkdir2(dirname6(groupTarget), { recursive: true });
|
|
54497
54536
|
await writeFile2(groupTarget, output, "utf8");
|
|
@@ -54504,14 +54543,23 @@ async function generateGuardrails(options) {
|
|
|
54504
54543
|
} else {
|
|
54505
54544
|
const compiled = Handlebars2.compile(templateContent, { noEscape: true });
|
|
54506
54545
|
const output = compiled(ctx);
|
|
54507
|
-
if (
|
|
54508
|
-
|
|
54509
|
-
|
|
54510
|
-
|
|
54511
|
-
|
|
54546
|
+
if (shouldSkipEmpty && output.trim().length === 0) {
|
|
54547
|
+
if (!dryRun) {
|
|
54548
|
+
try {
|
|
54549
|
+
await unlink2(targetPath);
|
|
54550
|
+
} catch {
|
|
54551
|
+
}
|
|
54552
|
+
}
|
|
54553
|
+
} else {
|
|
54554
|
+
if (!dryRun) {
|
|
54555
|
+
await mkdir2(dirname6(targetPath), { recursive: true });
|
|
54556
|
+
await writeFile2(targetPath, output, "utf8");
|
|
54557
|
+
if (outputDef.executable) {
|
|
54558
|
+
await chmod(targetPath, 493);
|
|
54559
|
+
}
|
|
54512
54560
|
}
|
|
54561
|
+
outputFiles.push(targetPath);
|
|
54513
54562
|
}
|
|
54514
|
-
outputFiles.push(targetPath);
|
|
54515
54563
|
}
|
|
54516
54564
|
}
|
|
54517
54565
|
}
|