@hachej/boring-agent 0.1.64 → 0.1.65

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.
@@ -1,134 +1,3 @@
1
- import { d as SessionStore } from './chatSubmitPayload-DHqQL2wD.js';
2
-
3
- interface TelemetrySink {
4
- capture(event: TelemetryEvent): void | Promise<void>;
5
- flush?(): void | Promise<void>;
6
- }
7
- interface TelemetryEvent {
8
- name: string;
9
- distinctId?: string;
10
- properties?: Record<string, unknown>;
11
- }
12
- declare const noopTelemetry: TelemetrySink;
13
- declare function safeCapture(telemetry: TelemetrySink, event: TelemetryEvent): void;
14
-
15
- type JSONSchema = Record<string, unknown>;
16
- type ToolReadinessRequirement = 'workspace-fs' | 'sandbox-exec' | 'ui-bridge' | 'runtime-dependencies' | `runtime:${string}`;
17
- interface AgentTool {
18
- name: string;
19
- description: string;
20
- /** Optional one-line prompt entry. Pi-built tools should preserve pi's snippet verbatim. */
21
- promptSnippet?: string;
22
- readinessRequirements?: ToolReadinessRequirement[];
23
- parameters: JSONSchema;
24
- execute(params: Record<string, unknown>, ctx: ToolExecContext): Promise<ToolResult>;
25
- }
26
- interface ToolExecContext {
27
- abortSignal: AbortSignal;
28
- toolCallId: string;
29
- onUpdate?: (partial: string) => void;
30
- /** Agent chat/session id executing this tool, when known. */
31
- sessionId?: string;
32
- }
33
- interface ToolResult {
34
- content: Array<{
35
- type: 'text';
36
- text: string;
37
- }>;
38
- isError?: boolean;
39
- details?: unknown;
40
- }
41
-
42
- interface AgentHarnessFactoryInput {
43
- tools: AgentTool[];
44
- /** Host/storage cwd used for harness-owned filesystem resources. */
45
- cwd: string;
46
- /** Agent-visible cwd used by Pi/system prompt/session metadata. */
47
- runtimeCwd?: string;
48
- systemPromptAppend?: string;
49
- sessionNamespace?: string;
50
- sessionRoot?: string;
51
- sessionDir?: string;
52
- /**
53
- * Optional dynamic system-prompt source. Harness calls it whenever it
54
- * builds or rebuilds a session prompt and appends the returned string.
55
- * Workspace plugin layer wires this so live-reloaded plugins can contribute
56
- * prompt context without a workspace-injected harness extension.
57
- */
58
- systemPromptDynamic?: () => string | undefined | Promise<string | undefined>;
59
- /** Host-provided telemetry sink. Optional and best-effort; harnesses may ignore it. */
60
- telemetry?: TelemetrySink;
61
- }
62
- type AgentHarnessFactory = (input: AgentHarnessFactoryInput) => AgentHarness | Promise<AgentHarness>;
63
- interface AgentHarness {
64
- readonly id: string;
65
- readonly placement: 'server' | 'browser';
66
- /** Session lifecycle; may delegate to an underlying runtime (e.g. pi's JSONL). */
67
- sessions: SessionStore;
68
- /**
69
- * Resolved system prompt currently in effect for `sessionId`. Returns
70
- * `undefined` when the underlying runtime hasn't yet instantiated a
71
- * session (typical pre-first-turn state — pi creates lazily on the first
72
- * prompt). Optional so non-pi harnesses can opt out cleanly.
73
- */
74
- getSystemPrompt?: (sessionId: string) => string | undefined;
75
- /** Reload native agent resources/extensions for an existing session. */
76
- reloadSession?: (sessionId: string) => Promise<boolean>;
77
- /**
78
- * Resource (skill/extension) load diagnostics for an existing session.
79
- * Returns `[]` when the session has no live agent session yet. Lets the
80
- * /reload route and the `plugin_diagnostics` tool surface silent
81
- * skill/extension load failures back to the UI and the agent.
82
- */
83
- getResourceDiagnostics?: (sessionId: string) => Array<{
84
- source: string;
85
- message: string;
86
- path?: string;
87
- }>;
88
- /** List slash commands registered in the agent runtime for a given session. */
89
- getSlashCommands?: (sessionId: string, ctx: RunContext) => ReadonlyArray<AgentSlashCommandSummary> | Promise<ReadonlyArray<AgentSlashCommandSummary>>;
90
- /**
91
- * Execute a named slash command registered via `pi.registerCommand` in a
92
- * plugin extension. Calls the handler in-process; the handler may dispatch
93
- * UI commands (openPanel, notify) through the workspace bridge. Throws if
94
- * the command is not found or the handler throws.
95
- */
96
- executeSlashCommand?: (sessionId: string, name: string, args: string, ctx: RunContext) => Promise<void>;
97
- }
98
- interface AgentSlashCommandSummary {
99
- name: string;
100
- description?: string;
101
- source: 'extension' | 'prompt' | 'skill';
102
- /**
103
- * Name of the originating plugin/package, when derivable from Pi's
104
- * sourceInfo (e.g. a `.pi/extensions/<name>` runtime plugin, or an
105
- * `npm:`/`git/` package). Surfaced as a tag in the slash-command picker.
106
- * Absent for built-in/top-level commands with no package origin.
107
- */
108
- sourcePlugin?: string;
109
- }
110
- interface MessageAttachment {
111
- filename?: string;
112
- mediaType?: string;
113
- /** data: URL (base64) or remote URL */
114
- url: string;
115
- }
116
- interface SendMessageInput {
117
- sessionId: string;
118
- message: string;
119
- thinkingLevel?: 'off' | 'low' | 'medium' | 'high';
120
- model?: {
121
- provider: string;
122
- id: string;
123
- };
124
- attachments?: MessageAttachment[];
125
- }
126
- interface RunContext {
127
- abortSignal: AbortSignal;
128
- workdir: string;
129
- userId?: string;
130
- }
131
-
132
1
  interface WorkspaceRuntimeContext {
133
2
  /** Agent-visible working directory shared by file-tree and shell execution. */
134
3
  readonly runtimeCwd: string;
@@ -330,8 +199,8 @@ interface Sandbox {
330
199
  * The optional `onStdout` / `onStderr` callbacks (when implemented)
331
200
  * stream output incrementally as bytes arrive. When omitted,
332
201
  * implementations buffer normally and surface output via
333
- * `ExecResult.stdout` / `stderr` only. See `Sandbox.exec` streaming
334
- * extension under bead [Phase 1.0].
202
+ * `ExecResult.stdout` / `stderr` only. See the `Sandbox.exec` streaming
203
+ * extension added in Phase 1.0.
335
204
  */
336
205
  exec(cmd: string, opts?: ExecOptions): Promise<ExecResult>;
337
206
  /**
@@ -478,4 +347,4 @@ interface CommandNotifyPayload {
478
347
  command?: string;
479
348
  }
480
349
 
481
- export { type AgentTool as A, type CommandNotifyPayload as C, type Entry as E, type FileSearch as F, type IsolatedCodeInput as I, type JSONSchema as J, type PluginRestartWarning as P, type RunContext as R, type Sandbox as S, type TelemetryEvent as T, type Workspace as W, type AgentHarness as a, type ExecOptions as b, type ExecResult as c, type IsolatedCodeOutput as d, type SandboxCapability as e, type SandboxHandleRecord as f, type SandboxHandleStore as g, type SendMessageInput as h, type Stat as i, type TelemetrySink as j, type ToolExecContext as k, type ToolResult as l, WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT as m, WORKSPACE_COMMAND_NOTIFY_EVENT as n, type WorkspaceRuntimeContext as o, noopTelemetry as p, type ToolReadinessRequirement as q, type WorkspaceChangeEvent as r, safeCapture as s, type AgentHarnessFactory as t, type AgentHarnessFactoryInput as u };
350
+ export { type CommandNotifyPayload as C, type Entry as E, type FileSearch as F, type IsolatedCodeInput as I, type PluginRestartWarning as P, type Sandbox as S, type Workspace as W, type ExecOptions as a, type ExecResult as b, type IsolatedCodeOutput as c, type SandboxCapability as d, type SandboxHandleRecord as e, type SandboxHandleStore as f, type Stat as g, WORKSPACE_AGENT_PLUGINS_RELOADED_EVENT as h, WORKSPACE_COMMAND_NOTIFY_EVENT as i, type WorkspaceRuntimeContext as j, type WorkspaceChangeEvent as k };
@@ -0,0 +1,22 @@
1
+ type ThinkingLevel = 'off' | 'low' | 'medium' | 'high';
2
+ interface ChatModelSelection {
3
+ provider: string;
4
+ id: string;
5
+ }
6
+ interface ChatAttachmentPayload {
7
+ filename?: string;
8
+ mediaType?: string;
9
+ url: string;
10
+ /** Workspace-relative path when the browser upload endpoint persisted the attachment. */
11
+ path?: string;
12
+ }
13
+ interface ChatSubmitPayload {
14
+ message: string;
15
+ displayMessage?: string;
16
+ clientNonce: string;
17
+ model?: ChatModelSelection;
18
+ thinkingLevel?: ThinkingLevel;
19
+ attachments?: ChatAttachmentPayload[];
20
+ }
21
+
22
+ export type { ChatSubmitPayload as C, ThinkingLevel as T, ChatAttachmentPayload as a, ChatModelSelection as b };
@@ -0,0 +1,290 @@
1
+ import {
2
+ ErrorCode
3
+ } from "./chunk-XZKU7FBV.js";
4
+
5
+ // src/shared/tool-ui.ts
6
+ function isRecord(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8
+ }
9
+ function isToolUiMetadata(value) {
10
+ if (!isRecord(value)) return false;
11
+ return (value.rendererId === void 0 || typeof value.rendererId === "string") && (value.displayGroup === void 0 || typeof value.displayGroup === "string") && (value.icon === void 0 || typeof value.icon === "string");
12
+ }
13
+ function sanitizeToolUiMetadata(value) {
14
+ if (!isToolUiMetadata(value)) return void 0;
15
+ const rendererId = value.rendererId?.trim();
16
+ const displayGroup = value.displayGroup?.trim();
17
+ const icon = value.icon?.trim();
18
+ return {
19
+ ...rendererId ? { rendererId } : {},
20
+ ...displayGroup ? { displayGroup } : {},
21
+ ...icon ? { icon } : {},
22
+ ...value.details !== void 0 ? { details: value.details } : {}
23
+ };
24
+ }
25
+ function extractToolUiMetadata(output) {
26
+ if (!isRecord(output)) return void 0;
27
+ const details = output.details;
28
+ if (!isRecord(details)) return void 0;
29
+ return sanitizeToolUiMetadata(details.ui);
30
+ }
31
+
32
+ // src/shared/chat/piChatSchemas.ts
33
+ import { z } from "zod";
34
+ var nonEmptyString = z.string().min(1);
35
+ var seqNumber = z.number().int().nonnegative();
36
+ var ShallowPayloadSchema = z.union([
37
+ z.string(),
38
+ z.number(),
39
+ z.boolean(),
40
+ z.null(),
41
+ z.array(z.unknown()),
42
+ z.record(z.unknown())
43
+ ]);
44
+ function isRecord2(value) {
45
+ return typeof value === "object" && value !== null && !Array.isArray(value);
46
+ }
47
+ var ToolUiMetadataSchema = z.object({
48
+ rendererId: z.string().optional(),
49
+ displayGroup: z.string().optional(),
50
+ icon: z.string().optional(),
51
+ details: z.unknown().optional()
52
+ });
53
+ function sanitizeToolUiMetadata2(value) {
54
+ if (!isRecord2(value)) return void 0;
55
+ const parsed = ToolUiMetadataSchema.safeParse(value);
56
+ return parsed.success ? parsed.data : void 0;
57
+ }
58
+ var OptionalToolUiMetadataSchema = z.preprocess(
59
+ (value) => sanitizeToolUiMetadata2(value),
60
+ ToolUiMetadataSchema.optional()
61
+ );
62
+ var ChatErrorSchema = z.object({
63
+ code: ErrorCode,
64
+ message: nonEmptyString,
65
+ retryable: z.boolean().optional(),
66
+ details: z.unknown().optional()
67
+ });
68
+ var BoringChatPartSchema = z.discriminatedUnion("type", [
69
+ z.object({ type: z.literal("text"), id: z.string().optional(), text: z.string() }),
70
+ z.object({
71
+ type: z.literal("reasoning"),
72
+ id: nonEmptyString,
73
+ text: z.string(),
74
+ state: z.enum(["streaming", "done"]).optional()
75
+ }),
76
+ z.object({
77
+ type: z.literal("tool-call"),
78
+ id: nonEmptyString,
79
+ toolName: nonEmptyString,
80
+ input: z.unknown().optional(),
81
+ state: z.enum(["input-streaming", "input-available", "output-available", "output-error", "aborted"]),
82
+ output: z.unknown().optional(),
83
+ errorText: z.string().optional(),
84
+ ui: OptionalToolUiMetadataSchema
85
+ }),
86
+ z.object({
87
+ type: z.literal("file"),
88
+ id: z.string().optional(),
89
+ filename: z.string().optional(),
90
+ mediaType: z.string().optional(),
91
+ url: z.string().optional(),
92
+ path: z.string().optional(),
93
+ filesystem: z.string().optional()
94
+ }),
95
+ z.object({
96
+ type: z.literal("notice"),
97
+ id: z.string().optional(),
98
+ level: z.enum(["info", "warning", "error"]),
99
+ text: z.string()
100
+ })
101
+ ]);
102
+ var BoringChatMessageSchema = z.object({
103
+ id: nonEmptyString,
104
+ role: z.enum(["user", "assistant", "system"]),
105
+ status: z.enum(["pending", "streaming", "done", "aborted", "error"]).optional(),
106
+ parts: z.array(BoringChatPartSchema),
107
+ createdAt: z.string().optional(),
108
+ clientNonce: z.string().optional(),
109
+ clientSeq: z.number().int().nonnegative().optional(),
110
+ piEntryId: z.string().optional(),
111
+ turnId: z.string().optional()
112
+ });
113
+ var QueuedUserMessageSchema = z.object({
114
+ id: nonEmptyString,
115
+ kind: z.literal("followup"),
116
+ clientNonce: z.string().optional(),
117
+ clientSeq: z.number().int().nonnegative().optional(),
118
+ displayText: z.string(),
119
+ createdAt: z.string().optional()
120
+ });
121
+ var PiChatStatusSchema = z.enum(["idle", "hydrating", "submitted", "streaming", "aborting", "error"]);
122
+ var PiChatSnapshotSchema = z.object({
123
+ protocolVersion: z.literal(1),
124
+ sessionId: nonEmptyString,
125
+ seq: seqNumber,
126
+ status: PiChatStatusSchema,
127
+ activeTurnId: z.string().optional(),
128
+ messages: z.array(BoringChatMessageSchema),
129
+ queue: z.object({ followUps: z.array(QueuedUserMessageSchema) }),
130
+ followUpMode: z.literal("one-at-a-time"),
131
+ error: ChatErrorSchema.optional()
132
+ });
133
+ var baseEvent = z.object({ seq: seqNumber });
134
+ var PiChatEventSchema = z.discriminatedUnion("type", [
135
+ baseEvent.extend({ type: z.literal("agent-start"), turnId: nonEmptyString }),
136
+ baseEvent.extend({ type: z.literal("agent-end"), turnId: nonEmptyString, status: z.enum(["ok", "aborted", "error"]), willRetry: z.boolean().optional() }),
137
+ baseEvent.extend({
138
+ type: z.literal("message-start"),
139
+ messageId: nonEmptyString,
140
+ role: z.enum(["user", "assistant"]),
141
+ clientNonce: z.string().optional(),
142
+ clientSeq: z.number().int().nonnegative().optional(),
143
+ createdAt: z.string().optional(),
144
+ text: z.string().optional(),
145
+ files: z.array(BoringChatPartSchema).optional()
146
+ }),
147
+ baseEvent.extend({
148
+ type: z.literal("message-delta"),
149
+ messageId: nonEmptyString,
150
+ partId: nonEmptyString,
151
+ kind: z.enum(["text", "reasoning"]),
152
+ delta: z.string()
153
+ }),
154
+ baseEvent.extend({
155
+ type: z.literal("message-part-end"),
156
+ messageId: nonEmptyString,
157
+ partId: nonEmptyString,
158
+ kind: z.enum(["text", "reasoning"]),
159
+ text: z.string()
160
+ }),
161
+ baseEvent.extend({ type: z.literal("message-end"), messageId: nonEmptyString, final: BoringChatMessageSchema }),
162
+ baseEvent.extend({
163
+ type: z.literal("tool-call"),
164
+ messageId: nonEmptyString,
165
+ toolCallId: nonEmptyString,
166
+ toolName: nonEmptyString,
167
+ input: ShallowPayloadSchema,
168
+ ui: OptionalToolUiMetadataSchema
169
+ }),
170
+ baseEvent.extend({
171
+ type: z.literal("tool-result"),
172
+ messageId: nonEmptyString,
173
+ toolCallId: nonEmptyString,
174
+ output: ShallowPayloadSchema,
175
+ isError: z.boolean().optional(),
176
+ errorText: z.string().optional(),
177
+ ui: OptionalToolUiMetadataSchema
178
+ }),
179
+ baseEvent.extend({ type: z.literal("queue-updated"), queue: z.object({ followUps: z.array(QueuedUserMessageSchema) }) }),
180
+ baseEvent.extend({
181
+ type: z.literal("followup-consumed"),
182
+ clientNonce: z.string().optional(),
183
+ clientSeq: z.number().int().nonnegative().optional(),
184
+ messageId: nonEmptyString
185
+ }),
186
+ baseEvent.extend({ type: z.literal("file-changed"), path: nonEmptyString, changeType: nonEmptyString }),
187
+ baseEvent.extend({ type: z.literal("ui-command"), command: ShallowPayloadSchema, displayOnly: z.literal(true) }),
188
+ baseEvent.extend({ type: z.literal("usage"), usage: ShallowPayloadSchema }),
189
+ baseEvent.extend({
190
+ type: z.literal("auto-retry-start"),
191
+ attempt: z.number().int().nonnegative(),
192
+ maxAttempts: z.number().int().nonnegative(),
193
+ delayMs: z.number().int().nonnegative(),
194
+ errorMessage: z.string()
195
+ }),
196
+ baseEvent.extend({
197
+ type: z.literal("auto-retry-end"),
198
+ success: z.boolean(),
199
+ attempt: z.number().int().nonnegative(),
200
+ finalError: z.string().optional()
201
+ }),
202
+ baseEvent.extend({ type: z.literal("error"), turnId: z.string().optional(), retryable: z.boolean().optional(), error: ChatErrorSchema })
203
+ ]);
204
+ var PiChatHeartbeatFrameSchema = z.object({ type: z.literal("heartbeat"), now: z.string() });
205
+ var PiChatStreamFrameSchema = z.union([PiChatEventSchema, PiChatHeartbeatFrameSchema]);
206
+ var ChatModelSelectionSchema = z.object({
207
+ provider: nonEmptyString,
208
+ id: nonEmptyString
209
+ });
210
+ var ThinkingLevelSchema = z.enum(["off", "low", "medium", "high"]);
211
+ var ChatAttachmentPayloadSchema = z.object({
212
+ filename: z.string().optional(),
213
+ mediaType: z.string().optional(),
214
+ url: nonEmptyString,
215
+ path: z.string().optional()
216
+ });
217
+ var PromptPayloadSchema = z.object({
218
+ message: z.string().min(1).max(1e6),
219
+ displayMessage: z.string().min(1).max(1e6).optional(),
220
+ clientNonce: nonEmptyString.max(128),
221
+ model: ChatModelSelectionSchema.optional(),
222
+ thinkingLevel: ThinkingLevelSchema.optional(),
223
+ attachments: z.array(ChatAttachmentPayloadSchema).max(20).optional()
224
+ });
225
+ var FollowUpPayloadSchema = z.object({
226
+ message: z.string().min(1).max(1e6),
227
+ displayMessage: z.string().min(1).max(1e6).optional(),
228
+ clientNonce: nonEmptyString.max(128),
229
+ clientSeq: z.number().int().nonnegative()
230
+ });
231
+ var QueueClearPayloadSchema = z.preprocess(
232
+ (value) => value ?? {},
233
+ z.object({
234
+ clientNonce: nonEmptyString.max(128).optional(),
235
+ clientSeq: z.number().int().nonnegative().optional()
236
+ }).strict()
237
+ );
238
+ var InterruptPayloadSchema = z.object({}).strict();
239
+ var StopPayloadSchema = z.object({}).strict();
240
+ var CommandReceiptSchema = z.object({
241
+ accepted: z.literal(true),
242
+ cursor: seqNumber
243
+ });
244
+ var PromptReceiptSchema = CommandReceiptSchema.extend({
245
+ clientNonce: nonEmptyString,
246
+ duplicate: z.boolean().optional()
247
+ });
248
+ var FollowUpReceiptSchema = CommandReceiptSchema.extend({
249
+ clientNonce: nonEmptyString,
250
+ clientSeq: z.number().int().nonnegative(),
251
+ queued: z.literal(true),
252
+ duplicate: z.boolean().optional()
253
+ });
254
+ var QueueClearReceiptSchema = CommandReceiptSchema.extend({
255
+ cleared: z.number().int().nonnegative()
256
+ });
257
+ var StopReceiptSchema = CommandReceiptSchema.extend({
258
+ stopped: z.boolean(),
259
+ clearedQueue: z.array(QueuedUserMessageSchema)
260
+ });
261
+
262
+ export {
263
+ isToolUiMetadata,
264
+ sanitizeToolUiMetadata,
265
+ extractToolUiMetadata,
266
+ ToolUiMetadataSchema,
267
+ sanitizeToolUiMetadata2,
268
+ ChatErrorSchema,
269
+ BoringChatPartSchema,
270
+ BoringChatMessageSchema,
271
+ QueuedUserMessageSchema,
272
+ PiChatStatusSchema,
273
+ PiChatSnapshotSchema,
274
+ PiChatEventSchema,
275
+ PiChatHeartbeatFrameSchema,
276
+ PiChatStreamFrameSchema,
277
+ ChatModelSelectionSchema,
278
+ ThinkingLevelSchema,
279
+ ChatAttachmentPayloadSchema,
280
+ PromptPayloadSchema,
281
+ FollowUpPayloadSchema,
282
+ QueueClearPayloadSchema,
283
+ InterruptPayloadSchema,
284
+ StopPayloadSchema,
285
+ CommandReceiptSchema,
286
+ PromptReceiptSchema,
287
+ FollowUpReceiptSchema,
288
+ QueueClearReceiptSchema,
289
+ StopReceiptSchema
290
+ };
@@ -0,0 +1,85 @@
1
+ // src/server/logging.ts
2
+ var SENSITIVE_KEYS = new Set([
3
+ "apiKey",
4
+ "api_key",
5
+ "token",
6
+ "secret",
7
+ "password",
8
+ "authorization",
9
+ "cookie",
10
+ "oidcToken",
11
+ "accessToken",
12
+ "refreshToken",
13
+ "ANTHROPIC_API_KEY",
14
+ "OPENAI_API_KEY",
15
+ "VERCEL_OIDC_TOKEN",
16
+ "VERCEL_TEAM_ID"
17
+ ].map((key) => key.toLowerCase()));
18
+ function isSensitiveKey(key) {
19
+ return SENSITIVE_KEYS.has(key.toLowerCase());
20
+ }
21
+ function redactValue(key, value, seen) {
22
+ if (key && isSensitiveKey(key) && value != null) return "***";
23
+ if (value == null || typeof value !== "object") return value;
24
+ if (value instanceof Date) return value;
25
+ if (seen.has(value)) return "[Circular]";
26
+ seen.add(value);
27
+ if (Array.isArray(value)) {
28
+ const out2 = value.map((item) => redactValue(void 0, item, seen));
29
+ seen.delete(value);
30
+ return out2;
31
+ }
32
+ const out = {};
33
+ for (const [childKey, childValue] of Object.entries(value)) {
34
+ out[childKey] = redactValue(childKey, childValue, seen);
35
+ }
36
+ seen.delete(value);
37
+ return out;
38
+ }
39
+ function redact(fields) {
40
+ const out = {};
41
+ const seen = /* @__PURE__ */ new WeakSet();
42
+ for (const [k, v] of Object.entries(fields)) {
43
+ out[k] = redactValue(k, v, seen);
44
+ }
45
+ return out;
46
+ }
47
+ function isVerbose() {
48
+ return typeof process !== "undefined" && process.env?.BORING_AGENT_VERBOSE === "1";
49
+ }
50
+ function createLogger(prefix) {
51
+ function emit(level, msg, fields) {
52
+ const entry = {
53
+ level,
54
+ prefix,
55
+ msg,
56
+ ...fields ? redact(fields) : {},
57
+ t: (/* @__PURE__ */ new Date()).toISOString()
58
+ };
59
+ if (level === "error") {
60
+ console.error(JSON.stringify(entry));
61
+ } else if (level === "warn") {
62
+ console.warn(JSON.stringify(entry));
63
+ } else {
64
+ console.log(JSON.stringify(entry));
65
+ }
66
+ }
67
+ return {
68
+ debug(msg, fields) {
69
+ if (isVerbose()) emit("debug", msg, fields);
70
+ },
71
+ info(msg, fields) {
72
+ emit("info", msg, fields);
73
+ },
74
+ warn(msg, fields) {
75
+ emit("warn", msg, fields);
76
+ },
77
+ error(msg, fields) {
78
+ emit("error", msg, fields);
79
+ }
80
+ };
81
+ }
82
+
83
+ export {
84
+ createLogger
85
+ };
@@ -0,0 +1,17 @@
1
+ // src/shared/telemetry.ts
2
+ var noopTelemetry = {
3
+ capture() {
4
+ }
5
+ };
6
+ function safeCapture(telemetry, event) {
7
+ try {
8
+ void Promise.resolve(telemetry.capture(event)).catch(() => {
9
+ });
10
+ } catch {
11
+ }
12
+ }
13
+
14
+ export {
15
+ noopTelemetry,
16
+ safeCapture
17
+ };