@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,224 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/storage/ImageStore.ts
4
- import { createHash } from "crypto";
5
- import { mkdirSync, writeFileSync, readFileSync, existsSync, unlinkSync } from "fs";
6
- import { join, extname, resolve } from "path";
7
- import { homedir } from "os";
8
- import Database from "better-sqlite3";
9
- import sharp from "sharp";
10
- var ImageStore = class _ImageStore {
11
- static {
12
- this.BASE_DIR = join(homedir(), ".bike4mind", "cli");
13
- }
14
- static {
15
- this.IMAGES_DIR = join(_ImageStore.BASE_DIR, "images");
16
- }
17
- static {
18
- this.DB_PATH = join(_ImageStore.BASE_DIR, "images.db");
19
- }
20
- static {
21
- this.RETENTION_DAYS = 7;
22
- }
23
- static {
24
- // Target max size before base64 encoding. Base64 adds ~33% overhead.
25
- // To stay under 1MB after base64, we need images < 750KB
26
- this.MAX_RAW_SIZE = 750 * 1024;
27
- }
28
- static {
29
- // 750KB
30
- // Maximum size before compression to prevent OOM with very large images
31
- this.MAX_PRECOMPRESS_SIZE = 50 * 1024 * 1024;
32
- }
33
- constructor() {
34
- this.ensureDirectories();
35
- this.db = new Database(_ImageStore.DB_PATH);
36
- this.initDatabase();
37
- try {
38
- this.cleanupOldImages();
39
- } catch (err) {
40
- console.warn("Failed to cleanup old images:", err);
41
- }
42
- }
43
- ensureDirectories() {
44
- mkdirSync(_ImageStore.BASE_DIR, { recursive: true });
45
- mkdirSync(_ImageStore.IMAGES_DIR, { recursive: true });
46
- }
47
- initDatabase() {
48
- this.db.exec(`
49
- CREATE TABLE IF NOT EXISTS images (
50
- hash TEXT PRIMARY KEY,
51
- format TEXT NOT NULL,
52
- size INTEGER NOT NULL,
53
- timestamp INTEGER NOT NULL,
54
- uploaded INTEGER NOT NULL DEFAULT 0,
55
- s3_url TEXT,
56
- original_filename TEXT
57
- )
58
- `);
59
- }
60
- /**
61
- * Store an image locally with content-based hashing for deduplication
62
- */
63
- async store(imageData, originalFilename) {
64
- const { buffer: processedData, format: processedFormat } = await this.processImage(imageData, originalFilename);
65
- const hash = this.generateHash(processedData);
66
- const format = processedFormat;
67
- const ext = format.toLowerCase();
68
- const localPath = join(_ImageStore.IMAGES_DIR, `${hash}.${ext}`);
69
- const existing = this.getMetadata(hash);
70
- if (existing) {
71
- return {
72
- hash,
73
- placeholder: "",
74
- // Will be set by caller
75
- localPath,
76
- metadata: existing
77
- };
78
- }
79
- writeFileSync(localPath, processedData);
80
- const metadata = {
81
- hash,
82
- format,
83
- size: processedData.length,
84
- timestamp: Date.now(),
85
- uploaded: false,
86
- originalFilename
87
- };
88
- this.db.prepare(
89
- `INSERT INTO images (hash, format, size, timestamp, uploaded, original_filename)
90
- VALUES (?, ?, ?, ?, ?, ?)`
91
- ).run(hash, format, metadata.size, metadata.timestamp, 0, originalFilename || null);
92
- return {
93
- hash,
94
- placeholder: "",
95
- localPath,
96
- metadata
97
- };
98
- }
99
- /**
100
- * Get image metadata by hash
101
- */
102
- getMetadata(hash) {
103
- const row = this.db.prepare("SELECT * FROM images WHERE hash = ?").get(hash);
104
- if (!row) return null;
105
- return {
106
- hash: row.hash,
107
- format: row.format,
108
- size: row.size,
109
- timestamp: row.timestamp,
110
- uploaded: Boolean(row.uploaded),
111
- s3Url: row.s3_url,
112
- originalFilename: row.original_filename
113
- };
114
- }
115
- /**
116
- * Read image data from local cache
117
- */
118
- readImage(hash) {
119
- const metadata = this.getMetadata(hash);
120
- if (!metadata) return null;
121
- const localPath = join(_ImageStore.IMAGES_DIR, `${hash}.${metadata.format.toLowerCase()}`);
122
- const normalizedPath = resolve(localPath);
123
- if (!normalizedPath.startsWith(resolve(_ImageStore.IMAGES_DIR))) {
124
- throw new Error("Invalid image path");
125
- }
126
- if (!existsSync(localPath)) return null;
127
- return readFileSync(localPath);
128
- }
129
- /**
130
- * Generate content hash for deduplication
131
- */
132
- generateHash(data) {
133
- return createHash("sha256").update(data).digest("hex").substring(0, 16);
134
- }
135
- /**
136
- * Process image: compress if needed to stay under size limit
137
- */
138
- async processImage(data, originalFilename) {
139
- if (data.length > _ImageStore.MAX_PRECOMPRESS_SIZE) {
140
- throw new Error(
141
- `Image too large to process (${Math.round(data.length / 1024 / 1024)}MB). Maximum size is ${_ImageStore.MAX_PRECOMPRESS_SIZE / 1024 / 1024}MB.`
142
- );
143
- }
144
- const originalFormat = this.detectFormat(data, originalFilename);
145
- if (data.length <= _ImageStore.MAX_RAW_SIZE) {
146
- return { buffer: data, format: originalFormat };
147
- }
148
- let image = sharp(data);
149
- const metadata = await image.metadata();
150
- if (!metadata.width || !metadata.height) {
151
- throw new Error("Unable to read image dimensions");
152
- }
153
- const maxDimension = 2048;
154
- let width = metadata.width;
155
- let height = metadata.height;
156
- if (width > maxDimension || height > maxDimension) {
157
- if (width > height) {
158
- height = Math.round(height * maxDimension / width);
159
- width = maxDimension;
160
- } else {
161
- width = Math.round(width * maxDimension / height);
162
- height = maxDimension;
163
- }
164
- }
165
- image = image.resize(width, height);
166
- let quality = 85;
167
- let buffer = await image.jpeg({ quality }).toBuffer();
168
- while (buffer.length > _ImageStore.MAX_RAW_SIZE && quality > 30) {
169
- quality -= 10;
170
- buffer = await image.jpeg({ quality }).toBuffer();
171
- }
172
- if (buffer.length > _ImageStore.MAX_RAW_SIZE) {
173
- throw new Error(`Unable to compress image below ${_ImageStore.MAX_RAW_SIZE / 1024}KB limit`);
174
- }
175
- return { buffer, format: "jpg" };
176
- }
177
- /**
178
- * Detect image format from buffer or filename
179
- */
180
- detectFormat(data, filename) {
181
- if (data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) {
182
- return "png";
183
- }
184
- if (data[0] === 255 && data[1] === 216 && data[2] === 255) {
185
- return "jpg";
186
- }
187
- if (data[0] === 71 && data[1] === 73 && data[2] === 70) {
188
- return "gif";
189
- }
190
- if (data[0] === 82 && data[1] === 73 && data[2] === 70 && data[3] === 70) {
191
- return "webp";
192
- }
193
- if (filename) {
194
- const ext = extname(filename).substring(1).toLowerCase();
195
- if (["png", "jpg", "jpeg", "gif", "webp"].includes(ext)) {
196
- return ext === "jpeg" ? "jpg" : ext;
197
- }
198
- }
199
- return "png";
200
- }
201
- /**
202
- * Clean up images older than retention period
203
- */
204
- cleanupOldImages() {
205
- const cutoffTime = Date.now() - _ImageStore.RETENTION_DAYS * 24 * 60 * 60 * 1e3;
206
- const oldImages = this.db.prepare("SELECT hash, format FROM images WHERE timestamp < ?").all(cutoffTime);
207
- for (const { hash, format } of oldImages) {
208
- const localPath = join(_ImageStore.IMAGES_DIR, `${hash}.${format.toLowerCase()}`);
209
- if (existsSync(localPath)) {
210
- unlinkSync(localPath);
211
- }
212
- }
213
- this.db.prepare("DELETE FROM images WHERE timestamp < ?").run(cutoffTime);
214
- }
215
- /**
216
- * Close database connection
217
- */
218
- close() {
219
- this.db.close();
220
- }
221
- };
222
- export {
223
- ImageStore
224
- };
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ProxyManager
4
- } from "./chunk-G4ZGEQFT.js";
5
- export {
6
- ProxyManager
7
- };
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- SandboxOrchestrator
4
- } from "./chunk-KQAMBXAW.js";
5
- import "./chunk-4BIBE3J7.js";
6
- export {
7
- SandboxOrchestrator
8
- };
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- createSandboxRuntime,
4
- detectPlatform,
5
- expandPath,
6
- isBinaryAvailable
7
- } from "./chunk-QWB6ZYY4.js";
8
- export {
9
- createSandboxRuntime,
10
- detectPlatform,
11
- expandPath,
12
- isBinaryAvailable
13
- };
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- expandPath,
4
- isBinaryAvailable
5
- } from "./chunk-QWB6ZYY4.js";
6
-
7
- // src/sandbox/runtime/SeatbeltRuntime.ts
8
- import { writeFileSync, mkdtempSync } from "fs";
9
- import path from "path";
10
- import os from "os";
11
- function escapeSeatbeltPath(p) {
12
- return p.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
13
- }
14
- var SeatbeltRuntime = class {
15
- constructor() {
16
- this.platform = "darwin";
17
- this.name = "seatbelt";
18
- }
19
- isAvailable() {
20
- return isBinaryAvailable("sandbox-exec");
21
- }
22
- /**
23
- * Generate a Seatbelt profile string from the filesystem config.
24
- *
25
- * Strategy:
26
- * - Start with (allow default) to permit most operations
27
- * - Deny all file writes globally
28
- * - Allow file writes only to the working directory
29
- * - Deny all access to explicitly denied paths
30
- * - Allow read access to explicitly allowed paths
31
- */
32
- generateProfile(options) {
33
- const { cwd, filesystemConfig } = options;
34
- const expandedDenied = filesystemConfig.deniedPaths.map(expandPath);
35
- const expandedAllowed = filesystemConfig.allowedReadPaths.map(expandPath);
36
- const lines = [
37
- "(version 1)",
38
- "",
39
- "; Start with permissive defaults (process exec, network, sysctl, etc.)",
40
- "(allow default)",
41
- ""
42
- ];
43
- if (filesystemConfig.writeOnlyToWorkingDir) {
44
- lines.push("; Deny all file writes globally");
45
- lines.push("(deny file-write*)");
46
- lines.push("");
47
- lines.push("; Allow writes to working directory");
48
- lines.push(`(allow file-write* (subpath "${escapeSeatbeltPath(cwd)}"))`);
49
- lines.push("");
50
- lines.push("; Allow writes to temp directories");
51
- lines.push(`(allow file-write* (subpath "/tmp"))`);
52
- lines.push(`(allow file-write* (subpath "/private/tmp"))`);
53
- lines.push(`(allow file-write* (subpath "${escapeSeatbeltPath(os.tmpdir())}"))`);
54
- lines.push("");
55
- }
56
- if (expandedDenied.length > 0) {
57
- lines.push("; Deny access to sensitive paths");
58
- for (const deniedPath of expandedDenied) {
59
- lines.push(`(deny file-read* file-write* (subpath "${escapeSeatbeltPath(deniedPath)}"))`);
60
- }
61
- lines.push("");
62
- }
63
- if (expandedAllowed.length > 0) {
64
- lines.push("; Explicitly allowed read paths");
65
- for (const allowedPath of expandedAllowed) {
66
- lines.push(`(allow file-read* (subpath "${escapeSeatbeltPath(allowedPath)}"))`);
67
- }
68
- lines.push("");
69
- }
70
- return lines.join("\n");
71
- }
72
- wrapCommand(options) {
73
- try {
74
- const profile = this.generateProfile(options);
75
- const tmpDir = mkdtempSync(path.join(os.tmpdir(), "b4m-sandbox-"));
76
- const profilePath = path.join(tmpDir, "sandbox.sb");
77
- writeFileSync(profilePath, profile, "utf-8");
78
- const args = ["-f", profilePath, "bash", "-c", options.command];
79
- const envEntries = Object.entries(options.env ?? {});
80
- const envPrefix = envEntries.length > 0 ? envEntries.map(([k, v]) => `${k}=${shellEscape(v)}`).join(" ") + " " : "";
81
- return {
82
- executable: "sandbox-exec",
83
- args,
84
- env: options.env ?? {},
85
- commandString: `${envPrefix}sandbox-exec -f ${profilePath} bash -c ${shellEscape(options.command)}`,
86
- cleanupPaths: [profilePath, tmpDir]
87
- };
88
- } catch (err) {
89
- throw new Error(`Failed to create sandbox profile: ${err instanceof Error ? err.message : String(err)}`);
90
- }
91
- }
92
- };
93
- function shellEscape(str) {
94
- return `'${str.replace(/'/g, "'\\''")}'`;
95
- }
96
- export {
97
- SeatbeltRuntime
98
- };
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/sandbox/logging/StderrViolationParser.ts
4
- function parseSeatbeltStderr(stderr) {
5
- const violations = [];
6
- const regex = /sandbox-exec:\s*deny\(\d+\)\s+(\S+)\s+(.+)/g;
7
- let match;
8
- while ((match = regex.exec(stderr)) !== null) {
9
- const operation = match[1];
10
- const targetPath = match[2].trim();
11
- const type = classifySeatbeltOperation(operation);
12
- violations.push({
13
- type,
14
- operation,
15
- path: type === "filesystem" ? targetPath : void 0,
16
- detail: match[0]
17
- });
18
- }
19
- return violations;
20
- }
21
- function parseBwrapStderr(stderr) {
22
- const violations = [];
23
- const regex = /bwrap:\s+(.+)/g;
24
- let match;
25
- while ((match = regex.exec(stderr)) !== null) {
26
- const message = match[1].trim();
27
- const pathMatch = message.match(/(?:Can't open file |Can't bind mount )(\S+)/);
28
- const extractedPath = pathMatch?.[1]?.replace(/:$/, "");
29
- violations.push({
30
- type: "filesystem",
31
- path: extractedPath,
32
- detail: match[0]
33
- });
34
- }
35
- return violations;
36
- }
37
- function parseSandboxStderr(stderr) {
38
- return [...parseSeatbeltStderr(stderr), ...parseBwrapStderr(stderr)];
39
- }
40
- function toSandboxViolations(parsed, command) {
41
- return parsed.map((p) => ({
42
- type: p.type,
43
- path: p.path,
44
- command,
45
- blockedBy: "sandbox",
46
- timestamp: /* @__PURE__ */ new Date(),
47
- detail: p.detail
48
- }));
49
- }
50
- function classifySeatbeltOperation(operation) {
51
- if (operation.startsWith("network")) return "network";
52
- return "filesystem";
53
- }
54
- export {
55
- parseBwrapStderr,
56
- parseSandboxStderr,
57
- parseSeatbeltStderr,
58
- toSandboxViolations
59
- };
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/sandbox/logging/ViolationLogStore.ts
4
- import { promises as fs } from "fs";
5
- import path from "path";
6
- import { homedir } from "os";
7
- var MAX_VIOLATIONS = 5e3;
8
- var DEFAULT_PATH = path.join(homedir(), ".bike4mind", "violations.jsonl");
9
- var ViolationLogStore = class {
10
- constructor(storePath) {
11
- this.cache = null;
12
- this.storePath = storePath ?? DEFAULT_PATH;
13
- }
14
- /** Ensure parent directory exists */
15
- async init() {
16
- const dir = path.dirname(this.storePath);
17
- await fs.mkdir(dir, { recursive: true });
18
- }
19
- /** Load all entries from disk (newest first) */
20
- async load() {
21
- if (this.cache) {
22
- return this.cache;
23
- }
24
- try {
25
- const data = await fs.readFile(this.storePath, "utf-8");
26
- const lines = data.trim().split("\n").filter((line) => line.length > 0);
27
- const entries = lines.map((line) => {
28
- try {
29
- return JSON.parse(line);
30
- } catch {
31
- return null;
32
- }
33
- }).filter((entry) => entry !== null);
34
- entries.sort((a, b) => b.timestamp - a.timestamp);
35
- this.cache = entries;
36
- return this.cache;
37
- } catch (error) {
38
- if (error.code === "ENOENT") {
39
- this.cache = [];
40
- return this.cache;
41
- }
42
- throw error;
43
- }
44
- }
45
- /** Record a new violation (converts Date → epoch ms, appends JSONL) */
46
- async record(violation) {
47
- const entry = {
48
- type: violation.type,
49
- command: violation.command,
50
- blockedBy: violation.blockedBy,
51
- timestamp: violation.timestamp.getTime(),
52
- ...violation.path && { path: violation.path },
53
- ...violation.domain && { domain: violation.domain },
54
- ...violation.detail && { detail: violation.detail }
55
- };
56
- await this.init();
57
- const line = JSON.stringify(entry) + "\n";
58
- await fs.appendFile(this.storePath, line, "utf-8");
59
- this.cache = [entry, ...this.cache ?? []];
60
- if (this.cache.length > MAX_VIOLATIONS) {
61
- await this.trim();
62
- }
63
- }
64
- /** Get recent violations (default 50) */
65
- async getRecent(count = 50) {
66
- const entries = await this.load();
67
- return entries.slice(0, count);
68
- }
69
- /** Count violations by type */
70
- async countByType() {
71
- const entries = await this.load();
72
- let filesystem = 0;
73
- let network = 0;
74
- for (const entry of entries) {
75
- if (entry.type === "filesystem") filesystem++;
76
- else if (entry.type === "network") network++;
77
- }
78
- return { filesystem, network };
79
- }
80
- /** Clear all violations */
81
- async clear() {
82
- try {
83
- await fs.unlink(this.storePath);
84
- } catch (error) {
85
- if (error.code !== "ENOENT") {
86
- throw error;
87
- }
88
- }
89
- this.cache = [];
90
- }
91
- /** Trim to MAX_VIOLATIONS (rewrite file) */
92
- async trim() {
93
- if (!this.cache || this.cache.length <= MAX_VIOLATIONS) {
94
- return;
95
- }
96
- const trimmed = this.cache.slice(0, MAX_VIOLATIONS);
97
- const lines = [...trimmed].reverse().map((entry) => JSON.stringify(entry)).join("\n");
98
- await fs.writeFile(this.storePath, lines + "\n", "utf-8");
99
- this.cache = trimmed;
100
- }
101
- };
102
- export {
103
- ViolationLogStore
104
- };
@@ -1,180 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- CurationArtifactType
4
- } from "./chunk-JW3JRHH7.js";
5
-
6
- // ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
7
- var ARTIFACT_TAG_REGEX = /<artifact\s+(.*?)>([\s\S]*?)<\/artifact>/gi;
8
- var ATTRIBUTE_REGEX = /(\w+)=["']([^"']*?)["']/g;
9
- var CODE_BLOCK_REGEX = /```(\w+)?\s*([\s\S]*?)```/g;
10
- function extractArtifactsFromMessage(message, options) {
11
- const artifacts = [];
12
- const messageId = message.id || message._id?.toString() || "unknown";
13
- const timestamp = message.timestamp ? new Date(message.timestamp) : /* @__PURE__ */ new Date();
14
- const textContent = [
15
- message.prompt || "",
16
- message.reply || "",
17
- ...message.replies || [],
18
- message.questMasterReply || ""
19
- ].filter(Boolean).join("\n\n");
20
- if (!textContent) {
21
- return artifacts;
22
- }
23
- if (options.includeCode || options.includeDiagrams || options.includeDataViz) {
24
- const tagArtifacts = extractArtifactTags(textContent, messageId, timestamp);
25
- artifacts.push(...tagArtifacts);
26
- }
27
- if (options.includeCode) {
28
- const codeArtifacts = extractCodeBlocks(textContent, messageId, timestamp);
29
- artifacts.push(...codeArtifacts);
30
- }
31
- if (options.includeQuestMaster && message.questMasterPlanId) {
32
- artifacts.push({
33
- type: CurationArtifactType.QUESTMASTER_PLAN,
34
- content: message.questMasterPlanId,
35
- messageId,
36
- timestamp,
37
- metadata: {
38
- planId: message.questMasterPlanId
39
- }
40
- });
41
- }
42
- if (options.includeResearch && message.deepResearchState) {
43
- const research = message.deepResearchState;
44
- artifacts.push({
45
- type: CurationArtifactType.DEEP_RESEARCH,
46
- content: JSON.stringify(research, null, 2),
47
- messageId,
48
- timestamp,
49
- metadata: {
50
- findingsCount: research.findings?.length || 0,
51
- sourcesCount: research.sources?.length || 0,
52
- depth: research.depth,
53
- completed: research.completed,
54
- topic: research.topic
55
- }
56
- });
57
- }
58
- if (options.includeImages && message.images && message.images.length > 0) {
59
- message.images.forEach((imagePath, index) => {
60
- artifacts.push({
61
- type: CurationArtifactType.IMAGE,
62
- content: imagePath,
63
- messageId,
64
- timestamp,
65
- metadata: {
66
- index,
67
- path: imagePath
68
- }
69
- });
70
- });
71
- }
72
- return artifacts;
73
- }
74
- function extractArtifactTags(content, messageId, timestamp) {
75
- const artifacts = [];
76
- let match;
77
- ARTIFACT_TAG_REGEX.lastIndex = 0;
78
- while ((match = ARTIFACT_TAG_REGEX.exec(content)) !== null) {
79
- const [, attributesString, artifactContent] = match;
80
- const attributes = {};
81
- let attrMatch;
82
- ATTRIBUTE_REGEX.lastIndex = 0;
83
- while ((attrMatch = ATTRIBUTE_REGEX.exec(attributesString)) !== null) {
84
- const [, key, value] = attrMatch;
85
- attributes[key] = value;
86
- }
87
- const mimeType = attributes.type || "";
88
- const title = attributes.title || "Untitled";
89
- const language = attributes.language;
90
- const identifier = attributes.identifier;
91
- const artifactType = mapMimeTypeToArtifactType(mimeType);
92
- if (artifactType) {
93
- artifacts.push({
94
- type: artifactType,
95
- content: artifactContent.trim(),
96
- language: language || inferLanguageFromType(artifactType),
97
- messageId,
98
- timestamp,
99
- metadata: {
100
- title,
101
- identifier,
102
- mimeType
103
- }
104
- });
105
- }
106
- }
107
- return artifacts;
108
- }
109
- function extractCodeBlocks(content, messageId, timestamp) {
110
- const artifacts = [];
111
- let match;
112
- CODE_BLOCK_REGEX.lastIndex = 0;
113
- while ((match = CODE_BLOCK_REGEX.exec(content)) !== null) {
114
- const [, language, codeContent] = match;
115
- if (!codeContent || !codeContent.trim()) {
116
- continue;
117
- }
118
- const lineCount = codeContent.trim().split("\n").length;
119
- if (lineCount < 3) {
120
- continue;
121
- }
122
- const lang = (language || "text").toLowerCase();
123
- let artifactType;
124
- if (["mermaid"].includes(lang)) {
125
- artifactType = CurationArtifactType.MERMAID;
126
- } else if (["recharts"].includes(lang)) {
127
- artifactType = CurationArtifactType.RECHARTS;
128
- } else if (["svg", "xml"].includes(lang)) {
129
- artifactType = CurationArtifactType.SVG;
130
- } else if (["html", "htm"].includes(lang)) {
131
- artifactType = CurationArtifactType.HTML;
132
- } else if (["tsx", "jsx", "javascript", "typescript", "react"].includes(lang) && (codeContent.includes("useState") || codeContent.includes("useEffect") || codeContent.includes("export default"))) {
133
- artifactType = CurationArtifactType.REACT;
134
- } else {
135
- artifactType = CurationArtifactType.CODE;
136
- }
137
- artifacts.push({
138
- type: artifactType,
139
- content: codeContent.trim(),
140
- language: lang || "text",
141
- messageId,
142
- timestamp,
143
- metadata: {
144
- lineCount
145
- }
146
- });
147
- }
148
- return artifacts;
149
- }
150
- function mapMimeTypeToArtifactType(mimeType) {
151
- const mimeMap = {
152
- "application/vnd.ant.react": CurationArtifactType.REACT,
153
- "text/html": CurationArtifactType.HTML,
154
- "image/svg+xml": CurationArtifactType.SVG,
155
- "application/vnd.ant.mermaid": CurationArtifactType.MERMAID,
156
- "application/vnd.ant.recharts": CurationArtifactType.RECHARTS,
157
- "application/vnd.ant.code": CurationArtifactType.CODE,
158
- "text/x.python": CurationArtifactType.CODE,
159
- "text/x.typescript": CurationArtifactType.CODE,
160
- "text/x.javascript": CurationArtifactType.CODE
161
- };
162
- return mimeMap[mimeType] || null;
163
- }
164
- function inferLanguageFromType(type) {
165
- const languageMap = {
166
- [CurationArtifactType.CODE]: "typescript",
167
- [CurationArtifactType.REACT]: "tsx",
168
- [CurationArtifactType.MERMAID]: "mermaid",
169
- [CurationArtifactType.RECHARTS]: "json",
170
- [CurationArtifactType.SVG]: "xml",
171
- [CurationArtifactType.HTML]: "html",
172
- [CurationArtifactType.QUESTMASTER_PLAN]: void 0,
173
- [CurationArtifactType.DEEP_RESEARCH]: "json",
174
- [CurationArtifactType.IMAGE]: void 0
175
- };
176
- return languageMap[type];
177
- }
178
- export {
179
- extractArtifactsFromMessage
180
- };