@bike4mind/cli 0.18.4 → 0.18.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -33,7 +33,21 @@ Additional Use Grant: You may make production use of the Licensed Work,
33
33
  provider — is expressly permitted and is not a Bike4Mind
34
34
  Service.
35
35
 
36
- Change Date: Four years from the date a given version of the Licensed
36
+ Nominative name use (an additional grant): notwithstanding
37
+ the trademark reservation in the Terms below, you may use
38
+ the name "Bike4Mind" solely to state accurately that your
39
+ product or service is built on, forked from, or derived
40
+ from the Licensed Work. This permission does not extend to
41
+ using "Bike4Mind" as the name of your own product or
42
+ service, or in any manner that implies sponsorship or
43
+ endorsement by Bike4Mind, Inc. Retaining the NOTICE file
44
+ provided with the Licensed Work is encouraged; and when you
45
+ distribute a version on or after its Change Date, retaining
46
+ it is required by the Change License (Apache-2.0, Section
47
+ 4(d)). That obligation attaches to distribution, not to
48
+ hosted use.
49
+
50
+ Change Date: Two years from the date a given version of the Licensed
37
51
  Work is first made publicly available. Each version
38
52
  carries its own Change Date (see Terms). Bike4Mind, Inc.
39
53
  may, at its discretion, designate an earlier Change Date
@@ -57,7 +71,7 @@ works, redistribute, and make non-production use of the Licensed Work. The
57
71
  Licensor may make an Additional Use Grant, above, permitting limited production
58
72
  use.
59
73
 
60
- Effective on the Change Date, or the fourth anniversary of the first publicly
74
+ Effective on the Change Date, or the second anniversary of the first publicly
61
75
  available distribution of a specific version of the Licensed Work under this
62
76
  License, whichever comes first, the Licensor hereby grants you rights under
63
77
  the terms of the Change License, and the rights granted in the paragraph
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { $ as Permission, A as ForbiddenError, At as VideoModels, B as ImageModels, Bt as isModelAccessible, C as CompletionApiUsageTransaction, Ct as ToolUsageTransaction, D as FavoriteDocumentType, Dt as UnprocessableEntityError, E as ElabsEvents, Et as UnauthorizedError, F as GenericCreditDeductTransaction, Ft as getMcpProviderMetadata, G as KnowledgeType, Gt as parseSkillArguments, H as InternalServerError, Ht as isZodError, I as HTTPError, It as getViewById, J as ModalEvents, Jt as secureParameters, K as LLMEvents, Kt as resolveNavigationIntents, L as HttpStatus, Lt as intersectAllowedTools, M as GEMINI_IMAGE_MODELS, Mt as b4mLLMTools, N as GenerateImageToolCallSchema, Nt as dayjsConfig_default, O as FeedbackEvents, Ot as VIDEO_SIZE_CONSTRAINTS, P as GenericCreditAddTransaction, Pt as getAccessibleDataLakes, Q as OpenAIImageGenerationInput, Qt as usdToCredits, R as ImageEditUsageTransaction, Rt as isGPTImage2Model, S as ClaudeArtifactMimeTypes, St as TooManyRequestsError, T as DashboardParamsSchema, Tt as UiNavigationEvents, U as InviteEvents, Ut as mapMimeTypeToArtifactType, V as InboxEvents, Vt as isSupportedEmbeddingModel, W as InviteType, Wt as obfuscateApiKey, X as NotFoundError, Xt as substituteArguments$1, Y as ModelBackend, Yt as settingsMap, Z as OpenAIEmbeddingModel, Zt as toDataLakeConfig, _ as BFL_SAFETY_TOLERANCE, _t as SubscriptionCreditTransaction, an as parseRateLimitHeaders, at as PurchaseTransaction, b as ChatCompletionCreateInputSchema, bt as TaskScheduleHandler, c as AiEvents, ct as ReceivedCreditTransaction, d as ApiKeyType, dt as ResearchModeParamsSchema, et as PermissionDeniedError, f as AppFileEvents, ft as ResearchTaskExecutionType, g as BFL_IMAGE_MODELS, gt as SpeechToTextUsageTransaction, h as BFLSafetyToleranceSchema, ht as SessionEvents, in as isNearLimit, it as PromptMetaZodSchema, j as FriendshipEvents, jt as XAI_IMAGE_MODELS, k as FileEvents, kt as VideoGenerationUsageTransaction, l as ApiKeyEvents, lt as RechartsChartTypeList, m as AuthEvents, mt as ResearchTaskType, n as logger, nn as buildRateLimitLogEntry, nt as ProjectEvents, on as CollectionType, ot as QuestMasterParamsSchema, p as ArtifactTypeSchema, pt as ResearchTaskPeriodicFrequencyType, q as MiscEvents, qt as sanitizeTelemetryError, rn as extractSnippetMeta, rt as PromptIntentSchema, s as ALERT_THRESHOLDS, st as RealtimeVoiceUsageTransaction, t as ConfigStore, tn as wrapUntrustedSkillBody, tt as ProfileEvents, u as ApiKeyScope, ut as RegInviteEvents, v as BadRequestError, vt as SupportedFabFileMimeTypes, w as CorruptedFileError, wt as TransferCreditTransaction, x as ChatModels, xt as TextGenerationUsageTransaction, yt as TagType, z as ImageGenerationUsageTransaction, zt as isGPTImageModel } from "./ConfigStore-Cq20962p.mjs";
2
+ import { $ as Permission, $t as toDataLakeConfig, A as ForbiddenError, At as VideoModels, B as ImageModels, Bt as isImageServeable, C as CompletionApiUsageTransaction, Ct as ToolUsageTransaction, D as FavoriteDocumentType, Dt as UnprocessableEntityError, E as ElabsEvents, Et as UnauthorizedError, F as GenericCreditDeductTransaction, Ft as getMcpProviderMetadata, G as KnowledgeType, Gt as mapMimeTypeToArtifactType, H as InternalServerError, Ht as isSupportedEmbeddingModel, I as HTTPError, It as getViewById, J as ModalEvents, Jt as resolveNavigationIntents, K as LLMEvents, Kt as obfuscateApiKey, L as HttpStatus, Lt as intersectAllowedTools, M as GEMINI_IMAGE_MODELS, Mt as b4mLLMTools, N as GenerateImageToolCallSchema, Nt as dayjsConfig_default, O as FeedbackEvents, Ot as VIDEO_SIZE_CONSTRAINTS, P as GenericCreditAddTransaction, Pt as getAccessibleDataLakes, Q as OpenAIImageGenerationInput, Qt as substituteArguments$1, R as ImageEditUsageTransaction, Rt as isGPTImage2Model, S as ClaudeArtifactMimeTypes, St as TooManyRequestsError, T as DashboardParamsSchema, Tt as UiNavigationEvents, U as InviteEvents, Ut as isSupportedFabFileMimeType, V as InboxEvents, Vt as isModelAccessible, W as InviteType, Wt as isZodError, X as NotFoundError, Xt as secureParameters, Y as ModelBackend, Yt as sanitizeTelemetryError, Z as OpenAIEmbeddingModel, Zt as settingsMap, _ as BFL_SAFETY_TOLERANCE, _t as SubscriptionCreditTransaction, an as extractSnippetMeta, at as PurchaseTransaction, b as ChatCompletionCreateInputSchema, bt as TaskScheduleHandler, c as AiEvents, cn as CollectionType, ct as ReceivedCreditTransaction, d as ApiKeyType, dt as ResearchModeParamsSchema, en as usdToCredits, et as PermissionDeniedError, f as AppFileEvents, ft as ResearchTaskExecutionType, g as BFL_IMAGE_MODELS, gt as SpeechToTextUsageTransaction, h as BFLSafetyToleranceSchema, ht as SessionEvents, in as buildRateLimitLogEntry, it as PromptMetaZodSchema, j as FriendshipEvents, jt as XAI_IMAGE_MODELS, k as FileEvents, kt as VideoGenerationUsageTransaction, l as ApiKeyEvents, lt as RechartsChartTypeList, m as AuthEvents, mt as ResearchTaskType, n as logger, nt as ProjectEvents, on as isNearLimit, ot as QuestMasterParamsSchema, p as ArtifactTypeSchema, pt as ResearchTaskPeriodicFrequencyType, q as MiscEvents, qt as parseSkillArguments, rn as wrapUntrustedSkillBody, rt as PromptIntentSchema, s as ALERT_THRESHOLDS, sn as parseRateLimitHeaders, st as RealtimeVoiceUsageTransaction, t as ConfigStore, tt as ProfileEvents, u as ApiKeyScope, ut as RegInviteEvents, v as BadRequestError, vt as SupportedFabFileMimeTypes, w as CorruptedFileError, wt as TransferCreditTransaction, x as ChatModels, xt as TextGenerationUsageTransaction, yt as TagType, z as ImageGenerationUsageTransaction, zt as isGPTImageModel } from "./ConfigStore-D39UqFnY.mjs";
3
3
  import { a as hashBackupCode, c as shouldResetFailedAttempts, d as userHasMFAConfigured, f as userRequiresMFA, i as getLockoutTimeRemaining, l as userCanDisableMFA, m as verifyTOTPToken, n as generateBackupCodes, o as isUserLockedOut, p as verifyBackupCode, r as generateTOTPSetup, s as recordFailedAttempt, t as clearFailedAttempts, u as userEligibleForMFA } from "./utils-Cdktpk_k.mjs";
4
4
  import { n as isPathAllowed, t as assertPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
5
- import { t as version } from "./package-CBaK53NX.mjs";
5
+ import { t as version } from "./package-I_v_WFUn.mjs";
6
6
  import { execFile, execFileSync, spawn } from "child_process";
7
7
  import crypto, { createHash, randomBytes, randomUUID } from "crypto";
8
8
  import { existsSync, promises, readFileSync, readdirSync, rmSync, statSync, unlinkSync, writeFileSync } from "fs";
@@ -36,7 +36,7 @@ import * as zlib from "node:zlib";
36
36
  import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
37
37
  import { ApiGatewayManagementApiClient, PostToConnectionCommand } from "@aws-sdk/client-apigatewaymanagementapi";
38
38
  import OpenAI from "openai";
39
- import { DetectModerationLabelsCommand, RekognitionClient } from "@aws-sdk/client-rekognition";
39
+ import { DetectModerationLabelsCommand, InvalidImageFormatException, RekognitionClient } from "@aws-sdk/client-rekognition";
40
40
  import { InvokeCommand, LambdaClient } from "@aws-sdk/client-lambda";
41
41
  import { GoogleGenAI } from "@google/genai";
42
42
  import FirecrawlApp, { FirecrawlError } from "@mendable/firecrawl-js";
@@ -3288,11 +3288,38 @@ const getMimeTypeByExtension = (ext) => {
3288
3288
  "conf"
3289
3289
  ].includes(lowerExt)) return SupportedFabFileMimeTypes.TXT_PLAIN;
3290
3290
  if (lowerExt === "tsx" || lowerExt === "ts") return SupportedFabFileMimeTypes.TS;
3291
+ if (lowerExt === "mdx") return SupportedFabFileMimeTypes.TXT_MARKDOWN;
3291
3292
  if (lowerExt === "xls") return SupportedFabFileMimeTypes.XLS;
3292
3293
  if (lowerExt === "xlsx") return SupportedFabFileMimeTypes.XLSX;
3293
3294
  if (lowerExt === "docx") return SupportedFabFileMimeTypes.DOCX;
3295
+ if (lowerExt === "pptx") return SupportedFabFileMimeTypes.PPTX;
3296
+ if (lowerExt === "jpeg") return SupportedFabFileMimeTypes.JPG;
3294
3297
  return EXT_TO_MIME[lowerExt] ?? "";
3295
3298
  };
3299
+ /**
3300
+ * Resolve the effective, supported MIME type for an uploaded file.
3301
+ *
3302
+ * Browsers frequently report an empty or generic (`application/octet-stream`)
3303
+ * MIME type — even for supported code/text files (e.g. `.py`, `.ts`). We trust
3304
+ * a claimed type only if it's already supported; otherwise we derive the type
3305
+ * from the file extension. The returned `mimeType` is what should be persisted
3306
+ * (so the chunker keys on a type it can actually process), and `supported`
3307
+ * gates ingest so unsupported/binary files (e.g. `.exe`) are rejected. (#9836)
3308
+ *
3309
+ * @param fileName - Original file name (used to derive the extension).
3310
+ * @param claimedMimeType - The browser/client-provided MIME type, if any.
3311
+ */
3312
+ function resolveSupportedMimeType(fileName, claimedMimeType) {
3313
+ if (isSupportedFabFileMimeType(claimedMimeType)) return {
3314
+ mimeType: claimedMimeType,
3315
+ supported: true
3316
+ };
3317
+ const byExtension = getMimeTypeByExtension(getFileExtension(fileName));
3318
+ return {
3319
+ mimeType: byExtension,
3320
+ supported: isSupportedFabFileMimeType(byExtension)
3321
+ };
3322
+ }
3296
3323
  const MIME_TO_EXT = {
3297
3324
  [SupportedFabFileMimeTypes.TXT_PLAIN]: "txt",
3298
3325
  [SupportedFabFileMimeTypes.TXT_MARKDOWN]: "md",
@@ -3301,9 +3328,14 @@ const MIME_TO_EXT = {
3301
3328
  [SupportedFabFileMimeTypes.CSV]: "csv",
3302
3329
  [SupportedFabFileMimeTypes.JPG]: "jpg",
3303
3330
  [SupportedFabFileMimeTypes.PNG]: "png",
3331
+ [SupportedFabFileMimeTypes.GIF]: "gif",
3332
+ [SupportedFabFileMimeTypes.SVG]: "svg",
3333
+ [SupportedFabFileMimeTypes.WEBP]: "webp",
3304
3334
  [SupportedFabFileMimeTypes.PDF]: "pdf",
3305
3335
  [SupportedFabFileMimeTypes.JSON]: "json",
3336
+ [SupportedFabFileMimeTypes.XML]: "xml",
3306
3337
  [SupportedFabFileMimeTypes.DOCX]: "docx",
3338
+ [SupportedFabFileMimeTypes.PPTX]: "pptx",
3307
3339
  [SupportedFabFileMimeTypes.XLSX]: "xlsx",
3308
3340
  [SupportedFabFileMimeTypes.XLS]: "xls",
3309
3341
  [SupportedFabFileMimeTypes.JS]: "js",
@@ -3790,6 +3822,10 @@ async function processFabFilesServer(embeddingFactory, fabFiles, userPrompt, max
3790
3822
  const processFileInParallel = async (file) => {
3791
3823
  try {
3792
3824
  if (supportsVision && file.mimeType.startsWith("image/")) {
3825
+ if (!isImageServeable(file)) {
3826
+ logger.warn(`[processFabFilesServer] Skipping image file ${file.fileName} — held pending moderation or blocked (#9776 Q2b).`);
3827
+ return;
3828
+ }
3793
3829
  sendStatusUpdate(`Processing image file ${file.fileName}...`);
3794
3830
  const fileUrl = file.filePath ? await getCachedSignedUrl(file.filePath, storage, db) : void 0;
3795
3831
  if (!fileUrl) throw new Error(`Failed to get signed URL for file ${file.fileName}`);
@@ -4868,6 +4904,19 @@ var ClientMessageSender = class {
4868
4904
  this.connectionCache.delete(userId);
4869
4905
  }
4870
4906
  };
4907
+ /**
4908
+ * Thrown by {@link ModerationService.checkPrompt} when a prompt is flagged. Carries the
4909
+ * flagged category labels so callers can record a per-user moderation hit (#9778) before
4910
+ * surfacing the block to the user. The `message` stays user-facing and unchanged.
4911
+ */
4912
+ var FlaggedContentError = class extends Error {
4913
+ categories;
4914
+ constructor(message, categories) {
4915
+ super(message);
4916
+ this.categories = categories;
4917
+ this.name = "FlaggedContentError";
4918
+ }
4919
+ };
4871
4920
  var OpenaiModerationsService = class {
4872
4921
  apiKey;
4873
4922
  logger;
@@ -4893,7 +4942,7 @@ var OpenaiModerationsService = class {
4893
4942
  return acc;
4894
4943
  }, []);
4895
4944
  this.logger.error(`Prompt has been flagged for potential harmful content:`, JSON.stringify(moderation, null, 2));
4896
- throw new Error(`We're sorry, your prompt has been flagged for potential harmful content on the following categories: ${flaggedCategories.join(", ")}`);
4945
+ throw new FlaggedContentError(`We're sorry, your prompt has been flagged for potential harmful content on the following categories: ${flaggedCategories.join(", ")}`, flaggedCategories);
4897
4946
  }
4898
4947
  }
4899
4948
  };
@@ -4935,6 +4984,25 @@ var ImageModerationBlockedError = class extends Error {
4935
4984
  this.labels = labels;
4936
4985
  }
4937
4986
  };
4987
+ /**
4988
+ * Thrown by `checkImage` when the image bytes are a format Rekognition's
4989
+ * `DetectModerationLabels` cannot process (`InvalidImageFormatException` — it only accepts
4990
+ * JPEG/PNG, and WEBP in some regions) AND jimp cannot decode/transcode them into something
4991
+ * it can (e.g. HEIC, SVG) — #9776 P1-4.
4992
+ *
4993
+ * Deliberately distinct from both `ImageModerationBlockedError` (a confirmed explicit-
4994
+ * content match, with `labels`) and a bare `Error` (a transient/retryable failure like
4995
+ * throttling): this is a deterministic, non-retryable "we structurally cannot scan this"
4996
+ * outcome. The caller (`moderateUploadedFile`) maps it to a terminal 'blocked' verdict
4997
+ * instead of rethrowing for S3 to redeliver forever — an unscannable image must fail closed
4998
+ * (not served) rather than get stuck 'pending' indefinitely.
4999
+ */
5000
+ var UnsupportedImageFormatError = class extends Error {
5001
+ constructor(message) {
5002
+ super(message);
5003
+ this.name = "UnsupportedImageFormatError";
5004
+ }
5005
+ };
4938
5006
  var RekognitionImageModerationService = class {
4939
5007
  client;
4940
5008
  logger;
@@ -4945,12 +5013,38 @@ var RekognitionImageModerationService = class {
4945
5013
  maxAttempts: 1
4946
5014
  });
4947
5015
  }
4948
- /** Downscale buffers that exceed Rekognition's inline 5 MB limit so the check still runs. */
5016
+ /**
5017
+ * Downscale buffers that exceed Rekognition's inline 5 MB limit so the check still runs.
5018
+ *
5019
+ * Split into two try/catches deliberately (#9776 Q2b): a `Jimp.read()` failure means jimp
5020
+ * could not even decode the format — the SAME condition `transcodeToJpeg`'s catch below
5021
+ * treats as a confirmed unsupported format — so it's terminal via `UnsupportedImageFormatError`
5022
+ * right here. Without this, an oversized+undecodable buffer (e.g. HEIC from an iPhone, which
5023
+ * is both large and a format jimp can't read) would fall through with the ORIGINAL oversized
5024
+ * bytes; Rekognition would then likely throw `ImageTooLargeException` rather than
5025
+ * `InvalidImageFormatException` (it never gets far enough to inspect the format), which isn't
5026
+ * caught by the reactive transcode branch in `checkImage` — so it would burn the
5027
+ * transient-retry budget and get stuck 'pending' until DLQ instead of terminating cleanly.
5028
+ * `Jimp.read()` is a synchronous local decode with no I/O, so unlike the Rekognition call
5029
+ * there is no throttling/5xx-style transient failure mode to preserve here — any read failure
5030
+ * is safely treated as terminal.
5031
+ *
5032
+ * A failure in the SECOND try (resize/re-encode, after a successful decode) is NOT a format
5033
+ * problem — jimp already proved it can read these bytes — so that one keeps the original
5034
+ * fall-through-with-original-bytes behavior: the Rekognition call will fail-closed (block)
5035
+ * rather than silently skip, which is the safe direction.
5036
+ */
4949
5037
  async fitForInlineDetection(bytes) {
4950
5038
  if (bytes.length <= MAX_INLINE_IMAGE_BYTES) return bytes;
5039
+ const { Jimp } = await import("jimp");
5040
+ let image;
5041
+ try {
5042
+ image = await Jimp.read(bytes);
5043
+ } catch (err) {
5044
+ this.logger.warn(`[ImageModeration] oversized image (${bytes.length}B) could not be decoded for downscaling, unsupported format: ${err.message}`);
5045
+ throw new UnsupportedImageFormatError(`Oversized image (${bytes.length}B) could not be decoded for downscaling: ${err.message}`);
5046
+ }
4951
5047
  try {
4952
- const { Jimp } = await import("jimp");
4953
- const image = await Jimp.read(bytes);
4954
5048
  const { width, height } = image.bitmap;
4955
5049
  const scale = 2048 / Math.max(width, height);
4956
5050
  const resized = Buffer.from(await image.resize({
@@ -4964,8 +5058,22 @@ var RekognitionImageModerationService = class {
4964
5058
  return bytes;
4965
5059
  }
4966
5060
  }
5061
+ /**
5062
+ * Re-encode arbitrary jimp-decodable bytes as JPEG (#9776 P1-4). Used reactively when
5063
+ * Rekognition rejects the original format — jimp decodes jpeg/png/webp/gif/bmp/tiff, a
5064
+ * broader set than Rekognition itself accepts (jpeg/png, webp in some regions), so this
5065
+ * recovers formats Rekognition can't parse but jimp can. If jimp ALSO can't decode the
5066
+ * bytes (e.g. HEIC, SVG), it throws and the caller treats that as a confirmed unsupported
5067
+ * format rather than a transient failure.
5068
+ */
5069
+ async transcodeToJpeg(bytes) {
5070
+ const { Jimp } = await import("jimp");
5071
+ const image = await Jimp.read(bytes);
5072
+ return Buffer.from(await image.getBuffer("image/jpeg"));
5073
+ }
4967
5074
  async checkImage(bytes, _mimeType) {
4968
- const image = await this.fitForInlineDetection(bytes);
5075
+ let image = await this.fitForInlineDetection(bytes);
5076
+ let triedTranscode = false;
4969
5077
  let lastError;
4970
5078
  for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) try {
4971
5079
  const hits = ((await this.client.send(new DetectModerationLabelsCommand({
@@ -4980,6 +5088,18 @@ var RekognitionImageModerationService = class {
4980
5088
  return;
4981
5089
  } catch (err) {
4982
5090
  if (err instanceof ImageModerationBlockedError) throw err;
5091
+ if (err instanceof InvalidImageFormatException && !triedTranscode) {
5092
+ triedTranscode = true;
5093
+ try {
5094
+ image = await this.transcodeToJpeg(image);
5095
+ this.logger.warn("[ImageModeration] Rekognition rejected the original format; transcoded to JPEG via jimp and retrying");
5096
+ attempt--;
5097
+ continue;
5098
+ } catch (transcodeErr) {
5099
+ this.logger.warn(`[ImageModeration] unsupported image format, cannot transcode: ${transcodeErr.message}`);
5100
+ throw new UnsupportedImageFormatError(`Rekognition rejected the format (${err.name}) and it could not be transcoded: ${transcodeErr.message}`);
5101
+ }
5102
+ }
4983
5103
  lastError = err;
4984
5104
  this.logger.warn(`[ImageModeration] Rekognition attempt ${attempt}/${MAX_ATTEMPTS} failed: ${err.message}`);
4985
5105
  }
@@ -8091,6 +8211,7 @@ __reExport(/* @__PURE__ */ __exportAll$1({
8091
8211
  EmbeddingFactory: () => EmbeddingFactory,
8092
8212
  EmbeddingModelProvider: () => EmbeddingModelProvider,
8093
8213
  EmbeddingService: () => EmbeddingService,
8214
+ FlaggedContentError: () => FlaggedContentError,
8094
8215
  ForbiddenError: () => ForbiddenError,
8095
8216
  FunctionQueueRunner: () => FunctionQueueRunner,
8096
8217
  GeminiImageService: () => GeminiImageService,
@@ -8127,6 +8248,7 @@ __reExport(/* @__PURE__ */ __exportAll$1({
8127
8248
  URL_REGEX: () => URL_REGEX,
8128
8249
  UnauthorizedError: () => UnauthorizedError,
8129
8250
  UnprocessableEntityError: () => UnprocessableEntityError,
8251
+ UnsupportedImageFormatError: () => UnsupportedImageFormatError,
8130
8252
  VOYAGEAI_EMBEDDING_MODEL_MAP: () => VOYAGEAI_EMBEDDING_MODEL_MAP,
8131
8253
  VoyageAIEmbeddingProvider: () => VoyageAIEmbeddingProvider,
8132
8254
  XAIImageService: () => XAIImageService,
@@ -8202,6 +8324,7 @@ __reExport(/* @__PURE__ */ __exportAll$1({
8202
8324
  processUrlsFromPrompt: () => processUrlsFromPrompt,
8203
8325
  registerLambdaErrorHandlers: () => registerLambdaErrorHandlers,
8204
8326
  registerProcessErrorHandlers: () => registerProcessErrorHandlers,
8327
+ resolveSupportedMimeType: () => resolveSupportedMimeType,
8205
8328
  secureParameters: () => secureParameters,
8206
8329
  sendToConnection: () => sendToConnection,
8207
8330
  shouldTriggerFallback: () => shouldTriggerFallback,
@@ -9005,7 +9128,7 @@ function sanitizeJsonStringWithMeta(jsonStr, options) {
9005
9128
  };
9006
9129
  }
9007
9130
  //#endregion
9008
- //#region ../../b4m-core/services/dist/tools-BuXYw9Ho.mjs
9131
+ //#region ../../b4m-core/services/dist/tools-CVuY-EzZ.mjs
9009
9132
  const createFabFileSchema = z.object({
9010
9133
  fileName: z.string(),
9011
9134
  mimeType: z.string(),
@@ -9039,12 +9162,10 @@ const createFabFile = async (userId, parameters, { db, storage }) => {
9039
9162
  const params = secureParameters(parameters, createFabFileSchema);
9040
9163
  const user = await db.users.findById(userId);
9041
9164
  if (!user) throw new BadRequestError("User not found");
9042
- let ext = "";
9043
- let mimeType = parameters.mimeType;
9044
- ext = getFileExtension(params.fileName);
9045
- mimeType = params.mimeType || getMimeTypeByExtension(ext);
9046
- if (!mimeType) mimeType = SupportedFabFileMimeTypes.TXT_PLAIN;
9047
- if (!Object.values(SupportedFabFileMimeTypes).some((type) => type === mimeType)) throw new BadRequestError(`File type ${mimeType} is not supported`);
9165
+ const ext = getFileExtension(params.fileName);
9166
+ let mimeType = params.mimeType || getMimeTypeByExtension(ext);
9167
+ if (!mimeType && !ext) mimeType = SupportedFabFileMimeTypes.TXT_PLAIN;
9168
+ if (!isSupportedFabFileMimeType(mimeType)) throw new BadRequestError(`File type ${mimeType || (ext ? `.${ext}` : "unknown")} is not supported`);
9048
9169
  let filePath = params.prefix ? `${params.prefix}/` : "";
9049
9170
  filePath += `${v4()}${ext ? `.${ext}` : ".txt"}`;
9050
9171
  const maxFileSize = getSettingsValue("MaxFileSize", await getSettingsMap(db), DEFAULT_MAX_FILE_SIZE) * 1024 * 1024;
@@ -9067,8 +9188,10 @@ const createFabFile = async (userId, parameters, { db, storage }) => {
9067
9188
  ContentType: params.contentType,
9068
9189
  ContentLength: params.fileSize
9069
9190
  });
9070
- buildData.fileUrl = await storage.generateSignedUrl(filePath, DEFAULT_EXPIRE_IN_SECONDS, "get");
9071
- buildData.fileUrlExpireAt = new Date(Date.now() + DEFAULT_EXPIRE_IN_SECONDS * 1e3);
9191
+ if (!mimeType.startsWith("image/")) {
9192
+ buildData.fileUrl = await storage.generateSignedUrl(filePath, DEFAULT_EXPIRE_IN_SECONDS, "get");
9193
+ buildData.fileUrlExpireAt = new Date(Date.now() + DEFAULT_EXPIRE_IN_SECONDS * 1e3);
9194
+ }
9072
9195
  } else buildData.presignedUrl = await storage.generateSignedUrl(filePath, 600, "put");
9073
9196
  return await db.fabFiles.create(buildData);
9074
9197
  };
@@ -10785,6 +10908,7 @@ const editFileTool = {
10785
10908
  const fabFile = await context.db.fabFiles?.findById(fileId);
10786
10909
  if (!fabFile) throw new NotFoundError(`File with ID ${fileId} not found`);
10787
10910
  if (!fabFile || !fabFile.fileUrl && !fabFile.filePath) throw new Error("File has no content to edit");
10911
+ if (fabFile && !isImageServeable(fabFile)) throw new Error("This image is not available.");
10788
10912
  let contentToEdit = "";
10789
10913
  if (fabFile.fileUrl) {
10790
10914
  context.logger.info(`📝 Edit File Tool: Fetching content from URL for file ${fileId}`);
@@ -10942,6 +11066,7 @@ async function getImageFromFileId(fileId, context) {
10942
11066
  const fabFile = await context.db.fabfiles?.findById(fileId);
10943
11067
  if (!fabFile) throw new NotFoundError(`File with ID ${fileId} not found`);
10944
11068
  if (!fabFile.mimeType?.startsWith("image/")) throw new Error(`File ${fileId} is not an image`);
11069
+ if (!isImageServeable(fabFile)) throw new Error("This image is not available.");
10945
11070
  if (fabFile.filePath) return await context.storage.getSignedUrl(fabFile.filePath);
10946
11071
  if (fabFile.fileUrl) return fabFile.fileUrl;
10947
11072
  throw new Error(`File ${fileId} has no accessible URL`);
@@ -17950,7 +18075,13 @@ updateUserSchema.extend({
17950
18075
  userName: z.string()
17951
18076
  })).optional(),
17952
18077
  numReferralsAvailable: z.number().optional(),
17953
- disputePending: z.boolean().optional()
18078
+ disputePending: z.boolean().optional(),
18079
+ moderationStatus: z.enum([
18080
+ "active",
18081
+ "throttled",
18082
+ "suspend_pending",
18083
+ "suspended"
18084
+ ]).optional()
17954
18085
  });
17955
18086
  new Set(disposableDomains);
17956
18087
  z.object({
@@ -18421,6 +18552,7 @@ z.object({
18421
18552
  dataLakeTags: z.array(z.string()).optional(),
18422
18553
  dataLakeTagPrefixes: z.array(z.string()).optional(),
18423
18554
  scopedTagPrefixes: z.array(z.string()).optional(),
18555
+ restrictToDataLake: z.coerce.boolean().optional(),
18424
18556
  excludeContent: z.coerce.boolean().optional()
18425
18557
  }).optional()
18426
18558
  });
@@ -1261,6 +1261,51 @@ const CREDIT_DEDUCT_TRANSACTION_TYPES = [
1261
1261
  "transfer_credit",
1262
1262
  "generic_deduct"
1263
1263
  ];
1264
+ z.object({
1265
+ id: z.string().optional(),
1266
+ /** App-level correlation id: questId for chat/image/video, session/run id otherwise. */
1267
+ requestId: z.string(),
1268
+ userId: z.string(),
1269
+ /** Credit holder actually debited (user or organization). */
1270
+ ownerId: z.string(),
1271
+ ownerType: z.enum(CreditHolderType),
1272
+ sessionId: z.string().optional(),
1273
+ feature: z.enum([
1274
+ "chat",
1275
+ "image_generation",
1276
+ "image_edit",
1277
+ "video_generation",
1278
+ "voice",
1279
+ "transcription",
1280
+ "agent_execution",
1281
+ "completion_api",
1282
+ "tool"
1283
+ ]),
1284
+ /** Provider/backend, e.g. 'bedrock', 'openai', 'gemini'. */
1285
+ provider: z.string(),
1286
+ /** Exact model id string used for the call. */
1287
+ model: z.string(),
1288
+ inputTokens: z.number().default(0),
1289
+ outputTokens: z.number().default(0),
1290
+ cachedInputTokens: z.number().default(0),
1291
+ cacheWriteTokens: z.number().default(0),
1292
+ providerInputTokens: z.number().optional(),
1293
+ providerOutputTokens: z.number().optional(),
1294
+ /** Images generated / video seconds, for per-unit modalities. */
1295
+ units: z.number().optional(),
1296
+ /** True provider COGS in USD, computed and frozen at write time. */
1297
+ costUsd: z.number(),
1298
+ /** Credits actually debited from the owner for this call. */
1299
+ creditsCharged: z.number(),
1300
+ status: z.enum([
1301
+ "ok",
1302
+ "error",
1303
+ "timeout"
1304
+ ]).default("ok"),
1305
+ latencyMs: z.number().optional(),
1306
+ createdAt: z.date(),
1307
+ updatedAt: z.date()
1308
+ });
1264
1309
  let ResearchTaskExecutionType = /* @__PURE__ */ function(ResearchTaskExecutionType) {
1265
1310
  /**
1266
1311
  * The task is executed on demand
@@ -1647,6 +1692,23 @@ let SupportedFabFileMimeTypes = /* @__PURE__ */ function(SupportedFabFileMimeTyp
1647
1692
  return SupportedFabFileMimeTypes;
1648
1693
  }({});
1649
1694
  /**
1695
+ * The canonical set of MIME types the ingest pipeline can actually chunk +
1696
+ * vectorize. Kept in lockstep with the `SmartChunker` switch in
1697
+ * `@bike4mind/fab-pipeline`.
1698
+ */
1699
+ const SUPPORTED_FAB_FILE_MIME_TYPES = new Set(Object.values(SupportedFabFileMimeTypes));
1700
+ /**
1701
+ * Type guard: is a claimed MIME type one we actually support ingesting?
1702
+ *
1703
+ * Used to gate uploads so unsupported/binary files (e.g. `.exe`) are rejected
1704
+ * with a clear error instead of being stored and silently "vectorized" into 0
1705
+ * chunks. Node-free so it can run on both the client (upload UI) and server
1706
+ * (ingest endpoints).
1707
+ */
1708
+ function isSupportedFabFileMimeType(mimeType) {
1709
+ return !!mimeType && SUPPORTED_FAB_FILE_MIME_TYPES.has(mimeType);
1710
+ }
1711
+ /**
1650
1712
  * Canonical agent execution status tuple. Shared between the database model
1651
1713
  * (`AgentExecutionModel`), the client store (`useAgentExecutionStore`), and
1652
1714
  * wire schemas (`ChildExecutionSnapshotSchema`, etc.) so the value space can't
@@ -2090,6 +2152,17 @@ const DataLakeBatchProgressAction = z.object({
2090
2152
  "cancelled"
2091
2153
  ]).optional()
2092
2154
  });
2155
+ /** Verdict for a freshly-uploaded FabFile after the S3-event moderation scan (#9776 Q2b). */
2156
+ const ImageModerationStatusAction = z.object({
2157
+ action: z.literal("image_moderation_status"),
2158
+ clientId: z.string().optional(),
2159
+ fabFileId: z.string(),
2160
+ moderationStatus: z.enum([
2161
+ "pending",
2162
+ "clean",
2163
+ "blocked"
2164
+ ])
2165
+ });
2093
2166
  const UpdateResearchTaskStatusAction = z.object({
2094
2167
  action: z.literal("update_research_task_status"),
2095
2168
  clientId: z.string().optional(),
@@ -2988,6 +3061,7 @@ z.discriminatedUnion("action", [
2988
3061
  TavernStockUpdateAction,
2989
3062
  JupyterNotebookProgressAction,
2990
3063
  DataLakeBatchProgressAction,
3064
+ ImageModerationStatusAction,
2991
3065
  CcAgentCommandAction,
2992
3066
  QuantumRunUpdatedAction,
2993
3067
  ExecutionStartedAction,
@@ -4074,6 +4148,7 @@ z.enum([
4074
4148
  "SlackLiveopsWebhookUrl",
4075
4149
  "SlackUserActivityWebhookUrl",
4076
4150
  "SlackFeedbackWebhookUrl",
4151
+ "SlackEmailAuditWebhookUrl",
4077
4152
  "slackSigningSecret",
4078
4153
  "slackBotToken",
4079
4154
  "enforceMFA",
@@ -4084,7 +4159,6 @@ z.enum([
4084
4159
  "voiceSessionTranscriptionModel",
4085
4160
  "voiceSessionVadType",
4086
4161
  "voiceSessionVadEagerness",
4087
- "pdfjsExpressViewerKey",
4088
4162
  "EnableEmailAnalysis",
4089
4163
  "EmailAnalysisModel",
4090
4164
  "EmailAnalysisTemperature",
@@ -5016,6 +5090,10 @@ const API_SERVICE_GROUPS = {
5016
5090
  key: "SlackUserActivityWebhookUrl",
5017
5091
  order: 6
5018
5092
  },
5093
+ {
5094
+ key: "SlackEmailAuditWebhookUrl",
5095
+ order: 6.5
5096
+ },
5019
5097
  {
5020
5098
  key: "FeedbackSendEmailUsername",
5021
5099
  order: 7
@@ -5421,16 +5499,6 @@ const API_SERVICE_GROUPS = {
5421
5499
  order: 1
5422
5500
  }]
5423
5501
  },
5424
- PDF_VIEWER: {
5425
- id: "pdfViewerService",
5426
- name: "PDF Viewer",
5427
- description: "PDF.js Express Viewer settings",
5428
- icon: "PictureAsPdf",
5429
- settings: [{
5430
- key: "pdfjsExpressViewerKey",
5431
- order: 1
5432
- }]
5433
- },
5434
5502
  DATETIME_ASTRONOMY: {
5435
5503
  id: "datetimeAstronomyService",
5436
5504
  name: "Time Machine & Night Sky",
@@ -5986,6 +6054,16 @@ const settingsMap = {
5986
6054
  order: 7,
5987
6055
  isSensitive: true
5988
6056
  }),
6057
+ SlackEmailAuditWebhookUrl: makeStringSetting({
6058
+ key: "SlackEmailAuditWebhookUrl",
6059
+ name: "Email Audit Channel Webhook URL",
6060
+ defaultValue: "",
6061
+ description: "Incoming-webhook URL for mirroring a redacted copy of every outbound email to a dedicated audit Slack channel (e.g. #b4m-emails) for real-time visibility (#9872). Use a PRIVATE, need-to-know channel — mirrored copies contain recipient email addresses. Secrets/tokens (reset & verification links) are redacted before posting.",
6062
+ category: "Feedback",
6063
+ group: API_SERVICE_GROUPS.FEEDBACK.id,
6064
+ order: 8,
6065
+ isSensitive: true
6066
+ }),
5989
6067
  liveFeedbackEmail: makeStringSetting({
5990
6068
  key: "liveFeedbackEmail",
5991
6069
  name: "Live Feedback Email",
@@ -6767,16 +6845,6 @@ const settingsMap = {
6767
6845
  order: 10,
6768
6846
  schema: RapidReplySettingsSchema
6769
6847
  }),
6770
- pdfjsExpressViewerKey: makeStringSetting({
6771
- key: "pdfjsExpressViewerKey",
6772
- name: "PDF.js Express Viewer Key",
6773
- defaultValue: "",
6774
- description: "The license key for PDF.js Express Viewer for PDF document viewing.",
6775
- isSensitive: true,
6776
- category: "Tools",
6777
- group: API_SERVICE_GROUPS.PDF_VIEWER.id,
6778
- order: 1
6779
- }),
6780
6848
  EnableEmailAnalysis: makeBooleanSetting({
6781
6849
  key: "EnableEmailAnalysis",
6782
6850
  name: "Enable Email Analysis",
@@ -8570,6 +8638,7 @@ const PromptBatchQuerySchema = z.object({
8570
8638
  z.object({ queries: z.array(PromptBatchQuerySchema).min(1).max(32).refine((qs) => new Set(qs.map((q) => q.key)).size === qs.length, { message: "Batch query keys must be unique" }) });
8571
8639
  const DATA_LAKES = [{
8572
8640
  id: "ionq-sales",
8641
+ slug: "ionq-sales",
8573
8642
  name: "IonQ Sales Intelligence",
8574
8643
  requiredUserTag: "Opti",
8575
8644
  requiredEntitlement: "optihashi:pro",
@@ -8577,6 +8646,7 @@ const DATA_LAKES = [{
8577
8646
  datalakeTag: "datalake:ionq-sales"
8578
8647
  }, {
8579
8648
  id: "opti-knowledge",
8649
+ slug: "opti-knowledge",
8580
8650
  name: "Optimization Knowledge Base",
8581
8651
  requiredUserTag: "Opti",
8582
8652
  requiredEntitlement: "optihashi:pro",
@@ -8617,6 +8687,7 @@ function lakeMatchesAccess(lake, normalizedUserTags, normalizedKeys) {
8617
8687
  function toDataLakeConfig(dl) {
8618
8688
  return {
8619
8689
  id: dl.id,
8690
+ slug: dl.slug,
8620
8691
  name: dl.name,
8621
8692
  requiredUserTag: dl.requiredUserTag,
8622
8693
  requiredEntitlement: dl.requiredEntitlement,
@@ -9547,6 +9618,8 @@ z.object({
9547
9618
  userId: z.string(),
9548
9619
  sessionId: z.string().optional(),
9549
9620
  questId: z.string().optional(),
9621
+ /** Uploaded-image incidents (#9776 Q2b) reference the FabFile instead of a quest/session. */
9622
+ fabFileId: z.string().optional(),
9550
9623
  provider: z.string(),
9551
9624
  model: z.string(),
9552
9625
  labels: z.array(ModerationLabelHitSchema),
@@ -9834,6 +9907,33 @@ function intersectAllowedTools(skillAllowedTools, invokerAllowedTools) {
9834
9907
  const invokerSet = new Set(invokerAllowedTools);
9835
9908
  return skillAllowedTools.filter((tool) => invokerSet.has(tool));
9836
9909
  }
9910
+ /**
9911
+ * Serve gate for uploaded FabFiles (#9776 Q2b, hold-until-scanned; P1-1 fail-closed on ALL
9912
+ * mime types, not just images). A file is serveable only once moderation has run to
9913
+ * completion on it — REGARDLESS of its declared `mimeType`.
9914
+ *
9915
+ * Why gate non-images too: `mimeType` is client-declared at upload time and is only
9916
+ * corrected by the S3 scan ~1-2s later (see `moderateUploadedFile`'s byte-sniffing). If this
9917
+ * gate special-cased "non-images always serveable" based on that same untrusted declared
9918
+ * mimeType, a file uploaded as `application/pdf` but actually a PNG (or vice versa) would be
9919
+ * served during that window before the sniff/scan ever runs. Gating on `moderationStatus`
9920
+ * alone closes that window for every file, image or not.
9921
+ *
9922
+ * `moderationStatus` semantics:
9923
+ * - 'clean' -> serveable
9924
+ * - 'pending' | 'scanning' -> NOT serveable (not yet through the scan)
9925
+ * - 'blocked' -> NOT serveable (confirmed block / unscannable format)
9926
+ * - null | undefined -> NOT serveable (fail-closed; legacy pre-Q2b rows are
9927
+ * backfilled to 'clean', see backfill-fabfile-moderation-status.ts)
9928
+ *
9929
+ * Non-image files (PDFs, docs, text, ...) are NOT scanned by Rekognition, but they still
9930
+ * pass through `moderateUploadedFile`/`objectCreated`, which resolves them to 'clean'
9931
+ * immediately (no image bytes to hold on) — so the hold is brief (one S3 event round trip),
9932
+ * not an indefinite block.
9933
+ */
9934
+ function isImageServeable(f) {
9935
+ return f.moderationStatus === "clean";
9936
+ }
9837
9937
  const VIEW_REGISTRY = [
9838
9938
  {
9839
9939
  id: "opti.root",
@@ -12012,4 +12112,4 @@ var ConfigStore = class {
12012
12112
  }
12013
12113
  };
12014
12114
  //#endregion
12015
- export { Permission as $, validateJupyterKernelName as $t, ForbiddenError as A, VideoModels as At, ImageModels as B, isModelAccessible as Bt, CompletionApiUsageTransaction as C, ToolUsageTransaction as Ct, FavoriteDocumentType as D, UnprocessableEntityError as Dt, ElabsEvents as E, UnauthorizedError as Et, GenericCreditDeductTransaction as F, getMcpProviderMetadata as Ft, KnowledgeType as G, parseSkillArguments as Gt, InternalServerError as H, isZodError as Ht, HTTPError as I, getViewById as It, ModalEvents as J, secureParameters as Jt, LLMEvents as K, resolveNavigationIntents as Kt, HttpStatus as L, intersectAllowedTools as Lt, GEMINI_IMAGE_MODELS as M, b4mLLMTools as Mt, GenerateImageToolCallSchema as N, dayjsConfig_default as Nt, FeedbackEvents as O, VIDEO_SIZE_CONSTRAINTS as Ot, GenericCreditAddTransaction as P, getAccessibleDataLakes as Pt, OpenAIImageGenerationInput as Q, usdToCredits as Qt, ImageEditUsageTransaction as R, isGPTImage2Model as Rt, ClaudeArtifactMimeTypes as S, TooManyRequestsError as St, DashboardParamsSchema as T, UiNavigationEvents as Tt, InviteEvents as U, mapMimeTypeToArtifactType as Ut, InboxEvents as V, isSupportedEmbeddingModel as Vt, InviteType as W, obfuscateApiKey as Wt, NotFoundError as X, substituteArguments as Xt, ModelBackend as Y, settingsMap as Yt, OpenAIEmbeddingModel as Z, toDataLakeConfig as Zt, BFL_SAFETY_TOLERANCE as _, SubscriptionCreditTransaction as _t, getDefaultApiUrl as a, parseRateLimitHeaders as an, PurchaseTransaction as at, ChatCompletionCreateInputSchema as b, TaskScheduleHandler as bt, AiEvents as c, ReceivedCreditTransaction as ct, ApiKeyType as d, ResearchModeParamsSchema as dt, validateNotebookPath as en, PermissionDeniedError as et, AppFileEvents as f, ResearchTaskExecutionType as ft, BFL_IMAGE_MODELS as g, SpeechToTextUsageTransaction as gt, BFLSafetyToleranceSchema as h, SessionEvents as ht, getCreditsUrl as i, isNearLimit as in, PromptMetaZodSchema as it, FriendshipEvents as j, XAI_IMAGE_MODELS as jt, FileEvents as k, VideoGenerationUsageTransaction as kt, ApiKeyEvents as l, RechartsChartTypeList as lt, AuthEvents as m, ResearchTaskType as mt, logger as n, buildRateLimitLogEntry as nn, ProjectEvents as nt, getEnvironmentName as o, CollectionType as on, QuestMasterParamsSchema as ot, ArtifactTypeSchema as p, ResearchTaskPeriodicFrequencyType as pt, MiscEvents as q, sanitizeTelemetryError as qt, getApiUrl as r, extractSnippetMeta as rn, PromptIntentSchema as rt, ALERT_THRESHOLDS as s, RealtimeVoiceUsageTransaction as st, ConfigStore as t, wrapUntrustedSkillBody as tn, ProfileEvents as tt, ApiKeyScope as u, RegInviteEvents as ut, BadRequestError as v, SupportedFabFileMimeTypes as vt, CorruptedFileError as w, TransferCreditTransaction as wt, ChatModels as x, TextGenerationUsageTransaction as xt, CREDIT_DEDUCT_TRANSACTION_TYPES as y, TagType as yt, ImageGenerationUsageTransaction as z, isGPTImageModel as zt };
12115
+ export { Permission as $, toDataLakeConfig as $t, ForbiddenError as A, VideoModels as At, ImageModels as B, isImageServeable as Bt, CompletionApiUsageTransaction as C, ToolUsageTransaction as Ct, FavoriteDocumentType as D, UnprocessableEntityError as Dt, ElabsEvents as E, UnauthorizedError as Et, GenericCreditDeductTransaction as F, getMcpProviderMetadata as Ft, KnowledgeType as G, mapMimeTypeToArtifactType as Gt, InternalServerError as H, isSupportedEmbeddingModel as Ht, HTTPError as I, getViewById as It, ModalEvents as J, resolveNavigationIntents as Jt, LLMEvents as K, obfuscateApiKey as Kt, HttpStatus as L, intersectAllowedTools as Lt, GEMINI_IMAGE_MODELS as M, b4mLLMTools as Mt, GenerateImageToolCallSchema as N, dayjsConfig_default as Nt, FeedbackEvents as O, VIDEO_SIZE_CONSTRAINTS as Ot, GenericCreditAddTransaction as P, getAccessibleDataLakes as Pt, OpenAIImageGenerationInput as Q, substituteArguments as Qt, ImageEditUsageTransaction as R, isGPTImage2Model as Rt, ClaudeArtifactMimeTypes as S, TooManyRequestsError as St, DashboardParamsSchema as T, UiNavigationEvents as Tt, InviteEvents as U, isSupportedFabFileMimeType as Ut, InboxEvents as V, isModelAccessible as Vt, InviteType as W, isZodError as Wt, NotFoundError as X, secureParameters as Xt, ModelBackend as Y, sanitizeTelemetryError as Yt, OpenAIEmbeddingModel as Z, settingsMap as Zt, BFL_SAFETY_TOLERANCE as _, SubscriptionCreditTransaction as _t, getDefaultApiUrl as a, extractSnippetMeta as an, PurchaseTransaction as at, ChatCompletionCreateInputSchema as b, TaskScheduleHandler as bt, AiEvents as c, CollectionType as cn, ReceivedCreditTransaction as ct, ApiKeyType as d, ResearchModeParamsSchema as dt, usdToCredits as en, PermissionDeniedError as et, AppFileEvents as f, ResearchTaskExecutionType as ft, BFL_IMAGE_MODELS as g, SpeechToTextUsageTransaction as gt, BFLSafetyToleranceSchema as h, SessionEvents as ht, getCreditsUrl as i, buildRateLimitLogEntry as in, PromptMetaZodSchema as it, FriendshipEvents as j, XAI_IMAGE_MODELS as jt, FileEvents as k, VideoGenerationUsageTransaction as kt, ApiKeyEvents as l, RechartsChartTypeList as lt, AuthEvents as m, ResearchTaskType as mt, logger as n, validateNotebookPath as nn, ProjectEvents as nt, getEnvironmentName as o, isNearLimit as on, QuestMasterParamsSchema as ot, ArtifactTypeSchema as p, ResearchTaskPeriodicFrequencyType as pt, MiscEvents as q, parseSkillArguments as qt, getApiUrl as r, wrapUntrustedSkillBody as rn, PromptIntentSchema as rt, ALERT_THRESHOLDS as s, parseRateLimitHeaders as sn, RealtimeVoiceUsageTransaction as st, ConfigStore as t, validateJupyterKernelName as tn, ProfileEvents as tt, ApiKeyScope as u, RegInviteEvents as ut, BadRequestError as v, SupportedFabFileMimeTypes as vt, CorruptedFileError as w, TransferCreditTransaction as wt, ChatModels as x, TextGenerationUsageTransaction as xt, CREDIT_DEDUCT_TRANSACTION_TYPES as y, TagType as yt, ImageGenerationUsageTransaction as z, isGPTImageModel as zt };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as getDefaultApiUrl, t as ConfigStore } from "../ConfigStore-Cq20962p.mjs";
2
+ import { a as getDefaultApiUrl, t as ConfigStore } from "../ConfigStore-D39UqFnY.mjs";
3
3
  //#region src/commands/apiCommand.ts
4
4
  /**
5
5
  * External API config command (--api-url / --reset-api)
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "../package-CBaK53NX.mjs";
2
+ import { t as version } from "../package-I_v_WFUn.mjs";
3
3
  import { a as fetchLatestVersion, c as isNpmPrefixWritable, i as compareSemver } from "../updateChecker-C8xsNY2L.mjs";
4
4
  import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
5
5
  import { execSync } from "child_process";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-Cq20962p.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-D39UqFnY.mjs";
3
3
  //#region src/commands/envCommand.ts
4
4
  /**
5
5
  * Environment switching for the `--dev` / `--prod` launch flags.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { C as createCoordinateTaskTool, D as FallbackLlmBackend, E as ApiClient, F as generateCliTools, G as ReActAgent, N as loadContextFiles, O as ServerLlmBackend, P as PermissionManager, Q as CheckpointStore, T as createAgentDelegateTool, W as setWebSocketToolExecutor, X as RemoteSkillSource, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createGetFileStructureTool, a as WebSocketToolExecutor, b as createWriteTodosTool, et as SessionStore, i as McpManager, n as SubagentOrchestrator, o as WebSocketConnectionManager, q as buildSystemPrompt, r as AgentStore, s as WebSocketLlmBackend, t as BackgroundAgentManager, v as createFindDefinitionTool, w as createBackgroundAgentTools, x as createSkillTool, y as createTodoStore } from "../BackgroundAgentManager-DOesheMD.mjs";
3
- import { n as logger, r as getApiUrl, t as ConfigStore } from "../ConfigStore-Cq20962p.mjs";
2
+ import { C as createCoordinateTaskTool, D as FallbackLlmBackend, E as ApiClient, F as generateCliTools, G as ReActAgent, N as loadContextFiles, O as ServerLlmBackend, P as PermissionManager, Q as CheckpointStore, T as createAgentDelegateTool, W as setWebSocketToolExecutor, X as RemoteSkillSource, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createGetFileStructureTool, a as WebSocketToolExecutor, b as createWriteTodosTool, et as SessionStore, i as McpManager, n as SubagentOrchestrator, o as WebSocketConnectionManager, q as buildSystemPrompt, r as AgentStore, s as WebSocketLlmBackend, t as BackgroundAgentManager, v as createFindDefinitionTool, w as createBackgroundAgentTools, x as createSkillTool, y as createTodoStore } from "../BackgroundAgentManager-D-xsWd3C.mjs";
3
+ import { n as logger, r as getApiUrl, t as ConfigStore } from "../ConfigStore-D39UqFnY.mjs";
4
4
  import { t as DEFAULT_SANDBOX_CONFIG } from "../types-LyRNHOiS.mjs";
5
5
  import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-ChGlxSGQ.mjs";
6
6
  import { t as SandboxOrchestrator } from "../SandboxOrchestrator-BoINxbX4.mjs";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-Cq20962p.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-D39UqFnY.mjs";
3
3
  //#region src/commands/mcpCommand.ts
4
4
  /**
5
5
  * External MCP commands (b4m mcp list, b4m mcp add, etc.)
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "../package-CBaK53NX.mjs";
2
+ import { t as version } from "../package-I_v_WFUn.mjs";
3
3
  import { c as isNpmPrefixWritable, l as setAutoUpdatePreference, n as REEXEC_GUARD_ENV, o as forceCheckForUpdate, r as checkForUpdate, s as getAutoUpdatePreference, t as INSTALL_CMD, u as shouldAttemptAutoUpdate } from "../updateChecker-C8xsNY2L.mjs";
4
4
  import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
5
5
  import { execSync, spawnSync } from "child_process";
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { $ as CommandHistoryStore, A as substituteArguments, B as DEFAULT_RETRY_CONFIG, C as createCoordinateTaskTool, D as FallbackLlmBackend, E as ApiClient, F as generateCliTools, G as ReActAgent, H as clearFeatureModuleTools, I as getProcessHooks, J as buildSkillsPromptSection, K as getPlanModeFilePath, L as ALWAYS_DENIED_FOR_AGENTS, M as extractCompactInstructions, N as loadContextFiles, O as ServerLlmBackend, P as PermissionManager, Q as CheckpointStore, R as DEFAULT_AGENT_MODEL, S as parseAgentConfig, T as createAgentDelegateTool, U as registerFeatureModuleTools, V as DEFAULT_THOROUGHNESS, W as setWebSocketToolExecutor, X as RemoteSkillSource, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createGetFileStructureTool, a as WebSocketToolExecutor, at as mergeCommands, b as createWriteTodosTool, c as createReviewGateStore, ct as warmFileCache, d as createBlockerStore, et as SessionStore, f as createBlockerTools, g as formatDecisionsOutput, h as createDecisionStore, i as McpManager, it as searchCommands, j as formatStep, k as isTransientNetworkError, l as createReviewGateTool, m as createDecisionLogTool, n as SubagentOrchestrator, nt as hasFileReferences, o as WebSocketConnectionManager, ot as formatFileSize, p as formatBlockersOutput, q as buildSystemPrompt, r as AgentStore, rt as processFileReferences, s as WebSocketLlmBackend, st as searchFiles, t as BackgroundAgentManager, tt as OAuthClient, u as formatReviewGatesOutput, v as createFindDefinitionTool, w as createBackgroundAgentTools, x as createSkillTool, y as createTodoStore, z as DEFAULT_MAX_ITERATIONS } from "./BackgroundAgentManager-DOesheMD.mjs";
2
+ import { $ as CommandHistoryStore, A as substituteArguments, B as DEFAULT_RETRY_CONFIG, C as createCoordinateTaskTool, D as FallbackLlmBackend, E as ApiClient, F as generateCliTools, G as ReActAgent, H as clearFeatureModuleTools, I as getProcessHooks, J as buildSkillsPromptSection, K as getPlanModeFilePath, L as ALWAYS_DENIED_FOR_AGENTS, M as extractCompactInstructions, N as loadContextFiles, O as ServerLlmBackend, P as PermissionManager, Q as CheckpointStore, R as DEFAULT_AGENT_MODEL, S as parseAgentConfig, T as createAgentDelegateTool, U as registerFeatureModuleTools, V as DEFAULT_THOROUGHNESS, W as setWebSocketToolExecutor, X as RemoteSkillSource, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createGetFileStructureTool, a as WebSocketToolExecutor, at as mergeCommands, b as createWriteTodosTool, c as createReviewGateStore, ct as warmFileCache, d as createBlockerStore, et as SessionStore, f as createBlockerTools, g as formatDecisionsOutput, h as createDecisionStore, i as McpManager, it as searchCommands, j as formatStep, k as isTransientNetworkError, l as createReviewGateTool, m as createDecisionLogTool, n as SubagentOrchestrator, nt as hasFileReferences, o as WebSocketConnectionManager, ot as formatFileSize, p as formatBlockersOutput, q as buildSystemPrompt, r as AgentStore, rt as processFileReferences, s as WebSocketLlmBackend, st as searchFiles, t as BackgroundAgentManager, tt as OAuthClient, u as formatReviewGatesOutput, v as createFindDefinitionTool, w as createBackgroundAgentTools, x as createSkillTool, y as createTodoStore, z as DEFAULT_MAX_ITERATIONS } from "./BackgroundAgentManager-D-xsWd3C.mjs";
3
3
  import { n as useCliStore, t as selectActiveBackgroundAgents } from "./store-DV5s-qni.mjs";
4
- import { $t as validateJupyterKernelName, en as validateNotebookPath$1, i as getCreditsUrl, n as logger, o as getEnvironmentName, r as getApiUrl, t as ConfigStore, x as ChatModels, y as CREDIT_DEDUCT_TRANSACTION_TYPES } from "./ConfigStore-Cq20962p.mjs";
5
- import { t as version } from "./package-CBaK53NX.mjs";
4
+ import { i as getCreditsUrl, n as logger, nn as validateNotebookPath$1, o as getEnvironmentName, r as getApiUrl, t as ConfigStore, tn as validateJupyterKernelName, x as ChatModels, y as CREDIT_DEDUCT_TRANSACTION_TYPES } from "./ConfigStore-D39UqFnY.mjs";
5
+ import { t as version } from "./package-I_v_WFUn.mjs";
6
6
  import { r as checkForUpdate } from "./updateChecker-C8xsNY2L.mjs";
7
7
  import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
8
8
  import { Box, Static, Text, render, useApp, useInput, usePaste, useStdout } from "ink";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  //#region package.json
3
- var version = "0.18.4";
3
+ var version = "0.18.5";
4
4
  //#endregion
5
5
  export { version as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.18.4",
3
+ "version": "0.18.5",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -107,8 +107,8 @@
107
107
  "zod": "^4.4.3",
108
108
  "zod-validation-error": "^5.0.0",
109
109
  "zustand": "^5.0.13",
110
- "@bike4mind/fab-pipeline": "0.4.8",
111
- "@bike4mind/llm-adapters": "0.9.0",
110
+ "@bike4mind/fab-pipeline": "0.5.0",
111
+ "@bike4mind/llm-adapters": "0.9.1",
112
112
  "@bike4mind/observability": "0.2.0"
113
113
  },
114
114
  "devDependencies": {
@@ -124,11 +124,11 @@
124
124
  "tsx": "^4.22.3",
125
125
  "typescript": "^5.9.3",
126
126
  "vitest": "^4.1.9",
127
- "@bike4mind/agents": "0.18.2",
128
- "@bike4mind/common": "2.119.0",
129
- "@bike4mind/mcp": "1.40.2",
130
- "@bike4mind/services": "2.103.0",
131
- "@bike4mind/utils": "2.27.0"
127
+ "@bike4mind/common": "2.120.0",
128
+ "@bike4mind/agents": "0.18.3",
129
+ "@bike4mind/mcp": "1.40.3",
130
+ "@bike4mind/services": "2.104.0",
131
+ "@bike4mind/utils": "2.28.0"
132
132
  },
133
133
  "optionalDependencies": {
134
134
  "@vscode/ripgrep": "^1.18.0"