Commit Graph

317 Commits

Author SHA1 Message Date
harshitsinghbhandari 0d03c46ca5 Merge upstream/main into session/aa-22-lifecycle-fixes
Resolved conflicts in:
- packages/web/src/lib/types.ts (merged canonical type imports with DashboardAttentionZoneMode)
- packages/web/src/lib/dashboard-page-data.ts (kept upstream imports)
- packages/web/src/components/Dashboard.tsx (kept upstream mobileKanbanOrder)

Updated getAttentionLevel to support mode parameter from upstream
while preserving lifecycle-aware helper functions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 00:53:06 +05:30
harshitsinghbhandari 0ab62c8f13 fix: set detectingEscalatedAt for time-based escalation too
The isDetectingEscalated check now considers both attempt limit
AND time limit, ensuring detectingEscalatedAt is set regardless
of which escalation path triggers the stuck state.

Addresses suppressed review comment about time-based escalation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 00:46:02 +05:30
harshitsinghbhandari 7b82374ca8 fix: address PR review comments for lifecycle transitions
- Allow spawning sessions in shouldAuditSession for acknowledge timeout
- Remove dead agent_blocked trigger type (never returned)
- Clear audit metadata when no trigger fires
- Protect completedAt/terminatedAt from being overwritten
- Ensure lifecycle patch takes precedence over additionalMetadata
- Add changeset entry for new exports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 00:39:35 +05:30
harshitsinghbhandari 89c17f49f4 feat(lifecycle): bounded detecting state + centralized transitions + report watcher
Issue #137: Centralize lifecycle transitions
- Create lifecycle-transition.ts with applyLifecycleDecision function
- Provide consistent mutation boundary for lifecycle state changes
- Export buildTransitionMetadataPatch and createStateTransitionDecision helpers

Issue #138: Make detecting a real bounded transition state
- Add time-based escalation (5 min hard cap) in addition to attempt-based (3 attempts)
- Add evidence hashing to prevent counter reset on unchanged evidence
- Track detectingStartedAt and detectingEvidenceHash in metadata
- Escalate to stuck when either limit is exceeded

Issue #140: Report Watcher for agent reports
- Create report-watcher.ts with audit functions
- Add checkAcknowledgeTimeout (10 min default)
- Add checkStaleReport (30 min default)
- Add checkBlockedAgent for needs_input state
- Integrate auditAndReactToReports into lifecycle polling loop
- Surface triggers as reactions (report-no-acknowledge, report-stale, etc.)

Tests:
- 19 tests for lifecycle-status-decisions (detecting bounds, hashing)
- 13 tests for lifecycle-transition (decision application, metadata)
- 19 tests for report-watcher (audit triggers, priorities)

Closes #137, #138, #140

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-18 00:27:21 +05:30
harshitsinghbhandari 6b36efd9ee refactor(core): keep lifecycle decision helpers internal
Move extracted determineStatus decision helpers into an internal module so the refactor does not expand the public lifecycle-manager API surface.

Also share merged and closed PR terminal-state mapping between cached and live SCM decision paths to prevent drift while addressing PR review feedback.
2026-04-17 23:35:23 +05:30
harshitsinghbhandari 245db8f8f9 refactor(core): split lifecycle status decisions for #136
Extract probe and PR decision helpers out of determineStatus so lifecycle state selection is easier to review without mixing it with mutation and metadata commits.

Add focused helper coverage and lock merged PR metadata truth to avoid regressions toward a no-PR state while refactoring the lifecycle path.
2026-04-17 23:00:55 +05:30
Ashish Huddar 237c99f76e
feat(web): collapse attention zones to 4 with 5-zone feature flag (#1202)
* feat(web): collapse attention zones to 4 with feature flag for 5 (#1201)

Simplify the dashboard to a 4-zone kanban by default (WORKING,
PENDING, ACTION, READY), merging the former REVIEW + RESPOND
columns into a single ACTION zone that just asks "does the human
need to do something?". The card-level badges still surface the
underlying granular state (ci_failed, needs_input, changes_requested),
so nothing is lost — it just moves off the column header.

Add a `dashboard.attentionZones` config (defaults to "simple") that
opts back into the original 5-zone layout for power users. The
function-level `getAttentionLevel(session, mode)` still defaults to
"detailed" so card-level call sites (SessionCard, BottomSheet,
ProjectSidebar, etc.) keep their granular behavior untouched. Only
the Dashboard kanban and SSE server routes read the config and pass
the mode.

Closes #1201

* fix(web): address PR review feedback on attention zones (#1201)

- Drop .strict() from DashboardConfigSchema (Cursor Bugbot):
  matches other schemas in config.ts so typos in the dashboard
  block gracefully default instead of crashing the whole loader.

- DynamicFavicon: keep `action` at yellow, not red (Codex P2).
  In simple mode, `action` collapses respond + review, which
  means it necessarily catches routine review work (ci_failed,
  changes_requested) that was previously yellow. Escalating to
  red would make every typical PR scream critical. Only the
  detailed-mode `respond` bucket still triggers red.

- useSessionEvents default → "detailed" (Codex P3). The hook
  default now matches getAttentionLevel's default so callers
  that seed with `getAttentionLevel(s)` (no mode) — notably
  PullRequestsPage — stay consistent with their seed after
  the first live SSE/refresh snapshot. Dashboard explicitly
  passes the config's attentionZones to opt into simple mode.

- Expand mobile action chip (Codex P3). When a session
  collapses to `action`, derive the most specific underlying
  cause (needs input, stuck, errored, ci failed, changes,
  waiting, conflicts) instead of falling through to the
  generic "action" label, so mobile users keep the reason to
  intervene.

- DynamicFavicon tests: add cases for `action` staying yellow
  and `respond` still escalating when both are present.

* fix(web): thread attentionZones config through PullRequestsPage (#1201)

Cursor Bugbot caught a deeper version of the same inconsistency
my previous fix didn't fully resolve: the server SSE route uses
`config.dashboard?.attentionZones ?? "simple"`, but PullRequestsPage
was seeding `initialAttentionLevels` and calling useSessionEvents
without passing any mode (falling back to the hook's "detailed"
default). Result: snapshots from the server arrived as "action"/
"merge", then scheduleRefresh recomputed them client-side as
"respond"/"review", and the favicon oscillated between yellow
and red on every refresh cycle.

Fix: plumb pageData.attentionZones through prs/page.tsx into
PullRequestsPage, use it in both the seed and useSessionEvents.
Now the seed, the server SSE, and the client refresh all use the
same mode — stable, no flicker.

* fix(web): accurate action labels for crashed agents + yellow tone (#1201)

Two Cursor Bugbot findings on the action-zone collapse work:

1. [Medium] Mobile chip mislabeled crashed agents as "needs input".
   When an agent's activity is `exited` and the session is in the
   action bucket, the agent has crashed — sending it a message
   won't help, the user needs to restart. Split the label: exited
   → "crashed", blocked → "blocked".

2. [Low] ProjectMetric for Action used tone="error" (red), which
   contradicts the favicon fix's rationale. The action bucket
   catches routine review work (ci_failed, changes_requested)
   that was previously orange/yellow severity; screaming red in
   the project overview grid would have the same cry-wolf problem
   as the favicon did. Use tone="orange" (the less severe of the
   two merged buckets) to match.

* refactor(web): make attentionZones required in useSessionEvents (#1201)

Cursor Bugbot caught that the hook default of "detailed" mismatches
the server SSE route default of "simple" — a latent footgun for any
future caller that forgets to pass the mode explicitly. The exact
oscillation bug I already fixed once for PullRequestsPage would
silently come back on the next page that uses this hook.

Real fix: refactor the hook to take an options object and make
`attentionZones` required with no default. TypeScript now enforces
that every caller explicitly passes the mode the server is using.
You literally cannot call useSessionEvents without supplying it.

Also cleaner: the hook had 6 positional parameters, which is past
the point where an options object helps readability. Dashboard and
PullRequestsPage call sites now read as self-documenting.

* fix(web): address human code review on attention zones (#1201)

Review from i-trytoohard on commit 8d27db79:

1. [Medium] `ZoneCounts` in sessions/[id]/page.tsx had an `action`
   field that was always 0 — the page always computes in detailed
   mode (getAttentionLevel with no mode = detailed), and the
   consumer (`OrchestratorZones` in SessionDetail) never reads
   an `action` field either. Removed the dead field, added a
   `continue` guard for the never-reached "action" case so
   TypeScript narrows the index correctly, and documented the
   intent in a header comment.

2. [Medium] The simple-mode action chip had 10+ sub-conditions
   with no tests. Extracted the label logic into a pure
   `getActionChipLabel(session)` helper and added 16 unit tests
   covering every branch: status-based signals (needs_input,
   stuck, errored, ci_failed, changes_requested), activity-based
   (waiting_input, exited→crashed, blocked), PR-based (failing
   CI, changes_requested, conflicts), precedence between signal
   classes, and the generic fallback.

3. [Low] `LEVEL_LABELS.action` in ProjectSidebar is dead code
   today (sidebar uses detailed mode). Added a comment explaining
   why the entry still exists (TypeScript exhaustiveness on
   `Record<AttentionLevel, string>` + forward-compat).

* fix(web): address inline review on attention zones (#1201)

- Reorder getActionChipLabel to mirror getDetailedAttentionLevel: respond-class
  activity (waiting_input/exited/blocked) now outranks review-class status
  (ci_failed/changes_requested). A crashed agent with changes_requested no
  longer reads as "changes" and hides the crash.
- Paint data-level="action" dot with --color-accent-orange to match the
  favicon's yellow-severity treatment of the collapsed bucket.
- Tighten attentionLevel on the mux boundary (mux-protocol, mux-websocket,
  useSessionEvents) from string to AttentionLevel so invalid values like "none"
  no longer launder through into DynamicFavicon's count.

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 22:24:25 +05:30
harshitsinghbhandari 542a3b6a89 fix: address PR review feedback (#131) 2026-04-17 22:01:52 +05:30
harshitsinghbhandari e7ad928812 feat: report non-terminal PR workflow events (#131) 2026-04-17 21:46:57 +05:30
harshitsinghbhandari 795ccfb21c fix: require fresh runtime evidence for unavailable-activity downgrade (#129) 2026-04-17 21:29:54 +05:30
harshitsinghbhandari a862327dc5 fix: avoid stuck probe failures for unavailable activity (#129) 2026-04-17 21:22:44 +05:30
harshitsinghbhandari 1cbf6579c2 fix: address PR review feedback for session audit trail 2026-04-17 21:06:08 +05:30
harshitsinghbhandari 28ce462ef0 feat: unify session detail auditability and lifecycle stability (#123 #124 #126) 2026-04-17 20:48:02 +05:30
harshitsinghbhandari ca8c4cc7ab fix: address lifecycle review feedback (#122)
Keep reconstructed activity and activitySignal coherent, preserve stronger lifecycle states when repeated polls only surface weak evidence, and switch release notes from manual changelog edits to a Changesets entry. This also stabilizes the respond/working path investigated in issue #126.
2026-04-17 19:38:32 +05:30
harshitsinghbhandari dd83a11503 fix: model missing activity evidence explicitly (#122)
Represent missing activity probes as first-class signal states so lifecycle inference only treats valid idle evidence as proof. This prevents false stuck transitions, keeps API/UI lifecycle truth aligned, and makes root monorepo verification deterministic by serializing recursive build and typecheck.
2026-04-17 19:28:56 +05:30
harshitsinghbhandari e584843978 fix: remove unused observability helper arg (#121) 2026-04-17 16:58:57 +05:30
harshitsinghbhandari 1acefddc89 fix: address review feedback for observability logging (#121) 2026-04-17 16:44:56 +05:30
harshitsinghbhandari bd36c7b447 chore: replace changelog entry with changeset (#121) 2026-04-17 16:36:37 +05:30
harshitsinghbhandari 77f9ccf637 fix: keep lifecycle observability out of session terminals (#121) 2026-04-17 16:33:36 +05:30
harshitsinghbhandari d3cf4ae3de fix: address PR review comments on stage 5 rollout (#119) 2026-04-17 13:36:09 +05:30
harshitsinghbhandari 88cd9e7ed1 merge: resolve sessions-redone conflicts for stage5
Preserve the split lifecycle observability and UI truth model while retaining the latest sessions-redone PR transition handling and dependency updates.
2026-04-17 13:09:13 +05:30
harshitsinghbhandari 7072143138 feat: expose split lifecycle truth in dashboard
Implement the Stage 5 rollout so API and UI consumers stop depending on one overloaded status and operators can see structured transition evidence without breaking older session metadata.
2026-04-17 13:00:26 +05:30
Harshit Singh Bhandari ffdfd869ff
Merge pull request #118 from harshitsinghbhandari/stage4-pr-policy
fix: decouple PR truth from worker session policy
2026-04-17 11:51:01 +05:30
harshitsinghbhandari b5c969c6b4 fix: address PR review policy regressions (#118) 2026-04-17 11:39:13 +05:30
harshitsinghbhandari 7ccbe5b260 fix: preserve session truth over PR aliases (#118) 2026-04-17 11:02:06 +05:30
Harshit Singh Bhandari 7361e5b5ee
Merge branch 'ComposioHQ:main' into sessions-redone 2026-04-17 10:48:42 +05:30
harshitsinghbhandari a45eb322bb fix: decouple PR truth from worker session policy 2026-04-17 10:44:35 +05:30
Pritom Mazumdar 685fd42c3d
fix: resolve three Next.js build warnings in web package (#1087)
* fix Next.js build warnings, pin flatted override, regenerate lockfile

* fix ignoreDuringBuilds, add ao-core to serverExternalPackages, clean dist-server in prebuild

* fix ESLint plugin detection, remove ao-core from transpilePackages, suppress plugin-registry webpack warning

* fix(web): restore ao-core to transpilePackages, document overrides, fix dev:optimized cleanup

Move @aoagents/ao-core back to transpilePackages only. dist/ is gitignored so fresh
checkout has no dist/index.js; serverExternalPackages causes a hard crash at runtime.
Client components (SessionDetail, ProjectSidebar, sessions/[id]/page) also import
@aoagents/ao-core/types which serverExternalPackages does not cover.

Keep @composio/core in serverExternalPackages only with comment explaining it is an
optional transitive dep via tracker-linear dynamic import.

Add _overrides_rationale to document axios (SSRF CVE-2023-45857) and flatted
(prototype-pollution) security pins in root package.json.

Fix dev:optimized to clean both .next and dist-server, matching what prebuild does.

* fix: webpackIgnore dynamic imports in plugin-registry fixes #1056

* fix: move Next.js ESLint config to packages/web for build-time detection fixes #1058

* fix: remove scope creep and phantom agent-soma from lockfile

- remove agent-soma importer block from pnpm-lock.yaml
- remove @composio/core from serverExternalPackages
- remove redundant exprContextCritical webpack override
- remove flatted override and _overrides_rationale
- align @next/eslint-plugin-next to ^15.5.15

* fix: replace rm -rf with rimraf for cross-platform compatibility

* fix: use rimraf in clean script and sort devDependencies

* fix: add postcss.config.mjs to web ESLint ignores

* fix: restore no-console exemption for web package in root ESLint config
2026-04-17 10:43:01 +05:30
harshitsinghbhandari 0093e2b4e4 fix(core): use kind for orchestrator skip; honest report-surfacing copy
Address Copilot review feedback on PR #117:

- lifecycle-manager: replace string-matching guards (`metadata["role"]`,
  `session.id.endsWith("-orchestrator")`) with the authoritative
  `lifecycle.session.kind !== "orchestrator"` check. The previous guard
  missed numbered orchestrator IDs like `${prefix}-orchestrator-1`, which
  could let a fresh agent report incorrectly override an orchestrator
  session's status.
- orchestrator-prompt: reword the "Explicit Agent Reports" section to stop
  promising automatic surfacing in status/dashboard. CLI/UI display work
  is not part of this PR; the prompt now describes reports as a hint to
  lifecycle inference and explicitly notes SCM/runtime truth still wins.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-17 10:13:00 +05:30
harshitsinghbhandari 593eec441a fix(core): tighten agent-report contract per PR review
Address Copilot review feedback on PR #117:

- Drop the `done` alias from `INPUT_ALIASES`. Agents cannot self-report the
  terminal `done` state (AO owns that transition via SCM ground truth), so
  silently aliasing `done` → `completed` contradicted the prompts and
  weakened the reserved-transition boundary.
- Tighten `validateAgentReportTransition` to reject ALL reports when
  `session.state === "done"`. Previously `completed` slipped through, but
  `completed` maps to `idle` and would have re-opened a terminal session,
  contradicting the function's own doc comment.
- Reject future timestamps in `isAgentReportFresh`. A skewed/future
  `agentReportedAt` would otherwise yield a negative delta that satisfies
  `<= windowMs`, making the report appear "fresh" indefinitely and
  overriding stronger inference signals.

Tests updated:
- Replace done→completed alias assertion with explicit null expectation.
- Expand `done`-state rejection test to cover `completed` and `needs_input`.
- Add freshness test for future-dated timestamps.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-17 10:11:03 +05:30
harshitsinghbhandari cab0a2656d feat(core): add explicit agent reporting for workflow coordination (Stage 3)
Introduce an explicit reporting channel so worker agents can self-declare
their workflow phase (started/working/waiting/needs-input/fixing-ci/
addressing-reviews/completed). Fresh reports are trusted over weak inference
but runtime death, activity-based waiting_input, and SCM ground truth still
take precedence.

- Add `applyAgentReport`, validator, canonical mapping, and freshness helper
  in `packages/core/src/agent-report.ts`.
- Wire the fallback into `determineStatus` just before the idle-beyond-
  threshold promotion, skipping orchestrator and terminal sessions.
- Add `ao acknowledge` and `ao report <state>` CLI commands. Both resolve
  the session from `AO_SESSION_ID` when no argument is passed.
- Teach the base agent prompt and orchestrator prompt about the new
  reporting commands.
- Ship unit tests covering normalization, mapping, transition validation,
  metadata persistence, freshness, and first-start behavior.

Stage 3 of the state-machine redesign (see aa-2/state-machine-redesign-
rollout-plan.md).
2026-04-17 10:11:03 +05:30
Harshit Singh Bhandari 47c4b877f7
Merge branch 'ComposioHQ:main' into sessions-redone 2026-04-17 10:06:26 +05:30
yyovil 8b7a54ba5a
Merge pull request #1206 from yyovil/yyovil/fix-issue-1175
refactor(core): templated orchestrator prompt
2026-04-16 23:54:44 +05:30
harshitsinghbhandari f4fdaa7f3f fix: honor live startup evidence in recovery (#95) 2026-04-16 23:06:49 +05:30
harshitsinghbhandari f2f1a4ddb6 fix: address follow-up stage 2 review feedback (#95) 2026-04-16 23:00:20 +05:30
harshitsinghbhandari c447c7c41f fix: address stage 2 PR review feedback (#95) 2026-04-16 22:46:12 +05:30
harshitsinghbhandari 008ca45618 Merge remote-tracking branch 'origin/sessions-redone' into feat/stage2-evidence-recovery
# Conflicts:
#	packages/core/src/lifecycle-manager.ts
2026-04-16 22:43:57 +05:30
harshitsinghbhandari 0a55b12f19 feat: implement stage 2 evidence-based recovery rules (#95) 2026-04-16 22:33:27 +05:30
Harshit Singh Bhandari 42e9be13a5
Merge pull request #114 from harshitsinghbhandari/plan/stage1-lifecycle-foundation
Plan/stage1 lifecycle foundation
2026-04-16 22:09:41 +05:30
yyovil 4f687dd59e fix(core): validate template placeholders before render
Entire-Checkpoint: 7fdb8af31510
2026-04-16 20:13:58 +05:30
yyovil e418f6f9f3 chore(core): simplify command prompt markdown 2026-04-16 19:14:41 +05:30
Dhruv Sharma 87fb598d87
Merge pull request #1126 from gautamtayal1/fix/spawn-ao-for-opencode
fix (opencode): use local AGENTS.md for OpenCode orchestrator instructions
2026-04-16 18:21:12 +05:30
yyovil b853fe3080 fix(core): harden prompt template rendering 2026-04-16 14:43:33 +05:30
yyovil f4870c41c9 Merge remote-tracking branch 'origin/main' into yyovil/fix-issue-1175
# Conflicts:
#	packages/core/src/__tests__/orchestrator-prompt.test.ts
#	packages/core/src/orchestrator-prompt.ts
2026-04-15 22:08:28 +05:30
Adil Shaikh ba77929c93
Merge pull request #1158 from ComposioHQ/feat/issue-1154
fix(cli): stop writing broken yaml when `ao start` runs in a new folder
2026-04-15 15:10:10 +05:30
Gautam Tayal 179c0a6083 fix: add agents.md file for restore command 2026-04-15 13:56:35 +05:30
Harshit Singh Bhandari ae302ea221
Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-15 13:50:28 +05:30
Harshit Singh Bhandari bfe85876e4
Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-04-15 13:50:09 +05:30
harshitsinghbhandari 81d88c4412 fix(core): address lifecycle review feedback 2026-04-15 12:41:06 +05:30
harshitsinghbhandari d466118450 feat(core): add canonical lifecycle persistence foundation 2026-04-15 12:41:06 +05:30