@xemahq/agent-session-runtime 0.6.5 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // ═══════════════════════════════════════════════════════════════════════════
2
2
  // ── Agent → CompiledWorkspaceManifest reconstruction ──
3
3
  //
4
- // Phase 10 (`workspace-manifests-api` retirement). The composer turns a
4
+ // The composer turns a
5
5
  // `CompiledWorkspaceManifest` into a `WorkspaceMountPlan`; before this
6
6
  // module the only way to obtain that compiled manifest was to fetch the
7
7
  // `WorkspaceManifest` row from `workspace-manifests-api` and run
@@ -47,7 +47,7 @@ import {
47
47
  type ManifestSeedFile,
48
48
  type ManifestSubAgent,
49
49
  type ManifestWorkingFile,
50
- type WorkspaceManifest as DslWorkspaceManifest,
50
+ type AgentWorkspaceSpec as DslWorkspaceManifest,
51
51
  type WorkspaceManifestSpec,
52
52
  } from '@xemahq/dsl/workspace-manifest';
53
53
 
@@ -359,10 +359,19 @@ export function compileAgentWorkspaceManifest(
359
359
  metadata: {
360
360
  slug,
361
361
  version,
362
- // Agents resolved for a session bootstrap are, by definition,
363
- // agent-session compatible — the runtime EnvironmentResolver still
364
- // re-asserts `surfaceCompat` against the AGENT_SESSION surface.
365
- surfaceCompat: [ManifestSurface.AGENT_SESSION],
362
+ // A manifest RECONSTRUCTED from a bare `agentRef` carries no inherent
363
+ // surface restriction — the SAME agent (e.g. `demo-runner`,
364
+ // `requirements-coordinator`) is legitimately driven on BOTH the
365
+ // agent-session surface (interactive bootstrap) AND the workflow surface
366
+ // (pipeline `xema/agent@v1` jobs). Defaulting to AGENT_SESSION only made
367
+ // every workflow agent run fail `assertSurfaceCompat` with
368
+ // "surfaceCompat=[agent-session] but was resolved on 'workflow'". Mirror
369
+ // the DSL compiler's permissive `DEFAULT_SURFACE_COMPAT` ([workflow,
370
+ // agent-session]); the runtime EnvironmentResolver still re-asserts the
371
+ // ACTUAL surface, so widening the reconstructed set cannot let an agent
372
+ // run somewhere its real manifest forbids — an authored manifest that
373
+ // explicitly narrows `surfaceCompat` is parsed via the DSL path, not here.
374
+ surfaceCompat: [ManifestSurface.WORKFLOW, ManifestSurface.AGENT_SESSION],
366
375
  },
367
376
  spec,
368
377
  };
@@ -328,8 +328,8 @@ export class DefaultWorkspaceImageComposer implements WorkspaceImageComposer {
328
328
  // `/<skillKey>` in a session loads and applies that skill natively.
329
329
  //
330
330
  // Kernel-shipped System skills are PREPENDED to whatever skills the
331
- // caller already named in `agentContext.skills` (see
332
- // `.claude/rules/skills-and-composition.md` — `SkillSpace.System`
331
+ // caller already named in `agentContext.skills` (per the skill
332
+ // composition rules — `SkillSpace.System`
333
333
  // skills are auto-injected into every agent's mounted bundle).
334
334
  // `dedupe` collapses any overlap so a caller that re-mentions a
335
335
  // System skill in `agentContext.skills` does not double-mount it.
@@ -57,8 +57,8 @@ export enum DriftKind {
57
57
 
58
58
  /**
59
59
  * Advisory drift severity — `info` (benign) or `warning` (worth a look).
60
- * There is deliberately no `critical`: resume is non-blocking by design
61
- * (plan Epic D §D4), so severity only drives how the operator's drift
60
+ * There is deliberately no `critical`: resume is non-blocking by design,
61
+ * so severity only drives how the operator's drift
62
62
  * toast renders, never whether the session resumes.
63
63
  */
64
64
  export type DriftSeverity = 'info' | 'warning';
@@ -124,7 +124,7 @@ export interface EnvironmentResolverRequest {
124
124
  */
125
125
  readonly systemSkillSlugs?: readonly string[];
126
126
  /**
127
- * Optional MCP stanza resolver (Phase D1). Translates the manifest's
127
+ * Optional MCP stanza resolver. Translates the manifest's
128
128
  * `toolSelection` into a `mcpServers` map suitable for direct write
129
129
  * into `opencode.jsonc:mcp`. When absent, the resolved environment
130
130
  * carries no MCP stanzas — appropriate for workflow surfaces today
@@ -205,7 +205,7 @@ export interface ResolvedEnvironment {
205
205
  readonly mountPlan: WorkspaceMountPlan;
206
206
  readonly env: readonly { readonly name: string; readonly value: string }[];
207
207
  /**
208
- * Phase D1: resolved `mcpServers` map ready to drop into
208
+ * Resolved `mcpServers` map ready to drop into
209
209
  * `opencode.jsonc:mcp`. Empty `{}` when the manifest declares no
210
210
  * toolSelection or when the request omits an `mcpResolver`. Keeps
211
211
  * the snapshot self-contained so downstream callers (workflow
@@ -279,7 +279,7 @@ export class DefaultEnvironmentResolver implements EnvironmentResolver {
279
279
  req.briefcase?.mcpTools,
280
280
  );
281
281
 
282
- // Phase H.2: capability federation. When an `mcpResolver` is wired
282
+ // Capability federation. When an `mcpResolver` is wired
283
283
  // (session-boot, workflow-runtime-worker) the resolver ALWAYS runs —
284
284
  // the returned stanza is the fixed three meta-tool surface
285
285
  // (`xema-capabilities-{list,describe,invoke}`), regardless of
@@ -1,139 +1,30 @@
1
1
  // ═══════════════════════════════════════════════════════════════════════════
2
- // ── Agent-session lifecycle state machine ──
2
+ // ── Agent-session lifecycle state machine — re-export of the kernel SSOT ──
3
3
  //
4
- // Pure enums + transitions. Mirrors the `SessionStatus` enum persisted by
5
- // the agent-session-api service; the worker imports from here (the
6
- // service's persistence-layer enums are not importable across the apps
7
- // boundary).
4
+ // This file is a thin re-export surface. The closed `SessionLifecycleState` /
5
+ // `SessionOwnerKind` value sets, the transition FSM (`canTransition`), and the
6
+ // `isTerminal` / `isPausable` / `isResumable` predicates are the canonical
7
+ // Layer-0 contract owned by `@xemahq/kernel-contracts/agent-session`. The former
8
+ // hand-maintained copy that lived here was collapsed into that single source of
9
+ // truth; this module is retained ONLY so the package's public surface
10
+ // (re-exported from `src/index.ts`) is unchanged.
8
11
  //
9
- // Single source of truth for "can this session be paused right now?".
10
- // Both interactive-session callers AND the workflow-runtime-worker
11
- // dispatch activity consult `canTransition()` before issuing the HTTP
12
- // call so misuse fails fast at compile time rather than as a 409 from
13
- // the service.
12
+ // Prisma cannot import a TS value, so the agent-session-api schema re-declares
13
+ // the same members and CI guards parity
14
+ // (`tooling/boundaries/check-session-enum-parity.mjs`).
14
15
  // ═══════════════════════════════════════════════════════════════════════════
15
16
 
16
- /**
17
- * Lifecycle state of an agent-session row. Mirrors the persisted enum on
18
- * the agent-session-api service. Closed set.
19
- */
20
- export const SessionLifecycleState = {
21
- creating: 'creating',
22
- provisioning: 'provisioning',
23
- active: 'active',
24
- paused: 'paused',
25
- recovering: 'recovering',
26
- completing: 'completing',
27
- completed: 'completed',
28
- failed: 'failed',
29
- archived: 'archived',
30
- } as const;
31
-
32
- export type SessionLifecycleStateValue =
33
- (typeof SessionLifecycleState)[keyof typeof SessionLifecycleState];
34
-
35
- /**
36
- * Who created the session row. Mirrors the persisted `SessionOwnerKind`.
37
- *
38
- * - `interactive_session` — user-facing chat sessions
39
- * - `pipeline_run` — workflow-runtime-worker redraft loop spines
40
- * - `chat_thread` — reserved (no dispatcher today)
41
- *
42
- * The CI enum-parity check verifies this stays in lockstep with the
43
- * persisted enum.
44
- */
45
- export const SessionOwnerKind = {
46
- interactive_session: 'interactive_session',
47
- pipeline_run: 'pipeline_run',
48
- chat_thread: 'chat_thread',
49
- } as const;
50
-
51
- export type SessionOwnerKindValue =
52
- (typeof SessionOwnerKind)[keyof typeof SessionOwnerKind];
53
-
54
- /**
55
- * Per-state transition matrix. `canTransition(from, to)` returns true
56
- * iff the transition is valid.
57
- *
58
- * Notable transitions:
59
- * - `paused → recovering` (resume claim)
60
- * - `recovering → active` (resume success)
61
- * - `recovering → paused` (resume rollback)
62
- * - `active → completing → completed` (terminal success)
63
- * - any-non-terminal → `failed` (terminal failure)
64
- * - `paused | completed | failed → archived` (cleanup sweep)
65
- */
66
- const TRANSITIONS: Readonly<
67
- Record<SessionLifecycleStateValue, ReadonlySet<SessionLifecycleStateValue>>
68
- > = {
69
- creating: new Set([
70
- SessionLifecycleState.provisioning,
71
- SessionLifecycleState.failed,
72
- ]),
73
- provisioning: new Set([
74
- SessionLifecycleState.active,
75
- SessionLifecycleState.failed,
76
- ]),
77
- active: new Set([
78
- SessionLifecycleState.paused,
79
- SessionLifecycleState.completing,
80
- SessionLifecycleState.failed,
81
- ]),
82
- paused: new Set([
83
- SessionLifecycleState.recovering,
84
- SessionLifecycleState.archived,
85
- SessionLifecycleState.failed,
86
- ]),
87
- recovering: new Set([
88
- SessionLifecycleState.active,
89
- SessionLifecycleState.paused,
90
- SessionLifecycleState.failed,
91
- ]),
92
- completing: new Set([
93
- SessionLifecycleState.completed,
94
- SessionLifecycleState.failed,
95
- ]),
96
- completed: new Set([SessionLifecycleState.archived]),
97
- failed: new Set([SessionLifecycleState.archived]),
98
- archived: new Set(),
99
- };
100
-
101
- export function canTransition(
102
- from: SessionLifecycleStateValue,
103
- to: SessionLifecycleStateValue,
104
- ): boolean {
105
- return TRANSITIONS[from].has(to);
106
- }
107
-
108
- /**
109
- * Terminal states — no further transitions possible (except the
110
- * `completed | failed → archived` cleanup sweep). Callers use this to
111
- * short-circuit "is this session done?" checks.
112
- */
113
- export function isTerminal(state: SessionLifecycleStateValue): boolean {
114
- return (
115
- state === SessionLifecycleState.completed ||
116
- state === SessionLifecycleState.failed ||
117
- state === SessionLifecycleState.archived
118
- );
119
- }
120
-
121
- /**
122
- * Pausable states — the session has a live worker that can be told to
123
- * snapshot. `provisioning` is intentionally excluded: the worker isn't
124
- * ready yet, so a pause request would 409. Callers receiving such a
125
- * 409 should retry with backoff once `active` is reached.
126
- */
127
- export function isPausable(state: SessionLifecycleStateValue): boolean {
128
- return state === SessionLifecycleState.active;
129
- }
130
-
131
- /**
132
- * Resumable states. `paused` is the canonical case. `failed` rows are
133
- * NOT resumable from here — they require explicit operator action
134
- * (the resume API would 409). `recovering` is a transient state owned
135
- * by an in-flight resume; another caller observing it should back off.
136
- */
137
- export function isResumable(state: SessionLifecycleStateValue): boolean {
138
- return state === SessionLifecycleState.paused;
139
- }
17
+ export {
18
+ SessionLifecycleState,
19
+ SessionOwnerKind,
20
+ canTransition,
21
+ isTerminal,
22
+ isPausable,
23
+ isResumable,
24
+ SessionLifecycleStateSchema,
25
+ SessionOwnerKindSchema,
26
+ } from '@xemahq/kernel-contracts/agent-session';
27
+ export type {
28
+ SessionLifecycleStateValue,
29
+ SessionOwnerKindValue,
30
+ } from '@xemahq/kernel-contracts/agent-session';
@@ -1,7 +1,7 @@
1
1
  // ═══════════════════════════════════════════════════════════════════════════
2
2
  // ── Skill-bundle-backed TemplateResolver ──
3
3
  //
4
- // Phase 10 (workspace-manifests-api retirement). Seed-file templates used to
4
+ // Seed-file templates used to
5
5
  // live in `workspace-manifests-api` (the `workspace_manifest_templates` table)
6
6
  // and were fetched by name. They are now SKILL-BUNDLE RESOURCES served by
7
7
  // `skill-registry-api` (`GET /skills/bundle`): a biome that ships templates
package/src/lib/types.ts CHANGED
@@ -69,7 +69,7 @@ export interface ComposeWorkspaceImageRequest {
69
69
  readonly templateResolver?: TemplateResolver;
70
70
  /**
71
71
  * Kernel-shipped System-scope skill slugs to PREPEND to the composer's
72
- * mounted skill set. Per `.claude/rules/skills-and-composition.md`,
72
+ * mounted skill set. Per the skill composition rules,
73
73
  * skills owned by `SkillSpace.System` are auto-injected into every
74
74
  * agent's mounted bundle — they ship from `@xemahq/system-skills`
75
75
  * via the System-tier seeder in `skill-registry-api`. The caller