Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:57:54 +08:00
commit 8f952ee727
50 changed files with 11199 additions and 0 deletions

914
commands/install.md Normal file
View File

@@ -0,0 +1,914 @@
---
name: smith:install
description: Interactive Agent Smith setup wizard with intelligent suggestions based on your financial setup
argument-hints:
- "[--reset]"
---
# Agent Smith - Intelligent Financial Assistant
You are guiding a user through Agent Smith. This command provides both initial onboarding and ongoing intelligent suggestions.
## Your Role
- Be encouraging and supportive
- Explain each step clearly
- Show progress throughout the journey
- Celebrate wins (data discovered, rules created, transactions categorized)
- Provide concrete, actionable next steps
## Execution Logic
**FIRST: Immediately notify the user that the workflow is loading:**
Display this message before doing anything else:
```
Loading Agent Smith installation workflow...
This may take a moment as I analyze your setup. Please wait...
```
**Check for --reset argument:**
If the user provides `--reset` argument:
1. **Confirm with the user** before proceeding (this will delete all data!)
2. Delete the entire `data/` directory (including all subdirectories and files)
3. Display message: "Reset complete. All onboarding state and data cleared. Running fresh installation..."
4. Proceed to **Stages 1-8 (Onboarding)** then **Stage 9 (Suggestions)**
**Check for onboarding completion:**
1. Check if `data/onboarding_state.json` exists and has `"onboarding_completed": true`
2. If YES → Skip to **Stage 9: Intelligent Suggestions** only
3. If NO → Run **Stages 1-8 (Onboarding)** then **Stage 9 (Suggestions)**
**When onboarding is complete:**
- Set `"onboarding_completed": true` in `data/onboarding_state.json`
- Always run Stage 9 (Suggestions) every time this command is invoked
---
## Onboarding Workflow (Stages 1-8)
### Stage 1: Welcome & Prerequisites Check
Greet the user and verify they have:
1. Agent Smith plugin installed (verify via plugin system)
2. API key configured in .env (in current directory)
3. PocketSmith account accessible
**IMPORTANT:** When Agent Smith is installed as a plugin, the codebase is in the plugin directory, NOT the user's working directory. The user only needs:
- A `.env` file with `POCKETSMITH_API_KEY` in their working directory
- Agent Smith plugin installed
**Plugin Detection:**
Check if this command is running from the plugin by looking for the plugin installation path. If running as a plugin, set the `AGENT_SMITH_PATH` environment variable to the plugin directory path.
If the user doesn't have a `.env` file, guide them to create one:
```bash
echo "POCKETSMITH_API_KEY=your_key_here" > .env
```
Get API key from: https://app.pocketsmith.com/keys/new
### Stage 2: Discovery
Run the discovery script to analyze their PocketSmith account.
**Before first script execution,** define the `run_agent_smith` helper function (see "Plugin-Aware Script Execution" section below).
**Run discovery:**
```bash
run_agent_smith "onboarding/discovery.py"
```
**Note:** The `.env` file should be in the user's current working directory. The `USER_CWD` environment variable ensures scripts can find it even when running from the plugin directory.
**What to look for:**
- Account count and types
- Category structure
- Transaction volume and date range
- Uncategorized transaction count
- Baseline health score (if available)
**Present findings:**
- Summarize their PocketSmith setup
- Highlight the uncategorized transaction count
- Show the recommended template
- Display account classifications (household_shared, parenting_shared, individual)
- Show any name suggestions detected
### Stage 2a: Category Structure Assessment
**IMPORTANT:** This stage determines whether to apply the Foundation template based on the user's existing category count.
**Check existing category count** from discovery report:
```python
existing_category_count = len(discovery_report.categories)
```
**Decision logic:**
- **0-5 categories**: Auto-apply Foundation (user has minimal setup)
- **6-19 categories**: Offer Foundation with recommendation to apply (partial setup)
- **20+ categories**: Offer Foundation with recommendation to skip (established setup)
**For users with 20+ categories, present this choice:**
```
I detected {existing_category_count} existing categories in your PocketSmith account.
Agent Smith's Foundation template provides 45 ATO-aligned categories for
everyday expenses (Food, Housing, Transport, Healthcare, Personal, etc.).
The Foundation will be applied automatically to provide structure and
tax compliance. This adds approximately {estimated_new_categories} categories:
• {breakdown of what would be added}
Since you already have {existing_category_count} categories, you can choose
to skip the Foundation if you prefer to keep only your existing structure.
Apply Agent Smith Foundation? (Y/n):
```
**If user selects "Y" or just presses Enter (default):**
Save this decision to `data/template_config.json`:
```json
{
"apply_foundation": true
}
```
The Foundation template will be merged in Stage 4 with priority 0 (applied first).
**If user selects "n":**
Save this decision:
```json
{
"apply_foundation": false
}
```
Foundation will be skipped (--foundation=none in Stage 4).
**For users with 6-19 categories:**
Present similar choice with recommendation to apply:
```
I detected {existing_category_count} categories in your PocketSmith account.
Agent Smith's Foundation template adds ATO-aligned structure and better
tax tracking with 45 categories for everyday expenses.
This would add approximately {estimated_new_categories} categories.
Apply Agent Smith Foundation? (Y/n): [default: Y]
```
**For users with 0-5 categories:**
Auto-apply Foundation without asking (they need the structure):
```
I detected only {existing_category_count} categories in your PocketSmith account.
Applying Agent Smith's Foundation template (45 ATO-aligned categories)...
```
Save to config:
```json
{
"apply_foundation": true
}
```
### Stage 2b: Account Selection (Interactive)
**IMPORTANT:** This stage enables context-aware name detection by identifying which accounts are used for household vs parenting expenses.
**Check if shared accounts were detected:**
Look at the discovery report's `account_classifications` field. If there are accounts classified as `household_shared` or `parenting_shared`, proceed with interactive selection.
**For Household Shared Accounts:**
If `household_shared` accounts were detected:
1. **Show detected accounts** with confidence scores:
```
I detected these potential household shared accounts:
1. Shared Bills - Simon & Caitlin (Macquarie Bank)
Confidence: 90%
Indicators: "shared" in account name
2. Joint Savings (CBA)
Confidence: 60%
Indicators: "joint" in account name
Which account do you use for household shared expenses?
```
2. **Use AskUserQuestion** to let the user select:
```python
# Build options from household_shared accounts
household_accounts = [acc for acc in report.account_classifications
if acc.account_type == "household_shared"]
if household_accounts:
# Sort by confidence
household_accounts.sort(key=lambda x: x.confidence, reverse=True)
options = []
for acc in household_accounts:
options.append({
"label": f"{acc.account_name} ({acc.institution})",
"description": f"Confidence: {acc.confidence*100:.0f}% - Indicators: {', '.join(acc.indicators)}"
})
# Ask user to select
response = AskUserQuestion(
questions=[{
"question": "Which account do you use for household shared expenses?",
"header": "Household Acct",
"options": options,
"multiSelect": false
}]
)
# User selected index or "Other"
# If "Other", show full account list and let them choose
```
3. **Extract names** from selected account:
```python
# Get the selected account
selected_account = household_accounts[selected_index]
# Extract names using the account-specific data
suggestion = _extract_names_from_account(
selected_account,
transactions,
categories
)
# Show detected names
if suggestion and suggestion.person_1:
if suggestion.person_2:
print(f"✓ Detected contributors: {suggestion.person_1} and {suggestion.person_2}")
else:
print(f"✓ Detected contributor: {suggestion.person_1}")
print(f" Source: {suggestion.source} (confidence: {suggestion.confidence*100:.0f}%)")
# Ask for confirmation
response = AskUserQuestion(
questions=[{
"question": f"Use '{suggestion.person_1} and {suggestion.person_2}' for household shared expenses?",
"header": "Confirm Names",
"options": [
{"label": "Yes", "description": "Use these names"},
{"label": "No", "description": "I'll enter different names"}
],
"multiSelect": false
}]
)
# If "No", ask for manual entry using AskUserQuestion with text input
```
4. **Save to template_config.json:**
```python
config = {
"household_shared_account": {
"account_id": selected_account.account_id,
"account_name": selected_account.account_name,
"person_1": confirmed_person_1,
"person_2": confirmed_person_2
}
}
```
**For Parenting Shared Accounts:**
If `parenting_shared` accounts were detected, repeat the same flow:
1. Show detected parenting accounts with confidence scores
2. Use AskUserQuestion to let user select
3. Extract names from selected account
4. Ask for confirmation
5. Save to template_config.json under `parenting_shared_account`
**Example output:**
```
=== Household Shared Account Selection ===
I detected these potential household shared accounts:
1. Shared Bills - Simon & Caitlin (Macquarie Bank)
Confidence: 90%
Why: "shared" in account name
Which account do you use for household shared expenses? (1): 1
Analyzing 'Shared Bills - Simon & Caitlin' for contributor names...
✓ Detected contributors: Simon and Caitlin
Source: account_name (confidence: 90%)
Use 'Simon and Caitlin' for household shared expenses? (y/n): y
=== Parenting Shared Account Selection ===
I detected these potential parenting shared accounts:
1. Kids Account - Simon & Tori (CBA)
Confidence: 90%
Why: "kids" in account name
Which account do you use for parenting/child expenses? (1): 1
Analyzing 'Kids Account - Simon & Tori' for contributor names...
✓ Detected contributors: Simon and Tori
Source: account_name (confidence: 90%)
Use 'Simon and Tori' for parenting shared expenses? (y/n): y
✓ Account selections saved to template_config.json
```
**If no shared accounts detected:**
Skip this stage and continue to template selection.
### Stage 3: Template Selection
Agent Smith uses a **composable template system** with up to three layers. Users select:
1. **Primary Income** (ONE choice, REQUIRED) - How you earn most of your income
2. **Living Arrangement** (ONE OR MORE choices, OPTIONAL) - Special tracking for shared finances or child support
3. **Additional Income** (MULTIPLE choices, OPTIONAL) - Extra income sources beyond your primary
**Step 3a: Select Primary Income Template**
Present discovery recommendation, then let user select ONE:
```bash
echo "Select your PRIMARY income structure (choose ONE):"
run_agent_smith "setup/template_selector.py" --layer=primary --interactive
```
**Available primary templates:**
- `payg-employee` - Salary/wage earner, PAYG tax withheld
- `sole-trader` - ABN holder, contractor, quarterly BAS
**Step 3b: Select Living Arrangement Template(s) (OPTIONAL)**
**IMPORTANT:** Living templates are for special tracking needs only:
- Shared household finances with expense splitting
- Child support and custody expense tracking
**If none of these apply, SKIP this step.**
Present discovery recommendation, then let user select ONE OR MORE (or skip):
```bash
echo "Select your LIVING arrangement (select all that apply, or skip if none apply):"
run_agent_smith "setup/template_selector.py" --layer=living --multiple --interactive --optional
```
**Available living templates:**
- `shared-hybrid` - Shared household with mixed accounts (partners/couples)
- Adds labels: "Shared Expense", "Contributor: {name}", "Personal: {name}"
- Enables expense splitting and contribution tracking
- `separated-parents` - Child support and custody expense tracking
- Adds labels: "Child Support", "Kids Expense", "Custody Period"
- Tracks child-related spending for tax and legal documentation
**Note:**
- You can select MULTIPLE living arrangements if needed (e.g., separated-parents + shared-hybrid if you're divorced with kids AND now living with a new partner)
- If you're managing finances independently without shared expenses or child support, **skip this step entirely**
**Step 3c: Select Additional Income Templates**
Present discovery recommendations, then let user select MULTIPLE:
```bash
echo "Select ADDITIONAL income sources (select all that apply):"
run_agent_smith "setup/template_selector.py" --layer=additional --multiple --interactive
```
**Available additional templates:**
- `property-investor` - Rental income, negative gearing, CGT tracking
- `share-investor` - Dividends, franking credits, share CGT
**Step 3d: Configure Template Labels (if applicable)**
For templates with configurable labels, prompt for customization:
**If Shared Hybrid selected:**
```bash
echo "Who are the two contributors in your household?"
read -p "Contributor 1 name (e.g., Alex): " CONTRIBUTOR_1
read -p "Contributor 2 name (e.g., Jordan): " CONTRIBUTOR_2
```
**If Separated Parents selected:**
```bash
echo "Who are the two parents for custody tracking?"
read -p "Parent 1 name (e.g., Sarah): " PARENT_1
read -p "Parent 2 name (e.g., David): " PARENT_2
```
**If Property Investor selected:**
```bash
read -p "Property address (optional, for multi-property tracking): " PROPERTY_ADDRESS
```
Save configurations to `data/template_config.json` for use during merge.
### Stage 4: Template Merging & Application Strategy
**Step 4a: Merge Selected Templates**
Combine the selected templates using priority-based merging.
**Check if Foundation should be applied:**
Read `data/template_config.json` and check for `"apply_foundation": true|false`.
**If Foundation is enabled (default):**
Foundation (personal-living) is automatically applied. Simply merge with primary and optional layers:
```bash
echo "Merging templates (Foundation + Primary + optional layers)..."
run_agent_smith "setup/template_merger.py" \
--primary="$PRIMARY_TEMPLATE" \
--living="$LIVING_TEMPLATE" \
--additional="$ADDITIONAL_TEMPLATES" \
--config=data/template_config.json \
--output=data/merged_template.json
```
**If Foundation is disabled:**
Use `--foundation=none` to skip the Foundation layer:
```bash
echo "Merging templates (Primary only, skipping Foundation)..."
run_agent_smith "setup/template_merger.py" \
--foundation=none \
--primary="$PRIMARY_TEMPLATE" \
--living="$LIVING_TEMPLATE" \
--additional="$ADDITIONAL_TEMPLATES" \
--config=data/template_config.json \
--output=data/merged_template.json
```
**Note:** The `--living` and `--additional` parameters are optional. Omit them if no templates were selected for those layers.
**Example - Most common case (Foundation + Primary only):**
```bash
run_agent_smith "setup/template_merger.py" \
--primary=payg-employee \
--output=data/merged_template.json
```
Foundation (personal-living) is automatically included.
**Template merge order:**
1. Foundation (priority 0) - 45 ATO-aligned base categories (automatic unless --foundation=none)
2. Primary Income (priority 1) - Income-specific categories (REQUIRED)
3. Living Arrangement (priority 2) - Tracking labels for shared finances/child support (OPTIONAL)
4. Additional Income (priority 3) - Investment categories (OPTIONAL)
Later priorities can override/extend earlier ones.
**Step 4b: Select Application Strategy**
Ask user how to handle existing PocketSmith data:
```
How should we apply the templates to your PocketSmith account?
1. Add New Only (RECOMMENDED)
- Keep all your existing categories and rules
- Add only NEW categories and rules from templates
- Safest option, nothing gets overwritten
2. Smart Merge
- Intelligently match template categories to existing ones
- Add new categories where no match found
- Deduplicate rules based on payee patterns
- Good for accounts with some setup already
3. Archive & Replace
- Create backup of existing setup
- Apply templates fresh (existing categories remain but unused)
- Use this if starting over completely
- Note: PocketSmith API doesn't delete categories, so old ones remain
Choose strategy (1/2/3):
```
**Map user choice to strategy argument:**
- Choice 1 → `add_new`
- Choice 2 → `smart_merge` (note: underscore, not hyphen)
- Choice 3 → `replace`
Save user choice to `data/onboarding_state.json`.
**Step 4c: Preview Before Apply**
Show what will be created/changed:
```bash
echo "Previewing changes (dry run)..."
run_agent_smith "setup/template_applier.py" \
--template=data/merged_template.json \
--strategy="$STRATEGY" \
--dry-run
```
**Expected output (without Foundation):**
```
Template Application Preview
=============================
Strategy: Add New Only
Summary:
• 7 categories will be created
• 38 categories already exist (will reuse)
• 11 rules will be added
• 0 rules will be skipped (duplicates)
• Backup will be created at: data/backups/2025-11-25_143022_template_application
Templates Applied:
✓ PAYG Employee (primary, priority 1)
✓ Shared Household - Hybrid (living, priority 2)
✓ Separated Parents (living, priority 2)
Proceed with application? (y/n):
```
**Expected output (with Foundation enabled):**
```
Template Application Preview
=============================
Strategy: Smart Merge
Summary:
• 12 categories will be created
• 33 categories matched/reused (fuzzy matching)
• 11 rules will be added
• 0 rules will be skipped (duplicates)
• Backup will be created at: data/backups/2025-11-25_143022_template_application
Templates Applied:
✓ Foundation: Personal Living (foundation, priority 0)
✓ PAYG Employee (primary, priority 1)
✓ Shared Household - Hybrid (living, priority 2)
✓ Separated Parents (living, priority 2)
Proceed with application? (y/n):
```
**Step 4d: Apply Templates**
If user confirms, apply the merged template:
```bash
echo "Applying templates to PocketSmith..."
run_agent_smith "setup/template_applier.py" \
--template=data/merged_template.json \
--strategy="$STRATEGY" \
--apply
```
**Show results:**
```
Template Application Complete!
==============================
✓ Created 23 new categories
✓ Reused 12 existing categories
✓ Created 47 new rules
✓ Backup saved: data/backups/2025-11-22_143022_template_application
Your PocketSmith account is now configured with:
• PAYG Employee income tracking
• Shared household expense splitting
• Property investment tracking
Next: Run categorization to apply these rules to your transactions.
```
### Stage 5: Intelligence Mode Selection
Ask user to choose their preferred intelligence mode:
**Categorization mode:**
- Conservative: Approve every AI suggestion
- Smart (recommended): Auto-apply high confidence (≥90%)
- Aggressive: Auto-apply medium+ confidence (≥80%)
**Tax intelligence level:**
- Reference: Basic ATO category mapping
- Smart: Deduction detection, thresholds
- Full: BAS prep, compliance checks
Save to `data/config.json`.
### Stage 6: Incremental Categorization
Recommend starting with recent transactions:
**Suggested batch strategy:**
1. Start with current month (test rules on small dataset)
2. Expand to last 3 months (validate at scale)
3. Backfill historical data (complete the archive)
**Run categorization:**
```bash
# Dry run first
run_agent_smith "operations/categorize_batch.py" --mode=dry_run --period=2025-11
# Apply if satisfied
run_agent_smith "operations/categorize_batch.py" --mode=apply --period=2025-11
```
**After each batch:**
- Show results (matched, auto-applied, needs review, failed)
- Review medium-confidence suggestions
- Learn new rules from user corrections
- Track progress
### Stage 7: Post-Onboarding Health Check
After categorization, run health check to show improvement:
```bash
/smith:health --full
```
**Show before/after:**
- Baseline health score (from Stage 2)
- Current health score (after categorization)
- Improvement in each dimension
- Remaining priorities
### Stage 8: Next Steps & Usage Guide
Provide the user with ongoing usage patterns:
**Daily/Weekly:**
- Categorize new transactions: `/smith:categorize --mode=smart`
**Monthly:**
- Spending analysis: `/smith:analyze spending --period=YYYY-MM`
- Quick health check: `/smith:health --quick`
**Quarterly:**
- Tax deduction review: `/smith:tax deductions --period=YYYY-YY`
**Annual (EOFY):**
- Tax preparation: `/smith:tax eofy`
**Mark onboarding as complete:**
Update `data/onboarding_state.json` with `"onboarding_completed": true`
---
## Stage 9: Intelligent Suggestions
**This stage ALWAYS runs** - whether onboarding just completed or user is returning.
Analyze the user's financial setup and provide intelligent, actionable suggestions based on:
### Analysis Areas
1. **Configuration Analysis**
- Read `data/onboarding_state.json` - What templates are active?
- Read `data/config.json` - What intelligence modes are configured?
- Read `data/template_config.json` - What labels/customizations exist?
2. **Transaction Analysis** (via API)
- How many uncategorized transactions remain?
- What's the date range of uncategorized transactions?
- Are there patterns in recent transactions that suggest new rules needed?
- Transaction volume trends (increasing/decreasing/seasonal)?
3. **Category & Rule Health**
- How many categories are defined vs. actually used?
- How many rules exist? Are they effective (categorizing transactions)?
- Are there dormant categories (no transactions in 6+ months)?
- Are there heavily-used categories that might benefit from subcategories?
4. **Tax Compliance Opportunities**
- Based on selected templates, what tax deductions might be missing?
- Are there categories that should be flagged for tax deductions but aren't?
- For EOFY proximity (May-June), suggest tax prep tasks
- For BAS proximity (quarterly), suggest BAS prep tasks
5. **Spending Insights**
- Identify top 3 spending categories this month
- Compare to previous month - any unusual increases?
- Identify opportunities for budget alerts or scenario planning
6. **Optimization Opportunities**
- Suggest merchant name normalization for frequently-used payees
- Recommend rule refinements based on manual categorizations
- Identify categories that could be consolidated
### Suggestion Output Format
Present suggestions in this structure:
```
═══════════════════════════════════════════════════════════
AGENT SMITH SUGGESTIONS
[Current Date]
═══════════════════════════════════════════════════════════
Your Setup:
• Templates: [list active templates]
• Intelligence Mode: [Conservative/Smart/Aggressive]
• Tax Level: [Reference/Smart/Full]
Current Status:
• [X] uncategorized transactions ([date range])
• [Y] categories defined ([Z] actively used)
• [N] categorization rules
• Last analysis: [date or "Never"]
───────────────────────────────────────────────────────────
🎯 PRIORITY ACTIONS
───────────────────────────────────────────────────────────
[1-3 highest-priority suggestions based on analysis]
Example:
1. Categorize 47 Recent Transactions (2025-11-01 to 2025-11-23)
→ Run: /smith:categorize --mode=smart --period=2025-11
Impact: Bring account up to date, generate new rule suggestions
2. Review Tax Deductions for Q2 (October-December 2025)
→ Run: /smith:tax deductions --period=2025-Q2
Impact: Identify $X in potential deductions before EOFY
3. Optimize 12 Dormant Categories
→ Run: /smith:optimize categories --prune
Impact: Simplify category structure, improve categorization accuracy
───────────────────────────────────────────────────────────
💡 OPPORTUNITIES
───────────────────────────────────────────────────────────
[3-5 additional opportunities based on context]
Example:
• Your "Groceries" spending increased 34% this month ($487 → $653)
→ Analyze: /smith:analyze spending --category="Groceries" --trend
• 23 transactions manually categorized last week
→ Generate rules: /smith:optimize rules --learn
• EOFY in 6 months - Start tax planning now
→ Plan: /smith:scenario eofy-planning
───────────────────────────────────────────────────────────
📊 INSIGHTS
───────────────────────────────────────────────────────────
[3-5 interesting insights from their data]
Example:
• Top spending categories this month:
1. Groceries: $653 (22% of total)
2. Transport: $412 (14% of total)
3. Utilities: $387 (13% of total)
• Most active categorization rule: "Woolworths → Groceries" (47 matches)
• Longest uncategorized streak: 12 days (Nov 10-22)
→ Suggest: Enable weekly categorization reminders
───────────────────────────────────────────────────────────
🔧 MAINTENANCE
───────────────────────────────────────────────────────────
[Recommended maintenance tasks based on setup age]
Example:
• Run health check (last run: 3 weeks ago)
→ /smith:health --full
• Backup local rules (23 rules defined)
→ Agent Smith auto-backups on mutation, but manual backup available
• Update ATO tax guidelines (last update: 45 days ago)
→ Agent Smith will auto-refresh in May before EOFY
═══════════════════════════════════════════════════════════
```
### Intelligence Rules for Suggestions
**Priority ranking:**
1. **Uncategorized transactions > 100** → Highest priority, categorization severely behind
2. **Upcoming tax deadlines (30 days)** → Time-sensitive compliance
3. **Manual categorizations > 20 in last week** → Rule learning opportunity
4. **Health score < 60%** → Fundamental setup issues
5. **Unusual spending changes > 30%** → Budget alert opportunity
6. **Dormant categories > 10** → Optimization needed
**Contextual suggestions based on templates:**
- **PAYG Employee**: Focus on expense claims, work-from-home deductions
- **Sole Trader**: Focus on BAS prep, quarterly tax estimates, deduction maximization
- **Property Investor**: Focus on rental income/expenses, depreciation, CGT events
- **Share Investor**: Focus on dividend tracking, franking credits, CGT events
- **Separated Parents**: Focus on child support tracking, custody expense splits
- **Shared Hybrid**: Focus on contribution balancing, shared expense analysis
**Seasonal suggestions:**
- **Jan-Mar**: Review EOFY preparation, plan deductions
- **Apr-Jun**: EOFY tasks, tax return prep, compliance checks
- **Jul-Sep**: New FY setup, Q1 BAS (sole traders), budget planning
- **Oct-Dec**: Q2 BAS (sole traders), holiday spending analysis
---
## Important Notes
- **Use `uv run python -u`** for all Python scripts (ensures unbuffered output)
- **Save onboarding state** in `data/onboarding_state.json` to resume if interrupted
- **Celebrate progress** - Show metrics like "1,245 → 87 uncategorized transactions"
- **Be patient** - First categorization can take time for large datasets
## Plugin-Aware Script Execution
**All Python scripts must be run using this pattern** to work in both repository and plugin modes:
```bash
# Helper function to run Agent Smith scripts (define once at start)
run_agent_smith() {
local script_path="$1"
shift # Remove first argument, leaving remaining args
if [ -n "${CLAUDE_PLUGIN_ROOT}" ]; then
# Plugin mode - run from skill directory with USER_CWD set and venv isolation
local skill_dir="${CLAUDE_PLUGIN_ROOT}/skills/agent-smith"
local user_cwd="$(pwd)"
if [ ! -d "$skill_dir" ]; then
echo "Error: Agent Smith skill directory not found: $skill_dir"
return 1
fi
# Run from skill directory with:
# - USER_CWD: preserve user's working directory for .env access
# - env -u VIRTUAL_ENV: ignore conflicting virtual environments
# uv will automatically use the plugin's .venv
(cd "$skill_dir" && \
USER_CWD="$user_cwd" \
env -u VIRTUAL_ENV -u VIRTUAL_ENV_PROMPT \
uv run python -u "scripts/$script_path" "$@")
elif [ -f "./scripts/$script_path" ]; then
# Development/repository mode - run from current directory
uv run python -u "./scripts/$script_path" "$@"
else
echo "Error: Agent Smith script not found: $script_path"
echo "CLAUDE_PLUGIN_ROOT: ${CLAUDE_PLUGIN_ROOT:-not set}"
echo "Current directory: $(pwd)"
return 1
fi
}
```
Then call scripts like:
```bash
run_agent_smith "onboarding/discovery.py"
run_agent_smith "operations/categorize_batch.py" --mode=dry_run --period=2025-11
```
## Execution
**Start here:**
1. Check if `data/onboarding_state.json` exists with `"onboarding_completed": true`
2. If NO → Run Stages 1-8 (Onboarding) then Stage 9 (Suggestions)
3. If YES → Skip to Stage 9 (Suggestions) only
After each onboarding stage, confirm user is ready to continue before proceeding.