@engramx/owner 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,190 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to the Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by the Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding any notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ Copyright 2025 EngramX contributors
179
+
180
+ Licensed under the Apache License, Version 2.0 (the "License");
181
+ you may not use this file except in compliance with the License.
182
+ You may obtain a copy of the License at
183
+
184
+ http://www.apache.org/licenses/LICENSE-2.0
185
+
186
+ Unless required by applicable law or agreed to in writing, software
187
+ distributed under the License is distributed on an "AS IS" BASIS,
188
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189
+ See the License for the specific language governing permissions and
190
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # @engramx/owner
2
+
3
+ Create an **EngramX engram** that _you_ own — the standalone owner-side creation CLI.
4
+
5
+ This package is deliberately **separate from `@engramx/client`** (the operator SDK). Creating an engram
6
+ makes the caller the **owner** (root); operating one is append-only. Keeping them in different packages
7
+ means an operator host never gains owner powers, and vice-versa.
8
+
9
+ - **Create** (owner) → this package.
10
+ - **Operate** (append-only) → `@engramx/client` + the MCP server.
11
+
12
+ ## Reserve, then activate
13
+
14
+ Creation is two-stage, on purpose:
15
+
16
+ - **Reserve** (the default) — a **free** registry record (~$0). Nothing runs yet; idempotent (one per
17
+ principal).
18
+ - **Activate** (`--activate`) — spawns the live canister (the platform funds the ~1.15T-cycle spawn).
19
+
20
+ Reserving costs nothing, so a "create-and-walk-away" never wastes cycles — the spend happens only when
21
+ you activate. Interactively, a bare `npx @engramx/owner` reserves and then asks whether to spin it up
22
+ now; headless (`--yes`/non-TTY) stays reserve-only unless you pass `--activate`.
23
+
24
+ ## Quick start
25
+
26
+ ```bash
27
+ # Reserve (free). Reuse an existing icp-cli identity so you keep custody; EngramX holds nothing:
28
+ npx @engramx/owner --icp-identity <name> --registry <registry-canister-id> --yes
29
+
30
+ # Or generate a local owner key at ~/.engramx/owner.key (BACK IT UP — loss = total loss):
31
+ npx @engramx/owner --registry <registry-canister-id> --yes
32
+
33
+ # Activate when you're ready to use it (spawns the canister) — same flags plus --activate:
34
+ npx @engramx/owner --activate --registry <registry-canister-id> --yes
35
+
36
+ # Local dev replica: add --local
37
+ npx @engramx/owner --registry <id> --local --activate
38
+ ```
39
+
40
+ Run `npx @engramx/owner --help` for all options.
41
+
42
+ ## Ownership & custody
43
+
44
+ The registry makes the **caller** the owner — there is no owner parameter and no reassignment, so the
45
+ signing identity _is_ the owner, by construction. Your options:
46
+
47
+ | Mode | Who owns | Recovery |
48
+ | --- | --- | --- |
49
+ | `--icp-identity <name>` | your icp-cli identity | whatever that identity has (e.g. its 24-word seed) — single key |
50
+ | _default_ (local key) | a fresh Ed25519 key at `~/.engramx/owner.key` | **none** — back up the seed, or loss is permanent |
51
+ | web wizard (wallet) | your OISY / Internet Identity | real wallet recovery — the recommended path for humans |
52
+
53
+ ## What this does **not** do
54
+
55
+ - It does not read or write memory — that's the operator flow (`@engramx/client`).
56
+ - No hosted/managed creation (EngramX never signs on your behalf).
57
+ - Reserving is free and activation is free to you (the platform funds the spawn); paying to create is
58
+ not a thing. Ongoing cycles can optionally be topped up with ckUSDC via the cashier.
59
+
60
+ ## Use as an agent skill
61
+
62
+ `SKILL.md` in this package is a cross-agent capability (Agent Skills format) that lets a coding/agent
63
+ host (Claude Code, Codex, OpenClaw, …) create an engram on the user's behalf by shelling to this CLI.
64
+
65
+ ## Honesty
66
+
67
+ The record is tamper-**evident**, not immutable (the owner can overwrite; every change is a signed
68
+ entry). A single owner key is a total-loss risk. Nothing is on a public fleet yet.
package/SKILL.md ADDED
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: create-engram
3
+ description: Create an EngramX engram — a personal, user-OWNED memory store plus a tamper-evident action record on the Internet Computer. Use when the user wants to set up their own engram so an AI agent can remember them across sessions and across models. Creation is free and makes the user the owner; the agent connects separately, later, as an append-only operator.
4
+ ---
5
+
6
+ # Create an EngramX engram
7
+
8
+ An **engram** is a per-user canister on the Internet Computer that holds an agent's memory and a
9
+ tamper-evident audit record, **owned by the user** — not the AI vendor, and not you (the agent).
10
+ Creating one is **free** (the platform funds it). This skill CREATES an engram the user owns; it does
11
+ **not** operate one — reading and appending memory is a separate *operator* step (`@engramx/client`),
12
+ kept in a different package so operators never gain owner powers.
13
+
14
+ ## When to use
15
+ The user says something like "create an engram", "set up my EngramX memory", "give me my own memory
16
+ store", or "I want my own agent memory that I control." If they instead want an agent to *read/write*
17
+ an engram that already exists, that's the operator flow (`@engramx/client pair`), not this skill.
18
+
19
+ ## Reserve, then activate (important)
20
+ Creation is two-stage on purpose:
21
+ - **Reserve** (the default) = a **free** registry record (~$0). Nothing runs yet.
22
+ - **Activate** (`--activate`) = spawns the live canister (the platform funds the ~1.15T-cycle spawn).
23
+
24
+ This is a deliberate cycle anti-drain: reserving costs nothing, so a speculative "create" never wastes
25
+ money. **Only pass `--activate` once the user has confirmed they actually want to spin it up now** —
26
+ i.e. they're going to use it. Reserving is idempotent (one per principal), so a reserve-now,
27
+ activate-later flow is safe.
28
+
29
+ ## How to run
30
+ Creation goes through the standalone CLI. You need the EngramX **registry canister id** (ask the user,
31
+ or read `ENGRAMX_REGISTRY` from the environment). Always pass `--yes` when running as an agent so it
32
+ doesn't wait on a prompt.
33
+
34
+ 1. **Reserve** (free — do this first):
35
+ - Reusing the user's icp-cli identity (they keep full custody; EngramX holds nothing):
36
+ ```
37
+ npx @engramx/owner --icp-identity <name> --registry <registry-canister-id> --yes
38
+ ```
39
+ - Otherwise a local Ed25519 owner key is generated at `~/.engramx/owner.key`:
40
+ ```
41
+ npx @engramx/owner --registry <registry-canister-id> --yes
42
+ ```
43
+ ⚠ That seed is the user's **only** key. Tell them to back up `~/.engramx/owner.key`; losing it
44
+ means permanently losing ownership of the engram.
45
+ 2. **Activate** once the user confirms they want it running — same flags plus `--activate`:
46
+ ```
47
+ npx @engramx/owner --activate --icp-identity <name> --registry <registry-canister-id> --yes
48
+ ```
49
+ The command prints the live engram's canister id and the owner principal.
50
+
51
+ - **Local dev replica**: add `--local` (host defaults to `http://127.0.0.1:4943`).
52
+
53
+ ## After activating
54
+ 1. The user **owns** the engram. To let this agent (or any host) read and append its memory, connect as
55
+ an **operator** — a separate, append-only step: `npx @engramx/client pair <invite-code> --engram <id>`.
56
+ Owner ≠ operator, by design.
57
+ 2. Ongoing cycles can be funded with **ckUSDC** via the cashier (optional).
58
+
59
+ ## Honesty (state these plainly to the user)
60
+ - The owner key is the **user's own** — EngramX never holds it. A single local key means loss = total,
61
+ unrecoverable loss; recommend backing it up (or using their icp-cli identity, or the web wizard with a
62
+ wallet for real recovery).
63
+ - The record is tamper-**evident**, not immutable: the owner can overwrite their own memory, but every
64
+ change is a signed entry anyone can check.
65
+ - Nothing is on a public fleet yet — until the registry is deployed, this creates against a dev replica.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from 'node:util';
3
+ import * as readline from 'node:readline';
4
+ import { execFileSync } from 'node:child_process';
5
+ import { Principal } from '@icp-sdk/core/principal';
6
+ import { createEngram, provision, connectAgent } from './create.js';
7
+ import { localOwnerKey, icpCliOwnerKey, DEFAULT_KEY_PATH } from './owner-key.js';
8
+ import { CANONICAL_REGISTRY_CANISTER_ID, CANONICAL_WIZARD_URL } from './config.js';
9
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
10
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
11
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
12
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
13
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
14
+ const ok = (m) => console.log(`${green('✓')} ${m}`);
15
+ const fail = (m) => console.error(`${red('✗')} ${m}`);
16
+ const warn = (m) => console.error(`${yellow('⚠')} ${m}`);
17
+ const info = (m) => console.log(` ${dim(m)}`);
18
+ const HELP = `${bold('engramx-owner')} — create an EngramX engram that YOU own.
19
+
20
+ An engram is a per-user canister on the Internet Computer holding an agent's memory + a tamper-evident
21
+ action record. You own it; an agent connects SEPARATELY as an append-only operator (@engramx/client)
22
+ — this package never mixes the two.
23
+
24
+ ${bold('Reserve, then spawn on real use.')} By default this RESERVES your engram — a free registry
25
+ record (~$0). The live canister spawns only when you actually use it: ${bold('--connect')} (spin it up
26
+ AND mint an invite for your agent, the usual path) or ${bold('--activate')} (spawn without an agent).
27
+ This keeps a "create-and-walk-away" from ever costing cycles. Reserve is idempotent (one per principal).
28
+
29
+ ${bold('Usage')}
30
+ npx @engramx/owner [ownership] [target] ${dim('# reserve (free); prompts to spin up if interactive')}
31
+ npx @engramx/owner --connect [ownership] [target] ${dim('# spawn + mint an operator invite for your agent')}
32
+ npx @engramx/owner --activate [ownership] [target] ${dim('# spawn without connecting an agent')}
33
+
34
+ ${bold('Ownership / custody')} (pick one; local key is the default)
35
+ (default) Generate a local Ed25519 owner key at ${DEFAULT_KEY_PATH}.
36
+ ${yellow('That seed is your ONLY key — back it up. Loss = permanent loss of ownership.')}
37
+ --icp-identity <name> Reuse an existing icp-cli identity (you keep custody; EngramX holds nothing).
38
+ --key-file <path> Use/create the local owner key at <path> instead of the default.
39
+ --wallet Own it with your browser wallet (OISY / Internet Identity) via the web
40
+ wizard — the recoverable path. Opens the wizard and records the result.
41
+
42
+ ${bold('Target')}
43
+ --registry <id> EngramX registry canister id. Defaults to the CANONICAL registry
44
+ (or ENGRAMX_REGISTRY); a different id creates against a fork.
45
+ --wizard-url <url> Web-wizard URL for --wallet (or ENGRAMX_WIZARD_URL; default: canonical).
46
+ --host <url> Replica host. Default: https://icp-api.io, or http://127.0.0.1:4943 with --local.
47
+ --local Target a local replica (fetches the root key first). Never use for mainnet.
48
+ --connect Spawn the engram AND mint an append-only operator invite in one step (the
49
+ usual way to wire an agent). Prints the invite + the pair command.
50
+ --agent-name <name> Label for the operator minted by --connect (default: "agent").
51
+ --invite <code> Invite code, for deployments that arm the reserve gate (raw-keypair
52
+ identities like this CLI's need one there; wallet identities do not).
53
+ --activate Spawn the live canister WITHOUT connecting an agent (use the web app / SDK
54
+ to add memory). Headless (--yes/non-TTY) stays reserve-only unless you pass
55
+ --activate or --connect — the cycle anti-drain default.
56
+ -y, --yes Don't prompt (headless/agent use). Reserves only unless --connect/--activate.
57
+ -h, --help Show this help.
58
+
59
+ ${bold('After creating')}
60
+ • You own the engram. Give an agent append-only access as an OPERATOR (a separate step):
61
+ npx @engramx/client pair <invite-code> --engram <engram-canister-id>
62
+ • Fund ongoing cycles with ckUSDC via the cashier (optional).`;
63
+ function question(q) {
64
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
65
+ return new Promise((resolve) => rl.question(q, (a) => (rl.close(), resolve(a)))).then((a) => a.trim());
66
+ }
67
+ async function confirm(q, defaultYes = false) {
68
+ const a = await question(`${q} ${defaultYes ? '[Y/n]' : '[y/N]'} `);
69
+ if (a === '')
70
+ return defaultYes;
71
+ return defaultYes ? !/^n(o)?$/i.test(a) : /^y(es)?$/i.test(a);
72
+ }
73
+ function tryOpenBrowser(url) {
74
+ const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
75
+ try {
76
+ execFileSync(cmd, [url], { stdio: 'ignore' });
77
+ }
78
+ catch {
79
+ /* user opens it manually from the printed URL */
80
+ }
81
+ }
82
+ /**
83
+ * Wallet-ownership handoff. The signature + creation happen in the web wizard (with OISY / Internet
84
+ * Identity), so the engram is owned by the user's durable, recoverable wallet — EngramX never touches
85
+ * the key and this CLI never signs. The CLI opens the wizard and records the resulting engram id.
86
+ * (In-CLI ICRC-34 delegation is a later hardening; this handoff is the v1 wallet path.)
87
+ */
88
+ async function walletHandoff(wizardUrl) {
89
+ console.log(`${bold('Wallet ownership')} — create your engram in the browser with your wallet, so it is ` +
90
+ `recoverable and EngramX never touches your key.\n`);
91
+ info(`Opening: ${wizardUrl}`);
92
+ tryOpenBrowser(wizardUrl);
93
+ console.log('');
94
+ console.log(' 1. Sign in with your wallet (OISY / Internet Identity) and create your engram.');
95
+ console.log(' 2. Copy its canister id (shown on the dashboard).');
96
+ console.log('');
97
+ const id = await question('Paste your engram canister id (blank to skip): ');
98
+ if (!id) {
99
+ info('Skipped. Once created, your wallet owns it; attach an operator with `npx @engramx/client pair`.');
100
+ return;
101
+ }
102
+ let principal;
103
+ try {
104
+ principal = Principal.fromText(id).toText();
105
+ }
106
+ catch {
107
+ fail(`"${id}" is not a valid canister id.`);
108
+ process.exit(1);
109
+ }
110
+ ok(`Your wallet owns engram ${bold(principal)}.`);
111
+ console.log('');
112
+ console.log(bold('Next:'));
113
+ console.log(` • Attach an agent as an operator: ${dim(`npx @engramx/client pair <invite-code> --engram ${principal}`)}`);
114
+ }
115
+ async function main() {
116
+ const { values } = parseArgs({
117
+ options: {
118
+ registry: { type: 'string' },
119
+ 'wizard-url': { type: 'string' },
120
+ host: { type: 'string' },
121
+ 'icp-identity': { type: 'string' },
122
+ 'key-file': { type: 'string' },
123
+ wallet: { type: 'boolean' },
124
+ local: { type: 'boolean' },
125
+ activate: { type: 'boolean' },
126
+ connect: { type: 'boolean' },
127
+ invite: { type: 'string' },
128
+ 'agent-name': { type: 'string' },
129
+ yes: { type: 'boolean', short: 'y' },
130
+ help: { type: 'boolean', short: 'h' },
131
+ },
132
+ allowPositionals: true,
133
+ });
134
+ if (values.help) {
135
+ console.log(HELP);
136
+ return;
137
+ }
138
+ // ── Wallet handoff: owned by your wallet, created in the web wizard (no local signing here). ──
139
+ if (values.wallet) {
140
+ const wizardUrl = values['wizard-url'] ?? process.env['ENGRAMX_WIZARD_URL'] ?? CANONICAL_WIZARD_URL;
141
+ if (!wizardUrl) {
142
+ fail('No wizard URL. Pass --wizard-url <url> or set ENGRAMX_WIZARD_URL (the canonical default is unset until deploy).');
143
+ process.exit(1);
144
+ }
145
+ await walletHandoff(wizardUrl);
146
+ return;
147
+ }
148
+ // ── Self-signed create (local key or icp-cli identity). ──
149
+ const registryCanisterId = values.registry ?? process.env['ENGRAMX_REGISTRY'] ?? CANONICAL_REGISTRY_CANISTER_ID;
150
+ if (!registryCanisterId) {
151
+ fail('No registry canister id. Pass --registry <id> or set ENGRAMX_REGISTRY (the canonical default is unset until deploy).');
152
+ process.exit(1);
153
+ }
154
+ const local = Boolean(values.local);
155
+ const host = values.host ?? (local ? 'http://127.0.0.1:4943' : 'https://icp-api.io');
156
+ let identity;
157
+ const icpName = values['icp-identity'];
158
+ if (icpName) {
159
+ identity = icpCliOwnerKey(icpName);
160
+ info(`Owner = your icp-cli identity "${icpName}" (EngramX holds nothing).`);
161
+ }
162
+ else {
163
+ const key = localOwnerKey(values['key-file']);
164
+ identity = key.identity;
165
+ if (key.created) {
166
+ warn(`Generated a NEW local owner key at ${key.keyPath}. ` +
167
+ `${bold('This seed is your ONLY key — back it up now. Loss = permanent loss of ownership.')}`);
168
+ }
169
+ else {
170
+ info(`Owner = your local key at ${key.keyPath}.`);
171
+ }
172
+ }
173
+ const ownerPrincipal = identity.getPrincipal().toText();
174
+ info(`Owner principal: ${ownerPrincipal}`);
175
+ // The ownership/target flags to re-supply when activating later (so the SAME principal provisions).
176
+ const activateFlags = [
177
+ icpName ? `--icp-identity ${icpName}` : values['key-file'] ? `--key-file ${values['key-file']}` : '',
178
+ values.registry ? `--registry ${values.registry}` : '',
179
+ values.host ? `--host ${values.host}` : '',
180
+ local ? '--local' : '',
181
+ ]
182
+ .filter(Boolean)
183
+ .join(' ');
184
+ const activateCmd = `npx @engramx/owner --activate${activateFlags ? ' ' + activateFlags : ''}`;
185
+ const interactive = Boolean(process.stdout.isTTY && process.stdin.isTTY);
186
+ const backupNote = () => {
187
+ if (!icpName) {
188
+ console.log(` • ${yellow('Back up')} your owner key (${values['key-file'] ?? DEFAULT_KEY_PATH}) — it is the only key to this engram.`);
189
+ }
190
+ };
191
+ // --connect: the owner's real-use spawn trigger — provision (if needed) AND mint an append-only
192
+ // operator invite in one step, so the engram spawns exactly when you're wiring an agent to it.
193
+ if (values.connect) {
194
+ try {
195
+ const r = await connectAgent({ identity, registryCanisterId, host, local, invite: values.invite }, { name: values['agent-name'] });
196
+ ok(`Engram live: ${bold(r.canisterId)} — operator invite minted for "${r.operatorName}".`);
197
+ info(`You own it (owner principal ${r.owner}).`);
198
+ console.log('');
199
+ console.log(bold('Give this to your agent (append-only operator access):'));
200
+ console.log(` ${dim(`npx @engramx/client pair ${r.inviteCode} --engram ${r.canisterId}`)}`);
201
+ console.log('');
202
+ console.log(`${bold('The grant is append-only')} — the agent can read and add memory, never overwrite, delete, or move funds.`);
203
+ backupNote();
204
+ }
205
+ catch (e) {
206
+ fail(e instanceof Error ? e.message : String(e));
207
+ process.exit(1);
208
+ }
209
+ return;
210
+ }
211
+ // Reserve (free) — or reserve+provision now if --activate was explicitly passed.
212
+ let result = await createEngram({
213
+ identity,
214
+ registryCanisterId,
215
+ host,
216
+ local,
217
+ activate: Boolean(values.activate),
218
+ invite: values.invite,
219
+ });
220
+ // Interactive human who only reserved: offer to spin it up now (default yes — they ran this on purpose).
221
+ // Headless/agent (--yes or non-TTY) stays reserve-only unless --activate — that's the anti-drain gate.
222
+ if (result.state === 'reserved' && interactive && !values.yes) {
223
+ if (await confirm('Spin up your engram now? This provisions a live canister the platform funds.', true)) {
224
+ result = await provision({ identity, registryCanisterId, host, local, invite: values.invite });
225
+ }
226
+ }
227
+ if (result.state === 'provisioned') {
228
+ ok(result.alreadyExisted ? `You already own an engram: ${bold(result.canisterId)}` : `Engram live: ${bold(result.canisterId)}`);
229
+ info(`You own it (owner principal ${result.owner}). The platform funds the spawn (bounded by the registry reserve).`);
230
+ console.log('');
231
+ console.log(bold('Next:'));
232
+ console.log(` • Give an agent append-only access as an operator: ${dim(`npx @engramx/client pair <invite-code> --engram ${result.canisterId}`)}`);
233
+ console.log(` • Fund ongoing cycles with ckUSDC via the cashier (optional).`);
234
+ backupNote();
235
+ }
236
+ else {
237
+ ok(result.alreadyExisted ? 'Reservation already held — no cycles spent.' : 'Reserved — free, no cycles spent.');
238
+ info(`Owner principal ${result.owner}. Nothing is running yet; activate when you're ready to use it.`);
239
+ console.log('');
240
+ console.log(bold('Activate (spawns the canister):'));
241
+ console.log(` ${dim(activateCmd)}`);
242
+ backupNote();
243
+ }
244
+ }
245
+ main().catch((e) => {
246
+ fail(e instanceof Error ? e.message : String(e));
247
+ process.exit(1);
248
+ });
249
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const CANONICAL_REGISTRY_CANISTER_ID = "";
2
+ export declare const CANONICAL_WIZARD_URL = "";
package/dist/config.js ADDED
@@ -0,0 +1,10 @@
1
+ // Canonical fleet endpoints — SET AT FLEET DEPLOY (see the deployment runbook's distribution steps).
2
+ //
3
+ // The canonical registry is the one anchored by the constitutional REGISTRY_ROOT. Creating against it
4
+ // puts your engram in the canonical fleet (registered + third-party-verifiable); a different --registry
5
+ // creates against a fork. These defaults make the canonical fleet the zero-config target once deployed;
6
+ // until then they are empty and --registry / ENGRAMX_REGISTRY (or --wizard-url) is required. Override
7
+ // anytime for self-hosting or a dev replica.
8
+ export const CANONICAL_REGISTRY_CANISTER_ID = '';
9
+ export const CANONICAL_WIZARD_URL = '';
10
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,EAAE;AACF,sGAAsG;AACtG,wGAAwG;AACxG,wGAAwG;AACxG,sGAAsG;AACtG,6CAA6C;AAC7C,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AACjD,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC"}
@@ -0,0 +1,74 @@
1
+ import type { Identity } from '@icp-sdk/core/agent';
2
+ import type { OperatorPermissions } from './engram-idl.js';
3
+ export interface CreateOptions {
4
+ /** The owner identity — its principal becomes the engram's owner (root). Never EngramX's key. */
5
+ identity: Identity;
6
+ /** The EngramX registry canister id to create against (defaults to the canonical registry). */
7
+ registryCanisterId: string;
8
+ /** Replica host, e.g. https://icp-api.io (mainnet) or http://127.0.0.1:4943 (local). */
9
+ host: string;
10
+ /** Local replica → fetch the root key before calling. Never do this against mainnet. */
11
+ local: boolean;
12
+ /**
13
+ * Spawn the live canister in this same call. Default false → RESERVE only (a free registry
14
+ * record, ~$0). See the module docs for why reserve is the default.
15
+ */
16
+ activate?: boolean;
17
+ /**
18
+ * Invite code for deployments that arm the reserve gate (invite-or-wallet-proof admission).
19
+ * Raw-keypair identities (the kind this CLI mints) need one there; wallet-rooted identities
20
+ * do not. Ignored by deployments with the gate off (the default).
21
+ */
22
+ invite?: string;
23
+ }
24
+ export type EngramState = 'none' | 'reserved' | 'provisioned';
25
+ export interface CreateResult {
26
+ /** What exists now: 'none' (nothing yet), a free 'reserved' record, or a live 'provisioned' canister. */
27
+ state: EngramState;
28
+ /** The engram canister id — present only once provisioned (null while merely reserved). */
29
+ canisterId: string | null;
30
+ /** The owner principal (the identity that signed — you). */
31
+ owner: string;
32
+ /** True if the record already existed (one-per-principal) and was returned as-is. */
33
+ alreadyExisted: boolean;
34
+ }
35
+ /**
36
+ * Create an engram owned by `opts.identity`.
37
+ *
38
+ * RESERVE IS THE DEFAULT, and provisioning (the real ~1.15T-cycle canister spawn) is a separate,
39
+ * opt-in step. This is the cycle anti-drain: a skill/agent that calls "create" speculatively and
40
+ * walks away leaves only a FREE registry record (`reserved`), never a funded canister. The spawn
41
+ * happens only when the owner actually commits — `activate: true` here, or a later `provision()`
42
+ * call — i.e. when there is a real signal the engram will be used.
43
+ *
44
+ * The registry makes the CALLER the owner — no owner parameter, no reassignment — so the signing
45
+ * identity IS the owner, by construction. Idempotent on both steps: an existing reservation or
46
+ * engram (one-per-principal) is returned as-is rather than provoking an Err.
47
+ */
48
+ export declare function createEngram(opts: CreateOptions): Promise<CreateResult>;
49
+ /**
50
+ * Provision (spawn) the canister for an already-reserved principal — the funded step, split out so
51
+ * a two-phase flow (reserve now, activate later) can call it directly. Idempotent.
52
+ */
53
+ export declare function provision(opts: Omit<CreateOptions, 'activate'>): Promise<CreateResult>;
54
+ /**
55
+ * Read-only: what does this principal have — nothing, a free reservation, or a live engram? No
56
+ * writes, no spend. Used by the owner-side status surfaces (CLI check, owner MCP).
57
+ */
58
+ export declare function status(opts: Omit<CreateOptions, 'activate'>): Promise<CreateResult>;
59
+ export interface ConnectAgentResult extends CreateResult {
60
+ /** The invite code the AGENT redeems with `@engramx/client pair` to become an append-only operator. */
61
+ inviteCode: string;
62
+ /** The label recorded for this operator. */
63
+ operatorName: string;
64
+ }
65
+ /**
66
+ * Connect an agent: provision the engram if needed (the owner's real-use spawn trigger — you only
67
+ * spin it up when you're actually wiring an agent), then mint an append-only OPERATOR invite for it.
68
+ * The agent redeems the returned code with `@engramx/client pair`. Owner ≠ operator, by construction:
69
+ * this mints a scoped, append-only grant, never owner powers.
70
+ */
71
+ export declare function connectAgent(opts: Omit<CreateOptions, 'activate'>, params?: {
72
+ name?: string;
73
+ permissions?: OperatorPermissions;
74
+ }): Promise<ConnectAgentResult>;
package/dist/create.js ADDED
@@ -0,0 +1,124 @@
1
+ import { HttpAgent, Actor } from '@icp-sdk/core/agent';
2
+ import { registryIdlFactory } from './registry-idl.js';
3
+ import { engramIdlFactory, DEFAULT_OPERATOR_PERMISSIONS } from './engram-idl.js';
4
+ const gateOpts = (invite) => invite ? [{ invite: [invite], walletProof: [] }] : [];
5
+ const createOpts = (invite) => invite ? [{ genesis: [], invite: [invite], walletProof: [] }] : [];
6
+ function connect(opts) {
7
+ const agent = HttpAgent.createSync({ identity: opts.identity, host: opts.host });
8
+ const ready = opts.local ? agent.fetchRootKey() : Promise.resolve();
9
+ return ready.then(() => Actor.createActor(registryIdlFactory, {
10
+ agent,
11
+ canisterId: opts.registryCanisterId,
12
+ }));
13
+ }
14
+ /**
15
+ * Create an engram owned by `opts.identity`.
16
+ *
17
+ * RESERVE IS THE DEFAULT, and provisioning (the real ~1.15T-cycle canister spawn) is a separate,
18
+ * opt-in step. This is the cycle anti-drain: a skill/agent that calls "create" speculatively and
19
+ * walks away leaves only a FREE registry record (`reserved`), never a funded canister. The spawn
20
+ * happens only when the owner actually commits — `activate: true` here, or a later `provision()`
21
+ * call — i.e. when there is a real signal the engram will be used.
22
+ *
23
+ * The registry makes the CALLER the owner — no owner parameter, no reassignment — so the signing
24
+ * identity IS the owner, by construction. Idempotent on both steps: an existing reservation or
25
+ * engram (one-per-principal) is returned as-is rather than provoking an Err.
26
+ */
27
+ export async function createEngram(opts) {
28
+ const registry = await connect(opts);
29
+ const owner = opts.identity.getPrincipal().toText();
30
+ // Already provisioned? (one-per-principal) — return the live canister, regardless of `activate`.
31
+ const existingEngram = await registry.getMyEngram();
32
+ if (existingEngram.length > 0 && existingEngram[0]) {
33
+ return {
34
+ state: 'provisioned',
35
+ canisterId: existingEngram[0].canisterId.toText(),
36
+ owner,
37
+ alreadyExisted: true,
38
+ };
39
+ }
40
+ // Reserve (idempotent, free). A pre-existing reservation counts as "already existed".
41
+ const priorReservation = await registry.getMyReservation();
42
+ const hadReservation = priorReservation.length > 0;
43
+ if (!hadReservation) {
44
+ const r = await registry.reserveEngram(gateOpts(opts.invite));
45
+ if (r.Err)
46
+ throw new Error(r.Err);
47
+ }
48
+ if (!opts.activate) {
49
+ return { state: 'reserved', canisterId: null, owner, alreadyExisted: hadReservation };
50
+ }
51
+ // Activate: consume the reservation and spawn the canister (the funded step).
52
+ return provisionReserved(registry, owner, opts.invite);
53
+ }
54
+ /**
55
+ * Provision (spawn) the canister for an already-reserved principal — the funded step, split out so
56
+ * a two-phase flow (reserve now, activate later) can call it directly. Idempotent.
57
+ */
58
+ export async function provision(opts) {
59
+ const registry = await connect(opts);
60
+ const owner = opts.identity.getPrincipal().toText();
61
+ const existingEngram = await registry.getMyEngram();
62
+ if (existingEngram.length > 0 && existingEngram[0]) {
63
+ return {
64
+ state: 'provisioned',
65
+ canisterId: existingEngram[0].canisterId.toText(),
66
+ owner,
67
+ alreadyExisted: true,
68
+ };
69
+ }
70
+ return provisionReserved(registry, owner, opts.invite);
71
+ }
72
+ /**
73
+ * Read-only: what does this principal have — nothing, a free reservation, or a live engram? No
74
+ * writes, no spend. Used by the owner-side status surfaces (CLI check, owner MCP).
75
+ */
76
+ export async function status(opts) {
77
+ const registry = await connect(opts);
78
+ const owner = opts.identity.getPrincipal().toText();
79
+ const existingEngram = await registry.getMyEngram();
80
+ if (existingEngram.length > 0 && existingEngram[0]) {
81
+ return { state: 'provisioned', canisterId: existingEngram[0].canisterId.toText(), owner, alreadyExisted: true };
82
+ }
83
+ const reservation = await registry.getMyReservation();
84
+ if (reservation.length > 0) {
85
+ return { state: 'reserved', canisterId: null, owner, alreadyExisted: true };
86
+ }
87
+ return { state: 'none', canisterId: null, owner, alreadyExisted: false };
88
+ }
89
+ /**
90
+ * Connect an agent: provision the engram if needed (the owner's real-use spawn trigger — you only
91
+ * spin it up when you're actually wiring an agent), then mint an append-only OPERATOR invite for it.
92
+ * The agent redeems the returned code with `@engramx/client pair`. Owner ≠ operator, by construction:
93
+ * this mints a scoped, append-only grant, never owner powers.
94
+ */
95
+ export async function connectAgent(opts, params) {
96
+ const provisioned = await provision(opts);
97
+ if (!provisioned.canisterId)
98
+ throw new Error('Engram was not provisioned — cannot mint an invite');
99
+ const agent = HttpAgent.createSync({ identity: opts.identity, host: opts.host });
100
+ if (opts.local)
101
+ await agent.fetchRootKey();
102
+ const engram = Actor.createActor(engramIdlFactory, {
103
+ agent,
104
+ canisterId: provisioned.canisterId,
105
+ });
106
+ const operatorName = params?.name ?? 'agent';
107
+ const res = await engram.createOperatorInvite(operatorName, params?.permissions ?? DEFAULT_OPERATOR_PERMISSIONS);
108
+ if (res.Err)
109
+ throw new Error(res.Err);
110
+ if (!res.Ok)
111
+ throw new Error('Engram returned no invite code');
112
+ return { ...provisioned, inviteCode: res.Ok, operatorName };
113
+ }
114
+ async function provisionReserved(registry, owner, invite) {
115
+ // The invite normally rides the reservation (consumed at reserve); passing it here too covers the
116
+ // DIRECT-provision case (no prior reservation) on gate-armed deployments, and is retry-idempotent.
117
+ const p = await registry.provisionEngram(createOpts(invite));
118
+ if (p.Err)
119
+ throw new Error(p.Err);
120
+ if (!p.Ok)
121
+ throw new Error('Registry returned no result for provisionEngram');
122
+ return { state: 'provisioned', canisterId: p.Ok.canisterId.toText(), owner, alreadyExisted: false };
123
+ }
124
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare const engramIdlFactory: ({ IDL }: {
2
+ IDL: any;
3
+ }) => any;
4
+ /** The default connect-an-agent grant: read + append (the standard append-only operator), no wallet. */
5
+ export interface OperatorPermissions {
6
+ canReadMemory: boolean;
7
+ scopes: [] | [string[]];
8
+ canReadBackup: [] | [boolean];
9
+ callsPerMinute: bigint;
10
+ canAppendMemory: boolean;
11
+ canReadWallet: boolean;
12
+ }
13
+ export declare const DEFAULT_OPERATOR_PERMISSIONS: OperatorPermissions;
@@ -0,0 +1,28 @@
1
+ // Minimal engram IDL — the OWNER's connect-an-agent subset only (createOperatorInvite).
2
+ //
3
+ // A deliberate SUBSET of engramx/src/generated/engram.idl.js, hand-vendored so @engramx/owner stays
4
+ // self-contained AND carries no operator/memory surface. The owner mints an append-only operator
5
+ // invite; the AGENT redeems it with @engramx/client. Types copied verbatim from the generated factory.
6
+ export const engramIdlFactory = ({ IDL }) => {
7
+ const OperatorPermissions = IDL.Record({
8
+ canReadMemory: IDL.Bool,
9
+ scopes: IDL.Opt(IDL.Vec(IDL.Text)),
10
+ canReadBackup: IDL.Opt(IDL.Bool),
11
+ callsPerMinute: IDL.Nat,
12
+ canAppendMemory: IDL.Bool,
13
+ canReadWallet: IDL.Bool,
14
+ });
15
+ return IDL.Service({
16
+ // Owner-only. Returns the invite code the agent redeems via `@engramx/client pair`.
17
+ createOperatorInvite: IDL.Func([IDL.Text, OperatorPermissions], [IDL.Variant({ Ok: IDL.Text, Err: IDL.Text })], []),
18
+ });
19
+ };
20
+ export const DEFAULT_OPERATOR_PERMISSIONS = {
21
+ canReadMemory: true,
22
+ canAppendMemory: true,
23
+ canReadWallet: false,
24
+ canReadBackup: [],
25
+ scopes: [],
26
+ callsPerMinute: 120n,
27
+ };
28
+ //# sourceMappingURL=engram-idl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engram-idl.js","sourceRoot":"","sources":["../src/engram-idl.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,EAAE;AACF,oGAAoG;AACpG,iGAAiG;AACjG,uGAAuG;AAEvG,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,EAAE,GAAG,EAAgB,EAAE,EAAE;IACxD,MAAM,mBAAmB,GAAG,GAAG,CAAC,MAAM,CAAC;QACrC,aAAa,EAAE,GAAG,CAAC,IAAI;QACvB,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;QAChC,cAAc,EAAE,GAAG,CAAC,GAAG;QACvB,eAAe,EAAE,GAAG,CAAC,IAAI;QACzB,aAAa,EAAE,GAAG,CAAC,IAAI;KACxB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,OAAO,CAAC;QACjB,oFAAoF;QACpF,oBAAoB,EAAE,GAAG,CAAC,IAAI,CAC5B,CAAC,GAAG,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAC/B,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAC9C,EAAE,CACH;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AAYF,MAAM,CAAC,MAAM,4BAA4B,GAAwB;IAC/D,aAAa,EAAE,IAAI;IACnB,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,EAAE;IACjB,MAAM,EAAE,EAAE;IACV,cAAc,EAAE,IAAI;CACrB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { createEngram, provision, status, connectAgent } from './create.js';
2
+ export type { CreateOptions, CreateResult, EngramState, ConnectAgentResult } from './create.js';
3
+ export { DEFAULT_OPERATOR_PERMISSIONS } from './engram-idl.js';
4
+ export type { OperatorPermissions } from './engram-idl.js';
5
+ export { localOwnerKey, icpCliOwnerKey, DEFAULT_KEY_PATH } from './owner-key.js';
6
+ export type { LocalKey } from './owner-key.js';
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ // @engramx/owner — the owner-side engram-creation surface. Kept separate from @engramx/client (the
2
+ // operator SDK) so operators never gain owner powers. See SKILL.md for the agent-invocable capability.
3
+ export { createEngram, provision, status, connectAgent } from './create.js';
4
+ export { DEFAULT_OPERATOR_PERMISSIONS } from './engram-idl.js';
5
+ export { localOwnerKey, icpCliOwnerKey, DEFAULT_KEY_PATH } from './owner-key.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,uGAAuG;AACvG,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { Ed25519KeyIdentity } from '@icp-sdk/core/identity';
2
+ import type { Identity } from '@icp-sdk/core/agent';
3
+ /** Default self-custody owner-key location. A 32-byte Ed25519 seed. */
4
+ export declare const DEFAULT_KEY_PATH: string;
5
+ export interface LocalKey {
6
+ identity: Ed25519KeyIdentity;
7
+ created: boolean;
8
+ keyPath: string;
9
+ }
10
+ /**
11
+ * Load or generate a LOCAL, self-custody Ed25519 owner key (a 32-byte seed at ~/.engramx/owner.key by
12
+ * default). EngramX holds nothing. A bare local key means loss = permanent loss of ownership — the
13
+ * caller is responsible for backing up the seed. Refuses symlinks and world/group-readable files.
14
+ */
15
+ export declare function localOwnerKey(keyPath?: string): LocalKey;
16
+ /**
17
+ * Reuse an existing icp-cli identity (secp256k1) by name, via `icp identity export`. Custody stays in
18
+ * the user's icp-cli store; EngramX holds nothing, and the user keeps whatever backup/recovery the
19
+ * icp-cli identity already has (e.g. its 24-word seed). Still a single key.
20
+ */
21
+ export declare function icpCliOwnerKey(name: string): Identity;
@@ -0,0 +1,63 @@
1
+ import { Ed25519KeyIdentity } from '@icp-sdk/core/identity';
2
+ import { Secp256k1KeyIdentity } from '@icp-sdk/core/identity/secp256k1';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { createPrivateKey, randomBytes } from 'node:crypto';
5
+ import * as fs from 'node:fs';
6
+ import * as path from 'node:path';
7
+ import * as os from 'node:os';
8
+ /** Default self-custody owner-key location. A 32-byte Ed25519 seed. */
9
+ export const DEFAULT_KEY_PATH = path.join(os.homedir(), '.engramx', 'owner.key');
10
+ /**
11
+ * Load or generate a LOCAL, self-custody Ed25519 owner key (a 32-byte seed at ~/.engramx/owner.key by
12
+ * default). EngramX holds nothing. A bare local key means loss = permanent loss of ownership — the
13
+ * caller is responsible for backing up the seed. Refuses symlinks and world/group-readable files.
14
+ */
15
+ export function localOwnerKey(keyPath = DEFAULT_KEY_PATH) {
16
+ if (fs.existsSync(keyPath)) {
17
+ if (fs.lstatSync(keyPath).isSymbolicLink()) {
18
+ throw new Error(`Owner key cannot be a symlink: ${keyPath}`);
19
+ }
20
+ const mode = fs.statSync(keyPath).mode & 0o777;
21
+ if (mode & 0o077) {
22
+ throw new Error(`Owner key ${keyPath} has insecure permissions (${mode.toString(8)}); expected 0600. ` +
23
+ `Fix with: chmod 600 ${keyPath}`);
24
+ }
25
+ const seed = fs.readFileSync(keyPath);
26
+ if (seed.length !== 32) {
27
+ throw new Error(`Invalid owner key: expected 32 bytes, got ${seed.length}`);
28
+ }
29
+ return { identity: Ed25519KeyIdentity.generate(seed), created: false, keyPath };
30
+ }
31
+ const seed = randomBytes(32);
32
+ const dir = path.dirname(keyPath);
33
+ if (!fs.existsSync(dir))
34
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
35
+ fs.writeFileSync(keyPath, seed, { mode: 0o600 });
36
+ return { identity: Ed25519KeyIdentity.generate(seed), created: true, keyPath };
37
+ }
38
+ /**
39
+ * Reuse an existing icp-cli identity (secp256k1) by name, via `icp identity export`. Custody stays in
40
+ * the user's icp-cli store; EngramX holds nothing, and the user keeps whatever backup/recovery the
41
+ * icp-cli identity already has (e.g. its 24-word seed). Still a single key.
42
+ */
43
+ export function icpCliOwnerKey(name) {
44
+ let pem;
45
+ try {
46
+ pem = execFileSync('icp', ['identity', 'export', name], { encoding: 'utf-8' }).trim();
47
+ }
48
+ catch {
49
+ throw new Error(`Could not export icp-cli identity "${name}". Is icp-cli installed and the identity present? ` +
50
+ `List them with: icp identity list`);
51
+ }
52
+ const jwk = createPrivateKey(pem).export({ format: 'jwk' });
53
+ if (!jwk.d) {
54
+ throw new Error(`icp-cli identity "${name}" is not an exportable private key.`);
55
+ }
56
+ if (jwk.crv && jwk.crv !== 'secp256k1') {
57
+ throw new Error(`icp-cli identity "${name}" is ${jwk.crv}; only secp256k1 identities are supported here. ` +
58
+ `Create one with: icp identity new <name>`);
59
+ }
60
+ const secret = Uint8Array.from(Buffer.from(jwk.d, 'base64url'));
61
+ return Secp256k1KeyIdentity.fromSecretKey(secret);
62
+ }
63
+ //# sourceMappingURL=owner-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-key.js","sourceRoot":"","sources":["../src/owner-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,uEAAuE;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAQjF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,gBAAgB;IAC9D,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,kCAAkC,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;QAC/C,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,aAAa,OAAO,8BAA8B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,oBAAoB;gBACpF,uBAAuB,OAAO,EAAE,CACnC,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAClF,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,OAAO,EAAE,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,sCAAsC,IAAI,oDAAoD;YAC5F,mCAAmC,CACtC,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAiC,CAAC;IAC5F,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,qCAAqC,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,qBAAqB,IAAI,QAAQ,GAAG,CAAC,GAAG,kDAAkD;YACxF,0CAA0C,CAC7C,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,OAAO,oBAAoB,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare const registryIdlFactory: ({ IDL }: {
2
+ IDL: any;
3
+ }) => any;
@@ -0,0 +1,55 @@
1
+ // Minimal registry IDL — the CREATE subset only (create / reserve / provision + read-back).
2
+ //
3
+ // A deliberate SUBSET of engramx/src/generated/registry.idl.js, hand-vendored here so @engramx/owner
4
+ // stays self-contained and publishable (a package can't reach into ../../src/generated) AND so this
5
+ // owner-side package carries no operator/engram surface at all. If the registry's create surface
6
+ // changes, mirror the matching entries here. All types are copied verbatim from the generated factory.
7
+ export const registryIdlFactory = ({ IDL }) => {
8
+ const CreateEngramResult = IDL.Variant({
9
+ Ok: IDL.Record({ canisterId: IDL.Principal }),
10
+ Err: IDL.Text,
11
+ });
12
+ const ReserveResult = IDL.Variant({
13
+ Ok: IDL.Record({ reserved: IDL.Bool }),
14
+ Err: IDL.Text,
15
+ });
16
+ const EngramStatus = IDL.Variant({
17
+ Active: IDL.Null,
18
+ Deleted: IDL.Null,
19
+ Frozen: IDL.Null,
20
+ });
21
+ const EngramRecord = IDL.Record({
22
+ status: EngramStatus,
23
+ owner: IDL.Principal,
24
+ createdAt: IDL.Int,
25
+ canisterId: IDL.Principal,
26
+ });
27
+ const Reservation = IDL.Record({ reservedAt: IDL.Int });
28
+ const ActivationFunnel = IDL.Record({
29
+ reserved: IDL.Nat,
30
+ provisioned: IDL.Nat,
31
+ reservedStale: IDL.Nat,
32
+ spawnsToday: IDL.Nat,
33
+ dailyCap: IDL.Nat,
34
+ spawnCeiling: IDL.Nat,
35
+ });
36
+ // Opts records gain opt fields forever, so passing null stays valid. genesis = the owner's first
37
+ // real content, written atomically as the canister spawns. invite / walletProof = the OPTIONAL
38
+ // admission gate (when the deployment arms it): a one-shot invite code, or the caller's DER public
39
+ // key proving a wallet-rooted (canister-signature) identity.
40
+ const CreateOpts = IDL.Opt(IDL.Record({
41
+ genesis: IDL.Opt(IDL.Record({ path: IDL.Text, content: IDL.Vec(IDL.Nat8) })),
42
+ invite: IDL.Opt(IDL.Text),
43
+ walletProof: IDL.Opt(IDL.Vec(IDL.Nat8)),
44
+ }));
45
+ const ReserveOpts = IDL.Opt(IDL.Record({ invite: IDL.Opt(IDL.Text), walletProof: IDL.Opt(IDL.Vec(IDL.Nat8)) }));
46
+ return IDL.Service({
47
+ createEngram: IDL.Func([CreateOpts], [CreateEngramResult], []),
48
+ reserveEngram: IDL.Func([ReserveOpts], [ReserveResult], []),
49
+ provisionEngram: IDL.Func([CreateOpts], [CreateEngramResult], []),
50
+ getMyEngram: IDL.Func([], [IDL.Opt(EngramRecord)], ['query']),
51
+ getMyReservation: IDL.Func([], [IDL.Opt(Reservation)], ['query']),
52
+ getActivationFunnel: IDL.Func([], [ActivationFunnel], ['query']),
53
+ });
54
+ };
55
+ //# sourceMappingURL=registry-idl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-idl.js","sourceRoot":"","sources":["../src/registry-idl.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@engramx/owner",
3
+ "version": "0.1.0",
4
+ "description": "Own an EngramX engram — the standalone owner-side CLI/SDK (create, reserve, activate). Deliberately separate from the operator SDK (@engramx/client) so operators never gain owner powers.",
5
+ "license": "MIT",
6
+ "author": "EngramX <developer@engramx.ai>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/vhew/engramx",
10
+ "directory": "packages/owner"
11
+ },
12
+ "homepage": "https://github.com/vhew/engramx#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/vhew/engramx/issues"
15
+ },
16
+ "keywords": [
17
+ "icp",
18
+ "internet-computer",
19
+ "ai-agent",
20
+ "engram",
21
+ "memory",
22
+ "decentralized",
23
+ "skill"
24
+ ],
25
+ "type": "module",
26
+ "engines": {
27
+ "node": ">=22.12.0"
28
+ },
29
+ "main": "dist/index.js",
30
+ "types": "dist/index.d.ts",
31
+ "bin": {
32
+ "engramx-owner": "./dist/cli.js"
33
+ },
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.js"
38
+ }
39
+ },
40
+ "files": [
41
+ "dist/",
42
+ "SKILL.md",
43
+ "README.md",
44
+ "LICENSE"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "dependencies": {
50
+ "@icp-sdk/core": "^5.4.0"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^25.9.2",
54
+ "typescript": "^6.0.3",
55
+ "vitest": "^4.1.8"
56
+ },
57
+ "scripts": {
58
+ "build": "tsc",
59
+ "typecheck": "tsc --noEmit",
60
+ "test": "vitest run"
61
+ }
62
+ }