@runtypelabs/cli 2.59.1 → 2.59.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/chunk-0x7UKC1U.js +17 -0
  2. package/dist/chunk-2ySxXtcg.js +418 -0
  3. package/dist/chunk-3An_BRHv.js +501 -0
  4. package/dist/chunk-6uTxgdiY.js +16218 -0
  5. package/dist/chunk-87nRnNRG.js +1363 -0
  6. package/dist/chunk-B3wo8uRx.js +322 -0
  7. package/dist/chunk-BGp3ZdBy.js +560 -0
  8. package/dist/chunk-BJQv9Elp.js +107 -0
  9. package/dist/chunk-BOpO6xE-.js +6053 -0
  10. package/dist/chunk-BQXXCL8B.js +102 -0
  11. package/dist/chunk-BV-8isOd.js +34 -0
  12. package/dist/chunk-BVMhjGVe.js +826 -0
  13. package/dist/chunk-BW2fg46T.js +141 -0
  14. package/dist/chunk-BWJdY5Ag.js +36 -0
  15. package/dist/chunk-BYJOrLhh.js +302 -0
  16. package/dist/chunk-BYab8EVL.js +127 -0
  17. package/dist/chunk-BfEKvp7h.js +82 -0
  18. package/dist/chunk-BhgLSfH6.js +1123 -0
  19. package/dist/chunk-BirUxTtH.js +296 -0
  20. package/dist/chunk-BmB6UVZ9.js +1559 -0
  21. package/dist/chunk-BnWhIqW1.js +109 -0
  22. package/dist/chunk-Bpfnfk0t.js +123 -0
  23. package/dist/chunk-BrhgdnM3.js +108 -0
  24. package/dist/chunk-Bt0XAgX5.js +327 -0
  25. package/dist/chunk-Bu0FJr6S.js +84 -0
  26. package/dist/chunk-BvEoKpN3.js +255 -0
  27. package/dist/chunk-BxNJgYbE.js +28 -0
  28. package/dist/chunk-C1OFhd7F.js +6131 -0
  29. package/dist/chunk-C7e7WwbU.js +331 -0
  30. package/dist/chunk-CDTYP6bN.js +558 -0
  31. package/dist/chunk-CGDQoqDC.js +24 -0
  32. package/dist/chunk-CJraEBVd.js +127 -0
  33. package/dist/chunk-CQrNhOtv.js +40 -0
  34. package/dist/chunk-CW6AzBH6.js +128 -0
  35. package/dist/chunk-CXgL4w-9.js +317 -0
  36. package/dist/chunk-CZrqoPyf.js +233 -0
  37. package/dist/chunk-CcFCyqbB.js +83 -0
  38. package/dist/chunk-CdaIvO-y.js +485 -0
  39. package/dist/chunk-CehSXtgK.js +624 -0
  40. package/dist/chunk-Ciqkop65.js +218 -0
  41. package/dist/chunk-CoAWdSiE.js +43 -0
  42. package/dist/chunk-Crb4y7t4.js +830 -0
  43. package/dist/chunk-CrlqIfmb.js +337 -0
  44. package/dist/chunk-Cs4pwCQ-.js +324 -0
  45. package/dist/chunk-CwM_9y01.js +519 -0
  46. package/dist/chunk-CyRbIJg8.js +440 -0
  47. package/dist/chunk-D0OHsyMy.js +212 -0
  48. package/dist/chunk-D3y2bURs.js +1347 -0
  49. package/dist/chunk-D4_mJk03.js +2338 -0
  50. package/dist/chunk-D6C8rned.js +578 -0
  51. package/dist/chunk-D9ZbUnks.js +11 -0
  52. package/dist/chunk-DEPmLshX.js +834 -0
  53. package/dist/chunk-DFj1UPB2.js +330 -0
  54. package/dist/chunk-DGdFdZVf.js +197 -0
  55. package/dist/chunk-DGv7X9S_.js +63 -0
  56. package/dist/chunk-DJQ47WYZ.js +664 -0
  57. package/dist/chunk-DJw3O61j.js +1974 -0
  58. package/dist/chunk-DK4FbWVK.js +100 -0
  59. package/dist/chunk-DPuofXMp.js +3907 -0
  60. package/dist/chunk-DSRYhUus.js +993 -0
  61. package/dist/chunk-DajZ9Eg4.js +299 -0
  62. package/dist/chunk-Df4dunvU.js +195 -0
  63. package/dist/chunk-DjNTPhfO.js +481 -0
  64. package/dist/chunk-Dn8eaJuu.js +1042 -0
  65. package/dist/chunk-DwDWqSxM.js +637 -0
  66. package/dist/chunk-Dz7cEtxl.js +84 -0
  67. package/dist/chunk-E_0bgjrS.js +359 -0
  68. package/dist/chunk-KPYN2vUp.js +776 -0
  69. package/dist/chunk-KcqPQJBi.js +86 -0
  70. package/dist/chunk-N9H0JnoG.js +349 -0
  71. package/dist/chunk-NONFcXkn.js +728 -0
  72. package/dist/chunk-PrFjcpmH.js +256 -0
  73. package/dist/chunk-QSfNYiw9.js +11 -0
  74. package/dist/chunk-R265bzj9.js +226 -0
  75. package/dist/chunk-X9V_r6jM.js +166 -0
  76. package/dist/chunk-ZBtPUtyA.js +55 -0
  77. package/dist/chunk-ZCTfmOs7.js +4939 -0
  78. package/dist/chunk-h6oavj0t.js +97 -0
  79. package/dist/chunk-i7DwkvvD.js +42 -0
  80. package/dist/chunk-mG-4eZ6S.js +203 -0
  81. package/dist/chunk-o0ygUbCf.js +313 -0
  82. package/dist/chunk-ucu5lrDZ.js +5715 -0
  83. package/dist/index.js +11367 -73789
  84. package/package.json +5 -5
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/env node
2
+ import { t as isTTY } from "./index.js";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { Box, Text, useApp, useInput } from "ink";
5
+ import { ErrorDisplay, Spinner, theme } from "@runtypelabs/ink-components";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ // src/ink/shared/altScreen.ts
8
+ /**
9
+ * Enter the terminal's alternate screen buffer for fullscreen TUI apps.
10
+ * Fullscreen apps use the alternate screen so rendering doesn't pollute scrollback history.
11
+ * Returns a cleanup function that restores the original screen.
12
+ * Cleanup is idempotent and also registered on process 'exit' as a safety net.
13
+ */
14
+ function enterAltScreen() {
15
+ if (!process.stdout.isTTY) return () => {};
16
+ process.stdout.write("\x1B[?1049h\x1B[2J\x1B[H");
17
+ let restored = false;
18
+ const restore = () => {
19
+ if (restored) return;
20
+ restored = true;
21
+ process.removeListener("exit", restore);
22
+ process.stdout.write("\x1B[?1049l");
23
+ };
24
+ process.on("exit", restore);
25
+ return restore;
26
+ }
27
+ // src/ink/shared/EntityCard.tsx
28
+ function EntityCard({ fields, title }) {
29
+ const visibleFields = fields.filter((f) => f.value !== null && f.value !== void 0);
30
+ return /* @__PURE__ */ jsxs(Box, {
31
+ flexDirection: "column",
32
+ marginBottom: 1,
33
+ children: [title && /* @__PURE__ */ jsx(Text, {
34
+ color: theme.primary,
35
+ bold: true,
36
+ children: title
37
+ }), visibleFields.map((field, index) => /* @__PURE__ */ jsxs(Text, { children: [
38
+ " ",
39
+ /* @__PURE__ */ jsxs(Text, {
40
+ color: theme.dimLabel,
41
+ children: [field.label, ":"]
42
+ }),
43
+ " ",
44
+ /* @__PURE__ */ jsx(Text, {
45
+ color: field.color || theme.label,
46
+ children: String(field.value)
47
+ })
48
+ ] }, index))]
49
+ });
50
+ }
51
+ // src/ink/shared/ConfirmPrompt.tsx
52
+ function ConfirmPrompt({ message, defaultValue = false, onConfirm }) {
53
+ const [answered, setAnswered] = useState(false);
54
+ const [result, setResult] = useState(null);
55
+ const hint = defaultValue ? "Y/n" : "y/N";
56
+ useInput((input, key) => {
57
+ if (answered) return;
58
+ const lower = input.toLowerCase();
59
+ if (lower === "y") {
60
+ setAnswered(true);
61
+ setResult(true);
62
+ onConfirm(true);
63
+ } else if (lower === "n") {
64
+ setAnswered(true);
65
+ setResult(false);
66
+ onConfirm(false);
67
+ } else if (key.return) {
68
+ setAnswered(true);
69
+ setResult(defaultValue);
70
+ onConfirm(defaultValue);
71
+ }
72
+ }, { isActive: !answered });
73
+ if (answered) return /* @__PURE__ */ jsxs(Text, { children: [
74
+ message,
75
+ " ",
76
+ /* @__PURE__ */ jsx(Text, {
77
+ color: result ? theme.success : theme.muted,
78
+ children: result ? "Yes" : "No"
79
+ })
80
+ ] });
81
+ return /* @__PURE__ */ jsxs(Text, { children: [
82
+ message,
83
+ " ",
84
+ /* @__PURE__ */ jsxs(Text, {
85
+ color: theme.muted,
86
+ children: [
87
+ "(",
88
+ hint,
89
+ ")"
90
+ ]
91
+ })
92
+ ] });
93
+ }
94
+ // src/ink/shared/DataList.tsx
95
+ function DataList({ title, items, error, loading, renderCard, emptyMessage = "None found", total, onRetry, onDone }) {
96
+ const { exit } = useApp();
97
+ const hasDone = useRef(false);
98
+ useEffect(() => {
99
+ if (hasDone.current) return void 0;
100
+ if (loading) return void 0;
101
+ if (error && !onRetry) {
102
+ hasDone.current = true;
103
+ onDone?.();
104
+ const timer = setTimeout(() => exit(), 0);
105
+ return () => clearTimeout(timer);
106
+ }
107
+ if (items !== null) {
108
+ hasDone.current = true;
109
+ onDone?.();
110
+ const timer = setTimeout(() => exit(), 0);
111
+ return () => clearTimeout(timer);
112
+ }
113
+ }, [
114
+ loading,
115
+ error,
116
+ items,
117
+ onRetry,
118
+ onDone,
119
+ exit
120
+ ]);
121
+ useInput((input) => {
122
+ if (input === "r" && error && onRetry) onRetry();
123
+ }, { isActive: !!error && !!onRetry });
124
+ if (loading) return /* @__PURE__ */ jsx(Spinner, { label: `Fetching ${title}...` });
125
+ if (error) return /* @__PURE__ */ jsxs(Box, {
126
+ flexDirection: "column",
127
+ children: [/* @__PURE__ */ jsx(ErrorDisplay, { error }), onRetry && /* @__PURE__ */ jsx(Text, {
128
+ color: theme.muted,
129
+ children: "Press 'r' to retry"
130
+ })]
131
+ });
132
+ if (items !== null && items.length === 0) return /* @__PURE__ */ jsx(Text, {
133
+ color: theme.muted,
134
+ children: emptyMessage
135
+ });
136
+ return /* @__PURE__ */ jsxs(Box, {
137
+ flexDirection: "column",
138
+ children: [
139
+ /* @__PURE__ */ jsxs(Text, {
140
+ color: theme.primary,
141
+ bold: true,
142
+ children: [title, ":"]
143
+ }),
144
+ items?.map((item, index) => /* @__PURE__ */ jsx(Box, { children: renderCard(item) }, index)),
145
+ total !== void 0 && /* @__PURE__ */ jsxs(Text, {
146
+ dimColor: true,
147
+ children: [
148
+ "\n",
149
+ " Total: ",
150
+ total
151
+ ]
152
+ })
153
+ ]
154
+ });
155
+ }
156
+ // src/ink/shared/MutationResult.tsx
157
+ function MutationResult({ loading, loadingLabel = "Processing...", success, successMessage, result, error, onRetry, onDone }) {
158
+ const { exit } = useApp();
159
+ const hasDone = useRef(false);
160
+ useEffect(() => {
161
+ if (hasDone.current) return void 0;
162
+ if (loading) return void 0;
163
+ if (success === true) {
164
+ hasDone.current = true;
165
+ onDone?.();
166
+ const timer = setTimeout(() => exit(), 0);
167
+ return () => clearTimeout(timer);
168
+ }
169
+ if (success === false && !onRetry) {
170
+ hasDone.current = true;
171
+ onDone?.();
172
+ const timer = setTimeout(() => exit(), 0);
173
+ return () => clearTimeout(timer);
174
+ }
175
+ if (error && !onRetry) {
176
+ hasDone.current = true;
177
+ onDone?.();
178
+ const timer = setTimeout(() => exit(), 0);
179
+ return () => clearTimeout(timer);
180
+ }
181
+ }, [
182
+ loading,
183
+ success,
184
+ error,
185
+ onRetry,
186
+ onDone,
187
+ exit
188
+ ]);
189
+ useInput((input) => {
190
+ if (input === "r" && (error || success === false) && onRetry) onRetry();
191
+ }, { isActive: !!(error || success === false) && !!onRetry });
192
+ if (loading) return /* @__PURE__ */ jsx(Spinner, { label: loadingLabel });
193
+ if (success === true) return /* @__PURE__ */ jsxs(Box, {
194
+ flexDirection: "column",
195
+ children: [/* @__PURE__ */ jsxs(Text, { children: [
196
+ /* @__PURE__ */ jsx(Text, {
197
+ color: theme.success,
198
+ children: "✓"
199
+ }),
200
+ " ",
201
+ successMessage || "Done"
202
+ ] }), result]
203
+ });
204
+ if (error) return /* @__PURE__ */ jsxs(Box, {
205
+ flexDirection: "column",
206
+ children: [/* @__PURE__ */ jsx(ErrorDisplay, { error }), onRetry && /* @__PURE__ */ jsx(Text, {
207
+ color: theme.muted,
208
+ children: "Press 'r' to retry"
209
+ })]
210
+ });
211
+ return null;
212
+ }
213
+ // src/ink/shared/useMutationState.ts
214
+ function useMutationState(initial = "loading") {
215
+ const [state, setState] = useState({ status: initial });
216
+ return {
217
+ state,
218
+ start: useCallback(() => setState({ status: "loading" }), []),
219
+ succeed: useCallback((result) => setState({
220
+ status: "success",
221
+ result
222
+ }), []),
223
+ fail: useCallback((error) => setState({
224
+ status: "error",
225
+ error: error instanceof Error ? error : new Error(String(error))
226
+ }), [])
227
+ };
228
+ }
229
+ /** The MutationResult props a lifecycle state renders as. */
230
+ function mutationResultProps(state) {
231
+ switch (state.status) {
232
+ case "idle": return {
233
+ loading: false,
234
+ success: null,
235
+ error: null
236
+ };
237
+ case "loading": return {
238
+ loading: true,
239
+ success: null,
240
+ error: null
241
+ };
242
+ case "success": return {
243
+ loading: false,
244
+ success: true,
245
+ error: null,
246
+ result: state.result
247
+ };
248
+ case "error": return {
249
+ loading: false,
250
+ success: false,
251
+ error: state.error
252
+ };
253
+ }
254
+ }
255
+ export { ConfirmPrompt, DataList, EntityCard, MutationResult, enterAltScreen, isTTY, mutationResultProps, useMutationState };
256
+
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ // ../shared/dist/chunk-CRRVsJap.mjs
3
+ /**
4
+ * Canonical record type guard: a non-null object that is NOT an array.
5
+ * This is the array-EXCLUDING variant — `isRecord([])` is false.
6
+ */
7
+ function isRecord(value) {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9
+ }
10
+ export { isRecord as t };
11
+
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env node
2
+ import { S as union, b as string, c as boolean, f as literal, h as object, m as number, s as array, x as tuple } from "./chunk-BOpO6xE-.js";
3
+ import { t as HARNESS_ATTRIBUTES } from "./chunk-Bu0FJr6S.js";
4
+ /**
5
+ * The same attribute names, exported for readers of GenAI spans.
6
+ * OTLP trace ingest reads back the identical vocabulary a customer's own SDK produced.
7
+ * A second hand-typed copy on the read side is a silent-drift hazard: a misspelling fails no build,
8
+ * it just makes every ingested run report zero tokens.
9
+ */
10
+ const GEN_AI_ATTRIBUTES = {
11
+ operationName: "gen_ai.operation.name",
12
+ agentId: "gen_ai.agent.id",
13
+ agentName: "gen_ai.agent.name",
14
+ conversationId: "gen_ai.conversation.id",
15
+ requestModel: "gen_ai.request.model",
16
+ usageInputTokens: "gen_ai.usage.input_tokens",
17
+ usageOutputTokens: "gen_ai.usage.output_tokens",
18
+ /** Input tokens served from the provider's prompt cache, when the provider reports them. */
19
+ usageCacheReadTokens: "gen_ai.usage.cache_read.input_tokens",
20
+ /** Input tokens written INTO the provider's prompt cache, when the provider reports them. */
21
+ usageCacheCreationTokens: "gen_ai.usage.cache_creation.input_tokens",
22
+ /** The model the provider reported having SERVED; the more accurate one to price. */
23
+ responseModel: "gen_ai.response.model",
24
+ toolName: "gen_ai.tool.name",
25
+ toolType: "gen_ai.tool.type",
26
+ toolCallId: "gen_ai.tool.call.id"
27
+ };
28
+ // ../shared/dist/context-manifest-wire.mjs
29
+ const entryTupleSchema = union([tuple([
30
+ string(),
31
+ number().int(),
32
+ number().int(),
33
+ number().int(),
34
+ number().int(),
35
+ number().int(),
36
+ number().int()
37
+ ]), tuple([
38
+ string(),
39
+ number().int(),
40
+ number().int(),
41
+ number().int(),
42
+ number().int(),
43
+ number().int(),
44
+ number().int(),
45
+ string(),
46
+ string()
47
+ ])]);
48
+ object({
49
+ v: literal(1),
50
+ s: number().int().nonnegative(),
51
+ e: array(entryTupleSchema),
52
+ b: array(number().int().nonnegative()),
53
+ x: array(tuple([entryTupleSchema, number().int()]))
54
+ });
55
+ object({
56
+ v: literal(1),
57
+ b: array(tuple([
58
+ string(),
59
+ string(),
60
+ union([literal(0), literal(1)])
61
+ ]))
62
+ });
63
+ array(object({
64
+ hash: string(),
65
+ content: string(),
66
+ truncated: boolean()
67
+ }));
68
+ /**
69
+ * The runtype.* extension attributes, keyed for readers and builders, at resource/invoke_agent/any-span/chat/approval levels.
70
+ * agentId has two placements; the resource-level claim is authoritative, and the span placement is consulted only when absent.
71
+ * Two envelope spans in one trace claiming different agentIds is ambiguous and refused, same as conflicting resource claims.
72
+ * chat-span providerFinishReason/gatewayLogId are optional diagnostics and never count toward the achieved fidelity tier.
73
+ */
74
+ const RUNTYPE_ATTRIBUTES = {
75
+ agentId: "runtype.agent.id",
76
+ /**
77
+ * The published agent version that produced the run, beside `agentId` (resource first, then the
78
+ * envelope). Ingest stamps it on the Run only when it names a version of the attributed agent.
79
+ */
80
+ agentVersionId: "runtype.agent.version_id",
81
+ /** The release alias (`live`, `staging`, ...) the version was resolved through, when one was. */
82
+ agentAlias: "runtype.agent.alias",
83
+ /** The alias binding's revision at export time; provenance only, never a grouping key. */
84
+ agentAliasRevision: "runtype.agent.alias_revision",
85
+ schemaVersion: "runtype.schema.version",
86
+ adapterName: "runtype.adapter.name",
87
+ adapterVersion: "runtype.adapter.version",
88
+ executionId: "runtype.execution.id",
89
+ /**
90
+ * The execution that spawned this one, on the envelope span. Carried, never
91
+ * synthesized: a producer that names no parent leaves it absent, which is what
92
+ * keeps the header's partial index proportional to child runs.
93
+ */
94
+ parentExecutionId: "runtype.parent.execution_id",
95
+ /**
96
+ * The parent's own tool-call id for the call that spawned this run, on the
97
+ * envelope span. The graft key: it is what grafts this trace under one
98
+ * `execute_tool` span of the parent rather than under the parent as a whole.
99
+ */
100
+ parentToolCallId: "runtype.parent.tool_call_id",
101
+ iteration: "runtype.iteration",
102
+ /**
103
+ * The loop's own iteration COUNT, on the envelope. A producer whose iterations
104
+ * hold several model calls reports it so the run does not read as `highest
105
+ * position + 1`; readers prefer it over the positions when present.
106
+ */
107
+ iterations: "runtype.iterations",
108
+ /**
109
+ * The producer's own USD cost claim for the run, on the envelope. Read only
110
+ * when no span carried a priceable model id; stored as self-reported cost,
111
+ * never billed (`cost-aggregation.ts` keeps it out of billed units).
112
+ */
113
+ totalCost: "runtype.total_cost",
114
+ stopReason: "runtype.stop_reason",
115
+ toolsReported: "runtype.tools.reported",
116
+ toolType: "runtype.tool.type",
117
+ toolName: "runtype.tool.name",
118
+ approvalDecision: "runtype.approval.decision",
119
+ /**
120
+ * Identifier of ONE model invocation, on its `chat` span. An id, never
121
+ * content: it lets a host correlate a span with the usage report the same
122
+ * call produced (`RuntimeModelUsageReport.modelCallId`).
123
+ */
124
+ modelCallId: "runtype.model.call_id",
125
+ turnId: "runtype.turn.id",
126
+ turnIndex: "runtype.turn.index",
127
+ /** The provider's raw finish value before normalization (2.x-only, provider-dependent). */
128
+ providerFinishReason: "runtype.provider.finish_reason",
129
+ /**
130
+ * The service tier the provider was asked for or served a model turn under
131
+ * (`flex`, `priority`, an Anthropic speed value). A `chat`-span diagnostic
132
+ * that survives on the retained span row; nothing projects it, and it never
133
+ * counts toward the achieved fidelity tier.
134
+ */
135
+ providerServiceTier: "runtype.provider.service_tier",
136
+ /**
137
+ * The gateway log id for a model turn (e.g. Cloudflare AI Gateway's
138
+ * `cf-aig-log-id`), for correlating a specific turn with its entry in the
139
+ * gateway dashboard. A pointer to content without shipping the content.
140
+ * Emitted on `chat` spans only when the producer provides it.
141
+ */
142
+ gatewayLogId: "runtype.gateway.log_id",
143
+ /**
144
+ * Test-plane only: names the e2e/smoke test run a span was exported under,
145
+ * so the test-trace-collector worker can shard storage one Durable Object
146
+ * per run. A resource attribute set by test harnesses; the production
147
+ * ingest lanes ignore it, and no production emitter sets it.
148
+ */
149
+ testRunId: "runtype.test.run_id"
150
+ };
151
+ /**
152
+ * GenAI semconv content attributes, set by a customer's own instrumentation when it opts into content export.
153
+ * Two first-party producers write them: @runtypelabs/runtime's OTLP tracer for exported agents (content on by default), and @runtypelabs/flue-otel (opt-in).
154
+ * Content read from these attributes is accepted only under the ingest-side scrub + caps posture.
155
+ */
156
+ const GEN_AI_TOOL_CALL_ARGUMENTS = "gen_ai.tool.call.arguments";
157
+ const GEN_AI_TOOL_CALL_RESULT = "gen_ai.tool.call.result";
158
+ const GEN_AI_INPUT_MESSAGES = "gen_ai.input.messages";
159
+ const GEN_AI_OUTPUT_MESSAGES = "gen_ai.output.messages";
160
+ const GEN_AI_CONTENT_ATTRIBUTES = {
161
+ /** Chat history sent to the model, as semconv structured messages. */
162
+ inputMessages: GEN_AI_INPUT_MESSAGES,
163
+ /** Messages the model produced (includes reasoning content parts). */
164
+ outputMessages: GEN_AI_OUTPUT_MESSAGES,
165
+ /** System instructions, when separate from the input messages. */
166
+ systemInstructions: "gen_ai.system_instructions",
167
+ /** `execute_tool` span: the arguments the tool was called with. */
168
+ toolCallArguments: GEN_AI_TOOL_CALL_ARGUMENTS,
169
+ /** `execute_tool` span: the result the tool returned. */
170
+ toolCallResult: GEN_AI_TOOL_CALL_RESULT,
171
+ /** `chat` span: the tool schemas the call offered the model. */
172
+ toolDefinitions: "gen_ai.tool.definitions"
173
+ };
174
+ /**
175
+ * Read-side aliases for content attributes: canonical semconv name to vendor-namespaced spellings a stock instrumentation uses.
176
+ * The aliased value is read through the same budget+scrub path as the canonical name; keys must be canonical (test-pinned).
177
+ */
178
+ const GEN_AI_CONTENT_ATTRIBUTE_ALIASES = {
179
+ [GEN_AI_INPUT_MESSAGES]: ["ai.prompt.messages", "ai.prompt"],
180
+ [GEN_AI_OUTPUT_MESSAGES]: ["ai.response.text", "ai.response.object"],
181
+ [GEN_AI_TOOL_CALL_ARGUMENTS]: ["flue.tool.call.arguments", "ai.toolCall.args"],
182
+ [GEN_AI_TOOL_CALL_RESULT]: ["flue.tool.call.result", "ai.toolCall.result"]
183
+ };
184
+ /**
185
+ * OpenInference content, as LangGraph / OpenAI Agents SDK / every Arize instrumentation emits it.
186
+ * A message array arrives flattened into indexed keys, so no 1:1 alias can name it; the OpenInference
187
+ * normalizer reassembles the family into the canonical names above before anything reads it.
188
+ */
189
+ const OPENINFERENCE_CONTENT_PREFIXES = [
190
+ "llm.input_messages.",
191
+ "llm.output_messages.",
192
+ "llm.tools.",
193
+ "llm.prompts",
194
+ "llm.prompt_template.",
195
+ "llm.choices",
196
+ "llm.function_call",
197
+ "retrieval.documents.",
198
+ "embedding.embeddings.",
199
+ "input.value",
200
+ "output.value"
201
+ ];
202
+ /** Vercel AI SDK `experimental_telemetry` payloads with no canonical counterpart to alias onto. */
203
+ const AI_SDK_CONTENT_PREFIXES = ["ai.response.toolCalls"];
204
+ /** Mastra's raw provider response body; its sibling `mastra.metadata.*` keys are identifiers, not payloads. */
205
+ const MASTRA_CONTENT_PREFIXES = ["mastra.metadata.body"];
206
+ /**
207
+ * The Cloudflare Agents SDK's two open-segment namespaces, holding whatever scalars the app put in
208
+ * `experimental_telemetry.metadata` / `runtimeContext`. Cloudflare's own guidance is that context
209
+ * filtering "is not a security boundary", and these are the one place a careless author stashes a
210
+ * user message, so they are excluded whole rather than read.
211
+ */
212
+ const CLOUDFLARE_AGENTS_CONTENT_PREFIXES = ["cloudflare.agents.metadata.", "cloudflare.agents.runtime_context."];
213
+ [
214
+ ...OPENINFERENCE_CONTENT_PREFIXES,
215
+ ...AI_SDK_CONTENT_PREFIXES,
216
+ ...MASTRA_CONTENT_PREFIXES,
217
+ ...CLOUDFLARE_AGENTS_CONTENT_PREFIXES
218
+ ];
219
+ [
220
+ HARNESS_ATTRIBUTES.nativeContent,
221
+ ...Object.values(GEN_AI_CONTENT_ATTRIBUTES),
222
+ ...Object.values(GEN_AI_CONTENT_ATTRIBUTE_ALIASES).flat()
223
+ ];
224
+ GEN_AI_ATTRIBUTES.responseModel;
225
+ export { RUNTYPE_ATTRIBUTES as n, GEN_AI_ATTRIBUTES as r, GEN_AI_CONTENT_ATTRIBUTES as t };
226
+
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+ import { t as isTTY } from "./index.js";
3
+ import { DataList, EntityCard, MutationResult, React, Text, render, useEffect, useState } from "./chunk-CoAWdSiE.js";
4
+ import { r as createCliClient } from "./chunk-BW2fg46T.js";
5
+ import { n as ensureAuth } from "./chunk-CJraEBVd.js";
6
+ import { a as printJson, i as printDetail, r as getTotalCount } from "./chunk-CcFCyqbB.js";
7
+ import { Command } from "commander";
8
+ import chalk from "chalk";
9
+ // src/commands/analytics.ts
10
+ const analyticsCommand = new Command("analytics").description("View analytics and execution results");
11
+ analyticsCommand.command("stats").description("Show account statistics").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
12
+ const apiKey = await ensureAuth();
13
+ if (!apiKey) return;
14
+ const client = createCliClient(apiKey);
15
+ if (!isTTY(options) || options.json) {
16
+ try {
17
+ const data = await client.get("/analytics/stats");
18
+ if (options.json) printJson(data);
19
+ else printDetail("Account Statistics", [
20
+ {
21
+ label: "Flows",
22
+ value: data.flows
23
+ },
24
+ {
25
+ label: "Prompts",
26
+ value: data.prompts
27
+ },
28
+ {
29
+ label: "Records",
30
+ value: data.records
31
+ },
32
+ {
33
+ label: "Executions",
34
+ value: data.executions
35
+ }
36
+ ]);
37
+ } catch (error) {
38
+ const message = error instanceof Error ? error.message : "Unknown error";
39
+ console.error(chalk.red("Failed to fetch stats"));
40
+ console.error(chalk.red(message));
41
+ process.exit(1);
42
+ }
43
+ return;
44
+ }
45
+ const App = () => {
46
+ const [loading, setLoading] = useState(true);
47
+ const [success, setSuccess] = useState(null);
48
+ const [error, setError] = useState(null);
49
+ const [resultNode, setResultNode] = useState(void 0);
50
+ useEffect(() => {
51
+ const run = async () => {
52
+ try {
53
+ const data = await client.get("/analytics/stats");
54
+ setResultNode(React.createElement(EntityCard, { fields: [
55
+ {
56
+ label: "Flows",
57
+ value: data.flows
58
+ },
59
+ {
60
+ label: "Prompts",
61
+ value: data.prompts
62
+ },
63
+ {
64
+ label: "Records",
65
+ value: data.records
66
+ },
67
+ {
68
+ label: "Executions",
69
+ value: data.executions
70
+ }
71
+ ] }));
72
+ setSuccess(true);
73
+ setLoading(false);
74
+ } catch (err) {
75
+ setError(err instanceof Error ? err : new Error(String(err)));
76
+ setSuccess(false);
77
+ setLoading(false);
78
+ }
79
+ };
80
+ run();
81
+ }, []);
82
+ return React.createElement(MutationResult, {
83
+ loading,
84
+ loadingLabel: "Fetching stats...",
85
+ success,
86
+ successMessage: "Account Statistics",
87
+ error,
88
+ result: resultNode
89
+ });
90
+ };
91
+ const { waitUntilExit } = render(React.createElement(App));
92
+ await waitUntilExit();
93
+ });
94
+ analyticsCommand.command("results").description("List execution results").option("--flow <id>", "Filter by flow ID").option("--record <id>", "Filter by record ID").option("--status <status>", "Filter by status").option("--limit <n>", "Limit results", "20").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
95
+ const apiKey = await ensureAuth();
96
+ if (!apiKey) return;
97
+ const client = createCliClient(apiKey);
98
+ const params = { limit: options.limit };
99
+ if (options.flow) params.flowId = options.flow;
100
+ if (options.record) params.recordId = options.record;
101
+ if (options.status) params.status = options.status;
102
+ if (!isTTY(options) || options.json) {
103
+ try {
104
+ const data = await client.get("/analytics/record-results", params);
105
+ if (options.json) printJson(data);
106
+ else {
107
+ const results = data.data ?? [];
108
+ if (results.length === 0) {
109
+ console.log(chalk.gray("No results found"));
110
+ return;
111
+ }
112
+ console.log(chalk.cyan("Execution Results:"));
113
+ for (const result of results) {
114
+ const statusColor = result.status === "completed" ? "green" : "red";
115
+ const date = result.createdAt ? chalk.gray(` ${result.createdAt}`) : "";
116
+ console.log(` ${chalk.green(result.id)} ${chalk[statusColor](`[${result.status}]`)} flow=${chalk.gray(result.flowId)} record=${chalk.gray(result.recordId)}${date}`);
117
+ }
118
+ const total = getTotalCount(data.pagination);
119
+ if (total !== void 0) console.log(chalk.dim(`\n Total: ${total} results`));
120
+ }
121
+ } catch (error) {
122
+ const message = error instanceof Error ? error.message : "Unknown error";
123
+ console.error(chalk.red("Failed to fetch results"));
124
+ console.error(chalk.red(message));
125
+ process.exit(1);
126
+ }
127
+ return;
128
+ }
129
+ const App = () => {
130
+ const [loading, setLoading] = useState(true);
131
+ const [items, setItems] = useState(null);
132
+ const [total, setTotal] = useState(void 0);
133
+ const [error, setError] = useState(null);
134
+ useEffect(() => {
135
+ const run = async () => {
136
+ try {
137
+ const data = await client.get("/analytics/record-results", params);
138
+ setItems(data.data ?? []);
139
+ setTotal(getTotalCount(data.pagination));
140
+ setLoading(false);
141
+ } catch (err) {
142
+ setError(err instanceof Error ? err : new Error(String(err)));
143
+ setLoading(false);
144
+ }
145
+ };
146
+ run();
147
+ }, []);
148
+ return React.createElement(DataList, {
149
+ title: "Execution Results",
150
+ items,
151
+ error,
152
+ loading,
153
+ total,
154
+ emptyMessage: "No results found",
155
+ renderCard: (item) => {
156
+ const r = item;
157
+ const statusColor = r.status === "completed" ? "green" : "red";
158
+ return React.createElement(Text, { color: statusColor }, ` ${r.id} [${r.status}] flow=${r.flowId} record=${r.recordId}${r.createdAt ? ` ${r.createdAt}` : ""}`);
159
+ }
160
+ });
161
+ };
162
+ const { waitUntilExit } = render(React.createElement(App));
163
+ await waitUntilExit();
164
+ });
165
+ export { analyticsCommand };
166
+