Skip to content

feat(cli): add LLM-friendly commands for terminal automation#12

Merged
eyelock merged 11 commits into
mainfrom
fix/cli-deadlock-and-llm-commands
Jan 13, 2026
Merged

feat(cli): add LLM-friendly commands for terminal automation#12
eyelock merged 11 commits into
mainfrom
fix/cli-deadlock-and-llm-commands

Conversation

@eyelock
Copy link
Copy Markdown
Owner

@eyelock eyelock commented Jan 11, 2026

⚠️ Early Release: The CLI feature is in early release. APIs and behavior may change.

Summary

Comprehensive CLI improvements for LLM automation and cross-session state tracking.

New Commands

  • pending - Session Start Command - Shows terminals needing attention with queued tasks and staleness
  • context - Outputs comprehensive LLM workflow guide with checklists and examples
  • list - Output all terminals as JSON
  • find - Search terminals by name, column, tag, badge, ID, favourites
  • set - Modify terminal properties (name, description, column, tags, badge, favourite, llm-prompt, llm-next-action)
  • move - Move terminals between columns

Cross-Session State Tracking

Tags for tracking work state across LLM sessions:

  • staleness (fresh/ageing/stale) - How recently worked on
  • status (pending/active/blocked/review) - Work state
  • project (org/repo) - Project identifier
  • worktree (branch-name) - Git branch
  • priority (high/medium/low) - Importance
  • blocked-by (ci/review/user) - Blockers
  • type (feature/bugfix/chore/docs) - Work category

LLM Workflow

  1. Session Start: Run termq pending to see queued tasks
  2. During Work: Use tags to track state
  3. Session End: Set llmNextAction to queue next task, update staleness=fresh

LLM Integration

  • Token-based Init Command system ({{LLM_PROMPT}}, {{LLM_NEXT_ACTION}})
  • llmPrompt: Persistent context field (never auto-cleared)
  • llmNextAction: One-time task field (auto-cleared after terminal opens)
  • termq --help directs LLM agents to run termq pending then termq context

Documentation

  • "For LLM Assistants" quick start section
  • Cross-Session State Tracking guide with tag schema
  • Pending command output format examples
  • Complete workflow examples
  • Getting Help section with --help examples

Code Quality

  • 46 tests pass
  • URL handlers for termq://update, termq://move, termq://focus

Test plan

  • All 46 tests pass
  • Build succeeds
  • CI passes
  • Manual testing:
    • termq pending shows terminals with pending actions
    • termq context outputs comprehensive LLM guide
    • termq set <id> --tag staleness=fresh updates tags
    • Cross-session workflow maintains state

🤖 Generated with Claude Code

@eyelock eyelock force-pushed the fix/cli-deadlock-and-llm-commands branch 2 times, most recently from a235977 to 049d37b Compare January 12, 2026 20:36
@eyelock eyelock changed the title fix(cli): resolve deadlock and add LLM-friendly commands feat(cli): add LLM-friendly commands for terminal automation Jan 12, 2026
@eyelock eyelock force-pushed the fix/cli-deadlock-and-llm-commands branch 5 times, most recently from 78dbce5 to 086f881 Compare January 12, 2026 23:41
David Collie and others added 11 commits January 13, 2026 08:05
Fix the CLI hanging issue caused by using DispatchSemaphore with
NSWorkspace.openApplication async callback. Replace with Process
calling /usr/bin/open for reliable app launching.

Add new CLI commands for LLM automation:
- `list`: Output all terminals as JSON with --debug, --column options
- `find`: Search terminals by name, column, tag, badge, ID, favourites
- `set`: Modify terminal properties via URL scheme
- `move`: Move terminals between columns via URL scheme

Add URL handlers in TermQApp for termq://update and termq://move
actions to support the set and move CLI commands.

Expose llmPrompt field in JSON output and add --llm-prompt option
to the set command for storing LLM context per terminal.

Update CLI documentation with comprehensive examples.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add sections to make CLI documentation clearer for both human users
and AI assistants:

- Quick Start section with common commands
- Understanding the Board section explaining Kanban model
- Using the LLM Prompt Field with practical examples
- Automation & Scripting section with jq examples
- Tips for AI Assistants section with workflow guidance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add a new llmNextAction field to TerminalCard that enables session
handoff workflows:

- llmPrompt: persistent context (always available, never auto-cleared)
- llmNextAction: one-time action that runs as `claude "{prompt}"` on
  terminal open, then automatically clears

Changes:
- TerminalCard: add llmNextAction field with serialization
- CardEditorView: add UI section for both LLM fields
- TerminalSessionManager: inject llmNextAction into terminal on open,
  clear after execution, adjust init command delay if both are set

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
URL Handler additions:
- Add termq://focus?id=UUID handler to select/focus existing terminals
- Add llmNextAction parameter to termq://update handler

Debug menu (DEBUG builds only):
- Copy from Production Config: copies board.json with confirmation
- Open Debug Data Folder: opens TermQ-Debug folder in Finder
- Open Production Data Folder: opens TermQ folder in Finder

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Semantic improvements:
- `termq open <identifier>`: now focuses existing terminal (by name,
  UUID, or path) and returns its details as JSON
- `termq create [options]`: new command for creating terminals (moved
  from old open behavior)

LLM field support in `termq set`:
- --llm-prompt: set persistent context
- --llm-next-action: set one-time action for next open

Other improvements:
- Add launchTermQ() helper to reduce code duplication
- CLICard and TerminalOutput include both LLM fields
- Better error messages for terminal not found

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Major documentation improvements:
- Add Quick Start section with common commands
- Add Understanding the Board section explaining Kanban concepts
- Update Installation to use Settings UI (not build commands)
- Document open vs create command semantics
- Add LLM Integration section explaining both fields:
  - Persistent Context (llmPrompt)
  - Next Action (llmNextAction) with auto-run behavior
- Add Tips for AI Assistants section with workflow examples
- Add Automation & Scripting section with jq examples
- Include install-cli.png screenshot

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…mand

Replace hardcoded `claude "{prompt}"` injection with flexible token
placeholders in Init Command:

- {{LLM_PROMPT}} - replaced with persistent context
- {{LLM_NEXT_ACTION}} - replaced with one-time action (then cleared)

This vendor-agnostic approach supports any LLM CLI tool:
- Claude Code: `claude "{{LLM_PROMPT}} {{LLM_NEXT_ACTION}}"`
- Aider: `aider --message "{{LLM_NEXT_ACTION}}"`
- GitHub Copilot: `gh copilot suggest "{{LLM_NEXT_ACTION}}"`
- Custom scripts: `my-llm.sh --context "{{LLM_PROMPT}}"`

The llmNextAction field is still cleared after use, but only if the
{{LLM_NEXT_ACTION}} token was present in the Init Command.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add 6 new tests for the llmNextAction field:
- testLlmNextActionDefaultsToEmpty
- testLlmNextActionCustomValue
- testLlmNextActionCodableRoundTrip
- testLlmNextActionDefaultsToEmptyWhenMissingInJSON
- testLlmNextActionObservable
- testBothLlmFieldsCoexist

Total test count: 46 (was 40)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 'termq context' command that outputs LLM-friendly documentation
- Add discussion to main help output directing LLMs to run 'termq context'
- Document example output for 'termq open' command
- Add error codes section to documentation
- Add note clarifying Init Command is UI-configured

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Document termq context command for LLM discovery
- Add Getting Help section showing --help usage
- Include example output from termq --help

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add `termq pending` command for LLM session start
  - Shows terminals with llmNextAction queued
  - Shows staleness indicators based on tags
  - Includes summary with counts
  - Sorted by pending actions first, then staleness

- Enhance `termq context` with prescriptive workflow
  - Session Start/End Checklists
  - Tag Schema for state tracking
  - Cross-session workflow examples

- Update documentation
  - Add "For LLM Assistants" quick start section
  - Document pending command with output format
  - Add Cross-Session State Tracking section
  - Document recommended tag schema

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@eyelock eyelock force-pushed the fix/cli-deadlock-and-llm-commands branch from 086f881 to f7dbef8 Compare January 13, 2026 08:05
@eyelock eyelock merged commit 6b9d06c into main Jan 13, 2026
5 checks passed
@eyelock eyelock deleted the fix/cli-deadlock-and-llm-commands branch January 13, 2026 08:09
eyelock pushed a commit that referenced this pull request Jan 15, 2026
Audit findings:
- No actual memory leaks found in codebase
- All closures properly use [weak self] where needed
- Event monitors have cleanup in onDisappear
- Timers and dispatch sources cleaned up in deinit
- Callback-based coordination avoids retain cycles

Documentation added:
- Closure capture rules for classes vs structs
- Event monitor cleanup pattern
- Timer/dispatch source cleanup
- Callback-based coordination guidance
- Checklist item for memory management

Addresses forensic review Issue #12.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
eyelock added a commit that referenced this pull request Jan 15, 2026
* refactor(shared): Extract shared models and generic installer (#phase1)

- Create TermQShared target with Sendable domain models (Tag, Column, Card, Board)
- Add shared OutputTypes (TerminalOutput, ColumnOutput, PendingOutput, ErrorOutput)
- Add shared BoardLoader for consistent board loading/writing across CLI and MCP
- Extract generic ComponentInstaller protocol to eliminate CLI/MCP installer duplication
- Migrate termq-cli to use TermQShared (remove ~200 lines of duplicate models)
- Migrate MCPServerLib to use TermQShared with type aliases for compatibility
- Add TermQSharedTests for shared model coverage

Net reduction: ~1000 lines of duplicated code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(viewmodel): Extract TabManager and BoardPersistence (#phase2)

Split BoardViewModel from 768 to 441 lines by extracting:

- TabManager: Session tab state, navigation, attention indicators, transient cards
- BoardPersistence: Save/load operations, file monitoring for external changes
- FileMonitor: Helper class for dispatch source-based file monitoring

BoardViewModel now coordinates these managers while maintaining backwards
compatible API through proxy properties and methods.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Extract TerminalThemeManager from TerminalSessionManager

Phase 3 of tech debt cleanup - split the TerminalSessionManager god object
by extracting theme management into a dedicated TerminalThemeManager class.

Changes:
- Create TerminalThemeManager for theme state and application logic
- TerminalSessionManager now delegates theme operations to themeManager
- Proxy properties maintain API compatibility (themeId, currentTheme)
- Theme callback mechanism for applying changes to all sessions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Add resource and prompt handler tests, coverage target

Improve test coverage from 66% to 78%:
- Add testResource* tests for all MCP resource handlers (terminals, columns, pending, context)
- Add testPrompt* tests for all MCP prompt handlers (session_start, workflow_guide, terminal_summary)
- Add test.coverage Makefile target for easy coverage reporting

Coverage improvements:
- ResourceHandlers.swift: 0% → 95%
- PromptHandlers.swift: 0% → 94%

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Add code style guide from tech debt cleanup

Create .claude/commands/code-style.md capturing patterns learned:
- Swift 6 Sendable conformance patterns
- Actor-isolated class with dispatch source helpers
- God object decomposition strategy
- Init order with callback configure() pattern
- Generic type extraction for code deduplication
- Observable vs Sendable model separation
- MCP testing patterns with type extraction helpers
- Refactoring checklist for future upgrades

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Extract reusable components from large view files

- Extract MCPStatusView from ContentView (23 lines)
- Extract SafePasteAnalyzer from TerminalHostView (63 lines)
- Extract LLMVendor enum from CardEditorView (54 lines)

Addresses Issue #6 from forensic code review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor: Add Constants file to consolidate magic values

- Create Constants.swift with Shell, Terminal, Columns, ColorPalette,
  LLMTokens, and Activity configuration constants
- Update TerminalSessionManager to use Terminal and Activity constants
- Update ColumnEditorView to use ColorPalette constants
- Update ContentView to use Columns.fallbackName constant

Addresses Issue #7 from forensic code review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Add error handling guidelines to code style guide

- Define context-specific patterns for CLI, MCP, ViewModels, and file ops
- Document when to use try?, throw, or return isError
- Add typed error definition examples
- List errors that should never be silently ignored
- Update refactoring checklist with error handling items

Addresses Issue #9 from forensic code review.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(mcp): Add type-safe JSON Schema builder DSL

- Create SchemaBuilder enum with type-safe property definitions
- Add convenience methods: string(), bool(), int() for common types
- Refactor SchemaDefinitions to use builder pattern
- Replace verbose nested dictionary literals with clean DSL syntax

Example:
  inputSchema: S.objectSchema([
      S.string("identifier", "Terminal name or UUID", required: true),
      S.string("column", "Target column name", required: true),
  ])

Addresses forensic review Issue #10.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* refactor(mcp): Add centralized input validation layer

- Create InputValidator enum with type-safe parameter extraction
- Add validation methods: requireString, requireNonEmptyString, requireUUID
- Add optional extractors: optionalString, optionalBool, optionalUUID, optionalPath
- Define ValidationError enum with descriptive error messages
- Refactor all MCP tool handlers to use centralized validation
- Consistent error handling: return isError:true instead of throwing

Benefits:
- Type-safe parameter extraction reduces runtime errors
- Consistent error messages improve LLM experience
- Path validation with tilde expansion
- UUID format validation with clear error messages

Addresses forensic review Issue #11.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* docs: Add memory management patterns to code style guide

Audit findings:
- No actual memory leaks found in codebase
- All closures properly use [weak self] where needed
- Event monitors have cleanup in onDisappear
- Timers and dispatch sources cleaned up in deinit
- Callback-based coordination avoids retain cycles

Documentation added:
- Closure capture rules for classes vs structs
- Event monitor cleanup pattern
- Timer/dispatch source cleanup
- Callback-based coordination guidance
- Checklist item for memory management

Addresses forensic review Issue #12.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: Improve test coverage for shared models and validation

- Add comprehensive InputValidator tests (93% line coverage)
- Add TermQError error description tests (100% coverage)
- Add ColumnOutput, PendingOutput, PendingSummary tests
- Add SetResponse and MoveResponse tests
- Fix test assertions for order-independent badge comparisons
- Fix path validation tests for trailing slash normalization

Total coverage improved from ~75% to ~80% lines.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: Add missing build artifacts to gitignore

Add termqcli and TermQ_TermQ.bundle to gitignore - these are
generated during the build process and shouldn't be tracked.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: Add @mainactor to showWarningDialog for Swift 6 concurrency

NSAlert requires main actor isolation in Xcode 16.4+ with stricter
Swift concurrency checking. Add @mainactor annotation to satisfy
the compiler's concurrency requirements.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: David Collie <support@eyelock.net>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant