@engramx/client 0.15.0 → 0.16.0-rc.11

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.
Files changed (57) hide show
  1. package/README.md +262 -26
  2. package/dist/EngramClient.d.ts +235 -229
  3. package/dist/EngramClient.js +446 -1247
  4. package/dist/EngramClient.js.map +1 -1
  5. package/dist/MarketClient.d.ts +137 -0
  6. package/dist/MarketClient.js +228 -0
  7. package/dist/MarketClient.js.map +1 -0
  8. package/dist/ProfileManager.d.ts +4 -4
  9. package/dist/SessionManager.d.ts +3 -3
  10. package/dist/SessionManager.js +1 -1
  11. package/dist/SessionManager.js.map +1 -1
  12. package/dist/actionReceipt.d.ts +67 -0
  13. package/dist/actionReceipt.js +76 -2
  14. package/dist/actionReceipt.js.map +1 -1
  15. package/dist/auth.d.ts +16 -0
  16. package/dist/auth.js +38 -5
  17. package/dist/auth.js.map +1 -1
  18. package/dist/certifiedAudit.d.ts +32 -6
  19. package/dist/certifiedAudit.js +75 -14
  20. package/dist/certifiedAudit.js.map +1 -1
  21. package/dist/cli.js +100 -26
  22. package/dist/cli.js.map +1 -1
  23. package/dist/encryption.d.ts +30 -12
  24. package/dist/encryption.js +13 -15
  25. package/dist/encryption.js.map +1 -1
  26. package/dist/idl.d.ts +69 -0
  27. package/dist/idl.js +242 -0
  28. package/dist/idl.js.map +1 -0
  29. package/dist/index.d.ts +12 -18
  30. package/dist/index.js +58 -9
  31. package/dist/index.js.map +1 -1
  32. package/dist/ledgerfsHash.js +1 -1
  33. package/dist/ledgerfsHash.js.map +1 -1
  34. package/dist/lineage.js +8 -5
  35. package/dist/lineage.js.map +1 -1
  36. package/dist/memoryArchive.d.ts +428 -0
  37. package/dist/memoryArchive.js +504 -0
  38. package/dist/memoryArchive.js.map +1 -0
  39. package/dist/migrate.js +31 -4
  40. package/dist/migrate.js.map +1 -1
  41. package/dist/openEngram.d.ts +55 -0
  42. package/dist/openEngram.js +185 -0
  43. package/dist/openEngram.js.map +1 -0
  44. package/dist/pair.d.ts +33 -2
  45. package/dist/pair.js +56 -9
  46. package/dist/pair.js.map +1 -1
  47. package/dist/types.d.ts +246 -307
  48. package/dist/version.d.ts +8 -0
  49. package/dist/version.js +45 -0
  50. package/dist/version.js.map +1 -0
  51. package/dist/wire.d.ts +76 -0
  52. package/dist/wire.js +79 -0
  53. package/dist/wire.js.map +1 -0
  54. package/package.json +11 -19
  55. package/dist/bootstrap.d.ts +0 -21
  56. package/dist/bootstrap.js +0 -71
  57. package/dist/bootstrap.js.map +0 -1
@@ -0,0 +1,45 @@
1
+ // This package's own version, for the commands it prints.
2
+ //
3
+ // ⟨ADDED 2026-10-03⟩ WHY. The owner's ruling of 2026-10-03: every place that prints the pairing
4
+ // command prints the exact version it was built with — `npx @engramx/client@<version> pair …`, never
5
+ // the bare `npx @engramx/client pair …`, which installs npm's default (the last FINAL release) and
6
+ // so, while a release candidate soaks, a release that cannot pair with this release's engram. This
7
+ // package is @engramx/client, so its own version is the one to print. Internal: not exported from
8
+ // index.ts.
9
+ //
10
+ // The version is READ from the package.json this module ships beside — the file the release's
11
+ // version change (scripts/version.sh, from mops.toml, at every cut, rc and final alike) already
12
+ // writes — never typed here a second time. `../package.json` is the package's own manifest from both
13
+ // `src/` (tests) and `dist/` (the published build); npm always packs package.json. The name is
14
+ // checked because this SDK can be bundled into another program, where `../package.json` would be
15
+ // that program's manifest and its version would be printed as ours; read nothing rather than that.
16
+ //
17
+ // WHAT WOULD MAKE THIS WRONG: this module moving to a different depth under the package root.
18
+ // Held by test/shipped-copy.test.ts ("the pairing command names the version it was built with"),
19
+ // which compares every package's VERSION with its package.json and with mops.toml.
20
+ import { createRequire } from 'node:module';
21
+ const NAME = '@engramx/client';
22
+ /** What version.sh accepts: X.Y.Z, or X.Y.Z-<pre-release> such as X.Y.Z-rc.N. */
23
+ const RELEASE_VERSION = /^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.]+)?$/;
24
+ /** Printed in place of a version this module could not read: a visible blank, never the bare form. */
25
+ export const UNREAD_VERSION = '<version>';
26
+ function readOwnVersion() {
27
+ try {
28
+ const pkg = createRequire(import.meta.url)('../package.json');
29
+ if (pkg.name === NAME && typeof pkg.version === 'string' && RELEASE_VERSION.test(pkg.version))
30
+ return pkg.version;
31
+ }
32
+ catch {
33
+ // Bundled into another program: there is no manifest of ours beside this module.
34
+ }
35
+ return UNREAD_VERSION;
36
+ }
37
+ /** The version this package was built with (its package.json's), or UNREAD_VERSION. */
38
+ export const VERSION = readOwnVersion();
39
+ /** `npx @engramx/client@<version>` — the prefix of every command this package's help prints. */
40
+ export const NPX_CLIENT = `npx @engramx/client@${VERSION}`;
41
+ /** The pairing command, pinned to this build's version. */
42
+ export function pairCommand(code = '<code>', engram = '<id>') {
43
+ return `${NPX_CLIENT} pair ${code} --engram ${engram}`;
44
+ }
45
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,EAAE;AACF,gGAAgG;AAChG,qGAAqG;AACrG,mGAAmG;AACnG,mGAAmG;AACnG,kGAAkG;AAClG,YAAY;AACZ,EAAE;AACF,8FAA8F;AAC9F,gGAAgG;AAChG,qGAAqG;AACrG,+FAA+F;AAC/F,iGAAiG;AACjG,mGAAmG;AACnG,EAAE;AACF,8FAA8F;AAC9F,iGAAiG;AACjG,mFAAmF;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,IAAI,GAAG,iBAAiB,CAAC;AAE/B,iFAAiF;AACjF,MAAM,eAAe,GAAG,2CAA2C,CAAC;AAEpE,sGAAsG;AACtG,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;AAE1C,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAG3D,CAAC;QACF,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAC3F,OAAO,GAAG,CAAC,OAAO,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,iFAAiF;IACnF,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,OAAO,GAAW,cAAc,EAAE,CAAC;AAEhD,gGAAgG;AAChG,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,OAAO,EAAE,CAAC;AAE3D,2DAA2D;AAC3D,MAAM,UAAU,WAAW,CAAC,IAAI,GAAG,QAAQ,EAAE,MAAM,GAAG,MAAM;IAC1D,OAAO,GAAG,UAAU,SAAS,IAAI,aAAa,MAAM,EAAE,CAAC;AACzD,CAAC"}
package/dist/wire.d.ts ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * wire.ts — the house envelope, on the client side.
3
+ *
4
+ * ⟨0.16.0, leg B-5⟩ Every canister now answers `Result<T> = { Ok : T } | { Err : Error }`, where
5
+ * `Error` is a SIX-ARMED VARIANT rather than the `text` it used to be. That change breaks the
6
+ * obvious unwrap in a way TypeScript cannot see:
7
+ *
8
+ * if ('Err' in result) throw new Error(result.Err); // Err is an object now
9
+ *
10
+ * `new Error({ Refused: "…" })` stringifies to **"[object Object]"**. It compiles, it runs, and it
11
+ * destroys the message — which on this codebase is the whole product: the refusals were written to
12
+ * tell a caller what to do next, and this is the one line that decides whether they ever read one.
13
+ */
14
+ /** The six arms, spelled as the canisters spell them. */
15
+ export type WireError = {
16
+ Refused: string;
17
+ } | {
18
+ Invalid: string;
19
+ } | {
20
+ NotFound: string;
21
+ } | {
22
+ Conflict: string;
23
+ } | {
24
+ Unavailable: string;
25
+ } | {
26
+ Other: string;
27
+ };
28
+ export type WireResult<T> = {
29
+ Ok: T;
30
+ } | {
31
+ Err: WireError;
32
+ };
33
+ /** A page, as every list method returns one. `withheld` is how many rows the caller may not see. */
34
+ export interface WirePage<T> {
35
+ items: T[];
36
+ total: bigint;
37
+ withheld: bigint;
38
+ }
39
+ /** Which kind of no this is. */
40
+ export type WireErrorKind = 'Refused' | 'Invalid' | 'NotFound' | 'Conflict' | 'Unavailable' | 'Other';
41
+ /** The arm name, or 'Other' for an arm this build does not recognise. */
42
+ export declare function errorKind(e: WireError): WireErrorKind;
43
+ /** The message the canister wrote, without the arm. */
44
+ export declare function errorMessage(e: WireError): string;
45
+ /**
46
+ * An Error carrying the canister's refusal — the KIND on `.kind` so a caller can branch, and the
47
+ * message intact so a human can read it.
48
+ */
49
+ export declare class CanisterRefusal extends Error {
50
+ readonly kind: WireErrorKind;
51
+ readonly method: string;
52
+ /**
53
+ * ⟨2026-10-01⟩ The canister's sentence exactly as it wrote it, without the method and arm this
54
+ * class prefixes to `message`. A command that promises to print "the engram's sentence verbatim"
55
+ * (open-engram) reads this rather than cutting the prefix back off `message`.
56
+ */
57
+ readonly text: string;
58
+ constructor(method: string, err: WireError);
59
+ }
60
+ /**
61
+ * Unwrap a `Result<T>`, throwing a `CanisterRefusal` that preserves both halves of the answer.
62
+ *
63
+ * Branching on `.kind` rather than on message text is the point of the variant: `#Unavailable` is
64
+ * the arm that means retry, `#Conflict` means the state refused you, `#Refused` means your standing
65
+ * did. Matching prose to tell those apart is what the envelope replaced.
66
+ *
67
+ * ⟨2026-10-02, RATIFIED as the 0.16.0 contract⟩ ONE EXCEPTION, at the payment library's seam. Where
68
+ * a refusal comes from ic402 rather than from the canister's own checks, the library answers every
69
+ * refusal down one text channel and the canister can only pass it on as `Conflict`: on the market's
70
+ * `claimJob`, `submitJobResult`, `confirmJob` and `disputeJob`, and on the engram's
71
+ * `recoverEscrow`, a `Conflict` can mean "not yours" (not the assigned operator, not the
72
+ * buyer, not the session's payer) as well as a state. On those methods read `.text` — the
73
+ * canister's sentence names which — and do not retry a `Conflict` blindly. Each method's interface
74
+ * comment says so. Separating the two in the library is post-cut dependency work.
75
+ */
76
+ export declare function unwrapResult<T>(result: unknown, method: string): T;
package/dist/wire.js ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * wire.ts — the house envelope, on the client side.
3
+ *
4
+ * ⟨0.16.0, leg B-5⟩ Every canister now answers `Result<T> = { Ok : T } | { Err : Error }`, where
5
+ * `Error` is a SIX-ARMED VARIANT rather than the `text` it used to be. That change breaks the
6
+ * obvious unwrap in a way TypeScript cannot see:
7
+ *
8
+ * if ('Err' in result) throw new Error(result.Err); // Err is an object now
9
+ *
10
+ * `new Error({ Refused: "…" })` stringifies to **"[object Object]"**. It compiles, it runs, and it
11
+ * destroys the message — which on this codebase is the whole product: the refusals were written to
12
+ * tell a caller what to do next, and this is the one line that decides whether they ever read one.
13
+ */
14
+ const KINDS = [
15
+ 'Refused',
16
+ 'Invalid',
17
+ 'NotFound',
18
+ 'Conflict',
19
+ 'Unavailable',
20
+ 'Other',
21
+ ];
22
+ /** The arm name, or 'Other' for an arm this build does not recognise. */
23
+ export function errorKind(e) {
24
+ for (const k of KINDS)
25
+ if (k in e)
26
+ return k;
27
+ return 'Other';
28
+ }
29
+ /** The message the canister wrote, without the arm. */
30
+ export function errorMessage(e) {
31
+ for (const k of KINDS) {
32
+ const v = e[k];
33
+ if (typeof v === 'string')
34
+ return v;
35
+ }
36
+ // An arm we do not know about still carries its message; surface it rather than losing it to a
37
+ // generic string, because an unrecognised arm is exactly when a caller most needs the text.
38
+ const first = Object.values(e).find((v) => typeof v === 'string');
39
+ return typeof first === 'string' ? first : JSON.stringify(e);
40
+ }
41
+ /**
42
+ * An Error carrying the canister's refusal — the KIND on `.kind` so a caller can branch, and the
43
+ * message intact so a human can read it.
44
+ */
45
+ export class CanisterRefusal extends Error {
46
+ constructor(method, err) {
47
+ super(`${method}: ${errorKind(err)} — ${errorMessage(err)}`);
48
+ this.name = 'CanisterRefusal';
49
+ this.kind = errorKind(err);
50
+ this.method = method;
51
+ this.text = errorMessage(err);
52
+ }
53
+ }
54
+ /**
55
+ * Unwrap a `Result<T>`, throwing a `CanisterRefusal` that preserves both halves of the answer.
56
+ *
57
+ * Branching on `.kind` rather than on message text is the point of the variant: `#Unavailable` is
58
+ * the arm that means retry, `#Conflict` means the state refused you, `#Refused` means your standing
59
+ * did. Matching prose to tell those apart is what the envelope replaced.
60
+ *
61
+ * ⟨2026-10-02, RATIFIED as the 0.16.0 contract⟩ ONE EXCEPTION, at the payment library's seam. Where
62
+ * a refusal comes from ic402 rather than from the canister's own checks, the library answers every
63
+ * refusal down one text channel and the canister can only pass it on as `Conflict`: on the market's
64
+ * `claimJob`, `submitJobResult`, `confirmJob` and `disputeJob`, and on the engram's
65
+ * `recoverEscrow`, a `Conflict` can mean "not yours" (not the assigned operator, not the
66
+ * buyer, not the session's payer) as well as a state. On those methods read `.text` — the
67
+ * canister's sentence names which — and do not retry a `Conflict` blindly. Each method's interface
68
+ * comment says so. Separating the two in the library is post-cut dependency work.
69
+ */
70
+ export function unwrapResult(result, method) {
71
+ if (result && typeof result === 'object') {
72
+ if ('Ok' in result)
73
+ return result.Ok;
74
+ if ('Err' in result)
75
+ throw new CanisterRefusal(method, result.Err);
76
+ }
77
+ throw new Error(`${method}: invalid canister response — neither Ok nor Err (${JSON.stringify(result)})`);
78
+ }
79
+ //# sourceMappingURL=wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.js","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAwBH,MAAM,KAAK,GAAoB;IAC7B,SAAS;IACT,SAAS;IACT,UAAU;IACV,UAAU;IACV,aAAa;IACb,OAAO;CACR,CAAC;AAEF,yEAAyE;AACzE,MAAM,UAAU,SAAS,CAAC,CAAY;IACpC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,YAAY,CAAC,CAAY;IACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAI,CAA6B,CAAC,CAAC,CAAC,CAAC;QAC5C,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,+FAA+F;IAC/F,4FAA4F;IAC5F,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAA4B,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC7F,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IASxC,YAAY,MAAc,EAAE,GAAc;QACxC,KAAK,CAAC,GAAG,MAAM,KAAK,SAAS,CAAC,GAAG,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,YAAY,CAAI,MAAe,EAAE,MAAc;IAC7D,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACzC,IAAI,IAAI,IAAI,MAAM;YAAE,OAAQ,MAAoB,CAAC,EAAE,CAAC;QACpD,IAAI,KAAK,IAAI,MAAM;YAAE,MAAM,IAAI,eAAe,CAAC,MAAM,EAAG,MAA6B,CAAC,GAAG,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,qDAAqD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CACxF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,18 +1,9 @@
1
1
  {
2
2
  "name": "@engramx/client",
3
- "version": "0.15.0",
4
- "description": "Client SDK for EngramX — persistent, decentralized memory for AI agents on ICP",
3
+ "version": "0.16.0-rc.11",
4
+ "description": "Client SDK for EngramX — persistent, decentralized memory for AI agents on the Internet Computer",
5
5
  "license": "Apache-2.0",
6
6
  "author": "EngramX <developer@engramx.ai>",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/vhew/engramx",
10
- "directory": "packages/client"
11
- },
12
- "homepage": "https://github.com/vhew/engramx#readme",
13
- "bugs": {
14
- "url": "https://github.com/vhew/engramx/issues"
15
- },
16
7
  "keywords": [
17
8
  "icp",
18
9
  "internet-computer",
@@ -47,21 +38,22 @@
47
38
  "access": "public"
48
39
  },
49
40
  "peerDependencies": {
50
- "@icp-sdk/core": "^5.4.0"
41
+ "@icp-sdk/core": "^6.1.0"
51
42
  },
52
43
  "dependencies": {
53
- "@ic402/client": "^2.13.1",
54
- "@icp-sdk/core": "^5.4.0",
55
- "@icp-sdk/vetkeys": "0.5.0-beta.0",
56
- "cborg": "^5.1.7"
44
+ "@engramx/idl": "0.16.0-rc.11",
45
+ "@icp-sdk/core": "^6.1.0",
46
+ "@icp-sdk/vetkeys": "0.7.0",
47
+ "@noble/curves": "^2.4.0"
57
48
  },
58
49
  "devDependencies": {
59
- "@types/node": "^26.1.1",
50
+ "@types/node": "^26.6.4",
60
51
  "typescript": "^6.0.3",
61
- "vitest": "^4.1.10"
52
+ "vite": "^8.3.2",
53
+ "vitest": "^5.0.3"
62
54
  },
63
55
  "scripts": {
64
- "build": "tsc",
56
+ "build": "pnpm --filter @engramx/idl build && tsc",
65
57
  "test": "vitest run"
66
58
  }
67
59
  }
@@ -1,21 +0,0 @@
1
- import { EngramClient } from './EngramClient.js';
2
- export interface BootstrapConfig {
3
- engram: {
4
- canisterId: string;
5
- sessionKeyPath: string;
6
- host?: string;
7
- };
8
- }
9
- /**
10
- * Load config with remote overlay: reads local bootstrap config, then fetches
11
- * the remote config from the engram (if available) and deep-merges them.
12
- * Local values override remote values.
13
- */
14
- export declare function loadBootstrapConfig(localConfigPath: string): Promise<Record<string, any>>;
15
- /**
16
- * Save config to the engram's config/openclaw.json path. Owner-only operation —
17
- * only succeeds when the caller's principal is the engram owner. Uses raw
18
- * actor access since `writeMemory` is intentionally NOT exposed on the
19
- * EngramClient SDK (operator hosts can't satisfy this).
20
- */
21
- export declare function saveBootstrapConfig(client: EngramClient, config: object): Promise<void>;
package/dist/bootstrap.js DELETED
@@ -1,71 +0,0 @@
1
- import * as fs from 'fs';
2
- import { EngramClient } from './EngramClient.js';
3
- /**
4
- * Load config with remote overlay: reads local bootstrap config, then fetches
5
- * the remote config from the engram (if available) and deep-merges them.
6
- * Local values override remote values.
7
- */
8
- export async function loadBootstrapConfig(localConfigPath) {
9
- if (localConfigPath.startsWith('~') && !process.env['HOME']) {
10
- throw new Error('HOME environment variable is not set');
11
- }
12
- const resolvedPath = localConfigPath.replace(/^~/, process.env['HOME'] || '');
13
- let local;
14
- try {
15
- local = JSON.parse(fs.readFileSync(resolvedPath, 'utf-8'));
16
- }
17
- catch (err) {
18
- throw new Error(`Failed to load config from ${resolvedPath}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
19
- }
20
- const engram = local['engram'];
21
- if (!engram?.['canisterId'] || !engram?.['sessionKeyPath']) {
22
- return local;
23
- }
24
- const client = new EngramClient({
25
- canisterId: engram['canisterId'],
26
- sessionKeyPath: engram['sessionKeyPath'],
27
- host: engram['host'],
28
- });
29
- try {
30
- const remoteFile = await client.readMemory('config/openclaw.json');
31
- const remote = JSON.parse(remoteFile.content);
32
- return deepMerge(remote, local); // local overrides remote
33
- }
34
- catch {
35
- return local;
36
- }
37
- }
38
- /**
39
- * Save config to the engram's config/openclaw.json path. Owner-only operation —
40
- * only succeeds when the caller's principal is the engram owner. Uses raw
41
- * actor access since `writeMemory` is intentionally NOT exposed on the
42
- * EngramClient SDK (operator hosts can't satisfy this).
43
- */
44
- export async function saveBootstrapConfig(client, config) {
45
- const ciphertext = new TextEncoder().encode(JSON.stringify(config, null, 2));
46
- const actor = client.actor;
47
- const result = await actor.writeMemory('config/openclaw.json', ciphertext);
48
- if ('Err' in result)
49
- throw new Error(result.Err);
50
- }
51
- const UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
52
- function deepMerge(base, override) {
53
- const result = { ...base };
54
- for (const key of Object.keys(override)) {
55
- if (UNSAFE_KEYS.has(key))
56
- continue;
57
- if (override[key] !== null &&
58
- typeof override[key] === 'object' &&
59
- !Array.isArray(override[key]) &&
60
- result[key] !== null &&
61
- typeof result[key] === 'object' &&
62
- !Array.isArray(result[key])) {
63
- result[key] = deepMerge(result[key], override[key]);
64
- }
65
- else {
66
- result[key] = override[key];
67
- }
68
- }
69
- return result;
70
- }
71
- //# sourceMappingURL=bootstrap.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}