feat(server): support restoring and listing archived sessions#1071
Open
sailist wants to merge 92 commits into
Open
feat(server): support restoring and listing archived sessions#1071sailist wants to merge 92 commits into
sailist wants to merge 92 commits into
Conversation
- run the supervised server via `server run --foreground` (default `server run` now spawns a detached daemon) - schtasks: use the absolute exe path and redirect stdout/stderr to the log file via cmd.exe - systemd: route stdout/stderr to the log file via StandardOutput=append - systemd: enable loginctl linger on install so the user service survives logout; report linger state in status
- add I...Service interface, createDecorator token, and ...Service subclass for each manager\n- switch Agent and KimiCore to instantiate and reference service interfaces\n- add unwrap() migration bridge for call sites that still need the raw manager\n- update tests to construct service classes and interface types
construct Agent and Session services via InstantiationService child scopes\nregister per-agent services (records, compaction, context, turn, etc.) as SyncDescriptors in a ServiceCollection\nregister session services (hooks, skill registry, MCP connection) the same way\nthread an optional instantiationService through KimiCore, Session, and Agent options\nexport service interfaces as values so they can serve as DI identifiers
- inject IRecordsService through DI instead of reading agent.records\n- accept emitStatusUpdated as a callback instead of the Agent instance
- goal, plan, swarm and replay services take explicit deps instead of Agent\n- inject records/replay/context/config via DI decorators\n- pass telemetry, kaos, homedir and emit callbacks as constructor args\n- update agent service registration and affected tests
- add AgentEventBus pub/sub service and route event emission through it - add LifecycleService with a beforePrompt hook for system reminders - move plan-mode reminders from PlanModeInjector onto the lifecycle hook - fire the beforePrompt hook in the turn loop before each step's prompt
- add onContextMessageRemoved lifecycle hook, fired when context drops a message - move beforePrompt firing from the turn loop into InjectionManager.inject - dedup plan-mode reminders into full/sparse/reentry variants by turn distance - track the injected reminder index and realign it on context message removal - use reentry reminder when re-entering plan mode with existing plan content
Add a vitest fence that scans packages/agent-core/src/{rpc,session,agent,di}
and forbids runtime modules from importing back into services/ (relative
paths or the @moonshot-ai/agent-core/services bare subpath), pinning the
rule from src/services/AGENTS.md. A pure exported findViolations helper is
driven by both the positive (real src) and negative (planted fixture) cases.
Co-Authored-By: Claude <noreply@anthropic.com>
Extend ILifecycleService/LifecycleService with additive session, agent, and turn hook pairs (onXxx/fireXxx) mirroring the existing Set<handler> + IDisposable + sequential-await pattern. onBeforePrompt and onContextMessageRemoved are unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
Append fireXxx calls at session, agent, and turn boundaries. Inject a session-scoped ILifecycleService into Session via the established DI accessor pattern; thread the agent id into Agent so it can fire agent hooks; fire turn hooks in runOneTurn (DidEnd in a finally). All fires are inert no-ops today (no subscribers); onBeforePrompt / onContextMessageRemoved call sites are untouched. Co-Authored-By: Claude <noreply@anthropic.com>
Introduce the per-session repository role for state.json persistence: ISessionRepository (read/write/flush) in services/session/session.ts and a SessionRepository implementation that mirrors Session.writeMetadata/readMetadata/flushMetadata byte-for-byte (same metadataPath, JSON.stringify indent, mkdir options, and serialized write chain). archive/restore/purge are deferred to M1.5 (archive IO lives in session-store.ts; restore/purge have no existing implementation). Adds 7 tests incl. concurrent-write serialization. Co-Authored-By: Claude <noreply@anthropic.com>
Add a normative note to services/AGENTS.md stating that repositories/indexes consumed directly by a runtime aggregate live in the runtime layer (e.g. src/session/sessionRepository.ts), since runtime must not import from services/. RPC/SDK-facing command/query/runtime facades stay under services/<domain>/ and depend on those runtime repositories (services->runtime allowed). Dependency direction is unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
Relocate ISessionRepository + SessionRepository from services/session/ to src/session/ so the runtime Session can depend on it without crossing the M0.1 dependency-direction fence (runtime must not import from services/). The interface now lives beside its implementation in src/session/sessionRepository.ts (no createDecorator - still a per-session plain class). Behavior is byte-for-byte identical: same metadataPath, JSON.stringify indent, mkdir options, and serialized write chain. Move the test to test/session/ and fix imports; remove the interface from services/session/session.ts (ISessionService et al. unchanged). Co-Authored-By: Claude <noreply@anthropic.com>
Session now constructs a per-session SessionRepository (same homedir + persistenceKaos as before) and delegates writeMetadata/readMetadata/flushMetadata to it. The method names and signatures are unchanged so all call sites (rpc/core-impl.ts, session/rpc.ts, and internal callers) keep compiling and behaving identically; readMetadata still assigns into this.metadata and returns it. Behavior is byte-for-byte identical because SessionRepository.write captures JSON.stringify(this.metadata, null, 2) synchronously and serializes writes through the same chained promise. The now-redundant writeMetadataPromise field and metadataPath getter are removed. Legal now that both Session and SessionRepository live in the runtime layer (no services/ import). Co-Authored-By: Claude <noreply@anthropic.com>
Split the session query path out of ISessionService into a new ISessionQueryService that serves list / count / listGlobal / listByWorkspace / listChildren / search from the SessionIndex read model (M1.2). Each query re-seeds a fresh index from core.rpc.listSessions so freshness matches today's per-call reads. - New sessionQueryService.ts: SessionQueryService facade. Cold path only (listSessions + per-row getSessionMetadata); never resumes an agent. - New sessionStatus.ts: shared, side-effect-free computeSessionStatus, applySessionTurnEvent and tryGetSessionMeta used by both SessionService and SessionQueryService (no duplicated status logic, no reach into SessionService privates). - session.ts: add ISessionQueryService + SessionSearchQuery. - sessionService.ts: re-route _computeStatus / _handleBusEvent / tryGetMeta through the shared helpers (behavior-preserving). - New sessionQueryService.test.ts (14 cases), including a no-agent-resume assertion. Byte-for-byte parity with today's SessionService.list is preserved by re-sorting with a comparator matching core.rpc.listSessions (updatedAt desc, createdAt desc, id asc) and mirroring the existing cursor pivot, page-size clamp, and post-hydration status filter. Co-Authored-By: Claude <noreply@anthropic.com>
…ervice SessionService.list and listChildren are now thin wrappers that delegate to the SessionQueryService facade (M1.3a). ISessionService.list and listChildren are marked @deprecated and point at ISessionQueryService; they will be removed in M7.1. SessionService composes a SessionQueryService from its own deps in the constructor (eager, so the facade's event-bus subscription sees every event and live status stays in lock-step with SessionService). It is disposed via this._register. Composition (rather than IInstantiationService resolution) keeps direct `new SessionService(...)` callers — notably the existing session-service.test.ts, which is outside this phase's allowlist — working without an ISessionQueryService stub. Command / single-entity methods (create, get, update, fork, createChild, getStatus, compact, undo, archive) stay on SessionService. Behavior is byte-for-byte identical (the existing 60 session-service cases pass unchanged). Removed the now-unused ListSessionsPayload import and the DEFAULT_PAGE_SIZE / MAX_PAGE_SIZE constants. Co-Authored-By: Claude <noreply@anthropic.com>
Keep a writer-synced SessionIndex read model current after every mutating
SessionService command (create/update/fork/createChild/compact/undo/archive)
by re-reading the affected summary via listSessions({ includeArchive: true })
and upserting it (removing when gone). create/fork/createChild continue to
publish event.session.created via emitCreated; no new protocol event types
are introduced for update/archive/compact/undo (none exist). The index is
exposed as a class-level SessionService.sessionIndex accessor (not on the
ISessionService command interface) for read-model consumers and tests.
Co-Authored-By: Claude <noreply@anthropic.com>
Introduce a unified IWorkspaceService facade that absorbs the workspace registry + root resolution + recent + browse surfaces previously split across IWorkspaceRegistry and IWorkspaceFsService. WorkspaceService is a pure facade: every method delegates to the injected registry / fs services, so no workspace logic is duplicated. - registry: list/get/createOrTouch/update/delete - root resolution: resolveRoot(workspaceId) -> workDir - recent: listRecent() (derived view over the registry's recency ordering, capped at RECENT_ROOTS_LIMIT; no new persistence) - browse: browse/home IWorkspaceRegistry / IWorkspaceFsService (and their impls and consumers) are left in place; consolidating those call sites is a later step. The new service is registered via registerSingleton and wired into the services + workspace barrels so the registration fires at runtime. Co-Authored-By: Claude <noreply@anthropic.com>
SessionHost now owns the agent registry (agents map + agentIdCounter + toolKaos) and the agent lifecycle (createMain/resume/close/closeForReload/instantiateAgent/readyAgents/resumePersistedAgent). Session keeps its identity (id, options, lifecycle, mcp, persistence, metadata) and delegates agent management to an internal SessionHost constructed with the few session-level deps it still needs (scope, logHandle, skillsReady, and a back-reference to the Session for metadata/systemContextKaos/SubagentHostService). M0.4 session lifecycle hooks keep firing at the same points. KimiCore.sessions stays Map<string, Session> and core-impl.ts is untouched (the switch is deferred to M1.7b). Behavior is byte-identical. Co-Authored-By: Claude <noreply@anthropic.com>
Switch KimiCore.sessions from Map<string, Session> to Map<string, SessionHost>. Construction stores session.host; read sites unwrap the owning Session via the host.session back-ref so SessionAPIImpl, rename/close/reload/fork/export keep operating on the same Session object. SessionHost.session is widened to a documented public accessor (the same deps.session object). Session's public surface is unchanged. Harness tests that reach into core.sessions for session-owned members (experimentalFlags/options/flushMetadata/skills) unwrap .session; host-level getReadyAgent calls and the busy-reload host identity assertion are left operating on hosts. SessionAPIImpl still takes a Session (unwrap at call sites).
Introduce the generic ScopeManager base + IManagerService contract for the di-v3 scope mechanism (per scope-mechanism.md). A manager lives in the parent scope, is the sole up-going event publisher for its children, attaches to a child via child.accessor.get(...) and re-emits collection-view events (adding the child id), and pairs disposeChild with onDidChildDispose + eventBus.publish in a try/finally. Children never reverse-call the manager's write methods. Publishes through a generic IManagerEventBus<TPublish> port so the scope mechanism stays decoupled from the rpc-coupled IDomainEventBus. Validated with a FakeManager/FakeChild test double (7 cases). Co-Authored-By: Claude <noreply@anthropic.com>
Validate the scope mechanism's Core-registration path with ILogService. agent-core ships no production ILogService adapter/registration (the server wires PinoLogger via services.set), so there was no registerSingleton(ILogService, ...) to replace. The new test (test/services/logger.test.ts) registers registerScopedService(Core, ILogService, FakeLogService, Delayed) — which aliases to registerSingleton — and asserts: Core-alias routing to the singleton registry, unchanged ILogService behavior (info/warn/error/debug + child bindings), resolution through a ScopeBuilder-built Session scope via the DI parent chain, and lazy (Delayed) construction. Production behavior is unchanged (no src change). Co-Authored-By: Claude <noreply@anthropic.com>
Add packages/agent-core/src/scope/index.ts as an explicit barrel for the di-v3 scope mechanism (LifecycleScope, registerScopedService / getScopedServiceDescriptors / markBuilt / isBuilt, IScopeHandle / IServiceAccessor, the ScopeBuilder family, the manager pattern base and contracts, and the I*Context identity decorators), then re-export it from the top-level index so the surface is reachable from @moonshot-ai/agent-core. The barrel is explicit (not export *) so internal helpers stay private, and a wildcard re-export at the top level is safe because none of the scope names collide with the existing top-level surface. Co-Authored-By: Claude <noreply@anthropic.com>
Move the DI container from src/di/ into the new infrastructure layer at src/_base/di/. Keep src/di/ as deprecated re-export aliases (removed in P9) so all ~86 consumers keep working unchanged. Fix the one intra-di import that pointed outside di/ (lifecycle.ts → ../../errors/unexpectedError). Zero behavior change. Co-Authored-By: Claude <noreply@anthropic.com>
…orts Delete the 13 deprecated re-export shims under src/di/ left by a86e55a and rewrite every consumer to the #/_base/di barrel (production) or the #/_base/di/test subpath (test utilities). No deep imports into _base/di/<submodule> remain except the sanctioned test subpath. - src/di/** removed (no re-export alias layer). - ~178 consumer import specifiers rewritten: 95 bare, 73 deep collapsed to the barrel, 10 routed to #/_base/di/test (incl. 2 _util imports). - _base/di/index.ts: add Trace, Graph (public symbols needed after the collapse); stays sinon-free, no test/testInstantiationService re-export. - _base/di/test.ts: re-export _util (test-only internal) so tests do not need to reach into the instantiation submodule. - package.json imports: add explicit "#/_base/di" -> src/_base/di/index.ts so the bare nested barrel resolves under vitest (the #/* wildcard's index fallback does not cover a nested "*"). - descriptor.test.ts: drop the obsolete "InstantiationType not re-exported from descriptors" guard (the barrel legitimately re-exports it; the descriptors submodule is no longer importable). typecheck + full test (3233 passed) + dependency-direction fence green; all five verification gates clean (0 hits). Co-Authored-By: Claude <noreply@anthropic.com>
Codify two architectural rules for the di-v3 refactor: - barrel-only exports: every layer (_base/<x>, _utils/<x>, <domain>) exposes its public surface only via index.ts; consumers import from the barrel, never deep-import submodules. - no re-import / re-export shims: migrations leave no old-path re-export aliases; consumers are fully rewritten to the new barrel in the same step, and the old path is deleted immediately. PLAN.md: §0.2 goals, §1.4 rejected alternatives, §2.3 barrel-only note, §5 acceptance. ROADMAP.md: Global constraints, P2 intro + P2.1/P2.2/P2.4/P2.5 rewritten to the new shape, P9.1 repurposed to a final import audit. Co-Authored-By: Claude <noreply@anthropic.com>
Move Event/Emitter from src/base/common/event.ts into the _base/ infrastructure layer as a barrel-only module, and delete the now-empty base/ tree. No re-export shim is left behind (per the amended plan). - src/_base/event/event.ts: pure move of the implementation (internal imports ../../errors/unexpectedError and ../../_base/di resolve identically from the new depth, so the file is unchanged). - src/_base/event/index.ts: new barrel exporting the full public surface (Event, Emitter). - 11 src + 2 test consumers rewritten to the _base/event barrel: src uses relative …/_base/event (matching the existing …/_base/di convention), tests use #/_base/event. No base/common/event or deep _base/event/<x> import remains. - src/index.ts: top-level Emitter re-export now points at ./_base/event; surrounding note updated to the new subpath. - package.json imports: add explicit "#/_base/event" -> src/_base/event/index.ts so the bare nested barrel resolves under vitest (the #/* wildcard's index fallback does not cover a nested "*"). typecheck + full test (3233 passed) + dependency-direction fence green; all three verification gates clean (0 hits, src/base absent). Co-Authored-By: Claude <noreply@anthropic.com>
Move the non-DI logging core (types/logger/formatter/sinks/resolve-config + barrel) into the _base/ layer. logging/ held no DI (ILogService lives in services/logger/), so the whole dir is sunk and deleted with no re-export shim. - git mv src/logging/ -> src/_base/logging/ (5 impl files R100; index.ts R075) - expand _base/logging/index.ts barrel to also export resolveLoggingConfig/ResolveLoggingInput (from resolve-config) and PENDING_MAX/RotatingFileSink (from sinks) so barrel-only consumption typechecks - rewrite 27 consumer files to the #/_base/logging barrel (or relative …/_base/logging); collapse src/index.ts deep ./logging/<x> re-exports to ./_base/logging (top-level surface unchanged) - add "#/_base/logging" to package.json imports (nested-barrel resolution) Gates: typecheck clean; vitest 3233 passed | 1 todo (baseline); dependency-direction fence 14/14. Verification gates literal-0 (no old bare/deep logging imports, no deep #/_base/logging/<x>, src/logging gone).
Move errors/unexpectedError.ts (onUnexpectedError / safelyCallListener / setUnexpectedErrorHandler / resetUnexpectedErrorHandler / UnexpectedErrorHandler) into the _base/ layer under the barrel-only / no-reexport-shim rule. - git mv src/errors/unexpectedError.ts -> src/_base/errors/unexpectedError.ts (R100); add src/_base/errors/index.ts barrel exporting the 5 symbols - drop the unexpectedError re-export block from src/errors/index.ts (Kimi codes/classes/serialize barrel intact) - add export * from './_base/errors' to src/index.ts (next to ./_base/di) so the package root surface is unchanged — setUnexpectedErrorHandler stays importable from @moonshot-ai/agent-core for server - rewrite 5 consumers to the #/_base/errors barrel (src: _base/di/lifecycle.ts, _base/event/event.ts; test: di/lifecycle.test.ts, errors/unexpectedError.test.ts, base/common/event.test.ts) - add "#/_base/errors" to package.json imports (nested-barrel resolution) Gates: agent-core typecheck clean; server typecheck clean (public API preserved); vitest 3233 passed | 1 todo (baseline); dependency-direction fence 14/14. Verification gates literal-0 (no errors/unexpectedError imports, no deep #/_base/errors/<x>, src/errors/unexpectedError.ts gone, root re-exports ./_base/errors).
Sink the pure-function utils/ tree into _utils/<topic>/ subdirs, each exposed only through an index.ts barrel (barrel-only, no re-export shim, full consumer rewrite, moved paths deleted). kosong-dependent tokens.ts + completion-budget.ts stay in utils/ for P3. Move map (9 files into 8 subdirs): - abort.ts → _utils/abort/ (#/_utils/abort) - fs.ts → _utils/fs/ (#/_utils/fs) - hero-slug.ts workdir-slug.ts → _utils/slug/ (#/_utils/slug, re-exports both) - xml-escape.ts → _utils/xml/ (#/_utils/xml) - render-prompt.ts→ _utils/template/ (#/_utils/template) - types.ts → _utils/types/ (#/_utils/types) - per-id-json-store.ts → _utils/persistence/ (#/_utils/persistence) - proxy.ts → _utils/net/ (#/_utils/net) Each _utils/<topic>/index.ts re-exports its module's full surface via export *. Intra-util cross-import (persistence → fs) repointed to the sibling barrel (../fs). 46 sunk-util import sites across 45 consumer files rewritten to the #/_utils/<topic> barrels. src/index.ts root re-export of installGlobalProxyDispatcher repointed to ./_utils/net. package.json imports: 8 explicit #/_utils/<x> entries added (chosen over the wildcard form to match the established #/_base/<x> convention; proven to resolve under both tsc and vitest). exports block untouched. Gates: agent-core typecheck 0, server typecheck 0, agent-core test 227 files / 3233 passed, dependency-direction fence 14 passed. Co-Authored-By: Claude <noreply@anthropic.com>
Rename the two stale di-v3 fence it() descriptions: the _utils ← _base ← domains layering rule and the cross-domain impl fence are now active assertions against the real tree (post P2.1-P2.5), not vacuously-clean placeholders. Add a comment noting isDiV3LayoutActive(SRC) is now true. Assertions unchanged; both return [] on the real tree (14/14 green). oxlint cannot express this rule (no import/no-restricted-paths or import/no-restricted-imports); the vitest fence remains the enforcement (deviation documented in STATUS). Co-Authored-By: Claude <noreply@anthropic.com>
Move the pure approval contract out of services/ into its own domain barrel. - git mv src/services/approval/approval.ts → src/approval/approval.ts; rewrite its infra imports to #/_base/di and #/rpc. - New src/approval/index.ts barrel exports the contract surface (IApprovalService, ApprovalRequest/ApprovalResponse types, and the renamed approvalToAgentCoreResponse / approvalToBrokerRequest / ApprovalToBrokerRequestParams helpers), mirroring the surface services/index.ts used to expose. No register* — approval is a pure contract (no impl, no tools). - Remove the approval re-exports from services/index.ts. - Repoint all consumers (5 production files, 8 test files) to #/approval. - Root barrel: add 'export * from "./approval"' (adjacent to the _base/errors anchor) so @moonshot-ai/agent-core's public surface is byte-for-byte unchanged for consumers like server — the established P2.4 precedent and documented P3.8 end state. - package.json: add explicit '#/approval' imports entry. The '#/' array-wildcard resolved for tsc but NOT for vitest, so the explicit entry is required for the test runner (recipe §4 ⑥). Gates: agent-core typecheck + test (3233 passed) + fence (14/14) pass; server typecheck passes (public surface preserved); services/approval and #/approval deep-import greps both 0. Co-Authored-By: Claude <noreply@anthropic.com>
Move the event contract (event.ts, IEventService) and impl (eventService.ts, EventService) out of services/ into the pre-existing src/event/ module, co-locating them with event-bus.ts and projection.ts. Add a src/event/index.ts barrel (IEventService, EventService, IDomainEventBus, DomainEventBus, shouldProjectToProtocol), repoint every consumer to #/event, and re-export ./event from the root barrel so @moonshot-ai/server keeps seeing IEventService / EventService. Register the explicit #/event imports entry (required for vitest). SyntheticPrompt* types stay in services/index.ts — they are prompt-domain (defined in prompt.ts, consumed only by prompt), not event. One fragile singleton-registry index-0 assertion in coreProcessService.test.ts is relaxed to a by-identifier lookup, since the new event barrel's registerSingleton shifts registration order. Gates: agent-core typecheck + test (3233 passed) + fence (14/14) clean; server typecheck clean; services/event and #/event/<file> greps at 0. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Move the coreProcess contract (coreProcess.ts — ICoreRuntime, CoreProcessServiceOptions), client (coreProcessClient.ts — BridgeClientAPI, CoreProcessClientDeps) and impl (coreProcessService.ts — CoreProcessService + its top-level registerSingleton) out of services/ into a fresh src/coreProcess/ module. Add a src/coreProcess/index.ts barrel mirroring the old services/index.ts:1-7 surface (BridgeClientAPI, CoreProcessClientDeps, ICoreRuntime, CoreProcessServiceOptions, CoreProcessService — impl included so its registerSingleton fires on barrel import, same as event). Repoint every consumer to #/coreProcess (13 production + 12 test, including multi-line import blocks), drop the coreProcess re-exports from services/index.ts, and delete the now-empty services/coreProcess/ dir. Root barrel src/index.ts gains export * from './coreProcess' (adjacent to the approval/event/question anchors) and package.json gains an explicit #/coreProcess imports entry (required for vitest) so @moonshot-ai/server keeps seeing CoreProcessService / ICoreRuntime / CoreProcessServiceOptions. Backward edges to the still-unmigrated auth/environment/logger services are repointed to relative ../services/<x>/<x> (fence-clean: coreProcess is not a runtime dir and services is in DIV3_RESERVED_DIRS); they will move to #/auth, #/environment, #/logger in P3.7. The session/provider-manager and rpc imports stay relative (../session/provider-manager is type-only; ../rpc is used instead of #/rpc because vitest cannot resolve the #/rpc wildcard for value imports and adding a #/rpc package.json entry is out of scope). No production registration-order change; the existing by-identifier singleton-registry assertion in coreProcessService.test.ts is unchanged, and the only production consumer (server serviceCollection) feeds an order-independent ServiceCollection. coreProcess is not explicitly listed in ROADMAP P3.7 (plan gap); the di-v3 end state empties services/ and P3.1 (session) needs this upstream contract migrated first, so src/coreProcess/ is the correct home. Proceeded and documented, not a BLOCKER. Gates: agent-core typecheck + test (3233 passed) + fence (14/14) clean; server typecheck clean; services/coreProcess and #/coreProcess/<file> greps at 0. Co-Authored-By: Claude <noreply@anthropic.com>
Move services/message/{message.ts,messageService.ts,transcript.ts} to
src/message/ with a barrel mirroring the old services/index.ts surface,
repoint consumers to #/message, add the #/message imports entry, and
re-export from the package root so the server surface is preserved. The
impl's top-level registerSingleton still fires on barrel import (mirrors
coreProcess). The lone backward edge to session (still in services/) stays
relative (../services/session/session) and fence-clean.
Co-Authored-By: Claude <noreply@anthropic.com>
Move services/prompt/{prompt.ts,promptService.ts} to src/prompt/ with a
barrel mirroring the old services/index.ts surface, repoint all consumers
to #/prompt, add the #/prompt imports entry, and re-export from the package
root so the server surface is preserved. The impl's top-level
registerSingleton still fires on barrel import (mirrors message/coreProcess).
Backward edges to the still-unmigrated authSummary/logger/session stay
relative (../services/<x>/<x>) and fence-clean. The SyntheticPrompt* event
types and AgentStateSnapshot/AgentStatePatch (defined in prompt.ts) move
with the domain and are exported from the new barrel; SessionBusyError is
kept on the surface for server's prompts route.
Co-Authored-By: Claude <noreply@anthropic.com>
Move src/services/session/* (6 files: contract + SessionService / SessionQueryService / SessionRuntimeService / SessionIndex + status helpers) into the existing runtime module src/session/. Barrel-only, no alias. Repoint all consumers (incl. the message + prompt backward edges) to #/session. Remove session re-exports from services/index.ts; add #/session to package.json imports. Rule 1 stays clean (fence 14/14): session's impls already import their 6 upstream contracts from #/<domain> barrels, so the move into the runtime dir introduces no runtime→services violations. Co-Authored-By: Claude <noreply@anthropic.com>
- add a `:restore` session action that clears the archived flag in state.json and returns the restored session - add an `archived_only` list query param, mutually exclusive with `include_archive`, that post-filters to archived sessions - keep the implementation in the server layer as a temporary measure until agent-core exposes restore natively
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
🦋 Changeset detectedLatest commit: f98edca The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue
No linked issue; the problem is described below.
Problem
Archived sessions could be included in session listings, but server clients had no API to restore an archived session or to query only archived sessions. That blocks the web archive/resume flow, where the UI needs to bring an archived session back before resuming it.
What changed
1. Restore archived sessions through the server API
Problem: Clients could see archived sessions but could not restore them through the server.
What was done:
2. List only archived sessions
Problem: The existing list API could include archived sessions, but it could not filter to archived sessions only.
What was done:
archived_onlylist query parameter.include_archiveto avoid ambiguous list semantics.3. Groundwork carried on this branch
Problem: The archived-session server work sits on top of the in-process core architecture used by the server.
What was done:
Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.