cast-code 1.0.9 → 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.
Files changed (30) hide show
  1. package/dist/modules/core/services/deep-agent.service.js +1 -1
  2. package/dist/modules/core/services/deep-agent.service.js.map +1 -1
  3. package/dist/modules/kanban/kanban.module.js +36 -0
  4. package/dist/modules/kanban/kanban.module.js.map +1 -0
  5. package/dist/modules/kanban/services/kanban-server.service.js +322 -0
  6. package/dist/modules/kanban/services/kanban-server.service.js.map +1 -0
  7. package/dist/modules/kanban/views/kanban-ui.js +858 -0
  8. package/dist/modules/kanban/views/kanban-ui.js.map +1 -0
  9. package/dist/modules/mentions/services/mentions.service.js +3 -3
  10. package/dist/modules/mentions/services/mentions.service.js.map +1 -1
  11. package/dist/modules/permissions/services/prompt.service.js +17 -70
  12. package/dist/modules/permissions/services/prompt.service.js.map +1 -1
  13. package/dist/modules/repl/repl.module.js +3 -1
  14. package/dist/modules/repl/repl.module.js.map +1 -1
  15. package/dist/modules/repl/services/commands/project-commands.service.js +7 -9
  16. package/dist/modules/repl/services/commands/project-commands.service.js.map +1 -1
  17. package/dist/modules/repl/services/repl.service.js +112 -38
  18. package/dist/modules/repl/services/repl.service.js.map +1 -1
  19. package/dist/modules/repl/services/smart-input.js +2 -2
  20. package/dist/modules/repl/services/smart-input.js.map +1 -1
  21. package/dist/modules/tasks/services/plan-executor.service.js +2 -2
  22. package/dist/modules/tasks/services/plan-executor.service.js.map +1 -1
  23. package/dist/modules/tasks/services/plan-mode.service.js +11 -10
  24. package/dist/modules/tasks/services/plan-mode.service.js.map +1 -1
  25. package/dist/modules/tasks/services/task-management.service.js +54 -21
  26. package/dist/modules/tasks/services/task-management.service.js.map +1 -1
  27. package/dist/modules/tasks/services/task-tools.service.js +2 -2
  28. package/dist/modules/tasks/services/task-tools.service.js.map +1 -1
  29. package/dist/modules/tasks/types/task.types.js.map +1 -1
  30. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/modules/kanban/views/kanban-ui.ts"],"sourcesContent":["export function getKanbanHtml(): string {\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>cast · kanban</title>\n<style>\n * { box-sizing: border-box; margin: 0; padding: 0; }\n\n :root {\n --bg: #0d1117;\n --surface: #161b22;\n --card: #21262d;\n --border: #30363d;\n --border-hover: #484f58;\n --text: #e6edf3;\n --muted: #7d8590;\n --cyan: #58a6ff;\n --green: #3fb950;\n --yellow: #d29922;\n --red: #f85149;\n --orange: #e3b341;\n --purple: #bc8cff;\n }\n\n body {\n background: var(--bg);\n color: var(--text);\n font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;\n font-size: 13px;\n height: 100vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n\n header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px;\n border-bottom: 1px solid var(--border);\n background: var(--surface);\n flex-shrink: 0;\n }\n\n .logo {\n font-weight: 700;\n font-size: 14px;\n color: var(--cyan);\n letter-spacing: 0.05em;\n }\n\n .logo span {\n color: var(--muted);\n font-weight: 400;\n }\n\n .live-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--green);\n box-shadow: 0 0 6px var(--green);\n animation: pulse 2s infinite;\n }\n\n .live-dot.disconnected {\n background: var(--red);\n box-shadow: 0 0 6px var(--red);\n animation: none;\n }\n\n @keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n }\n\n .header-right {\n margin-left: auto;\n display: flex;\n align-items: center;\n gap: 16px;\n }\n\n .btn-primary {\n background: var(--cyan);\n color: var(--bg);\n border: none;\n padding: 6px 12px;\n border-radius: 4px;\n font-size: 12px;\n font-weight: 700;\n cursor: pointer;\n transition: opacity 0.2s;\n }\n\n .btn-primary:hover {\n opacity: 0.9;\n }\n\n .btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .task-count {\n color: var(--muted);\n font-size: 12px;\n }\n\n .plan-badge {\n background: rgba(88, 166, 255, 0.1);\n border: 1px solid rgba(88, 166, 255, 0.3);\n color: var(--cyan);\n padding: 2px 8px;\n border-radius: 4px;\n font-size: 11px;\n }\n\n /* Modal */\n .modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.7);\n display: none;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n backdrop-filter: blur(2px);\n }\n\n .modal {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 8px;\n width: 100%;\n max-width: 450px;\n padding: 24px;\n box-shadow: 0 10px 25px rgba(0,0,0,0.5);\n }\n\n .modal-title {\n font-size: 16px;\n font-weight: 700;\n margin-bottom: 20px;\n color: var(--cyan);\n }\n\n .form-group {\n margin-bottom: 16px;\n }\n\n .form-group label {\n display: block;\n font-size: 11px;\n color: var(--muted);\n text-transform: uppercase;\n margin-bottom: 6px;\n font-weight: 600;\n }\n\n .form-group input, .form-group textarea {\n width: 100%;\n background: var(--bg);\n border: 1px solid var(--border);\n border-radius: 4px;\n color: var(--text);\n padding: 8px 12px;\n font-family: inherit;\n font-size: 13px;\n outline: none;\n }\n\n .form-group input:focus, .form-group textarea:focus {\n border-color: var(--cyan);\n }\n\n .modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: 12px;\n margin-top: 24px;\n }\n\n .btn-ghost {\n background: transparent;\n color: var(--muted);\n border: 1px solid var(--border);\n padding: 6px 12px;\n border-radius: 4px;\n font-size: 12px;\n cursor: pointer;\n }\n\n .btn-ghost:hover {\n border-color: var(--border-hover);\n color: var(--text);\n }\n\n .board {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n padding: 16px;\n flex: 1;\n overflow: hidden;\n min-height: 0;\n }\n\n .column {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 8px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n transition: background 0.2s;\n }\n\n .column.drag-over {\n background: rgba(88, 166, 255, 0.05);\n border-color: var(--cyan);\n }\n\n .column-header {\n padding: 10px 14px;\n border-bottom: 1px solid var(--border);\n display: flex;\n align-items: center;\n gap: 8px;\n flex-shrink: 0;\n }\n\n .column-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.08em;\n }\n\n .col-pending .column-label { color: var(--muted); }\n .col-inprogress .column-label { color: var(--orange); }\n .col-done .column-label { color: var(--green); }\n .col-failed .column-label { color: var(--red); }\n\n .col-inprogress { border-top: 2px solid var(--orange); }\n .col-done { border-top: 2px solid var(--green); }\n .col-failed { border-top: 2px solid var(--red); }\n .col-pending { border-top: 2px solid var(--border); }\n\n .column-count {\n margin-left: auto;\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 10px;\n padding: 1px 7px;\n font-size: 11px;\n color: var(--muted);\n min-width: 22px;\n text-align: center;\n }\n\n .cards {\n flex: 1;\n overflow-y: auto;\n padding: 10px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n min-height: 50px;\n }\n\n .cards::-webkit-scrollbar { width: 4px; }\n .cards::-webkit-scrollbar-track { background: transparent; }\n .cards::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }\n\n .card {\n background: var(--card);\n border: 1px solid var(--border);\n border-radius: 6px;\n padding: 10px 12px;\n cursor: grab;\n transition: border-color 0.15s, transform 0.15s;\n animation: cardIn 0.2s ease-out;\n position: relative;\n }\n\n .card:active {\n cursor: grabbing;\n }\n\n .card.dragging {\n opacity: 0.4;\n transform: scale(0.95);\n }\n\n @keyframes cardIn {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .card:hover {\n border-color: var(--border-hover);\n }\n\n .card:hover .card-actions {\n opacity: 1;\n }\n\n .card-actions {\n position: absolute;\n top: 8px;\n right: 8px;\n opacity: 0;\n transition: opacity 0.2s;\n }\n\n .btn-mini {\n background: var(--bg);\n border: 1px solid var(--border);\n color: var(--cyan);\n border-radius: 3px;\n padding: 2px 6px;\n font-size: 9px;\n font-weight: 700;\n cursor: pointer;\n text-transform: uppercase;\n }\n\n .btn-mini:hover {\n border-color: var(--cyan);\n }\n\n .btn-mini:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n .card.highlight {\n animation: highlight 0.6s ease-out;\n }\n\n @keyframes highlight {\n 0% { border-color: var(--cyan); box-shadow: 0 0 8px rgba(88, 166, 255, 0.3); }\n 100% { border-color: var(--border); box-shadow: none; }\n }\n\n .card-top {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n margin-bottom: 6px;\n padding-right: 40px;\n }\n\n .card-id {\n color: var(--muted);\n font-size: 10px;\n flex-shrink: 0;\n margin-top: 2px;\n }\n\n .card-subject {\n font-weight: 600;\n font-size: 12px;\n line-height: 1.4;\n flex: 1;\n word-break: break-word;\n }\n\n .card-description {\n color: var(--muted);\n font-size: 11px;\n line-height: 1.5;\n margin-bottom: 8px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n }\n\n .card-footer {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 5px;\n }\n\n .badge {\n padding: 2px 6px;\n border-radius: 3px;\n font-size: 10px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n .badge-pending { background: rgba(125, 133, 144, 0.15); color: var(--muted); }\n .badge-in_progress { background: rgba(227, 179, 65, 0.15); color: var(--orange); }\n .badge-completed { background: rgba(63, 185, 80, 0.15); color: var(--green); }\n .badge-failed { background: rgba(248, 81, 73, 0.15); color: var(--red); }\n .badge-blocked { background: rgba(210, 153, 34, 0.15); color: var(--yellow); }\n .badge-cancelled { background: rgba(125, 133, 144, 0.1); color: var(--muted); }\n\n .badge-agent {\n background: rgba(188, 140, 255, 0.12);\n color: var(--purple);\n border: 1px solid rgba(188, 140, 255, 0.2);\n font-weight: 400;\n text-transform: none;\n letter-spacing: 0;\n }\n\n .badge-dep {\n background: rgba(88, 166, 255, 0.08);\n color: rgba(88, 166, 255, 0.6);\n border: 1px solid rgba(88, 166, 255, 0.15);\n font-weight: 400;\n text-transform: none;\n letter-spacing: 0;\n }\n\n .spinner {\n display: inline-block;\n width: 10px;\n height: 10px;\n border: 1.5px solid rgba(227, 179, 65, 0.2);\n border-top-color: var(--orange);\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n flex-shrink: 0;\n }\n\n @keyframes spin {\n to { transform: rotate(360deg); }\n }\n\n .empty-state {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--border);\n font-size: 11px;\n padding: 20px;\n text-align: center;\n }\n\n .thinking-indicator {\n color: var(--purple);\n font-size: 11px;\n display: flex;\n align-items: center;\n gap: 6px;\n }\n</style>\n</head>\n<body>\n\n<header>\n <div class=\"logo\">cast <span>·</span> kanban</div>\n <div class=\"live-dot\" id=\"liveDot\"></div>\n <div id=\"header-right-container\" class=\"header-right\">\n <button class=\"btn-primary\" onclick=\"showModal()\">+ New Task</button>\n <span class=\"task-count\" id=\"taskCount\">0 tasks</span>\n <span class=\"plan-badge\" id=\"planBadge\" style=\"display:none\"></span>\n </div>\n</header>\n\n<div class=\"board\">\n <div class=\"column col-pending\" id=\"col-pending\" ondragover=\"handleDragOver(event)\" ondragleave=\"handleDragLeave(event)\" ondrop=\"handleDrop(event, 'pending')\">\n <div class=\"column-header\">\n <span class=\"column-label\">To-Do</span>\n <button id=\"btn-auto-planner\" class=\"btn-mini\" style=\"margin-left: 10px; border-color: var(--purple); color: var(--purple);\" onclick=\"runAutoPlanner()\">⚡ Run</button>\n <span class=\"column-count\" id=\"count-pending\">0</span>\n </div>\n <div class=\"cards\" id=\"cards-pending\"></div>\n </div>\n <div class=\"column col-inprogress\" id=\"col-inprogress\" ondragover=\"handleDragOver(event)\" ondragleave=\"handleDragLeave(event)\" ondrop=\"handleDrop(event, 'in_progress')\">\n <div class=\"column-header\">\n <span class=\"column-label\">In Progress</span>\n <span class=\"column-count\" id=\"count-inprogress\">0</span>\n </div>\n <div class=\"cards\" id=\"cards-inprogress\"></div>\n </div>\n <div class=\"column col-done\" id=\"col-done\" ondragover=\"handleDragOver(event)\" ondragleave=\"handleDragLeave(event)\" ondrop=\"handleDrop(event, 'completed')\">\n <div class=\"column-header\">\n <span class=\"column-label\">Done</span>\n <span class=\"column-count\" id=\"count-done\">0</span>\n </div>\n <div class=\"cards\" id=\"cards-done\"></div>\n </div>\n <div class=\"column col-failed\" id=\"col-failed\" ondragover=\"handleDragOver(event)\" ondragleave=\"handleDragLeave(event)\" ondrop=\"handleDrop(event, 'failed')\">\n <div class=\"column-header\">\n <span class=\"column-label\">Failed / Blocked</span>\n <span class=\"column-count\" id=\"count-failed\">0</span>\n </div>\n <div class=\"cards\" id=\"cards-failed\"></div>\n </div>\n</div>\n\n<div class=\"modal-overlay\" id=\"modalOverlay\">\n <div class=\"modal\">\n <div class=\"modal-title\">Create New Task</div>\n <div class=\"form-group\">\n <label>Subject</label>\n <input type=\"text\" id=\"taskSubject\" placeholder=\"What needs to be done?\">\n </div>\n <div class=\"form-group\">\n <label>Description (Optional)</label>\n <textarea id=\"taskDescription\" rows=\"3\" placeholder=\"Add more details...\"></textarea>\n </div>\n <div class=\"modal-actions\">\n <button class=\"btn-ghost\" onclick=\"hideModal()\">Cancel</button>\n <button class=\"btn-primary\" onclick=\"createTask()\">Create Task</button>\n </div>\n </div>\n</div>\n\n<script>\n const COL_MAP = {\n pending: 'pending',\n in_progress: 'inprogress',\n completed: 'done',\n failed: 'failed',\n blocked: 'failed',\n cancelled: 'failed',\n };\n\n let tasks = {};\n let sseRetryTimer = null;\n let isAutoPlanning = false;\n\n // Drag and Drop State\n let draggedTaskId = null;\n\n function handleDragStart(e, taskId) {\n draggedTaskId = taskId;\n e.target.classList.add('dragging');\n e.dataTransfer.setData('text/plain', taskId);\n e.dataTransfer.effectAllowed = 'move';\n }\n\n function handleDragEnd(e) {\n e.target.classList.remove('dragging');\n draggedTaskId = null;\n }\n\n function handleDragOver(e) {\n e.preventDefault();\n e.currentTarget.classList.add('drag-over');\n e.dataTransfer.dropEffect = 'move';\n }\n\n function handleDragLeave(e) {\n e.currentTarget.classList.remove('drag-over');\n }\n\n async function handleDrop(e, targetStatus) {\n e.preventDefault();\n e.currentTarget.classList.remove('drag-over');\n \n const taskId = e.dataTransfer.getData('text/plain');\n const task = tasks[taskId];\n \n if (!task || task.status === targetStatus) return;\n\n // Rules\n if (task.status === 'completed' && targetStatus === 'in_progress') {\n const reason = prompt(\\`Why are you redoing task \"\\${task.subject}\"?\\`);\n if (!reason) return;\n \n await updateTask(taskId, { \n status: targetStatus,\n metadata: { ...task.metadata, redoReason: reason, redoneAt: Date.now() }\n });\n } else {\n await updateTask(taskId, { status: targetStatus });\n }\n }\n\n async function runAutoPlanner() {\n if (isAutoPlanning) return;\n isAutoPlanning = true;\n renderHeaderRight();\n document.getElementById('btn-auto-planner').disabled = true;\n\n try {\n await fetch('/api/tasks/auto-execute', { method: 'POST' });\n } catch (err) {\n console.error('Failed to start auto-planner:', err);\n isAutoPlanning = false;\n renderHeaderRight();\n document.getElementById('btn-auto-planner').disabled = false;\n }\n }\n\n function renderHeaderRight() {\n const container = document.getElementById('header-right-container');\n const thinking = isAutoPlanning ? '<span class=\"thinking-indicator\"><div class=\"spinner\" style=\"border-top-color:var(--purple)\"></div> Auto-Planner thinking...</span>' : '';\n \n container.innerHTML = \\`\n \\${thinking}\n <button class=\"btn-primary\" onclick=\"showModal()\">+ New Task</button>\n <span class=\"task-count\" id=\"taskCount\">\\${Object.keys(tasks).length} tasks</span>\n <span class=\"plan-badge\" id=\"planBadge\" style=\"display:none\"></span>\n \\`;\n }\n\n function showModal() {\n document.getElementById('modalOverlay').style.display = 'flex';\n document.getElementById('taskSubject').focus();\n }\n\n function hideModal() {\n document.getElementById('modalOverlay').style.display = 'none';\n document.getElementById('taskSubject').value = '';\n document.getElementById('taskDescription').value = '';\n }\n\n async function createTask() {\n const subject = document.getElementById('taskSubject').value.trim();\n const description = document.getElementById('taskDescription').value.trim();\n\n if (!subject) return;\n\n try {\n const res = await fetch('/api/tasks', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ subject, description })\n });\n \n if (res.ok) {\n hideModal();\n }\n } catch (err) {\n console.error('Failed to create task:', err);\n }\n }\n\n async function updateTask(taskId, updates) {\n try {\n await fetch(\\`/api/tasks/\\${taskId}\\`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(updates)\n });\n } catch (err) {\n console.error('Failed to update task:', err);\n }\n }\n\n async function executeTask(taskId) {\n try {\n await fetch(\\`/api/tasks/\\${taskId}/execute\\`, { method: 'POST' });\n } catch (err) {\n console.error('Failed to execute task:', err);\n }\n }\n\n function col(status) {\n return COL_MAP[status] || 'pending';\n }\n\n function makeCard(task) {\n const colKey = col(task.status);\n const isInProgress = task.status === 'in_progress';\n const isPending = task.status === 'pending';\n\n const depBadges = task.dependencies.length > 0\n ? task.dependencies.map(d => '<span class=\"badge badge-dep\">↳ ' + d + '</span>').join('')\n : '';\n\n const agentBadge = task.assignedAgent\n ? '<span class=\"badge badge-agent\">⬡ ' + task.assignedAgent + '</span>'\n : '';\n\n const spinner = isInProgress ? '<div class=\"spinner\"></div>' : '';\n \n const actionBtn = isPending \n ? \\`<div class=\"card-actions\"><button class=\"btn-mini\" onclick=\"executeTask('\\${task.id}')\">Run</button></div>\\` \n : '';\n\n return \\`\n <div class=\"card\" \n id=\"card-\\${task.id}\" \n data-status=\"\\${task.status}\" \n draggable=\"true\" \n onsubmit=\"return false;\"\n ondragstart=\"handleDragStart(event, '\\${task.id}')\"\n ondragend=\"handleDragEnd(event)\">\n \\${actionBtn}\n <div class=\"card-top\">\n \\${spinner}\n <span class=\"card-id\">\\${task.id}</span>\n <span class=\"card-subject\">\\${escHtml(task.subject)}</span>\n </div>\n \\${task.description ? '<div class=\"card-description\">' + escHtml(task.description) + '</div>' : ''}\n <div class=\"card-footer\">\n <span class=\"badge badge-\\${task.status}\">\\${task.status.replace('_', ' ')}</span>\n \\${agentBadge}\n \\${depBadges}\n </div>\n </div>\n \\`;\n }\n\n function escHtml(str) {\n return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\"/g,'&quot;');\n }\n\n function renderAll() {\n const cols = { pending: [], inprogress: [], done: [], failed: [] };\n\n for (const task of Object.values(tasks)) {\n cols[col(task.status)].push(task);\n }\n\n for (const [key, list] of Object.entries(cols)) {\n const container = document.getElementById('cards-' + key);\n const count = document.getElementById('count-' + key);\n\n if (list.length === 0) {\n container.innerHTML = '<div class=\"empty-state\">—</div>';\n } else {\n container.innerHTML = list.map(makeCard).join('');\n }\n count.textContent = list.length;\n }\n\n renderHeaderRight();\n }\n\n function upsertTask(task) {\n const existed = !!tasks[task.id];\n tasks[task.id] = task;\n\n if (task.status === 'in_progress' || task.status === 'completed') {\n // If we get an update that is progress, stop showing auto-planner thinking\n if (isAutoPlanning) {\n isAutoPlanning = false;\n renderHeaderRight();\n document.getElementById('btn-auto-planner').disabled = false;\n }\n }\n\n if (existed) {\n const card = document.getElementById('card-' + task.id);\n const newColKey = col(task.status);\n\n if (card) {\n const currentContainer = card.parentElement;\n const targetContainer = document.getElementById('cards-' + newColKey);\n\n if (currentContainer !== targetContainer) {\n renderAll();\n } else {\n card.outerHTML = makeCard(task);\n const updated = document.getElementById('card-' + task.id);\n if (updated) {\n updated.classList.add('highlight');\n setTimeout(() => updated.classList.remove('highlight'), 700);\n }\n updateCounts();\n }\n } else {\n renderAll();\n }\n } else {\n renderAll();\n }\n }\n\n function updateCounts() {\n const cols = { pending: 0, inprogress: 0, done: 0, failed: 0 };\n for (const task of Object.values(tasks)) {\n cols[col(task.status)]++;\n }\n for (const [key, count] of Object.entries(cols)) {\n document.getElementById('count-' + key).textContent = count;\n }\n renderHeaderRight();\n }\n\n async function loadState() {\n try {\n const res = await fetch('/api/state');\n const data = await res.json();\n tasks = {};\n for (const t of data.tasks) tasks[t.id] = t;\n\n if (data.plans && data.plans.length > 0) {\n const plan = data.plans[data.plans.length - 1];\n const badge = document.getElementById('planBadge');\n badge.textContent = plan.title;\n badge.style.display = 'inline';\n }\n\n renderAll();\n } catch {}\n }\n\n function connectSSE() {\n const dot = document.getElementById('liveDot');\n const es = new EventSource('/api/events');\n\n es.onopen = () => {\n dot.classList.remove('disconnected');\n if (sseRetryTimer) { clearTimeout(sseRetryTimer); sseRetryTimer = null; }\n };\n\n es.addEventListener('task:created', e => {\n const task = JSON.parse(e.data);\n upsertTask(task);\n });\n\n es.addEventListener('task:updated', e => {\n const task = JSON.parse(e.data);\n upsertTask(task);\n });\n\n es.addEventListener('plan:created', e => {\n const plan = JSON.parse(e.data);\n const badge = document.getElementById('planBadge');\n badge.textContent = plan.title;\n badge.style.display = 'inline';\n });\n\n es.onerror = () => {\n dot.classList.add('disconnected');\n es.close();\n sseRetryTimer = setTimeout(connectSSE, 3000);\n };\n }\n\n loadState().then(connectSSE);\n</script>\n</body>\n</html>`;\n}\n"],"names":["getKanbanHtml"],"mappings":";;;;+BAAgBA;;;eAAAA;;;AAAT,SAASA;IACd,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA20BH,CAAC;AACR"}
@@ -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"}
@@ -26,6 +26,7 @@ const _mcpmodule = require("../mcp/mcp.module");
26
26
  const _projectmodule = require("../project/project.module");
27
27
  const _memorymodule = require("../memory/memory.module");
28
28
  const _config = require("../config");
29
+ const _kanbanmodule = require("../kanban/kanban.module");
29
30
  function _ts_decorate(decorators, target, key, desc) {
30
31
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
31
32
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -45,7 +46,8 @@ ReplModule = _ts_decorate([
45
46
  _skillsmodule.SkillsModule,
46
47
  _mcpmodule.McpModule,
47
48
  _projectmodule.ProjectModule,
48
- _memorymodule.MemoryModule
49
+ _memorymodule.MemoryModule,
50
+ _kanbanmodule.KanbanModule
49
51
  ],
50
52
  providers: [
51
53
  _replservice.ReplService,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/repl/repl.module.ts"],"sourcesContent":["import { Module } from '@nestjs/common';\nimport { ReplService } from './services/repl.service';\nimport { WelcomeScreenService } from './services/welcome-screen.service';\nimport { ReplCommandsService } from './services/commands/repl-commands.service';\nimport { GitCommandsService } from './services/commands/git-commands.service';\nimport { AgentCommandsService } from './services/commands/agent-commands.service';\nimport { McpCommandsService } from './services/commands/mcp-commands.service';\nimport { ConfigCommandsService } from '../config/services/config-commands.service';\nimport { ProjectCommandsService } from './services/commands/project-commands.service';\nimport { CoreModule } from '../core/core.module';\nimport { ToolsModule } from '../tools/tools.module';\nimport { GitModule } from '../git/git.module';\nimport { AgentsModule } from '../agents/agents.module';\nimport { SkillsModule } from '../skills/skills.module';\nimport { McpModule } from '../mcp/mcp.module';\nimport { ProjectModule } from '../project/project.module';\nimport { MemoryModule } from '../memory/memory.module';\nimport { ConfigModule } from '../config';\n\n@Module({\n imports: [ConfigModule, CoreModule, ToolsModule, GitModule, AgentsModule, SkillsModule, McpModule, ProjectModule, MemoryModule],\n providers: [\n ReplService,\n WelcomeScreenService,\n ReplCommandsService,\n GitCommandsService,\n AgentCommandsService,\n McpCommandsService,\n ConfigCommandsService,\n ProjectCommandsService,\n ],\n exports: [ReplService],\n})\nexport class ReplModule {}\n"],"names":["ReplModule","imports","ConfigModule","CoreModule","ToolsModule","GitModule","AgentsModule","SkillsModule","McpModule","ProjectModule","MemoryModule","providers","ReplService","WelcomeScreenService","ReplCommandsService","GitCommandsService","AgentCommandsService","McpCommandsService","ConfigCommandsService","ProjectCommandsService","exports"],"mappings":";;;;+BAiCaA;;;eAAAA;;;wBAjCU;6BACK;sCACS;qCACD;oCACD;sCACE;oCACF;uCACG;wCACC;4BACZ;6BACC;2BACF;8BACG;8BACA;2BACH;+BACI;8BACD;wBACA;;;;;;;AAgBtB,IAAA,AAAMA,aAAN,MAAMA;AAAY;;;QAbvBC,SAAS;YAACC,oBAAY;YAAEC,sBAAU;YAAEC,wBAAW;YAAEC,oBAAS;YAAEC,0BAAY;YAAEC,0BAAY;YAAEC,oBAAS;YAAEC,4BAAa;YAAEC,0BAAY;SAAC;QAC/HC,WAAW;YACTC,wBAAW;YACXC,0CAAoB;YACpBC,wCAAmB;YACnBC,sCAAkB;YAClBC,0CAAoB;YACpBC,sCAAkB;YAClBC,4CAAqB;YACrBC,8CAAsB;SACvB;QACDC,SAAS;YAACR,wBAAW;SAAC"}
1
+ {"version":3,"sources":["../../../src/modules/repl/repl.module.ts"],"sourcesContent":["import { Module } from '@nestjs/common';\nimport { ReplService } from './services/repl.service';\nimport { WelcomeScreenService } from './services/welcome-screen.service';\nimport { ReplCommandsService } from './services/commands/repl-commands.service';\nimport { GitCommandsService } from './services/commands/git-commands.service';\nimport { AgentCommandsService } from './services/commands/agent-commands.service';\nimport { McpCommandsService } from './services/commands/mcp-commands.service';\nimport { ConfigCommandsService } from '../config/services/config-commands.service';\nimport { ProjectCommandsService } from './services/commands/project-commands.service';\nimport { CoreModule } from '../core/core.module';\nimport { ToolsModule } from '../tools/tools.module';\nimport { GitModule } from '../git/git.module';\nimport { AgentsModule } from '../agents/agents.module';\nimport { SkillsModule } from '../skills/skills.module';\nimport { McpModule } from '../mcp/mcp.module';\nimport { ProjectModule } from '../project/project.module';\nimport { MemoryModule } from '../memory/memory.module';\nimport { ConfigModule } from '../config';\nimport { KanbanModule } from '../kanban/kanban.module';\n\n@Module({\n imports: [ConfigModule, CoreModule, ToolsModule, GitModule, AgentsModule, SkillsModule, McpModule, ProjectModule, MemoryModule, KanbanModule],\n providers: [\n ReplService,\n WelcomeScreenService,\n ReplCommandsService,\n GitCommandsService,\n AgentCommandsService,\n McpCommandsService,\n ConfigCommandsService,\n ProjectCommandsService,\n ],\n exports: [ReplService],\n})\nexport class ReplModule {}\n"],"names":["ReplModule","imports","ConfigModule","CoreModule","ToolsModule","GitModule","AgentsModule","SkillsModule","McpModule","ProjectModule","MemoryModule","KanbanModule","providers","ReplService","WelcomeScreenService","ReplCommandsService","GitCommandsService","AgentCommandsService","McpCommandsService","ConfigCommandsService","ProjectCommandsService","exports"],"mappings":";;;;+BAkCaA;;;eAAAA;;;wBAlCU;6BACK;sCACS;qCACD;oCACD;sCACE;oCACF;uCACG;wCACC;4BACZ;6BACC;2BACF;8BACG;8BACA;2BACH;+BACI;8BACD;wBACA;8BACA;;;;;;;AAgBtB,IAAA,AAAMA,aAAN,MAAMA;AAAY;;;QAbvBC,SAAS;YAACC,oBAAY;YAAEC,sBAAU;YAAEC,wBAAW;YAAEC,oBAAS;YAAEC,0BAAY;YAAEC,0BAAY;YAAEC,oBAAS;YAAEC,4BAAa;YAAEC,0BAAY;YAAEC,0BAAY;SAAC;QAC7IC,WAAW;YACTC,wBAAW;YACXC,0CAAoB;YACpBC,wCAAmB;YACnBC,sCAAkB;YAClBC,0CAAoB;YACpBC,sCAAkB;YAClBC,4CAAqB;YACrBC,8CAAsB;SACvB;QACDC,SAAS;YAACR,wBAAW;SAAC"}
@@ -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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"}