Merge sessions/sdlc/3b6c6c3e into main

Resolved conflicts:
- analysis/memory.md: kept condensed documentation from incoming branch
- crates/g3-core/src/skills/embedded.rs: removed unused HashMap import, kept better doc comment

Additional fix:
- crates/g3-core/src/prompts.rs: updated test to match current prompt file content
This commit is contained in:
Dhanji R. Prasanna
2026-02-05 14:38:08 +11:00
15 changed files with 1472 additions and 976 deletions

View File

@@ -30,6 +30,7 @@
- **New tool**: Add definition in `tool_definitions.rs`, implement in `tools/`, add dispatch case - **New tool**: Add definition in `tool_definitions.rs`, implement in `tools/`, add dispatch case
- **New provider**: Implement `LLMProvider` trait in `g3-providers` - **New provider**: Implement `LLMProvider` trait in `g3-providers`
- **New CLI mode**: Add to CLI args, implement handler in `g3-cli` - **New CLI mode**: Add to CLI args, implement handler in `g3-cli`
- **New skill**: Create `skills/<name>/SKILL.md`, optionally add to `embedded.rs` for binary inclusion
- **New config option**: Add to `g3-config` structs - **New config option**: Add to `g3-config` structs
## Dangerous Code Paths ## Dangerous Code Paths
@@ -43,6 +44,7 @@ These areas have subtle bugs if modified incorrectly:
| **Tool dispatch** | Missing dispatch cases cause silent failures | | **Tool dispatch** | Missing dispatch cases cause silent failures |
| **Retry logic** | Aggressive retries hit rate limits harder | | **Retry logic** | Aggressive retries hit rate limits harder |
| **Parser sanitization** | Inline JSON can trigger false tool call detection | | **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 ## 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 | | `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. 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 `<available_skills>` 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

View File

@@ -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. 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): **Skill Locations** (in priority order, later overrides earlier):
1. Global: `~/.g3/skills/` 1. Embedded skills (compiled into binary)
2. Extra paths from config 2. Global: `~/.g3/skills/`
3. Workspace: `.g3/skills/` (highest priority) 3. Extra paths from config
4. Workspace: `.g3/skills/`
5. Repo: `skills/` (highest priority, checked into git)
**SKILL.md Format**: **SKILL.md Format**:
```yaml ```yaml
@@ -146,6 +148,12 @@ Each skill adds ~50-100 tokens to context (name + description + path). Skills ca
- `references/` - Additional documentation - `references/` - Additional documentation
- `assets/` - Templates, data files - `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/<id>/report.md`.
See [Skills Guide](docs/skills.md) for detailed documentation.
### Provider Flexibility ### Provider Flexibility
- Support for multiple LLM providers through a unified interface - Support for multiple LLM providers through a unified interface
- Hot-swappable providers without code changes - 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 | | [Tools Reference](docs/tools.md) | Complete reference for all available tools |
| [Providers Guide](docs/providers.md) | LLM provider setup and selection guide | | [Providers Guide](docs/providers.md) | LLM provider setup and selection guide |
| [Control Commands](docs/CONTROL_COMMANDS.md) | Interactive `/` commands for context management | | [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 | | [Code Search](docs/CODE_SEARCH.md) | Tree-sitter code search query patterns |
For AI agents working with this codebase, see [AGENTS.md](AGENTS.md). For AI agents working with this codebase, see [AGENTS.md](AGENTS.md).

View File

@@ -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:
<skill>
<name>research</name>
<description>...</description>
<location><embedded:research>/SKILL.md</location>
</skill>
# The prompt instructs:
"read the full skill file using `read_file` to get detailed instructions"
# Agent attempts:
read_file("<embedded:research>/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 `<embedded:name>/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 `<embedded:*>` 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.

View File

@@ -1,344 +1,440 @@
{ {
"metadata": { "metadata": {
"generated_by": "euler structural analysis agent", "generated_at": "2025-02-05T14:00:00Z",
"generated_at": "2025-02-02T17:30:00Z", "scope": "Changes in commits b6d2582..9443f933 (10 commits)",
"workspace": "g3", "extraction_method": "Static analysis of Rust use/mod statements and Cargo.toml",
"node_count": 127, "tool_version": "euler-manual-1.0"
"edge_count": 218,
"crate_count": 9,
"file_count": 118,
"extraction_method": "static import parsing via ripgrep"
}, },
"nodes": [ "nodes": {
{"id": "crate:g3", "type": "crate", "name": "g3", "path": "."}, "crates": [
{"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": "g3-core",
{"id": "crate:g3-providers", "type": "crate", "name": "g3-providers", "path": "crates/g3-providers"}, "type": "crate",
{"id": "crate:g3-config", "type": "crate", "name": "g3-config", "path": "crates/g3-config"}, "path": "crates/g3-core",
{"id": "crate:g3-execution", "type": "crate", "name": "g3-execution", "path": "crates/g3-execution"}, "changed_in_scope": true
{"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": "g3-cli",
"type": "crate",
{"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}, "path": "crates/g3-cli",
{"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"}, "changed_in_scope": true
{"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": "g3-config",
{"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"}, "type": "crate",
{"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"}, "path": "crates/g3-config",
{"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"}, "changed_in_scope": true
{"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": "studio",
{"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"}, "type": "crate",
{"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"}, "path": "crates/studio",
{"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"}, "changed_in_scope": true
{"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": "g3-providers",
{"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"}, "type": "crate",
{"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"}, "path": "crates/g3-providers",
{"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"}, "changed_in_scope": false
{"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": "g3-execution",
{"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"}, "type": "crate",
{"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"}, "path": "crates/g3-execution",
"changed_in_scope": false
{"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": "g3-computer-control",
{"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"}, "type": "crate",
{"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"}, "path": "crates/g3-computer-control",
{"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"}, "changed_in_scope": false
{"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": "g3-planner",
{"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"}, "type": "crate",
{"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"}, "path": "crates/g3-planner",
{"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"}, "changed_in_scope": false
{"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": [ "files": [
{"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\" }"}, "id": "g3-core/src/skills/mod.rs",
"type": "module",
{"from": "crate:g3-cli", "to": "crate:g3-core", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-core = { path = \"../g3-core\" }"}, "crate": "g3-core",
{"from": "crate:g3-cli", "to": "crate:g3-config", "type": "crate_dependency", "evidence": "crates/g3-cli/Cargo.toml: g3-config = { path = \"../g3-config\" }"}, "status": "added"
{"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\" }"}, "id": "g3-core/src/skills/parser.rs",
"type": "file",
{"from": "crate:g3-core", "to": "crate:g3-providers", "type": "crate_dependency", "evidence": "crates/g3-core/Cargo.toml: g3-providers = { path = \"../g3-providers\" }"}, "crate": "g3-core",
{"from": "crate:g3-core", "to": "crate:g3-config", "type": "crate_dependency", "evidence": "crates/g3-core/Cargo.toml: g3-config = { path = \"../g3-config\" }"}, "status": "added"
{"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\" }"}, {
"id": "g3-core/src/skills/discovery.rs",
{"from": "crate:g3-planner", "to": "crate:g3-providers", "type": "crate_dependency", "evidence": "crates/g3-planner/Cargo.toml: g3-providers = { path = \"../g3-providers\" }"}, "type": "file",
{"from": "crate:g3-planner", "to": "crate:g3-core", "type": "crate_dependency", "evidence": "crates/g3-planner/Cargo.toml: g3-core = { path = \"../g3-core\" }"}, "crate": "g3-core",
{"from": "crate:g3-planner", "to": "crate:g3-config", "type": "crate_dependency", "evidence": "crates/g3-planner/Cargo.toml: g3-config = { path = \"../g3-config\" }"}, "status": "added"
},
{"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"}, "id": "g3-core/src/skills/prompt.rs",
"type": "file",
{"from": "file:crates/g3-cli/src/utils.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, "crate": "g3-core",
{"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"}, "status": "added"
{"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"}, {
"id": "g3-core/src/skills/embedded.rs",
{"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"}, "type": "file",
{"from": "file:crates/g3-cli/src/interactive.rs", "to": "file:crates/g3-cli/src/completion.rs", "type": "import", "evidence": "use crate::completion::G3Helper"}, "crate": "g3-core",
{"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}"}, "status": "added"
{"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"}, "id": "g3-core/src/skills/extraction.rs",
{"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"}, "type": "file",
{"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"}, "crate": "g3-core",
{"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"}, "status": "added"
{"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"}, "id": "g3-core/src/prompts.rs",
"type": "file",
{"from": "file:crates/g3-cli/src/ui_writer_impl.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::ui_writer::UiWriter"}, "crate": "g3-core",
{"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}"}, "status": "modified"
{"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"}, {
"id": "g3-core/src/lib.rs",
{"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"}, "type": "file",
{"from": "file:crates/g3-cli/src/autonomous.rs", "to": "file:crates/g3-cli/src/coach_feedback.rs", "type": "import", "evidence": "use crate::coach_feedback"}, "crate": "g3-core",
{"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}"}, "status": "modified"
{"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"}, {
"id": "g3-core/src/tool_definitions.rs",
{"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"}, "type": "file",
"crate": "g3-core",
{"from": "file:crates/g3-cli/src/coach_feedback.rs", "to": "crate:g3-core", "type": "import", "evidence": "use g3_core::Agent"}, "status": "modified"
{"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"}, {
"id": "g3-core/src/tool_dispatch.rs",
{"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"}, "type": "file",
{"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/autonomous.rs", "type": "import", "evidence": "use crate::autonomous::run_autonomous"}, "crate": "g3-core",
{"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"}, "status": "modified"
{"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"}, "id": "g3-core/src/tools/mod.rs",
{"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"}, "type": "file",
{"from": "file:crates/g3-cli/src/accumulative.rs", "to": "file:crates/g3-cli/src/template.rs", "type": "import", "evidence": "use crate::template::process_template"}, "crate": "g3-core",
"status": "modified"
{"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}"}, "id": "g3-core/src/tools/executor.rs",
"type": "file",
{"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"}, "crate": "g3-core",
{"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"}, "status": "modified"
{"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"}, "id": "g3-core/src/tools/acd.rs",
{"from": "file:crates/g3-cli/src/commands.rs", "to": "file:crates/g3-cli/src/completion.rs", "type": "import", "evidence": "use crate::completion::G3Helper"}, "type": "file",
{"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}"}, "crate": "g3-core",
{"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"}, "status": "modified"
{"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"}, "id": "g3-core/src/pending_research.rs",
"type": "file",
{"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"}, "crate": "g3-core",
"status": "deleted"
{"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}"}, "id": "g3-core/src/tools/research.rs",
{"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}"}, "type": "file",
{"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"}, "crate": "g3-core",
{"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"}, "status": "deleted"
{"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"}, "id": "g3-cli/src/lib.rs",
{"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}"}, "type": "file",
{"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"}, "crate": "g3-cli",
"status": "modified"
{"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"}, "id": "g3-cli/src/project_files.rs",
"type": "file",
{"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}"}, "crate": "g3-cli",
{"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"}, "status": "modified"
{"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"}, "id": "g3-cli/src/agent_mode.rs",
"type": "file",
{"from": "file:crates/g3-core/src/compaction.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CompletionRequest, Message, MessageRole, ProviderRegistry}"}, "crate": "g3-cli",
{"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"}, "status": "modified"
{"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"}, {
"id": "g3-cli/src/interactive.rs",
{"from": "file:crates/g3-core/src/stats.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::MessageRole"}, "type": "file",
{"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"}, "crate": "g3-cli",
{"from": "file:crates/g3-core/src/stats.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::CacheStats"}, "status": "modified"
},
{"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"}, "id": "g3-cli/src/commands.rs",
{"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"}, "type": "file",
{"from": "file:crates/g3-core/src/streaming.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "crate": "g3-cli",
"status": "modified"
{"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"}, "id": "g3-cli/src/g3_status.rs",
{"from": "file:crates/g3-core/src/provider_registration.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::ProviderRegistry"}, "type": "file",
"crate": "g3-cli",
{"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}"}, "status": "modified"
},
{"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"}, "id": "g3-cli/src/ui_writer_impl.rs",
{"from": "file:crates/g3-core/src/acd.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "type": "file",
"crate": "g3-cli",
{"from": "file:crates/g3-core/src/streaming_parser.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "status": "modified"
},
{"from": "file:crates/g3-core/src/task_result.rs", "to": "file:crates/g3-core/src/context_window.rs", "type": "import", "evidence": "use crate::ContextWindow"}, {
"id": "g3-cli/src/accumulative.rs",
{"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"}, "type": "file",
{"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}"}, "crate": "g3-cli",
{"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"}, "status": "modified"
{"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"}, "id": "g3-config/src/lib.rs",
{"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"}, "type": "file",
{"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}"}, "crate": "g3-config",
"status": "modified"
{"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"}, "id": "studio/src/main.rs",
"type": "file",
{"from": "file:crates/g3-core/src/feedback_extraction.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::{Agent, TaskResult}"}, "crate": "studio",
{"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"}, "status": "modified"
},
{"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"}, "id": "studio/src/sdlc.rs",
{"from": "file:crates/g3-core/src/tools/acd.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "type": "file",
"crate": "studio",
{"from": "file:crates/g3-core/src/tools/executor.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, "status": "modified"
{"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}"}, "id": "skills/research/SKILL.md",
{"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"}, "type": "skill",
{"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"}, "crate": null,
{"from": "file:crates/g3-core/src/tools/executor.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "status": "added"
},
{"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"}, "id": "skills/research/g3-research",
{"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"}, "type": "script",
{"from": "file:crates/g3-core/src/tools/shell.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "crate": null,
"status": "added"
{"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"}, "id": "prompts/system/native.md",
"type": "prompt",
{"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"}, "crate": null,
{"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"}, "status": "modified"
{"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"}, "edges": {
{"from": "file:crates/g3-core/src/tools/plan.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "crate_dependencies": [
{
{"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": "g3-cli",
{"from": "file:crates/g3-core/src/tools/memory.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "to": "g3-core",
"type": "cargo_dependency",
{"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"}, "evidence": "crates/g3-cli/Cargo.toml: g3-core = { path = \"../g3-core\" }"
{"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": "g3-cli",
{"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"}, "to": "g3-config",
{"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"}, "type": "cargo_dependency",
{"from": "file:crates/g3-core/src/tools/webdriver.rs", "to": "file:crates/g3-core/src/lib.rs", "type": "import", "evidence": "use crate::ToolCall"}, "evidence": "crates/g3-cli/Cargo.toml: g3-config = { path = \"../g3-config\" }"
},
{"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": "g3-cli",
{"from": "file:crates/g3-providers/src/gemini.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, "to": "g3-providers",
{"from": "file:crates/g3-providers/src/databricks.rs", "to": "file:crates/g3-providers/src/lib.rs", "type": "import", "evidence": "use crate::{...}"}, "type": "cargo_dependency",
{"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}"}, "evidence": "crates/g3-cli/Cargo.toml: g3-providers = { path = \"../g3-providers\" }"
{"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": "g3-cli",
"to": "g3-planner",
{"from": "file:crates/g3-planner/src/lib.rs", "to": "crate:g3-providers", "type": "import", "evidence": "use g3_providers::{CompletionRequest, LLMProvider, Message, MessageRole}"}, "type": "cargo_dependency",
{"from": "file:crates/g3-planner/src/llm.rs", "to": "crate:g3-config", "type": "import", "evidence": "use g3_config::Config"}, "evidence": "crates/g3-cli/Cargo.toml: g3-planner = { path = \"../g3-planner\" }"
{"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": "g3-cli",
{"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/git.rs", "type": "import", "evidence": "use crate::git"}, "to": "g3-computer-control",
{"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/history.rs", "type": "import", "evidence": "use crate::history"}, "type": "cargo_dependency",
{"from": "file:crates/g3-planner/src/planner.rs", "to": "file:crates/g3-planner/src/llm.rs", "type": "import", "evidence": "use crate::llm"}, "evidence": "crates/g3-cli/Cargo.toml: g3-computer-control = { path = \"../g3-computer-control\" }"
{"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": "g3-core",
{"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}"}, "to": "g3-config",
{"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}"}, "type": "cargo_dependency",
"evidence": "crates/g3-core/Cargo.toml: g3-config = { path = \"../g3-config\" }"
{"from": "file:crates/studio/src/git.rs", "to": "file:crates/studio/src/session.rs", "type": "import", "evidence": "use crate::session::Session"} },
{
"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"
}
] ]
} }
}

View File

@@ -1,105 +1,105 @@
# Dependency Graph Summary # Dependency Graph Summary
**Generated**: 2025-02-02 **Scope**: Changes in commits `b6d2582..9443f933` (10 commits)
**Extraction Method**: Static import parsing via ripgrep **Generated**: 2025-02-05
**Workspace**: g3
## Metrics ## Metrics
| Metric | Count | | Metric | Count |
|--------|-------| |--------|-------|
| Total Nodes | 127 | | Crates (total) | 8 |
| Crate Nodes | 9 | | Crates (changed) | 4 |
| File Nodes | 118 | | Files (changed) | 29 |
| Total Edges | 156 | | Files (added) | 8 |
| Crate-level Edges | 14 | | Files (deleted) | 2 |
| File-level Edges | 142 | | Files (modified) | 19 |
| Crate-level edges | 12 |
| File-level edges | 21 |
## Crate Dependency Structure ## Changed Crates
``` | Crate | Path | Role |
g3 (root binary) |-------|------|------|
├── g3-cli | g3-core | crates/g3-core | Core engine, skills module added |
│ ├── g3-core | g3-cli | crates/g3-cli | CLI interface, skills integration |
│ ├── g3-config | g3-config | crates/g3-config | Configuration, SkillsConfig added |
│ ├── g3-planner | studio | crates/studio | Multi-agent workspace, SDLC changes |
│ ├── 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)
```
## Entrypoints ## Entrypoints
| Entrypoint | Path | Type | | Entrypoint | Type | Evidence |
|------------|------|------| |------------|------|----------|
| g3 | `src/main.rs` | Binary | | g3-cli/src/lib.rs | Library root | `pub fn run()` |
| studio | `crates/studio/src/main.rs` | Binary | | studio/src/main.rs | Binary | `fn main()` |
| g3-cli | `crates/g3-cli/src/lib.rs` | Library | | 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 | | Node | Fan-In | Dependents |
|------|--------|-------------| |------|--------|------------|
| `g3-core/src/lib.rs` | 18 | Core Agent, ToolCall types | | g3-core/src/skills/parser.rs | 3 | discovery.rs, prompt.rs, mod.rs |
| `g3-core/src/ui_writer.rs` | 14 | UiWriter trait | | g3-core/src/skills/embedded.rs | 3 | discovery.rs, extraction.rs, mod.rs |
| `g3-cli/src/simple_output.rs` | 9 | SimpleOutput helper | | g3-core/src/skills/mod.rs | 3 | lib.rs, prompts.rs, project_files.rs |
| `g3-cli/src/template.rs` | 6 | Template processing | | g3-config/src/lib.rs | 2 | g3-core (crate), g3-cli (crate) |
| `g3-core/src/paths.rs` | 6 | Path utilities | | g3-cli/src/project_files.rs | 2 | lib.rs, agent_mode.rs |
| `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 |
## 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 (crate) | 5 | g3-core, g3-config, g3-providers, g3-planner, g3-computer-control |
| `g3-cli/src/agent_mode.rs` | 11 | Agent mode runner | | g3-core/src/skills/mod.rs | 5 | parser.rs, discovery.rs, prompt.rs, embedded.rs, extraction.rs |
| `g3-cli/src/accumulative.rs` | 8 | Accumulative mode | | g3-core/src/skills/discovery.rs | 2 | parser.rs, embedded.rs |
| `g3-cli/src/commands.rs` | 7 | CLI commands | | g3-cli/src/project_files.rs | 2 | g3-core::skills, g3-config::SkillsConfig |
| `g3-core/src/tools/executor.rs` | 7 | Tool execution context | | studio/src/main.rs | 3 | sdlc.rs, git.rs, session.rs |
| `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 |
## Crate File Counts ## Major Structural Changes
| Crate | Source Files | Test Files | ### Added: Skills Module (`g3-core/src/skills/`)
|-------|--------------|------------|
| g3-cli | 21 | 5 | New module implementing Agent Skills specification:
| g3-core | 32 | 33 |
| g3-providers | 12 | 4 | ```
| g3-planner | 7 | 4 | g3-core/src/skills/
| g3-computer-control | 12 | 1 | ├── mod.rs # Module root, re-exports
| g3-config | 2 | 0 | ├── parser.rs # SKILL.md YAML frontmatter parser
| g3-execution | 1 | 0 | ├── discovery.rs # Skill directory scanning
| studio | 3 | 0 | ├── 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 ## Extraction Limitations
1. **Dynamic imports not captured**: Any runtime module loading is not reflected - Dynamic imports not detected (none expected in Rust)
2. **Macro-generated imports**: Imports generated by macros may be missed - Test-only dependencies not distinguished from production
3. **Conditional compilation**: `#[cfg(...)]` gated imports are included regardless of target - Conditional compilation (`#[cfg(...)]`) not analyzed
4. **Re-exports**: Transitive re-exports through `pub use` are not fully traced - External crate dependencies (from crates.io) not enumerated
5. **Test files excluded from graph**: Test files (`tests/`) are not included in file nodes

View File

@@ -1,79 +1,101 @@
# Coupling Hotspots # Coupling Hotspots
**Generated**: 2025-02-02 **Scope**: Changes in commits `b6d2582..9443f933` (10 commits)
**Method**: Fan-in/fan-out analysis from dependency graph
## High Fan-In Files (Most Depended Upon) ## 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 | | File | Fan-In | Dependents | Risk |
|------|--------|------------| |------|--------|------------|------|
| `g3-core/src/lib.rs` | 18 | streaming_parser, context_window, acd, streaming, stats, retry, feedback_extraction, task_result, tool_dispatch, tools/* | | `g3-core/src/skills/parser.rs` | 3 | discovery.rs, prompt.rs, mod.rs | Medium |
| `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-core/src/skills/embedded.rs` | 3 | discovery.rs, extraction.rs, mod.rs | Medium |
| `g3-cli/src/simple_output.rs` | 9 | utils, interactive, autonomous, coach_feedback, accumulative, task_execution, commands, agent_mode | | `g3-core/src/skills/mod.rs` | 3 | lib.rs, prompts.rs, project_files.rs (cross-crate) | High |
| `g3-cli/src/template.rs` | 6 | project_files, accumulative, commands, embedded_agents, agent_mode, interactive | | `g3-config/src/lib.rs` | 2 | g3-core, g3-cli (cross-crate) | High |
| `g3-core/src/paths.rs` | 6 | acd, session, context_window, tools/{executor,shell,plan} | | `g3-cli/src/project_files.rs` | 2 | lib.rs, agent_mode.rs | Medium |
| `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 | ### Analysis
| `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/skills/mod.rs`** (Fan-In: 3, Cross-Crate: Yes)
| `g3-core/src/utils.rs` | 3 | tools/{shell,file_ops} | - 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) ## 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 | | File | Fan-Out | Dependencies | Risk |
|------|---------|-------------| |------|---------|--------------|------|
| `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-core/src/skills/mod.rs` | 5 | parser, discovery, prompt, embedded, extraction | Medium |
| `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-core/src/skills/discovery.rs` | 2 | parser.rs, embedded.rs | Low |
| `g3-cli/src/accumulative.rs` | 8 | g3-core, autonomous, cli_args, interactive, simple_output, ui_writer_impl, utils, template | | `g3-cli/src/project_files.rs` | 2 | g3-core::skills, g3-config | Medium |
| `g3-cli/src/commands.rs` | 7 | g3-core, completion, g3_status, simple_output, project, template, task_execution | | `studio/src/main.rs` | 3 | sdlc.rs, git.rs, session.rs | Low |
| `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) |
## 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-cli/src/project_files.rs`** (Fan-Out: 2, Cross-Crate: Yes)
|------|---------------------|----------------| - Bridges g3-core skills and g3-config
| `g3-core/src/lib.rs` | 2 | g3-config, g3-providers | - **Evidence**: `use g3_core::{discover_skills, ...}`, `use g3_config::SkillsConfig`
| `g3-core/src/webdriver_session.rs` | 1 | g3-computer-control | - **Impact**: Integration point for skills feature in CLI
| `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 |
## Crate-Level Coupling ## Cross-Crate Coupling
| Crate | Outgoing Deps | Incoming Deps | Coupling Score | Edges that cross crate boundaries. Higher coordination cost for changes.
|-------|---------------|---------------|----------------|
| 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 |
## 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

View File

@@ -1,152 +1,120 @@
# Observed Layering Structure # Observed Layering
**Generated**: 2025-02-02 **Scope**: Changes in commits `b6d2582..9443f933` (10 commits)
**Method**: Derived from crate dependencies and file import patterns
## 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): ┌─────────────────────────────────────────────────────────────┐
┌─────────────────┬─────────────────┬─────────────────────────┬─────────────────┐ │ Layer 4: Binaries / Entry Points │
g3-config g3-execution g3-computer-control g3-providers ┌─────────────┐ ┌─────────────┐
(config mgmt)(code execution)│ (browser/UI control) │ (LLM providers) │ g3-cli │ studio │
└─────────────────┴─────────────────┴─────────────────────────┴─────────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Layer 1 (Core Engine): ┌─────────────────────────────────────────────────────────────┐
┌───────────────────────────────────────────────────────────────────────────────┐ │ Layer 3: Orchestration │
g3-core ┌─────────────┐
(Agent, ToolCall, context management, tool dispatch, streaming) │ g3-planner │
└───────────────────────────────────────────────────────────────────────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Layer 2 (Orchestration): ┌─────────────────────────────────────────────────────────────┐
┌───────────────────────────────────────────────────────────────────────────────┐ │ Layer 2: Core Engine │
g3-planner ┌─────────────────────────────────────────────────────┐
(fast-discovery planner, git integration, LLM orchestration) │ g3-core
└───────────────────────────────────────────────────────────────────────────────┘ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ skills │ │ tools │ │ prompts │ │ context │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Layer 3 (CLI/Application): ┌─────────────────────────────────────────────────────────────┐
┌───────────────────────────────────────────────────────────────────────────────┐ │ Layer 1: Infrastructure │
g3-cli ┌─────────────┐ ┌─────────────┐ ┌───────────────────────┐
(interactive mode, autonomous mode, agent mode, commands, UI) │ g3-config │ │g3-providers │ │ g3-computer-control
└─────────────────────────────────────────────────────────────────────────────── └─────────────┘ └─────────────┘ └───────────────────────┘
│ ┌─────────────┐ │
│ │g3-execution │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
Layer 4 (Binary Entry): ┌─────────────────────────────────────────────────────────────┐
┌───────────────────────────────────────────────────────────────────────────────┐ │ Layer 0: External Assets │
g3 ┌─────────────────────────────────────────────────────┐
(main binary, minimal - delegates to g3-cli) │ skills/research/ (SKILL.md, g3-research script) │
───────────────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────┘
│ ┌─────────────────────────────────────────────────────┐ │
Separate: │ │ prompts/system/ (native.md, etc.) │ │
┌─────────────────────────────────────────────────────────────────────────────── │ └─────────────────────────────────────────────────────┘ │
│ studio │ └─────────────────────────────────────────────────────────────┘
│ (standalone multi-agent workspace manager, no g3 crate dependencies) │
└───────────────────────────────────────────────────────────────────────────────┘
``` ```
## 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 ## 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) mod.rs (coordinator, re-exports) │ Layer 2.3
└───────────────────────────────────────┘
Mode Layer: ┌───────────────────────────────────────┐
interactive.rs, autonomous.rs, agent_mode.rs, accumulative.rs discovery.rs, prompt.rs, extraction │ Layer 2.2
│ (use parser.rs and/or embedded.rs) │
└───────────────────────────────────────┘
Command/Execution Layer: ┌───────────────────────────────────────┐
commands.rs, task_execution.rs, coach_feedback.rs parser.rs, embedded.rs (leaf nodes) │ Layer 2.1
│ (no internal dependencies)
└───────────────────────────────────────┘
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
``` ```
## File-Level Layering Within g3-core ## Derivation Method
``` Layers derived mechanically from:
Entry Layer: 1. Cargo.toml `[dependencies]` sections
lib.rs (Agent struct, stream_completion_with_tools) 2. `use` statement analysis
3. `mod` declaration hierarchy
4. `include_str!` compile-time references
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
```
## File-Level Layering Within g3-providers No semantic interpretation applied.
```
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.

View File

@@ -1,114 +1,66 @@
# Analysis Limitations # Analysis Limitations
**Generated**: 2025-02-02 **Scope**: Changes in commits `b6d2582..9443f933` (10 commits)
## What Could Not Be Observed ## What Could Not Be Observed
### 1. Dynamic/Runtime Dependencies | Limitation | Impact | Mitigation |
|------------|--------|------------|
- **Plugin loading**: Any runtime module loading via `dlopen` or similar | Runtime dispatch | Tool dispatch uses string matching, not static imports | Analyzed `tool_dispatch.rs` manually |
- **Reflection-based imports**: Dependencies resolved at runtime | Conditional compilation | `#[cfg(...)]` blocks not analyzed | May miss platform-specific deps |
- **Configuration-driven imports**: Modules loaded based on config values | 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 |
### 2. Macro-Generated Code | 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 |
- **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
## What Was Inferred ## 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: ## Potential Invalidators
- `mod` declarations in `lib.rs` and `mod.rs` files
- File system structure (`foo/mod.rs` implies `foo` module)
**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: 2. **Workspace-level dependencies**: The `[workspace.dependencies]` section in root `Cargo.toml` was not analyzed for version constraints.
- `Cargo.toml` `[dependencies]` sections
- `path = "..."` declarations for workspace crates
**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: 5. **Path aliases**: If `Cargo.toml` uses `[patch]` or path aliases, actual dependency resolution may differ.
- `^use (g3_|crate::)` for internal imports
- `^(pub )?mod ` for module declarations
**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: ```bash
- New files added # Get changed files
- Import statements changed git diff --name-only 9443f933~10..9443f933
- Module structure reorganized
- Cargo.toml dependencies modified
### 2. Incomplete Extraction # Extract imports from Rust files
rg "^use |^mod |use g3_|use crate::" crates/*/src/*.rs
The regex-based extraction may miss: # Check Cargo.toml dependencies
- Multi-line `use` statements with unusual formatting cat crates/*/Cargo.toml | grep -A20 "\[dependencies\]"
- 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

View File

@@ -1,83 +1,61 @@
# Strongly Connected Components (Cycles) # Strongly Connected Components (Cycles)
**Generated**: 2025-02-02 **Scope**: Changes in commits `b6d2582..9443f933` (10 commits)
**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.
## Summary ## Summary
| Scope | Cycles Found | Severity | | Metric | Count |
|-------|--------------|----------| |--------|-------|
| Crate-level | 0 | N/A | | SCCs with >1 node | 0 |
| File-level (g3-core) | 0 problematic | N/A | | Trivial SCCs (single node) | 29 |
| File-level (g3-cli) | 0 | N/A |
| File-level (g3-providers) | 0 | N/A |
| File-level (g3-planner) | 0 | N/A |
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.

View File

@@ -1,5 +1,5 @@
# Workspace Memory # Workspace Memory
> Updated: 2026-02-04T23:42:21Z | Size: 19.9k chars > Updated: 2026-02-05T14:30:00Z | Size: ~19k chars
### Remember Tool Wiring ### Remember Tool Wiring
- `crates/g3-core/src/tools/memory.rs` [0..5000] - `execute_remember()`, `get_memory_path()`, `merge_memory()` - `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 ### UTF-8 Safe String Slicing
Rust `&s[..n]` panics on multi-byte chars (emoji, CJK) if sliced mid-character. 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())` **Pattern**: `s.char_indices().nth(n).map(|(i,_)| i).unwrap_or(s.len())`
**Danger zones**: Display truncation, ACD stubs, user input, non-ASCII text. **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_language_prompts_for_workspace()` [88..108]
- `get_agent_language_prompts_for_workspace()` [124..137] - `get_agent_language_prompts_for_workspace()` [124..137]
- `crates/g3-cli/src/agent_mode.rs` [149..159] - appends agent-specific prompts - `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/<lang>.md`, add to `LANGUAGE_PROMPTS` **To add language**: Create `prompts/langs/<lang>.md`, add to `LANGUAGE_PROMPTS`
**To add agent+lang**: Create `prompts/langs/<agent>.<lang>.md`, add to `AGENT_LANGUAGE_PROMPTS` **To add agent+lang**: Create `prompts/langs/<agent>.<lang>.md`, add to `AGENT_LANGUAGE_PROMPTS`
@@ -165,7 +164,6 @@ Auto-detects languages and injects toolchain guidance.
- `done()` [72] - bold green "[done]" - `done()` [72] - bold green "[done]"
- `failed()` [81] - red "[failed]" - `failed()` [81] - red "[failed]"
- `thin_result()` [236] - formats ThinResult with colors - `thin_result()` [236] - formats ThinResult with colors
- `resuming()` [213] - session resume with cyan ID
### Prompt Cache Statistics ### Prompt Cache Statistics
- `crates/g3-providers/src/lib.rs` [195..210] - `Usage.cache_creation_tokens`, `cache_read_tokens` - `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 gpu_layers = 99
``` ```
### Plan Mode (replaces TODO system) ### Agent Skills System
Structured task planning with cognitive forcing - requires happy/negative/boundary checks. Portable skill packages with SKILL.md + optional scripts per Agent Skills spec (agentskills.io).
- `crates/g3-core/src/tools/plan.rs` - `crates/g3-core/src/skills/mod.rs` [0..47] - exports: `Skill`, `discover_skills`, `generate_skills_prompt`
- `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/<id>/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 <desc>` → 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<end>)
- `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<String, YamlValue>
- `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/<id>/rulespec.yaml`
- `get_envelope_path()` [642..647] - `.g3/sessions/<id>/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/parser.rs` [0..363] - `crates/g3-core/src/skills/parser.rs` [0..363]
- `Skill` [11..30] - parsed skill struct with name, description, metadata, body, path - `Skill` [11..30] - name, description, metadata, body, path
- `Skill::parse()` [45..100] - parses SKILL.md content with YAML frontmatter - `Skill::parse()` [45..100] - parses SKILL.md with YAML frontmatter
- `Skill::from_file()` [95..105] - loads and parses from disk - `validate_name()` [133..175] - 1-64 chars, lowercase+hyphens
- `split_frontmatter()` [107..130] - extracts YAML between `---` delimiters - `crates/g3-core/src/skills/discovery.rs` [0..383]
- `validate_name()` [133..175] - validates 1-64 chars, lowercase+hyphens - `discover_skills()` [38..85] - scans 5 locations: embedded → global → extra → workspace → repo
- `crates/g3-core/src/skills/discovery.rs` [0..268] - `load_embedded_skills()` [88..102] - synthetic path `<embedded:name>/SKILL.md`
- `discover_skills()` [28..65] - scans global, extra, workspace dirs in priority order - `is_embedded_skill()` [161..163] - checks `<embedded:` prefix
- `load_skills_from_dir()` [68..100] - loads SKILL.md from subdirectories - `crates/g3-core/src/skills/embedded.rs` [0..87]
- `expand_tilde()` [120..125] - uses shellexpand for path expansion - `EmbeddedSkill` [22..28] - name, skill_md, scripts[]
- `EMBEDDED_SKILLS` [32..42] - static array with include_str! for research skill
- `crates/g3-core/src/skills/extraction.rs` [0..234]
- `extract_script()` [28..85] - extracts to `.g3/bin/`, tracks version hash
- `needs_update()` [107..118] - compares stored hash vs content
- `crates/g3-core/src/skills/prompt.rs` [0..140] - `crates/g3-core/src/skills/prompt.rs` [0..140]
- `generate_skills_prompt()` [12..40] - generates `<available_skills>` XML block - `generate_skills_prompt()` [12..40] - generates `<available_skills>` XML
- `escape_xml()` [42..48] - escapes special XML characters - `crates/g3-config/src/lib.rs` [180..200] - `SkillsConfig` (enabled, extra_paths)
- `crates/g3-config/src/lib.rs` - `crates/g3-cli/src/project_files.rs` [180..210] - `discover_and_format_skills()`
- `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
**Skill Locations** (priority order): **Skill Locations** (priority: later overrides earlier):
1. `~/.g3/skills/` (global) 1. Embedded (compiled in)
2. Config extra_paths 2. `~/.g3/skills/` (global)
3. `.g3/skills/` (workspace, highest priority) 3. Config extra_paths
4. `.g3/skills/` (workspace)
5. `skills/` (repo root)
**SKILL.md Format**: **SKILL.md Format**:
```yaml ```yaml
@@ -372,12 +245,81 @@ Implements the Agent Skills specification (https://agentskills.io) for portable
name: skill-name # Required: 1-64 chars, lowercase + hyphens name: skill-name # Required: 1-64 chars, lowercase + hyphens
description: What it does # Required: 1-1024 chars description: What it does # Required: 1-1024 chars
license: Apache-2.0 # Optional license: Apache-2.0 # Optional
compatibility: Requires X # Optional: max 500 chars compatibility: Requires X # Optional
metadata: # Optional: arbitrary key-value
author: org
allowed-tools: Bash Read # Optional/experimental
--- ---
# Instructions...
# Skill Title
Detailed 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 <id>") # or --list
read_file(".g3/research/<id>/report.md")
```
**Output**: `.g3/research/<id>/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/<id>/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/<id>/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`

View File

@@ -263,7 +263,7 @@ mod tests {
// Verify the include_str! macro successfully loads the file // Verify the include_str! macro successfully loads the file
let prompt = EMBEDDED_NATIVE_PROMPT; let prompt = EMBEDDED_NATIVE_PROMPT;
assert!(!prompt.is_empty(), "Embedded prompt should not be empty"); 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] #[test]

View File

@@ -161,11 +161,6 @@ fn expand_tilde(path: &str) -> PathBuf {
PathBuf::from(expanded.as_ref()) 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("<embedded:")
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -247,7 +242,7 @@ mod tests {
let research = skills.iter().find(|s| s.name == "research").unwrap(); let research = skills.iter().find(|s| s.name == "research").unwrap();
assert_eq!(research.description, "Custom research skill"); assert_eq!(research.description, "Custom research skill");
assert!(!is_embedded_skill(research), "Should not be marked as embedded"); assert!(!research.path.starts_with("<embedded:"), "Should not be marked as embedded");
} }
#[test] #[test]
@@ -373,11 +368,4 @@ mod tests {
let no_tilde = expand_tilde("/absolute/path"); let no_tilde = expand_tilde("/absolute/path");
assert_eq!(no_tilde, PathBuf::from("/absolute/path")); assert_eq!(no_tilde, PathBuf::from("/absolute/path"));
} }
#[test]
fn test_is_embedded_skill() {
let skills = discover_skills(None, &[]);
let research = skills.iter().find(|s| s.name == "research").unwrap();
assert!(is_embedded_skill(research));
}
} }

View File

@@ -10,9 +10,7 @@
//! 4. Global `~/.g3/skills/` directory //! 4. Global `~/.g3/skills/` directory
//! 5. Embedded skills (this module - always available) //! 5. Embedded skills (this module - always available)
use std::collections::HashMap; /// An embedded skill with its SKILL.md content and optional scripts.
/// An embedded skill with its SKILL.md content.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct EmbeddedSkill { pub struct EmbeddedSkill {
/// Skill name (must match the name in SKILL.md frontmatter) /// Skill name (must match the name in SKILL.md frontmatter)
@@ -43,11 +41,6 @@ pub fn get_embedded_skill(name: &str) -> Option<&'static EmbeddedSkill> {
EMBEDDED_SKILLS.iter().find(|s| s.name == name) 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -72,10 +65,4 @@ mod tests {
assert!(get_embedded_skill("research").is_some()); assert!(get_embedded_skill("research").is_some());
assert!(get_embedded_skill("nonexistent").is_none()); assert!(get_embedded_skill("nonexistent").is_none());
} }
#[test]
fn test_skills_map() {
let map = get_embedded_skills_map();
assert!(map.contains_key("research"));
}
} }

View File

@@ -1,7 +1,7 @@
# g3 Architecture # g3 Architecture
**Last updated**: January 2025 **Last updated**: February 2025
**Source of truth**: Crate structure in `crates/`, `Cargo.toml`, `DESIGN.md` **Source of truth**: Crate structure in `crates/`, `Cargo.toml`, `DESIGN.md`, `skills/`
## Purpose ## Purpose
@@ -72,6 +72,7 @@ g3/
│ ├── g3-planner/ # Planning mode workflow │ ├── g3-planner/ # Planning mode workflow
│ └── studio/ # Multi-agent workspace manager │ └── studio/ # Multi-agent workspace manager
├── agents/ # Agent persona definitions ├── agents/ # Agent persona definitions
├── skills/ # Embedded skills (research, etc.)
├── logs/ # Session logs (auto-created) ├── logs/ # Session logs (auto-created)
└── g3-plan/ # Planning artifacts └── g3-plan/ # Planning artifacts
``` ```
@@ -94,6 +95,7 @@ Key modules:
- `retry.rs` - Retry logic with exponential backoff - `retry.rs` - Retry logic with exponential backoff
- `prompts.rs` - System prompt generation - `prompts.rs` - System prompt generation
- `code_search/` - Tree-sitter based code search - `code_search/` - Tree-sitter based code search
- `skills/` - Agent Skills discovery, parsing, and extraction
**Key types**: **Key types**:
- `Agent<W: UiWriter>` - Main agent struct, generic over UI output - `Agent<W: UiWriter>` - 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. 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 `<available_skills>` 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/<script>.version`
- Automatic re-extraction when embedded version changes
- Scripts are made executable (chmod 755 on Unix)
**Key types**:
- `Skill` - Parsed skill with name, description, metadata, body, path
- `EmbeddedSkill` - Compile-time skill with SKILL.md and scripts
See [Skills Guide](skills.md) for detailed usage and authoring instructions.
## Data Flow ## Data Flow
### Request Flow ### Request Flow

340
docs/skills.md Normal file
View File

@@ -0,0 +1,340 @@
# Agent Skills Guide
**Last updated**: February 2025
**Source of truth**: `crates/g3-core/src/skills/`, `skills/`
## Purpose
This document describes g3's Agent Skills system - a mechanism for extending agent capabilities through portable skill packages. Skills allow g3 to learn new abilities without code changes.
## Overview
g3 implements the [Agent Skills](https://agentskills.io) specification, an open format for portable skill packages. Each skill is a directory containing:
- `SKILL.md` - Skill definition with YAML frontmatter and instructions
- `scripts/` (optional) - Executable scripts the skill can use
- `references/` (optional) - Additional documentation
- `assets/` (optional) - Templates, data files, etc.
At startup, g3 discovers skills from multiple locations and injects a summary into the system prompt. When the agent needs a skill, it reads the full `SKILL.md` using the `read_file` tool.
## Quick Start
### Using Existing Skills
Skills are automatically discovered. To see available skills, check the system prompt or look in:
```bash
# Global skills (shared across all projects)
ls ~/.g3/skills/
# Workspace skills (project-specific)
ls .g3/skills/
# Repo skills (checked into git)
ls skills/
```
### Creating a New Skill
1. Create a skill directory:
```bash
mkdir -p skills/my-skill
```
2. Create `SKILL.md` with frontmatter:
```markdown
---
name: my-skill
description: Brief description of what this skill does and when to use it.
license: MIT
compatibility: Any requirements (e.g., "Requires Python 3.8+")
---
# My Skill
Detailed instructions for the agent...
```
3. The skill is now available to g3.
## SKILL.md Format
### Frontmatter (Required)
The YAML frontmatter between `---` markers defines skill metadata:
```yaml
---
name: skill-name # Required: 1-64 chars, lowercase + hyphens only
description: What it does # Required: 1-1024 chars, when to use this skill
license: Apache-2.0 # Optional: SPDX license identifier
compatibility: Requires X # Optional: Environment requirements (max 500 chars)
metadata: # Optional: Arbitrary key-value pairs
author: your-org
version: "1.0"
---
```
**Name validation rules**:
- 1-64 characters
- Lowercase letters, numbers, and hyphens only
- Must start with a letter
- No consecutive hyphens
### Body (Instructions)
After the frontmatter, write detailed instructions for the agent:
```markdown
# Skill Title
## Quick Start
How to use this skill in the simplest case.
## Detailed Usage
Step-by-step instructions, examples, edge cases.
## Troubleshooting
Common issues and solutions.
```
**Best practices**:
- Keep the description concise (it's shown in the skill summary)
- Put detailed instructions in the body (only loaded when needed)
- Include concrete examples
- Document error handling
## Discovery Priority
Skills are discovered from multiple locations. Higher priority sources override lower ones:
| Priority | Location | Use Case |
|----------|----------|----------|
| 1 (lowest) | Embedded | Core skills compiled into binary |
| 2 | `~/.g3/skills/` | Global user skills |
| 3 | Config `extra_paths` | Organization-wide skills |
| 4 | `.g3/skills/` | Workspace-local customizations |
| 5 (highest) | `skills/` | Repo skills (checked into git) |
**Override behavior**: If the same skill name exists in multiple locations, the highest priority version wins. This allows:
- Customizing embedded skills per-project
- Testing skill changes without modifying global installs
- Sharing skills across an organization via config paths
## Configuration
Skills can be configured in `~/.config/g3/config.toml` or `./g3.toml`:
```toml
[skills]
enabled = true # Default: true
extra_paths = [ # Additional skill directories
"/org/shared/skills",
"~/my-skills"
]
```
To disable skills entirely:
```toml
[skills]
enabled = false
```
## Embedded Skills
Core skills are embedded into the g3 binary at compile time, ensuring they work anywhere without external files.
### Currently Embedded Skills
| Skill | Description |
|-------|-------------|
| `research` | Web-based research via scout agent with browser automation |
### How Embedding Works
Embedded skills use Rust's `include_str!` macro to compile SKILL.md and scripts into the binary:
```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:
1. **First run**: Script is written to `.g3/bin/<script-name>`
2. **Permissions**: Made executable (chmod 755 on Unix)
3. **Version tracking**: Content hash stored in `.g3/bin/<script-name>.version`
4. **Updates**: Re-extracted automatically when embedded version changes
This ensures:
- Scripts are always available, even in fresh workspaces
- Updates propagate automatically when g3 is upgraded
- No manual installation required
## The Research Skill
The embedded `research` skill enables asynchronous web research:
### Usage
```bash
# Start research (always use background_process)
background_process("research-topic", ".g3/bin/g3-research 'Your query here'")
# Check status
shell(".g3/bin/g3-research --list")
# Read results when complete
read_file(".g3/research/<research-id>/report.md")
```
### How It Works
1. **Start**: `g3-research` spawns a scout agent in the background
2. **Execute**: Scout uses browser automation to research the topic
3. **Save**: Results written to `.g3/research/<id>/report.md`
4. **Read**: Agent reads the report when needed
### Directory Structure
```
.g3/research/
├── research_1738700000_a1b2c3/
│ ├── status.json # Machine-readable status
│ └── report.md # The research brief
└── research_1738700100_d4e5f6/
├── status.json
└── report.md
```
### Status Values
- `running` - Research in progress
- `complete` - Report ready to read
- `failed` - Error occurred (check `error` field in status.json)
## Creating Skills with Scripts
Skills can include executable scripts for complex operations:
### Script Location
Place scripts in the skill directory:
```
skills/my-skill/
├── SKILL.md
├── my-script.sh # Bash script
├── helper.py # Python script
└── scripts/
└── complex-tool # Subdirectory also works
```
### Referencing Scripts
In SKILL.md, reference scripts relative to the skill directory:
```markdown
## Usage
Run the helper script:
```bash
shell("skills/my-skill/my-script.sh arg1 arg2")
```
```
### Embedding Scripts
To embed scripts in the binary (for core skills), add them to `embedded.rs`:
```rust
EmbeddedSkill {
name: "my-skill",
skill_md: include_str!("../../../../skills/my-skill/SKILL.md"),
scripts: &[
("my-script", include_str!("../../../../skills/my-skill/my-script.sh")),
],
},
```
## Context Budget
Each skill adds approximately 50-100 tokens to the system prompt (name + description + path). The full SKILL.md body is only loaded when the agent reads it.
**Recommendations**:
- Keep descriptions under 200 characters
- Put detailed instructions in the body, not the description
- Avoid creating many small skills; consolidate related functionality
## Troubleshooting
### Skill Not Discovered
1. Check the skill directory exists and contains `SKILL.md`
2. Verify the frontmatter is valid YAML
3. Ensure `name` and `description` fields are present
4. Check for syntax errors in the YAML (use a YAML validator)
### Skill Overridden Unexpectedly
Skills with the same name are overridden by higher-priority sources. Check:
- `skills/` (repo) overrides everything
- `.g3/skills/` (workspace) overrides global and embedded
- `~/.g3/skills/` (global) overrides embedded only
### Embedded Script Not Found
If `.g3/bin/<script>` doesn't exist:
1. The skill may not have been used yet (extraction is lazy)
2. Check permissions on `.g3/bin/` directory
3. Try deleting `.g3/bin/<script>.version` to force re-extraction
### Research Skill Issues
- **Takes too long**: Try a more specific query
- **WebDriver errors**: Ensure Safari or Chrome WebDriver is configured
- **Empty report**: Check `status.json` for error details
## Adding a New Embedded Skill
To add a new skill to the g3 binary:
1. Create the skill in `skills/<name>/`:
```
skills/new-skill/
├── SKILL.md
└── optional-script.sh
```
2. Add to `crates/g3-core/src/skills/embedded.rs`:
```rust
EmbeddedSkill {
name: "new-skill",
skill_md: include_str!("../../../../skills/new-skill/SKILL.md"),
scripts: &[
("optional-script", include_str!("../../../../skills/new-skill/optional-script.sh")),
],
},
```
3. Rebuild g3:
```bash
cargo build --release
```
## See Also
- [Agent Skills Specification](https://agentskills.io) - The open standard
- [Architecture: Skills System](architecture.md#skills-system-extensible-capabilities) - Internal implementation
- [README: Agent Skills](../README.md#agent-skills) - Quick overview