cast-code 1.0.10 → 1.0.11

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.
@@ -82,11 +82,11 @@ let MentionsService = class MentionsService {
82
82
  }
83
83
  parseMentions(message) {
84
84
  const mentions = [];
85
- const mentionRegex = /(?:^|\s)@((?:https?:\/\/\S+)|(?:git:[a-z]+)|(?:\.?\/?[\w./-]+\.[\w]+)|(?:\.?\/?[\w./-]+\/))/g;
85
+ const mentionRegex = /(?:^|\s)@(?:\[)?((?:https?:\/\/\S+)|(?:git:[a-z]+)|(?:\.?\/?[\w./-]+\.[\w]+)|(?:\.?\/?[\w./-]+\/))(?:\])?/g;
86
86
  let match;
87
87
  while((match = mentionRegex.exec(message)) !== null){
88
- const target = match[1];
89
- const raw = '@' + target;
88
+ let target = match[1];
89
+ const raw = match[0].trim();
90
90
  let type;
91
91
  let resolved;
92
92
  if (target.startsWith('http://') || target.startsWith('https://')) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/mentions/services/mentions.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport {\n MentionType,\n ParsedMention,\n ResolvedMention,\n MentionResult,\n} from '../types';\n\nconst execAsync = promisify(exec);\n\n@Injectable()\nexport class MentionsService {\n private readonly MAX_FILE_LINES = 500;\n private readonly MAX_FILE_SIZE = 100 * 1024; // 100KB\n private readonly MAX_DIR_ENTRIES = 100;\n private readonly MAX_URL_LENGTH = 50000;\n\n async processMessage(message: string): Promise<MentionResult> {\n const mentions = this.parseMentions(message);\n\n if (mentions.length === 0) {\n return {\n expandedMessage: message,\n mentions: [],\n originalMessage: message,\n };\n }\n\n const resolved = await Promise.all(\n mentions.map((m) => this.resolveMention(m)),\n );\n\n const expandedMessage = this.buildExpandedMessage(message, resolved);\n\n return {\n expandedMessage,\n mentions: resolved,\n originalMessage: message,\n };\n }\n\n private parseMentions(message: string): ParsedMention[] {\n const mentions: ParsedMention[] = [];\n\n const mentionRegex = /(?:^|\\s)@((?:https?:\\/\\/\\S+)|(?:git:[a-z]+)|(?:\\.?\\/?[\\w./-]+\\.[\\w]+)|(?:\\.?\\/?[\\w./-]+\\/))/g;\n\n let match: RegExpExecArray | null;\n\n while ((match = mentionRegex.exec(message)) !== null) {\n const target = match[1];\n const raw = '@' + target;\n\n let type: MentionType;\n let resolved: string;\n\n if (target.startsWith('http://') || target.startsWith('https://')) {\n type = MentionType.URL;\n resolved = target;\n } else if (target.startsWith('git:')) {\n type = MentionType.GIT;\n resolved = target;\n } else if (target.endsWith('/')) {\n type = MentionType.DIRECTORY;\n resolved = path.resolve(process.cwd(), target);\n } else {\n type = MentionType.FILE;\n resolved = path.resolve(process.cwd(), target);\n }\n\n mentions.push({ type, raw, target, resolved });\n }\n\n return mentions;\n }\n\n private async resolveMention(mention: ParsedMention): Promise<ResolvedMention> {\n try {\n switch (mention.type) {\n case MentionType.FILE:\n return await this.resolveFile(mention);\n case MentionType.DIRECTORY:\n return await this.resolveDirectory(mention);\n case MentionType.URL:\n return await this.resolveUrl(mention);\n case MentionType.GIT:\n return await this.resolveGit(mention);\n default:\n return { ...mention, content: '', error: 'Unknown mention type' };\n }\n } catch (error) {\n return {\n ...mention,\n content: '',\n error: `Failed to resolve: ${(error as Error).message}`,\n };\n }\n }\n\n private async resolveFile(mention: ParsedMention): Promise<ResolvedMention> {\n const filePath = mention.resolved;\n\n try {\n const stat = await fs.stat(filePath);\n\n if (stat.isDirectory()) {\n return this.resolveDirectory({\n ...mention,\n type: MentionType.DIRECTORY,\n });\n }\n\n if (stat.size > this.MAX_FILE_SIZE) {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n').slice(0, this.MAX_FILE_LINES);\n const numbered = lines.map((l, i) => `${i + 1}: ${l}`).join('\\n');\n return {\n ...mention,\n content: numbered + `\\n... (truncated, file is ${Math.round(stat.size / 1024)}KB)`,\n };\n }\n\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n const numbered = lines.map((l, i) => `${i + 1}: ${l}`).join('\\n');\n\n return { ...mention, content: numbered };\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n return { ...mention, content: '', error: `File not found: ${filePath}` };\n }\n throw error;\n }\n }\n\n private async resolveDirectory(mention: ParsedMention): Promise<ResolvedMention> {\n const dirPath = mention.resolved;\n\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n const limited = entries.slice(0, this.MAX_DIR_ENTRIES);\n\n const lines = limited.map((e) => {\n const prefix = e.isDirectory() ? 'd' : 'f';\n return `${prefix} ${e.name}`;\n });\n\n let content = lines.join('\\n');\n\n if (entries.length > this.MAX_DIR_ENTRIES) {\n content += `\\n... (${entries.length - this.MAX_DIR_ENTRIES} more entries)`;\n }\n\n return { ...mention, content };\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n return { ...mention, content: '', error: `Directory not found: ${dirPath}` };\n }\n throw error;\n }\n }\n\n private async resolveUrl(mention: ParsedMention): Promise<ResolvedMention> {\n try {\n const response = await fetch(mention.resolved, {\n headers: { 'User-Agent': 'Cast-Code/1.0' },\n signal: AbortSignal.timeout(10000),\n });\n\n if (!response.ok) {\n return {\n ...mention,\n content: '',\n error: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n\n let text = await response.text();\n\n if (text.length > this.MAX_URL_LENGTH) {\n text = text.slice(0, this.MAX_URL_LENGTH) + '\\n... (truncated)';\n }\n\n return { ...mention, content: text };\n } catch (error) {\n return {\n ...mention,\n content: '',\n error: `Fetch failed: ${(error as Error).message}`,\n };\n }\n }\n\n private async resolveGit(mention: ParsedMention): Promise<ResolvedMention> {\n const command = mention.target.replace('git:', '');\n\n const gitCommands: Record<string, string> = {\n status: 'git status',\n diff: 'git diff',\n log: 'git log --oneline -20',\n branch: 'git branch -a',\n stash: 'git stash list',\n };\n\n const cmd = gitCommands[command];\n\n if (!cmd) {\n return {\n ...mention,\n content: '',\n error: `Unknown git command: ${command}. Available: ${Object.keys(gitCommands).join(', ')}`,\n };\n }\n\n try {\n const { stdout, stderr } = await execAsync(cmd, {\n cwd: process.cwd(),\n timeout: 10000,\n });\n\n return { ...mention, content: stdout || stderr || '(no output)' };\n } catch (error) {\n return {\n ...mention,\n content: '',\n error: `Git command failed: ${(error as Error).message}`,\n };\n }\n }\n\n private buildExpandedMessage(\n originalMessage: string,\n mentions: ResolvedMention[],\n ): string {\n let expanded = originalMessage;\n\n for (const mention of mentions) {\n expanded = expanded.replace(mention.raw, '').trim();\n }\n\n const contextParts: string[] = [];\n\n for (const mention of mentions) {\n if (mention.error) {\n contextParts.push(\n `<mention_error target=\"${mention.target}\">\\n${mention.error}\\n</mention_error>`,\n );\n continue;\n }\n\n switch (mention.type) {\n case MentionType.FILE:\n contextParts.push(\n `<file path=\"${mention.target}\">\\n${mention.content}\\n</file>`,\n );\n break;\n case MentionType.DIRECTORY:\n contextParts.push(\n `<directory path=\"${mention.target}\">\\n${mention.content}\\n</directory>`,\n );\n break;\n case MentionType.URL:\n contextParts.push(\n `<url href=\"${mention.target}\">\\n${mention.content}\\n</url>`,\n );\n break;\n case MentionType.GIT:\n contextParts.push(\n `<git command=\"${mention.target.replace('git:', '')}\">\\n${mention.content}\\n</git>`,\n );\n break;\n }\n }\n\n if (contextParts.length > 0) {\n return expanded + '\\n\\n' + contextParts.join('\\n\\n');\n }\n\n return expanded;\n }\n\n getMentionsSummary(mentions: ResolvedMention[]): string[] {\n return mentions.map((m) => {\n if (m.error) {\n return ` ✗ ${m.raw} → ${m.error}`;\n }\n\n const lines = m.content.split('\\n').length;\n switch (m.type) {\n case MentionType.FILE:\n return ` ✓ ${m.raw} (${lines} lines)`;\n case MentionType.DIRECTORY:\n return ` ✓ ${m.raw} (${lines} entries)`;\n case MentionType.URL:\n return ` ✓ ${m.raw} (${m.content.length} chars)`;\n case MentionType.GIT:\n return ` ✓ ${m.raw}`;\n default:\n return ` ✓ ${m.raw}`;\n }\n });\n }\n}\n"],"names":["MentionsService","execAsync","promisify","exec","processMessage","message","mentions","parseMentions","length","expandedMessage","originalMessage","resolved","Promise","all","map","m","resolveMention","buildExpandedMessage","mentionRegex","match","target","raw","type","startsWith","MentionType","URL","GIT","endsWith","DIRECTORY","path","resolve","process","cwd","FILE","push","mention","resolveFile","resolveDirectory","resolveUrl","resolveGit","content","error","filePath","stat","fs","isDirectory","size","MAX_FILE_SIZE","readFile","lines","split","slice","MAX_FILE_LINES","numbered","l","i","join","Math","round","err","code","dirPath","entries","readdir","withFileTypes","limited","MAX_DIR_ENTRIES","e","prefix","name","response","fetch","headers","signal","AbortSignal","timeout","ok","status","statusText","text","MAX_URL_LENGTH","command","replace","gitCommands","diff","log","branch","stash","cmd","Object","keys","stdout","stderr","expanded","trim","contextParts","getMentionsSummary"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/modules/mentions/services/mentions.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport {\n MentionType,\n ParsedMention,\n ResolvedMention,\n MentionResult,\n} from '../types';\n\nconst execAsync = promisify(exec);\n\n@Injectable()\nexport class MentionsService {\n private readonly MAX_FILE_LINES = 500;\n private readonly MAX_FILE_SIZE = 100 * 1024; // 100KB\n private readonly MAX_DIR_ENTRIES = 100;\n private readonly MAX_URL_LENGTH = 50000;\n\n async processMessage(message: string): Promise<MentionResult> {\n const mentions = this.parseMentions(message);\n\n if (mentions.length === 0) {\n return {\n expandedMessage: message,\n mentions: [],\n originalMessage: message,\n };\n }\n\n const resolved = await Promise.all(\n mentions.map((m) => this.resolveMention(m)),\n );\n\n const expandedMessage = this.buildExpandedMessage(message, resolved);\n\n return {\n expandedMessage,\n mentions: resolved,\n originalMessage: message,\n };\n }\n\n private parseMentions(message: string): ParsedMention[] {\n const mentions: ParsedMention[] = [];\n\n const mentionRegex = /(?:^|\\s)@(?:\\[)?((?:https?:\\/\\/\\S+)|(?:git:[a-z]+)|(?:\\.?\\/?[\\w./-]+\\.[\\w]+)|(?:\\.?\\/?[\\w./-]+\\/))(?:\\])?/g;\n\n let match: RegExpExecArray | null;\n\n while ((match = mentionRegex.exec(message)) !== null) {\n let target = match[1];\n const raw = match[0].trim();\n\n let type: MentionType;\n let resolved: string;\n\n if (target.startsWith('http://') || target.startsWith('https://')) {\n type = MentionType.URL;\n resolved = target;\n } else if (target.startsWith('git:')) {\n type = MentionType.GIT;\n resolved = target;\n } else if (target.endsWith('/')) {\n type = MentionType.DIRECTORY;\n resolved = path.resolve(process.cwd(), target);\n } else {\n type = MentionType.FILE;\n resolved = path.resolve(process.cwd(), target);\n }\n\n mentions.push({ type, raw, target, resolved });\n }\n\n return mentions;\n }\n\n private async resolveMention(mention: ParsedMention): Promise<ResolvedMention> {\n try {\n switch (mention.type) {\n case MentionType.FILE:\n return await this.resolveFile(mention);\n case MentionType.DIRECTORY:\n return await this.resolveDirectory(mention);\n case MentionType.URL:\n return await this.resolveUrl(mention);\n case MentionType.GIT:\n return await this.resolveGit(mention);\n default:\n return { ...mention, content: '', error: 'Unknown mention type' };\n }\n } catch (error) {\n return {\n ...mention,\n content: '',\n error: `Failed to resolve: ${(error as Error).message}`,\n };\n }\n }\n\n private async resolveFile(mention: ParsedMention): Promise<ResolvedMention> {\n const filePath = mention.resolved;\n\n try {\n const stat = await fs.stat(filePath);\n\n if (stat.isDirectory()) {\n return this.resolveDirectory({\n ...mention,\n type: MentionType.DIRECTORY,\n });\n }\n\n if (stat.size > this.MAX_FILE_SIZE) {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n').slice(0, this.MAX_FILE_LINES);\n const numbered = lines.map((l, i) => `${i + 1}: ${l}`).join('\\n');\n return {\n ...mention,\n content: numbered + `\\n... (truncated, file is ${Math.round(stat.size / 1024)}KB)`,\n };\n }\n\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n const numbered = lines.map((l, i) => `${i + 1}: ${l}`).join('\\n');\n\n return { ...mention, content: numbered };\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n return { ...mention, content: '', error: `File not found: ${filePath}` };\n }\n throw error;\n }\n }\n\n private async resolveDirectory(mention: ParsedMention): Promise<ResolvedMention> {\n const dirPath = mention.resolved;\n\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n const limited = entries.slice(0, this.MAX_DIR_ENTRIES);\n\n const lines = limited.map((e) => {\n const prefix = e.isDirectory() ? 'd' : 'f';\n return `${prefix} ${e.name}`;\n });\n\n let content = lines.join('\\n');\n\n if (entries.length > this.MAX_DIR_ENTRIES) {\n content += `\\n... (${entries.length - this.MAX_DIR_ENTRIES} more entries)`;\n }\n\n return { ...mention, content };\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n return { ...mention, content: '', error: `Directory not found: ${dirPath}` };\n }\n throw error;\n }\n }\n\n private async resolveUrl(mention: ParsedMention): Promise<ResolvedMention> {\n try {\n const response = await fetch(mention.resolved, {\n headers: { 'User-Agent': 'Cast-Code/1.0' },\n signal: AbortSignal.timeout(10000),\n });\n\n if (!response.ok) {\n return {\n ...mention,\n content: '',\n error: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n\n let text = await response.text();\n\n if (text.length > this.MAX_URL_LENGTH) {\n text = text.slice(0, this.MAX_URL_LENGTH) + '\\n... (truncated)';\n }\n\n return { ...mention, content: text };\n } catch (error) {\n return {\n ...mention,\n content: '',\n error: `Fetch failed: ${(error as Error).message}`,\n };\n }\n }\n\n private async resolveGit(mention: ParsedMention): Promise<ResolvedMention> {\n const command = mention.target.replace('git:', '');\n\n const gitCommands: Record<string, string> = {\n status: 'git status',\n diff: 'git diff',\n log: 'git log --oneline -20',\n branch: 'git branch -a',\n stash: 'git stash list',\n };\n\n const cmd = gitCommands[command];\n\n if (!cmd) {\n return {\n ...mention,\n content: '',\n error: `Unknown git command: ${command}. Available: ${Object.keys(gitCommands).join(', ')}`,\n };\n }\n\n try {\n const { stdout, stderr } = await execAsync(cmd, {\n cwd: process.cwd(),\n timeout: 10000,\n });\n\n return { ...mention, content: stdout || stderr || '(no output)' };\n } catch (error) {\n return {\n ...mention,\n content: '',\n error: `Git command failed: ${(error as Error).message}`,\n };\n }\n }\n\n private buildExpandedMessage(\n originalMessage: string,\n mentions: ResolvedMention[],\n ): string {\n let expanded = originalMessage;\n\n for (const mention of mentions) {\n expanded = expanded.replace(mention.raw, '').trim();\n }\n\n const contextParts: string[] = [];\n\n for (const mention of mentions) {\n if (mention.error) {\n contextParts.push(\n `<mention_error target=\"${mention.target}\">\\n${mention.error}\\n</mention_error>`,\n );\n continue;\n }\n\n switch (mention.type) {\n case MentionType.FILE:\n contextParts.push(\n `<file path=\"${mention.target}\">\\n${mention.content}\\n</file>`,\n );\n break;\n case MentionType.DIRECTORY:\n contextParts.push(\n `<directory path=\"${mention.target}\">\\n${mention.content}\\n</directory>`,\n );\n break;\n case MentionType.URL:\n contextParts.push(\n `<url href=\"${mention.target}\">\\n${mention.content}\\n</url>`,\n );\n break;\n case MentionType.GIT:\n contextParts.push(\n `<git command=\"${mention.target.replace('git:', '')}\">\\n${mention.content}\\n</git>`,\n );\n break;\n }\n }\n\n if (contextParts.length > 0) {\n return expanded + '\\n\\n' + contextParts.join('\\n\\n');\n }\n\n return expanded;\n }\n\n getMentionsSummary(mentions: ResolvedMention[]): string[] {\n return mentions.map((m) => {\n if (m.error) {\n return ` ✗ ${m.raw} → ${m.error}`;\n }\n\n const lines = m.content.split('\\n').length;\n switch (m.type) {\n case MentionType.FILE:\n return ` ✓ ${m.raw} (${lines} lines)`;\n case MentionType.DIRECTORY:\n return ` ✓ ${m.raw} (${lines} entries)`;\n case MentionType.URL:\n return ` ✓ ${m.raw} (${m.content.length} chars)`;\n case MentionType.GIT:\n return ` ✓ ${m.raw}`;\n default:\n return ` ✓ ${m.raw}`;\n }\n });\n }\n}\n"],"names":["MentionsService","execAsync","promisify","exec","processMessage","message","mentions","parseMentions","length","expandedMessage","originalMessage","resolved","Promise","all","map","m","resolveMention","buildExpandedMessage","mentionRegex","match","target","raw","trim","type","startsWith","MentionType","URL","GIT","endsWith","DIRECTORY","path","resolve","process","cwd","FILE","push","mention","resolveFile","resolveDirectory","resolveUrl","resolveGit","content","error","filePath","stat","fs","isDirectory","size","MAX_FILE_SIZE","readFile","lines","split","slice","MAX_FILE_LINES","numbered","l","i","join","Math","round","err","code","dirPath","entries","readdir","withFileTypes","limited","MAX_DIR_ENTRIES","e","prefix","name","response","fetch","headers","signal","AbortSignal","timeout","ok","status","statusText","text","MAX_URL_LENGTH","command","replace","gitCommands","diff","log","branch","stash","cmd","Object","keys","stdout","stderr","expanded","contextParts","getMentionsSummary"],"mappings":"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"}
@@ -9,49 +9,8 @@ Object.defineProperty(exports, "PromptService", {
9
9
  }
10
10
  });
11
11
  const _common = require("@nestjs/common");
12
- const _readline = /*#__PURE__*/ _interop_require_wildcard(require("readline"));
12
+ const _prompts = require("@inquirer/prompts");
13
13
  const _theme = require("../../repl/utils/theme");
14
- function _getRequireWildcardCache(nodeInterop) {
15
- if (typeof WeakMap !== "function") return null;
16
- var cacheBabelInterop = new WeakMap();
17
- var cacheNodeInterop = new WeakMap();
18
- return (_getRequireWildcardCache = function(nodeInterop) {
19
- return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
20
- })(nodeInterop);
21
- }
22
- function _interop_require_wildcard(obj, nodeInterop) {
23
- if (!nodeInterop && obj && obj.__esModule) {
24
- return obj;
25
- }
26
- if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
27
- return {
28
- default: obj
29
- };
30
- }
31
- var cache = _getRequireWildcardCache(nodeInterop);
32
- if (cache && cache.has(obj)) {
33
- return cache.get(obj);
34
- }
35
- var newObj = {
36
- __proto__: null
37
- };
38
- var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
39
- for(var key in obj){
40
- if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
41
- var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
42
- if (desc && (desc.get || desc.set)) {
43
- Object.defineProperty(newObj, key, desc);
44
- } else {
45
- newObj[key] = obj[key];
46
- }
47
- }
48
- }
49
- newObj.default = obj;
50
- if (cache) {
51
- cache.set(obj, newObj);
52
- }
53
- return newObj;
54
- }
55
14
  function _ts_decorate(decorators, target, key, desc) {
56
15
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
57
16
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -60,40 +19,28 @@ function _ts_decorate(decorators, target, key, desc) {
60
19
  }
61
20
  let PromptService = class PromptService {
62
21
  async question(query) {
63
- return new Promise((resolve)=>{
64
- const rl = _readline.createInterface({
65
- input: process.stdin,
66
- output: process.stdout,
67
- terminal: false
68
- });
69
- rl.question(query + ' ', (answer)=>{
70
- rl.close();
71
- resolve(answer);
72
- });
22
+ const answer = await (0, _prompts.input)({
23
+ message: `${_theme.Colors.primary}${query}${_theme.Colors.reset}`
73
24
  });
25
+ return answer;
74
26
  }
75
27
  async confirm(message, defaultValue = false) {
76
- const suffix = defaultValue ? ' [Y/n]' : ' [y/N]';
77
- const answer = await this.question(`${_theme.Colors.yellow}${message}${suffix}${_theme.Colors.reset}`);
78
- if (!answer.trim()) return defaultValue;
79
- return answer.toLowerCase().startsWith('y');
28
+ const answer = await (0, _prompts.confirm)({
29
+ message: `${_theme.Colors.yellow}${message}${_theme.Colors.reset}`,
30
+ default: defaultValue
31
+ });
32
+ return answer;
80
33
  }
81
34
  async choice(message, choices) {
82
- console.log(`\n${_theme.Colors.cyan}${message}${_theme.Colors.reset}`);
83
- console.log('');
84
- choices.forEach((choice, index)=>{
85
- const desc = choice.description ? `${_theme.Colors.dim} - ${choice.description}${_theme.Colors.reset}` : '';
86
- console.log(` ${_theme.Colors.white}${index + 1}.${_theme.Colors.reset} ${_theme.Colors.bold}${choice.label}${_theme.Colors.reset}${desc}`);
35
+ const answer = await (0, _prompts.select)({
36
+ message: `${_theme.Colors.cyan}${message}${_theme.Colors.reset}`,
37
+ choices: choices.map((choice)=>({
38
+ value: choice.key,
39
+ name: `${_theme.Colors.bold}${choice.label}${_theme.Colors.reset}`,
40
+ description: choice.description ? `${_theme.Colors.dim}${choice.description}${_theme.Colors.reset}` : undefined
41
+ }))
87
42
  });
88
- console.log('');
89
- while(true){
90
- const answer = await this.question(`${_theme.Colors.yellow}Choose (1-${choices.length}):${_theme.Colors.reset}`);
91
- const index = parseInt(answer) - 1;
92
- if (index >= 0 && index < choices.length) {
93
- return choices[index].key;
94
- }
95
- console.log(`${_theme.Colors.red}Invalid choice. Please try again.${_theme.Colors.reset}`);
96
- }
43
+ return answer;
97
44
  }
98
45
  warn(message) {
99
46
  console.log(`${_theme.Colors.yellow} ${message}${_theme.Colors.reset}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/permissions/services/prompt.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport * as readline from 'readline';\nimport { Colors } from '../../repl/utils/theme';\n\n@Injectable()\nexport class PromptService {\n async question(query: string): Promise<string> {\n return new Promise((resolve) => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: false,\n });\n\n rl.question(query + ' ', (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n }\n\n async confirm(message: string, defaultValue = false): Promise<boolean> {\n const suffix = defaultValue ? ' [Y/n]' : ' [y/N]';\n const answer = await this.question(\n `${Colors.yellow}${message}${suffix}${Colors.reset}`,\n );\n\n if (!answer.trim()) return defaultValue;\n\n return answer.toLowerCase().startsWith('y');\n }\n\n async choice<T extends string>(\n message: string,\n choices: { key: T; label: string; description?: string }[],\n ): Promise<T> {\n console.log(`\\n${Colors.cyan}${message}${Colors.reset}`);\n console.log('');\n\n choices.forEach((choice, index) => {\n const desc = choice.description\n ? `${Colors.dim} - ${choice.description}${Colors.reset}`\n : '';\n console.log(\n ` ${Colors.white}${index + 1}.${Colors.reset} ${Colors.bold}${choice.label}${Colors.reset}${desc}`,\n );\n });\n\n console.log('');\n\n while (true) {\n const answer = await this.question(\n `${Colors.yellow}Choose (1-${choices.length}):${Colors.reset}`,\n );\n const index = parseInt(answer) - 1;\n\n if (index >= 0 && index < choices.length) {\n return choices[index].key;\n }\n\n console.log(\n `${Colors.red}Invalid choice. Please try again.${Colors.reset}`,\n );\n }\n }\n\n warn(message: string): void {\n console.log(`${Colors.yellow} ${message}${Colors.reset}`);\n }\n\n error(message: string): void {\n console.log(`${Colors.red} ${message}${Colors.reset}`);\n }\n\n success(message: string): void {\n console.log(`${Colors.green} ${message}${Colors.reset}`);\n }\n\n info(message: string): void {\n console.log(`${Colors.blue} ${message}${Colors.reset}`);\n }\n\n close(): void {}\n}\n"],"names":["PromptService","question","query","Promise","resolve","rl","readline","createInterface","input","process","stdin","output","stdout","terminal","answer","close","confirm","message","defaultValue","suffix","Colors","yellow","reset","trim","toLowerCase","startsWith","choice","choices","console","log","cyan","forEach","index","desc","description","dim","white","bold","label","length","parseInt","key","red","warn","error","success","green","info","blue"],"mappings":";;;;+BAKaA;;;eAAAA;;;wBALc;kEACD;uBACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGhB,IAAA,AAAMA,gBAAN,MAAMA;IACX,MAAMC,SAASC,KAAa,EAAmB;QAC7C,OAAO,IAAIC,QAAQ,CAACC;YAClB,MAAMC,KAAKC,UAASC,eAAe,CAAC;gBAClCC,OAAOC,QAAQC,KAAK;gBACpBC,QAAQF,QAAQG,MAAM;gBACtBC,UAAU;YACZ;YAEAR,GAAGJ,QAAQ,CAACC,QAAQ,KAAK,CAACY;gBACxBT,GAAGU,KAAK;gBACRX,QAAQU;YACV;QACF;IACF;IAEA,MAAME,QAAQC,OAAe,EAAEC,eAAe,KAAK,EAAoB;QACrE,MAAMC,SAASD,eAAe,WAAW;QACzC,MAAMJ,SAAS,MAAM,IAAI,CAACb,QAAQ,CAChC,GAAGmB,aAAM,CAACC,MAAM,GAAGJ,UAAUE,SAASC,aAAM,CAACE,KAAK,EAAE;QAGtD,IAAI,CAACR,OAAOS,IAAI,IAAI,OAAOL;QAE3B,OAAOJ,OAAOU,WAAW,GAAGC,UAAU,CAAC;IACzC;IAEA,MAAMC,OACJT,OAAe,EACfU,OAA0D,EAC9C;QACZC,QAAQC,GAAG,CAAC,CAAC,EAAE,EAAET,aAAM,CAACU,IAAI,GAAGb,UAAUG,aAAM,CAACE,KAAK,EAAE;QACvDM,QAAQC,GAAG,CAAC;QAEZF,QAAQI,OAAO,CAAC,CAACL,QAAQM;YACvB,MAAMC,OAAOP,OAAOQ,WAAW,GAC3B,GAAGd,aAAM,CAACe,GAAG,CAAC,GAAG,EAAET,OAAOQ,WAAW,GAAGd,aAAM,CAACE,KAAK,EAAE,GACtD;YACJM,QAAQC,GAAG,CACT,CAAC,EAAE,EAAET,aAAM,CAACgB,KAAK,GAAGJ,QAAQ,EAAE,CAAC,EAAEZ,aAAM,CAACE,KAAK,CAAC,CAAC,EAAEF,aAAM,CAACiB,IAAI,GAAGX,OAAOY,KAAK,GAAGlB,aAAM,CAACE,KAAK,GAAGW,MAAM;QAEvG;QAEAL,QAAQC,GAAG,CAAC;QAEZ,MAAO,KAAM;YACX,MAAMf,SAAS,MAAM,IAAI,CAACb,QAAQ,CAChC,GAAGmB,aAAM,CAACC,MAAM,CAAC,UAAU,EAAEM,QAAQY,MAAM,CAAC,EAAE,EAAEnB,aAAM,CAACE,KAAK,EAAE;YAEhE,MAAMU,QAAQQ,SAAS1B,UAAU;YAEjC,IAAIkB,SAAS,KAAKA,QAAQL,QAAQY,MAAM,EAAE;gBACxC,OAAOZ,OAAO,CAACK,MAAM,CAACS,GAAG;YAC3B;YAEAb,QAAQC,GAAG,CACT,GAAGT,aAAM,CAACsB,GAAG,CAAC,iCAAiC,EAAEtB,aAAM,CAACE,KAAK,EAAE;QAEnE;IACF;IAEAqB,KAAK1B,OAAe,EAAQ;QAC1BW,QAAQC,GAAG,CAAC,GAAGT,aAAM,CAACC,MAAM,CAAC,EAAE,EAAEJ,UAAUG,aAAM,CAACE,KAAK,EAAE;IAC3D;IAEAsB,MAAM3B,OAAe,EAAQ;QAC3BW,QAAQC,GAAG,CAAC,GAAGT,aAAM,CAACsB,GAAG,CAAC,EAAE,EAAEzB,UAAUG,aAAM,CAACE,KAAK,EAAE;IACxD;IAEAuB,QAAQ5B,OAAe,EAAQ;QAC7BW,QAAQC,GAAG,CAAC,GAAGT,aAAM,CAAC0B,KAAK,CAAC,EAAE,EAAE7B,UAAUG,aAAM,CAACE,KAAK,EAAE;IAC1D;IAEAyB,KAAK9B,OAAe,EAAQ;QAC1BW,QAAQC,GAAG,CAAC,GAAGT,aAAM,CAAC4B,IAAI,CAAC,EAAE,EAAE/B,UAAUG,aAAM,CAACE,KAAK,EAAE;IACzD;IAEAP,QAAc,CAAC;AACjB"}
1
+ {"version":3,"sources":["../../../../src/modules/permissions/services/prompt.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport { input, confirm, select } from '@inquirer/prompts';\nimport { Colors } from '../../repl/utils/theme';\n\n@Injectable()\nexport class PromptService {\n async question(query: string): Promise<string> {\n const answer = await input({\n message: `${Colors.primary}${query}${Colors.reset}`,\n });\n return answer;\n }\n\n async confirm(message: string, defaultValue = false): Promise<boolean> {\n const answer = await confirm({\n message: `${Colors.yellow}${message}${Colors.reset}`,\n default: defaultValue,\n });\n return answer;\n }\n\n async choice<T extends string>(\n message: string,\n choices: { key: T; label: string; description?: string }[],\n ): Promise<T> {\n const answer = await select({\n message: `${Colors.cyan}${message}${Colors.reset}`,\n choices: choices.map((choice) => ({\n value: choice.key,\n name: `${Colors.bold}${choice.label}${Colors.reset}`,\n description: choice.description ? `${Colors.dim}${choice.description}${Colors.reset}` : undefined,\n })),\n });\n return answer;\n }\n\n warn(message: string): void {\n console.log(`${Colors.yellow} ${message}${Colors.reset}`);\n }\n\n error(message: string): void {\n console.log(`${Colors.red} ${message}${Colors.reset}`);\n }\n\n success(message: string): void {\n console.log(`${Colors.green} ${message}${Colors.reset}`);\n }\n\n info(message: string): void {\n console.log(`${Colors.blue} ${message}${Colors.reset}`);\n }\n\n close(): void { }\n}\n"],"names":["PromptService","question","query","answer","input","message","Colors","primary","reset","confirm","defaultValue","yellow","default","choice","choices","select","cyan","map","value","key","name","bold","label","description","dim","undefined","warn","console","log","error","red","success","green","info","blue","close"],"mappings":";;;;+BAKaA;;;eAAAA;;;wBALc;yBACY;uBAChB;;;;;;;AAGhB,IAAA,AAAMA,gBAAN,MAAMA;IACX,MAAMC,SAASC,KAAa,EAAmB;QAC7C,MAAMC,SAAS,MAAMC,IAAAA,cAAK,EAAC;YACzBC,SAAS,GAAGC,aAAM,CAACC,OAAO,GAAGL,QAAQI,aAAM,CAACE,KAAK,EAAE;QACrD;QACA,OAAOL;IACT;IAEA,MAAMM,QAAQJ,OAAe,EAAEK,eAAe,KAAK,EAAoB;QACrE,MAAMP,SAAS,MAAMM,IAAAA,gBAAO,EAAC;YAC3BJ,SAAS,GAAGC,aAAM,CAACK,MAAM,GAAGN,UAAUC,aAAM,CAACE,KAAK,EAAE;YACpDI,SAASF;QACX;QACA,OAAOP;IACT;IAEA,MAAMU,OACJR,OAAe,EACfS,OAA0D,EAC9C;QACZ,MAAMX,SAAS,MAAMY,IAAAA,eAAM,EAAC;YAC1BV,SAAS,GAAGC,aAAM,CAACU,IAAI,GAAGX,UAAUC,aAAM,CAACE,KAAK,EAAE;YAClDM,SAASA,QAAQG,GAAG,CAAC,CAACJ,SAAY,CAAA;oBAChCK,OAAOL,OAAOM,GAAG;oBACjBC,MAAM,GAAGd,aAAM,CAACe,IAAI,GAAGR,OAAOS,KAAK,GAAGhB,aAAM,CAACE,KAAK,EAAE;oBACpDe,aAAaV,OAAOU,WAAW,GAAG,GAAGjB,aAAM,CAACkB,GAAG,GAAGX,OAAOU,WAAW,GAAGjB,aAAM,CAACE,KAAK,EAAE,GAAGiB;gBAC1F,CAAA;QACF;QACA,OAAOtB;IACT;IAEAuB,KAAKrB,OAAe,EAAQ;QAC1BsB,QAAQC,GAAG,CAAC,GAAGtB,aAAM,CAACK,MAAM,CAAC,EAAE,EAAEN,UAAUC,aAAM,CAACE,KAAK,EAAE;IAC3D;IAEAqB,MAAMxB,OAAe,EAAQ;QAC3BsB,QAAQC,GAAG,CAAC,GAAGtB,aAAM,CAACwB,GAAG,CAAC,EAAE,EAAEzB,UAAUC,aAAM,CAACE,KAAK,EAAE;IACxD;IAEAuB,QAAQ1B,OAAe,EAAQ;QAC7BsB,QAAQC,GAAG,CAAC,GAAGtB,aAAM,CAAC0B,KAAK,CAAC,EAAE,EAAE3B,UAAUC,aAAM,CAACE,KAAK,EAAE;IAC1D;IAEAyB,KAAK5B,OAAe,EAAQ;QAC1BsB,QAAQC,GAAG,CAAC,GAAGtB,aAAM,CAAC4B,IAAI,CAAC,EAAE,EAAE7B,UAAUC,aAAM,CAACE,KAAK,EAAE;IACzD;IAEA2B,QAAc,CAAE;AAClB"}
@@ -74,18 +74,17 @@ let ProjectCommandsService = class ProjectCommandsService {
74
74
  break;
75
75
  case 'deep':
76
76
  case 'project-deep':
77
- await this.generateContext(smartInput, true);
78
- break;
77
+ return await this.generateContext(smartInput, true);
79
78
  case 'show':
80
79
  await this.showContext();
81
- break;
80
+ return;
82
81
  case 'edit':
83
82
  await this.editContext();
84
- break;
83
+ return;
85
84
  case 'help':
86
85
  default:
87
86
  this.printProjectHelp();
88
- break;
87
+ return;
89
88
  }
90
89
  }
91
90
  async generateContext(smartInput, useAgent) {
@@ -123,10 +122,9 @@ let ProjectCommandsService = class ProjectCommandsService {
123
122
  const agentInstructions = this.projectAnalyzer.generateAgentInstructions(context);
124
123
  await _promises.writeFile(agentInstructionsPath, agentInstructions, 'utf-8');
125
124
  w(`${(0, _theme.colorize)('✓', 'success')} Instruções para agente: ${(0, _theme.colorize)(agentInstructionsPath, 'accent')}\r\n\r\n`);
126
- w((0, _theme.colorize)('📋 Para análise profunda, você pode:\r\n', 'bold'));
127
- w((0, _theme.colorize)(' 1. Copiar as instruções de ' + agentInstructionsPath + '\r\n', 'muted'));
128
- w((0, _theme.colorize)(' 2. Colar em uma nova conversa com um agente especialista\r\n', 'muted'));
129
- w((0, _theme.colorize)(' 3. O agente analisará profundamente o projeto\r\n\r\n', 'muted'));
125
+ const mentionText = `@[${agentInstructionsPath}]`;
126
+ w((0, _theme.colorize)(` Iniciando agente com ${mentionText}...\r\n`, 'bold'));
127
+ return mentionText;
130
128
  }
131
129
  const showPreview = await (0, _promptswithesc.confirmWithEsc)({
132
130
  message: 'Deseja ver um preview do contexto gerado?',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/modules/repl/services/commands/project-commands.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { ProjectAnalyzerService, ProjectContext } from '../../../project/services/project-analyzer.service';\nimport { Colors, colorize, Box, Icons } from '../../utils/theme';\nimport { confirmWithEsc } from '../../utils/prompts-with-esc';\n\ninterface SmartInput {\n askChoice: (question: string, choices: { key: string; label: string; description: string }[]) => Promise<string>;\n question: (prompt: string) => Promise<string>;\n}\n\n@Injectable()\nexport class ProjectCommandsService {\n constructor(\n private readonly projectAnalyzer: ProjectAnalyzerService,\n ) {}\n\n async cmdProject(args: string[], smartInput: SmartInput): Promise<void> {\n const sub = args[0] || 'analyze';\n \n switch (sub) {\n case 'analyze':\n case 'generate':\n await this.generateContext(smartInput, false);\n break;\n\n case 'deep':\n case 'project-deep':\n await this.generateContext(smartInput, true);\n break;\n\n case 'show':\n await this.showContext();\n break;\n\n case 'edit':\n await this.editContext();\n break;\n\n case 'help':\n default:\n this.printProjectHelp();\n break;\n }\n }\n\n private async generateContext(smartInput: SmartInput, useAgent: boolean): Promise<void> {\n smartInput.pause();\n \n const w = (s: string) => process.stdout.write(s);\n \n w('\\r\\n');\n w(colorize(Icons.folder + ' ', 'accent') + colorize('Análise de Projeto', 'bold') + '\\r\\n');\n w(colorize(Box.horizontal.repeat(30), 'subtle') + '\\r\\n\\r\\n');\n\n const castDir = path.join(process.cwd(), '.cast');\n const contextPath = path.join(castDir, 'context.md');\n const agentInstructionsPath = path.join(castDir, 'agent-instructions.md');\n\n try {\n await fs.mkdir(castDir, { recursive: true });\n } catch {}\n\n w(colorize(' 🔍 Analisando estrutura do projeto...\\r\\n', 'info'));\n\n try {\n const context = await this.projectAnalyzer.analyze();\n \n w(colorize(` ✓ Linguagem principal: ${context.primaryLanguage}\\r\\n`, 'success'));\n if (context.languages.length > 1) {\n w(colorize(` ✓ Outras linguagens: ${context.languages.slice(1).join(', ')}\\r\\n`, 'success'));\n }\n if (context.architecture) {\n w(colorize(` ✓ Arquitetura detectada: ${context.architecture.pattern} (${context.architecture.confidence})\\r\\n`, 'success'));\n }\n w(colorize(` ✓ ${context.modules.length} módulo(s) encontrado(s)\\r\\n`, 'success'));\n w(colorize(` ✓ ${context.rawData.allFiles.length} arquivo(s) de código\\r\\n`, 'success'));\n\n const markdown = this.projectAnalyzer.generateMarkdown(context);\n await fs.writeFile(contextPath, markdown, 'utf-8');\n\n w(`\\r\\n${colorize('✓', 'success')} Contexto básico gerado: ${colorize(contextPath, 'accent')}\\r\\n`);\n w(colorize(' O Cast usará este contexto em todas as conversas!\\r\\n\\r\\n', 'muted'));\n\n if (useAgent) {\n w(colorize(' 🤖 Gerando instruções para análise profunda...\\r\\n\\r\\n', 'info'));\n \n const agentInstructions = this.projectAnalyzer.generateAgentInstructions(context);\n await fs.writeFile(agentInstructionsPath, agentInstructions, 'utf-8');\n \n w(`${colorize('✓', 'success')} Instruções para agente: ${colorize(agentInstructionsPath, 'accent')}\\r\\n\\r\\n`);\n \n w(colorize('📋 Para análise profunda, você pode:\\r\\n', 'bold'));\n w(colorize(' 1. Copiar as instruções de ' + agentInstructionsPath + '\\r\\n', 'muted'));\n w(colorize(' 2. Colar em uma nova conversa com um agente especialista\\r\\n', 'muted'));\n w(colorize(' 3. O agente analisará profundamente o projeto\\r\\n\\r\\n', 'muted'));\n }\n\n const showPreview = await confirmWithEsc({\n message: 'Deseja ver um preview do contexto gerado?',\n default: true,\n });\n \n if (showPreview === true) {\n w('\\r\\n');\n w(colorize('─'.repeat(60), 'subtle') + '\\r\\n');\n const lines = markdown.split('\\n').slice(0, 40);\n lines.forEach(line => {\n const truncated = line.length > 78 ? line.slice(0, 75) + '...' : line;\n w(' ' + truncated + '\\r\\n');\n });\n if (markdown.split('\\n').length > 40) {\n w(colorize(' ... (mais conteúdo no arquivo)\\r\\n', 'muted'));\n }\n w(colorize('─'.repeat(60), 'subtle') + '\\r\\n\\r\\n');\n }\n\n } catch (error: any) {\n w(`\\r\\n${colorize('✗', 'error')} Erro ao analisar projeto: ${error.message}\\r\\n\\r\\n`);\n } finally {\n smartInput.resume();\n }\n }\n\n private async showContext(): Promise<void> {\n const w = (s: string) => process.stdout.write(s);\n const contextPath = path.join(process.cwd(), '.cast', 'context.md');\n\n w('\\r\\n');\n w(colorize(Icons.file + ' ', 'accent') + colorize('Contexto do Projeto', 'bold') + '\\r\\n');\n w(colorize(Box.horizontal.repeat(30), 'subtle') + '\\r\\n\\r\\n');\n\n try {\n const content = await fs.readFile(contextPath, 'utf-8');\n w(content);\n w('\\r\\n');\n } catch {\n w(colorize(' ⚠️ Nenhum context.md encontrado!\\r\\n', 'warning'));\n w(colorize(' Use \"/project\" ou \"/project analyze\" para gerar.\\r\\n\\r\\n', 'muted'));\n }\n }\n\n private async editContext(): Promise<void> {\n const contextPath = path.join(process.cwd(), '.cast', 'context.md');\n \n const { spawn } = require('child_process');\n const editor = process.env.EDITOR || 'code';\n\n try {\n spawn(editor, [contextPath], { \n detached: true, \n stdio: 'ignore'\n }).unref();\n \n console.log(`\\r\\n ${colorize('✓', 'success')} Abrindo ${contextPath} no editor...\\r\\n`);\n } catch {\n console.log(`\\r\\n ${colorize('✗', 'error')} Não foi possível abrir o editor.\\r\\n`);\n console.log(` ${colorize('Arquivo:', 'muted')} ${contextPath}\\r\\n\\r\\n`);\n }\n }\n\n private printProjectHelp(): void {\n const w = (s: string) => process.stdout.write(s);\n\n w('\\r\\n');\n w(colorize(Icons.folder + ' ', 'accent') + colorize('Project Context Commands', 'bold') + '\\r\\n');\n w(colorize(Box.horizontal.repeat(35), 'subtle') + '\\r\\n\\r\\n');\n\n w(colorize('Comandos:', 'bold') + '\\r\\n');\n w(` ${colorize('/project', 'cyan')} → Análise rápida do projeto\\r\\n`);\n w(` ${colorize('/project-deep', 'cyan')} → Análise profunda (gera instruções para agente)\\r\\n`);\n w(` ${colorize('/project analyze', 'cyan')} → Gera context.md (mesmo que /project)\\r\\n`);\n w(` ${colorize('/project deep', 'cyan')} → Análise + instruções para agente\\r\\n`);\n w(` ${colorize('/project show', 'cyan')} → Mostra o contexto atual\\r\\n`);\n w(` ${colorize('/project edit', 'cyan')} → Abre no editor\\r\\n\\r\\n`);\n\n w(colorize('Modo Rápido vs Profundo:', 'bold') + '\\r\\n\\r\\n');\n \n w(colorize('⚡ Modo Rápido (/project):', 'accent') + '\\r\\n');\n w(` • Detecta linguagem (TypeScript, Python, Go, Rust, Java, etc.)\\r\\n`);\n w(` • Identifica arquitetura (MVC, Clean, Hexagonal, DDD, etc.)\\r\\n`);\n w(` • Lista módulos e suas responsabilidades\\r\\n`);\n w(` • Extrai dependências principais\\r\\n`);\n w(` • Funciona com QUALQUER linguagem/framework\\r\\n\\r\\n`);\n \n w(colorize('🤖 Modo Profundo (/project-deep):', 'accent') + '\\r\\n');\n w(` • Faz tudo do modo rápido\\r\\n`);\n w(` • Gera instruções para um agente especialista\\r\\n`);\n w(` • O agente pode analisar fluxos de dados completos\\r\\n`);\n w(` • Documenta casos de uso e regras de negócio\\r\\n`);\n w(` • Identifica débito técnico\\r\\n\\r\\n`);\n\n w(colorize('Suporte a Linguagens:', 'bold') + '\\r\\n');\n w(` TypeScript/JavaScript, Python, Go, Rust, Java, PHP, Ruby, C#\\r\\n\\r\\n`);\n }\n}\n"],"names":["ProjectCommandsService","cmdProject","args","smartInput","sub","generateContext","showContext","editContext","printProjectHelp","useAgent","pause","w","s","process","stdout","write","colorize","Icons","folder","Box","horizontal","repeat","castDir","path","join","cwd","contextPath","agentInstructionsPath","fs","mkdir","recursive","context","projectAnalyzer","analyze","primaryLanguage","languages","length","slice","architecture","pattern","confidence","modules","rawData","allFiles","markdown","generateMarkdown","writeFile","agentInstructions","generateAgentInstructions","showPreview","confirmWithEsc","message","default","lines","split","forEach","line","truncated","error","resume","file","content","readFile","spawn","require","editor","env","EDITOR","detached","stdio","unref","console","log"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/modules/repl/services/commands/project-commands.service.ts"],"sourcesContent":["import { Injectable } from '@nestjs/common';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport { ProjectAnalyzerService, ProjectContext } from '../../../project/services/project-analyzer.service';\nimport { Colors, colorize, Box, Icons } from '../../utils/theme';\nimport { confirmWithEsc } from '../../utils/prompts-with-esc';\n\ninterface SmartInput {\n askChoice: (question: string, choices: { key: string; label: string; description: string }[]) => Promise<string>;\n question: (prompt: string) => Promise<string>;\n}\n\n@Injectable()\nexport class ProjectCommandsService {\n constructor(\n private readonly projectAnalyzer: ProjectAnalyzerService,\n ) { }\n\n async cmdProject(args: string[], smartInput: SmartInput): Promise<string | void> {\n const sub = args[0] || 'analyze';\n\n switch (sub) {\n case 'analyze':\n case 'generate':\n await this.generateContext(smartInput, false);\n break;\n\n case 'deep':\n case 'project-deep':\n return await this.generateContext(smartInput, true);\n\n case 'show':\n await this.showContext();\n return;\n\n case 'edit':\n await this.editContext();\n return;\n\n case 'help':\n default:\n this.printProjectHelp();\n return;\n }\n }\n\n private async generateContext(smartInput: SmartInput, useAgent: boolean): Promise<string | void> {\n smartInput.pause();\n\n const w = (s: string) => process.stdout.write(s);\n\n w('\\r\\n');\n w(colorize(Icons.folder + ' ', 'accent') + colorize('Análise de Projeto', 'bold') + '\\r\\n');\n w(colorize(Box.horizontal.repeat(30), 'subtle') + '\\r\\n\\r\\n');\n\n const castDir = path.join(process.cwd(), '.cast');\n const contextPath = path.join(castDir, 'context.md');\n const agentInstructionsPath = path.join(castDir, 'agent-instructions.md');\n\n try {\n await fs.mkdir(castDir, { recursive: true });\n } catch { }\n\n w(colorize(' 🔍 Analisando estrutura do projeto...\\r\\n', 'info'));\n\n try {\n const context = await this.projectAnalyzer.analyze();\n\n w(colorize(` ✓ Linguagem principal: ${context.primaryLanguage}\\r\\n`, 'success'));\n if (context.languages.length > 1) {\n w(colorize(` ✓ Outras linguagens: ${context.languages.slice(1).join(', ')}\\r\\n`, 'success'));\n }\n if (context.architecture) {\n w(colorize(` ✓ Arquitetura detectada: ${context.architecture.pattern} (${context.architecture.confidence})\\r\\n`, 'success'));\n }\n w(colorize(` ✓ ${context.modules.length} módulo(s) encontrado(s)\\r\\n`, 'success'));\n w(colorize(` ✓ ${context.rawData.allFiles.length} arquivo(s) de código\\r\\n`, 'success'));\n\n const markdown = this.projectAnalyzer.generateMarkdown(context);\n await fs.writeFile(contextPath, markdown, 'utf-8');\n\n w(`\\r\\n${colorize('✓', 'success')} Contexto básico gerado: ${colorize(contextPath, 'accent')}\\r\\n`);\n w(colorize(' O Cast usará este contexto em todas as conversas!\\r\\n\\r\\n', 'muted'));\n\n if (useAgent) {\n w(colorize(' 🤖 Gerando instruções para análise profunda...\\r\\n\\r\\n', 'info'));\n\n const agentInstructions = this.projectAnalyzer.generateAgentInstructions(context);\n await fs.writeFile(agentInstructionsPath, agentInstructions, 'utf-8');\n\n w(`${colorize('✓', 'success')} Instruções para agente: ${colorize(agentInstructionsPath, 'accent')}\\r\\n\\r\\n`);\n\n const mentionText = `@[${agentInstructionsPath}]`;\n w(colorize(` Iniciando agente com ${mentionText}...\\r\\n`, 'bold'));\n\n return mentionText;\n }\n\n const showPreview = await confirmWithEsc({\n message: 'Deseja ver um preview do contexto gerado?',\n default: true,\n });\n\n if (showPreview === true) {\n w('\\r\\n');\n w(colorize('─'.repeat(60), 'subtle') + '\\r\\n');\n const lines = markdown.split('\\n').slice(0, 40);\n lines.forEach(line => {\n const truncated = line.length > 78 ? line.slice(0, 75) + '...' : line;\n w(' ' + truncated + '\\r\\n');\n });\n if (markdown.split('\\n').length > 40) {\n w(colorize(' ... (mais conteúdo no arquivo)\\r\\n', 'muted'));\n }\n w(colorize('─'.repeat(60), 'subtle') + '\\r\\n\\r\\n');\n }\n\n } catch (error: any) {\n w(`\\r\\n${colorize('✗', 'error')} Erro ao analisar projeto: ${error.message}\\r\\n\\r\\n`);\n } finally {\n smartInput.resume();\n }\n }\n\n private async showContext(): Promise<void> {\n const w = (s: string) => process.stdout.write(s);\n const contextPath = path.join(process.cwd(), '.cast', 'context.md');\n\n w('\\r\\n');\n w(colorize(Icons.file + ' ', 'accent') + colorize('Contexto do Projeto', 'bold') + '\\r\\n');\n w(colorize(Box.horizontal.repeat(30), 'subtle') + '\\r\\n\\r\\n');\n\n try {\n const content = await fs.readFile(contextPath, 'utf-8');\n w(content);\n w('\\r\\n');\n } catch {\n w(colorize(' ⚠️ Nenhum context.md encontrado!\\r\\n', 'warning'));\n w(colorize(' Use \"/project\" ou \"/project analyze\" para gerar.\\r\\n\\r\\n', 'muted'));\n }\n }\n\n private async editContext(): Promise<void> {\n const contextPath = path.join(process.cwd(), '.cast', 'context.md');\n\n const { spawn } = require('child_process');\n const editor = process.env.EDITOR || 'code';\n\n try {\n spawn(editor, [contextPath], {\n detached: true,\n stdio: 'ignore'\n }).unref();\n\n console.log(`\\r\\n ${colorize('✓', 'success')} Abrindo ${contextPath} no editor...\\r\\n`);\n } catch {\n console.log(`\\r\\n ${colorize('✗', 'error')} Não foi possível abrir o editor.\\r\\n`);\n console.log(` ${colorize('Arquivo:', 'muted')} ${contextPath}\\r\\n\\r\\n`);\n }\n }\n\n private printProjectHelp(): void {\n const w = (s: string) => process.stdout.write(s);\n\n w('\\r\\n');\n w(colorize(Icons.folder + ' ', 'accent') + colorize('Project Context Commands', 'bold') + '\\r\\n');\n w(colorize(Box.horizontal.repeat(35), 'subtle') + '\\r\\n\\r\\n');\n\n w(colorize('Comandos:', 'bold') + '\\r\\n');\n w(` ${colorize('/project', 'cyan')} → Análise rápida do projeto\\r\\n`);\n w(` ${colorize('/project-deep', 'cyan')} → Análise profunda (gera instruções para agente)\\r\\n`);\n w(` ${colorize('/project analyze', 'cyan')} → Gera context.md (mesmo que /project)\\r\\n`);\n w(` ${colorize('/project deep', 'cyan')} → Análise + instruções para agente\\r\\n`);\n w(` ${colorize('/project show', 'cyan')} → Mostra o contexto atual\\r\\n`);\n w(` ${colorize('/project edit', 'cyan')} → Abre no editor\\r\\n\\r\\n`);\n\n w(colorize('Modo Rápido vs Profundo:', 'bold') + '\\r\\n\\r\\n');\n\n w(colorize('⚡ Modo Rápido (/project):', 'accent') + '\\r\\n');\n w(` • Detecta linguagem (TypeScript, Python, Go, Rust, Java, etc.)\\r\\n`);\n w(` • Identifica arquitetura (MVC, Clean, Hexagonal, DDD, etc.)\\r\\n`);\n w(` • Lista módulos e suas responsabilidades\\r\\n`);\n w(` • Extrai dependências principais\\r\\n`);\n w(` • Funciona com QUALQUER linguagem/framework\\r\\n\\r\\n`);\n\n w(colorize('🤖 Modo Profundo (/project-deep):', 'accent') + '\\r\\n');\n w(` • Faz tudo do modo rápido\\r\\n`);\n w(` • Gera instruções para um agente especialista\\r\\n`);\n w(` • O agente pode analisar fluxos de dados completos\\r\\n`);\n w(` • Documenta casos de uso e regras de negócio\\r\\n`);\n w(` • Identifica débito técnico\\r\\n\\r\\n`);\n\n w(colorize('Suporte a Linguagens:', 'bold') + '\\r\\n');\n w(` TypeScript/JavaScript, Python, Go, Rust, Java, PHP, Ruby, C#\\r\\n\\r\\n`);\n }\n}\n"],"names":["ProjectCommandsService","cmdProject","args","smartInput","sub","generateContext","showContext","editContext","printProjectHelp","useAgent","pause","w","s","process","stdout","write","colorize","Icons","folder","Box","horizontal","repeat","castDir","path","join","cwd","contextPath","agentInstructionsPath","fs","mkdir","recursive","context","projectAnalyzer","analyze","primaryLanguage","languages","length","slice","architecture","pattern","confidence","modules","rawData","allFiles","markdown","generateMarkdown","writeFile","agentInstructions","generateAgentInstructions","mentionText","showPreview","confirmWithEsc","message","default","lines","split","forEach","line","truncated","error","resume","file","content","readFile","spawn","require","editor","env","EDITOR","detached","stdio","unref","console","log"],"mappings":"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"}
@@ -238,46 +238,104 @@ let ReplService = class ReplService {
238
238
  ...this.getFileEntries(partial)
239
239
  ].slice(0, 30);
240
240
  }
241
+ getCachedFiles() {
242
+ const now = Date.now();
243
+ if (this.fileCache && now - this.lastCacheTime < 5000) {
244
+ return this.fileCache;
245
+ }
246
+ const fs = require('fs');
247
+ const path = require('path');
248
+ const ignore = [
249
+ 'node_modules',
250
+ '.git',
251
+ 'dist',
252
+ 'coverage',
253
+ '.next',
254
+ '__pycache__'
255
+ ];
256
+ const results = [];
257
+ const walk = (dir)=>{
258
+ try {
259
+ const entries = fs.readdirSync(dir, {
260
+ withFileTypes: true
261
+ });
262
+ for (const e of entries){
263
+ if (ignore.includes(e.name)) continue;
264
+ if (e.name.startsWith('.') && e.name !== '.cast' && e.name !== '.claude') continue;
265
+ const fullPath = path.join(dir, e.name);
266
+ const relPath = path.relative(process.cwd(), fullPath);
267
+ if (e.isDirectory()) {
268
+ walk(fullPath);
269
+ } else {
270
+ results.push(relPath);
271
+ }
272
+ }
273
+ } catch {}
274
+ };
275
+ walk(process.cwd());
276
+ this.fileCache = results;
277
+ this.lastCacheTime = now;
278
+ return results;
279
+ }
241
280
  getFileEntries(partial) {
242
281
  const fs = require('fs');
243
282
  const path = require('path');
244
- try {
245
- let dir;
246
- let prefix;
247
- if (partial.endsWith('/')) {
248
- dir = partial.slice(0, -1) || '.';
249
- prefix = '';
250
- } else if (partial.includes('/')) {
251
- dir = path.dirname(partial);
252
- prefix = path.basename(partial);
253
- } else {
254
- dir = '.';
255
- prefix = partial;
283
+ if (partial === '' || partial.includes('/') || partial.startsWith('.')) {
284
+ try {
285
+ let dir;
286
+ let prefix;
287
+ if (partial.endsWith('/')) {
288
+ dir = partial.slice(0, -1) || '.';
289
+ prefix = '';
290
+ } else if (partial.includes('/')) {
291
+ dir = path.dirname(partial);
292
+ prefix = path.basename(partial);
293
+ } else {
294
+ dir = '.';
295
+ prefix = partial;
296
+ }
297
+ const resolved = path.resolve(process.cwd(), dir);
298
+ if (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory()) return [];
299
+ const entries = fs.readdirSync(resolved, {
300
+ withFileTypes: true
301
+ });
302
+ const ignore = [
303
+ 'node_modules',
304
+ '.git',
305
+ 'dist',
306
+ 'coverage',
307
+ '.next',
308
+ '__pycache__'
309
+ ];
310
+ return entries.filter((e)=>!ignore.includes(e.name)).filter((e)=>!e.name.startsWith('.') || prefix.startsWith('.') || e.name === '.cast' || e.name === '.claude').filter((e)=>prefix === '' || e.name.toLowerCase().startsWith(prefix.toLowerCase())).map((e)=>{
311
+ const relDir = dir === '.' ? '' : dir + '/';
312
+ const isDir = e.isDirectory();
313
+ return {
314
+ text: '@' + relDir + e.name + (isDir ? '/' : ''),
315
+ display: '@' + relDir + e.name + (isDir ? '/' : ''),
316
+ description: isDir ? 'dir' : ''
317
+ };
318
+ }).slice(0, 20);
319
+ } catch {
320
+ return [];
256
321
  }
257
- const resolved = path.resolve(process.cwd(), dir);
258
- if (!fs.existsSync(resolved) || !fs.statSync(resolved).isDirectory()) return [];
259
- const entries = fs.readdirSync(resolved, {
260
- withFileTypes: true
322
+ } else {
323
+ const allFiles = this.getCachedFiles();
324
+ const lowerPartial = partial.toLowerCase();
325
+ const matched = allFiles.filter((f)=>f.toLowerCase().includes(lowerPartial)).sort((a, b)=>{
326
+ const aName = path.basename(a).toLowerCase();
327
+ const bName = path.basename(b).toLowerCase();
328
+ const aStarts = aName.startsWith(lowerPartial);
329
+ const bStarts = bName.startsWith(lowerPartial);
330
+ if (aStarts && !bStarts) return -1;
331
+ if (!aStarts && bStarts) return 1;
332
+ return a.length - b.length;
261
333
  });
262
- const ignore = [
263
- 'node_modules',
264
- '.git',
265
- 'dist',
266
- 'coverage',
267
- '.next',
268
- '__pycache__'
269
- ];
270
- return entries.filter((e)=>!ignore.includes(e.name)).filter((e)=>!e.name.startsWith('.') || prefix.startsWith('.')).filter((e)=>prefix === '' || e.name.toLowerCase().startsWith(prefix.toLowerCase())).map((e)=>{
271
- const relDir = dir === '.' ? '' : dir + '/';
272
- const isDir = e.isDirectory();
273
- return {
274
- text: '@' + relDir + e.name + (isDir ? '/' : ''),
275
- display: '@' + relDir + e.name + (isDir ? '/' : ''),
276
- description: isDir ? 'dir' : ''
277
- };
278
- }).slice(0, 20);
279
- } catch {
280
- return [];
334
+ return matched.slice(0, 20).map((f)=>({
335
+ text: '@' + f,
336
+ display: '@' + f,
337
+ description: 'file'
338
+ }));
281
339
  }
282
340
  }
283
341
  handleCancel() {
@@ -398,9 +456,12 @@ let ReplService = class ReplService {
398
456
  await this.projectCommands.cmdProject(args, this.smartInput);
399
457
  break;
400
458
  case 'project-deep':
401
- await this.projectCommands.cmdProject([
459
+ const deepResult = await this.projectCommands.cmdProject([
402
460
  'deep'
403
461
  ], this.smartInput);
462
+ if (typeof deepResult === 'string') {
463
+ return await this.handleMessage(deepResult);
464
+ }
404
465
  break;
405
466
  case 'kanban':
406
467
  this.kanbanServer.start();
@@ -641,6 +702,8 @@ let ReplService = class ReplService {
641
702
  this.abortController = null;
642
703
  this.isProcessing = false;
643
704
  this.spinnerTimer = null;
705
+ this.fileCache = null;
706
+ this.lastCacheTime = 0;
644
707
  }
645
708
  };
646
709
  ReplService = _ts_decorate([