Commit Graph

5 Commits

Author SHA1 Message Date
Harsh Batheja 4e2144d99e
feat: OpenCode session lifecycle and CLI controls (#315)
* feat: refine OpenCode session reuse strategy and cleanup

* fix: harden OpenCode session selection and lint errors

* refactor: centralize OpenCode reuse resolution flow

* fix: return 404 for missing session in message route

* feat: replace force remap with terminal reload control

* fix: protect project path from session kill cleanup

* fix: preserve fullscreen alignment without reload action

* fix: harden OpenCode session id handling and title reuse selection

* fix: show OpenCode reload control and remap before restart

* fix: preserve title-only OpenCode reuse with fallback mapping persistence

* fix: resolve remaining PR315 Bugbot findings

* fix: keep OpenCode discovery title-based without timestamp sorting

* fix: avoid enrichment race fallout in session listing

* fix: guard OpenCode discovery parse with array check

* fix: stabilize Linear comment integration check

* fix: harden OpenCode discovery and prompt option flow

* ux: clarify OpenCode terminal restart action

* fix: remap OpenCode session fresh on each restart

* fix: validate remap session ids before reuse

* fix: clean archived metadata only after purge

* docs: align OpenCode remap selection with title-based behavior

* fix: harden opencode cleanup and ignore local sisyphus state

* test: add timeout cleanup coverage for session enrichment

* fix: harden Linear integration helper against transient non-JSON errors

* fix: make linear integration assertions resilient to eventual consistency

* fix: remove unused fs import after rebase

* fix: address remaining Bugbot blockers for opencode session handling

* fix: avoid stale metadata overwrite during restore post-launch

* fix: forward subagent in orchestrator flows and defer reuse lookup

* fix: apply configured subagent fallback for session spawn

* fix: scope archived cleanup by project and delay archive restore write

* fix: normalize orchestrator strategy aliases in start display logic

* fix: centralize orchestrator strategy normalization in core

* fix: derive orchestrator reuse display from spawn result

* fix: keep cleanup results consistent across project-id collisions

* fix: namespace cleanup results when session IDs collide

* fix: harden GitHub issue stateReason fallback

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: avoid false failing CI state mapping

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: add tmux command timeouts

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: bound session API enrichment latency

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: repair scm-github merge resolution

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: repair lifecycle-manager test merge

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: delay archive metadata recreation until restore passes

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* test: restore claim-pr session mocks

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: address review findings for OpenCode lifecycle PR

- Fix stripControlChars to preserve newlines for reload commands
- Add SessionNotFoundError and use instanceof checks in API routes
- Document orchestratorSessionStrategy in YAML example
- Validate existingSessionId with asValidOpenCodeSessionId()
- Extract inline Node script to buildSessionLookupScript helper
- Create OpenCodeSessionManager interface for remap capability
- Create OpenCodeAgentConfig type for agent-specific config
- Change default orchestratorSessionStrategy from delete to reuse

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

* fix: guard reused session display without metadata

* chore: add agent config files to .gitignore

Agent configuration files (CLAUDE.md, AGENTS.md, IMPROVEMENTS.md, etc.) are personal and project-specific. They should not be committed to the repository.

Changes:
- Remove CLAUDE.md from git tracking
- Add agent config files to .gitignore
- Create .gitignore-template for reference

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

* chore: update gitignore for agent config folder structure

Reorganized agent configuration files:
- CLAUDE.md and AGENTS.md stay in root (agents read them there)
- Tracking files move to .opencode/ (IMPROVEMENTS.md, etc.)
- Optional Claude files in .claude/

Updated .gitignore to ignore folders instead of individual files.

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

* fix: tighten opencode remap and session discovery safeguards

* fix: address Bugbot findings in session manager

* fix: scope opencode discovery to opencode sessions

* fix: restore concurrent listing and strict permission literals

* fix: throw SessionNotFoundError, parallelize list enrichment, fix permissions type

- Session manager now throws SessionNotFoundError instead of plain Error
  for missing sessions, so web API routes correctly return 404 (not 500)
- Parallelize session enrichment in list() — was sequential, causing O(N)
  latency for N sessions with subprocess enrichment
- Fix AgentLaunchConfig.permissions type to accept legacy "skip" value
  (AgentPermissionInput instead of AgentPermissionMode)
- Add happy-path and validation tests for /api/sessions/:id/message route
- Update all test mocks to use SessionNotFoundError

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

* fix: route ao send through session manager

* feat: add purge option to orchestrator stop

* fix: register opencode agent in web services

* test: align web API missing-session coverage

* fix: match notifier config by plugin name

* refactor: dedupe session lookup and tmux buffer send flow

* test: update send lifecycle wait expectation

* fix: harden send routing and cleanup purge controls

---------

Co-authored-by: Harsh <harsh@Ubuntu-24-Forrest.lan>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Prateek <karnalprateek@gmail.com>
2026-03-08 09:55:44 +05:30
prateek ef40c529f8
fix: handle permissions=skip correctly in codex plugin (#337)
* fix: handle permissions=skip correctly in codex plugin

* refactor: rename permission mode to permissionless and align agent mappings

---------

Co-authored-by: Jayesh Sharma <wjayesh@outlook.com>
2026-03-07 20:27:01 +05:30
prateek 520010d5a2
feat: configurable terminal server ports for multi-dashboard support (#113)
* feat: make terminal server ports configurable to fix multi-dashboard EADDRINUSE

When multiple ao dashboards run simultaneously (e.g., ao on port 3000,
integrator on port 3002), both try to start terminal WebSocket servers
on hardcoded ports 3001/3003, causing EADDRINUSE. Add terminalPort and
directTerminalPort to config schema so each instance can use unique ports.

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

* fix: use optional() instead of default() for terminal port schema

Zod .default() always fills in the value, making config.terminalPort
never undefined and the env var fallback in buildDashboardEnv dead code.
Switch to .optional() so the priority chain works correctly:
config value > TERMINAL_PORT env var > hardcoded default.

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

* fix: move terminal server defaults from 3001/3003 to 14800/14801

The 3000-3009 range is the most contested in dev tooling (Next.js
auto-increments, BrowserSync, Grafana, Rails, Express all default to
3000+). Port 14800-14899 has zero IANA registrations, zero known dev
tool conflicts, and is safely below OS ephemeral ranges.

Updated all hardcoded fallbacks, .env.local.example, docker-compose
port mappings, and documentation.

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

* feat: auto-detect available terminal ports for zero-config multi-dashboard

When no terminal ports are configured (no config, no env vars),
buildDashboardEnv now probes for an available port pair starting at
14800. The second `ao start` automatically gets 14802/14803 (or the
next free pair), eliminating EADDRINUSE without any user configuration.

Port detection scans in steps of 2 to keep the pair consecutive.
Explicit config/env values bypass auto-detection entirely.

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

* fix: update onboarding test to use new default terminal port (14801)

The onboarding integration test had port 3003 hardcoded for the
WebSocket health check. Updated to read from DIRECT_TERMINAL_PORT
env var with 14801 as the default, matching the new port defaults.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 04:00:19 +05:30
prateek 90111da18d
feat: layered prompt system for agent sessions (#27)
* feat: implement layered prompt system for agent sessions

Replace hardcoded spawn prompts with a 3-layer composition system:
- Layer 1: BASE_AGENT_PROMPT constant with session lifecycle, git workflow, PR handling
- Layer 2: Config-derived context (project, repo, tracker, issue details via generatePrompt())
- Layer 3: User-customizable rules via agentRules (inline) and agentRulesFile (path)

The session-manager path fetches issue context from the tracker plugin and passes
the composed prompt via AgentLaunchConfig.prompt. The CLI spawn path delivers it
via tmux send-keys to keep agents interactive for follow-up messages.

Returns null when nothing to compose (no issue, no rules), preserving backward
compatibility for bare launches.

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

* fix: use tmuxSendKeys for multi-line prompt delivery in CLI spawn

The buildPrompt() output contains newlines which tmux send-keys -l treats
as Enter keypresses, splitting the prompt into separate submissions. Use
the core tmuxSendKeys() helper which handles multi-line text via
load-buffer/paste-buffer.

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

* fix: update spawn test to verify tmuxSendKeys usage

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 20:07:13 +05:30
Prateek 5058c409d5 feat: scaffold TypeScript monorepo with all plugin interfaces
Phase 0 complete. Establishes:
- pnpm workspace with 18 packages (core, cli, web, 15 plugins)
- Complete type definitions in packages/core/src/types.ts defining
  all 8 plugin slot interfaces (Runtime, Agent, Workspace, Tracker,
  SCM, Notifier, Terminal) + core service interfaces
- YAML config loader with Zod validation and sensible defaults
- Plugin registry with built-in discovery
- CLAUDE.md with conventions for spawned agents

All agents can now branch from main and implement their assigned
packages against the interfaces defined in types.ts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 17:02:42 +05:30