1. Guard safeRemoveAttachmentsDir with retainAttachmentsOnKeep check
in the session-mode TTL sweep, matching the existing pattern in
finalizeSubagentCleanup (Codex P1)
2. Start sweeper unconditionally in restoreSubagentRunsOnce(), matching
the register paths — ensures TTL cleanup runs after restart even
when all restored entries are session-mode (Codex P2)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The new registeredAt and lastActiveAt fields on AgentRunContext cause
toEqual to fail because it expects exact property counts. Switch to
toMatchObject which validates expected properties without requiring
exact match — the standard pattern for objects with auto-injected
timestamps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The sweeper was only started when archiveAtMs was truthy, so pure
session-mode workloads (archiveAtMs=undefined) never triggered the
60s sweep interval. This meant the TTL cleanup for session-mode runs,
pending lifecycle errors, and orphaned contexts never executed —
defeating the OOM fix for the exact batch scenario it was designed for.
Remove the if(archiveAtMs) guard at both registration sites so the
sweeper runs for all workloads. startSweeper() is idempotent (returns
immediately if already running) so this is safe.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. clearAgentRunContext now also deletes seqByRun (Greptile P2)
2. TTL constants moved to module scope (Greptile P2)
3. Session-mode TTL uses cleanupCompletedAt instead of endedAt to
avoid interrupting deferred cleanup flows (Codex P1)
4. Added lastActiveAt to AgentRunContext, refreshed on every
emitAgentEvent — long-running active agents are not swept (Codex P1)
5. resetAgentRunContextForTest also clears seqByRun (P2 drive-by)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gateway crashes with OOM after batch processing ~1000+ agent sessions.
Three Maps accumulate entries without cleanup:
1. subagentRuns: session-mode runs have archiveAtMs=undefined, so the
60s sweeper skips them forever. Add 5-min absolute TTL for completed
session runs. Also sweep orphaned pendingLifecycleError entries with
5-min TTL.
2. runContextById: only cleaned via manual clearAgentRunContext() calls.
Add registeredAt timestamp and sweepStaleRunContexts() with 30-min
TTL, called from the existing 60s maintenance timer. Also sweeps
the companion seqByRun Map for the same runIds.
3. pendingLifecycleErrorByRunId: 15s retry timer but no absolute TTL.
Now swept in sweepSubagentRuns() after 5 min.
Pre-deploy entries without registeredAt are treated as infinitely old
and swept immediately.
Fixes#52725
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Wizard: coerce integer plugin config input
Regeneration-Prompt: |
Fix the interactive plugin-config wizard so JSON Schema fields declared as type "integer" are coerced from text input the same way type "number" already is. Keep the change narrow in src/wizard/setup.plugin-config.ts rather than refactoring the broader prompt flow. Add a focused regression test in src/wizard/setup.plugin-config.test.ts that exercises setupPluginConfig with an integer-typed schema field, verifies the text response "3" is stored as numeric 3, and run only the relevant wizard test slice before committing.
* Wizard: type select mock in setup plugin config test
Regeneration-Prompt: |
Fix the CI type failure on PR #63346 in src/wizard/setup.plugin-config.test.ts with the smallest possible change. The new integer-coercion test needs its mocked prompter to satisfy the generic WizardPrompter select signature, matching the surrounding test style without changing production code or test behavior. After the one-line test fix, rerun pnpm tsgo --pretty false and pnpm test src/wizard/setup.plugin-config.test.ts on branch aristotle-3f605963-fix-config-integer-coercion.
* Wizard: coerce integer plugin config input
* Changelog: remove stray conflict marker
* Refine plugin debug plumbing
* Tighten plugin debug handling
* Reduce active memory overhead
* Abort active memory sidecar on timeout
* Rename active memory blocking subagent wording
* Fix active memory cache and recall selection
* Preserve active memory session scope
* Sanitize recalled context before retrieval
* Add active memory changelog entry
* Harden active memory debug and transcript handling
* Add active memory policy config
* Raise active memory timeout default
* Keep usage footer on primary reply
* Clear stale active memory status lines
* Match legacy active memory status prefixes
* Preserve numeric active memory bullets
* Reuse canonical session keys for active memory
* Let active memory subagent decide relevance
* Refine active memory plugin summary flow
* Fix active memory main-session DM detection
* Trim active memory summaries at word boundaries
* Add active memory prompt styles
* Fix active memory stale status cleanup
* Rename active memory subagent wording
* Add active memory prompt and thinking overrides
* Remove active memory legacy status compat
* Resolve active memory session id status
* Add active memory session toggle
* Add active memory global toggle
* Fix active memory toggle state handling
* Harden active memory transcript persistence
* Fix active memory chat type gating
* Scope active memory transcripts by agent
* Show plugin debug before replies
* fix(cron): repair nextRunAtMs=0 on non-schedule edits
Treat nextRunAtMs <= 0 as invalid during non-schedule updates so editing
a description or other metadata field recomputes the next run time instead
of silently keeping the corrupt value.
Made-with: Cursor
* fix(cron): treat zero nextRunAtMs as invalid
* fix: treat zero nextRunAtMs as invalid (#63507) (thanks @WarrenJones)
---------
Co-authored-by: WarrenJones <8704779+WarrenJones@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* fix(qqbot): replace raw fetch in image-size probe with SSRF-guarded fetchRemoteMedia
Replace the bare fetch() in getImageSizeFromUrl() with fetchRemoteMedia()
from the plugin SDK, closing the blind SSRF via markdown image dimension
probing (GHSA-2767-2q9v-9326).
fetchRemoteMedia options: maxBytes 65536, maxRedirects 0, generic
public-network-only SSRF policy (no hostname allowlist, blocks
private/reserved/loopback/link-local/metadata IPs after DNS resolution).
Also fixes the repo-root resolution in scripts/lib/ts-guard-utils.mjs
which caused lint:tmp:no-raw-channel-fetch to miss extension files
entirely. The guard now walks up to .git instead of hardcoding two parent
traversals, and the allowlist is refreshed with all pre-existing raw
fetch callsites that became visible.
* fix(qqbot): guard image-size probe against SSRF (#63495) (thanks @dims)
---------
Co-authored-by: sliverp <870080352@qq.com>