@cleocode/lafs 2026.3.74 → 2026.4.3

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.
Files changed (143) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +97 -68
  3. package/dist/schemas/v1/agent-card.schema.json +230 -0
  4. package/dist/schemas/v1/conformance-profiles.json +0 -0
  5. package/dist/schemas/v1/context-ledger.schema.json +70 -0
  6. package/dist/schemas/v1/discovery.schema.json +132 -0
  7. package/dist/schemas/v1/envelope.schema.json +0 -0
  8. package/dist/schemas/v1/error-registry.json +0 -0
  9. package/dist/src/a2a/bindings/grpc.d.ts +118 -11
  10. package/dist/src/a2a/bindings/grpc.d.ts.map +1 -0
  11. package/dist/src/a2a/bindings/grpc.js +80 -8
  12. package/dist/src/a2a/bindings/grpc.js.map +1 -0
  13. package/dist/src/a2a/bindings/http.d.ts +131 -15
  14. package/dist/src/a2a/bindings/http.d.ts.map +1 -0
  15. package/dist/src/a2a/bindings/http.js +101 -14
  16. package/dist/src/a2a/bindings/http.js.map +1 -0
  17. package/dist/src/a2a/bindings/index.d.ts +83 -9
  18. package/dist/src/a2a/bindings/index.d.ts.map +1 -0
  19. package/dist/src/a2a/bindings/index.js +74 -6
  20. package/dist/src/a2a/bindings/index.js.map +1 -0
  21. package/dist/src/a2a/bindings/jsonrpc.d.ts +194 -9
  22. package/dist/src/a2a/bindings/jsonrpc.d.ts.map +1 -0
  23. package/dist/src/a2a/bindings/jsonrpc.js +155 -10
  24. package/dist/src/a2a/bindings/jsonrpc.js.map +1 -0
  25. package/dist/src/a2a/bridge.d.ts +237 -44
  26. package/dist/src/a2a/bridge.d.ts.map +1 -0
  27. package/dist/src/a2a/bridge.js +187 -48
  28. package/dist/src/a2a/bridge.js.map +1 -0
  29. package/dist/src/a2a/extensions.d.ts +222 -12
  30. package/dist/src/a2a/extensions.d.ts.map +1 -0
  31. package/dist/src/a2a/extensions.js +178 -13
  32. package/dist/src/a2a/extensions.js.map +1 -0
  33. package/dist/src/a2a/index.d.ts +10 -7
  34. package/dist/src/a2a/index.d.ts.map +1 -0
  35. package/dist/src/a2a/index.js +24 -27
  36. package/dist/src/a2a/index.js.map +1 -0
  37. package/dist/src/a2a/streaming.d.ts +276 -3
  38. package/dist/src/a2a/streaming.d.ts.map +1 -0
  39. package/dist/src/a2a/streaming.js +255 -11
  40. package/dist/src/a2a/streaming.js.map +1 -0
  41. package/dist/src/a2a/task-lifecycle.d.ts +341 -20
  42. package/dist/src/a2a/task-lifecycle.d.ts.map +1 -0
  43. package/dist/src/a2a/task-lifecycle.js +327 -26
  44. package/dist/src/a2a/task-lifecycle.js.map +1 -0
  45. package/dist/src/budgetEnforcement.d.ts +93 -20
  46. package/dist/src/budgetEnforcement.d.ts.map +1 -0
  47. package/dist/src/budgetEnforcement.js +146 -31
  48. package/dist/src/budgetEnforcement.js.map +1 -0
  49. package/dist/src/circuit-breaker/index.d.ts +260 -10
  50. package/dist/src/circuit-breaker/index.d.ts.map +1 -0
  51. package/dist/src/circuit-breaker/index.js +226 -14
  52. package/dist/src/circuit-breaker/index.js.map +1 -0
  53. package/dist/src/cli.d.ts +1 -0
  54. package/dist/src/cli.d.ts.map +1 -0
  55. package/dist/src/cli.js +12 -11
  56. package/dist/src/cli.js.map +1 -0
  57. package/dist/src/compliance.d.ts +180 -3
  58. package/dist/src/compliance.d.ts.map +1 -0
  59. package/dist/src/compliance.js +114 -13
  60. package/dist/src/compliance.js.map +1 -0
  61. package/dist/src/conformance.d.ts +55 -2
  62. package/dist/src/conformance.d.ts.map +1 -0
  63. package/dist/src/conformance.js +124 -76
  64. package/dist/src/conformance.js.map +1 -0
  65. package/dist/src/conformanceProfiles.d.ts +68 -1
  66. package/dist/src/conformanceProfiles.d.ts.map +1 -0
  67. package/dist/src/conformanceProfiles.js +53 -1
  68. package/dist/src/conformanceProfiles.js.map +1 -0
  69. package/dist/src/deprecationRegistry.d.ts +82 -1
  70. package/dist/src/deprecationRegistry.d.ts.map +1 -0
  71. package/dist/src/deprecationRegistry.js +58 -7
  72. package/dist/src/deprecationRegistry.js.map +1 -0
  73. package/dist/src/discovery.d.ts +347 -65
  74. package/dist/src/discovery.d.ts.map +1 -0
  75. package/dist/src/discovery.js +130 -72
  76. package/dist/src/discovery.js.map +1 -0
  77. package/dist/src/envelope.d.ts +262 -9
  78. package/dist/src/envelope.d.ts.map +1 -0
  79. package/dist/src/envelope.js +179 -15
  80. package/dist/src/envelope.js.map +1 -0
  81. package/dist/src/errorRegistry.d.ts +163 -3
  82. package/dist/src/errorRegistry.d.ts.map +1 -0
  83. package/dist/src/errorRegistry.js +119 -3
  84. package/dist/src/errorRegistry.js.map +1 -0
  85. package/dist/src/fieldExtraction.d.ts +128 -27
  86. package/dist/src/fieldExtraction.d.ts.map +1 -0
  87. package/dist/src/fieldExtraction.js +100 -27
  88. package/dist/src/fieldExtraction.js.map +1 -0
  89. package/dist/src/flagResolver.d.ts +77 -10
  90. package/dist/src/flagResolver.d.ts.map +1 -0
  91. package/dist/src/flagResolver.js +22 -5
  92. package/dist/src/flagResolver.js.map +1 -0
  93. package/dist/src/flagSemantics.d.ts +80 -4
  94. package/dist/src/flagSemantics.d.ts.map +1 -0
  95. package/dist/src/flagSemantics.js +78 -11
  96. package/dist/src/flagSemantics.js.map +1 -0
  97. package/dist/src/health/index.d.ts +103 -9
  98. package/dist/src/health/index.d.ts.map +1 -0
  99. package/dist/src/health/index.js +75 -26
  100. package/dist/src/health/index.js.map +1 -0
  101. package/dist/src/index.d.ts +34 -23
  102. package/dist/src/index.d.ts.map +1 -0
  103. package/dist/src/index.js +40 -28
  104. package/dist/src/index.js.map +1 -0
  105. package/dist/src/mviProjection.d.ts +43 -6
  106. package/dist/src/mviProjection.d.ts.map +1 -0
  107. package/dist/src/mviProjection.js +32 -5
  108. package/dist/src/mviProjection.js.map +1 -0
  109. package/dist/src/native-loader.d.ts +49 -0
  110. package/dist/src/native-loader.d.ts.map +1 -0
  111. package/dist/src/native-loader.js +56 -0
  112. package/dist/src/native-loader.js.map +1 -0
  113. package/dist/src/problemDetails.d.ts +71 -4
  114. package/dist/src/problemDetails.d.ts.map +1 -0
  115. package/dist/src/problemDetails.js +27 -3
  116. package/dist/src/problemDetails.js.map +1 -0
  117. package/dist/src/shutdown/index.d.ts +103 -9
  118. package/dist/src/shutdown/index.d.ts.map +1 -0
  119. package/dist/src/shutdown/index.js +78 -12
  120. package/dist/src/shutdown/index.js.map +1 -0
  121. package/dist/src/tokenEstimator.d.ts +98 -11
  122. package/dist/src/tokenEstimator.d.ts.map +1 -0
  123. package/dist/src/tokenEstimator.js +91 -13
  124. package/dist/src/tokenEstimator.js.map +1 -0
  125. package/dist/src/types.d.ts +477 -11
  126. package/dist/src/types.d.ts.map +1 -0
  127. package/dist/src/types.js +76 -2
  128. package/dist/src/types.js.map +1 -0
  129. package/dist/src/validateEnvelope.d.ts +61 -2
  130. package/dist/src/validateEnvelope.d.ts.map +1 -0
  131. package/dist/src/validateEnvelope.js +81 -14
  132. package/dist/src/validateEnvelope.js.map +1 -0
  133. package/dist/tsconfig.build.tsbuildinfo +1 -0
  134. package/lafs.md +3 -4
  135. package/package.json +14 -12
  136. package/schemas/v1/agent-card.schema.json +0 -0
  137. package/schemas/v1/conformance-profiles.json +0 -0
  138. package/schemas/v1/context-ledger.schema.json +0 -0
  139. package/schemas/v1/discovery.schema.json +0 -0
  140. package/schemas/v1/envelope.schema.json +0 -0
  141. package/schemas/v1/error-registry.json +0 -0
  142. package/dist/src/mcpAdapter.d.ts +0 -28
  143. package/dist/src/mcpAdapter.js +0 -281
@@ -1,9 +1,22 @@
1
1
  /**
2
2
  * Project an envelope to the declared MVI verbosity level.
3
- * - 'minimal': Only fields required for agent control flow
4
- * - 'standard': All commonly useful fields (current default behavior)
5
- * - 'full': Complete echo-back including request parameters
6
- * - 'custom': No projection (controlled by _fields)
3
+ *
4
+ * @param envelope - The full LAFS envelope to project
5
+ * @param mviLevel - Override MVI level; falls back to `envelope._meta.mvi`, then `'standard'`
6
+ * @returns A plain object containing only the fields appropriate for the resolved MVI level
7
+ *
8
+ * @remarks
9
+ * MVI levels control projection behavior:
10
+ * - `'minimal'`: only fields required for agent control flow (success, error code, retry info)
11
+ * - `'standard'`: all commonly useful fields (current default behavior)
12
+ * - `'full'`: complete echo-back including request parameters
13
+ * - `'custom'`: no projection (controlled by field extraction layer)
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const minimal = projectEnvelope(envelope, 'minimal');
18
+ * // minimal contains only: success, _meta (requestId, contextVersion), result/error
19
+ * ```
7
20
  */
8
21
  export function projectEnvelope(envelope, mviLevel) {
9
22
  const level = mviLevel ?? envelope._meta.mvi ?? 'standard';
@@ -108,9 +121,23 @@ function projectErrorMinimal(error) {
108
121
  }
109
122
  /**
110
123
  * Estimate token count for a projected envelope.
111
- * Uses simple heuristic: 1 token per ~4 characters of JSON.
124
+ *
125
+ * @param projected - The projected envelope object to estimate
126
+ * @returns The estimated token count based on JSON serialization length
127
+ *
128
+ * @remarks
129
+ * Uses a simple heuristic of 1 token per approximately 4 characters of
130
+ * JSON-serialized output. This is an approximation suitable for budget
131
+ * enforcement, not an exact tokenizer count.
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * const tokens = estimateProjectedTokens(projectEnvelope(envelope, 'minimal'));
136
+ * // tokens ~= Math.ceil(JSON.stringify(projected).length / 4)
137
+ * ```
112
138
  */
113
139
  export function estimateProjectedTokens(projected) {
114
140
  const json = JSON.stringify(projected);
115
141
  return Math.ceil(json.length / 4);
116
142
  }
143
+ //# sourceMappingURL=mviProjection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mviProjection.js","sourceRoot":"","sources":["../../src/mviProjection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Native addon loader for lafs-core schema validation via napi-rs.
3
+ *
4
+ * @remarks
5
+ * Loads the napi-rs native addon synchronously on first use. Falls back
6
+ * gracefully if the native addon is not available (e.g., unsupported platform,
7
+ * Rust toolchain not installed). When unavailable, the AJV-based validator
8
+ * in `validateEnvelope.ts` is used instead.
9
+ *
10
+ * Follows the same pattern as `packages/cant/src/native-loader.ts`.
11
+ */
12
+ /** Shape of a structured validation error from the native binding. */
13
+ interface NativeValidationError {
14
+ /** JSON Pointer path to the failing property. */
15
+ path: string;
16
+ /** JSON Schema keyword that triggered the error. */
17
+ keyword: string;
18
+ /** Human-readable error message. */
19
+ message: string;
20
+ /** Keyword-specific parameters. */
21
+ params: Record<string, unknown>;
22
+ }
23
+ /** Shape of the validation result from the native binding. */
24
+ export interface NativeValidationResult {
25
+ /** Whether the envelope conforms to the schema. */
26
+ valid: boolean;
27
+ /** Flattened human-readable error messages. */
28
+ errors: string[];
29
+ /** Structured error objects. */
30
+ structuredErrors: NativeValidationError[];
31
+ }
32
+ /** Shape of the native LAFS addon. */
33
+ interface LafsNativeModule {
34
+ lafsValidateEnvelope(payload: string): NativeValidationResult;
35
+ }
36
+ /**
37
+ * Check if the native addon is available.
38
+ *
39
+ * @returns `true` if the native Rust binding was loaded successfully.
40
+ */
41
+ export declare function isNativeAvailable(): boolean;
42
+ /**
43
+ * Get the native module, or `null` if unavailable.
44
+ *
45
+ * @returns The loaded native module, or `null` for AJV fallback.
46
+ */
47
+ export declare function getNativeModule(): LafsNativeModule | null;
48
+ export {};
49
+ //# sourceMappingURL=native-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-loader.d.ts","sourceRoot":"","sources":["../../src/native-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,sEAAsE;AACtE,UAAU,qBAAqB;IAC7B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,8DAA8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC,mDAAmD;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,+CAA+C;IAC/C,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gCAAgC;IAChC,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;CAC3C;AAED,sCAAsC;AACtC,UAAU,gBAAgB;IACxB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,sBAAsB,CAAC;CAC/D;AA2BD;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,gBAAgB,GAAG,IAAI,CAGzD"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Native addon loader for lafs-core schema validation via napi-rs.
3
+ *
4
+ * @remarks
5
+ * Loads the napi-rs native addon synchronously on first use. Falls back
6
+ * gracefully if the native addon is not available (e.g., unsupported platform,
7
+ * Rust toolchain not installed). When unavailable, the AJV-based validator
8
+ * in `validateEnvelope.ts` is used instead.
9
+ *
10
+ * Follows the same pattern as `packages/cant/src/native-loader.ts`.
11
+ */
12
+ import { createRequire } from 'node:module';
13
+ let nativeModule = null;
14
+ let loadAttempted = false;
15
+ /**
16
+ * Attempt to load the native addon. Called lazily on first use.
17
+ * Native addons load synchronously via require() — no async init needed.
18
+ */
19
+ function ensureLoaded() {
20
+ if (loadAttempted)
21
+ return;
22
+ loadAttempted = true;
23
+ const req = createRequire(import.meta.url);
24
+ try {
25
+ nativeModule = req('@cleocode/lafs-native');
26
+ }
27
+ catch {
28
+ try {
29
+ // Development fallback: try loading from the crate build output
30
+ nativeModule = req('../../crates/lafs-napi/index.cjs');
31
+ }
32
+ catch {
33
+ // Native addon not available — AJV fallback will be used
34
+ nativeModule = null;
35
+ }
36
+ }
37
+ }
38
+ /**
39
+ * Check if the native addon is available.
40
+ *
41
+ * @returns `true` if the native Rust binding was loaded successfully.
42
+ */
43
+ export function isNativeAvailable() {
44
+ ensureLoaded();
45
+ return nativeModule !== null;
46
+ }
47
+ /**
48
+ * Get the native module, or `null` if unavailable.
49
+ *
50
+ * @returns The loaded native module, or `null` for AJV fallback.
51
+ */
52
+ export function getNativeModule() {
53
+ ensureLoaded();
54
+ return nativeModule;
55
+ }
56
+ //# sourceMappingURL=native-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-loader.js","sourceRoot":"","sources":["../../src/native-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA6B5C,IAAI,YAAY,GAA4B,IAAI,CAAC;AACjD,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B;;;GAGG;AACH,SAAS,YAAY;IACnB,IAAI,aAAa;QAAE,OAAO;IAC1B,aAAa,GAAG,IAAI,CAAC;IAErB,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,YAAY,GAAG,GAAG,CAAC,uBAAuB,CAAqB,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,CAAC;YACH,gEAAgE;YAChE,YAAY,GAAG,GAAG,CAAC,kCAAkC,CAAqB,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;YACzD,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,YAAY,EAAE,CAAC;IACf,OAAO,YAAY,KAAK,IAAI,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe;IAC7B,YAAY,EAAE,CAAC;IACf,OAAO,YAAY,CAAC;AACtB,CAAC"}
@@ -4,31 +4,98 @@
4
4
  * Available for any transport, not just HTTP.
5
5
  */
6
6
  import type { LAFSError } from './types.js';
7
- /** RFC 9457 Problem Details with LAFS extensions */
7
+ /**
8
+ * RFC 9457 Problem Details with LAFS extensions.
9
+ *
10
+ * @remarks
11
+ * Extends the standard RFC 9457 Problem Details object with LAFS-specific
12
+ * agent-actionable fields. The index signature allows pass-through of
13
+ * additional error details from {@link LAFSError.details}.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const pd: LafsProblemDetails = {
18
+ * type: "https://lafs.dev/errors/v1/E_VALIDATION",
19
+ * title: "E_VALIDATION",
20
+ * status: 400,
21
+ * detail: "Invalid input",
22
+ * retryable: false,
23
+ * };
24
+ * ```
25
+ */
8
26
  export interface LafsProblemDetails {
27
+ /** URI reference identifying the problem type */
9
28
  type: string;
29
+ /** Short human-readable summary (typically the error code) */
10
30
  title: string;
31
+ /** HTTP status code for this error */
11
32
  status: number;
33
+ /** Human-readable explanation of the specific occurrence */
12
34
  detail: string;
35
+ /**
36
+ * URI reference identifying the specific occurrence (typically the request ID).
37
+ * @defaultValue `undefined`
38
+ */
13
39
  instance?: string;
40
+ /** Whether the operation that caused this error can be retried */
14
41
  retryable: boolean;
42
+ /**
43
+ * Recommended agent action (e.g., `"retry"`, `"escalate"`).
44
+ * @defaultValue `undefined`
45
+ */
15
46
  agentAction?: string;
47
+ /**
48
+ * Suggested delay in milliseconds before retrying.
49
+ * @defaultValue `undefined`
50
+ */
16
51
  retryAfterMs?: number;
52
+ /**
53
+ * Whether the error requires human escalation.
54
+ * @defaultValue `undefined`
55
+ */
17
56
  escalationRequired?: boolean;
57
+ /**
58
+ * Human-readable suggestion for resolving the error.
59
+ * @defaultValue `undefined`
60
+ */
18
61
  suggestedAction?: string;
62
+ /**
63
+ * Documentation URL for more information.
64
+ * @defaultValue `undefined`
65
+ */
19
66
  docUrl?: string;
67
+ /** Pass-through extension members from error details */
20
68
  [key: string]: unknown;
21
69
  }
22
70
  /**
23
71
  * Convert a LAFSError to an RFC 9457 Problem Details object.
72
+ *
73
+ * @param error - The LAFS error to convert
74
+ * @param requestId - Optional request ID to set as the `instance` field
75
+ * @returns An RFC 9457-compliant {@link LafsProblemDetails} object
76
+ *
77
+ * @remarks
24
78
  * Uses the error registry for HTTP status and type URI resolution.
79
+ * Agent-actionable fields (`agentAction`, `escalationRequired`, `suggestedAction`,
80
+ * `docUrl`) are mapped from the error when present. Non-empty `error.details`
81
+ * entries are spread as extension members, skipping keys that already exist
82
+ * in the Problem Details object.
25
83
  *
26
- * Agent-actionable fields (agentAction, escalationRequired, suggestedAction, docUrl)
27
- * are extracted from error.details if present, enabling forward-compatible extension
28
- * without requiring LAFSError type changes.
84
+ * @example
85
+ * ```typescript
86
+ * import { lafsErrorToProblemDetails } from "@cleocode/lafs";
87
+ *
88
+ * const pd = lafsErrorToProblemDetails(envelope.error!, envelope._meta.requestId);
89
+ * // pd.status === 400, pd.type === "https://lafs.dev/errors/v1/E_VALIDATION"
90
+ * ```
29
91
  */
30
92
  export declare function lafsErrorToProblemDetails(error: LAFSError, requestId?: string): LafsProblemDetails;
31
93
  /**
32
94
  * Content-Type for RFC 9457 Problem Details responses.
95
+ *
96
+ * @remarks
97
+ * Per RFC 9457, Problem Details responses MUST be served with this media type
98
+ * to distinguish them from regular JSON responses.
33
99
  */
34
100
  export declare const PROBLEM_DETAILS_CONTENT_TYPE: "application/problem+json";
101
+ //# sourceMappingURL=problemDetails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"problemDetails.d.ts","sourceRoot":"","sources":["../../src/problemDetails.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,SAAS,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,kBAAkB,CA8BpB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAG,0BAAmC,CAAC"}
@@ -1,11 +1,30 @@
1
+ /**
2
+ * Core RFC 9457 Problem Details bridge.
3
+ * Converts LAFSError to RFC 9457-compliant Problem Details objects.
4
+ * Available for any transport, not just HTTP.
5
+ */
1
6
  import { getRegistryCode } from './errorRegistry.js';
2
7
  /**
3
8
  * Convert a LAFSError to an RFC 9457 Problem Details object.
9
+ *
10
+ * @param error - The LAFS error to convert
11
+ * @param requestId - Optional request ID to set as the `instance` field
12
+ * @returns An RFC 9457-compliant {@link LafsProblemDetails} object
13
+ *
14
+ * @remarks
4
15
  * Uses the error registry for HTTP status and type URI resolution.
16
+ * Agent-actionable fields (`agentAction`, `escalationRequired`, `suggestedAction`,
17
+ * `docUrl`) are mapped from the error when present. Non-empty `error.details`
18
+ * entries are spread as extension members, skipping keys that already exist
19
+ * in the Problem Details object.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { lafsErrorToProblemDetails } from "@cleocode/lafs";
5
24
  *
6
- * Agent-actionable fields (agentAction, escalationRequired, suggestedAction, docUrl)
7
- * are extracted from error.details if present, enabling forward-compatible extension
8
- * without requiring LAFSError type changes.
25
+ * const pd = lafsErrorToProblemDetails(envelope.error!, envelope._meta.requestId);
26
+ * // pd.status === 400, pd.type === "https://lafs.dev/errors/v1/E_VALIDATION"
27
+ * ```
9
28
  */
10
29
  export function lafsErrorToProblemDetails(error, requestId) {
11
30
  const registry = getRegistryCode(error.code);
@@ -41,5 +60,10 @@ export function lafsErrorToProblemDetails(error, requestId) {
41
60
  }
42
61
  /**
43
62
  * Content-Type for RFC 9457 Problem Details responses.
63
+ *
64
+ * @remarks
65
+ * Per RFC 9457, Problem Details responses MUST be served with this media type
66
+ * to distinguish them from regular JSON responses.
44
67
  */
45
68
  export const PROBLEM_DETAILS_CONTENT_TYPE = 'application/problem+json';
69
+ //# sourceMappingURL=problemDetails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"problemDetails.js","sourceRoot":"","sources":["../../src/problemDetails.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAmErD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,yBAAyB,CACvC,KAAgB,EAChB,SAAkB;IAElB,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE7C,MAAM,EAAE,GAAuB;QAC7B,IAAI,EAAE,8BAA8B,KAAK,CAAC,IAAI,EAAE;QAChD,KAAK,EAAE,KAAK,CAAC,IAAI;QACjB,MAAM,EAAE,QAAQ,EAAE,UAAU,IAAI,GAAG;QACnC,MAAM,EAAE,KAAK,CAAC,OAAO;QACrB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IAEF,IAAI,SAAS;QAAE,EAAE,CAAC,QAAQ,GAAG,SAAS,CAAC;IACvC,IAAI,KAAK,CAAC,YAAY,IAAI,IAAI;QAAE,EAAE,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IAErE,wCAAwC;IACxC,IAAI,KAAK,CAAC,WAAW,IAAI,IAAI;QAAE,EAAE,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IAClE,IAAI,KAAK,CAAC,kBAAkB,IAAI,IAAI;QAAE,EAAE,CAAC,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,CAAC;IACvF,IAAI,KAAK,CAAC,eAAe,IAAI,IAAI;QAAE,EAAE,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;IAC9E,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI;QAAE,EAAE,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAEnD,gDAAgD;IAChD,IAAI,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;gBACjB,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,0BAAmC,CAAC"}
@@ -1,22 +1,58 @@
1
1
  /**
2
2
  * LAFS Graceful Shutdown Module
3
3
  *
4
- * Handles graceful shutdown of LAFS servers
4
+ * Handles graceful shutdown of LAFS servers.
5
+ *
6
+ * @packageDocumentation
5
7
  */
6
- import { Server } from 'http';
8
+ import type { Server } from 'http';
9
+ /** Configuration for the {@link gracefulShutdown} handler. */
7
10
  export interface GracefulShutdownConfig {
11
+ /**
12
+ * Maximum time in milliseconds to wait for in-flight requests before forcing exit.
13
+ * @defaultValue 30000
14
+ */
8
15
  timeout?: number;
16
+ /**
17
+ * POSIX signals that trigger a graceful shutdown.
18
+ * @defaultValue ['SIGTERM', 'SIGINT']
19
+ */
9
20
  signals?: NodeJS.Signals[];
21
+ /**
22
+ * Callback invoked at the start of shutdown, before the server stops accepting connections.
23
+ * @defaultValue undefined
24
+ */
10
25
  onShutdown?: () => Promise<void> | void;
26
+ /**
27
+ * Callback invoked after all connections have closed (or the timeout elapsed).
28
+ * @defaultValue undefined
29
+ */
11
30
  onClose?: () => Promise<void> | void;
12
31
  }
32
+ /** Snapshot of the current shutdown state. */
13
33
  export interface ShutdownState {
34
+ /** Whether a shutdown sequence is currently in progress. */
14
35
  isShuttingDown: boolean;
36
+ /** Number of TCP connections still open. */
15
37
  activeConnections: number;
38
+ /**
39
+ * Timestamp when the shutdown sequence began.
40
+ * @defaultValue undefined
41
+ */
16
42
  shutdownStartTime?: Date;
17
43
  }
18
44
  /**
19
- * Enable graceful shutdown for an HTTP server
45
+ * Enable graceful shutdown for an HTTP server.
46
+ *
47
+ * @remarks
48
+ * Registers listeners for the configured signals (and uncaught errors) that
49
+ * trigger an orderly shutdown sequence: invoke the `onShutdown` callback,
50
+ * stop accepting new connections, drain existing connections up to the
51
+ * timeout, invoke the `onClose` callback, and exit the process. New
52
+ * connections received after shutdown starts are immediately destroyed.
53
+ *
54
+ * @param server - The Node.js HTTP server to manage
55
+ * @param config - Optional shutdown configuration
20
56
  *
21
57
  * @example
22
58
  * ```typescript
@@ -38,28 +74,85 @@ export interface ShutdownState {
38
74
  */
39
75
  export declare function gracefulShutdown(server: Server, config?: GracefulShutdownConfig): void;
40
76
  /**
41
- * Check if server is shutting down
77
+ * Check whether a shutdown sequence is currently in progress.
78
+ *
79
+ * @remarks
80
+ * Returns `true` once a shutdown signal has been received and the shutdown
81
+ * handler has started executing. Useful for guards that need to short-circuit
82
+ * work when the process is going down.
83
+ *
84
+ * @returns `true` if the server is shutting down, `false` otherwise
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * if (isShuttingDown()) {
89
+ * return; // skip expensive work
90
+ * }
91
+ * ```
42
92
  */
43
93
  export declare function isShuttingDown(): boolean;
44
94
  /**
45
- * Get shutdown state
95
+ * Get a snapshot of the current shutdown state.
96
+ *
97
+ * @remarks
98
+ * Returns a shallow copy of the internal {@link ShutdownState}, including
99
+ * whether shutdown is in progress, the active connection count, and the
100
+ * shutdown start time (if applicable).
101
+ *
102
+ * @returns A copy of the current {@link ShutdownState}
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const state = getShutdownState();
107
+ * console.log(`Connections: ${state.activeConnections}`);
108
+ * ```
46
109
  */
47
110
  export declare function getShutdownState(): ShutdownState;
48
111
  /**
49
- * Force immediate shutdown (emergency use only)
112
+ * Terminate the process immediately without waiting for connections to drain.
113
+ *
114
+ * @remarks
115
+ * Calls `process.exit()` with the given exit code. Intended only for
116
+ * emergency situations where a graceful shutdown has stalled or a fatal
117
+ * condition prevents orderly teardown.
118
+ *
119
+ * @param exitCode - Process exit code
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * forceShutdown(1);
124
+ * ```
50
125
  */
51
126
  export declare function forceShutdown(exitCode?: number): void;
52
127
  /**
53
- * Middleware to reject requests during shutdown
128
+ * Express middleware that rejects requests with 503 while the server is shutting down.
129
+ *
130
+ * @remarks
131
+ * Should be mounted early in the middleware stack so that new requests are
132
+ * immediately rejected once shutdown begins, preventing work from starting
133
+ * that cannot complete before the process exits.
134
+ *
135
+ * @returns An Express-compatible middleware function
54
136
  *
55
137
  * @example
56
138
  * ```typescript
57
139
  * app.use(shutdownMiddleware());
58
140
  * ```
59
141
  */
60
- export declare function shutdownMiddleware(): (req: any, res: any, next: any) => void;
142
+ export declare function shutdownMiddleware(): (_req: unknown, res: {
143
+ status: (code: number) => {
144
+ json: (body: unknown) => void;
145
+ };
146
+ }, next: () => void) => void;
61
147
  /**
62
- * Wait for shutdown to complete
148
+ * Wait until a shutdown sequence begins.
149
+ *
150
+ * @remarks
151
+ * Polls the internal shutdown state every 100ms and resolves once
152
+ * `isShuttingDown` becomes `true`. Useful for test harnesses or background
153
+ * workers that need to block until the process is going down.
154
+ *
155
+ * @returns A promise that resolves when shutdown has started
63
156
  *
64
157
  * @example
65
158
  * ```typescript
@@ -67,3 +160,4 @@ export declare function shutdownMiddleware(): (req: any, res: any, next: any) =>
67
160
  * ```
68
161
  */
69
162
  export declare function waitForShutdown(): Promise<void>;
163
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shutdown/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,8DAA8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAE3B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAExC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACtC;AAED,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,cAAc,EAAE,OAAO,CAAC;IAExB,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,IAAI,CAAC;CAC1B;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,sBAA2B,GAAG,IAAI,CAoC1F;AAgED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,QAAQ,GAAE,MAAU,GAAG,IAAI,CAGxD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,KAE9B,MAAM,OAAO,EACb,KAAK;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE,CAAA;CAAE,EACpE,MAAM,MAAM,IAAI,UAWnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAIrD"}
@@ -1,14 +1,26 @@
1
1
  /**
2
2
  * LAFS Graceful Shutdown Module
3
3
  *
4
- * Handles graceful shutdown of LAFS servers
4
+ * Handles graceful shutdown of LAFS servers.
5
+ *
6
+ * @packageDocumentation
5
7
  */
6
8
  const state = {
7
9
  isShuttingDown: false,
8
- activeConnections: 0
10
+ activeConnections: 0,
9
11
  };
10
12
  /**
11
- * Enable graceful shutdown for an HTTP server
13
+ * Enable graceful shutdown for an HTTP server.
14
+ *
15
+ * @remarks
16
+ * Registers listeners for the configured signals (and uncaught errors) that
17
+ * trigger an orderly shutdown sequence: invoke the `onShutdown` callback,
18
+ * stop accepting new connections, drain existing connections up to the
19
+ * timeout, invoke the `onClose` callback, and exit the process. New
20
+ * connections received after shutdown starts are immediately destroyed.
21
+ *
22
+ * @param server - The Node.js HTTP server to manage
23
+ * @param config - Optional shutdown configuration
12
24
  *
13
25
  * @example
14
26
  * ```typescript
@@ -70,7 +82,7 @@ async function performShutdown(server, timeout, onShutdown, onClose) {
70
82
  if (onShutdown) {
71
83
  await Promise.race([
72
84
  onShutdown(),
73
- new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown timeout')), timeout))
85
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown timeout')), timeout)),
74
86
  ]);
75
87
  }
76
88
  // Stop accepting new connections
@@ -104,29 +116,75 @@ async function performShutdown(server, timeout, onShutdown, onClose) {
104
116
  }
105
117
  }
106
118
  function sleep(ms) {
107
- return new Promise(resolve => setTimeout(resolve, ms));
119
+ return new Promise((resolve) => setTimeout(resolve, ms));
108
120
  }
109
121
  /**
110
- * Check if server is shutting down
122
+ * Check whether a shutdown sequence is currently in progress.
123
+ *
124
+ * @remarks
125
+ * Returns `true` once a shutdown signal has been received and the shutdown
126
+ * handler has started executing. Useful for guards that need to short-circuit
127
+ * work when the process is going down.
128
+ *
129
+ * @returns `true` if the server is shutting down, `false` otherwise
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * if (isShuttingDown()) {
134
+ * return; // skip expensive work
135
+ * }
136
+ * ```
111
137
  */
112
138
  export function isShuttingDown() {
113
139
  return state.isShuttingDown;
114
140
  }
115
141
  /**
116
- * Get shutdown state
142
+ * Get a snapshot of the current shutdown state.
143
+ *
144
+ * @remarks
145
+ * Returns a shallow copy of the internal {@link ShutdownState}, including
146
+ * whether shutdown is in progress, the active connection count, and the
147
+ * shutdown start time (if applicable).
148
+ *
149
+ * @returns A copy of the current {@link ShutdownState}
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * const state = getShutdownState();
154
+ * console.log(`Connections: ${state.activeConnections}`);
155
+ * ```
117
156
  */
118
157
  export function getShutdownState() {
119
158
  return { ...state };
120
159
  }
121
160
  /**
122
- * Force immediate shutdown (emergency use only)
161
+ * Terminate the process immediately without waiting for connections to drain.
162
+ *
163
+ * @remarks
164
+ * Calls `process.exit()` with the given exit code. Intended only for
165
+ * emergency situations where a graceful shutdown has stalled or a fatal
166
+ * condition prevents orderly teardown.
167
+ *
168
+ * @param exitCode - Process exit code
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * forceShutdown(1);
173
+ * ```
123
174
  */
124
175
  export function forceShutdown(exitCode = 1) {
125
176
  console.log('Force shutting down...');
126
177
  process.exit(exitCode);
127
178
  }
128
179
  /**
129
- * Middleware to reject requests during shutdown
180
+ * Express middleware that rejects requests with 503 while the server is shutting down.
181
+ *
182
+ * @remarks
183
+ * Should be mounted early in the middleware stack so that new requests are
184
+ * immediately rejected once shutdown begins, preventing work from starting
185
+ * that cannot complete before the process exits.
186
+ *
187
+ * @returns An Express-compatible middleware function
130
188
  *
131
189
  * @example
132
190
  * ```typescript
@@ -134,11 +192,11 @@ export function forceShutdown(exitCode = 1) {
134
192
  * ```
135
193
  */
136
194
  export function shutdownMiddleware() {
137
- return (req, res, next) => {
195
+ return (_req, res, next) => {
138
196
  if (state.isShuttingDown) {
139
197
  res.status(503).json({
140
198
  error: 'Service is shutting down',
141
- status: 'unavailable'
199
+ status: 'unavailable',
142
200
  });
143
201
  return;
144
202
  }
@@ -146,7 +204,14 @@ export function shutdownMiddleware() {
146
204
  };
147
205
  }
148
206
  /**
149
- * Wait for shutdown to complete
207
+ * Wait until a shutdown sequence begins.
208
+ *
209
+ * @remarks
210
+ * Polls the internal shutdown state every 100ms and resolves once
211
+ * `isShuttingDown` becomes `true`. Useful for test harnesses or background
212
+ * workers that need to block until the process is going down.
213
+ *
214
+ * @returns A promise that resolves when shutdown has started
150
215
  *
151
216
  * @example
152
217
  * ```typescript
@@ -158,3 +223,4 @@ export async function waitForShutdown() {
158
223
  await sleep(100);
159
224
  }
160
225
  }
226
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shutdown/index.ts"],"names":[],"mappings":"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"}