Commit Graph

346 Commits

Author SHA1 Message Date
Lucas Berger 1a8749cceb test(06): complete UAT - 4 passed, 0 issues
Verified all n8n API capabilities:
- Authentication with X-N8N-API-KEY header
- Read workflow JSON (96 nodes)
- Update workflow via PUT
- View execution history

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:55:31 -05:00
Lucas Berger fef21fd39a fix(07): revise plans based on checker feedback
- Plan 02: Added Task 4 (checkpoint:human-action) to remove docker.sock
  volume mount from n8n container after verifying proxy works
- Plan 02: Added must_have truth for docker.sock removal (SEC-02 complete)
- Plan 03: Removed "Create API returns 403" from must_haves - container
  create is intentionally ALLOWED for update command functionality
- Plan 03: Added rationale explaining why container create is needed
- Clarified that blocked APIs are: exec, build, commit (not create)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:48:37 -05:00
Lucas Berger f539bcbba4 docs(07): create phase plan for Socket Security
Phase 07: Socket Security
- 3 plan(s) in 2 wave(s)
- Wave 1: 07-01 (deploy proxy - checkpoint)
- Wave 2: 07-02 (migrate workflow), 07-03 (verify blocking) - parallel
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:45:04 -05:00
Lucas Berger 1432d4feb2 docs(07): research phase domain
Phase 07: socket-security
- Standard stack identified
- Architecture patterns documented
- Pitfalls catalogued

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:40:04 -05:00
Lucas Berger e17c5bf0d4 docs(07): capture phase context
Phase 07: Socket Security
- Implementation decisions documented
- Phase boundary established
2026-02-03 08:33:57 -05:00
Lucas Berger 5aa07e8dfa docs(phase-6): complete n8n API Access phase
- All 4 API requirements verified (API-01 through API-04)
- Phase goal achieved: Claude Code can programmatically read, update, and test workflows
- Verification passed: 4/4 must-haves confirmed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:21:34 -05:00
Lucas Berger 45e0cd9a0f docs(06-01): complete n8n API access plan
Tasks completed: 2/2
- Task 1: Create n8n API Key (checkpoint:human-action - user provided credentials)
- Task 2: Verify API Access and Document Commands

All 4 API requirements verified:
- API-01: Authentication (200 OK)
- API-02: Read workflow (96 nodes)
- API-03: Update workflow (PUT successful)
- API-04: Execution history (5 recent runs)

SUMMARY: .planning/phases/06-n8n-api-access/06-01-SUMMARY.md
2026-02-03 08:17:22 -05:00
Lucas Berger 7e85697899 feat(06-01): verify n8n API access and configure credentials
All 4 API requirements verified successfully:
- API-01: Authentication works (200 response from /api/v1/workflows)
- API-02: Can read workflow (Docker Manager Bot - 96 nodes)
- API-03: Can update workflow (PUT successful, updatedAt: 2026-02-03T13:15:35.015Z)
- API-04: Can view execution history (5 recent executions retrieved)

Created .env.n8n-api with N8N_HOST and N8N_API_KEY (gitignored)
Created .gitignore to protect API credentials

Workflow ID: HmiXBlJefBRPMS0m4iNYc
n8n Instance: https://api.bergerhouse.net
2026-02-03 08:16:05 -05:00
Lucas Berger c15c5e3892 docs(06): create phase plan for n8n API access
Phase 6: n8n API Access
- 1 plan in 1 wave
- Covers API-01 through API-04 requirements
- Human checkpoint for API key creation + automated verification
- Fixed: Use PUT (not PATCH) per current n8n docs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:10:13 -05:00
Lucas Berger 3d5c8392d7 docs(06): create phase plan
Phase 06: n8n API Access
- 1 plan in 1 wave
- 0 parallel (sequential due to human checkpoint)
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:07:41 -05:00
Lucas Berger bc26a7bc88 docs(phase-6): research n8n API access
Phase 6: n8n API Access
- n8n REST API capabilities identified
- Authentication patterns documented (X-N8N-API-KEY header)
- Workflow CRUD operations researched
- Execution history access patterns found
- Common pitfalls catalogued (activation timeout, public vs private endpoints)
- No official SDK exists - raw HTTP client required

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 08:04:36 -05:00
Lucas Berger c6abf62021 docs: create v1.1 roadmap (5 phases)
Phases:
6. n8n API Access: Claude Code workflow management
7. Socket Security: Docker socket proxy migration
8. Inline Keyboard Infrastructure: Telegram buttons
9. Batch Operations: Multi-container updates
10. Polish & Audit: Unraid sync, env var verification

22 requirements mapped across 5 phases.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:20:01 -05:00
Lucas Berger a970f8d6fc docs: define v1.1 requirements + research
22 requirements across 6 categories:
- Security: Socket proxy migration (4)
- n8n API: Claude Code workflow access (4)
- Telegram Keyboards: Inline buttons + confirmations (5)
- Batch Operations: Multi-container updates (6)
- Unraid Sync: Clear update badge (1)
- Environment Audit: Verify container vars (2)

Research: Stack, Features, Architecture, Pitfalls

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:16:45 -05:00
Lucas Berger 811030cee4 docs: complete v1.1 research (4 researchers + synthesis)
Files:
- STACK.md: Socket proxy, n8n API, Telegram keyboards
- FEATURES.md: Table stakes, differentiators, MVP scope
- ARCHITECTURE.md: Integration points, data flow changes
- PITFALLS.md: Top 5 risks with prevention strategies
- SUMMARY.md: Executive summary, build order, confidence

Key findings:
- Stack: LinuxServer socket-proxy, HTTP Request nodes for keyboards
- Architecture: TCP curl migration (~15 nodes), new callback routes
- Critical pitfall: Socket proxy breaks existing curl commands

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:09:06 -05:00
Lucas Berger ff289677ab docs: start milestone v1.1 n8n Integration & Polish
Target features:
- n8n API for Claude Code (programmatic workflow access)
- Telegram inline keyboard buttons
- Batch container updates
- Docker socket security
- Environment variable audit
- Unraid update sync

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 22:01:37 -05:00
Lucas Berger 9b0e5fd8a5 chore: archive v1.0 milestone
Archived:
- milestones/v1.0-ROADMAP.md (full phase details)

Updated:
- MILESTONES.md (new entry for v1.0)
- PROJECT.md (requirements → Validated, Current State added)
- ROADMAP.md (collapsed to one-line with archive link)
- STATE.md (reset for next milestone)

v1.0 Docker Control via Telegram shipped:
- 5 phases, 12 plans, 5 days
- Telegram bot with keyword commands
- Docker socket integration via n8n

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:50:39 -05:00
Lucas Berger e5c02f9a21 docs: complete v1.0 milestone - Phase 5 Plan 3 approved
- Add 05-03-SUMMARY.md documenting testing session and bug fixes
- Update STATE.md to 100% complete
- Update ROADMAP.md marking all Phase 5 plans complete
- Remove .continue-here checkpoint

v1.0 Docker Manager Bot is production-ready:
- All 6 commands working (status, start, stop, restart, update, logs)
- Keyword routing (no Claude API dependency)
- Single-user Telegram auth
- Terse error messages
- Complete deployment README

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:48:22 -05:00
Lucas Berger c979a7fe7b feat(update): notify user when container is already up to date
Previously the "no update needed" branch was empty, leaving users
with no feedback after the update check completed.

Added Format No Update and Send No Update nodes to display
"<container> is already up to date" message.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:39:08 -05:00
Lucas Berger 808d1afe21 fix(logs): correct property name for line count parameter
Parse Logs Command returned 'lineCount' but Match Logs Container
expected 'lines', causing the line count to always be undefined
and Docker to return its default.

Renamed to 'lines' for consistency throughout the logs flow.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:33:39 -05:00
Lucas Berger 287c7220cb fix(logs): escape HTML entities in log output
Log content may contain <, >, & characters (like "<computed>") which
Telegram interprets as HTML tags when using parse_mode=HTML.

Added escapeHtml() function to convert:
- & → &amp;
- < → &lt;
- > → &gt;

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:31:22 -05:00
Lucas Berger 74dd8f1a94 fix(update): ensure image tag is specified to prevent pulling all tags
When Config.Image has no tag (e.g., "nitnelave/lldap" instead of
"nitnelave/lldap:latest"), Docker's API pulls ALL tags for that image.
This caused massive downloads and rate limit hits.

Now appends ":latest" if no tag or digest is present in the image name.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:21:57 -05:00
Lucas Berger 3e3b9ae47f fix(update): pipe pull output through tail to prevent memory exhaustion
Docker's /images/create API streams progress JSON for every layer.
For large images, this can be gigabytes of output that was being
buffered by curl and n8n, causing hangs and disk usage spikes.

Now pipes through `tail -c 10000` to only keep the last 10KB where
error/success messages appear. Discards the streaming progress data.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:14:25 -05:00
Lucas Berger 88830a8b61 fix(update): correct image removal node data reference
- Reference $('Format Update Result') instead of $json for currentImageId
- The Telegram node doesn't pass through input data, it returns API response
- Also add no-op command fallback when currentImageId is missing

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 20:56:00 -05:00
Lucas Berger 4f85e00dc4 fix(update): add timeout to prevent pull command from hanging
- Add --max-time 600 (10 min) to curl pull command
- Add timeout: 660 to n8n executeCommand node

Docker's /images/create API streams progress until complete.
Without timeout, large image pulls could hang indefinitely.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 20:50:22 -05:00
Lucas Berger b0b22c3b39 wip: 05-polish-deploy paused at task 2/2 (testing checkpoint)
Testing session found and fixed multiple issues:
- Show Menu keyboard/HTML issues
- Container exact match priority
- Update acknowledgment and error handling
- Old image removal after update

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:08:43 -05:00
Lucas Berger d03e79cc7f feat(05): add update acknowledgment and pull error handling
1. Send "Updating <container>..." message immediately when update starts
   so user knows the command was received during long image pulls

2. Check pull response for rate limiting and other errors before
   continuing with update. Errors like "toomanyrequests" now show
   a proper error message instead of silently failing to update.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 22:07:40 -05:00
Lucas Berger 0839c44b50 feat(05): remove old image after successful container update
Mimics Unraid's update behavior by removing the orphan image after
the new container is started. The old image ID is now passed through
the entire update flow and used to call DELETE /images/{id} at the end.

Removal is fire-and-forget with force=false so it will fail gracefully
if another container still uses the image.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:58:41 -05:00
Lucas Berger 004911ea32 fix(05): improve container matching to prioritize exact matches
Fixed matching in Match Container, Match Update Container, and Match
Logs Container nodes:
1. First check for exact name match (e.g., "jellyplex" matches only jellyplex)
2. Then fall back to substring matching (container name contains query)
3. Removed reverse matching (query contains container name) which caused
   "jellyplex" to incorrectly match "plex"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:41:27 -05:00
Lucas Berger 0b6dfe69d9 fix(05-01): escape angle brackets in Show Menu text
Changed <name> to [name] to avoid HTML parse errors in Telegram.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:36:23 -05:00
Lucas Berger 0b140c4f1e fix(05-01): simplify Show Menu to text-only help message
Native Telegram node replyKeyboard wasn't displaying. Fallback to
simple text message listing available commands. Can revisit persistent
keyboard feature later.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:34:45 -05:00
Lucas Berger 6defb2daaf fix(05-01): switch Show Menu to native Telegram node
HTTP Request node with $credentials reference was causing 404 errors.
Native Telegram node handles credentials more reliably for static menus.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:31:16 -05:00
Lucas Berger 32fd965a2f fix(05-02): revert credential reference to hardcoded user ID
n8n IF nodes don't support credentials - $credentials syntax only works
in nodes that make external calls. Reverted to direct user ID in the
IF conditions and updated README with simpler configuration instructions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:28:20 -05:00
Lucas Berger e92bfc8061 docs(05-03): write deployment README
- Step-by-step installation guide for Unraid
- n8n container configuration with Docker socket access
- Credential creation instructions for Telegram API and Auth
- Usage section with all 6 commands documented
- No troubleshooting section (focused on initial setup)
2026-01-31 21:18:27 -05:00
Lucas Berger 09a4c9ba07 docs(05-02): complete error hardening and credential migration plan
Tasks completed: 2/2
- Standardize error messages to terse format
- Migrate user ID to n8n credentials system

SUMMARY: .planning/phases/05-polish-deploy/05-02-SUMMARY.md
2026-01-31 21:16:36 -05:00
Lucas Berger 1e6c31f790 feat(05-02): migrate user ID to n8n credentials system
- Auth nodes now reference $credentials.telegramAuth.userId
- Added telegramAuth credential reference to both IF nodes
- Removed hardcoded user ID from workflow JSON
- Workflow can now be safely exported/shared
2026-01-31 21:15:20 -05:00
Lucas Berger cab0914788 chore(05-02): standardize error messages to terse format
- Docker socket errors now show 'Cannot connect to Docker'
- Action failures now show 'Failed to {action} {container}'
- Removed HTTP status codes and technical details from error messages
- Simplified callback action error handling
2026-01-31 21:14:36 -05:00
Lucas Berger 9ae500cdf5 docs(05-01): complete NLU cleanup plan
Tasks completed: 2/2
- Task 1: Remove NLU/Claude nodes and add Keyword Router
- Task 2: Add persistent Telegram menu

SUMMARY: .planning/phases/05-polish-deploy/05-01-SUMMARY.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:11:01 -05:00
Lucas Berger a29f444e08 feat(05-01): replace NLU/Claude with keyword routing
- Remove Prepare Claude Request, Claude Intent Parser, Parse Intent,
  Intent Router, Send Unknown Intent, Send Intent Error nodes
- Remove Anthropic API credential reference
- Rename Route Message to Keyword Router with updated rules
- Update IF User Authenticated to connect to Keyword Router
- Update Parse and Match to work without NLU context
- Update Parse Action Command to parse from message text directly
- Update Match Container to reference Parse Action Command
- Update Parse Logs Command to work with keyword routing

Keyword Router handles: /start, status, restart, start, stop,
update, logs with fallback to menu

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:09:33 -05:00
Lucas Berger b7cefd931e docs(05): create phase plan
Phase 05: Polish & Deploy
- 3 plans in 3 waves
- 1 parallel (Wave 1), 2 sequential (Waves 2-3)
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:00:51 -05:00
Lucas Berger 4c09d61943 docs(05): research phase domain
Phase 5: Polish & Deploy
- Standard stack identified (n8n, Telegram Bot API, Docker)
- Architecture patterns documented (Switch routing, persistent keyboards, error workflows)
- Pitfalls catalogued (credential leaks, testing limitations, configuration issues)
- Code examples for keyword routing, persistent menus, error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:55:29 -05:00
Lucas Berger fc1eda2b07 docs(05): capture phase context
Phase 05: Polish & Deploy
- Implementation decisions documented
- Phase boundary established

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:49:04 -05:00
Lucas Berger b82ce152bb docs: add NLU workflow cleanup to Phase 5
Workflow currently has Claude API nodes that need removal.
Added to Phase 5 scope along with keyword routing replacement.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:54:25 -05:00
Lucas Berger 21e888c1ce docs: remove NLU from v1.0 scope
- Remove Claude API integration and intent parsing (04-02-PLAN)
- REQ-08 (conversational queries) moved to out of scope
- Phase 4 renamed from "Logs & Intelligence" to "Logs" (complete)
- v1.0 now focuses on keyword-based container control

Simple substring matching works well for container management.
NLU adds complexity without proportional value for v1.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 14:52:37 -05:00
Lucas Berger 9ae67ccd7b wip: phase 4 paused at checkpoint verification
Multiple workflow bugs fixed during testing. Awaiting user
verification of conversational routing via Telegram.
2026-01-30 22:38:18 -05:00
Lucas Berger 5e7cab54ca fix(batch): convert Send Batch Confirmation to native Telegram node
HTTP Request node with credential access via URL expression was
failing. Native Telegram node handles credentials internally and
is more reliable for this use case.
2026-01-30 22:37:09 -05:00
Lucas Berger 23ce6a88d5 fix(batch): add chatId validation in Build Batch Keyboard
Add defensive error handling to throw clear error if chatId is
missing before attempting to send Telegram message. This helps
debug 'resource not found' errors by identifying data flow issues.
2026-01-30 22:36:44 -05:00
Lucas Berger 5d55bdecac fix(04): fix type validation in all Switch nodes with number comparisons
Fixed Check Match Count and Check Update Match Count nodes:
- Changed typeValidation from 'strict' to 'loose'
- Changed rightValue from strings ('0', '1') to numbers (0, 1)
- Removed empty leftValue from options

This fixes 'Wrong type: string but expecting number' errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:26:08 -05:00
Lucas Berger aa677703c9 fix(04): update Match Container to use Parse Intent
Changed Match Container to get action data from Parse Intent node
instead of the old Parse Action node which isn't executed in the
intent-based routing flow.

Mapping:
- action -> intent.parameters.action
- containerQuery -> intent.container
- chatId -> intent.original_message.chat.id

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:21:37 -05:00
Lucas Berger d842efbf17 fix(04): bypass Format Response for intent-based status queries
Parse and Match now returns formatted text directly, so Format Response
node is redundant. Connect Parse and Match directly to Send Docker Response
to avoid 'Unexpected response format' error.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:18:44 -05:00
Lucas Berger ada8800bff fix(04): fix Check Logs Match Count type validation
Changed typeValidation from 'strict' to 'loose' and rightValue from
strings to numbers to fix type mismatch error in Switch node conditions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:13:56 -05:00