Commit Graph

37 Commits (9a3ba54974c4be3361a67629b4564e52aa7a0649)

Author SHA1 Message Date
PeninsulaInd 9a3ba54974 Fix 8: Reset task to 'to do' when outline file is missing
When Phase 2 cannot find the outline file at any of the searched
locations, the task is now reset to its initial poll status in ClickUp
with a comment explaining the issue and suggesting a Phase 1 re-run.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:03:43 -06:00
PeninsulaInd 1eb7df6143 Fix 7: Report attachment upload failures in ClickUp comment
When upload_attachment() returns False, the ClickUp comment now includes
a warning listing which files failed to upload and their local paths,
so Bryan can retrieve them manually.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:02:54 -06:00
PeninsulaInd c80d237e36 Fix 2: Store OutlinePath in ClickUp custom field for Phase 2 retrieval
Phase 1 now writes OutlinePath to a ClickUp custom field via
set_custom_field_by_name(). Phase 2 reads it back with
get_custom_field_by_name(), falling back to convention path
({outline_dir}/{slug}/outline.md) if the field is empty.

Added get_task(), set_custom_field_by_name(), and
get_custom_field_by_name() helpers to ClickUpClient.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 15:58:26 -06:00
PeninsulaInd 5ddeb93033 Fix 1: AutoCora prioritized sweep and KV-free result polling
Replace single-day task filter with multi-pass sweep when no explicit
target_date: (1) due today, (2) overdue + current month tag, (3) last
month tag, (4) look-ahead 2 days. Deduplicate across passes.

Remove KV store from submit (dedup by job file existence) and result
poller (scan results/ folder directly, move to processed/ after handling).
Scheduler auto-submit no longer passes explicit target_date.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 15:57:09 -06:00
PeninsulaInd 41487c8d6b Add file-first content creation pipeline with Cora inbox watcher
Content tasks now trigger from Cora xlsx files dropped in Z:/content-cora-inbox/
instead of auto-firing from ClickUp polling. The watcher fuzzy-matches files to
ClickUp tasks and auto-detects content type from URL presence (optimization vs
new content). Adds cli_flags support for service page hints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:29:04 -06:00
PeninsulaInd 2ef7ae2607 Merge branch 'content-creation' 2026-02-25 15:13:57 -06:00
PeninsulaInd a3b8457afe Add two-phase content creation tool with human-in-the-loop outline review
Phase 1 researches competitors and generates an outline via the execution brain,
saves it to a network/local path, and pauses for human review. Phase 2 picks up
the approved outline and writes full SEO-optimized content. ClickUp integration
maps "On Page Optimization" and "Content Creation" work categories, with
"outline approved" added to poll_statuses for automatic Phase 2 triggering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:10:09 -06:00
PeninsulaInd ada28d1655 Add AutoCora auto-submit for today's tasks and fix pipeline issues
- Auto-submit Cora jobs for tasks due today on each autocora loop cycle
- Move ClickUp tasks to "automation underway" at submission time
- Default to blank URL for tasks missing IMSURL (new content)
- Use task Keyword field as project_name in folder watcher (not task name)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:09:12 -06:00
PeninsulaInd bc64fae6f1 Add AutoCora job submission and result polling automation
Automates Cora SEO report workflow: queries ClickUp for qualifying tasks,
submits jobs to a shared folder queue, polls for results, and updates task
statuses. Includes two tools (submit_autocora_jobs, poll_autocora_results),
a scheduler polling loop, and 30 tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 07:52:53 -06:00
PeninsulaInd 0b3ab904de Add API cost tracking and switch planner to Grok 4.1 Fast
Track per-call token usage and estimated costs across all OpenRouter models.
Switch planner agent from Claude Sonnet 4.6 ($3/$15 per M) to Grok 4.1 Fast
($0.20/$0.50 per M) for ~25x cost reduction. Add budget alerts, a dashboard
card, and a check_api_usage tool for visibility into spending.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:00:11 -06:00
PeninsulaInd ab2c313baa Add report_issue tool and planner agent for self-improvement tracking
- New report_issue tool logs bugs/improvements to memory/improvement_requests.md
- Planner agent (Sonnet via OpenRouter) for architecture and debugging tasks
- Heartbeat checks for pending improvement requests to surface to Bryan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:31:28 -06:00
PeninsulaInd 3f2798d338 Add "automation underway" and "error" ClickUp statuses for bot visibility
Tasks now show "automation underway" when the bot picks them up and "error"
on failure, replacing the old "in progress" / "to do" fallbacks that were
invisible on Bryan's ClickUp board. Folder watcher also syncs ClickUp status
on match, missing IMSURL, pipeline failure, success, and exceptions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:36:58 -06:00
PeninsulaInd 62186d8dec Fix folder watcher matching, notifications, and BLM venv isolation
- Remove status filter from folder watcher so tasks in any open status
  (including "internal review") are matched by keyword
- Add retry logic for stuck processing/blocked/unmatched KV states
- Fix notification ordering (newest first, limit 50) and date parsing
- Use BLM's own .venv Python instead of uv run for subprocess calls
- Document external tools venv convention in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:35:54 -06:00
PeninsulaInd 3b4a8e47be Require IMSURL for Cora pipeline, fail early if missing
Remove placeholder URL fallback from ingest-cora args. Add early
validation in run_cora_backlinks and folder watcher — if IMSURL is
empty, block the task with a notification instead of running with a
fake URL. Update tests to pass money_site_url and add missing-URL test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 12:11:11 -06:00
PeninsulaInd f67f1b9124 Rename Client field to Customer and refine Overview sections
ClickUp "Client" custom field was deleted; switch all references to
"Customer" across config, tools, tests, and docs. Refine Overview tab:
rename Due Soon to Up Next (today/tomorrow, fallback next 5), expand
This Month to include both month tag and due-date-in-month matches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:20:19 -06:00
PeninsulaInd e1992fa049 Add data-driven dashboard with API backend
- New cheddahbot/api.py: FastAPI router with endpoints for tasks,
  link building, press releases, agents, system health, notifications,
  KV states, and cache management (all cached 5min)
- Rewrote dashboard/index.html: replaces all hardcoded data with JS
  that fetches from /api/ endpoints. Tabs: Overview, Link Building,
  Press Releases, By Company, System Health, Agents, Notifications
- Updated __main__.py: mounts API router, removes old inline
  /api/linkbuilding/status endpoint
- Fixed run_link_building to reject empty LB Method instead of
  defaulting to Cora Backlinks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:53:51 -06:00
PeninsulaInd 916bec8c0e Reformat code and update ClickUp tools to reset pattern
- Ruff format: consistent dict/call wrapping in agent.py, db.py,
  skills.py, delegate.py
- Replace clickup_approve_task/clickup_decline_task with
  clickup_reset_task/clickup_reset_all (simpler state machine)
- Add kv_delete() method to Database
- Add due_date and field filter tests to test_clickup.py
- Update test_clickup_tools.py for new reset tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:44:40 -06:00
PeninsulaInd a1fc5a7c0f Fix lint issues across link building files
- Remove f-prefix from strings with no placeholders
- Use list unpacking instead of concatenation
- Fix import sorting in test file
- Remove unused Path import
- Use contextlib.suppress instead of try/except/pass
- Wrap long lines to stay under 100 chars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:13:37 -06:00
PeninsulaInd 2d5ed29c0d Add link building tool module with pipeline orchestration
- run_link_building: dispatcher that routes to correct pipeline by LB Method
- run_cora_backlinks: full pipeline (ingest-cora → generate-batch) with ClickUp sync
- blm_ingest_cora: standalone ingest tool
- blm_generate_batch: standalone generate tool
- scan_cora_folder: utility to inspect watch folder contents
- setup_linkbuilding_fields: one-time ClickUp field creation
- Private helpers for subprocess execution, output parsing, fuzzy matching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:04:02 -06:00
PeninsulaInd 0becf1dd89 Revert "Add link building agent with content generation pipeline"
This reverts commit 8a98b37725.
2026-02-19 18:38:51 -06:00
PeninsulaInd 8a98b37725 Add link building agent with content generation pipeline
New linkbuilder agent that handles ClickUp "Link Building" tasks.
For each keyword/company, generates three content pieces via the
execution brain: a guest article (500-700 words), a directory
listing, and a social media post — each with proper SEO anchor
text and backlinks. Integrates with ClickUp for status updates,
comments, and file attachments.

- cheddahbot/tools/linkbuilding.py: build_links tool with full pipeline
- skills/linkbuilding.md: skill prompt for SEO content generation
- config.yaml: linkbuilder agent config + Link Building skill_map entry
- tests/test_linkbuilding.py: 36 tests covering helpers, prompts,
  pipeline, file output, error handling, and ClickUp sync

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 11:52:06 -06:00
PeninsulaInd deae147795 Hide clickup_task_id from LLM tool schema to prevent hallucination
Removed clickup_task_id from write_press_releases function signature
so the LLM cannot see or fabricate a task ID. The parameter is now
passed through ctx by the ToolRegistry — the scheduler sets it in
args, and execute() moves it into the ctx dict before filtering.
Only system-injected task IDs can reach the tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:38:11 -06:00
PeninsulaInd 082ca6ba44 Fix PR task flow: add ClickUp status updates, comments, and attachments
The press release tool now handles its own ClickUp sync lifecycle when
a clickup_task_id is provided — sets status to "in progress" with a
starting comment, uploads docx attachments after creation, then sets
status to "internal review" with a completion comment. The scheduler
now passes clickup_task_id to tools and defers to tool-level sync when
detected, falling back to scheduler-level sync for other tools.
ToolRegistry.execute() now filters args to accepted params to prevent
TypeError when extra keys (like clickup_task_id) are passed to tools
that don't accept them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:36:45 -06:00
PeninsulaInd e5e9442e3d 3.6: Add delegate_to_agent tool for cross-agent delegation
New tool in delegate.py routes tasks to named agents via
agent.respond_to_prompt(). Includes thread-local depth counter
(max 3) to prevent infinite A->B->A delegation loops. Extended
ctx injection in ToolRegistry to include agent_registry. Wired
agent_registry into ToolRegistry from __main__.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:13:32 -06:00
PeninsulaInd 86511d5a0f 3.3: Modify Agent and ToolRegistry for multi-agent
Agent changes:
- Accept optional AgentConfig in __init__
- Add name property
- Filter tools via agent_config.tools whitelist in respond()
- Use agent-specific personality file when configured
- Pass agent name to skills registry for filtering

ToolRegistry changes:
- get_tools_schema() accepts filter_names parameter
- get_tools_description() accepts filter_names parameter
- When filter_names is None, all tools are returned (backward compat)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:08:16 -06:00
PeninsulaInd 724ccfebd6 2.4: Strip frontmatter in press_release.py _load_skill()
The _load_skill() function now strips YAML frontmatter (--- ... ---)
before returning skill content. This prevents the execution brain
from receiving metadata intended for the skill registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:03:22 -06:00
PeninsulaInd 202a5e99e4 1.4: Wire require_approval check for shell commands
When config.shell.require_approval is True, run_command now refuses
execution and directs the user to delegate_task instead. The execution
brain (Claude Code CLI) has its own approval controls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:59:27 -06:00
PeninsulaInd 0bef1e71b3 1.1: Delete dead code and fix all lint errors
Remove unused modules that were never called at startup:
- cheddahbot/skills/__init__.py (dead @skill decorator system)
- cheddahbot/providers/__init__.py (empty placeholder)
- cheddahbot/tools/build_skill.py (depends on dead skills system)
- cheddahbot/tools/build_tool.py (security risk: generates arbitrary Python)

Also fix all pre-existing ruff lint errors across the codebase:
- Fix import sorting, unused imports, line length violations
- Fix type comparisons (use `is` instead of `==`)
- Fix implicit Optional types (dict -> dict | None)
- Fix unused variables, ambiguous variable names
- Apply ruff format for consistent style

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:56:36 -06:00
PeninsulaInd a7171673fc Add clickup_task_id param to write_press_releases for chat-triggered sync
When a press release is triggered via chat with a ClickUp task ID, the
tool now uploads .docx attachments, posts a result comment, and updates
task status — matching what the scheduler does automatically. ClickUp
sync is wrapped in try/except so failures don't lose PR results.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 21:42:41 -06:00
PeninsulaInd 5e9cef5e39 Add submit_press_release tool with Press Advantage API integration
Adds PressAdvantageClient API wrapper and submit_press_release tool that
posts finished press releases to PA as drafts. Auto-constructs SEO links
(brand+keyword → IMSURL, company name → SocialURL/GBP/homepage) with
fuzzy anchor matching and warnings when phrases can't be found. The PR
writing prompt now requests anchor text phrases and validates them after
generation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:37:41 -06:00
PeninsulaInd 8f6e218221 Add document export (.docx) and email delivery feature
Press releases now auto-generate .docx files alongside .txt for native
Google Docs import. New email_file chat tool sends files via Gmail SMTP
with app password auth, auto-converting .txt to .docx before sending.
Also includes Press Advantage API config and submit_press_release tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:00:54 -06:00
PeninsulaInd 7864ec6f17 Add pipeline status box to show PR tool progress in the UI
The press release pipeline takes 2-4 minutes per run with no feedback.
This adds a DB-polled status box (gr.Timer every 3s) that shows the
current step (e.g. "Step 3/4: Writing press release 1/2 — headline...")
and auto-hides when the pipeline completes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:41:33 -06:00
PeninsulaInd 7153e65ae6 Add clickup_query_tasks tool and Press Advantage API integration plan
New tool queries ClickUp API live for tasks, with optional status and
task_type filters. Fixes the execution brain instantiation bug by
providing a proper @tool wrapper around ClickUpClient.

Also saves the Press Advantage API integration plan for future work
once API access is restored.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 13:21:04 -06:00
PeninsulaInd e02f5a5cb3 Add ClickUp chat tools for task management
Four chat-facing tools: clickup_list_tasks (list/filter tracked tasks),
clickup_task_status (detailed state view), clickup_approve_task and
clickup_decline_task (approval flow for tasks awaiting permission).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:27:34 -06:00
PeninsulaInd b3140d3522 Add autonomous press release pipeline tool
Implements write_press_releases tool that generates 7 headlines via chat
brain, AI-judges the best 2, writes 2 full press releases via execution
brain, and generates JSON-LD schemas via Sonnet with WebSearch. Saves all
output files to data/generated/press_releases/.

Also adds tools/model pass-through in agent and LLM layers, fixes Windows
command line length limit by piping prompts via stdin, and updates model
references to current versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:04:29 -06:00
PeninsulaInd af767f9684 Implement two-brain architecture: chat brain + execution brain
Chat brain uses OpenAI-compatible APIs (OpenRouter/Ollama/LM Studio) for
all UI conversations, giving full control over system prompts so the
Cheddah personality works correctly. Execution brain uses Claude Code CLI
for heartbeat, scheduled tasks, and delegated system-level work.

- Split llm.py: chat() routes through OpenAI-compat only, new execute()
  calls Claude CLI with Bash/Read/Edit/Write/Glob/Grep tools
- Add chat_model config field (default: openai/gpt-4o-mini)
- Add delegate_task tool bridging chat brain to execution brain
- Scheduler/heartbeat now use execute_task() for real CLI power
- UI dropdown shows chat-only models with custom value support
- Updated model list to current OpenRouter top models (Feb 2026)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:59:32 -06:00
PeninsulaInd 1b73cf2e5d Initial implementation of CheddahBot personal AI assistant
Multi-model AI assistant with Gradio UI, persistent memory, 15+ tools,
and meta-tools for runtime tool creation. Routes Claude models through
Claude Code SDK (Max subscription), cloud models through OpenRouter,
and local models through Ollama/LM Studio.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:20:39 -06:00