@smartergpt/lexrunner 1.2.1 → 1.4.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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  computeMergeOrder
3
- } from "./chunk-6TB2UCBZ.js";
4
- import "./chunk-L7YDEIPO.js";
3
+ } from "./chunk-VAGHAQT2.js";
4
+ import "./chunk-26SCN2LJ.js";
5
5
  import "./chunk-AXOAVRTU.js";
6
6
  import "./chunk-V3BU2VDU.js";
7
7
 
@@ -7,8 +7,8 @@ import {
7
7
  import "./chunk-6A4IE3TI.js";
8
8
  import {
9
9
  computeMergeOrder
10
- } from "./chunk-6TB2UCBZ.js";
11
- import "./chunk-L7YDEIPO.js";
10
+ } from "./chunk-VAGHAQT2.js";
11
+ import "./chunk-26SCN2LJ.js";
12
12
  import "./chunk-AXOAVRTU.js";
13
13
  import "./chunk-V3BU2VDU.js";
14
14
 
@@ -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>;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  securitySecretNotFoundError
3
- } from "./chunk-L7YDEIPO.js";
3
+ } from "./chunk-26SCN2LJ.js";
4
4
  import "./chunk-V3BU2VDU.js";
5
5
 
6
6
  // src/security/secrets.ts
package/mcp-server.mjs CHANGED
@@ -45,15 +45,27 @@ try {
45
45
  }
46
46
 
47
47
  const attemptLifecycleHandlers = core.createAttemptLifecycleHandlers();
48
+ const containmentPreflightHandler = core.createAgentWorkContainmentPreflightHandler();
49
+ const projectionLifecycleHandlers = core.createNativeWslProjectionLifecycleHandlers();
48
50
  const attemptWorkerHandlers = core.createAttemptWorkerHandlers();
49
51
  const attemptReceiptHandlers = core.createAttemptReceiptHandlers();
50
52
  const attemptVerificationHandlers = core.createAttemptVerificationHandlers();
51
53
 
52
54
  function sharedServiceError(error, tool, fallbackCode) {
53
55
  if (error && typeof error === "object" && typeof error.code === "string") {
56
+ const planArtifactContext =
57
+ error.name === "PlanArtifactServiceError"
58
+ ? {
59
+ operation: "resolve plan artifact",
60
+ details: error.source ? { source: error.source } : undefined,
61
+ }
62
+ : {};
54
63
  return new Error(
55
64
  core.canonicalJSONStringify(
56
- core.mcpToolError(error.code, error.message || "Shared service failed", { tool })
65
+ core.mcpToolError(error.code, error.message || "Shared service failed", {
66
+ tool,
67
+ ...planArtifactContext,
68
+ })
57
69
  )
58
70
  );
59
71
  }
@@ -68,6 +80,43 @@ function sharedServiceError(error, tool, fallbackCode) {
68
80
 
69
81
  // MCP Tool implementations
70
82
  const tools = {
83
+ preflight_attempt_containment: {
84
+ description:
85
+ "Read physical-containment capability before constructing an agent-work Attempt packet",
86
+ inputSchema: core.AgentWorkContainmentPreflightRequestJsonSchema,
87
+ call: async (args) => canonicalToolResult(await containmentPreflightHandler.preflight(args)),
88
+ },
89
+
90
+ prepare_native_wsl_projection: {
91
+ description: "Prepare or exactly reuse an identity-anchored native WSL projection",
92
+ inputSchema: core.NativeWslProjectionPrepareRequestJsonSchema,
93
+ call: async (args) =>
94
+ mutationToolCall("prepare a native WSL projection", () =>
95
+ projectionLifecycleHandlers.prepare(args)
96
+ ),
97
+ },
98
+
99
+ get_native_wsl_projection_status: {
100
+ description: "Read bounded native WSL projection status without creating state",
101
+ inputSchema: core.NativeWslProjectionStatusRequestJsonSchema,
102
+ call: async (args) => canonicalToolResult(await projectionLifecycleHandlers.status(args)),
103
+ },
104
+
105
+ cleanup_native_wsl_projection: {
106
+ description: "Remove exact idle native WSL projection and quarantine state",
107
+ inputSchema: core.NativeWslProjectionCleanupRequestJsonSchema,
108
+ call: async (args) =>
109
+ mutationToolCall("clean up a native WSL projection", () =>
110
+ projectionLifecycleHandlers.cleanup(args)
111
+ ),
112
+ },
113
+
114
+ inspect_native_wsl_projection_quarantine: {
115
+ description: "Inspect privacy-bounded native WSL projection quarantine state",
116
+ inputSchema: core.NativeWslProjectionQuarantineRequestJsonSchema,
117
+ call: async (args) => canonicalToolResult(await projectionLifecycleHandlers.quarantine(args)),
118
+ },
119
+
71
120
  verify_attempt: {
72
121
  description: "Run packet-declared engine verification for one fenced Attempt",
73
122
  inputSchema: core.AttemptVerificationRunRequestJsonSchema,
@@ -389,6 +438,11 @@ const tools = {
389
438
  inputSchema: {
390
439
  type: "object",
391
440
  properties: {
441
+ planFile: {
442
+ type: "string",
443
+ description:
444
+ "Explicit plan.json path (default: repository plan.json, then profile runner fallback)",
445
+ },
392
446
  onlyItem: {
393
447
  type: "string",
394
448
  description: "Run gates for specific item only",
@@ -405,31 +459,25 @@ const tools = {
405
459
  },
406
460
  call: async (args) => {
407
461
  try {
408
- // Resolve profile directory
409
- const { resolveProfile } = await import("./dist/cli.js");
410
- const resolved = resolveProfile(config.profileDir, process.cwd());
411
-
412
- // Load plan
413
- const planPath = resolve(resolved.path, "runner", "plan.json");
414
- if (!existsSync(planPath)) {
415
- throw new Error("No plan found. Run plan.create first.");
416
- }
417
-
418
- const { loadPlan, GateExecutionService } = await import("./dist/cli.js");
419
- const planContent = readFileSync(planPath, "utf-8");
420
- const plan = loadPlan(planContent);
462
+ const artifact = new core.PlanArtifactService().resolve({
463
+ planFile: args.planFile,
464
+ workingDir: process.cwd(),
465
+ profileDir: config.profileDir,
466
+ });
421
467
 
422
468
  // Determine output directory
423
- const outDir = args.outDir || resolve(resolved.path, "runner", "gates");
469
+ const outDir = args.outDir || resolve(dirname(artifact.filePath), "gates");
424
470
 
425
- const result = (
426
- await new GateExecutionService().run({
427
- plan,
471
+ const summary = (
472
+ await new core.GateExecutionService().run({
473
+ plan: artifact.plan,
428
474
  artifactDir: outDir,
429
475
  onlyItem: args.onlyItem,
430
476
  onlyGate: args.onlyGate,
477
+ options: { emitReceipt: false, suppressStdout: true },
431
478
  })
432
479
  ).summary;
480
+ const result = { ...summary, planArtifact: artifact.identity };
433
481
 
434
482
  return {
435
483
  content: [
@@ -440,7 +488,9 @@ const tools = {
440
488
  ],
441
489
  };
442
490
  } catch (error) {
443
- throw new Error(`Failed to run gates: ${error.message}`);
491
+ const validationFailure = planValidationToolResult(error);
492
+ if (validationFailure) return validationFailure;
493
+ throw sharedServiceError(error, "gates.run", "GATE_EXECUTION_FAILED");
444
494
  }
445
495
  },
446
496
  },
@@ -450,6 +500,11 @@ const tools = {
450
500
  inputSchema: {
451
501
  type: "object",
452
502
  properties: {
503
+ planFile: {
504
+ type: "string",
505
+ description:
506
+ "Explicit plan.json path (default: repository plan.json, then profile runner fallback)",
507
+ },
453
508
  dryRun: {
454
509
  type: "boolean",
455
510
  description: "Simulate merge without making changes",
@@ -459,28 +514,21 @@ const tools = {
459
514
  },
460
515
  call: async (args) => {
461
516
  try {
462
- // Resolve profile directory
463
- const { resolveProfile } = await import("./dist/cli.js");
464
- const resolved = resolveProfile(config.profileDir, process.cwd());
465
-
466
- // Load plan
467
- const planPath = resolve(resolved.path, "runner", "plan.json");
468
- if (!existsSync(planPath)) {
469
- throw new Error("No plan found. Run plan.create first.");
470
- }
471
-
472
- const { loadPlan, MergeApplicationService } = await import("./dist/cli.js");
473
- const planContent = readFileSync(planPath, "utf-8");
474
- const plan = loadPlan(planContent);
517
+ const artifact = new core.PlanArtifactService().resolve({
518
+ planFile: args.planFile,
519
+ workingDir: process.cwd(),
520
+ profileDir: config.profileDir,
521
+ });
475
522
 
476
- const result = (
477
- await new MergeApplicationService().run({
478
- plan,
523
+ const summary = (
524
+ await new core.MergeApplicationService().run({
525
+ plan: artifact.plan,
479
526
  workingDir: process.cwd(),
480
527
  dryRun: args.dryRun ?? true,
481
528
  mutationAuthorized: config.allowMutations,
482
529
  })
483
530
  ).summary;
531
+ const result = { ...summary, planArtifact: artifact.identity };
484
532
 
485
533
  return {
486
534
  content: [
@@ -491,6 +539,8 @@ const tools = {
491
539
  ],
492
540
  };
493
541
  } catch (error) {
542
+ const validationFailure = planValidationToolResult(error);
543
+ if (validationFailure) return validationFailure;
494
544
  if (error?.name === "MergeApplicationServiceError" && typeof error.code === "string") {
495
545
  const { mcpToolError } = await import("./dist/errors/index.js");
496
546
  throw new Error(
@@ -499,7 +549,7 @@ const tools = {
499
549
  )
500
550
  );
501
551
  }
502
- throw new Error(`Failed to apply merge: ${error.message}`);
552
+ throw sharedServiceError(error, "merge.apply", "MERGE_APPLICATION_FAILED");
503
553
  }
504
554
  },
505
555
  },
@@ -831,24 +881,22 @@ const tools = {
831
881
  properties: {
832
882
  planFile: {
833
883
  type: "string",
834
- description: "Path to plan.json file (default: plan.json)",
835
- default: "plan.json",
884
+ description:
885
+ "Explicit plan.json path (default: repository plan.json, then profile runner fallback)",
836
886
  },
837
887
  },
838
888
  },
839
889
  call: async (args) => {
840
890
  try {
841
- const planFile = args.planFile || "plan.json";
842
-
843
- if (!existsSync(planFile)) {
844
- throw new Error(`Plan file not found: ${planFile}`);
845
- }
846
-
847
- const { loadPlan, IntegrationStatusQueryService } = await import("./dist/cli.js");
848
- const planContent = readFileSync(planFile, "utf-8");
849
- const plan = loadPlan(planContent);
850
-
851
- const result = new IntegrationStatusQueryService().run(plan);
891
+ const artifact = new core.PlanArtifactService().resolve({
892
+ planFile: args.planFile,
893
+ workingDir: process.cwd(),
894
+ profileDir: config.profileDir,
895
+ });
896
+ const result = {
897
+ ...new core.IntegrationStatusQueryService().run(artifact.plan),
898
+ planArtifact: artifact.identity,
899
+ };
852
900
 
853
901
  return {
854
902
  content: [
@@ -859,7 +907,9 @@ const tools = {
859
907
  ],
860
908
  };
861
909
  } catch (error) {
862
- throw new Error(`Failed to get status: ${error.message}`);
910
+ const validationFailure = planValidationToolResult(error);
911
+ if (validationFailure) return validationFailure;
912
+ throw sharedServiceError(error, "status", "INTEGRATION_STATUS_FAILED");
863
913
  }
864
914
  },
865
915
  },
@@ -898,24 +948,22 @@ const tools = {
898
948
  properties: {
899
949
  planFile: {
900
950
  type: "string",
901
- description: "Path to plan.json file (default: plan.json)",
902
- default: "plan.json",
951
+ description:
952
+ "Explicit plan.json path (default: repository plan.json, then profile runner fallback)",
903
953
  },
904
954
  },
905
955
  },
906
956
  call: async (args) => {
907
957
  try {
908
- const planFile = args.planFile || "plan.json";
909
-
910
- if (!existsSync(planFile)) {
911
- throw new Error(`Plan file not found: ${planFile}`);
912
- }
913
-
914
- const { loadPlan, MergeOrderQueryService } = await import("./dist/cli.js");
915
- const planContent = readFileSync(planFile, "utf-8");
916
- const plan = loadPlan(planContent);
917
-
918
- const result = new MergeOrderQueryService().run(plan);
958
+ const artifact = new core.PlanArtifactService().resolve({
959
+ planFile: args.planFile,
960
+ workingDir: process.cwd(),
961
+ profileDir: config.profileDir,
962
+ });
963
+ const result = {
964
+ ...new core.MergeOrderQueryService().run(artifact.plan),
965
+ planArtifact: artifact.identity,
966
+ };
919
967
 
920
968
  return {
921
969
  content: [
@@ -926,7 +974,9 @@ const tools = {
926
974
  ],
927
975
  };
928
976
  } catch (error) {
929
- throw new Error(`Failed to compute merge order: ${error.message}`);
977
+ const validationFailure = planValidationToolResult(error);
978
+ if (validationFailure) return validationFailure;
979
+ throw sharedServiceError(error, "merge-order", "MERGE_ORDER_FAILED");
930
980
  }
931
981
  },
932
982
  },
@@ -1013,6 +1063,11 @@ function canonicalToolResult(result) {
1013
1063
  };
1014
1064
  }
1015
1065
 
1066
+ function planValidationToolResult(error) {
1067
+ const failure = core.asPlanValidationFailure(error);
1068
+ return failure ? canonicalToolResult(failure) : null;
1069
+ }
1070
+
1016
1071
  async function mutationToolCall(action, call) {
1017
1072
  if (!config.allowMutations) {
1018
1073
  return canonicalToolResult({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartergpt/lexrunner",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -93,6 +93,7 @@
93
93
  "validate:manifests": "tsx scripts/validate-manifests.ts",
94
94
  "validate:build-artifacts": "tsx scripts/validate-build-artifacts.ts",
95
95
  "validate:package": "tsx scripts/validate-package-boundary.ts",
96
+ "check:install-scripts": "node scripts/check-install-script-policy.mjs",
96
97
  "test:package": "node scripts/smoke-packed-package.mjs",
97
98
  "docs:check": "node scripts/check-doc-links.mjs",
98
99
  "docs:surface": "node scripts/render-doc-surfaces.mjs",
@@ -129,7 +130,7 @@
129
130
  "@modelcontextprotocol/sdk": "^1.18.2",
130
131
  "@octokit/auth-token": "^6.0.0",
131
132
  "@octokit/rest": "^22.0.0",
132
- "@smartergpt/lex": "^3.0.1",
133
+ "@smartergpt/lex": "^4.0.0",
133
134
  "@types/babel__traverse": "^7.28.0",
134
135
  "ajv": "^8.20.0",
135
136
  "better-sqlite3-multiple-ciphers": "^12.6.2",
@@ -166,5 +167,10 @@
166
167
  "*.{json,md,yaml,yml}": [
167
168
  "prettier --check"
168
169
  ]
170
+ },
171
+ "allowScripts": {
172
+ "better-sqlite3-multiple-ciphers@12.11.1": true,
173
+ "esbuild@0.28.1": true,
174
+ "@smartergpt/lex": false
169
175
  }
170
176
  }