@outfitter/contracts 0.2.0 → 0.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.
Files changed (40) hide show
  1. package/README.md +41 -2
  2. package/dist/actions.d.ts +4 -3
  3. package/dist/assert/index.d.ts +2 -2
  4. package/dist/assert/index.js +2 -2
  5. package/dist/context.d.ts +4 -3
  6. package/dist/envelope.d.ts +2 -2
  7. package/dist/envelope.js +4 -4
  8. package/dist/errors.d.ts +2 -2
  9. package/dist/errors.js +4 -2
  10. package/dist/handler.d.ts +3 -2
  11. package/dist/index.d.ts +13 -12
  12. package/dist/index.js +36 -30
  13. package/dist/logging.d.ts +2 -0
  14. package/dist/logging.js +7 -0
  15. package/dist/recovery.d.ts +2 -2
  16. package/dist/resilience.d.ts +2 -2
  17. package/dist/resilience.js +2 -2
  18. package/dist/serialization.d.ts +2 -2
  19. package/dist/serialization.js +2 -2
  20. package/dist/shared/@outfitter/{contracts-k2jdpbb6.js → contracts-0snpmkdt.js} +1 -1
  21. package/dist/shared/@outfitter/{contracts-jbhbyhtt.d.ts → contracts-18vcxecr.d.ts} +1 -1
  22. package/dist/shared/@outfitter/{contracts-t68dwjbk.d.ts → contracts-25bkj17f.d.ts} +2 -1
  23. package/dist/shared/@outfitter/contracts-2g8r01zf.d.ts +73 -0
  24. package/dist/shared/@outfitter/{contracts-agvdgx9j.js → contracts-5k6q4n48.js} +41 -9
  25. package/dist/shared/@outfitter/{contracts-n9hb6hqt.d.ts → contracts-6j6z9dsd.d.ts} +1 -1
  26. package/dist/shared/@outfitter/{contracts-r64j5rsm.d.ts → contracts-bdwg55c5.d.ts} +1 -1
  27. package/dist/shared/@outfitter/{contracts-rtsa2s0f.js → contracts-btg89x4h.js} +2 -2
  28. package/dist/shared/@outfitter/{contracts-2f3khqcc.js → contracts-cp5c6dws.js} +1 -1
  29. package/dist/shared/@outfitter/{contracts-md2mvvyt.d.ts → contracts-evxky148.d.ts} +1 -1
  30. package/dist/shared/@outfitter/{contracts-6atxbfag.d.ts → contracts-j08e95jw.d.ts} +1 -1
  31. package/dist/shared/@outfitter/{contracts-k0rhaye3.d.ts → contracts-jggbn5tn.d.ts} +1 -1
  32. package/dist/shared/@outfitter/{contracts-0cj49e1a.js → contracts-phjhz5q3.js} +26 -1
  33. package/dist/shared/@outfitter/{contracts-pdk7s4t8.js → contracts-r21yet6j.js} +1 -1
  34. package/dist/shared/@outfitter/{contracts-5hr9pdcq.d.ts → contracts-r35bn9p6.d.ts} +62 -3
  35. package/dist/shared/@outfitter/{contracts-zyanj0gf.d.ts → contracts-sf1z80yc.d.ts} +2 -2
  36. package/dist/shared/@outfitter/contracts-sm6vak1a.js +14 -0
  37. package/dist/shared/@outfitter/{contracts-amd2ykn8.d.ts → contracts-ss9vjjft.d.ts} +3 -43
  38. package/dist/validation.d.ts +2 -2
  39. package/dist/validation.js +2 -2
  40. package/package.json +50 -44
package/README.md CHANGED
@@ -4,7 +4,7 @@ Result/Error patterns, error taxonomy, handler contracts, and shared interfaces
4
4
 
5
5
  ## Status
6
6
 
7
- **Scaffold** - Types and interfaces defined, implementations pending.
7
+ **Active** - Stable core contracts with active feature development.
8
8
 
9
9
  ## Installation
10
10
 
@@ -36,7 +36,7 @@ import {
36
36
  // Define a handler
37
37
  const getNote: Handler<{ id: string }, Note, NotFoundError> = async (input, ctx) => {
38
38
  const note = await db.notes.find(input.id);
39
- if (!note) return Result.err(new NotFoundError("note", input.id));
39
+ if (!note) return Result.err(NotFoundError.create("note", input.id));
40
40
  return Result.ok(note);
41
41
  };
42
42
 
@@ -45,6 +45,45 @@ const ctx = createContext({ logger, config });
45
45
  const result = await getNote({ id: "abc123" }, ctx);
46
46
  ```
47
47
 
48
+ ## Error Factory Reference
49
+
50
+ All error classes provide a static `create()` factory method that generates a consistent message from structured parameters. Use `create()` for structured errors and the constructor for custom messages.
51
+
52
+ | Error Class | `create()` Signature | Generated Message |
53
+ |---|---|---|
54
+ | `ValidationError` | `create(field, reason, context?)` | `"email: format invalid"` |
55
+ | `ValidationError` | `fromMessage(message, context?)` | *(your message as-is)* |
56
+ | `AmbiguousError` | `create(what, candidates, context?)` | `"Ambiguous heading: 2 matches found"` |
57
+ | `NotFoundError` | `create(resourceType, resourceId, context?)` | `"note not found: abc123"` |
58
+ | `AlreadyExistsError` | `create(resourceType, resourceId, context?)` | `"file already exists: notes/meeting.md"` |
59
+ | `ConflictError` | `create(message, context?)` | *(your message as-is)* |
60
+ | `PermissionError` | `create(message, context?)` | *(your message as-is)* |
61
+ | `TimeoutError` | `create(operation, timeoutMs)` | `"database query timed out after 5000ms"` |
62
+ | `RateLimitError` | `create(message, retryAfterSeconds?)` | *(your message as-is)* |
63
+ | `NetworkError` | `create(message, context?)` | *(your message as-is)* |
64
+ | `InternalError` | `create(message, context?)` | *(your message as-is)* |
65
+ | `AuthError` | `create(message, reason?)` | *(your message as-is)* |
66
+ | `CancelledError` | `create(message)` | *(your message as-is)* |
67
+
68
+ ### Message Casing
69
+
70
+ `create()` factories that auto-generate messages use **lowercase** `resourceType`:
71
+
72
+ ```typescript
73
+ NotFoundError.create("piece", "abc123");
74
+ // → "piece not found: abc123" (not "Piece not found: abc123")
75
+ ```
76
+
77
+ If you need a capitalized message, use the constructor directly:
78
+
79
+ ```typescript
80
+ new NotFoundError({
81
+ message: "Piece not found: abc123",
82
+ resourceType: "piece",
83
+ resourceId: "abc123",
84
+ });
85
+ ```
86
+
48
87
  ## License
49
88
 
50
89
  MIT
package/dist/actions.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-zyanj0gf";
2
- import "./shared/@outfitter/contracts-amd2ykn8";
3
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-sf1z80yc";
2
+ import "./shared/@outfitter/contracts-ss9vjjft";
3
+ import "./shared/@outfitter/contracts-r35bn9p6";
4
+ import "./shared/@outfitter/contracts-2g8r01zf";
4
5
  export { defineAction, createActionRegistry, HttpMethod, DEFAULT_REGISTRY_SURFACES, AnyActionSpec, ActionTrpcSpec, ActionSurface, ActionSpec, ActionRegistry, ActionMcpSpec, ActionCliSpec, ActionCliOption, ActionCliInputContext, ActionApiSpec, ACTION_SURFACES };
@@ -1,3 +1,3 @@
1
- import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "../shared/@outfitter/contracts-jbhbyhtt";
2
- import "../shared/@outfitter/contracts-5hr9pdcq";
1
+ import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "../shared/@outfitter/contracts-18vcxecr";
2
+ import "../shared/@outfitter/contracts-r35bn9p6";
3
3
  export { isNonEmptyArray, assertNonEmpty, assertMatches, assertDefined, NonEmptyArray };
@@ -4,8 +4,8 @@ import {
4
4
  assertMatches,
5
5
  assertNonEmpty,
6
6
  isNonEmptyArray
7
- } from "../shared/@outfitter/contracts-2f3khqcc.js";
8
- import"../shared/@outfitter/contracts-0cj49e1a.js";
7
+ } from "../shared/@outfitter/contracts-cp5c6dws.js";
8
+ import"../shared/@outfitter/contracts-phjhz5q3.js";
9
9
  export {
10
10
  isNonEmptyArray,
11
11
  assertNonEmpty,
package/dist/context.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { CreateContextOptions, createContext, generateRequestId } from "./shared/@outfitter/contracts-t68dwjbk";
2
- import "./shared/@outfitter/contracts-amd2ykn8";
3
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { CreateContextOptions, createContext, generateRequestId } from "./shared/@outfitter/contracts-25bkj17f";
2
+ import "./shared/@outfitter/contracts-ss9vjjft";
3
+ import "./shared/@outfitter/contracts-r35bn9p6";
4
+ import "./shared/@outfitter/contracts-2g8r01zf";
4
5
  export { generateRequestId, createContext, CreateContextOptions };
@@ -1,3 +1,3 @@
1
- import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-k0rhaye3";
2
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-jggbn5tn";
2
+ import "./shared/@outfitter/contracts-r35bn9p6";
3
3
  export { toHttpResponse, toEnvelope, SuccessEnvelope, PaginationMeta, HttpResponse, ErrorEnvelope, EnvelopeMeta, Envelope };
package/dist/envelope.js CHANGED
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  toEnvelope,
4
4
  toHttpResponse
5
- } from "./shared/@outfitter/contracts-rtsa2s0f.js";
6
- import"./shared/@outfitter/contracts-agvdgx9j.js";
7
- import"./shared/@outfitter/contracts-s15x2rs4.js";
5
+ } from "./shared/@outfitter/contracts-btg89x4h.js";
6
+ import"./shared/@outfitter/contracts-5k6q4n48.js";
8
7
  import"./shared/@outfitter/contracts-agmt8915.js";
9
- import"./shared/@outfitter/contracts-0cj49e1a.js";
8
+ import"./shared/@outfitter/contracts-phjhz5q3.js";
9
+ import"./shared/@outfitter/contracts-s15x2rs4.js";
10
10
  export {
11
11
  toHttpResponse,
12
12
  toEnvelope
package/dist/errors.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { AmbiguousError, AnyKitError, AssertionError, AuthError, CancelledError, ConflictError, ERROR_CODES, ErrorCategory, ErrorCode, InternalError, KitErrorProps, NetworkError, NotFoundError, OutfitterError, PermissionError, RateLimitError, SerializedError, TimeoutError, ValidationError, exitCodeMap, getExitCode, getStatusCode, statusCodeMap } from "./shared/@outfitter/contracts-5hr9pdcq";
2
- export { statusCodeMap, getStatusCode, getExitCode, exitCodeMap, ValidationError, TimeoutError, SerializedError, RateLimitError, PermissionError, OutfitterError, NotFoundError, NetworkError, KitErrorProps, InternalError, ErrorCode, ErrorCategory, ERROR_CODES, ConflictError, CancelledError, AuthError, AssertionError, AnyKitError, AmbiguousError };
1
+ import { AlreadyExistsError, AmbiguousError, AnyKitError, AssertionError, AuthError, CancelledError, ConflictError, ERROR_CODES, ErrorCategory, ErrorCode, InternalError, KitErrorProps, NetworkError, NotFoundError, OutfitterError, PermissionError, RateLimitError, SerializedError, TimeoutError, ValidationError, exitCodeMap, getExitCode, getStatusCode, statusCodeMap } from "./shared/@outfitter/contracts-r35bn9p6";
2
+ export { statusCodeMap, getStatusCode, getExitCode, exitCodeMap, ValidationError, TimeoutError, SerializedError, RateLimitError, PermissionError, OutfitterError, NotFoundError, NetworkError, KitErrorProps, InternalError, ErrorCode, ErrorCategory, ERROR_CODES, ConflictError, CancelledError, AuthError, AssertionError, AnyKitError, AmbiguousError, AlreadyExistsError };
package/dist/errors.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // @bun
2
2
  import {
3
+ AlreadyExistsError,
3
4
  AmbiguousError,
4
5
  AssertionError,
5
6
  AuthError,
@@ -17,7 +18,7 @@ import {
17
18
  getExitCode,
18
19
  getStatusCode,
19
20
  statusCodeMap
20
- } from "./shared/@outfitter/contracts-0cj49e1a.js";
21
+ } from "./shared/@outfitter/contracts-phjhz5q3.js";
21
22
  export {
22
23
  statusCodeMap,
23
24
  getStatusCode,
@@ -35,5 +36,6 @@ export {
35
36
  CancelledError,
36
37
  AuthError,
37
38
  AssertionError,
38
- AmbiguousError
39
+ AmbiguousError,
40
+ AlreadyExistsError
39
41
  };
package/dist/handler.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- import { Handler, HandlerContext, Logger, ResolvedConfig, SyncHandler } from "./shared/@outfitter/contracts-amd2ykn8";
2
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { Handler, HandlerContext, ResolvedConfig, SyncHandler } from "./shared/@outfitter/contracts-ss9vjjft";
2
+ import "./shared/@outfitter/contracts-r35bn9p6";
3
+ import { Logger } from "./shared/@outfitter/contracts-2g8r01zf";
3
4
  export { SyncHandler, ResolvedConfig, Logger, HandlerContext, Handler };
package/dist/index.d.ts CHANGED
@@ -1,18 +1,19 @@
1
+ import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-sf1z80yc";
1
2
  import { ACTION_CAPABILITIES, ActionCapability, CAPABILITY_SURFACES, CapabilitySurface, DEFAULT_ACTION_SURFACES, capability, capabilityAll, getActionsForSurface } from "./shared/@outfitter/contracts-bb4hjt8g";
2
- import { DEFAULT_PATTERNS, DEFAULT_SENSITIVE_KEYS, RedactionCallback, RedactionEvent, Redactor, RedactorConfig, createRedactor } from "./shared/@outfitter/contracts-e70qdasg";
3
- import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-md2mvvyt";
4
- import { ACTION_SURFACES, ActionApiSpec, ActionCliInputContext, ActionCliOption, ActionCliSpec, ActionMcpSpec, ActionRegistry, ActionSpec, ActionSurface, ActionTrpcSpec, AnyActionSpec, DEFAULT_REGISTRY_SURFACES, HttpMethod, createActionRegistry, defineAction } from "./shared/@outfitter/contracts-zyanj0gf";
5
- import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-r64j5rsm";
3
+ import { SerializeErrorOptions, deserializeError, safeParse, safeStringify, serializeError } from "./shared/@outfitter/contracts-j08e95jw";
4
+ import { CreateContextOptions, createContext, generateRequestId } from "./shared/@outfitter/contracts-25bkj17f";
5
+ import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "./shared/@outfitter/contracts-18vcxecr";
6
6
  import "./shared/@outfitter/contracts-qaccq0gf";
7
7
  import { combine2, combine3, expect, orElse, unwrapOrElse } from "./shared/@outfitter/contracts-ar0etwtx";
8
- import { NonEmptyArray, assertDefined, assertMatches, assertNonEmpty, isNonEmptyArray } from "./shared/@outfitter/contracts-jbhbyhtt";
8
+ import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-jggbn5tn";
9
9
  import { AdapterAuthError, AuthAdapter, CacheAdapter, CacheError, IndexAdapter, IndexError, IndexStats, SearchOptions, SearchResult, StorageAdapter, StorageError } from "./shared/@outfitter/contracts-93dx53mt";
10
- import { Envelope, EnvelopeMeta, ErrorEnvelope, HttpResponse, PaginationMeta, SuccessEnvelope, toEnvelope, toHttpResponse } from "./shared/@outfitter/contracts-k0rhaye3";
11
- import { SerializeErrorOptions, deserializeError, safeParse, safeStringify, serializeError } from "./shared/@outfitter/contracts-6atxbfag";
12
- import { CreateContextOptions, createContext, generateRequestId } from "./shared/@outfitter/contracts-t68dwjbk";
13
- import { Handler, HandlerContext, Logger, ResolvedConfig, SyncHandler } from "./shared/@outfitter/contracts-amd2ykn8";
14
- import { createValidator, validateInput } from "./shared/@outfitter/contracts-n9hb6hqt";
15
- import { AmbiguousError, AnyKitError, AssertionError, AuthError, CancelledError, ConflictError, ERROR_CODES, ErrorCategory, ErrorCode, InternalError, KitErrorProps, NetworkError, NotFoundError, OutfitterError, PermissionError, RateLimitError, SerializedError, TimeoutError, ValidationError, exitCodeMap, getExitCode, getStatusCode, statusCodeMap } from "./shared/@outfitter/contracts-5hr9pdcq";
10
+ import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-evxky148";
11
+ import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-bdwg55c5";
12
+ import { createValidator, validateInput } from "./shared/@outfitter/contracts-6j6z9dsd";
13
+ import { Handler, HandlerContext, ResolvedConfig, SyncHandler } from "./shared/@outfitter/contracts-ss9vjjft";
14
+ import { AlreadyExistsError, AmbiguousError, AnyKitError, AssertionError, AuthError, CancelledError, ConflictError, ERROR_CODES, ErrorCategory, ErrorCode, InternalError, KitErrorProps, NetworkError, NotFoundError, OutfitterError, PermissionError, RateLimitError, SerializedError, TimeoutError, ValidationError, exitCodeMap, getExitCode, getStatusCode, statusCodeMap } from "./shared/@outfitter/contracts-r35bn9p6";
15
+ import { LogLevel, LogMetadata, LogMethod, Logger, LoggerAdapter, LoggerFactory, LoggerFactoryConfig, createLoggerFactory } from "./shared/@outfitter/contracts-2g8r01zf";
16
+ import { DEFAULT_PATTERNS, DEFAULT_SENSITIVE_KEYS, RedactionCallback, RedactionEvent, Redactor, RedactorConfig, createRedactor } from "./shared/@outfitter/contracts-e70qdasg";
16
17
  import { TaggedErrorClass } from "better-result";
17
18
  import { Result, TaggedError } from "better-result";
18
- export { withTimeout, validateInput, unwrapOrElse, toHttpResponse, toEnvelope, statusCodeMap, shouldRetry, serializeError, safeStringify, safeParse, retry, orElse, isRetryable, isRecoverable, isNonEmptyArray, getStatusCode, getExitCode, getBackoffDelay, getActionsForSurface, generateRequestId, expect, exitCodeMap, deserializeError, defineAction, createValidator, createRedactor, createContext, createActionRegistry, combine3, combine2, capabilityAll, capability, assertNonEmpty, assertMatches, assertDefined, ValidationError, TimeoutOptions, TimeoutError, TaggedErrorClass, TaggedError, SyncHandler, SuccessEnvelope, StorageError, StorageAdapter, SerializedError, SerializeErrorOptions, SearchResult, SearchOptions, RetryOptions, Result, ResolvedConfig, RedactorConfig, Redactor, RedactionEvent, RedactionCallback, RateLimitError, PermissionError, PaginationMeta, OutfitterError, NotFoundError, NonEmptyArray, NetworkError, Logger, KitErrorProps, InternalError, IndexStats, IndexError, IndexAdapter, HttpResponse, HttpMethod, HandlerContext, Handler, ErrorEnvelope, ErrorCode, ErrorCategory, EnvelopeMeta, Envelope, ERROR_CODES, DEFAULT_SENSITIVE_KEYS, DEFAULT_REGISTRY_SURFACES, DEFAULT_PATTERNS, DEFAULT_ACTION_SURFACES, CreateContextOptions, ConflictError, CapabilitySurface, CancelledError, CacheError, CacheAdapter, CAPABILITY_SURFACES, BackoffOptions, AuthError, AuthAdapter, AssertionError, AnyKitError, AnyActionSpec, AmbiguousError, AdapterAuthError, ActionTrpcSpec, ActionSurface, ActionSpec, ActionRegistry, ActionMcpSpec, ActionCliSpec, ActionCliOption, ActionCliInputContext, ActionCapability, ActionApiSpec, ACTION_SURFACES, ACTION_CAPABILITIES };
19
+ export { withTimeout, validateInput, unwrapOrElse, toHttpResponse, toEnvelope, statusCodeMap, shouldRetry, serializeError, safeStringify, safeParse, retry, orElse, isRetryable, isRecoverable, isNonEmptyArray, getStatusCode, getExitCode, getBackoffDelay, getActionsForSurface, generateRequestId, expect, exitCodeMap, deserializeError, defineAction, createValidator, createRedactor, createLoggerFactory, createContext, createActionRegistry, combine3, combine2, capabilityAll, capability, assertNonEmpty, assertMatches, assertDefined, ValidationError, TimeoutOptions, TimeoutError, TaggedErrorClass, TaggedError, SyncHandler, SuccessEnvelope, StorageError, StorageAdapter, SerializedError, SerializeErrorOptions, SearchResult, SearchOptions, RetryOptions, Result, ResolvedConfig, RedactorConfig, Redactor, RedactionEvent, RedactionCallback, RateLimitError, PermissionError, PaginationMeta, OutfitterError, NotFoundError, NonEmptyArray, NetworkError, LoggerFactoryConfig, LoggerFactory, LoggerAdapter, Logger, LogMethod, LogMetadata, LogLevel, KitErrorProps, InternalError, IndexStats, IndexError, IndexAdapter, HttpResponse, HttpMethod, HandlerContext, Handler, ErrorEnvelope, ErrorCode, ErrorCategory, EnvelopeMeta, Envelope, ERROR_CODES, DEFAULT_SENSITIVE_KEYS, DEFAULT_REGISTRY_SURFACES, DEFAULT_PATTERNS, DEFAULT_ACTION_SURFACES, CreateContextOptions, ConflictError, CapabilitySurface, CancelledError, CacheError, CacheAdapter, CAPABILITY_SURFACES, BackoffOptions, AuthError, AuthAdapter, AssertionError, AnyKitError, AnyActionSpec, AmbiguousError, AlreadyExistsError, AdapterAuthError, ActionTrpcSpec, ActionSurface, ActionSpec, ActionRegistry, ActionMcpSpec, ActionCliSpec, ActionCliOption, ActionCliInputContext, ActionCapability, ActionApiSpec, ACTION_SURFACES, ACTION_CAPABILITIES };
package/dist/index.js CHANGED
@@ -1,4 +1,10 @@
1
1
  // @bun
2
+ import {
3
+ ACTION_SURFACES,
4
+ DEFAULT_REGISTRY_SURFACES,
5
+ createActionRegistry,
6
+ defineAction
7
+ } from "./shared/@outfitter/contracts-q0v44kef.js";
2
8
  import {
3
9
  ACTION_CAPABILITIES,
4
10
  CAPABILITY_SURFACES,
@@ -8,21 +14,11 @@ import {
8
14
  getActionsForSurface
9
15
  } from "./shared/@outfitter/contracts-d0tq2adf.js";
10
16
  import {
11
- getBackoffDelay,
12
- isRecoverable,
13
- isRetryable,
14
- shouldRetry
15
- } from "./shared/@outfitter/contracts-4zaj7ejb.js";
16
- import {
17
- ACTION_SURFACES,
18
- DEFAULT_REGISTRY_SURFACES,
19
- createActionRegistry,
20
- defineAction
21
- } from "./shared/@outfitter/contracts-q0v44kef.js";
22
- import {
23
- retry,
24
- withTimeout
25
- } from "./shared/@outfitter/contracts-pdk7s4t8.js";
17
+ assertDefined,
18
+ assertMatches,
19
+ assertNonEmpty,
20
+ isNonEmptyArray
21
+ } from "./shared/@outfitter/contracts-cp5c6dws.js";
26
22
  import"./shared/@outfitter/contracts-37gpc56f.js";
27
23
  import {
28
24
  combine2,
@@ -31,36 +27,36 @@ import {
31
27
  orElse,
32
28
  unwrapOrElse
33
29
  } from "./shared/@outfitter/contracts-zx72gyh1.js";
34
- import {
35
- assertDefined,
36
- assertMatches,
37
- assertNonEmpty,
38
- isNonEmptyArray
39
- } from "./shared/@outfitter/contracts-2f3khqcc.js";
40
30
  import {
41
31
  toEnvelope,
42
32
  toHttpResponse
43
- } from "./shared/@outfitter/contracts-rtsa2s0f.js";
33
+ } from "./shared/@outfitter/contracts-btg89x4h.js";
44
34
  import {
45
35
  deserializeError,
46
36
  safeParse,
47
37
  safeStringify,
48
38
  serializeError
49
- } from "./shared/@outfitter/contracts-agvdgx9j.js";
50
- import {
51
- DEFAULT_PATTERNS,
52
- DEFAULT_SENSITIVE_KEYS,
53
- createRedactor
54
- } from "./shared/@outfitter/contracts-s15x2rs4.js";
39
+ } from "./shared/@outfitter/contracts-5k6q4n48.js";
55
40
  import {
56
41
  createContext,
57
42
  generateRequestId
58
43
  } from "./shared/@outfitter/contracts-agmt8915.js";
44
+ import {
45
+ getBackoffDelay,
46
+ isRecoverable,
47
+ isRetryable,
48
+ shouldRetry
49
+ } from "./shared/@outfitter/contracts-4zaj7ejb.js";
50
+ import {
51
+ retry,
52
+ withTimeout
53
+ } from "./shared/@outfitter/contracts-r21yet6j.js";
59
54
  import {
60
55
  createValidator,
61
56
  validateInput
62
- } from "./shared/@outfitter/contracts-k2jdpbb6.js";
57
+ } from "./shared/@outfitter/contracts-0snpmkdt.js";
63
58
  import {
59
+ AlreadyExistsError,
64
60
  AmbiguousError,
65
61
  AssertionError,
66
62
  AuthError,
@@ -78,7 +74,15 @@ import {
78
74
  getExitCode,
79
75
  getStatusCode,
80
76
  statusCodeMap
81
- } from "./shared/@outfitter/contracts-0cj49e1a.js";
77
+ } from "./shared/@outfitter/contracts-phjhz5q3.js";
78
+ import {
79
+ createLoggerFactory
80
+ } from "./shared/@outfitter/contracts-sm6vak1a.js";
81
+ import {
82
+ DEFAULT_PATTERNS,
83
+ DEFAULT_SENSITIVE_KEYS,
84
+ createRedactor
85
+ } from "./shared/@outfitter/contracts-s15x2rs4.js";
82
86
 
83
87
  // packages/contracts/src/index.ts
84
88
  import { Result, TaggedError } from "better-result";
@@ -109,6 +113,7 @@ export {
109
113
  defineAction,
110
114
  createValidator,
111
115
  createRedactor,
116
+ createLoggerFactory,
112
117
  createContext,
113
118
  createActionRegistry,
114
119
  combine3,
@@ -138,6 +143,7 @@ export {
138
143
  AuthError,
139
144
  AssertionError,
140
145
  AmbiguousError,
146
+ AlreadyExistsError,
141
147
  ACTION_SURFACES,
142
148
  ACTION_CAPABILITIES
143
149
  };
@@ -0,0 +1,2 @@
1
+ import { LogLevel, LogMetadata, LogMethod, Logger, LoggerAdapter, LoggerFactory, LoggerFactoryConfig, createLoggerFactory } from "./shared/@outfitter/contracts-2g8r01zf";
2
+ export { createLoggerFactory, LoggerFactoryConfig, LoggerFactory, LoggerAdapter, Logger, LogMethod, LogMetadata, LogLevel };
@@ -0,0 +1,7 @@
1
+ // @bun
2
+ import {
3
+ createLoggerFactory
4
+ } from "./shared/@outfitter/contracts-sm6vak1a.js";
5
+ export {
6
+ createLoggerFactory
7
+ };
@@ -1,3 +1,3 @@
1
- import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-md2mvvyt";
2
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { BackoffOptions, getBackoffDelay, isRecoverable, isRetryable, shouldRetry } from "./shared/@outfitter/contracts-evxky148";
2
+ import "./shared/@outfitter/contracts-r35bn9p6";
3
3
  export { shouldRetry, isRetryable, isRecoverable, getBackoffDelay, BackoffOptions };
@@ -1,3 +1,3 @@
1
- import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-r64j5rsm";
2
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { RetryOptions, TimeoutOptions, retry, withTimeout } from "./shared/@outfitter/contracts-bdwg55c5";
2
+ import "./shared/@outfitter/contracts-r35bn9p6";
3
3
  export { withTimeout, retry, TimeoutOptions, RetryOptions };
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  retry,
4
4
  withTimeout
5
- } from "./shared/@outfitter/contracts-pdk7s4t8.js";
6
- import"./shared/@outfitter/contracts-0cj49e1a.js";
5
+ } from "./shared/@outfitter/contracts-r21yet6j.js";
6
+ import"./shared/@outfitter/contracts-phjhz5q3.js";
7
7
  export {
8
8
  withTimeout,
9
9
  retry
@@ -1,3 +1,3 @@
1
- import { SerializeErrorOptions, deserializeError, safeParse, safeStringify, serializeError } from "./shared/@outfitter/contracts-6atxbfag";
2
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { SerializeErrorOptions, deserializeError, safeParse, safeStringify, serializeError } from "./shared/@outfitter/contracts-j08e95jw";
2
+ import "./shared/@outfitter/contracts-r35bn9p6";
3
3
  export { serializeError, safeStringify, safeParse, deserializeError, SerializeErrorOptions };
@@ -4,9 +4,9 @@ import {
4
4
  safeParse,
5
5
  safeStringify,
6
6
  serializeError
7
- } from "./shared/@outfitter/contracts-agvdgx9j.js";
7
+ } from "./shared/@outfitter/contracts-5k6q4n48.js";
8
+ import"./shared/@outfitter/contracts-phjhz5q3.js";
8
9
  import"./shared/@outfitter/contracts-s15x2rs4.js";
9
- import"./shared/@outfitter/contracts-0cj49e1a.js";
10
10
  export {
11
11
  serializeError,
12
12
  safeStringify,
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  ValidationError
4
- } from "./contracts-0cj49e1a.js";
4
+ } from "./contracts-phjhz5q3.js";
5
5
 
6
6
  // packages/contracts/src/validation.ts
7
7
  import { Result } from "better-result";
@@ -1,4 +1,4 @@
1
- import { AssertionError } from "./contracts-5hr9pdcq";
1
+ import { AssertionError } from "./contracts-r35bn9p6";
2
2
  import { Result } from "better-result";
3
3
  /**
4
4
  * Array type guaranteed to have at least one element.
@@ -1,4 +1,5 @@
1
- import { HandlerContext, Logger, ResolvedConfig } from "./contracts-amd2ykn8";
1
+ import { HandlerContext, ResolvedConfig } from "./contracts-ss9vjjft";
2
+ import { Logger } from "./contracts-2g8r01zf";
2
3
  /**
3
4
  * Options for creating a handler context.
4
5
  */
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Shared logging contracts for backend-agnostic logger integration.
3
+ *
4
+ * The `Logger` interface is the minimal surface required by handler contexts.
5
+ * `LoggerAdapter` and `createLoggerFactory` allow runtime packages to plug in
6
+ * backend-specific implementations while keeping transports backend-agnostic.
7
+ */
8
+ /**
9
+ * Log levels ordered from least to most severe.
10
+ *
11
+ * The special `silent` level disables logging output.
12
+ */
13
+ type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "silent";
14
+ /** Structured metadata attached to log messages. */
15
+ type LogMetadata = Record<string, unknown>;
16
+ /**
17
+ * Message-first logger method with metadata-first overload for strict misuse
18
+ * detection in TypeScript. Calling with metadata first intentionally resolves to
19
+ * `never` for compile-time feedback.
20
+ */
21
+ interface LogMethod {
22
+ (message: string, metadata?: LogMetadata): void;
23
+ (metadata: LogMetadata, message: string): never;
24
+ }
25
+ /**
26
+ * Logger interface for handler contexts and cross-package contracts.
27
+ */
28
+ interface Logger {
29
+ trace: LogMethod;
30
+ debug: LogMethod;
31
+ info: LogMethod;
32
+ warn: LogMethod;
33
+ error: LogMethod;
34
+ fatal: LogMethod;
35
+ child(context: LogMetadata): Logger;
36
+ }
37
+ /**
38
+ * Configuration passed through the logger factory to backend adapters.
39
+ *
40
+ * `backend` carries adapter-specific configuration in a strongly typed way.
41
+ */
42
+ interface LoggerFactoryConfig<TBackendOptions = unknown> {
43
+ /** Logger category/name identifying the source (e.g., "cli", "mcp") */
44
+ name: string;
45
+ /** Minimum level to emit */
46
+ level?: LogLevel;
47
+ /** Static context attached to every emitted record */
48
+ context?: LogMetadata;
49
+ /** Adapter-specific backend options */
50
+ backend?: TBackendOptions;
51
+ }
52
+ /**
53
+ * Backend adapter contract used by the logger factory.
54
+ *
55
+ * Runtime packages provide concrete adapters (for example logtape or custom
56
+ * implementations) behind this contract.
57
+ */
58
+ interface LoggerAdapter<TBackendOptions = unknown> {
59
+ createLogger(config: LoggerFactoryConfig<TBackendOptions>): Logger;
60
+ flush?(): Promise<void>;
61
+ }
62
+ /**
63
+ * Backend-agnostic logger factory surface consumed by CLI/MCP runtime code.
64
+ */
65
+ interface LoggerFactory<TBackendOptions = unknown> {
66
+ createLogger(config: LoggerFactoryConfig<TBackendOptions>): Logger;
67
+ flush(): Promise<void>;
68
+ }
69
+ /**
70
+ * Create a logger factory from a backend adapter implementation.
71
+ */
72
+ declare function createLoggerFactory<TBackendOptions = unknown>(adapter: LoggerAdapter<TBackendOptions>): LoggerFactory<TBackendOptions>;
73
+ export { LogLevel, LogMetadata, LogMethod, Logger, LoggerFactoryConfig, LoggerAdapter, LoggerFactory, createLoggerFactory };
@@ -1,10 +1,6 @@
1
1
  // @bun
2
2
  import {
3
- DEFAULT_PATTERNS,
4
- DEFAULT_SENSITIVE_KEYS,
5
- createRedactor
6
- } from "./contracts-s15x2rs4.js";
7
- import {
3
+ AlreadyExistsError,
8
4
  AmbiguousError,
9
5
  AssertionError,
10
6
  AuthError,
@@ -17,7 +13,12 @@ import {
17
13
  RateLimitError,
18
14
  TimeoutError,
19
15
  ValidationError
20
- } from "./contracts-0cj49e1a.js";
16
+ } from "./contracts-phjhz5q3.js";
17
+ import {
18
+ DEFAULT_PATTERNS,
19
+ DEFAULT_SENSITIVE_KEYS,
20
+ createRedactor
21
+ } from "./contracts-s15x2rs4.js";
21
22
 
22
23
  // packages/contracts/src/serialization.ts
23
24
  import { Result } from "better-result";
@@ -26,6 +27,7 @@ var errorRegistry = {
26
27
  AmbiguousError,
27
28
  AssertionError,
28
29
  NotFoundError,
30
+ AlreadyExistsError,
29
31
  ConflictError,
30
32
  PermissionError,
31
33
  TimeoutError,
@@ -50,10 +52,22 @@ function extractContext(error) {
50
52
  }
51
53
  case "NotFoundError": {
52
54
  const nfe = error;
55
+ if (nfe.context !== undefined) {
56
+ Object.assign(context, nfe.context);
57
+ }
53
58
  context["resourceType"] = nfe.resourceType;
54
59
  context["resourceId"] = nfe.resourceId;
55
60
  break;
56
61
  }
62
+ case "AlreadyExistsError": {
63
+ const aee = error;
64
+ if (aee.context !== undefined) {
65
+ Object.assign(context, aee.context);
66
+ }
67
+ context["resourceType"] = aee.resourceType;
68
+ context["resourceId"] = aee.resourceId;
69
+ break;
70
+ }
57
71
  case "TimeoutError": {
58
72
  const te = error;
59
73
  context["operation"] = te.operation;
@@ -139,12 +153,30 @@ function deserializeError(data) {
139
153
  }
140
154
  return new ValidationError(props);
141
155
  }
142
- case "NotFoundError":
143
- return new NotFoundError({
156
+ case "NotFoundError": {
157
+ const props = {
144
158
  message: data.message,
145
159
  resourceType: context["resourceType"] ?? "unknown",
146
160
  resourceId: context["resourceId"] ?? "unknown"
147
- });
161
+ };
162
+ const contextWithoutIdentity = Object.fromEntries(Object.entries(context).filter(([key]) => key !== "resourceType" && key !== "resourceId"));
163
+ if (Object.keys(contextWithoutIdentity).length > 0) {
164
+ props.context = contextWithoutIdentity;
165
+ }
166
+ return new NotFoundError(props);
167
+ }
168
+ case "AlreadyExistsError": {
169
+ const props = {
170
+ message: data.message,
171
+ resourceType: context["resourceType"] ?? "unknown",
172
+ resourceId: context["resourceId"] ?? "unknown"
173
+ };
174
+ const contextWithoutIdentity = Object.fromEntries(Object.entries(context).filter(([key]) => key !== "resourceType" && key !== "resourceId"));
175
+ if (Object.keys(contextWithoutIdentity).length > 0) {
176
+ props.context = contextWithoutIdentity;
177
+ }
178
+ return new AlreadyExistsError(props);
179
+ }
148
180
  case "ConflictError": {
149
181
  const props = {
150
182
  message: data.message
@@ -1,4 +1,4 @@
1
- import { ValidationError } from "./contracts-5hr9pdcq";
1
+ import { ValidationError } from "./contracts-r35bn9p6";
2
2
  import { Result } from "better-result";
3
3
  import { z } from "zod";
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { OutfitterError, TimeoutError } from "./contracts-5hr9pdcq";
1
+ import { OutfitterError, TimeoutError } from "./contracts-r35bn9p6";
2
2
  import { Result } from "better-result";
3
3
  /**
4
4
  * Options for retry behavior.
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  serializeError
4
- } from "./contracts-agvdgx9j.js";
4
+ } from "./contracts-5k6q4n48.js";
5
5
  import {
6
6
  generateRequestId
7
7
  } from "./contracts-agmt8915.js";
8
8
  import {
9
9
  statusCodeMap
10
- } from "./contracts-0cj49e1a.js";
10
+ } from "./contracts-phjhz5q3.js";
11
11
 
12
12
  // packages/contracts/src/envelope.ts
13
13
  function buildMeta(overrides) {
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  AssertionError
4
- } from "./contracts-0cj49e1a.js";
4
+ } from "./contracts-phjhz5q3.js";
5
5
 
6
6
  // packages/contracts/src/assert/index.ts
7
7
  import { Result } from "better-result";
@@ -1,4 +1,4 @@
1
- import { ErrorCategory } from "./contracts-5hr9pdcq";
1
+ import { ErrorCategory } from "./contracts-r35bn9p6";
2
2
  /**
3
3
  * Backoff strategy configuration options
4
4
  */
@@ -1,4 +1,4 @@
1
- import { OutfitterError, SerializedError, ValidationError } from "./contracts-5hr9pdcq";
1
+ import { OutfitterError, SerializedError, ValidationError } from "./contracts-r35bn9p6";
2
2
  import { Result } from "better-result";
3
3
  import { z } from "zod";
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { OutfitterError, SerializedError } from "./contracts-5hr9pdcq";
1
+ import { OutfitterError, SerializedError } from "./contracts-r35bn9p6";
2
2
  import { Result } from "better-result";
3
3
  /**
4
4
  * Metadata attached to every response envelope.
@@ -80,6 +80,7 @@ var ValidationErrorBase = TaggedError("ValidationError")();
80
80
  var AmbiguousErrorBase = TaggedError("AmbiguousError")();
81
81
  var AssertionErrorBase = TaggedError("AssertionError")();
82
82
  var NotFoundErrorBase = TaggedError("NotFoundError")();
83
+ var AlreadyExistsErrorBase = TaggedError("AlreadyExistsError")();
83
84
  var ConflictErrorBase = TaggedError("ConflictError")();
84
85
  var PermissionErrorBase = TaggedError("PermissionError")();
85
86
  var TimeoutErrorBase = TaggedError("TimeoutError")();
@@ -98,6 +99,12 @@ class ValidationError extends ValidationErrorBase {
98
99
  ...context != null && { context }
99
100
  });
100
101
  }
102
+ static fromMessage(message, context) {
103
+ return new ValidationError({
104
+ message,
105
+ ...context != null && { context }
106
+ });
107
+ }
101
108
  exitCode() {
102
109
  return getExitCode(this.category);
103
110
  }
@@ -151,6 +158,24 @@ class NotFoundError extends NotFoundErrorBase {
151
158
  }
152
159
  }
153
160
 
161
+ class AlreadyExistsError extends AlreadyExistsErrorBase {
162
+ category = "conflict";
163
+ static create(resourceType, resourceId, context) {
164
+ return new AlreadyExistsError({
165
+ message: `${resourceType} already exists: ${resourceId}`,
166
+ resourceType,
167
+ resourceId,
168
+ ...context != null && { context }
169
+ });
170
+ }
171
+ exitCode() {
172
+ return getExitCode(this.category);
173
+ }
174
+ statusCode() {
175
+ return getStatusCode(this.category);
176
+ }
177
+ }
178
+
154
179
  class ConflictError extends ConflictErrorBase {
155
180
  category = "conflict";
156
181
  static create(message, context) {
@@ -265,4 +290,4 @@ class CancelledError extends CancelledErrorBase {
265
290
  }
266
291
  }
267
292
 
268
- export { exitCodeMap, statusCodeMap, ERROR_CODES, getExitCode, getStatusCode, ValidationError, AmbiguousError, AssertionError, NotFoundError, ConflictError, PermissionError, TimeoutError, RateLimitError, NetworkError, InternalError, AuthError, CancelledError };
293
+ export { exitCodeMap, statusCodeMap, ERROR_CODES, getExitCode, getStatusCode, ValidationError, AmbiguousError, AssertionError, NotFoundError, AlreadyExistsError, ConflictError, PermissionError, TimeoutError, RateLimitError, NetworkError, InternalError, AuthError, CancelledError };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  TimeoutError
4
- } from "./contracts-0cj49e1a.js";
4
+ } from "./contracts-phjhz5q3.js";
5
5
 
6
6
  // packages/contracts/src/resilience.ts
7
7
  import { Result } from "better-result";
@@ -129,6 +129,12 @@ declare const NotFoundErrorBase: TaggedErrorClass<"NotFoundError", {
129
129
  resourceId: string;
130
130
  context?: Record<string, unknown>;
131
131
  }>;
132
+ declare const AlreadyExistsErrorBase: TaggedErrorClass<"AlreadyExistsError", {
133
+ message: string;
134
+ resourceType: string;
135
+ resourceId: string;
136
+ context?: Record<string, unknown>;
137
+ }>;
132
138
  declare const ConflictErrorBase: TaggedErrorClass<"ConflictError", {
133
139
  message: string;
134
140
  context?: Record<string, unknown>;
@@ -178,6 +184,16 @@ declare class ValidationError extends ValidationErrorBase {
178
184
  readonly category: "validation";
179
185
  /** Create a ValidationError with auto-generated message from field name. */
180
186
  static create(field: string, reason: string, context?: Record<string, unknown>): ValidationError;
187
+ /**
188
+ * Create a freeform ValidationError without a specific field.
189
+ *
190
+ * Use when the validation failure applies to the input as a whole
191
+ * rather than a single field (e.g., "Invalid pipeline configuration").
192
+ *
193
+ * @param message - Human-readable validation error message
194
+ * @param context - Optional structured context for debugging
195
+ */
196
+ static fromMessage(message: string, context?: Record<string, unknown>): ValidationError;
181
197
  exitCode(): number;
182
198
  statusCode(): number;
183
199
  }
@@ -256,12 +272,55 @@ declare class NotFoundError extends NotFoundErrorBase {
256
272
  statusCode(): number;
257
273
  }
258
274
  /**
259
- * State conflict (optimistic locking, concurrent modification).
275
+ * Resource already exists the inverse of {@link NotFoundError}.
276
+ *
277
+ * Use when a create/write operation fails because the target resource
278
+ * is already present. Carries `resourceType` and `resourceId` to identify
279
+ * what already exists, mirroring {@link NotFoundError}'s structure.
280
+ *
281
+ * Maps to HTTP 409 (Conflict) and exit code 3.
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * new AlreadyExistsError({
286
+ * message: "File already exists: notes/meeting.md",
287
+ * resourceType: "file",
288
+ * resourceId: "notes/meeting.md",
289
+ * });
290
+ * AlreadyExistsError.create("file", "notes/meeting.md");
291
+ * ```
292
+ *
293
+ * @see ConflictError - For general state conflicts (version mismatch, concurrent modification)
294
+ * @see NotFoundError - The inverse: resource does not exist
295
+ */
296
+ declare class AlreadyExistsError extends AlreadyExistsErrorBase {
297
+ readonly category: "conflict";
298
+ /** Create an AlreadyExistsError with auto-generated message. */
299
+ static create(resourceType: string, resourceId: string, context?: Record<string, unknown>): AlreadyExistsError;
300
+ exitCode(): number;
301
+ statusCode(): number;
302
+ }
303
+ /**
304
+ * State conflict (version mismatch, concurrent modification).
305
+ *
306
+ * Use for general conflicts that don't fit {@link AlreadyExistsError}:
307
+ * optimistic locking failures, concurrent writes, ETag mismatches,
308
+ * or any case where the operation can't proceed due to state divergence.
309
+ *
310
+ * Maps to HTTP 409 (Conflict) and exit code 3.
311
+ *
312
+ * **Choosing the right conflict error:**
313
+ * - Resource already exists? Use {@link AlreadyExistsError}
314
+ * - Version/ETag mismatch? Use {@link ConflictError}
315
+ * - Concurrent modification detected? Use {@link ConflictError}
260
316
  *
261
317
  * @example
262
318
  * ```typescript
263
319
  * new ConflictError({ message: "Resource was modified by another process" });
320
+ * ConflictError.create("ETag mismatch: expected abc, got def");
264
321
  * ```
322
+ *
323
+ * @see AlreadyExistsError - For "resource already exists" specifically
265
324
  */
266
325
  declare class ConflictError extends ConflictErrorBase {
267
326
  readonly category: "conflict";
@@ -378,10 +437,10 @@ declare class CancelledError extends CancelledErrorBase {
378
437
  /**
379
438
  * Union type of all concrete error class instances.
380
439
  */
381
- type AnyKitError = InstanceType<typeof ValidationError> | InstanceType<typeof AmbiguousError> | InstanceType<typeof AssertionError> | InstanceType<typeof NotFoundError> | InstanceType<typeof ConflictError> | InstanceType<typeof PermissionError> | InstanceType<typeof TimeoutError> | InstanceType<typeof RateLimitError> | InstanceType<typeof NetworkError> | InstanceType<typeof InternalError> | InstanceType<typeof AuthError> | InstanceType<typeof CancelledError>;
440
+ type AnyKitError = InstanceType<typeof ValidationError> | InstanceType<typeof AmbiguousError> | InstanceType<typeof AssertionError> | InstanceType<typeof NotFoundError> | InstanceType<typeof AlreadyExistsError> | InstanceType<typeof ConflictError> | InstanceType<typeof PermissionError> | InstanceType<typeof TimeoutError> | InstanceType<typeof RateLimitError> | InstanceType<typeof NetworkError> | InstanceType<typeof InternalError> | InstanceType<typeof AuthError> | InstanceType<typeof CancelledError>;
382
441
  /**
383
442
  * Type alias for backwards compatibility with handler signatures.
384
443
  * Use AnyKitError for the union type.
385
444
  */
386
445
  type OutfitterError = AnyKitError;
387
- export { ErrorCategory, exitCodeMap, statusCodeMap, ERROR_CODES, ErrorCode, SerializedError, KitErrorProps, getExitCode, getStatusCode, ValidationError, AmbiguousError, AssertionError, NotFoundError, ConflictError, PermissionError, TimeoutError, RateLimitError, NetworkError, InternalError, AuthError, CancelledError, AnyKitError, OutfitterError };
446
+ export { ErrorCategory, exitCodeMap, statusCodeMap, ERROR_CODES, ErrorCode, SerializedError, KitErrorProps, getExitCode, getStatusCode, ValidationError, AmbiguousError, AssertionError, NotFoundError, AlreadyExistsError, ConflictError, PermissionError, TimeoutError, RateLimitError, NetworkError, InternalError, AuthError, CancelledError, AnyKitError, OutfitterError };
@@ -1,5 +1,5 @@
1
- import { Handler, SyncHandler } from "./contracts-amd2ykn8";
2
- import { OutfitterError } from "./contracts-5hr9pdcq";
1
+ import { Handler, SyncHandler } from "./contracts-ss9vjjft";
2
+ import { OutfitterError } from "./contracts-r35bn9p6";
3
3
  import { z } from "zod";
4
4
  declare const ACTION_SURFACES: readonly ["cli", "mcp", "api", "server"];
5
5
  type ActionSurface = (typeof ACTION_SURFACES)[number];
@@ -0,0 +1,14 @@
1
+ // @bun
2
+ // packages/contracts/src/logging.ts
3
+ function createLoggerFactory(adapter) {
4
+ return {
5
+ createLogger(config) {
6
+ return adapter.createLogger(config);
7
+ },
8
+ async flush() {
9
+ await adapter.flush?.();
10
+ }
11
+ };
12
+ }
13
+
14
+ export { createLoggerFactory };
@@ -1,47 +1,7 @@
1
- import { OutfitterError } from "./contracts-5hr9pdcq";
1
+ import { OutfitterError } from "./contracts-r35bn9p6";
2
+ import { Logger } from "./contracts-2g8r01zf";
2
3
  import { Result } from "better-result";
3
4
  /**
4
- * Logger interface for handler context.
5
- * Implementations provided by @outfitter/logging.
6
- *
7
- * All log methods accept an optional context object that will be merged
8
- * with any context inherited from parent loggers created via `child()`.
9
- */
10
- interface Logger {
11
- trace(message: string, metadata?: Record<string, unknown>): void;
12
- trace(metadata: Record<string, unknown>, message: string): never;
13
- debug(message: string, metadata?: Record<string, unknown>): void;
14
- debug(metadata: Record<string, unknown>, message: string): never;
15
- info(message: string, metadata?: Record<string, unknown>): void;
16
- info(metadata: Record<string, unknown>, message: string): never;
17
- warn(message: string, metadata?: Record<string, unknown>): void;
18
- warn(metadata: Record<string, unknown>, message: string): never;
19
- error(message: string, metadata?: Record<string, unknown>): void;
20
- error(metadata: Record<string, unknown>, message: string): never;
21
- fatal(message: string, metadata?: Record<string, unknown>): void;
22
- fatal(metadata: Record<string, unknown>, message: string): never;
23
- /**
24
- * Creates a child logger with additional context.
25
- *
26
- * Context from the child is merged with the parent's context,
27
- * with child context taking precedence for duplicate keys.
28
- * Child loggers are composable (can create nested children).
29
- *
30
- * @param context - Additional context to include in all log messages
31
- * @returns A new Logger instance with the merged context
32
- *
33
- * @example
34
- * ```typescript
35
- * const requestLogger = ctx.logger.child({ requestId: ctx.requestId });
36
- * requestLogger.info("Processing request"); // includes requestId
37
- *
38
- * const opLogger = requestLogger.child({ operation: "create" });
39
- * opLogger.debug("Starting"); // includes requestId + operation
40
- * ```
41
- */
42
- child(context: Record<string, unknown>): Logger;
43
- }
44
- /**
45
5
  * Resolved configuration interface.
46
6
  * Implementations provided by @outfitter/config.
47
7
  */
@@ -108,4 +68,4 @@ type SyncHandler<
108
68
  TOutput,
109
69
  TError extends OutfitterError = OutfitterError
110
70
  > = (input: TInput, ctx: HandlerContext) => Result<TOutput, TError>;
111
- export { Logger, ResolvedConfig, HandlerContext, Handler, SyncHandler };
71
+ export { ResolvedConfig, HandlerContext, Handler, SyncHandler };
@@ -1,3 +1,3 @@
1
- import { createValidator, validateInput } from "./shared/@outfitter/contracts-n9hb6hqt";
2
- import "./shared/@outfitter/contracts-5hr9pdcq";
1
+ import { createValidator, validateInput } from "./shared/@outfitter/contracts-6j6z9dsd";
2
+ import "./shared/@outfitter/contracts-r35bn9p6";
3
3
  export { validateInput, createValidator };
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  createValidator,
4
4
  validateInput
5
- } from "./shared/@outfitter/contracts-k2jdpbb6.js";
6
- import"./shared/@outfitter/contracts-0cj49e1a.js";
5
+ } from "./shared/@outfitter/contracts-0snpmkdt.js";
6
+ import"./shared/@outfitter/contracts-phjhz5q3.js";
7
7
  export {
8
8
  validateInput,
9
9
  createValidator
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@outfitter/contracts",
3
3
  "description": "Result/Error patterns, error taxonomy, and handler contracts for Outfitter",
4
- "version": "0.2.0",
4
+ "version": "0.3.0",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"
@@ -9,12 +9,6 @@
9
9
  "module": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
11
11
  "exports": {
12
- "./validation": {
13
- "import": {
14
- "types": "./dist/validation.d.ts",
15
- "default": "./dist/validation.js"
16
- }
17
- },
18
12
  ".": {
19
13
  "import": {
20
14
  "types": "./dist/index.d.ts",
@@ -27,16 +21,10 @@
27
21
  "default": "./dist/actions.js"
28
22
  }
29
23
  },
30
- "./handler": {
31
- "import": {
32
- "types": "./dist/handler.d.ts",
33
- "default": "./dist/handler.js"
34
- }
35
- },
36
- "./recovery": {
24
+ "./adapters": {
37
25
  "import": {
38
- "types": "./dist/recovery.d.ts",
39
- "default": "./dist/recovery.js"
26
+ "types": "./dist/adapters.d.ts",
27
+ "default": "./dist/adapters.js"
40
28
  }
41
29
  },
42
30
  "./assert": {
@@ -45,22 +33,16 @@
45
33
  "default": "./dist/assert/index.js"
46
34
  }
47
35
  },
48
- "./result": {
49
- "import": {
50
- "types": "./dist/result/index.d.ts",
51
- "default": "./dist/result/index.js"
52
- }
53
- },
54
- "./result/utilities": {
36
+ "./capabilities": {
55
37
  "import": {
56
- "types": "./dist/result/utilities.d.ts",
57
- "default": "./dist/result/utilities.js"
38
+ "types": "./dist/capabilities.d.ts",
39
+ "default": "./dist/capabilities.js"
58
40
  }
59
41
  },
60
- "./adapters": {
42
+ "./context": {
61
43
  "import": {
62
- "types": "./dist/adapters.d.ts",
63
- "default": "./dist/adapters.js"
44
+ "types": "./dist/context.d.ts",
45
+ "default": "./dist/context.js"
64
46
  }
65
47
  },
66
48
  "./envelope": {
@@ -69,16 +51,29 @@
69
51
  "default": "./dist/envelope.js"
70
52
  }
71
53
  },
72
- "./resilience": {
54
+ "./errors": {
73
55
  "import": {
74
- "types": "./dist/resilience.d.ts",
75
- "default": "./dist/resilience.js"
56
+ "types": "./dist/errors.d.ts",
57
+ "default": "./dist/errors.js"
76
58
  }
77
59
  },
78
- "./serialization": {
60
+ "./handler": {
79
61
  "import": {
80
- "types": "./dist/serialization.d.ts",
81
- "default": "./dist/serialization.js"
62
+ "types": "./dist/handler.d.ts",
63
+ "default": "./dist/handler.js"
64
+ }
65
+ },
66
+ "./logging": {
67
+ "import": {
68
+ "types": "./dist/logging.d.ts",
69
+ "default": "./dist/logging.js"
70
+ }
71
+ },
72
+ "./package.json": "./package.json",
73
+ "./recovery": {
74
+ "import": {
75
+ "types": "./dist/recovery.d.ts",
76
+ "default": "./dist/recovery.js"
82
77
  }
83
78
  },
84
79
  "./redactor": {
@@ -87,25 +82,36 @@
87
82
  "default": "./dist/redactor.js"
88
83
  }
89
84
  },
90
- "./errors": {
85
+ "./resilience": {
91
86
  "import": {
92
- "types": "./dist/errors.d.ts",
93
- "default": "./dist/errors.js"
87
+ "types": "./dist/resilience.d.ts",
88
+ "default": "./dist/resilience.js"
94
89
  }
95
90
  },
96
- "./context": {
91
+ "./result": {
97
92
  "import": {
98
- "types": "./dist/context.d.ts",
99
- "default": "./dist/context.js"
93
+ "types": "./dist/result/index.d.ts",
94
+ "default": "./dist/result/index.js"
100
95
  }
101
96
  },
102
- "./capabilities": {
97
+ "./result/utilities": {
103
98
  "import": {
104
- "types": "./dist/capabilities.d.ts",
105
- "default": "./dist/capabilities.js"
99
+ "types": "./dist/result/utilities.d.ts",
100
+ "default": "./dist/result/utilities.js"
106
101
  }
107
102
  },
108
- "./package.json": "./package.json"
103
+ "./serialization": {
104
+ "import": {
105
+ "types": "./dist/serialization.d.ts",
106
+ "default": "./dist/serialization.js"
107
+ }
108
+ },
109
+ "./validation": {
110
+ "import": {
111
+ "types": "./dist/validation.d.ts",
112
+ "default": "./dist/validation.js"
113
+ }
114
+ }
109
115
  },
110
116
  "sideEffects": false,
111
117
  "scripts": {