Packages
portfolio_coder
0.1.0
Code Intelligence Platform built on the Portfolio RAG ecosystem. Repository analysis, semantic code search, dependency graphs, and AI-powered code understanding with multi-language support.
Current section
Files
Jump to
Current section
Files
lib/portfolio_coder.ex
defmodule PortfolioCoder do
@moduledoc """
Code Intelligence Platform built on the Portfolio RAG Ecosystem.
Portfolio Coder provides:
- Repository indexing with multi-language support
- Semantic code search
- Dependency graph building and querying
- AI-powered code analysis
## Quick Start
# Index a repository
{:ok, stats} = PortfolioCoder.index_repo("/path/to/repo")
# Search code
{:ok, results} = PortfolioCoder.search_code("authentication")
# Ask questions
{:ok, answer} = PortfolioCoder.ask("How does this work?")
## Configuration
Configure in your manifest or application config:
config :portfolio_coder,
default_index: "default",
supported_languages: [:elixir, :python, :javascript]
"""
alias PortfolioCoder.Graph
alias PortfolioCoder.Indexer
alias PortfolioCoder.Search
@doc """
Returns the current version of Portfolio Coder.
"""
@spec version() :: String.t()
def version, do: "0.1.0"
@doc """
Index a code repository.
Scans the repository for source files, parses them, chunks the content,
and stores embeddings in the configured vector store.
## Options
- `:index_id` - Name of the index (default: "default")
- `:languages` - List of languages to index (default: all supported)
- `:exclude` - Patterns to exclude (default: deps/, _build/, etc.)
- `:chunk_size` - Size of text chunks (default: 1000)
- `:chunk_overlap` - Overlap between chunks (default: 200)
## Examples
{:ok, stats} = PortfolioCoder.index_repo("/path/to/repo")
{:ok, stats} = PortfolioCoder.index_repo("/path/to/repo",
index_id: "my_project",
languages: [:elixir]
)
"""
@spec index_repo(String.t(), keyword()) :: {:ok, map()} | {:error, term()}
def index_repo(repo_path, opts \\ []) do
Indexer.index_repo(repo_path, opts)
end
@doc """
Index specific files.
## Examples
{:ok, stats} = PortfolioCoder.index_files(["/path/to/file.ex"])
"""
@spec index_files([String.t()], keyword()) :: {:ok, map()} | {:error, term()}
def index_files(file_paths, opts \\ []) do
Indexer.index_files(file_paths, opts)
end
@doc """
Semantic code search.
Searches the indexed code using semantic similarity.
## Options
- `:index_id` - Index to search (default: "default")
- `:limit` - Maximum results (default: 10)
- `:language` - Filter by language
- `:file_pattern` - Filter by file pattern
## Examples
{:ok, results} = PortfolioCoder.search_code("authentication middleware")
{:ok, results} = PortfolioCoder.search_code("error handling",
language: :elixir,
limit: 5
)
"""
@spec search_code(String.t(), keyword()) :: {:ok, [map()]} | {:error, term()}
def search_code(query, opts \\ []) do
Search.semantic_search(query, opts)
end
@doc """
Text-based code search.
Searches using keyword matching.
## Examples
{:ok, results} = PortfolioCoder.search_text("def handle_call")
"""
@spec search_text(String.t(), keyword()) :: {:ok, [map()]} | {:error, term()}
def search_text(query, opts \\ []) do
Search.text_search(query, opts)
end
@doc """
Ask a question about the codebase.
Uses RAG to retrieve relevant code and generate an answer.
## Options
- `:index_id` - Index to query (default: "default")
- `:strategy` - RAG strategy (default: :hybrid)
- `:k` - Number of chunks to retrieve (default: 5)
## Examples
{:ok, answer} = PortfolioCoder.ask("How does authentication work?")
{:ok, answer} = PortfolioCoder.ask("What patterns are used?",
strategy: :self_rag
)
"""
@spec ask(String.t(), keyword()) :: {:ok, String.t()} | {:error, term()}
def ask(question, opts \\ []) do
Search.ask(question, opts)
end
@doc """
Stream an answer about the codebase.
## Examples
PortfolioCoder.stream_ask("Explain the architecture", fn chunk ->
IO.write(chunk)
end)
"""
@spec stream_ask(String.t(), (String.t() -> any()), keyword()) :: :ok | {:error, term()}
def stream_ask(question, callback, opts \\ []) when is_function(callback, 1) do
Search.stream_ask(question, callback, opts)
end
@doc """
Build a dependency graph from a repository.
## Options
- `:language` - Language to analyze (default: auto-detect)
## Examples
{:ok, stats} = PortfolioCoder.build_dependency_graph("deps", "/path/to/repo")
"""
@spec build_dependency_graph(String.t(), String.t(), keyword()) ::
{:ok, map()} | {:error, term()}
def build_dependency_graph(graph_id, repo_path, opts \\ []) do
Graph.build_dependency_graph(graph_id, repo_path, opts)
end
@doc """
Get dependencies of a module/package.
## Examples
{:ok, deps} = PortfolioCoder.get_dependencies("deps", "MyApp.Core")
"""
@spec get_dependencies(String.t(), String.t(), keyword()) ::
{:ok, [map()]} | {:error, term()}
def get_dependencies(graph_id, entity, opts \\ []) do
Graph.get_dependencies(graph_id, entity, opts)
end
@doc """
Get modules/packages that depend on an entity.
## Examples
{:ok, dependents} = PortfolioCoder.get_dependents("deps", "MyApp.Utils")
"""
@spec get_dependents(String.t(), String.t(), keyword()) ::
{:ok, [map()]} | {:error, term()}
def get_dependents(graph_id, entity, opts \\ []) do
Graph.get_dependents(graph_id, entity, opts)
end
@doc """
Find circular dependencies.
## Examples
{:ok, cycles} = PortfolioCoder.find_cycles("deps")
"""
@spec find_cycles(String.t()) :: {:ok, [[String.t()]]} | {:error, term()}
def find_cycles(graph_id) do
Graph.find_cycles(graph_id)
end
@doc """
Find usages of a symbol in the codebase.
## Examples
{:ok, usages} = PortfolioCoder.find_usages("MyApp.User", index_id: "my_project")
"""
@spec find_usages(String.t(), keyword()) :: {:ok, [map()]} | {:error, term()}
def find_usages(symbol, opts \\ []) do
Search.find_usages(symbol, opts)
end
@doc """
Get supported languages.
"""
@spec supported_languages() :: [atom()]
def supported_languages do
Application.get_env(:portfolio_coder, :supported_languages, [:elixir, :python, :javascript])
end
end