Commit Graph

148 Commits

Author SHA1 Message Date
Dhruv Sharma 1701e03aac
Merge pull request #833 from ComposioHQ/feat/plugin-marketplace
Feat/plugin marketplace
2026-03-31 20:01:39 +05:30
Dhruv Sharma f9b3a4af20
Merge pull request #831 from ComposioHQ/feat/core-plugin-config
Feat/core plugin config
2026-03-31 19:55:16 +05:30
Dhruv Sharma 6cfb1cc864 fix: guard statSync against permission errors, add fetch timeout
- Wrap statSync in try/catch in resolveLocalPluginEntrypoint so
  permission-denied errors return null instead of crashing
- Add 30s AbortSignal timeout to refreshMarketplaceCatalog fetch
  to prevent indefinite hangs on slow networks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 14:37:52 +05:30
Dhruv Sharma d36c0947cf refactor: deduplicate plugin resolution logic between core and CLI
Export isPluginModule, normalizeImportedPluginModule,
resolvePackageExportsEntry, and resolveLocalPluginEntrypoint from
@composio/ao-core and import them in the CLI instead of maintaining
independent copies that have already diverged.

Removes ~70 lines of duplicated code from plugin-marketplace.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:53:30 +05:30
harshitsinghbhandari 23e006b00c fix: add type casts for mock promisify and registry.get
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 13:25:17 +05:30
harshitsinghbhandari 23f2f0dbeb fix: remove unused variable declarations in session-manager test
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 13:25:17 +05:30
harshitsinghbhandari 994297ca7e test: clean up session directories in recovery-actions afterEach
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 13:25:17 +05:30
harshitsinghbhandari 03e3426625 test: clarify error propagation test scope in session-manager
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 13:25:17 +05:30
harshitsinghbhandari 8fdcaff11e test: fix execFile mock to match Node callback contract
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 13:25:17 +05:30
harshitsinghbhandari 4a68fd9f99 test(core): fix timeouts in session manager communication tests
- Mock runtime output changes in OpenCode unit tests to trigger early
  delivery confirmation, reducing poll time from 3s to 500ms.
- Increase timeout for confirmation fallback tests to 10s to accommodate
  process-spawn overhead of mock binaries on some systems.
- Ensures reliable CI execution for @composio/ao-core tests.
2026-03-31 10:51:54 +05:30
harshitsinghbhandari 4d91457a01 test: ensure fake timers are restored in afterEach cleanup
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 10:14:59 +05:30
Dhruv Sharma 4c39dbe3ad refactor(plugin-registry): improve plugin specifier resolution and error handling 2026-03-31 04:24:30 +05:30
Dhruv Sharma 147cd2ea37 support custom import function in plugin registry 2026-03-31 04:02:14 +05:30
Dhruv Sharma 582c296737 add InstalledPluginConfig type and plugin config schema 2026-03-31 04:02:14 +05:30
harshitsinghbhandari 37777bc55b test: add retry loop coverage for deleteSession
Add comprehensive tests for retry logic including retry count,
delays, error propagation, early exit, and not-found handling.

Fixes Issue #5

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-31 00:35:07 +05:30
harshitsinghbhandari 282e8ae9fd test: add error path coverage for recovery system
Add tests for runtime.isAlive, workspace.destroy, and runtime.destroy
error handling to ensure cleanup continues despite partial failures.

Fixes test coverage gaps in validator and cleanup actions.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-30 23:58:23 +05:30
Gautam Tayal 56b36613f6 refactor(cli): streamline agent handling in spawn command 2026-03-30 15:32:15 +05:30
Gautam Tayal 8c23903fa2 feat: add agent selection prompt 2026-03-30 15:32:15 +05:30
Deepak Veluvolu 852f1f93c8
fix: added GraphQL batch PRfeat: add GraphQL batch PR enrichment for orchestrator polling enrichment for orchestrator polling (fixes #608) (#637)
## Approach

  The orchestrator polling loop previously made individual API calls for each PR's
  state, CI status, and review decision - 3 separate calls per PR per poll.
  With multiple PRs being monitored, this quickly exhausted GitHub's 5,000-point
  hourly rate limit.

  This PR implements GraphQL batching using aliases, which allows fetching data
  for up to 25 PRs in a single GraphQL query. Additionally, a 2-Guard ETag
  strategy is used to skip queries entirely when nothing has changed.

  ## Implementation

  ### GraphQL Batching
  - `generateBatchQuery()` creates a single GraphQL query with unique aliases (pr0, pr1, pr2...)
  - Each PR gets the same set of fields: state, CI status, review decision, mergeability
  - Uses inline fragments for union types (CheckRun/StatusContext)
  - Variable types: String! for owner/repo, Int! for PR numbers

  ### 2-Guard ETag Strategy
  Before running expensive GraphQL queries, two lightweight REST ETag checks detect if
  anything changed:

  **Guard 1 (PR List ETag):**
  - Checks `/repos/{owner}/{repo}/pulls` with If-None-Match header
  - Returns 304 if no changes → skips GraphQL (0 points)
  - Detects: New commits, title/body edits, labels, reviews, state changes

  **Guard 2 (Commit Status ETag):**
  - Checks `/repos/{owner}/{repo}/commits/{sha}/status` per cached PR
  - Returns 304 if no changes → skips GraphQL (0 points)
  - Detects: CI status transitions (failing → passing, passing → failing, etc.)

  ### Caching
  - LRU caches for PR metadata (max 200 entries), ETags (100/500 entries)
  - Cache misses trigger individual API fallback via lifecycle-manager
  - No placeholder caching on errors - allows proper fallback behavior

  ## Impact

  - **API reduction:** ~88% fewer REST calls (216 vs 1,800 calls/hour for 5 PRs)
  - **GraphQL efficiency:** Batch query fetches 25 PRs for ~40 points vs ~400 for individual calls
  - **Polling interval:** Still 30s, but most polls return cached data (0 cost)
  - **Fallback:** Individual SCM calls still work for edge cases (permissions, cache misses)

  ## Testing

  - Unit tests for query generation and parsing helpers
  - Integration tests for real GraphQL API calls (skipped by default)
  - Covers batch failures, partial success, empty arrays, edge cases
2026-03-30 00:31:04 +05:30
harshitsinghbhandari 8cafb578ba fix(core): sync enrichment timeout with discovery constant to ensure sufficient headroom 2026-03-29 18:47:00 +05:30
harshitsinghbhandari dd21054f48 extend opencode discovery timeout, include integration tests in pnpm test 2026-03-29 16:44:53 +05:30
harshitsinghbhandari 5f7a3d50cb fix: comments fixed 2026-03-28 03:15:35 +05:30
harshitsinghbhandari 2a7c4a3f57 phase3-done 2026-03-28 02:57:53 +05:30
Dhruv Sharma a26b0bc5c5
Merge pull request #728 from ComposioHQ/feat/724
refactor(core): decompose session-manager.test.ts into modular test files
2026-03-28 02:01:22 +05:30
Dhruv Sharma ff48b052a8
Merge pull request #720 from harshitsinghbhandari/patch-1
feat(core): extract shared test utilities and migrate lifecycle-manager tests
2026-03-28 00:51:58 +05:30
harshitsinghbhandari 47fa76c0de fix: latest issue 2026-03-27 22:34:05 +05:30
Dhruv Sharma c487b40919
Merge pull request #735 from ruskaruma/fix/mandate-ao-cli-in-prompt
fix(core): mandate ao send and ban raw tmux in orchestrator prompt
2026-03-27 22:16:35 +05:30
ruskaruma b65cc702be fix: correct ao send --no-wait wording per review 2026-03-27 20:50:13 +05:30
harshitsinghbhandari 540dad772b fix: comments from #720 fixed 2026-03-27 20:32:20 +05:30
Harshit Singh Bhandari 01b93706f4
Merge pull request #3 from ComposioHQ/main
merge
2026-03-27 19:30:27 +05:30
ruskaruma c975f952ff fix(core):mandate ao send and ban raw tmux (#340) 2026-03-27 12:28:02 +05:30
AO Bot 2eedb613ad refactor(core): decompose session-manager.test.ts into modular test files (#724)
The monolithic 5,032-line session-manager.test.ts has been split into
focused, domain-specific files to improve maintainability and enable
parallel test execution.

New structure:
- session-manager/test-utils.ts - shared mock factories and test setup
- session-manager/opencode-helpers.ts - parameterized shell mock installers
- session-manager/spawn.test.ts - 41 spawn tests
- session-manager/spawn-orchestrator.test.ts - 31 spawnOrchestrator tests
- session-manager/query.test.ts - 19 list + get tests
- session-manager/lifecycle.test.ts - 23 kill + cleanup tests
- session-manager/communication.test.ts - 18 send + remap tests
- session-manager/restore.test.ts - 19 restore tests
- session-manager/claim-pr.test.ts - 19 claimPR + PluginRegistry + isIssueNotFoundError tests

Total test count preserved at 174. Zero changes to core logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 18:28:00 +00:00
Harshit Singh Bhandari 5449acd04e
Add mock implementation for workspace list function 2026-03-26 19:30:41 +05:30
Harshit Singh Bhandari 532fdd22a4
Remove unused imports from lifecycle-manager test 2026-03-26 19:24:05 +05:30
AO Bot 0d4ddcc8c7 feat(core): extract shared test utilities and migrate lifecycle-manager tests (#715)
Create test-utils.ts with reusable factories (createTestEnvironment,
createMockPlugins, createMockRegistry, createMockSCM, createMockNotifier,
createMockSessionManager, makeSession, makePR) and refactor
lifecycle-manager.test.ts to use them, reducing setup boilerplate by >70%.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:41:43 +00:00
Dhruv Sharma 36d354e0c2 feat: OpenClaw plugin, AO skill, Discord notifier, and setup wizard
Adds bidirectional integration between Agent Orchestrator and OpenClaw,
enabling AI bots on Discord/Telegram/WhatsApp to manage coding agent
fleets through natural conversation.

OpenClaw Plugin (openclaw-plugin/):
- 14 AI tools: ao_spawn, ao_issues, ao_sessions, ao_status, ao_batch_spawn,
  ao_send, ao_kill, ao_session_restore, ao_session_cleanup,
  ao_session_claim_pr, ao_review_check, ao_verify, ao_doctor, ao_session_list
- Hooks: message_received + before_prompt_build for live data injection
- /ao slash command with subcommands (sessions, spawn, issues, doctor, setup)
- Background services: health monitor + issue board scanner
- Security: execFileSync with arg arrays (no shell injection)

AO Skill (skills/agent-orchestrator/):
- Natural language intent → AO tool mapping
- Decision heuristic: quick fix → direct, multi-issue → AO
- Designed for ClawHub publishing (blocked on ClawHub server bug)

CLI: ao setup openclaw (packages/cli/src/commands/setup.ts):
- Interactive wizard + non-interactive mode
- Auto-detects OpenClaw gateway on localhost
- Auto-generates secure token
- Writes both configs (agent-orchestrator.yaml + openclaw.json)
- Appends OPENCLAW_HOOKS_TOKEN to shell profile
- Validates connection end-to-end

CLI: ao doctor notifier checks:
- Probes OpenClaw gateway reachability + token validity
- --test-notify flag sends test event through all configured notifiers
- Failure count propagated to exit code

Discord Notifier (packages/plugins/notifier-discord/):
- Rich webhook embeds with colors, fields, action links
- Retry with exponential backoff + Discord Retry-After header
- Request timeouts, embed truncation, webhook URL validation
- thread_id via URL query string (Discord API requirement)

OpenClaw Notifier improvements:
- Added request timeouts via AbortController
- Improved README

Reviewed through 5 rounds of Codex code review.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 21:52:28 +05:30
suraj-markup 596913aa34 Fix review issues: busy-wait loops, lock race, import hygiene, typed errors
- Replace CPU-burning spin loops in running-state.ts with async setTimeout
  and jittered backoff; make all exports async
- Fix TOCTOU race in acquireLock by extracting tryAcquire helper with
  retry loop instead of force-remove-and-retry-once
- Hoist dynamic imports in addProjectToConfig/choice-2 to static imports
- Add try/finally around readline in detectAgentRuntime
- Validate session prefix uniqueness in "Start new orchestrator" menu
- Add ConfigNotFoundError class to @composio/ao-core, replace fragile
  string matching in ao start with instanceof check
- Fix setup.sh to recommend `ao start` instead of deprecated `ao init`
- Fix start-all.ts: resolve next binary with fallback, wait for children
  on SIGTERM instead of immediate process.exit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 17:33:06 +05:30
suraj-markup 44313f925d Remove two-arg support from ao spawn and batch-spawn
- spawn now takes only `[issue]` — project is always auto-detected
- batch-spawn now takes only `<issues...>` — no project prefix
- Commander rejects extra positional args automatically
- Update orchestrator prompt to remove projectId from spawn example
- Rewrite spawn tests to use auto-detected project (single project in config)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 14:29:14 +05:30
suraj-markup a1a9966ed5 Fix CI failures: lint eqeqeq + test manifest displayName
- Change != null to !== undefined && !== null in caller-context.ts and
  session-manager.ts (3 locations) to satisfy eqeqeq lint rule
- Add displayName field to all 4 agent plugin test manifest assertions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:55:08 +05:30
suraj-markup 694681f728 Fix review issues: ESM compat, prompt accuracy, port registration
- Replace require() with execFileSync in all 4 agent plugin detect()
  functions — fixes ReferenceError in ESM-only environments
- Remove non-existent -p flag from orchestrator prompt spawn/batch-spawn
  docs — prevents orchestrator agent from generating broken commands
- Return actual port from runStartup() and pass to register() — fixes
  running.json storing wrong port when auto-escalation picks a free port

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 05:49:53 +05:30
suraj-markup f3f81dad84 Simplify onboarding: absorb init + add-project into ao start
Reduces onboarding to `npm install -g @composio/ao && ao start`.

- Absorb init and add-project logic into `ao start` with auto-config
  creation, environment detection, and project type detection
- Add single-instance tracking via running.json with already-running
  interactive menu (human) and info+exit (agent)
- Add caller context detection (human/orchestrator/agent) via TTY and
  AO_CALLER_TYPE env var
- Add plugin-based agent runtime detection — no hardcoded binary paths,
  each plugin exports detect() and displayName
- Simplify `ao spawn` to just `ao spawn <issue>` with auto-detected
  project (backward compat: `ao spawn <project> <issue>` still works)
- Set AO_CALLER_TYPE, AO_PROJECT_ID, AO_CONFIG_PATH, AO_PORT env vars
  on all spawned sessions (worker, orchestrator, restore)
- Add `ao config-help` subcommand for config schema reference
- Deprecate `ao init` to thin wrapper, fully remove `ao add-project`
- Register/unregister in running.json on start/stop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 01:17:33 +05:30
suraj-markup 14fa726551 Publish ao-web on npm, harden error handling, deduplicate code
- Publish @composio/ao-web dashboard as npm package (removed private flag,
  added files field, production entry point, node-pty made optional)
- CLI auto-detects dev vs production mode for dashboard startup
- Use local next binary instead of npx in production start-all.ts
- findWebDir() throws with install-specific guidance instead of returning
  broken path
- Fix CI-silent failure: setup.sh and ao-update.sh exit 1 on non-interactive
  npm link failure
- Deduplicate detectDefaultBranch into shared cli/lib/git-utils.ts
- Add EACCES permission guidance to README.md and SETUP.md
- Move resolveProjectIdForSessionId to @composio/ao-core
- Update design doc with problems #8-13, changes #9-12, known limitations
  section, and expanded test plan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 19:01:49 +05:30
Joakim Sigvardt a64c051e9f
fix(lifecycle): implement stuck detection using agent-stuck threshold (#376)
* fix(lifecycle): implement stuck detection using agent-stuck threshold

The agent-stuck reaction config supported a threshold field (e.g.
"10m"), but determineStatus() never returned "stuck" — there was no
code path that consumed the threshold or transitioned sessions based
on idle time. Sessions would stay parked at pr_open/working forever
even when the agent had been idle for hours.

Added idle-time check in determineStatus(): when getActivityState()
reports "idle" or "blocked" with a timestamp, compare the idle
duration against the agent-stuck.threshold config. If exceeded,
return "stuck" so the reaction system can fire notifications.

Also removed the priority !== "info" guard on transition
notifications, so all priority levels (including info) are routed
through notificationRouting. This lets the config control which
notifiers receive each priority level, rather than silently dropping
info-level transition events.

* fix(lifecycle): add post-PR stuck detection as safety net

The original stuck check in step 2 (before PR checks) can be bypassed
when getActivityState() returns null (session file not found, cache miss,
I/O failure). When this happens, the code falls through to the PR path
which returns 'pr_open' without ever checking idle duration.

Fix: extract isIdleBeyondThreshold() helper and call it in three places:
1. Step 2: before PR checks (fast path, catches most cases)
2. Step 4b: after PR checks return 'pr_open' (safety net)
3. Step 5: after all checks, for agents that finish without a PR

This ensures stuck detection fires even when the JSONL activity detection
fails to return idle state. Sessions can no longer get permanently stuck
at 'pr_open' when the agent has been idle beyond the threshold.

Also removes the debug console.error calls from the previous commit.

* fix(lifecycle): treat reviewDecision 'none' as approved for merge readiness

PRs with no required reviewers never reached 'mergeable' status because
getReviewDecision returned 'none', which was not handled. The lifecycle
poll fell through to 'review_pending' or the default, so merge.ready
never fired and the approved-and-green reaction never triggered.

Also: skip stuck short-circuit when session has an open PR so merge
readiness checks in step 4 can still run. Without this, idle agents
with open PRs get stuck status and never transition to mergeable.

Closes composio#0 (internal fix)

* fix(opencode): classify activity state from session timestamps

* test(lifecycle): cover opencode idle-threshold stuck transition

* fix(lifecycle): preserve global stuck threshold with project overrides

* fix(lifecycle): run PR auto-detection before stuck transitions

---------

Co-authored-by: Harsh <harshb012@gmail.com>
2026-03-13 10:02:33 +05:30
Harsh Batheja 1d960feb6b
fix: protect orchestrators from session cleanup (#453)
* fix: harden orchestrator cleanup selection

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

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

* fix: suppress orchestrators in cleanup command output

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

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

* fix: remove unreachable cleanup guard branch

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

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

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-13 09:39:49 +05:30
Harsh Batheja 63889c2b00
fix: use tmux metadata handle for reliable active session status (#449)
Treat persisted tmuxName as metadata-derived runtime identity when runtimeHandle is missing so active sessions are not misclassified as exited/unknown across agents.
2026-03-12 22:31:31 +05:30
Harsh Batheja 3deea32bda
feat: support distinct worker and orchestrator agents (#439)
* feat: add role-specific agent resolution

* test: cover role-specific agent precedence

* docs: show role-specific agent config

* fix: preserve shared agent config fallbacks

* fix: avoid role-config permission clobbering

* fix: keep orchestrator launches permissionless

* fix: remove stale lifecycle imports
2026-03-12 20:58:55 +05:30
Harsh Batheja 0797f933e1
fix: gate fresh session sends on interactive readiness (#438)
* fix: gate fresh session sends on interactive readiness

Wait for spawning tmux-backed sessions to settle before injecting input, and use OpenCode session timestamps to confirm delivery without relying on pane churn alone.

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

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

* fix: satisfy lint in opencode send regression helper

Remove unnecessary escaping in generated shell snippets used by the new OpenCode confirmation tests so CI lint passes cleanly.

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

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

* fix: avoid false opencode delivery confirmation

Only treat OpenCode timestamp confirmation as delivered when updatedAt advances beyond a known baseline, and add regression coverage for transient baseline visibility.

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

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

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-12 20:44:04 +05:30
Harsh Batheja b04d3e21de
feat: add end-to-end observability across core, web, and terminal (#436)
* feat: add end-to-end observability across core, web, and terminal

Instrument lifecycle/API/websocket flows with correlation-aware metrics and operator health surfaces so the system can self-diagnose and escalate failures.

* fix: realign session restore set and unblock claim PR typecheck

* fix(web): restore project-filtered sessions route after main merge

* fix(core): remove unused orchestrator import to unblock lint

* fix(core): always record lifecycle poll failures and remove dead review branches

* fix(web): harden websocket metrics and reuse SSE observers

* fix(web): preserve primary session API errors when services bootstrap fails

* fix(web): use full orchestrator config type in SSE observer helper

* fix(web): restore project-scoped SSE and guard observability error paths

* fix(web): address remaining Bugbot review gaps

* fix(web): align SSE project attribution and share session project resolver

* fix(web): require request arg for SSE route and align tests

* fix(web): record websocket error disconnects as failures

* fix(web): use path alias for session project resolver import

* fix(web): include active connection count in disconnect metrics
2026-03-12 16:57:40 +05:30
Jayesh Sharma 1194697b3b
fix: skip PR auto-detection for orchestrator sessions (#442)
* fix: skip PR auto-detection for orchestrator sessions

Orchestrator sessions sit on the base branch (e.g. master) and should
never own a PR. When the lifecycle worker ran detectPR for these
sessions, any PR whose head branch matched master (e.g. a master->prod
deploy PR) would get incorrectly attached and keep re-attaching after
manual cleanup.

Add a role=orchestrator check to the PR auto-detection guard so
orchestrator sessions are skipped entirely.

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

* fix: add session ID suffix fallback for orchestrator PR auto-detection skip

Pre-existing orchestrator sessions spawned before the role metadata field
was added lack role=orchestrator. Mirror the session-manager pattern by
also checking session.id.endsWith("-orchestrator") as a fallback.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 14:46:39 +05:30
Harsh 238752b29e fix: reuse shared orchestrator detection in lifecycle manager
Drop the lifecycle manager's local orchestrator predicate so the final remaining core polling path follows the same shared detection logic as session cleanup, web filters, and CLI status.
2026-03-12 02:42:50 +05:30