@cleocode/cleo 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/cli/index.js CHANGED
@@ -199,6 +199,39 @@ var init_exit_codes = __esm({
199
199
  }
200
200
  });
201
201
 
202
+ // packages/contracts/src/facade.ts
203
+ var BRAIN_OBSERVATION_TYPES, AGENT_INSTANCE_STATUSES, AGENT_TYPES;
204
+ var init_facade = __esm({
205
+ "packages/contracts/src/facade.ts"() {
206
+ "use strict";
207
+ BRAIN_OBSERVATION_TYPES = [
208
+ "discovery",
209
+ "change",
210
+ "feature",
211
+ "bugfix",
212
+ "decision",
213
+ "refactor"
214
+ ];
215
+ AGENT_INSTANCE_STATUSES = [
216
+ "starting",
217
+ "active",
218
+ "idle",
219
+ "error",
220
+ "crashed",
221
+ "stopped"
222
+ ];
223
+ AGENT_TYPES = [
224
+ "orchestrator",
225
+ "executor",
226
+ "researcher",
227
+ "architect",
228
+ "validator",
229
+ "documentor",
230
+ "custom"
231
+ ];
232
+ }
233
+ });
234
+
202
235
  // packages/contracts/src/lafs.ts
203
236
  function isLafsSuccess(envelope) {
204
237
  return envelope.success === true;
@@ -489,6 +522,7 @@ var init_src = __esm({
489
522
  "packages/contracts/src/index.ts"() {
490
523
  init_errors();
491
524
  init_exit_codes();
525
+ init_facade();
492
526
  init_lafs();
493
527
  init_operations();
494
528
  init_session2();
@@ -8915,12 +8949,12 @@ var init_status_registry2 = __esm({
8915
8949
 
8916
8950
  // packages/core/src/agents/agent-schema.ts
8917
8951
  import { sql as sql2 } from "drizzle-orm";
8918
- var AGENT_INSTANCE_STATUSES, AGENT_TYPES, agentInstances, agentErrorLog;
8952
+ var AGENT_INSTANCE_STATUSES2, AGENT_TYPES2, agentInstances, agentErrorLog;
8919
8953
  var init_agent_schema = __esm({
8920
8954
  "packages/core/src/agents/agent-schema.ts"() {
8921
8955
  "use strict";
8922
8956
  init_sqlite_core();
8923
- AGENT_INSTANCE_STATUSES = [
8957
+ AGENT_INSTANCE_STATUSES2 = [
8924
8958
  "starting",
8925
8959
  "active",
8926
8960
  "idle",
@@ -8928,7 +8962,7 @@ var init_agent_schema = __esm({
8928
8962
  "crashed",
8929
8963
  "stopped"
8930
8964
  ];
8931
- AGENT_TYPES = [
8965
+ AGENT_TYPES2 = [
8932
8966
  "orchestrator",
8933
8967
  "executor",
8934
8968
  "researcher",
@@ -8941,8 +8975,8 @@ var init_agent_schema = __esm({
8941
8975
  "agent_instances",
8942
8976
  {
8943
8977
  id: text("id").primaryKey(),
8944
- agentType: text("agent_type", { enum: AGENT_TYPES }).notNull(),
8945
- status: text("status", { enum: AGENT_INSTANCE_STATUSES }).notNull().default("starting"),
8978
+ agentType: text("agent_type", { enum: AGENT_TYPES2 }).notNull(),
8979
+ status: text("status", { enum: AGENT_INSTANCE_STATUSES2 }).notNull().default("starting"),
8946
8980
  // T033: FK constraints enforced at DB level by migration; kept soft here
8947
8981
  // to avoid circular dependency with tasks-schema.ts (which imports agent-schema.ts).
8948
8982
  // The migration SQL adds: session_id -> sessions ON DELETE SET NULL,
@@ -9042,8 +9076,8 @@ var init_chain_schema = __esm({
9042
9076
  var tasks_schema_exports = {};
9043
9077
  __export(tasks_schema_exports, {
9044
9078
  ADR_STATUSES: () => ADR_STATUSES,
9045
- AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
9046
- AGENT_TYPES: () => AGENT_TYPES,
9079
+ AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES2,
9080
+ AGENT_TYPES: () => AGENT_TYPES2,
9047
9081
  EXTERNAL_LINK_TYPES: () => EXTERNAL_LINK_TYPES,
9048
9082
  GATE_STATUSES: () => GATE_STATUSES,
9049
9083
  LIFECYCLE_EVIDENCE_TYPES: () => LIFECYCLE_EVIDENCE_TYPES,
@@ -10473,7 +10507,7 @@ __export(brain_schema_exports, {
10473
10507
  BRAIN_MEMORY_TYPES: () => BRAIN_MEMORY_TYPES,
10474
10508
  BRAIN_NODE_TYPES: () => BRAIN_NODE_TYPES,
10475
10509
  BRAIN_OBSERVATION_SOURCE_TYPES: () => BRAIN_OBSERVATION_SOURCE_TYPES,
10476
- BRAIN_OBSERVATION_TYPES: () => BRAIN_OBSERVATION_TYPES,
10510
+ BRAIN_OBSERVATION_TYPES: () => BRAIN_OBSERVATION_TYPES2,
10477
10511
  BRAIN_OUTCOME_TYPES: () => BRAIN_OUTCOME_TYPES,
10478
10512
  BRAIN_PATTERN_TYPES: () => BRAIN_PATTERN_TYPES,
10479
10513
  BRAIN_STICKY_COLORS: () => BRAIN_STICKY_COLORS,
@@ -10490,7 +10524,7 @@ __export(brain_schema_exports, {
10490
10524
  brainStickyNotes: () => brainStickyNotes
10491
10525
  });
10492
10526
  import { sql as sql5 } from "drizzle-orm";
10493
- 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;
10527
+ 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;
10494
10528
  var init_brain_schema = __esm({
10495
10529
  "packages/core/src/store/brain-schema.ts"() {
10496
10530
  "use strict";
@@ -10518,7 +10552,7 @@ var init_brain_schema = __esm({
10518
10552
  "informed_by",
10519
10553
  "contradicts"
10520
10554
  ];
10521
- BRAIN_OBSERVATION_TYPES = [
10555
+ BRAIN_OBSERVATION_TYPES2 = [
10522
10556
  "discovery",
10523
10557
  "change",
10524
10558
  "feature",
@@ -10607,7 +10641,7 @@ var init_brain_schema = __esm({
10607
10641
  "brain_observations",
10608
10642
  {
10609
10643
  id: text("id").primaryKey(),
10610
- type: text("type", { enum: BRAIN_OBSERVATION_TYPES }).notNull(),
10644
+ type: text("type", { enum: BRAIN_OBSERVATION_TYPES2 }).notNull(),
10611
10645
  title: text("title").notNull(),
10612
10646
  subtitle: text("subtitle"),
10613
10647
  narrative: text("narrative"),
@@ -16861,8 +16895,8 @@ var init_retry = __esm({
16861
16895
  // packages/core/src/agents/index.ts
16862
16896
  var agents_exports = {};
16863
16897
  __export(agents_exports, {
16864
- AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
16865
- AGENT_TYPES: () => AGENT_TYPES,
16898
+ AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES2,
16899
+ AGENT_TYPES: () => AGENT_TYPES2,
16866
16900
  DEFAULT_RETRY_POLICY: () => DEFAULT_RETRY_POLICY,
16867
16901
  HEARTBEAT_INTERVAL_MS: () => HEARTBEAT_INTERVAL_MS,
16868
16902
  MAX_TASKS_PER_AGENT: () => MAX_TASKS_PER_AGENT,
@@ -64178,7 +64212,7 @@ var init_validation_schemas = __esm({
64178
64212
  externalLinkTypeSchema = external_exports.enum(EXTERNAL_LINK_TYPES);
64179
64213
  syncDirectionSchema = external_exports.enum(SYNC_DIRECTIONS);
64180
64214
  lifecycleTransitionTypeSchema = external_exports.enum(LIFECYCLE_TRANSITION_TYPES);
64181
- brainObservationTypeSchema = external_exports.enum(BRAIN_OBSERVATION_TYPES);
64215
+ brainObservationTypeSchema = external_exports.enum(BRAIN_OBSERVATION_TYPES2);
64182
64216
  brainObservationSourceTypeSchema = external_exports.enum(BRAIN_OBSERVATION_SOURCE_TYPES);
64183
64217
  brainDecisionTypeSchema = external_exports.enum(BRAIN_DECISION_TYPES);
64184
64218
  brainConfidenceLevelSchema = external_exports.enum(BRAIN_CONFIDENCE_LEVELS);
@@ -64348,8 +64382,8 @@ var init_validation_schemas = __esm({
64348
64382
  );
64349
64383
  insertAgentErrorLogSchema = createInsertSchema2(agentErrorLog);
64350
64384
  selectAgentErrorLogSchema = createSelectSchema2(agentErrorLog);
64351
- agentInstanceStatusSchema = external_exports.enum(AGENT_INSTANCE_STATUSES);
64352
- agentTypeSchema = external_exports.enum(AGENT_TYPES);
64385
+ agentInstanceStatusSchema = external_exports.enum(AGENT_INSTANCE_STATUSES2);
64386
+ agentTypeSchema = external_exports.enum(AGENT_TYPES2);
64353
64387
  }
64354
64388
  });
64355
64389
 
@@ -67850,6 +67884,162 @@ var init_bootstrap = __esm({
67850
67884
  }
67851
67885
  });
67852
67886
 
67887
+ // packages/core/src/sessions/snapshot.ts
67888
+ async function serializeSession(projectRoot, options = {}, accessor) {
67889
+ const acc = accessor ?? await getAccessor(projectRoot);
67890
+ const maxObs = options.maxObservations ?? 10;
67891
+ const maxDescLen = options.maxDescriptionLength ?? 500;
67892
+ const sessions2 = await acc.loadSessions();
67893
+ let session;
67894
+ if (options.sessionId) {
67895
+ session = sessions2.find((s) => s.id === options.sessionId);
67896
+ } else {
67897
+ session = sessions2.filter((s) => s.status === "active").sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime())[0];
67898
+ }
67899
+ if (!session) {
67900
+ throw new CleoError(
67901
+ 31 /* SESSION_NOT_FOUND */,
67902
+ options.sessionId ? `Session '${options.sessionId}' not found` : "No active session to serialize",
67903
+ { fix: "Use 'cleo session list' to see available sessions" }
67904
+ );
67905
+ }
67906
+ const handoff = await computeHandoff(projectRoot, { sessionId: session.id });
67907
+ const decisionLog = await getDecisionLog(projectRoot, { sessionId: session.id });
67908
+ const decisions = decisionLog.map((d) => ({
67909
+ decision: d.decision,
67910
+ rationale: d.rationale,
67911
+ taskId: d.taskId,
67912
+ recordedAt: d.timestamp ?? (/* @__PURE__ */ new Date()).toISOString()
67913
+ }));
67914
+ let observations = [];
67915
+ try {
67916
+ const { searchBrainCompact: searchBrainCompact2 } = await Promise.resolve().then(() => (init_brain_retrieval(), brain_retrieval_exports));
67917
+ const results = await searchBrainCompact2(projectRoot, {
67918
+ query: session.id,
67919
+ limit: maxObs,
67920
+ tables: ["observations"]
67921
+ });
67922
+ if (Array.isArray(results)) {
67923
+ observations = results.map(
67924
+ (r) => ({
67925
+ id: r.id,
67926
+ text: r.text ?? "",
67927
+ type: r.type ?? "discovery",
67928
+ createdAt: r.createdAt ?? ""
67929
+ })
67930
+ );
67931
+ }
67932
+ } catch {
67933
+ }
67934
+ let activeTask = null;
67935
+ if (session.taskWork?.taskId) {
67936
+ try {
67937
+ const { tasks: tasks2 } = await acc.queryTasks({});
67938
+ const task = tasks2.find((t) => t.id === session.taskWork?.taskId);
67939
+ if (task) {
67940
+ const desc7 = task.description ?? "";
67941
+ activeTask = {
67942
+ taskId: task.id,
67943
+ title: task.title,
67944
+ status: task.status,
67945
+ priority: task.priority ?? "medium",
67946
+ description: desc7.length > maxDescLen ? desc7.slice(0, maxDescLen) + "..." : desc7,
67947
+ acceptance: Array.isArray(task.acceptance) ? task.acceptance.join("\n") : task.acceptance ?? void 0
67948
+ };
67949
+ }
67950
+ } catch {
67951
+ }
67952
+ }
67953
+ const startTime = new Date(session.startedAt).getTime();
67954
+ const now2 = Date.now();
67955
+ const durationMinutes = Math.round((now2 - startTime) / 6e4);
67956
+ return {
67957
+ version: SNAPSHOT_VERSION,
67958
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
67959
+ session,
67960
+ handoff,
67961
+ decisions,
67962
+ observations,
67963
+ activeTask,
67964
+ durationMinutes
67965
+ };
67966
+ }
67967
+ async function restoreSession(projectRoot, snapshot, options = {}, accessor) {
67968
+ if (snapshot.version > SNAPSHOT_VERSION) {
67969
+ throw new CleoError(
67970
+ 6 /* VALIDATION_ERROR */,
67971
+ `Snapshot version ${snapshot.version} is newer than supported version ${SNAPSHOT_VERSION}`,
67972
+ { fix: "Upgrade @cleocode/core to a newer version that supports this snapshot format" }
67973
+ );
67974
+ }
67975
+ const acc = accessor ?? await getAccessor(projectRoot);
67976
+ const activate = options.activate ?? true;
67977
+ if (activate) {
67978
+ const sessions2 = await acc.loadSessions();
67979
+ const scope = snapshot.session.scope;
67980
+ const activeConflict = sessions2.find(
67981
+ (s) => s.status === "active" && s.scope.type === scope.type && s.scope.epicId === scope.epicId && s.id !== snapshot.session.id
67982
+ );
67983
+ if (activeConflict) {
67984
+ throw new CleoError(
67985
+ 32 /* SCOPE_CONFLICT */,
67986
+ `Active session '${activeConflict.id}' already exists for scope ${scope.type}${scope.epicId ? ":" + scope.epicId : ""}`,
67987
+ {
67988
+ fix: `End the active session first with 'cleo session end' or restore without activating`,
67989
+ alternatives: [
67990
+ { action: "End conflicting session", command: "cleo session end" },
67991
+ { action: "Restore without activating", command: "Restore with activate: false" }
67992
+ ]
67993
+ }
67994
+ );
67995
+ }
67996
+ }
67997
+ const restoredSession = {
67998
+ ...snapshot.session,
67999
+ status: activate ? "active" : snapshot.session.status,
68000
+ notes: [
68001
+ ...snapshot.session.notes ?? [],
68002
+ `Restored from snapshot at ${(/* @__PURE__ */ new Date()).toISOString()} (captured ${snapshot.capturedAt}, duration ${snapshot.durationMinutes}m)`
68003
+ ],
68004
+ resumeCount: (snapshot.session.resumeCount ?? 0) + 1
68005
+ };
68006
+ if (options.agent) {
68007
+ restoredSession.agent = options.agent;
68008
+ restoredSession.notes = [
68009
+ ...restoredSession.notes ?? [],
68010
+ `Agent handoff: ${snapshot.session.agent ?? "unknown"} \u2192 ${options.agent}`
68011
+ ];
68012
+ }
68013
+ restoredSession.handoffJson = JSON.stringify(snapshot.handoff);
68014
+ await acc.upsertSingleSession(restoredSession);
68015
+ try {
68016
+ const { hooks: hooks2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
68017
+ await hooks2.dispatch("onSessionStart", projectRoot, {
68018
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
68019
+ sessionId: restoredSession.id,
68020
+ name: restoredSession.name,
68021
+ scope: restoredSession.scope,
68022
+ agent: restoredSession.agent,
68023
+ restored: true,
68024
+ snapshotCapturedAt: snapshot.capturedAt
68025
+ });
68026
+ } catch {
68027
+ }
68028
+ return restoredSession;
68029
+ }
68030
+ var SNAPSHOT_VERSION;
68031
+ var init_snapshot2 = __esm({
68032
+ "packages/core/src/sessions/snapshot.ts"() {
68033
+ "use strict";
68034
+ init_src();
68035
+ init_errors3();
68036
+ init_data_accessor();
68037
+ init_decisions();
68038
+ init_handoff();
68039
+ SNAPSHOT_VERSION = 1;
68040
+ }
68041
+ });
68042
+
67853
68043
  // packages/core/src/cleo.ts
67854
68044
  import path from "node:path";
67855
68045
  var Cleo;
@@ -67872,6 +68062,7 @@ var init_cleo = __esm({
67872
68062
  init_link_store();
67873
68063
  init_release2();
67874
68064
  init_sessions();
68065
+ init_snapshot2();
67875
68066
  init_sticky();
67876
68067
  init_data_accessor();
67877
68068
  init_task_work();
@@ -67981,7 +68172,15 @@ var init_cleo = __esm({
67981
68172
  recordAssumption: (p) => recordAssumption(root, p),
67982
68173
  contextDrift: (p) => getContextDrift(root, p),
67983
68174
  decisionLog: (p) => getDecisionLog(root, { sessionId: p?.sessionId, taskId: p?.taskId }),
67984
- lastHandoff: (scope) => getLastHandoff(root, scope)
68175
+ lastHandoff: (scope) => getLastHandoff(root, scope),
68176
+ serialize: (p) => serializeSession(root, {
68177
+ sessionId: p?.sessionId,
68178
+ maxObservations: p?.maxObservations
68179
+ }),
68180
+ restore: (snapshot, p) => restoreSession(root, snapshot, {
68181
+ agent: p?.agent,
68182
+ activate: p?.activate
68183
+ })
67985
68184
  };
67986
68185
  }
67987
68186
  // === Memory ===
@@ -68158,7 +68357,10 @@ var init_cleo = __esm({
68158
68357
  var src_exports = {};
68159
68358
  __export(src_exports, {
68160
68359
  ADR_STATUSES: () => ADR_STATUSES,
68360
+ AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
68361
+ AGENT_TYPES: () => AGENT_TYPES,
68161
68362
  AdapterManager: () => AdapterManager,
68363
+ BRAIN_OBSERVATION_TYPES: () => BRAIN_OBSERVATION_TYPES,
68162
68364
  CORE_PROTECTED_FILES: () => CORE_PROTECTED_FILES,
68163
68365
  Cleo: () => Cleo,
68164
68366
  CleoError: () => CleoError,
@@ -68334,6 +68536,7 @@ __export(src_exports, {
68334
68536
  remote: () => remote_exports,
68335
68537
  research: () => research_exports,
68336
68538
  resolveProjectPath: () => resolveProjectPath,
68539
+ restoreSession: () => restoreSession,
68337
68540
  resumeSession: () => resumeSession,
68338
68541
  roadmap: () => roadmap_exports,
68339
68542
  routing: () => routing_exports,
@@ -68350,6 +68553,7 @@ __export(src_exports, {
68350
68553
  selectSessionSchema: () => selectSessionSchema,
68351
68554
  selectTaskSchema: () => selectTaskSchema,
68352
68555
  sequence: () => sequence_exports,
68556
+ serializeSession: () => serializeSession,
68353
68557
  sessionStatus: () => sessionStatus,
68354
68558
  sessionStatusSchema: () => sessionStatusSchema,
68355
68559
  sessions: () => sessions_exports,
@@ -68460,6 +68664,7 @@ var init_src2 = __esm({
68460
68664
  init_migration();
68461
68665
  init_reconciliation();
68462
68666
  init_sessions();
68667
+ init_snapshot2();
68463
68668
  init_migrate();
68464
68669
  init_storage_preflight();
68465
68670
  init_task_work();
@@ -79133,9 +79338,12 @@ var init_plan = __esm({
79133
79338
  var internal_exports = {};
79134
79339
  __export(internal_exports, {
79135
79340
  ADR_STATUSES: () => ADR_STATUSES,
79341
+ AGENT_INSTANCE_STATUSES: () => AGENT_INSTANCE_STATUSES,
79342
+ AGENT_TYPES: () => AGENT_TYPES,
79136
79343
  ALL_VALID_STATUSES: () => ALL_VALID_STATUSES,
79137
79344
  AdapterManager: () => AdapterManager,
79138
79345
  AuditLogInsertSchema: () => AuditLogInsertSchema,
79346
+ BRAIN_OBSERVATION_TYPES: () => BRAIN_OBSERVATION_TYPES,
79139
79347
  BUILD_CONFIG: () => BUILD_CONFIG,
79140
79348
  CORE_PROTECTED_FILES: () => CORE_PROTECTED_FILES,
79141
79349
  Cleo: () => Cleo,
@@ -79705,6 +79913,7 @@ __export(internal_exports, {
79705
79913
  resolveTask: () => resolveTask,
79706
79914
  restoreBackup: () => restoreBackup,
79707
79915
  restoreFromBackup: () => restoreFromBackup,
79916
+ restoreSession: () => restoreSession,
79708
79917
  resumeSession: () => resumeSession,
79709
79918
  roadmap: () => roadmap_exports,
79710
79919
  rollbackRelease: () => rollbackRelease,
@@ -79732,6 +79941,7 @@ __export(internal_exports, {
79732
79941
  selectSessionSchema: () => selectSessionSchema,
79733
79942
  selectTaskSchema: () => selectTaskSchema,
79734
79943
  sequence: () => sequence_exports,
79944
+ serializeSession: () => serializeSession,
79735
79945
  sessionStatus: () => sessionStatus,
79736
79946
  sessionStatusSchema: () => sessionStatusSchema,
79737
79947
  sessions: () => sessions_exports,