Make research skill self-contained without external scripts

- Rewrite SKILL.md with inline instructions to spawn g3 --agent scout directly
- Extend read_file to handle embedded skill paths (<embedded:name>/SKILL.md)
- Remove scripts field from EmbeddedSkill struct (no longer needed)
- Delete extraction.rs module (was only for script extraction)
- Delete g3-research bash script
- Remove obsolete Async Research Tool section from workspace memory

Skills are now fully portable - they work when g3 is installed as a
binary without access to source files. Agents can read embedded skill
content via read_file with the special <embedded:...> path syntax.
This commit is contained in:
Dhanji R. Prasanna
2026-02-05 14:22:17 +11:00
parent 788debb93a
commit cff32bf0ba
7 changed files with 130 additions and 710 deletions

View File

@@ -5,115 +5,114 @@ license: Apache-2.0
compatibility: Requires g3 binary in PATH. WebDriver (Safari or Chrome) recommended for best results.
metadata:
author: g3
version: "1.0"
version: "2.0"
---
# Research Skill
Perform asynchronous web research without blocking your current work. Research runs in the background and saves results to disk for you to read when ready.
Perform asynchronous web research without blocking your current work. Research runs in the background and results are saved to disk.
## Quick Start
```bash
# Start research (ALWAYS use background_process, never blocking shell)
background_process("research-<topic>", ".g3/bin/g3-research 'Your research question here'")
# 1. Create research directory and status file
RESEARCH_ID="research_$(date +%s)_$(head -c 3 /dev/urandom | xxd -p)"
mkdir -p ".g3/research/$RESEARCH_ID"
echo '{"id":"'$RESEARCH_ID'","status":"running","query":"YOUR QUERY"}' > ".g3/research/$RESEARCH_ID/status.json"
# Check status
shell(".g3/bin/g3-research --status <research-id>")
# Or list all:
shell(".g3/bin/g3-research --list")
# 2. Start research in background
background_process("research-topic", "g3 --agent scout --new-session --quiet 'Your research question' > .g3/research/$RESEARCH_ID/report.md 2>&1 && sed -i '' 's/running/complete/' .g3/research/$RESEARCH_ID/status.json || sed -i '' 's/running/failed/' .g3/research/$RESEARCH_ID/status.json")
# Read the report when complete
read_file(".g3/research/<research-id>/report.md")
# 3. Check status
cat .g3/research/$RESEARCH_ID/status.json
# 4. Read report when complete
read_file(".g3/research/$RESEARCH_ID/report.md")
```
## How It Works
## Step-by-Step Instructions
1. **Start research** - The `g3-research` script spawns a scout agent that performs web research
2. **Background execution** - Research runs asynchronously; you can continue other work
3. **Filesystem handoff** - Results are written to `.g3/research/<id>/` with machine-readable status
4. **Read when ready** - Use `read_file` to load the report into context only when needed
### 1. Generate a Unique Research ID
Use shell to create a unique ID and directory:
```bash
shell("RESEARCH_ID=\"research_$(date +%s)_$(head -c 3 /dev/urandom | xxd -p)\" && mkdir -p \".g3/research/$RESEARCH_ID\" && echo $RESEARCH_ID")
```
Save the returned ID for later use.
### 2. Write Initial Status File
```bash
shell("echo '{\"id\":\"<RESEARCH_ID>\",\"status\":\"running\",\"query\":\"<YOUR_QUERY>\",\"started_at\":\"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'\"}' > .g3/research/<RESEARCH_ID>/status.json")
```
### 3. Start the Scout Agent
Use `background_process` to run the scout agent (NEVER use blocking `shell`):
```bash
background_process("research-<topic>", "g3 --agent scout --new-session --quiet '<Your detailed research question>' > .g3/research/<RESEARCH_ID>/report.md 2>&1; if [ $? -eq 0 ]; then sed -i '' 's/running/complete/' .g3/research/<RESEARCH_ID>/status.json; else sed -i '' 's/running/failed/' .g3/research/<RESEARCH_ID>/status.json; fi")
```
**Important flags:**
- `--agent scout` - Uses the scout agent optimized for web research
- `--new-session` - Starts a fresh session
- `--quiet` - Reduces UI noise in output
### 4. Check Research Status
```bash
shell("cat .g3/research/<RESEARCH_ID>/status.json")
```
Status values:
- `running` - Research in progress
- `complete` - Report ready to read
- `failed` - Error occurred
### 5. Read the Report
Once status is `complete`:
```bash
read_file(".g3/research/<RESEARCH_ID>/report.md")
```
## Directory Structure
```
.g3/research/
── research_1738700000_a1b2c3/
├── status.json # Machine-readable status
└── report.md # The research brief (when complete)
└── research_1738700100_d4e5f6/
├── status.json
└── report.md
── research_1738700000_a1b2c3/
├── status.json # Machine-readable status
└── report.md # The research brief (when complete)
```
## status.json Schema
```json
{
"id": "research_1738700000_a1b2c3",
"query": "What are the best Rust async runtimes?",
"status": "complete",
"started_at": "2026-02-04T12:00:00Z",
"completed_at": "2026-02-04T12:01:30Z",
"report_path": ".g3/research/research_1738700000_a1b2c3/report.md",
"error": null
}
```
**Status values:**
- `running` - Research in progress
- `complete` - Report ready to read
- `failed` - Error occurred (check `error` field)
## Commands
### Start Research
## Example: Complete Workflow
```bash
.g3/bin/g3-research "<query>"
```
# Step 1: Create research task
shell("RESEARCH_ID=\"research_$(date +%s)_$(head -c 3 /dev/urandom | xxd -p)\" && mkdir -p \".g3/research/$RESEARCH_ID\" && echo '{\"id\":\"'$RESEARCH_ID'\",\"status\":\"running\",\"query\":\"Rust async runtimes comparison\"}' > \".g3/research/$RESEARCH_ID/status.json\" && echo $RESEARCH_ID")
# Returns: research_1738700000_a1b2c3
Outputs the research ID and path on success. **Always run via `background_process`**, not `shell`.
# Step 2: Start scout in background
background_process("research-rust-async", "g3 --agent scout --new-session --quiet 'Compare Tokio vs async-std vs smol for Rust async runtimes. Include performance, ecosystem, and ease of use.' > .g3/research/research_1738700000_a1b2c3/report.md 2>&1; [ $? -eq 0 ] && sed -i '' 's/running/complete/' .g3/research/research_1738700000_a1b2c3/status.json || sed -i '' 's/running/failed/' .g3/research/research_1738700000_a1b2c3/status.json")
### Check Status
```bash
# Check specific research
.g3/bin/g3-research --status <research-id>
# List all research tasks
.g3/bin/g3-research --list
```
Outputs JSON for machine parsing.
### Read Report
Once status is `complete`, read the report:
```bash
read_file(".g3/research/<research-id>/report.md")
```
**Tip:** If the report is large, use partial reads:
```bash
read_file(".g3/research/<id>/report.md", start=0, end=2000)
```
## Example Workflow
```
# 1. Start research on async runtimes
background_process("research-async", ".g3/bin/g3-research 'Compare Tokio vs async-std vs smol for Rust async runtimes'")
# 2. Continue with other work while research runs...
# Step 3: Continue other work...
shell("cargo check")
# 3. Check if research is done
shell(".g3/bin/g3-research --list")
# Step 4: Check if done
shell("cat .g3/research/research_1738700000_a1b2c3/status.json")
# 4. Read the report
read_file(".g3/research/research_1738700000_abc123/report.md")
# Step 5: Read report
read_file(".g3/research/research_1738700000_a1b2c3/report.md")
```
## Listing All Research Tasks
```bash
shell("for f in .g3/research/*/status.json; do cat \"$f\" 2>/dev/null; echo; done")
```
## Best Practices
@@ -121,7 +120,7 @@ read_file(".g3/research/research_1738700000_abc123/report.md")
1. **Always use `background_process`** - Never run research with blocking `shell`
2. **Be specific** - Narrow queries get better results faster
3. **Read selectively** - Only load reports into context when you need them
4. **Check status first** - Don't try to read reports that aren't complete
4. **Check status first** - Don't try to read reports that aren't complete yet
## Troubleshooting
@@ -129,16 +128,11 @@ read_file(".g3/research/research_1738700000_abc123/report.md")
- Try a more specific query
- Complex topics may take 1-2 minutes
### WebDriver not available
### WebDriver not available
- Research will still work but may have limited web access
- Install Safari WebDriver or Chrome for best results
- The scout agent will fall back to shell-based methods
### Report is empty or failed
- Check `status.json` for error details
- Check status.json for the status
- Look at the report.md file for any error output
- The query may be too broad or the topic too obscure
## Notes
- Research results accumulate in `.g3/research/` - they are not auto-cleaned
- Each research task gets a unique ID based on timestamp
- Multiple concurrent research tasks are supported