@bike4mind/cli 0.2.64-worktree-refactor-extract-search-query-builders.21815 → 0.2.64

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 (85) hide show
  1. package/bin/bike4mind-cli.mjs +6 -6
  2. package/dist/BubblewrapRuntime-BHbtqvLx.mjs +72 -0
  3. package/dist/ConfigStore-CllM6jOf.mjs +8614 -0
  4. package/dist/ImageStore-DaKT_Ew8.mjs +202 -0
  5. package/dist/ProxyManager-Dl2nFk-A.mjs +259 -0
  6. package/dist/ProxyManager-kiOD1X8-.mjs +3 -0
  7. package/dist/SandboxOrchestrator-BEW3rqYi.mjs +159 -0
  8. package/dist/SandboxOrchestrator-CHZgSR3P.mjs +3 -0
  9. package/dist/SandboxRuntimeAdapter-C1B4t20N.mjs +57 -0
  10. package/dist/SandboxRuntimeAdapter-D7UAG13n.mjs +3 -0
  11. package/dist/SeatbeltRuntime-D4m0VOcD.mjs +116 -0
  12. package/dist/StderrViolationParser-D0afQ3-1.mjs +70 -0
  13. package/dist/ViolationLogStore-CZl35HcA.mjs +96 -0
  14. package/dist/bashExecute-BTkdqlSs-5foM20Lb.mjs +466 -0
  15. package/dist/commands/doctorCommand.mjs +101 -0
  16. package/dist/commands/headlessCommand.mjs +319 -0
  17. package/dist/commands/mcpCommand.mjs +218 -0
  18. package/dist/commands/updateCommand.mjs +40 -0
  19. package/dist/createFile-yQfh8uvk-I-yM5DxC.mjs +63 -0
  20. package/dist/deleteFile-DKHfnyny-G3b1Kj2T.mjs +66 -0
  21. package/dist/globFiles-D1en6joM-8jekiXdX.mjs +100 -0
  22. package/dist/grepSearch-aMamoBn_-DCJcY8JS.mjs +173 -0
  23. package/dist/index.mjs +6722 -0
  24. package/dist/pathValidation-Cgjh5WQO-DiCZTcq6.mjs +63 -0
  25. package/dist/store-Dw1nZX2Y.mjs +128 -0
  26. package/dist/store-nZExNOWX.mjs +3 -0
  27. package/dist/terminalSetup-rmr1P8KF.mjs +254 -0
  28. package/dist/tools-C6M5aW8W.mjs +20907 -0
  29. package/dist/treeSitterEngine-DCSXcm_3.mjs +309 -0
  30. package/dist/types-DBEjF9YS.mjs +59 -0
  31. package/dist/types-DK3P88Px.mjs +3 -0
  32. package/dist/updateChecker-Cu9dkHxV.mjs +120 -0
  33. package/package.json +10 -10
  34. package/dist/BubblewrapRuntime-PMIOLWKR.js +0 -71
  35. package/dist/HydrationEngine-YL2HWJ3V.js +0 -9
  36. package/dist/ImageStore-MMUOUPI2.js +0 -224
  37. package/dist/ProxyManager-HEB4TLVX.js +0 -7
  38. package/dist/SandboxOrchestrator-UIJ5GYBB.js +0 -8
  39. package/dist/SandboxRuntimeAdapter-FQ56MAB2.js +0 -13
  40. package/dist/SeatbeltRuntime-EE3TTLEP.js +0 -98
  41. package/dist/StderrViolationParser-7OYPM2DJ.js +0 -59
  42. package/dist/ViolationLogStore-RIIUVURH.js +0 -104
  43. package/dist/artifactExtractor-R7DIP2XO.js +0 -180
  44. package/dist/bashExecute-GLGLD3JD.js +0 -379
  45. package/dist/chunk-4BIBE3J7.js +0 -48
  46. package/dist/chunk-5LZS5CVJ.js +0 -161
  47. package/dist/chunk-BDQBOLYG.js +0 -120
  48. package/dist/chunk-BPFEGDC7.js +0 -192
  49. package/dist/chunk-EPIYC3LA.js +0 -13770
  50. package/dist/chunk-G4ZGEQFT.js +0 -250
  51. package/dist/chunk-GQGOWACU.js +0 -770
  52. package/dist/chunk-J6ZBI6TI.js +0 -1079
  53. package/dist/chunk-JW3JRHH7.js +0 -12433
  54. package/dist/chunk-KQAMBXAW.js +0 -163
  55. package/dist/chunk-KUVV2NAB.js +0 -19125
  56. package/dist/chunk-LTLJRF6I.js +0 -44
  57. package/dist/chunk-PFBYGCOW.js +0 -449
  58. package/dist/chunk-QWB6ZYY4.js +0 -48
  59. package/dist/chunk-SGPRXN4C.js +0 -245
  60. package/dist/chunk-UZUHPHZC.js +0 -95
  61. package/dist/chunk-WBE7SQUB.js +0 -241
  62. package/dist/chunk-Y4WOJJM3.js +0 -147
  63. package/dist/commands/doctorCommand.js +0 -87
  64. package/dist/commands/headlessCommand.js +0 -380
  65. package/dist/commands/mcpCommand.js +0 -203
  66. package/dist/commands/updateCommand.js +0 -42
  67. package/dist/create-C4VEEEYR.js +0 -12
  68. package/dist/createFile-6PSPLW6R.js +0 -71
  69. package/dist/deleteFile-AUSRLWIK.js +0 -73
  70. package/dist/formatConverter-5QEJDW24.js +0 -7
  71. package/dist/globFiles-TSRN64N2.js +0 -120
  72. package/dist/grepSearch-634XWZOJ.js +0 -216
  73. package/dist/index.js +0 -6779
  74. package/dist/llmMarkdownGenerator-Z6NB26TT.js +0 -371
  75. package/dist/markdownGenerator-SK2ZQQL4.js +0 -269
  76. package/dist/mementoService-N4IM6QAC.js +0 -12
  77. package/dist/notificationDeduplicator-HUC53NEW.js +0 -9
  78. package/dist/src-F4KZCAA2.js +0 -319
  79. package/dist/src-ISX322I7.js +0 -1101
  80. package/dist/store-CAB6BV3P.js +0 -11
  81. package/dist/subtractCredits-D4KEM6VU.js +0 -12
  82. package/dist/terminalSetup-C5FHMLC3.js +0 -214
  83. package/dist/treeSitterEngine-4SGFQDY3.js +0 -330
  84. package/dist/types-KB5NP6T4.js +0 -7
  85. package/dist/utils-JCHWDM4Z.js +0 -31
@@ -1,379 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/bashExecute/index.js
4
- import { spawn } from "child_process";
5
- import path from "path";
6
- var DEFAULT_TIMEOUT_MS = 6e4;
7
- var MAX_OUTPUT_SIZE = 100 * 1024;
8
- var DANGEROUS_PATTERNS = [
9
- // Destructive file operations
10
- {
11
- pattern: /\brm\s+(-[a-zA-Z]*r[a-zA-Z]*\s+|.*\s+-[a-zA-Z]*r).*\//i,
12
- reason: "Recursive delete with path",
13
- block: true
14
- },
15
- {
16
- pattern: /\brm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+|.*\s+-[a-zA-Z]*f).*--no-preserve-root/i,
17
- reason: "Force delete without preserve root",
18
- block: true
19
- },
20
- {
21
- pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+\//i,
22
- reason: "Recursive force delete on root paths",
23
- block: true
24
- },
25
- {
26
- pattern: /\brm\s+-[a-zA-Z]*f[a-zA-Z]*r[a-zA-Z]*\s+\//i,
27
- reason: "Force recursive delete on root paths",
28
- block: true
29
- },
30
- // System-level dangerous commands
31
- { pattern: /\bsudo\b/i, reason: "Elevated privileges (sudo)", block: true },
32
- { pattern: /\bsu\s+(-|root)/i, reason: "Switch to root user", block: true },
33
- { pattern: /\bchmod\s+777\b/i, reason: "Overly permissive chmod", block: false },
34
- { pattern: /\bchown\s+-R\s+root/i, reason: "Recursive chown to root", block: true },
35
- // Disk/partition operations
36
- { pattern: /\bmkfs\b/i, reason: "Filesystem creation", block: true },
37
- { pattern: /\bfdisk\b/i, reason: "Disk partitioning", block: true },
38
- { pattern: /\bdd\s+.*of=\/dev\//i, reason: "Direct disk write", block: true },
39
- // Network attacks
40
- { pattern: /\b(nc|netcat)\s+.*-e\s+\/bin\/(ba)?sh/i, reason: "Reverse shell attempt", block: true },
41
- { pattern: /\bcurl\s+.*\|\s*(ba)?sh/i, reason: "Piping remote script to shell", block: true },
42
- { pattern: /\bwget\s+.*\|\s*(ba)?sh/i, reason: "Piping remote script to shell", block: true },
43
- // Fork bombs and resource exhaustion
44
- { pattern: /:\(\)\s*\{\s*:\|:&\s*\}\s*;/i, reason: "Fork bomb", block: true },
45
- { pattern: /\bwhile\s+true.*do.*done.*&/i, reason: "Infinite loop in background", block: false },
46
- // Credential/sensitive data access
47
- { pattern: /\/etc\/shadow/i, reason: "Access to shadow file", block: true },
48
- { pattern: /\/etc\/passwd.*>/i, reason: "Modifying passwd file", block: true },
49
- { pattern: /\baws\s+.*--profile\s+/i, reason: "AWS profile access", block: false },
50
- // History/log manipulation
51
- { pattern: /\bhistory\s+-c\b/i, reason: "Clearing shell history", block: false },
52
- { pattern: />\s*\/var\/log\//i, reason: "Overwriting system logs", block: true },
53
- // Dangerous redirects
54
- { pattern: />\s*\/dev\/sda/i, reason: "Writing to block device", block: true },
55
- { pattern: />\s*\/dev\/null.*2>&1.*</i, reason: "Potentially hiding output", block: false },
56
- // Environment manipulation
57
- { pattern: /\bexport\s+PATH\s*=\s*[^$]/i, reason: "Overwriting PATH", block: false },
58
- { pattern: /\bexport\s+LD_PRELOAD/i, reason: "LD_PRELOAD manipulation", block: true },
59
- // Process/system control
60
- { pattern: /\bkill\s+-9\s+(-1|1)\b/i, reason: "Killing all processes", block: true },
61
- { pattern: /\bkillall\s+-9\b/i, reason: "Force killing processes", block: false },
62
- { pattern: /\bshutdown\b/i, reason: "System shutdown", block: true },
63
- { pattern: /\breboot\b/i, reason: "System reboot", block: true },
64
- { pattern: /\binit\s+[06]\b/i, reason: "System runlevel change", block: true }
65
- ];
66
- var SAFE_COMMAND_PREFIXES = [
67
- "ls",
68
- "cat",
69
- "head",
70
- "tail",
71
- "grep",
72
- "find",
73
- "echo",
74
- "pwd",
75
- "whoami",
76
- "date",
77
- "cal",
78
- "wc",
79
- "sort",
80
- "uniq",
81
- "cut",
82
- "tr",
83
- "sed",
84
- "awk",
85
- "git",
86
- "npm",
87
- "pnpm",
88
- "yarn",
89
- "node",
90
- "npx",
91
- "tsx",
92
- "ts-node",
93
- "python",
94
- "python3",
95
- "pip",
96
- "pip3",
97
- "docker",
98
- "docker-compose",
99
- "curl",
100
- "wget",
101
- // These are safe for fetching, blocked when piped to shell
102
- "mkdir",
103
- "touch",
104
- "cp",
105
- "mv",
106
- // File operations (still require permission)
107
- "which",
108
- "whereis",
109
- "type",
110
- "file",
111
- "stat",
112
- "env",
113
- "printenv",
114
- "set",
115
- "man",
116
- "help",
117
- "info",
118
- "diff",
119
- "comm",
120
- "cmp",
121
- "tar",
122
- "zip",
123
- "unzip",
124
- "gzip",
125
- "gunzip",
126
- "ssh",
127
- "scp",
128
- "rsync",
129
- // Network tools
130
- "make",
131
- "cmake",
132
- "cargo",
133
- "go",
134
- "rustc",
135
- "gcc",
136
- "g++",
137
- // Build tools
138
- "jest",
139
- "vitest",
140
- "mocha",
141
- "pytest",
142
- // Test runners
143
- "eslint",
144
- "prettier",
145
- "tsc"
146
- // Linters/formatters
147
- ];
148
- function checkDangerousPatterns(command) {
149
- for (const { pattern, reason, block } of DANGEROUS_PATTERNS) {
150
- if (pattern.test(command)) {
151
- return { blocked: block, reason };
152
- }
153
- }
154
- return { blocked: false };
155
- }
156
- function getBaseCommand(command) {
157
- const trimmed = command.trim();
158
- const match = trimmed.match(/^(\S+)/);
159
- return match ? match[1] : "";
160
- }
161
- function isSafeCommandPrefix(command) {
162
- const baseCommand = getBaseCommand(command);
163
- return SAFE_COMMAND_PREFIXES.some((safe) => baseCommand === safe || baseCommand.endsWith(`/${safe}`));
164
- }
165
- async function executeBashCommand(params) {
166
- const { command, cwd: relativeCwd, timeout = DEFAULT_TIMEOUT_MS } = params;
167
- if (!command || command.trim().length === 0) {
168
- return {
169
- stdout: "",
170
- stderr: "Error: Command cannot be empty",
171
- exitCode: 1,
172
- timedOut: false,
173
- blocked: true,
174
- blockedReason: "Empty command"
175
- };
176
- }
177
- const dangerCheck = checkDangerousPatterns(command);
178
- if (dangerCheck.blocked) {
179
- return {
180
- stdout: "",
181
- stderr: `Command blocked for safety: ${dangerCheck.reason}`,
182
- exitCode: 1,
183
- timedOut: false,
184
- blocked: true,
185
- blockedReason: dangerCheck.reason
186
- };
187
- }
188
- const baseCwd = process.cwd();
189
- const targetCwd = relativeCwd ? path.resolve(baseCwd, relativeCwd) : baseCwd;
190
- const effectiveTimeout = Math.min(timeout, 5 * 60 * 1e3);
191
- return new Promise((resolve) => {
192
- let stdout = "";
193
- let stderr = "";
194
- let timedOut = false;
195
- const proc = spawn("bash", ["-c", command], {
196
- cwd: targetCwd,
197
- env: {
198
- ...process.env,
199
- // Prevent color codes that might be hard to read
200
- NO_COLOR: "1",
201
- FORCE_COLOR: "0"
202
- },
203
- stdio: ["ignore", "pipe", "pipe"]
204
- });
205
- const timeoutId = setTimeout(() => {
206
- timedOut = true;
207
- proc.kill("SIGTERM");
208
- setTimeout(() => {
209
- if (!proc.killed) {
210
- proc.kill("SIGKILL");
211
- }
212
- }, 5e3);
213
- }, effectiveTimeout);
214
- proc.stdout.on("data", (data) => {
215
- if (stdout.length < MAX_OUTPUT_SIZE) {
216
- stdout += data.toString();
217
- if (stdout.length > MAX_OUTPUT_SIZE) {
218
- stdout = stdout.slice(0, MAX_OUTPUT_SIZE) + "\n... [output truncated]";
219
- }
220
- }
221
- });
222
- proc.stderr.on("data", (data) => {
223
- if (stderr.length < MAX_OUTPUT_SIZE) {
224
- stderr += data.toString();
225
- if (stderr.length > MAX_OUTPUT_SIZE) {
226
- stderr = stderr.slice(0, MAX_OUTPUT_SIZE) + "\n... [output truncated]";
227
- }
228
- }
229
- });
230
- proc.on("close", (exitCode) => {
231
- clearTimeout(timeoutId);
232
- resolve({
233
- stdout: stdout.trim(),
234
- stderr: stderr.trim(),
235
- exitCode,
236
- timedOut,
237
- blocked: false
238
- });
239
- });
240
- proc.on("error", (error) => {
241
- clearTimeout(timeoutId);
242
- resolve({
243
- stdout: "",
244
- stderr: `Failed to execute command: ${error.message}`,
245
- exitCode: 1,
246
- timedOut: false,
247
- blocked: false
248
- });
249
- });
250
- });
251
- }
252
- function formatResult(result, command) {
253
- const parts = [];
254
- parts.push(`$ ${command}`);
255
- parts.push("");
256
- if (result.blocked) {
257
- parts.push(`BLOCKED: ${result.blockedReason}`);
258
- parts.push("");
259
- parts.push("This command was blocked for safety reasons.");
260
- parts.push("If you believe this is a false positive, please run the command manually.");
261
- return parts.join("\n");
262
- }
263
- if (result.timedOut) {
264
- parts.push("WARNING: Command timed out and was terminated.");
265
- parts.push("");
266
- }
267
- if (result.stdout) {
268
- parts.push(result.stdout);
269
- }
270
- if (result.stderr) {
271
- if (result.stdout) {
272
- parts.push("");
273
- }
274
- parts.push("STDERR:");
275
- parts.push(result.stderr);
276
- }
277
- if (result.exitCode !== 0 && result.exitCode !== null) {
278
- parts.push("");
279
- parts.push(`Exit code: ${result.exitCode}`);
280
- }
281
- if (!result.stdout && !result.stderr && !result.timedOut) {
282
- parts.push("(command completed with no output)");
283
- }
284
- return parts.join("\n");
285
- }
286
- var bashExecuteTool = {
287
- name: "bash_execute",
288
- implementation: (context) => ({
289
- toolFn: async (value) => {
290
- const params = value;
291
- const isSafe = isSafeCommandPrefix(params.command);
292
- context.logger.info("Bash: Executing command", {
293
- command: params.command,
294
- cwd: params.cwd || ".",
295
- timeout: params.timeout || DEFAULT_TIMEOUT_MS,
296
- isSafeCommand: isSafe
297
- });
298
- if (context.onStart) {
299
- await context.onStart("bash_execute", {
300
- command: params.command,
301
- cwd: params.cwd
302
- });
303
- }
304
- try {
305
- const result = await executeBashCommand(params);
306
- const formattedResult = formatResult(result, params.command);
307
- context.logger.info("Bash: Command completed", {
308
- exitCode: result.exitCode,
309
- timedOut: result.timedOut,
310
- blocked: result.blocked
311
- });
312
- if (context.onFinish) {
313
- await context.onFinish("bash_execute", {
314
- command: params.command,
315
- exitCode: result.exitCode,
316
- blocked: result.blocked
317
- });
318
- }
319
- return formattedResult;
320
- } catch (error) {
321
- context.logger.error("Bash: Command failed", error);
322
- if (context.onFinish) {
323
- await context.onFinish("bash_execute", {
324
- command: params.command,
325
- error: error instanceof Error ? error.message : "Unknown error"
326
- });
327
- }
328
- throw error;
329
- }
330
- },
331
- toolSchema: {
332
- name: "bash_execute",
333
- description: `Execute a bash command in the terminal. Use this for running shell commands, scripts, build tools, git operations, and other CLI tasks.
334
-
335
- SAFETY NOTES:
336
- - Commands are executed in the current working directory (or specified cwd)
337
- - Dangerous commands (sudo, rm -rf /, etc.) are automatically blocked
338
- - Commands have a default timeout of 60 seconds (max 5 minutes)
339
- - Output is limited to prevent overwhelming responses
340
- - This tool ALWAYS requires user permission before execution
341
-
342
- COMMON USE CASES:
343
- - Running build commands: npm run build, make, cargo build
344
- - Git operations: git status, git log, git diff
345
- - Viewing system info: ls, pwd, cat, head, tail
346
- - Running tests: npm test, pytest, cargo test
347
- - Package management: npm install, pip install
348
- - File operations: mkdir, cp, mv (with permission)
349
-
350
- BLOCKED OPERATIONS:
351
- - sudo and privilege escalation
352
- - Recursive deletes on system paths
353
- - Direct disk operations
354
- - Fork bombs and resource exhaustion
355
- - Piping remote scripts to shell`,
356
- parameters: {
357
- type: "object",
358
- properties: {
359
- command: {
360
- type: "string",
361
- description: "The bash command to execute. Can include pipes, redirects, and chained commands."
362
- },
363
- cwd: {
364
- type: "string",
365
- description: "Working directory for the command (optional). Can be relative or absolute path. Defaults to current directory."
366
- },
367
- timeout: {
368
- type: "number",
369
- description: "Timeout in milliseconds (optional, default: 60000, max: 300000). Command will be terminated if it exceeds this time."
370
- }
371
- },
372
- required: ["command"]
373
- }
374
- }
375
- })
376
- };
377
- export {
378
- bashExecuteTool
379
- };
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/sandbox/types.ts
4
- var DEFAULT_SANDBOX_CONFIG = {
5
- enabled: false,
6
- mode: "disabled",
7
- filesystem: {
8
- writeOnlyToWorkingDir: true,
9
- allowedReadPaths: ["$HOME/.gitconfig", "$HOME/.npmrc", "$HOME/.node_modules"],
10
- deniedPaths: ["$HOME/.ssh", "$HOME/.aws", "$HOME/.gnupg", "$HOME/.env", "/etc/shadow", "/etc/passwd"]
11
- },
12
- network: {
13
- enabled: false,
14
- allowedDomains: [
15
- "registry.npmjs.org",
16
- "*.npmjs.org",
17
- "pypi.org",
18
- "*.pypi.org",
19
- "files.pythonhosted.org",
20
- "crates.io",
21
- "*.crates.io",
22
- "rubygems.org",
23
- "github.com",
24
- "*.github.com",
25
- "gitlab.com",
26
- "*.gitlab.com",
27
- "bitbucket.org",
28
- "*.bitbucket.org",
29
- "*.githubusercontent.com",
30
- "*.cloudflare.com"
31
- ]
32
- },
33
- excludedCommands: ["docker", "watchman", "podman"],
34
- allowUnsandboxedCommands: true,
35
- platform: {
36
- linux: {
37
- runtime: "bubblewrap"
38
- },
39
- macos: {
40
- runtime: "seatbelt",
41
- profileTemplate: "default"
42
- }
43
- }
44
- };
45
-
46
- export {
47
- DEFAULT_SANDBOX_CONFIG
48
- };
@@ -1,161 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- BadRequestError,
4
- secureParameters
5
- } from "./chunk-EPIYC3LA.js";
6
- import {
7
- CompletionApiUsageTransaction,
8
- GenericCreditDeductTransaction,
9
- ImageEditUsageTransaction,
10
- ImageGenerationUsageTransaction,
11
- RealtimeVoiceUsageTransaction,
12
- TextGenerationUsageTransaction,
13
- ToolUsageTransaction,
14
- TransferCreditTransaction,
15
- VideoGenerationUsageTransaction
16
- } from "./chunk-JW3JRHH7.js";
17
-
18
- // ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
19
- import { z } from "zod";
20
- var SubtractCreditsSchema = z.discriminatedUnion("type", [
21
- GenericCreditDeductTransaction.omit({ createdAt: true, updatedAt: true }),
22
- TextGenerationUsageTransaction.omit({ createdAt: true, updatedAt: true }),
23
- ImageGenerationUsageTransaction.omit({ createdAt: true, updatedAt: true }),
24
- VideoGenerationUsageTransaction.omit({ createdAt: true, updatedAt: true }),
25
- RealtimeVoiceUsageTransaction.omit({ createdAt: true, updatedAt: true }),
26
- ImageEditUsageTransaction.omit({ createdAt: true, updatedAt: true }),
27
- ToolUsageTransaction.omit({ createdAt: true, updatedAt: true }),
28
- CompletionApiUsageTransaction.omit({ createdAt: true, updatedAt: true }),
29
- TransferCreditTransaction.omit({ createdAt: true, updatedAt: true })
30
- ]);
31
- async function subtractCredits(parameters, { db, creditHolderMethods, skipBalanceUpdate, currentCreditHolder }) {
32
- const params = secureParameters(parameters, SubtractCreditsSchema);
33
- const { ownerId, ownerType, credits, type, description, metadata } = params;
34
- let updatedEntity;
35
- if (skipBalanceUpdate) {
36
- if (!currentCreditHolder) {
37
- throw new BadRequestError("currentCreditHolder is required when skipBalanceUpdate is true");
38
- }
39
- updatedEntity = currentCreditHolder;
40
- } else {
41
- updatedEntity = await creditHolderMethods.incrementCredits(ownerId, -credits);
42
- if (!updatedEntity) {
43
- throw new BadRequestError("Failed to update credits");
44
- }
45
- }
46
- if (type === "generic_deduct") {
47
- await db.creditTransactions.createTransaction("generic_deduct", {
48
- ownerId,
49
- ownerType,
50
- credits: -Math.abs(credits),
51
- // Negative for usage
52
- description: description || "Generic credit deduction",
53
- metadata,
54
- reason: params.reason,
55
- // Backward compatibility
56
- userId: params.userId
57
- });
58
- } else if (type === "text_generation_usage") {
59
- await db.creditTransactions.createTransaction("text_generation_usage", {
60
- ownerId,
61
- ownerType,
62
- credits: -Math.abs(credits),
63
- // Negative for usage
64
- description: description || "Text generation usage",
65
- metadata,
66
- model: params.model,
67
- questId: params.questId,
68
- sessionId: params.sessionId,
69
- inputTokens: params.inputTokens,
70
- outputTokens: params.outputTokens
71
- });
72
- } else if (type === "completion_api_usage") {
73
- await db.creditTransactions.createTransaction("completion_api_usage", {
74
- ownerId,
75
- ownerType,
76
- credits: -Math.abs(credits),
77
- // Negative for usage
78
- description: description || "Completion API usage",
79
- metadata,
80
- model: params.model,
81
- apiKeyId: params.apiKeyId,
82
- // Optional - present for API key auth, undefined for JWT
83
- inputTokens: params.inputTokens,
84
- outputTokens: params.outputTokens
85
- });
86
- } else if (type === "image_generation_usage") {
87
- await db.creditTransactions.createTransaction("image_generation_usage", {
88
- ownerId,
89
- ownerType,
90
- credits: -Math.abs(credits),
91
- // Negative for usage
92
- description: description || "Image generation usage",
93
- metadata,
94
- model: params.model,
95
- questId: params.questId,
96
- sessionId: params.sessionId
97
- });
98
- } else if (type === "image_edit_usage") {
99
- await db.creditTransactions.createTransaction("image_edit_usage", {
100
- ownerId,
101
- ownerType,
102
- credits: -Math.abs(credits),
103
- // Negative for usage
104
- description: description || "Image editing usage",
105
- metadata,
106
- model: params.model,
107
- questId: params.questId,
108
- sessionId: params.sessionId
109
- });
110
- } else if (type === "video_generation_usage") {
111
- await db.creditTransactions.createTransaction("video_generation_usage", {
112
- ownerId,
113
- ownerType,
114
- credits: -Math.abs(credits),
115
- // Negative for usage
116
- description: description || "Video generation usage",
117
- metadata,
118
- model: params.model,
119
- questId: params.questId,
120
- sessionId: params.sessionId
121
- });
122
- } else if (type === "tool_usage") {
123
- await db.creditTransactions.createTransaction("tool_usage", {
124
- ownerId,
125
- ownerType,
126
- credits: -Math.abs(credits),
127
- description: description || "Tool usage",
128
- metadata,
129
- model: params.model,
130
- questId: params.questId,
131
- sessionId: params.sessionId
132
- });
133
- } else if (type === "transfer_credit") {
134
- await db.creditTransactions.createTransaction("transfer_credit", {
135
- ownerId,
136
- ownerType,
137
- credits: -Math.abs(credits),
138
- // Negative for usage
139
- description: description || "Transfer credits",
140
- recipientId: params.recipientId,
141
- recipientType: params.recipientType
142
- });
143
- } else {
144
- await db.creditTransactions.createTransaction("realtime_voice_usage", {
145
- ownerId,
146
- ownerType,
147
- credits: -Math.abs(credits),
148
- // Negative for usage
149
- description: description || "Voice usage",
150
- metadata,
151
- model: params.model,
152
- sessionId: params.sessionId
153
- });
154
- }
155
- return updatedEntity;
156
- }
157
-
158
- export {
159
- SubtractCreditsSchema,
160
- subtractCredits
161
- };
@@ -1,120 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // ../../b4m-core/packages/services/dist/src/mfaService/utils.js
4
- import speakeasy from "speakeasy";
5
- import QRCode from "qrcode";
6
- var originalEmitWarning = process.emitWarning;
7
- process.emitWarning = (warning, name) => {
8
- if (name === "DeprecationWarning" && warning?.toString().includes("Buffer")) {
9
- return;
10
- }
11
- return originalEmitWarning.call(process, warning, name);
12
- };
13
- process.emitWarning = originalEmitWarning;
14
- async function generateTOTPSetup(userEmail, appName = "Bike4Mind") {
15
- const secret = speakeasy.generateSecret({ name: `${appName} (${userEmail})` });
16
- const qrCodeUrl = await QRCode.toDataURL(secret.otpauth_url);
17
- return {
18
- secret: secret.base32,
19
- qrCodeUrl,
20
- manualEntryKey: secret.base32
21
- };
22
- }
23
- function verifyTOTPToken(secret, token, window = 1) {
24
- return speakeasy.totp.verify({
25
- secret,
26
- encoding: "base32",
27
- token,
28
- window
29
- // Allow ±30 seconds for clock drift (industry standard)
30
- });
31
- }
32
- function generateBackupCodes(count = 10) {
33
- return Array.from({ length: count }, () => {
34
- const secret = speakeasy.generateSecret({ length: 20 });
35
- return secret.base32.substring(0, 10).toUpperCase();
36
- });
37
- }
38
- function verifyBackupCode(userBackupCodes, providedCode) {
39
- if (!userBackupCodes || !providedCode) {
40
- return { isValid: false };
41
- }
42
- const cleanProvidedCode = providedCode.trim().toUpperCase();
43
- const idx = userBackupCodes.findIndex((code) => {
44
- const cleanStoredCode = code.trim().toUpperCase();
45
- return cleanStoredCode === cleanProvidedCode;
46
- });
47
- if (idx !== -1) {
48
- return { isValid: true, usedBackupCode: userBackupCodes[idx] };
49
- }
50
- return { isValid: false };
51
- }
52
- function userRequiresMFA(user, enforceMFASetting) {
53
- return enforceMFASetting;
54
- }
55
- function userHasMFAConfigured(user) {
56
- return !!(user.mfa && user.mfa.totpEnabled && user.mfa.totpSecret);
57
- }
58
- var MAX_FAILED_ATTEMPTS = 3;
59
- var LOCKOUT_DURATION_MS = 15 * 60 * 1e3;
60
- var ATTEMPT_RESET_WINDOW_MS = 60 * 60 * 1e3;
61
- function isUserLockedOut(user) {
62
- if (!user.mfa?.lockedUntil)
63
- return false;
64
- return /* @__PURE__ */ new Date() < new Date(user.mfa.lockedUntil);
65
- }
66
- function getLockoutTimeRemaining(user) {
67
- if (!user.mfa?.lockedUntil)
68
- return 0;
69
- const remaining = new Date(user.mfa.lockedUntil).getTime() - Date.now();
70
- return Math.max(0, Math.ceil(remaining / (60 * 1e3)));
71
- }
72
- function shouldResetFailedAttempts(user) {
73
- if (!user.mfa?.lastFailedAttempt)
74
- return false;
75
- const timeSinceLastFailure = Date.now() - new Date(user.mfa.lastFailedAttempt).getTime();
76
- return timeSinceLastFailure > ATTEMPT_RESET_WINDOW_MS;
77
- }
78
- function recordFailedAttempt(user) {
79
- const currentAttempts = shouldResetFailedAttempts(user) ? 0 : user.mfa?.failedAttempts || 0;
80
- const newAttempts = currentAttempts + 1;
81
- const now = /* @__PURE__ */ new Date();
82
- const updatedMFA = { ...user.mfa };
83
- updatedMFA.failedAttempts = newAttempts;
84
- updatedMFA.lastFailedAttempt = now;
85
- if (newAttempts >= MAX_FAILED_ATTEMPTS) {
86
- updatedMFA.lockedUntil = new Date(Date.now() + LOCKOUT_DURATION_MS);
87
- }
88
- return updatedMFA;
89
- }
90
- function clearFailedAttempts(user) {
91
- if (!user.mfa)
92
- return null;
93
- const updatedMFA = { ...user.mfa };
94
- updatedMFA.failedAttempts = 0;
95
- updatedMFA.lastFailedAttempt = void 0;
96
- updatedMFA.lockedUntil = void 0;
97
- return updatedMFA;
98
- }
99
- function userEligibleForMFA(user) {
100
- return true;
101
- }
102
- function userCanDisableMFA(user, enforceMFASetting) {
103
- return !enforceMFASetting;
104
- }
105
-
106
- export {
107
- generateTOTPSetup,
108
- verifyTOTPToken,
109
- generateBackupCodes,
110
- verifyBackupCode,
111
- userRequiresMFA,
112
- userHasMFAConfigured,
113
- isUserLockedOut,
114
- getLockoutTimeRemaining,
115
- shouldResetFailedAttempts,
116
- recordFailedAttempt,
117
- clearFailedAttempts,
118
- userEligibleForMFA,
119
- userCanDisableMFA
120
- };