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.
- package/dist/modules/mentions/services/mentions.service.js +3 -3
- package/dist/modules/mentions/services/mentions.service.js.map +1 -1
- package/dist/modules/permissions/services/prompt.service.js +17 -70
- package/dist/modules/permissions/services/prompt.service.js.map +1 -1
- package/dist/modules/repl/services/commands/project-commands.service.js +7 -9
- package/dist/modules/repl/services/commands/project-commands.service.js.map +1 -1
- package/dist/modules/repl/services/repl.service.js +99 -36
- package/dist/modules/repl/services/repl.service.js.map +1 -1
- package/dist/modules/repl/services/smart-input.js +2 -2
- package/dist/modules/repl/services/smart-input.js.map +1 -1
- package/dist/modules/tasks/services/plan-mode.service.js +11 -10
- package/dist/modules/tasks/services/plan-mode.service.js.map +1 -1
- package/dist/modules/tasks/services/task-management.service.js +19 -19
- package/dist/modules/tasks/services/task-management.service.js.map +1 -1
- package/dist/modules/tasks/services/task-tools.service.js +2 -2
- package/dist/modules/tasks/services/task-tools.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -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./-]+\/))
|
|
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
|
-
|
|
89
|
-
const raw =
|
|
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
|
|
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
|
-
|
|
64
|
-
|
|
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
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
80
|
+
return;
|
|
82
81
|
case 'edit':
|
|
83
82
|
await this.editContext();
|
|
84
|
-
|
|
83
|
+
return;
|
|
85
84
|
case 'help':
|
|
86
85
|
default:
|
|
87
86
|
this.printProjectHelp();
|
|
88
|
-
|
|
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
|
-
|
|
127
|
-
w((0, _theme.colorize)(
|
|
128
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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([
|