@clude/sdk 3.0.3 → 3.0.4

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/README.md CHANGED
@@ -471,7 +471,7 @@ Memories form a graph with typed bonds:
471
471
  This package also includes the full Clude bot — an autonomous AI agent on X ([@Cludebot](https://x.com/Cludebot)).
472
472
 
473
473
  ```bash
474
- git clone https://github.com/sebbsssss/cludebot.git
474
+ git clone https://github.com/sebbsssss/clude.git
475
475
  cd cludebot
476
476
  npm install
477
477
  cp .env.example .env # fill in API keys
package/dist/cli/index.js CHANGED
@@ -2143,7 +2143,7 @@ async function runInit() {
2143
2143
  }
2144
2144
  }
2145
2145
  console.log(`
2146
- ${c.dim}Docs: https://github.com/sebbsssss/cludebot${c.reset}`);
2146
+ ${c.dim}Docs: https://github.com/sebbsssss/clude${c.reset}`);
2147
2147
  console.log(` ${c.dim}Website: https://clude.io${c.reset}`);
2148
2148
  printDivider();
2149
2149
  console.log("");
@@ -2797,6 +2797,232 @@ var init_status = __esm({
2797
2797
  }
2798
2798
  });
2799
2799
 
2800
+ // packages/brain/src/memorypack/types.ts
2801
+ var MEMORYPACK_VERSION;
2802
+ var init_types = __esm({
2803
+ "packages/brain/src/memorypack/types.ts"() {
2804
+ "use strict";
2805
+ MEMORYPACK_VERSION = "0.1";
2806
+ }
2807
+ });
2808
+
2809
+ // packages/brain/src/memorypack/sign.ts
2810
+ function hashRecordLine(line) {
2811
+ const clean = line.replace(/\n$/, "");
2812
+ const hex = (0, import_crypto.createHash)("sha256").update(clean, "utf-8").digest("hex");
2813
+ return `sha256:${hex}`;
2814
+ }
2815
+ function signHash(hash, secretKey) {
2816
+ const messageBytes = Buffer.from(hash, "utf-8");
2817
+ const sig = import_tweetnacl.default.sign.detached(messageBytes, secretKey);
2818
+ return `base58:${bs58.encode(sig)}`;
2819
+ }
2820
+ function verifyHash(hash, signature, publicKey) {
2821
+ try {
2822
+ const messageBytes = Buffer.from(hash, "utf-8");
2823
+ const sigRaw = signature.startsWith("base58:") ? signature.slice("base58:".length) : signature;
2824
+ const sigBytes = bs58.decode(sigRaw);
2825
+ const pkBytes = bs58.decode(publicKey);
2826
+ return import_tweetnacl.default.sign.detached.verify(messageBytes, sigBytes, pkBytes);
2827
+ } catch {
2828
+ return false;
2829
+ }
2830
+ }
2831
+ var import_crypto, import_tweetnacl, bs58Module, bs58;
2832
+ var init_sign = __esm({
2833
+ "packages/brain/src/memorypack/sign.ts"() {
2834
+ "use strict";
2835
+ import_crypto = require("crypto");
2836
+ import_tweetnacl = __toESM(require("tweetnacl"));
2837
+ bs58Module = __toESM(require("bs58"));
2838
+ bs58 = bs58Module.default || bs58Module;
2839
+ }
2840
+ });
2841
+
2842
+ // packages/brain/src/memorypack/writer.ts
2843
+ function serializeRecord(record) {
2844
+ const KNOWN_ORDER = [
2845
+ "id",
2846
+ "created_at",
2847
+ "kind",
2848
+ "content",
2849
+ "tags",
2850
+ "importance",
2851
+ "source",
2852
+ "summary",
2853
+ "embedding",
2854
+ "embedding_model",
2855
+ "metadata",
2856
+ "access_count",
2857
+ "last_accessed_at",
2858
+ "parent_ids",
2859
+ "compacted_from",
2860
+ "blob_ref"
2861
+ ];
2862
+ const out = {};
2863
+ for (const k of KNOWN_ORDER) {
2864
+ if (record[k] !== void 0) out[k] = record[k];
2865
+ }
2866
+ const recAsUnknown = record;
2867
+ const unknownKeys = Object.keys(recAsUnknown).filter(
2868
+ (k) => !KNOWN_ORDER.includes(k)
2869
+ );
2870
+ for (const k of unknownKeys.sort()) {
2871
+ out[k] = recAsUnknown[k];
2872
+ }
2873
+ return JSON.stringify(out);
2874
+ }
2875
+ function writeMemoryPack(dir, records, opts, anchors) {
2876
+ (0, import_fs2.mkdirSync)(dir, { recursive: true });
2877
+ const manifest = {
2878
+ memorypack_version: MEMORYPACK_VERSION,
2879
+ producer: opts.producer,
2880
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
2881
+ record_count: records.length,
2882
+ record_schema: opts.record_schema,
2883
+ signature_algorithm: opts.secretKey ? "ed25519" : void 0,
2884
+ anchor_chain: opts.anchor_chain
2885
+ };
2886
+ (0, import_fs2.writeFileSync)((0, import_path3.join)(dir, "manifest.json"), JSON.stringify(manifest, null, 2));
2887
+ const recordLines = [];
2888
+ const sigs = [];
2889
+ for (const record of records) {
2890
+ const line = serializeRecord(record);
2891
+ recordLines.push(line);
2892
+ if (opts.secretKey && opts.producer.public_key) {
2893
+ const hash = hashRecordLine(line);
2894
+ const signature = signHash(hash, opts.secretKey);
2895
+ sigs.push({
2896
+ record_hash: hash,
2897
+ signature,
2898
+ algorithm: "ed25519",
2899
+ public_key: opts.producer.public_key
2900
+ });
2901
+ }
2902
+ }
2903
+ (0, import_fs2.writeFileSync)((0, import_path3.join)(dir, "records.jsonl"), recordLines.join("\n") + "\n");
2904
+ if (sigs.length > 0) {
2905
+ (0, import_fs2.writeFileSync)(
2906
+ (0, import_path3.join)(dir, "signatures.jsonl"),
2907
+ sigs.map((s) => JSON.stringify(s)).join("\n") + "\n"
2908
+ );
2909
+ }
2910
+ if (anchors && anchors.length > 0) {
2911
+ (0, import_fs2.writeFileSync)(
2912
+ (0, import_path3.join)(dir, "anchors.jsonl"),
2913
+ anchors.map((a) => JSON.stringify(a)).join("\n") + "\n"
2914
+ );
2915
+ }
2916
+ }
2917
+ var import_fs2, import_path3;
2918
+ var init_writer = __esm({
2919
+ "packages/brain/src/memorypack/writer.ts"() {
2920
+ "use strict";
2921
+ import_fs2 = require("fs");
2922
+ import_path3 = require("path");
2923
+ init_types();
2924
+ init_sign();
2925
+ }
2926
+ });
2927
+
2928
+ // packages/brain/src/memorypack/reader.ts
2929
+ function readMemoryPack(dir, opts = {}) {
2930
+ const warnings = [];
2931
+ const manifestPath = (0, import_path4.join)(dir, "manifest.json");
2932
+ if (!(0, import_fs3.existsSync)(manifestPath)) {
2933
+ throw new Error(`MemoryPack: manifest.json not found in ${dir}`);
2934
+ }
2935
+ const manifest = JSON.parse((0, import_fs3.readFileSync)(manifestPath, "utf-8"));
2936
+ if (!manifest.memorypack_version) {
2937
+ throw new Error("MemoryPack: manifest missing memorypack_version");
2938
+ }
2939
+ if (!manifest.memorypack_version.startsWith("0.")) {
2940
+ throw new Error(
2941
+ `MemoryPack: unsupported memorypack_version ${manifest.memorypack_version} (reader supports 0.x)`
2942
+ );
2943
+ }
2944
+ const recordsPath = (0, import_path4.join)(dir, "records.jsonl");
2945
+ if (!(0, import_fs3.existsSync)(recordsPath)) {
2946
+ throw new Error(`MemoryPack: records.jsonl not found in ${dir}`);
2947
+ }
2948
+ const recordLines = (0, import_fs3.readFileSync)(recordsPath, "utf-8").split("\n").filter((l) => l.length > 0);
2949
+ const records = [];
2950
+ const lineByHash = /* @__PURE__ */ new Map();
2951
+ for (const line of recordLines) {
2952
+ const rec = JSON.parse(line);
2953
+ records.push(rec);
2954
+ lineByHash.set(hashRecordLine(line), line);
2955
+ }
2956
+ if (records.length !== manifest.record_count) {
2957
+ warnings.push(`record_count mismatch: manifest ${manifest.record_count} vs jsonl ${records.length}`);
2958
+ }
2959
+ const verifiedRecords = /* @__PURE__ */ new Set();
2960
+ const sigsPath = (0, import_path4.join)(dir, "signatures.jsonl");
2961
+ const signaturesFilePresent = (0, import_fs3.existsSync)(sigsPath);
2962
+ if (signaturesFilePresent) {
2963
+ const sigLines = (0, import_fs3.readFileSync)(sigsPath, "utf-8").split("\n").filter((l) => l.length > 0);
2964
+ const pubkey = opts.publicKey ?? manifest.producer.public_key;
2965
+ if (!pubkey) {
2966
+ throw new Error("MemoryPack: signatures.jsonl present but no public_key in manifest");
2967
+ }
2968
+ const validSigHashes = /* @__PURE__ */ new Set();
2969
+ for (const line of sigLines) {
2970
+ const sig = JSON.parse(line);
2971
+ const ok = verifyHash(sig.record_hash, sig.signature, pubkey);
2972
+ if (!ok) {
2973
+ throw new Error(`MemoryPack: signature verification failed for ${sig.record_hash}`);
2974
+ }
2975
+ validSigHashes.add(sig.record_hash);
2976
+ }
2977
+ for (const recordHash of lineByHash.keys()) {
2978
+ if (!validSigHashes.has(recordHash)) {
2979
+ throw new Error(
2980
+ `MemoryPack: signature verification failed \u2014 record ${recordHash} has no matching signature`
2981
+ );
2982
+ }
2983
+ verifiedRecords.add(recordHash);
2984
+ }
2985
+ }
2986
+ const unsignedRecords = /* @__PURE__ */ new Set();
2987
+ if (!signaturesFilePresent) {
2988
+ for (const hash of lineByHash.keys()) unsignedRecords.add(hash);
2989
+ }
2990
+ if (opts.strictSignatures && unsignedRecords.size > 0) {
2991
+ throw new Error(
2992
+ `MemoryPack: strictSignatures=true but ${unsignedRecords.size} records are unsigned`
2993
+ );
2994
+ }
2995
+ const anchors = [];
2996
+ const anchorsPath = (0, import_path4.join)(dir, "anchors.jsonl");
2997
+ if ((0, import_fs3.existsSync)(anchorsPath)) {
2998
+ const anchorLines = (0, import_fs3.readFileSync)(anchorsPath, "utf-8").split("\n").filter((l) => l.length > 0);
2999
+ for (const line of anchorLines) {
3000
+ anchors.push(JSON.parse(line));
3001
+ }
3002
+ }
3003
+ return { manifest, records, verifiedRecords, unsignedRecords, anchors, warnings };
3004
+ }
3005
+ var import_fs3, import_path4;
3006
+ var init_reader = __esm({
3007
+ "packages/brain/src/memorypack/reader.ts"() {
3008
+ "use strict";
3009
+ import_fs3 = require("fs");
3010
+ import_path4 = require("path");
3011
+ init_sign();
3012
+ }
3013
+ });
3014
+
3015
+ // packages/brain/src/memorypack/index.ts
3016
+ var init_memorypack = __esm({
3017
+ "packages/brain/src/memorypack/index.ts"() {
3018
+ "use strict";
3019
+ init_types();
3020
+ init_writer();
3021
+ init_reader();
3022
+ init_sign();
3023
+ }
3024
+ });
3025
+
2800
3026
  // packages/brain/src/mcp/local-store.ts
2801
3027
  var local_store_exports = {};
2802
3028
  __export(local_store_exports, {
@@ -2809,22 +3035,22 @@ __export(local_store_exports, {
2809
3035
  localUpdate: () => localUpdate
2810
3036
  });
2811
3037
  function ensureDir() {
2812
- if (!(0, import_fs2.existsSync)(CLUDE_DIR2)) {
2813
- (0, import_fs2.mkdirSync)(CLUDE_DIR2, { recursive: true });
3038
+ if (!(0, import_fs4.existsSync)(CLUDE_DIR2)) {
3039
+ (0, import_fs4.mkdirSync)(CLUDE_DIR2, { recursive: true });
2814
3040
  }
2815
3041
  }
2816
3042
  function loadStore() {
2817
3043
  ensureDir();
2818
- if (!(0, import_fs2.existsSync)(MEMORIES_FILE2)) {
3044
+ if (!(0, import_fs4.existsSync)(MEMORIES_FILE2)) {
2819
3045
  return { version: 1, next_id: 1, memories: [] };
2820
3046
  }
2821
3047
  try {
2822
- const raw = (0, import_fs2.readFileSync)(MEMORIES_FILE2, "utf-8");
3048
+ const raw = (0, import_fs4.readFileSync)(MEMORIES_FILE2, "utf-8");
2823
3049
  const data = JSON.parse(raw);
2824
3050
  if (!data || !Array.isArray(data.memories)) {
2825
3051
  console.error("[clude-local] Warning: memories.json has invalid structure, starting fresh. Backup saved.");
2826
3052
  try {
2827
- (0, import_fs2.writeFileSync)(MEMORIES_FILE2 + ".bak", raw);
3053
+ (0, import_fs4.writeFileSync)(MEMORIES_FILE2 + ".bak", raw);
2828
3054
  } catch {
2829
3055
  }
2830
3056
  return { version: 1, next_id: 1, memories: [] };
@@ -2833,8 +3059,8 @@ function loadStore() {
2833
3059
  } catch (err) {
2834
3060
  console.error("[clude-local] Warning: failed to parse memories.json:", err.message);
2835
3061
  try {
2836
- const raw = (0, import_fs2.readFileSync)(MEMORIES_FILE2, "utf-8");
2837
- (0, import_fs2.writeFileSync)(MEMORIES_FILE2 + ".bak", raw);
3062
+ const raw = (0, import_fs4.readFileSync)(MEMORIES_FILE2, "utf-8");
3063
+ (0, import_fs4.writeFileSync)(MEMORIES_FILE2 + ".bak", raw);
2838
3064
  console.error("[clude-local] Backup saved to memories.json.bak");
2839
3065
  } catch {
2840
3066
  }
@@ -2844,8 +3070,8 @@ function loadStore() {
2844
3070
  function saveStore(store) {
2845
3071
  ensureDir();
2846
3072
  const tmpFile = MEMORIES_FILE2 + ".tmp";
2847
- (0, import_fs2.writeFileSync)(tmpFile, JSON.stringify(store, null, 2));
2848
- (0, import_fs2.renameSync)(tmpFile, MEMORIES_FILE2);
3073
+ (0, import_fs4.writeFileSync)(tmpFile, JSON.stringify(store, null, 2));
3074
+ (0, import_fs4.renameSync)(tmpFile, MEMORIES_FILE2);
2849
3075
  }
2850
3076
  function scoreRelevance(query, memory) {
2851
3077
  const queryTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
@@ -3031,14 +3257,14 @@ function localList(opts) {
3031
3257
  const start = (page - 1) * pageSize;
3032
3258
  return { memories: memories.slice(start, start + pageSize), total };
3033
3259
  }
3034
- var import_fs2, import_path3, CLUDE_DIR2, MEMORIES_FILE2;
3260
+ var import_fs4, import_path5, CLUDE_DIR2, MEMORIES_FILE2;
3035
3261
  var init_local_store = __esm({
3036
3262
  "packages/brain/src/mcp/local-store.ts"() {
3037
3263
  "use strict";
3038
- import_fs2 = require("fs");
3039
- import_path3 = require("path");
3040
- CLUDE_DIR2 = (0, import_path3.join)(process.env.HOME || process.env.USERPROFILE || ".", ".clude");
3041
- MEMORIES_FILE2 = (0, import_path3.join)(CLUDE_DIR2, "memories.json");
3264
+ import_fs4 = require("fs");
3265
+ import_path5 = require("path");
3266
+ CLUDE_DIR2 = (0, import_path5.join)(process.env.HOME || process.env.USERPROFILE || ".", ".clude");
3267
+ MEMORIES_FILE2 = (0, import_path5.join)(CLUDE_DIR2, "memories.json");
3042
3268
  }
3043
3269
  });
3044
3270
 
@@ -3679,11 +3905,12 @@ var init_text = __esm({
3679
3905
  });
3680
3906
 
3681
3907
  // packages/shared/src/utils/constants.ts
3682
- var MEMO_PROGRAM_ID, BOT_X_HANDLE, MEMORY_MIN_DECAY, MEMORY_MAX_CONTENT_LENGTH, MEMORY_MAX_SUMMARY_LENGTH, DECAY_RATES, RECENCY_DECAY_BASE, RETRIEVAL_WEIGHT_RECENCY, RETRIEVAL_WEIGHT_RELEVANCE, RETRIEVAL_WEIGHT_IMPORTANCE, RETRIEVAL_WEIGHT_VECTOR, KNOWLEDGE_TYPE_BOOST, VECTOR_MATCH_THRESHOLD, BOND_TYPE_WEIGHTS, RETRIEVAL_WEIGHT_GRAPH, RETRIEVAL_WEIGHT_COOCCURRENCE, LINK_SIMILARITY_THRESHOLD, MAX_AUTO_LINKS, LINK_CO_RETRIEVAL_BOOST, INTERNAL_MEMORY_SOURCES, INTERNAL_IMPORTANCE_BOOST, REFLECTION_MIN_INTERVAL_MS, WHALE_SELL_COOLDOWN_MS, MEMO_MAX_LENGTH;
3908
+ var MEMO_PROGRAM_ID, SOLSCAN_TX_BASE_URL, BOT_X_HANDLE, MEMORY_MIN_DECAY, MEMORY_MAX_CONTENT_LENGTH, MEMORY_MAX_SUMMARY_LENGTH, DECAY_RATES, RECENCY_DECAY_BASE, RETRIEVAL_WEIGHT_RECENCY, RETRIEVAL_WEIGHT_RELEVANCE, RETRIEVAL_WEIGHT_IMPORTANCE, RETRIEVAL_WEIGHT_VECTOR, KNOWLEDGE_TYPE_BOOST, VECTOR_MATCH_THRESHOLD, BOND_TYPE_WEIGHTS, RETRIEVAL_WEIGHT_GRAPH, RETRIEVAL_WEIGHT_COOCCURRENCE, LINK_SIMILARITY_THRESHOLD, MAX_AUTO_LINKS, LINK_CO_RETRIEVAL_BOOST, INTERNAL_MEMORY_SOURCES, INTERNAL_IMPORTANCE_BOOST, REFLECTION_MIN_INTERVAL_MS, WHALE_SELL_COOLDOWN_MS, MEMO_MAX_LENGTH;
3683
3909
  var init_constants = __esm({
3684
3910
  "packages/shared/src/utils/constants.ts"() {
3685
3911
  "use strict";
3686
3912
  MEMO_PROGRAM_ID = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
3913
+ SOLSCAN_TX_BASE_URL = "https://solscan.io/tx";
3687
3914
  BOT_X_HANDLE = process.env.BOT_X_HANDLE || "cludebot";
3688
3915
  MEMORY_MIN_DECAY = 0.05;
3689
3916
  MEMORY_MAX_CONTENT_LENGTH = 5e3;
@@ -3990,12 +4217,46 @@ var init_claude_client = __esm({
3990
4217
  });
3991
4218
 
3992
4219
  // packages/shared/src/core/solana-client.ts
4220
+ var solana_client_exports = {};
4221
+ __export(solana_client_exports, {
4222
+ _configureMemoryRegistry: () => _configureMemoryRegistry,
4223
+ _configureSolana: () => _configureSolana,
4224
+ getBotWallet: () => getBotWallet,
4225
+ getConnection: () => getConnection,
4226
+ initializeRegistry: () => initializeRegistry,
4227
+ isRegistryEnabled: () => isRegistryEnabled,
4228
+ parseMemoContentHash: () => parseMemoContentHash,
4229
+ registerMemoryOnChain: () => registerMemoryOnChain,
4230
+ solscanTxUrl: () => solscanTxUrl,
4231
+ verifyMemoTransaction: () => verifyMemoTransaction,
4232
+ verifyMemoryOnChain: () => verifyMemoryOnChain,
4233
+ verifySignature: () => verifySignature,
4234
+ writeMemo: () => writeMemo,
4235
+ writeMemoDevnet: () => writeMemoDevnet
4236
+ });
3993
4237
  function getConnection() {
3994
4238
  if (!connection) {
3995
4239
  connection = new import_web3.Connection(config.solana.rpcUrl, "confirmed");
3996
4240
  }
3997
4241
  return connection;
3998
4242
  }
4243
+ function _configureSolana(rpcUrl, privateKey) {
4244
+ connection = new import_web3.Connection(rpcUrl, "confirmed");
4245
+ if (privateKey) {
4246
+ try {
4247
+ const raw = privateKey.trim();
4248
+ let secretKey;
4249
+ if (raw.startsWith("[")) {
4250
+ secretKey = Uint8Array.from(JSON.parse(raw));
4251
+ } else {
4252
+ secretKey = bs582.decode(raw);
4253
+ }
4254
+ botWallet = import_web3.Keypair.fromSecretKey(secretKey);
4255
+ } catch (err) {
4256
+ log6.error({ err }, "SDK: Failed to load bot wallet");
4257
+ }
4258
+ }
4259
+ }
3999
4260
  function getBotWallet() {
4000
4261
  if (!botWallet && config.solana.botWalletPrivateKey) {
4001
4262
  try {
@@ -4004,7 +4265,7 @@ function getBotWallet() {
4004
4265
  if (raw.startsWith("[")) {
4005
4266
  secretKey = Uint8Array.from(JSON.parse(raw));
4006
4267
  } else {
4007
- secretKey = bs58.decode(raw);
4268
+ secretKey = bs582.decode(raw);
4008
4269
  }
4009
4270
  botWallet = import_web3.Keypair.fromSecretKey(secretKey);
4010
4271
  log6.info({ publicKey: botWallet.publicKey.toBase58() }, "Bot wallet loaded");
@@ -4037,6 +4298,50 @@ async function writeMemo(memo) {
4037
4298
  return null;
4038
4299
  }
4039
4300
  }
4301
+ function getDevnetConnection() {
4302
+ if (!devnetConnection) {
4303
+ devnetConnection = new import_web3.Connection("https://api.devnet.solana.com", "confirmed");
4304
+ }
4305
+ return devnetConnection;
4306
+ }
4307
+ async function writeMemoDevnet(memo) {
4308
+ const wallet = getBotWallet();
4309
+ if (!wallet) {
4310
+ log6.error("No bot wallet configured, cannot write devnet memo");
4311
+ return null;
4312
+ }
4313
+ const conn = getDevnetConnection();
4314
+ const truncatedMemo = memo.slice(0, MEMO_MAX_LENGTH);
4315
+ const instruction = new import_web3.TransactionInstruction({
4316
+ keys: [{ pubkey: wallet.publicKey, isSigner: true, isWritable: true }],
4317
+ programId: MEMO_PROGRAM_ID2,
4318
+ data: Buffer.from(truncatedMemo, "utf-8")
4319
+ });
4320
+ const transaction = new import_web3.Transaction().add(instruction);
4321
+ try {
4322
+ const signature = await (0, import_web3.sendAndConfirmTransaction)(conn, transaction, [wallet]);
4323
+ log6.info({ signature, memoLength: truncatedMemo.length }, "Memo written on devnet");
4324
+ return signature;
4325
+ } catch (err) {
4326
+ log6.error({ err }, "Failed to write devnet memo");
4327
+ return null;
4328
+ }
4329
+ }
4330
+ function verifySignature(message, signature, publicKey) {
4331
+ const messageBytes = new TextEncoder().encode(message);
4332
+ return import_tweetnacl2.default.sign.detached.verify(messageBytes, signature, publicKey);
4333
+ }
4334
+ function solscanTxUrl(signature) {
4335
+ return `${SOLSCAN_TX_BASE_URL}/${signature}`;
4336
+ }
4337
+ function _configureMemoryRegistry(programId) {
4338
+ try {
4339
+ registryProgramId = new import_web3.PublicKey(programId);
4340
+ log6.info({ programId: programId.slice(0, 12) + "..." }, "Memory registry program configured");
4341
+ } catch (err) {
4342
+ log6.error({ err }, "Invalid memory registry program ID");
4343
+ }
4344
+ }
4040
4345
  function isRegistryEnabled() {
4041
4346
  return registryProgramId !== null;
4042
4347
  }
@@ -4048,10 +4353,42 @@ function deriveRegistryPDA(authority) {
4048
4353
  );
4049
4354
  }
4050
4355
  function anchorDiscriminator(name) {
4051
- const { createHash: createHash3 } = require("crypto");
4052
- const hash = createHash3("sha256").update(`global:${name}`).digest();
4356
+ const { createHash: createHash4 } = require("crypto");
4357
+ const hash = createHash4("sha256").update(`global:${name}`).digest();
4053
4358
  return hash.subarray(0, 8);
4054
4359
  }
4360
+ async function initializeRegistry() {
4361
+ if (registryInitialized) return;
4362
+ const wallet = getBotWallet();
4363
+ if (!wallet || !registryProgramId) return;
4364
+ const conn = getConnection();
4365
+ const [registryPDA] = deriveRegistryPDA(wallet.publicKey);
4366
+ const accountInfo = await conn.getAccountInfo(registryPDA);
4367
+ if (accountInfo) {
4368
+ registryInitialized = true;
4369
+ log6.info({ registry: registryPDA.toBase58() }, "Registry PDA already exists");
4370
+ return;
4371
+ }
4372
+ const discriminator = anchorDiscriminator("initialize");
4373
+ const instruction = new import_web3.TransactionInstruction({
4374
+ keys: [
4375
+ { pubkey: registryPDA, isSigner: false, isWritable: true },
4376
+ { pubkey: wallet.publicKey, isSigner: true, isWritable: true },
4377
+ { pubkey: import_web3.SystemProgram.programId, isSigner: false, isWritable: false }
4378
+ ],
4379
+ programId: registryProgramId,
4380
+ data: discriminator
4381
+ });
4382
+ const transaction = new import_web3.Transaction().add(instruction);
4383
+ try {
4384
+ const signature = await (0, import_web3.sendAndConfirmTransaction)(conn, transaction, [wallet]);
4385
+ registryInitialized = true;
4386
+ log6.info({ signature, registry: registryPDA.toBase58() }, "Registry PDA initialized on-chain");
4387
+ } catch (err) {
4388
+ log6.error({ err }, "Failed to initialize registry PDA");
4389
+ throw err;
4390
+ }
4391
+ }
4055
4392
  function memoryTypeToU8(type) {
4056
4393
  switch (type) {
4057
4394
  case "episodic":
@@ -4103,21 +4440,82 @@ async function registerMemoryOnChain(contentHash, memoryType, importance, memory
4103
4440
  return null;
4104
4441
  }
4105
4442
  }
4106
- var import_web3, bs58Module, import_tweetnacl, bs58, log6, connection, botWallet, MEMO_PROGRAM_ID2, registryProgramId;
4443
+ async function verifyMemoryOnChain(contentHash, authority) {
4444
+ const wallet = getBotWallet();
4445
+ const authPubkey = authority || wallet?.publicKey;
4446
+ if (!authPubkey || !registryProgramId) return false;
4447
+ const conn = getConnection();
4448
+ const [registryPDA] = deriveRegistryPDA(authPubkey);
4449
+ try {
4450
+ const accountInfo = await conn.getAccountInfo(registryPDA);
4451
+ if (!accountInfo || !accountInfo.data) return false;
4452
+ const data = accountInfo.data;
4453
+ if (data.length < 53) return false;
4454
+ const vecLen = data.readUInt32LE(49);
4455
+ const ENTRY_SIZE = 56;
4456
+ const entriesStart = 53;
4457
+ for (let i = 0; i < vecLen; i++) {
4458
+ const offset = entriesStart + i * ENTRY_SIZE;
4459
+ if (offset + 32 > data.length) break;
4460
+ const hash = data.subarray(offset, offset + 32);
4461
+ if (contentHash.equals(hash)) return true;
4462
+ }
4463
+ return false;
4464
+ } catch (err) {
4465
+ log6.warn({ err }, "Failed to verify memory on-chain");
4466
+ return false;
4467
+ }
4468
+ }
4469
+ function parseMemoContentHash(memo) {
4470
+ if (!memo.startsWith("clude-memory |")) return null;
4471
+ const v2Match = memo.match(/^clude-memory \| v2 \| ([a-f0-9]{64})$/);
4472
+ if (v2Match) return v2Match[1];
4473
+ const v1Match = memo.match(/^clude-memory \| id: \d+ \| type: \w+ \| hash: ([a-f0-9]{16}) \|/);
4474
+ if (v1Match) return v1Match[1];
4475
+ return null;
4476
+ }
4477
+ async function verifyMemoTransaction(signature, contentHash) {
4478
+ const conn = getConnection();
4479
+ try {
4480
+ const tx = await conn.getTransaction(signature, { maxSupportedTransactionVersion: 0 });
4481
+ if (!tx?.meta || !tx.transaction.message) return false;
4482
+ const memoProgram = MEMO_PROGRAM_ID2.toBase58();
4483
+ const message = tx.transaction.message;
4484
+ const accountKeys = message.staticAccountKeys?.map((k) => k.toBase58()) ?? [];
4485
+ const compiledIxs = message.compiledInstructions;
4486
+ for (const ix of compiledIxs) {
4487
+ if (accountKeys[ix.programIdIndex] !== memoProgram) continue;
4488
+ const memoStr = Buffer.from(ix.data).toString("utf-8");
4489
+ const parsedHash = parseMemoContentHash(memoStr);
4490
+ if (!parsedHash) continue;
4491
+ const contentHashHex = contentHash.toString("hex");
4492
+ if (parsedHash.length === 64) {
4493
+ return parsedHash === contentHashHex;
4494
+ }
4495
+ return contentHashHex.startsWith(parsedHash);
4496
+ }
4497
+ return false;
4498
+ } catch (err) {
4499
+ log6.warn({ err, signature: signature.slice(0, 16) }, "Failed to verify memo transaction");
4500
+ return false;
4501
+ }
4502
+ }
4503
+ var import_web3, bs58Module2, import_tweetnacl2, bs582, log6, connection, botWallet, MEMO_PROGRAM_ID2, devnetConnection, registryProgramId, registryInitialized;
4107
4504
  var init_solana_client = __esm({
4108
4505
  "packages/shared/src/core/solana-client.ts"() {
4109
4506
  "use strict";
4110
4507
  import_web3 = require("@solana/web3.js");
4111
- bs58Module = __toESM(require("bs58"));
4508
+ bs58Module2 = __toESM(require("bs58"));
4112
4509
  init_config();
4113
4510
  init_logger();
4114
- import_tweetnacl = __toESM(require("tweetnacl"));
4511
+ import_tweetnacl2 = __toESM(require("tweetnacl"));
4115
4512
  init_constants();
4116
- bs58 = bs58Module.default || bs58Module;
4513
+ bs582 = bs58Module2.default || bs58Module2;
4117
4514
  log6 = createChildLogger("solana-client");
4118
4515
  botWallet = null;
4119
4516
  MEMO_PROGRAM_ID2 = new import_web3.PublicKey(MEMO_PROGRAM_ID);
4120
4517
  registryProgramId = null;
4518
+ registryInitialized = false;
4121
4519
  }
4122
4520
  });
4123
4521
 
@@ -4391,9 +4789,9 @@ function encryptContent(plaintext) {
4391
4789
  if (!encryptionKey) {
4392
4790
  throw new Error("Encryption not configured. Call configureEncryption() first.");
4393
4791
  }
4394
- const nonce = import_tweetnacl2.default.randomBytes(NONCE_LENGTH);
4792
+ const nonce = import_tweetnacl3.default.randomBytes(NONCE_LENGTH);
4395
4793
  const messageBytes = new TextEncoder().encode(plaintext);
4396
- const ciphertext = import_tweetnacl2.default.secretbox(messageBytes, nonce, encryptionKey);
4794
+ const ciphertext = import_tweetnacl3.default.secretbox(messageBytes, nonce, encryptionKey);
4397
4795
  const combined = new Uint8Array(NONCE_LENGTH + ciphertext.length);
4398
4796
  combined.set(nonce, 0);
4399
4797
  combined.set(ciphertext, NONCE_LENGTH);
@@ -4410,7 +4808,7 @@ function decryptContent(encrypted) {
4410
4808
  }
4411
4809
  const nonce = combined.subarray(0, NONCE_LENGTH);
4412
4810
  const ciphertext = combined.subarray(NONCE_LENGTH);
4413
- const plaintext = import_tweetnacl2.default.secretbox.open(ciphertext, nonce, encryptionKey);
4811
+ const plaintext = import_tweetnacl3.default.secretbox.open(ciphertext, nonce, encryptionKey);
4414
4812
  if (!plaintext) {
4415
4813
  return null;
4416
4814
  }
@@ -4436,17 +4834,17 @@ function decryptMemoryBatch(memories) {
4436
4834
  }
4437
4835
  return memories;
4438
4836
  }
4439
- var import_tweetnacl2, import_crypto, import_util, log9, hkdfAsync, NONCE_LENGTH, encryptionKey, encryptionPubkey;
4837
+ var import_tweetnacl3, import_crypto2, import_util, log9, hkdfAsync, NONCE_LENGTH, encryptionKey, encryptionPubkey;
4440
4838
  var init_encryption = __esm({
4441
4839
  "packages/shared/src/core/encryption.ts"() {
4442
4840
  "use strict";
4443
- import_tweetnacl2 = __toESM(require("tweetnacl"));
4444
- import_crypto = require("crypto");
4841
+ import_tweetnacl3 = __toESM(require("tweetnacl"));
4842
+ import_crypto2 = require("crypto");
4445
4843
  import_util = require("util");
4446
4844
  init_logger();
4447
4845
  log9 = createChildLogger("encryption");
4448
- hkdfAsync = (0, import_util.promisify)(import_crypto.hkdf);
4449
- NONCE_LENGTH = import_tweetnacl2.default.secretbox.nonceLength;
4846
+ hkdfAsync = (0, import_util.promisify)(import_crypto2.hkdf);
4847
+ NONCE_LENGTH = import_tweetnacl3.default.secretbox.nonceLength;
4450
4848
  encryptionKey = null;
4451
4849
  encryptionPubkey = null;
4452
4850
  }
@@ -4787,7 +5185,7 @@ function scopeToOwner(query) {
4787
5185
  return query;
4788
5186
  }
4789
5187
  function generateHashId() {
4790
- return `${HASH_ID_PREFIX}-${(0, import_crypto2.randomBytes)(4).toString("hex")}`;
5188
+ return `${HASH_ID_PREFIX}-${(0, import_crypto3.randomBytes)(4).toString("hex")}`;
4791
5189
  }
4792
5190
  function isValidHashId(id) {
4793
5191
  return /^clude-[a-f0-9]{8}$/.test(id);
@@ -4899,7 +5297,7 @@ async function storeMemory(opts) {
4899
5297
  }
4900
5298
  async function commitMemoryToChain(memoryId, opts) {
4901
5299
  if (opts.source === "demo" || opts.source === "demo-maas" || opts.source === "locomo-benchmark" || opts.source === "longmemeval-benchmark") return;
4902
- const contentHashBuf = (0, import_crypto2.createHash)("sha256").update(opts.content).digest();
5300
+ const contentHashBuf = (0, import_crypto3.createHash)("sha256").update(opts.content).digest();
4903
5301
  let signature = null;
4904
5302
  if (isRegistryEnabled()) {
4905
5303
  const encrypted = isEncryptionEnabled();
@@ -4913,7 +5311,7 @@ async function commitMemoryToChain(memoryId, opts) {
4913
5311
  }
4914
5312
  if (!signature) {
4915
5313
  const contentHashHex = contentHashBuf.toString("hex");
4916
- const memo = `clude-memory | v2 | ${contentHashHex}`;
5314
+ const memo = `clude:v1:sha256:${contentHashHex}`;
4917
5315
  signature = await writeMemo(memo);
4918
5316
  }
4919
5317
  if (!signature) return;
@@ -5865,7 +6263,7 @@ function moodToValence(mood) {
5865
6263
  return 0;
5866
6264
  }
5867
6265
  }
5868
- var import_crypto2, EMBED_CACHE_MAX, embeddingCache, _ownerWallet, SCOPE_BOT_OWN, HASH_ID_PREFIX, log11, DEDUP_TTL_MS, dedupCache, STOPWORDS;
6266
+ var import_crypto3, EMBED_CACHE_MAX, embeddingCache, _ownerWallet, SCOPE_BOT_OWN, HASH_ID_PREFIX, log11, DEDUP_TTL_MS, dedupCache, STOPWORDS;
5869
6267
  var init_memory = __esm({
5870
6268
  "packages/brain/src/memory/memory.ts"() {
5871
6269
  "use strict";
@@ -5880,7 +6278,7 @@ var init_memory = __esm({
5880
6278
  init_openrouter_client();
5881
6279
  init_encryption();
5882
6280
  init_event_bus();
5883
- import_crypto2 = require("crypto");
6281
+ import_crypto3 = require("crypto");
5884
6282
  init_graph();
5885
6283
  init_owner_context();
5886
6284
  EMBED_CACHE_MAX = 200;
@@ -6179,7 +6577,8 @@ async function runExport() {
6179
6577
  -h, --help Show this help
6180
6578
 
6181
6579
  ${c.bold}Formats:${c.reset}
6182
- ${c.cyan}json${c.reset} MemoryPack JSON (default)
6580
+ ${c.cyan}json${c.reset} Legacy single-file JSON (default)
6581
+ ${c.cyan}memorypack${c.reset} MemoryPack v0.1 spec directory (manifest + records.jsonl + sigs)
6183
6582
  ${c.cyan}md${c.reset} Clean Markdown
6184
6583
  ${c.cyan}chatgpt${c.reset} System prompt for ChatGPT Custom Instructions
6185
6584
  ${c.cyan}gemini${c.reset} System prompt for Gemini Gems
@@ -6199,7 +6598,7 @@ async function runExport() {
6199
6598
  const output = getFlag(args, "--output") || getFlag(args, "-o");
6200
6599
  const typesRaw = getFlag(args, "--types");
6201
6600
  const types = typesRaw ? typesRaw.split(",").map((t) => t.trim()) : void 0;
6202
- const validFormats = ["json", "md", "chatgpt", "gemini", "clipboard"];
6601
+ const validFormats = ["json", "md", "chatgpt", "gemini", "clipboard", "memorypack"];
6203
6602
  if (!validFormats.includes(format)) {
6204
6603
  printError(`Format must be one of: ${validFormats.join(", ")}`);
6205
6604
  process.exit(1);
@@ -6346,6 +6745,63 @@ async function runExport() {
6346
6745
  } else if (format === "md") {
6347
6746
  content = formatMarkdown(memories);
6348
6747
  defaultName = "clude-memories.md";
6748
+ } else if (format === "memorypack") {
6749
+ const outputDir = output || "clude-memorypack";
6750
+ const records = memories.map((m, i) => {
6751
+ const id = m.id ? String(m.id) : String(i + 1);
6752
+ const kind = m.type || m.memory_type || "episodic";
6753
+ const rec = {
6754
+ id,
6755
+ created_at: m.created_at || (/* @__PURE__ */ new Date()).toISOString(),
6756
+ kind,
6757
+ content: m.content || "",
6758
+ tags: m.tags || [],
6759
+ importance: typeof m.importance === "number" ? m.importance : 0.5,
6760
+ source: m.source || ""
6761
+ };
6762
+ if (m.summary) rec.summary = m.summary;
6763
+ if (m.access_count != null) rec.access_count = m.access_count;
6764
+ if (m.last_accessed_at) rec.last_accessed_at = m.last_accessed_at;
6765
+ return rec;
6766
+ });
6767
+ let secretKey;
6768
+ let publicKey;
6769
+ try {
6770
+ const { getBotWallet: getBotWallet2 } = (init_solana_client(), __toCommonJS(solana_client_exports));
6771
+ const wallet = getBotWallet2();
6772
+ if (wallet) {
6773
+ secretKey = wallet.secretKey;
6774
+ publicKey = wallet.publicKey.toBase58();
6775
+ }
6776
+ } catch {
6777
+ }
6778
+ writeMemoryPack(outputDir, records, {
6779
+ producer: {
6780
+ name: "clude",
6781
+ version: "3.0.3",
6782
+ agent_id: config3?.agent?.id,
6783
+ public_key: publicKey
6784
+ },
6785
+ record_schema: "clude-memory-v3",
6786
+ secretKey,
6787
+ anchor_chain: "solana-mainnet"
6788
+ });
6789
+ printSuccess(
6790
+ `MemoryPack written to ${outputDir}/ (${records.length} records${secretKey ? ", signed" : ", UNSIGNED"})`
6791
+ );
6792
+ if (!secretKey) {
6793
+ console.log(
6794
+ `
6795
+ ${c.dim}No wallet configured \u2014 pack is unsigned. Set CLUDE_WALLET_SECRET to sign.${c.reset}`
6796
+ );
6797
+ }
6798
+ console.log(
6799
+ `
6800
+ ${c.dim}Contents: manifest.json, records.jsonl${secretKey ? ", signatures.jsonl" : ""}${c.reset}`
6801
+ );
6802
+ printDivider();
6803
+ console.log("");
6804
+ return;
6349
6805
  } else {
6350
6806
  defaultName = "clude-memories.json";
6351
6807
  const pack = {
@@ -6374,7 +6830,7 @@ async function runExport() {
6374
6830
  content = JSON.stringify(pack, null, 2);
6375
6831
  }
6376
6832
  const filename = output || defaultName;
6377
- (0, import_fs3.writeFileSync)(filename, content, "utf-8");
6833
+ (0, import_fs5.writeFileSync)(filename, content, "utf-8");
6378
6834
  printSuccess(`Written to ${filename} (${formatBytes(Buffer.byteLength(content))})`);
6379
6835
  if (format === "chatgpt") {
6380
6836
  console.log(`
@@ -6389,12 +6845,13 @@ async function runExport() {
6389
6845
  printDivider();
6390
6846
  console.log("");
6391
6847
  }
6392
- var import_fs3;
6848
+ var import_fs5;
6393
6849
  var init_export = __esm({
6394
6850
  "packages/brain/src/cli/export.ts"() {
6395
6851
  "use strict";
6396
- import_fs3 = require("fs");
6852
+ import_fs5 = require("fs");
6397
6853
  init_banner();
6854
+ init_memorypack();
6398
6855
  }
6399
6856
  });
6400
6857
 
@@ -6406,9 +6863,35 @@ __export(import_exports, {
6406
6863
  function hasFlag2(args, flag) {
6407
6864
  return args.includes(flag);
6408
6865
  }
6866
+ function isMemoryPackDir(path8) {
6867
+ try {
6868
+ return (0, import_fs6.statSync)(path8).isDirectory() && (0, import_fs6.existsSync)((0, import_path6.join)(path8, "manifest.json"));
6869
+ } catch {
6870
+ return false;
6871
+ }
6872
+ }
6873
+ function parseMemoryPackDir(dir) {
6874
+ const result = readMemoryPack(dir);
6875
+ const signedCount = result.verifiedRecords.size;
6876
+ if (signedCount > 0) {
6877
+ const pubFp = result.manifest.producer.public_key?.slice(0, 8) ?? "?";
6878
+ printInfo(`Verified ${signedCount} record signature(s) against ${pubFp}...`);
6879
+ } else {
6880
+ printInfo("Pack is unsigned (no signatures.jsonl) \u2014 proceeding without verification");
6881
+ }
6882
+ for (const w of result.warnings) printInfo(`warning: ${w}`);
6883
+ return result.records.map((r) => ({
6884
+ content: r.content,
6885
+ summary: r.summary || r.content.slice(0, 200),
6886
+ type: ["episodic", "semantic", "procedural"].includes(r.kind) ? r.kind : "episodic",
6887
+ importance: r.importance,
6888
+ tags: [...r.tags || [], "imported", "memorypack"],
6889
+ source: r.source || "memorypack"
6890
+ }));
6891
+ }
6409
6892
  function isZipFile(path8) {
6410
6893
  try {
6411
- const buf = (0, import_fs4.readFileSync)(path8);
6894
+ const buf = (0, import_fs6.readFileSync)(path8);
6412
6895
  return buf[0] === 80 && buf[1] === 75;
6413
6896
  } catch {
6414
6897
  return false;
@@ -6536,9 +7019,9 @@ function extractFromChatGPTConversations(conversations) {
6536
7019
  async function parseChatGPTZip(filePath) {
6537
7020
  const { execSync: execSync2 } = require("child_process");
6538
7021
  const { mkdtempSync, readdirSync: readdirSync2 } = require("fs");
6539
- const { join: join8 } = require("path");
7022
+ const { join: join11 } = require("path");
6540
7023
  const os5 = require("os");
6541
- const tmpDir = mkdtempSync(join8(os5.tmpdir(), "clude-import-"));
7024
+ const tmpDir = mkdtempSync(join11(os5.tmpdir(), "clude-import-"));
6542
7025
  try {
6543
7026
  execSync2(`unzip -o -q "${filePath}" -d "${tmpDir}"`);
6544
7027
  } catch {
@@ -6546,7 +7029,7 @@ async function parseChatGPTZip(filePath) {
6546
7029
  process.exit(1);
6547
7030
  }
6548
7031
  const files = readdirSync2(tmpDir);
6549
- const convFile = files.find((f) => f === "conversations.json") ? join8(tmpDir, "conversations.json") : null;
7032
+ const convFile = files.find((f) => f === "conversations.json") ? join11(tmpDir, "conversations.json") : null;
6550
7033
  if (!convFile) {
6551
7034
  const { execSync: exec2 } = require("child_process");
6552
7035
  try {
@@ -6555,18 +7038,18 @@ async function parseChatGPTZip(filePath) {
6555
7038
  printError("No conversations.json found in ZIP.");
6556
7039
  process.exit(1);
6557
7040
  }
6558
- const conversations2 = JSON.parse((0, import_fs4.readFileSync)(found.split("\n")[0], "utf-8"));
7041
+ const conversations2 = JSON.parse((0, import_fs6.readFileSync)(found.split("\n")[0], "utf-8"));
6559
7042
  return extractFromChatGPTConversations(conversations2);
6560
7043
  } catch {
6561
7044
  printError("No conversations.json found in ZIP.");
6562
7045
  process.exit(1);
6563
7046
  }
6564
7047
  }
6565
- const conversations = JSON.parse((0, import_fs4.readFileSync)(convFile, "utf-8"));
7048
+ const conversations = JSON.parse((0, import_fs6.readFileSync)(convFile, "utf-8"));
6566
7049
  return extractFromChatGPTConversations(conversations);
6567
7050
  }
6568
7051
  function parseMarkdown(filePath) {
6569
- const content = (0, import_fs4.readFileSync)(filePath, "utf-8");
7052
+ const content = (0, import_fs6.readFileSync)(filePath, "utf-8");
6570
7053
  const memories = [];
6571
7054
  const sections = content.split(/\n#{1,3}\s+|\n\n+/).filter((s) => s.trim().length > 20);
6572
7055
  for (const section of sections) {
@@ -6600,7 +7083,7 @@ function parseMarkdown(filePath) {
6600
7083
  return memories;
6601
7084
  }
6602
7085
  function parseMemoryPack(filePath) {
6603
- const data = JSON.parse((0, import_fs4.readFileSync)(filePath, "utf-8"));
7086
+ const data = JSON.parse((0, import_fs6.readFileSync)(filePath, "utf-8"));
6604
7087
  if (data.memories && Array.isArray(data.memories)) {
6605
7088
  return data.memories.map((m) => ({
6606
7089
  content: m.content || m.summary || "",
@@ -6684,9 +7167,10 @@ async function runImport() {
6684
7167
  ${c.bold}Usage:${c.reset} npx @clude/sdk import <file> [options]
6685
7168
 
6686
7169
  ${c.bold}Supported formats:${c.reset}
7170
+ ${c.cyan}pack/${c.reset} MemoryPack v0.1 directory (manifest.json + records.jsonl)
6687
7171
  ${c.cyan}chatgpt-export.zip${c.reset} ChatGPT data export (ZIP with conversations.json)
6688
7172
  ${c.cyan}memories.md${c.reset} Markdown or text file (paragraphs \u2192 memories)
6689
- ${c.cyan}pack.json${c.reset} Clude MemoryPack JSON
7173
+ ${c.cyan}pack.json${c.reset} Legacy Clude MemoryPack JSON
6690
7174
 
6691
7175
  ${c.bold}Options:${c.reset}
6692
7176
  --dry-run Show what would be imported without storing
@@ -6702,7 +7186,7 @@ async function runImport() {
6702
7186
  }
6703
7187
  const filePath = args.find((a) => !a.startsWith("--"));
6704
7188
  const dryRun = hasFlag2(args, "--dry-run");
6705
- if (!(0, import_fs4.existsSync)(filePath)) {
7189
+ if (!(0, import_fs6.existsSync)(filePath)) {
6706
7190
  printError(`File not found: ${filePath}`);
6707
7191
  process.exit(1);
6708
7192
  }
@@ -6730,11 +7214,14 @@ async function runImport() {
6730
7214
  ${c.bold}Import${c.reset}
6731
7215
  `);
6732
7216
  let memories;
6733
- if (isZipFile(filePath)) {
7217
+ if (isMemoryPackDir(filePath)) {
7218
+ printInfo("Detected: MemoryPack v0.1 directory");
7219
+ memories = parseMemoryPackDir(filePath);
7220
+ } else if (isZipFile(filePath)) {
6734
7221
  printInfo("Detected: ChatGPT data export (ZIP)");
6735
7222
  memories = await parseChatGPTZip(filePath);
6736
7223
  } else if (isJsonFile(filePath)) {
6737
- printInfo("Detected: MemoryPack JSON");
7224
+ printInfo("Detected: Legacy MemoryPack JSON");
6738
7225
  memories = parseMemoryPack(filePath);
6739
7226
  } else if (isMarkdownOrText(filePath)) {
6740
7227
  printInfo("Detected: Markdown/text file");
@@ -6778,12 +7265,14 @@ async function runImport() {
6778
7265
  printDivider();
6779
7266
  console.log("");
6780
7267
  }
6781
- var import_fs4;
7268
+ var import_fs6, import_path6;
6782
7269
  var init_import = __esm({
6783
7270
  "packages/brain/src/cli/import.ts"() {
6784
7271
  "use strict";
6785
- import_fs4 = require("fs");
7272
+ import_fs6 = require("fs");
7273
+ import_path6 = require("path");
6786
7274
  init_banner();
7275
+ init_memorypack();
6787
7276
  }
6788
7277
  });
6789
7278
 
@@ -6895,7 +7384,7 @@ async function runSync() {
6895
7384
  const refresh = async () => {
6896
7385
  try {
6897
7386
  const content = await generatePrompt(format);
6898
- (0, import_fs5.writeFileSync)(output, content, "utf-8");
7387
+ (0, import_fs7.writeFileSync)(output, content, "utf-8");
6899
7388
  printSuccess(`Updated ${output} (${content.split(/\s+/).length} words) \u2014 ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`);
6900
7389
  } catch (err) {
6901
7390
  printError(`Refresh failed: ${err.message}`);
@@ -6911,11 +7400,11 @@ async function runSync() {
6911
7400
  `);
6912
7401
  setInterval(refresh, interval * 1e3);
6913
7402
  }
6914
- var import_fs5;
7403
+ var import_fs7;
6915
7404
  var init_sync = __esm({
6916
7405
  "packages/brain/src/cli/sync.ts"() {
6917
7406
  "use strict";
6918
- import_fs5 = require("fs");
7407
+ import_fs7 = require("fs");
6919
7408
  init_banner();
6920
7409
  }
6921
7410
  });
@@ -2717,7 +2717,7 @@ async function commitMemoryToChain(memoryId, opts) {
2717
2717
  }
2718
2718
  if (!signature) {
2719
2719
  const contentHashHex = contentHashBuf.toString("hex");
2720
- const memo = `clude-memory | v2 | ${contentHashHex}`;
2720
+ const memo = `clude:v1:sha256:${contentHashHex}`;
2721
2721
  signature = await writeMemo(memo);
2722
2722
  }
2723
2723
  if (!signature) return;
package/dist/sdk/index.js CHANGED
@@ -2542,7 +2542,7 @@ async function commitMemoryToChain(memoryId, opts) {
2542
2542
  }
2543
2543
  if (!signature) {
2544
2544
  const contentHashHex = contentHashBuf.toString("hex");
2545
- const memo = `clude-memory | v2 | ${contentHashHex}`;
2545
+ const memo = `clude:v1:sha256:${contentHashHex}`;
2546
2546
  signature = await writeMemo(memo);
2547
2547
  }
2548
2548
  if (!signature) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clude/sdk",
3
- "version": "3.0.3",
3
+ "version": "3.0.4",
4
4
  "mcpName": "io.github.sebbsssss/clude",
5
5
  "description": "Persistent memory SDK for AI agents — Stanford Generative Agents architecture on Supabase + pgvector",
6
6
  "main": "dist/sdk/index.js",