@habitat-ai/cli 0.2.3 → 0.3.0
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/dist/nx-plugin.js +219 -74
- package/oclif.manifest.json +1 -1
- package/package.json +5 -5
package/dist/nx-plugin.js
CHANGED
|
@@ -1733,6 +1733,7 @@ var HABITAT_CATALOG_PATHS = [
|
|
|
1733
1733
|
var HABITAT_AUTHORITY_GLOB = `{${HABITAT_CATALOG_PATHS.join(",")}}`;
|
|
1734
1734
|
var DEFAULT_CHECK_TARGET = "check:policy";
|
|
1735
1735
|
var HABITAT_EXECUTABLE = "habitat";
|
|
1736
|
+
var PORTABLE_OWNER_PROJECT = /^[A-Za-z0-9@][A-Za-z0-9@._/+:-]*$/u;
|
|
1736
1737
|
function createHabitatNxPlugin(binding) {
|
|
1737
1738
|
const createNodes = [
|
|
1738
1739
|
HABITAT_AUTHORITY_GLOB,
|
|
@@ -1778,8 +1779,7 @@ function projectCatalogTargets(matchedFiles, catalog, runtimeInputs) {
|
|
|
1778
1779
|
addLeafTarget(project, compatibilityTargetName(rule), compatibilityTarget(rule, runtimeInputs));
|
|
1779
1780
|
}
|
|
1780
1781
|
return [...projects.entries()].sort(([left], [right]) => compareText(left, right)).map(([root, project]) => {
|
|
1781
|
-
|
|
1782
|
-
project.targets[DEFAULT_CHECK_TARGET] = ownerTarget(project.ownerProject, leafTargets, project.compatibilityManifests.size > 0);
|
|
1782
|
+
project.targets[DEFAULT_CHECK_TARGET] = ownerTarget(project.ownerProject, ownerInputs(project.targets, runtimeInputs), project.compatibilityManifests.size > 0);
|
|
1783
1783
|
return [
|
|
1784
1784
|
projectionSource(project),
|
|
1785
1785
|
{
|
|
@@ -1900,17 +1900,32 @@ function compatibilityTarget(rule, runtimeInputs) {
|
|
|
1900
1900
|
metadata: { description: `Check Habitat compatibility rule ${rule.ruleId}` }
|
|
1901
1901
|
};
|
|
1902
1902
|
}
|
|
1903
|
-
function ownerTarget(ownerProject,
|
|
1903
|
+
function ownerTarget(ownerProject, inputs, hasCompatibility) {
|
|
1904
|
+
if (!PORTABLE_OWNER_PROJECT.test(ownerProject)) {
|
|
1905
|
+
throw new Error(`Habitat Nx projection rejected owner '${ownerProject}': identity is not portable as an Nx command argument.`);
|
|
1906
|
+
}
|
|
1904
1907
|
return {
|
|
1905
|
-
|
|
1906
|
-
cache:
|
|
1908
|
+
command: `${HABITAT_EXECUTABLE} check --owner ${ownerProject}`,
|
|
1909
|
+
cache: true,
|
|
1910
|
+
inputs,
|
|
1907
1911
|
outputs: [],
|
|
1908
|
-
|
|
1912
|
+
options: { cwd: "{workspaceRoot}" },
|
|
1909
1913
|
metadata: {
|
|
1910
1914
|
description: hasCompatibility ? `Check resolved Habitat policy owned by ${ownerProject}` : `Check resolved Habitat applications owned by ${ownerProject}`
|
|
1911
1915
|
}
|
|
1912
1916
|
};
|
|
1913
1917
|
}
|
|
1918
|
+
function ownerInputs(targets, runtimeInputs) {
|
|
1919
|
+
const runtimeStrings = new Set(runtimeInputs.filter((input) => typeof input === "string"));
|
|
1920
|
+
const corpusInputs = new Set;
|
|
1921
|
+
for (const target of Object.values(targets)) {
|
|
1922
|
+
for (const input of target.inputs ?? []) {
|
|
1923
|
+
if (typeof input === "string" && !runtimeStrings.has(input))
|
|
1924
|
+
corpusInputs.add(input);
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
return [...runtimeInputs, ...[...corpusInputs].sort(compareText)];
|
|
1928
|
+
}
|
|
1914
1929
|
function applicationInputs(application, runtimeInputs) {
|
|
1915
1930
|
const files = new Set(HABITAT_CATALOG_PATHS.map(workspaceInput));
|
|
1916
1931
|
if (application.runner.name === "grit") {
|
|
@@ -1934,15 +1949,25 @@ function compatibilityInputs(rule, runtimeInputs) {
|
|
|
1934
1949
|
files.add(workspaceInput(rule.baseline.relativePath));
|
|
1935
1950
|
for (const pattern of rule.coveragePatterns)
|
|
1936
1951
|
files.add(workspaceInput(pattern));
|
|
1937
|
-
|
|
1952
|
+
if (rule.runner.name === "grit") {
|
|
1953
|
+
files.add(workspaceInput(rule.runner.pattern.relativePath));
|
|
1954
|
+
for (const entry of rule.runner.acquisition.entries) {
|
|
1955
|
+
addSubjectInputs(files, entry.path, entry.kind);
|
|
1956
|
+
}
|
|
1957
|
+
} else {
|
|
1958
|
+
files.add(workspaceInput(rule.runner.structure.relativePath));
|
|
1959
|
+
}
|
|
1938
1960
|
return [...runtimeInputs, ...[...files].sort(compareText)];
|
|
1939
1961
|
}
|
|
1940
1962
|
function addSubjectInputs(target, path, kind) {
|
|
1941
1963
|
const exact = workspaceInput(path);
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1964
|
+
if (kind === "directory" && path === ".") {
|
|
1965
|
+
target.add("{workspaceRoot}/**/*");
|
|
1966
|
+
return;
|
|
1945
1967
|
}
|
|
1968
|
+
target.add(exact);
|
|
1969
|
+
if (kind === "directory")
|
|
1970
|
+
target.add(`${exact}/**/*`);
|
|
1946
1971
|
}
|
|
1947
1972
|
function workspaceInput(path) {
|
|
1948
1973
|
const normalized = normalizeWorkspacePath(path);
|
|
@@ -44644,6 +44669,17 @@ var MAX_RULE_EVALUATION_FAILURE_DETAIL = 4096;
|
|
|
44644
44669
|
var NonEmptyStringSchema = exports_typebox.String({
|
|
44645
44670
|
minLength: 1
|
|
44646
44671
|
});
|
|
44672
|
+
var RuleEvaluationProgramSchema = ReadonlyObject(exports_typebox.Object({
|
|
44673
|
+
id: exports_typebox.String({
|
|
44674
|
+
minLength: 1,
|
|
44675
|
+
maxLength: 1024,
|
|
44676
|
+
description: "Invocation-local program identity used to attribute findings"
|
|
44677
|
+
}),
|
|
44678
|
+
program: exports_typebox.String({
|
|
44679
|
+
minLength: 1,
|
|
44680
|
+
description: "Already-resolved evaluator program"
|
|
44681
|
+
})
|
|
44682
|
+
}), { additionalProperties: false });
|
|
44647
44683
|
var RuleEvaluationPositionSchema = ReadonlyObject(exports_typebox.Object({
|
|
44648
44684
|
line: exports_typebox.Integer({
|
|
44649
44685
|
minimum: 1,
|
|
@@ -44670,20 +44706,31 @@ var RuleEvaluationFindingSchema = ReadonlyObject(exports_typebox.Object({
|
|
|
44670
44706
|
})
|
|
44671
44707
|
}), { additionalProperties: false });
|
|
44672
44708
|
var RuleEvaluationRequestSchema = ReadonlyObject(exports_typebox.Object({
|
|
44673
|
-
|
|
44674
|
-
|
|
44675
|
-
description: "
|
|
44709
|
+
programs: ReadonlyObject(exports_typebox.Array(RuleEvaluationProgramSchema), {
|
|
44710
|
+
minItems: 1,
|
|
44711
|
+
description: "Non-empty ordered programs evaluated against the same subjects"
|
|
44676
44712
|
}),
|
|
44677
44713
|
subjectPaths: ReadonlyObject(exports_typebox.Array(NonEmptyStringSchema), {
|
|
44678
44714
|
minItems: 1,
|
|
44679
44715
|
description: "Non-empty caller-resolved absolute subject paths"
|
|
44680
44716
|
})
|
|
44681
44717
|
}), { additionalProperties: false });
|
|
44682
|
-
var
|
|
44718
|
+
var RuleEvaluationProgramResultSchema = ReadonlyObject(exports_typebox.Object({
|
|
44719
|
+
programId: exports_typebox.String({
|
|
44720
|
+
minLength: 1,
|
|
44721
|
+
maxLength: 1024,
|
|
44722
|
+
description: "Invocation-local identity of the evaluated program"
|
|
44723
|
+
}),
|
|
44683
44724
|
findings: ReadonlyObject(exports_typebox.Array(RuleEvaluationFindingSchema), {
|
|
44684
44725
|
description: "Findings reported by the evaluator in provider-defined stable order"
|
|
44685
44726
|
})
|
|
44686
44727
|
}), { additionalProperties: false });
|
|
44728
|
+
var RuleEvaluationResultSchema = ReadonlyObject(exports_typebox.Object({
|
|
44729
|
+
results: ReadonlyObject(exports_typebox.Array(RuleEvaluationProgramResultSchema), {
|
|
44730
|
+
minItems: 1,
|
|
44731
|
+
description: "Per-program results in request order"
|
|
44732
|
+
})
|
|
44733
|
+
}), { additionalProperties: false });
|
|
44687
44734
|
var RuleEvaluationFailureReasonSchema = exports_typebox.Union([
|
|
44688
44735
|
exports_typebox.Literal("InvalidInput"),
|
|
44689
44736
|
exports_typebox.Literal("SetupFailed"),
|
|
@@ -46194,8 +46241,9 @@ __export(exports_value, {
|
|
|
46194
46241
|
});
|
|
46195
46242
|
// ../../resources/rule-evaluation/dist/providers/grit-effect-platform-node/index.js
|
|
46196
46243
|
var TEMP_CATALOG_PREFIX = "habitat-rule-evaluation-";
|
|
46197
|
-
var
|
|
46198
|
-
var
|
|
46244
|
+
var GRIT_PATTERN_PREFIX = "habitat_rule_evaluation_";
|
|
46245
|
+
var MAX_GRIT_OUTPUT_BYTES_PER_PROGRAM = 256 * 1024;
|
|
46246
|
+
var MAX_GRIT_BATCH_OUTPUT_BYTES = 16 * 1024 * 1024;
|
|
46199
46247
|
var GritRuleEvaluationProviderConfigSchema = ReadonlyObject(exports_typebox.Object({
|
|
46200
46248
|
executable: exports_typebox.String({
|
|
46201
46249
|
minLength: 1,
|
|
@@ -46213,11 +46261,12 @@ var GritPositionSchema = exports_typebox.Object({
|
|
|
46213
46261
|
}, { additionalProperties: false, description: "Grit-reported source position" });
|
|
46214
46262
|
var GritResultSchema = exports_typebox.Object({
|
|
46215
46263
|
check_id: exports_typebox.String({
|
|
46216
|
-
|
|
46217
|
-
description: "
|
|
46264
|
+
minLength: 1,
|
|
46265
|
+
description: "Grit check identity with evaluator suffix"
|
|
46218
46266
|
}),
|
|
46219
|
-
local_name: exports_typebox.
|
|
46220
|
-
|
|
46267
|
+
local_name: exports_typebox.String({
|
|
46268
|
+
minLength: 1,
|
|
46269
|
+
description: "Local Grit catalog pattern name"
|
|
46221
46270
|
}),
|
|
46222
46271
|
path: exports_typebox.String({ minLength: 1, description: "Grit-reported subject path" }),
|
|
46223
46272
|
start: GritPositionSchema,
|
|
@@ -46247,13 +46296,24 @@ function makeGritRuleEvaluationResource(config) {
|
|
|
46247
46296
|
return yield* fail11("InvalidInput", "Grit provider configuration does not match its structural contract");
|
|
46248
46297
|
}
|
|
46249
46298
|
if (!requestValidator.Check(input)) {
|
|
46250
|
-
return yield* fail11("InvalidInput", "Rule-evaluation request requires
|
|
46299
|
+
return yield* fail11("InvalidInput", "Rule-evaluation request requires resolved programs and non-empty subject paths");
|
|
46251
46300
|
}
|
|
46252
46301
|
const path = yield* exports_Path.Path;
|
|
46253
46302
|
if (input.subjectPaths.some((subjectPath) => !path.isAbsolute(subjectPath))) {
|
|
46254
46303
|
return yield* fail11("InvalidInput", "Rule-evaluation subject paths must be caller-resolved absolute paths");
|
|
46255
46304
|
}
|
|
46256
|
-
|
|
46305
|
+
const [firstProgram, ...remainingPrograms] = input.programs;
|
|
46306
|
+
if (firstProgram === undefined) {
|
|
46307
|
+
return yield* fail11("InvalidInput", "Rule-evaluation request requires at least one program");
|
|
46308
|
+
}
|
|
46309
|
+
if (new Set(input.programs.map(({ id: id3 }) => id3)).size !== input.programs.length) {
|
|
46310
|
+
return yield* fail11("InvalidInput", "Rule-evaluation program identities must be unique");
|
|
46311
|
+
}
|
|
46312
|
+
const programs = [
|
|
46313
|
+
materializeProgram(firstProgram, 0),
|
|
46314
|
+
...remainingPrograms.map((program, index4) => materializeProgram(program, index4 + 1))
|
|
46315
|
+
];
|
|
46316
|
+
return yield* exports_Effect.scoped(withScopedGritCatalog(programs, (catalog) => runGritCheck(config, catalog, programs, input.subjectPaths)));
|
|
46257
46317
|
});
|
|
46258
46318
|
return Object.freeze({ evaluate: evaluate6 });
|
|
46259
46319
|
}
|
|
@@ -46263,7 +46323,7 @@ function makeNodeGritRuleEvaluationResource(config) {
|
|
|
46263
46323
|
evaluate: (input) => resource.evaluate(input).pipe(exports_Effect.provide(exports_NodeServices.layer))
|
|
46264
46324
|
});
|
|
46265
46325
|
}
|
|
46266
|
-
function withScopedGritCatalog(
|
|
46326
|
+
function withScopedGritCatalog(programs, use) {
|
|
46267
46327
|
return exports_Effect.gen(function* () {
|
|
46268
46328
|
const fs = yield* exports_FileSystem.FileSystem;
|
|
46269
46329
|
const path = yield* exports_Path.Path;
|
|
@@ -46277,11 +46337,12 @@ function withScopedGritCatalog(program, use) {
|
|
|
46277
46337
|
yield* fs.makeDirectory(catalog.gritDirectory).pipe(mapPlatform("SetupFailed", "Failed to create Grit catalog directory"));
|
|
46278
46338
|
yield* fs.makeDirectory(catalog.userConfigDirectory).pipe(mapPlatform("SetupFailed", "Failed to create Grit user-config directory"));
|
|
46279
46339
|
yield* fs.makeDirectory(catalog.cacheDirectory).pipe(mapPlatform("SetupFailed", "Failed to create Grit cache directory"));
|
|
46280
|
-
yield* fs.writeFileString(path.join(catalog.gritDirectory, "grit.yaml"), renderGritCatalog(
|
|
46340
|
+
yield* fs.writeFileString(path.join(catalog.gritDirectory, "grit.yaml"), renderGritCatalog(programs)).pipe(mapPlatform("SetupFailed", "Failed to write temporary Grit catalog"));
|
|
46281
46341
|
return yield* use(catalog);
|
|
46282
46342
|
});
|
|
46283
46343
|
}
|
|
46284
|
-
function runGritCheck(config, catalog, subjectPaths) {
|
|
46344
|
+
function runGritCheck(config, catalog, programs, subjectPaths) {
|
|
46345
|
+
const outputLimit = gritOutputLimit(programs.length);
|
|
46285
46346
|
const observe = exports_Effect.gen(function* () {
|
|
46286
46347
|
const command = exports_ChildProcess.make(config.executable, ["--json", "check", "--no-cache", "--grit-dir", catalog.gritDirectory, ...subjectPaths], {
|
|
46287
46348
|
cwd: catalog.root,
|
|
@@ -46290,7 +46351,8 @@ function runGritCheck(config, catalog, subjectPaths) {
|
|
|
46290
46351
|
GRIT_CACHE_DIR: catalog.cacheDirectory,
|
|
46291
46352
|
GRIT_USER_CONFIG: catalog.userConfigDirectory,
|
|
46292
46353
|
GRIT_TELEMETRY_DISABLED: "true",
|
|
46293
|
-
NO_COLOR: undefined
|
|
46354
|
+
NO_COLOR: undefined,
|
|
46355
|
+
RAYON_NUM_THREADS: "2"
|
|
46294
46356
|
},
|
|
46295
46357
|
extendEnv: true,
|
|
46296
46358
|
stdin: "ignore",
|
|
@@ -46299,8 +46361,8 @@ function runGritCheck(config, catalog, subjectPaths) {
|
|
|
46299
46361
|
});
|
|
46300
46362
|
const process2 = yield* command.pipe(mapPlatform("ExecutionFailed", "Failed to start Grit"));
|
|
46301
46363
|
const output = yield* exports_Effect.all({
|
|
46302
|
-
stdout: collectBoundedOutput(process2.stdout, "stdout"),
|
|
46303
|
-
stderr: collectBoundedOutput(process2.stderr, "stderr"),
|
|
46364
|
+
stdout: collectBoundedOutput(process2.stdout, "stdout", outputLimit),
|
|
46365
|
+
stderr: collectBoundedOutput(process2.stderr, "stderr", outputLimit),
|
|
46304
46366
|
exitCode: process2.exitCode.pipe(exports_Effect.map(Number), mapPlatform("ExecutionFailed", "Failed to observe Grit exit"))
|
|
46305
46367
|
}, { concurrency: "unbounded" });
|
|
46306
46368
|
return Object.freeze(output);
|
|
@@ -46316,7 +46378,7 @@ function runGritCheck(config, catalog, subjectPaths) {
|
|
|
46316
46378
|
if (observation.stdout.trim().length > 0) {
|
|
46317
46379
|
return fail11("InvalidOutput", "Grit check emitted unexpected stdout alongside its stderr JSON report");
|
|
46318
46380
|
}
|
|
46319
|
-
return decodeGritReport(observation.stderr).pipe(exports_Effect.
|
|
46381
|
+
return decodeGritReport(observation.stderr).pipe(exports_Effect.flatMap((report) => resultFromGritReport(report, programs)));
|
|
46320
46382
|
}));
|
|
46321
46383
|
}
|
|
46322
46384
|
function decodeGritReport(stderr) {
|
|
@@ -46328,45 +46390,61 @@ function decodeGritReport(stderr) {
|
|
|
46328
46390
|
catch: (error2) => failure("InvalidOutput", `Grit check emitted an invalid report: ${errorMessage(error2)}`)
|
|
46329
46391
|
})));
|
|
46330
46392
|
}
|
|
46331
|
-
function resultFromGritReport(report) {
|
|
46332
|
-
const
|
|
46333
|
-
|
|
46334
|
-
|
|
46335
|
-
|
|
46336
|
-
|
|
46337
|
-
|
|
46338
|
-
}
|
|
46339
|
-
|
|
46340
|
-
|
|
46341
|
-
|
|
46342
|
-
|
|
46343
|
-
|
|
46344
|
-
|
|
46345
|
-
|
|
46393
|
+
function resultFromGritReport(report, programs) {
|
|
46394
|
+
const programsByPattern = new Map(programs.map((program) => [program.patternName, program]));
|
|
46395
|
+
const findingsByProgram = new Map(programs.map(({ id: id3 }) => [id3, []]));
|
|
46396
|
+
for (const result4 of report.results) {
|
|
46397
|
+
const program = programsByPattern.get(result4.local_name);
|
|
46398
|
+
if (program === undefined || !result4.check_id.startsWith(`#${result4.local_name}/`)) {
|
|
46399
|
+
return fail11("InvalidOutput", `Grit check reported unexpected pattern identity '${result4.local_name}'`);
|
|
46400
|
+
}
|
|
46401
|
+
findingsByProgram.get(program.id)?.push(Object.freeze({
|
|
46402
|
+
path: result4.path,
|
|
46403
|
+
start: Object.freeze({
|
|
46404
|
+
line: result4.start.line,
|
|
46405
|
+
column: result4.start.col,
|
|
46406
|
+
offset: result4.start.offset
|
|
46407
|
+
}),
|
|
46408
|
+
end: Object.freeze({
|
|
46409
|
+
line: result4.end.line,
|
|
46410
|
+
column: result4.end.col,
|
|
46411
|
+
offset: result4.end.offset
|
|
46412
|
+
}),
|
|
46413
|
+
message: result4.extra.message
|
|
46414
|
+
}));
|
|
46415
|
+
}
|
|
46416
|
+
return exports_Effect.succeed(Object.freeze({
|
|
46417
|
+
results: Object.freeze(programs.map(({ id: id3 }) => Object.freeze({
|
|
46418
|
+
programId: id3,
|
|
46419
|
+
findings: Object.freeze((findingsByProgram.get(id3) ?? []).sort(compareFindings))
|
|
46420
|
+
})))
|
|
46421
|
+
}));
|
|
46422
|
+
}
|
|
46423
|
+
function materializeProgram(program, index4) {
|
|
46346
46424
|
return Object.freeze({
|
|
46347
|
-
|
|
46425
|
+
id: program.id,
|
|
46426
|
+
patternName: `${GRIT_PATTERN_PREFIX}${index4}`,
|
|
46427
|
+
program: program.program
|
|
46348
46428
|
});
|
|
46349
46429
|
}
|
|
46350
|
-
function renderGritCatalog(
|
|
46430
|
+
function renderGritCatalog(programs) {
|
|
46351
46431
|
return `${JSON.stringify({
|
|
46352
46432
|
version: "0.0.2",
|
|
46353
|
-
patterns:
|
|
46354
|
-
|
|
46355
|
-
|
|
46356
|
-
|
|
46357
|
-
|
|
46358
|
-
|
|
46359
|
-
}
|
|
46360
|
-
]
|
|
46433
|
+
patterns: programs.map(({ id: id3, patternName, program }) => Object.freeze({
|
|
46434
|
+
name: patternName,
|
|
46435
|
+
title: id3,
|
|
46436
|
+
level: "error",
|
|
46437
|
+
body: program
|
|
46438
|
+
}))
|
|
46361
46439
|
}, undefined, 2)}
|
|
46362
46440
|
`;
|
|
46363
46441
|
}
|
|
46364
|
-
function collectBoundedOutput(stream2, channel) {
|
|
46365
|
-
return exports_Stream.runFoldEffect(stream2.pipe(exports_Stream.mapError((error2) => failure("ExecutionFailed", `Failed to drain Grit ${channel}: ${error2.message}`))), () => Object.freeze({ buffer: new Uint8Array(
|
|
46442
|
+
function collectBoundedOutput(stream2, channel, outputLimit) {
|
|
46443
|
+
return exports_Stream.runFoldEffect(stream2.pipe(exports_Stream.mapError((error2) => failure("ExecutionFailed", `Failed to drain Grit ${channel}: ${error2.message}`))), () => Object.freeze({ buffer: new Uint8Array(outputLimit), bytes: 0 }), (state2, chunk) => {
|
|
46366
46444
|
if (chunk.byteLength === 0)
|
|
46367
46445
|
return exports_Effect.succeed(state2);
|
|
46368
46446
|
const bytes = state2.bytes + chunk.byteLength;
|
|
46369
|
-
return bytes >
|
|
46447
|
+
return bytes > outputLimit ? fail11("InvalidOutput", `Grit ${channel} exceeded its ${outputLimit}-byte output limit`) : exports_Effect.sync(() => {
|
|
46370
46448
|
state2.buffer.set(chunk, state2.bytes);
|
|
46371
46449
|
return Object.freeze({ buffer: state2.buffer, bytes });
|
|
46372
46450
|
});
|
|
@@ -46375,6 +46453,9 @@ function collectBoundedOutput(stream2, channel) {
|
|
|
46375
46453
|
catch: (error2) => failure("InvalidOutput", `Grit ${channel} was not valid UTF-8: ${errorMessage(error2)}`)
|
|
46376
46454
|
})));
|
|
46377
46455
|
}
|
|
46456
|
+
function gritOutputLimit(programCount) {
|
|
46457
|
+
return Math.min(MAX_GRIT_BATCH_OUTPUT_BYTES, MAX_GRIT_OUTPUT_BYTES_PER_PROGRAM * programCount);
|
|
46458
|
+
}
|
|
46378
46459
|
function mapPlatform(reason, context4) {
|
|
46379
46460
|
return (effect2) => effect2.pipe(exports_Effect.mapError((error2) => failure(reason, `${context4}: ${error2.message}`)));
|
|
46380
46461
|
}
|
|
@@ -48230,7 +48311,7 @@ function createRouterClient(router, ...rest3) {
|
|
|
48230
48311
|
return recursive;
|
|
48231
48312
|
}
|
|
48232
48313
|
|
|
48233
|
-
// ../../
|
|
48314
|
+
// ../../node_modules/.bun/@habitat-ai+typebox-adapter@0.1.1/node_modules/@habitat-ai/typebox-adapter/dist/index.js
|
|
48234
48315
|
function standard(schema5) {
|
|
48235
48316
|
const validator = new Validator({}, Clone2(schema5));
|
|
48236
48317
|
const jsonSchema = ({ target: target2 }) => {
|
|
@@ -51941,21 +52022,22 @@ var check7 = module3.check.effect(function* ({ context: context4, input }) {
|
|
|
51941
52022
|
};
|
|
51942
52023
|
}
|
|
51943
52024
|
}
|
|
51944
|
-
const reports =
|
|
51945
|
-
|
|
52025
|
+
const reports = new Array(preparations.length);
|
|
52026
|
+
const readyGritEvaluations = [];
|
|
52027
|
+
for (const [applicationIndex, prepared] of preparations.entries()) {
|
|
51946
52028
|
if (prepared.kind === "structure") {
|
|
51947
52029
|
if (prepared.preparation.kind === "failed") {
|
|
51948
|
-
reports
|
|
52030
|
+
reports[applicationIndex] = prepared.preparation.report;
|
|
51949
52031
|
continue;
|
|
51950
52032
|
}
|
|
51951
52033
|
const admitted = prepared.preparation.value;
|
|
51952
52034
|
const application2 = admitted.application;
|
|
51953
52035
|
if (admitted.scopes.length === 0) {
|
|
51954
|
-
reports
|
|
52036
|
+
reports[applicationIndex] = evaluatedStructureApplication(application2, []);
|
|
51955
52037
|
continue;
|
|
51956
52038
|
}
|
|
51957
52039
|
if (inventoryPreparation.kind === "failed") {
|
|
51958
|
-
reports
|
|
52040
|
+
reports[applicationIndex] = failedStructureApplication(application2, "InventoryFailed", inventoryPreparation.detail);
|
|
51959
52041
|
continue;
|
|
51960
52042
|
}
|
|
51961
52043
|
if (inventoryPreparation.kind === "not-required") {
|
|
@@ -51969,48 +52051,85 @@ var check7 = module3.check.effect(function* ({ context: context4, input }) {
|
|
|
51969
52051
|
return yield* prepareStructureObservations(structureChildObservationPaths(plan, roots.kinds), roots.kinds);
|
|
51970
52052
|
});
|
|
51971
52053
|
if (observations.kind === "failed") {
|
|
51972
|
-
reports
|
|
52054
|
+
reports[applicationIndex] = failedStructureApplication(application2, "StructureObservationFailed", observations.detail);
|
|
51973
52055
|
continue;
|
|
51974
52056
|
}
|
|
51975
|
-
reports
|
|
52057
|
+
reports[applicationIndex] = evaluatedStructureApplication(application2, evaluateStructurePlan(plan, observations.kinds));
|
|
51976
52058
|
continue;
|
|
51977
52059
|
}
|
|
51978
52060
|
const application = prepared.application;
|
|
51979
52061
|
const patternAttempt = yield* exports_Effect.result(context4.fileSystem.readFileString(application.runner.pattern.absolutePath));
|
|
51980
52062
|
if (patternAttempt._tag === "Failure") {
|
|
51981
|
-
reports
|
|
52063
|
+
reports[applicationIndex] = failedApplication(application, "PatternReadFailed", `Unable to read pattern asset "${application.runner.pattern.relativePath}".`);
|
|
51982
52064
|
continue;
|
|
51983
52065
|
}
|
|
51984
52066
|
const program = extractGritProgram(patternAttempt.success);
|
|
51985
52067
|
if (!program.ok) {
|
|
51986
|
-
reports
|
|
52068
|
+
reports[applicationIndex] = failedApplication(application, "PatternInvalid", program.detail);
|
|
51987
52069
|
continue;
|
|
51988
52070
|
}
|
|
51989
52071
|
const subjectPreparation = yield* prepareGritSubjects(application, context4.workspaceRoot, context4.fileSystem, context4.path);
|
|
51990
52072
|
if (subjectPreparation.kind === "failed") {
|
|
51991
|
-
reports
|
|
52073
|
+
reports[applicationIndex] = failedApplication(application, "SetupFailed", subjectPreparation.detail);
|
|
51992
52074
|
continue;
|
|
51993
52075
|
}
|
|
51994
52076
|
if (subjectPreparation.kind === "not-applicable") {
|
|
51995
52077
|
if (!isCompatibilityRule(application)) {
|
|
51996
52078
|
return yield* exports_Effect.die(new Error("Version-three Grit applications cannot be not applicable."));
|
|
51997
52079
|
}
|
|
51998
|
-
reports
|
|
52080
|
+
reports[applicationIndex] = notApplicableApplication(application);
|
|
51999
52081
|
continue;
|
|
52000
52082
|
}
|
|
52001
52083
|
const subjects = subjectPreparation.subjects;
|
|
52002
|
-
|
|
52084
|
+
readyGritEvaluations.push({
|
|
52085
|
+
applicationIndex,
|
|
52086
|
+
application,
|
|
52087
|
+
programId: `application-${applicationIndex}`,
|
|
52003
52088
|
program: program.program,
|
|
52089
|
+
subjects,
|
|
52004
52090
|
subjectPaths: subjects.map((subject) => subject.absolutePath)
|
|
52091
|
+
});
|
|
52092
|
+
}
|
|
52093
|
+
for (const evaluations of groupGritEvaluations(readyGritEvaluations)) {
|
|
52094
|
+
const first = evaluations[0];
|
|
52095
|
+
if (first === undefined) {
|
|
52096
|
+
return yield* exports_Effect.die(new Error("A Grit evaluation group must not be empty."));
|
|
52097
|
+
}
|
|
52098
|
+
const evaluation = yield* exports_Effect.result(context4.ruleEvaluation.evaluate({
|
|
52099
|
+
programs: evaluations.map(({ programId, program }) => ({ id: programId, program })),
|
|
52100
|
+
subjectPaths: first.subjectPaths
|
|
52005
52101
|
}));
|
|
52006
52102
|
if (evaluation._tag === "Failure") {
|
|
52007
|
-
|
|
52103
|
+
for (const prepared of evaluations) {
|
|
52104
|
+
reports[prepared.applicationIndex] = failedApplication(prepared.application, evaluation.failure.reason, evaluation.failure.detail);
|
|
52105
|
+
}
|
|
52008
52106
|
continue;
|
|
52009
52107
|
}
|
|
52010
|
-
const
|
|
52011
|
-
|
|
52108
|
+
const resultMismatch = evaluationResultMismatch(evaluations, evaluation.success.results);
|
|
52109
|
+
if (resultMismatch !== undefined) {
|
|
52110
|
+
for (const prepared of evaluations) {
|
|
52111
|
+
reports[prepared.applicationIndex] = failedApplication(prepared.application, "InvalidOutput", resultMismatch);
|
|
52112
|
+
}
|
|
52113
|
+
continue;
|
|
52114
|
+
}
|
|
52115
|
+
const results = indexEvaluationResults(evaluation.success.results);
|
|
52116
|
+
for (const prepared of evaluations) {
|
|
52117
|
+
const result4 = results.get(prepared.programId);
|
|
52118
|
+
if (result4 === undefined) {
|
|
52119
|
+
return yield* exports_Effect.die(new Error(`Validated evaluation result '${prepared.programId}' is absent.`));
|
|
52120
|
+
}
|
|
52121
|
+
const normalized = normalizeFindings(result4.findings, prepared.subjects, context4.workspaceRoot, context4.path);
|
|
52122
|
+
reports[prepared.applicationIndex] = normalized.ok ? evaluatedApplication(prepared.application, normalized.findings) : failedApplication(prepared.application, "FindingPathInvalid", normalized.detail);
|
|
52123
|
+
}
|
|
52012
52124
|
}
|
|
52013
|
-
|
|
52125
|
+
const completedReports = [];
|
|
52126
|
+
for (const [applicationIndex, report] of reports.entries()) {
|
|
52127
|
+
if (report === undefined) {
|
|
52128
|
+
return yield* exports_Effect.die(new Error(`Habitat check produced no report for application ${applicationIndex}.`));
|
|
52129
|
+
}
|
|
52130
|
+
completedReports.push(report);
|
|
52131
|
+
}
|
|
52132
|
+
return completedCheck(completedReports);
|
|
52014
52133
|
});
|
|
52015
52134
|
var catalog2 = { resolve: resolve5, check: check7 };
|
|
52016
52135
|
function catalogRejected(issues) {
|
|
@@ -52043,6 +52162,32 @@ function hasExactCauseCode(error2, code) {
|
|
|
52043
52162
|
const cause = "cause" in error2.reason ? error2.reason.cause : undefined;
|
|
52044
52163
|
return typeof cause === "object" && cause !== null && "code" in cause && cause.code === code;
|
|
52045
52164
|
}
|
|
52165
|
+
function groupGritEvaluations(evaluations) {
|
|
52166
|
+
const groups = new Map;
|
|
52167
|
+
for (const evaluation of evaluations) {
|
|
52168
|
+
const key = JSON.stringify(evaluation.subjectPaths);
|
|
52169
|
+
const group = groups.get(key);
|
|
52170
|
+
if (group === undefined)
|
|
52171
|
+
groups.set(key, [evaluation]);
|
|
52172
|
+
else
|
|
52173
|
+
group.push(evaluation);
|
|
52174
|
+
}
|
|
52175
|
+
return [...groups.values()];
|
|
52176
|
+
}
|
|
52177
|
+
function evaluationResultMismatch(evaluations, results) {
|
|
52178
|
+
if (results.length !== evaluations.length) {
|
|
52179
|
+
return `Rule evaluator returned ${results.length} program results for ${evaluations.length} requested programs.`;
|
|
52180
|
+
}
|
|
52181
|
+
const uniqueIds = new Set(results.map(({ programId }) => programId));
|
|
52182
|
+
if (uniqueIds.size !== results.length) {
|
|
52183
|
+
return "Rule evaluator returned duplicate program result identities.";
|
|
52184
|
+
}
|
|
52185
|
+
const unexpected = results.find((result4, index4) => result4.programId !== evaluations[index4]?.programId);
|
|
52186
|
+
return unexpected === undefined ? undefined : "Rule evaluator did not preserve requested program result order and identity.";
|
|
52187
|
+
}
|
|
52188
|
+
function indexEvaluationResults(results) {
|
|
52189
|
+
return new Map(results.map((result4) => [result4.programId, result4]));
|
|
52190
|
+
}
|
|
52046
52191
|
function prepareGritSubjects(application, workspaceRoot, fileSystem, path) {
|
|
52047
52192
|
if (!isCompatibilityRule(application)) {
|
|
52048
52193
|
return exports_Effect.succeed({
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@habitat-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@effect/platform-node": "4.0.0-beta.101",
|
|
50
50
|
"@getgrit/cli": "0.1.0-alpha.1743007075",
|
|
51
|
-
"@habitat-ai/plugin-cli": "0.
|
|
52
|
-
"@habitat-ai/resource-rule-evaluation": "0.
|
|
53
|
-
"@habitat-ai/resource-source-inventory": "0.
|
|
54
|
-
"@habitat-ai/service": "0.
|
|
51
|
+
"@habitat-ai/plugin-cli": "0.3.0",
|
|
52
|
+
"@habitat-ai/resource-rule-evaluation": "0.3.0",
|
|
53
|
+
"@habitat-ai/resource-source-inventory": "0.3.0",
|
|
54
|
+
"@habitat-ai/service": "0.3.0",
|
|
55
55
|
"@nx/devkit": "23.1.0",
|
|
56
56
|
"@oclif/core": "^4.11.4",
|
|
57
57
|
"@oclif/plugin-help": "^6.2.27",
|