Commit Graph

45 Commits (f4e642240c9238cf32a13b8ff47349f68230d3e3)

Author SHA1 Message Date
PeninsulaInd dcfabc2261 Fix NoneType crash in LLM plural check when OpenRouter returns null content
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:30:36 -05:00
PeninsulaInd c12c655220 Pass statuses to ClickUp API for task matching and reduce watcher interval
Server-side filter tasks by _CORA_ELIGIBLE_STATUSES in _match_xlsx_to_clickup,
_match_xlsx_to_content_task, and _distribute_cora_file instead of fetching all
tasks and filtering client-side. Reduce watcher interval from 40m to 10m.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:33:32 -05:00
PeninsulaInd fdafa42122 Strip all emoji and unicode from runtime strings
Replace emoji prefixes in ClickUp comments and notifications with
plain ASCII tags ([FAILED], [DONE], [WARNING], [STARTED], [OUTLINE]).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:59:41 -05:00
PeninsulaInd 305b3161c4 Replace unicode arrows with ASCII in log/output strings
Windows cp1252 console encoding can't handle → (U+2192), causing
UnicodeEncodeError in logging. Replaced with -> in all runtime strings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:56:48 -05:00
PeninsulaInd 48d2e47835 Replace fuzzy keyword matching with exact match + LLM plural check
Substring and word-overlap matching caused cross-contamination between
similar keywords (e.g. "shaft manufacturing" matching "custom shaft
manufacturing"). Now only exact matches pass immediately; non-exact
pairs are checked via OpenRouter LLM call with session-level caching.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:53:24 -05:00
PeninsulaInd b857d3cb8c Fix missing ClickUp comments on error status transitions and add pipeline error audit log
- File handler now captures DEBUG+ (was WARNING) for full pipeline visibility
- Add ClickUp comments at every error status transition (missing IMSURL, pipeline crash, content crash)
- Content watcher exception now also sets error status (was silently failing)
- Cora distributor resets matched error tasks to "running cora" when new XLSX arrives
- Add dedicated logs/pipeline_errors.log for tool-handled errors (audit trail)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:28:48 -05:00
PeninsulaInd e8df7a9750 Add get_active_tasks tool to show what's running before restart
Thread-safe active execution registry in Scheduler tracks which tool
functions are currently blocking. New get_active_tasks chat tool reads
this registry plus loop timestamps to report running tasks, durations,
loop health, and a safe-to-restart verdict.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 17:04:19 -05:00
PeninsulaInd eae55fd714 Reduce scheduler log noise and update loop timing docs
- Move repetitive "Skipping task", "ClickUp task skipped", and "AutoCora
  result" messages from INFO to DEBUG level
- Update task-pipeline-flows.md: folder watchers now 40m, add cora_distribute loop

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 13:20:38 -05:00
PeninsulaInd 5cb15756fc Filter Cora distribution to eligible statuses and reduce poll interval to 40m
- Add _CORA_ELIGIBLE_STATUSES filter so only "running cora" and "error" tasks
  get matched during xlsx distribution (prevents accidental "to do" matches)
- Reduce watch_interval_minutes from 60 to 40 for faster Cora file pickup
- Add .txt output to test block generator
- Include docs, scripts, and reference files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:29:02 -05:00
PeninsulaInd f60928f3fa Clarify notification and ClickUp comment messages
- "pipeline completed" → descriptive messages for link building and content
- "ClickUp task completed" → "{task} done — ran {tool} successfully"
- "Cora report completed" → "Cora report generated — ready for you to look at it"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 18:14:23 -05:00
PeninsulaInd fb4498b978 Enhance ClickUp task creation, smart field setting, and Cora distribution comments
- Add set_custom_field_smart() to auto-resolve dropdown option UUIDs
- Extend create_task with priority, assignees, time_estimate params
- Expand clickup_create_task tool and CLI script with tags, due dates, custom fields
- Add _comment_distributed_tasks to post clear ClickUp comments on Cora distribution
  (e.g. "Cora XLSX moved to cora-inbox" / "content-cora-inbox")
- Remove unused _find_all_todo_tasks; simplify AutoCora sibling matching
- Add tests for set_custom_field_smart dropdown and text fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 18:06:03 -05:00
PeninsulaInd 6250918e5e Migrate ClickUp Customer field to space-level Client field
Replaces all "Customer" field lookups with "Client" to match the new
space-wide dropdown, eliminating the 20+ duplicate list-level fields.
Includes migration script that populated 400 active tasks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 12:23:14 -05:00
PeninsulaInd 85d9fc7a1f Route create_content by content_type instead of URL presence
Content Creation tasks with a URL were incorrectly routed to the
optimization path. Now the scheduler sets content_type from Work
Category, and the tool routes on that. Chat callers fall back to
URL-based detection when content_type is empty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 20:58:07 -05:00
PeninsulaInd b4f1ddfced Fix Phase 2 detection: pass original task status to create_content
The scheduler sets status to "automation underway" before the tool runs,
so create_content's API re-fetch never saw "outline approved". Now the
scheduler passes the pre-change status via clickup_task_status arg.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:18:12 -05:00
PeninsulaInd a3eacbd0e5 Add status-aware auto_execute gate for Content Creation Phase 2
The scheduler's blanket auto_execute check was blocking "outline approved"
Content Creation tasks from reaching Phase 2. Now checks
auto_execute_on_status for status-specific overrides. Also adds
trigger_hint to skip log messages for easier debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:05:50 -05:00
PeninsulaInd 8f2ec48e10 Increase CLI timeout to 15min, fix result file reprocessing, and save outlines directly
- Bump Claude Code subprocess timeout from 5 to 15 minutes for longer content tasks
- Fix scheduler result file loop: unlink source if already exists in processed/ dir
- Pass outline save path to execution brain so it writes directly to network share

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:38:48 -05:00
PeninsulaInd 1e26969ff8 Add explicit poll_task_types allowlist to filter ClickUp polling
Only tasks with Work Category in poll_task_types are fetched and
processed. Prevents unrecognized types (SEO Audit, AEO, etc.) from
being evaluated every poll cycle. Falls back to skill_map keys if
the list is empty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:28:42 -06:00
PeninsulaInd 6b5d0ac71e Add daily morning briefing via ntfy push notifications
Sends a summary at 6:30 AM weekdays / 8:00 AM weekends (Central) with
Cora reports needing action, outlines to approve, PRs to review, and
errors — grouped by customer. Cora tasks cross-reference network share
folders to show file pipeline status. No LLM API credits burned.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:15:49 -06:00
PeninsulaInd 45ab4c1b33 Fix task looping: increase stale recovery to 6h, add file logging, use UNC paths
- Stale task recovery threshold 2h → 6h to prevent resetting tasks while Cora is still running
- Add rotating file logger (WARNING+) to logs/cheddahbot.log for debugging
- Silence httpx/httpcore INFO spam from terminal
- Switch watch folder paths from Z: drive letters to UNC paths to avoid intermittent mount drops
- Fix test_db tests to add messages so list_conversations includes them

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 21:41:46 -06:00
PeninsulaInd 236b64c11c Add Cora report distribution watcher to route xlsx to pipeline inboxes
New watcher thread scans Z:/Cora-For-Human for post-macro Cora xlsx files,
matches them to ClickUp tasks by keyword, and copies to the appropriate
pipeline inbox (Z:/cora-inbox for Link Building, Z:/content-cora-inbox for
Content/OPO). Fixes issue where shared Cora reports left one pipeline's
tasks stuck in automation underway forever.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:07:03 -06:00
PeninsulaInd 594245fec3 Pull PR topic from custom field and validate required fields before executing
- Changed Press Release topic source from task_name to "PR Topic" custom field
- Added required_fields config to skill_map so scheduler validates before
  setting task to "automation underway"
- Tasks missing PR Topic, Customer, or IMSURL are silently skipped with
  a notification and re-checked on next poll
- Updated docs and CLAUDE.md with new field mapping

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 16:29:12 -06:00
PeninsulaInd 917445ade4 Steps 7-8: Eliminate KV store from task pipelines and update tests
Remove all KV store reads/writes from task pipeline code. ClickUp is now
the single source of truth for task state. File location (processed/
subfolder) tracks file processing state. Loop timestamps use in-memory
dict on Scheduler.

Source changes:
- scheduler.py: Remove KV dedup, fallback sync path, docx extraction;
  tools own their ClickUp sync; in-memory timestamps
- press_release.py: Remove KV state writes, log-only _set_status
- linkbuilding.py: Remove KV state writes, processed/ subfolder check
- content_creation.py: Phase detection via ClickUp API status, remove
  KV phase/state tracking, _update_kv_state removed
- clickup_tool.py: Rewrite to query ClickUp API directly
- ui.py: Pipeline status polling is now a no-op

Test changes:
- test_scheduler.py: Remove KV dedup tests, remove fallback path test,
  verify ClickUp API calls instead of KV state
- test_content_creation.py: Mock _get_clickup_client for phase detection,
  verify ClickUp sync calls instead of KV assertions
- test_linkbuilding.py: Remove KV status test, verify ClickUp API calls
- test_clickup_tools.py: Rewrite for API-backed tools
- test_scheduler_helpers.py: Test in-memory timestamps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:26:44 -06:00
PeninsulaInd 8c82ccf2de Fixes 4,5: Content watcher sets automation status and moves files to processed/
Fix 4: Content watcher now sets ClickUp task to "automation underway" after
matching, matching the behavior of the link building watcher.

Fix 5: Content watcher now moves .xlsx files to a processed/ subfolder on
success, preventing re-processing on subsequent scans.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:01:57 -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 7d44014d7a Fix 3: Add staleness recovery for stuck automation tasks
Add date_updated field to ClickUpTask dataclass. Add _recover_stale_tasks()
to scheduler that resets tasks stuck in "automation underway" for >2 hours
back to "to do" with an explanatory comment. This prevents tasks from being
permanently stuck if CheddahBot crashes mid-execution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 15:52:04 -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 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 0e3e3bc945 Wire scheduler to API/UI and improve loop control and PR headlines
- Pass scheduler instance to API router and UI for loop timestamps
  and force-run endpoints
- Add interruptible waits and force_heartbeat/force_poll methods
- Record last_run timestamps for all scheduler loops in KV store
- Update press release headline examples with real client headlines

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:18:29 -06:00
PeninsulaInd f8320a9fea Set folder watcher completed tasks to 'complete' instead of 'internal review'
Link building runs that finish successfully are already deployed,
so they go straight to complete. PRs still go to internal review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:20:56 -06:00
PeninsulaInd f9142e6669 Skip Office temp/lock files (~$) in folder watcher
Prevents the watcher from picking up ~$*.xlsx lock files created by
Excel, which would match the same ClickUp task and corrupt its status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:02:06 -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 d9e0020b67 Fix UI errors, message formatting, scheduler auto_execute, and LLM retry
Core fixes:
- Rewrite router.py format_messages_for_llm() to properly handle tool
  call/result message pairs in OpenAI format instead of faking them as
  user messages — root cause of most LLM API errors
- Fix scheduler ignoring auto_execute:false flag, which caused all Link
  Building tasks to be incorrectly executed and moved to internal review
- Add safety check so Skipped/Error tool results don't get marked as
  completed in ClickUp

Additional improvements:
- Add LLM retry logic (2 retries on transient 5xx/timeout/rate-limit)
- Replace raw LLM tracebacks with friendly error messages
- Fix ghost assistant bubble in UI by deferring append to first chunk
- Auto-title conversations from first user message
- Consistent tool_call_id generation (resolve once, reuse everywhere)
- Reduce pipeline status polling from 3s to 10s
- Update CLAUDE.md: remove stale watchdog/autostart docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:34:02 -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 90e79b77ab Add folder watcher thread to scheduler for Cora inbox
- 4th daemon thread _folder_watch_loop scans Z:/cora-inbox
- Fuzzy-matches .xlsx filename stems to ClickUp Keyword fields
- On match: runs run_cora_backlinks, moves file to processed/
- On failure: marks in KV store, notifies via NotificationBus
- Uses existing _get_clickup_client and notification infrastructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:07:24 -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 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 76c0711704 Fix scheduler breaking DB encapsulation for one-time task disabling
Add Database.disable_task() public method and replace direct _conn
access in scheduler._run_due_tasks().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:09:38 -06:00
PeninsulaInd ff3114b515 Add .docx attachment uploads to ClickUp tasks after press release generation
When a press release task completes, docx file paths are extracted from
the tool output and uploaded as attachments to the ClickUp task. The
completion comment now includes an attachment count note.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:04:23 -06:00
PeninsulaInd a67e714045 Add ClickUp polling loop to scheduler
Third daemon thread polls ClickUp every 20 minutes, discovers new tasks,
maps Task Type to skills via config, and auto-executes or queues for
approval. On completion updates ClickUp status + comments with results.
Recovers orphaned executing tasks on startup. Pushes all events through
the NotificationBus for UI-agnostic delivery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:28:35 -06:00
PeninsulaInd 1866d48cb2 Fix chat memory persistence, duplicate tool calls, and heartbeat log noise
- Agent: deduplicate tool calls across iterations, reduce max iterations
  10→5, add system prompt instructions to prevent re-calling tools
- Router: preserve tool name in history messages, add anti-loop and
  delegate_task instructions to system prompt
- Memory: auto_flush now deletes flushed messages from DB so conversations
  don't get re-summarized repeatedly, skip tool results in summaries
- DB: add delete_messages() method, include message id in get_messages()
- Scheduler: stop logging routine heartbeat checks to daily log

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 14:23:33 -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