@amistio/cli 0.1.25 → 0.1.27
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/index.js +135 -4
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1691,6 +1691,7 @@ var appEvaluationFindingResultSchema = z.object({
|
|
|
1691
1691
|
proposedPlanTitle: z.string().trim().min(1).max(200).optional(),
|
|
1692
1692
|
proposedPlanRepoPath: z.string().trim().min(1).max(300).optional(),
|
|
1693
1693
|
proposedPlanContent: z.string().trim().min(1).max(3e4).optional(),
|
|
1694
|
+
dedupeKey: z.string().trim().min(1).max(240).optional(),
|
|
1694
1695
|
status: appEvaluationFindingStatusSchema.default("open")
|
|
1695
1696
|
});
|
|
1696
1697
|
var appEvaluationScanResultSchema = z.object({
|
|
@@ -1736,6 +1737,7 @@ var appEvaluationFindingItemSchema = baseItemSchema.extend({
|
|
|
1736
1737
|
verificationPlan: z.array(z.string().trim().min(1).max(300)).min(1),
|
|
1737
1738
|
proposedLifecycleAction: appEvaluationPlanLifecycleActionSchema.default("none"),
|
|
1738
1739
|
relatedArtifactIds: z.array(z.string().trim().min(1).max(160)).default([]),
|
|
1740
|
+
dedupeKey: z.string().trim().min(1).max(240).optional(),
|
|
1739
1741
|
proposedPlanDocumentId: z.string().min(1).optional(),
|
|
1740
1742
|
implementationWorkItemId: z.string().min(1).optional(),
|
|
1741
1743
|
reviewNotes: z.string().trim().min(1).optional(),
|
|
@@ -5452,6 +5454,68 @@ var canonicalAppEvaluationCategories = /* @__PURE__ */ new Map([
|
|
|
5452
5454
|
["operations", "other"],
|
|
5453
5455
|
["ops", "other"]
|
|
5454
5456
|
]);
|
|
5457
|
+
var canonicalTestCommandKinds = /* @__PURE__ */ new Map([
|
|
5458
|
+
["verify", "verify"],
|
|
5459
|
+
["verification", "verify"],
|
|
5460
|
+
["wholeapp", "verify"],
|
|
5461
|
+
["wholeappverification", "verify"],
|
|
5462
|
+
["full", "verify"],
|
|
5463
|
+
["fullcheck", "verify"],
|
|
5464
|
+
["fullchecks", "verify"],
|
|
5465
|
+
["allcheck", "verify"],
|
|
5466
|
+
["allchecks", "verify"],
|
|
5467
|
+
["ci", "verify"],
|
|
5468
|
+
["continuousintegration", "verify"],
|
|
5469
|
+
["test", "test"],
|
|
5470
|
+
["tests", "test"],
|
|
5471
|
+
["testing", "test"],
|
|
5472
|
+
["unittest", "test"],
|
|
5473
|
+
["unittests", "test"],
|
|
5474
|
+
["integrationtest", "test"],
|
|
5475
|
+
["integrationtests", "test"],
|
|
5476
|
+
["e2etest", "test"],
|
|
5477
|
+
["e2etests", "test"],
|
|
5478
|
+
["endtoend", "test"],
|
|
5479
|
+
["endtoendtest", "test"],
|
|
5480
|
+
["spec", "test"],
|
|
5481
|
+
["specs", "test"],
|
|
5482
|
+
["suite", "test"],
|
|
5483
|
+
["testsuite", "test"],
|
|
5484
|
+
["jest", "test"],
|
|
5485
|
+
["vitest", "test"],
|
|
5486
|
+
["coverage", "coverage"],
|
|
5487
|
+
["coveragereport", "coverage"],
|
|
5488
|
+
["lint", "lint"],
|
|
5489
|
+
["linting", "lint"],
|
|
5490
|
+
["eslint", "lint"],
|
|
5491
|
+
["format", "lint"],
|
|
5492
|
+
["formatting", "lint"],
|
|
5493
|
+
["style", "lint"],
|
|
5494
|
+
["quality", "lint"],
|
|
5495
|
+
["qualitycheck", "lint"],
|
|
5496
|
+
["staticanalysis", "lint"],
|
|
5497
|
+
["typecheck", "typecheck"],
|
|
5498
|
+
["typechecks", "typecheck"],
|
|
5499
|
+
["typechecking", "typecheck"],
|
|
5500
|
+
["typecheck", "typecheck"],
|
|
5501
|
+
["tsc", "typecheck"],
|
|
5502
|
+
["typescript", "typecheck"],
|
|
5503
|
+
["build", "build"],
|
|
5504
|
+
["compile", "build"],
|
|
5505
|
+
["focused", "focused"],
|
|
5506
|
+
["focus", "focused"],
|
|
5507
|
+
["targeted", "focused"],
|
|
5508
|
+
["scoped", "focused"],
|
|
5509
|
+
["package", "focused"],
|
|
5510
|
+
["packaged", "focused"],
|
|
5511
|
+
["affected", "focused"],
|
|
5512
|
+
["affectedtests", "focused"],
|
|
5513
|
+
["touched", "focused"],
|
|
5514
|
+
["touchedtests", "focused"],
|
|
5515
|
+
["changed", "focused"],
|
|
5516
|
+
["changedtests", "focused"],
|
|
5517
|
+
["other", "focused"]
|
|
5518
|
+
]);
|
|
5455
5519
|
var canonicalProjectContextCitationSources = /* @__PURE__ */ new Map([
|
|
5456
5520
|
["projectbrain", "projectBrain"],
|
|
5457
5521
|
["approvedbrain", "projectBrain"],
|
|
@@ -5551,9 +5615,10 @@ function createTestQualityScanPrompt(workItem, context) {
|
|
|
5551
5615
|
"## Output Contract",
|
|
5552
5616
|
"",
|
|
5553
5617
|
"Print exactly one JSON object between the markers below. The CLI will submit only this structured test scan result back to Amistio.",
|
|
5554
|
-
"Accepted command kind values:
|
|
5618
|
+
"Accepted command kind values: verify, test, coverage, lint, typecheck, build, focused.",
|
|
5555
5619
|
"Accepted command status values: passed, failed, skipped, missing, blocked.",
|
|
5556
5620
|
"Accepted finding categories: missingTests, missingCoverage, lowCoverage, failingTests, failingQuality, missingCommand, flakyTests, unverifiedImplementation, testGap, other.",
|
|
5621
|
+
"Omit optional fields when unavailable; do not emit null for optional command summary fields such as exitCode, durationMs, outputExcerpt, commandId, or safePaths.",
|
|
5557
5622
|
"",
|
|
5558
5623
|
testQualityStart,
|
|
5559
5624
|
'{"summary":"Whole-app verification exists, but coverage reporting is missing for one package.","profile":{"testProfileId":"test_profile_detected","repositoryLinkId":"repository_link_placeholder","status":"detected","enabled":true,"detectedPackageManager":"pnpm","packageManagers":["pnpm"],"commands":[{"commandId":"verify","kind":"verify","label":"Whole-app verification","source":"detected","scriptName":"verify","workingDirectory":".","required":true}],"coverageThresholds":{"lines":80},"defaultWholeAppCommandId":"verify","focusedCommandIds":[],"lastDetectedAt":"2026-01-01T00:00:00.000Z"},"commandSummaries":[{"commandId":"verify","kind":"verify","label":"Whole-app verification","status":"passed","exitCode":0,"summary":"The repository verification script completed successfully.","safePaths":["package.json"]}],"coverage":{"status":"missing","thresholds":{"lines":80},"summary":"No coverage report was found."},"findings":[{"title":"Coverage report is missing","category":"missingCoverage","severity":"medium","confidence":"high","summary":"The repository test profile does not produce a coverage summary.","affectedSurfaces":["Test verification"],"evidence":["The scan found a test command but no coverage output."],"safePaths":["package.json"],"suggestedAction":"Add or document a coverage command for the affected package and include it in whole-app verification.","verificationPlan":["Run the new coverage command locally","Confirm coverage appears in the Test panel"],"dedupeKey":"missing-coverage"}],"blockedReasons":[],"redactionState":{"status":"clean","redactedFields":[]},"verificationPlan":["Review generated Test findings","Run the whole-app verification command before implementation handoff"],"warnings":[]}',
|
|
@@ -5594,6 +5659,7 @@ function createImplementationTestGatePrompt(workItem) {
|
|
|
5594
5659
|
"",
|
|
5595
5660
|
"Print exactly one JSON object between the markers below. The CLI will submit only this structured gate result back to Amistio.",
|
|
5596
5661
|
"Accepted outcome values: passed, failed, blocked, overridden.",
|
|
5662
|
+
"Omit optional fields when unavailable; do not emit null for optional command summary fields such as exitCode, durationMs, outputExcerpt, commandId, or safePaths.",
|
|
5597
5663
|
"",
|
|
5598
5664
|
implementationTestGateStart,
|
|
5599
5665
|
'{"outcome":"passed","summary":"Focused checks and whole-app verification passed.","commandSummaries":[{"commandId":"verify","kind":"verify","label":"Whole-app verification","status":"passed","exitCode":0,"summary":"The repository verification script completed successfully.","safePaths":["package.json"]}],"coverage":{"status":"unknown","thresholds":{},"summary":"No coverage threshold was configured for this gate."},"findings":[],"blockedReasons":[],"redactionState":{"status":"clean","redactedFields":[]},"verificationPlan":["Record this gate result before marking implementation complete"],"warnings":[]}',
|
|
@@ -5875,9 +5941,10 @@ function createAppEvaluationScanPrompt(workItem, context) {
|
|
|
5875
5941
|
"Accepted severity values: info, low, medium, high, critical.",
|
|
5876
5942
|
"Accepted confidence values: low, medium, high.",
|
|
5877
5943
|
"Accepted proposedLifecycleAction values: createPlan, updatePlan, markCompleted, markImplemented, markSuperseded, markBlocked, archive, keepActive, none.",
|
|
5944
|
+
"Include a stable dedupeKey for each finding based on the underlying issue identity, not scan time, generated wording, or transient ordering.",
|
|
5878
5945
|
"",
|
|
5879
5946
|
appEvaluationStart,
|
|
5880
|
-
'{"summary":"The app is generally healthy, but one release-readiness plan needs cleanup and verification evidence should be refreshed.","baselineVersion":"amistio-app-evaluation-v1","findings":[{"title":"Stale release plan should be marked superseded","category":"planCleanup","severity":"low","confidence":"high","summary":"A release plan appears to describe a workflow that has since been replaced by a newer accepted plan.","affectedSurfaces":["docs/plans"],"evidence":["A newer plan references the same scope and status, while the older plan remains proposed."],"suggestedAction":"Prepare a cleanup update that marks the stale plan superseded and links to the newer plan.","verificationPlan":["Review both plan files","Confirm the newer plan is accepted before changing lifecycle state"],"safePaths":["docs/plans/PLAN-example.md"],"proposedLifecycleAction":"markSuperseded","relatedArtifactIds":[]}],"verificationPlan":["Review App Evaluation findings for approval","Run the canonical verify gate before implementing approved actions"]}',
|
|
5947
|
+
'{"summary":"The app is generally healthy, but one release-readiness plan needs cleanup and verification evidence should be refreshed.","baselineVersion":"amistio-app-evaluation-v1","findings":[{"title":"Stale release plan should be marked superseded","category":"planCleanup","severity":"low","confidence":"high","dedupeKey":"plan-cleanup-docs-plans-plan-example-superseded","summary":"A release plan appears to describe a workflow that has since been replaced by a newer accepted plan.","affectedSurfaces":["docs/plans"],"evidence":["A newer plan references the same scope and status, while the older plan remains proposed."],"suggestedAction":"Prepare a cleanup update that marks the stale plan superseded and links to the newer plan.","verificationPlan":["Review both plan files","Confirm the newer plan is accepted before changing lifecycle state"],"safePaths":["docs/plans/PLAN-example.md"],"proposedLifecycleAction":"markSuperseded","relatedArtifactIds":[]}],"verificationPlan":["Review App Evaluation findings for approval","Run the canonical verify gate before implementing approved actions"]}',
|
|
5881
5948
|
appEvaluationEnd,
|
|
5882
5949
|
"",
|
|
5883
5950
|
"Do not put Markdown fences around the markers. Do not implement improvements or cleanup."
|
|
@@ -6237,7 +6304,71 @@ function parseTestQualityScanResult(output) {
|
|
|
6237
6304
|
}
|
|
6238
6305
|
const payload = output.slice(start + testQualityStart.length, end).trim();
|
|
6239
6306
|
const parsed = JSON.parse(stripJsonFence(payload));
|
|
6240
|
-
return testQualityScanResultSchema.parse(parsed);
|
|
6307
|
+
return testQualityScanResultSchema.parse(normalizeTestQualityScanResult(parsed));
|
|
6308
|
+
}
|
|
6309
|
+
function normalizeTestQualityScanResult(value) {
|
|
6310
|
+
if (!isObjectRecord(value)) {
|
|
6311
|
+
return value;
|
|
6312
|
+
}
|
|
6313
|
+
const normalized = { ...value };
|
|
6314
|
+
if (isObjectRecord(normalized.profile) && Array.isArray(normalized.profile.commands)) {
|
|
6315
|
+
normalized.profile = {
|
|
6316
|
+
...normalized.profile,
|
|
6317
|
+
commands: normalized.profile.commands.map(normalizeTestCommandKindObject)
|
|
6318
|
+
};
|
|
6319
|
+
}
|
|
6320
|
+
if (Array.isArray(normalized.commandSummaries)) {
|
|
6321
|
+
normalized.commandSummaries = normalized.commandSummaries.map(normalizeTestCommandSummaryObject);
|
|
6322
|
+
}
|
|
6323
|
+
return normalized;
|
|
6324
|
+
}
|
|
6325
|
+
function normalizeImplementationTestGateResult(value) {
|
|
6326
|
+
if (!isObjectRecord(value)) {
|
|
6327
|
+
return value;
|
|
6328
|
+
}
|
|
6329
|
+
const normalized = { ...value };
|
|
6330
|
+
if (Array.isArray(normalized.commandSummaries)) {
|
|
6331
|
+
normalized.commandSummaries = normalized.commandSummaries.map(normalizeTestCommandSummaryObject);
|
|
6332
|
+
}
|
|
6333
|
+
return normalized;
|
|
6334
|
+
}
|
|
6335
|
+
function normalizeTestCommandSummaryObject(value) {
|
|
6336
|
+
if (!isObjectRecord(value)) {
|
|
6337
|
+
return value;
|
|
6338
|
+
}
|
|
6339
|
+
const normalized = { ...value, kind: normalizeTestCommandKind(value.kind) };
|
|
6340
|
+
for (const key of ["commandId", "durationMs", "exitCode", "outputExcerpt", "safePaths"]) {
|
|
6341
|
+
if (normalized[key] === null) {
|
|
6342
|
+
delete normalized[key];
|
|
6343
|
+
}
|
|
6344
|
+
}
|
|
6345
|
+
return normalized;
|
|
6346
|
+
}
|
|
6347
|
+
function normalizeTestCommandKindObject(value) {
|
|
6348
|
+
if (!isObjectRecord(value)) {
|
|
6349
|
+
return value;
|
|
6350
|
+
}
|
|
6351
|
+
return { ...value, kind: normalizeTestCommandKind(value.kind) };
|
|
6352
|
+
}
|
|
6353
|
+
function normalizeTestCommandKind(value) {
|
|
6354
|
+
if (typeof value !== "string") {
|
|
6355
|
+
return value;
|
|
6356
|
+
}
|
|
6357
|
+
const trimmed = value.trim();
|
|
6358
|
+
if (!trimmed) {
|
|
6359
|
+
return value;
|
|
6360
|
+
}
|
|
6361
|
+
const direct = canonicalTestCommandKinds.get(normalizeEnumKey(trimmed));
|
|
6362
|
+
if (direct) {
|
|
6363
|
+
return direct;
|
|
6364
|
+
}
|
|
6365
|
+
for (const segment of trimmed.split(/[\/,|]+/)) {
|
|
6366
|
+
const segmentKind = canonicalTestCommandKinds.get(normalizeEnumKey(segment));
|
|
6367
|
+
if (segmentKind) {
|
|
6368
|
+
return segmentKind;
|
|
6369
|
+
}
|
|
6370
|
+
}
|
|
6371
|
+
return "focused";
|
|
6241
6372
|
}
|
|
6242
6373
|
function parseImplementationTestGateResult(output) {
|
|
6243
6374
|
const start = output.indexOf(implementationTestGateStart);
|
|
@@ -6247,7 +6378,7 @@ function parseImplementationTestGateResult(output) {
|
|
|
6247
6378
|
}
|
|
6248
6379
|
const payload = output.slice(start + implementationTestGateStart.length, end).trim();
|
|
6249
6380
|
const parsed = JSON.parse(stripJsonFence(payload));
|
|
6250
|
-
return implementationTestGateResultSchema.parse(parsed);
|
|
6381
|
+
return implementationTestGateResultSchema.parse(normalizeImplementationTestGateResult(parsed));
|
|
6251
6382
|
}
|
|
6252
6383
|
function projectContextRefreshSubmissionFailureSummary(result) {
|
|
6253
6384
|
if (result.refresh.status !== "failed" && result.workItem.status !== "failed") {
|