enigma-memory 0.1.5 → 0.1.6
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 +43 -35
- package/apps/cli/bin/enigma.mjs +662 -67
- package/docs/developer-ecosystem.md +73 -6
- package/docs/sdk-api.md +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/src/index.js +1 -1
- package/scripts/build-installer-assets.mjs +1 -1
- package/scripts/run-standard-memory-benchmarks.mjs +1 -1
package/README.md
CHANGED
|
@@ -1,48 +1,41 @@
|
|
|
1
1
|
# Enigma
|
|
2
2
|
|
|
3
|
-
Enigma is a
|
|
3
|
+
Enigma Memory is a local-first AI Memory Passport. It gives you one canonical local memory vault, receipt-backed proof for Enigma-controlled events, and MCP connections into assistants such as Claude Desktop, Cursor, Kimi Code, and generic MCP clients.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Start with the package path below. You do not need to understand relay, gateway, mesh, browser, desktop, or hosted infrastructure before trying Enigma locally.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- Published npm package: package bins and module entry points are available as `enigma-memory`; use the npm install path below for the simplest onboarding flow.
|
|
9
|
-
- Source-only artifacts: `docs/`, `Dockerfile`, and `docker-compose.yml` live in the source checkout. The package README and CLI help are the package-included install guides; the full runbooks require the repository or hosted docs.
|
|
10
|
-
- Hosted cloud is not included by default. Hosted relay/gateway/cloud operation requires deployment credentials, a domain, TLS, production durable storage, KMS/secrets, monitoring, backups, operator policy, and a completed operator acceptance packet. Local relay/gateway `--state-file` demo state does not satisfy those hosted/BYOC requirements.
|
|
11
|
-
- Cloudflare API/domain/hosting automation is documented but safe-by-default: [`docs/cloudflare-token-and-domain-runbook.md`](docs/cloudflare-token-and-domain-runbook.md) gives the token recipe, Registrar prerequisites, local token storage rule, search/check flow, explicit domain+price purchase gate, Pages deploy gate, custom-domain steps, and post-setup token rotation.
|
|
12
|
-
- Overnight execution plan: [`docs/overnight-build-master-plan.md`](docs/overnight-build-master-plan.md) defines the GPT-5.5/Kimi overnight build cadence, acceptance gates, exact non-claims, and hosted/BYOC blockers.
|
|
13
|
-
- Security and production review artifacts: [`SECURITY.md`](SECURITY.md) defines reporting, safe harbor, disclosure, incident, secret-handling, plaintext-minimization, and proof-boundary policy; [`docs/security-threat-model.md`](docs/security-threat-model.md) maps assets, trust boundaries, controls, residual risks, and verification evidence; [`docs/operator-acceptance-packet.md`](docs/operator-acceptance-packet.md) is required before hosted/BYOC can be called live.
|
|
14
|
-
- Public API reference: [`docs/public-api-reference.md`](docs/public-api-reference.md) lists package exports, CLI bins, MCP tools/resources/prompts, relay/gateway endpoints, importer/capsule APIs, connector profiles, verifier outputs, schemas, and local-vs-hosted boundaries.
|
|
15
|
-
- Local release provenance/SBOM: [`docs/release-provenance-and-sbom.md`](docs/release-provenance-and-sbom.md) documents `npm run provenance:local -- --out ./.enigma/release-provenance.json` as unsigned local package-surface inventory and SHA-256 evidence only, not signed attestation, registry provenance, source-control proof, SLSA/compliance, Docker image, or hosted/cloud deployment evidence.
|
|
16
|
-
- Reviewer packet: [`docs/reviewer-packet.md`](docs/reviewer-packet.md) documents `npm run review:packet -- --out ./.enigma-review-packet --public-site <path-to-_public_site>` as a local hand-review bundle for package, release-audit, provenance, and optional generated public-site evidence; it is not npm publication, live Cloudflare deployment, Docker runtime proof, hosted/BYOC readiness, legal approval, signed provenance, or compliance evidence.
|
|
7
|
+
The package path needs no database, provider credential, cloud credential, npm publishing token, or external account. Hosted cloud and BYOC operation are separate advanced modes that require real deployment credentials, domains, TLS, durable storage, KMS/secrets, monitoring, backups, and operator acceptance.
|
|
17
8
|
|
|
18
9
|
Enigma does not claim that a closed provider deleted internal data, that model weights forgot, or that provider-native memory disappeared. It proves facts about Enigma-controlled vault state, receipts, checkpoints, and declared boundary operations.
|
|
19
10
|
|
|
20
|
-
## Install
|
|
11
|
+
## Install once, use everywhere
|
|
21
12
|
|
|
22
13
|
Prerequisites:
|
|
23
14
|
|
|
24
15
|
- Node.js `>=24`
|
|
25
|
-
- No database, package registry account, provider credential, or cloud credential for the local
|
|
16
|
+
- No database, package registry account, provider credential, or cloud credential for the local setup path
|
|
26
17
|
- Git only when you choose the advanced source-checkout path
|
|
27
18
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Use the published package first:
|
|
19
|
+
Use Enigma as a one-time AI Memory Passport setup: install the package, create the local Enigma workspace once, then use the same memory/search/context/verify/connect loop from any supported client.
|
|
31
20
|
|
|
32
21
|
```sh
|
|
33
22
|
npm install -g enigma-memory
|
|
34
|
-
enigma
|
|
35
|
-
enigma
|
|
36
|
-
enigma
|
|
37
|
-
enigma
|
|
23
|
+
enigma setup --overwrite
|
|
24
|
+
enigma remember --text-file ./memory.txt
|
|
25
|
+
enigma search --query "..."
|
|
26
|
+
enigma context --query "..." --optimize
|
|
27
|
+
enigma verify --export ./.enigma/export.json
|
|
28
|
+
enigma connect claude-desktop --dry-run
|
|
38
29
|
```
|
|
39
30
|
|
|
40
|
-
`enigma
|
|
31
|
+
`enigma setup --overwrite` writes local Enigma artifacts under the workspace `.enigma` path and emits deterministic, public-safe JSON. It does not write Claude, Cursor, Kimi, or other third-party app configs. Client config writes happen only when you explicitly run `enigma connect <client>` without `--dry-run`; keep `--dry-run` while reviewing the planned MCP entry.
|
|
32
|
+
|
|
33
|
+
The local Enigma vault remains canonical. Provider-native memory should be treated as a convenience cache only. Enigma receipts prove Enigma-controlled vault state, receipts, checkpoints, and declared boundary operations; they do not prove provider deletion, provider model forgetting, provider-native memory removal, hosted availability, ROI/savings, or compliance certification.
|
|
41
34
|
|
|
42
35
|
One-off execution without a global install:
|
|
43
36
|
|
|
44
37
|
```sh
|
|
45
|
-
npx --yes --package enigma-memory enigma
|
|
38
|
+
npx --yes --package enigma-memory enigma setup --overwrite
|
|
46
39
|
```
|
|
47
40
|
|
|
48
41
|
## Advanced/source-only path
|
|
@@ -60,7 +53,7 @@ enigma-gateway demo
|
|
|
60
53
|
|
|
61
54
|
`install:local` is dry-run unless `--execute` is present. The command above installs the checked-out package globally and creates a local vault bundle. It does not require Cloudflare, OpenAI, Anthropic, npm publish credentials, a database, or hosted infrastructure.
|
|
62
55
|
|
|
63
|
-
Manual alternative:
|
|
56
|
+
Manual alternative: inspect the lower-level local vault steps that `enigma setup` prepares for you. Use a tenant-approved smoke file; do not expand private memory into shell argv.
|
|
64
57
|
|
|
65
58
|
POSIX shell:
|
|
66
59
|
|
|
@@ -72,7 +65,7 @@ enigma init --bundle ./.enigma/bundle.json --subject local-user --display-name "
|
|
|
72
65
|
enigma remember --bundle ./.enigma/bundle.json --text-file "$ENIGMA_DEMO_MEMORY_FILE" --purpose user_memory --tags local
|
|
73
66
|
enigma context --bundle ./.enigma/bundle.json --query "local context" --purpose local_answer --out ./.enigma/context-pack.json
|
|
74
67
|
enigma export --bundle ./.enigma/bundle.json --out ./.enigma/export.json
|
|
75
|
-
enigma verify --
|
|
68
|
+
enigma verify --export ./.enigma/export.json
|
|
76
69
|
```
|
|
77
70
|
|
|
78
71
|
Windows PowerShell:
|
|
@@ -85,7 +78,7 @@ enigma init --bundle .\.enigma\bundle.json --subject local-user --display-name "
|
|
|
85
78
|
enigma remember --bundle .\.enigma\bundle.json --text-file $env:ENIGMA_DEMO_MEMORY_FILE --purpose user_memory --tags local
|
|
86
79
|
enigma context --bundle .\.enigma\bundle.json --query "local context" --purpose local_answer --out .\.enigma\context-pack.json
|
|
87
80
|
enigma export --bundle .\.enigma\bundle.json --out .\.enigma\export.json
|
|
88
|
-
enigma verify --
|
|
81
|
+
enigma verify --export .\.enigma\export.json
|
|
89
82
|
```
|
|
90
83
|
|
|
91
84
|
The bundle is local. Exported proof artifacts contain encrypted/committed vault state and receipt metadata; do not paste raw memory plaintext into relay records, witness checkpoints, SIEM events, public proof artifacts, or shell command lines.
|
|
@@ -150,16 +143,31 @@ Supported connector profiles are:
|
|
|
150
143
|
- `opencode`
|
|
151
144
|
- `generic-mcp`
|
|
152
145
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
CLI connector commands:
|
|
146
|
+
After `enigma setup --overwrite`, preview a client connection before writing anything:
|
|
156
147
|
|
|
157
148
|
```sh
|
|
158
|
-
enigma
|
|
159
|
-
enigma
|
|
160
|
-
enigma connect
|
|
161
|
-
enigma connect
|
|
162
|
-
|
|
149
|
+
enigma connect claude-desktop --dry-run
|
|
150
|
+
enigma connect cursor --dry-run
|
|
151
|
+
enigma connect kimi-code --dry-run
|
|
152
|
+
enigma connect generic-mcp --dry-run
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Remove `--dry-run` only after you are ready for Enigma to merge the `mcpServers.enigma` entry into that client config. The setup command itself never writes third-party app configs.
|
|
156
|
+
|
|
157
|
+
Manual MCP entry for Claude Desktop, Cursor, Kimi Code, or any generic MCP client:
|
|
158
|
+
|
|
159
|
+
```json
|
|
160
|
+
{
|
|
161
|
+
"mcpServers": {
|
|
162
|
+
"enigma": {
|
|
163
|
+
"command": "enigma-mcp",
|
|
164
|
+
"args": [],
|
|
165
|
+
"env": {
|
|
166
|
+
"ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
163
171
|
```
|
|
164
172
|
|
|
165
173
|
Use `--mcp-command` (alias `--command`) when a GUI app cannot find shell-installed binaries or needs a `.cmd` path on Windows.
|
|
@@ -291,7 +299,7 @@ test -f "$ENIGMA_DEMO_MEMORY_FILE"
|
|
|
291
299
|
enigma init --bundle ./.enigma/bundle.json
|
|
292
300
|
enigma remember --bundle ./.enigma/bundle.json --text-file "$ENIGMA_DEMO_MEMORY_FILE" --purpose local_test
|
|
293
301
|
enigma export --bundle ./.enigma/bundle.json --out ./.enigma/export.json
|
|
294
|
-
enigma verify --
|
|
302
|
+
enigma verify --export ./.enigma/export.json
|
|
295
303
|
enigma boundary run --scenario committed_crossing
|
|
296
304
|
```
|
|
297
305
|
|
package/apps/cli/bin/enigma.mjs
CHANGED
|
@@ -11,13 +11,17 @@ import { runBoundarySimulation } from '../../../packages/boundary/src/index.js';
|
|
|
11
11
|
import { startStdioServer } from '../../../packages/mcp-server/src/index.js';
|
|
12
12
|
import { runMeshDemo } from '../../../packages/mesh/src/index.js';
|
|
13
13
|
import { runEnterpriseDemo } from '../../../packages/enterprise/src/index.js';
|
|
14
|
-
import { connectClient, disconnectClient, doctorConnectors, getClientProfile, renderMcpConfig, supportedClients } from '../../../packages/connectors/src/index.js';
|
|
14
|
+
import { connectClient, disconnectClient, doctorConnectors, getClientProfile, planConnectWizard, renderMcpConfig, supportedClients } from '../../../packages/connectors/src/index.js';
|
|
15
15
|
import { exportEnigmaCapsule, importChatGptExport, importClaudeMemory, importEnigmaCapsule, importLangGraphStore, importLettaAgentFile, importMem0Export, importZepGraphitiExport } from '../../../packages/importers/src/index.js';
|
|
16
16
|
import * as relayServer from '../../relay/src/server.mjs';
|
|
17
17
|
import * as gatewayServer from '../../gateway/src/server.mjs';
|
|
18
18
|
import { verifyBundle } from '../../verifier/bin/enigma-verify.mjs';
|
|
19
19
|
import { createNativeHostInstallPlan, createNativeHostManifest } from '../../native-host/bin/enigma-native-host.mjs';
|
|
20
20
|
import { aggregateUsageEvents, createUsageEvent } from '../../../packages/metering/src/index.js';
|
|
21
|
+
import {
|
|
22
|
+
createMemoryAccessReceipt,
|
|
23
|
+
createMemoryOptimizationPlan,
|
|
24
|
+
} from '../../../packages/optimizer/src/index.js';
|
|
21
25
|
import {
|
|
22
26
|
createConsumerGpuCapacityProfile,
|
|
23
27
|
createOperatorServiceQuote,
|
|
@@ -33,6 +37,21 @@ export const DEFAULT_GATEWAY_PORT = 8797;
|
|
|
33
37
|
const DEFAULT_QUICKSTART_MEMORY = 'Enigma quickstart demo memory: local proof bundles can be created and verified without provider or cloud credentials.';
|
|
34
38
|
const DEFAULT_CROSS_MODEL_DEMO_BUNDLE = '.enigma/cross-model-demo-bundle.json';
|
|
35
39
|
const DEFAULT_CROSS_MODEL_MEMORY = 'Enigma cross-model demo memory: a local encrypted memory can be packaged for ChatGPT, Claude, Kimi, Cursor, and a local LLM without provider credentials.';
|
|
40
|
+
const DEFAULT_SETUP_CLIENTS = Object.freeze(['generic-mcp', 'claude-desktop', 'cursor', 'kimi-code']);
|
|
41
|
+
const SETUP_CLAIM_BOUNDARIES = Object.freeze({
|
|
42
|
+
local_only: true,
|
|
43
|
+
provider_credentials_required: false,
|
|
44
|
+
provider_native_memory_canonical: false,
|
|
45
|
+
provider_deletion_proof: false,
|
|
46
|
+
model_forgetting_proof: false,
|
|
47
|
+
roi_or_savings_guarantee: false,
|
|
48
|
+
compliance_certification: false,
|
|
49
|
+
});
|
|
50
|
+
const QUICKSTART_ARTIFACT_NAMES = Object.freeze({
|
|
51
|
+
contextPack: 'context-pack.json',
|
|
52
|
+
export: 'export.json',
|
|
53
|
+
verifyReport: 'verify-report.json',
|
|
54
|
+
});
|
|
36
55
|
const CROSS_MODEL_PROFILES = Object.freeze([
|
|
37
56
|
{ id: 'chatgpt', provider: 'chatgpt', model: 'chatgpt-mcp-profile', label: 'ChatGPT' },
|
|
38
57
|
{ id: 'claude', provider: 'claude', model: 'claude-mcp-profile', label: 'Claude' },
|
|
@@ -77,6 +96,19 @@ const IMPORTERS = Object.freeze({
|
|
|
77
96
|
|
|
78
97
|
export const REQUIRED_PACKAGE_BINS = Object.freeze(['enigma', 'enigma-verify', 'enigma-mcp', 'enigma-relay', 'enigma-gateway', 'enigma-native-host']);
|
|
79
98
|
|
|
99
|
+
function setFlagValue(flags, name, value) {
|
|
100
|
+
if (!flags.has(name)) {
|
|
101
|
+
flags.set(name, value);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const current = flags.get(name);
|
|
105
|
+
if (Array.isArray(current)) {
|
|
106
|
+
current.push(value);
|
|
107
|
+
} else {
|
|
108
|
+
flags.set(name, [current, value]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
80
112
|
function parseArgs(argv) {
|
|
81
113
|
const flags = new Map();
|
|
82
114
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -84,11 +116,11 @@ function parseArgs(argv) {
|
|
|
84
116
|
if (!arg.startsWith('--')) continue;
|
|
85
117
|
const eq = arg.indexOf('=');
|
|
86
118
|
if (eq !== -1) {
|
|
87
|
-
flags
|
|
119
|
+
setFlagValue(flags, arg.slice(2, eq), arg.slice(eq + 1));
|
|
88
120
|
} else if (!argv[i + 1] || argv[i + 1].startsWith('--')) {
|
|
89
|
-
flags
|
|
121
|
+
setFlagValue(flags, arg.slice(2), true);
|
|
90
122
|
} else {
|
|
91
|
-
flags
|
|
123
|
+
setFlagValue(flags, arg.slice(2), argv[i + 1]);
|
|
92
124
|
i += 1;
|
|
93
125
|
}
|
|
94
126
|
}
|
|
@@ -100,6 +132,19 @@ function getFlag(flags, names, fallback = undefined) {
|
|
|
100
132
|
return fallback;
|
|
101
133
|
}
|
|
102
134
|
|
|
135
|
+
function lastFlagValue(value) {
|
|
136
|
+
return Array.isArray(value) ? value[value.length - 1] : value;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function booleanFlag(flags, names, fallback = false) {
|
|
140
|
+
const value = lastFlagValue(getFlag(flags, names, fallback));
|
|
141
|
+
if (value === true || value === false) return value;
|
|
142
|
+
if (value === undefined || value === '') return fallback;
|
|
143
|
+
if (String(value) === 'true') return true;
|
|
144
|
+
if (String(value) === 'false') return false;
|
|
145
|
+
throw new Error(`--${names[0]} must be true or false.`);
|
|
146
|
+
}
|
|
147
|
+
|
|
103
148
|
function requireFlag(flags, names, label = names[0]) {
|
|
104
149
|
const value = getFlag(flags, names);
|
|
105
150
|
if (value === undefined || value === true || value === '') throw new Error(`Missing required --${label}.`);
|
|
@@ -166,7 +211,7 @@ async function fileExists(path) {
|
|
|
166
211
|
}
|
|
167
212
|
|
|
168
213
|
function pathFlag(flags, names, fallback) {
|
|
169
|
-
const value = getFlag(flags, names, fallback);
|
|
214
|
+
const value = lastFlagValue(getFlag(flags, names, fallback));
|
|
170
215
|
if (value === true || value === '') throw new Error(`Missing required --${names[0]}.`);
|
|
171
216
|
return String(value);
|
|
172
217
|
}
|
|
@@ -210,6 +255,74 @@ async function quickstartMemoryTextFromFlags(flags) {
|
|
|
210
255
|
return DEFAULT_QUICKSTART_MEMORY;
|
|
211
256
|
}
|
|
212
257
|
|
|
258
|
+
function quickstartOutputs(bundleInput, outDirInput) {
|
|
259
|
+
const bundlePath = resolve(bundleInput);
|
|
260
|
+
const outDirPath = resolve(outDirInput);
|
|
261
|
+
const contextPackPath = resolve(outDirPath, QUICKSTART_ARTIFACT_NAMES.contextPack);
|
|
262
|
+
const exportPath = resolve(outDirPath, QUICKSTART_ARTIFACT_NAMES.export);
|
|
263
|
+
const verifyReportPath = resolve(outDirPath, QUICKSTART_ARTIFACT_NAMES.verifyReport);
|
|
264
|
+
return {
|
|
265
|
+
bundlePath,
|
|
266
|
+
outDirPath,
|
|
267
|
+
contextPackPath,
|
|
268
|
+
exportPath,
|
|
269
|
+
verifyReportPath,
|
|
270
|
+
contextPackDisplay: quickstartPathDisplay(outDirInput, QUICKSTART_ARTIFACT_NAMES.contextPack),
|
|
271
|
+
exportDisplay: quickstartPathDisplay(outDirInput, QUICKSTART_ARTIFACT_NAMES.export),
|
|
272
|
+
verifyReportDisplay: quickstartPathDisplay(outDirInput, QUICKSTART_ARTIFACT_NAMES.verifyReport),
|
|
273
|
+
outputs: [
|
|
274
|
+
{ path: bundlePath, display: bundleInput },
|
|
275
|
+
{ path: contextPackPath, display: quickstartPathDisplay(outDirInput, QUICKSTART_ARTIFACT_NAMES.contextPack) },
|
|
276
|
+
{ path: exportPath, display: quickstartPathDisplay(outDirInput, QUICKSTART_ARTIFACT_NAMES.export) },
|
|
277
|
+
{ path: verifyReportPath, display: quickstartPathDisplay(outDirInput, QUICKSTART_ARTIFACT_NAMES.verifyReport) },
|
|
278
|
+
],
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async function buildQuickstartArtifacts(flags, { bundleInput = DEFAULT_BUNDLE, outDirInput = dirname(bundleInput), overwrite = false, write = true } = {}) {
|
|
283
|
+
const paths = quickstartOutputs(bundleInput, outDirInput);
|
|
284
|
+
ensureDistinctOutputPaths(paths.outputs.map((output) => output.path));
|
|
285
|
+
await assertCanWriteQuickstartOutputs(paths.outputs, overwrite);
|
|
286
|
+
|
|
287
|
+
const vault = createVault({
|
|
288
|
+
subjectId: String(getFlag(flags, ['subject', 'subject-id'], 'local-user')),
|
|
289
|
+
displayName: String(getFlag(flags, ['display-name', 'name'], 'Local user')),
|
|
290
|
+
passphrase: String(getFlag(flags, ['passphrase'], 'local-development-passphrase')),
|
|
291
|
+
});
|
|
292
|
+
const passport = createPassport({
|
|
293
|
+
vault,
|
|
294
|
+
subjectId: vault.subject_id,
|
|
295
|
+
displayName: String(getFlag(flags, ['display-name', 'name'], 'Local user')),
|
|
296
|
+
});
|
|
297
|
+
remember({
|
|
298
|
+
vault,
|
|
299
|
+
passport,
|
|
300
|
+
text: await quickstartMemoryTextFromFlags(flags),
|
|
301
|
+
purpose: 'quickstart_local_proof',
|
|
302
|
+
purpose_tags: ['quickstart'],
|
|
303
|
+
metadata: { source: 'enigma quickstart' },
|
|
304
|
+
});
|
|
305
|
+
const contextPack = compileContextPack({
|
|
306
|
+
vault,
|
|
307
|
+
passport,
|
|
308
|
+
query: '',
|
|
309
|
+
purpose: 'quickstart_local_context',
|
|
310
|
+
limit: 8,
|
|
311
|
+
});
|
|
312
|
+
const exported = exportBundle({ vault, includePlaintext: false });
|
|
313
|
+
const bundle = exported.bundle ?? exported;
|
|
314
|
+
const verifyReport = verifyBundle(bundle);
|
|
315
|
+
|
|
316
|
+
if (write) {
|
|
317
|
+
await writeJson(paths.bundlePath, bundle);
|
|
318
|
+
await writeJson(paths.contextPackPath, contextPack);
|
|
319
|
+
await writeJson(paths.exportPath, bundle);
|
|
320
|
+
await writeJson(paths.verifyReportPath, verifyReport);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return { ...paths, vault, passport, contextPack, bundle, verifyReport };
|
|
324
|
+
}
|
|
325
|
+
|
|
213
326
|
async function crossModelMemoryTextFromFlags(flags) {
|
|
214
327
|
const textFile = getFlag(flags, ['memory-file', 'memoryFile', 'text-file', 'textFile']);
|
|
215
328
|
if (textFile === undefined) return DEFAULT_CROSS_MODEL_MEMORY;
|
|
@@ -273,6 +386,157 @@ function publicContextPackSummary(pack) {
|
|
|
273
386
|
};
|
|
274
387
|
}
|
|
275
388
|
|
|
389
|
+
const SEARCH_RELEVANCE_STOPWORDS = new Set([
|
|
390
|
+
'about',
|
|
391
|
+
'after',
|
|
392
|
+
'again',
|
|
393
|
+
'against',
|
|
394
|
+
'also',
|
|
395
|
+
'and',
|
|
396
|
+
'any',
|
|
397
|
+
'are',
|
|
398
|
+
'assistant',
|
|
399
|
+
'because',
|
|
400
|
+
'been',
|
|
401
|
+
'before',
|
|
402
|
+
'being',
|
|
403
|
+
'between',
|
|
404
|
+
'can',
|
|
405
|
+
'could',
|
|
406
|
+
'current',
|
|
407
|
+
'does',
|
|
408
|
+
'from',
|
|
409
|
+
'has',
|
|
410
|
+
'have',
|
|
411
|
+
'how',
|
|
412
|
+
'into',
|
|
413
|
+
'its',
|
|
414
|
+
'latest',
|
|
415
|
+
'more',
|
|
416
|
+
'most',
|
|
417
|
+
'number',
|
|
418
|
+
'own',
|
|
419
|
+
'owns',
|
|
420
|
+
'please',
|
|
421
|
+
'should',
|
|
422
|
+
'that',
|
|
423
|
+
'the',
|
|
424
|
+
'their',
|
|
425
|
+
'then',
|
|
426
|
+
'there',
|
|
427
|
+
'these',
|
|
428
|
+
'they',
|
|
429
|
+
'this',
|
|
430
|
+
'use',
|
|
431
|
+
'using',
|
|
432
|
+
'was',
|
|
433
|
+
'what',
|
|
434
|
+
'when',
|
|
435
|
+
'where',
|
|
436
|
+
'which',
|
|
437
|
+
'who',
|
|
438
|
+
'whose',
|
|
439
|
+
'why',
|
|
440
|
+
'with',
|
|
441
|
+
'would',
|
|
442
|
+
]);
|
|
443
|
+
|
|
444
|
+
function addSearchToken(tokens, token) {
|
|
445
|
+
if (token.length < 3) return;
|
|
446
|
+
if (!/[a-z]/u.test(token)) return;
|
|
447
|
+
if (SEARCH_RELEVANCE_STOPWORDS.has(token)) return;
|
|
448
|
+
tokens.add(token);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function searchTokensFrom(value) {
|
|
452
|
+
const tokens = new Set();
|
|
453
|
+
if (value === undefined || value === null) return tokens;
|
|
454
|
+
for (const match of String(value).toLowerCase().matchAll(/[a-z0-9]+(?:[-_][a-z0-9]+)*/gu)) {
|
|
455
|
+
const token = match[0];
|
|
456
|
+
addSearchToken(tokens, token);
|
|
457
|
+
if (token.includes('-') || token.includes('_')) {
|
|
458
|
+
for (const part of token.split(/[-_]+/u)) addSearchToken(tokens, part);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return tokens;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function addSearchTokensFromValue(tokens, value) {
|
|
465
|
+
for (const token of searchTokensFrom(value)) tokens.add(token);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function recordSearchTokens(record, content) {
|
|
469
|
+
const tokens = new Set();
|
|
470
|
+
addSearchTokensFromValue(tokens, content);
|
|
471
|
+
addSearchTokensFromValue(tokens, record?.kind);
|
|
472
|
+
for (const tag of record?.purpose_tags ?? []) addSearchTokensFromValue(tokens, tag);
|
|
473
|
+
return tokens;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function searchScore(queryTokens, memoryTokens) {
|
|
477
|
+
if (queryTokens.size === 0) return 0;
|
|
478
|
+
let overlap = 0;
|
|
479
|
+
for (const token of queryTokens) {
|
|
480
|
+
if (memoryTokens.has(token)) overlap += 1;
|
|
481
|
+
}
|
|
482
|
+
return Math.round((overlap / queryTokens.size) * 1_000_000) / 1_000_000;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
function searchResultReceiptIds(vault, memoryAddr) {
|
|
486
|
+
return vault.receipts
|
|
487
|
+
.filter((receipt) => receipt?.memory_addr === memoryAddr || receipt?.source_addr === memoryAddr)
|
|
488
|
+
.map((receipt) => receipt.receipt_id)
|
|
489
|
+
.filter((receiptId) => typeof receiptId === 'string' && receiptId.length > 0);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function publicAccessReceiptRef(receipt) {
|
|
493
|
+
return {
|
|
494
|
+
access_receipt_ref: `enigma://memory-access/${receipt.receipt_id}`,
|
|
495
|
+
receipt_id: receipt.receipt_id,
|
|
496
|
+
operation: receipt.operation,
|
|
497
|
+
memory_addr: receipt.address,
|
|
498
|
+
plan_hash: receipt.plan_hash,
|
|
499
|
+
estimated_prompt_tokens: receipt.estimated_prompt_tokens,
|
|
500
|
+
access_boundary: receipt.access_boundary,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function searchCandidates(vault, queryTokens) {
|
|
505
|
+
const candidates = [];
|
|
506
|
+
const byAddress = new Map();
|
|
507
|
+
for (const memoryAddr of [...vault.activeAddresses].sort()) {
|
|
508
|
+
const record = vault.__getRecord(memoryAddr);
|
|
509
|
+
if (!record || record.state !== 'active') continue;
|
|
510
|
+
const content = vault.__getPlaintext(memoryAddr);
|
|
511
|
+
const score = searchScore(queryTokens, recordSearchTokens(record, content));
|
|
512
|
+
if (queryTokens.size > 0 && score === 0) continue;
|
|
513
|
+
const candidate = {
|
|
514
|
+
address: memoryAddr,
|
|
515
|
+
content,
|
|
516
|
+
importance: typeof record.importance === 'number' ? record.importance : typeof record.confidence === 'number' ? record.confidence : undefined,
|
|
517
|
+
last_accessed_at: record.updated_at ?? record.created_at,
|
|
518
|
+
metadata: {
|
|
519
|
+
kind: record.kind,
|
|
520
|
+
sensitivity: record.sensitivity,
|
|
521
|
+
purpose_tags: record.purpose_tags ?? [],
|
|
522
|
+
},
|
|
523
|
+
};
|
|
524
|
+
candidates.push(candidate);
|
|
525
|
+
byAddress.set(memoryAddr, { record, content, score });
|
|
526
|
+
}
|
|
527
|
+
return { candidates, byAddress };
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function connectorReadinessSummary(bundlePath) {
|
|
531
|
+
return {
|
|
532
|
+
ready: true,
|
|
533
|
+
bundle: bundlePath,
|
|
534
|
+
bundle_env: 'ENIGMA_BUNDLE',
|
|
535
|
+
mcp_command: 'enigma-mcp',
|
|
536
|
+
supported_clients: supportedClients,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
276
540
|
function demoBundleRef(bundleWasSupplied) {
|
|
277
541
|
return bundleWasSupplied ? 'supplied_bundle' : DEFAULT_CROSS_MODEL_DEMO_BUNDLE;
|
|
278
542
|
}
|
|
@@ -493,85 +757,275 @@ async function initCommand(flags, io) {
|
|
|
493
757
|
return 0;
|
|
494
758
|
}
|
|
495
759
|
|
|
496
|
-
|
|
760
|
+
function setupClientIds(flags) {
|
|
761
|
+
const raw = getFlag(flags, ['client']);
|
|
762
|
+
if (raw === undefined) return [...DEFAULT_SETUP_CLIENTS];
|
|
763
|
+
const values = Array.isArray(raw) ? raw : [raw];
|
|
764
|
+
const clients = [];
|
|
765
|
+
for (const value of values) {
|
|
766
|
+
if (value === true || value === '') throw new Error('Missing required --client.');
|
|
767
|
+
for (const client of String(value).split(',').map((item) => item.trim()).filter(Boolean)) {
|
|
768
|
+
getClientProfile(client);
|
|
769
|
+
if (!clients.includes(client)) clients.push(client);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return clients.length > 0 ? clients : [...DEFAULT_SETUP_CLIENTS];
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
function setupMemorySource(flags) {
|
|
776
|
+
if (getFlag(flags, ['memory-file', 'memoryFile', 'text-file', 'textFile']) !== undefined) return 'memory_file';
|
|
777
|
+
if (getFlag(flags, ['memory-text', 'memoryText']) !== undefined) return 'demo_text';
|
|
778
|
+
return 'default_demo';
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
function commandPath(path) {
|
|
782
|
+
return `"${String(path).replace(/"/g, '\\"')}"`;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function publicPathDisplay(path, label) {
|
|
786
|
+
const value = String(path);
|
|
787
|
+
if (/^[A-Za-z]:[\\/]/.test(value) || value.startsWith('/') || value.startsWith('\\\\')) return `<${label}>`;
|
|
788
|
+
return value;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
function setupPublicDisplays(bundleInput, outDirInput) {
|
|
792
|
+
const outDir = publicPathDisplay(outDirInput, 'out-dir');
|
|
793
|
+
return {
|
|
794
|
+
bundle: publicPathDisplay(bundleInput, 'bundle-path'),
|
|
795
|
+
context_pack: quickstartPathDisplay(outDir, QUICKSTART_ARTIFACT_NAMES.contextPack),
|
|
796
|
+
export: quickstartPathDisplay(outDir, QUICKSTART_ARTIFACT_NAMES.export),
|
|
797
|
+
verify_report: quickstartPathDisplay(outDir, QUICKSTART_ARTIFACT_NAMES.verifyReport),
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
function setupRawDisplays(bundleInput, outDirInput) {
|
|
802
|
+
const plan = quickstartOutputs(bundleInput, outDirInput);
|
|
803
|
+
return {
|
|
804
|
+
bundle: plan.outputs[0].display,
|
|
805
|
+
context_pack: plan.contextPackDisplay,
|
|
806
|
+
export: plan.exportDisplay,
|
|
807
|
+
verify_report: plan.verifyReportDisplay,
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
function publicSetupError(error, rawDisplays, publicDisplays) {
|
|
812
|
+
let message = error.message;
|
|
813
|
+
for (const [raw, safe] of Object.entries({
|
|
814
|
+
[rawDisplays.bundle]: publicDisplays.bundle,
|
|
815
|
+
[rawDisplays.context_pack]: publicDisplays.context_pack,
|
|
816
|
+
[rawDisplays.export]: publicDisplays.export,
|
|
817
|
+
[rawDisplays.verify_report]: publicDisplays.verify_report,
|
|
818
|
+
})) {
|
|
819
|
+
message = message.split(raw).join(safe);
|
|
820
|
+
}
|
|
821
|
+
return new Error(message);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
function setupNextCommands(bundleInput, exportDisplay, clients, writeConnectors) {
|
|
825
|
+
const primaryClient = clients[0] ?? DEFAULT_SETUP_CLIENTS[0];
|
|
826
|
+
const commands = [
|
|
827
|
+
`enigma remember --bundle ${commandPath(bundleInput)} --text-file ./memory.txt`,
|
|
828
|
+
`enigma search --bundle ${commandPath(bundleInput)} --query "project context"`,
|
|
829
|
+
`enigma context --bundle ${commandPath(bundleInput)} --query "project context"`,
|
|
830
|
+
`enigma verify --export ${commandPath(exportDisplay)}`,
|
|
831
|
+
];
|
|
832
|
+
if (!writeConnectors) commands.push(`enigma connect ${primaryClient} --bundle ${commandPath(bundleInput)}`);
|
|
833
|
+
return commands;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
async function setupDoctorChecks(flags, artifacts, clients, displays) {
|
|
837
|
+
const packageJson = await readPackageJson();
|
|
838
|
+
const requiredNodeMajor = minimumNodeMajor(packageJson.engines?.node);
|
|
839
|
+
const currentNodeMajor = nodeMajor(process.versions.node);
|
|
840
|
+
const binMap = packageJson.bin && typeof packageJson.bin === 'object' && !Array.isArray(packageJson.bin) ? packageJson.bin : {};
|
|
841
|
+
const binEntries = await Promise.all(REQUIRED_PACKAGE_BINS.map(async (name) => {
|
|
842
|
+
const target = binMap[name];
|
|
843
|
+
const declared = typeof target === 'string' && target.length > 0;
|
|
844
|
+
return {
|
|
845
|
+
name,
|
|
846
|
+
target: declared ? target : null,
|
|
847
|
+
declared,
|
|
848
|
+
exists: declared ? await fileExists(packageFileUrl(target)) : false,
|
|
849
|
+
};
|
|
850
|
+
}));
|
|
851
|
+
const schemas = await schemaFiles();
|
|
852
|
+
const connectorBaseOptions = {
|
|
853
|
+
...connectorOptions(flags),
|
|
854
|
+
bundlePath: artifacts.bundlePath,
|
|
855
|
+
redactPaths: true,
|
|
856
|
+
};
|
|
857
|
+
const connectorClients = [];
|
|
858
|
+
for (const client of clients) {
|
|
859
|
+
const doctor = await doctorConnectors({ ...connectorBaseOptions, clientId: client });
|
|
860
|
+
connectorClients.push(...doctor.clients);
|
|
861
|
+
}
|
|
862
|
+
const checks = {
|
|
863
|
+
node: {
|
|
864
|
+
ok: requiredNodeMajor === 0 || currentNodeMajor >= requiredNodeMajor,
|
|
865
|
+
current: process.versions.node,
|
|
866
|
+
required: packageJson.engines?.node ?? null,
|
|
867
|
+
},
|
|
868
|
+
package_bins: {
|
|
869
|
+
ok: binEntries.every((entry) => entry.declared && entry.exists),
|
|
870
|
+
required: REQUIRED_PACKAGE_BINS,
|
|
871
|
+
entries: binEntries,
|
|
872
|
+
missing: binEntries.filter((entry) => !entry.declared).map((entry) => entry.name),
|
|
873
|
+
missing_targets: binEntries.filter((entry) => entry.declared && !entry.exists).map((entry) => entry.name),
|
|
874
|
+
},
|
|
875
|
+
artifacts: {
|
|
876
|
+
ok: artifacts.verifyReport.ok === true,
|
|
877
|
+
bundle: displays.bundle,
|
|
878
|
+
context_pack: displays.context_pack,
|
|
879
|
+
export: displays.export,
|
|
880
|
+
verify_report: displays.verify_report,
|
|
881
|
+
},
|
|
882
|
+
schemas: {
|
|
883
|
+
ok: schemas.length > 0,
|
|
884
|
+
count: schemas.length,
|
|
885
|
+
files: schemas,
|
|
886
|
+
},
|
|
887
|
+
connectors: {
|
|
888
|
+
ok: connectorClients.every((client) => client.ok !== false),
|
|
889
|
+
clients: connectorClients,
|
|
890
|
+
},
|
|
891
|
+
};
|
|
892
|
+
return { ok: Object.values(checks).every((check) => check.ok !== false), checks };
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function publicConnectPlan(plan, wizard, profile, snippet) {
|
|
896
|
+
const changed = plan?.changed !== false;
|
|
897
|
+
const dryRun = plan?.dryRun === true || plan?.dry_run === true;
|
|
898
|
+
const plannedWrites = changed ? [{ type: 'write', path: wizard.default_config_path }] : [];
|
|
899
|
+
return {
|
|
900
|
+
ok: plan?.ok !== false,
|
|
901
|
+
action: 'connect',
|
|
902
|
+
client_id: profile.client_id,
|
|
903
|
+
configPath: wizard.default_config_path,
|
|
904
|
+
config_path: wizard.default_config_path,
|
|
905
|
+
serverName: profile.server_name,
|
|
906
|
+
server_name: profile.server_name,
|
|
907
|
+
changed,
|
|
908
|
+
dryRun,
|
|
909
|
+
dry_run: dryRun,
|
|
910
|
+
writes_performed: changed && !dryRun,
|
|
911
|
+
backup_planned: Boolean(plan?.backupPath),
|
|
912
|
+
plannedWrites,
|
|
913
|
+
planned_writes: plannedWrites,
|
|
914
|
+
config: snippet,
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
async function setupConnectorPlans(flags, artifacts, clients, writeConnectors, displays) {
|
|
919
|
+
const publicOptions = {
|
|
920
|
+
...connectorOptions(flags),
|
|
921
|
+
bundlePath: displays.bundle,
|
|
922
|
+
};
|
|
923
|
+
const writeOptions = {
|
|
924
|
+
...connectorOptions(flags),
|
|
925
|
+
bundlePath: artifacts.bundlePath,
|
|
926
|
+
};
|
|
927
|
+
const connectors = [];
|
|
928
|
+
for (const client of clients) {
|
|
929
|
+
const profile = getClientProfile(client, publicOptions);
|
|
930
|
+
const snippet = renderMcpConfig(client, publicOptions);
|
|
931
|
+
const wizard = planConnectWizard(client, { platform: profile.platform }).clients[0];
|
|
932
|
+
const rawPlan = writeConnectors
|
|
933
|
+
? await connectClient(client, { ...writeOptions, dryRun: false })
|
|
934
|
+
: { ok: true, changed: true, dryRun: true };
|
|
935
|
+
const plan = publicConnectPlan(rawPlan, wizard, profile, snippet);
|
|
936
|
+
connectors.push({
|
|
937
|
+
client_id: client,
|
|
938
|
+
display_name: profile.display_name,
|
|
939
|
+
default_config_path: wizard.default_config_path,
|
|
940
|
+
mcp_config_snippet: snippet,
|
|
941
|
+
connect_command: `enigma connect ${client} --bundle ${commandPath(displays.bundle)}`,
|
|
942
|
+
connect_plan: plan,
|
|
943
|
+
wizard,
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
return connectors;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
export async function setupCommand(flags, io) {
|
|
497
950
|
const bundleInput = pathFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE);
|
|
498
951
|
const outDirInput = pathFlag(flags, ['out-dir', 'outDir'], dirname(bundleInput));
|
|
499
|
-
const
|
|
500
|
-
const
|
|
501
|
-
const
|
|
502
|
-
const
|
|
503
|
-
const
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
const overwrite = getFlag(flags, ['overwrite'], false) === true || getFlag(flags, ['overwrite'], false) === 'true';
|
|
515
|
-
await assertCanWriteQuickstartOutputs(outputs, overwrite);
|
|
952
|
+
const clients = setupClientIds(flags);
|
|
953
|
+
const overwrite = booleanFlag(flags, ['overwrite'], false);
|
|
954
|
+
const dryRun = booleanFlag(flags, ['dry-run', 'dryRun'], false);
|
|
955
|
+
const writeConnectors = booleanFlag(flags, ['write-connectors', 'writeConnectors'], false) && !dryRun;
|
|
956
|
+
const displays = setupPublicDisplays(bundleInput, outDirInput);
|
|
957
|
+
const rawDisplays = setupRawDisplays(bundleInput, outDirInput);
|
|
958
|
+
let artifacts;
|
|
959
|
+
try {
|
|
960
|
+
artifacts = await buildQuickstartArtifacts(flags, { bundleInput, outDirInput, overwrite, write: !dryRun });
|
|
961
|
+
} catch (error) {
|
|
962
|
+
throw publicSetupError(error, rawDisplays, displays);
|
|
963
|
+
}
|
|
964
|
+
const connectors = await setupConnectorPlans(flags, artifacts, clients, writeConnectors, displays);
|
|
965
|
+
const doctor = await setupDoctorChecks(flags, artifacts, clients, displays);
|
|
966
|
+
const ok = artifacts.verifyReport.ok === true;
|
|
516
967
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
968
|
+
print({
|
|
969
|
+
ok,
|
|
970
|
+
schema: 'enigma.setup.v1',
|
|
971
|
+
command: 'enigma setup',
|
|
972
|
+
dry_run: dryRun,
|
|
973
|
+
artifacts_written: !dryRun,
|
|
974
|
+
client_configs_written: writeConnectors,
|
|
975
|
+
bundle: displays.bundle,
|
|
976
|
+
context_pack: displays.context_pack,
|
|
977
|
+
export: displays.export,
|
|
978
|
+
verify_report: displays.verify_report,
|
|
979
|
+
memory_source: setupMemorySource(flags),
|
|
980
|
+
memory_plaintext_echoed: false,
|
|
981
|
+
memory_count: Array.isArray(artifacts.bundle.memory_objects) ? artifacts.bundle.memory_objects.length : 0,
|
|
982
|
+
receipt_count: Array.isArray(artifacts.bundle.receipts) ? artifacts.bundle.receipts.length : 0,
|
|
983
|
+
context_item_count: Array.isArray(artifacts.contextPack.memories) ? artifacts.contextPack.memories.length : 0,
|
|
984
|
+
verify_ok: artifacts.verifyReport.ok === true,
|
|
985
|
+
provider_credentials_required: false,
|
|
986
|
+
provider_native_memory_canonical: false,
|
|
987
|
+
selected_clients: clients,
|
|
988
|
+
connectors,
|
|
989
|
+
mcp_config_snippets: Object.fromEntries(connectors.map((connector) => [connector.client_id, connector.mcp_config_snippet])),
|
|
990
|
+
connect_plans: Object.fromEntries(connectors.map((connector) => [connector.client_id, connector.connect_plan])),
|
|
991
|
+
next_commands: setupNextCommands(displays.bundle, displays.export, clients, writeConnectors),
|
|
992
|
+
checks: doctor.checks,
|
|
993
|
+
claim_boundaries: { ...SETUP_CLAIM_BOUNDARIES },
|
|
994
|
+
}, io);
|
|
995
|
+
return ok ? 0 : 1;
|
|
996
|
+
}
|
|
545
997
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
998
|
+
export async function quickstartCommand(flags, io) {
|
|
999
|
+
const bundleInput = pathFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE);
|
|
1000
|
+
const outDirInput = pathFlag(flags, ['out-dir', 'outDir'], dirname(bundleInput));
|
|
1001
|
+
const overwrite = booleanFlag(flags, ['overwrite'], false);
|
|
1002
|
+
const artifacts = await buildQuickstartArtifacts(flags, { bundleInput, outDirInput, overwrite, write: true });
|
|
550
1003
|
|
|
551
1004
|
print({
|
|
552
|
-
ok: verifyReport.ok === true,
|
|
1005
|
+
ok: artifacts.verifyReport.ok === true,
|
|
553
1006
|
bundle: bundleInput,
|
|
554
|
-
context_pack: contextPackDisplay,
|
|
555
|
-
export: exportDisplay,
|
|
556
|
-
verify_report: verifyReportDisplay,
|
|
557
|
-
memory_count: Array.isArray(bundle.memory_objects) ? bundle.memory_objects.length : 0,
|
|
558
|
-
receipt_count: Array.isArray(bundle.receipts) ? bundle.receipts.length : 0,
|
|
559
|
-
context_item_count: Array.isArray(contextPack.memories) ? contextPack.memories.length : 0,
|
|
560
|
-
verify_ok: verifyReport.ok === true,
|
|
1007
|
+
context_pack: artifacts.contextPackDisplay,
|
|
1008
|
+
export: artifacts.exportDisplay,
|
|
1009
|
+
verify_report: artifacts.verifyReportDisplay,
|
|
1010
|
+
memory_count: Array.isArray(artifacts.bundle.memory_objects) ? artifacts.bundle.memory_objects.length : 0,
|
|
1011
|
+
receipt_count: Array.isArray(artifacts.bundle.receipts) ? artifacts.bundle.receipts.length : 0,
|
|
1012
|
+
context_item_count: Array.isArray(artifacts.contextPack.memories) ? artifacts.contextPack.memories.length : 0,
|
|
1013
|
+
verify_ok: artifacts.verifyReport.ok === true,
|
|
561
1014
|
next_commands: [
|
|
562
|
-
`enigma verify --export ${exportDisplay}`,
|
|
1015
|
+
`enigma verify --export ${artifacts.exportDisplay}`,
|
|
563
1016
|
`enigma connect generic-mcp --bundle ${bundleInput} --dry-run`,
|
|
564
1017
|
],
|
|
565
1018
|
claim_boundaries: {
|
|
566
1019
|
local_only: true,
|
|
567
1020
|
provider_credentials_required: false,
|
|
1021
|
+
provider_native_memory_canonical: false,
|
|
568
1022
|
provider_deletion_proof: false,
|
|
569
1023
|
model_forgetting_proof: false,
|
|
570
1024
|
roi_or_savings_guarantee: false,
|
|
571
1025
|
compliance_certification: false,
|
|
572
1026
|
},
|
|
573
1027
|
}, io);
|
|
574
|
-
return verifyReport.ok === true ? 0 : 1;
|
|
1028
|
+
return artifacts.verifyReport.ok === true ? 0 : 1;
|
|
575
1029
|
}
|
|
576
1030
|
|
|
577
1031
|
export async function crossModelDemoCommand(flags, io) {
|
|
@@ -767,6 +1221,118 @@ async function contextCommand(flags, io) {
|
|
|
767
1221
|
return 0;
|
|
768
1222
|
}
|
|
769
1223
|
|
|
1224
|
+
|
|
1225
|
+
async function searchCommand(flags, io) {
|
|
1226
|
+
const bundlePath = resolve(String(getFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE)));
|
|
1227
|
+
const query = String(requireFlag(flags, ['query', 'q'], 'query'));
|
|
1228
|
+
const limit = integerFlag(flags, ['limit'], 'limit', 8);
|
|
1229
|
+
if (limit < 0) throw new Error('--limit must be non-negative.');
|
|
1230
|
+
const includeContent = getFlag(flags, ['include-content', 'includeContent']) === true || getFlag(flags, ['include-content', 'includeContent']) === 'true';
|
|
1231
|
+
const { vault } = await loadState(bundlePath);
|
|
1232
|
+
const roots = vault.__computeRoots();
|
|
1233
|
+
const queryTokens = searchTokensFrom(query);
|
|
1234
|
+
const { candidates, byAddress } = searchCandidates(vault, queryTokens);
|
|
1235
|
+
const plan = createMemoryOptimizationPlan({
|
|
1236
|
+
candidates,
|
|
1237
|
+
prompt: query,
|
|
1238
|
+
now: getFlag(flags, ['now'], '2026-01-01T00:00:00.000Z'),
|
|
1239
|
+
});
|
|
1240
|
+
const planIndex = new Map(plan.items.map((item, index) => [item.address, index]));
|
|
1241
|
+
const selectedItems = plan.items
|
|
1242
|
+
.filter((item) => byAddress.has(item.address))
|
|
1243
|
+
.sort((left, right) => {
|
|
1244
|
+
const scoreDiff = byAddress.get(right.address).score - byAddress.get(left.address).score;
|
|
1245
|
+
if (scoreDiff !== 0) return scoreDiff;
|
|
1246
|
+
return planIndex.get(left.address) - planIndex.get(right.address);
|
|
1247
|
+
})
|
|
1248
|
+
.slice(0, limit);
|
|
1249
|
+
const accessReceipts = selectedItems.map((item, index) => createMemoryAccessReceipt({
|
|
1250
|
+
item,
|
|
1251
|
+
plan,
|
|
1252
|
+
sequence: index,
|
|
1253
|
+
timestamp: null,
|
|
1254
|
+
pricing: plan.pricing,
|
|
1255
|
+
}));
|
|
1256
|
+
const accessReceiptByAddress = new Map(accessReceipts.map((receipt) => [receipt.address, publicAccessReceiptRef(receipt)]));
|
|
1257
|
+
const results = selectedItems.map((item) => {
|
|
1258
|
+
const hit = byAddress.get(item.address);
|
|
1259
|
+
const record = hit.record;
|
|
1260
|
+
const accessReceipt = accessReceiptByAddress.get(item.address);
|
|
1261
|
+
return {
|
|
1262
|
+
memory_ref: `enigma://memory/${item.address}`,
|
|
1263
|
+
memory_addr: item.address,
|
|
1264
|
+
address: item.address,
|
|
1265
|
+
kind: record.kind,
|
|
1266
|
+
sensitivity: record.sensitivity,
|
|
1267
|
+
tags: Array.isArray(record.purpose_tags) ? [...record.purpose_tags] : [],
|
|
1268
|
+
purpose_tags: Array.isArray(record.purpose_tags) ? [...record.purpose_tags] : [],
|
|
1269
|
+
score: hit.score,
|
|
1270
|
+
tier: item.tier,
|
|
1271
|
+
receipt_ids: searchResultReceiptIds(vault, item.address),
|
|
1272
|
+
access_receipt_ref: accessReceipt?.access_receipt_ref,
|
|
1273
|
+
access_receipt_id: accessReceipt?.receipt_id,
|
|
1274
|
+
access_receipt_refs: accessReceipt?.access_receipt_ref ? [accessReceipt.access_receipt_ref] : [],
|
|
1275
|
+
content_redacted: !includeContent,
|
|
1276
|
+
...(includeContent ? { content: hit.content } : {}),
|
|
1277
|
+
};
|
|
1278
|
+
});
|
|
1279
|
+
print({
|
|
1280
|
+
ok: true,
|
|
1281
|
+
schema: 'enigma.memory_search.v1',
|
|
1282
|
+
bundle: bundlePath,
|
|
1283
|
+
query_redacted: true,
|
|
1284
|
+
limit,
|
|
1285
|
+
result_count: results.length,
|
|
1286
|
+
results,
|
|
1287
|
+
access_receipts: accessReceipts.map(publicAccessReceiptRef),
|
|
1288
|
+
active_set_root: roots.active_set_root,
|
|
1289
|
+
receipt_log_root: roots.receipt_log_root,
|
|
1290
|
+
claim_boundary: includeContent
|
|
1291
|
+
? 'Search ran against the selected local bundle and includes plaintext only because --include-content was explicit; this does not prove provider deletion, provider-native memory state, or model forgetting.'
|
|
1292
|
+
: 'Search ran against the selected local bundle and redacts plaintext by default; refs, scores, tags, roots, and receipt refs are not provider deletion proof or model forgetting proof.',
|
|
1293
|
+
}, io);
|
|
1294
|
+
return 0;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
async function statusCommand(flags, io) {
|
|
1298
|
+
const bundlePath = resolve(String(getFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE)));
|
|
1299
|
+
const { stored, vault, passport } = await loadState(bundlePath);
|
|
1300
|
+
const roots = vault.__computeRoots();
|
|
1301
|
+
const activeCount = activeMemoryCount(vault);
|
|
1302
|
+
const tombstoneCount = vault.tombstones instanceof Map ? vault.tombstones.size : 0;
|
|
1303
|
+
const receiptCount = Array.isArray(vault.receipts) ? vault.receipts.length : 0;
|
|
1304
|
+
print({
|
|
1305
|
+
ok: true,
|
|
1306
|
+
schema: 'enigma.passport_status.v1',
|
|
1307
|
+
bundle: bundlePath,
|
|
1308
|
+
passport_ref: `enigma://passport/${passport.passport_id}`,
|
|
1309
|
+
owner: {
|
|
1310
|
+
subject_id: stored.owner?.subject_id ?? stored.passport?.owner?.subject_id ?? stored.vault?.subject_id ?? passport.owner?.subject_id ?? vault.subject_id,
|
|
1311
|
+
display_name: stored.owner?.display_name ?? stored.passport?.owner?.display_name ?? stored.vault?.display_name ?? passport.owner?.display_name ?? 'Local user',
|
|
1312
|
+
},
|
|
1313
|
+
counts: {
|
|
1314
|
+
active_memories: activeCount,
|
|
1315
|
+
tombstoned_memories: tombstoneCount,
|
|
1316
|
+
receipts: receiptCount,
|
|
1317
|
+
},
|
|
1318
|
+
active_memory_count: activeCount,
|
|
1319
|
+
tombstoned_memory_count: tombstoneCount,
|
|
1320
|
+
receipt_count: receiptCount,
|
|
1321
|
+
active_set_root: roots.active_set_root,
|
|
1322
|
+
receipt_log_root: roots.receipt_log_root,
|
|
1323
|
+
connector_readiness: connectorReadinessSummary(bundlePath),
|
|
1324
|
+
next_recommended_commands: [
|
|
1325
|
+
`enigma remember --bundle "${bundlePath}" --text-file <path>`,
|
|
1326
|
+
`enigma search --bundle "${bundlePath}" --query <text>`,
|
|
1327
|
+
`enigma context --bundle "${bundlePath}" --query <text>`,
|
|
1328
|
+
`enigma verify --bundle "${bundlePath}"`,
|
|
1329
|
+
`enigma connect <client> --bundle "${bundlePath}"`,
|
|
1330
|
+
],
|
|
1331
|
+
claim_boundary: 'Status reports local bundle counters, owner display fields, connector readiness hints, and commitment roots only; it does not expose raw memory, certify compliance, prove provider deletion, or prove model forgetting.',
|
|
1332
|
+
}, io);
|
|
1333
|
+
return 0;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
770
1336
|
async function exportCommand(flags, io) {
|
|
771
1337
|
const bundlePath = resolve(String(getFlag(flags, ['bundle', 'file'], DEFAULT_BUNDLE)));
|
|
772
1338
|
const { vault } = await loadState(bundlePath);
|
|
@@ -1272,6 +1838,7 @@ function usage() {
|
|
|
1272
1838
|
usage: 'enigma <command> [options]',
|
|
1273
1839
|
commands: [
|
|
1274
1840
|
'init',
|
|
1841
|
+
'setup',
|
|
1275
1842
|
'quickstart',
|
|
1276
1843
|
'demo cross-model',
|
|
1277
1844
|
'doctor',
|
|
@@ -1283,6 +1850,9 @@ function usage() {
|
|
|
1283
1850
|
'update',
|
|
1284
1851
|
'delete',
|
|
1285
1852
|
'context',
|
|
1853
|
+
'search',
|
|
1854
|
+
'status',
|
|
1855
|
+
'passport status',
|
|
1286
1856
|
'export',
|
|
1287
1857
|
'import <source>',
|
|
1288
1858
|
'capsule export',
|
|
@@ -1318,6 +1888,27 @@ function usage() {
|
|
|
1318
1888
|
'--text <text>': 'Inline local memory text. Avoid for private content because argv can be logged by process tooling.',
|
|
1319
1889
|
'--text-file <path>': 'Read local memory text from a file so private smoke input is not exposed in shell argv. Aliases: --memory-file, --textFile, --memoryFile.',
|
|
1320
1890
|
},
|
|
1891
|
+
search_options: {
|
|
1892
|
+
'--query <text>': 'Required local query. Output redacts the query and memory plaintext by default. Alias: --q.',
|
|
1893
|
+
'--bundle <path>': 'Bundle JSON to search. Defaults to .enigma/bundle.json.',
|
|
1894
|
+
'--limit <n>': 'Maximum ranked active memories to return. Defaults to 8.',
|
|
1895
|
+
'--json': 'Reserved for explicit JSON output; CLI output is JSON by default.',
|
|
1896
|
+
'--include-content': 'Opt in to returning plaintext local memory content in the JSON result.',
|
|
1897
|
+
},
|
|
1898
|
+
status_options: {
|
|
1899
|
+
'enigma status --bundle <path>': 'Show local Memory Passport counts, roots, owner display fields, connector readiness, and next commands.',
|
|
1900
|
+
'enigma passport status --bundle <path>': 'Alias for enigma status.',
|
|
1901
|
+
},
|
|
1902
|
+
setup_options: {
|
|
1903
|
+
'--bundle <path>': 'Bundle JSON to create. Defaults to .enigma/bundle.json.',
|
|
1904
|
+
'--out-dir <path>': 'Directory for context-pack.json, export.json, and verify-report.json. Defaults to the bundle directory.',
|
|
1905
|
+
'--client <id>': `Client to plan; repeat or comma-separate. Defaults to ${DEFAULT_SETUP_CLIENTS.join(', ')}.`,
|
|
1906
|
+
'--memory-file <path>': 'Read local memory text from a file without echoing plaintext. Alias: --text-file.',
|
|
1907
|
+
'--memory-text <text>': 'Inline demo-only memory text. Avoid for private content because argv can be logged.',
|
|
1908
|
+
'--overwrite': 'Replace existing local setup artifacts.',
|
|
1909
|
+
'--dry-run': 'Plan setup without writing local artifacts or client configs.',
|
|
1910
|
+
'--write-connectors': 'Also write selected client MCP config files. Defaults to false.',
|
|
1911
|
+
},
|
|
1321
1912
|
quickstart_options: {
|
|
1322
1913
|
'--bundle <path>': 'Bundle JSON to create. Defaults to .enigma/bundle.json.',
|
|
1323
1914
|
'--out-dir <path>': 'Directory for context-pack.json, export.json, and verify-report.json. Defaults to the bundle directory.',
|
|
@@ -1398,15 +1989,16 @@ export async function main(argv = process.argv.slice(2), io = { stdout: process.
|
|
|
1398
1989
|
print(usage(), io);
|
|
1399
1990
|
return 0;
|
|
1400
1991
|
}
|
|
1401
|
-
const twoPartCommands = ['boundary', 'mcp', 'mesh', 'enterprise', 'capsule', 'relay', 'gateway', 'connect', 'disconnect', 'import', 'native-host', 'meter', 'settlement', 'demo'];
|
|
1992
|
+
const twoPartCommands = ['boundary', 'mcp', 'mesh', 'enterprise', 'capsule', 'relay', 'gateway', 'connect', 'disconnect', 'import', 'native-host', 'meter', 'settlement', 'demo', 'passport'];
|
|
1402
1993
|
const flags = parseArgs(twoPartCommands.includes(command) ? argv.slice(2) : argv.slice(1));
|
|
1403
1994
|
const positionalFile = optionalPositional(argv[2]);
|
|
1404
|
-
if ((flags.has('help') || argv.includes('-h')) && (((command === 'relay' || command === 'gateway') && (subcommand === 'serve' || subcommand === 'demo')) || (command === 'native-host' && (subcommand === 'manifest' || subcommand === 'install-plan')) || (command === 'demo' && subcommand === 'cross-model'))) {
|
|
1995
|
+
if ((flags.has('help') || argv.includes('-h')) && (command === 'setup' || command === 'search' || command === 'status' || (command === 'passport' && subcommand === 'status') || ((command === 'relay' || command === 'gateway') && (subcommand === 'serve' || subcommand === 'demo')) || (command === 'native-host' && (subcommand === 'manifest' || subcommand === 'install-plan')) || (command === 'demo' && subcommand === 'cross-model'))) {
|
|
1405
1996
|
print(usage(), io);
|
|
1406
1997
|
return 0;
|
|
1407
1998
|
}
|
|
1408
1999
|
try {
|
|
1409
2000
|
if (command === 'init') return await initCommand(flags, io);
|
|
2001
|
+
if (command === 'setup') return await setupCommand(flags, io);
|
|
1410
2002
|
if (command === 'quickstart') return await quickstartCommand(flags, io);
|
|
1411
2003
|
if (command === 'demo' && subcommand === 'cross-model') return await crossModelDemoCommand(flags, io);
|
|
1412
2004
|
if (command === 'doctor') return await doctorCommand(flags, io);
|
|
@@ -1418,6 +2010,9 @@ export async function main(argv = process.argv.slice(2), io = { stdout: process.
|
|
|
1418
2010
|
if (command === 'update') return await updateCommand(flags, io);
|
|
1419
2011
|
if (command === 'delete') return await deleteCommand(flags, io);
|
|
1420
2012
|
if (command === 'context') return await contextCommand(flags, io);
|
|
2013
|
+
if (command === 'search') return await searchCommand(flags, io);
|
|
2014
|
+
if (command === 'status') return await statusCommand(flags, io);
|
|
2015
|
+
if (command === 'passport' && subcommand === 'status') return await statusCommand(flags, io);
|
|
1421
2016
|
if (command === 'export') return await exportCommand(flags, io);
|
|
1422
2017
|
if (command === 'import') return await importCommand(subcommand, flags, io, positionalFile);
|
|
1423
2018
|
if (command === 'capsule' && subcommand === 'export') return await capsuleExportCommand(flags, io, positionalFile);
|
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
Enigma Memory is a local-first SDK, CLI, MCP server, and service-contract package. The developer surfaces are designed to be copied without secrets, cloud credentials, hidden local paths, or account identifiers.
|
|
4
4
|
|
|
5
|
+
## CLI memory passport loop
|
|
6
|
+
|
|
7
|
+
For most developers, start with the installed CLI before reading the SDK internals or service contracts:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install -g enigma-memory
|
|
11
|
+
enigma setup --overwrite
|
|
12
|
+
enigma remember --text-file ./memory.txt
|
|
13
|
+
enigma search --query "..."
|
|
14
|
+
enigma context --query "..." --optimize
|
|
15
|
+
enigma verify --export ./.enigma/export.json
|
|
16
|
+
enigma connect claude-desktop --dry-run
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`enigma setup --overwrite` writes local Enigma artifacts under the workspace `.enigma` path and emits deterministic, public-safe JSON. It does not write third-party app configs unless you explicitly run `enigma connect <client>` without `--dry-run`. Treat provider-native memory as cache only; the local Enigma vault is canonical.
|
|
20
|
+
|
|
5
21
|
## Copyable starting points
|
|
6
22
|
|
|
7
23
|
- SDK/API guide: [`docs/sdk-api.md`](./sdk-api.md)
|
|
@@ -25,11 +41,11 @@ The example app prints ids, counts, roots, and verification status only. It does
|
|
|
25
41
|
|
|
26
42
|
## CLI and CI loop
|
|
27
43
|
|
|
28
|
-
The CI example installs Node 24, installs the published `enigma-memory@0.1.
|
|
44
|
+
The CI example installs Node 24, installs the published `enigma-memory@0.1.6` package, runs:
|
|
29
45
|
|
|
30
46
|
```sh
|
|
31
|
-
npx enigma
|
|
32
|
-
npx enigma doctor
|
|
47
|
+
npx --yes --package enigma-memory enigma setup --overwrite
|
|
48
|
+
npx --yes --package enigma-memory enigma doctor
|
|
33
49
|
npm run benchmark:memory-suite -- --out benchmark-report.json
|
|
34
50
|
```
|
|
35
51
|
|
|
@@ -49,22 +65,73 @@ Use the workflow as a template in a consumer repository. It is intentionally lim
|
|
|
49
65
|
|
|
50
66
|
## MCP client loop
|
|
51
67
|
|
|
52
|
-
The generic MCP
|
|
68
|
+
The same installed package can be used by Claude Desktop, Cursor, Kimi Code, or any generic MCP client. Copy one snippet, replace the bundle path with the local path from your setup output, and restart the client.
|
|
69
|
+
|
|
70
|
+
Claude Desktop:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"enigma": {
|
|
76
|
+
"command": "enigma-mcp",
|
|
77
|
+
"args": [],
|
|
78
|
+
"env": {
|
|
79
|
+
"ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Cursor:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"mcpServers": {
|
|
91
|
+
"enigma": {
|
|
92
|
+
"command": "enigma-mcp",
|
|
93
|
+
"args": [],
|
|
94
|
+
"env": {
|
|
95
|
+
"ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Kimi Code:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{
|
|
106
|
+
"mcpServers": {
|
|
107
|
+
"enigma": {
|
|
108
|
+
"command": "enigma-mcp",
|
|
109
|
+
"args": [],
|
|
110
|
+
"env": {
|
|
111
|
+
"ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Generic MCP:
|
|
53
119
|
|
|
54
120
|
```json
|
|
55
121
|
{
|
|
56
122
|
"mcpServers": {
|
|
57
123
|
"enigma": {
|
|
58
124
|
"command": "enigma-mcp",
|
|
125
|
+
"args": [],
|
|
59
126
|
"env": {
|
|
60
|
-
"ENIGMA_BUNDLE": "
|
|
127
|
+
"ENIGMA_BUNDLE": "/absolute/path/to/.enigma/bundle.json"
|
|
61
128
|
}
|
|
62
129
|
}
|
|
63
130
|
}
|
|
64
131
|
}
|
|
65
132
|
```
|
|
66
133
|
|
|
67
|
-
|
|
134
|
+
Do not commit private bundle paths if they reveal local usernames, workspace names, account ids, or other personal details.
|
|
68
135
|
|
|
69
136
|
## Claim boundaries for developers
|
|
70
137
|
|
package/docs/sdk-api.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SDK and API guide
|
|
2
2
|
|
|
3
|
-
This guide covers the public package imports for `enigma-memory@0.1.
|
|
3
|
+
This guide covers the public package imports for `enigma-memory@0.1.6`. The SDK runs locally by default: vaults, passports, context packs, receipts, relay/gateway demo state, storage contracts, metering artifacts, and settlement artifacts are package-level developer surfaces. They are not evidence of hosted Enigma cloud, provider-side deletion, provider model forgetting, token ROI, invoice savings, compliance certification, or benchmark leadership.
|
|
4
4
|
|
|
5
5
|
## Install and import style
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
const DEFAULT_BUNDLE = '.enigma/bundle.json';
|
|
18
18
|
const JSONRPC_VERSION = '2.0';
|
|
19
19
|
const MCP_PROTOCOL_VERSION = '2024-11-05';
|
|
20
|
-
const SERVER_INFO = Object.freeze({ name: 'enigma-mcp-server', version: '0.1.
|
|
20
|
+
const SERVER_INFO = Object.freeze({ name: 'enigma-mcp-server', version: '0.1.6' });
|
|
21
21
|
const JSON_RPC_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
22
22
|
const JSON_RPC_ERROR = Object.freeze({
|
|
23
23
|
INVALID_REQUEST: -32600,
|
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
|
|
7
7
|
export const INSTALLER_ASSET_SCHEMA = 'enigma.installer_assets.v1';
|
|
8
8
|
export const INSTALLER_ASSET_PACKAGE = 'enigma-memory';
|
|
9
|
-
export const INSTALLER_ASSET_VERSION = '0.1.
|
|
9
|
+
export const INSTALLER_ASSET_VERSION = '0.1.6';
|
|
10
10
|
export const INSTALLER_ASSET_GENERATED_AT = '1970-01-01T00:00:00.000Z';
|
|
11
11
|
|
|
12
12
|
const SCRIPT_PATH = fileURLToPath(import.meta.url);
|
|
@@ -995,7 +995,7 @@ function buildSuiteReport(datasetRows, topK, options) {
|
|
|
995
995
|
generated_at: options.generated_at ?? new Date().toISOString(),
|
|
996
996
|
package: {
|
|
997
997
|
name: 'enigma-memory',
|
|
998
|
-
version: '0.1.
|
|
998
|
+
version: '0.1.6',
|
|
999
999
|
},
|
|
1000
1000
|
public_safe: true,
|
|
1001
1001
|
top_k: topK,
|