@sylphx/flow 0.2.1 → 0.2.3

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 (102) hide show
  1. package/assets/agents/coder.md +1 -1
  2. package/assets/agents/orchestrator.md +1 -1
  3. package/assets/agents/reviewer.md +1 -1
  4. package/assets/agents/writer.md +13 -13
  5. package/assets/slash-commands/context.md +112 -0
  6. package/dist/assets/agents/coder.md +32 -0
  7. package/dist/assets/agents/orchestrator.md +36 -0
  8. package/dist/assets/agents/reviewer.md +30 -0
  9. package/dist/assets/agents/writer.md +30 -0
  10. package/dist/assets/knowledge/data/sql.md +216 -0
  11. package/dist/assets/knowledge/guides/saas-template.md +85 -0
  12. package/dist/assets/knowledge/guides/system-prompt.md +344 -0
  13. package/dist/assets/knowledge/guides/tech-stack.md +92 -0
  14. package/dist/assets/knowledge/guides/ui-ux.md +44 -0
  15. package/dist/assets/knowledge/stacks/nextjs-app.md +165 -0
  16. package/dist/assets/knowledge/stacks/node-api.md +220 -0
  17. package/dist/assets/knowledge/stacks/react-app.md +232 -0
  18. package/dist/assets/knowledge/universal/deployment.md +109 -0
  19. package/dist/assets/knowledge/universal/performance.md +121 -0
  20. package/dist/assets/knowledge/universal/security.md +79 -0
  21. package/dist/assets/knowledge/universal/testing.md +111 -0
  22. package/dist/assets/output-styles/silent.md +23 -0
  23. package/dist/assets/rules/core.md +144 -0
  24. package/dist/assets/slash-commands/commit.md +23 -0
  25. package/dist/assets/slash-commands/context.md +112 -0
  26. package/dist/assets/slash-commands/explain.md +35 -0
  27. package/dist/assets/slash-commands/mep.md +63 -0
  28. package/dist/assets/slash-commands/review.md +39 -0
  29. package/dist/assets/slash-commands/test.md +30 -0
  30. package/dist/chunk-1rptg3yg.js +4 -0
  31. package/dist/chunk-1rptg3yg.js.map +10 -0
  32. package/dist/{chunk-124wqbdb.js → chunk-4fr8q0jy.js} +3 -3
  33. package/dist/{chunk-124wqbdb.js.map → chunk-4fr8q0jy.js.map} +1 -1
  34. package/dist/{chunk-f6y5vttn.js → chunk-5szm4n3x.js} +3 -3
  35. package/dist/{chunk-f6y5vttn.js.map → chunk-5szm4n3x.js.map} +1 -1
  36. package/dist/chunk-7nht27vs.js +4 -0
  37. package/dist/{chunk-g9t3me0w.js.map → chunk-7nht27vs.js.map} +2 -2
  38. package/dist/chunk-8krxe10w.js +3 -0
  39. package/dist/{chunk-e966bjm5.js.map → chunk-8krxe10w.js.map} +2 -2
  40. package/dist/{chunk-wpe7rw5c.js → chunk-8z1sf25t.js} +3 -3
  41. package/dist/{chunk-wpe7rw5c.js.map → chunk-8z1sf25t.js.map} +1 -1
  42. package/dist/chunk-9c2nr2fz.js +25 -0
  43. package/dist/chunk-9c2nr2fz.js.map +61 -0
  44. package/dist/{chunk-4p754rhd.js → chunk-asr22mbn.js} +2 -2
  45. package/dist/{chunk-4p754rhd.js.map → chunk-asr22mbn.js.map} +2 -2
  46. package/dist/chunk-bnxtqetr.js +23 -0
  47. package/dist/chunk-bnxtqetr.js.map +11 -0
  48. package/dist/chunk-cs1s5c3g.js +54 -0
  49. package/dist/chunk-cs1s5c3g.js.map +53 -0
  50. package/dist/chunk-cv1nhr27.js +2 -0
  51. package/dist/{chunk-hshjnpm0.js.map → chunk-cv1nhr27.js.map} +1 -1
  52. package/dist/chunk-d4hj6d4t.js +6 -0
  53. package/dist/chunk-d4hj6d4t.js.map +11 -0
  54. package/dist/chunk-f06ma45b.js +15 -0
  55. package/dist/chunk-f06ma45b.js.map +16 -0
  56. package/dist/chunk-fs3f7acb.js +4 -0
  57. package/dist/chunk-fs3f7acb.js.map +12 -0
  58. package/dist/{chunk-5r4afhzp.js → chunk-gh83x9ya.js} +3 -3
  59. package/dist/{chunk-5r4afhzp.js.map → chunk-gh83x9ya.js.map} +1 -1
  60. package/dist/{chunk-qa8b725g.js → chunk-gyq335sw.js} +6 -5
  61. package/dist/{chunk-qa8b725g.js.map → chunk-gyq335sw.js.map} +1 -1
  62. package/dist/{chunk-hs3nxzyz.js → chunk-hft1735c.js} +2 -2
  63. package/dist/{chunk-hs3nxzyz.js.map → chunk-hft1735c.js.map} +2 -2
  64. package/dist/chunk-hj6r7703.js +3 -0
  65. package/dist/{chunk-78bfvh46.js.map → chunk-hj6r7703.js.map} +2 -2
  66. package/dist/chunk-hxj4eapp.js +14 -0
  67. package/dist/chunk-hxj4eapp.js.map +20 -0
  68. package/dist/chunk-jgsq3xax.js +23 -0
  69. package/dist/chunk-jgsq3xax.js.map +132 -0
  70. package/dist/{chunk-646h52kd.js → chunk-m9nt0bj3.js} +3 -3
  71. package/dist/{chunk-646h52kd.js.map → chunk-m9nt0bj3.js.map} +1 -1
  72. package/dist/{chunk-bd11hvvz.js → chunk-ndah8mn9.js} +2 -2
  73. package/dist/{chunk-bd11hvvz.js.map → chunk-ndah8mn9.js.map} +1 -1
  74. package/dist/chunk-s6g21d1g.js +27 -0
  75. package/dist/{chunk-0h7sfwq3.js.map → chunk-s6g21d1g.js.map} +4 -5
  76. package/dist/{chunk-hshjnpm0.js → chunk-sxy6vp20.js} +2 -2
  77. package/dist/chunk-sxy6vp20.js.map +9 -0
  78. package/dist/chunk-vjf57v4h.js +4 -0
  79. package/dist/chunk-vjf57v4h.js.map +10 -0
  80. package/dist/{chunk-jxny6xft.js → chunk-w2vbmr93.js} +2 -2
  81. package/dist/{chunk-jxny6xft.js.map → chunk-w2vbmr93.js.map} +1 -1
  82. package/dist/chunk-wd9qbbe5.js +5 -0
  83. package/dist/chunk-wd9qbbe5.js.map +10 -0
  84. package/dist/chunk-wnaa55wn.js +108 -0
  85. package/dist/chunk-wnaa55wn.js.map +24 -0
  86. package/dist/chunk-wrx1n6q6.js +16 -0
  87. package/dist/chunk-wrx1n6q6.js.map +16 -0
  88. package/dist/chunk-xata5rw6.js +119 -0
  89. package/dist/{chunk-878q8xdr.js.map → chunk-xata5rw6.js.map} +7 -18
  90. package/dist/chunk-z2rtyk3d.js +7 -0
  91. package/dist/{chunk-ygdr4fw7.js.map → chunk-z2rtyk3d.js.map} +2 -2
  92. package/dist/index.js +446 -482
  93. package/dist/index.js.map +301 -202
  94. package/package.json +4 -1
  95. package/dist/chunk-0h7sfwq3.js +0 -27
  96. package/dist/chunk-78bfvh46.js +0 -3
  97. package/dist/chunk-878q8xdr.js +0 -86
  98. package/dist/chunk-e966bjm5.js +0 -3
  99. package/dist/chunk-fxwaa2mg.js +0 -4
  100. package/dist/chunk-fxwaa2mg.js.map +0 -10
  101. package/dist/chunk-g9t3me0w.js +0 -4
  102. package/dist/chunk-ygdr4fw7.js +0 -7
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/rule-loader.ts", "../src/core/rule-manager.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Rule Loader\n * Loads rule definitions from markdown files with front matter\n */\n\nimport { readFile, readdir, access } from 'node:fs/promises';\nimport { join, parse, relative } from 'node:path';\nimport { homedir } from 'node:os';\nimport matter from 'gray-matter';\nimport type { Rule, RuleMetadata } from '../types/rule.types.js';\n\n/**\n * Load a single rule from a markdown file\n */\nexport async function loadRuleFromFile(\n filePath: string,\n isBuiltin: boolean = false,\n ruleId?: string\n): Promise<Rule | null> {\n try {\n const fileContent = await readFile(filePath, 'utf-8');\n const { data, content } = matter(fileContent);\n\n // Validate front matter\n if (!data.name || typeof data.name !== 'string') {\n console.error(`Rule file ${filePath} missing required 'name' field`);\n return null;\n }\n\n const metadata: RuleMetadata = {\n name: data.name,\n description: data.description || '',\n enabled: data.enabled !== undefined ? Boolean(data.enabled) : true,\n };\n\n // Get rule ID from parameter or filename\n const id = ruleId || parse(filePath).name;\n\n return {\n id,\n metadata,\n content: content.trim(),\n isBuiltin,\n filePath,\n };\n } catch (error) {\n console.error(`Failed to load rule from ${filePath}:`, error);\n return null;\n }\n}\n\n/**\n * Load all rules from a directory (recursively)\n */\nexport async function loadRulesFromDirectory(dirPath: string, isBuiltin: boolean = false): Promise<Rule[]> {\n try {\n // Read directory recursively to support subdirectories\n const files = await readdir(dirPath, { recursive: true, withFileTypes: true });\n\n // Filter for .md files and calculate rule IDs from relative paths\n const ruleFiles = files\n .filter((f) => f.isFile() && f.name.endsWith('.md'))\n .map((f) => {\n const fullPath = join(f.parentPath || f.path, f.name);\n // Calculate relative path from dirPath and remove .md extension\n const relativePath = relative(dirPath, fullPath).replace(/\\.md$/, '');\n return { fullPath, ruleId: relativePath };\n });\n\n const rules = await Promise.all(\n ruleFiles.map(({ fullPath, ruleId }) => loadRuleFromFile(fullPath, isBuiltin, ruleId))\n );\n\n return rules.filter((rule): rule is Rule => rule !== null);\n } catch (error) {\n // Directory doesn't exist or can't be read\n return [];\n }\n}\n\n/**\n * Get system rules path (bundled with the app)\n */\nexport async function getSystemRulesPath(): Promise<string> {\n // Get the directory of the current module\n const currentDir = new URL('.', import.meta.url).pathname;\n\n // In production (dist), assets are at dist/assets/rules\n // In development (src), go up to project root: src/core -> project root\n const distPath = join(currentDir, '..', 'assets', 'rules');\n const devPath = join(currentDir, '..', '..', 'assets', 'rules');\n\n // Check which one exists (try dist first, then dev)\n try {\n await access(distPath);\n return distPath;\n } catch {\n return devPath;\n }\n}\n\n/**\n * Get all rule search paths\n */\nexport function getRuleSearchPaths(cwd: string): string[] {\n const globalPath = join(homedir(), '.sylphx-flow', 'rules');\n const projectPath = join(cwd, '.sylphx-flow', 'rules');\n\n return [globalPath, projectPath];\n}\n\n/**\n * Load all available rules from all sources\n */\nexport async function loadAllRules(cwd: string): Promise<Rule[]> {\n const systemPath = await getSystemRulesPath();\n const [globalPath, projectPath] = getRuleSearchPaths(cwd);\n\n const [systemRules, globalRules, projectRules] = await Promise.all([\n loadRulesFromDirectory(systemPath, true), // System rules are marked as builtin\n loadRulesFromDirectory(globalPath, false),\n loadRulesFromDirectory(projectPath, false),\n ]);\n\n // Priority: system < global < project\n // Use Map to deduplicate by ID (later entries override earlier ones)\n const ruleMap = new Map<string, Rule>();\n\n // Add system rules first (lowest priority)\n for (const rule of systemRules) {\n ruleMap.set(rule.id, rule);\n }\n\n // Add global rules (override system)\n for (const rule of globalRules) {\n ruleMap.set(rule.id, rule);\n }\n\n // Add project rules (override globals and system)\n for (const rule of projectRules) {\n ruleMap.set(rule.id, rule);\n }\n\n return Array.from(ruleMap.values());\n}\n",
6
+ "/**\n * Rule Manager\n * Manages rule state and operations\n */\n\nimport type { Rule } from '../types/rule.types.js';\nimport { loadAllRules } from './rule-loader.js';\n\n/**\n * Rule manager state\n */\ninterface RuleManagerState {\n rules: Map<string, Rule>;\n cwd: string;\n}\n\nlet state: RuleManagerState | null = null;\n\n/**\n * Get the app store (lazy import to avoid circular dependencies)\n */\nlet getAppStore: (() => any) | null = null;\n\n/**\n * Set the app store getter (called during initialization)\n */\nexport function setRuleAppStoreGetter(getter: () => any): void {\n getAppStore = getter;\n}\n\n/**\n * Initialize rule manager\n */\nexport async function initializeRuleManager(cwd: string): Promise<void> {\n const allRules = await loadAllRules(cwd);\n\n const ruleMap = new Map<string, Rule>();\n for (const rule of allRules) {\n ruleMap.set(rule.id, rule);\n }\n\n state = {\n rules: ruleMap,\n cwd,\n };\n\n // Initialize store with default enabled rules\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n const currentEnabledRules = store.getState().enabledRuleIds || [];\n\n // If no rules are enabled yet, enable all rules that have enabled: true in metadata\n if (currentEnabledRules.length === 0) {\n const defaultEnabledRules = allRules\n .filter((rule) => rule.metadata.enabled !== false)\n .map((rule) => rule.id);\n\n if (defaultEnabledRules.length > 0) {\n store.getState().setEnabledRuleIds(defaultEnabledRules);\n }\n }\n }\n }\n}\n\n/**\n * Get all available rules\n */\nexport function getAllRules(): Rule[] {\n if (!state) {\n return [];\n }\n return Array.from(state.rules.values());\n}\n\n/**\n * Get rule by ID\n */\nexport function getRuleById(id: string): Rule | null {\n if (!state) {\n return null;\n }\n return state.rules.get(id) || null;\n}\n\n/**\n * Get enabled rule IDs from store\n */\nexport function getEnabledRuleIds(): string[] {\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n return store.getState().enabledRuleIds || [];\n }\n }\n return [];\n}\n\n/**\n * Get enabled rules\n */\nexport function getEnabledRules(): Rule[] {\n if (!state) {\n return [];\n }\n\n const enabledIds = getEnabledRuleIds();\n return enabledIds\n .map((id) => state!.rules.get(id))\n .filter((rule): rule is Rule => rule !== null);\n}\n\n/**\n * Toggle a rule on/off\n */\nexport function toggleRule(ruleId: string): boolean {\n if (!state || !state.rules.has(ruleId)) {\n return false;\n }\n\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n const currentEnabled = store.getState().enabledRuleIds || [];\n\n if (currentEnabled.includes(ruleId)) {\n // Disable: remove from list\n store.getState().setEnabledRuleIds(currentEnabled.filter((id) => id !== ruleId));\n } else {\n // Enable: add to list\n store.getState().setEnabledRuleIds([...currentEnabled, ruleId]);\n }\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Enable a rule\n */\nexport function enableRule(ruleId: string): boolean {\n if (!state || !state.rules.has(ruleId)) {\n return false;\n }\n\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n const currentEnabled = store.getState().enabledRuleIds || [];\n\n if (!currentEnabled.includes(ruleId)) {\n store.getState().setEnabledRuleIds([...currentEnabled, ruleId]);\n }\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Disable a rule\n */\nexport function disableRule(ruleId: string): boolean {\n if (!state || !state.rules.has(ruleId)) {\n return false;\n }\n\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n const currentEnabled = store.getState().enabledRuleIds || [];\n store.getState().setEnabledRuleIds(currentEnabled.filter((id) => id !== ruleId));\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Reload rules from disk\n */\nexport async function reloadRules(): Promise<void> {\n if (!state) {\n return;\n }\n\n const cwd = state.cwd;\n const currentEnabled = getEnabledRuleIds();\n\n await initializeRuleManager(cwd);\n\n // Keep only enabled rules that still exist\n if (state && getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n const validEnabled = currentEnabled.filter((id) => state!.rules.has(id));\n store.getState().setEnabledRuleIds(validEnabled);\n }\n }\n}\n\n/**\n * Set enabled rules (replaces current enabled rules)\n */\nexport function setEnabledRules(ruleIds: string[]): boolean {\n if (!state) {\n return false;\n }\n\n // Validate all rule IDs exist\n const validRuleIds = ruleIds.filter((id) => state!.rules.has(id));\n\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n store.getState().setEnabledRuleIds(validRuleIds);\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Get combined content of all enabled rules\n */\nexport function getEnabledRulesContent(): string {\n const enabledRules = getEnabledRules();\n\n if (enabledRules.length === 0) {\n return '';\n }\n\n return enabledRules.map((rule) => rule.content).join('\\n\\n');\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "41BCE5C735DC020964756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,15 @@
1
+ import"./chunk-9c2nr2fz.js";import{M as r}from"./chunk-wrx1n6q6.js";import{V as L}from"./chunk-vjf57v4h.js";import"./chunk-8z1sf25t.js";import"./chunk-jgsq3xax.js";import"./chunk-m9nt0bj3.js";import{pb as K}from"./chunk-hxj4eapp.js";import"./chunk-cv1nhr27.js";import{Kb as V}from"./chunk-gyq335sw.js";import{Lb as s,Ob as e}from"./chunk-sxy6vp20.js";import{readFile as p,writeFile as u,mkdir as t}from"node:fs/promises";import{dirname as JJ}from"node:path";var VJ=K({description:"Read contents of a file from the filesystem",inputSchema:V.object({file_path:V.string().describe("Path to file"),offset:V.number().optional().describe("Start line number (1-based)"),limit:V.number().optional().describe("Number of lines to read")}),execute:async({file_path:J,offset:X,limit:Y})=>{try{let{stat:O}=await import("node:fs/promises"),E=await O(J);if(E.size>10485760)return{path:J,error:`File too large (${Math.round(E.size/1024/1024)}MB). Maximum size is 10MB. Use offset and limit parameters to read specific sections.`,encoding:"utf8"}}catch(O){return{path:J,error:`Failed to check file size: ${O instanceof Error?O.message:String(O)}`,encoding:"utf8"}}let Z=await p(J,"utf8");if(X!==void 0||Y!==void 0){let O=Z.split(`
2
+ `),E=X?X-1:0,H=Y?E+Y:O.length,U=O.slice(E,H);return{path:J,content:U.join(`
3
+ `),encoding:"utf8"}}return{path:J,content:Z,encoding:"utf8"}}}),XJ=K({description:"Write content to a file",inputSchema:V.object({file_path:V.string().describe("Path to file (overwrites if exists)"),content:V.string().describe("Content to write")}),execute:async({file_path:J,content:X})=>{let Y=JJ(J);await t(Y,{recursive:!0}),await u(J,X,"utf8");let $=J.split("/").pop()||"",Z=X.split(`
4
+ `);return{path:J,bytes:Buffer.byteLength(X,"utf8"),fileName:$,lineCount:Z.length,preview:Z.slice(0,5)}}}),YJ=K({description:"Perform exact string replacements in files",inputSchema:V.object({file_path:V.string().describe("Path to file"),old_string:V.string().describe("Text to replace (must be exact and unique unless replace_all=true)"),new_string:V.string().describe("Replacement text"),replace_all:V.boolean().default(!1).optional().describe("Replace all occurrences. If false, old_string must be unique")}),execute:async({file_path:J,old_string:X,new_string:Y,replace_all:$=!1})=>{if(X===Y)throw Error("old_string and new_string must be different");let Z=await p(J,"utf8");if(!Z.includes(X))throw Error(`old_string not found in file: ${J}`);if(!$){let M=Z.indexOf(X),Q=Z.lastIndexOf(X);if(M!==Q)throw Error("old_string appears multiple times in the file. Either provide more context to make it unique or use replace_all=true")}let O=Z.split(`
5
+ `),H=Z.substring(0,Z.indexOf(X)).split(`
6
+ `).length,U=2,W=Math.max(0,H-U-1),B=Math.min(O.length,H+U),v=$?Z.split(X).join(Y):Z.replace(X,Y);await u(J,v,"utf8");let G=$?Z.split(X).length-1:1,D=O.slice(W,B),j=[];for(let M=0;M<D.length;M++){let Q=W+M+1,A=D[M];if(Q===H){let w=X.split(`
7
+ `),P=Y.split(`
8
+ `);w.forEach((N)=>{j.push(`${Q.toString().padStart(6)} - ${N}`)}),P.forEach((N)=>{j.push(`${Q.toString().padStart(6)} + ${N}`)})}else j.push(`${Q.toString().padStart(6)} ${A}`)}return{path:J,replacements:G,old_length:X.length,new_length:Y.length,diff:j,old_string:X,new_string:Y}}}),b={read:VJ,write:XJ,edit:YJ};import{exec as ZJ}from"node:child_process";import{promisify as $J}from"node:util";var OJ=$J(ZJ),BJ=K({description:"Execute a bash command and return its output",inputSchema:V.object({command:V.string().describe("Bash command to execute"),cwd:V.string().optional().describe("Working directory"),timeout:V.number().default(30000).optional().describe("Timeout in milliseconds (foreground mode only)"),run_in_background:V.boolean().default(!1).optional().describe("Run in background. Returns bash_id for bash-output tool")}),execute:async({command:J,cwd:X,timeout:Y=30000,run_in_background:$=!1})=>{if($){let Z=L.spawn(J,X);return{bash_id:Z,command:J,mode:"background",message:`Started in background. Use bash-output tool with bash_id: ${Z}`}}try{let{stdout:Z,stderr:O}=await OJ(J,{cwd:X||process.cwd(),timeout:Y,maxBuffer:10485760});return{command:J,stdout:Z.trim(),stderr:O.trim(),exitCode:0}}catch(Z){if(Z.code!==void 0)return{command:J,stdout:Z.stdout?.trim()||"",stderr:Z.stderr?.trim()||"",exitCode:Z.code};throw Error(`Command execution failed: ${Z.message}`)}}}),EJ=K({description:"Get output from a background bash process",inputSchema:V.object({bash_id:V.string().describe("bash_id from background bash command"),filter:V.string().optional().describe("Regex to filter output lines")}),execute:async({bash_id:J,filter:X})=>{let Y=L.getOutput(J);if(!Y)throw Error(`Bash process not found: ${J}`);let{stdout:$,stderr:Z}=Y;if(X)try{let O=new RegExp(X);$=$.split(`
9
+ `).filter((E)=>O.test(E)).join(`
10
+ `),Z=Z.split(`
11
+ `).filter((E)=>O.test(E)).join(`
12
+ `)}catch(O){throw Error(`Invalid regex filter: ${O instanceof Error?O.message:String(O)}`)}return{bash_id:J,command:Y.command,stdout:$,stderr:Z,exitCode:Y.exitCode,isRunning:Y.isRunning,duration:Y.duration}}}),KJ=K({description:"Kill a background bash process",inputSchema:V.object({bash_id:V.string().describe("bash_id of process to kill")}),execute:async({bash_id:J})=>{if(!L.kill(J))throw Error(`Bash process not found: ${J}`);return{bash_id:J,status:"killed",message:`Sent termination signal to bash process ${J}`}}}),z={bash:BJ,"bash-output":EJ,"kill-bash":KJ};import{readdir as WJ,readFile as GJ,stat as HJ}from"node:fs/promises";import{join as vJ}from"node:path";function d(J,X){let Y=J.replace(/\./g,"\\.").replace(/\*\*/g,".*").replace(/\*/g,"[^/]*").replace(/\?/g,".");return new RegExp(`^${Y}$`).test(X)}async function g(J,X,Y,$=[]){if($.length>=Y)return $;try{let Z=await WJ(J,{withFileTypes:!0});for(let O of Z){if($.length>=Y)break;let E=vJ(J,O.name);if(O.isDirectory()&&["node_modules",".git","dist","build",".next"].includes(O.name))continue;if(O.isDirectory())await g(E,X,Y,$);else if(d(X,E)||d(X,O.name))$.push(E)}return $}catch(Z){return $}}var UJ=K({description:"Search for files matching a glob pattern",inputSchema:V.object({pattern:V.string().describe('Glob pattern: * (any except /), ** (any), ? (single). Examples: "*.ts", "src/**/*.tsx"'),path:V.string().optional().describe("Directory to search")}),execute:async({pattern:J,path:X})=>{let Y=X||process.cwd(),$=await g(Y,J,1000);return{pattern:J,directory:Y,files:$,count:$.length}}}),DJ=K({description:"Search for text content within files using regex patterns",inputSchema:V.object({pattern:V.string().describe("Regex pattern to search"),path:V.string().optional().describe("File or directory to search"),output_mode:V.enum(["content","files_with_matches","count"]).default("files_with_matches").optional().describe("content: show lines | files_with_matches: show paths | count: show counts"),type:V.string().optional().describe("File type: js, ts, py, rust, go, java, c, cpp, html, css, json, yaml, md"),glob:V.string().optional().describe('Glob filter: "*.js", "*.{ts,tsx}"'),"-i":V.boolean().optional().describe("Case insensitive"),"-n":V.boolean().optional().describe("Show line numbers (content mode only)"),"-A":V.number().optional().describe("Lines after match (content mode only)"),"-B":V.number().optional().describe("Lines before match (content mode only)"),"-C":V.number().optional().describe("Lines before and after match (content mode only)"),multiline:V.boolean().optional().describe("Multiline mode: . matches newlines"),head_limit:V.number().optional().describe("Limit output to first N entries")}),execute:async({pattern:J,path:X,output_mode:Y="files_with_matches",type:$,glob:Z,"-i":O=!1,"-n":E=!1,"-A":H=0,"-B":U=0,"-C":W,multiline:B=!1,head_limit:v})=>{let G=X||process.cwd(),D="**/*";if(Z)D=Z;else if($)D={js:"*.{js,jsx}",ts:"*.{ts,tsx}",py:"*.py",rust:"*.rs",go:"*.go",java:"*.java",c:"*.{c,h}",cpp:"*.{cpp,hpp,cc,cxx}",html:"*.{html,htm}",css:"*.{css,scss,sass}",json:"*.json",yaml:"*.{yaml,yml}",md:"*.md"}[$]||`*.${$}`;let j=await g(G,D,1000),M=W!==void 0?W:U||0,Q=W!==void 0?W:H||0,A="g";if(O)A+="i";if(B)A+="s";let w=new RegExp(J,A),P=[],N=new Set,k=0;for(let R of j)try{if((await HJ(R)).size>1048576)continue;let c=await GJ(R,"utf8");if(B){if(w.test(c))N.add(R),k++}else{let S=c.split(`
13
+ `);for(let C=0;C<S.length;C++)if(w.test(S[C])){if(N.add(R),k++,Y==="content"){let n=Math.max(0,C-M),a=Math.min(S.length-1,C+Q);for(let F=n;F<=a;F++){let o=E?`${F+1}: ${S[F]}`:S[F];P.push({file:R,line:F+1,content:o})}}}}}catch{continue}let h=(R)=>{return v?R.slice(0,v):R};if(Y==="content")return{pattern:J,directory:G,matches:h(P),count:P.length};else if(Y==="files_with_matches")return{pattern:J,directory:G,files:h(Array.from(N)),count:N.size};else return{pattern:J,directory:G,count:k}}}),m={glob:UJ,grep:DJ};var x=null,q=[],I=!1,y=null;function l(){if(y)y(q.length)}function _J(J){y=J}function fJ(){return q.length}function hJ(J){x=J}function cJ(){x=null,q=[],I=!1,y=null}async function i(){if(I||q.length===0||!x)return;I=!0;let J=q.shift();l(),console.error("[processAsk] Processing:",{id:J.id,question:J.question.substring(0,50),queueRemaining:q.length});try{let X=await x({type:"selection",questions:[{id:J.id,question:J.question,options:J.options,multiSelect:J.multiSelect}]}),Y=typeof X==="string"?X:X[J.id],$=Array.isArray(Y)?Y.join(", "):Y||"";console.error("[processAsk] Got answer:",$),J.resolve($)}catch(X){console.error("[processAsk] Error:",X),J.resolve("")}finally{if(I=!1,q.length>0)console.error("[processAsk] Processing next in queue..."),i()}}var RJ=K({description:"Ask the user a multiple choice question and wait for their selection",inputSchema:V.object({question:V.string().describe("Question to ask. Use only when you have specific options, not for free-form text"),options:V.array(V.object({label:V.string().describe("Display text"),value:V.string().optional().describe("Return value")})).min(2).describe("Options to choose from"),multiSelect:V.boolean().optional().describe("Allow multiple selections. Returns comma-separated. Call multiple times in same response to batch questions")}),execute:async({question:J,options:X,multiSelect:Y})=>{if(!x)throw Error("User input handler not available. This tool can only be used in interactive mode.");return new Promise(($)=>{let Z=`ask_${Date.now()}_${Math.random()}`;if(console.error("[ask execute] Adding to queue:",{id:Z,question:J.substring(0,50),optionsCount:X?.length||0,multiSelect:Y||!1,queueLength:q.length,isProcessing:I}),q.push({id:Z,question:J,options:X,multiSelect:Y,resolve:$}),l(),!I)console.error("[ask execute] Starting queue processing..."),i();else console.error("[ask execute] Already processing, will queue")})}}),_={ask:RJ};var uJ=(J)=>{switch(J){case"in_progress":return"▶";case"pending":return"○";case"completed":return"✓";case"removed":return"✗"}},dJ=(J)=>{switch(J){case"in_progress":return"#00FF88";case"pending":return"gray";case"completed":return"green";case"removed":return"red"}},lJ=(J)=>{return J.status==="in_progress"?J.activeForm:J.content},iJ=(J)=>{return J==="pending"||J==="completed"},rJ=(J)=>{return J==="in_progress"},nJ=(J)=>{return J==="completed"},T=(J,X,Y,$)=>{if(J==="added")return`+ ${X.content}`;if(J==="reordered"&&$)return`[${X.id}] reordered to ${$}`;if(J==="updated"&&Y&&Y!==X.status)return`[${X.id}] ${Y} → ${X.status}`;return`[${X.id}] updated`};var qJ=K({description:"Update task list to track work progress",inputSchema:V.object({todos:V.array(V.object({id:V.number().optional().describe("ID to update existing, omit to add new"),content:V.string().optional().describe('Imperative form: "Build feature"'),activeForm:V.string().optional().describe('Present continuous: "Building feature"'),status:V.enum(["pending","in_progress","completed","removed"]).optional().describe("pending | in_progress (keep ONE only) | completed | removed"),reorder:V.object({type:V.enum(["top","last","before","after"]).describe("top | last | before | after"),id:V.number().optional().describe("Target ID (for before/after)")}).optional().describe("Change order")})).describe('Add/update todos. Examples: [{ content: "Build login", activeForm: "Building login", status: "pending" }] | [{ id: 1, status: "completed" }]')}),execute:({todos:J})=>{let X=r.getState(),Y=X.currentSessionId;if(!Y)return{error:"No active session",summary:"Failed: no active session",changes:[],total:0};let $=X.sessions.find((B)=>B.id===Y);if(!$)return{error:"Session not found",summary:"Failed: session not found",changes:[],total:0};let Z=$.todos;X.updateTodos(Y,J);let E=X.sessions.find((B)=>B.id===Y)?.todos||[],H=J.filter((B)=>B.id===void 0),U=J.filter((B)=>B.id!==void 0),W=[];if(H.length>0)H.forEach((B)=>{let v=E.find((G)=>G.content===B.content);if(v)W.push(T("added",v))});if(U.length>0)U.forEach((B)=>{let v=Z.find((D)=>D.id===B.id),G=E.find((D)=>D.id===B.id);if(v&&G){if(B.status&&B.status!==v.status)W.push(T("updated",G,v.status));else if(B.reorder)W.push(T("reordered",G,void 0,B.reorder.type))}});return{summary:`${H.length} added, ${U.length} updated`,changes:W.length>0?W:["No changes"],total:E.filter((B)=>B.status!=="removed").length}}}),f={updateTodos:qJ};function MJ(){return{...b,...z,...m,..._,...f}}function OV(){return{filesystem:Object.keys(b),shell:Object.keys(z),search:Object.keys(m),interaction:Object.keys(_),todo:Object.keys(f)}}function BV(){return Object.keys(MJ())}export{XJ as writeFileTool,z as shellTools,hJ as setUserInputHandler,_J as setQueueUpdateCallback,m as searchTools,VJ as readFileTool,KJ as killBashTool,_ as interactionTools,DJ as grepTool,UJ as globTool,OV as getToolCategories,fJ as getQueueLength,BV as getAllToolNames,MJ as getAISDKTools,b as filesystemTools,BJ as executeBashTool,YJ as editFileTool,cJ as clearUserInputHandler,EJ as bashOutputTool,RJ as askUserSelectionTool};export{_J as A,hJ as B,cJ as C,uJ as D,dJ as E,lJ as F,iJ as G,rJ as H,nJ as I,MJ as J};
14
+
15
+ //# debugId=EE784603412EE20F64756E2164756E21
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/tools/filesystem.ts", "../src/tools/shell.ts", "../src/tools/search.ts", "../src/tools/interaction.ts", "../src/ui/utils/todo-formatters.ts", "../src/tools/todo.ts", "../src/tools/registry.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Filesystem Tools\n * Tools for reading and writing files\n */\n\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { tool } from 'ai';\nimport { z } from 'zod';\n\n/**\n * Read file tool with size limits to prevent crashes\n */\nexport const readFileTool = tool({\n description: 'Read contents of a file from the filesystem',\n inputSchema: z.object({\n file_path: z.string().describe('Path to file'),\n offset: z\n .number()\n .optional()\n .describe('Start line number (1-based)'),\n limit: z\n .number()\n .optional()\n .describe('Number of lines to read'),\n }),\n execute: async ({ file_path, offset, limit }) => {\n // Check file size before reading to prevent memory exhaustion\n const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit\n try {\n const { stat } = await import('node:fs/promises');\n const stats = await stat(file_path);\n\n if (stats.size > MAX_FILE_SIZE) {\n return {\n path: file_path,\n error: `File too large (${Math.round(stats.size / 1024 / 1024)}MB). Maximum size is ${MAX_FILE_SIZE / 1024 / 1024}MB. Use offset and limit parameters to read specific sections.`,\n encoding: 'utf8',\n };\n }\n } catch (error) {\n return {\n path: file_path,\n error: `Failed to check file size: ${error instanceof Error ? error.message : String(error)}`,\n encoding: 'utf8',\n };\n }\n\n const content = await readFile(file_path, 'utf8');\n\n // Apply line filtering if offset/limit specified\n if (offset !== undefined || limit !== undefined) {\n const lines = content.split('\\n');\n const start = offset ? offset - 1 : 0; // Convert to 0-based index\n const end = limit ? start + limit : lines.length;\n const filteredLines = lines.slice(start, end);\n\n return {\n path: file_path,\n content: filteredLines.join('\\n'),\n encoding: 'utf8',\n };\n }\n\n return {\n path: file_path,\n content,\n encoding: 'utf8',\n };\n },\n});\n\n/**\n * Write file tool\n */\nexport const writeFileTool = tool({\n description: 'Write content to a file',\n inputSchema: z.object({\n file_path: z.string().describe('Path to file (overwrites if exists)'),\n content: z.string().describe('Content to write'),\n }),\n execute: async ({ file_path, content }) => {\n // Create parent directories if they don't exist\n const dir = dirname(file_path);\n await mkdir(dir, { recursive: true });\n\n await writeFile(file_path, content, 'utf8');\n\n // Get file name and line preview\n const fileName = file_path.split('/').pop() || '';\n const lines = content.split('\\n');\n\n return {\n path: file_path,\n bytes: Buffer.byteLength(content, 'utf8'),\n fileName,\n lineCount: lines.length,\n preview: lines.slice(0, 5), // First 5 lines for preview\n };\n },\n});\n\n/**\n * Edit file tool\n */\nexport const editFileTool = tool({\n description: 'Perform exact string replacements in files',\n inputSchema: z.object({\n file_path: z.string().describe('Path to file'),\n old_string: z.string().describe('Text to replace (must be exact and unique unless replace_all=true)'),\n new_string: z.string().describe('Replacement text'),\n replace_all: z\n .boolean()\n .default(false)\n .optional()\n .describe('Replace all occurrences. If false, old_string must be unique'),\n }),\n execute: async ({ file_path, old_string, new_string, replace_all = false }) => {\n // Validate strings are different\n if (old_string === new_string) {\n throw new Error('old_string and new_string must be different');\n }\n\n // Read file\n const content = await readFile(file_path, 'utf8');\n\n // Check if old_string exists\n if (!content.includes(old_string)) {\n throw new Error(`old_string not found in file: ${file_path}`);\n }\n\n // Check for multiple occurrences if not replace_all\n if (!replace_all) {\n const firstIndex = content.indexOf(old_string);\n const lastIndex = content.lastIndexOf(old_string);\n if (firstIndex !== lastIndex) {\n throw new Error(\n 'old_string appears multiple times in the file. Either provide more context to make it unique or use replace_all=true'\n );\n }\n }\n\n // Find line number where replacement occurs\n const lines = content.split('\\n');\n const beforeContent = content.substring(0, content.indexOf(old_string));\n const lineNumber = beforeContent.split('\\n').length;\n\n // Get context lines (few lines before and after)\n const contextSize = 2;\n const startLine = Math.max(0, lineNumber - contextSize - 1);\n const endLine = Math.min(lines.length, lineNumber + contextSize);\n\n // Perform replacement\n const newContent = replace_all\n ? content.split(old_string).join(new_string)\n : content.replace(old_string, new_string);\n\n // Write back\n await writeFile(file_path, newContent, 'utf8');\n\n // Count replacements\n const occurrences = replace_all\n ? content.split(old_string).length - 1\n : 1;\n\n // Generate diff lines for display\n const contextLines = lines.slice(startLine, endLine);\n const diffLines: string[] = [];\n\n for (let i = 0; i < contextLines.length; i++) {\n const currentLineNum = startLine + i + 1;\n const line = contextLines[i];\n\n if (currentLineNum === lineNumber) {\n // This is the changed line\n const oldLines = old_string.split('\\n');\n const newLines = new_string.split('\\n');\n\n // Show removed lines\n oldLines.forEach((oldLine) => {\n diffLines.push(`${currentLineNum.toString().padStart(6)} - ${oldLine}`);\n });\n\n // Show added lines\n newLines.forEach((newLine) => {\n diffLines.push(`${currentLineNum.toString().padStart(6)} + ${newLine}`);\n });\n } else {\n // Context line\n diffLines.push(`${currentLineNum.toString().padStart(6)} ${line}`);\n }\n }\n\n return {\n path: file_path,\n replacements: occurrences,\n old_length: old_string.length,\n new_length: new_string.length,\n diff: diffLines,\n old_string,\n new_string,\n };\n },\n});\n\n/**\n * All filesystem tools\n */\nexport const filesystemTools = {\n read: readFileTool,\n write: writeFileTool,\n edit: editFileTool,\n};\n",
6
+ "/**\n * Shell Tools\n * Tools for executing shell commands\n */\n\nimport { exec } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { bashManager } from './bash-manager.js';\n\nconst execAsync = promisify(exec);\n\n/**\n * Execute bash command tool\n */\nexport const executeBashTool = tool({\n description: 'Execute a bash command and return its output',\n inputSchema: z.object({\n command: z.string().describe('Bash command to execute'),\n cwd: z.string().optional().describe('Working directory'),\n timeout: z\n .number()\n .default(30000)\n .optional()\n .describe('Timeout in milliseconds (foreground mode only)'),\n run_in_background: z\n .boolean()\n .default(false)\n .optional()\n .describe('Run in background. Returns bash_id for bash-output tool'),\n }),\n execute: async ({ command, cwd, timeout = 30000, run_in_background = false }) => {\n // Background mode - spawn and return immediately\n if (run_in_background) {\n const bashId = bashManager.spawn(command, cwd);\n return {\n bash_id: bashId,\n command,\n mode: 'background',\n message: `Started in background. Use bash-output tool with bash_id: ${bashId}`,\n };\n }\n\n // Foreground mode - wait for completion\n try {\n const { stdout, stderr } = await execAsync(command, {\n cwd: cwd || process.cwd(),\n timeout,\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n });\n\n return {\n command,\n stdout: stdout.trim(),\n stderr: stderr.trim(),\n exitCode: 0,\n };\n } catch (error: any) {\n // exec throws error on non-zero exit code\n if (error.code !== undefined) {\n return {\n command,\n stdout: error.stdout?.trim() || '',\n stderr: error.stderr?.trim() || '',\n exitCode: error.code,\n };\n }\n\n throw new Error(`Command execution failed: ${error.message}`);\n }\n },\n});\n\n/**\n * Get output from background bash process\n */\nexport const bashOutputTool = tool({\n description: 'Get output from a background bash process',\n inputSchema: z.object({\n bash_id: z.string().describe('bash_id from background bash command'),\n filter: z.string().optional().describe('Regex to filter output lines'),\n }),\n execute: async ({ bash_id, filter }) => {\n const output = bashManager.getOutput(bash_id);\n\n if (!output) {\n throw new Error(`Bash process not found: ${bash_id}`);\n }\n\n let stdout = output.stdout;\n let stderr = output.stderr;\n\n // Apply filter if provided\n if (filter) {\n try {\n const regex = new RegExp(filter);\n stdout = stdout.split('\\n').filter(line => regex.test(line)).join('\\n');\n stderr = stderr.split('\\n').filter(line => regex.test(line)).join('\\n');\n } catch (error) {\n throw new Error(`Invalid regex filter: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n return {\n bash_id,\n command: output.command,\n stdout,\n stderr,\n exitCode: output.exitCode,\n isRunning: output.isRunning,\n duration: output.duration,\n };\n },\n});\n\n/**\n * Kill a background bash process\n */\nexport const killBashTool = tool({\n description: 'Kill a background bash process',\n inputSchema: z.object({\n bash_id: z.string().describe('bash_id of process to kill'),\n }),\n execute: async ({ bash_id }) => {\n const success = bashManager.kill(bash_id);\n\n if (!success) {\n throw new Error(`Bash process not found: ${bash_id}`);\n }\n\n return {\n bash_id,\n status: 'killed',\n message: `Sent termination signal to bash process ${bash_id}`,\n };\n },\n});\n\n/**\n * All shell tools\n */\nexport const shellTools = {\n bash: executeBashTool,\n 'bash-output': bashOutputTool,\n 'kill-bash': killBashTool,\n};\n",
7
+ "/**\n * Search Tools\n * Tools for searching files and content\n */\n\nimport { readdir, readFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { tool } from 'ai';\nimport { z } from 'zod';\n\n/**\n * Match a glob pattern\n */\nfunction matchGlob(pattern: string, path: string): boolean {\n // Simple glob matching - supports *, **, and ?\n const regexPattern = pattern\n .replace(/\\./g, '\\\\.')\n .replace(/\\*\\*/g, '.*')\n .replace(/\\*/g, '[^/]*')\n .replace(/\\?/g, '.');\n\n const regex = new RegExp(`^${regexPattern}$`);\n return regex.test(path);\n}\n\n/**\n * Recursively search files matching pattern\n */\nasync function searchFiles(\n dir: string,\n pattern: string,\n maxResults: number,\n results: string[] = []\n): Promise<string[]> {\n if (results.length >= maxResults) return results;\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (results.length >= maxResults) break;\n\n const fullPath = join(dir, entry.name);\n\n // Skip common directories\n if (\n entry.isDirectory() &&\n ['node_modules', '.git', 'dist', 'build', '.next'].includes(entry.name)\n ) {\n continue;\n }\n\n if (entry.isDirectory()) {\n await searchFiles(fullPath, pattern, maxResults, results);\n } else if (matchGlob(pattern, fullPath) || matchGlob(pattern, entry.name)) {\n results.push(fullPath);\n }\n }\n\n return results;\n } catch (error) {\n // Skip directories we can't read\n return results;\n }\n}\n\n/**\n * Glob file search tool\n */\nexport const globTool = tool({\n description: 'Search for files matching a glob pattern',\n inputSchema: z.object({\n pattern: z.string().describe('Glob pattern: * (any except /), ** (any), ? (single). Examples: \"*.ts\", \"src/**/*.tsx\"'),\n path: z\n .string()\n .optional()\n .describe('Directory to search'),\n }),\n execute: async ({ pattern, path }) => {\n const searchDir = path || process.cwd();\n const results = await searchFiles(searchDir, pattern, 1000); // Internal limit of 1000\n\n return {\n pattern,\n directory: searchDir,\n files: results,\n count: results.length,\n };\n },\n});\n\n/**\n * Grep content search tool\n */\nexport const grepTool = tool({\n description: 'Search for text content within files using regex patterns',\n inputSchema: z.object({\n pattern: z.string().describe('Regex pattern to search'),\n path: z.string().optional().describe('File or directory to search'),\n output_mode: z\n .enum(['content', 'files_with_matches', 'count'])\n .default('files_with_matches')\n .optional()\n .describe('content: show lines | files_with_matches: show paths | count: show counts'),\n type: z.string().optional().describe('File type: js, ts, py, rust, go, java, c, cpp, html, css, json, yaml, md'),\n glob: z.string().optional().describe('Glob filter: \"*.js\", \"*.{ts,tsx}\"'),\n '-i': z.boolean().optional().describe('Case insensitive'),\n '-n': z.boolean().optional().describe('Show line numbers (content mode only)'),\n '-A': z.number().optional().describe('Lines after match (content mode only)'),\n '-B': z.number().optional().describe('Lines before match (content mode only)'),\n '-C': z.number().optional().describe('Lines before and after match (content mode only)'),\n multiline: z.boolean().optional().describe('Multiline mode: . matches newlines'),\n head_limit: z.number().optional().describe('Limit output to first N entries'),\n }),\n execute: async ({\n pattern,\n path,\n output_mode = 'files_with_matches',\n type,\n glob: globPattern,\n '-i': caseInsensitive = false,\n '-n': showLineNumbers = false,\n '-A': afterContext = 0,\n '-B': beforeContext = 0,\n '-C': aroundContext,\n multiline = false,\n head_limit,\n }) => {\n const searchDir = path || process.cwd();\n\n // Determine file pattern based on type or glob\n let filePattern = '**/*';\n if (globPattern) {\n filePattern = globPattern;\n } else if (type) {\n // Map common file types to extensions\n const typeMap: Record<string, string> = {\n js: '*.{js,jsx}',\n ts: '*.{ts,tsx}',\n py: '*.py',\n rust: '*.rs',\n go: '*.go',\n java: '*.java',\n c: '*.{c,h}',\n cpp: '*.{cpp,hpp,cc,cxx}',\n html: '*.{html,htm}',\n css: '*.{css,scss,sass}',\n json: '*.json',\n yaml: '*.{yaml,yml}',\n md: '*.md',\n };\n filePattern = typeMap[type] || `*.${type}`;\n }\n\n const files = await searchFiles(searchDir, filePattern, 1000);\n\n // Determine context lines\n const before = aroundContext !== undefined ? aroundContext : beforeContext || 0;\n const after = aroundContext !== undefined ? aroundContext : afterContext || 0;\n\n // Build regex flags\n let regexFlags = 'g';\n if (caseInsensitive) regexFlags += 'i';\n if (multiline) regexFlags += 's'; // 's' flag makes . match newlines\n\n const regex = new RegExp(pattern, regexFlags);\n\n const matches: Array<{ file: string; line: number; content: string }> = [];\n const filesWithMatches = new Set<string>();\n let matchCount = 0;\n\n for (const file of files) {\n try {\n const stats = await stat(file);\n if (stats.size > 1024 * 1024) continue; // Skip files > 1MB\n\n const content = await readFile(file, 'utf8');\n\n if (multiline) {\n // Multiline matching - check if file contains pattern\n if (regex.test(content)) {\n filesWithMatches.add(file);\n matchCount++;\n }\n } else {\n // Line-by-line matching\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n if (regex.test(lines[i])) {\n filesWithMatches.add(file);\n matchCount++;\n\n if (output_mode === 'content') {\n // Collect context lines\n const startLine = Math.max(0, i - before);\n const endLine = Math.min(lines.length - 1, i + after);\n\n for (let j = startLine; j <= endLine; j++) {\n const lineContent = showLineNumbers\n ? `${j + 1}: ${lines[j]}`\n : lines[j];\n\n matches.push({\n file,\n line: j + 1,\n content: lineContent,\n });\n }\n }\n }\n }\n }\n } catch {\n // Skip files we can't read\n continue;\n }\n }\n\n // Apply head_limit\n const applyLimit = <T>(arr: T[]): T[] => {\n return head_limit ? arr.slice(0, head_limit) : arr;\n };\n\n // Return based on output mode\n if (output_mode === 'content') {\n return {\n pattern,\n directory: searchDir,\n matches: applyLimit(matches),\n count: matches.length,\n };\n } else if (output_mode === 'files_with_matches') {\n return {\n pattern,\n directory: searchDir,\n files: applyLimit(Array.from(filesWithMatches)),\n count: filesWithMatches.size,\n };\n } else {\n // count mode\n return {\n pattern,\n directory: searchDir,\n count: matchCount,\n };\n }\n },\n});\n\n/**\n * All search tools\n */\nexport const searchTools = {\n glob: globTool,\n grep: grepTool,\n};\n",
8
+ "/**\n * User Interaction Tools\n * Tools for the AI to ask questions and get user input\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport type { Question } from '../ui/commands/types.js';\n\nexport interface SelectOption {\n label: string;\n value?: string;\n}\n\n/**\n * User input request - matches WaitForInputOptions from command system\n * This allows the ask tool to use the same selection UI as commands\n */\nexport type UserInputRequest = {\n type: 'selection';\n questions: Question[];\n};\n\n/**\n * Global user input request handler\n * This will be set by the Chat component to handle user input requests\n * Returns: string for single question, Record<questionId, answer | answer[]> for multiple questions\n * - Single-select: answer is string\n * - Multi-select: answer is string[]\n */\nlet userInputHandler: ((request: UserInputRequest) => Promise<string | Record<string, string | string[]>>) | null = null;\n\n/**\n * Ask call queue\n */\ninterface AskCall {\n id: string;\n question: string;\n options: SelectOption[];\n multiSelect?: boolean;\n resolve: (answer: string) => void;\n}\n\nlet askQueue: AskCall[] = [];\nlet isProcessingAsk = false;\nlet queueUpdateCallback: ((count: number) => void) | null = null;\n\n/**\n * Notify queue update\n */\nfunction notifyQueueUpdate() {\n if (queueUpdateCallback) {\n queueUpdateCallback(askQueue.length);\n }\n}\n\n/**\n * Set queue update callback\n * Called by Chat component to receive queue length updates\n */\nexport function setQueueUpdateCallback(callback: (count: number) => void) {\n queueUpdateCallback = callback;\n}\n\n/**\n * Get current queue length\n */\nexport function getQueueLength() {\n return askQueue.length;\n}\n\n/**\n * Set the user input handler\n * Called by the Chat component to register the handler\n */\nexport function setUserInputHandler(handler: (request: UserInputRequest) => Promise<string | Record<string, string | string[]>>) {\n userInputHandler = handler;\n}\n\n/**\n * Clear the user input handler\n */\nexport function clearUserInputHandler() {\n userInputHandler = null;\n askQueue = [];\n isProcessingAsk = false;\n queueUpdateCallback = null;\n}\n\n/**\n * Process next ask in queue\n */\nasync function processNextAsk() {\n // If already processing or queue empty, do nothing\n if (isProcessingAsk || askQueue.length === 0 || !userInputHandler) {\n return;\n }\n\n isProcessingAsk = true;\n const ask = askQueue.shift()!; // Take first from queue\n notifyQueueUpdate(); // Notify queue changed\n\n console.error('[processAsk] Processing:', {\n id: ask.id,\n question: ask.question.substring(0, 50),\n queueRemaining: askQueue.length,\n });\n\n try {\n // Show single question to user\n const result = await userInputHandler({\n type: 'selection',\n questions: [{\n id: ask.id,\n question: ask.question,\n options: ask.options,\n multiSelect: ask.multiSelect,\n }],\n });\n\n // Extract answer (handle both string and string[] for multi-select)\n const rawAnswer = typeof result === 'string' ? result : result[ask.id];\n const answer = Array.isArray(rawAnswer) ? rawAnswer.join(', ') : (rawAnswer || '');\n console.error('[processAsk] Got answer:', answer);\n\n // Resolve this ask's promise\n ask.resolve(answer);\n } catch (error) {\n console.error('[processAsk] Error:', error);\n ask.resolve(''); // Resolve with empty on error\n } finally {\n isProcessingAsk = false;\n\n // Process next ask in queue if any\n if (askQueue.length > 0) {\n console.error('[processAsk] Processing next in queue...');\n processNextAsk();\n }\n }\n}\n\n/**\n * Ask user a multiple choice question\n */\nexport const askUserSelectionTool = tool({\n description: 'Ask the user a multiple choice question and wait for their selection',\n inputSchema: z.object({\n question: z.string().describe('Question to ask. Use only when you have specific options, not for free-form text'),\n options: z.array(z.object({\n label: z.string().describe('Display text'),\n value: z.string().optional().describe('Return value'),\n })).min(2).describe('Options to choose from'),\n multiSelect: z.boolean().optional().describe('Allow multiple selections. Returns comma-separated. Call multiple times in same response to batch questions'),\n }),\n execute: async ({ question, options, multiSelect }) => {\n if (!userInputHandler) {\n throw new Error('User input handler not available. This tool can only be used in interactive mode.');\n }\n\n // Create a promise that will be resolved when this ask is processed\n return new Promise<string>((resolve) => {\n const callId = `ask_${Date.now()}_${Math.random()}`;\n\n console.error('[ask execute] Adding to queue:', {\n id: callId,\n question: question.substring(0, 50),\n optionsCount: options?.length || 0,\n multiSelect: multiSelect || false,\n queueLength: askQueue.length,\n isProcessing: isProcessingAsk,\n });\n\n // Add to queue\n askQueue.push({\n id: callId,\n question,\n options,\n multiSelect,\n resolve,\n });\n\n // Notify queue changed\n notifyQueueUpdate();\n\n // Start processing if not already processing\n if (!isProcessingAsk) {\n console.error('[ask execute] Starting queue processing...');\n processNextAsk();\n } else {\n console.error('[ask execute] Already processing, will queue');\n }\n });\n },\n});\n\n/**\n * Export all interaction tools\n */\nexport const interactionTools = {\n ask: askUserSelectionTool,\n};\n",
9
+ "/**\n * Todo Formatters\n * Centralized todo display logic - single source of truth\n */\n\nimport type { Todo } from '../../types/todo.types.js';\n\n/**\n * Get icon for todo status\n */\nexport const getTodoIcon = (status: Todo['status']): string => {\n switch (status) {\n case 'in_progress':\n return '▶';\n case 'pending':\n return '○';\n case 'completed':\n return '✓';\n case 'removed':\n return '✗';\n }\n};\n\n/**\n * Get color for todo status\n */\nexport const getTodoColor = (status: Todo['status']): string => {\n switch (status) {\n case 'in_progress':\n return '#00FF88';\n case 'pending':\n return 'gray';\n case 'completed':\n return 'green';\n case 'removed':\n return 'red';\n }\n};\n\n/**\n * Get display text for todo (activeForm for in_progress, content otherwise)\n */\nexport const getTodoDisplayText = (todo: Todo): string => {\n return todo.status === 'in_progress' ? todo.activeForm : todo.content;\n};\n\n/**\n * Check if todo text should be dimmed\n */\nexport const isTodoDimmed = (status: Todo['status']): boolean => {\n return status === 'pending' || status === 'completed';\n};\n\n/**\n * Check if todo text should be bold\n */\nexport const isTodoBold = (status: Todo['status']): boolean => {\n return status === 'in_progress';\n};\n\n/**\n * Check if todo text should have strikethrough\n */\nexport const isTodoStrikethrough = (status: Todo['status']): boolean => {\n return status === 'completed';\n};\n\n/**\n * Format todo for tool result display\n */\nexport const formatTodoChange = (\n type: 'added' | 'updated' | 'reordered',\n todo: Todo,\n beforeStatus?: Todo['status'],\n reorderType?: string\n): string => {\n if (type === 'added') {\n return `+ ${todo.content}`;\n }\n\n if (type === 'reordered' && reorderType) {\n return `[${todo.id}] reordered to ${reorderType}`;\n }\n\n if (type === 'updated' && beforeStatus && beforeStatus !== todo.status) {\n return `[${todo.id}] ${beforeStatus} → ${todo.status}`;\n }\n\n return `[${todo.id}] updated`;\n};\n\n/**\n * Format todo count for summary\n */\nexport const formatTodoCount = (todos: Todo[]): string => {\n const active = todos.filter((t) => t.status !== 'removed');\n const completed = todos.filter((t) => t.status === 'completed');\n const inProgress = todos.filter((t) => t.status === 'in_progress');\n const pending = todos.filter((t) => t.status === 'pending');\n\n return `${completed.length}/${active.length} (${inProgress.length} in progress, ${pending.length} pending)`;\n};\n",
10
+ "/**\n * Todo Management Tools\n * Tools for LLM to track and manage work progress\n *\n * Design: Per-session todo lists\n * ===============================\n *\n * Todos are scoped to sessions (not global) to prevent cross-contamination:\n * - Each session has independent todos\n * - updateTodos tool operates on current session\n * - New sessions start with empty todo list\n *\n * Why per-session?\n * - Context isolation: Session A's todos don't interfere with Session B\n * - LLM clarity: AI only sees tasks relevant to current conversation\n * - Prevents bug: Starting new session and seeing old session's todos\n *\n * Implementation:\n * - Tool gets current sessionId from store\n * - Calls store.updateTodos(sessionId, updates)\n * - Returns error if no active session\n */\n\nimport { tool } from 'ai';\nimport { z } from 'zod';\nimport { useAppStore } from '../ui/stores/app-store.js';\nimport { formatTodoChange } from '../ui/utils/todo-formatters.js';\n\n/**\n * Update todos - Batch add/update todos\n *\n * ⚠️ IMPORTANT: This tool operates on the CURRENT session's todos only.\n * It does not affect other sessions' todos.\n */\nexport const updateTodosTool = tool({\n description: 'Update task list to track work progress',\n inputSchema: z.object({\n todos: z.array(z.object({\n id: z.number().optional().describe('ID to update existing, omit to add new'),\n content: z.string().optional().describe('Imperative form: \"Build feature\"'),\n activeForm: z.string().optional().describe('Present continuous: \"Building feature\"'),\n status: z.enum(['pending', 'in_progress', 'completed', 'removed']).optional().describe('pending | in_progress (keep ONE only) | completed | removed'),\n reorder: z.object({\n type: z.enum(['top', 'last', 'before', 'after']).describe('top | last | before | after'),\n id: z.number().optional().describe('Target ID (for before/after)'),\n }).optional().describe('Change order'),\n })).describe('Add/update todos. Examples: [{ content: \"Build login\", activeForm: \"Building login\", status: \"pending\" }] | [{ id: 1, status: \"completed\" }]'),\n }),\n execute: ({ todos }) => {\n const store = useAppStore.getState();\n const sessionId = store.currentSessionId;\n\n if (!sessionId) {\n return {\n error: 'No active session',\n summary: 'Failed: no active session',\n changes: [],\n total: 0,\n };\n }\n\n // Get current session's todos before update\n const session = store.sessions.find((s) => s.id === sessionId);\n if (!session) {\n return {\n error: 'Session not found',\n summary: 'Failed: session not found',\n changes: [],\n total: 0,\n };\n }\n\n const beforeState = session.todos;\n\n // Update todos for this session\n store.updateTodos(sessionId, todos);\n\n // Get updated session todos\n const updatedSession = store.sessions.find((s) => s.id === sessionId);\n const afterState = updatedSession?.todos || [];\n\n // Categorize changes\n const addedTodos = todos.filter((t) => t.id === undefined);\n const updatedTodos = todos.filter((t) => t.id !== undefined);\n\n // Build result using centralized formatters\n const changes: string[] = [];\n\n if (addedTodos.length > 0) {\n addedTodos.forEach((t) => {\n const addedTodo = afterState.find((todo) => todo.content === t.content);\n if (addedTodo) {\n changes.push(formatTodoChange('added', addedTodo));\n }\n });\n }\n\n if (updatedTodos.length > 0) {\n updatedTodos.forEach((t) => {\n const before = beforeState.find((todo) => todo.id === t.id);\n const after = afterState.find((todo) => todo.id === t.id);\n if (before && after) {\n if (t.status && t.status !== before.status) {\n changes.push(formatTodoChange('updated', after, before.status));\n } else if (t.reorder) {\n changes.push(formatTodoChange('reordered', after, undefined, t.reorder.type));\n }\n }\n });\n }\n\n return {\n summary: `${addedTodos.length} added, ${updatedTodos.length} updated`,\n changes: changes.length > 0 ? changes : ['No changes'],\n total: afterState.filter((t) => t.status !== 'removed').length,\n };\n },\n});\n\n/**\n * Export all todo tools\n */\nexport const todoTools = {\n updateTodos: updateTodosTool,\n};\n",
11
+ "/**\n * Tool Registry\n * Central registry for all AI SDK tools\n */\n\nimport { filesystemTools } from './filesystem.js';\nimport { shellTools } from './shell.js';\nimport { searchTools } from './search.js';\nimport { interactionTools } from './interaction.js';\nimport { todoTools } from './todo.js';\n\n/**\n * Get all tools in AI SDK Tool format\n */\nexport function getAISDKTools() {\n return {\n ...filesystemTools,\n ...shellTools,\n ...searchTools,\n ...interactionTools,\n ...todoTools,\n };\n}\n\n/**\n * Get tool names grouped by category\n */\nexport function getToolCategories() {\n return {\n filesystem: Object.keys(filesystemTools),\n shell: Object.keys(shellTools),\n search: Object.keys(searchTools),\n interaction: Object.keys(interactionTools),\n todo: Object.keys(todoTools),\n };\n}\n\n/**\n * Get all tool names\n */\nexport function getAllToolNames(): string[] {\n return Object.keys(getAISDKTools());\n}\n"
12
+ ],
13
+ "mappings": "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",
14
+ "debugId": "EE784603412EE20F64756E2164756E21",
15
+ "names": []
16
+ }
@@ -0,0 +1,4 @@
1
+ import{U}from"./chunk-cs1s5c3g.js";import{Lb as C}from"./chunk-sxy6vp20.js";var b=C(U(),1);import{readFile as B,readdir as M,access as w}from"node:fs/promises";import{join as Z,parse as y,relative as N}from"node:path";import{homedir as j}from"node:os";async function G(k,q=!1,x){try{let H=await B(k,"utf-8"),{data:Q,content:J}=b.default(H);if(!Q.name||typeof Q.name!=="string")return console.error(`Agent file ${k} missing required 'name' field`),null;let V={name:Q.name,description:Q.description||""};return{id:x||y(k).name,metadata:V,systemPrompt:J.trim(),isBuiltin:q,filePath:k}}catch(H){return console.error(`Failed to load agent from ${k}:`,H),null}}async function z(k,q=!1){try{let H=(await M(k,{recursive:!0,withFileTypes:!0})).filter((J)=>J.isFile()&&J.name.endsWith(".md")).map((J)=>{let V=Z(J.parentPath||J.path,J.name),Y=N(k,V).replace(/\.md$/,"");return{fullPath:V,agentId:Y}});return(await Promise.all(H.map(({fullPath:J,agentId:V})=>G(J,q,V)))).filter((J)=>J!==null)}catch(x){return[]}}async function S(){let k=new URL(".",import.meta.url).pathname,q=Z(k,"..","assets","agents"),x=Z(k,"..","..","assets","agents");try{return await w(q),q}catch{return x}}function D(k){let q=Z(j(),".sylphx-flow","agents"),x=Z(k,".sylphx-flow","agents");return[q,x]}async function v(k){let q=await S(),[x,H]=D(k),[Q,J,V]=await Promise.all([z(q,!0),z(x,!1),z(H,!1)]),Y=new Map;for(let W of Q)Y.set(W.id,W);for(let W of J)Y.set(W.id,W);for(let W of V)Y.set(W.id,W);return Array.from(Y.values())}var X="coder";var O=null,R=null,$={id:X,metadata:{name:"Coder",description:"Fallback agent (agent manager not initialized)"},systemPrompt:"You are a helpful coding assistant.",isBuiltin:!0};function f(k){R=k}async function u(k){let q=await v(k),x=new Map;for(let H of q)x.set(H.id,H);if(O={agents:x,cwd:k},R){let H=R();if(H.getState){let Q=H.getState().currentAgentId||X;if(!x.has(Q))H.getState().setCurrentAgentId(X)}}}function P(){if(!O)return[$];return Array.from(O.agents.values())}function h(k){if(!O)return k===X?$:null;return O.agents.get(k)||null}function L(){let k=K();if(!O)return $;return O.agents.get(k)||$}function K(){if(R){let k=R();if(k.getState)return k.getState().currentAgentId||X}return X}function p(k){if(!O)return!1;if(!O.agents.get(k))return!1;if(R){let x=R();if(x.getState)x.getState().setCurrentAgentId(k)}return!0}async function l(){if(!O)return;let k=O.cwd,q=K();if(await u(k),O&&!O.agents.has(q)){if(R){let x=R();if(x.getState)x.getState().setCurrentAgentId(X)}}}function o(){return L().systemPrompt}export{p as switchAgent,f as setAppStoreGetter,l as reloadAgents,u as initializeAgentManager,o as getCurrentSystemPrompt,K as getCurrentAgentId,L as getCurrentAgent,P as getAllAgents,h as getAgentById};
2
+ export{f as Q,u as R,h as S,o as T};
3
+
4
+ //# debugId=932F635DE10488EC64756E2164756E21
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/agent-loader.ts", "../src/core/builtin-agents.ts", "../src/core/agent-manager.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Agent Loader\n * Loads agent definitions from markdown files with front matter\n */\n\nimport { readFile, readdir, access } from 'node:fs/promises';\nimport { join, parse, relative } from 'node:path';\nimport { homedir } from 'node:os';\nimport matter from 'gray-matter';\nimport type { Agent, AgentMetadata } from '../types/agent.types.js';\n\n/**\n * Load a single agent from a markdown file\n */\nexport async function loadAgentFromFile(\n filePath: string,\n isBuiltin: boolean = false,\n agentId?: string\n): Promise<Agent | null> {\n try {\n const content = await readFile(filePath, 'utf-8');\n const { data, content: systemPrompt } = matter(content);\n\n // Validate front matter\n if (!data.name || typeof data.name !== 'string') {\n console.error(`Agent file ${filePath} missing required 'name' field`);\n return null;\n }\n\n const metadata: AgentMetadata = {\n name: data.name,\n description: data.description || '',\n };\n\n // Get agent ID from parameter or filename\n const id = agentId || parse(filePath).name;\n\n return {\n id,\n metadata,\n systemPrompt: systemPrompt.trim(),\n isBuiltin,\n filePath,\n };\n } catch (error) {\n console.error(`Failed to load agent from ${filePath}:`, error);\n return null;\n }\n}\n\n/**\n * Load all agents from a directory (recursively)\n */\nexport async function loadAgentsFromDirectory(dirPath: string, isBuiltin: boolean = false): Promise<Agent[]> {\n try {\n // Read directory recursively to support subdirectories\n const files = await readdir(dirPath, { recursive: true, withFileTypes: true });\n\n // Filter for .md files and calculate agent IDs from relative paths\n const agentFiles = files\n .filter((f) => f.isFile() && f.name.endsWith('.md'))\n .map((f) => {\n const fullPath = join(f.parentPath || f.path, f.name);\n // Calculate relative path from dirPath and remove .md extension\n const relativePath = relative(dirPath, fullPath).replace(/\\.md$/, '');\n return { fullPath, agentId: relativePath };\n });\n\n const agents = await Promise.all(\n agentFiles.map(({ fullPath, agentId }) => loadAgentFromFile(fullPath, isBuiltin, agentId))\n );\n\n return agents.filter((agent): agent is Agent => agent !== null);\n } catch (error) {\n // Directory doesn't exist or can't be read\n return [];\n }\n}\n\n/**\n * Get system agents path (bundled with the app)\n */\nexport async function getSystemAgentsPath(): Promise<string> {\n // Get the directory of the current module\n const currentDir = new URL('.', import.meta.url).pathname;\n\n // In production (dist), assets are at dist/assets/agents\n // In development (src), go up to project root: src/core -> project root\n const distPath = join(currentDir, '..', 'assets', 'agents');\n const devPath = join(currentDir, '..', '..', 'assets', 'agents');\n\n // Check which one exists (try dist first, then dev)\n try {\n await access(distPath);\n return distPath;\n } catch {\n return devPath;\n }\n}\n\n/**\n * Get all agent search paths\n */\nexport function getAgentSearchPaths(cwd: string): string[] {\n const globalPath = join(homedir(), '.sylphx-flow', 'agents');\n const projectPath = join(cwd, '.sylphx-flow', 'agents');\n\n return [globalPath, projectPath];\n}\n\n/**\n * Load all available agents from all sources\n */\nexport async function loadAllAgents(cwd: string): Promise<Agent[]> {\n const systemPath = await getSystemAgentsPath();\n const [globalPath, projectPath] = getAgentSearchPaths(cwd);\n\n const [systemAgents, globalAgents, projectAgents] = await Promise.all([\n loadAgentsFromDirectory(systemPath, true), // System agents are marked as builtin\n loadAgentsFromDirectory(globalPath, false),\n loadAgentsFromDirectory(projectPath, false),\n ]);\n\n // Priority: system < global < project\n // Use Map to deduplicate by ID (later entries override earlier ones)\n const agentMap = new Map<string, Agent>();\n\n // Add system agents first (lowest priority)\n for (const agent of systemAgents) {\n agentMap.set(agent.id, agent);\n }\n\n // Add global agents (override system)\n for (const agent of globalAgents) {\n agentMap.set(agent.id, agent);\n }\n\n // Add project agents (override globals and system)\n for (const agent of projectAgents) {\n agentMap.set(agent.id, agent);\n }\n\n return Array.from(agentMap.values());\n}\n",
6
+ "/**\n * Agent Constants\n * Default agent ID for fallback purposes\n */\n\n/**\n * Default agent ID (must match an agent in assets/agents/)\n */\nexport const DEFAULT_AGENT_ID = 'coder';\n",
7
+ "/**\n * Agent Manager\n * Manages agent state and operations\n */\n\nimport type { Agent } from '../types/agent.types.js';\nimport { loadAllAgents } from './agent-loader.js';\nimport { DEFAULT_AGENT_ID } from './builtin-agents.js';\n\n/**\n * Agent manager state\n */\ninterface AgentManagerState {\n agents: Map<string, Agent>;\n cwd: string;\n}\n\nlet state: AgentManagerState | null = null;\n\n/**\n * Get the app store (lazy import to avoid circular dependencies)\n */\nlet getAppStore: (() => any) | null = null;\n\n/**\n * Fallback agent when state is not initialized\n */\nconst FALLBACK_AGENT: Agent = {\n id: DEFAULT_AGENT_ID,\n metadata: {\n name: 'Coder',\n description: 'Fallback agent (agent manager not initialized)',\n },\n systemPrompt: 'You are a helpful coding assistant.',\n isBuiltin: true,\n};\n\n/**\n * Set the app store getter (called during initialization)\n */\nexport function setAppStoreGetter(getter: () => any): void {\n getAppStore = getter;\n}\n\n/**\n * Initialize agent manager\n */\nexport async function initializeAgentManager(cwd: string): Promise<void> {\n const allAgents = await loadAllAgents(cwd);\n\n const agentMap = new Map<string, Agent>();\n for (const agent of allAgents) {\n agentMap.set(agent.id, agent);\n }\n\n state = {\n agents: agentMap,\n cwd,\n };\n\n // Initialize store with default agent if store is available\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n const currentAgentId = store.getState().currentAgentId || DEFAULT_AGENT_ID;\n // Ensure the current agent exists, fallback to default if not\n if (!agentMap.has(currentAgentId)) {\n store.getState().setCurrentAgentId(DEFAULT_AGENT_ID);\n }\n }\n }\n}\n\n/**\n * Get all available agents\n */\nexport function getAllAgents(): Agent[] {\n if (!state) {\n return [FALLBACK_AGENT];\n }\n return Array.from(state.agents.values());\n}\n\n/**\n * Get agent by ID\n */\nexport function getAgentById(id: string): Agent | null {\n if (!state) {\n return id === DEFAULT_AGENT_ID ? FALLBACK_AGENT : null;\n }\n return state.agents.get(id) || null;\n}\n\n/**\n * Get current agent\n */\nexport function getCurrentAgent(): Agent {\n const currentAgentId = getCurrentAgentId();\n\n if (!state) {\n return FALLBACK_AGENT;\n }\n return state.agents.get(currentAgentId) || FALLBACK_AGENT;\n}\n\n/**\n * Get current agent ID\n */\nexport function getCurrentAgentId(): string {\n // Try to get from store first\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n return store.getState().currentAgentId || DEFAULT_AGENT_ID;\n }\n }\n // Fallback to default\n return DEFAULT_AGENT_ID;\n}\n\n/**\n * Switch to a different agent\n */\nexport function switchAgent(agentId: string): boolean {\n if (!state) {\n return false;\n }\n\n const agent = state.agents.get(agentId);\n if (!agent) {\n return false;\n }\n\n // Update store if available (this triggers reactive updates)\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n store.getState().setCurrentAgentId(agentId);\n }\n }\n\n return true;\n}\n\n/**\n * Reload agents from disk\n */\nexport async function reloadAgents(): Promise<void> {\n if (!state) {\n return;\n }\n\n const cwd = state.cwd;\n const currentAgentId = getCurrentAgentId();\n\n await initializeAgentManager(cwd);\n\n // Restore current agent if it still exists, otherwise reset to default\n if (state && !state.agents.has(currentAgentId)) {\n if (getAppStore) {\n const store = getAppStore();\n if (store.getState) {\n store.getState().setCurrentAgentId(DEFAULT_AGENT_ID);\n }\n }\n }\n}\n\n/**\n * Get system prompt for current agent\n */\nexport function getCurrentSystemPrompt(): string {\n return getCurrentAgent().systemPrompt;\n}\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "932F635DE10488EC64756E2164756E21",
11
+ "names": []
12
+ }
@@ -1,4 +1,4 @@
1
- import"./chunk-hshjnpm0.js";import{AutoTokenizer as j}from"@huggingface/transformers";class R{tokenizer;initialized=!1;modelPath;constructor(B={}){this.modelPath=B.modelPath||"./models/starcoder2"}async initialize(){if(this.initialized)return;try{this.tokenizer=await j.from_pretrained(this.modelPath),this.initialized=!0}catch(B){throw Error(`Tokenizer initialization failed: ${B.message}`)}}async tokenize(B){if(!this.initialized)await this.initialize();let H=Date.now();if(!B||B.trim().length===0)return{tokens:[],metadata:{totalTokens:0,vocabSize:49152,processingTime:Date.now()-H,averageConfidence:0},raw:{inputIds:[],decodedText:""}};try{let J=(await this.tokenizer(B)).input_ids.tolist()[0],O=await this.tokenizer.decode(J),U=await this.createDirectTokens(O,J),K=Date.now()-H;return{tokens:U,metadata:{totalTokens:U.length,vocabSize:49152,processingTime:K,averageConfidence:0.95},raw:{inputIds:J,decodedText:O}}}catch(G){throw Error(`Tokenization failed: ${G.message}`)}}async createDirectTokens(B,H){let G=[];for(let J=0;J<H.length;J++){let O=H[J];try{let K=(await this.tokenizer.decode([O],{skip_special_tokens:!0})).trim().toLowerCase();if(K.length>0)G.push({text:K,id:O,score:1,confidence:1,relevance:"high"})}catch(U){}}return G}async getTopTokens(B,H=20){return(await this.tokenize(B)).tokens.slice(0,H)}async getTechnicalTokens(B){return(await this.tokenize(B)).tokens}async decode(B){if(!this.initialized)throw Error("Tokenizer not initialized. Call initialize() first.");return await this.tokenizer.decode(B)}async encode(B){if(!this.initialized)throw Error("Tokenizer not initialized. Call initialize() first.");return(await this.tokenizer(B)).input_ids.tolist()[0]}}async function k(B,H){try{let G=await B.getAllCodebaseFiles();if(H){if(H.file_extensions&&H.file_extensions.length>0)G=G.filter((K)=>H.file_extensions?.some((W)=>K.path.endsWith(W)));if(H.path_filter)G=G.filter((K)=>K.path.includes(H.path_filter));if(H.exclude_paths&&H.exclude_paths.length>0)G=G.filter((K)=>!H.exclude_paths?.some((W)=>K.path.includes(W)))}if(G.length===0)return null;let J=[];for(let K of G){let W=await B.getTFIDFDocument(K.path);if(W){let _=await B.getTFIDFTerms(K.path),X=new Map,$=new Map;for(let[E,Y]of Object.entries(_))X.set(E,Y);let Z=W.rawTerms||{};for(let[E,Y]of Object.entries(Z))$.set(E,Y);J.push({uri:`file://${K.path}`,terms:X,rawTerms:$,magnitude:W.magnitude})}}if(J.length===0)return null;let O=await B.getIDFValues(),U=new Map;for(let[K,W]of Object.entries(O))U.set(K,W);return{documents:J,idf:U,totalDocuments:J.length,metadata:{generatedAt:new Date().toISOString(),version:"1.0.0"}}}catch(G){return console.error("[ERROR] Failed to build search index from database:",G),null}}function M(B){let H=Array.from(B.values()).reduce((J,O)=>J+O,0),G=new Map;for(let[J,O]of B.entries())G.set(J,O/H);return G}function z(B,H){let G=new Map;for(let O of B){let U=new Set(O.keys());for(let K of U)G.set(K,(G.get(K)||0)+1)}let J=new Map;for(let[O,U]of G.entries())J.set(O,Math.log(H/U));return J}function V(B,H){let G=new Map;for(let[J,O]of B.entries()){let U=H.get(J)||0;G.set(J,O*U)}return G}function w(B){let H=0;for(let G of B.values())H+=G*G;return Math.sqrt(H)}var Q=null,v=!1;async function D(){if(!Q)Q=new R({modelPath:"./models/starcoder2"});if(!v){let{log:B,error:H}=console;console.log=()=>{},console.error=()=>{};try{await Q.initialize(),v=!0}finally{console.log=B,console.error=H}}return Q}async function S(B){let G=await(await D()).tokenize(B),J=new Map;for(let O of G.tokens){let U=O.text.toLowerCase(),K=J.get(U)||0;J.set(U,K+O.score)}return J}async function P(B){let G=await(await D()).tokenize(B),J=new Map;for(let O of G.tokens){let U=O.text.toLowerCase();if(!J.has(U)||O.score>0.8)J.set(U,O.text)}return Array.from(J.values())}async function q(B,H){let J=[];for(let K=0;K<B.length;K+=1){let W=B.slice(K,K+1),_=[];for(let X=0;X<W.length;X++){let $=W[X],Z=$.uri.split("/").pop()||$.uri;H?.({current:K+X+1,total:B.length,fileName:Z,status:"processing"});try{let E=await S($.content);_.push({uri:$.uri,terms:E}),H?.({current:K+X+1,total:B.length,fileName:Z,status:"completed"})}catch(E){_.push({uri:$.uri,terms:new Map}),H?.({current:K+X+1,total:B.length,fileName:Z,status:"skipped"})}}J.push(..._)}let O=z(J.map((K)=>K.terms),B.length);return{documents:J.map((K)=>{let W=M(K.terms),_=V(W,O),X=w(_);return{uri:K.uri,terms:_,rawTerms:K.terms,magnitude:X}}),idf:O,totalDocuments:B.length,metadata:{generatedAt:new Date().toISOString(),version:"5.0.0",tokenizer:"AdvancedCodeTokenizer",features:["Industry-leading code understanding","Advanced technical term recognition","Optimized for code search","Simple and effective approach","No unnecessary complexity"]}}}function h(B,H){let G=0;for(let[O,U]of B.entries()){let K=H.terms.get(O)||0;G+=U*K}let J=w(B);if(J===0||H.magnitude===0)return 0;return G/(J*H.magnitude)}async function I(B,H){let G=await P(B),J=new Map;for(let O of G){let U=O.toLowerCase(),K=H.get(U)||0;if(K>0)J.set(U,K)}return J}async function y(B,H,G={}){let{limit:J=10,minScore:O=0,boostFactors:U={}}=G,{exactMatch:K=1.5,phraseMatch:W=2,technicalMatch:_=1.8,identifierMatch:X=1.3}=U,$=await I(B,H.idf),Z=(await P(B)).map((Y)=>Y.toLowerCase());return H.documents.map((Y)=>{let L=h($,Y),C=[];for(let N of Z)if(Y.rawTerms.has(N)){let A=K;if(b(N))A=Math.max(A,_);if(p(N))A=Math.max(A,X);L*=A,C.push(N)}if(C.length===Z.length&&Z.length>1)L*=W;if(Z.length>3&&C.length>=Z.length*0.7)L*=1.2;return{uri:Y.uri,score:L,matchedTerms:C}}).filter((Y)=>Y.score>=O).sort((Y,L)=>L.score-Y.score).slice(0,J)}function b(B){return[/\b[A-Z]{2,}\b/,/\b[A-Z][a-z]+(?:[A-Z][a-z]+)+\b/,/\b[a-z]+[A-Z][a-z]*\b/,/\b\w+(?:Dir|Config|File|Path|Data|Service|Manager|Handler)\b/,/\b(?:get|set|is|has|can|should|will|do)[A-Z]\w*\b/,/\b(?:http|https|json|xml|yaml|sql|api|url|uri)\b/].some((G)=>G.test(B))}function p(B){return/^[a-zA-Z][a-zA-Z0-9_]*$/.test(B)&&B.length>1}function T(B){let H={documents:B.documents.map((G)=>({uri:G.uri,terms:Array.from(G.terms.entries()),rawTerms:Array.from(G.rawTerms.entries()),magnitude:G.magnitude})),idf:Array.from(B.idf.entries()),totalDocuments:B.totalDocuments,metadata:B.metadata};return JSON.stringify(H,null,2)}function f(B){let H=JSON.parse(B);return{documents:H.documents.map((G)=>({uri:G.uri,terms:new Map(G.terms),rawTerms:new Map(G.rawTerms),magnitude:G.magnitude})),idf:new Map(H.idf),totalDocuments:H.totalDocuments,metadata:H.metadata}}export{T as serializeIndex,y as searchDocuments,I as processQuery,f as deserializeIndex,h as calculateCosineSimilarity,k as buildSearchIndexFromDB,q as buildSearchIndex};
2
- export{q as d,y as e};
1
+ import"./chunk-sxy6vp20.js";import{AutoTokenizer as j}from"@huggingface/transformers";class R{tokenizer;initialized=!1;modelPath;constructor(B={}){this.modelPath=B.modelPath||"./models/starcoder2"}async initialize(){if(this.initialized)return;try{this.tokenizer=await j.from_pretrained(this.modelPath),this.initialized=!0}catch(B){throw Error(`Tokenizer initialization failed: ${B.message}`)}}async tokenize(B){if(!this.initialized)await this.initialize();let H=Date.now();if(!B||B.trim().length===0)return{tokens:[],metadata:{totalTokens:0,vocabSize:49152,processingTime:Date.now()-H,averageConfidence:0},raw:{inputIds:[],decodedText:""}};try{let J=(await this.tokenizer(B)).input_ids.tolist()[0],O=await this.tokenizer.decode(J),U=await this.createDirectTokens(O,J),K=Date.now()-H;return{tokens:U,metadata:{totalTokens:U.length,vocabSize:49152,processingTime:K,averageConfidence:0.95},raw:{inputIds:J,decodedText:O}}}catch(G){throw Error(`Tokenization failed: ${G.message}`)}}async createDirectTokens(B,H){let G=[];for(let J=0;J<H.length;J++){let O=H[J];try{let K=(await this.tokenizer.decode([O],{skip_special_tokens:!0})).trim().toLowerCase();if(K.length>0)G.push({text:K,id:O,score:1,confidence:1,relevance:"high"})}catch(U){}}return G}async getTopTokens(B,H=20){return(await this.tokenize(B)).tokens.slice(0,H)}async getTechnicalTokens(B){return(await this.tokenize(B)).tokens}async decode(B){if(!this.initialized)throw Error("Tokenizer not initialized. Call initialize() first.");return await this.tokenizer.decode(B)}async encode(B){if(!this.initialized)throw Error("Tokenizer not initialized. Call initialize() first.");return(await this.tokenizer(B)).input_ids.tolist()[0]}}async function k(B,H){try{let G=await B.getAllCodebaseFiles();if(H){if(H.file_extensions&&H.file_extensions.length>0)G=G.filter((K)=>H.file_extensions?.some((W)=>K.path.endsWith(W)));if(H.path_filter)G=G.filter((K)=>K.path.includes(H.path_filter));if(H.exclude_paths&&H.exclude_paths.length>0)G=G.filter((K)=>!H.exclude_paths?.some((W)=>K.path.includes(W)))}if(G.length===0)return null;let J=[];for(let K of G){let W=await B.getTFIDFDocument(K.path);if(W){let _=await B.getTFIDFTerms(K.path),X=new Map,$=new Map;for(let[E,Y]of Object.entries(_))X.set(E,Y);let Z=W.rawTerms||{};for(let[E,Y]of Object.entries(Z))$.set(E,Y);J.push({uri:`file://${K.path}`,terms:X,rawTerms:$,magnitude:W.magnitude})}}if(J.length===0)return null;let O=await B.getIDFValues(),U=new Map;for(let[K,W]of Object.entries(O))U.set(K,W);return{documents:J,idf:U,totalDocuments:J.length,metadata:{generatedAt:new Date().toISOString(),version:"1.0.0"}}}catch(G){return console.error("[ERROR] Failed to build search index from database:",G),null}}function M(B){let H=Array.from(B.values()).reduce((J,O)=>J+O,0),G=new Map;for(let[J,O]of B.entries())G.set(J,O/H);return G}function z(B,H){let G=new Map;for(let O of B){let U=new Set(O.keys());for(let K of U)G.set(K,(G.get(K)||0)+1)}let J=new Map;for(let[O,U]of G.entries())J.set(O,Math.log(H/U));return J}function V(B,H){let G=new Map;for(let[J,O]of B.entries()){let U=H.get(J)||0;G.set(J,O*U)}return G}function w(B){let H=0;for(let G of B.values())H+=G*G;return Math.sqrt(H)}var Q=null,v=!1;async function D(){if(!Q)Q=new R({modelPath:"./models/starcoder2"});if(!v){let{log:B,error:H}=console;console.log=()=>{},console.error=()=>{};try{await Q.initialize(),v=!0}finally{console.log=B,console.error=H}}return Q}async function S(B){let G=await(await D()).tokenize(B),J=new Map;for(let O of G.tokens){let U=O.text.toLowerCase(),K=J.get(U)||0;J.set(U,K+O.score)}return J}async function P(B){let G=await(await D()).tokenize(B),J=new Map;for(let O of G.tokens){let U=O.text.toLowerCase();if(!J.has(U)||O.score>0.8)J.set(U,O.text)}return Array.from(J.values())}async function q(B,H){let J=[];for(let K=0;K<B.length;K+=1){let W=B.slice(K,K+1),_=[];for(let X=0;X<W.length;X++){let $=W[X],Z=$.uri.split("/").pop()||$.uri;H?.({current:K+X+1,total:B.length,fileName:Z,status:"processing"});try{let E=await S($.content);_.push({uri:$.uri,terms:E}),H?.({current:K+X+1,total:B.length,fileName:Z,status:"completed"})}catch(E){_.push({uri:$.uri,terms:new Map}),H?.({current:K+X+1,total:B.length,fileName:Z,status:"skipped"})}}J.push(..._)}let O=z(J.map((K)=>K.terms),B.length);return{documents:J.map((K)=>{let W=M(K.terms),_=V(W,O),X=w(_);return{uri:K.uri,terms:_,rawTerms:K.terms,magnitude:X}}),idf:O,totalDocuments:B.length,metadata:{generatedAt:new Date().toISOString(),version:"5.0.0",tokenizer:"AdvancedCodeTokenizer",features:["Industry-leading code understanding","Advanced technical term recognition","Optimized for code search","Simple and effective approach","No unnecessary complexity"]}}}function h(B,H){let G=0;for(let[O,U]of B.entries()){let K=H.terms.get(O)||0;G+=U*K}let J=w(B);if(J===0||H.magnitude===0)return 0;return G/(J*H.magnitude)}async function I(B,H){let G=await P(B),J=new Map;for(let O of G){let U=O.toLowerCase(),K=H.get(U)||0;if(K>0)J.set(U,K)}return J}async function y(B,H,G={}){let{limit:J=10,minScore:O=0,boostFactors:U={}}=G,{exactMatch:K=1.5,phraseMatch:W=2,technicalMatch:_=1.8,identifierMatch:X=1.3}=U,$=await I(B,H.idf),Z=(await P(B)).map((Y)=>Y.toLowerCase());return H.documents.map((Y)=>{let L=h($,Y),C=[];for(let N of Z)if(Y.rawTerms.has(N)){let A=K;if(b(N))A=Math.max(A,_);if(p(N))A=Math.max(A,X);L*=A,C.push(N)}if(C.length===Z.length&&Z.length>1)L*=W;if(Z.length>3&&C.length>=Z.length*0.7)L*=1.2;return{uri:Y.uri,score:L,matchedTerms:C}}).filter((Y)=>Y.score>=O).sort((Y,L)=>L.score-Y.score).slice(0,J)}function b(B){return[/\b[A-Z]{2,}\b/,/\b[A-Z][a-z]+(?:[A-Z][a-z]+)+\b/,/\b[a-z]+[A-Z][a-z]*\b/,/\b\w+(?:Dir|Config|File|Path|Data|Service|Manager|Handler)\b/,/\b(?:get|set|is|has|can|should|will|do)[A-Z]\w*\b/,/\b(?:http|https|json|xml|yaml|sql|api|url|uri)\b/].some((G)=>G.test(B))}function p(B){return/^[a-zA-Z][a-zA-Z0-9_]*$/.test(B)&&B.length>1}function T(B){let H={documents:B.documents.map((G)=>({uri:G.uri,terms:Array.from(G.terms.entries()),rawTerms:Array.from(G.rawTerms.entries()),magnitude:G.magnitude})),idf:Array.from(B.idf.entries()),totalDocuments:B.totalDocuments,metadata:B.metadata};return JSON.stringify(H,null,2)}function f(B){let H=JSON.parse(B);return{documents:H.documents.map((G)=>({uri:G.uri,terms:new Map(G.terms),rawTerms:new Map(G.rawTerms),magnitude:G.magnitude})),idf:new Map(H.idf),totalDocuments:H.totalDocuments,metadata:H.metadata}}export{T as serializeIndex,y as searchDocuments,I as processQuery,f as deserializeIndex,h as calculateCosineSimilarity,k as buildSearchIndexFromDB,q as buildSearchIndex};
2
+ export{q as c,y as d};
3
3
 
4
- //# debugId=F6CC4F566F5A987064756E2164756E21
4
+ //# debugId=A2D767B1A03BB0A664756E2164756E21
@@ -6,6 +6,6 @@
6
6
  "/**\n * TF-IDF (Term Frequency-Inverse Document Frequency) implementation\n * Used for ranking document relevance in semantic search\n */\n\nimport { AdvancedCodeTokenizer } from '../../utils/advanced-tokenizer.js';\nimport type { SeparatedMemoryStorage } from './separated-storage.js';\n\nexport interface DocumentVector {\n uri: string;\n terms: Map<string, number>; // term → TF-IDF score\n rawTerms: Map<string, number>; // term → raw frequency\n magnitude: number; // Vector magnitude for cosine similarity\n}\n\nexport interface SearchIndex {\n documents: DocumentVector[];\n idf: Map<string, number>; // term → IDF score\n totalDocuments: number;\n metadata: {\n generatedAt: string;\n version: string;\n };\n}\n\n/**\n * Build search index from database (shared between CLI and MCP)\n */\nexport async function buildSearchIndexFromDB(\n memoryStorage: SeparatedMemoryStorage,\n filters?: {\n file_extensions?: string[];\n path_filter?: string;\n exclude_paths?: string[];\n }\n): Promise<SearchIndex | null> {\n try {\n // Get all files from database\n let files = await memoryStorage.getAllCodebaseFiles();\n\n // Apply filters\n if (filters) {\n if (filters.file_extensions && filters.file_extensions.length > 0) {\n files = files.filter((file) =>\n filters.file_extensions?.some((ext: string) => file.path.endsWith(ext))\n );\n }\n\n if (filters.path_filter) {\n files = files.filter((file) => file.path.includes(filters.path_filter!));\n }\n\n if (filters.exclude_paths && filters.exclude_paths.length > 0) {\n files = files.filter(\n (file) => !filters.exclude_paths?.some((exclude: string) => file.path.includes(exclude))\n );\n }\n }\n\n if (files.length === 0) {\n return null;\n }\n\n // Build search documents - read TF-IDF terms directly from database\n const documents = [];\n for (const file of files) {\n const tfidfDoc = await memoryStorage.getTFIDFDocument(file.path);\n if (tfidfDoc) {\n // Get TF-IDF terms from database (already calculated)\n const tfidfTerms = await memoryStorage.getTFIDFTerms(file.path);\n const terms = new Map<string, number>();\n const rawTermsMap = new Map<string, number>();\n\n // Use TF-IDF terms for search scoring\n for (const [term, tfidfScore] of Object.entries(tfidfTerms)) {\n terms.set(term, tfidfScore as number);\n }\n\n // Use rawTerms for reference\n const rawTerms = tfidfDoc.rawTerms || {};\n for (const [term, freq] of Object.entries(rawTerms)) {\n rawTermsMap.set(term, freq as number);\n }\n\n documents.push({\n uri: `file://${file.path}`,\n terms,\n rawTerms: rawTermsMap,\n magnitude: tfidfDoc.magnitude,\n });\n }\n }\n\n if (documents.length === 0) {\n return null;\n }\n\n // Get IDF values from database\n const idfRecords = await memoryStorage.getIDFValues();\n const idf = new Map<string, number>();\n for (const [term, value] of Object.entries(idfRecords)) {\n idf.set(term, value as number);\n }\n\n return {\n documents,\n idf,\n totalDocuments: documents.length,\n metadata: {\n generatedAt: new Date().toISOString(),\n version: '1.0.0',\n },\n };\n } catch (error) {\n console.error('[ERROR] Failed to build search index from database:', error);\n return null;\n }\n}\n\n/**\n * Calculate Term Frequency (TF)\n * TF = (number of times term appears in document) / (total terms in document)\n */\nfunction calculateTF(termFrequency: Map<string, number>): Map<string, number> {\n const totalTerms = Array.from(termFrequency.values()).reduce((sum, freq) => sum + freq, 0);\n const tf = new Map<string, number>();\n\n for (const [term, freq] of termFrequency.entries()) {\n tf.set(term, freq / totalTerms);\n }\n\n return tf;\n}\n\n/**\n * Calculate Inverse Document Frequency (IDF)\n * IDF = log(total documents / documents containing term)\n */\nfunction calculateIDF(\n documents: Map<string, number>[],\n totalDocuments: number\n): Map<string, number> {\n const documentFrequency = new Map<string, number>();\n\n // Count how many documents contain each term\n for (const doc of documents) {\n const uniqueTerms = new Set(doc.keys());\n for (const term of uniqueTerms) {\n documentFrequency.set(term, (documentFrequency.get(term) || 0) + 1);\n }\n }\n\n // Calculate IDF for each term\n const idf = new Map<string, number>();\n for (const [term, docFreq] of documentFrequency.entries()) {\n idf.set(term, Math.log(totalDocuments / docFreq));\n }\n\n return idf;\n}\n\n/**\n * Calculate TF-IDF scores for a document\n */\nfunction calculateTFIDF(tf: Map<string, number>, idf: Map<string, number>): Map<string, number> {\n const tfidf = new Map<string, number>();\n\n for (const [term, tfScore] of tf.entries()) {\n const idfScore = idf.get(term) || 0;\n tfidf.set(term, tfScore * idfScore);\n }\n\n return tfidf;\n}\n\n/**\n * Calculate vector magnitude for cosine similarity\n */\nfunction calculateMagnitude(vector: Map<string, number>): number {\n let sum = 0;\n for (const value of vector.values()) {\n sum += value * value;\n }\n return Math.sqrt(sum);\n}\n\n// Global tokenizer instance for performance\nlet globalTokenizer: AdvancedCodeTokenizer | null = null;\nlet tokenizerInitialized = false;\n\n/**\n * Get or create the global tokenizer\n */\nasync function getTokenizer(): Promise<AdvancedCodeTokenizer> {\n if (!globalTokenizer) {\n globalTokenizer = new AdvancedCodeTokenizer({\n modelPath: './models/starcoder2',\n });\n }\n\n if (!tokenizerInitialized) {\n // Silently initialize - no console output\n const originalLog = console.log;\n const originalError = console.error;\n console.log = () => {}; // Temporarily silence console.log\n console.error = () => {}; // Temporarily silence console.error\n try {\n await globalTokenizer.initialize();\n tokenizerInitialized = true;\n } finally {\n console.log = originalLog; // Restore console.log\n console.error = originalError; // Restore console.error\n }\n }\n\n return globalTokenizer;\n}\n\n/**\n * Extract terms using our advanced tokenizer\n */\nasync function extractTerms(content: string): Promise<Map<string, number>> {\n const tokenizer = await getTokenizer();\n const result = await tokenizer.tokenize(content);\n const terms = new Map<string, number>();\n\n // Use token scores as TF weights\n for (const token of result.tokens) {\n const term = token.text.toLowerCase();\n const currentScore = terms.get(term) || 0;\n terms.set(term, currentScore + token.score);\n }\n\n return terms;\n}\n\n/**\n * Extract simple tokens for query processing\n */\nasync function extractQueryTokens(query: string): Promise<string[]> {\n const tokenizer = await getTokenizer();\n const result = await tokenizer.tokenize(query);\n\n // Return unique tokens, sorted by score (highest first)\n const uniqueTokens = new Map<string, string>();\n for (const token of result.tokens) {\n const lowerText = token.text.toLowerCase();\n if (!uniqueTokens.has(lowerText) || token.score > 0.8) {\n uniqueTokens.set(lowerText, token.text);\n }\n }\n\n return Array.from(uniqueTokens.values());\n}\n\nexport interface BuildIndexProgress {\n current: number;\n total: number;\n fileName: string;\n status: 'processing' | 'completed' | 'skipped';\n}\n\n/**\n * Build TF-IDF search index from documents using our advanced tokenizer\n */\nexport async function buildSearchIndex(\n documents: Array<{ uri: string; content: string }>,\n onProgress?: (progress: BuildIndexProgress) => void\n): Promise<SearchIndex> {\n // Process documents one by one to avoid hanging\n const batchSize = 1; // Process 1 document at a time to avoid hanging\n const documentTerms: Array<{ uri: string; terms: Map<string, number> }> = [];\n\n for (let i = 0; i < documents.length; i += batchSize) {\n const batch = documents.slice(i, i + batchSize);\n\n // Process sequentially to avoid hanging\n const batchResults = [];\n for (let j = 0; j < batch.length; j++) {\n const doc = batch[j];\n const fileName = doc.uri.split('/').pop() || doc.uri;\n\n // Report progress\n onProgress?.({\n current: i + j + 1,\n total: documents.length,\n fileName,\n status: 'processing',\n });\n\n try {\n const result = await extractTerms(doc.content);\n\n batchResults.push({\n uri: doc.uri,\n terms: result,\n });\n\n // Report completion\n onProgress?.({\n current: i + j + 1,\n total: documents.length,\n fileName,\n status: 'completed',\n });\n } catch (_error) {\n batchResults.push({\n uri: doc.uri,\n terms: new Map<string, number>(),\n });\n\n // Report skip\n onProgress?.({\n current: i + j + 1,\n total: documents.length,\n fileName,\n status: 'skipped',\n });\n }\n }\n\n documentTerms.push(...batchResults);\n }\n\n // Calculate IDF scores\n const idf = calculateIDF(\n documentTerms.map((d) => d.terms),\n documents.length\n );\n\n // Calculate TF-IDF for each document\n const documentVectors: DocumentVector[] = documentTerms.map((doc) => {\n const tf = calculateTF(doc.terms);\n const tfidf = calculateTFIDF(tf, idf);\n const magnitude = calculateMagnitude(tfidf);\n\n return {\n uri: doc.uri,\n terms: tfidf,\n rawTerms: doc.terms,\n magnitude,\n };\n });\n\n return {\n documents: documentVectors,\n idf,\n totalDocuments: documents.length,\n metadata: {\n generatedAt: new Date().toISOString(),\n version: '5.0.0',\n tokenizer: 'AdvancedCodeTokenizer',\n features: [\n 'Industry-leading code understanding',\n 'Advanced technical term recognition',\n 'Optimized for code search',\n 'Simple and effective approach',\n 'No unnecessary complexity',\n ],\n },\n };\n}\n\n/**\n * Calculate cosine similarity between query and document\n */\nexport function calculateCosineSimilarity(\n queryVector: Map<string, number>,\n docVector: DocumentVector\n): number {\n let dotProduct = 0;\n\n // Calculate dot product\n for (const [term, queryScore] of queryVector.entries()) {\n const docScore = docVector.terms.get(term) || 0;\n dotProduct += queryScore * docScore;\n }\n\n // Calculate query magnitude\n const queryMagnitude = calculateMagnitude(queryVector);\n\n if (queryMagnitude === 0 || docVector.magnitude === 0) {\n return 0;\n }\n\n return dotProduct / (queryMagnitude * docVector.magnitude);\n}\n\n/**\n * Process query into TF-IDF vector using database values\n */\nexport async function processQuery(\n query: string,\n idf: Map<string, number>\n): Promise<Map<string, number>> {\n const terms = await extractQueryTokens(query);\n const queryVector = new Map<string, number>();\n\n // 為每個查詢詞使用 IDF 值(查詢本身無 TF-IDF,直接用 IDF)\n for (const term of terms) {\n const lowerTerm = term.toLowerCase();\n const idfValue = idf.get(lowerTerm) || 0;\n\n // 純粹用 IDF 值,完全信任 StarCoder2 嘅 tokenization\n if (idfValue > 0) {\n queryVector.set(lowerTerm, idfValue);\n }\n }\n\n return queryVector;\n}\n\n/**\n * Search documents using TF-IDF and cosine similarity with Advanced Code Tokenizer\n */\nexport async function searchDocuments(\n query: string,\n index: SearchIndex,\n options: {\n limit?: number;\n minScore?: number;\n boostFactors?: {\n exactMatch?: number; // Boost for exact term matches\n phraseMatch?: number; // Boost for phrase matches\n technicalMatch?: number; // Boost for technical term matches\n identifierMatch?: number; // Boost for identifier matches\n };\n } = {}\n): Promise<Array<{ uri: string; score: number; matchedTerms: string[] }>> {\n const { limit = 10, minScore = 0, boostFactors = {} } = options;\n const {\n exactMatch = 1.5,\n phraseMatch = 2.0,\n technicalMatch = 1.8,\n identifierMatch = 1.3,\n } = boostFactors;\n\n // Process query using Advanced Code Tokenizer\n const queryVector = await processQuery(query, index.idf);\n const queryTokens = (await extractQueryTokens(query)).map((t) => t.toLowerCase());\n\n // Calculate similarity for each document\n const results = index.documents.map((doc) => {\n let score = calculateCosineSimilarity(queryVector, doc);\n\n // Boost for exact term matches with enhanced scoring\n const matchedTerms: string[] = [];\n for (const token of queryTokens) {\n if (doc.rawTerms.has(token)) {\n // Apply different boost factors based on term characteristics\n let boostFactor = exactMatch;\n\n // Additional boost for technical terms\n if (isTechnicalTerm(token)) {\n boostFactor = Math.max(boostFactor, technicalMatch);\n }\n\n // Additional boost for identifiers\n if (isIdentifier(token)) {\n boostFactor = Math.max(boostFactor, identifierMatch);\n }\n\n score *= boostFactor;\n matchedTerms.push(token);\n }\n }\n\n // Enhanced phrase match detection (all query terms appear in document)\n if (matchedTerms.length === queryTokens.length && queryTokens.length > 1) {\n score *= phraseMatch;\n }\n\n // Contextual relevance boost for longer queries\n if (queryTokens.length > 3 && matchedTerms.length >= queryTokens.length * 0.7) {\n score *= 1.2; // Boost for partial matches on complex queries\n }\n\n return {\n uri: doc.uri,\n score,\n matchedTerms,\n };\n });\n\n // Filter and sort\n return results\n .filter((result) => result.score >= minScore)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n}\n\n/**\n * Check if a term is likely a technical term\n */\nfunction isTechnicalTerm(term: string): boolean {\n const technicalPatterns = [\n /\\b[A-Z]{2,}\\b/, // Acronyms like HTTP, API, JSON\n /\\b[A-Z][a-z]+(?:[A-Z][a-z]+)+\\b/, // PascalCase like ComponentName\n /\\b[a-z]+[A-Z][a-z]*\\b/, // camelCase like functionName\n /\\b\\w+(?:Dir|Config|File|Path|Data|Service|Manager|Handler)\\b/, // Common suffixes\n /\\b(?:get|set|is|has|can|should|will|do)[A-Z]\\w*\\b/, // Common prefixes\n /\\b(?:http|https|json|xml|yaml|sql|api|url|uri)\\b/, // Technical keywords\n ];\n\n return technicalPatterns.some((pattern) => pattern.test(term));\n}\n\n/**\n * Check if a term is likely an identifier\n */\nfunction isIdentifier(term: string): boolean {\n // Identifiers typically contain letters and numbers, maybe underscores\n return /^[a-zA-Z][a-zA-Z0-9_]*$/.test(term) && term.length > 1;\n}\n\n/**\n * Serialize search index to JSON\n */\nexport function serializeIndex(index: SearchIndex): string {\n const serializable = {\n documents: index.documents.map((doc) => ({\n uri: doc.uri,\n terms: Array.from(doc.terms.entries()),\n rawTerms: Array.from(doc.rawTerms.entries()),\n magnitude: doc.magnitude,\n })),\n idf: Array.from(index.idf.entries()),\n totalDocuments: index.totalDocuments,\n metadata: index.metadata,\n };\n\n return JSON.stringify(serializable, null, 2);\n}\n\n/**\n * Deserialize search index from JSON\n */\nexport function deserializeIndex(json: string): SearchIndex {\n const data = JSON.parse(json);\n\n return {\n documents: data.documents.map(\n (doc: {\n uri: string;\n terms: [string, number][];\n rawTerms: [string, number][];\n magnitude: number;\n }) => ({\n uri: doc.uri,\n terms: new Map(doc.terms),\n rawTerms: new Map(doc.rawTerms),\n magnitude: doc.magnitude,\n })\n ),\n idf: new Map(data.idf),\n totalDocuments: data.totalDocuments,\n metadata: data.metadata,\n };\n}\n"
7
7
  ],
8
8
  "mappings": "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",
9
- "debugId": "F6CC4F566F5A987064756E2164756E21",
9
+ "debugId": "A2D767B1A03BB0A664756E2164756E21",
10
10
  "names": []
11
11
  }