agent-contracts 0.11.1 → 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 +75 -26
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +17 -9
- package/dist/index.js +77 -28
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -97,29 +97,31 @@ type Artifact = z.infer<typeof ArtifactSchema>;
|
|
|
97
97
|
declare const MatcherSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
98
98
|
type: z.ZodLiteral<"command_regex">;
|
|
99
99
|
pattern: z.ZodString;
|
|
100
|
-
}, z.core.$
|
|
100
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
101
101
|
type: z.ZodLiteral<"content_regex">;
|
|
102
102
|
pattern: z.ZodString;
|
|
103
103
|
file_glob: z.ZodOptional<z.ZodString>;
|
|
104
104
|
exclude_glob: z.ZodOptional<z.ZodString>;
|
|
105
|
-
}, z.core.$
|
|
105
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
106
106
|
type: z.ZodLiteral<"file_glob">;
|
|
107
107
|
pattern: z.ZodString;
|
|
108
|
-
|
|
108
|
+
exclude_glob: z.ZodOptional<z.ZodString>;
|
|
109
|
+
}, z.core.$loose>], "type">;
|
|
109
110
|
type Matcher = z.infer<typeof MatcherSchema>;
|
|
110
111
|
declare const CheckSchema: z.ZodObject<{
|
|
111
112
|
matcher: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
112
113
|
type: z.ZodLiteral<"command_regex">;
|
|
113
114
|
pattern: z.ZodString;
|
|
114
|
-
}, z.core.$
|
|
115
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
115
116
|
type: z.ZodLiteral<"content_regex">;
|
|
116
117
|
pattern: z.ZodString;
|
|
117
118
|
file_glob: z.ZodOptional<z.ZodString>;
|
|
118
119
|
exclude_glob: z.ZodOptional<z.ZodString>;
|
|
119
|
-
}, z.core.$
|
|
120
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
120
121
|
type: z.ZodLiteral<"file_glob">;
|
|
121
122
|
pattern: z.ZodString;
|
|
122
|
-
|
|
123
|
+
exclude_glob: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$loose>], "type">>;
|
|
123
125
|
script: z.ZodOptional<z.ZodString>;
|
|
124
126
|
message: z.ZodOptional<z.ZodString>;
|
|
125
127
|
}, z.core.$loose>;
|
|
@@ -134,6 +136,7 @@ declare const BindingOutputSchema: z.ZodObject<{
|
|
|
134
136
|
}>>;
|
|
135
137
|
group_by: z.ZodOptional<z.ZodString>;
|
|
136
138
|
executable: z.ZodOptional<z.ZodBoolean>;
|
|
139
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
137
140
|
}, z.core.$loose>;
|
|
138
141
|
type BindingOutput = z.infer<typeof BindingOutputSchema>;
|
|
139
142
|
declare const ReportingSchema: z.ZodObject<{
|
|
@@ -151,15 +154,16 @@ declare const SoftwareBindingSchema: z.ZodObject<{
|
|
|
151
154
|
matcher: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
152
155
|
type: z.ZodLiteral<"command_regex">;
|
|
153
156
|
pattern: z.ZodString;
|
|
154
|
-
}, z.core.$
|
|
157
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
155
158
|
type: z.ZodLiteral<"content_regex">;
|
|
156
159
|
pattern: z.ZodString;
|
|
157
160
|
file_glob: z.ZodOptional<z.ZodString>;
|
|
158
161
|
exclude_glob: z.ZodOptional<z.ZodString>;
|
|
159
|
-
}, z.core.$
|
|
162
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
160
163
|
type: z.ZodLiteral<"file_glob">;
|
|
161
164
|
pattern: z.ZodString;
|
|
162
|
-
|
|
165
|
+
exclude_glob: z.ZodOptional<z.ZodString>;
|
|
166
|
+
}, z.core.$loose>], "type">>;
|
|
163
167
|
script: z.ZodOptional<z.ZodString>;
|
|
164
168
|
message: z.ZodOptional<z.ZodString>;
|
|
165
169
|
}, z.core.$loose>>;
|
|
@@ -174,6 +178,7 @@ declare const SoftwareBindingSchema: z.ZodObject<{
|
|
|
174
178
|
}>>;
|
|
175
179
|
group_by: z.ZodOptional<z.ZodString>;
|
|
176
180
|
executable: z.ZodOptional<z.ZodBoolean>;
|
|
181
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
177
182
|
}, z.core.$loose>>>;
|
|
178
183
|
reporting: z.ZodOptional<z.ZodObject<{
|
|
179
184
|
commands: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -944,6 +949,7 @@ declare const RenderTargetSchema: z.ZodObject<{
|
|
|
944
949
|
output: z.ZodString;
|
|
945
950
|
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
946
951
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
952
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
947
953
|
}, z.core.$strip>;
|
|
948
954
|
type RenderTarget = z.infer<typeof RenderTargetSchema>;
|
|
949
955
|
declare const AgentContractsConfigSchema: z.ZodObject<{
|
|
@@ -967,6 +973,7 @@ declare const AgentContractsConfigSchema: z.ZodObject<{
|
|
|
967
973
|
output: z.ZodString;
|
|
968
974
|
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
969
975
|
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
976
|
+
skip_empty: z.ZodOptional<z.ZodBoolean>;
|
|
970
977
|
}, z.core.$strip>>;
|
|
971
978
|
bindings: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
972
979
|
active_guardrail_policy: z.ZodOptional<z.ZodString>;
|
|
@@ -979,6 +986,7 @@ interface ResolvedRenderTarget {
|
|
|
979
986
|
output: string;
|
|
980
987
|
include?: string[];
|
|
981
988
|
exclude?: string[];
|
|
989
|
+
skip_empty?: boolean;
|
|
982
990
|
}
|
|
983
991
|
interface ResolvedConfig {
|
|
984
992
|
dsl: string;
|
package/dist/index.js
CHANGED
|
@@ -50485,17 +50485,18 @@ import { z as z3 } from "zod";
|
|
|
50485
50485
|
var CommandRegexMatcherSchema = z3.object({
|
|
50486
50486
|
type: z3.literal("command_regex"),
|
|
50487
50487
|
pattern: z3.string()
|
|
50488
|
-
});
|
|
50488
|
+
}).passthrough();
|
|
50489
50489
|
var ContentRegexMatcherSchema = z3.object({
|
|
50490
50490
|
type: z3.literal("content_regex"),
|
|
50491
50491
|
pattern: z3.string(),
|
|
50492
50492
|
file_glob: z3.string().optional(),
|
|
50493
50493
|
exclude_glob: z3.string().optional()
|
|
50494
|
-
});
|
|
50494
|
+
}).passthrough();
|
|
50495
50495
|
var FileGlobMatcherSchema = z3.object({
|
|
50496
50496
|
type: z3.literal("file_glob"),
|
|
50497
|
-
pattern: z3.string()
|
|
50498
|
-
|
|
50497
|
+
pattern: z3.string(),
|
|
50498
|
+
exclude_glob: z3.string().optional()
|
|
50499
|
+
}).passthrough();
|
|
50499
50500
|
var MatcherSchema = z3.discriminatedUnion("type", [
|
|
50500
50501
|
CommandRegexMatcherSchema,
|
|
50501
50502
|
ContentRegexMatcherSchema,
|
|
@@ -50512,7 +50513,8 @@ var BindingOutputSchema = z3.object({
|
|
|
50512
50513
|
inline_template: z3.string().optional(),
|
|
50513
50514
|
mode: z3.enum(["write", "patch"]).default("write"),
|
|
50514
50515
|
group_by: z3.string().optional(),
|
|
50515
|
-
executable: z3.boolean().optional()
|
|
50516
|
+
executable: z3.boolean().optional(),
|
|
50517
|
+
skip_empty: z3.boolean().optional()
|
|
50516
50518
|
}).passthrough().refine(
|
|
50517
50519
|
(data) => !(data.template && data.inline_template),
|
|
50518
50520
|
{ message: "template and inline_template are mutually exclusive" }
|
|
@@ -52827,7 +52829,7 @@ async function spectralLint(dslObject) {
|
|
|
52827
52829
|
}
|
|
52828
52830
|
|
|
52829
52831
|
// src/renderer/renderer.ts
|
|
52830
|
-
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
52832
|
+
import { readFile as readFile2, writeFile, mkdir, unlink } from "fs/promises";
|
|
52831
52833
|
import { dirname as dirname3 } from "path";
|
|
52832
52834
|
import Handlebars from "handlebars";
|
|
52833
52835
|
|
|
@@ -53958,6 +53960,15 @@ function buildEntityContext(dsl, context, entityId) {
|
|
|
53958
53960
|
async function loadTemplate(templatePath) {
|
|
53959
53961
|
return readFile2(templatePath, "utf8");
|
|
53960
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
|
+
}
|
|
53961
53972
|
async function renderFromConfig(dsl, renderTargets) {
|
|
53962
53973
|
const outputFiles = [];
|
|
53963
53974
|
for (const target of renderTargets) {
|
|
@@ -53966,6 +53977,10 @@ async function renderFromConfig(dsl, renderTargets) {
|
|
|
53966
53977
|
if (target.context === "system") {
|
|
53967
53978
|
const ctx = buildSystemContext(dsl);
|
|
53968
53979
|
const output = compiled(ctx);
|
|
53980
|
+
if (target.skip_empty && isEffectivelyEmpty(output)) {
|
|
53981
|
+
await removeIfExists(target.output);
|
|
53982
|
+
continue;
|
|
53983
|
+
}
|
|
53969
53984
|
await mkdir(dirname3(target.output), { recursive: true });
|
|
53970
53985
|
await writeFile(target.output, output, "utf8");
|
|
53971
53986
|
outputFiles.push(target.output);
|
|
@@ -53977,6 +53992,10 @@ async function renderFromConfig(dsl, renderTargets) {
|
|
|
53977
53992
|
const ctx = buildEntityContext(dsl, target.context, entityId);
|
|
53978
53993
|
const output = compiled(ctx);
|
|
53979
53994
|
const outputPath = expandOutputPath(target.output, target.context, entityId);
|
|
53995
|
+
if (target.skip_empty && isEffectivelyEmpty(output)) {
|
|
53996
|
+
await removeIfExists(outputPath);
|
|
53997
|
+
continue;
|
|
53998
|
+
}
|
|
53980
53999
|
await mkdir(dirname3(outputPath), { recursive: true });
|
|
53981
54000
|
await writeFile(outputPath, output, "utf8");
|
|
53982
54001
|
outputFiles.push(outputPath);
|
|
@@ -53985,6 +54004,26 @@ async function renderFromConfig(dsl, renderTargets) {
|
|
|
53985
54004
|
}
|
|
53986
54005
|
return outputFiles;
|
|
53987
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
|
+
}
|
|
53988
54027
|
async function checkDriftFromConfig(dsl, renderTargets) {
|
|
53989
54028
|
const diffs = [];
|
|
53990
54029
|
for (const target of renderTargets) {
|
|
@@ -53993,12 +54032,7 @@ async function checkDriftFromConfig(dsl, renderTargets) {
|
|
|
53993
54032
|
if (target.context === "system") {
|
|
53994
54033
|
const ctx = buildSystemContext(dsl);
|
|
53995
54034
|
const expected = compiled(ctx);
|
|
53996
|
-
|
|
53997
|
-
const existing = await readFile2(target.output, "utf8");
|
|
53998
|
-
if (existing !== expected) diffs.push(target.output);
|
|
53999
|
-
} catch {
|
|
54000
|
-
diffs.push(target.output);
|
|
54001
|
-
}
|
|
54035
|
+
await checkExpectedVsExisting(expected, target.output, target.skip_empty, diffs);
|
|
54002
54036
|
} else {
|
|
54003
54037
|
const section = getDslSection(dsl, target.context);
|
|
54004
54038
|
const allIds = Object.keys(section);
|
|
@@ -54007,12 +54041,7 @@ async function checkDriftFromConfig(dsl, renderTargets) {
|
|
|
54007
54041
|
const ctx = buildEntityContext(dsl, target.context, entityId);
|
|
54008
54042
|
const expected = compiled(ctx);
|
|
54009
54043
|
const outputPath = expandOutputPath(target.output, target.context, entityId);
|
|
54010
|
-
|
|
54011
|
-
const existing = await readFile2(outputPath, "utf8");
|
|
54012
|
-
if (existing !== expected) diffs.push(outputPath);
|
|
54013
|
-
} catch {
|
|
54014
|
-
diffs.push(outputPath);
|
|
54015
|
-
}
|
|
54044
|
+
await checkExpectedVsExisting(expected, outputPath, target.skip_empty, diffs);
|
|
54016
54045
|
}
|
|
54017
54046
|
}
|
|
54018
54047
|
}
|
|
@@ -54054,7 +54083,8 @@ var RenderTargetSchema = z16.object({
|
|
|
54054
54083
|
context: ContextTypeSchema,
|
|
54055
54084
|
output: z16.string(),
|
|
54056
54085
|
include: z16.array(z16.string()).optional(),
|
|
54057
|
-
exclude: z16.array(z16.string()).optional()
|
|
54086
|
+
exclude: z16.array(z16.string()).optional(),
|
|
54087
|
+
skip_empty: z16.boolean().optional()
|
|
54058
54088
|
}).refine(
|
|
54059
54089
|
(data) => !(data.include && data.exclude),
|
|
54060
54090
|
{ message: "include and exclude are mutually exclusive" }
|
|
@@ -54086,7 +54116,7 @@ var ConfigLoadError = class extends Error {
|
|
|
54086
54116
|
}
|
|
54087
54117
|
filePath;
|
|
54088
54118
|
};
|
|
54089
|
-
async function
|
|
54119
|
+
async function fileExists2(filePath) {
|
|
54090
54120
|
try {
|
|
54091
54121
|
await access(filePath);
|
|
54092
54122
|
return true;
|
|
@@ -54097,7 +54127,7 @@ async function fileExists(filePath) {
|
|
|
54097
54127
|
async function loadConfig(configPath) {
|
|
54098
54128
|
const isExplicit = configPath !== void 0;
|
|
54099
54129
|
const targetPath = resolve4(configPath ?? DEFAULT_CONFIG_NAME);
|
|
54100
|
-
if (!await
|
|
54130
|
+
if (!await fileExists2(targetPath)) {
|
|
54101
54131
|
if (isExplicit) {
|
|
54102
54132
|
throw new ConfigLoadError(
|
|
54103
54133
|
`Config file not found: ${targetPath}`,
|
|
@@ -54298,7 +54328,7 @@ ${issues}`,
|
|
|
54298
54328
|
}
|
|
54299
54329
|
|
|
54300
54330
|
// src/guardrail-generator/generator.ts
|
|
54301
|
-
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";
|
|
54302
54332
|
import { resolve as resolve6, dirname as dirname6 } from "path";
|
|
54303
54333
|
import Handlebars2 from "handlebars";
|
|
54304
54334
|
|
|
@@ -54472,6 +54502,7 @@ async function generateGuardrails(options) {
|
|
|
54472
54502
|
});
|
|
54473
54503
|
continue;
|
|
54474
54504
|
}
|
|
54505
|
+
const shouldSkipEmpty = outputDef.skip_empty === true;
|
|
54475
54506
|
if (outputDef.group_by) {
|
|
54476
54507
|
const groupField = outputDef.group_by;
|
|
54477
54508
|
const groups = /* @__PURE__ */ new Map();
|
|
@@ -54491,6 +54522,15 @@ async function generateGuardrails(options) {
|
|
|
54491
54522
|
const compiled = Handlebars2.compile(templateContent, { noEscape: true });
|
|
54492
54523
|
const output = compiled(groupCtx);
|
|
54493
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
|
+
}
|
|
54494
54534
|
if (!dryRun) {
|
|
54495
54535
|
await mkdir2(dirname6(groupTarget), { recursive: true });
|
|
54496
54536
|
await writeFile2(groupTarget, output, "utf8");
|
|
@@ -54503,14 +54543,23 @@ async function generateGuardrails(options) {
|
|
|
54503
54543
|
} else {
|
|
54504
54544
|
const compiled = Handlebars2.compile(templateContent, { noEscape: true });
|
|
54505
54545
|
const output = compiled(ctx);
|
|
54506
|
-
if (
|
|
54507
|
-
|
|
54508
|
-
|
|
54509
|
-
|
|
54510
|
-
|
|
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
|
+
}
|
|
54511
54560
|
}
|
|
54561
|
+
outputFiles.push(targetPath);
|
|
54512
54562
|
}
|
|
54513
|
-
outputFiles.push(targetPath);
|
|
54514
54563
|
}
|
|
54515
54564
|
}
|
|
54516
54565
|
}
|