Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions docs/plans/2026-02-03-bird-cli-implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def check_npm_available() -> bool:

**Step 2: Verify the module loads**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print('OK')"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print('OK')"`
Expected: `OK`

**Step 3: Commit**
Expand Down Expand Up @@ -139,7 +139,7 @@ def get_bird_status() -> Dict[str, Any]:

**Step 2: Verify functions work**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print(bird_x.get_bird_status())"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print(bird_x.get_bird_status())"`
Expected: Dict with installed/authenticated status

**Step 3: Commit**
Expand Down Expand Up @@ -232,7 +232,7 @@ def search_x(

**Step 2: Verify search function signature**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import bird_x; import inspect; print(inspect.signature(bird_x.search_x))"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import bird_x; import inspect; print(inspect.signature(bird_x.search_x))"`
Expected: `(topic: str, from_date: str, to_date: str, depth: str = 'default') -> Dict[str, Any]`

**Step 3: Commit**
Expand Down Expand Up @@ -343,7 +343,7 @@ def parse_bird_response(response: Dict[str, Any]) -> List[Dict[str, Any]]:

**Step 2: Verify parser handles empty input**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print(bird_x.parse_bird_response({}))"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print(bird_x.parse_bird_response({}))"`
Expected: `[]`

**Step 3: Commit**
Expand Down Expand Up @@ -451,7 +451,7 @@ Add these methods to the `ProgressDisplay` class (after `show_promo` method, aro

**Step 3: Verify new methods exist**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib.ui import ProgressDisplay; p = ProgressDisplay('test', show_banner=False); print(hasattr(p, 'prompt_bird_install'))"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib.ui import ProgressDisplay; p = ProgressDisplay('test', show_banner=False); print(hasattr(p, 'prompt_bird_install'))"`
Expected: `True`

**Step 4: Commit**
Expand Down Expand Up @@ -534,7 +534,7 @@ def get_x_source_status(config: Dict[str, Any]) -> Dict[str, Any]:

**Step 2: Verify function works**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import env; print(env.get_x_source_status(env.get_config()))"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import env; print(env.get_x_source_status(env.get_config()))"`
Expected: Dict with source status

**Step 3: Commit**
Expand Down Expand Up @@ -562,7 +562,7 @@ from . import bird_x

**Step 2: Verify import works**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print('OK')"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import bird_x; print('OK')"`
Expected: `OK`

**Step 3: Commit**
Expand Down Expand Up @@ -651,7 +651,7 @@ def setup_bird_if_needed(progress: ui.ProgressDisplay) -> Optional[str]:

**Step 3: Verify script still loads**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "import scripts.last30days; print('OK')"`
Run: `cd $HOME/last30days-skill-private && python3 -c "import scripts.last30days; print('OK')"`
Expected: `OK`

**Step 4: Commit**
Expand Down Expand Up @@ -772,7 +772,7 @@ Then update the `_search_x` call inside (around line 218-222) to pass `x_source`

**Step 3: Verify script syntax is valid**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -m py_compile scripts/last30days.py && echo "OK"`
Run: `cd $HOME/last30days-skill-private && python3 -m py_compile scripts/last30days.py && echo "OK"`
Expected: `OK`

**Step 4: Commit**
Expand Down Expand Up @@ -858,7 +858,7 @@ Find the `run_research` call (around line 413) and add `x_source` parameter:

**Step 4: Verify script runs with --help**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 scripts/last30days.py --help`
Run: `cd $HOME/last30days-skill-private && python3 scripts/last30days.py --help`
Expected: Help text displays without errors

**Step 5: Commit**
Expand All @@ -877,12 +877,12 @@ git commit -m "feat(main): integrate Bird setup into main flow"

**Step 1: Test mock mode still works**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 scripts/last30days.py "Claude Code" --mock --emit=compact 2>&1 | head -20`
Run: `cd $HOME/last30days-skill-private && python3 scripts/last30days.py "Claude Code" --mock --emit=compact 2>&1 | head -20`
Expected: Output showing research results without errors

**Step 2: Test Bird detection (informational)**

Run: `cd /Users/mvanhorn/last30days-skill-private && python3 -c "from scripts.lib import env; import json; print(json.dumps(env.get_x_source_status(env.get_config()), indent=2))"`
Run: `cd $HOME/last30days-skill-private && python3 -c "from scripts.lib import env; import json; print(json.dumps(env.get_x_source_status(env.get_config()), indent=2))"`
Expected: JSON showing current Bird/xAI status

**Step 3: Commit any fixes if needed, then final commit**
Expand All @@ -907,12 +907,12 @@ git commit -m "feat(bird): complete Bird CLI integration

**Step 1: Push all changes**

Run: `cd /Users/mvanhorn/last30days-skill-private && git push origin main`
Run: `cd $HOME/last30days-skill-private && git push origin main`
Expected: Changes pushed to private repo

**Step 2: Verify commit history**

Run: `cd /Users/mvanhorn/last30days-skill-private && git log --oneline -10`
Run: `cd $HOME/last30days-skill-private && git log --oneline -10`
Expected: Shows Bird integration commits

---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ set -euo pipefail

# === Config ===
SKILL_DIR="$HOME/.claude/skills/last30days"
REPO_DIR="/Users/mvanhorn/last30days-skill-private"
REPO_DIR="$HOME/last30days-skill-private"
OUT_DIR="$REPO_DIR/docs/test-results/v1-vs-v2-$(date +%Y%m%d-%H%M%S)"
V1_DIR="$OUT_DIR/v1"
V2_DIR="$OUT_DIR/v2"
Expand Down Expand Up @@ -255,7 +255,7 @@ rm -f "$SKILL_DIR/SKILL.md.v2.bak"
## How to Run

```bash
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private
chmod +x scripts/test-v1-vs-v2.sh
./scripts/test-v1-vs-v2.sh
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ The current `openai_reddit.py` gets relevance scores **from OpenAI** (the AI jud
### Phase 0: Fork Repository

- [ ] Create new repo `last30days-free-reddit` (or branch in private repo)
- [ ] `git clone /Users/mvanhorn/last30days-skill-private /Users/mvanhorn/last30days-free-reddit`
- [ ] `git clone $HOME/last30days-skill-private $HOME/last30days-free-reddit`
- [ ] Create feature branch: `feat/free-reddit`
- [ ] Verify all existing tests pass on the new branch

Expand Down Expand Up @@ -317,8 +317,8 @@ The current `openai_reddit.py` gets relevance scores **from OpenAI** (the AI jud

```bash
# Fork into new working repo
cp -r /Users/mvanhorn/last30days-skill-private /Users/mvanhorn/last30days-free-reddit
cd /Users/mvanhorn/last30days-free-reddit
cp -r $HOME/last30days-skill-private $HOME/last30days-free-reddit
cd $HOME/last30days-free-reddit

# Create feature branch
git checkout -b feat/free-reddit
Expand Down
24 changes: 12 additions & 12 deletions docs/plans/2026-02-06-feat-last30days-bird-cli-release-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Remove the old skill so only the new one is active. This eliminates ambiguity du
rm ~/.claude/skills/last30daystest

# Create new symlink with the primary name
ln -s /Users/mvanhorn/last30days-skill-private ~/.claude/skills/last30days
ln -s $HOME/last30days-skill-private ~/.claude/skills/last30days
```

3. **Verify only one `/last30days` appears**:
Expand Down Expand Up @@ -78,7 +78,7 @@ Run the Python scripts directly to verify core functionality without invoking th
```bash
# Test: Bird is installed and authenticated
python3 -c "
import sys; sys.path.insert(0, '/Users/mvanhorn/last30days-skill-private/scripts/lib')
import sys; sys.path.insert(0, '$HOME/last30days-skill-private/scripts/lib')
import bird_x
print('installed:', bird_x.is_bird_installed())
print('authenticated:', bird_x.is_bird_authenticated())
Expand All @@ -92,7 +92,7 @@ print('status:', bird_x.get_bird_status())
#### Environment & Source Detection
```bash
python3 -c "
import sys; sys.path.insert(0, '/Users/mvanhorn/last30days-skill-private/scripts/lib')
import sys; sys.path.insert(0, '$HOME/last30days-skill-private/scripts/lib')
import env
config = env.load_config()
print('x_source:', env.get_x_source(config))
Expand All @@ -105,7 +105,7 @@ print('has_openai:', bool(config.get('OPENAI_API_KEY')))
#### Bird Search (Direct)
```bash
python3 -c "
import sys, json; sys.path.insert(0, '/Users/mvanhorn/last30days-skill-private/scripts/lib')
import sys, json; sys.path.insert(0, '$HOME/last30days-skill-private/scripts/lib')
import bird_x
result = bird_x.search_x('Claude Code tips', '2026-01-07', '2026-02-06', 'quick')
print(json.dumps(result, indent=2, default=str)[:2000])
Expand All @@ -117,7 +117,7 @@ print(json.dumps(result, indent=2, default=str)[:2000])

#### Full Research Pipeline (Compact Output)
```bash
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private
python3 scripts/last30days.py "Claude Code tips" --emit=compact --quick 2>&1 | head -100
```
- [ ] Completes without error
Expand All @@ -136,7 +136,7 @@ PATH_BACKUP="$PATH"
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v "$(dirname $(which bird 2>/dev/null))" | tr '\n' ':')

python3 -c "
import sys; sys.path.insert(0, '/Users/mvanhorn/last30days-skill-private/scripts/lib')
import sys; sys.path.insert(0, '$HOME/last30days-skill-private/scripts/lib')
import env
config = env.load_config()
print('x_source (no bird):', env.get_x_source(config))
Expand All @@ -150,7 +150,7 @@ export PATH="$PATH_BACKUP"
#### No X source at all
```bash
python3 -c "
import sys; sys.path.insert(0, '/Users/mvanhorn/last30days-skill-private/scripts/lib')
import sys; sys.path.insert(0, '$HOME/last30days-skill-private/scripts/lib')
import env
config = {} # empty config, no keys
print('x_source (nothing):', env.get_x_source(config))
Expand All @@ -165,7 +165,7 @@ Validate that Bird responses are correctly normalized to the canonical schema.

```bash
python3 -c "
import sys; sys.path.insert(0, '/Users/mvanhorn/last30days-skill-private/scripts/lib')
import sys; sys.path.insert(0, '$HOME/last30days-skill-private/scripts/lib')
import bird_x

# Test with sample Bird response format
Expand Down Expand Up @@ -197,7 +197,7 @@ print('Author:', parsed[0].get('author_handle'))
# Verify YAML frontmatter parses correctly
python3 -c "
import yaml
with open('/Users/mvanhorn/last30days-skill-private/SKILL.md') as f:
with open('$HOME/last30days-skill-private/SKILL.md') as f:
content = f.read()
# Extract YAML between --- markers
parts = content.split('---', 2)
Expand All @@ -218,7 +218,7 @@ with open('/Users/mvanhorn/last30days-skill-private/SKILL.md') as f:
```bash
# Verify the only meaningful addition is bird_x.py
diff -rq ~/.claude/skills/last30days.backup-v1/scripts/lib/ \
/Users/mvanhorn/last30days-skill-private/scripts/lib/ 2>/dev/null
$HOME/last30days-skill-private/scripts/lib/ 2>/dev/null
```
- [ ] Only new file is `bird_x.py`
- [ ] Modified files: `env.py` (source detection), `__init__.py` (exports)
Expand Down Expand Up @@ -345,7 +345,7 @@ Before merging to `main` on the public repo:
- [ ] SKILL.md frontmatter is correct (`name: last30days`, not `last30daystest`)
- [ ] README.md documents Bird CLI setup
- [ ] No debug/test artifacts in codebase
- [ ] No hardcoded paths (e.g., `/Users/mvanhorn/...`)
- [ ] No hardcoded paths (e.g., `$HOME/...`)
- [ ] `.env` files are gitignored
- [ ] Git history is clean (no "test" or "WIP" commits on main)
- [ ] Bird CLI failure doesn't break the skill (graceful fallback verified)
Expand Down Expand Up @@ -379,7 +379,7 @@ git checkout cc892d7 # last known good commit from old version
| Bird CLI breaks after X API changes | Medium | Low | Fallback to xAI/WebSearch still works |
| Bird auth expires silently | Medium | Low | `is_bird_authenticated()` check + user message |
| Old xAI workflows regress | Low | High | Comparison test in Phase 2.5 |
| Hardcoded paths in codebase | Low | Medium | Grep for `/Users/mvanhorn` before release |
| Hardcoded paths in codebase | Low | Medium | Grep for `/Users/` or `/home/` before release |
| SKILL.md name still says `last30daystest` | Low | High | Already fixed in commit `4e972d0` |

## References
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Add an explicit "Display your parsing" instruction between the "Parse User Inten

### SKILL.md Change

**File:** `/Users/mvanhorn/last30days-skill-private/SKILL.md`
**File:** `$HOME/last30days-skill-private/SKILL.md`

After the "Store these variables" block (line ~38) and before "Research Execution" (line ~42), add:

Expand All @@ -74,7 +74,7 @@ This text MUST appear before you call any tools. It confirms to the user that yo

After editing SKILL.md:
```bash
cp /Users/mvanhorn/last30days-skill-private/SKILL.md ~/.claude/skills/last30days/SKILL.md
cp $HOME/last30days-skill-private/SKILL.md ~/.claude/skills/last30days/SKILL.md
```

## Test Plan
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Re-run the same 4 queries after fixes:
## References

- Current SKILL.md: `~/.claude/skills/last30days/SKILL.md`
- Private repo: `/Users/mvanhorn/last30days-skill-private/`
- Private repo: `$HOME/last30days-skill-private/`
- Old working SKILL.md: `~/.claude/skills/last30days.backup-v1/SKILL.md`
- Reddit search module: `scripts/lib/openai_reddit.py:53-93` (prompt), `:160-166` (API call)
- Scoring module: `scripts/lib/score.py:151-157` (penalties)
Expand Down
2 changes: 1 addition & 1 deletion docs/plans/2026-02-06-test-v1-vs-v2-comparison-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Run the same queries through both the public v1 and private v2 of last30days, co
cp ~/.claude/skills/last30days/SKILL.md ~/.claude/skills/last30days/SKILL.md.v2

# Install v1 from upstream
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private
git show upstream/main:SKILL.md > ~/.claude/skills/last30days/SKILL.md
```

Expand Down
2 changes: 1 addition & 1 deletion docs/plans/2026-02-07-release-v2-public-launch-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Push all V2 changes from the private development repo to the public GitHub repo,
### Step 2: Push to public

```bash
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private
git push upstream main
```

Expand Down
18 changes: 9 additions & 9 deletions docs/plans/2026-02-14-feat-merge-openclaw-variant-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,15 @@ The open variant's SKILL.md uses `{baseDir}` which resolves to the skill root. B
## References

### Internal
- OpenClaw plan: `/Users/mvanhorn/last30days-openclaw/docs/plans/2026-02-10-feat-openclaw-last30days-skill-plan.md` (989 lines, comprehensive spec)
- OpenClaw plan: `$HOME/last30days-openclaw/docs/plans/2026-02-10-feat-openclaw-last30days-skill-plan.md` (989 lines, comprehensive spec)
- Codex compat plan: `docs/plans/2026-02-14-feat-codex-skill-compatibility-plan.md` (portable paths, platform-neutral text)
- OpenClaw source: `/Users/mvanhorn/last30days-openclaw/`
- OpenClaw source: `$HOME/last30days-openclaw/`

### Key files to port
- `store.py`: `/Users/mvanhorn/last30days-openclaw/scripts/store.py` (20KB, SQLite with FTS5)
- `watchlist.py`: `/Users/mvanhorn/last30days-openclaw/scripts/watchlist.py` (10KB)
- `briefing.py`: `/Users/mvanhorn/last30days-openclaw/scripts/briefing.py` (8KB)
- `brave_search.py`: `/Users/mvanhorn/last30days-openclaw/scripts/lib/brave_search.py` (6KB)
- `parallel_search.py`: `/Users/mvanhorn/last30days-openclaw/scripts/lib/parallel_search.py` (4KB)
- `openrouter_search.py`: `/Users/mvanhorn/last30days-openclaw/scripts/lib/openrouter_search.py` (7KB)
- `env.py` (openclaw version): `/Users/mvanhorn/last30days-openclaw/scripts/lib/env.py` (9KB — has web search key functions)
- `store.py`: `$HOME/last30days-openclaw/scripts/store.py` (20KB, SQLite with FTS5)
- `watchlist.py`: `$HOME/last30days-openclaw/scripts/watchlist.py` (10KB)
- `briefing.py`: `$HOME/last30days-openclaw/scripts/briefing.py` (8KB)
- `brave_search.py`: `$HOME/last30days-openclaw/scripts/lib/brave_search.py` (6KB)
- `parallel_search.py`: `$HOME/last30days-openclaw/scripts/lib/parallel_search.py` (4KB)
- `openrouter_search.py`: `$HOME/last30days-openclaw/scripts/lib/openrouter_search.py` (7KB)
- `env.py` (openclaw version): `$HOME/last30days-openclaw/scripts/lib/env.py` (9KB — has web search key functions)
2 changes: 1 addition & 1 deletion docs/plans/2026-02-17-feat-github-release-v2.1-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Initial public release. Reddit + X search via OpenAI and xAI APIs.
#### 2. Create annotated tag on the public repo

```bash
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private

# Tag on the current HEAD (which matches upstream/main)
git tag -a v2.1.0 -m "Release v2.1.0: Watchlists, YouTube transcripts, Codex CLI, bundled X search"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,14 @@ valid and sidesteps the isolation problem entirely.

### Step 1: Fix the test

In the **private source repo** (`/Users/mvanhorn/last30days-skill-private/`):
In the **private source repo** (`$HOME/last30days-skill-private/`):

Edit `tests/test_codex_auth.py` line 77-84. Replace the bare test with the `@patch.dict` version above. Run `python3 -m pytest tests/test_codex_auth.py -v` to confirm 22/22.

### Step 2: Run full test suite

```bash
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private
python3 -m pytest tests/ -v 2>&1 | tail -20
```

Expand All @@ -165,7 +165,7 @@ Check that `.gitignore` (or the upstream push config) prevents `docs/comparison-
from leaking to the public GitHub remote.

```bash
cat /Users/mvanhorn/last30days-skill-private/.gitignore | grep -E "comparison|evaluate|generate"
cat $HOME/last30days-skill-private/.gitignore | grep -E "comparison|evaluate|generate"
```

If not present, add:
Expand All @@ -181,7 +181,7 @@ variants/open/references/research.md
### Step 4: Commit and sync

```bash
cd /Users/mvanhorn/last30days-skill-private
cd $HOME/last30days-skill-private
git add tests/test_codex_auth.py
git commit -m "fix(tests): patch OPENAI_API_KEY env isolation in test_api_key_takes_priority"
bash scripts/sync.sh
Expand Down
2 changes: 1 addition & 1 deletion docs/plans/2026-03-06-fix-save-output-noise-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Remove auto-save. Add a note to the invitation: "Say 'save' to save this researc

## Context

- Source: `/Users/mvanhorn/last30days-skill-private/SKILL.md`
- Source: `$HOME/last30days-skill-private/SKILL.md`
- Deployed to: `~/.claude/skills/last30days/SKILL.md`
- Sync command: `bash scripts/sync.sh`
- Current version: v2.9.3
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Rules:
**How it works:**

1. **Tag Watcher** - `marketing/scripts/watch_releases.py`
- Runs `git -C /Users/mvanhorn/last30days-skill-private fetch upstream --tags` every 6 hours
- Runs `git -C $HOME/last30days-skill-private fetch upstream --tags` every 6 hours
- Compares local tags vs upstream tags
- On new tag: reads CHANGELOG.md diff since last tag

Expand Down
Loading