@copilotkit/aimock 1.38.0 → 1.40.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +56 -0
- package/README.md +24 -2
- package/dist/agui-handler.cjs +20 -18
- package/dist/agui-handler.cjs.map +1 -1
- package/dist/agui-handler.d.cts +8 -1
- package/dist/agui-handler.d.cts.map +1 -1
- package/dist/agui-handler.d.ts +8 -1
- package/dist/agui-handler.d.ts.map +1 -1
- package/dist/agui-handler.js +20 -18
- package/dist/agui-handler.js.map +1 -1
- package/dist/agui-stub.d.cts +2 -2
- package/dist/agui-stub.d.ts +2 -2
- package/dist/agui-types.d.cts +84 -3
- package/dist/agui-types.d.cts.map +1 -1
- package/dist/agui-types.d.ts +84 -3
- package/dist/agui-types.d.ts.map +1 -1
- package/dist/aimock-cli.cjs +1 -1
- package/dist/aimock-cli.cjs.map +1 -1
- package/dist/aimock-cli.js +1 -1
- package/dist/aimock-cli.js.map +1 -1
- package/dist/cli.cjs +10 -10
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +10 -10
- package/dist/cli.js.map +1 -1
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/helpers.cjs +8 -4
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +8 -4
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/llmock.cjs +23 -9
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +22 -0
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +22 -0
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +25 -11
- package/dist/llmock.js.map +1 -1
- package/dist/openrouter-chat.cjs +41 -0
- package/dist/openrouter-chat.cjs.map +1 -1
- package/dist/openrouter-chat.js +41 -0
- package/dist/openrouter-chat.js.map +1 -1
- package/dist/openrouter-video.cjs.map +1 -1
- package/dist/openrouter-video.js.map +1 -1
- package/dist/recorder.cjs +77 -8
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +77 -8
- package/dist/recorder.js.map +1 -1
- package/dist/server.cjs +80 -17
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +6 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts +6 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +80 -18
- package/dist/server.js.map +1 -1
- package/dist/stream-collapse.cjs +97 -6
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +16 -0
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +16 -0
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +97 -6
- package/dist/stream-collapse.js.map +1 -1
- package/dist/types.d.cts +22 -3
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +22 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-types.d.ts.map +1 -1
- package/dist/ws-gemini-live.cjs +41 -6
- package/dist/ws-gemini-live.cjs.map +1 -1
- package/dist/ws-gemini-live.js +41 -6
- package/dist/ws-gemini-live.js.map +1 -1
- package/package.json +5 -3
package/dist/agui-types.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
//#region src/agui-types.d.ts
|
|
2
|
-
type AGUIEventType = "RUN_STARTED" | "RUN_FINISHED" | "RUN_ERROR" | "STEP_STARTED" | "STEP_FINISHED" | "TEXT_MESSAGE_START" | "TEXT_MESSAGE_CONTENT" | "TEXT_MESSAGE_END" | "TEXT_MESSAGE_CHUNK" | "TOOL_CALL_START" | "TOOL_CALL_ARGS" | "TOOL_CALL_END" | "TOOL_CALL_CHUNK" | "TOOL_CALL_RESULT" | "STATE_SNAPSHOT" | "STATE_DELTA" | "MESSAGES_SNAPSHOT" | "ACTIVITY_SNAPSHOT" | "ACTIVITY_DELTA" | "REASONING_START" | "REASONING_MESSAGE_START" | "REASONING_MESSAGE_CONTENT" | "REASONING_MESSAGE_END" | "REASONING_MESSAGE_CHUNK" | "REASONING_END" | "REASONING_ENCRYPTED_VALUE" | "RAW" | "CUSTOM" | "THINKING_START" | "THINKING_END" | "THINKING_TEXT_MESSAGE_START" | "THINKING_TEXT_MESSAGE_CONTENT" | "THINKING_TEXT_MESSAGE_END";
|
|
2
|
+
type AGUIEventType = "RUN_STARTED" | "RUN_FINISHED" | "RUN_ERROR" | "STEP_STARTED" | "STEP_FINISHED" | "TEXT_MESSAGE_START" | "TEXT_MESSAGE_CONTENT" | "TEXT_MESSAGE_END" | "TEXT_MESSAGE_CHUNK" | "TOOL_CALL_START" | "TOOL_CALL_ARGS" | "TOOL_CALL_END" | "TOOL_CALL_CHUNK" | "TOOL_CALL_RESULT" | "STATE_SNAPSHOT" | "STATE_DELTA" | "MESSAGES_SNAPSHOT" | "ACTIVITY_SNAPSHOT" | "ACTIVITY_DELTA" | "REASONING_START" | "REASONING_MESSAGE_START" | "REASONING_MESSAGE_CONTENT" | "REASONING_MESSAGE_END" | "REASONING_MESSAGE_CHUNK" | "REASONING_END" | "REASONING_ENCRYPTED_VALUE" | "SUBAGENT_STARTED" | "SUBAGENT_FINISHED" | "SUBAGENT_ERROR" | "RAW" | "CUSTOM" | "THINKING_START" | "THINKING_END" | "THINKING_TEXT_MESSAGE_START" | "THINKING_TEXT_MESSAGE_CONTENT" | "THINKING_TEXT_MESSAGE_END";
|
|
3
3
|
interface AGUIBaseEvent {
|
|
4
4
|
type: AGUIEventType;
|
|
5
5
|
timestamp?: number;
|
|
6
6
|
rawEvent?: unknown;
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
7
8
|
}
|
|
8
9
|
interface AGUIRunStartedEvent extends AGUIBaseEvent {
|
|
9
10
|
type: "RUN_STARTED";
|
|
@@ -18,19 +19,23 @@ interface AGUIRunFinishedEvent extends AGUIBaseEvent {
|
|
|
18
19
|
runId: string;
|
|
19
20
|
result?: unknown;
|
|
20
21
|
outcome?: AGUIRunFinishedOutcome;
|
|
22
|
+
usage?: AGUITokenUsage[];
|
|
21
23
|
}
|
|
22
24
|
interface AGUIRunErrorEvent extends AGUIBaseEvent {
|
|
23
25
|
type: "RUN_ERROR";
|
|
24
26
|
message: string;
|
|
25
27
|
code?: string;
|
|
28
|
+
usage?: AGUITokenUsage[];
|
|
26
29
|
}
|
|
27
30
|
interface AGUIStepStartedEvent extends AGUIBaseEvent {
|
|
28
31
|
type: "STEP_STARTED";
|
|
29
32
|
stepName: string;
|
|
33
|
+
subagentRunId?: string;
|
|
30
34
|
}
|
|
31
35
|
interface AGUIStepFinishedEvent extends AGUIBaseEvent {
|
|
32
36
|
type: "STEP_FINISHED";
|
|
33
37
|
stepName: string;
|
|
38
|
+
subagentRunId?: string;
|
|
34
39
|
}
|
|
35
40
|
type AGUITextMessageRole = "developer" | "system" | "assistant" | "user";
|
|
36
41
|
type AGUIMessageRole = "developer" | "system" | "assistant" | "user" | "tool" | "activity" | "reasoning";
|
|
@@ -39,15 +44,18 @@ interface AGUITextMessageStartEvent extends AGUIBaseEvent {
|
|
|
39
44
|
messageId: string;
|
|
40
45
|
role: AGUITextMessageRole;
|
|
41
46
|
name?: string;
|
|
47
|
+
subagentRunId?: string;
|
|
42
48
|
}
|
|
43
49
|
interface AGUITextMessageContentEvent extends AGUIBaseEvent {
|
|
44
50
|
type: "TEXT_MESSAGE_CONTENT";
|
|
45
51
|
messageId: string;
|
|
46
52
|
delta: string;
|
|
53
|
+
subagentRunId?: string;
|
|
47
54
|
}
|
|
48
55
|
interface AGUITextMessageEndEvent extends AGUIBaseEvent {
|
|
49
56
|
type: "TEXT_MESSAGE_END";
|
|
50
57
|
messageId: string;
|
|
58
|
+
subagentRunId?: string;
|
|
51
59
|
}
|
|
52
60
|
interface AGUITextMessageChunkEvent extends AGUIBaseEvent {
|
|
53
61
|
type: "TEXT_MESSAGE_CHUNK";
|
|
@@ -55,21 +63,25 @@ interface AGUITextMessageChunkEvent extends AGUIBaseEvent {
|
|
|
55
63
|
role?: AGUITextMessageRole;
|
|
56
64
|
delta?: string;
|
|
57
65
|
name?: string;
|
|
66
|
+
subagentRunId?: string;
|
|
58
67
|
}
|
|
59
68
|
interface AGUIToolCallStartEvent extends AGUIBaseEvent {
|
|
60
69
|
type: "TOOL_CALL_START";
|
|
61
70
|
toolCallId: string;
|
|
62
71
|
toolCallName: string;
|
|
63
72
|
parentMessageId?: string;
|
|
73
|
+
subagentRunId?: string;
|
|
64
74
|
}
|
|
65
75
|
interface AGUIToolCallArgsEvent extends AGUIBaseEvent {
|
|
66
76
|
type: "TOOL_CALL_ARGS";
|
|
67
77
|
toolCallId: string;
|
|
68
78
|
delta: string;
|
|
79
|
+
subagentRunId?: string;
|
|
69
80
|
}
|
|
70
81
|
interface AGUIToolCallEndEvent extends AGUIBaseEvent {
|
|
71
82
|
type: "TOOL_CALL_END";
|
|
72
83
|
toolCallId: string;
|
|
84
|
+
subagentRunId?: string;
|
|
73
85
|
}
|
|
74
86
|
interface AGUIToolCallChunkEvent extends AGUIBaseEvent {
|
|
75
87
|
type: "TOOL_CALL_CHUNK";
|
|
@@ -77,6 +89,7 @@ interface AGUIToolCallChunkEvent extends AGUIBaseEvent {
|
|
|
77
89
|
toolCallName?: string;
|
|
78
90
|
parentMessageId?: string;
|
|
79
91
|
delta?: string;
|
|
92
|
+
subagentRunId?: string;
|
|
80
93
|
}
|
|
81
94
|
interface AGUIToolCallResultEvent extends AGUIBaseEvent {
|
|
82
95
|
type: "TOOL_CALL_RESULT";
|
|
@@ -84,14 +97,17 @@ interface AGUIToolCallResultEvent extends AGUIBaseEvent {
|
|
|
84
97
|
toolCallId: string;
|
|
85
98
|
content: string;
|
|
86
99
|
role?: "tool";
|
|
100
|
+
subagentRunId?: string;
|
|
87
101
|
}
|
|
88
102
|
interface AGUIStateSnapshotEvent extends AGUIBaseEvent {
|
|
89
103
|
type: "STATE_SNAPSHOT";
|
|
90
104
|
snapshot: unknown;
|
|
105
|
+
subagentRunId?: string;
|
|
91
106
|
}
|
|
92
107
|
interface AGUIStateDeltaEvent extends AGUIBaseEvent {
|
|
93
108
|
type: "STATE_DELTA";
|
|
94
109
|
delta: unknown[];
|
|
110
|
+
subagentRunId?: string;
|
|
95
111
|
}
|
|
96
112
|
interface AGUIMessagesSnapshotEvent extends AGUIBaseEvent {
|
|
97
113
|
type: "MESSAGES_SNAPSHOT";
|
|
@@ -103,39 +119,47 @@ interface AGUIActivitySnapshotEvent extends AGUIBaseEvent {
|
|
|
103
119
|
activityType: string;
|
|
104
120
|
content: Record<string, unknown>;
|
|
105
121
|
replace?: boolean;
|
|
122
|
+
subagentRunId?: string;
|
|
106
123
|
}
|
|
107
124
|
interface AGUIActivityDeltaEvent extends AGUIBaseEvent {
|
|
108
125
|
type: "ACTIVITY_DELTA";
|
|
109
126
|
messageId: string;
|
|
110
127
|
activityType: string;
|
|
111
128
|
patch: unknown[];
|
|
129
|
+
subagentRunId?: string;
|
|
112
130
|
}
|
|
113
131
|
interface AGUIReasoningStartEvent extends AGUIBaseEvent {
|
|
114
132
|
type: "REASONING_START";
|
|
115
133
|
messageId: string;
|
|
134
|
+
subagentRunId?: string;
|
|
116
135
|
}
|
|
117
136
|
interface AGUIReasoningMessageStartEvent extends AGUIBaseEvent {
|
|
118
137
|
type: "REASONING_MESSAGE_START";
|
|
119
138
|
messageId: string;
|
|
120
139
|
role: "reasoning";
|
|
140
|
+
subagentRunId?: string;
|
|
121
141
|
}
|
|
122
142
|
interface AGUIReasoningMessageContentEvent extends AGUIBaseEvent {
|
|
123
143
|
type: "REASONING_MESSAGE_CONTENT";
|
|
124
144
|
messageId: string;
|
|
125
145
|
delta: string;
|
|
146
|
+
subagentRunId?: string;
|
|
126
147
|
}
|
|
127
148
|
interface AGUIReasoningMessageEndEvent extends AGUIBaseEvent {
|
|
128
149
|
type: "REASONING_MESSAGE_END";
|
|
129
150
|
messageId: string;
|
|
151
|
+
subagentRunId?: string;
|
|
130
152
|
}
|
|
131
153
|
interface AGUIReasoningMessageChunkEvent extends AGUIBaseEvent {
|
|
132
154
|
type: "REASONING_MESSAGE_CHUNK";
|
|
133
155
|
messageId?: string;
|
|
134
156
|
delta?: string;
|
|
157
|
+
subagentRunId?: string;
|
|
135
158
|
}
|
|
136
159
|
interface AGUIReasoningEndEvent extends AGUIBaseEvent {
|
|
137
160
|
type: "REASONING_END";
|
|
138
161
|
messageId: string;
|
|
162
|
+
subagentRunId?: string;
|
|
139
163
|
}
|
|
140
164
|
type AGUIReasoningEncryptedValueSubtype = "tool-call" | "message";
|
|
141
165
|
interface AGUIReasoningEncryptedValueEvent extends AGUIBaseEvent {
|
|
@@ -143,16 +167,40 @@ interface AGUIReasoningEncryptedValueEvent extends AGUIBaseEvent {
|
|
|
143
167
|
subtype: AGUIReasoningEncryptedValueSubtype;
|
|
144
168
|
entityId: string;
|
|
145
169
|
encryptedValue: string;
|
|
170
|
+
subagentRunId?: string;
|
|
171
|
+
}
|
|
172
|
+
interface AGUISubagentStartedEvent extends AGUIBaseEvent {
|
|
173
|
+
type: "SUBAGENT_STARTED";
|
|
174
|
+
subagentRunId: string;
|
|
175
|
+
name: string;
|
|
176
|
+
description?: string;
|
|
177
|
+
parentSubagentRunId?: string;
|
|
178
|
+
parentToolCallId?: string;
|
|
179
|
+
parentMessageId?: string;
|
|
180
|
+
}
|
|
181
|
+
interface AGUISubagentFinishedEvent extends AGUIBaseEvent {
|
|
182
|
+
type: "SUBAGENT_FINISHED";
|
|
183
|
+
subagentRunId: string;
|
|
184
|
+
result?: unknown;
|
|
185
|
+
outcome?: AGUISubagentFinishedOutcome;
|
|
186
|
+
}
|
|
187
|
+
interface AGUISubagentErrorEvent extends AGUIBaseEvent {
|
|
188
|
+
type: "SUBAGENT_ERROR";
|
|
189
|
+
subagentRunId: string;
|
|
190
|
+
message: string;
|
|
191
|
+
code?: string;
|
|
146
192
|
}
|
|
147
193
|
interface AGUIRawEvent extends AGUIBaseEvent {
|
|
148
194
|
type: "RAW";
|
|
149
195
|
event: unknown;
|
|
150
196
|
source?: string;
|
|
197
|
+
subagentRunId?: string;
|
|
151
198
|
}
|
|
152
199
|
interface AGUICustomEvent extends AGUIBaseEvent {
|
|
153
200
|
type: "CUSTOM";
|
|
154
201
|
name: string;
|
|
155
202
|
value: unknown;
|
|
203
|
+
subagentRunId?: string;
|
|
156
204
|
}
|
|
157
205
|
interface AGUIThinkingStartEvent extends AGUIBaseEvent {
|
|
158
206
|
type: "THINKING_START";
|
|
@@ -171,7 +219,7 @@ interface AGUIThinkingTextMessageContentEvent extends AGUIBaseEvent {
|
|
|
171
219
|
interface AGUIThinkingTextMessageEndEvent extends AGUIBaseEvent {
|
|
172
220
|
type: "THINKING_TEXT_MESSAGE_END";
|
|
173
221
|
}
|
|
174
|
-
type AGUIEvent = AGUIRunStartedEvent | AGUIRunFinishedEvent | AGUIRunErrorEvent | AGUIStepStartedEvent | AGUIStepFinishedEvent | AGUITextMessageStartEvent | AGUITextMessageContentEvent | AGUITextMessageEndEvent | AGUITextMessageChunkEvent | AGUIToolCallStartEvent | AGUIToolCallArgsEvent | AGUIToolCallEndEvent | AGUIToolCallChunkEvent | AGUIToolCallResultEvent | AGUIStateSnapshotEvent | AGUIStateDeltaEvent | AGUIMessagesSnapshotEvent | AGUIActivitySnapshotEvent | AGUIActivityDeltaEvent | AGUIReasoningStartEvent | AGUIReasoningMessageStartEvent | AGUIReasoningMessageContentEvent | AGUIReasoningMessageEndEvent | AGUIReasoningMessageChunkEvent | AGUIReasoningEndEvent | AGUIReasoningEncryptedValueEvent | AGUIRawEvent | AGUICustomEvent | AGUIThinkingStartEvent | AGUIThinkingEndEvent | AGUIThinkingTextMessageStartEvent | AGUIThinkingTextMessageContentEvent | AGUIThinkingTextMessageEndEvent;
|
|
222
|
+
type AGUIEvent = AGUIRunStartedEvent | AGUIRunFinishedEvent | AGUIRunErrorEvent | AGUIStepStartedEvent | AGUIStepFinishedEvent | AGUITextMessageStartEvent | AGUITextMessageContentEvent | AGUITextMessageEndEvent | AGUITextMessageChunkEvent | AGUIToolCallStartEvent | AGUIToolCallArgsEvent | AGUIToolCallEndEvent | AGUIToolCallChunkEvent | AGUIToolCallResultEvent | AGUIStateSnapshotEvent | AGUIStateDeltaEvent | AGUIMessagesSnapshotEvent | AGUIActivitySnapshotEvent | AGUIActivityDeltaEvent | AGUIReasoningStartEvent | AGUIReasoningMessageStartEvent | AGUIReasoningMessageContentEvent | AGUIReasoningMessageEndEvent | AGUIReasoningMessageChunkEvent | AGUIReasoningEndEvent | AGUIReasoningEncryptedValueEvent | AGUISubagentStartedEvent | AGUISubagentFinishedEvent | AGUISubagentErrorEvent | AGUIRawEvent | AGUICustomEvent | AGUIThinkingStartEvent | AGUIThinkingEndEvent | AGUIThinkingTextMessageStartEvent | AGUIThinkingTextMessageContentEvent | AGUIThinkingTextMessageEndEvent;
|
|
175
223
|
interface AGUIInterrupt {
|
|
176
224
|
id: string;
|
|
177
225
|
reason: string;
|
|
@@ -180,6 +228,7 @@ interface AGUIInterrupt {
|
|
|
180
228
|
responseSchema?: Record<string, unknown>;
|
|
181
229
|
expiresAt?: string;
|
|
182
230
|
metadata?: Record<string, unknown>;
|
|
231
|
+
subagentRunId?: string;
|
|
183
232
|
}
|
|
184
233
|
interface AGUIResumeEntry {
|
|
185
234
|
interruptId: string;
|
|
@@ -192,6 +241,37 @@ type AGUIRunFinishedOutcome = {
|
|
|
192
241
|
type: "interrupt";
|
|
193
242
|
interrupts: AGUIInterrupt[];
|
|
194
243
|
};
|
|
244
|
+
/**
|
|
245
|
+
* Mirrors `AGUIRunFinishedOutcome` one level down: a subagent's terminal closes
|
|
246
|
+
* its stream segment for this run either because the work completed
|
|
247
|
+
* ("success") or because the workflow is paused awaiting outside input
|
|
248
|
+
* ("suspended" — on resume the same `subagentRunId` is re-announced as a
|
|
249
|
+
* continuation). `interruptIds` names the run-level interrupts this subagent
|
|
250
|
+
* directly owns, and may be absent: an ancestor that suspended because a
|
|
251
|
+
* descendant interrupted owns no interrupt itself.
|
|
252
|
+
*/
|
|
253
|
+
type AGUISubagentFinishedOutcome = {
|
|
254
|
+
type: "success";
|
|
255
|
+
} | {
|
|
256
|
+
type: "suspended";
|
|
257
|
+
interruptIds?: string[];
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Numeric-only token usage summary, mirroring `TokenUsageSchema` in
|
|
261
|
+
* `@ag-ui/core`. Deliberately carries no content-bearing or identifying
|
|
262
|
+
* fields — only provider/model labels and non-negative integer token counts.
|
|
263
|
+
* Carried as an array on RUN_FINISHED / RUN_ERROR so a run that invokes
|
|
264
|
+
* multiple models keeps them separate.
|
|
265
|
+
*/
|
|
266
|
+
interface AGUITokenUsage {
|
|
267
|
+
provider?: string;
|
|
268
|
+
model?: string;
|
|
269
|
+
inputTokens?: number;
|
|
270
|
+
outputTokens?: number;
|
|
271
|
+
totalTokens?: number;
|
|
272
|
+
reasoningTokens?: number;
|
|
273
|
+
cachedInputTokens?: number;
|
|
274
|
+
}
|
|
195
275
|
interface AGUIRunAgentInput {
|
|
196
276
|
threadId: string;
|
|
197
277
|
runId: string;
|
|
@@ -231,6 +311,7 @@ interface AGUIMessage {
|
|
|
231
311
|
error?: string;
|
|
232
312
|
toolCallId?: string;
|
|
233
313
|
toolCalls?: AGUIToolCall[];
|
|
314
|
+
subagentRunId?: string;
|
|
234
315
|
}
|
|
235
316
|
interface AGUIToolDefinition {
|
|
236
317
|
name: string;
|
|
@@ -275,5 +356,5 @@ interface AGUIRecordConfig {
|
|
|
275
356
|
}
|
|
276
357
|
//# sourceMappingURL=agui-types.d.ts.map
|
|
277
358
|
//#endregion
|
|
278
|
-
export { AGUIActivityDeltaEvent, AGUIActivitySnapshotEvent, AGUIBaseEvent, AGUICustomEvent, AGUIEvent, AGUIEventType, AGUIFixture, AGUIFixtureMatch, AGUIInterrupt, AGUIMessage, AGUIMessageContentPart, AGUIMessageRole, AGUIMessagesSnapshotEvent, AGUIMockOptions, AGUIRawEvent, AGUIReasoningEncryptedValueEvent, AGUIReasoningEncryptedValueSubtype, AGUIReasoningEndEvent, AGUIReasoningMessageChunkEvent, AGUIReasoningMessageContentEvent, AGUIReasoningMessageEndEvent, AGUIReasoningMessageStartEvent, AGUIReasoningStartEvent, AGUIRecordConfig, AGUIResumeEntry, AGUIRunAgentInput, AGUIRunErrorEvent, AGUIRunFinishedEvent, AGUIRunFinishedOutcome, AGUIRunStartedEvent, AGUIStateDeltaEvent, AGUIStateSnapshotEvent, AGUIStepFinishedEvent, AGUIStepStartedEvent, AGUITextMessageChunkEvent, AGUITextMessageContentEvent, AGUITextMessageEndEvent, AGUITextMessageRole, AGUITextMessageStartEvent, AGUIThinkingEndEvent, AGUIThinkingStartEvent, AGUIThinkingTextMessageContentEvent, AGUIThinkingTextMessageEndEvent, AGUIThinkingTextMessageStartEvent, AGUIToolCall, AGUIToolCallArgsEvent, AGUIToolCallChunkEvent, AGUIToolCallEndEvent, AGUIToolCallResultEvent, AGUIToolCallStartEvent, AGUIToolDefinition };
|
|
359
|
+
export { AGUIActivityDeltaEvent, AGUIActivitySnapshotEvent, AGUIBaseEvent, AGUICustomEvent, AGUIEvent, AGUIEventType, AGUIFixture, AGUIFixtureMatch, AGUIInterrupt, AGUIMessage, AGUIMessageContentPart, AGUIMessageRole, AGUIMessagesSnapshotEvent, AGUIMockOptions, AGUIRawEvent, AGUIReasoningEncryptedValueEvent, AGUIReasoningEncryptedValueSubtype, AGUIReasoningEndEvent, AGUIReasoningMessageChunkEvent, AGUIReasoningMessageContentEvent, AGUIReasoningMessageEndEvent, AGUIReasoningMessageStartEvent, AGUIReasoningStartEvent, AGUIRecordConfig, AGUIResumeEntry, AGUIRunAgentInput, AGUIRunErrorEvent, AGUIRunFinishedEvent, AGUIRunFinishedOutcome, AGUIRunStartedEvent, AGUIStateDeltaEvent, AGUIStateSnapshotEvent, AGUIStepFinishedEvent, AGUIStepStartedEvent, AGUISubagentErrorEvent, AGUISubagentFinishedEvent, AGUISubagentFinishedOutcome, AGUISubagentStartedEvent, AGUITextMessageChunkEvent, AGUITextMessageContentEvent, AGUITextMessageEndEvent, AGUITextMessageRole, AGUITextMessageStartEvent, AGUIThinkingEndEvent, AGUIThinkingStartEvent, AGUIThinkingTextMessageContentEvent, AGUIThinkingTextMessageEndEvent, AGUIThinkingTextMessageStartEvent, AGUITokenUsage, AGUIToolCall, AGUIToolCallArgsEvent, AGUIToolCallChunkEvent, AGUIToolCallEndEvent, AGUIToolCallResultEvent, AGUIToolCallStartEvent, AGUIToolDefinition };
|
|
279
360
|
//# sourceMappingURL=agui-types.d.ts.map
|
package/dist/agui-types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agui-types.d.ts","names":[],"sources":["../src/agui-types.ts"],"sourcesContent":[],"mappings":";KAOY,aAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"agui-types.d.ts","names":[],"sources":["../src/agui-types.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/aimock-cli.cjs
CHANGED
|
@@ -99,7 +99,6 @@ function runAimockCli(deps = {}) {
|
|
|
99
99
|
port,
|
|
100
100
|
host
|
|
101
101
|
});
|
|
102
|
-
log(`aimock server listening on ${url}`);
|
|
103
102
|
function shutdown() {
|
|
104
103
|
log("Shutting down...");
|
|
105
104
|
process.removeListener("SIGINT", shutdown);
|
|
@@ -111,6 +110,7 @@ function runAimockCli(deps = {}) {
|
|
|
111
110
|
}
|
|
112
111
|
process.on("SIGINT", shutdown);
|
|
113
112
|
process.on("SIGTERM", shutdown);
|
|
113
|
+
log(`aimock server listening on ${url}`);
|
|
114
114
|
if (deps.onReady) deps.onReady({ shutdown });
|
|
115
115
|
}
|
|
116
116
|
main().catch((err) => {
|
package/dist/aimock-cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aimock-cli.cjs","names":["loadConfig","startFromConfig"],"sources":["../src/aimock-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { resolve, basename } from \"node:path\";\nimport { loadConfig, startFromConfig } from \"./config-loader.js\";\nimport { runConvertCli, type ConvertCliDeps } from \"./convert.js\";\n\nconst HELP = `\nUsage: aimock [options]\n aimock convert <format> <input> [output]\n\nOptions:\n -c, --config <path> Path to aimock config JSON file (required)\n -p, --port <number> Port override (default: from config or 0)\n -h, --host <string> Host override (default: from config or 127.0.0.1)\n --help Show this help message\n\nSubcommands:\n convert Convert third-party mock configs to aimock format\n Run \"aimock convert --help\" for details\n`.trim();\n\nexport interface AimockCliDeps {\n argv?: string[];\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n loadConfigFn?: typeof loadConfig;\n startFromConfigFn?: typeof startFromConfig;\n onReady?: (ctx: { shutdown: () => void }) => void;\n convertDeps?: Partial<ConvertCliDeps>;\n}\n\nexport function runAimockCli(deps: AimockCliDeps = {}): void {\n /* v8 ignore next 6 -- defaults used only when called from CLI entry point */\n const argv = deps.argv ?? process.argv.slice(2);\n const log = deps.log ?? console.log.bind(console);\n const logError = deps.logError ?? console.error.bind(console);\n const exit = deps.exit ?? process.exit.bind(process);\n const loadConfigFn = deps.loadConfigFn ?? loadConfig;\n const startFromConfigFn = deps.startFromConfigFn ?? startFromConfig;\n\n // Intercept \"convert\" subcommand before parseArgs (which uses strict mode)\n if (argv[0] === \"convert\") {\n runConvertCli({\n argv: argv.slice(1),\n log,\n logError,\n exit,\n ...deps.convertDeps,\n });\n return;\n }\n\n let values;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\", short: \"c\" },\n port: { type: \"string\", short: \"p\" },\n host: { type: \"string\", short: \"h\" },\n help: { type: \"boolean\", default: false },\n },\n strict: true,\n }));\n } catch (err) {\n /* v8 ignore next -- parseArgs always throws Error subclasses */\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Error: ${msg}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n if (values.help) {\n log(HELP);\n exit(0);\n return;\n }\n if (!values.config) {\n logError(\"Error: --config is required.\\n\\n\" + HELP);\n exit(1);\n return;\n }\n\n const configPath = resolve(values.config);\n let config;\n try {\n config = loadConfigFn(configPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Failed to load config from ${configPath}: ${msg}`);\n exit(1);\n return;\n }\n\n const port = values.port ? Number(values.port) : undefined;\n if (\n port !== undefined &&\n (Number.isNaN(port) || !Number.isInteger(port) || port < 0 || port > 65535)\n ) {\n logError(`Error: invalid port \"${values.port}\".\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const host = values.host;\n\n async function main() {\n const { llmock, url } = await startFromConfigFn(config!, { port, host });\n
|
|
1
|
+
{"version":3,"file":"aimock-cli.cjs","names":["loadConfig","startFromConfig"],"sources":["../src/aimock-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { resolve, basename } from \"node:path\";\nimport { loadConfig, startFromConfig } from \"./config-loader.js\";\nimport { runConvertCli, type ConvertCliDeps } from \"./convert.js\";\n\nconst HELP = `\nUsage: aimock [options]\n aimock convert <format> <input> [output]\n\nOptions:\n -c, --config <path> Path to aimock config JSON file (required)\n -p, --port <number> Port override (default: from config or 0)\n -h, --host <string> Host override (default: from config or 127.0.0.1)\n --help Show this help message\n\nSubcommands:\n convert Convert third-party mock configs to aimock format\n Run \"aimock convert --help\" for details\n`.trim();\n\nexport interface AimockCliDeps {\n argv?: string[];\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n loadConfigFn?: typeof loadConfig;\n startFromConfigFn?: typeof startFromConfig;\n onReady?: (ctx: { shutdown: () => void }) => void;\n convertDeps?: Partial<ConvertCliDeps>;\n}\n\nexport function runAimockCli(deps: AimockCliDeps = {}): void {\n /* v8 ignore next 6 -- defaults used only when called from CLI entry point */\n const argv = deps.argv ?? process.argv.slice(2);\n const log = deps.log ?? console.log.bind(console);\n const logError = deps.logError ?? console.error.bind(console);\n const exit = deps.exit ?? process.exit.bind(process);\n const loadConfigFn = deps.loadConfigFn ?? loadConfig;\n const startFromConfigFn = deps.startFromConfigFn ?? startFromConfig;\n\n // Intercept \"convert\" subcommand before parseArgs (which uses strict mode)\n if (argv[0] === \"convert\") {\n runConvertCli({\n argv: argv.slice(1),\n log,\n logError,\n exit,\n ...deps.convertDeps,\n });\n return;\n }\n\n let values;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\", short: \"c\" },\n port: { type: \"string\", short: \"p\" },\n host: { type: \"string\", short: \"h\" },\n help: { type: \"boolean\", default: false },\n },\n strict: true,\n }));\n } catch (err) {\n /* v8 ignore next -- parseArgs always throws Error subclasses */\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Error: ${msg}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n if (values.help) {\n log(HELP);\n exit(0);\n return;\n }\n if (!values.config) {\n logError(\"Error: --config is required.\\n\\n\" + HELP);\n exit(1);\n return;\n }\n\n const configPath = resolve(values.config);\n let config;\n try {\n config = loadConfigFn(configPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Failed to load config from ${configPath}: ${msg}`);\n exit(1);\n return;\n }\n\n const port = values.port ? Number(values.port) : undefined;\n if (\n port !== undefined &&\n (Number.isNaN(port) || !Number.isInteger(port) || port < 0 || port > 65535)\n ) {\n logError(`Error: invalid port \"${values.port}\".\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const host = values.host;\n\n async function main() {\n const { llmock, url } = await startFromConfigFn(config!, { port, host });\n\n function shutdown() {\n log(\"Shutting down...\");\n process.removeListener(\"SIGINT\", shutdown);\n process.removeListener(\"SIGTERM\", shutdown);\n llmock.stop().then(\n () => exit(0),\n (err) => {\n logError(`Shutdown error: ${err instanceof Error ? err.message : String(err)}`);\n exit(1);\n },\n );\n }\n // Register BEFORE announcing readiness — see the note in src/cli.ts. A supervisor\n // that reacts to the readiness line must never win a race against this listener.\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n log(`aimock server listening on ${url}`);\n\n if (deps.onReady) {\n deps.onReady({ shutdown });\n }\n }\n\n main().catch((err) => {\n logError(err instanceof Error ? err.message : String(err));\n exit(1);\n });\n}\n\n// Run when executed as a script (not when imported for testing).\n/* v8 ignore start -- entry-point guard, exercised by integration tests */\nconst scriptName = process.argv[1] ?? \"\";\nconst base = basename(scriptName);\nif (base === \"aimock\" || base === \"aimock-cli.js\" || base === \"aimock-cli.ts\") {\n runAimockCli();\n}\n/* v8 ignore stop */\n"],"mappings":";;;;;;;;;AAMA,MAAM,OAAO;;;;;;;;;;;;;EAaX,MAAM;AAaR,SAAgB,aAAa,OAAsB,EAAE,EAAQ;;CAE3D,MAAM,OAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,EAAE;CAC/C,MAAM,MAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,QAAQ;CACjD,MAAM,WAAW,KAAK,YAAY,QAAQ,MAAM,KAAK,QAAQ;CAC7D,MAAM,OAAO,KAAK,QAAQ,QAAQ,KAAK,KAAK,QAAQ;CACpD,MAAM,eAAe,KAAK,gBAAgBA;CAC1C,MAAM,oBAAoB,KAAK,qBAAqBC;AAGpD,KAAI,KAAK,OAAO,WAAW;AACzB,gCAAc;GACZ,MAAM,KAAK,MAAM,EAAE;GACnB;GACA;GACA;GACA,GAAG,KAAK;GACT,CAAC;AACF;;CAGF,IAAI;AACJ,KAAI;AACF,GAAC,CAAE,mCAAqB;GACtB,MAAM;GACN,SAAS;IACP,QAAQ;KAAE,MAAM;KAAU,OAAO;KAAK;IACtC,MAAM;KAAE,MAAM;KAAU,OAAO;KAAK;IACpC,MAAM;KAAE,MAAM;KAAU,OAAO;KAAK;IACpC,MAAM;KAAE,MAAM;KAAW,SAAS;KAAO;IAC1C;GACD,QAAQ;GACT,CAAC;UACK,KAAK;AAGZ,WAAS,UADG,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CACrC,MAAM,OAAO;AACpC,OAAK,EAAE;AACP;;AAGF,KAAI,OAAO,MAAM;AACf,MAAI,KAAK;AACT,OAAK,EAAE;AACP;;AAEF,KAAI,CAAC,OAAO,QAAQ;AAClB,WAAS,qCAAqC,KAAK;AACnD,OAAK,EAAE;AACP;;CAGF,MAAM,oCAAqB,OAAO,OAAO;CACzC,IAAI;AACJ,KAAI;AACF,WAAS,aAAa,WAAW;UAC1B,KAAK;AAEZ,WAAS,8BAA8B,WAAW,IADtC,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GACA;AAC5D,OAAK,EAAE;AACP;;CAGF,MAAM,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,GAAG;AACjD,KACE,SAAS,WACR,OAAO,MAAM,KAAK,IAAI,CAAC,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,OAAO,QACrE;AACA,WAAS,wBAAwB,OAAO,KAAK,QAAQ,OAAO;AAC5D,OAAK,EAAE;AACP;;CAEF,MAAM,OAAO,OAAO;CAEpB,eAAe,OAAO;EACpB,MAAM,EAAE,QAAQ,QAAQ,MAAM,kBAAkB,QAAS;GAAE;GAAM;GAAM,CAAC;EAExE,SAAS,WAAW;AAClB,OAAI,mBAAmB;AACvB,WAAQ,eAAe,UAAU,SAAS;AAC1C,WAAQ,eAAe,WAAW,SAAS;AAC3C,UAAO,MAAM,CAAC,WACN,KAAK,EAAE,GACZ,QAAQ;AACP,aAAS,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAC/E,SAAK,EAAE;KAEV;;AAIH,UAAQ,GAAG,UAAU,SAAS;AAC9B,UAAQ,GAAG,WAAW,SAAS;AAE/B,MAAI,8BAA8B,MAAM;AAExC,MAAI,KAAK,QACP,MAAK,QAAQ,EAAE,UAAU,CAAC;;AAI9B,OAAM,CAAC,OAAO,QAAQ;AACpB,WAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC1D,OAAK,EAAE;GACP;;AAMJ,MAAM,+BADa,QAAQ,KAAK,MAAM,GACL;AACjC,IAAI,SAAS,YAAY,SAAS,mBAAmB,SAAS,gBAC5D,eAAc"}
|
package/dist/aimock-cli.js
CHANGED
|
@@ -97,7 +97,6 @@ function runAimockCli(deps = {}) {
|
|
|
97
97
|
port,
|
|
98
98
|
host
|
|
99
99
|
});
|
|
100
|
-
log(`aimock server listening on ${url}`);
|
|
101
100
|
function shutdown() {
|
|
102
101
|
log("Shutting down...");
|
|
103
102
|
process.removeListener("SIGINT", shutdown);
|
|
@@ -109,6 +108,7 @@ function runAimockCli(deps = {}) {
|
|
|
109
108
|
}
|
|
110
109
|
process.on("SIGINT", shutdown);
|
|
111
110
|
process.on("SIGTERM", shutdown);
|
|
111
|
+
log(`aimock server listening on ${url}`);
|
|
112
112
|
if (deps.onReady) deps.onReady({ shutdown });
|
|
113
113
|
}
|
|
114
114
|
main().catch((err) => {
|
package/dist/aimock-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aimock-cli.js","names":[],"sources":["../src/aimock-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { resolve, basename } from \"node:path\";\nimport { loadConfig, startFromConfig } from \"./config-loader.js\";\nimport { runConvertCli, type ConvertCliDeps } from \"./convert.js\";\n\nconst HELP = `\nUsage: aimock [options]\n aimock convert <format> <input> [output]\n\nOptions:\n -c, --config <path> Path to aimock config JSON file (required)\n -p, --port <number> Port override (default: from config or 0)\n -h, --host <string> Host override (default: from config or 127.0.0.1)\n --help Show this help message\n\nSubcommands:\n convert Convert third-party mock configs to aimock format\n Run \"aimock convert --help\" for details\n`.trim();\n\nexport interface AimockCliDeps {\n argv?: string[];\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n loadConfigFn?: typeof loadConfig;\n startFromConfigFn?: typeof startFromConfig;\n onReady?: (ctx: { shutdown: () => void }) => void;\n convertDeps?: Partial<ConvertCliDeps>;\n}\n\nexport function runAimockCli(deps: AimockCliDeps = {}): void {\n /* v8 ignore next 6 -- defaults used only when called from CLI entry point */\n const argv = deps.argv ?? process.argv.slice(2);\n const log = deps.log ?? console.log.bind(console);\n const logError = deps.logError ?? console.error.bind(console);\n const exit = deps.exit ?? process.exit.bind(process);\n const loadConfigFn = deps.loadConfigFn ?? loadConfig;\n const startFromConfigFn = deps.startFromConfigFn ?? startFromConfig;\n\n // Intercept \"convert\" subcommand before parseArgs (which uses strict mode)\n if (argv[0] === \"convert\") {\n runConvertCli({\n argv: argv.slice(1),\n log,\n logError,\n exit,\n ...deps.convertDeps,\n });\n return;\n }\n\n let values;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\", short: \"c\" },\n port: { type: \"string\", short: \"p\" },\n host: { type: \"string\", short: \"h\" },\n help: { type: \"boolean\", default: false },\n },\n strict: true,\n }));\n } catch (err) {\n /* v8 ignore next -- parseArgs always throws Error subclasses */\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Error: ${msg}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n if (values.help) {\n log(HELP);\n exit(0);\n return;\n }\n if (!values.config) {\n logError(\"Error: --config is required.\\n\\n\" + HELP);\n exit(1);\n return;\n }\n\n const configPath = resolve(values.config);\n let config;\n try {\n config = loadConfigFn(configPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Failed to load config from ${configPath}: ${msg}`);\n exit(1);\n return;\n }\n\n const port = values.port ? Number(values.port) : undefined;\n if (\n port !== undefined &&\n (Number.isNaN(port) || !Number.isInteger(port) || port < 0 || port > 65535)\n ) {\n logError(`Error: invalid port \"${values.port}\".\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const host = values.host;\n\n async function main() {\n const { llmock, url } = await startFromConfigFn(config!, { port, host });\n
|
|
1
|
+
{"version":3,"file":"aimock-cli.js","names":[],"sources":["../src/aimock-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { resolve, basename } from \"node:path\";\nimport { loadConfig, startFromConfig } from \"./config-loader.js\";\nimport { runConvertCli, type ConvertCliDeps } from \"./convert.js\";\n\nconst HELP = `\nUsage: aimock [options]\n aimock convert <format> <input> [output]\n\nOptions:\n -c, --config <path> Path to aimock config JSON file (required)\n -p, --port <number> Port override (default: from config or 0)\n -h, --host <string> Host override (default: from config or 127.0.0.1)\n --help Show this help message\n\nSubcommands:\n convert Convert third-party mock configs to aimock format\n Run \"aimock convert --help\" for details\n`.trim();\n\nexport interface AimockCliDeps {\n argv?: string[];\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n loadConfigFn?: typeof loadConfig;\n startFromConfigFn?: typeof startFromConfig;\n onReady?: (ctx: { shutdown: () => void }) => void;\n convertDeps?: Partial<ConvertCliDeps>;\n}\n\nexport function runAimockCli(deps: AimockCliDeps = {}): void {\n /* v8 ignore next 6 -- defaults used only when called from CLI entry point */\n const argv = deps.argv ?? process.argv.slice(2);\n const log = deps.log ?? console.log.bind(console);\n const logError = deps.logError ?? console.error.bind(console);\n const exit = deps.exit ?? process.exit.bind(process);\n const loadConfigFn = deps.loadConfigFn ?? loadConfig;\n const startFromConfigFn = deps.startFromConfigFn ?? startFromConfig;\n\n // Intercept \"convert\" subcommand before parseArgs (which uses strict mode)\n if (argv[0] === \"convert\") {\n runConvertCli({\n argv: argv.slice(1),\n log,\n logError,\n exit,\n ...deps.convertDeps,\n });\n return;\n }\n\n let values;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\", short: \"c\" },\n port: { type: \"string\", short: \"p\" },\n host: { type: \"string\", short: \"h\" },\n help: { type: \"boolean\", default: false },\n },\n strict: true,\n }));\n } catch (err) {\n /* v8 ignore next -- parseArgs always throws Error subclasses */\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Error: ${msg}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n if (values.help) {\n log(HELP);\n exit(0);\n return;\n }\n if (!values.config) {\n logError(\"Error: --config is required.\\n\\n\" + HELP);\n exit(1);\n return;\n }\n\n const configPath = resolve(values.config);\n let config;\n try {\n config = loadConfigFn(configPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Failed to load config from ${configPath}: ${msg}`);\n exit(1);\n return;\n }\n\n const port = values.port ? Number(values.port) : undefined;\n if (\n port !== undefined &&\n (Number.isNaN(port) || !Number.isInteger(port) || port < 0 || port > 65535)\n ) {\n logError(`Error: invalid port \"${values.port}\".\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const host = values.host;\n\n async function main() {\n const { llmock, url } = await startFromConfigFn(config!, { port, host });\n\n function shutdown() {\n log(\"Shutting down...\");\n process.removeListener(\"SIGINT\", shutdown);\n process.removeListener(\"SIGTERM\", shutdown);\n llmock.stop().then(\n () => exit(0),\n (err) => {\n logError(`Shutdown error: ${err instanceof Error ? err.message : String(err)}`);\n exit(1);\n },\n );\n }\n // Register BEFORE announcing readiness — see the note in src/cli.ts. A supervisor\n // that reacts to the readiness line must never win a race against this listener.\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n log(`aimock server listening on ${url}`);\n\n if (deps.onReady) {\n deps.onReady({ shutdown });\n }\n }\n\n main().catch((err) => {\n logError(err instanceof Error ? err.message : String(err));\n exit(1);\n });\n}\n\n// Run when executed as a script (not when imported for testing).\n/* v8 ignore start -- entry-point guard, exercised by integration tests */\nconst scriptName = process.argv[1] ?? \"\";\nconst base = basename(scriptName);\nif (base === \"aimock\" || base === \"aimock-cli.js\" || base === \"aimock-cli.ts\") {\n runAimockCli();\n}\n/* v8 ignore stop */\n"],"mappings":";;;;;;;AAMA,MAAM,OAAO;;;;;;;;;;;;;EAaX,MAAM;AAaR,SAAgB,aAAa,OAAsB,EAAE,EAAQ;;CAE3D,MAAM,OAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,EAAE;CAC/C,MAAM,MAAM,KAAK,OAAO,QAAQ,IAAI,KAAK,QAAQ;CACjD,MAAM,WAAW,KAAK,YAAY,QAAQ,MAAM,KAAK,QAAQ;CAC7D,MAAM,OAAO,KAAK,QAAQ,QAAQ,KAAK,KAAK,QAAQ;CACpD,MAAM,eAAe,KAAK,gBAAgB;CAC1C,MAAM,oBAAoB,KAAK,qBAAqB;AAGpD,KAAI,KAAK,OAAO,WAAW;AACzB,gBAAc;GACZ,MAAM,KAAK,MAAM,EAAE;GACnB;GACA;GACA;GACA,GAAG,KAAK;GACT,CAAC;AACF;;CAGF,IAAI;AACJ,KAAI;AACF,GAAC,CAAE,UAAW,UAAU;GACtB,MAAM;GACN,SAAS;IACP,QAAQ;KAAE,MAAM;KAAU,OAAO;KAAK;IACtC,MAAM;KAAE,MAAM;KAAU,OAAO;KAAK;IACpC,MAAM;KAAE,MAAM;KAAU,OAAO;KAAK;IACpC,MAAM;KAAE,MAAM;KAAW,SAAS;KAAO;IAC1C;GACD,QAAQ;GACT,CAAC;UACK,KAAK;AAGZ,WAAS,UADG,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CACrC,MAAM,OAAO;AACpC,OAAK,EAAE;AACP;;AAGF,KAAI,OAAO,MAAM;AACf,MAAI,KAAK;AACT,OAAK,EAAE;AACP;;AAEF,KAAI,CAAC,OAAO,QAAQ;AAClB,WAAS,qCAAqC,KAAK;AACnD,OAAK,EAAE;AACP;;CAGF,MAAM,aAAa,QAAQ,OAAO,OAAO;CACzC,IAAI;AACJ,KAAI;AACF,WAAS,aAAa,WAAW;UAC1B,KAAK;AAEZ,WAAS,8BAA8B,WAAW,IADtC,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GACA;AAC5D,OAAK,EAAE;AACP;;CAGF,MAAM,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK,GAAG;AACjD,KACE,SAAS,WACR,OAAO,MAAM,KAAK,IAAI,CAAC,OAAO,UAAU,KAAK,IAAI,OAAO,KAAK,OAAO,QACrE;AACA,WAAS,wBAAwB,OAAO,KAAK,QAAQ,OAAO;AAC5D,OAAK,EAAE;AACP;;CAEF,MAAM,OAAO,OAAO;CAEpB,eAAe,OAAO;EACpB,MAAM,EAAE,QAAQ,QAAQ,MAAM,kBAAkB,QAAS;GAAE;GAAM;GAAM,CAAC;EAExE,SAAS,WAAW;AAClB,OAAI,mBAAmB;AACvB,WAAQ,eAAe,UAAU,SAAS;AAC1C,WAAQ,eAAe,WAAW,SAAS;AAC3C,UAAO,MAAM,CAAC,WACN,KAAK,EAAE,GACZ,QAAQ;AACP,aAAS,mBAAmB,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAAG;AAC/E,SAAK,EAAE;KAEV;;AAIH,UAAQ,GAAG,UAAU,SAAS;AAC9B,UAAQ,GAAG,WAAW,SAAS;AAE/B,MAAI,8BAA8B,MAAM;AAExC,MAAI,KAAK,QACP,MAAK,QAAQ,EAAE,UAAU,CAAC;;AAI9B,OAAM,CAAC,OAAO,QAAQ;AACpB,WAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,CAAC;AAC1D,OAAK,EAAE;GACP;;AAMJ,MAAM,OAAO,SADM,QAAQ,KAAK,MAAM,GACL;AACjC,IAAI,SAAS,YAAY,SAAS,mBAAmB,SAAS,gBAC5D,eAAc"}
|
package/dist/cli.cjs
CHANGED
|
@@ -428,8 +428,17 @@ async function main() {
|
|
|
428
428
|
fixtureCountsMaxTestIds: fixtureCountsMax,
|
|
429
429
|
auth: require_api_key_auth.resolveInboundAuth(require_api_key_auth.selectInboundAuthSource(void 0)).publicConfig
|
|
430
430
|
}, mounts);
|
|
431
|
-
logger.info(`aimock server listening on ${instance.url}`);
|
|
432
431
|
let watcher = null;
|
|
432
|
+
function shutdown() {
|
|
433
|
+
logger.info("Shutting down...");
|
|
434
|
+
if (watcher) watcher.close();
|
|
435
|
+
instance.server.close(() => {
|
|
436
|
+
process.exit(0);
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
process.on("SIGINT", shutdown);
|
|
440
|
+
process.on("SIGTERM", shutdown);
|
|
441
|
+
logger.info(`aimock server listening on ${instance.url}`);
|
|
433
442
|
if (watchMode) {
|
|
434
443
|
const primary = sources[0];
|
|
435
444
|
if (!primary) logger.warn("--watch requested but no resolvable fixture sources; skipping watcher");
|
|
@@ -443,15 +452,6 @@ async function main() {
|
|
|
443
452
|
logger.info(`Watching ${primary.path} for changes`);
|
|
444
453
|
}
|
|
445
454
|
}
|
|
446
|
-
function shutdown() {
|
|
447
|
-
logger.info("Shutting down...");
|
|
448
|
-
if (watcher) watcher.close();
|
|
449
|
-
instance.server.close(() => {
|
|
450
|
-
process.exit(0);
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
process.on("SIGINT", shutdown);
|
|
454
|
-
process.on("SIGTERM", shutdown);
|
|
455
455
|
}
|
|
456
456
|
main().catch((err) => {
|
|
457
457
|
console.error(err);
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["Logger","readProviderKeysFromEnv","AGUIMock","resolveFixturesValue","loadFixturesFromDir","loadFixtureFile","validateFixtures","createServer","resolveInboundAuth","selectInboundAuthSource","watchFixtures"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { createServer } from \"./server.js\";\nimport { loadFixtureFile, loadFixturesFromDir, validateFixtures } from \"./fixture-loader.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\nimport { watchFixtures } from \"./watcher.js\";\nimport { AGUIMock } from \"./agui-mock.js\";\nimport { resolveFixturesValue } from \"./fixtures-remote.js\";\nimport { readProviderKeysFromEnv } from \"./provider-auth.js\";\nimport { resolveInboundAuth, selectInboundAuthSource } from \"./api-key-auth.js\";\nimport type { Fixture, ChaosConfig, RecordConfig } from \"./types.js\";\n\nconst HELP = `\nUsage: aimock [options]\n\nOptions:\n -p, --port <number> Port to listen on (default: 4010)\n -h, --host <string> Host to bind to (default: 127.0.0.1)\n -f, --fixtures <value> Fixture source (repeatable). Accepts:\n - filesystem path to a directory or .json file (default: ./fixtures)\n - https:// or http:// URL to a .json fixture file\n -l, --latency <ms> Latency in ms between SSE chunks (default: 0)\n -c, --chunk-size <chars> Chunk size in characters (default: 20)\n -w, --watch Watch fixture path for changes and reload\n --log-level <level> Log verbosity: silent, warn, info, debug (default: info)\n --validate-on-load Validate fixture schemas at startup\n --metrics Enable Prometheus metrics at GET /metrics\n --record Record mode: proxy unmatched requests and save fixtures\n --record-full-model-version Record exact model version without date stripping (default: false)\n --proxy-only Proxy mode: forward unmatched requests without saving\n --strict Strict mode: fail on unmatched requests (overridable per-request via X-AIMock-Strict header)\n --journal-max <n> Max request entries retained in memory (default: 1000, 0 = unbounded)\n --fixture-counts-max <n> Max unique testIds retained in fixture match-count map (default: 500, 0 = unbounded)\n --provider-openai <url> Upstream URL for OpenAI (used with --record)\n --provider-anthropic <url> Upstream URL for Anthropic\n --provider-gemini <url> Upstream URL for Gemini\n --provider-vertexai <url> Upstream URL for Vertex AI\n --provider-bedrock <url> Upstream URL for Bedrock\n --provider-azure <url> Upstream URL for Azure OpenAI\n --provider-ollama <url> Upstream URL for Ollama\n --provider-cohere <url> Upstream URL for Cohere\n --provider-openrouter <url> Upstream URL for OpenRouter (video record proxy)\n --upstream-timeout-ms <ms> Idle timeout (ms) on upstream socket before response (default: 30000)\n --body-timeout-ms <ms> Idle timeout (ms) on upstream response body between chunks (default: 30000)\n --max-proxy-buffer-bytes <n> Cap (bytes) on in-memory proxy-path buffer; full body still relayed (default: 67108864)\n --max-proxy-buffer-frames <n> Cap (frames) on in-memory proxy-path per-frame state; full body still relayed (default: 5000000)\n --agui-record Enable AG-UI recording (proxy unmatched AG-UI requests)\n --agui-upstream <url> Upstream AG-UI agent URL (used with --agui-record)\n --agui-proxy-only AG-UI proxy mode: forward without saving\n --replay-speed <n> Replay speed multiplier (default: 1.0, 2.0 = 2x faster)\n --chaos-drop <rate> Probability (0-1) of dropping requests with 500\n --chaos-malformed <rate> Probability (0-1) of returning malformed JSON\n --chaos-disconnect <rate> Probability (0-1) of destroying connection\n AIMOCK_API_KEYS Comma-separated inbound test API keys (environment only)\n --help Show this help message\n`.trim();\n\nconst { values } = parseArgs({\n options: {\n port: { type: \"string\", short: \"p\", default: \"4010\" },\n host: { type: \"string\", short: \"h\", default: \"127.0.0.1\" },\n fixtures: { type: \"string\", short: \"f\", multiple: true },\n latency: { type: \"string\", short: \"l\", default: \"0\" },\n \"chunk-size\": { type: \"string\", short: \"c\", default: \"20\" },\n watch: { type: \"boolean\", short: \"w\", default: false },\n \"log-level\": { type: \"string\", default: \"info\" },\n \"validate-on-load\": { type: \"boolean\", default: false },\n metrics: { type: \"boolean\", default: false },\n record: { type: \"boolean\", default: false },\n \"record-full-model-version\": { type: \"boolean\", default: false },\n \"proxy-only\": { type: \"boolean\", default: false },\n strict: { type: \"boolean\", default: false },\n \"provider-openai\": { type: \"string\" },\n \"provider-anthropic\": { type: \"string\" },\n \"provider-gemini\": { type: \"string\" },\n \"provider-vertexai\": { type: \"string\" },\n \"provider-bedrock\": { type: \"string\" },\n \"provider-azure\": { type: \"string\" },\n \"provider-ollama\": { type: \"string\" },\n \"provider-cohere\": { type: \"string\" },\n \"provider-openrouter\": { type: \"string\" },\n \"upstream-timeout-ms\": { type: \"string\" },\n \"body-timeout-ms\": { type: \"string\" },\n \"max-proxy-buffer-bytes\": { type: \"string\" },\n \"max-proxy-buffer-frames\": { type: \"string\" },\n \"agui-record\": { type: \"boolean\", default: false },\n \"agui-upstream\": { type: \"string\" },\n \"agui-proxy-only\": { type: \"boolean\", default: false },\n \"replay-speed\": { type: \"string\", default: \"1.0\" },\n \"chaos-drop\": { type: \"string\" },\n \"chaos-malformed\": { type: \"string\" },\n \"chaos-disconnect\": { type: \"string\" },\n \"journal-max\": { type: \"string\", default: \"1000\" },\n \"fixture-counts-max\": { type: \"string\", default: \"500\" },\n help: { type: \"boolean\", default: false },\n },\n strict: true,\n});\n\nif (values.help) {\n console.log(HELP);\n process.exit(0);\n}\n\nconst port = Number(values.port);\nconst host = values.host!;\nconst latency = Number(values.latency);\nconst chunkSize = Number(values[\"chunk-size\"]);\nconst fixtureValues: string[] =\n values.fixtures && values.fixtures.length > 0 ? values.fixtures : [\"./fixtures\"];\nconst watchMode = values.watch!;\nconst validateOnLoad = values[\"validate-on-load\"]!;\nconst logLevelStr = values[\"log-level\"]!;\n\nif (![\"silent\", \"warn\", \"info\", \"debug\"].includes(logLevelStr)) {\n console.error(`Invalid log-level: ${logLevelStr} (must be silent, warn, info, or debug)`);\n process.exit(1);\n}\nconst logLevel = logLevelStr as LogLevel;\n\nif (Number.isNaN(port) || port < 0 || port > 65535) {\n console.error(`Invalid port: ${values.port}`);\n process.exit(1);\n}\n\nif (Number.isNaN(latency) || latency < 0) {\n console.error(`Invalid latency: ${values.latency}`);\n process.exit(1);\n}\n\nif (Number.isNaN(chunkSize) || chunkSize < 1) {\n console.error(`Invalid chunk-size: ${values[\"chunk-size\"]}`);\n process.exit(1);\n}\n\nconst replaySpeed = Number(values[\"replay-speed\"]);\nif (Number.isNaN(replaySpeed) || replaySpeed <= 0) {\n console.error(\"--replay-speed must be a positive number\");\n process.exit(1);\n}\n\nconst journalMax = Number(values[\"journal-max\"]);\nif (Number.isNaN(journalMax) || !Number.isInteger(journalMax) || journalMax < 0) {\n console.error(\n `Invalid journal-max: ${values[\"journal-max\"]} (must be a non-negative integer; 0 = unbounded)`,\n );\n process.exit(1);\n}\n\nconst fixtureCountsMaxStr = values[\"fixture-counts-max\"];\nconst fixtureCountsMax = Number(fixtureCountsMaxStr);\nif (Number.isNaN(fixtureCountsMax) || !Number.isInteger(fixtureCountsMax) || fixtureCountsMax < 0) {\n console.error(\n `Invalid fixture-counts-max: ${fixtureCountsMaxStr} (must be a non-negative integer; 0 = unbounded)`,\n );\n process.exit(1);\n}\n\nconst upstreamTimeoutMsStr = values[\"upstream-timeout-ms\"];\nlet upstreamTimeoutMs: number | undefined;\nif (upstreamTimeoutMsStr !== undefined) {\n upstreamTimeoutMs = Number(upstreamTimeoutMsStr);\n if (!Number.isFinite(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) {\n console.error(\n `Invalid upstream-timeout-ms: ${upstreamTimeoutMsStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst bodyTimeoutMsStr = values[\"body-timeout-ms\"];\nlet bodyTimeoutMs: number | undefined;\nif (bodyTimeoutMsStr !== undefined) {\n bodyTimeoutMs = Number(bodyTimeoutMsStr);\n if (!Number.isFinite(bodyTimeoutMs) || bodyTimeoutMs <= 0) {\n console.error(\n `Invalid body-timeout-ms: ${bodyTimeoutMsStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst maxProxyBufferBytesStr = values[\"max-proxy-buffer-bytes\"];\nlet maxProxyBufferBytes: number | undefined;\nif (maxProxyBufferBytesStr !== undefined) {\n maxProxyBufferBytes = Number(maxProxyBufferBytesStr);\n if (!Number.isFinite(maxProxyBufferBytes) || maxProxyBufferBytes <= 0) {\n console.error(\n `Invalid max-proxy-buffer-bytes: ${maxProxyBufferBytesStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst maxProxyBufferFramesStr = values[\"max-proxy-buffer-frames\"];\nlet maxProxyBufferFrames: number | undefined;\nif (maxProxyBufferFramesStr !== undefined) {\n maxProxyBufferFrames = Number(maxProxyBufferFramesStr);\n if (!Number.isFinite(maxProxyBufferFrames) || maxProxyBufferFrames <= 0) {\n console.error(\n `Invalid max-proxy-buffer-frames: ${maxProxyBufferFramesStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst logger = new Logger(logLevel);\n\n// Parse chaos config from CLI flags\nlet chaos: ChaosConfig | undefined;\n{\n const dropStr = values[\"chaos-drop\"];\n const malformedStr = values[\"chaos-malformed\"];\n const disconnectStr = values[\"chaos-disconnect\"];\n\n if (dropStr !== undefined || malformedStr !== undefined || disconnectStr !== undefined) {\n chaos = {};\n if (dropStr !== undefined) {\n const val = parseFloat(dropStr);\n if (isNaN(val) || val < 0 || val > 1) {\n console.error(`Invalid chaos-drop: ${dropStr} (must be 0-1)`);\n process.exit(1);\n }\n chaos.dropRate = val;\n }\n if (malformedStr !== undefined) {\n const val = parseFloat(malformedStr);\n if (isNaN(val) || val < 0 || val > 1) {\n console.error(`Invalid chaos-malformed: ${malformedStr} (must be 0-1)`);\n process.exit(1);\n }\n chaos.malformedRate = val;\n }\n if (disconnectStr !== undefined) {\n const val = parseFloat(disconnectStr);\n if (isNaN(val) || val < 0 || val > 1) {\n console.error(`Invalid chaos-disconnect: ${disconnectStr} (must be 0-1)`);\n process.exit(1);\n }\n chaos.disconnectRate = val;\n }\n }\n}\n\n// Parse record/proxy config from CLI flags\nlet record: RecordConfig | undefined;\nif (values.record || values[\"proxy-only\"]) {\n const providers: RecordConfig[\"providers\"] = {};\n if (values[\"provider-openai\"]) providers.openai = values[\"provider-openai\"];\n if (values[\"provider-anthropic\"]) providers.anthropic = values[\"provider-anthropic\"];\n if (values[\"provider-gemini\"]) providers.gemini = values[\"provider-gemini\"];\n if (values[\"provider-vertexai\"]) providers.vertexai = values[\"provider-vertexai\"];\n if (values[\"provider-bedrock\"]) providers.bedrock = values[\"provider-bedrock\"];\n if (values[\"provider-azure\"]) providers.azure = values[\"provider-azure\"];\n if (values[\"provider-ollama\"]) providers.ollama = values[\"provider-ollama\"];\n if (values[\"provider-cohere\"]) providers.cohere = values[\"provider-cohere\"];\n if (values[\"provider-openrouter\"]) providers.openrouter = values[\"provider-openrouter\"];\n\n if (Object.keys(providers).length === 0) {\n console.error(\n `Error: --${values[\"proxy-only\"] ? \"proxy-only\" : \"record\"} requires at least one --provider-* flag`,\n );\n process.exit(1);\n }\n\n // For --record, the first --fixtures value is the base path for the recording\n // destination and must be a local filesystem path — writing to a URL is not supported.\n // For --proxy-only, unmatched requests are forwarded without saving, so no writable\n // destination is required; URL-only --fixtures is valid in that mode.\n const recordBase = fixtureValues[0];\n const recordBaseIsUrl = /^https?:\\/\\//i.test(recordBase);\n if (values.record && recordBaseIsUrl) {\n console.error(\n `Error: --record requires a local --fixtures path for the recording destination; got URL ${recordBase}`,\n );\n process.exit(1);\n }\n record = {\n providers,\n // aimock's own upstream keys, sourced from AIMOCK_PROVIDER_*_KEY env vars\n // (not CLI flags — secrets must not appear in `ps`). Injected on a\n // fixture-miss passthrough when the caller sent no/dummy credential.\n providerKeys: readProviderKeysFromEnv(),\n // In proxy-only mode with only URL sources, fixturePath is never consumed\n // (recorder.ts skips disk writes when proxyOnly is set). Leave it undefined\n // rather than resolving a URL string as a filesystem path.\n fixturePath: recordBaseIsUrl ? undefined : resolve(recordBase, \"recorded\"),\n proxyOnly: values[\"proxy-only\"],\n recordFullModelVersion: values[\"record-full-model-version\"],\n upstreamTimeoutMs,\n bodyTimeoutMs,\n maxProxyBufferBytes,\n maxProxyBufferFrames,\n };\n} else {\n // These flags configure upstream proxying — without --record or\n // --proxy-only they would be parsed and then silently dropped. Routed\n // through the constructed logger so --log-level is respected.\n const droppedProviderFlags = (\n [\n \"provider-openai\",\n \"provider-anthropic\",\n \"provider-gemini\",\n \"provider-vertexai\",\n \"provider-bedrock\",\n \"provider-azure\",\n \"provider-ollama\",\n \"provider-cohere\",\n \"provider-openrouter\",\n ] as const\n ).filter((flag) => values[flag] !== undefined);\n if (droppedProviderFlags.length > 0) {\n logger.warn(\n `--${droppedProviderFlags.join(\"/--\")} only apply to --record/--proxy-only upstream proxying — ignored without one of those flags.`,\n );\n }\n if (\n upstreamTimeoutMs !== undefined ||\n bodyTimeoutMs !== undefined ||\n maxProxyBufferBytes !== undefined ||\n maxProxyBufferFrames !== undefined\n ) {\n logger.warn(\n \"--upstream-timeout-ms/--body-timeout-ms/--max-proxy-buffer-bytes/--max-proxy-buffer-frames only apply to --record/--proxy-only upstream proxying — ignored without one of those flags.\",\n );\n }\n}\n\n// Parse AG-UI record/proxy config from CLI flags\nlet aguiMount: { path: string; handler: AGUIMock } | undefined;\nif (values[\"agui-record\"] || values[\"agui-proxy-only\"]) {\n if (!values[\"agui-upstream\"]) {\n console.error(\"Error: --agui-record/--agui-proxy-only requires --agui-upstream\");\n process.exit(1);\n }\n // --agui-record writes recorded AG-UI fixtures to disk, so a URL source is unsupported.\n // --agui-proxy-only forwards without saving, so URL-only --fixtures is valid.\n const aguiBase = fixtureValues[0];\n const aguiBaseIsUrl = /^https?:\\/\\//i.test(aguiBase);\n if (values[\"agui-record\"] && aguiBaseIsUrl) {\n console.error(\n `Error: --agui-record requires a local --fixtures path for the recording destination; got URL ${aguiBase}`,\n );\n process.exit(1);\n }\n const agui = new AGUIMock();\n agui.enableRecording({\n upstream: values[\"agui-upstream\"],\n // In proxy-only mode with a URL-only --fixtures, the AG-UI recorder never\n // writes to disk (see agui-recorder.ts). Leave fixturePath undefined rather\n // than resolving a URL as a filesystem path.\n fixturePath: aguiBaseIsUrl ? undefined : resolve(aguiBase, \"agui-recorded\"),\n proxyOnly: values[\"agui-proxy-only\"],\n });\n aguiMount = { path: \"/agui\", handler: agui };\n}\n\ninterface ResolvedFixtureSource {\n source: string;\n path: string;\n isDir: boolean;\n}\n\nasync function resolveAllFixtureSources(): Promise<ResolvedFixtureSource[]> {\n const resolved: ResolvedFixtureSource[] = [];\n for (const value of fixtureValues) {\n let local;\n try {\n local = await resolveFixturesValue(value, {\n validateOnLoad,\n logger,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`Failed to resolve --fixtures value \"${value}\": ${msg}`);\n process.exit(1);\n }\n if (!local.path) {\n // Remote fetch failed without validate-on-load and no cache — already warned; skip.\n continue;\n }\n try {\n const stat = statSync(local.path);\n resolved.push({ source: local.source, path: local.path, isDir: stat.isDirectory() });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n console.error(`Fixtures path not found: ${local.path}`);\n } else {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`Failed to load fixtures from ${local.path}: ${msg}`);\n }\n process.exit(1);\n }\n }\n return resolved;\n}\n\nfunction loadSource(source: ResolvedFixtureSource): Fixture[] {\n return source.isDir\n ? loadFixturesFromDir(source.path, logger)\n : loadFixtureFile(source.path, logger);\n}\n\nasync function main() {\n const sources = await resolveAllFixtureSources();\n\n const fixtures: Fixture[] = [];\n for (const src of sources) {\n fixtures.push(...loadSource(src));\n }\n\n if (fixtures.length === 0) {\n if (validateOnLoad || values.strict) {\n console.error(\"Error: No fixtures loaded and validation/strict mode is enabled — aborting.\");\n process.exit(1);\n }\n console.warn(\"Warning: No fixtures loaded. The server will return 404 for all requests.\");\n }\n\n const sourceLabel = sources.map((s) => s.source).join(\", \") || \"<none>\";\n logger.info(`Loaded ${fixtures.length} fixture(s) from ${sourceLabel}`);\n\n // Validate fixtures if requested\n if (validateOnLoad) {\n const results = validateFixtures(fixtures);\n const errors = results.filter((r) => r.severity === \"error\");\n const warnings = results.filter((r) => r.severity === \"warning\");\n\n for (const w of warnings) {\n logger.warn(`Fixture ${w.fixtureIndex}: ${w.message}`);\n }\n for (const e of errors) {\n logger.error(`Fixture ${e.fixtureIndex}: ${e.message}`);\n }\n\n if (errors.length > 0) {\n console.error(`Validation failed: ${errors.length} error(s), ${warnings.length} warning(s)`);\n process.exit(1);\n }\n }\n\n const mounts = aguiMount ? [aguiMount] : undefined;\n\n const instance = await createServer(\n fixtures,\n {\n port,\n host,\n latency,\n chunkSize,\n replaySpeed,\n logLevel,\n chaos,\n metrics: values.metrics,\n record,\n strict: values.strict,\n journalMaxEntries: journalMax,\n fixtureCountsMaxTestIds: fixtureCountsMax,\n auth: resolveInboundAuth(selectInboundAuthSource(undefined)).publicConfig,\n },\n mounts,\n );\n\n logger.info(`aimock server listening on ${instance.url}`);\n\n // Start file watcher if requested. Only the first local source is watched —\n // remote URL sources are fetched once at boot and are not monitored.\n let watcher: { close: () => void } | null = null;\n if (watchMode) {\n const primary = sources[0];\n if (!primary) {\n logger.warn(\"--watch requested but no resolvable fixture sources; skipping watcher\");\n } else {\n const loadFn = (): Fixture[] => loadSource(primary);\n watcher = watchFixtures(primary.path, fixtures, loadFn, {\n logger,\n validate: validateOnLoad,\n validateFn: validateFixtures,\n });\n logger.info(`Watching ${primary.path} for changes`);\n }\n }\n\n function shutdown() {\n logger.info(\"Shutting down...\");\n if (watcher) watcher.close();\n instance.server.close(() => {\n process.exit(0);\n });\n }\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["Logger","readProviderKeysFromEnv","AGUIMock","resolveFixturesValue","loadFixturesFromDir","loadFixtureFile","validateFixtures","createServer","resolveInboundAuth","selectInboundAuthSource","watchFixtures"],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { createServer } from \"./server.js\";\nimport { loadFixtureFile, loadFixturesFromDir, validateFixtures } from \"./fixture-loader.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\nimport { watchFixtures } from \"./watcher.js\";\nimport { AGUIMock } from \"./agui-mock.js\";\nimport { resolveFixturesValue } from \"./fixtures-remote.js\";\nimport { readProviderKeysFromEnv } from \"./provider-auth.js\";\nimport { resolveInboundAuth, selectInboundAuthSource } from \"./api-key-auth.js\";\nimport type { Fixture, ChaosConfig, RecordConfig } from \"./types.js\";\n\nconst HELP = `\nUsage: aimock [options]\n\nOptions:\n -p, --port <number> Port to listen on (default: 4010)\n -h, --host <string> Host to bind to (default: 127.0.0.1)\n -f, --fixtures <value> Fixture source (repeatable). Accepts:\n - filesystem path to a directory or .json file (default: ./fixtures)\n - https:// or http:// URL to a .json fixture file\n -l, --latency <ms> Latency in ms between SSE chunks (default: 0)\n -c, --chunk-size <chars> Chunk size in characters (default: 20)\n -w, --watch Watch fixture path for changes and reload\n --log-level <level> Log verbosity: silent, warn, info, debug (default: info)\n --validate-on-load Validate fixture schemas at startup\n --metrics Enable Prometheus metrics at GET /metrics\n --record Record mode: proxy unmatched requests and save fixtures\n --record-full-model-version Record exact model version without date stripping (default: false)\n --proxy-only Proxy mode: forward unmatched requests without saving\n --strict Strict mode: fail on unmatched requests (overridable per-request via X-AIMock-Strict header)\n --journal-max <n> Max request entries retained in memory (default: 1000, 0 = unbounded)\n --fixture-counts-max <n> Max unique testIds retained in fixture match-count map (default: 500, 0 = unbounded)\n --provider-openai <url> Upstream URL for OpenAI (used with --record)\n --provider-anthropic <url> Upstream URL for Anthropic\n --provider-gemini <url> Upstream URL for Gemini\n --provider-vertexai <url> Upstream URL for Vertex AI\n --provider-bedrock <url> Upstream URL for Bedrock\n --provider-azure <url> Upstream URL for Azure OpenAI\n --provider-ollama <url> Upstream URL for Ollama\n --provider-cohere <url> Upstream URL for Cohere\n --provider-openrouter <url> Upstream URL for OpenRouter (video record proxy)\n --upstream-timeout-ms <ms> Idle timeout (ms) on upstream socket before response (default: 30000)\n --body-timeout-ms <ms> Idle timeout (ms) on upstream response body between chunks (default: 30000)\n --max-proxy-buffer-bytes <n> Cap (bytes) on in-memory proxy-path buffer; full body still relayed (default: 67108864)\n --max-proxy-buffer-frames <n> Cap (frames) on in-memory proxy-path per-frame state; full body still relayed (default: 5000000)\n --agui-record Enable AG-UI recording (proxy unmatched AG-UI requests)\n --agui-upstream <url> Upstream AG-UI agent URL (used with --agui-record)\n --agui-proxy-only AG-UI proxy mode: forward without saving\n --replay-speed <n> Replay speed multiplier (default: 1.0, 2.0 = 2x faster)\n --chaos-drop <rate> Probability (0-1) of dropping requests with 500\n --chaos-malformed <rate> Probability (0-1) of returning malformed JSON\n --chaos-disconnect <rate> Probability (0-1) of destroying connection\n AIMOCK_API_KEYS Comma-separated inbound test API keys (environment only)\n --help Show this help message\n`.trim();\n\nconst { values } = parseArgs({\n options: {\n port: { type: \"string\", short: \"p\", default: \"4010\" },\n host: { type: \"string\", short: \"h\", default: \"127.0.0.1\" },\n fixtures: { type: \"string\", short: \"f\", multiple: true },\n latency: { type: \"string\", short: \"l\", default: \"0\" },\n \"chunk-size\": { type: \"string\", short: \"c\", default: \"20\" },\n watch: { type: \"boolean\", short: \"w\", default: false },\n \"log-level\": { type: \"string\", default: \"info\" },\n \"validate-on-load\": { type: \"boolean\", default: false },\n metrics: { type: \"boolean\", default: false },\n record: { type: \"boolean\", default: false },\n \"record-full-model-version\": { type: \"boolean\", default: false },\n \"proxy-only\": { type: \"boolean\", default: false },\n strict: { type: \"boolean\", default: false },\n \"provider-openai\": { type: \"string\" },\n \"provider-anthropic\": { type: \"string\" },\n \"provider-gemini\": { type: \"string\" },\n \"provider-vertexai\": { type: \"string\" },\n \"provider-bedrock\": { type: \"string\" },\n \"provider-azure\": { type: \"string\" },\n \"provider-ollama\": { type: \"string\" },\n \"provider-cohere\": { type: \"string\" },\n \"provider-openrouter\": { type: \"string\" },\n \"upstream-timeout-ms\": { type: \"string\" },\n \"body-timeout-ms\": { type: \"string\" },\n \"max-proxy-buffer-bytes\": { type: \"string\" },\n \"max-proxy-buffer-frames\": { type: \"string\" },\n \"agui-record\": { type: \"boolean\", default: false },\n \"agui-upstream\": { type: \"string\" },\n \"agui-proxy-only\": { type: \"boolean\", default: false },\n \"replay-speed\": { type: \"string\", default: \"1.0\" },\n \"chaos-drop\": { type: \"string\" },\n \"chaos-malformed\": { type: \"string\" },\n \"chaos-disconnect\": { type: \"string\" },\n \"journal-max\": { type: \"string\", default: \"1000\" },\n \"fixture-counts-max\": { type: \"string\", default: \"500\" },\n help: { type: \"boolean\", default: false },\n },\n strict: true,\n});\n\nif (values.help) {\n console.log(HELP);\n process.exit(0);\n}\n\nconst port = Number(values.port);\nconst host = values.host!;\nconst latency = Number(values.latency);\nconst chunkSize = Number(values[\"chunk-size\"]);\nconst fixtureValues: string[] =\n values.fixtures && values.fixtures.length > 0 ? values.fixtures : [\"./fixtures\"];\nconst watchMode = values.watch!;\nconst validateOnLoad = values[\"validate-on-load\"]!;\nconst logLevelStr = values[\"log-level\"]!;\n\nif (![\"silent\", \"warn\", \"info\", \"debug\"].includes(logLevelStr)) {\n console.error(`Invalid log-level: ${logLevelStr} (must be silent, warn, info, or debug)`);\n process.exit(1);\n}\nconst logLevel = logLevelStr as LogLevel;\n\nif (Number.isNaN(port) || port < 0 || port > 65535) {\n console.error(`Invalid port: ${values.port}`);\n process.exit(1);\n}\n\nif (Number.isNaN(latency) || latency < 0) {\n console.error(`Invalid latency: ${values.latency}`);\n process.exit(1);\n}\n\nif (Number.isNaN(chunkSize) || chunkSize < 1) {\n console.error(`Invalid chunk-size: ${values[\"chunk-size\"]}`);\n process.exit(1);\n}\n\nconst replaySpeed = Number(values[\"replay-speed\"]);\nif (Number.isNaN(replaySpeed) || replaySpeed <= 0) {\n console.error(\"--replay-speed must be a positive number\");\n process.exit(1);\n}\n\nconst journalMax = Number(values[\"journal-max\"]);\nif (Number.isNaN(journalMax) || !Number.isInteger(journalMax) || journalMax < 0) {\n console.error(\n `Invalid journal-max: ${values[\"journal-max\"]} (must be a non-negative integer; 0 = unbounded)`,\n );\n process.exit(1);\n}\n\nconst fixtureCountsMaxStr = values[\"fixture-counts-max\"];\nconst fixtureCountsMax = Number(fixtureCountsMaxStr);\nif (Number.isNaN(fixtureCountsMax) || !Number.isInteger(fixtureCountsMax) || fixtureCountsMax < 0) {\n console.error(\n `Invalid fixture-counts-max: ${fixtureCountsMaxStr} (must be a non-negative integer; 0 = unbounded)`,\n );\n process.exit(1);\n}\n\nconst upstreamTimeoutMsStr = values[\"upstream-timeout-ms\"];\nlet upstreamTimeoutMs: number | undefined;\nif (upstreamTimeoutMsStr !== undefined) {\n upstreamTimeoutMs = Number(upstreamTimeoutMsStr);\n if (!Number.isFinite(upstreamTimeoutMs) || upstreamTimeoutMs <= 0) {\n console.error(\n `Invalid upstream-timeout-ms: ${upstreamTimeoutMsStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst bodyTimeoutMsStr = values[\"body-timeout-ms\"];\nlet bodyTimeoutMs: number | undefined;\nif (bodyTimeoutMsStr !== undefined) {\n bodyTimeoutMs = Number(bodyTimeoutMsStr);\n if (!Number.isFinite(bodyTimeoutMs) || bodyTimeoutMs <= 0) {\n console.error(\n `Invalid body-timeout-ms: ${bodyTimeoutMsStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst maxProxyBufferBytesStr = values[\"max-proxy-buffer-bytes\"];\nlet maxProxyBufferBytes: number | undefined;\nif (maxProxyBufferBytesStr !== undefined) {\n maxProxyBufferBytes = Number(maxProxyBufferBytesStr);\n if (!Number.isFinite(maxProxyBufferBytes) || maxProxyBufferBytes <= 0) {\n console.error(\n `Invalid max-proxy-buffer-bytes: ${maxProxyBufferBytesStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst maxProxyBufferFramesStr = values[\"max-proxy-buffer-frames\"];\nlet maxProxyBufferFrames: number | undefined;\nif (maxProxyBufferFramesStr !== undefined) {\n maxProxyBufferFrames = Number(maxProxyBufferFramesStr);\n if (!Number.isFinite(maxProxyBufferFrames) || maxProxyBufferFrames <= 0) {\n console.error(\n `Invalid max-proxy-buffer-frames: ${maxProxyBufferFramesStr} (must be a positive finite number)`,\n );\n process.exit(1);\n }\n}\n\nconst logger = new Logger(logLevel);\n\n// Parse chaos config from CLI flags\nlet chaos: ChaosConfig | undefined;\n{\n const dropStr = values[\"chaos-drop\"];\n const malformedStr = values[\"chaos-malformed\"];\n const disconnectStr = values[\"chaos-disconnect\"];\n\n if (dropStr !== undefined || malformedStr !== undefined || disconnectStr !== undefined) {\n chaos = {};\n if (dropStr !== undefined) {\n const val = parseFloat(dropStr);\n if (isNaN(val) || val < 0 || val > 1) {\n console.error(`Invalid chaos-drop: ${dropStr} (must be 0-1)`);\n process.exit(1);\n }\n chaos.dropRate = val;\n }\n if (malformedStr !== undefined) {\n const val = parseFloat(malformedStr);\n if (isNaN(val) || val < 0 || val > 1) {\n console.error(`Invalid chaos-malformed: ${malformedStr} (must be 0-1)`);\n process.exit(1);\n }\n chaos.malformedRate = val;\n }\n if (disconnectStr !== undefined) {\n const val = parseFloat(disconnectStr);\n if (isNaN(val) || val < 0 || val > 1) {\n console.error(`Invalid chaos-disconnect: ${disconnectStr} (must be 0-1)`);\n process.exit(1);\n }\n chaos.disconnectRate = val;\n }\n }\n}\n\n// Parse record/proxy config from CLI flags\nlet record: RecordConfig | undefined;\nif (values.record || values[\"proxy-only\"]) {\n const providers: RecordConfig[\"providers\"] = {};\n if (values[\"provider-openai\"]) providers.openai = values[\"provider-openai\"];\n if (values[\"provider-anthropic\"]) providers.anthropic = values[\"provider-anthropic\"];\n if (values[\"provider-gemini\"]) providers.gemini = values[\"provider-gemini\"];\n if (values[\"provider-vertexai\"]) providers.vertexai = values[\"provider-vertexai\"];\n if (values[\"provider-bedrock\"]) providers.bedrock = values[\"provider-bedrock\"];\n if (values[\"provider-azure\"]) providers.azure = values[\"provider-azure\"];\n if (values[\"provider-ollama\"]) providers.ollama = values[\"provider-ollama\"];\n if (values[\"provider-cohere\"]) providers.cohere = values[\"provider-cohere\"];\n if (values[\"provider-openrouter\"]) providers.openrouter = values[\"provider-openrouter\"];\n\n if (Object.keys(providers).length === 0) {\n console.error(\n `Error: --${values[\"proxy-only\"] ? \"proxy-only\" : \"record\"} requires at least one --provider-* flag`,\n );\n process.exit(1);\n }\n\n // For --record, the first --fixtures value is the base path for the recording\n // destination and must be a local filesystem path — writing to a URL is not supported.\n // For --proxy-only, unmatched requests are forwarded without saving, so no writable\n // destination is required; URL-only --fixtures is valid in that mode.\n const recordBase = fixtureValues[0];\n const recordBaseIsUrl = /^https?:\\/\\//i.test(recordBase);\n if (values.record && recordBaseIsUrl) {\n console.error(\n `Error: --record requires a local --fixtures path for the recording destination; got URL ${recordBase}`,\n );\n process.exit(1);\n }\n record = {\n providers,\n // aimock's own upstream keys, sourced from AIMOCK_PROVIDER_*_KEY env vars\n // (not CLI flags — secrets must not appear in `ps`). Injected on a\n // fixture-miss passthrough when the caller sent no/dummy credential.\n providerKeys: readProviderKeysFromEnv(),\n // In proxy-only mode with only URL sources, fixturePath is never consumed\n // (recorder.ts skips disk writes when proxyOnly is set). Leave it undefined\n // rather than resolving a URL string as a filesystem path.\n fixturePath: recordBaseIsUrl ? undefined : resolve(recordBase, \"recorded\"),\n proxyOnly: values[\"proxy-only\"],\n recordFullModelVersion: values[\"record-full-model-version\"],\n upstreamTimeoutMs,\n bodyTimeoutMs,\n maxProxyBufferBytes,\n maxProxyBufferFrames,\n };\n} else {\n // These flags configure upstream proxying — without --record or\n // --proxy-only they would be parsed and then silently dropped. Routed\n // through the constructed logger so --log-level is respected.\n const droppedProviderFlags = (\n [\n \"provider-openai\",\n \"provider-anthropic\",\n \"provider-gemini\",\n \"provider-vertexai\",\n \"provider-bedrock\",\n \"provider-azure\",\n \"provider-ollama\",\n \"provider-cohere\",\n \"provider-openrouter\",\n ] as const\n ).filter((flag) => values[flag] !== undefined);\n if (droppedProviderFlags.length > 0) {\n logger.warn(\n `--${droppedProviderFlags.join(\"/--\")} only apply to --record/--proxy-only upstream proxying — ignored without one of those flags.`,\n );\n }\n if (\n upstreamTimeoutMs !== undefined ||\n bodyTimeoutMs !== undefined ||\n maxProxyBufferBytes !== undefined ||\n maxProxyBufferFrames !== undefined\n ) {\n logger.warn(\n \"--upstream-timeout-ms/--body-timeout-ms/--max-proxy-buffer-bytes/--max-proxy-buffer-frames only apply to --record/--proxy-only upstream proxying — ignored without one of those flags.\",\n );\n }\n}\n\n// Parse AG-UI record/proxy config from CLI flags\nlet aguiMount: { path: string; handler: AGUIMock } | undefined;\nif (values[\"agui-record\"] || values[\"agui-proxy-only\"]) {\n if (!values[\"agui-upstream\"]) {\n console.error(\"Error: --agui-record/--agui-proxy-only requires --agui-upstream\");\n process.exit(1);\n }\n // --agui-record writes recorded AG-UI fixtures to disk, so a URL source is unsupported.\n // --agui-proxy-only forwards without saving, so URL-only --fixtures is valid.\n const aguiBase = fixtureValues[0];\n const aguiBaseIsUrl = /^https?:\\/\\//i.test(aguiBase);\n if (values[\"agui-record\"] && aguiBaseIsUrl) {\n console.error(\n `Error: --agui-record requires a local --fixtures path for the recording destination; got URL ${aguiBase}`,\n );\n process.exit(1);\n }\n const agui = new AGUIMock();\n agui.enableRecording({\n upstream: values[\"agui-upstream\"],\n // In proxy-only mode with a URL-only --fixtures, the AG-UI recorder never\n // writes to disk (see agui-recorder.ts). Leave fixturePath undefined rather\n // than resolving a URL as a filesystem path.\n fixturePath: aguiBaseIsUrl ? undefined : resolve(aguiBase, \"agui-recorded\"),\n proxyOnly: values[\"agui-proxy-only\"],\n });\n aguiMount = { path: \"/agui\", handler: agui };\n}\n\ninterface ResolvedFixtureSource {\n source: string;\n path: string;\n isDir: boolean;\n}\n\nasync function resolveAllFixtureSources(): Promise<ResolvedFixtureSource[]> {\n const resolved: ResolvedFixtureSource[] = [];\n for (const value of fixtureValues) {\n let local;\n try {\n local = await resolveFixturesValue(value, {\n validateOnLoad,\n logger,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`Failed to resolve --fixtures value \"${value}\": ${msg}`);\n process.exit(1);\n }\n if (!local.path) {\n // Remote fetch failed without validate-on-load and no cache — already warned; skip.\n continue;\n }\n try {\n const stat = statSync(local.path);\n resolved.push({ source: local.source, path: local.path, isDir: stat.isDirectory() });\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n console.error(`Fixtures path not found: ${local.path}`);\n } else {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(`Failed to load fixtures from ${local.path}: ${msg}`);\n }\n process.exit(1);\n }\n }\n return resolved;\n}\n\nfunction loadSource(source: ResolvedFixtureSource): Fixture[] {\n return source.isDir\n ? loadFixturesFromDir(source.path, logger)\n : loadFixtureFile(source.path, logger);\n}\n\nasync function main() {\n const sources = await resolveAllFixtureSources();\n\n const fixtures: Fixture[] = [];\n for (const src of sources) {\n fixtures.push(...loadSource(src));\n }\n\n if (fixtures.length === 0) {\n if (validateOnLoad || values.strict) {\n console.error(\"Error: No fixtures loaded and validation/strict mode is enabled — aborting.\");\n process.exit(1);\n }\n console.warn(\"Warning: No fixtures loaded. The server will return 404 for all requests.\");\n }\n\n const sourceLabel = sources.map((s) => s.source).join(\", \") || \"<none>\";\n logger.info(`Loaded ${fixtures.length} fixture(s) from ${sourceLabel}`);\n\n // Validate fixtures if requested\n if (validateOnLoad) {\n const results = validateFixtures(fixtures);\n const errors = results.filter((r) => r.severity === \"error\");\n const warnings = results.filter((r) => r.severity === \"warning\");\n\n for (const w of warnings) {\n logger.warn(`Fixture ${w.fixtureIndex}: ${w.message}`);\n }\n for (const e of errors) {\n logger.error(`Fixture ${e.fixtureIndex}: ${e.message}`);\n }\n\n if (errors.length > 0) {\n console.error(`Validation failed: ${errors.length} error(s), ${warnings.length} warning(s)`);\n process.exit(1);\n }\n }\n\n const mounts = aguiMount ? [aguiMount] : undefined;\n\n const instance = await createServer(\n fixtures,\n {\n port,\n host,\n latency,\n chunkSize,\n replaySpeed,\n logLevel,\n chaos,\n metrics: values.metrics,\n record,\n strict: values.strict,\n journalMaxEntries: journalMax,\n fixtureCountsMaxTestIds: fixtureCountsMax,\n auth: resolveInboundAuth(selectInboundAuthSource(undefined)).publicConfig,\n },\n mounts,\n );\n\n // Only the first local source is watched — remote URL sources are fetched once\n // at boot and are not monitored. Declared before the readiness announcement so\n // shutdown can close it whenever the signal arrives.\n let watcher: { close: () => void } | null = null;\n\n function shutdown() {\n logger.info(\"Shutting down...\");\n if (watcher) watcher.close();\n instance.server.close(() => {\n process.exit(0);\n });\n }\n\n // Register BEFORE announcing readiness. Writes to a pipe are synchronous on Linux\n // (and to a file on every POSIX platform), so a supervisor that reacts to the line\n // below can deliver SIGTERM while this process is still mid-statement. Announcing\n // first left a window in which SIGTERM hit Node's default disposition, which\n // re-raises: the process died with a null exit code instead of shutting down.\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n logger.info(`aimock server listening on ${instance.url}`);\n\n // Start file watcher if requested.\n if (watchMode) {\n const primary = sources[0];\n if (!primary) {\n logger.warn(\"--watch requested but no resolvable fixture sources; skipping watcher\");\n } else {\n const loadFn = (): Fixture[] => loadSource(primary);\n watcher = watchFixtures(primary.path, fixtures, loadFn, {\n logger,\n validate: validateOnLoad,\n validateFn: validateFixtures,\n });\n logger.info(`Watching ${primary.path} for changes`);\n }\n }\n}\n\nmain().catch((err) => {\n console.error(err);\n process.exit(1);\n});\n"],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -427,8 +427,17 @@ async function main() {
|
|
|
427
427
|
fixtureCountsMaxTestIds: fixtureCountsMax,
|
|
428
428
|
auth: resolveInboundAuth(selectInboundAuthSource(void 0)).publicConfig
|
|
429
429
|
}, mounts);
|
|
430
|
-
logger.info(`aimock server listening on ${instance.url}`);
|
|
431
430
|
let watcher = null;
|
|
431
|
+
function shutdown() {
|
|
432
|
+
logger.info("Shutting down...");
|
|
433
|
+
if (watcher) watcher.close();
|
|
434
|
+
instance.server.close(() => {
|
|
435
|
+
process.exit(0);
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
process.on("SIGINT", shutdown);
|
|
439
|
+
process.on("SIGTERM", shutdown);
|
|
440
|
+
logger.info(`aimock server listening on ${instance.url}`);
|
|
432
441
|
if (watchMode) {
|
|
433
442
|
const primary = sources[0];
|
|
434
443
|
if (!primary) logger.warn("--watch requested but no resolvable fixture sources; skipping watcher");
|
|
@@ -442,15 +451,6 @@ async function main() {
|
|
|
442
451
|
logger.info(`Watching ${primary.path} for changes`);
|
|
443
452
|
}
|
|
444
453
|
}
|
|
445
|
-
function shutdown() {
|
|
446
|
-
logger.info("Shutting down...");
|
|
447
|
-
if (watcher) watcher.close();
|
|
448
|
-
instance.server.close(() => {
|
|
449
|
-
process.exit(0);
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
process.on("SIGINT", shutdown);
|
|
453
|
-
process.on("SIGTERM", shutdown);
|
|
454
454
|
}
|
|
455
455
|
main().catch((err) => {
|
|
456
456
|
console.error(err);
|