@smartergpt/lexrunner 1.2.1 → 1.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  securityCommandBlockedError
3
- } from "./chunk-L7YDEIPO.js";
3
+ } from "./chunk-26SCN2LJ.js";
4
4
  import "./chunk-V3BU2VDU.js";
5
5
 
6
6
  // src/security/commandValidator.ts
@@ -384,15 +384,23 @@ function gitOperationError(ctx) {
384
384
  }
385
385
  function planValidationError(ctx) {
386
386
  const nextActions = ["Review the plan file for schema violations"];
387
+ const errorCount = ctx.errorCount ?? ctx.errors.length;
387
388
  if (ctx.planPath) {
388
389
  nextActions.push(`Plan file: ${ctx.planPath}`);
389
390
  }
390
- nextActions.push(`Errors: ${ctx.errors.join("; ")}`);
391
+ if (ctx.errors.length > 0) {
392
+ nextActions.push(`Errors: ${ctx.errors.join("; ")}`);
393
+ }
394
+ if (ctx.errorsTruncated) {
395
+ nextActions.push(
396
+ `Only the first ${ctx.errors.length} of ${errorCount} validation errors are included`
397
+ );
398
+ }
391
399
  return createAXError(
392
400
  ErrorCodes.PLAN_VALIDATION_FAILED,
393
- `Plan validation failed with ${ctx.errors.length} error(s)`,
401
+ `Plan validation failed with ${errorCount} error(s)`,
394
402
  nextActions,
395
- { ...ctx }
403
+ { ...ctx, errorCount, errorsTruncated: ctx.errorsTruncated ?? false }
396
404
  );
397
405
  }
398
406
  function toAXError(error, code = ErrorCodes.INTERNAL_ERROR, nextActions) {
@@ -739,6 +747,12 @@ var ErrorCodes = {
739
747
  PLAN_VALIDATION_FAILED: "PLAN_VALIDATION_FAILED",
740
748
  /** Plan file not found */
741
749
  PLAN_NOT_FOUND: "PLAN_NOT_FOUND",
750
+ /** Explicit plan reference is empty, overlong, or otherwise invalid */
751
+ PLAN_REFERENCE_INVALID: "PLAN_REFERENCE_INVALID",
752
+ /** Plan reference exists but cannot be read as a bounded regular file */
753
+ PLAN_UNREADABLE: "PLAN_UNREADABLE",
754
+ /** Plan exceeds the bounded integration artifact limits */
755
+ PLAN_ARTIFACT_LIMIT_EXCEEDED: "PLAN_ARTIFACT_LIMIT_EXCEEDED",
742
756
  /** Cycle detected in plan item dependencies */
743
757
  PLAN_CYCLE_DETECTED: "PLAN_CYCLE_DETECTED",
744
758
  /** Referenced dependency not found in plan */
@@ -1,5 +1,5 @@
1
1
  export { AXError, AXErrorException, AXErrorSchema, createAXError, isAXError, isAXErrorException, wrapAsAXError } from '@smartergpt/lex/errors';
2
- export { C as CycleDetectedContext, G as GateFailureContext, a as GitHubErrorContext, b as GitOperationContext, c as GovernanceContext, M as MCPErrorContext, d as MergeConflictContext, P as PlanValidationContext, R as RunNotFoundContext, S as SecurityAuthContext, e as SecurityCommandBlockedContext, f as SecurityComplianceViolationContext, g as SecuritySarifParseErrorContext, h as SecurityScanFailedContext, i as SecuritySecretDetectedContext, j as SecuritySecretNotFoundContext, k as SecurityUnauthorizedContext, T as ToolBudgetExceededContext, U as UnknownDependencyContext, W as WeaveLockConflictContext, l as WeavePreflightFailedContext, n as WeaveStateInvalidContext, o as WithGovernance, p as configInvalidError, q as cycleDetectedError, r as gateFailedError, s as gitOperationError, t as githubApiError, m as mcpToolError, u as mergeConflictError, v as planNotFoundError, w as planValidationError, x as profileNotFoundError, y as runNotFoundError, z as securityAuthFailedError, A as securityCommandBlockedError, B as securityComplianceViolationError, D as securitySarifParseError, E as securityScanFailedError, F as securitySecretDetectedError, H as securitySecretNotFoundError, I as securityUnauthorizedError, J as throwAXError, K as toAXError, L as toolBudgetExceededError, N as unknownDependencyError, O as weaveLockConflictError, Q as weavePreflightFailedError, V as weaveStateInvalidError, X as writeProtectionError } from '../adapters-DciX_uRh.js';
2
+ export { C as CycleDetectedContext, G as GateFailureContext, a as GitHubErrorContext, b as GitOperationContext, c as GovernanceContext, M as MCPErrorContext, d as MergeConflictContext, P as PlanValidationContext, R as RunNotFoundContext, S as SecurityAuthContext, e as SecurityCommandBlockedContext, f as SecurityComplianceViolationContext, g as SecuritySarifParseErrorContext, h as SecurityScanFailedContext, i as SecuritySecretDetectedContext, j as SecuritySecretNotFoundContext, k as SecurityUnauthorizedContext, T as ToolBudgetExceededContext, U as UnknownDependencyContext, W as WeaveLockConflictContext, l as WeavePreflightFailedContext, n as WeaveStateInvalidContext, o as WithGovernance, p as configInvalidError, q as cycleDetectedError, r as gateFailedError, s as gitOperationError, t as githubApiError, m as mcpToolError, u as mergeConflictError, v as planNotFoundError, w as planValidationError, x as profileNotFoundError, y as runNotFoundError, z as securityAuthFailedError, A as securityCommandBlockedError, B as securityComplianceViolationError, D as securitySarifParseError, E as securityScanFailedError, F as securitySecretDetectedError, H as securitySecretNotFoundError, I as securityUnauthorizedError, J as throwAXError, K as toAXError, L as toolBudgetExceededError, N as unknownDependencyError, O as weaveLockConflictError, Q as weavePreflightFailedError, V as weaveStateInvalidError, X as writeProtectionError } from '../adapters-r7_TjMwo.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
@@ -47,6 +47,12 @@ declare const ErrorCodes: {
47
47
  readonly PLAN_VALIDATION_FAILED: "PLAN_VALIDATION_FAILED";
48
48
  /** Plan file not found */
49
49
  readonly PLAN_NOT_FOUND: "PLAN_NOT_FOUND";
50
+ /** Explicit plan reference is empty, overlong, or otherwise invalid */
51
+ readonly PLAN_REFERENCE_INVALID: "PLAN_REFERENCE_INVALID";
52
+ /** Plan reference exists but cannot be read as a bounded regular file */
53
+ readonly PLAN_UNREADABLE: "PLAN_UNREADABLE";
54
+ /** Plan exceeds the bounded integration artifact limits */
55
+ readonly PLAN_ARTIFACT_LIMIT_EXCEEDED: "PLAN_ARTIFACT_LIMIT_EXCEEDED";
50
56
  /** Cycle detected in plan item dependencies */
51
57
  readonly PLAN_CYCLE_DETECTED: "PLAN_CYCLE_DETECTED";
52
58
  /** Referenced dependency not found in plan */
@@ -33,7 +33,7 @@ import {
33
33
  weaveStateInvalidError,
34
34
  wrapAsAXError,
35
35
  writeProtectionError
36
- } from "../chunk-L7YDEIPO.js";
36
+ } from "../chunk-26SCN2LJ.js";
37
37
  import "../chunk-V3BU2VDU.js";
38
38
  export {
39
39
  AXErrorException,
@@ -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
 
@@ -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.3.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"