@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.
- package/LICENSE +0 -0
- package/README.md +97 -68
- package/dist/schemas/v1/agent-card.schema.json +230 -0
- package/dist/schemas/v1/conformance-profiles.json +0 -0
- package/dist/schemas/v1/context-ledger.schema.json +70 -0
- package/dist/schemas/v1/discovery.schema.json +132 -0
- package/dist/schemas/v1/envelope.schema.json +0 -0
- package/dist/schemas/v1/error-registry.json +0 -0
- package/dist/src/a2a/bindings/grpc.d.ts +118 -11
- package/dist/src/a2a/bindings/grpc.d.ts.map +1 -0
- package/dist/src/a2a/bindings/grpc.js +80 -8
- package/dist/src/a2a/bindings/grpc.js.map +1 -0
- package/dist/src/a2a/bindings/http.d.ts +131 -15
- package/dist/src/a2a/bindings/http.d.ts.map +1 -0
- package/dist/src/a2a/bindings/http.js +101 -14
- package/dist/src/a2a/bindings/http.js.map +1 -0
- package/dist/src/a2a/bindings/index.d.ts +83 -9
- package/dist/src/a2a/bindings/index.d.ts.map +1 -0
- package/dist/src/a2a/bindings/index.js +74 -6
- package/dist/src/a2a/bindings/index.js.map +1 -0
- package/dist/src/a2a/bindings/jsonrpc.d.ts +194 -9
- package/dist/src/a2a/bindings/jsonrpc.d.ts.map +1 -0
- package/dist/src/a2a/bindings/jsonrpc.js +155 -10
- package/dist/src/a2a/bindings/jsonrpc.js.map +1 -0
- package/dist/src/a2a/bridge.d.ts +237 -44
- package/dist/src/a2a/bridge.d.ts.map +1 -0
- package/dist/src/a2a/bridge.js +187 -48
- package/dist/src/a2a/bridge.js.map +1 -0
- package/dist/src/a2a/extensions.d.ts +222 -12
- package/dist/src/a2a/extensions.d.ts.map +1 -0
- package/dist/src/a2a/extensions.js +178 -13
- package/dist/src/a2a/extensions.js.map +1 -0
- package/dist/src/a2a/index.d.ts +10 -7
- package/dist/src/a2a/index.d.ts.map +1 -0
- package/dist/src/a2a/index.js +24 -27
- package/dist/src/a2a/index.js.map +1 -0
- package/dist/src/a2a/streaming.d.ts +276 -3
- package/dist/src/a2a/streaming.d.ts.map +1 -0
- package/dist/src/a2a/streaming.js +255 -11
- package/dist/src/a2a/streaming.js.map +1 -0
- package/dist/src/a2a/task-lifecycle.d.ts +341 -20
- package/dist/src/a2a/task-lifecycle.d.ts.map +1 -0
- package/dist/src/a2a/task-lifecycle.js +327 -26
- package/dist/src/a2a/task-lifecycle.js.map +1 -0
- package/dist/src/budgetEnforcement.d.ts +93 -20
- package/dist/src/budgetEnforcement.d.ts.map +1 -0
- package/dist/src/budgetEnforcement.js +146 -31
- package/dist/src/budgetEnforcement.js.map +1 -0
- package/dist/src/circuit-breaker/index.d.ts +260 -10
- package/dist/src/circuit-breaker/index.d.ts.map +1 -0
- package/dist/src/circuit-breaker/index.js +226 -14
- package/dist/src/circuit-breaker/index.js.map +1 -0
- package/dist/src/cli.d.ts +1 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +12 -11
- package/dist/src/cli.js.map +1 -0
- package/dist/src/compliance.d.ts +180 -3
- package/dist/src/compliance.d.ts.map +1 -0
- package/dist/src/compliance.js +114 -13
- package/dist/src/compliance.js.map +1 -0
- package/dist/src/conformance.d.ts +55 -2
- package/dist/src/conformance.d.ts.map +1 -0
- package/dist/src/conformance.js +124 -76
- package/dist/src/conformance.js.map +1 -0
- package/dist/src/conformanceProfiles.d.ts +68 -1
- package/dist/src/conformanceProfiles.d.ts.map +1 -0
- package/dist/src/conformanceProfiles.js +53 -1
- package/dist/src/conformanceProfiles.js.map +1 -0
- package/dist/src/deprecationRegistry.d.ts +82 -1
- package/dist/src/deprecationRegistry.d.ts.map +1 -0
- package/dist/src/deprecationRegistry.js +58 -7
- package/dist/src/deprecationRegistry.js.map +1 -0
- package/dist/src/discovery.d.ts +347 -65
- package/dist/src/discovery.d.ts.map +1 -0
- package/dist/src/discovery.js +130 -72
- package/dist/src/discovery.js.map +1 -0
- package/dist/src/envelope.d.ts +262 -9
- package/dist/src/envelope.d.ts.map +1 -0
- package/dist/src/envelope.js +179 -15
- package/dist/src/envelope.js.map +1 -0
- package/dist/src/errorRegistry.d.ts +163 -3
- package/dist/src/errorRegistry.d.ts.map +1 -0
- package/dist/src/errorRegistry.js +119 -3
- package/dist/src/errorRegistry.js.map +1 -0
- package/dist/src/fieldExtraction.d.ts +128 -27
- package/dist/src/fieldExtraction.d.ts.map +1 -0
- package/dist/src/fieldExtraction.js +100 -27
- package/dist/src/fieldExtraction.js.map +1 -0
- package/dist/src/flagResolver.d.ts +77 -10
- package/dist/src/flagResolver.d.ts.map +1 -0
- package/dist/src/flagResolver.js +22 -5
- package/dist/src/flagResolver.js.map +1 -0
- package/dist/src/flagSemantics.d.ts +80 -4
- package/dist/src/flagSemantics.d.ts.map +1 -0
- package/dist/src/flagSemantics.js +78 -11
- package/dist/src/flagSemantics.js.map +1 -0
- package/dist/src/health/index.d.ts +103 -9
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +75 -26
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/index.d.ts +34 -23
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +40 -28
- package/dist/src/index.js.map +1 -0
- package/dist/src/mviProjection.d.ts +43 -6
- package/dist/src/mviProjection.d.ts.map +1 -0
- package/dist/src/mviProjection.js +32 -5
- package/dist/src/mviProjection.js.map +1 -0
- package/dist/src/native-loader.d.ts +49 -0
- package/dist/src/native-loader.d.ts.map +1 -0
- package/dist/src/native-loader.js +56 -0
- package/dist/src/native-loader.js.map +1 -0
- package/dist/src/problemDetails.d.ts +71 -4
- package/dist/src/problemDetails.d.ts.map +1 -0
- package/dist/src/problemDetails.js +27 -3
- package/dist/src/problemDetails.js.map +1 -0
- package/dist/src/shutdown/index.d.ts +103 -9
- package/dist/src/shutdown/index.d.ts.map +1 -0
- package/dist/src/shutdown/index.js +78 -12
- package/dist/src/shutdown/index.js.map +1 -0
- package/dist/src/tokenEstimator.d.ts +98 -11
- package/dist/src/tokenEstimator.d.ts.map +1 -0
- package/dist/src/tokenEstimator.js +91 -13
- package/dist/src/tokenEstimator.js.map +1 -0
- package/dist/src/types.d.ts +477 -11
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +76 -2
- package/dist/src/types.js.map +1 -0
- package/dist/src/validateEnvelope.d.ts +61 -2
- package/dist/src/validateEnvelope.d.ts.map +1 -0
- package/dist/src/validateEnvelope.js +81 -14
- package/dist/src/validateEnvelope.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/lafs.md +3 -4
- package/package.json +14 -12
- package/schemas/v1/agent-card.schema.json +0 -0
- package/schemas/v1/conformance-profiles.json +0 -0
- package/schemas/v1/context-ledger.schema.json +0 -0
- package/schemas/v1/discovery.schema.json +0 -0
- package/schemas/v1/envelope.schema.json +0 -0
- package/schemas/v1/error-registry.json +0 -0
- package/dist/src/mcpAdapter.d.ts +0 -28
- package/dist/src/mcpAdapter.js +0 -281
|
@@ -1,19 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Field extraction resolution for LAFS envelopes.
|
|
3
|
+
*
|
|
4
|
+
* Implements section 9.2 of the LAFS spec: `--field` extracts a single value
|
|
5
|
+
* as plain text (no envelope), `--fields` filters the JSON envelope to a subset,
|
|
6
|
+
* and `--mvi` controls envelope verbosity.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* This module provides both resolution (flag parsing) and runtime extraction/filtering
|
|
10
|
+
* functions. The resolution layer is consumed by the unified resolver in `flagResolver.ts`.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.5.0
|
|
13
|
+
*/
|
|
14
|
+
import { LAFSFlagError } from './flagSemantics.js';
|
|
15
|
+
import { isMVILevel } from './types.js';
|
|
16
|
+
/**
|
|
17
|
+
* Resolve field extraction flags into a validated configuration.
|
|
18
|
+
*
|
|
19
|
+
* @param input - The field extraction flag inputs
|
|
20
|
+
* @returns The resolved extraction configuration with mvi level and source
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* Parses and validates the `--field`, `--fields`, and `--mvi` flags. Throws
|
|
24
|
+
* `E_FIELD_CONFLICT` if both `--field` and `--fields` are provided. The `'custom'`
|
|
25
|
+
* MVI level is server-set per section 9.1 and is rejected as a client-requested value;
|
|
26
|
+
* invalid or absent `--mvi` falls back to `'minimal'`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const resolution = resolveFieldExtraction({ fieldsFlag: 'id,title' });
|
|
31
|
+
* // => { fields: ['id', 'title'], mvi: 'minimal', mviSource: 'default', expectsCustomMvi: true }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @throws {@link LAFSFlagError} When both `fieldFlag` and `fieldsFlag` are set.
|
|
35
|
+
*/
|
|
3
36
|
export function resolveFieldExtraction(input) {
|
|
4
37
|
if (input.fieldFlag && input.fieldsFlag) {
|
|
5
|
-
throw new LAFSFlagError('E_FIELD_CONFLICT', 'Cannot combine --field and --fields: --field extracts a single value '
|
|
6
|
-
|
|
7
|
-
|
|
38
|
+
throw new LAFSFlagError('E_FIELD_CONFLICT', 'Cannot combine --field and --fields: --field extracts a single value ' +
|
|
39
|
+
'as plain text (no envelope); --fields filters the JSON envelope. ' +
|
|
40
|
+
'Use one or the other.', { conflictingModes: ['single-field-extraction', 'multi-field-filter'] });
|
|
8
41
|
}
|
|
9
42
|
const fields = typeof input.fieldsFlag === 'string'
|
|
10
|
-
? input.fieldsFlag
|
|
43
|
+
? input.fieldsFlag
|
|
44
|
+
.split(',')
|
|
45
|
+
.map((f) => f.trim())
|
|
46
|
+
.filter(Boolean)
|
|
11
47
|
: Array.isArray(input.fieldsFlag)
|
|
12
|
-
? input.fieldsFlag.map(f => f.trim()).filter(Boolean)
|
|
48
|
+
? input.fieldsFlag.map((f) => f.trim()).filter(Boolean)
|
|
13
49
|
: undefined;
|
|
14
50
|
// 'custom' is server-set (§9.1) — not a client-requestable level
|
|
15
51
|
const validMvi = isMVILevel(input.mviFlag) && input.mviFlag !== 'custom';
|
|
16
|
-
const mvi = validMvi ? input.mviFlag : '
|
|
52
|
+
const mvi = validMvi ? input.mviFlag : 'minimal';
|
|
17
53
|
const mviSource = validMvi ? 'flag' : 'default';
|
|
18
54
|
const hasFields = (fields?.length ?? 0) > 0;
|
|
19
55
|
return {
|
|
@@ -27,20 +63,29 @@ export function resolveFieldExtraction(input) {
|
|
|
27
63
|
/**
|
|
28
64
|
* Extract a named field from a LAFS result object.
|
|
29
65
|
*
|
|
66
|
+
* @param result - The envelope result value (object, array, or null)
|
|
67
|
+
* @param field - The field name to extract
|
|
68
|
+
* @returns The extracted value, or `undefined` if not found at any level
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
30
71
|
* Handles four result shapes:
|
|
31
|
-
* 1. Direct array: result[0][field]
|
|
32
|
-
* 2. Direct:
|
|
33
|
-
* 3. Nested:
|
|
34
|
-
* 4. Array value:
|
|
72
|
+
* 1. Direct array: `result[0][field]` (list operations where result IS an array)
|
|
73
|
+
* 2. Direct: `result[field]` (flat result object)
|
|
74
|
+
* 3. Nested: `result.<key>[field]` (wrapper-entity, e.g. `result.task.title`)
|
|
75
|
+
* 4. Array value: `result.<key>[0][field]` (wrapper-array, e.g. `result.items[0].title`)
|
|
35
76
|
*
|
|
36
77
|
* Returns the value from the first match only. For array results (shapes 1
|
|
37
78
|
* and 4), returns the first element's field value only. To extract from all
|
|
38
|
-
* elements, iterate the array or use applyFieldFilter
|
|
79
|
+
* elements, iterate the array or use {@link applyFieldFilter}.
|
|
39
80
|
*
|
|
40
81
|
* When multiple wrapper keys contain the requested field (shapes 3 and 4),
|
|
41
82
|
* the first key in property insertion order wins.
|
|
42
83
|
*
|
|
43
|
-
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const result = { task: { id: 'T1', title: 'Fix bug' } };
|
|
87
|
+
* extractFieldFromResult(result, 'title'); // => 'Fix bug'
|
|
88
|
+
* ```
|
|
44
89
|
*/
|
|
45
90
|
export function extractFieldFromResult(result, field) {
|
|
46
91
|
if (result === null || typeof result !== 'object')
|
|
@@ -73,33 +118,60 @@ export function extractFieldFromResult(result, field) {
|
|
|
73
118
|
}
|
|
74
119
|
return undefined;
|
|
75
120
|
}
|
|
76
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Extract a named field from an envelope's result.
|
|
123
|
+
*
|
|
124
|
+
* @param envelope - The LAFS envelope to extract from
|
|
125
|
+
* @param field - The field name to extract
|
|
126
|
+
* @returns The extracted value, or `undefined` if not found
|
|
127
|
+
*
|
|
128
|
+
* @remarks
|
|
129
|
+
* Convenience wrapper around {@link extractFieldFromResult} that accepts
|
|
130
|
+
* the full envelope and delegates to the result extraction logic.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* const value = extractFieldFromEnvelope(envelope, 'title');
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
77
137
|
export function extractFieldFromEnvelope(envelope, field) {
|
|
78
138
|
return extractFieldFromResult(envelope.result, field);
|
|
79
139
|
}
|
|
80
140
|
/**
|
|
81
141
|
* Filter result fields in a LAFS envelope to the requested subset.
|
|
82
142
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* 3. Wrapper-entity: project nested entity's keys, preserve wrapper
|
|
87
|
-
* 4. Wrapper-array: project each element's keys, preserve wrapper
|
|
143
|
+
* @param envelope - The LAFS envelope whose result will be filtered
|
|
144
|
+
* @param fields - Array of field names to retain in the result
|
|
145
|
+
* @returns A new envelope with the filtered result and `_meta.mvi` set to `'custom'`
|
|
88
146
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
147
|
+
* @remarks
|
|
148
|
+
* Handles the same four result shapes as {@link extractFieldFromResult}:
|
|
149
|
+
* 1. Direct array: project each element
|
|
150
|
+
* 2. Flat result: project top-level keys
|
|
151
|
+
* 3. Wrapper-entity: project nested entity's keys, preserve wrapper
|
|
152
|
+
* 4. Wrapper-array: project each element's keys, preserve wrapper
|
|
153
|
+
*
|
|
154
|
+
* Sets `_meta.mvi = 'custom'` per section 9.1.
|
|
155
|
+
* Returns a new envelope with a new `_meta` object. Result values are not
|
|
91
156
|
* deep-cloned; nested object references are shared with the original.
|
|
92
|
-
* Unknown field names are silently omitted per
|
|
157
|
+
* Unknown field names are silently omitted per section 9.2.
|
|
93
158
|
*
|
|
94
159
|
* When result is a wrapper (shapes 3/4) with multiple keys, each key is
|
|
95
160
|
* projected independently. Primitive values at the wrapper level (numbers,
|
|
96
|
-
* strings, booleans) are preserved as-is
|
|
161
|
+
* strings, booleans) are preserved as-is; field filtering is applied to nested
|
|
97
162
|
* entity or array keys only, not to the wrapper's own primitive keys.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```ts
|
|
166
|
+
* const filtered = applyFieldFilter(envelope, ['id', 'title']);
|
|
167
|
+
* // filtered.result contains only 'id' and 'title' fields
|
|
168
|
+
* // filtered._meta.mvi === 'custom'
|
|
169
|
+
* ```
|
|
98
170
|
*/
|
|
99
171
|
export function applyFieldFilter(envelope, fields) {
|
|
100
172
|
if (fields.length === 0 || envelope.result === null)
|
|
101
173
|
return envelope;
|
|
102
|
-
const pick = (obj) => Object.fromEntries(fields.filter(f => f in obj).map(f => [f, obj[f]]));
|
|
174
|
+
const pick = (obj) => Object.fromEntries(fields.filter((f) => f in obj).map((f) => [f, obj[f]]));
|
|
103
175
|
let filtered;
|
|
104
176
|
if (Array.isArray(envelope.result)) {
|
|
105
177
|
// Shape 1: direct array
|
|
@@ -107,7 +179,7 @@ export function applyFieldFilter(envelope, fields) {
|
|
|
107
179
|
}
|
|
108
180
|
else {
|
|
109
181
|
const record = envelope.result;
|
|
110
|
-
const topLevelMatch = fields.some(f => f in record);
|
|
182
|
+
const topLevelMatch = fields.some((f) => f in record);
|
|
111
183
|
if (topLevelMatch) {
|
|
112
184
|
// Shape 2: flat result
|
|
113
185
|
filtered = pick(record);
|
|
@@ -116,7 +188,7 @@ export function applyFieldFilter(envelope, fields) {
|
|
|
116
188
|
// Shapes 3 & 4: wrapper — apply pick one level down, preserve wrapper keys
|
|
117
189
|
filtered = Object.fromEntries(Object.entries(record).map(([k, v]) => {
|
|
118
190
|
if (Array.isArray(v)) {
|
|
119
|
-
return [k, v.map(item => pick(item))];
|
|
191
|
+
return [k, v.map((item) => pick(item))];
|
|
120
192
|
}
|
|
121
193
|
if (v && typeof v === 'object') {
|
|
122
194
|
return [k, pick(v)];
|
|
@@ -131,3 +203,4 @@ export function applyFieldFilter(envelope, fields) {
|
|
|
131
203
|
result: filtered,
|
|
132
204
|
};
|
|
133
205
|
}
|
|
206
|
+
//# sourceMappingURL=fieldExtraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldExtraction.js","sourceRoot":"","sources":["../../src/fieldExtraction.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,41 +6,108 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @since 1.6.0
|
|
8
8
|
*/
|
|
9
|
-
import { type FlagResolution } from './flagSemantics.js';
|
|
10
9
|
import { type FieldExtractionResolution } from './fieldExtraction.js';
|
|
11
|
-
|
|
10
|
+
import { type FlagResolution } from './flagSemantics.js';
|
|
11
|
+
/**
|
|
12
|
+
* Combined input for both format and field extraction layers.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* Merges the format-layer flags (sections 5.1-5.3) with the field extraction
|
|
16
|
+
* flags (section 9.2) into a single input object for {@link resolveFlags}.
|
|
17
|
+
*/
|
|
12
18
|
export interface UnifiedFlagInput {
|
|
19
|
+
/**
|
|
20
|
+
* Request human-readable output (`--human` flag).
|
|
21
|
+
* @defaultValue undefined
|
|
22
|
+
*/
|
|
13
23
|
human?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Request JSON output (`--json` flag).
|
|
26
|
+
* @defaultValue undefined
|
|
27
|
+
*/
|
|
14
28
|
json?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Suppress non-essential output for scripting (`--quiet` flag).
|
|
31
|
+
* @defaultValue undefined
|
|
32
|
+
*/
|
|
15
33
|
quiet?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Explicit format override, taking highest precedence in the format layer.
|
|
36
|
+
* @defaultValue undefined
|
|
37
|
+
*/
|
|
16
38
|
requestedFormat?: 'json' | 'human';
|
|
39
|
+
/**
|
|
40
|
+
* Project-level default format from configuration.
|
|
41
|
+
* @defaultValue undefined
|
|
42
|
+
*/
|
|
17
43
|
projectDefault?: 'json' | 'human';
|
|
44
|
+
/**
|
|
45
|
+
* User-level default format from configuration.
|
|
46
|
+
* @defaultValue undefined
|
|
47
|
+
*/
|
|
18
48
|
userDefault?: 'json' | 'human';
|
|
19
49
|
/**
|
|
20
50
|
* TTY detection hint. When true, defaults to human format if no
|
|
21
51
|
* explicit format flag or project/user default is set.
|
|
22
52
|
* CLI tools should pass `process.stdout.isTTY ?? false`.
|
|
53
|
+
* @defaultValue undefined
|
|
23
54
|
*/
|
|
24
55
|
tty?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Extract a single field as plain text, discarding the envelope (`--field` flag).
|
|
58
|
+
* @defaultValue undefined
|
|
59
|
+
*/
|
|
25
60
|
field?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Filter result to these fields while preserving the envelope (`--fields` flag).
|
|
63
|
+
* Accepts a comma-separated string or an array of field names.
|
|
64
|
+
* @defaultValue undefined
|
|
65
|
+
*/
|
|
26
66
|
fields?: string | string[];
|
|
67
|
+
/**
|
|
68
|
+
* Requested MVI verbosity level (`--mvi` flag).
|
|
69
|
+
* @defaultValue undefined
|
|
70
|
+
*/
|
|
27
71
|
mvi?: string;
|
|
28
72
|
}
|
|
29
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Combined resolution result with cross-layer warnings.
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* Contains the independently resolved format and field extraction layers plus
|
|
78
|
+
* any cross-layer interaction warnings produced during validation (section 5.4).
|
|
79
|
+
*/
|
|
30
80
|
export interface UnifiedFlagResolution {
|
|
31
|
-
/** Resolved format layer. */
|
|
81
|
+
/** Resolved format layer from the format precedence chain. */
|
|
32
82
|
format: FlagResolution;
|
|
33
|
-
/** Resolved field extraction layer. */
|
|
83
|
+
/** Resolved field extraction layer from field/fields/mvi flags. */
|
|
34
84
|
fields: FieldExtractionResolution;
|
|
35
|
-
/** Warnings for cross-layer interactions (non-fatal). */
|
|
85
|
+
/** Warnings for cross-layer interactions (non-fatal, informational only). */
|
|
36
86
|
warnings: string[];
|
|
37
87
|
}
|
|
38
88
|
/**
|
|
39
89
|
* Resolve all flags across both layers and validate cross-layer semantics.
|
|
40
90
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
91
|
+
* @param input - Combined format and field extraction flags
|
|
92
|
+
* @returns The unified resolution containing format, fields, and any cross-layer warnings
|
|
93
|
+
*
|
|
94
|
+
* @remarks
|
|
95
|
+
* Delegates to {@link resolveOutputFormat} for the format layer and
|
|
96
|
+
* {@link resolveFieldExtraction} for the field extraction layer, then performs
|
|
97
|
+
* cross-layer validation per section 5.4. Cross-layer combinations are valid but
|
|
98
|
+
* MAY produce informational warnings. Format-layer conflicts (`E_FORMAT_CONFLICT`)
|
|
99
|
+
* and field-layer conflicts (`E_FIELD_CONFLICT`) still throw as before; they are
|
|
100
|
+
* delegated to the existing single-layer resolvers.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* const result = resolveFlags({ human: true, field: 'title' });
|
|
105
|
+
* // result.format => { format: 'human', source: 'flag', quiet: false }
|
|
106
|
+
* // result.fields => { field: 'title', mvi: 'minimal', ... }
|
|
107
|
+
* // result.warnings => ['Cross-layer: --human + --field "title". ...']
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @throws {@link LAFSFlagError} When format or field layer flags conflict.
|
|
45
111
|
*/
|
|
46
112
|
export declare function resolveFlags(input: UnifiedFlagInput): UnifiedFlagResolution;
|
|
113
|
+
//# sourceMappingURL=flagResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flagResolver.d.ts","sourceRoot":"","sources":["../../src/flagResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,KAAK,yBAAyB,EAA0B,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAG9E;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,8DAA8D;IAC9D,MAAM,EAAE,cAAc,CAAC;IACvB,mEAAmE;IACnE,MAAM,EAAE,yBAAyB,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,qBAAqB,CAqC3E"}
|
package/dist/src/flagResolver.js
CHANGED
|
@@ -6,15 +6,31 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @since 1.6.0
|
|
8
8
|
*/
|
|
9
|
-
import { resolveOutputFormat } from './flagSemantics.js';
|
|
10
9
|
import { resolveFieldExtraction } from './fieldExtraction.js';
|
|
10
|
+
import { resolveOutputFormat } from './flagSemantics.js';
|
|
11
11
|
/**
|
|
12
12
|
* Resolve all flags across both layers and validate cross-layer semantics.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* @param input - Combined format and field extraction flags
|
|
15
|
+
* @returns The unified resolution containing format, fields, and any cross-layer warnings
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* Delegates to {@link resolveOutputFormat} for the format layer and
|
|
19
|
+
* {@link resolveFieldExtraction} for the field extraction layer, then performs
|
|
20
|
+
* cross-layer validation per section 5.4. Cross-layer combinations are valid but
|
|
21
|
+
* MAY produce informational warnings. Format-layer conflicts (`E_FORMAT_CONFLICT`)
|
|
22
|
+
* and field-layer conflicts (`E_FIELD_CONFLICT`) still throw as before; they are
|
|
23
|
+
* delegated to the existing single-layer resolvers.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* const result = resolveFlags({ human: true, field: 'title' });
|
|
28
|
+
* // result.format => { format: 'human', source: 'flag', quiet: false }
|
|
29
|
+
* // result.fields => { field: 'title', mvi: 'minimal', ... }
|
|
30
|
+
* // result.warnings => ['Cross-layer: --human + --field "title". ...']
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @throws {@link LAFSFlagError} When format or field layer flags conflict.
|
|
18
34
|
*/
|
|
19
35
|
export function resolveFlags(input) {
|
|
20
36
|
const formatInput = {
|
|
@@ -45,3 +61,4 @@ export function resolveFlags(input) {
|
|
|
45
61
|
}
|
|
46
62
|
return { format, fields, warnings };
|
|
47
63
|
}
|
|
64
|
+
//# sourceMappingURL=flagResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flagResolver.js","sourceRoot":"","sources":["../../src/flagResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAkC,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAuB,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAkF9E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,YAAY,CAAC,KAAuB;IAClD,MAAM,WAAW,GAAc;QAC7B,SAAS,EAAE,KAAK,CAAC,KAAK;QACtB,QAAQ,EAAE,KAAK,CAAC,IAAI;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,GAAG,EAAE,KAAK,CAAC,GAAG;KACf,CAAC;IACF,MAAM,MAAM,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAyB;QACvC,SAAS,EAAE,KAAK,CAAC,KAAK;QACtB,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,OAAO,EAAE,KAAK,CAAC,GAAG;KACnB,CAAC;IACF,MAAM,MAAM,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAElD,gCAAgC;IAChC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9C,QAAQ,CAAC,IAAI,CACX,mCAAmC,MAAM,CAAC,KAAK,KAAK;YAClD,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,QAAQ,CAAC,IAAI,CACX,oCAAoC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;YAC/D,+DAA+D,CAClE,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -1,16 +1,92 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Flag semantics for LAFS output format resolution.
|
|
3
|
+
*
|
|
4
|
+
* Implements the precedence chain defined in LAFS spec sections 5.1-5.3:
|
|
5
|
+
* explicit flag > project config > user config > TTY detection > default (json).
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* This module is the single-layer resolver for format flags. For cross-layer
|
|
9
|
+
* resolution that also includes field extraction, use {@link resolveFlags} from
|
|
10
|
+
* `flagResolver.ts`.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.0.0
|
|
13
|
+
*/
|
|
14
|
+
import type { FlagInput, LAFSError, LAFSErrorCategory } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Result of resolving output format flags.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* Captures both the resolved format and which configuration layer determined it,
|
|
20
|
+
* enabling diagnostics and cross-layer validation in the unified resolver.
|
|
21
|
+
*/
|
|
2
22
|
export interface FlagResolution {
|
|
3
|
-
format:
|
|
4
|
-
|
|
5
|
-
/**
|
|
23
|
+
/** The resolved output format: `'json'` for machine-readable or `'human'` for human-readable. */
|
|
24
|
+
format: 'json' | 'human';
|
|
25
|
+
/** Which configuration layer determined the format value. */
|
|
26
|
+
source: 'flag' | 'project' | 'user' | 'default';
|
|
27
|
+
/** When true, suppress non-essential output for scripting. */
|
|
6
28
|
quiet: boolean;
|
|
7
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Error thrown when LAFS flag validation fails.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Wraps a registered LAFS error code with category and retryability information
|
|
35
|
+
* looked up from the error registry. The most common error is `E_FORMAT_CONFLICT`
|
|
36
|
+
* when `--human` and `--json` are used together.
|
|
37
|
+
*/
|
|
8
38
|
export declare class LAFSFlagError extends Error implements LAFSError {
|
|
39
|
+
/** The LAFS error code (e.g. `'E_FORMAT_CONFLICT'`). */
|
|
9
40
|
code: string;
|
|
41
|
+
/** The error category resolved from the error registry. */
|
|
10
42
|
category: LAFSErrorCategory;
|
|
43
|
+
/** Whether the operation that produced this error can be retried. */
|
|
11
44
|
retryable: boolean;
|
|
45
|
+
/** Milliseconds to wait before retrying, or `null` if not applicable. */
|
|
12
46
|
retryAfterMs: number | null;
|
|
47
|
+
/** Additional structured details about the error. */
|
|
13
48
|
details: Record<string, unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* Create a new LAFSFlagError.
|
|
51
|
+
*
|
|
52
|
+
* @param code - A registered LAFS error code (e.g. `'E_FORMAT_CONFLICT'`)
|
|
53
|
+
* @param message - Human-readable description of the error
|
|
54
|
+
* @param details - Optional structured details to attach to the error
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* Looks up the error code in the LAFS error registry to populate
|
|
58
|
+
* `category` and `retryable`. Falls back to `'CONTRACT'` category
|
|
59
|
+
* and non-retryable if the code is not found.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* throw new LAFSFlagError(
|
|
64
|
+
* 'E_FORMAT_CONFLICT',
|
|
65
|
+
* 'Cannot combine --human and --json.',
|
|
66
|
+
* );
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
14
69
|
constructor(code: string, message: string, details?: Record<string, unknown>);
|
|
15
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Resolve the output format from flag inputs using the LAFS precedence chain.
|
|
73
|
+
*
|
|
74
|
+
* @param input - The flag inputs including explicit flags, project/user defaults, and TTY state
|
|
75
|
+
* @returns The resolved format, its source layer, and quiet mode status
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* Precedence (highest to lowest): explicit `requestedFormat` > `--human`/`--json` flag >
|
|
79
|
+
* project default > user default > TTY detection > protocol default (`'json'`).
|
|
80
|
+
* Throws `LAFSFlagError` with code `E_FORMAT_CONFLICT` if both `--human` and `--json`
|
|
81
|
+
* are set simultaneously.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* const resolution = resolveOutputFormat({ humanFlag: true });
|
|
86
|
+
* // => { format: 'human', source: 'flag', quiet: false }
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @throws {@link LAFSFlagError} When `humanFlag` and `jsonFlag` are both truthy.
|
|
90
|
+
*/
|
|
16
91
|
export declare function resolveOutputFormat(input: FlagInput): FlagResolution;
|
|
92
|
+
//# sourceMappingURL=flagSemantics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flagSemantics.d.ts","sourceRoot":"","sources":["../../src/flagSemantics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,iGAAiG;IACjG,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IAChD,8DAA8D;IAC9D,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,KAAM,YAAW,SAAS;IAC3D,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qEAAqE;IACrE,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC;;;;;;;;;;;;;;;;;;;OAmBG;gBACS,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;CAUjF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,cAAc,CA+BpE"}
|
|
@@ -1,45 +1,112 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Flag semantics for LAFS output format resolution.
|
|
3
|
+
*
|
|
4
|
+
* Implements the precedence chain defined in LAFS spec sections 5.1-5.3:
|
|
5
|
+
* explicit flag > project config > user config > TTY detection > default (json).
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* This module is the single-layer resolver for format flags. For cross-layer
|
|
9
|
+
* resolution that also includes field extraction, use {@link resolveFlags} from
|
|
10
|
+
* `flagResolver.ts`.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.0.0
|
|
13
|
+
*/
|
|
14
|
+
import { getRegistryCode } from './errorRegistry.js';
|
|
15
|
+
/**
|
|
16
|
+
* Error thrown when LAFS flag validation fails.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* Wraps a registered LAFS error code with category and retryability information
|
|
20
|
+
* looked up from the error registry. The most common error is `E_FORMAT_CONFLICT`
|
|
21
|
+
* when `--human` and `--json` are used together.
|
|
22
|
+
*/
|
|
2
23
|
export class LAFSFlagError extends Error {
|
|
24
|
+
/** The LAFS error code (e.g. `'E_FORMAT_CONFLICT'`). */
|
|
3
25
|
code;
|
|
26
|
+
/** The error category resolved from the error registry. */
|
|
4
27
|
category;
|
|
28
|
+
/** Whether the operation that produced this error can be retried. */
|
|
5
29
|
retryable;
|
|
30
|
+
/** Milliseconds to wait before retrying, or `null` if not applicable. */
|
|
6
31
|
retryAfterMs;
|
|
32
|
+
/** Additional structured details about the error. */
|
|
7
33
|
details;
|
|
34
|
+
/**
|
|
35
|
+
* Create a new LAFSFlagError.
|
|
36
|
+
*
|
|
37
|
+
* @param code - A registered LAFS error code (e.g. `'E_FORMAT_CONFLICT'`)
|
|
38
|
+
* @param message - Human-readable description of the error
|
|
39
|
+
* @param details - Optional structured details to attach to the error
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* Looks up the error code in the LAFS error registry to populate
|
|
43
|
+
* `category` and `retryable`. Falls back to `'CONTRACT'` category
|
|
44
|
+
* and non-retryable if the code is not found.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* throw new LAFSFlagError(
|
|
49
|
+
* 'E_FORMAT_CONFLICT',
|
|
50
|
+
* 'Cannot combine --human and --json.',
|
|
51
|
+
* );
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
8
54
|
constructor(code, message, details = {}) {
|
|
9
55
|
super(message);
|
|
10
|
-
this.name =
|
|
56
|
+
this.name = 'LAFSFlagError';
|
|
11
57
|
this.code = code;
|
|
12
58
|
const entry = getRegistryCode(code);
|
|
13
|
-
this.category = (entry?.category ??
|
|
59
|
+
this.category = (entry?.category ?? 'CONTRACT');
|
|
14
60
|
this.retryable = entry?.retryable ?? false;
|
|
15
61
|
this.retryAfterMs = null;
|
|
16
62
|
this.details = details;
|
|
17
63
|
}
|
|
18
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolve the output format from flag inputs using the LAFS precedence chain.
|
|
67
|
+
*
|
|
68
|
+
* @param input - The flag inputs including explicit flags, project/user defaults, and TTY state
|
|
69
|
+
* @returns The resolved format, its source layer, and quiet mode status
|
|
70
|
+
*
|
|
71
|
+
* @remarks
|
|
72
|
+
* Precedence (highest to lowest): explicit `requestedFormat` > `--human`/`--json` flag >
|
|
73
|
+
* project default > user default > TTY detection > protocol default (`'json'`).
|
|
74
|
+
* Throws `LAFSFlagError` with code `E_FORMAT_CONFLICT` if both `--human` and `--json`
|
|
75
|
+
* are set simultaneously.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* const resolution = resolveOutputFormat({ humanFlag: true });
|
|
80
|
+
* // => { format: 'human', source: 'flag', quiet: false }
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @throws {@link LAFSFlagError} When `humanFlag` and `jsonFlag` are both truthy.
|
|
84
|
+
*/
|
|
19
85
|
export function resolveOutputFormat(input) {
|
|
20
86
|
if (input.humanFlag && input.jsonFlag) {
|
|
21
|
-
throw new LAFSFlagError(
|
|
87
|
+
throw new LAFSFlagError('E_FORMAT_CONFLICT', 'Cannot combine --human and --json in the same invocation.');
|
|
22
88
|
}
|
|
23
89
|
const quiet = input.quiet ?? false;
|
|
24
90
|
if (input.requestedFormat) {
|
|
25
|
-
return { format: input.requestedFormat, source:
|
|
91
|
+
return { format: input.requestedFormat, source: 'flag', quiet };
|
|
26
92
|
}
|
|
27
93
|
if (input.humanFlag) {
|
|
28
|
-
return { format:
|
|
94
|
+
return { format: 'human', source: 'flag', quiet };
|
|
29
95
|
}
|
|
30
96
|
if (input.jsonFlag) {
|
|
31
|
-
return { format:
|
|
97
|
+
return { format: 'json', source: 'flag', quiet };
|
|
32
98
|
}
|
|
33
99
|
if (input.projectDefault) {
|
|
34
|
-
return { format: input.projectDefault, source:
|
|
100
|
+
return { format: input.projectDefault, source: 'project', quiet };
|
|
35
101
|
}
|
|
36
102
|
if (input.userDefault) {
|
|
37
|
-
return { format: input.userDefault, source:
|
|
103
|
+
return { format: input.userDefault, source: 'user', quiet };
|
|
38
104
|
}
|
|
39
105
|
// TTY terminals default to human-readable output for usability.
|
|
40
106
|
// Non-TTY (piped, CI, agents) defaults to JSON per LAFS protocol.
|
|
41
107
|
if (input.tty) {
|
|
42
|
-
return { format:
|
|
108
|
+
return { format: 'human', source: 'default', quiet };
|
|
43
109
|
}
|
|
44
|
-
return { format:
|
|
110
|
+
return { format: 'json', source: 'default', quiet };
|
|
45
111
|
}
|
|
112
|
+
//# sourceMappingURL=flagSemantics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flagSemantics.js","sourceRoot":"","sources":["../../src/flagSemantics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAmBrD;;;;;;;GAOG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,wDAAwD;IACxD,IAAI,CAAS;IACb,2DAA2D;IAC3D,QAAQ,CAAoB;IAC5B,qEAAqE;IACrE,SAAS,CAAU;IACnB,yEAAyE;IACzE,YAAY,CAAgB;IAC5B,qDAAqD;IACrD,OAAO,CAA0B;IAEjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,YAAY,IAAY,EAAE,OAAe,EAAE,UAAmC,EAAE;QAC9E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,GAAG,CAAC,KAAK,EAAE,QAAQ,IAAI,UAAU,CAAsB,CAAC;QACrE,IAAI,CAAC,SAAS,GAAG,KAAK,EAAE,SAAS,IAAI,KAAK,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAgB;IAClD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,aAAa,CACrB,mBAAmB,EACnB,2DAA2D,CAC5D,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC;IAEnC,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAClE,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACpD,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACpE,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC9D,CAAC;IACD,gEAAgE;IAChE,kEAAkE;IAClE,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACvD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;AACtD,CAAC"}
|