@openclawbrain/cli 0.4.34 → 0.4.36

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/src/index.js CHANGED
@@ -8108,10 +8108,12 @@ export { CONTRACT_IDS, buildNormalizedEventExport, createFeedbackEvent, createIn
8108
8108
  export { describeNormalizedEventExportObservability } from "@openclawbrain/event-export";
8109
8109
  export { describeCompileFallbackUsage } from "@openclawbrain/compiler";
8110
8110
  export { describeActivationObservability, inspectActivationState, rollbackActivePack } from "@openclawbrain/pack-format";
8111
- export { createOpenClawLocalSessionTail, OpenClawLocalSessionTail } from "./session-tail.js";
8112
- export { discoverOpenClawMainSessionStores, discoverOpenClawSessionStores, loadOpenClawSessionIndex, readOpenClawAcpStreamFile, readOpenClawSessionFile } from "./session-store.js";
8111
+ export { buildOpenClawSessionCorpusSnapshot, createOpenClawLocalSessionTail, OpenClawLocalSessionTail } from "./session-tail.js";
8112
+ export { discoverOpenClawMainSessionStores, discoverOpenClawSessionStores, hashOpenClawStableJson, loadOpenClawSessionIndex, readOpenClawAcpStreamFile, readOpenClawSessionFile, summarizeOpenClawSessionFile, summarizeOpenClawSessionIndex } from "./session-store.js";
8113
8113
  export { buildPassiveLearningSessionExportFromOpenClawSessionStore, buildPassiveLearningStoreExportFromOpenClawSessionIndex } from "./local-session-passive-learning.js";
8114
8114
  export { DEFAULT_OLLAMA_BASE_URL, DEFAULT_OLLAMA_TIMEOUT_MS, OllamaClient, OllamaClientError, createOllamaClient } from "./ollama-client.js";
8115
8115
  export { resolveActivationRoot } from "./resolve-activation-root.js";
8116
8116
  export { runDaemonCommand, parseDaemonArgs } from "./daemon.js";
8117
+ export { exportGraphifySourceBundle } from "./import-export.js";
8118
+ export { exportGraphifyMaintenanceDiff } from "./import-export.js";
8117
8119
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,30 @@
1
+ import { createHash } from "node:crypto";
1
2
  import { existsSync, readFileSync, readdirSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import path from "node:path";
4
5
  import { discoverOpenClawHomes } from "./openclaw-home-layout.js";
6
+
7
+ function stableJsonValue(value) {
8
+ if (value === null || typeof value !== "object") {
9
+ return value;
10
+ }
11
+ if (Array.isArray(value)) {
12
+ return value.map((entry) => stableJsonValue(entry));
13
+ }
14
+ const sorted = {};
15
+ for (const key of Object.keys(value).sort((left, right) => left.localeCompare(right))) {
16
+ sorted[key] = stableJsonValue(value[key]);
17
+ }
18
+ return sorted;
19
+ }
20
+
21
+ function stableJsonText(value) {
22
+ return JSON.stringify(stableJsonValue(value));
23
+ }
24
+
25
+ export function hashOpenClawStableJson(value) {
26
+ return `sha256:${createHash("sha256").update(stableJsonText(value)).digest("hex")}`;
27
+ }
5
28
  export function loadOpenClawSessionIndex(indexFilePath) {
6
29
  return parseJsonFile(indexFilePath);
7
30
  }
@@ -11,6 +34,20 @@ export function readOpenClawSessionFile(sessionFilePath) {
11
34
  export function readOpenClawAcpStreamFile(streamFilePath) {
12
35
  return readJsonlFile(streamFilePath, parseOpenClawAcpStreamRecord);
13
36
  }
37
+
38
+ export function summarizeOpenClawSessionIndex(index) {
39
+ return {
40
+ digest: hashOpenClawStableJson(index),
41
+ sessionCount: Object.keys(index).length,
42
+ };
43
+ }
44
+
45
+ export function summarizeOpenClawSessionFile(records) {
46
+ return {
47
+ digest: hashOpenClawStableJson(records),
48
+ recordCount: records.length,
49
+ };
50
+ }
14
51
  export function discoverOpenClawMainSessionStores(options = {}) {
15
52
  const candidateRoots = options.profileRoots !== undefined
16
53
  ? [...new Set(options.profileRoots.map((root) => path.resolve(root)))]
@@ -1,10 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { existsSync } from "node:fs";
3
3
  import path from "node:path";
4
- import { CONTRACT_IDS, createInteractionEvent, sortNormalizedEvents } from "@openclawbrain/contracts";
4
+ import { CONTRACT_IDS, buildNormalizedEventExport, createInteractionEvent, sortNormalizedEvents } from "@openclawbrain/contracts";
5
5
  import { scanSession } from "@openclawbrain/events";
6
6
  import { extractFeedbackEventsFromInteractionRecords } from "@openclawbrain/event-export";
7
- import { discoverOpenClawSessionStores, loadOpenClawSessionIndex, readOpenClawSessionFile } from "./session-store.js";
7
+ import { hashOpenClawStableJson, summarizeOpenClawSessionFile, summarizeOpenClawSessionIndex, discoverOpenClawSessionStores, loadOpenClawSessionIndex, readOpenClawSessionFile } from "./session-store.js";
8
8
  import { inspectOpenClawHome } from "./openclaw-home-layout.js";
9
9
  const DEFAULT_SCANNER_ID = "openclaw-local-session-tail";
10
10
  const DEFAULT_SCANNER_LANE = "local_session_tail";
@@ -262,6 +262,115 @@ function buildBridgeableEvents(scannedSession, observedAt) {
262
262
  function isInteractionEvent(event) {
263
263
  return event.contract === CONTRACT_IDS.interactionEvents;
264
264
  }
265
+
266
+ function hashSessionSnapshotSeed(seed) {
267
+ return hashOpenClawStableJson(seed);
268
+ }
269
+
270
+ function summarizeCorpusSource(change, sessionIndexDigest, sessionFileDigest) {
271
+ const scannedEventExport = change.scannedEventExport;
272
+ const interactionEvents = scannedEventExport?.interactionEvents ?? [];
273
+ const feedbackEvents = scannedEventExport?.feedbackEvents ?? [];
274
+ const eventDigest = interactionEvents.length + feedbackEvents.length === 0
275
+ ? null
276
+ : hashSessionSnapshotSeed({
277
+ interactionEvents,
278
+ feedbackEvents
279
+ });
280
+ const sourceSeed = {
281
+ sourceIndexPath: change.source.indexPath,
282
+ sessionKey: change.sessionKey,
283
+ sessionId: change.sessionId,
284
+ sessionFile: change.sessionFile,
285
+ sessionIndexDigest,
286
+ sessionFileDigest,
287
+ changeKind: change.changeKind,
288
+ rawRecordCount: change.rawRecordCount,
289
+ bridgedEventCount: change.bridgedEventCount,
290
+ eventDigest,
291
+ scannerDigest: scannedEventExport?.scanner?.sourceManifestDigest ?? null
292
+ };
293
+ return {
294
+ sourceId: `graphify-session-source:${hashSessionSnapshotSeed(sourceSeed).slice(0, 32)}`,
295
+ profileRoot: change.source.profileRoot,
296
+ agentId: change.source.agentId,
297
+ sessionsDir: change.source.sessionsDir,
298
+ sourceIndexPath: change.source.indexPath,
299
+ sessionKey: change.sessionKey,
300
+ sessionId: change.sessionId,
301
+ sessionFile: change.sessionFile,
302
+ sessionIndexDigest,
303
+ sessionFileDigest,
304
+ changeKind: change.changeKind,
305
+ rawRecordCount: change.rawRecordCount,
306
+ bridgedEventCount: change.bridgedEventCount,
307
+ eventDigest,
308
+ sourceManifestDigest: scannedEventExport?.scanner?.sourceManifestDigest ?? null,
309
+ scanner: scannedEventExport?.scanner ?? null,
310
+ warnings: [...(change.warnings ?? [])],
311
+ eventCounts: {
312
+ interaction: interactionEvents.length,
313
+ feedback: feedbackEvents.length,
314
+ total: interactionEvents.length + feedbackEvents.length
315
+ }
316
+ };
317
+ }
318
+
319
+ export function buildOpenClawSessionCorpusSnapshot(input = {}) {
320
+ const observedAt = normalizeIsoTimestamp(input.observedAt, new Date().toISOString());
321
+ const tail = createOpenClawLocalSessionTail({
322
+ ...(input.homeDir === undefined ? {} : { homeDir: input.homeDir }),
323
+ ...(input.profileRoots === undefined ? {} : { profileRoots: input.profileRoots }),
324
+ ...(input.cursor === undefined ? {} : { cursor: input.cursor }),
325
+ emitExistingOnFirstPoll: input.emitExistingOnFirstPoll !== false
326
+ });
327
+ const poll = tail.pollOnce({ observedAt });
328
+ const sourceSummaries = [];
329
+ const interactionEvents = [];
330
+ const feedbackEvents = [];
331
+ for (const change of poll.changes) {
332
+ const index = loadOpenClawSessionIndex(change.source.indexPath);
333
+ const sessionIndexDigest = summarizeOpenClawSessionIndex(index).digest;
334
+ const sessionFileDigest = change.sessionFile === null
335
+ ? null
336
+ : summarizeOpenClawSessionFile(readOpenClawSessionFile(change.sessionFile)).digest;
337
+ sourceSummaries.push(summarizeCorpusSource(change, sessionIndexDigest, sessionFileDigest));
338
+ if (change.scannedEventExport !== null) {
339
+ interactionEvents.push(...change.scannedEventExport.interactionEvents);
340
+ feedbackEvents.push(...change.scannedEventExport.feedbackEvents);
341
+ }
342
+ }
343
+ const sortedEvents = sortNormalizedEvents([...interactionEvents, ...feedbackEvents]);
344
+ const sortedInteractionEvents = sortedEvents.filter(isInteractionEvent);
345
+ const sortedFeedbackEvents = sortedEvents.filter((event) => !isInteractionEvent(event));
346
+ const normalizedEventExport = sortedEvents.length === 0
347
+ ? null
348
+ : buildNormalizedEventExport({
349
+ interactionEvents: sortedInteractionEvents,
350
+ feedbackEvents: sortedFeedbackEvents
351
+ });
352
+ const corpusDigest = hashSessionSnapshotSeed({
353
+ lane: poll.lane,
354
+ observedAt,
355
+ noopReason: poll.noopReason,
356
+ warnings: poll.warnings,
357
+ sourceSummaries,
358
+ normalizedEventExportDigest: normalizedEventExport?.provenance.exportDigest ?? null
359
+ });
360
+ return {
361
+ runtimeOwner: "openclaw",
362
+ lane: poll.lane,
363
+ observedAt,
364
+ poll,
365
+ sourceSummaries,
366
+ interactionEvents: sortedInteractionEvents,
367
+ feedbackEvents: sortedFeedbackEvents,
368
+ normalizedEventExport,
369
+ corpusDigest,
370
+ corpusId: `graphify-source-corpus:${corpusDigest.slice(0, 32)}`
371
+ };
372
+ }
373
+
265
374
  function buildScannerManifest(input) {
266
375
  const sourceManifestDigest = createHash("sha256")
267
376
  .update(JSON.stringify({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclawbrain/cli",
3
- "version": "0.4.34",
3
+ "version": "0.4.36",
4
4
  "description": "OpenClawBrain operator CLI package with install/status helpers, daemon controls, and import/export tooling.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -46,13 +46,13 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@openclawbrain/compiler": "0.3.5",
49
- "@openclawbrain/contracts": "^0.3.5",
50
- "@openclawbrain/events": "^0.3.4",
51
- "@openclawbrain/event-export": "^0.3.4",
52
- "@openclawbrain/learner": "^0.3.4",
53
- "@openclawbrain/pack-format": "^0.3.4",
54
- "@openclawbrain/provenance": "^0.3.4",
55
- "@openclawbrain/workspace-metadata": "^0.3.4"
49
+ "@openclawbrain/contracts": "0.3.5",
50
+ "@openclawbrain/events": "0.3.4",
51
+ "@openclawbrain/event-export": "0.3.4",
52
+ "@openclawbrain/learner": "0.3.4",
53
+ "@openclawbrain/pack-format": "0.3.4",
54
+ "@openclawbrain/provenance": "0.3.4",
55
+ "@openclawbrain/workspace-metadata": "0.3.4"
56
56
  },
57
57
  "bin": {
58
58
  "openclawbrain": "dist/src/cli.js",
@@ -60,7 +60,7 @@
60
60
  },
61
61
  "scripts": {
62
62
  "prepublishOnly": "npm run release:verify",
63
- "release:verify": "npm test && node ../../scripts/verify-openclaw-cli-package-tarball.mjs",
63
+ "release:verify": "cd ../.. && node scripts/verify-dependency-policy.mjs && node --test packages/cli/dist/test/*.test.js && node scripts/verify-openclaw-cli-package-tarball.mjs",
64
64
  "test": "node --test dist/test/*.test.js"
65
65
  }
66
66
  }