diff --git a/AGENTS.md b/AGENTS.md index 5501c30..4c00584 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,6 +30,7 @@ - **New tool**: Add definition in `tool_definitions.rs`, implement in `tools/`, add dispatch case - **New provider**: Implement `LLMProvider` trait in `g3-providers` - **New CLI mode**: Add to CLI args, implement handler in `g3-cli` +- **New skill**: Create `skills//SKILL.md`, optionally add to `embedded.rs` for binary inclusion - **New config option**: Add to `g3-config` structs ## Dangerous Code Paths @@ -43,6 +44,7 @@ These areas have subtle bugs if modified incorrectly: | **Tool dispatch** | Missing dispatch cases cause silent failures | | **Retry logic** | Aggressive retries hit rate limits harder | | **Parser sanitization** | Inline JSON can trigger false tool call detection | +| **Skill extraction** | Version hash mismatch causes stale scripts; path issues on Windows | ## Do's and Don'ts @@ -82,3 +84,24 @@ The `analysis/deps/` directory contains static analysis artifacts generated by t | `limitations.md` | What could not be observed and what may invalidate conclusions | These artifacts are useful for understanding coupling, planning refactors, and identifying architectural boundaries. + +## Skills System Entry Points + +The skills system (`crates/g3-core/src/skills/`) provides extensible agent capabilities: + +| File | Purpose | +|------|--------| +| `mod.rs` | Public API: `Skill`, `discover_skills`, `generate_skills_prompt` | +| `parser.rs` | SKILL.md parsing with YAML frontmatter validation | +| `discovery.rs` | Multi-location discovery with priority ordering | +| `embedded.rs` | Compile-time skill embedding via `include_str!` | +| `extraction.rs` | Script extraction to `.g3/bin/` with version tracking | +| `prompt.rs` | Generates `` XML for system prompt | + +**Key invariants for skills**: +- Skill names must be 1-64 chars, lowercase + hyphens only +- SKILL.md must have valid YAML frontmatter with `name` and `description` +- Embedded scripts are extracted lazily (on first use) +- Version tracking uses content hash, not timestamps +- Higher priority locations override lower (repo > workspace > global > embedded) +- Script extraction is Unix-only (chmod 755); Windows support is incomplete diff --git a/README.md b/README.md index 76cd08a..74454ea 100644 --- a/README.md +++ b/README.md @@ -114,9 +114,11 @@ These commands give you fine-grained control over context management, allowing y g3 supports the [Agent Skills](https://agentskills.io) specification - an open format for portable skill packages that give the agent new capabilities. **Skill Locations** (in priority order, later overrides earlier): -1. Global: `~/.g3/skills/` -2. Extra paths from config -3. Workspace: `.g3/skills/` (highest priority) +1. Embedded skills (compiled into binary) +2. Global: `~/.g3/skills/` +3. Extra paths from config +4. Workspace: `.g3/skills/` +5. Repo: `skills/` (highest priority, checked into git) **SKILL.md Format**: ```yaml @@ -146,6 +148,12 @@ Each skill adds ~50-100 tokens to context (name + description + path). Skills ca - `references/` - Additional documentation - `assets/` - Templates, data files +**Embedded Skills**: Core skills like `research` are compiled into the binary, ensuring they work anywhere without external files. Embedded scripts are automatically extracted to `.g3/bin/` on first use. + +**Built-in Research Skill**: Perform asynchronous web research via `background_process("research", ".g3/bin/g3-research 'your query'")`. Results are saved to `.g3/research//report.md`. + +See [Skills Guide](docs/skills.md) for detailed documentation. + ### Provider Flexibility - Support for multiple LLM providers through a unified interface - Hot-swappable providers without code changes @@ -483,6 +491,7 @@ Detailed documentation is available in the `docs/` directory: | [Tools Reference](docs/tools.md) | Complete reference for all available tools | | [Providers Guide](docs/providers.md) | LLM provider setup and selection guide | | [Control Commands](docs/CONTROL_COMMANDS.md) | Interactive `/` commands for context management | +| [Skills Guide](docs/skills.md) | Agent Skills system, SKILL.md format, creating skills | | [Code Search](docs/CODE_SEARCH.md) | Tree-sitter code search query patterns | For AI agents working with this codebase, see [AGENTS.md](AGENTS.md). diff --git a/analysis/breaker/2025-02-05.md b/analysis/breaker/2025-02-05.md new file mode 100644 index 0000000..e1bfd4b --- /dev/null +++ b/analysis/breaker/2025-02-05.md @@ -0,0 +1,138 @@ +# Breaker Report: 2025-02-05 + +Focused on changes in commits b6d2582..9443f933 (past 10 commits). + +## Issue 1: JSON Escaping Bug in g3-research Script + +### Title +`g3-research` produces invalid JSON when query contains actual newlines + +### Repro +```bash +# In skills/research/g3-research, the write_status function uses: +escaped_query=$(echo -n "$query" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g') + +# Test with actual newlines: +QUERY=$'What is\nthe best\nRust library?' +escaped=$(echo -n "$QUERY" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g') +echo "{\"query\": \"$escaped\"}" | python3 -m json.tool +# Output: Invalid control character at: line 1 column 19 (char 18) +``` + +**Expected**: Valid JSON with `\n` escape sequences +**Actual**: Invalid JSON with literal newline characters + +### Diagnosis +- **File**: `skills/research/g3-research:66` +- **Root cause**: The sed pattern `s/\n/\\n/g` matches the literal two-character string `\n`, not actual newline characters. Sed processes line-by-line by default and doesn't see newlines in the pattern space. +- **Triggering condition**: User query contains actual newline characters (e.g., from multi-line input or programmatic construction) +- **Deterministic**: Yes + +### Impact +- **Severity**: Incorrect behavior - `status.json` becomes unparseable +- **Likelihood**: Uncommon but possible - queries are typically single-line, but multi-line queries from programmatic sources or copy-paste could trigger this + +### Fix +Replace sed with perl which handles newlines correctly: +```bash +escaped_query=$(echo -n "$query" | perl -pe 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g') +``` + +--- + +## Issue 2: Embedded Skill Path Not Readable + +### Title +Embedded skills have non-existent file paths that agents are instructed to `read_file` + +### Repro +``` +# When no repo skills/ directory exists, the research skill is loaded from embedded +# The generated prompt contains: + + research + ... + /SKILL.md + + +# The prompt instructs: +"read the full skill file using `read_file` to get detailed instructions" + +# Agent attempts: +read_file("/SKILL.md") +# Result: File not found error +``` + +**Expected**: Agent can read skill documentation +**Actual**: File path doesn't exist on disk + +### Diagnosis +- **File**: `crates/g3-core/src/skills/discovery.rs:97` - sets path to `/SKILL.md` +- **File**: `crates/g3-core/src/skills/prompt.rs:14-15` - instructs agent to use `read_file` +- **Root cause**: Embedded skills use a synthetic path marker, but the prompt doesn't account for this +- **Triggering condition**: User has no `skills/` directory in their repo (embedded skill not overridden) +- **Deterministic**: Yes + +### Impact +- **Severity**: Annoying - agent will fail to read skill docs and may hallucinate or ask for help +- **Likelihood**: Common for users outside the g3 repo itself + +### Possible Fixes +1. Include the full skill body in the prompt for embedded skills (increases prompt size) +2. Add special handling in `read_file` for `` paths +3. Change prompt to say "skill instructions are below" for embedded skills and inline the body + +--- + +## Issue 3: Hardcoded 'main' Branch in SDLC Pipeline + +### Title +`studio sdlc` assumes default branch is named 'main' + +### Repro +```bash +# In a repo where default branch is 'master': +studio sdlc run + +# has_commits_on_branch runs: +git rev-list --count main..sdlc/session-branch +# Fails silently (returns Ok(false)) because 'main' doesn't exist + +# merge_to_main runs: +git checkout main +# Fails with "Failed to checkout main" +``` + +**Expected**: Works with any default branch name +**Actual**: Fails or behaves incorrectly on repos using 'master' or other branch names + +### Diagnosis +- **File**: `crates/studio/src/main.rs:720` - `has_commits_on_branch()` hardcodes `main..{branch}` +- **File**: `crates/studio/src/git.rs` - `merge_to_main()` hardcodes `checkout main` +- **Root cause**: No detection of actual default branch name +- **Triggering condition**: Repository uses 'master' or custom default branch +- **Deterministic**: Yes + +### Impact +- **Severity**: Incorrect behavior - merge fails or skipped incorrectly +- **Likelihood**: Common - many repos still use 'master' + +### Fix +Detect default branch: +```bash +git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@' +# or +git config --get init.defaultBranch +``` + +--- + +## Summary + +| # | Issue | Severity | Likelihood | +|---|-------|----------|------------| +| 1 | JSON escaping with newlines | Incorrect behavior | Uncommon | +| 2 | Embedded skill path unreadable | Annoying | Common | +| 3 | Hardcoded 'main' branch | Incorrect behavior | Common | + +All issues are deterministic and reproducible. diff --git a/analysis/deps/graph.json b/analysis/deps/graph.json index 7bc0c82..935bf79 100644 --- a/analysis/deps/graph.json +++ b/analysis/deps/graph.json @@ -1,344 +1,440 @@ { "metadata": { - "generated_by": "euler structural analysis agent", - "generated_at": "2025-02-02T17:30:00Z", - "workspace": "g3", - "node_count": 127, - "edge_count": 218, - "crate_count": 9, - "file_count": 118, - "extraction_method": "static import parsing via ripgrep" + "generated_at": "2025-02-05T14:00:00Z", + "scope": "Changes in commits b6d2582..9443f933 (10 commits)", + "extraction_method": "Static analysis of Rust use/mod statements and Cargo.toml", + "tool_version": "euler-manual-1.0" }, - "nodes": [ - {"id": "crate:g3", "type": "crate", "name": "g3", "path": "."}, - {"id": "crate:g3-cli", "type": "crate", "name": "g3-cli", "path": "crates/g3-cli"}, - {"id": "crate:g3-core", "type": "crate", "name": "g3-core", "path": "crates/g3-core"}, - {"id": "crate:g3-providers", "type": "crate", "name": "g3-providers", "path": "crates/g3-providers"}, - {"id": "crate:g3-config", "type": "crate", "name": "g3-config", "path": "crates/g3-config"}, - {"id": "crate:g3-execution", "type": "crate", "name": "g3-execution", "path": "crates/g3-execution"}, - {"id": "crate:g3-planner", "type": "crate", "name": "g3-planner", "path": "crates/g3-planner"}, - {"id": "crate:g3-computer-control", "type": "crate", "name": "g3-computer-control", "path": "crates/g3-computer-control"}, - {"id": "crate:studio", "type": "crate", "name": "studio", "path": "crates/studio"}, - - {"id": "file:crates/g3-cli/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-cli/src/lib.rs", "crate": "g3-cli", "module": null}, - {"id": "file:crates/g3-cli/src/accumulative.rs", "type": "file", "name": "accumulative.rs", "path": "crates/g3-cli/src/accumulative.rs", "crate": "g3-cli", "module": "accumulative"}, - {"id": "file:crates/g3-cli/src/agent_mode.rs", "type": "file", "name": "agent_mode.rs", "path": "crates/g3-cli/src/agent_mode.rs", "crate": "g3-cli", "module": "agent_mode"}, - {"id": "file:crates/g3-cli/src/autonomous.rs", "type": "file", "name": "autonomous.rs", "path": "crates/g3-cli/src/autonomous.rs", "crate": "g3-cli", "module": "autonomous"}, - {"id": "file:crates/g3-cli/src/cli_args.rs", "type": "file", "name": "cli_args.rs", "path": "crates/g3-cli/src/cli_args.rs", "crate": "g3-cli", "module": "cli_args"}, - {"id": "file:crates/g3-cli/src/coach_feedback.rs", "type": "file", "name": "coach_feedback.rs", "path": "crates/g3-cli/src/coach_feedback.rs", "crate": "g3-cli", "module": "coach_feedback"}, - {"id": "file:crates/g3-cli/src/commands.rs", "type": "file", "name": "commands.rs", "path": "crates/g3-cli/src/commands.rs", "crate": "g3-cli", "module": "commands"}, - {"id": "file:crates/g3-cli/src/completion.rs", "type": "file", "name": "completion.rs", "path": "crates/g3-cli/src/completion.rs", "crate": "g3-cli", "module": "completion"}, - {"id": "file:crates/g3-cli/src/display.rs", "type": "file", "name": "display.rs", "path": "crates/g3-cli/src/display.rs", "crate": "g3-cli", "module": "display"}, - {"id": "file:crates/g3-cli/src/embedded_agents.rs", "type": "file", "name": "embedded_agents.rs", "path": "crates/g3-cli/src/embedded_agents.rs", "crate": "g3-cli", "module": "embedded_agents"}, - {"id": "file:crates/g3-cli/src/filter_json.rs", "type": "file", "name": "filter_json.rs", "path": "crates/g3-cli/src/filter_json.rs", "crate": "g3-cli", "module": "filter_json"}, - {"id": "file:crates/g3-cli/src/g3_status.rs", "type": "file", "name": "g3_status.rs", "path": "crates/g3-cli/src/g3_status.rs", "crate": "g3-cli", "module": "g3_status"}, - {"id": "file:crates/g3-cli/src/input_formatter.rs", "type": "file", "name": "input_formatter.rs", "path": "crates/g3-cli/src/input_formatter.rs", "crate": "g3-cli", "module": "input_formatter"}, - {"id": "file:crates/g3-cli/src/interactive.rs", "type": "file", "name": "interactive.rs", "path": "crates/g3-cli/src/interactive.rs", "crate": "g3-cli", "module": "interactive"}, - {"id": "file:crates/g3-cli/src/language_prompts.rs", "type": "file", "name": "language_prompts.rs", "path": "crates/g3-cli/src/language_prompts.rs", "crate": "g3-cli", "module": "language_prompts"}, - {"id": "file:crates/g3-cli/src/metrics.rs", "type": "file", "name": "metrics.rs", "path": "crates/g3-cli/src/metrics.rs", "crate": "g3-cli", "module": "metrics"}, - {"id": "file:crates/g3-cli/src/project.rs", "type": "file", "name": "project.rs", "path": "crates/g3-cli/src/project.rs", "crate": "g3-cli", "module": "project"}, - {"id": "file:crates/g3-cli/src/project_files.rs", "type": "file", "name": "project_files.rs", "path": "crates/g3-cli/src/project_files.rs", "crate": "g3-cli", "module": "project_files"}, - {"id": "file:crates/g3-cli/src/simple_output.rs", "type": "file", "name": "simple_output.rs", "path": "crates/g3-cli/src/simple_output.rs", "crate": "g3-cli", "module": "simple_output"}, - {"id": "file:crates/g3-cli/src/streaming_markdown.rs", "type": "file", "name": "streaming_markdown.rs", "path": "crates/g3-cli/src/streaming_markdown.rs", "crate": "g3-cli", "module": "streaming_markdown"}, - {"id": "file:crates/g3-cli/src/task_execution.rs", "type": "file", "name": "task_execution.rs", "path": "crates/g3-cli/src/task_execution.rs", "crate": "g3-cli", "module": "task_execution"}, - {"id": "file:crates/g3-cli/src/template.rs", "type": "file", "name": "template.rs", "path": "crates/g3-cli/src/template.rs", "crate": "g3-cli", "module": "template"}, - {"id": "file:crates/g3-cli/src/theme.rs", "type": "file", "name": "theme.rs", "path": "crates/g3-cli/src/theme.rs", "crate": "g3-cli", "module": "theme"}, - {"id": "file:crates/g3-cli/src/ui_writer_impl.rs", "type": "file", "name": "ui_writer_impl.rs", "path": "crates/g3-cli/src/ui_writer_impl.rs", "crate": "g3-cli", "module": "ui_writer_impl"}, - {"id": "file:crates/g3-cli/src/utils.rs", "type": "file", "name": "utils.rs", "path": "crates/g3-cli/src/utils.rs", "crate": "g3-cli", "module": "utils"}, - - {"id": "file:crates/g3-core/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-core/src/lib.rs", "crate": "g3-core", "module": null}, - {"id": "file:crates/g3-core/src/acd.rs", "type": "file", "name": "acd.rs", "path": "crates/g3-core/src/acd.rs", "crate": "g3-core", "module": "acd"}, - {"id": "file:crates/g3-core/src/background_process.rs", "type": "file", "name": "background_process.rs", "path": "crates/g3-core/src/background_process.rs", "crate": "g3-core", "module": "background_process"}, - {"id": "file:crates/g3-core/src/code_search/mod.rs", "type": "file", "name": "mod.rs", "path": "crates/g3-core/src/code_search/mod.rs", "crate": "g3-core", "module": "code_search"}, - {"id": "file:crates/g3-core/src/code_search/searcher.rs", "type": "file", "name": "searcher.rs", "path": "crates/g3-core/src/code_search/searcher.rs", "crate": "g3-core", "module": "code_search::searcher"}, - {"id": "file:crates/g3-core/src/compaction.rs", "type": "file", "name": "compaction.rs", "path": "crates/g3-core/src/compaction.rs", "crate": "g3-core", "module": "compaction"}, - {"id": "file:crates/g3-core/src/context_window.rs", "type": "file", "name": "context_window.rs", "path": "crates/g3-core/src/context_window.rs", "crate": "g3-core", "module": "context_window"}, - {"id": "file:crates/g3-core/src/error_handling.rs", "type": "file", "name": "error_handling.rs", "path": "crates/g3-core/src/error_handling.rs", "crate": "g3-core", "module": "error_handling"}, - {"id": "file:crates/g3-core/src/feedback_extraction.rs", "type": "file", "name": "feedback_extraction.rs", "path": "crates/g3-core/src/feedback_extraction.rs", "crate": "g3-core", "module": "feedback_extraction"}, - {"id": "file:crates/g3-core/src/paths.rs", "type": "file", "name": "paths.rs", "path": "crates/g3-core/src/paths.rs", "crate": "g3-core", "module": "paths"}, - {"id": "file:crates/g3-core/src/pending_research.rs", "type": "file", "name": "pending_research.rs", "path": "crates/g3-core/src/pending_research.rs", "crate": "g3-core", "module": "pending_research"}, - {"id": "file:crates/g3-core/src/project.rs", "type": "file", "name": "project.rs", "path": "crates/g3-core/src/project.rs", "crate": "g3-core", "module": "project"}, - {"id": "file:crates/g3-core/src/prompts.rs", "type": "file", "name": "prompts.rs", "path": "crates/g3-core/src/prompts.rs", "crate": "g3-core", "module": "prompts"}, - {"id": "file:crates/g3-core/src/provider_config.rs", "type": "file", "name": "provider_config.rs", "path": "crates/g3-core/src/provider_config.rs", "crate": "g3-core", "module": "provider_config"}, - {"id": "file:crates/g3-core/src/provider_registration.rs", "type": "file", "name": "provider_registration.rs", "path": "crates/g3-core/src/provider_registration.rs", "crate": "g3-core", "module": "provider_registration"}, - {"id": "file:crates/g3-core/src/retry.rs", "type": "file", "name": "retry.rs", "path": "crates/g3-core/src/retry.rs", "crate": "g3-core", "module": "retry"}, - {"id": "file:crates/g3-core/src/session.rs", "type": "file", "name": "session.rs", "path": "crates/g3-core/src/session.rs", "crate": "g3-core", "module": "session"}, - {"id": "file:crates/g3-core/src/session_continuation.rs", "type": "file", "name": "session_continuation.rs", "path": "crates/g3-core/src/session_continuation.rs", "crate": "g3-core", "module": "session_continuation"}, - {"id": "file:crates/g3-core/src/stats.rs", "type": "file", "name": "stats.rs", "path": "crates/g3-core/src/stats.rs", "crate": "g3-core", "module": "stats"}, - {"id": "file:crates/g3-core/src/streaming.rs", "type": "file", "name": "streaming.rs", "path": "crates/g3-core/src/streaming.rs", "crate": "g3-core", "module": "streaming"}, - {"id": "file:crates/g3-core/src/streaming_parser.rs", "type": "file", "name": "streaming_parser.rs", "path": "crates/g3-core/src/streaming_parser.rs", "crate": "g3-core", "module": "streaming_parser"}, - {"id": "file:crates/g3-core/src/task_result.rs", "type": "file", "name": "task_result.rs", "path": "crates/g3-core/src/task_result.rs", "crate": "g3-core", "module": "task_result"}, - {"id": "file:crates/g3-core/src/tool_definitions.rs", "type": "file", "name": "tool_definitions.rs", "path": "crates/g3-core/src/tool_definitions.rs", "crate": "g3-core", "module": "tool_definitions"}, - {"id": "file:crates/g3-core/src/tool_dispatch.rs", "type": "file", "name": "tool_dispatch.rs", "path": "crates/g3-core/src/tool_dispatch.rs", "crate": "g3-core", "module": "tool_dispatch"}, - {"id": "file:crates/g3-core/src/tools/mod.rs", "type": "file", "name": "mod.rs", "path": "crates/g3-core/src/tools/mod.rs", "crate": "g3-core", "module": "tools"}, - {"id": "file:crates/g3-core/src/tools/acd.rs", "type": "file", "name": "acd.rs", "path": "crates/g3-core/src/tools/acd.rs", "crate": "g3-core", "module": "tools::acd"}, - {"id": "file:crates/g3-core/src/tools/executor.rs", "type": "file", "name": "executor.rs", "path": "crates/g3-core/src/tools/executor.rs", "crate": "g3-core", "module": "tools::executor"}, - {"id": "file:crates/g3-core/src/tools/file_ops.rs", "type": "file", "name": "file_ops.rs", "path": "crates/g3-core/src/tools/file_ops.rs", "crate": "g3-core", "module": "tools::file_ops"}, - {"id": "file:crates/g3-core/src/tools/memory.rs", "type": "file", "name": "memory.rs", "path": "crates/g3-core/src/tools/memory.rs", "crate": "g3-core", "module": "tools::memory"}, - {"id": "file:crates/g3-core/src/tools/misc.rs", "type": "file", "name": "misc.rs", "path": "crates/g3-core/src/tools/misc.rs", "crate": "g3-core", "module": "tools::misc"}, - {"id": "file:crates/g3-core/src/tools/plan.rs", "type": "file", "name": "plan.rs", "path": "crates/g3-core/src/tools/plan.rs", "crate": "g3-core", "module": "tools::plan"}, - {"id": "file:crates/g3-core/src/tools/research.rs", "type": "file", "name": "research.rs", "path": "crates/g3-core/src/tools/research.rs", "crate": "g3-core", "module": "tools::research"}, - {"id": "file:crates/g3-core/src/tools/shell.rs", "type": "file", "name": "shell.rs", "path": "crates/g3-core/src/tools/shell.rs", "crate": "g3-core", "module": "tools::shell"}, - {"id": "file:crates/g3-core/src/tools/webdriver.rs", "type": "file", "name": "webdriver.rs", "path": "crates/g3-core/src/tools/webdriver.rs", "crate": "g3-core", "module": "tools::webdriver"}, - {"id": "file:crates/g3-core/src/ui_writer.rs", "type": "file", "name": "ui_writer.rs", "path": "crates/g3-core/src/ui_writer.rs", "crate": "g3-core", "module": "ui_writer"}, - {"id": "file:crates/g3-core/src/utils.rs", "type": "file", "name": "utils.rs", "path": "crates/g3-core/src/utils.rs", "crate": "g3-core", "module": "utils"}, - {"id": "file:crates/g3-core/src/webdriver_session.rs", "type": "file", "name": "webdriver_session.rs", "path": "crates/g3-core/src/webdriver_session.rs", "crate": "g3-core", "module": "webdriver_session"}, - - {"id": "file:crates/g3-providers/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-providers/src/lib.rs", "crate": "g3-providers", "module": null}, - {"id": "file:crates/g3-providers/src/anthropic.rs", "type": "file", "name": "anthropic.rs", "path": "crates/g3-providers/src/anthropic.rs", "crate": "g3-providers", "module": "anthropic"}, - {"id": "file:crates/g3-providers/src/databricks.rs", "type": "file", "name": "databricks.rs", "path": "crates/g3-providers/src/databricks.rs", "crate": "g3-providers", "module": "databricks"}, - {"id": "file:crates/g3-providers/src/embedded/mod.rs", "type": "file", "name": "mod.rs", "path": "crates/g3-providers/src/embedded/mod.rs", "crate": "g3-providers", "module": "embedded"}, - {"id": "file:crates/g3-providers/src/embedded/provider.rs", "type": "file", "name": "provider.rs", "path": "crates/g3-providers/src/embedded/provider.rs", "crate": "g3-providers", "module": "embedded::provider"}, - {"id": "file:crates/g3-providers/src/embedded/adapters/mod.rs", "type": "file", "name": "mod.rs", "path": "crates/g3-providers/src/embedded/adapters/mod.rs", "crate": "g3-providers", "module": "embedded::adapters"}, - {"id": "file:crates/g3-providers/src/embedded/adapters/glm.rs", "type": "file", "name": "glm.rs", "path": "crates/g3-providers/src/embedded/adapters/glm.rs", "crate": "g3-providers", "module": "embedded::adapters::glm"}, - {"id": "file:crates/g3-providers/src/gemini.rs", "type": "file", "name": "gemini.rs", "path": "crates/g3-providers/src/gemini.rs", "crate": "g3-providers", "module": "gemini"}, - {"id": "file:crates/g3-providers/src/mock.rs", "type": "file", "name": "mock.rs", "path": "crates/g3-providers/src/mock.rs", "crate": "g3-providers", "module": "mock"}, - {"id": "file:crates/g3-providers/src/oauth.rs", "type": "file", "name": "oauth.rs", "path": "crates/g3-providers/src/oauth.rs", "crate": "g3-providers", "module": "oauth"}, - {"id": "file:crates/g3-providers/src/openai.rs", "type": "file", "name": "openai.rs", "path": "crates/g3-providers/src/openai.rs", "crate": "g3-providers", "module": "openai"}, - {"id": "file:crates/g3-providers/src/streaming.rs", "type": "file", "name": "streaming.rs", "path": "crates/g3-providers/src/streaming.rs", "crate": "g3-providers", "module": "streaming"}, - - {"id": "file:crates/g3-config/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-config/src/lib.rs", "crate": "g3-config", "module": null}, - - {"id": "file:crates/g3-execution/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-execution/src/lib.rs", "crate": "g3-execution", "module": null}, - - {"id": "file:crates/g3-planner/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-planner/src/lib.rs", "crate": "g3-planner", "module": null}, - {"id": "file:crates/g3-planner/src/code_explore.rs", "type": "file", "name": "code_explore.rs", "path": "crates/g3-planner/src/code_explore.rs", "crate": "g3-planner", "module": "code_explore"}, - {"id": "file:crates/g3-planner/src/git.rs", "type": "file", "name": "git.rs", "path": "crates/g3-planner/src/git.rs", "crate": "g3-planner", "module": "git"}, - {"id": "file:crates/g3-planner/src/history.rs", "type": "file", "name": "history.rs", "path": "crates/g3-planner/src/history.rs", "crate": "g3-planner", "module": "history"}, - {"id": "file:crates/g3-planner/src/llm.rs", "type": "file", "name": "llm.rs", "path": "crates/g3-planner/src/llm.rs", "crate": "g3-planner", "module": "llm"}, - {"id": "file:crates/g3-planner/src/planner.rs", "type": "file", "name": "planner.rs", "path": "crates/g3-planner/src/planner.rs", "crate": "g3-planner", "module": "planner"}, - {"id": "file:crates/g3-planner/src/prompts.rs", "type": "file", "name": "prompts.rs", "path": "crates/g3-planner/src/prompts.rs", "crate": "g3-planner", "module": "prompts"}, - {"id": "file:crates/g3-planner/src/state.rs", "type": "file", "name": "state.rs", "path": "crates/g3-planner/src/state.rs", "crate": "g3-planner", "module": "state"}, - - {"id": "file:crates/g3-computer-control/src/lib.rs", "type": "file", "name": "lib.rs", "path": "crates/g3-computer-control/src/lib.rs", "crate": "g3-computer-control", "module": null}, - {"id": "file:crates/g3-computer-control/src/types.rs", "type": "file", "name": "types.rs", "path": "crates/g3-computer-control/src/types.rs", "crate": "g3-computer-control", "module": "types"}, - {"id": "file:crates/g3-computer-control/src/platform/mod.rs", "type": "file", "name": "mod.rs", "path": "crates/g3-computer-control/src/platform/mod.rs", "crate": "g3-computer-control", "module": "platform"}, - {"id": "file:crates/g3-computer-control/src/platform/macos.rs", "type": "file", "name": "macos.rs", "path": "crates/g3-computer-control/src/platform/macos.rs", "crate": "g3-computer-control", "module": "platform::macos"}, - {"id": "file:crates/g3-computer-control/src/platform/linux.rs", "type": "file", "name": "linux.rs", "path": "crates/g3-computer-control/src/platform/linux.rs", "crate": "g3-computer-control", "module": "platform::linux"}, - {"id": "file:crates/g3-computer-control/src/platform/windows.rs", "type": "file", "name": "windows.rs", "path": "crates/g3-computer-control/src/platform/windows.rs", "crate": "g3-computer-control", "module": "platform::windows"}, - {"id": "file:crates/g3-computer-control/src/webdriver/mod.rs", "type": "file", "name": "mod.rs", "path": "crates/g3-computer-control/src/webdriver/mod.rs", "crate": "g3-computer-control", "module": "webdriver"}, - {"id": "file:crates/g3-computer-control/src/webdriver/safari.rs", "type": "file", "name": "safari.rs", "path": "crates/g3-computer-control/src/webdriver/safari.rs", "crate": "g3-computer-control", "module": "webdriver::safari"}, - {"id": "file:crates/g3-computer-control/src/webdriver/chrome.rs", "type": "file", "name": "chrome.rs", "path": "crates/g3-computer-control/src/webdriver/chrome.rs", "crate": "g3-computer-control", "module": "webdriver::chrome"}, - {"id": "file:crates/g3-computer-control/src/webdriver/diagnostics.rs", "type": "file", "name": "diagnostics.rs", "path": "crates/g3-computer-control/src/webdriver/diagnostics.rs", "crate": "g3-computer-control", "module": "webdriver::diagnostics"}, - - {"id": "file:crates/studio/src/main.rs", "type": "file", "name": "main.rs", "path": "crates/studio/src/main.rs", "crate": "studio", "module": null}, - {"id": "file:crates/studio/src/git.rs", "type": "file", "name": "git.rs", "path": "crates/studio/src/git.rs", "crate": "studio", "module": "git"}, - {"id": "file:crates/studio/src/session.rs", "type": "file", "name": "session.rs", "path": "crates/studio/src/session.rs", "crate": "studio", "module": "session"} - ], - "edges": [ - {"from": "crate:g3", "to": "crate:g3-cli", "type": "crate_dependency", "evidence": "Cargo.toml: g3-cli = { path = \"crates/g3-cli\" }"}, - {"from": "crate:g3", "to": "crate:g3-providers", "type": "crate_dependency", "evidence": "Cargo.toml: g3-providers = { path = \"crates/g3-providers\" }"}, - - {"from": "crate:g3-cli", "to": "crate:g3-core", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-core = { path = \"../g3-core\" }"}, - {"from": "crate:g3-cli", "to": "crate:g3-config", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-config = { path = \"../g3-config\" }"}, - {"from": "crate:g3-cli", "to": "crate:g3-planner", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-planner = { path = \"../g3-planner\" }"}, - {"from": "crate:g3-cli", "to": "crate:g3-computer-control", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-computer-control = { path = \"../g3-computer-control\" }"}, - {"from": "crate:g3-cli", "to": "crate:g3-providers", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-providers = { path = \"../g3-providers\" }"}, - - {"from": "crate:g3-core", "to": "crate:g3-providers", "type": "crate_dependency", "evidence": "crates/g3-core/Cargo.toml: g3-providers = { path = \"../g3-providers\" }"}, - {"from": "crate:g3-core", "to": "crate:g3-config", "type": "crate_dependency", "evidence": "crates/g3-core/Cargo.toml: g3-config = { path = \"../g3-config\" }"}, - {"from": "crate:g3-core", "to": "crate:g3-execution", "type": "crate_dependency", "evidence": "crates/g3-core/Cargo.toml: g3-execution = { path = \"../g3-execution\" }"}, - {"from": "crate:g3-core", "to": "crate:g3-computer-control", "type": "crate_dependency", "evidence": "crates/g3-core/Cargo.toml: g3-computer-control = { path = \"../g3-computer-control\" }"}, - - {"from": "crate:g3-planner", "to": "crate:g3-providers", "type": "crate_dependency", "evidence": "crates/g3-planner/Cargo.toml: g3-providers = { path = \"../g3-providers\" }"}, - {"from": "crate:g3-planner", "to": "crate:g3-core", "type": "crate_dependency", "evidence": "crates/g3-planner/Cargo.toml: g3-core = { path = \"../g3-core\" }"}, - {"from": "crate:g3-planner", "to": "crate:g3-config", "type": "crate_dependency", "evidence": "crates/g3-planner/Cargo.toml: g3-config = { path = \"../g3-config\" }"}, - - {"from": "file:crates/g3-cli/src/lib.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - {"from": "file:crates/g3-cli/src/lib.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::project::Project; use g3_core::Agent; use g3_core::ui_writer::UiWriter"}, - - {"from": "file:crates/g3-cli/src/utils.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - {"from": "file:crates/g3-cli/src/utils.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::ui_writer::UiWriter; use g3_core::Agent"}, - {"from": "file:crates/g3-cli/src/utils.rs", "to": "file:crates/g3-cli/src/cli_args.rs", "type": "import", "evidence": "use crate::cli_args::Cli"}, - {"from": "file:crates/g3-cli/src/utils.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::ui_writer::UiWriter; use g3_core::Agent; use g3_core::ToolCall"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/completion.rs", "type": "import", "evidence": "use crate::completion::G3Helper"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/commands.rs", "type": "import", "evidence": "use crate::commands::{handle_command, CommandResult}"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/display.rs", "type": "import", "evidence": "use crate::display::{LoadedContent, print_loaded_status, print_project_heading, print_workspace_path}"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/g3_status.rs", "type": "import", "evidence": "use crate::g3_status::{G3Status, Status}"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/project.rs", "type": "import", "evidence": "use crate::project::Project"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/project_files.rs", "type": "import", "evidence": "use crate::project_files::extract_project_heading"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/input_formatter.rs", "type": "import", "evidence": "use crate::input_formatter::reprint_formatted_input"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/task_execution.rs", "type": "import", "evidence": "use crate::task_execution::execute_task_with_retry"}, - {"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/utils.rs", "type": "import", "evidence": "use crate::utils::display_context_progress"}, - - {"from": "file:crates/g3-cli/src/ui_writer_impl.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::ui_writer::UiWriter"}, - {"from": "file:crates/g3-cli/src/ui_writer_impl.rs", "to": "file:crates/g3-cli/src/filter_json.rs", "type": "import", "evidence": "use crate::filter_json::{filter_json_tool_calls, reset_json_tool_state, ToolParsingHint}"}, - {"from": "file:crates/g3-cli/src/ui_writer_impl.rs", "to": "file:crates/g3-cli/src/display.rs", "type": "import", "evidence": "use crate::display::{shorten_path, shorten_paths_in_command}"}, - {"from": "file:crates/g3-cli/src/ui_writer_impl.rs", "to": "file:crates/g3-cli/src/streaming_markdown.rs", "type": "import", "evidence": "use crate::streaming_markdown::StreamingMarkdownFormatter"}, - - {"from": "file:crates/g3-cli/src/autonomous.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::error_handling::{classify_error, ErrorType, RecoverableError}; use g3_core::project::Project; use g3_core::{Agent, DiscoveryOptions}; use g3_core::ui_writer::UiWriter"}, - {"from": "file:crates/g3-cli/src/autonomous.rs", "to": "file:crates/g3-cli/src/coach_feedback.rs", "type": "import", "evidence": "use crate::coach_feedback"}, - {"from": "file:crates/g3-cli/src/autonomous.rs", "to": "file:crates/g3-cli/src/metrics.rs", "type": "import", "evidence": "use crate::metrics::{format_elapsed_time, generate_turn_histogram, TurnMetrics}"}, - {"from": "file:crates/g3-cli/src/autonomous.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/autonomous.rs", "to": "file:crates/g3-cli/src/ui_writer_impl.rs", "type": "import", "evidence": "use crate::ui_writer_impl::ConsoleUiWriter"}, - - {"from": "file:crates/g3-cli/src/project_files.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, - - {"from": "file:crates/g3-cli/src/coach_feedback.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::Agent"}, - {"from": "file:crates/g3-cli/src/coach_feedback.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/coach_feedback.rs", "to": "file:crates/g3-cli/src/ui_writer_impl.rs", "type": "import", "evidence": "use crate::ui_writer_impl::ConsoleUiWriter"}, - - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::project::Project; use g3_core::Agent; use g3_core::ui_writer::UiWriter"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/autonomous.rs", "type": "import", "evidence": "use crate::autonomous::run_autonomous"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/cli_args.rs", "type": "import", "evidence": "use crate::cli_args::Cli"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/interactive.rs", "type": "import", "evidence": "use crate::interactive::run_interactive"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/ui_writer_impl.rs", "type": "import", "evidence": "use crate::ui_writer_impl::ConsoleUiWriter"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/utils.rs", "type": "import", "evidence": "use crate::utils::load_config_with_cli_overrides"}, - {"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, - - {"from": "file:crates/g3-cli/src/input_formatter.rs", "to": "file:crates/g3-cli/src/streaming_markdown.rs", "type": "import", "evidence": "use crate::streaming_markdown::StreamingMarkdownFormatter"}, - - {"from": "file:crates/g3-cli/src/simple_output.rs", "to": "file:crates/g3-cli/src/g3_status.rs", "type": "import", "evidence": "use crate::g3_status::{G3Status, Status}"}, - - {"from": "file:crates/g3-cli/src/task_execution.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::error_handling::{calculate_retry_delay, classify_error, ErrorType, RecoverableError}; use g3_core::ui_writer::UiWriter; use g3_core::Agent"}, - {"from": "file:crates/g3-cli/src/task_execution.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/task_execution.rs", "to": "file:crates/g3-cli/src/g3_status.rs", "type": "import", "evidence": "use crate::g3_status::G3Status"}, - - {"from": "file:crates/g3-cli/src/commands.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::ui_writer::UiWriter; use g3_core::Agent"}, - {"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/completion.rs", "type": "import", "evidence": "use crate::completion::G3Helper"}, - {"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/g3_status.rs", "type": "import", "evidence": "use crate::g3_status::{G3Status, Status}"}, - {"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/project.rs", "type": "import", "evidence": "use crate::project::Project; use crate::project::load_and_validate_project"}, - {"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, - {"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/task_execution.rs", "type": "import", "evidence": "use crate::task_execution::execute_task_with_retry"}, - - {"from": "file:crates/g3-cli/src/embedded_agents.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, - - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::ui_writer::UiWriter; use g3_core::Agent"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/project_files.rs", "type": "import", "evidence": "use crate::project_files::{combine_project_content, read_agents_config, read_include_prompt, read_workspace_memory}"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/display.rs", "type": "import", "evidence": "use crate::display::{LoadedContent, print_loaded_status, print_workspace_path}"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/language_prompts.rs", "type": "import", "evidence": "use crate::language_prompts::{get_language_prompts_for_workspace, get_agent_language_prompts_for_workspace_with_langs}"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/simple_output.rs", "type": "import", "evidence": "use crate::simple_output::SimpleOutput"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/embedded_agents.rs", "type": "import", "evidence": "use crate::embedded_agents::load_agent_prompt"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/ui_writer_impl.rs", "type": "import", "evidence": "use crate::ui_writer_impl::ConsoleUiWriter"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/interactive.rs", "type": "import", "evidence": "use crate::interactive::run_interactive"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/project.rs", "type": "import", "evidence": "use crate::project::{Project, load_and_validate_project}"}, - {"from": "file:crates/g3-cli/src/agent_mode.rs", "to": "file:crates/g3-cli/src/cli_args.rs", "type": "import", "evidence": "use crate::cli_args::CommonFlags"}, - - {"from": "file:crates/g3-core/src/lib.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - {"from": "file:crates/g3-core/src/lib.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CacheControl, CompletionRequest, Message, MessageRole, ProviderRegistry}"}, - {"from": "file:crates/g3-core/src/lib.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - - {"from": "file:crates/g3-core/src/retry.rs", "to": "file:crates/g3-core/src/error_handling.rs", "type": "import", "evidence": "use crate::error_handling::{calculate_retry_delay, classify_error, ErrorType, RecoverableError}"}, - {"from": "file:crates/g3-core/src/retry.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/retry.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::{Agent, DiscoveryOptions, TaskResult}"}, - - {"from": "file:crates/g3-core/src/provider_config.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - - {"from": "file:crates/g3-core/src/compaction.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CompletionRequest, Message, MessageRole, ProviderRegistry}"}, - {"from": "file:crates/g3-core/src/compaction.rs", "to": "file:crates/g3-core/src/context_window.rs", "type": "import", "evidence": "use crate::context_window::ContextWindow"}, - {"from": "file:crates/g3-core/src/compaction.rs", "to": "file:crates/g3-core/src/provider_config.rs", "type": "import", "evidence": "use crate::provider_config"}, - {"from": "file:crates/g3-core/src/compaction.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - - {"from": "file:crates/g3-core/src/stats.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::MessageRole"}, - {"from": "file:crates/g3-core/src/stats.rs", "to": "file:crates/g3-core/src/context_window.rs", "type": "import", "evidence": "use crate::context_window::ContextWindow"}, - {"from": "file:crates/g3-core/src/stats.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::CacheStats"}, - - {"from": "file:crates/g3-core/src/streaming.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CompletionRequest, MessageRole}"}, - {"from": "file:crates/g3-core/src/streaming.rs", "to": "file:crates/g3-core/src/context_window.rs", "type": "import", "evidence": "use crate::context_window::ContextWindow"}, - {"from": "file:crates/g3-core/src/streaming.rs", "to": "file:crates/g3-core/src/streaming_parser.rs", "type": "import", "evidence": "use crate::streaming_parser::StreamingToolParser"}, - {"from": "file:crates/g3-core/src/streaming.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tool_definitions.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::Tool"}, - - {"from": "file:crates/g3-core/src/provider_registration.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - {"from": "file:crates/g3-core/src/provider_registration.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::ProviderRegistry"}, - - {"from": "file:crates/g3-core/src/webdriver_session.rs", "to": "crate:g3-computer-control", "type": "import", "evidence": "use g3_computer_control::{ChromeDriver, SafariDriver, WebDriverController, WebElement}"}, - - {"from": "file:crates/g3-core/src/acd.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::Message"}, - {"from": "file:crates/g3-core/src/acd.rs", "to": "file:crates/g3-core/src/paths.rs", "type": "import", "evidence": "use crate::paths::get_fragments_dir"}, - {"from": "file:crates/g3-core/src/acd.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/streaming_parser.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/task_result.rs", "to": "file:crates/g3-core/src/context_window.rs", "type": "import", "evidence": "use crate::ContextWindow"}, - - {"from": "file:crates/g3-core/src/tool_dispatch.rs", "to": "file:crates/g3-core/src/tools/executor.rs", "type": "import", "evidence": "use crate::tools::executor::ToolContext"}, - {"from": "file:crates/g3-core/src/tool_dispatch.rs", "to": "file:crates/g3-core/src/tools/mod.rs", "type": "import", "evidence": "use crate::tools::{acd, file_ops, memory, misc, plan, research, shell, webdriver}"}, - {"from": "file:crates/g3-core/src/tool_dispatch.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tool_dispatch.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/session.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::MessageRole"}, - {"from": "file:crates/g3-core/src/session.rs", "to": "file:crates/g3-core/src/context_window.rs", "type": "import", "evidence": "use crate::context_window::ContextWindow"}, - {"from": "file:crates/g3-core/src/session.rs", "to": "file:crates/g3-core/src/paths.rs", "type": "import", "evidence": "use crate::paths::{ensure_session_dir, get_context_summary_file, get_g3_dir, get_session_file}"}, - - {"from": "file:crates/g3-core/src/context_window.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{Message, MessageRole, Usage}"}, - {"from": "file:crates/g3-core/src/context_window.rs", "to": "file:crates/g3-core/src/paths.rs", "type": "import", "evidence": "use crate::paths::get_thinned_dir"}, - {"from": "file:crates/g3-core/src/context_window.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/feedback_extraction.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::{Agent, TaskResult}"}, - {"from": "file:crates/g3-core/src/feedback_extraction.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - - {"from": "file:crates/g3-core/src/tools/acd.rs", "to": "file:crates/g3-core/src/acd.rs", "type": "import", "evidence": "use crate::acd::Fragment"}, - {"from": "file:crates/g3-core/src/tools/acd.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/acd.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/background_process.rs", "type": "import", "evidence": "use crate::background_process::BackgroundProcessManager"}, - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/pending_research.rs", "type": "import", "evidence": "use crate::pending_research::PendingResearchManager"}, - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/paths.rs", "type": "import", "evidence": "use crate::paths::{ensure_session_dir, get_session_todo_path, get_todo_path}"}, - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/webdriver_session.rs", "type": "import", "evidence": "use crate::webdriver_session::WebDriverSession"}, - {"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/shell.rs", "to": "file:crates/g3-core/src/paths.rs", "type": "import", "evidence": "use crate::paths::{generate_short_id, get_tools_output_dir}"}, - {"from": "file:crates/g3-core/src/tools/shell.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/shell.rs", "to": "file:crates/g3-core/src/utils.rs", "type": "import", "evidence": "use crate::utils::resolve_paths_in_shell_command; use crate::utils::shell_escape_command"}, - {"from": "file:crates/g3-core/src/tools/shell.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/research.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::WebDriverBrowser"}, - {"from": "file:crates/g3-core/src/tools/research.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/research.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/file_ops.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/file_ops.rs", "to": "file:crates/g3-core/src/utils.rs", "type": "import", "evidence": "use crate::utils::resolve_path_with_unicode_fallback; use crate::utils::apply_unified_diff_to_string"}, - {"from": "file:crates/g3-core/src/tools/file_ops.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/plan.rs", "to": "file:crates/g3-core/src/paths.rs", "type": "import", "evidence": "use crate::paths::{ensure_session_dir, get_session_logs_dir}"}, - {"from": "file:crates/g3-core/src/tools/plan.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/plan.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/memory.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/memory.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/misc.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/misc.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-core/src/tools/webdriver.rs", "to": "crate:g3-computer-control", "type": "import", "evidence": "use g3_computer_control::WebDriverController"}, - {"from": "file:crates/g3-core/src/tools/webdriver.rs", "to": "file:crates/g3-core/src/ui_writer.rs", "type": "import", "evidence": "use crate::ui_writer::UiWriter"}, - {"from": "file:crates/g3-core/src/tools/webdriver.rs", "to": "file:crates/g3-core/src/webdriver_session.rs", "type": "import", "evidence": "use crate::webdriver_session::WebDriverSession"}, - {"from": "file:crates/g3-core/src/tools/webdriver.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, - - {"from": "file:crates/g3-providers/src/openai.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-providers/src/anthropic.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-providers/src/gemini.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-providers/src/databricks.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-providers/src/databricks.rs", "to": "file:crates/g3-providers/src/streaming.rs", "type": "import", "evidence": "use crate::streaming::{decode_utf8_streaming, is_incomplete_json_error, make_final_chunk}"}, - {"from": "file:crates/g3-providers/src/mock.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-providers/src/embedded/provider.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-providers/src/streaming.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{CompletionChunk, ToolCall, Usage}"}, - - {"from": "file:crates/g3-planner/src/lib.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CompletionRequest, LLMProvider, Message, MessageRole}"}, - {"from": "file:crates/g3-planner/src/llm.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, - {"from": "file:crates/g3-planner/src/llm.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::project::Project; use g3_core::Agent; use g3_core::error_handling::{classify_error, ErrorType}"}, - {"from": "file:crates/g3-planner/src/llm.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CompletionRequest, LLMProvider, Message, MessageRole}"}, - {"from": "file:crates/g3-planner/src/llm.rs", "to": "file:crates/g3-planner/src/prompts.rs", "type": "import", "evidence": "use crate::prompts"}, - {"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/git.rs", "type": "import", "evidence": "use crate::git"}, - {"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/history.rs", "type": "import", "evidence": "use crate::history"}, - {"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/llm.rs", "type": "import", "evidence": "use crate::llm"}, - {"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/state.rs", "type": "import", "evidence": "use crate::state::{...}"}, - - {"from": "file:crates/g3-computer-control/src/platform/macos.rs", "to": "file:crates/g3-computer-control/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, - {"from": "file:crates/g3-computer-control/src/platform/linux.rs", "to": "file:crates/g3-computer-control/src/lib.rs", "type": "import", "evidence": "use crate::{types::Rect, ComputerController}"}, - {"from": "file:crates/g3-computer-control/src/platform/windows.rs", "to": "file:crates/g3-computer-control/src/lib.rs", "type": "import", "evidence": "use crate::{types::Rect, ComputerController}"}, - - {"from": "file:crates/studio/src/git.rs", "to": "file:crates/studio/src/session.rs", "type": "import", "evidence": "use crate::session::Session"} - ] + "nodes": { + "crates": [ + { + "id": "g3-core", + "type": "crate", + "path": "crates/g3-core", + "changed_in_scope": true + }, + { + "id": "g3-cli", + "type": "crate", + "path": "crates/g3-cli", + "changed_in_scope": true + }, + { + "id": "g3-config", + "type": "crate", + "path": "crates/g3-config", + "changed_in_scope": true + }, + { + "id": "studio", + "type": "crate", + "path": "crates/studio", + "changed_in_scope": true + }, + { + "id": "g3-providers", + "type": "crate", + "path": "crates/g3-providers", + "changed_in_scope": false + }, + { + "id": "g3-execution", + "type": "crate", + "path": "crates/g3-execution", + "changed_in_scope": false + }, + { + "id": "g3-computer-control", + "type": "crate", + "path": "crates/g3-computer-control", + "changed_in_scope": false + }, + { + "id": "g3-planner", + "type": "crate", + "path": "crates/g3-planner", + "changed_in_scope": false + } + ], + "files": [ + { + "id": "g3-core/src/skills/mod.rs", + "type": "module", + "crate": "g3-core", + "status": "added" + }, + { + "id": "g3-core/src/skills/parser.rs", + "type": "file", + "crate": "g3-core", + "status": "added" + }, + { + "id": "g3-core/src/skills/discovery.rs", + "type": "file", + "crate": "g3-core", + "status": "added" + }, + { + "id": "g3-core/src/skills/prompt.rs", + "type": "file", + "crate": "g3-core", + "status": "added" + }, + { + "id": "g3-core/src/skills/embedded.rs", + "type": "file", + "crate": "g3-core", + "status": "added" + }, + { + "id": "g3-core/src/skills/extraction.rs", + "type": "file", + "crate": "g3-core", + "status": "added" + }, + { + "id": "g3-core/src/prompts.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/lib.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/tool_definitions.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/tool_dispatch.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/tools/mod.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/tools/executor.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/tools/acd.rs", + "type": "file", + "crate": "g3-core", + "status": "modified" + }, + { + "id": "g3-core/src/pending_research.rs", + "type": "file", + "crate": "g3-core", + "status": "deleted" + }, + { + "id": "g3-core/src/tools/research.rs", + "type": "file", + "crate": "g3-core", + "status": "deleted" + }, + { + "id": "g3-cli/src/lib.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/project_files.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/agent_mode.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/interactive.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/commands.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/g3_status.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/ui_writer_impl.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-cli/src/accumulative.rs", + "type": "file", + "crate": "g3-cli", + "status": "modified" + }, + { + "id": "g3-config/src/lib.rs", + "type": "file", + "crate": "g3-config", + "status": "modified" + }, + { + "id": "studio/src/main.rs", + "type": "file", + "crate": "studio", + "status": "modified" + }, + { + "id": "studio/src/sdlc.rs", + "type": "file", + "crate": "studio", + "status": "modified" + }, + { + "id": "skills/research/SKILL.md", + "type": "skill", + "crate": null, + "status": "added" + }, + { + "id": "skills/research/g3-research", + "type": "script", + "crate": null, + "status": "added" + }, + { + "id": "prompts/system/native.md", + "type": "prompt", + "crate": null, + "status": "modified" + } + ] + }, + "edges": { + "crate_dependencies": [ + { + "from": "g3-cli", + "to": "g3-core", + "type": "cargo_dependency", + "evidence": "crates/g3-cli/Cargo.toml: g3-core = { path = \"../g3-core\" }" + }, + { + "from": "g3-cli", + "to": "g3-config", + "type": "cargo_dependency", + "evidence": "crates/g3-cli/Cargo.toml: g3-config = { path = \"../g3-config\" }" + }, + { + "from": "g3-cli", + "to": "g3-providers", + "type": "cargo_dependency", + "evidence": "crates/g3-cli/Cargo.toml: g3-providers = { path = \"../g3-providers\" }" + }, + { + "from": "g3-cli", + "to": "g3-planner", + "type": "cargo_dependency", + "evidence": "crates/g3-cli/Cargo.toml: g3-planner = { path = \"../g3-planner\" }" + }, + { + "from": "g3-cli", + "to": "g3-computer-control", + "type": "cargo_dependency", + "evidence": "crates/g3-cli/Cargo.toml: g3-computer-control = { path = \"../g3-computer-control\" }" + }, + { + "from": "g3-core", + "to": "g3-config", + "type": "cargo_dependency", + "evidence": "crates/g3-core/Cargo.toml: g3-config = { path = \"../g3-config\" }" + }, + { + "from": "g3-core", + "to": "g3-providers", + "type": "cargo_dependency", + "evidence": "crates/g3-core/Cargo.toml: g3-providers = { path = \"../g3-providers\" }" + }, + { + "from": "g3-core", + "to": "g3-execution", + "type": "cargo_dependency", + "evidence": "crates/g3-core/Cargo.toml: g3-execution = { path = \"../g3-execution\" }" + }, + { + "from": "g3-core", + "to": "g3-computer-control", + "type": "cargo_dependency", + "evidence": "crates/g3-core/Cargo.toml: g3-computer-control = { path = \"../g3-computer-control\" }" + }, + { + "from": "g3-planner", + "to": "g3-core", + "type": "cargo_dependency", + "evidence": "crates/g3-planner/Cargo.toml: g3-core = { path = \"../g3-core\" }" + }, + { + "from": "g3-planner", + "to": "g3-config", + "type": "cargo_dependency", + "evidence": "crates/g3-planner/Cargo.toml: g3-config = { path = \"../g3-config\" }" + }, + { + "from": "g3-planner", + "to": "g3-providers", + "type": "cargo_dependency", + "evidence": "crates/g3-planner/Cargo.toml: g3-providers = { path = \"../g3-providers\" }" + } + ], + "file_imports": [ + { + "from": "g3-core/src/skills/discovery.rs", + "to": "g3-core/src/skills/parser.rs", + "type": "use_super", + "evidence": "use super::parser::Skill" + }, + { + "from": "g3-core/src/skills/discovery.rs", + "to": "g3-core/src/skills/embedded.rs", + "type": "use_super", + "evidence": "use super::embedded::get_embedded_skills" + }, + { + "from": "g3-core/src/skills/prompt.rs", + "to": "g3-core/src/skills/parser.rs", + "type": "use_super", + "evidence": "use super::parser::Skill" + }, + { + "from": "g3-core/src/skills/extraction.rs", + "to": "g3-core/src/skills/embedded.rs", + "type": "use_super", + "evidence": "use super::embedded::get_embedded_skill" + }, + { + "from": "g3-core/src/skills/mod.rs", + "to": "g3-core/src/skills/parser.rs", + "type": "mod_declaration", + "evidence": "mod parser" + }, + { + "from": "g3-core/src/skills/mod.rs", + "to": "g3-core/src/skills/discovery.rs", + "type": "mod_declaration", + "evidence": "mod discovery" + }, + { + "from": "g3-core/src/skills/mod.rs", + "to": "g3-core/src/skills/prompt.rs", + "type": "mod_declaration", + "evidence": "mod prompt" + }, + { + "from": "g3-core/src/skills/mod.rs", + "to": "g3-core/src/skills/embedded.rs", + "type": "mod_declaration", + "evidence": "mod embedded" + }, + { + "from": "g3-core/src/skills/mod.rs", + "to": "g3-core/src/skills/extraction.rs", + "type": "mod_declaration", + "evidence": "pub mod extraction" + }, + { + "from": "g3-core/src/prompts.rs", + "to": "g3-core/src/skills/mod.rs", + "type": "use_crate", + "evidence": "use crate::skills::{Skill, generate_skills_prompt}" + }, + { + "from": "g3-core/src/lib.rs", + "to": "g3-core/src/skills/mod.rs", + "type": "pub_mod", + "evidence": "pub mod skills" + }, + { + "from": "g3-core/src/lib.rs", + "to": "g3-core/src/prompts.rs", + "type": "mod_declaration", + "evidence": "mod prompts" + }, + { + "from": "g3-cli/src/project_files.rs", + "to": "g3-core/src/skills/mod.rs", + "type": "use_external", + "evidence": "use g3_core::{discover_skills, generate_skills_prompt, Skill}" + }, + { + "from": "g3-cli/src/project_files.rs", + "to": "g3-config/src/lib.rs", + "type": "use_external", + "evidence": "use g3_config::SkillsConfig" + }, + { + "from": "g3-cli/src/agent_mode.rs", + "to": "g3-cli/src/project_files.rs", + "type": "use_crate", + "evidence": "use crate::project_files::{..., discover_and_format_skills, ...}" + }, + { + "from": "g3-cli/src/lib.rs", + "to": "g3-cli/src/project_files.rs", + "type": "use_crate", + "evidence": "use project_files::{..., discover_and_format_skills, ...}" + }, + { + "from": "g3-core/src/skills/embedded.rs", + "to": "skills/research/SKILL.md", + "type": "include_str", + "evidence": "include_str!(\"../../../../skills/research/SKILL.md\")" + }, + { + "from": "g3-core/src/skills/embedded.rs", + "to": "skills/research/g3-research", + "type": "include_str", + "evidence": "include_str!(\"../../../../skills/research/g3-research\")" + }, + { + "from": "studio/src/main.rs", + "to": "studio/src/sdlc.rs", + "type": "mod_declaration", + "evidence": "mod sdlc" + }, + { + "from": "studio/src/main.rs", + "to": "studio/src/git.rs", + "type": "mod_declaration", + "evidence": "mod git" + }, + { + "from": "studio/src/main.rs", + "to": "studio/src/session.rs", + "type": "mod_declaration", + "evidence": "mod session" + } + ] + } } diff --git a/analysis/deps/graph.summary.md b/analysis/deps/graph.summary.md index 02f3bff..ea64b7b 100644 --- a/analysis/deps/graph.summary.md +++ b/analysis/deps/graph.summary.md @@ -1,105 +1,105 @@ # Dependency Graph Summary -**Generated**: 2025-02-02 -**Extraction Method**: Static import parsing via ripgrep -**Workspace**: g3 +**Scope**: Changes in commits `b6d2582..9443f933` (10 commits) +**Generated**: 2025-02-05 ## Metrics | Metric | Count | |--------|-------| -| Total Nodes | 127 | -| Crate Nodes | 9 | -| File Nodes | 118 | -| Total Edges | 156 | -| Crate-level Edges | 14 | -| File-level Edges | 142 | +| Crates (total) | 8 | +| Crates (changed) | 4 | +| Files (changed) | 29 | +| Files (added) | 8 | +| Files (deleted) | 2 | +| Files (modified) | 19 | +| Crate-level edges | 12 | +| File-level edges | 21 | -## Crate Dependency Structure +## Changed Crates -``` -g3 (root binary) -├── g3-cli -│ ├── g3-core -│ ├── g3-config -│ ├── g3-planner -│ ├── g3-computer-control -│ └── g3-providers -├── g3-providers - -g3-core -├── g3-providers -├── g3-config -├── g3-execution -└── g3-computer-control - -g3-planner -├── g3-providers -├── g3-core -└── g3-config - -studio (standalone binary) -└── (no internal g3 dependencies) - -g3-config (leaf - no internal deps) -g3-execution (leaf - no internal deps) -g3-computer-control (leaf - no internal deps) -g3-providers (leaf - no internal deps) -``` +| Crate | Path | Role | +|-------|------|------| +| g3-core | crates/g3-core | Core engine, skills module added | +| g3-cli | crates/g3-cli | CLI interface, skills integration | +| g3-config | crates/g3-config | Configuration, SkillsConfig added | +| studio | crates/studio | Multi-agent workspace, SDLC changes | ## Entrypoints -| Entrypoint | Path | Type | -|------------|------|------| -| g3 | `src/main.rs` | Binary | -| studio | `crates/studio/src/main.rs` | Binary | -| g3-cli | `crates/g3-cli/src/lib.rs` | Library | +| Entrypoint | Type | Evidence | +|------------|------|----------| +| g3-cli/src/lib.rs | Library root | `pub fn run()` | +| studio/src/main.rs | Binary | `fn main()` | +| g3-core/src/lib.rs | Library root | Re-exports skills module | -## Top Fan-In Nodes (Most Depended Upon) +## Top Fan-In Nodes (most depended upon) -| Node | Fan-In | Description | -|------|--------|-------------| -| `g3-core/src/lib.rs` | 18 | Core Agent, ToolCall types | -| `g3-core/src/ui_writer.rs` | 14 | UiWriter trait | -| `g3-cli/src/simple_output.rs` | 9 | SimpleOutput helper | -| `g3-cli/src/template.rs` | 6 | Template processing | -| `g3-core/src/paths.rs` | 6 | Path utilities | -| `g3-core/src/context_window.rs` | 5 | Context window management | -| `g3-cli/src/g3_status.rs` | 5 | Status formatting | -| `crate:g3-providers` | 5 | Provider abstractions | -| `crate:g3-config` | 5 | Configuration | -| `crate:g3-core` | 5 | Core engine | +| Node | Fan-In | Dependents | +|------|--------|------------| +| g3-core/src/skills/parser.rs | 3 | discovery.rs, prompt.rs, mod.rs | +| g3-core/src/skills/embedded.rs | 3 | discovery.rs, extraction.rs, mod.rs | +| g3-core/src/skills/mod.rs | 3 | lib.rs, prompts.rs, project_files.rs | +| g3-config/src/lib.rs | 2 | g3-core (crate), g3-cli (crate) | +| g3-cli/src/project_files.rs | 2 | lib.rs, agent_mode.rs | -## Top Fan-Out Nodes (Most Dependencies) +## Top Fan-Out Nodes (most dependencies) -| Node | Fan-Out | Description | +| Node | Fan-Out | Dependencies | |------|---------|-------------| -| `g3-cli/src/interactive.rs` | 11 | Interactive REPL | -| `g3-cli/src/agent_mode.rs` | 11 | Agent mode runner | -| `g3-cli/src/accumulative.rs` | 8 | Accumulative mode | -| `g3-cli/src/commands.rs` | 7 | CLI commands | -| `g3-core/src/tools/executor.rs` | 7 | Tool execution context | -| `g3-cli/src/autonomous.rs` | 5 | Autonomous mode | -| `g3-core/src/compaction.rs` | 4 | Context compaction | -| `g3-core/src/tool_dispatch.rs` | 4 | Tool routing | +| g3-cli (crate) | 5 | g3-core, g3-config, g3-providers, g3-planner, g3-computer-control | +| g3-core/src/skills/mod.rs | 5 | parser.rs, discovery.rs, prompt.rs, embedded.rs, extraction.rs | +| g3-core/src/skills/discovery.rs | 2 | parser.rs, embedded.rs | +| g3-cli/src/project_files.rs | 2 | g3-core::skills, g3-config::SkillsConfig | +| studio/src/main.rs | 3 | sdlc.rs, git.rs, session.rs | -## Crate File Counts +## Major Structural Changes -| Crate | Source Files | Test Files | -|-------|--------------|------------| -| g3-cli | 21 | 5 | -| g3-core | 32 | 33 | -| g3-providers | 12 | 4 | -| g3-planner | 7 | 4 | -| g3-computer-control | 12 | 1 | -| g3-config | 2 | 0 | -| g3-execution | 1 | 0 | -| studio | 3 | 0 | +### Added: Skills Module (`g3-core/src/skills/`) + +New module implementing Agent Skills specification: + +``` +g3-core/src/skills/ +├── mod.rs # Module root, re-exports +├── parser.rs # SKILL.md YAML frontmatter parser +├── discovery.rs # Skill directory scanning +├── prompt.rs # XML prompt generation +├── embedded.rs # Compile-time embedded skills +└── extraction.rs # Script extraction to .g3/bin/ +``` + +**Internal dependency flow**: +``` +mod.rs + ├── parser.rs (Skill struct) + ├── discovery.rs → parser.rs, embedded.rs + ├── prompt.rs → parser.rs + ├── embedded.rs (standalone) + └── extraction.rs → embedded.rs +``` + +### Removed: Research Tool (hardcoded) + +- `g3-core/src/pending_research.rs` (540 lines deleted) +- `g3-core/src/tools/research.rs` (710 lines deleted) + +### Added: Research Skill (external) + +- `skills/research/SKILL.md` (144 lines) +- `skills/research/g3-research` (338 lines, bash script) + +Research functionality moved from hardcoded tool to external skill. + +### Modified: SDLC Pipeline + +- State storage moved from `analysis/sdlc/` to `.g3/sdlc/` +- Added merge-to-main on successful completion +- Worktree preserved on failure for debugging ## Extraction Limitations -1. **Dynamic imports not captured**: Any runtime module loading is not reflected -2. **Macro-generated imports**: Imports generated by macros may be missed -3. **Conditional compilation**: `#[cfg(...)]` gated imports are included regardless of target -4. **Re-exports**: Transitive re-exports through `pub use` are not fully traced -5. **Test files excluded from graph**: Test files (`tests/`) are not included in file nodes +- Dynamic imports not detected (none expected in Rust) +- Test-only dependencies not distinguished from production +- Conditional compilation (`#[cfg(...)]`) not analyzed +- External crate dependencies (from crates.io) not enumerated diff --git a/analysis/deps/hotspots.md b/analysis/deps/hotspots.md index f31525e..676fd12 100644 --- a/analysis/deps/hotspots.md +++ b/analysis/deps/hotspots.md @@ -1,79 +1,101 @@ # Coupling Hotspots -**Generated**: 2025-02-02 -**Method**: Fan-in/fan-out analysis from dependency graph +**Scope**: Changes in commits `b6d2582..9443f933` (10 commits) ## High Fan-In Files (Most Depended Upon) -These files are imported by many other files. Changes here have wide impact. +Files that many other files depend on. Changes here have wide impact. -| File | Fan-In | Dependents | -|------|--------|------------| -| `g3-core/src/lib.rs` | 18 | streaming_parser, context_window, acd, streaming, stats, retry, feedback_extraction, task_result, tool_dispatch, tools/* | -| `g3-core/src/ui_writer.rs` | 14 | retry, compaction, feedback_extraction, tool_dispatch, tools/{acd,executor,shell,research,file_ops,plan,memory,misc,webdriver} | -| `g3-cli/src/simple_output.rs` | 9 | utils, interactive, autonomous, coach_feedback, accumulative, task_execution, commands, agent_mode | -| `g3-cli/src/template.rs` | 6 | project_files, accumulative, commands, embedded_agents, agent_mode, interactive | -| `g3-core/src/paths.rs` | 6 | acd, session, context_window, tools/{executor,shell,plan} | -| `g3-core/src/context_window.rs` | 5 | compaction, stats, streaming, session, task_result | -| `g3-cli/src/g3_status.rs` | 5 | simple_output, interactive, task_execution, commands | -| `g3-cli/src/display.rs` | 4 | interactive, ui_writer_impl, agent_mode | -| `g3-cli/src/ui_writer_impl.rs` | 4 | autonomous, coach_feedback, accumulative, agent_mode | -| `g3-core/src/utils.rs` | 3 | tools/{shell,file_ops} | +| File | Fan-In | Dependents | Risk | +|------|--------|------------|------| +| `g3-core/src/skills/parser.rs` | 3 | discovery.rs, prompt.rs, mod.rs | Medium | +| `g3-core/src/skills/embedded.rs` | 3 | discovery.rs, extraction.rs, mod.rs | Medium | +| `g3-core/src/skills/mod.rs` | 3 | lib.rs, prompts.rs, project_files.rs (cross-crate) | High | +| `g3-config/src/lib.rs` | 2 | g3-core, g3-cli (cross-crate) | High | +| `g3-cli/src/project_files.rs` | 2 | lib.rs, agent_mode.rs | Medium | + +### Analysis + +**`g3-core/src/skills/mod.rs`** (Fan-In: 3, Cross-Crate: Yes) +- Re-exports `Skill`, `discover_skills`, `generate_skills_prompt`, `EmbeddedSkill` +- Used by `g3-core/src/lib.rs` (re-export), `g3-core/src/prompts.rs`, `g3-cli/src/project_files.rs` +- **Evidence**: `pub use parser::Skill`, `pub use discovery::discover_skills` +- **Impact**: API changes affect both g3-core internals and g3-cli + +**`g3-core/src/skills/parser.rs`** (Fan-In: 3, Cross-Crate: No) +- Defines `Skill` struct used throughout skills module +- **Evidence**: `use super::parser::Skill` in discovery.rs, prompt.rs +- **Impact**: Struct field changes ripple through entire skills subsystem + +**`g3-config/src/lib.rs`** (Fan-In: 2, Cross-Crate: Yes) +- Added `SkillsConfig` struct +- **Evidence**: `use g3_config::SkillsConfig` in project_files.rs +- **Impact**: Config schema changes affect CLI startup ## High Fan-Out Files (Most Dependencies) -These files import many other modules. They are integration points. +Files that depend on many others. Complex, potentially fragile. -| File | Fan-Out | Dependencies | -|------|---------|-------------| -| `g3-cli/src/interactive.rs` | 11 | g3-core, completion, commands, display, g3_status, project, project_files, simple_output, input_formatter, template, task_execution, utils | -| `g3-cli/src/agent_mode.rs` | 11 | g3-core, project_files, display, language_prompts, simple_output, embedded_agents, ui_writer_impl, interactive, template, project, cli_args | -| `g3-cli/src/accumulative.rs` | 8 | g3-core, autonomous, cli_args, interactive, simple_output, ui_writer_impl, utils, template | -| `g3-cli/src/commands.rs` | 7 | g3-core, completion, g3_status, simple_output, project, template, task_execution | -| `g3-core/src/tools/executor.rs` | 7 | g3-config, background_process, pending_research, paths, ui_writer, webdriver_session, lib (ToolCall) | -| `g3-cli/src/autonomous.rs` | 5 | g3-core, coach_feedback, metrics, simple_output, ui_writer_impl | -| `g3-core/src/compaction.rs` | 4 | g3-providers, context_window, provider_config, ui_writer | -| `g3-core/src/tool_dispatch.rs` | 4 | tools/executor, tools/mod, ui_writer, lib (ToolCall) | -| `g3-cli/src/ui_writer_impl.rs` | 4 | g3-core, filter_json, display, streaming_markdown | -| `g3-core/src/streaming.rs` | 4 | g3-providers, context_window, streaming_parser, lib (ToolCall) | +| File | Fan-Out | Dependencies | Risk | +|------|---------|--------------|------| +| `g3-core/src/skills/mod.rs` | 5 | parser, discovery, prompt, embedded, extraction | Medium | +| `g3-core/src/skills/discovery.rs` | 2 | parser.rs, embedded.rs | Low | +| `g3-cli/src/project_files.rs` | 2 | g3-core::skills, g3-config | Medium | +| `studio/src/main.rs` | 3 | sdlc.rs, git.rs, session.rs | Low | -## Cross-Crate Coupling Points +### Analysis -Files that bridge multiple crates: +**`g3-core/src/skills/mod.rs`** (Fan-Out: 5) +- Module root that coordinates all skills submodules +- **Evidence**: `mod parser; mod discovery; mod prompt; mod embedded; pub mod extraction` +- **Impact**: Central coordination point, but each submodule is relatively independent -| File | Cross-Crate Imports | Crates Touched | -|------|---------------------|----------------| -| `g3-core/src/lib.rs` | 2 | g3-config, g3-providers | -| `g3-core/src/webdriver_session.rs` | 1 | g3-computer-control | -| `g3-core/src/tools/webdriver.rs` | 1 | g3-computer-control | -| `g3-core/src/tools/executor.rs` | 1 | g3-config | -| `g3-core/src/tools/research.rs` | 1 | g3-config | -| `g3-core/src/provider_registration.rs` | 2 | g3-config, g3-providers | -| `g3-planner/src/llm.rs` | 3 | g3-config, g3-core, g3-providers | +**`g3-cli/src/project_files.rs`** (Fan-Out: 2, Cross-Crate: Yes) +- Bridges g3-core skills and g3-config +- **Evidence**: `use g3_core::{discover_skills, ...}`, `use g3_config::SkillsConfig` +- **Impact**: Integration point for skills feature in CLI -## Crate-Level Coupling +## Cross-Crate Coupling -| Crate | Outgoing Deps | Incoming Deps | Coupling Score | -|-------|---------------|---------------|----------------| -| g3-cli | 5 | 1 | High (consumer) | -| g3-core | 4 | 3 | High (hub) | -| g3-planner | 3 | 1 | Medium | -| g3-providers | 0 | 5 | High (foundation) | -| g3-config | 0 | 5 | High (foundation) | -| g3-computer-control | 0 | 2 | Low | -| g3-execution | 0 | 1 | Low | -| studio | 0 | 0 | Isolated | +Edges that cross crate boundaries. Higher coordination cost for changes. -## Observations +| From | To | Type | Evidence | +|------|----|------|----------| +| g3-cli/src/project_files.rs | g3-core::skills | use_external | `use g3_core::{discover_skills, generate_skills_prompt, Skill}` | +| g3-cli/src/project_files.rs | g3-config | use_external | `use g3_config::SkillsConfig` | +| g3-core/src/lib.rs | g3-core::skills | pub_use | `pub use skills::{Skill, discover_skills, generate_skills_prompt}` | -1. **g3-core/src/lib.rs** is the primary coupling hotspot. It defines `Agent`, `ToolCall`, and other core types used throughout the codebase. +## Compile-Time Coupling (include_str!) -2. **g3-core/src/ui_writer.rs** defines the `UiWriter` trait used by all tool implementations for output. High fan-in is expected for a trait definition. +Files embedded at compile time. Build breaks if missing. -3. **g3-cli/src/simple_output.rs** is a utility wrapper used by most CLI modules. High fan-in indicates it's a well-factored common dependency. +| Source | Embedded File | Evidence | +|--------|---------------|----------| +| g3-core/src/skills/embedded.rs | skills/research/SKILL.md | `include_str!("../../../../skills/research/SKILL.md")` | +| g3-core/src/skills/embedded.rs | skills/research/g3-research | `include_str!("../../../../skills/research/g3-research")` | -4. **g3-cli/src/interactive.rs** and **g3-cli/src/agent_mode.rs** have the highest fan-out, as expected for top-level orchestration modules. +**Impact**: +- Moving or renaming `skills/research/` breaks g3-core compilation +- Content changes require g3-core recompilation +- Relative path `../../../../` is fragile to directory restructuring -5. **g3-providers** and **g3-config** are foundation crates with zero outgoing dependencies and high incoming dependencies. This is the expected pattern for leaf crates. +## Deleted Code Impact -6. **studio** is completely isolated from the g3 crate ecosystem. +Removed files and their former dependents. + +| Deleted File | Lines | Former Dependents | +|--------------|-------|-------------------| +| g3-core/src/pending_research.rs | 540 | g3-core/src/lib.rs, tools/research.rs | +| g3-core/src/tools/research.rs | 710 | tool_dispatch.rs, tools/mod.rs | + +**Impact**: +- Research functionality moved to external skill +- `tool_dispatch.rs` and `tools/mod.rs` modified to remove research tool dispatch +- CLI commands related to research removed from `commands.rs` + +## Recommendations for Monitoring + +1. **`g3-core/src/skills/mod.rs`**: Watch for API surface changes +2. **`g3-config/src/lib.rs`**: Watch for `SkillsConfig` schema changes +3. **`skills/research/`**: Watch for path changes (compile-time dependency) +4. **`g3-cli/src/project_files.rs`**: Integration point, test after skills changes diff --git a/analysis/deps/layers.observed.md b/analysis/deps/layers.observed.md index 843a263..046e27e 100644 --- a/analysis/deps/layers.observed.md +++ b/analysis/deps/layers.observed.md @@ -1,152 +1,120 @@ -# Observed Layering Structure +# Observed Layering -**Generated**: 2025-02-02 -**Method**: Derived from crate dependencies and file import patterns +**Scope**: Changes in commits `b6d2582..9443f933` (10 commits) -## Crate Layers +## Layer Structure -Based on dependency direction, the crates form the following layers: +Observed from dependency direction (higher layers depend on lower): ``` -Layer 0 (Leaf/Foundation): -┌─────────────────┬─────────────────┬─────────────────────────┬─────────────────┐ -│ g3-config │ g3-execution │ g3-computer-control │ g3-providers │ -│ (config mgmt) │ (code execution)│ (browser/UI control) │ (LLM providers) │ -└─────────────────┴─────────────────┴─────────────────────────┴─────────────────┘ - │ - ▼ -Layer 1 (Core Engine): -┌───────────────────────────────────────────────────────────────────────────────┐ -│ g3-core │ -│ (Agent, ToolCall, context management, tool dispatch, streaming) │ -└───────────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -Layer 2 (Orchestration): -┌───────────────────────────────────────────────────────────────────────────────┐ -│ g3-planner │ -│ (fast-discovery planner, git integration, LLM orchestration) │ -└───────────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -Layer 3 (CLI/Application): -┌───────────────────────────────────────────────────────────────────────────────┐ -│ g3-cli │ -│ (interactive mode, autonomous mode, agent mode, commands, UI) │ -└───────────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -Layer 4 (Binary Entry): -┌───────────────────────────────────────────────────────────────────────────────┐ -│ g3 │ -│ (main binary, minimal - delegates to g3-cli) │ -└───────────────────────────────────────────────────────────────────────────────┘ - -Separate: -┌───────────────────────────────────────────────────────────────────────────────┐ -│ studio │ -│ (standalone multi-agent workspace manager, no g3 crate dependencies) │ -└───────────────────────────────────────────────────────────────────────────────┘ +┌─────────────────────────────────────────────────────────────┐ +│ Layer 4: Binaries / Entry Points │ +│ ┌─────────────┐ ┌─────────────┐ │ +│ │ g3-cli │ │ studio │ │ +│ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Layer 3: Orchestration │ +│ ┌─────────────┐ │ +│ │ g3-planner │ │ +│ └─────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Layer 2: Core Engine │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ g3-core │ │ +│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ +│ │ │ skills │ │ tools │ │ prompts │ │ context │ │ │ +│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ +│ └─────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Layer 1: Infrastructure │ +│ ┌─────────────┐ ┌─────────────┐ ┌───────────────────────┐ │ +│ │ g3-config │ │g3-providers │ │ g3-computer-control │ │ +│ └─────────────┘ └─────────────┘ └───────────────────────┘ │ +│ ┌─────────────┐ │ +│ │g3-execution │ │ +│ └─────────────┘ │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Layer 0: External Assets │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ skills/research/ (SKILL.md, g3-research script) │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ prompts/system/ (native.md, etc.) │ │ +│ └─────────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ ``` +## Layer Assignments (Changed Files) + +| Layer | File | Evidence | +|-------|------|----------| +| 4 | g3-cli/src/lib.rs | Entry point, depends on g3-core | +| 4 | g3-cli/src/agent_mode.rs | Uses g3-core::Agent | +| 4 | g3-cli/src/interactive.rs | Uses g3-core::Agent | +| 4 | g3-cli/src/project_files.rs | Uses g3-core::skills, g3-config | +| 4 | studio/src/main.rs | Binary entry point | +| 4 | studio/src/sdlc.rs | Orchestrates g3 agents | +| 2 | g3-core/src/lib.rs | Core library root | +| 2 | g3-core/src/skills/mod.rs | Skills subsystem | +| 2 | g3-core/src/skills/parser.rs | SKILL.md parsing | +| 2 | g3-core/src/skills/discovery.rs | Skill directory scanning | +| 2 | g3-core/src/skills/prompt.rs | XML prompt generation | +| 2 | g3-core/src/skills/embedded.rs | Compile-time embedding | +| 2 | g3-core/src/skills/extraction.rs | Script extraction | +| 2 | g3-core/src/prompts.rs | System prompt generation | +| 2 | g3-core/src/tool_definitions.rs | Tool schema definitions | +| 2 | g3-core/src/tool_dispatch.rs | Tool routing | +| 1 | g3-config/src/lib.rs | Configuration structs | +| 0 | skills/research/SKILL.md | External skill definition | +| 0 | skills/research/g3-research | External skill script | +| 0 | prompts/system/native.md | System prompt template | + ## Layer Violations -**None detected at crate level.** +**None detected** in the changed files. -All dependencies flow downward (higher layer → lower layer). No upward dependencies exist. +All dependencies flow downward (higher layer → lower layer). -## File-Level Layering Within g3-cli +## Skills Module Internal Layering + +Within `g3-core/src/skills/`: ``` -Entry Layer: - lib.rs (run function, mode dispatch) - │ - ▼ -Mode Layer: - interactive.rs, autonomous.rs, agent_mode.rs, accumulative.rs - │ - ▼ -Command/Execution Layer: - commands.rs, task_execution.rs, coach_feedback.rs - │ - ▼ -Utility Layer: - simple_output.rs, g3_status.rs, display.rs, template.rs, - ui_writer_impl.rs, streaming_markdown.rs, filter_json.rs, - metrics.rs, project_files.rs, language_prompts.rs, embedded_agents.rs - │ - ▼ -Data Layer: - cli_args.rs, project.rs, completion.rs, theme.rs +┌───────────────────────────────────────┐ +│ mod.rs (coordinator, re-exports) │ Layer 2.3 +└───────────────────────────────────────┘ + │ + ▼ +┌───────────────────────────────────────┐ +│ discovery.rs, prompt.rs, extraction │ Layer 2.2 +│ (use parser.rs and/or embedded.rs) │ +└───────────────────────────────────────┘ + │ + ▼ +┌───────────────────────────────────────┐ +│ parser.rs, embedded.rs (leaf nodes) │ Layer 2.1 +│ (no internal dependencies) │ +└───────────────────────────────────────┘ ``` -## File-Level Layering Within g3-core +## Derivation Method -``` -Entry Layer: - lib.rs (Agent struct, stream_completion_with_tools) - │ - ▼ -Orchestration Layer: - retry.rs, compaction.rs, feedback_extraction.rs - │ - ▼ -Tool Layer: - tool_dispatch.rs, tool_definitions.rs - tools/mod.rs → tools/{shell,file_ops,plan,webdriver,research,memory,misc,acd}.rs - tools/executor.rs - │ - ▼ -Streaming Layer: - streaming.rs, streaming_parser.rs - │ - ▼ -Context Layer: - context_window.rs, acd.rs, session.rs, session_continuation.rs - │ - ▼ -Infrastructure Layer: - paths.rs, utils.rs, error_handling.rs, stats.rs, - provider_config.rs, provider_registration.rs, - background_process.rs, pending_research.rs, - webdriver_session.rs, ui_writer.rs, project.rs, prompts.rs - │ - ▼ -Search Layer: - code_search/mod.rs, code_search/searcher.rs -``` +Layers derived mechanically from: +1. Cargo.toml `[dependencies]` sections +2. `use` statement analysis +3. `mod` declaration hierarchy +4. `include_str!` compile-time references -## File-Level Layering Within g3-providers - -``` -Entry Layer: - lib.rs (LLMProvider trait, ProviderRegistry, Message types) - │ - ▼ -Provider Implementations: - anthropic.rs, openai.rs, gemini.rs, databricks.rs, mock.rs - embedded/mod.rs → embedded/provider.rs, embedded/adapters/{mod,glm}.rs - │ - ▼ -Utility Layer: - streaming.rs, oauth.rs -``` - -## Directionality Confidence - -| Layer Boundary | Confidence | Notes | -|----------------|------------|-------| -| g3 → g3-cli | High | Single dependency, clear delegation | -| g3-cli → g3-core | High | Many imports, clear consumer relationship | -| g3-cli → g3-planner | High | Explicit dependency for planning features | -| g3-core → g3-providers | High | Core uses provider abstractions | -| g3-core → g3-config | High | Core reads configuration | -| g3-core → g3-computer-control | High | WebDriver integration | -| g3-core → g3-execution | Medium | Declared but minimal observed usage | -| g3-planner → g3-core | High | Planner uses Agent, error handling | - -## Uncertainty - -1. **g3-execution usage**: Declared as dependency of g3-core but no `use g3_execution::` statements found in source. May be used transitively or for future features. - -2. **studio isolation**: studio has no g3 crate dependencies. It may interact with g3 via filesystem/process boundaries rather than library calls. +No semantic interpretation applied. diff --git a/analysis/deps/limitations.md b/analysis/deps/limitations.md index ed33162..248a558 100644 --- a/analysis/deps/limitations.md +++ b/analysis/deps/limitations.md @@ -1,114 +1,66 @@ # Analysis Limitations -**Generated**: 2025-02-02 +**Scope**: Changes in commits `b6d2582..9443f933` (10 commits) ## What Could Not Be Observed -### 1. Dynamic/Runtime Dependencies - -- **Plugin loading**: Any runtime module loading via `dlopen` or similar -- **Reflection-based imports**: Dependencies resolved at runtime -- **Configuration-driven imports**: Modules loaded based on config values - -### 2. Macro-Generated Code - -- **Procedural macros**: Code generated by `#[derive(...)]` and custom proc macros -- **Declarative macros**: `macro_rules!` expansions that generate `use` statements -- **Build script outputs**: Code generated by `build.rs` files - -### 3. Conditional Compilation - -- **Platform-specific code**: `#[cfg(target_os = "...")]` blocks are included regardless of target -- **Feature flags**: `#[cfg(feature = "...")]` gated code is included unconditionally -- **Test-only code**: `#[cfg(test)]` modules are excluded from analysis - -### 4. Re-exports and Transitive Dependencies - -- **`pub use` chains**: Transitive re-exports are not fully traced -- **Glob imports**: `use module::*` does not enumerate specific items -- **Prelude imports**: Implicit prelude items are not tracked - -### 5. External Crate Dependencies - -- **Third-party crates**: Only internal g3 workspace crates are analyzed -- **Workspace dependency versions**: Version constraints not analyzed -- **Optional dependencies**: Not distinguished from required dependencies +| Limitation | Impact | Mitigation | +|------------|--------|------------| +| Runtime dispatch | Tool dispatch uses string matching, not static imports | Analyzed `tool_dispatch.rs` manually | +| Conditional compilation | `#[cfg(...)]` blocks not analyzed | May miss platform-specific deps | +| Macro-generated code | `include_str!` detected, other macros not | Limited to explicit macros | +| External crate deps | crates.io dependencies not enumerated | Focus on workspace crates only | +| Test-only imports | Not distinguished from production | May overcount dependencies | +| Dynamic skill loading | Skills loaded at runtime from filesystem | Only compile-time embedded skills tracked | ## What Was Inferred -### 1. Module Hierarchy +| Inference | Confidence | Rationale | +|-----------|------------|----------| +| Layer assignments | High | Based on Cargo.toml dependency direction | +| Fan-in/fan-out counts | High | Direct count of `use`/`mod` statements | +| Cross-crate edges | High | Explicit `use external_crate::` statements | +| Deleted file impact | Medium | Based on git diff, former imports not verified | -Module parent-child relationships inferred from: -- `mod` declarations in `lib.rs` and `mod.rs` files -- File system structure (`foo/mod.rs` implies `foo` module) +## Potential Invalidators -**Confidence**: High - Rust module system is deterministic +Conditions that would invalidate this analysis: -### 2. Crate Dependencies +1. **Feature flags**: If `Cargo.toml` uses `[features]` to conditionally include dependencies, the graph may be incomplete for non-default configurations. -Crate-level dependencies extracted from: -- `Cargo.toml` `[dependencies]` sections -- `path = "..."` declarations for workspace crates +2. **Workspace-level dependencies**: The `[workspace.dependencies]` section in root `Cargo.toml` was not analyzed for version constraints. -**Confidence**: High - Cargo.toml is authoritative +3. **Build scripts**: `build.rs` files may generate code or modify dependencies at build time. -### 3. File-Level Imports +4. **Proc macros**: Procedural macros in dependencies may generate additional imports not visible in source. -File imports extracted via regex pattern matching: -- `^use (g3_|crate::)` for internal imports -- `^(pub )?mod ` for module declarations +5. **Path aliases**: If `Cargo.toml` uses `[patch]` or path aliases, actual dependency resolution may differ. -**Confidence**: Medium-High - May miss unusual import patterns +## Scope Boundaries -### 4. Fan-In/Fan-Out Counts +- **Included**: All files changed in commits `b6d2582..9443f933` +- **Excluded**: Unchanged files, even if they depend on changed files +- **Excluded**: Files outside `crates/` and `skills/` directories (except prompts/) -Coupling metrics derived from edge counts in dependency graph. +## Tool Versions -**Confidence**: Medium - Depends on completeness of edge extraction +| Tool | Version | Purpose | +|------|---------|--------| +| git | system | Commit range, diff | +| rg (ripgrep) | system | Import pattern matching | +| Manual analysis | - | Cargo.toml parsing | -## What May Invalidate Conclusions +## Reproducibility -### 1. Code Changes +To reproduce this analysis: -This analysis reflects the codebase state at generation time. Any of the following invalidate the analysis: -- New files added -- Import statements changed -- Module structure reorganized -- Cargo.toml dependencies modified +```bash +# Get changed files +git diff --name-only 9443f933~10..9443f933 -### 2. Incomplete Extraction +# Extract imports from Rust files +rg "^use |^mod |use g3_|use crate::" crates/*/src/*.rs -The regex-based extraction may miss: -- Multi-line `use` statements with unusual formatting -- Imports inside function bodies -- Imports in macro invocations -- `extern crate` declarations (deprecated but valid) - -### 3. Test Code Exclusion - -Test files (`tests/*.rs`, `#[cfg(test)]` modules) are excluded. Test-only dependencies and coupling patterns are not reflected. - -### 4. Example Code Exclusion - -Example files (`examples/*.rs`) are excluded from the graph. - -### 5. Build Script Dependencies - -`build.rs` files may introduce compile-time dependencies not reflected in the import graph. - -## Extraction Method Details - -| Aspect | Method | Tool | -|--------|--------|------| -| Crate dependencies | Cargo.toml parsing | Manual inspection | -| Module declarations | Regex: `^(pub )?mod ` | ripgrep | -| Internal imports | Regex: `^use (g3_\|crate::)` | ripgrep | -| File enumeration | `find crates -name "*.rs"` | find | -| Cycle detection | Manual graph traversal | N/A | - -## Recommendations for Future Analysis - -1. **Use cargo metadata**: `cargo metadata --format-version 1` provides authoritative dependency information -2. **Use rust-analyzer**: LSP-based analysis would capture macro expansions -3. **Use cargo-depgraph**: Specialized tool for Rust dependency visualization -4. **Include test coverage**: Analyze test files separately for test-specific coupling +# Check Cargo.toml dependencies +cat crates/*/Cargo.toml | grep -A20 "\[dependencies\]" +``` diff --git a/analysis/deps/sccs.md b/analysis/deps/sccs.md index e553ce0..0724865 100644 --- a/analysis/deps/sccs.md +++ b/analysis/deps/sccs.md @@ -1,83 +1,61 @@ # Strongly Connected Components (Cycles) -**Generated**: 2025-02-02 -**Method**: Manual analysis of crate and file-level dependency graph - -## Crate-Level Cycles - -**None detected.** - -The crate dependency graph is a DAG (directed acyclic graph). All crate dependencies flow downward: - -``` -g3-cli → g3-core → g3-providers - → g3-config - → g3-planner → g3-core (creates diamond, not cycle) - → g3-providers - → g3-config - → g3-computer-control - → g3-providers - -g3-core → g3-execution - → g3-computer-control -``` - -## File-Level Cycles Within Crates - -### g3-core - -**Potential cycle via lib.rs re-exports:** - -Multiple modules import from `lib.rs` (for `ToolCall`, `Agent`, etc.), and `lib.rs` declares these modules. This is standard Rust module structure, not a problematic cycle. - -``` -lib.rs ←──mod──→ streaming_parser.rs (uses crate::ToolCall) -lib.rs ←──mod──→ context_window.rs (uses crate::ToolCall) -lib.rs ←──mod──→ acd.rs (uses crate::ToolCall) -lib.rs ←──mod──→ streaming.rs (uses crate::ToolCall) -lib.rs ←──mod──→ stats.rs (uses crate::CacheStats) -lib.rs ←──mod──→ retry.rs (uses crate::{Agent, DiscoveryOptions, TaskResult}) -lib.rs ←──mod──→ feedback_extraction.rs (uses crate::{Agent, TaskResult}) -``` - -This is the standard Rust pattern where `lib.rs` defines types and submodules import them via `crate::`. Not a problematic SCC. - -### g3-cli - -**No problematic cycles detected.** - -Dependencies flow from high-level modules (interactive, agent_mode, accumulative) down to utilities (simple_output, g3_status, template). - -### g3-providers - -**No cycles detected.** - -All provider implementations (anthropic, openai, gemini, databricks, embedded, mock) import from `lib.rs` only. - -### g3-planner - -**No cycles detected.** - -`planner.rs` imports from `git.rs`, `history.rs`, `llm.rs`, `state.rs`. No reverse dependencies. - -## Cross-Crate Diamonds (Not Cycles) - -The following diamond patterns exist but are not cycles: - -1. **g3-cli → g3-core → g3-config** and **g3-cli → g3-config** -2. **g3-cli → g3-planner → g3-core** and **g3-cli → g3-core** -3. **g3-cli → g3-planner → g3-providers** and **g3-cli → g3-providers** - -These are valid DAG structures where multiple paths lead to the same dependency. +**Scope**: Changes in commits `b6d2582..9443f933` (10 commits) ## Summary -| Scope | Cycles Found | Severity | -|-------|--------------|----------| -| Crate-level | 0 | N/A | -| File-level (g3-core) | 0 problematic | N/A | -| File-level (g3-cli) | 0 | N/A | -| File-level (g3-providers) | 0 | N/A | -| File-level (g3-planner) | 0 | N/A | +| Metric | Count | +|--------|-------| +| SCCs with >1 node | 0 | +| Trivial SCCs (single node) | 29 | -The codebase has a clean acyclic dependency structure. +## Analysis + +**No dependency cycles detected** in the changed files. + +The skills module has a clean DAG structure: + +``` +mod.rs (root) + │ + ├── parser.rs (leaf - no internal deps) + │ ▲ + │ │ + ├── discovery.rs ──┬──► parser.rs + │ └──► embedded.rs + │ + ├── prompt.rs ─────────► parser.rs + │ + ├── embedded.rs (leaf - no internal deps) + │ ▲ + │ │ + └── extraction.rs ─────► embedded.rs +``` + +## Crate-Level Cycles + +No cycles at crate level. Dependency direction: + +``` +g3-cli ──► g3-core ──► g3-config + │ │ + │ └──► g3-providers + │ └──► g3-execution + │ └──► g3-computer-control + │ + └──► g3-config + └──► g3-providers + └──► g3-planner ──► g3-core (creates potential for cycle) +``` + +**Note**: `g3-planner` depends on `g3-core`, and `g3-cli` depends on both. This is not a cycle but creates a diamond dependency pattern. + +## Verification Method + +Cycles detected by analyzing `use` statements and `mod` declarations: +- `use super::*` → parent module +- `use crate::*` → crate root +- `mod name` → child module +- `use external_crate::*` → cross-crate + +No bidirectional edges found within the changed file set. diff --git a/analysis/memory.md b/analysis/memory.md index ac27a35..202ad73 100644 --- a/analysis/memory.md +++ b/analysis/memory.md @@ -1,5 +1,5 @@ # Workspace Memory -> Updated: 2026-02-04T23:42:21Z | Size: 19.9k chars +> Updated: 2026-02-05T14:30:00Z | Size: ~19k chars ### Remember Tool Wiring - `crates/g3-core/src/tools/memory.rs` [0..5000] - `execute_remember()`, `get_memory_path()`, `merge_memory()` @@ -115,7 +115,6 @@ Saves conversation fragments to disk, replaces with stubs. ### UTF-8 Safe String Slicing Rust `&s[..n]` panics on multi-byte chars (emoji, CJK) if sliced mid-character. - **Pattern**: `s.char_indices().nth(n).map(|(i,_)| i).unwrap_or(s.len())` **Danger zones**: Display truncation, ACD stubs, user input, non-ASCII text. @@ -143,7 +142,7 @@ Auto-detects languages and injects toolchain guidance. - `get_language_prompts_for_workspace()` [88..108] - `get_agent_language_prompts_for_workspace()` [124..137] - `crates/g3-cli/src/agent_mode.rs` [149..159] - appends agent-specific prompts -- `prompts/langs/` - language prompt files (e.g., `racket.md`, `carmack.racket.md`) +- `prompts/langs/` - language prompt files **To add language**: Create `prompts/langs/.md`, add to `LANGUAGE_PROMPTS` **To add agent+lang**: Create `prompts/langs/..md`, add to `AGENT_LANGUAGE_PROMPTS` @@ -165,7 +164,6 @@ Auto-detects languages and injects toolchain guidance. - `done()` [72] - bold green "[done]" - `failed()` [81] - red "[failed]" - `thin_result()` [236] - formats ThinResult with colors - - `resuming()` [213] - session resume with cyan ID ### Prompt Cache Statistics - `crates/g3-providers/src/lib.rs` [195..210] - `Usage.cache_creation_tokens`, `cache_read_tokens` @@ -211,160 +209,35 @@ max_tokens = 4096 gpu_layers = 99 ``` -### Plan Mode (replaces TODO system) -Structured task planning with cognitive forcing - requires happy/negative/boundary checks. +### Agent Skills System +Portable skill packages with SKILL.md + optional scripts per Agent Skills spec (agentskills.io). -- `crates/g3-core/src/tools/plan.rs` - - `Plan` [200..240] - plan_id, revision, approved_revision, items[] - - `PlanItem` [110..145] - id, description, state, touches, checks, evidence, notes - - `PlanState` [25..45] - enum: Todo, Doing, Done, Blocked - - `Check` [60..85] - desc, target fields - - `Checks` [90..105] - happy, negative, boundary - - `get_plan_path()` [280..285] - returns `.g3/sessions//plan.g3.md` - - `read_plan()` [290..310] - loads plan from YAML in markdown - - `write_plan()` [315..335] - validates and saves plan - - `plan_verify()` [355..390] - placeholder called when all items done/blocked - - `execute_plan_read()` [395..420] - plan.read tool - - `execute_plan_write()` [425..490] - plan.write tool with validation - - `execute_plan_approve()` [495..530] - plan.approve tool - -- `crates/g3-core/src/tool_definitions.rs` [263..330] - plan.read, plan.write, plan.approve definitions -- `crates/g3-core/src/tool_dispatch.rs` [36..38] - dispatch cases for plan tools -- `crates/g3-cli/src/commands.rs` [460..490] - `/plan` command starts Plan Mode -- `crates/g3-core/src/prompts.rs` [21..130] - SHARED_PLAN_SECTION replaces TODO section - -**Plan Schema (YAML)**: -```yaml -plan_id: feature-name -revision: 1 -approved_revision: 1 # set by plan.approve -items: - - id: I1 - description: What to do - state: todo|doing|done|blocked - touches: [paths/modules] - checks: - happy: {desc, target} - negative: {desc, target} - boundary: {desc, target} - evidence: [file:line, test names] # required when done - notes: Implementation explanation # required when done -``` - -**Workflow**: `/plan ` → agent drafts plan → user approves → agent implements → plan_verify() called when complete - -### Plan Mode Tool Names (IMPORTANT) -Tool names must use underscores, not dots (Anthropic API restriction: `^[a-zA-Z0-9_-]{1,128}$`). - -- `plan_read` - Read current plan -- `plan_write` - Create/update plan -- `plan_approve` - Approve plan revision - -### Plan Verification System -Verifies evidence in completed plan items deterministically. - -- `crates/g3-core/src/tools/plan.rs` - - `EvidenceType` [283..300] - enum: CodeLocation{file_path, start_line, end_line}, TestReference{file_path, test_name}, Unknown - - `VerificationStatus` [303..320] - enum: Verified, Warning(String), Error(String), Skipped(String) - - `EvidenceVerification` [330..345] - evidence string + parsed type + status - - `ItemVerification` [348..365] - item_id, description, evidence_results[], missing_evidence flag - - `PlanVerification` [368..385] - plan_id, item_results[], skipped_count; has all_passed(), count_issues() - - `parse_evidence()` [390..428] - parses evidence string into EvidenceType - - `parse_line_range()` [429..440] - parses "42" or "42-118" into (start, Option) - - `verify_code_location()` [443..495] - checks file exists, line numbers in range - - `verify_test_reference()` [496..554] - checks test file exists, searches for fn test_name - - `verify_single_evidence()` [632..655] - dispatches to appropriate verifier - - `plan_verify()` [659..700] - iterates done items, collects verification results - - `format_verification_results()` [703..745] - formats results with emoji, loud warnings - -**Evidence formats supported:** -- Code location with range: `src/foo.rs:42-118` -- Code location single line: `src/foo.rs:42` -- Code location file only: `src/foo.rs` -- Test reference: `tests/foo.rs::test_bar` - -**Integration:** Called from `execute_plan_write()` when plan is complete and approved (line 828-833) - -### Invariants System (Rulespec & Action Envelope) -Machine-readable invariants for Plan Mode verification. - -- `crates/g3-core/src/tools/invariants.rs` - - `InvariantSource` [25..40] - enum: TaskPrompt, Memory - - `Claim` [50..75] - name + selector for envelope paths - - `PredicateRule` [80..120] - enum: Contains, Equals, Exists, NotExists, GreaterThan, LessThan, MinLength, MaxLength, Matches - - `Predicate` [125..180] - claim ref, rule, value, source, notes - - `Rulespec` [185..240] - claims[] + predicates[] - - `ActionEnvelope` [245..290] - facts HashMap - - `Selector` [295..410] - parse(), select() for XPath-like paths (foo.bar, foo[0], foo[*]) - - `evaluate_predicate()` [415..630] - evaluates predicate against selected values - - `get_rulespec_path()` [635..640] - `.g3/sessions//rulespec.yaml` - - `get_envelope_path()` [642..647] - `.g3/sessions//envelope.yaml` - - `read_rulespec()`, `write_rulespec()` [650..680] - - `read_envelope()`, `write_envelope()` [682..710] - - `evaluate_rulespec()` [780..850] - full rulespec evaluation against envelope - - `format_evaluation_results()` [855..900] - pretty-print evaluation - -- `crates/g3-core/src/tools/plan.rs` - - `format_verification_results()` [702..762] - now prints rulespec/envelope paths - -- `crates/g3-core/src/prompts.rs` [92..156] - Invariants section in SHARED_PLAN_SECTION - -**Selector syntax**: `foo.bar` (nested), `foo[0]` (index), `foo[*]` (wildcard) -**Predicate rules**: contains, equals, exists, not_exists, min_length, max_length, greater_than, less_than, matches - -### Studio SDLC Pipeline Command -Orchestrates 7 g3 agents in sequence for codebase maintenance. - -- `crates/studio/src/sdlc.rs` - - `PIPELINE_STAGES` [28..62] - static array of 7 agents: euler, breaker, hopper, fowler, carmack, lamport, huffman - - `Stage` [18..26] - name, description, focus fields - - `StageStatus` [65..80] - enum: Pending, Running, Complete, Failed, Skipped - - `PipelineState` [108..140] - run_id, stages[], commit_cursor, session_id - - `PipelineState::load()` [165..185] - loads from analysis/sdlc/pipeline.json, handles corruption - - `PipelineState::save()` [188..200] - persists state for crash recovery - - `PipelineState::resume()` [330..340] - finds first incomplete stage, resets Running→Pending - - `display_pipeline()` [354..390] - box display with status icons (○/◉/✓/✗/⊘) - - `generate_summary()` [410..475] - markdown table of results - -- `crates/studio/src/main.rs` - - `SdlcAction` [88..104] - enum: Run{commits}, Status, Reset - - `cmd_sdlc_run()` [540..655] - orchestrates pipeline in worktree - - `cmd_sdlc_status()` [658..695] - displays current state - - `cmd_sdlc_reset()` [698..710] - clears pipeline state - - `run_agent_in_worktree()` [770..800] - executes g3 --agent in worktree - -**Pipeline Order**: euler → breaker → hopper → fowler → carmack → lamport → huffman -**State Storage**: `analysis/sdlc/pipeline.json` (git-tracked) -**CLI**: `studio sdlc run [-c N]`, `studio sdlc status`, `studio sdlc reset` - -### Agent Skills Support -Implements the Agent Skills specification (https://agentskills.io) for portable skill packages. - -- `crates/g3-core/src/skills/mod.rs` [0..42] - module exports: `Skill`, `discover_skills`, `generate_skills_prompt` +- `crates/g3-core/src/skills/mod.rs` [0..47] - exports: `Skill`, `discover_skills`, `generate_skills_prompt` - `crates/g3-core/src/skills/parser.rs` [0..363] - - `Skill` [11..30] - parsed skill struct with name, description, metadata, body, path - - `Skill::parse()` [45..100] - parses SKILL.md content with YAML frontmatter - - `Skill::from_file()` [95..105] - loads and parses from disk - - `split_frontmatter()` [107..130] - extracts YAML between `---` delimiters - - `validate_name()` [133..175] - validates 1-64 chars, lowercase+hyphens -- `crates/g3-core/src/skills/discovery.rs` [0..268] - - `discover_skills()` [28..65] - scans global, extra, workspace dirs in priority order - - `load_skills_from_dir()` [68..100] - loads SKILL.md from subdirectories - - `expand_tilde()` [120..125] - uses shellexpand for path expansion + - `Skill` [11..30] - name, description, metadata, body, path + - `Skill::parse()` [45..100] - parses SKILL.md with YAML frontmatter + - `validate_name()` [133..175] - 1-64 chars, lowercase+hyphens +- `crates/g3-core/src/skills/discovery.rs` [0..383] + - `discover_skills()` [38..85] - scans 5 locations: embedded → global → extra → workspace → repo + - `load_embedded_skills()` [88..102] - synthetic path `/SKILL.md` + - `is_embedded_skill()` [161..163] - checks `` XML block - - `escape_xml()` [42..48] - escapes special XML characters -- `crates/g3-config/src/lib.rs` - - `SkillsConfig` [180..200] - enabled flag, extra_paths vector - - Config.skills field [13..14] -- `crates/g3-cli/src/project_files.rs` - - `discover_and_format_skills()` [180..210] - discovers skills and generates prompt section - - `combine_project_content()` [87..110] - now includes skills_content parameter + - `generate_skills_prompt()` [12..40] - generates `` XML +- `crates/g3-config/src/lib.rs` [180..200] - `SkillsConfig` (enabled, extra_paths) +- `crates/g3-cli/src/project_files.rs` [180..210] - `discover_and_format_skills()` -**Skill Locations** (priority order): -1. `~/.g3/skills/` (global) -2. Config extra_paths -3. `.g3/skills/` (workspace, highest priority) +**Skill Locations** (priority: later overrides earlier): +1. Embedded (compiled in) +2. `~/.g3/skills/` (global) +3. Config extra_paths +4. `.g3/skills/` (workspace) +5. `skills/` (repo root) **SKILL.md Format**: ```yaml @@ -372,12 +245,81 @@ Implements the Agent Skills specification (https://agentskills.io) for portable name: skill-name # Required: 1-64 chars, lowercase + hyphens description: What it does # Required: 1-1024 chars license: Apache-2.0 # Optional -compatibility: Requires X # Optional: max 500 chars -metadata: # Optional: arbitrary key-value - author: org -allowed-tools: Bash Read # Optional/experimental +compatibility: Requires X # Optional --- - -# Skill Title -Detailed instructions... +# Instructions... ``` + +### Research Skill (Embedded) +Async web research via background scout agent. Externalized from core to embedded skill. + +- `skills/research/SKILL.md` - skill definition +- `skills/research/g3-research` - bash script for async research + - `write_status()` - writes status.json + - `extract_report()` - extracts between markers or filters output + +**Usage**: +```bash +background_process("research-topic", ".g3/bin/g3-research 'query'") +shell(".g3/bin/g3-research --status ") # or --list +read_file(".g3/research//report.md") +``` + +**Output**: `.g3/research//status.json` + `report.md` + +### Plan Mode +Structured task planning with cognitive forcing - requires happy/negative/boundary checks. + +- `crates/g3-core/src/tools/plan.rs` + - `Plan` [200..240] - plan_id, revision, approved_revision, items[] + - `PlanItem` [110..145] - id, description, state, touches, checks, evidence, notes + - `PlanState` [25..45] - enum: Todo, Doing, Done, Blocked + - `Checks` [90..105] - happy, negative[], boundary[] + - `get_plan_path()` [280..285] - `.g3/sessions//plan.g3.md` + - `read_plan()`, `write_plan()` [290..335] - YAML in markdown + - `plan_verify()` [659..700] - verifies evidence when complete + - `execute_plan_read/write/approve()` [395..530] - tool implementations +- `crates/g3-core/src/tool_definitions.rs` [263..330] - plan_read, plan_write, plan_approve +- `crates/g3-core/src/prompts.rs` [21..130] - SHARED_PLAN_SECTION + +**Tool names**: `plan_read`, `plan_write`, `plan_approve` (underscores, not dots) + +### Plan Verification System +- `crates/g3-core/src/tools/plan.rs` + - `EvidenceType` [283..300] - CodeLocation, TestReference, Unknown + - `VerificationStatus` [303..320] - Verified, Warning, Error, Skipped + - `parse_evidence()` [390..428] - parses `file:line-line` or `file::test_name` + - `verify_code_location()` [443..495] - checks file exists, lines in range + - `verify_test_reference()` [496..554] - checks test file, searches for fn + +**Evidence formats**: `src/foo.rs:42-118`, `src/foo.rs:42`, `tests/foo.rs::test_bar` + +### Invariants System (Rulespec & Envelope) +Machine-readable invariants for Plan Mode verification. + +- `crates/g3-core/src/tools/invariants.rs` + - `Claim` [50..75] - name + selector + - `PredicateRule` [80..120] - Contains, Equals, Exists, NotExists, GreaterThan, LessThan, MinLength, MaxLength, Matches + - `Predicate` [125..180] - claim, rule, value, source, notes + - `Rulespec` [185..240] - claims[] + predicates[] + - `ActionEnvelope` [245..290] - facts HashMap + - `Selector` [295..410] - XPath-like: `foo.bar`, `foo[0]`, `foo[*]` + - `evaluate_rulespec()` [780..850] - evaluates against envelope + - Paths: `.g3/sessions//rulespec.yaml`, `envelope.yaml` + +### Studio SDLC Pipeline +Orchestrates 7 agents in sequence for codebase maintenance. + +- `crates/studio/src/sdlc.rs` + - `PIPELINE_STAGES` [28..62] - euler → breaker → hopper → fowler → carmack → lamport → huffman + - `Stage` [18..26] - name, description, focus + - `StageStatus` [65..80] - Pending, Running, Complete, Failed, Skipped + - `PipelineState` [108..140] - run_id, stages[], commit_cursor, session_id + - `display_pipeline()` [354..390] - box display with status icons +- `crates/studio/src/main.rs` + - `cmd_sdlc_run()` [540..655] - orchestrates pipeline, merges on completion + - `has_commits_on_branch()` [715..728] - counts commits ahead of main +- `crates/studio/src/git.rs` - `merge_to_main()` (hardcodes 'main') + +**State**: `.g3/sdlc/pipeline.json` +**CLI**: `studio sdlc run [-c N]`, `studio sdlc status`, `studio sdlc reset` diff --git a/crates/g3-core/src/prompts.rs b/crates/g3-core/src/prompts.rs index 595bc5e..20d3ab3 100644 --- a/crates/g3-core/src/prompts.rs +++ b/crates/g3-core/src/prompts.rs @@ -263,7 +263,7 @@ mod tests { // Verify the include_str! macro successfully loads the file let prompt = EMBEDDED_NATIVE_PROMPT; assert!(!prompt.is_empty(), "Embedded prompt should not be empty"); - assert!(prompt.starts_with("# G3 System Prompt"), "Prompt should start with header"); + assert!(prompt.starts_with("You are G3"), "Prompt should start with agent introduction"); } #[test] diff --git a/crates/g3-core/src/skills/discovery.rs b/crates/g3-core/src/skills/discovery.rs index ec26e60..190f6ef 100644 --- a/crates/g3-core/src/skills/discovery.rs +++ b/crates/g3-core/src/skills/discovery.rs @@ -161,11 +161,6 @@ fn expand_tilde(path: &str) -> PathBuf { PathBuf::from(expanded.as_ref()) } -/// Check if a skill is from an embedded source. -pub fn is_embedded_skill(skill: &Skill) -> bool { - skill.path.starts_with(" Option<&'static EmbeddedSkill> { EMBEDDED_SKILLS.iter().find(|s| s.name == name) } -/// Get embedded skills as a map for easy lookup. -pub fn get_embedded_skills_map() -> HashMap<&'static str, &'static EmbeddedSkill> { - EMBEDDED_SKILLS.iter().map(|s| (s.name, s)).collect() -} - #[cfg(test)] mod tests { use super::*; @@ -72,10 +65,4 @@ mod tests { assert!(get_embedded_skill("research").is_some()); assert!(get_embedded_skill("nonexistent").is_none()); } - - #[test] - fn test_skills_map() { - let map = get_embedded_skills_map(); - assert!(map.contains_key("research")); - } } diff --git a/docs/architecture.md b/docs/architecture.md index 6243558..3bc5d43 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,7 +1,7 @@ # g3 Architecture -**Last updated**: January 2025 -**Source of truth**: Crate structure in `crates/`, `Cargo.toml`, `DESIGN.md` +**Last updated**: February 2025 +**Source of truth**: Crate structure in `crates/`, `Cargo.toml`, `DESIGN.md`, `skills/` ## Purpose @@ -72,6 +72,7 @@ g3/ │ ├── g3-planner/ # Planning mode workflow │ └── studio/ # Multi-agent workspace manager ├── agents/ # Agent persona definitions +├── skills/ # Embedded skills (research, etc.) ├── logs/ # Session logs (auto-created) └── g3-plan/ # Planning artifacts ``` @@ -94,6 +95,7 @@ Key modules: - `retry.rs` - Retry logic with exponential backoff - `prompts.rs` - System prompt generation - `code_search/` - Tree-sitter based code search +- `skills/` - Agent Skills discovery, parsing, and extraction **Key types**: - `Agent` - Main agent struct, generic over UI output @@ -230,6 +232,57 @@ Key modules: Studio enables isolated agent sessions by creating git worktrees, allowing multiple agents to work on the same codebase without conflicts. +### Skills System (Extensible Capabilities) + +**Location**: `crates/g3-core/src/skills/` and `skills/` +**Purpose**: Portable skill packages that extend agent capabilities + +g3 implements the [Agent Skills](https://agentskills.io) specification, allowing skills to be discovered from multiple locations and embedded into the binary for portability. + +Key modules in `crates/g3-core/src/skills/`: +- `mod.rs` - Module exports and public API +- `parser.rs` - SKILL.md frontmatter and body parsing +- `discovery.rs` - Multi-location skill discovery with priority ordering +- `embedded.rs` - Skills compiled into the binary via `include_str!` +- `extraction.rs` - Script extraction to `.g3/bin/` with version tracking +- `prompt.rs` - Generates `` XML for system prompt + +**Discovery Priority** (lowest to highest): +1. Embedded skills (compiled into binary) +2. Global: `~/.g3/skills/` +3. Extra paths from config +4. Workspace: `.g3/skills/` +5. Repo: `skills/` (highest priority, checked into git) + +**Embedded Skills**: + +Core skills are embedded at compile time using `include_str!`, ensuring g3 works anywhere without external files: + +```rust +static EMBEDDED_SKILLS: &[EmbeddedSkill] = &[ + EmbeddedSkill { + name: "research", + skill_md: include_str!("../../../../skills/research/SKILL.md"), + scripts: &[ + ("g3-research", include_str!("../../../../skills/research/g3-research")), + ], + }, +]; +``` + +**Script Extraction**: + +Embedded scripts are extracted to `.g3/bin/` on first use: +- Version tracking via content hash in `.g3/bin/