memorio 5.1.3 → 5.2.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.
Files changed (48) hide show
  1. package/AGENTS.md +22 -13
  2. package/CHANGELOG.md +24 -9
  3. package/README.md +61 -19
  4. package/SECURITY-HARDENING.md +258 -0
  5. package/SECURITY.md +67 -3
  6. package/SUMMARY.md +55 -59
  7. package/adr/002-observer-semantics.md +1 -1
  8. package/adr/003-deep-mutation-semantics.md +1 -1
  9. package/adr/004-array-mutation-semantics.md +1 -1
  10. package/adr/010-logic-phase-0.md +42 -0
  11. package/adr/README.md +16 -11
  12. package/bin/cli.js +82 -60
  13. package/examples/acquired-knowledge.ts +174 -0
  14. package/examples/agent-memory-demo.ts +140 -0
  15. package/examples/sqlite-batched-writes.ts +60 -60
  16. package/examples/sync.ts +90 -90
  17. package/examples/useObserver.tsx +2 -2
  18. package/global.cjs +2026 -115
  19. package/global.js +2021 -116
  20. package/index.cjs +2026 -115
  21. package/index.d.ts +1 -0
  22. package/index.js +2021 -116
  23. package/llms.txt +135 -4
  24. package/markdown/EXTENSION_VSCODE_DESIGN.md +410 -0
  25. package/markdown/LOGIC.md +100 -0
  26. package/markdown/MEMORY-ATTACHMENT.md +17 -10
  27. package/markdown/MEMORY.md +404 -14
  28. package/markdown/MEM_FORMAT.md +313 -0
  29. package/markdown/SQLITE.md +2 -2
  30. package/markdown/STATE.md +27 -3
  31. package/markdown/SYNC.md +19 -15
  32. package/markdown/TEMPORAL.md +297 -0
  33. package/markdown/USEOBSERVER.md +7 -4
  34. package/modules/redux.cjs +1188 -38
  35. package/modules/redux.cjs.map +1 -1
  36. package/modules/redux.js +1187 -38
  37. package/modules/redux.js.map +1 -1
  38. package/package.json +14 -5
  39. package/types/exports.d.ts +47 -3
  40. package/types/logic.d.ts +79 -0
  41. package/types/memorio.d.ts +60 -16
  42. package/types/memory.d.ts +118 -0
  43. package/types/session.d.ts +1 -4
  44. package/types/state.d.ts +19 -5
  45. package/types/store.d.ts +1 -4
  46. package/types/temporal.d.ts +95 -0
  47. package/types/useObserver.d.ts +6 -10
  48. package/vsix/memorio.vsix +0 -0
package/SUMMARY.md CHANGED
@@ -1,59 +1,55 @@
1
- # Riepilogo dei file - memorio examples & markdown
2
-
3
- ## 📁 examples/ (20 file)
4
-
5
- | File | Cosa mostra |
6
- |---|---|
7
- | `basic.ts` | Tour introduttivo: platform detection, `state`, `store`, `session` in un unico script. |
8
- | `cache.ts` | Uso base della cache in-memory: set/get, oggetti complessi, cleanup. |
9
- | `cross-platform-guards.ts` | Come usare `getCapabilities()` invece di `isBrowser()`/`isNode()` per gestire in modo esplicito gli ambienti dove `store`/`session`/`idb` non sono durevoli. |
10
- | `history.ts` *(nuovo)* | State Intelligence: `snapshot()`/`diff()`/`rollback()` per il pattern "prova → ispeziona → conferma o annulla", undo/redo passo-passo, trace log con export/replay. |
11
- | `idb.ts` | CRUD completo su IndexedDB: database, tabelle, record, info (size/version/exist). |
12
- | `multi-tenant-context.ts` | Isolamento dati per richiesta/tenant con `memorio.createContext()` in un handler server-side, incluso cleanup. |
13
- | `node-server.ts` | Memorio lato server: cache in-memory, fallback di `store`/`session`, contesti multi-tenant, più snippet commentati (Express, WebSocket, job queue, CLI). |
14
- | `observer.ts` | Pattern observer: singolo valore, oggetti interi, più observer sullo stesso path, cleanup. |
15
- | `platform.ts` | Platform detection dettagliata + isolamento contesti per server multi-tenant, con verifica esplicita dell'isolamento tra due utenti. |
16
- | `react-app.tsx` | App React completa (header, profilo, cart, notifiche, settings, login/logout) costruita solo su `state`/`store`/`useObserver`. |
17
- | `react-observer.tsx` | `useObserver` in due modalità (auto-discovery vs deps espliciti) combinato con `typed<T>()` e `registerSchema()`. |
18
- | `semantic-memory.ts` | Memoria applicativa per un'app LLM-backed: remember/update con confidence e source, retrieval con `memory.context()` - con nota esplicita che non è ricerca semantica per embedding. |
19
- | `session-advanced.ts` | Uso avanzato di `session`: auth token, bozza di form, carrello, dimensione dello storage. |
20
- | `sqlite-batched-writes.ts` | Con il journal+checkpoint, i write sono incrementali ma i checkpoint (snapshot completo) sono costosi: batch di insert seguito da un solo flush. |
21
- | `state-advanced.ts` | Stato annidato, array, locking di un valore (`.lock()`), path tracking, rimozione stato. |
22
- | `store-advanced.ts` | `store` avanzato: persistenza, quota, alias dei metodi, gestione errori, serializzazione di vari tipi. |
23
- | `sync.ts` *(nuovo)* | Local-first sync: configurazione di un `SyncProvider` (push/pull/resolve), scope `device`/`user`/`shared`, ispezione e replay del journal. |
24
- | `typed-and-schema.ts` | Tutti gli snippet di `TYPED.md` e `SCHEMA.md` in un unico file TypeScript funzionante: typed state + validazione runtime combinati. |
25
- | `useObserver.tsx` | Guida step-by-step all'hook `useObserver`: dipendenza singola, multiple, auto-discovery, sync con `useState`, mini to-do app. |
26
- | `browser-vanilla.html` | Demo HTML/JS pura (nessun bundler) con UI per state, store, session, cache, observer e platform info. |
27
-
28
- ## 📁 markdown/ (24 file)
29
-
30
- | File | Cosa documenta |
31
- |---|---|
32
- | `AUDIT-REPORT.md` | Audit di sicurezza/performance/affidabilità/qualità del codice per la v5.1.0 (datato 2026-09-06), con azioni correttive già applicate. |
33
- | `CACHE.md` | Reference della cache in-memory: API, quando usarla, limiti. |
34
- | `CHANGELOG.md` | Storico versioni dalla v2.5.0 alla `Unreleased`, con bugfix, refactoring e note di sicurezza per ogni release. |
35
- | `DEVTOOLS.md` | Strumenti di debug da console del browser per ispezionare/gestire lo stato di Memorio. |
36
- | `DISPATCH.md` | Sistema di eventi pub/sub per app vanilla JS (alternativa a `useObserver` fuori da React). |
37
- | `HISTORY.md` | Reference completa di time-travel: enable/snapshot/diff/undo/redo/rollback/trace, con "how it works" e best practice. |
38
- | `IDB.md` | Reference IndexedDB: creazione DB/tabelle, CRUD, info sul database. |
39
- | `IMPORT.md` | I due stili di import (named vs `memorio/global`) e perché condividono la stessa istanza. |
40
- | `INSPECT.md` | Utility di introspezione per scoprire/verificare la forma dello `state` a runtime - utile per agenti AI. |
41
- | `LOGGER.md` | Middleware di logging automatico per tracciare le modifiche di stato in console. |
42
- | `MEMORY-ATTACHMENT.md` | Sistema di "attachment" tra elementi di memoria - estensione opzionale della memoria semantica. |
43
- | `MEMORY.md` | Reference del layer di memoria semantica: remember/update/context, TTL, confidence, tag, scope. |
44
- | `OBSERVER.md` | Reference del pattern observer per reagire ai cambi di stato. |
45
- | `PLATFORM.md` | Platform detection + sistema di context isolation per applicazioni multi-tenant server-side. |
46
- | `PROJECT.md` | Scheda di progetto interna: versione, team, moduli inclusi, stack tecnologico, target. |
47
- | `SCHEMA.md` | Validazione runtime dei percorsi di stato: schema oggetto/array/enum/funzione custom. |
48
- | `SECURITY.md` | Postura di sicurezza del progetto (minacce coperte, cosa NON fa Memorio, come viene gestito l'accesso ai dati). |
49
- | `SESSION.md` | Reference di `session` (sessionStorage) con fallback in-memory fuori dal browser. |
50
- | `SQLITE.md` | Reference del layer SQLite via `sql.js`/`bun:sqlite`: caricamento lazy, persistenza journal+checkpoint, query. |
51
- | `STATE.md` | Reference dello stato reattivo basato su Proxy - il layer centrale di Memorio. |
52
- | `STORE.md` | Reference di `store` (localStorage) con fallback in-memory fuori dal browser. |
53
- | `SYNC.md` | Sincronizzazione local-first opzionale: scope, journal, conflict resolution, strategie avanzate per multi-device (HLC, tombstones, fractional indexing). |
54
- | `TYPED.md` | `memorio.typed<T>()` per la sicurezza dei tipi a compile-time sullo stesso proxy di `state`. |
55
- | `USEOBSERVER.md` | Reference dell'hook React `useObserver`: modalità auto-discovery vs deps espliciti, tutte le forme di `deps` supportate. |
56
-
57
- ---
58
-
59
- **Nota di copertura:** ogni doc in `markdown/` ha ora almeno un esempio corrispondente in `examples/`, **tranne** `DEVTOOLS.md`, `DISPATCH.md`, `INSPECT.md`, `LOGGER.md` e `MEMORY-ATTACHMENT.md` - utile saperlo se in futuro vuoi completare anche quelli.
1
+ # Documentation map
2
+
3
+ This index points to the current public documentation shipped with Memorio 5.2.0. Historical and
4
+ proposed documents remain labelled so that design chronology is not confused with current behavior.
5
+
6
+ ## Start here
7
+
8
+ | Document | Purpose |
9
+ | --- | --- |
10
+ | [`README.md`](./README.md) | Product overview, first examples, limitations, and reading paths. |
11
+ | [`CURRENT_PROJECT_CHECKPOINT.md`](./CURRENT_PROJECT_CHECKPOINT.md) | Verified state at the 5.2.0 release boundary. |
12
+ | [`CHANGELOG.md`](./CHANGELOG.md) | User-visible release history. |
13
+ | [`SECURITY.md`](./SECURITY.md) | Security model, encryption, and epistemic boundaries. |
14
+ | [`SECURITY-HARDENING.md`](./SECURITY-HARDENING.md) | Deployment and operational hardening guidance. |
15
+
16
+ ## Memory, MEM, and Logic
17
+
18
+ | Document | Status and purpose |
19
+ | --- | --- |
20
+ | [`markdown/MEMORY.md`](./markdown/MEMORY.md) | Current memory API, including Acquire → Discover → Project and separate exact applicability selection. |
21
+ | [`markdown/MEM_FORMAT.md`](./markdown/MEM_FORMAT.md) | Current `.mem` ZIP/JSON package, MAP/DATA, integrity, signatures, inspection, and compatibility. |
22
+ | [`markdown/LOGIC.md`](./markdown/LOGIC.md) | Implemented and verified Logic PHASE 0 contract and repository isolation. |
23
+ | [`markdown/MEMORY-ATTACHMENT.md`](./markdown/MEMORY-ATTACHMENT.md) | Proposed attachment design; not implemented. |
24
+ | [`examples/acquired-knowledge.ts`](./examples/acquired-knowledge.ts) | Rerunnable production workflow example with acquisition, discovery, projection, exact selection, refinement, superseding, and current-reality verification. |
25
+ | [`examples/semantic-memory.ts`](./examples/semantic-memory.ts) | Key/value application memory; despite its historical filename, it is not embedding/vector search. |
26
+
27
+ ## API references
28
+
29
+ - Core: [`STATE.md`](./markdown/STATE.md), [`OBSERVER.md`](./markdown/OBSERVER.md),
30
+ [`DISPATCH.md`](./markdown/DISPATCH.md), [`HISTORY.md`](./markdown/HISTORY.md), and
31
+ [`TEMPORAL.md`](./markdown/TEMPORAL.md).
32
+ - Storage: [`STORE.md`](./markdown/STORE.md), [`SESSION.md`](./markdown/SESSION.md),
33
+ [`CACHE.md`](./markdown/CACHE.md), [`IDB.md`](./markdown/IDB.md), and
34
+ [`SQLITE.md`](./markdown/SQLITE.md).
35
+ - Integration and runtime: [`IMPORT.md`](./markdown/IMPORT.md), [`PLATFORM.md`](./markdown/PLATFORM.md),
36
+ [`TYPED.md`](./markdown/TYPED.md), [`SCHEMA.md`](./markdown/SCHEMA.md),
37
+ [`USEOBSERVER.md`](./markdown/USEOBSERVER.md), [`REDUX.md`](./markdown/REDUX.md), and
38
+ [`SYNC.md`](./markdown/SYNC.md).
39
+ - Operations: [`INSPECT.md`](./markdown/INSPECT.md), [`DEVTOOLS.md`](./markdown/DEVTOOLS.md), and
40
+ [`LOGGER.md`](./markdown/LOGGER.md).
41
+
42
+ ## Decisions and historical material
43
+
44
+ - [`adr/README.md`](./adr/README.md) classifies every ADR as CURRENT or OPEN while retaining its
45
+ original lifecycle status and text.
46
+ - [`markdown/AUDIT-REPORT.md`](./markdown/AUDIT-REPORT.md) is a historical internal 5.1.0 audit, not a
47
+ third-party audit and not the current release checkpoint.
48
+ - [`markdown/EXTENSION_VSCODE_DESIGN.md`](./markdown/EXTENSION_VSCODE_DESIGN.md) records extension
49
+ design material; it is not the authority for the core 5.2.0 runtime.
50
+
51
+ ## Examples
52
+
53
+ The [`examples/`](./examples/) directory contains runnable examples for the major public layers. Use
54
+ isolated state for examples that persist data. In particular, do not point examples at a real
55
+ `.memorio/project.mem` or `.memorio/logic/logic.mem` merely for cleanup or demonstration.
@@ -1,6 +1,6 @@
1
1
  # ADR-002: Observer Semantics
2
2
 
3
- > **Status:** Proposed
3
+ > **Status:** Accepted (CURRENT; compliance suite verified 2026-09-23)
4
4
  > **Date:** 2026-09-12
5
5
 
6
6
  ## Context
@@ -1,6 +1,6 @@
1
1
  # ADR-003: Deep Mutation Semantics
2
2
 
3
- > **Status:** Proposed
3
+ > **Status:** Accepted (CURRENT; compliance suite verified 2026-09-23)
4
4
  > **Date:** 2026-09-12
5
5
 
6
6
  ## Context
@@ -1,6 +1,6 @@
1
1
  # ADR-004: Array Mutation Semantics
2
2
 
3
- > **Status:** Proposed
3
+ > **Status:** Accepted (CURRENT; compliance suite verified 2026-09-23)
4
4
  > **Date:** 2026-09-12
5
5
 
6
6
  ## Context
@@ -0,0 +1,42 @@
1
+ # ADR 010: Logic PHASE 0 Repository Boundary
2
+
3
+ **Status:** Accepted
4
+
5
+ ## Context
6
+
7
+ `memorio.logic` needs to persist and select situation/action/outcome experience while reusing the
8
+ existing immutable acquired-claim, revision, MEM package, and selection machinery. Project acquired
9
+ experience already persists in `.memorio/project.mem`. Mixing both domains would couple clearing,
10
+ claim identities, revision validation, and discovery before cross-domain behavior has been designed.
11
+
12
+ PHASE 0 also needs totals across all active Logic claims. A first implementation added `_all` to the
13
+ general selector, but focused verification showed that the sentinel violated exact applicability
14
+ matching, collided with the applicability namespace, and interacted incorrectly with specificity.
15
+
16
+ ## Decision
17
+
18
+ - Persist Logic in its own `MemDirectoryKnowledgeRepository` rooted at `.memorio/logic`, with
19
+ `logic.mem` as its writable source.
20
+ - Keep `.memorio/project.mem` and `.memorio/logic/logic.mem` as independent repositories and runtime
21
+ instances.
22
+ - Keep claim identity, provenance, and revision validation repository-local. Do not imply or emulate
23
+ cross-repository revision relationships.
24
+ - Preserve exact structured applicability matching in the shared selector.
25
+ - Compute Logic totals by loading its repository and counting `activeClaims(state)`, not through a
26
+ wildcard query.
27
+ - Expose the PHASE 0 singleton through named exports and `globalThis.memorio.logic`.
28
+
29
+ ## Consequences
30
+
31
+ Logic cannot accidentally discover or clear project memory, and project acquired memory cannot
32
+ discover or clear Logic. The shared selector retains one meaning. Totals include active claims at all
33
+ applicability specificities.
34
+
35
+ There is no unified query, revision chain, provenance graph, or composition behavior across the two
36
+ repositories. Adding any of those is a future design decision, not an implied PHASE 0 capability.
37
+
38
+ ## Verification
39
+
40
+ `tests/vitest/tests/contracts/adr-010-logic.test.ts` is the compliance suite. It includes the
41
+ mixed-specificity regression added after `_all` was removed. The detailed investigation and
42
+ chronology remain in `.project/phase0-design-verification.md` and `.project/project_history.md`.
package/adr/README.md CHANGED
@@ -17,17 +17,22 @@ Decision Records) format. Each decision record answers four questions:
17
17
 
18
18
  ## Numbering
19
19
 
20
- | ADR | Title | Status |
21
- |-----|-------|--------|
22
- | [001](001-state-proxy-model.md) | State Proxy Model | Accepted |
23
- | [002](002-observer-semantics.md) | Observer Semantics | Proposed |
24
- | [003](003-deep-mutation-semantics.md) | Deep Mutation Semantics | Proposed |
25
- | [004](004-array-mutation-semantics.md) | Array Mutation Semantics | Proposed |
26
- | [005](005-scheduler-contract.md) | Scheduler Contract | Proposed |
27
- | [006](006-context-isolation.md) | Context Isolation Model | Accepted |
28
- | [007](007-mutation-records.md) | Mutation Records | Accepted |
29
- | [008](008-transactions.md) | Transactions | Accepted |
30
- | [009](009-history-model.md) | History Model (Snapshot/Delta) | Proposed |
20
+ | ADR | Title | Lifecycle status | 5.2.0 classification |
21
+ |-----|-------|------------------|----------------------|
22
+ | [001](001-state-proxy-model.md) | State Proxy Model | Accepted | **CURRENT** |
23
+ | [002](002-observer-semantics.md) | Observer Semantics | Accepted | **CURRENT** |
24
+ | [003](003-deep-mutation-semantics.md) | Deep Mutation Semantics | Accepted | **CURRENT** |
25
+ | [004](004-array-mutation-semantics.md) | Array Mutation Semantics | Accepted | **CURRENT** |
26
+ | [005](005-scheduler-contract.md) | Scheduler Contract | Proposed | **OPEN** — only the documented current microtask behavior is implemented; the configurable scheduler is not |
27
+ | [006](006-context-isolation.md) | Context Isolation Model | Accepted | **CURRENT** |
28
+ | [007](007-mutation-records.md) | Mutation Records | Accepted | **CURRENT** |
29
+ | [008](008-transactions.md) | Transactions | Accepted | **CURRENT** |
30
+ | [009](009-history-model.md) | History Model (Snapshot/Delta) | Proposed | **OPEN** — the document preserves the implemented flat baseline and a future commit model |
31
+ | [010](010-logic-phase-0.md) | Logic PHASE 0 Repository Boundary | Accepted | **CURRENT** |
32
+
33
+ No ADR is classified as **SUPERSEDED** or **HISTORICAL** at this checkpoint. Historical intermediate
34
+ implementation details (notably Logic's rejected `_all` sentinel) remain in the relevant ADR and
35
+ project history, while the accepted decision describes current behavior.
31
36
 
32
37
  ## Lifecycle
33
38
 
package/bin/cli.js CHANGED
@@ -1,68 +1,90 @@
1
1
  #!/usr/bin/env node
2
- import { spawnSync } from 'node:child_process';
3
- import path from 'node:path';
4
- import fs from 'node:fs';
5
- import os from 'node:os';
6
- import { fileURLToPath } from 'node:url';
7
-
8
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
-
10
- const args = process.argv.slice(2);
11
- const command = args[0];
12
-
2
+ import { spawnSync } from 'node:child_process'
3
+ import path from 'node:path'
4
+ import fs from 'node:fs'
5
+ import os from 'node:os'
6
+ import { fileURLToPath } from 'node:url'
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
+
10
+ const args = process.argv.slice(2)
11
+ const command = args[0]
12
+
13
13
  if (command === 'install-extension') {
14
- installExtension();
14
+ installExtension()
15
+ } else if (command === 'inspect') {
16
+ inspectMemory(args[1])
15
17
  } else {
16
- console.log('Usage: npx memorio install-extension');
17
- process.exit(command ? 1 : 0);
18
+ console.info('Usage: npx memorio <install-extension|inspect FILE.mem>')
19
+ process.exit(command ? 1 : 0)
18
20
  }
19
21
 
20
- function installExtension() {
21
- const vsixPath = path.join(__dirname, '..', 'vsix', 'memorio.vsix');
22
-
23
- if (!fs.existsSync(vsixPath)) {
24
- console.error(`VSIX file not found at ${vsixPath}.`);
25
- console.error('The npm package may be corrupted, or the build did not copy the .vsix into vsix/.');
26
- process.exit(1);
22
+ async function inspectMemory(file) {
23
+ if (!file) {
24
+ console.error('Usage: npx memorio inspect FILE.mem')
25
+ process.exitCode = 1
26
+ return
27
27
  }
28
-
29
- const candidates = candidateBinaries();
30
- const found = candidates.find((bin) => isAvailable(bin));
31
-
32
- if (!found) {
33
- console.error('No compatible editor found in PATH (tried: ' + candidates.join(', ') + ').');
34
- console.error('Manual installation:');
35
- console.error(' 1. Open your editor (VSCodium/VSCode)');
36
- console.error(' 2. Command Palette -> "Extensions: Install from VSIX..."');
37
- console.error(` 3. Select: ${vsixPath}`);
38
- process.exit(1);
28
+ try {
29
+ const [{ inspectMem }, bytes] = await Promise.all([
30
+ import('../index.js'),
31
+ fs.promises.readFile(path.resolve(file))
32
+ ])
33
+ const result = await inspectMem(bytes)
34
+ console.info(JSON.stringify(result, null, 2))
35
+ if (result.status !== 'valid') process.exitCode = 2
36
+ } catch (error) {
37
+ console.error(`Unable to inspect ${file}: ${error instanceof Error ? error.message : String(error)}`)
38
+ process.exitCode = 1
39
39
  }
40
-
41
- console.log(`Editor detected: ${found}. Installing memorio extension...`);
42
- const result = spawnSync(found, ['--install-extension', vsixPath], {
43
- stdio: 'inherit',
44
- shell: os.platform() === 'win32',
45
- });
46
-
47
- if (result.status !== 0) {
48
- console.error('Installation failed. Try manually:');
49
- console.error(` ${found} --install-extension "${vsixPath}"`);
50
- process.exit(result.status || 1);
51
- }
52
-
53
- console.log('Memorio extension installed successfully.');
54
- }
55
-
56
- function candidateBinaries() {
57
- const names = ['codium', 'vscodium', 'code', 'code-insiders'];
58
- if (os.platform() === 'win32') {
59
- return names.map((n) => `${n}.cmd`);
60
- }
61
- return names;
62
- }
63
-
64
- function isAvailable(bin) {
65
- const checkCmd = os.platform() === 'win32' ? 'where' : 'which';
66
- const result = spawnSync(checkCmd, [bin], { stdio: 'ignore', shell: true });
67
- return result.status === 0;
68
40
  }
41
+
42
+ function installExtension() {
43
+ const vsixPath = path.join(__dirname, '..', 'vsix', 'memorio.vsix')
44
+
45
+ if (!fs.existsSync(vsixPath)) {
46
+ console.error(`VSIX file not found at ${vsixPath}.`)
47
+ console.error('The npm package may be corrupted, or the build did not copy the .vsix into vsix/.')
48
+ process.exit(1)
49
+ }
50
+
51
+ const candidates = candidateBinaries()
52
+ const found = candidates.find((bin) => isAvailable(bin))
53
+
54
+ if (!found) {
55
+ console.error('No compatible editor found in PATH (tried: ' + candidates.join(', ') + ').')
56
+ console.error('Manual installation:')
57
+ console.error(' 1. Open your editor (VSCodium/VSCode)')
58
+ console.error(' 2. Command Palette -> "Extensions: Install from VSIX..."')
59
+ console.error(` 3. Select: ${vsixPath}`)
60
+ process.exit(1)
61
+ }
62
+
63
+ console.info(`Editor detected: ${found}. Installing memorio extension...`)
64
+ const result = spawnSync(found, ['--install-extension', vsixPath], {
65
+ stdio: 'inherit',
66
+ shell: os.platform() === 'win32',
67
+ })
68
+
69
+ if (result.status !== 0) {
70
+ console.error('Installation failed. Try manually:')
71
+ console.error(` ${found} --install-extension "${vsixPath}"`)
72
+ process.exit(result.status || 1)
73
+ }
74
+
75
+ console.info('Memorio extension installed successfully.')
76
+ }
77
+
78
+ function candidateBinaries() {
79
+ const names = ['codium', 'vscodium', 'code', 'code-insiders']
80
+ if (os.platform() === 'win32') {
81
+ return names.map((n) => `${n}.cmd`)
82
+ }
83
+ return names
84
+ }
85
+
86
+ function isAvailable(bin) {
87
+ const checkCmd = os.platform() === 'win32' ? 'where' : 'which'
88
+ const result = spawnSync(checkCmd, [bin], { stdio: 'ignore', shell: true })
89
+ return result.status === 0
90
+ }
@@ -0,0 +1,174 @@
1
+ /**
2
+ * acquired-knowledge.ts
3
+ *
4
+ * Scenario: an AI agent working on a real project needs to record lessons it
5
+ * learns during development so that future sessions can recall them instead
6
+ * of re-discovering the same issues.
7
+ *
8
+ * The complete workflow preserves an experience with `acquire()`, finds
9
+ * plausible prior experience from ordinary situation text with `discover()`,
10
+ * and prepares bounded untrusted context for an AI with `project()`.
11
+ * `context({ acquired })` remains the separate exact applicability selector.
12
+ *
13
+ * Run: npx tsx docs/examples/acquired-knowledge.ts
14
+ */
15
+ import { memorio } from 'memorio'
16
+
17
+ const mem = memorio.memory
18
+
19
+ async function main() {
20
+ // ============================================
21
+ // 1. Check exact current state before acquiring this fixed demo identity.
22
+ // This keeps the example safe to run again without duplicating claim IDs.
23
+ // ============================================
24
+
25
+ console.debug('=== Checking for Existing Knowledge ===\n')
26
+
27
+ const existing = await mem.context({
28
+ acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
29
+ })
30
+
31
+ if (existing.claims.length > 0) {
32
+ console.debug(`Found ${existing.claims.length} relevant claim(s):`)
33
+ for (const claim of existing.claims) {
34
+ console.debug(` - [${claim.id}]`, JSON.stringify(claim.knowledge))
35
+ console.debug(` Evidence:`, claim.evidence)
36
+ if (claim.revision) {
37
+ console.debug(` Revision:`, claim.revision)
38
+ }
39
+ }
40
+ console.debug('')
41
+ } else {
42
+ console.debug('No prior knowledge found for this context. Proceeding fresh.\n')
43
+ }
44
+
45
+ // ============================================
46
+ // 2. Acquire knowledge after learning it
47
+ // ============================================
48
+
49
+ console.debug('=== Acquiring Knowledge When Missing ===\n')
50
+
51
+ // Lesson learned: a CSS grid track sized with min-content also incorporates
52
+ // the inner element's margins. Replacing it with a fixed width changes the
53
+ // effective rendered track.
54
+ if (existing.claims.length === 0) await mem.acquire({
55
+ id: 'css.grid.min-content-margins',
56
+ knowledge: {
57
+ guidance: 'Replacing a min-content grid track with the inner element fixed width changes the effective rendered track width because min-content sizing incorporates the inner element margins.',
58
+ impact: 'Layout shifted when a fixed-width aside replaced a min-content grid track.'
59
+ },
60
+ applies: { area: 'css', component: 'layout', pattern: 'grid-min-content' },
61
+ evidence: [{
62
+ id: 'layout-debug-20260918',
63
+ source: 'real-project',
64
+ observedAt: '2026-09-18T12:30:00Z'
65
+ }],
66
+ epistemicType: 'observed',
67
+ provenance: { source: 'example-project', detail: 'Observed during layout debugging.' }
68
+ })
69
+ console.debug(existing.claims.length === 0
70
+ ? 'Acquired: css.grid.min-content-margins\n'
71
+ : 'The demo already has active general knowledge; acquisition skipped.\n')
72
+
73
+ // ============================================
74
+ // 3. Discover from ordinary situation text, then project for AI transfer
75
+ // ============================================
76
+
77
+ console.debug('=== Discovering and Projecting Prior Experience ===\n')
78
+
79
+ const found = await mem.discover(
80
+ 'An aside layout shifted after changing CSS grid track sizing and margins.'
81
+ )
82
+ const projected = mem.project(found, { maxCandidates: 3, maxCharacters: 4_000 })
83
+
84
+ console.debug('Discovered candidates:', found.candidates.map(candidate => candidate.claim.id))
85
+ console.debug('Projected candidates:', projected.experiences.map(experience => experience.id))
86
+ console.debug('Omitted candidates:', projected.omittedCandidates)
87
+ console.debug('AI context (prior experience, not current truth):\n', projected.text)
88
+ console.debug('Verify projected experience against the current project before acting.\n')
89
+
90
+ // ============================================
91
+ // 4. Use exact applicability selection when the context is known
92
+ // ============================================
93
+
94
+ console.debug('=== Selecting Exact Acquired Context ===\n')
95
+
96
+ const context = await mem.context({
97
+ acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
98
+ })
99
+
100
+ console.debug('Knowledge version:', context.knowledgeVersion)
101
+ for (const claim of context.claims) {
102
+ console.debug(`Claim: ${claim.id}`)
103
+ console.debug(' Knowledge:', JSON.stringify(claim.knowledge))
104
+ console.debug(' Applies:', JSON.stringify(claim.applicability))
105
+ console.debug(' Evidence:', JSON.stringify(claim.evidence))
106
+ }
107
+
108
+ // ============================================
109
+ // 5. Refine with more specific knowledge
110
+ // ============================================
111
+
112
+ console.debug('\n=== Refining with More Specific Knowledge ===\n')
113
+
114
+ let specific = await mem.context({
115
+ acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content', element: 'aside' }
116
+ })
117
+ const hasSpecificDemo = specific.claims.some(claim => claim.id === 'css.grid.aside-min-content')
118
+ if (!hasSpecificDemo) await mem.acquire({
119
+ id: 'css.grid.aside-min-content',
120
+ knowledge: {
121
+ guidance: 'For aside elements in a grid with min-content tracks, retain min-content and set max-width on the inner content instead of replacing the track sizing.',
122
+ },
123
+ applies: { area: 'css', component: 'layout', pattern: 'grid-min-content', element: 'aside' },
124
+ evidence: [{ id: 'layout-debug-20260918' }],
125
+ refines: 'css.grid.min-content-margins'
126
+ })
127
+ if (!hasSpecificDemo) {
128
+ console.debug('Acquired refinement: css.grid.aside-min-content\n')
129
+ specific = await mem.context({
130
+ acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content', element: 'aside' }
131
+ })
132
+ }
133
+
134
+ // Query the specific context - gets only the more specific claim
135
+ console.debug('Specific context claims:', specific.claims.map(c => c.id))
136
+
137
+ // Query the general context - gets only the general claim
138
+ const general = await mem.context({
139
+ acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
140
+ })
141
+ console.debug('General context claims:', general.claims.map(c => c.id))
142
+
143
+ // ============================================
144
+ // 6. Supersede outdated knowledge
145
+ // ============================================
146
+
147
+ console.debug('\n=== Superseding Outdated Knowledge ===\n')
148
+
149
+ if (!general.claims.some(claim => claim.id === 'css.grid.min-content-margins.v2')) await mem.acquire({
150
+ id: 'css.grid.min-content-margins.v2',
151
+ knowledge: {
152
+ guidance: 'Prefer explicit track sizing (fr units) over min-content for predictable layouts. Min-content still incorporates margins; use this understanding when explicit control is needed.',
153
+ },
154
+ applies: { area: 'css', component: 'layout', pattern: 'grid-min-content' },
155
+ evidence: [{ id: 'layout-debug-20260918' }],
156
+ supersedes: 'css.grid.min-content-margins'
157
+ })
158
+ console.debug(general.claims.some(claim => claim.id === 'css.grid.min-content-margins.v2')
159
+ ? 'The demo replacement is already current; supersede skipped.\n'
160
+ : 'Superseded old claim with v2.\n')
161
+
162
+ const afterSupersede = await mem.context({
163
+ acquired: { area: 'css', component: 'layout', pattern: 'grid-min-content' }
164
+ })
165
+ console.debug('After supersede, claims:', afterSupersede.claims.map(c => c.id))
166
+
167
+ // Acquired knowledge is intentionally persistent. Do not call clear() as
168
+ // routine cleanup: in a real project it would erase unrelated memory too.
169
+ }
170
+
171
+ main().catch(err => {
172
+ console.error('ERROR:', err)
173
+ process.exit(1)
174
+ })