@bonginkan/maria 4.3.37 → 4.3.38

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/dist/cli.cjs CHANGED
@@ -1709,7 +1709,7 @@ var init_AuthenticationManager = __esm({
1709
1709
  const response = await fetch(`${this.apiBase}/api/user/profile`, {
1710
1710
  headers: {
1711
1711
  "Authorization": `Bearer ${tokens2.accessToken}`,
1712
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.37"}`
1712
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.38"}`
1713
1713
  }
1714
1714
  });
1715
1715
  if (response.status === 401) {
@@ -2434,7 +2434,7 @@ async function callApi(path64, init3 = {}) {
2434
2434
  "Authorization": `Bearer ${token}`,
2435
2435
  "X-Device-Id": getDeviceId(),
2436
2436
  "X-Session-Id": getSessionId() || "",
2437
- "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.37"}`,
2437
+ "User-Agent": `maria-cli/${process.env.CLI_VERSION || "4.3.38"}`,
2438
2438
  "Content-Type": init3.headers?.["Content-Type"] || "application/json"
2439
2439
  });
2440
2440
  const doFetch = async (token) => {
@@ -3208,7 +3208,7 @@ async function mapInputToTopLevelCommand(input3) {
3208
3208
  const system = [
3209
3209
  "You are a router for the MARIA CLI.",
3210
3210
  "Decide the best command for a single user input.",
3211
- "Allowed commands: /help, /image, /code, /video, /whoami, /login, /logout, /evaluate, chat.",
3211
+ "Allowed commands: /help, /image, /code, /video, /whoami, /login, /logout, /evaluate, /research, chat.",
3212
3212
  "Note that /image and /video are for generating them. If a path of a file is provided, you should double think why it's referenced (it may be for coding or chatting or other commands, regarding on the context).",
3213
3213
  'Return JSON only with keys: { "command": string, "args"?: string[], "confidence": number }.',
3214
3214
  "Select chat when the input is a general question or conversation rather than a specific slash command.",
@@ -3236,7 +3236,7 @@ ${input3}`,
3236
3236
  }
3237
3237
  if (!parsed || typeof parsed.command !== "string") return null;
3238
3238
  const cmd = parsed.command;
3239
- if (!["/help", "/image", "/code", "/video", "/whoami", "/login", "/logout", "/evaluate", "chat"].includes(cmd)) return null;
3239
+ if (!["/help", "/image", "/code", "/video", "/whoami", "/login", "/logout", "/evaluate", "/research", "chat"].includes(cmd)) return null;
3240
3240
  const out = { command: cmd };
3241
3241
  if (Array.isArray(parsed.args)) {
3242
3242
  out.args = parsed.args.filter((a) => typeof a === "string" && a.trim()).map((s2) => s2.trim());
@@ -16382,8 +16382,8 @@ var require_package = __commonJS({
16382
16382
  "package.json"(exports, module) {
16383
16383
  module.exports = {
16384
16384
  name: "@bonginkan/maria",
16385
- version: "4.3.37",
16386
- description: "\u{1F680} MARIA v4.3.37 - Enterprise AI Development Platform with identity system and character voice implementation. Features 74 production-ready commands with comprehensive fallback implementation, local LLM support, and zero external dependencies. Includes natural language coding, AI safety evaluation, intelligent evolution system, episodic memory with PII masking, and real-time monitoring dashboard. Built with TypeScript AST-powered code generation, OAuth2.0 + PKCE authentication, quantum-resistant cryptography, and enterprise-grade performance.",
16385
+ version: "4.3.38",
16386
+ description: "\u{1F680} MARIA v4.3.38 - Enterprise AI Development Platform with identity system and character voice implementation. Features 74 production-ready commands with comprehensive fallback implementation, local LLM support, and zero external dependencies. Includes natural language coding, AI safety evaluation, intelligent evolution system, episodic memory with PII masking, and real-time monitoring dashboard. Built with TypeScript AST-powered code generation, OAuth2.0 + PKCE authentication, quantum-resistant cryptography, and enterprise-grade performance.",
16387
16387
  keywords: [
16388
16388
  "ai",
16389
16389
  "cli",
@@ -26389,7 +26389,7 @@ var init_about_command = __esm({
26389
26389
  async execute(args2, context2) {
26390
26390
  const output3 = [];
26391
26391
  output3.push("");
26392
- output3.push(chalk40__default.default.cyan.bold("\u{1F916} About MARIA v4.3.37"));
26392
+ output3.push(chalk40__default.default.cyan.bold("\u{1F916} About MARIA v4.3.38"));
26393
26393
  output3.push(chalk40__default.default.gray("\u2550".repeat(40)));
26394
26394
  output3.push("");
26395
26395
  output3.push(chalk40__default.default.white.bold("MARIA - Minimal API, Maximum Power"));
@@ -54017,50 +54017,6 @@ var init_UpdateCommand = __esm({
54017
54017
  }
54018
54018
  });
54019
54019
 
54020
- // src/slash-commands/categories/research/utils/HeadlessBrowser.ts
54021
- var HeadlessBrowser;
54022
- var init_HeadlessBrowser = __esm({
54023
- "src/slash-commands/categories/research/utils/HeadlessBrowser.ts"() {
54024
- HeadlessBrowser = class {
54025
- constructor(config2 = {}) {
54026
- this.config = config2;
54027
- }
54028
- async execute(params2 = {}) {
54029
- return {
54030
- success: true,
54031
- message: "Headless browser utility placeholder",
54032
- data: null
54033
- };
54034
- }
54035
- async process(input3) {
54036
- return this.execute(input3);
54037
- }
54038
- };
54039
- }
54040
- });
54041
-
54042
- // src/slash-commands/categories/research/utils/ContentExtractor.ts
54043
- var ContentExtractor;
54044
- var init_ContentExtractor = __esm({
54045
- "src/slash-commands/categories/research/utils/ContentExtractor.ts"() {
54046
- ContentExtractor = class {
54047
- constructor(config2 = {}) {
54048
- this.config = config2;
54049
- }
54050
- async execute(params2 = {}) {
54051
- return {
54052
- success: true,
54053
- message: "Content extraction utility placeholder",
54054
- data: null
54055
- };
54056
- }
54057
- async process(input3) {
54058
- return this.execute(input3);
54059
- }
54060
- };
54061
- }
54062
- });
54063
-
54064
54020
  // src/slash-commands/categories/research/handlers/ResearchCommand.ts
54065
54021
  var ResearchCommand_exports = {};
54066
54022
  __export(ResearchCommand_exports, {
@@ -54071,8 +54027,8 @@ var init_ResearchCommand = __esm({
54071
54027
  "src/slash-commands/categories/research/handlers/ResearchCommand.ts"() {
54072
54028
  init_base_command();
54073
54029
  init_logger();
54074
- init_HeadlessBrowser();
54075
- init_ContentExtractor();
54030
+ init_api_client();
54031
+ init_animations();
54076
54032
  ResearchCommand = class extends BaseCommand {
54077
54033
  name = "research";
54078
54034
  category = "analysis";
@@ -54106,17 +54062,13 @@ var init_ResearchCommand = __esm({
54106
54062
  author: "MARIA Team",
54107
54063
  since: "2.0.0"
54108
54064
  };
54109
- browser = null;
54110
- contentExtractor;
54111
54065
  knowledgeBasePath;
54112
54066
  constructor() {
54113
54067
  super();
54114
- this.contentExtractor = new ContentExtractor();
54115
54068
  this.knowledgeBasePath = path10__namespace.default.join(os10__namespace.default.homedir(), ".maria", "knowledge-base");
54116
54069
  }
54117
54070
  async initialize() {
54118
54071
  try {
54119
- this.browser = new HeadlessBrowser();
54120
54072
  await this.ensureKnowledgeBaseDirectory();
54121
54073
  logger.debug("Research command initialized");
54122
54074
  } catch (error2) {
@@ -54125,53 +54077,74 @@ var init_ResearchCommand = __esm({
54125
54077
  }
54126
54078
  }
54127
54079
  async execute(_args, context2) {
54080
+ const spinner = new ThinkingAnimation("Researching");
54128
54081
  try {
54129
- const _startTime = Date.now();
54130
- const _url = _args.parsed.positional?.[0];
54131
- const _action = !_url || !this.isValidUrl(_url) ? _url : null;
54132
- const _actualUrl = _action ? null : _url;
54133
- if (_action) {
54134
- return await this.handleAction(_action, _args, context2);
54135
- }
54136
- if (!_actualUrl) {
54137
- return this.error("URL required for research. Use: /research <_url> [_options]", "MISSING_URL");
54138
- }
54139
- const _options = this.parseResearchOptions(_args);
54140
- const _result = await this.performResearch(_actualUrl, _options);
54141
- const _commandResult = await this.formatResult(_result, _options);
54142
- _commandResult.metadata = {
54143
- ..._commandResult.metadata,
54144
- executionTime: Date.now() - _startTime
54145
- };
54146
- this.logExecution(_args, context2, _commandResult);
54147
- return _commandResult;
54148
- } catch (innerError) {
54149
- logger.error("Research command execution _failed:", error);
54082
+ const startedAt = Date.now();
54083
+ const first = _args.parsed?.positional?.[0] || "";
54084
+ const isUrl = this.isValidUrl(first);
54085
+ if (!isUrl && first && ["kb", "batch", "export", "import", "status", "help"].includes(first.toLowerCase())) {
54086
+ return await this.handleAction(first.toLowerCase(), _args, context2);
54087
+ }
54088
+ spinner.start();
54089
+ const payload = isUrl ? { url: first, topK: 5 } : { query: _args.raw?.join(" ") || (_args.parsed?.positional || []).join(" "), topK: 5 };
54090
+ if (!payload.url && !payload.query) {
54091
+ spinner.stop();
54092
+ return this.error("URL or query required. Usage: /research <url> | /research <query>", "MISSING_INPUT");
54093
+ }
54094
+ const resp = await callApiJson(
54095
+ "/api/v1/research",
54096
+ {
54097
+ method: "POST",
54098
+ body: JSON.stringify(payload),
54099
+ headers: { "Content-Type": "application/json" }
54100
+ }
54101
+ );
54102
+ spinner.stop();
54103
+ if (!resp?.success || !resp?.data) {
54104
+ return this.error("Research failed", "RESEARCH_ERROR");
54105
+ }
54106
+ const lines = [];
54107
+ lines.push(resp.data.summary?.trim() || "");
54108
+ if (Array.isArray(resp.data.sources) && resp.data.sources.length > 0) {
54109
+ lines.push("\nSources:");
54110
+ resp.data.sources.slice(0, 5).forEach((s2, idx) => {
54111
+ lines.push(` ${idx + 1}. ${s2.title ? `${s2.title} - ` : ""}${s2.url}`);
54112
+ });
54113
+ }
54114
+ const message = lines.filter(Boolean).join("\n");
54115
+ const result = this.success(message);
54116
+ result.metadata = { executionTime: Date.now() - startedAt };
54117
+ this.logExecution(_args, context2, result);
54118
+ return result;
54119
+ } catch (error2) {
54120
+ try {
54121
+ spinner.stop();
54122
+ } catch {
54123
+ }
54124
+ logger.error("Research command execution failed:", error2);
54150
54125
  return this.error(
54151
- `Research _failed: ${error instanceof Error ? error.message : "Unknown error"}`,
54126
+ `Research failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`,
54152
54127
  "RESEARCH_ERROR",
54153
- error
54128
+ error2
54154
54129
  );
54155
54130
  }
54156
54131
  }
54157
54132
  async validate(args2) {
54158
- const _url = args2.parsed.positional?.[0];
54159
- if (!_url) {
54133
+ const first = args2.parsed?.positional?.[0] || "";
54134
+ if (!first) {
54160
54135
  return {
54161
54136
  success: false,
54162
- error: "URL or _action required",
54163
- suggestions: ["Provide a URL to research: /research https://example.com", "Or use an _action: /research kb list"]
54137
+ error: "URL or query required",
54138
+ suggestions: [
54139
+ "Provide a URL to research: /research https://example.com",
54140
+ 'Or provide a query: /research "React performance optimization"',
54141
+ "Or use an action: /research kb list"
54142
+ ]
54164
54143
  };
54165
54144
  }
54166
- if (!this.isValidUrl(_url)) {
54167
- const _validActions = ["kb", "batch", "export", "import", "status", "help"];
54168
- if (!_validActions.includes(_url.toLowerCase())) {
54169
- return {
54170
- success: false,
54171
- error: `Invalid URL or _action: ${_url}`,
54172
- suggestions: [`Provide a valid URL starting with http:// or https://`, `Or use one of: ${_validActions.join(", ")}`]
54173
- };
54174
- }
54145
+ const _validActions = ["kb", "batch", "export", "import", "status", "help"];
54146
+ if (_validActions.includes(first.toLowerCase())) {
54147
+ return { success: true };
54175
54148
  }
54176
54149
  return { success: true };
54177
54150
  }
@@ -54200,101 +54173,7 @@ var init_ResearchCommand = __esm({
54200
54173
  /**
54201
54174
  * Perform the main research operation
54202
54175
  */
54203
- async performResearch(_url, _options) {
54204
- const _startTime = Date.now();
54205
- const id = this.generateResearchId();
54206
- try {
54207
- logger.info(`Starting research for: ${_url}`);
54208
- const browserOptions = {
54209
- headless: true,
54210
- timeout: _options.timeout,
54211
- javascript: _options.javascript,
54212
- waitFor: "domcontentloaded",
54213
- viewport: { width: 1920, height: 1080 }
54214
- };
54215
- if (!this.browser) {
54216
- this.browser = new HeadlessBrowser(browserOptions);
54217
- }
54218
- const _scrapingResult = await this.browser.scrape(_url, browserOptions);
54219
- if (!_scrapingResult.html) {
54220
- throw new Error(`Failed to retrieve _content from ${_url}: ${_scrapingResult.error || "Unknown error"}`);
54221
- }
54222
- const extractionOptions = {
54223
- includeImages: _options.includeImages,
54224
- includeLinks: _options.includeLinks,
54225
- includeTables: true,
54226
- includeCode: true,
54227
- minTextLength: 50,
54228
- language: _options.language,
54229
- extractKeywords: _options.depth !== "basic",
54230
- extractEntities: _options.depth === "comprehensive",
54231
- analyzeSentiment: _options.depth === "comprehensive",
54232
- preserveFormatting: _options._format === "markdown"
54233
- };
54234
- const _extractedContent = await this.contentExtractor.extractFromHtml(
54235
- _scrapingResult.html,
54236
- _url,
54237
- extractionOptions
54238
- );
54239
- const _summary = await this.generateSummary(_extractedContent, _options);
54240
- let knowledgeBaseId;
54241
- if (_options.save) {
54242
- knowledgeBaseId = await this.saveToKnowledgeBase(_extractedContent, _options);
54243
- }
54244
- const _processingTime = Date.now() - _startTime;
54245
- logger.info(`Research completed for ${_url} in ${_processingTime}ms`);
54246
- return {
54247
- id,
54248
- _url,
54249
- timestamp: /* @__PURE__ */ new Date(),
54250
- _processingTime,
54251
- success: true,
54252
- _content: _extractedContent,
54253
- _summary,
54254
- knowledgeBaseId
54255
- };
54256
- } catch (error2) {
54257
- const _processingTime = Date.now() - _startTime;
54258
- logger.error(`Research _failed for ${_url}:`, error2);
54259
- return {
54260
- id,
54261
- _url,
54262
- timestamp: /* @__PURE__ */ new Date(),
54263
- _processingTime,
54264
- success: false,
54265
- error: error2 instanceof Error ? error2.message : "Unknown error"
54266
- };
54267
- }
54268
- }
54269
- /**
54270
- * Format research results for display
54271
- */
54272
- async formatResult(_result, _options) {
54273
- if (!_result.success) {
54274
- return this.error(`Research _failed: ${_result.error}`, "RESEARCH_FAILED", _result);
54275
- }
54276
- if (!_result._content) {
54277
- return this.error("No _content extracted", "NO_CONTENT");
54278
- }
54279
- let message = "";
54280
- switch (_options.format) {
54281
- case "json":
54282
- message = this.formatAsJson(_result);
54283
- break;
54284
- case "markdown":
54285
- message = this.formatAsMarkdown(_result);
54286
- break;
54287
- case "structured":
54288
- message = this.formatAsStructured(_result);
54289
- break;
54290
- default:
54291
- message = this.formatAsText(_result);
54292
- }
54293
- if (_options.output) {
54294
- await this.saveToFile(message, _options.output, _options.format);
54295
- }
54296
- return this.success(message, _result);
54297
- }
54176
+ // Legacy local scraping implementation removed in favor of server API
54298
54177
  /**
54299
54178
  * Handle knowledge base operations
54300
54179
  */
@@ -54321,8 +54200,9 @@ var init_ResearchCommand = __esm({
54321
54200
  * Handle batch research
54322
54201
  */
54323
54202
  async handleBatchResearch(args2) {
54324
- const _filePath = args2.parsed.positional?.[1];
54325
- const _concurrent = args2._options._concurrent ? parseInt(args2._options._concurrent) : 3;
54203
+ const positional = args2.parsed?.positional || [];
54204
+ const _filePath = positional[1];
54205
+ const _concurrent = args2.options && args2.options._concurrent ? parseInt(String(args2.options._concurrent)) : 3;
54326
54206
  if (!_filePath) {
54327
54207
  return this.error("File path required for batch processing", "FILE_PATH_REQUIRED");
54328
54208
  }
@@ -54341,7 +54221,34 @@ var init_ResearchCommand = __esm({
54341
54221
  }
54342
54222
  let processed = 0;
54343
54223
  for (const batch of batches) {
54344
- const _batchPromises = batch.map((_url) => this.performResearch(_url, _options));
54224
+ const _batchPromises = batch.map(async (_url) => {
54225
+ try {
54226
+ const r2 = await callApiJson(
54227
+ "/api/v1/research",
54228
+ { method: "POST", body: JSON.stringify({ url: _url, topK: 1 }), headers: { "Content-Type": "application/json" } }
54229
+ );
54230
+ const ok = !!r2?.success;
54231
+ const now2 = Date.now();
54232
+ const base = {
54233
+ id: this.generateResearchId(),
54234
+ _url,
54235
+ timestamp: /* @__PURE__ */ new Date(),
54236
+ _processingTime: 0,
54237
+ success: ok,
54238
+ _summary: (r2?.data?.summary || "").trim()
54239
+ };
54240
+ return base;
54241
+ } catch (e2) {
54242
+ return {
54243
+ id: this.generateResearchId(),
54244
+ _url,
54245
+ timestamp: /* @__PURE__ */ new Date(),
54246
+ _processingTime: 0,
54247
+ success: false,
54248
+ error: e2 instanceof Error ? e2.message : "Unknown error"
54249
+ };
54250
+ }
54251
+ });
54345
54252
  const _batchResults = await Promise.allSettled(_batchPromises);
54346
54253
  _batchResults.forEach((_result, _index) => {
54347
54254
  if (_result.status === "fulfilled") {
@@ -54392,7 +54299,7 @@ var init_ResearchCommand = __esm({
54392
54299
 
54393
54300
  `;
54394
54301
  results.filter((r2) => r2.success).forEach((_result) => {
54395
- message += `\u2022 **${_result._content?.title || _result._url}**
54302
+ message += `\u2022 **${_result._url}**
54396
54303
  `;
54397
54304
  message += ` URL: ${_result._url}
54398
54305
  `;
@@ -54406,192 +54313,8 @@ var init_ResearchCommand = __esm({
54406
54313
  });
54407
54314
  return this.success(message, { results, _summary: { total: _urls.length, _successful, _failed } });
54408
54315
  } catch (innerError) {
54409
- return this.error(`Batch research _failed: ${error instanceof Error ? error.message : "Unknown error"}`, "BATCH_ERROR");
54410
- }
54411
- }
54412
- /**
54413
- * Generate a _summary based on extracted _content
54414
- */
54415
- async generateSummary(_content, _options) {
54416
- try {
54417
- let _summary = "";
54418
- _summary += `**${_content.title}**
54419
- `;
54420
- if (_content.description) {
54421
- _summary += `${_content.description}
54422
-
54423
- `;
54424
- }
54425
- _summary += `**Domain**: ${_content.metadata.domain}
54426
- `;
54427
- _summary += `**Word Count**: ${_content.metadata.wordCount}
54428
- `;
54429
- _summary += `**Reading Time**: ${_content.metadata.readingTime} minutes
54430
- `;
54431
- if (_content.metadata.author) {
54432
- _summary += `**Author**: ${_content.metadata.author}
54433
- `;
54434
- }
54435
- if (_content.metadata.publishDate) {
54436
- _summary += `**Published**: ${new Date(_content.metadata.publishDate).toLocaleDateString()}
54437
- `;
54438
- }
54439
- if (_content.analysis.topics.length > 0) {
54440
- _summary += `**Topics**: ${_content.analysis.topics.join(", ")}
54441
- `;
54442
- }
54443
- if (_content.analysis.keywords.length > 0) {
54444
- _summary += `**Keywords**: ${_content.analysis.keywords.slice(0, 10).join(", ")}
54445
- `;
54446
- }
54447
- if (_options.depth !== "basic") {
54448
- _summary += "\n**Content Structure**:\n";
54449
- _summary += `\u2022 Headings: ${_content.structure.headings.length}
54450
- `;
54451
- _summary += `\u2022 Paragraphs: ${_content.structure.paragraphs.length}
54452
- `;
54453
- _summary += `\u2022 Images: ${_content.media.images.length}
54454
- `;
54455
- _summary += `\u2022 External links: ${_content.links.external.length}
54456
- `;
54457
- }
54458
- return _summary;
54459
- } catch (error2) {
54460
- logger.error("Summary generation _failed:", error2);
54461
- return "Summary generation _failed";
54462
- }
54463
- }
54464
- // Format methods
54465
- formatAsText(_result) {
54466
- _result._content;
54467
- let message = `# \u{1F50D} Research Results
54468
-
54469
- `;
54470
- message += _result._summary || "No _summary available";
54471
- if (_result.knowledgeBaseId) {
54472
- message += `
54473
-
54474
- *Saved to knowledge base: ${_result.knowledgeBaseId}*`;
54475
- }
54476
- return message;
54477
- }
54478
- formatAsJson(_result) {
54479
- return `\`\`\`json
54480
- ${JSON.stringify(_result, null, 2)}
54481
- \`\`\``;
54482
- }
54483
- formatAsMarkdown(_result) {
54484
- const _content = _result._content;
54485
- let markdown = `# ${_content.title}
54486
-
54487
- `;
54488
- if (_content.description) {
54489
- markdown += `${_content.description}
54490
-
54491
- `;
54492
- }
54493
- markdown += `**URL**: [${_result._url}](${_result._url})
54494
- `;
54495
- markdown += `**Domain**: ${_content.metadata.domain}
54496
- `;
54497
- markdown += `**Research Date**: ${_result.timestamp.toLocaleDateString()}
54498
-
54499
- `;
54500
- if (_content.structure.headings.length > 0) {
54501
- markdown += `## Content Structure
54502
-
54503
- `;
54504
- _content.structure.headings.forEach((_heading) => {
54505
- markdown += `${"#".repeat(_heading.level + 1)} ${_heading.text}
54506
- `;
54507
- });
54508
- markdown += "\n";
54509
- }
54510
- if (_content.structure.paragraphs.length > 0) {
54511
- markdown += `## Key Content
54512
-
54513
- `;
54514
- _content.structure.paragraphs.slice(0, 3).forEach((_para) => {
54515
- markdown += `${_para}
54516
-
54517
- `;
54518
- });
54316
+ return this.error(`Batch research _failed: ${innerError instanceof Error ? innerError.message : "Unknown error"}`, "BATCH_ERROR");
54519
54317
  }
54520
- return markdown;
54521
- }
54522
- formatAsStructured(_result) {
54523
- const _content = _result._content;
54524
- let message = `# \u{1F4CB} Structured Analysis
54525
-
54526
- `;
54527
- message += `## \u{1F4CA} Metadata
54528
-
54529
- `;
54530
- message += `| Field | Value |
54531
- `;
54532
- message += `|-------|-------|
54533
- `;
54534
- message += `| Title | ${_content.title} |
54535
- `;
54536
- message += `| URL | ${_result._url} |
54537
- `;
54538
- message += `| Domain | ${_content.metadata.domain} |
54539
- `;
54540
- message += `| Language | ${_content.metadata.language} |
54541
- `;
54542
- message += `| Word Count | ${_content.metadata.wordCount} |
54543
- `;
54544
- message += `| Reading Time | ${_content.metadata.readingTime} min |
54545
- `;
54546
- message += `
54547
- ## \u{1F3D7}\uFE0F Content Structure
54548
-
54549
- `;
54550
- message += `- **Headings**: ${_content.structure.headings.length}
54551
- `;
54552
- message += `- **Paragraphs**: ${_content.structure.paragraphs.length}
54553
- `;
54554
- message += `- **Lists**: ${_content.structure.lists.length}
54555
- `;
54556
- message += `- **Tables**: ${_content.structure.tables.length}
54557
- `;
54558
- message += `- **Code Blocks**: ${_content.structure.codeBlocks.length}
54559
- `;
54560
- message += `
54561
- ## \u{1F5BC}\uFE0F Media Content
54562
-
54563
- `;
54564
- message += `- **Images**: ${_content.media.images.length}
54565
- `;
54566
- message += `- **Videos**: ${_content.media.videos.length}
54567
- `;
54568
- message += `- **Documents**: ${_content.media.documents.length}
54569
- `;
54570
- message += `
54571
- ## \u{1F517} Links
54572
-
54573
- `;
54574
- message += `- **Internal**: ${_content.links.internal.length}
54575
- `;
54576
- message += `- **External**: ${_content.links.external.length}
54577
- `;
54578
- if (_content.analysis.topics.length > 0 || _content.analysis.keywords.length > 0) {
54579
- message += `
54580
- ## \u{1F9E0} Analysis
54581
-
54582
- `;
54583
- if (_content.analysis.topics.length > 0) {
54584
- message += `**Topics**: ${_content.analysis.topics.join(", ")}
54585
-
54586
- `;
54587
- }
54588
- if (_content.analysis.keywords.length > 0) {
54589
- message += `**Top Keywords**: ${_content.analysis.keywords.slice(0, 15).join(", ")}
54590
-
54591
- `;
54592
- }
54593
- }
54594
- return message;
54595
54318
  }
54596
54319
  // Helper methods
54597
54320
  parseResearchOptions(args2) {
@@ -54622,25 +54345,25 @@ ${JSON.stringify(_result, null, 2)}
54622
54345
  type: "research",
54623
54346
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
54624
54347
  source: {
54625
- _url: _content.metadata._url,
54626
- domain: _content.metadata.domain,
54348
+ _url: String(_content?.metadata?._url || ""),
54349
+ domain: String(_content?.metadata?.domain || ""),
54627
54350
  accessDate: (/* @__PURE__ */ new Date()).toISOString()
54628
54351
  },
54629
54352
  _content: {
54630
- title: _content.title,
54631
- _summary: _content.description || "",
54632
- keyPoints: _content.analysis.keywords.slice(0, 10),
54633
- fullText: _content.cleanText
54353
+ title: String(_content?.title || ""),
54354
+ _summary: String(_content?.description || ""),
54355
+ keyPoints: Array.isArray(_content?.analysis?.keywords) ? _content.analysis.keywords.slice(0, 10) : [],
54356
+ fullText: String(_content?.cleanText || "")
54634
54357
  },
54635
54358
  classification: {
54636
54359
  category: _options.category || "general",
54637
- topics: _content.analysis.topics,
54360
+ topics: Array.isArray(_content?.analysis?.topics) ? _content.analysis.topics : [],
54638
54361
  tags: _options.tags || []
54639
54362
  },
54640
54363
  metadata: {
54641
- language: _content.metadata.language,
54642
- wordCount: _content.metadata.wordCount,
54643
- readingTime: _content.metadata.readingTime
54364
+ language: String(_content?.metadata?.language || ""),
54365
+ wordCount: Number(_content?.metadata?.wordCount || 0),
54366
+ readingTime: Number(_content?.metadata?.readingTime || 0)
54644
54367
  }
54645
54368
  };
54646
54369
  const _entryPath = path10__namespace.default.join(this.knowledgeBasePath, "entries", `${id}.json`);
@@ -54649,8 +54372,8 @@ ${JSON.stringify(_result, null, 2)}
54649
54372
  logger.info(`Saved to knowledge base: ${id}`);
54650
54373
  return id;
54651
54374
  } catch (innerError) {
54652
- logger.error("Failed to save to knowledge base:", error);
54653
- throw error;
54375
+ logger.error("Failed to save to knowledge base:", innerError);
54376
+ throw innerError;
54654
54377
  }
54655
54378
  }
54656
54379
  async updateKnowledgeBaseIndex(_entry) {
@@ -54659,11 +54382,11 @@ ${JSON.stringify(_result, null, 2)}
54659
54382
  const _indexContent = await fsp__namespace.default.readFile(_indexPath, "utf-8");
54660
54383
  const _index = JSON.parse(_indexContent);
54661
54384
  _index.entries[_entry.id] = {
54662
- title: _entry._content.title,
54663
- type: _entry.type,
54664
- category: _entry.classification.category,
54665
- topics: _entry.classification.topics,
54666
- timestamp: _entry.timestamp
54385
+ title: String(_entry?._content?.title || ""),
54386
+ type: String(_entry?.type || "research"),
54387
+ category: String(_entry?.classification?.category || "general"),
54388
+ topics: Array.isArray(_entry?.classification?.topics) ? _entry.classification.topics : [],
54389
+ timestamp: String(_entry?.timestamp || (/* @__PURE__ */ new Date()).toISOString())
54667
54390
  };
54668
54391
  _index.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
54669
54392
  await fsp__namespace.default.writeFile(_indexPath, JSON.stringify(_index, null, 2));
@@ -54676,7 +54399,7 @@ ${JSON.stringify(_result, null, 2)}
54676
54399
  await fsp__namespace.default.mkdir(this.knowledgeBasePath, { recursive: true });
54677
54400
  await fsp__namespace.default.mkdir(path10__namespace.default.join(this.knowledgeBasePath, "entries"), { recursive: true });
54678
54401
  } catch (innerError) {
54679
- logger.error("Failed to create knowledge base directory:", error);
54402
+ logger.error("Failed to create knowledge base directory:", innerError);
54680
54403
  }
54681
54404
  }
54682
54405
  isValidUrl(_url) {
@@ -54727,20 +54450,10 @@ ${JSON.stringify(_result, null, 2)}
54727
54450
  let message = `# \u{1F4CA} Research Service Status
54728
54451
 
54729
54452
  `;
54730
- if (this.browser) {
54731
- const _browserInfo = await this.browser.getBrowserInfo();
54732
- message += `**Browser Engine**: ${_browserInfo.engine}
54733
- `;
54734
- message += `**Browser Status**: ${_browserInfo.ready ? "\u2705 Ready" : "\u274C Not Ready"}
54453
+ message += `**Server Endpoint**: /api/v1/research
54735
54454
  `;
54736
- if (_browserInfo.version) {
54737
- message += `**Version**: ${_browserInfo.version}
54455
+ message += `**Grounding**: Gemini googleSearch enabled
54738
54456
  `;
54739
- }
54740
- } else {
54741
- message += `**Browser Status**: \u274C Not Initialized
54742
- `;
54743
- }
54744
54457
  try {
54745
54458
  const _indexPath = path10__namespace.default.join(this.knowledgeBasePath, "index.json");
54746
54459
  const _indexContent = await fsp__namespace.default.readFile(_indexPath, "utf-8");
@@ -54758,10 +54471,6 @@ ${JSON.stringify(_result, null, 2)}
54758
54471
  return this.success(message);
54759
54472
  }
54760
54473
  async cleanup() {
54761
- if (this.browser) {
54762
- await this.browser.close();
54763
- this.browser = null;
54764
- }
54765
54474
  logger.debug("Research command cleaned up");
54766
54475
  }
54767
54476
  };
@@ -76769,7 +76478,13 @@ async function handleLine(line, options = {}) {
76769
76478
  const consumed = await handleSlash(input3);
76770
76479
  if (consumed) return;
76771
76480
  if (!input3.startsWith("/")) {
76481
+ const spinner = new ProcessAnimation();
76482
+ spinner.start();
76772
76483
  const mapped = await mapInputToTopLevelCommand(input3);
76484
+ try {
76485
+ spinner.stop();
76486
+ } catch {
76487
+ }
76773
76488
  if (process.env.MARIA_DEBUG === "1") {
76774
76489
  console.log(chalk40__default.default.white(`Command: {command: '${mapped.command}', args: '${mapped.args}', confidence: '${mapped.confidence}'}`));
76775
76490
  }
@@ -76785,6 +76500,10 @@ async function handleLine(line, options = {}) {
76785
76500
  }
76786
76501
  }
76787
76502
  } finally {
76503
+ try {
76504
+ spinner.stop();
76505
+ } catch {
76506
+ }
76788
76507
  }
76789
76508
  }
76790
76509
  const isAuthenticated = await authManager.isAuthenticated();