@smartergpt/lexrunner 1.5.2 → 2.0.1

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.
@@ -62,8 +62,8 @@ type GateStatus = z.infer<typeof GateStatus>;
62
62
  * Merge status
63
63
  */
64
64
  declare const MergeStatus: z.ZodEnum<{
65
- error: "error";
66
65
  success: "success";
66
+ error: "error";
67
67
  conflict: "conflict";
68
68
  }>;
69
69
  type MergeStatus = z.infer<typeof MergeStatus>;
@@ -71,8 +71,8 @@ type MergeStatus = z.infer<typeof MergeStatus>;
71
71
  * Audit profile
72
72
  */
73
73
  declare const AuditProfile: z.ZodEnum<{
74
- basic: "basic";
75
74
  debug: "debug";
75
+ basic: "basic";
76
76
  standard: "standard";
77
77
  compliance: "compliance";
78
78
  }>;
@@ -167,8 +167,8 @@ type MergeDryRunStartedPayload = z.infer<typeof MergeDryRunStartedPayload>;
167
167
  declare const MergeDryRunFinishedPayload: z.ZodObject<{
168
168
  item: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
169
169
  status: z.ZodEnum<{
170
- error: "error";
171
170
  success: "success";
171
+ error: "error";
172
172
  conflict: "conflict";
173
173
  }>;
174
174
  conflicts: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -188,8 +188,8 @@ type MergeConflictDetectedPayload = z.infer<typeof MergeConflictDetectedPayload>
188
188
  declare const MergeFinishedPayload: z.ZodObject<{
189
189
  item: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
190
190
  status: z.ZodEnum<{
191
- error: "error";
192
191
  success: "success";
192
+ error: "error";
193
193
  conflict: "conflict";
194
194
  }>;
195
195
  commit: z.ZodOptional<z.ZodString>;
@@ -595,8 +595,8 @@ declare const MergeDryRunFinishedEvent: z.ZodObject<{
595
595
  payload: z.ZodObject<{
596
596
  item: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
597
597
  status: z.ZodEnum<{
598
- error: "error";
599
598
  success: "success";
599
+ error: "error";
600
600
  conflict: "conflict";
601
601
  }>;
602
602
  conflicts: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -718,8 +718,8 @@ declare const MergeFinishedEvent: z.ZodObject<{
718
718
  payload: z.ZodObject<{
719
719
  item: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
720
720
  status: z.ZodEnum<{
721
- error: "error";
722
721
  success: "success";
722
+ error: "error";
723
723
  conflict: "conflict";
724
724
  }>;
725
725
  commit: z.ZodOptional<z.ZodString>;
package/mcp-server.mjs CHANGED
@@ -19,6 +19,7 @@ import "dotenv/config";
19
19
  import { resolve, dirname } from "path";
20
20
  import { fileURLToPath } from "url";
21
21
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
22
+ import packageMetadata from "./package.json" with { type: "json" };
22
23
 
23
24
  const __dirname = dirname(fileURLToPath(import.meta.url));
24
25
 
@@ -455,10 +456,23 @@ const tools = {
455
456
  type: "string",
456
457
  description: "Output directory for gate results",
457
458
  },
459
+ timeoutMs: {
460
+ type: "integer",
461
+ minimum: 1,
462
+ maximum: 86400000,
463
+ description:
464
+ "Operation-default gate timeout in milliseconds; a plan gate timeoutMs overrides it exactly",
465
+ },
458
466
  },
459
467
  },
460
468
  call: async (args) => {
461
469
  try {
470
+ if (
471
+ args.timeoutMs !== undefined &&
472
+ (!Number.isInteger(args.timeoutMs) || args.timeoutMs < 1 || args.timeoutMs > 86400000)
473
+ ) {
474
+ throw new Error("timeoutMs must be an integer from 1 through 86400000 milliseconds");
475
+ }
462
476
  const artifact = new core.PlanArtifactService().resolve({
463
477
  planFile: args.planFile,
464
478
  workingDir: process.cwd(),
@@ -472,6 +486,7 @@ const tools = {
472
486
  await new core.GateExecutionService().run({
473
487
  plan: artifact.plan,
474
488
  artifactDir: outDir,
489
+ timeoutMs: args.timeoutMs,
475
490
  onlyItem: args.onlyItem,
476
491
  onlyGate: args.onlyGate,
477
492
  options: { emitReceipt: false, suppressStdout: true },
@@ -621,7 +636,7 @@ const tools = {
621
636
  },
622
637
 
623
638
  health: {
624
- description: "DEPRECATED: use doctor. Compatibility alias scheduled for removal in 2.0.0.",
639
+ description: "DEPRECATED: use doctor. Compatibility alias scheduled for removal in 3.0.0.",
625
640
  inputSchema: {
626
641
  type: "object",
627
642
  properties: {
@@ -640,7 +655,7 @@ const tools = {
640
655
  });
641
656
  const health = {
642
657
  ...doctor,
643
- deprecation: { tool: "health", replacement: "doctor", removeIn: "2.0.0" },
658
+ deprecation: { tool: "health", replacement: "doctor", removeIn: "3.0.0" },
644
659
  };
645
660
 
646
661
  return {
@@ -884,17 +899,52 @@ const tools = {
884
899
  description:
885
900
  "Explicit plan.json path (default: repository plan.json, then profile runner fallback)",
886
901
  },
902
+ evidenceFile: {
903
+ type: "string",
904
+ minLength: 1,
905
+ maxLength: 4096,
906
+ description: "Explicit gate evidence manifest returned by gates.run",
907
+ },
908
+ evidenceSha256: {
909
+ type: "string",
910
+ pattern: "^sha256:[a-f0-9]{64}$",
911
+ description: "Expected SHA-256 returned with the gate evidence manifest",
912
+ },
887
913
  },
888
914
  },
889
915
  call: async (args) => {
890
916
  try {
917
+ const hasEvidenceFile = args.evidenceFile !== undefined;
918
+ const hasEvidenceDigest = args.evidenceSha256 !== undefined;
919
+ if (hasEvidenceFile !== hasEvidenceDigest) {
920
+ throw new Error("evidenceFile and evidenceSha256 must be supplied together");
921
+ }
922
+ if (
923
+ hasEvidenceFile &&
924
+ (typeof args.evidenceFile !== "string" ||
925
+ args.evidenceFile.length < 1 ||
926
+ Buffer.byteLength(args.evidenceFile, "utf8") > 4096 ||
927
+ typeof args.evidenceSha256 !== "string" ||
928
+ !/^sha256:[a-f0-9]{64}$/u.test(args.evidenceSha256))
929
+ ) {
930
+ throw new Error("evidenceFile or evidenceSha256 is invalid");
931
+ }
891
932
  const artifact = new core.PlanArtifactService().resolve({
892
933
  planFile: args.planFile,
893
934
  workingDir: process.cwd(),
894
935
  profileDir: config.profileDir,
895
936
  });
896
937
  const result = {
897
- ...new core.IntegrationStatusQueryService().run(artifact.plan),
938
+ ...new core.IntegrationStatusQueryService().run(
939
+ artifact.plan,
940
+ args.evidenceFile
941
+ ? {
942
+ evidenceFile: args.evidenceFile,
943
+ evidenceSha256: args.evidenceSha256,
944
+ repoRoot: process.cwd(),
945
+ }
946
+ : undefined
947
+ ),
898
948
  planArtifact: artifact.identity,
899
949
  };
900
950
 
@@ -1098,7 +1148,7 @@ async function handleRequest(request) {
1098
1148
  },
1099
1149
  serverInfo: {
1100
1150
  name: "lexrunner",
1101
- version: "0.1.0",
1151
+ version: packageMetadata.version,
1102
1152
  },
1103
1153
  },
1104
1154
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartergpt/lexrunner",
3
- "version": "1.5.2",
3
+ "version": "2.0.1",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -0,0 +1,86 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://smartergpt.dev/schemas/lexrunner/gate-evidence-manifest-v1.json",
4
+ "title": "LexRunner Gate Evidence Manifest v1",
5
+ "type": "object",
6
+ "required": ["schemaVersion", "createdAt", "plan", "candidate", "selection", "entries"],
7
+ "properties": {
8
+ "schemaVersion": { "const": "lexrunner-gate-evidence-manifest/v1" },
9
+ "createdAt": { "type": "string" },
10
+ "plan": {
11
+ "type": "object",
12
+ "required": ["digest", "schemaVersion", "target", "itemCount"],
13
+ "properties": {
14
+ "digest": { "$ref": "#/$defs/sha256" },
15
+ "schemaVersion": { "type": "string" },
16
+ "target": { "type": "string" },
17
+ "itemCount": { "type": "integer", "minimum": 0 }
18
+ },
19
+ "additionalProperties": false
20
+ },
21
+ "candidate": {
22
+ "type": "object",
23
+ "required": ["repositoryRoot", "head", "worktreeDigest"],
24
+ "properties": {
25
+ "repositoryRoot": { "type": "string", "minLength": 1 },
26
+ "head": { "type": "string", "pattern": "^[a-f0-9]{40,64}$" },
27
+ "worktreeDigest": { "$ref": "#/$defs/sha256" }
28
+ },
29
+ "additionalProperties": false
30
+ },
31
+ "selection": {
32
+ "type": "object",
33
+ "required": ["onlyItem", "onlyGate"],
34
+ "properties": {
35
+ "onlyItem": { "type": ["string", "null"] },
36
+ "onlyGate": { "type": ["string", "null"] }
37
+ },
38
+ "additionalProperties": false
39
+ },
40
+ "entries": {
41
+ "type": "array",
42
+ "maxItems": 16384,
43
+ "items": {
44
+ "type": "object",
45
+ "required": ["item", "gate", "declaredGateDigest", "result", "receipt"],
46
+ "properties": {
47
+ "item": { "type": "string", "minLength": 1, "maxLength": 512 },
48
+ "gate": { "type": "string", "minLength": 1, "maxLength": 512 },
49
+ "declaredGateDigest": { "$ref": "#/$defs/sha256" },
50
+ "result": {
51
+ "type": "object",
52
+ "required": ["status", "attempts"],
53
+ "properties": {
54
+ "status": {
55
+ "enum": ["pass", "fail", "blocked", "skipped", "retrying"]
56
+ },
57
+ "exitCode": { "type": "number" },
58
+ "duration": { "type": "number", "minimum": 0 },
59
+ "timeoutMs": { "type": "integer", "minimum": 1 },
60
+ "failureKind": {
61
+ "enum": ["nonzero_exit", "spawn_error", "timeout", "evidence_error"]
62
+ },
63
+ "attempts": { "type": "integer", "minimum": 0 },
64
+ "lastAttempt": { "type": "string" }
65
+ },
66
+ "additionalProperties": false
67
+ },
68
+ "receipt": {
69
+ "type": "object",
70
+ "required": ["path", "sha256"],
71
+ "properties": {
72
+ "path": { "type": "string", "minLength": 1, "maxLength": 4096 },
73
+ "sha256": { "$ref": "#/$defs/sha256" }
74
+ },
75
+ "additionalProperties": false
76
+ }
77
+ },
78
+ "additionalProperties": false
79
+ }
80
+ }
81
+ },
82
+ "$defs": {
83
+ "sha256": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" }
84
+ },
85
+ "additionalProperties": false
86
+ }
@@ -8,6 +8,7 @@
8
8
  "required": [
9
9
  "schemaVersion",
10
10
  "attempt",
11
+ "binding",
11
12
  "declaredGate",
12
13
  "execution",
13
14
  "outcome",
@@ -15,8 +16,27 @@
15
16
  "artifacts"
16
17
  ],
17
18
  "properties": {
18
- "schemaVersion": { "const": "lexrunner-gate-execution-receipt/v1" },
19
+ "schemaVersion": { "const": "lexrunner-gate-execution-receipt/v2" },
19
20
  "attempt": { "type": "integer", "minimum": 1 },
21
+ "binding": {
22
+ "type": "object",
23
+ "additionalProperties": false,
24
+ "required": ["item", "declaredGateDigest", "candidateDigest", "timeoutMs"],
25
+ "properties": {
26
+ "item": { "type": ["string", "null"], "minLength": 1 },
27
+ "declaredGateDigest": {
28
+ "type": "string",
29
+ "pattern": "^sha256:[a-f0-9]{64}$"
30
+ },
31
+ "candidateDigest": {
32
+ "anyOf": [
33
+ { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
34
+ { "type": "null" }
35
+ ]
36
+ },
37
+ "timeoutMs": { "type": "integer", "minimum": 1 }
38
+ }
39
+ },
20
40
  "declaredGate": {
21
41
  "type": "object",
22
42
  "additionalProperties": false,
@@ -139,7 +139,7 @@
139
139
  "additionalProperties": false,
140
140
  "default": {}
141
141
  },
142
- "security": {
142
+ "security": {
143
143
  "type": "object",
144
144
  "properties": {
145
145
  "blockCritical": {
@@ -272,6 +272,11 @@
272
272
  "input": {
273
273
  "type": "object",
274
274
  "additionalProperties": {}
275
+ },
276
+ "timeoutMs": {
277
+ "type": "integer",
278
+ "exclusiveMinimum": 0,
279
+ "maximum": 86400000
275
280
  }
276
281
  },
277
282
  "required": [
@@ -297,4 +302,4 @@
297
302
  "additionalProperties": false
298
303
  }
299
304
  }
300
- }
305
+ }