@cleocode/core 2026.3.70 → 2026.3.72

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.
package/dist/index.js CHANGED
@@ -198,6 +198,39 @@ var init_exit_codes = __esm({
198
198
  }
199
199
  });
200
200
 
201
+ // packages/contracts/src/facade.ts
202
+ var BRAIN_OBSERVATION_TYPES, AGENT_INSTANCE_STATUSES, AGENT_TYPES;
203
+ var init_facade = __esm({
204
+ "packages/contracts/src/facade.ts"() {
205
+ "use strict";
206
+ BRAIN_OBSERVATION_TYPES = [
207
+ "discovery",
208
+ "change",
209
+ "feature",
210
+ "bugfix",
211
+ "decision",
212
+ "refactor"
213
+ ];
214
+ AGENT_INSTANCE_STATUSES = [
215
+ "starting",
216
+ "active",
217
+ "idle",
218
+ "error",
219
+ "crashed",
220
+ "stopped"
221
+ ];
222
+ AGENT_TYPES = [
223
+ "orchestrator",
224
+ "executor",
225
+ "researcher",
226
+ "architect",
227
+ "validator",
228
+ "documentor",
229
+ "custom"
230
+ ];
231
+ }
232
+ });
233
+
201
234
  // packages/contracts/src/lafs.ts
202
235
  function isLafsSuccess(envelope) {
203
236
  return envelope.success === true;
@@ -488,6 +521,7 @@ var init_src = __esm({
488
521
  "packages/contracts/src/index.ts"() {
489
522
  init_errors();
490
523
  init_exit_codes();
524
+ init_facade();
491
525
  init_lafs();
492
526
  init_operations();
493
527
  init_session2();
@@ -8914,12 +8948,12 @@ var init_status_registry2 = __esm({
8914
8948
 
8915
8949
  // packages/core/src/agents/agent-schema.ts
8916
8950
  import { sql as sql2 } from "drizzle-orm";
8917
- var AGENT_INSTANCE_STATUSES, AGENT_TYPES, agentInstances, agentErrorLog;
8951
+ var AGENT_INSTANCE_STATUSES2, AGENT_TYPES2, agentInstances, agentErrorLog;
8918
8952
  var init_agent_schema = __esm({
8919
8953
  "packages/core/src/agents/agent-schema.ts"() {
8920
8954
  "use strict";
8921
8955
  init_sqlite_core();
8922
- AGENT_INSTANCE_STATUSES = [
8956
+ AGENT_INSTANCE_STATUSES2 = [
8923
8957
  "starting",
8924
8958
  "active",
8925
8959
  "idle",
@@ -8927,7 +8961,7 @@ var init_agent_schema = __esm({
8927
8961
  "crashed",
8928
8962
  "stopped"
8929
8963
  ];
8930
- AGENT_TYPES = [
8964
+ AGENT_TYPES2 = [
8931
8965
  "orchestrator",
8932
8966
  "executor",
8933
8967
  "researcher",
@@ -8940,8 +8974,8 @@ var init_agent_schema = __esm({
8940
8974
  "agent_instances",
8941
8975
  {
8942
8976
  id: text("id").primaryKey(),
8943
- agentType: text("agent_type", { enum: AGENT_TYPES }).notNull(),
8944
- status: text("status", { enum: AGENT_INSTANCE_STATUSES }).notNull().default("starting"),
8977
+ agentType: text("agent_type", { enum: AGENT_TYPES2 }).notNull(),
8978
+ status: text("status", { enum: AGENT_INSTANCE_STATUSES2 }).notNull().default("starting"),
8945
8979
  // T033: FK constraints enforced at DB level by migration; kept soft here
8946
8980
  // to avoid circular dependency with tasks-schema.ts (which imports agent-schema.ts).
8947
8981
  // The migration SQL adds: session_id -> sessions ON DELETE SET NULL,
@@ -9041,8 +9075,8 @@ var init_chain_schema = __esm({
9041
9075
  var tasks_schema_exports = {};
9042
9076
  __export(tasks_schema_exports, {
9043
9077
  ADR_STATUSES: () => ADR_STATUSES,
9044
- AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
9045
- AGENT_TYPES: () => AGENT_TYPES,
9078
+ AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES2,
9079
+ AGENT_TYPES: () => AGENT_TYPES2,
9046
9080
  EXTERNAL_LINK_TYPES: () => EXTERNAL_LINK_TYPES,
9047
9081
  GATE_STATUSES: () => GATE_STATUSES,
9048
9082
  LIFECYCLE_EVIDENCE_TYPES: () => LIFECYCLE_EVIDENCE_TYPES,
@@ -10469,7 +10503,7 @@ __export(brain_schema_exports, {
10469
10503
  BRAIN_MEMORY_TYPES: () => BRAIN_MEMORY_TYPES,
10470
10504
  BRAIN_NODE_TYPES: () => BRAIN_NODE_TYPES,
10471
10505
  BRAIN_OBSERVATION_SOURCE_TYPES: () => BRAIN_OBSERVATION_SOURCE_TYPES,
10472
- BRAIN_OBSERVATION_TYPES: () => BRAIN_OBSERVATION_TYPES,
10506
+ BRAIN_OBSERVATION_TYPES: () => BRAIN_OBSERVATION_TYPES2,
10473
10507
  BRAIN_OUTCOME_TYPES: () => BRAIN_OUTCOME_TYPES,
10474
10508
  BRAIN_PATTERN_TYPES: () => BRAIN_PATTERN_TYPES,
10475
10509
  BRAIN_STICKY_COLORS: () => BRAIN_STICKY_COLORS,
@@ -10486,7 +10520,7 @@ __export(brain_schema_exports, {
10486
10520
  brainStickyNotes: () => brainStickyNotes
10487
10521
  });
10488
10522
  import { sql as sql5 } from "drizzle-orm";
10489
- var BRAIN_DECISION_TYPES, BRAIN_CONFIDENCE_LEVELS, BRAIN_OUTCOME_TYPES, BRAIN_PATTERN_TYPES, BRAIN_IMPACT_LEVELS, BRAIN_LINK_TYPES, BRAIN_OBSERVATION_TYPES, BRAIN_OBSERVATION_SOURCE_TYPES, BRAIN_MEMORY_TYPES, BRAIN_STICKY_STATUSES, BRAIN_STICKY_COLORS, BRAIN_STICKY_PRIORITIES, brainDecisions, brainPatterns, brainLearnings, brainObservations, brainStickyNotes, brainMemoryLinks, brainSchemaMeta, BRAIN_NODE_TYPES, BRAIN_EDGE_TYPES, brainPageNodes, brainPageEdges;
10523
+ var BRAIN_DECISION_TYPES, BRAIN_CONFIDENCE_LEVELS, BRAIN_OUTCOME_TYPES, BRAIN_PATTERN_TYPES, BRAIN_IMPACT_LEVELS, BRAIN_LINK_TYPES, BRAIN_OBSERVATION_TYPES2, BRAIN_OBSERVATION_SOURCE_TYPES, BRAIN_MEMORY_TYPES, BRAIN_STICKY_STATUSES, BRAIN_STICKY_COLORS, BRAIN_STICKY_PRIORITIES, brainDecisions, brainPatterns, brainLearnings, brainObservations, brainStickyNotes, brainMemoryLinks, brainSchemaMeta, BRAIN_NODE_TYPES, BRAIN_EDGE_TYPES, brainPageNodes, brainPageEdges;
10490
10524
  var init_brain_schema = __esm({
10491
10525
  "packages/core/src/store/brain-schema.ts"() {
10492
10526
  "use strict";
@@ -10514,7 +10548,7 @@ var init_brain_schema = __esm({
10514
10548
  "informed_by",
10515
10549
  "contradicts"
10516
10550
  ];
10517
- BRAIN_OBSERVATION_TYPES = [
10551
+ BRAIN_OBSERVATION_TYPES2 = [
10518
10552
  "discovery",
10519
10553
  "change",
10520
10554
  "feature",
@@ -10603,7 +10637,7 @@ var init_brain_schema = __esm({
10603
10637
  "brain_observations",
10604
10638
  {
10605
10639
  id: text("id").primaryKey(),
10606
- type: text("type", { enum: BRAIN_OBSERVATION_TYPES }).notNull(),
10640
+ type: text("type", { enum: BRAIN_OBSERVATION_TYPES2 }).notNull(),
10607
10641
  title: text("title").notNull(),
10608
10642
  subtitle: text("subtitle"),
10609
10643
  narrative: text("narrative"),
@@ -26997,8 +27031,8 @@ async function validateAllAdrs(projectRoot) {
26997
27031
  // packages/core/src/agents/index.ts
26998
27032
  var agents_exports = {};
26999
27033
  __export(agents_exports, {
27000
- AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
27001
- AGENT_TYPES: () => AGENT_TYPES,
27034
+ AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES2,
27035
+ AGENT_TYPES: () => AGENT_TYPES2,
27002
27036
  DEFAULT_RETRY_POLICY: () => DEFAULT_RETRY_POLICY,
27003
27037
  HEARTBEAT_INTERVAL_MS: () => HEARTBEAT_INTERVAL_MS,
27004
27038
  MAX_TASKS_PER_AGENT: () => MAX_TASKS_PER_AGENT,
@@ -62324,7 +62358,7 @@ var taskRelationTypeSchema = external_exports.enum(TASK_RELATION_TYPES);
62324
62358
  var externalLinkTypeSchema = external_exports.enum(EXTERNAL_LINK_TYPES);
62325
62359
  var syncDirectionSchema = external_exports.enum(SYNC_DIRECTIONS);
62326
62360
  var lifecycleTransitionTypeSchema = external_exports.enum(LIFECYCLE_TRANSITION_TYPES);
62327
- var brainObservationTypeSchema = external_exports.enum(BRAIN_OBSERVATION_TYPES);
62361
+ var brainObservationTypeSchema = external_exports.enum(BRAIN_OBSERVATION_TYPES2);
62328
62362
  var brainObservationSourceTypeSchema = external_exports.enum(BRAIN_OBSERVATION_SOURCE_TYPES);
62329
62363
  var brainDecisionTypeSchema = external_exports.enum(BRAIN_DECISION_TYPES);
62330
62364
  var brainConfidenceLevelSchema = external_exports.enum(BRAIN_CONFIDENCE_LEVELS);
@@ -62494,8 +62528,8 @@ var selectAgentInstanceSchema = createSelectSchema2(
62494
62528
  );
62495
62529
  var insertAgentErrorLogSchema = createInsertSchema2(agentErrorLog);
62496
62530
  var selectAgentErrorLogSchema = createSelectSchema2(agentErrorLog);
62497
- var agentInstanceStatusSchema = external_exports.enum(AGENT_INSTANCE_STATUSES);
62498
- var agentTypeSchema = external_exports.enum(AGENT_TYPES);
62531
+ var agentInstanceStatusSchema = external_exports.enum(AGENT_INSTANCE_STATUSES2);
62532
+ var agentTypeSchema = external_exports.enum(AGENT_TYPES2);
62499
62533
 
62500
62534
  // packages/core/src/validation/compliance.ts
62501
62535
  function checkManifestEntry(entry) {
@@ -65193,6 +65227,158 @@ init_brain_retrieval();
65193
65227
  init_brain_search();
65194
65228
  init_registry3();
65195
65229
  init_sessions();
65230
+
65231
+ // packages/core/src/sessions/snapshot.ts
65232
+ init_src();
65233
+ init_errors3();
65234
+ init_data_accessor();
65235
+ init_decisions();
65236
+ init_handoff();
65237
+ var SNAPSHOT_VERSION = 1;
65238
+ async function serializeSession(projectRoot, options = {}, accessor) {
65239
+ const acc = accessor ?? await getAccessor(projectRoot);
65240
+ const maxObs = options.maxObservations ?? 10;
65241
+ const maxDescLen = options.maxDescriptionLength ?? 500;
65242
+ const sessions2 = await acc.loadSessions();
65243
+ let session;
65244
+ if (options.sessionId) {
65245
+ session = sessions2.find((s) => s.id === options.sessionId);
65246
+ } else {
65247
+ session = sessions2.filter((s) => s.status === "active").sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime())[0];
65248
+ }
65249
+ if (!session) {
65250
+ throw new CleoError(
65251
+ 31 /* SESSION_NOT_FOUND */,
65252
+ options.sessionId ? `Session '${options.sessionId}' not found` : "No active session to serialize",
65253
+ { fix: "Use 'cleo session list' to see available sessions" }
65254
+ );
65255
+ }
65256
+ const handoff = await computeHandoff(projectRoot, { sessionId: session.id });
65257
+ const decisionLog = await getDecisionLog(projectRoot, { sessionId: session.id });
65258
+ const decisions = decisionLog.map((d) => ({
65259
+ decision: d.decision,
65260
+ rationale: d.rationale,
65261
+ taskId: d.taskId,
65262
+ recordedAt: d.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
65263
+ }));
65264
+ let observations = [];
65265
+ try {
65266
+ const { searchBrainCompact: searchBrainCompact2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
65267
+ const results = await searchBrainCompact2(projectRoot, {
65268
+ query: session.id,
65269
+ limit: maxObs,
65270
+ tables: ["observations"]
65271
+ });
65272
+ if (Array.isArray(results)) {
65273
+ observations = results.map(
65274
+ (r) => ({
65275
+ id: r.id,
65276
+ text: r.text ?? "",
65277
+ type: r.type ?? "discovery",
65278
+ createdAt: r.createdAt ?? ""
65279
+ })
65280
+ );
65281
+ }
65282
+ } catch {
65283
+ }
65284
+ let activeTask = null;
65285
+ if (session.taskWork?.taskId) {
65286
+ try {
65287
+ const { tasks: tasks2 } = await acc.queryTasks({});
65288
+ const task = tasks2.find((t) => t.id === session.taskWork?.taskId);
65289
+ if (task) {
65290
+ const desc5 = task.description ?? "";
65291
+ activeTask = {
65292
+ taskId: task.id,
65293
+ title: task.title,
65294
+ status: task.status,
65295
+ priority: task.priority ?? "medium",
65296
+ description: desc5.length > maxDescLen ? desc5.slice(0, maxDescLen) + "..." : desc5,
65297
+ acceptance: Array.isArray(task.acceptance) ? task.acceptance.join("\n") : task.acceptance ?? void 0
65298
+ };
65299
+ }
65300
+ } catch {
65301
+ }
65302
+ }
65303
+ const startTime = new Date(session.startedAt).getTime();
65304
+ const now = Date.now();
65305
+ const durationMinutes = Math.round((now - startTime) / 6e4);
65306
+ return {
65307
+ version: SNAPSHOT_VERSION,
65308
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
65309
+ session,
65310
+ handoff,
65311
+ decisions,
65312
+ observations,
65313
+ activeTask,
65314
+ durationMinutes
65315
+ };
65316
+ }
65317
+ async function restoreSession(projectRoot, snapshot, options = {}, accessor) {
65318
+ if (snapshot.version > SNAPSHOT_VERSION) {
65319
+ throw new CleoError(
65320
+ 6 /* VALIDATION_ERROR */,
65321
+ `Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION}`,
65322
+ { fix: "Upgrade @cleocode/core to a newer version that supports this snapshot format" }
65323
+ );
65324
+ }
65325
+ const acc = accessor ?? await getAccessor(projectRoot);
65326
+ const activate = options.activate ?? true;
65327
+ if (activate) {
65328
+ const sessions2 = await acc.loadSessions();
65329
+ const scope = snapshot.session.scope;
65330
+ const activeConflict = sessions2.find(
65331
+ (s) => s.status === "active" && s.scope.type === scope.type && s.scope.epicId === scope.epicId && s.id !== snapshot.session.id
65332
+ );
65333
+ if (activeConflict) {
65334
+ throw new CleoError(
65335
+ 32 /* SCOPE_CONFLICT */,
65336
+ `Active session '${activeConflict.id}' already exists for scope ${scope.type}${scope.epicId ? ":" + scope.epicId : ""}`,
65337
+ {
65338
+ fix: `End the active session first with 'cleo session end' or restore without activating`,
65339
+ alternatives: [
65340
+ { action: "End conflicting session", command: "cleo session end" },
65341
+ { action: "Restore without activating", command: "Restore with activate: false" }
65342
+ ]
65343
+ }
65344
+ );
65345
+ }
65346
+ }
65347
+ const restoredSession = {
65348
+ ...snapshot.session,
65349
+ status: activate ? "active" : snapshot.session.status,
65350
+ notes: [
65351
+ ...snapshot.session.notes ?? [],
65352
+ `Restored from snapshot at ${(/* @__PURE__ */ new Date()).toISOString()} (captured ${snapshot.capturedAt}, duration ${snapshot.durationMinutes}m)`
65353
+ ],
65354
+ resumeCount: (snapshot.session.resumeCount ?? 0) + 1
65355
+ };
65356
+ if (options.agent) {
65357
+ restoredSession.agent = options.agent;
65358
+ restoredSession.notes = [
65359
+ ...restoredSession.notes ?? [],
65360
+ `Agent handoff: ${snapshot.session.agent ?? "unknown"} \u2192 ${options.agent}`
65361
+ ];
65362
+ }
65363
+ restoredSession.handoffJson = JSON.stringify(snapshot.handoff);
65364
+ await acc.upsertSingleSession(restoredSession);
65365
+ try {
65366
+ const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
65367
+ await hooks2.dispatch("onSessionStart", projectRoot, {
65368
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
65369
+ sessionId: restoredSession.id,
65370
+ name: restoredSession.name,
65371
+ scope: restoredSession.scope,
65372
+ agent: restoredSession.agent,
65373
+ restored: true,
65374
+ snapshotCapturedAt: snapshot.capturedAt
65375
+ });
65376
+ } catch {
65377
+ }
65378
+ return restoredSession;
65379
+ }
65380
+
65381
+ // packages/core/src/cleo.ts
65196
65382
  init_data_accessor();
65197
65383
  init_add();
65198
65384
  init_complete();
@@ -65295,7 +65481,15 @@ var Cleo = class _Cleo {
65295
65481
  recordAssumption: (p) => recordAssumption(root, p),
65296
65482
  contextDrift: (p) => getContextDrift(root, p),
65297
65483
  decisionLog: (p) => getDecisionLog(root, { sessionId: p?.sessionId, taskId: p?.taskId }),
65298
- lastHandoff: (scope) => getLastHandoff(root, scope)
65484
+ lastHandoff: (scope) => getLastHandoff(root, scope),
65485
+ serialize: (p) => serializeSession(root, {
65486
+ sessionId: p?.sessionId,
65487
+ maxObservations: p?.maxObservations
65488
+ }),
65489
+ restore: (snapshot, p) => restoreSession(root, snapshot, {
65490
+ agent: p?.agent,
65491
+ activate: p?.activate
65492
+ })
65299
65493
  };
65300
65494
  }
65301
65495
  // === Memory ===
@@ -65476,7 +65670,10 @@ init_complete();
65476
65670
  init_update2();
65477
65671
  export {
65478
65672
  ADR_STATUSES,
65673
+ AGENT_INSTANCE_STATUSES,
65674
+ AGENT_TYPES,
65479
65675
  AdapterManager,
65676
+ BRAIN_OBSERVATION_TYPES,
65480
65677
  CORE_PROTECTED_FILES,
65481
65678
  Cleo,
65482
65679
  CleoError,
@@ -65652,6 +65849,7 @@ export {
65652
65849
  remote_exports as remote,
65653
65850
  research_exports as research,
65654
65851
  resolveProjectPath,
65852
+ restoreSession,
65655
65853
  resumeSession,
65656
65854
  roadmap_exports as roadmap,
65657
65855
  routing_exports as routing,
@@ -65668,6 +65866,7 @@ export {
65668
65866
  selectSessionSchema,
65669
65867
  selectTaskSchema,
65670
65868
  sequence_exports as sequence,
65869
+ serializeSession,
65671
65870
  sessionStatus,
65672
65871
  sessionStatusSchema,
65673
65872
  sessions_exports as sessions,