pacs-core 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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PACS Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,602 @@
1
+ # PACS Core — Personal AI Control System
2
+
3
+ **Phase 1 Foundation** | MIT License | Encrypted Storage Layer
4
+
5
+ > PACS replaces the traditional Agent/Skill MD-file system with encrypted, AI-controlled memory and routing.
6
+
7
+ ## What is PACS?
8
+
9
+ PACS (Personal AI Control System) gives AI assistants persistent, encrypted memory and user-controlled routing — without relying on plaintext markdown files.
10
+
11
+ ### Key Features
12
+
13
+ - **AES-256-GCM Encryption** — All sensitive data is encrypted at rest
14
+ - **3-Layer Architecture** — Commands (plaintext) → AI Logic (encrypted) → System Kernel (hardcoded)
15
+ - **Learn Mode** — AI asks before storing facts; user controls auto vs. manual learning
16
+ - **Trigger Commands** — Plaintext, human-editable commands in any language
17
+ - **Standalone or Integrated** — Works with OpenClaw or as a standalone npm package
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install pacs-core
23
+ ```
24
+
25
+ Or for development:
26
+
27
+ ```bash
28
+ git clone https://github.com/yourusername/pacs-core.git
29
+ cd pacs-core
30
+ npm install
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ### 1. Set your encryption key
36
+
37
+ ```bash
38
+ export PACS_ENCRYPTION_KEY="$(openssl rand -hex 32)"
39
+ ```
40
+
41
+ The key lives in the environment only — never in files.
42
+
43
+ ### 2. Bootstrap your PACS directory
44
+
45
+ ```bash
46
+ npm run bootstrap
47
+ ```
48
+
49
+ This creates `~/.openclaw/pacs/` with sample encrypted files.
50
+
51
+ ### 3. Use in your code
52
+
53
+ ```javascript
54
+ const pacs = require('pacs-core');
55
+
56
+ // Parse a trigger command
57
+ const parsed = pacs.triggers.parse('MERKE: Ich spreche Deutsch');
58
+ if (parsed) {
59
+ console.log(`Trigger: ${parsed.trigger.id}`);
60
+ console.log(`Payload: ${parsed.payload}`);
61
+ }
62
+
63
+ // Add a fact to memory
64
+ const memory = pacs.memory.addFact('I prefer German when writing');
65
+
66
+ // Search memory
67
+ const results = pacs.memory.search('German');
68
+
69
+ // Show help
70
+ console.log(pacs.triggers.getHelp());
71
+ ```
72
+
73
+ ## Architecture
74
+
75
+ ```
76
+ ┌─────────────────────────────────────────────┐
77
+ │ Layer 1: COMMANDS (plaintext) │
78
+ │ Human-editable, multi-language triggers │
79
+ │ MERKE:, ROUTING:, REGEL:, SUCHE:, etc. │
80
+ ├─────────────────────────────────────────────┤
81
+ │ Layer 2: PERSONAL AI LOGIC (encrypted) │
82
+ │ AES-256-GCM — AI can reject conflicts │
83
+ │ Memory, routing hints, core rules │
84
+ ├─────────────────────────────────────────────┤
85
+ │ Layer 3: SYSTEM KERNEL (hardcoded) │
86
+ │ AI's own immutable rules — never changed │
87
+ └─────────────────────────────────────────────┘
88
+ ```
89
+
90
+ ## Trigger Commands
91
+
92
+ | Command | Aliases | Description |
93
+ |---------|---------|-------------|
94
+ | `MERKE:` | `LEARN:` | Store a fact in encrypted memory |
95
+ | `PRIVAT:` | `PRIVATE:` | Mark info as private (excluded from exports) |
96
+ | `ROUTING:` | `ROUTE:` | Add routing hint for task delegation |
97
+ | `REGEL:` | `RULE:` | Add a personal AI behavior rule |
98
+ | `BEFEHLE:` | `COMMANDS:` | Show available commands |
99
+ | `WAS WEISST DU?` | `WHAT DO YOU KNOW?` | Query what AI remembers |
100
+ | `SUCHE:` | `SEARCH:` | Search encrypted memory |
101
+ | `VERGISS:` | `FORGET:` | Delete something from memory |
102
+ | `EXPORTIEREN:` | `EXPORT:` | Export memory (excludes private) |
103
+
104
+ ## Learn Modes
105
+
106
+ Control how PACS handles learning:
107
+
108
+ ```
109
+ AI: lern automatisch → Auto-learn mode (AI offers to remember)
110
+ AI: nur auf Befehl → Manual mode only (MERKE: required)
111
+ ```
112
+
113
+ ## Security
114
+
115
+ - **Encryption:** AES-256-GCM (Node.js built-in crypto)
116
+ - **Key storage:** `PACS_ENCRYPTION_KEY` env variable only
117
+ - **Private facts:** Excluded from all exports
118
+ - **AI override:** AI can reject facts that contradict its logic
119
+ - **No external dependencies** beyond Node.js standard library
120
+
121
+ ## API Reference
122
+
123
+ ### `pacs.crypto`
124
+
125
+ ```javascript
126
+ pacs.crypto.encrypt(plaintext) // → "iv:authTag:ciphertext"
127
+ pacs.crypto.decrypt(encryptedData) // → plaintext
128
+ pacs.crypto.generateKey() // → 64-char hex string
129
+ ```
130
+
131
+ ### `pacs.memory`
132
+
133
+ ```javascript
134
+ pacs.memory.read() // → { facts: [], private: [], learnedAt: {} }
135
+ pacs.memory.addFact(fact, isPrivate) // → updated memory
136
+ pacs.memory.removeFact(fact) // → updated memory
137
+ pacs.memory.search(query) // → string[]
138
+ ```
139
+
140
+ ### `pacs.triggers`
141
+
142
+ ```javascript
143
+ pacs.triggers.parse(message) // → { trigger, payload } or null
144
+ pacs.triggers.find('MERKE') // → trigger object or null
145
+ pacs.triggers.contains(message) // → boolean
146
+ pacs.triggers.detectLearnMode(msg) // → 'auto' | 'onDemand' | null
147
+ pacs.triggers.getHelp() // → formatted help string
148
+ ```
149
+
150
+ ### `pacs.routing`
151
+
152
+ ```javascript
153
+ pacs.routing.read() // → { hints: [], agents: [] }
154
+ pacs.routing.addHint(hint) // → updated routing
155
+ ```
156
+
157
+ ### `pacs.rules`
158
+
159
+ ```javascript
160
+ pacs.rules.read() // → { rules: [] }
161
+ pacs.rules.addRule(rule) // → updated rules
162
+ ```
163
+
164
+ ## File Structure
165
+
166
+ ```
167
+ pacs-core/
168
+ ├── package.json
169
+ ├── README.md
170
+ ├── LICENSE
171
+ └── src/
172
+ ├── index.js # Main entry point
173
+ ├── crypto.js # AES-256-GCM encryption
174
+ ├── memory-store.js # Encrypted storage layer
175
+ ├── trigger-parser.js # Command parsing
176
+ ├── triggers.json # Trigger definitions (plaintext)
177
+ ├── bootstrap.js # Setup script
178
+ └── test.js # Test suite
179
+
180
+ ~/.openclaw/pacs/ # Created by bootstrap
181
+ ├── memory.enc # Encrypted user facts
182
+ ├── routing.enc # Encrypted routing hints
183
+ ├── core-rules.enc # Encrypted AI rules
184
+ └── triggers/
185
+ └── triggers.json # Copy of trigger definitions
186
+ ```
187
+
188
+ ## Multi-Agent System
189
+
190
+ PACS Phase 2 adds an inter-agent communication bus and agent registry, enabling multi-agent workflows.
191
+
192
+ ### Agent Registry
193
+
194
+ Manages agent definitions with encrypted persistence.
195
+
196
+ ```javascript
197
+ const { AgentRegistry } = require('pacs-core');
198
+
199
+ // Register an agent
200
+ const agent = AgentRegistry.registerAgent('finance-agent', {
201
+ domain: 'finance',
202
+ capabilities: ['analysis', 'planning'],
203
+ description: 'Handles all financial analysis tasks'
204
+ });
205
+
206
+ // Get agent by name
207
+ const found = AgentRegistry.getAgent('finance-agent');
208
+
209
+ // List all agents
210
+ const all = AgentRegistry.listAgents();
211
+ const active = AgentRegistry.listAgents({ status: 'active' });
212
+
213
+ // Remove an agent
214
+ AgentRegistry.removeAgent('finance-agent');
215
+ ```
216
+
217
+ ### Inter-Agent Bus
218
+
219
+ Message passing between agents with encrypted message history.
220
+
221
+ ```javascript
222
+ const { InterAgentBus } = require('pacs-core');
223
+
224
+ // Send a message to a specific agent
225
+ InterAgentBus.emit('orchestrator', 'finance-agent', 'Analyze Q1 expenses');
226
+
227
+ // Broadcast to all agents
228
+ InterAgentBus.broadcast('orchestrator', 'System update: all agents report status');
229
+
230
+ // Request-response pattern (async)
231
+ const response = await InterAgentBus.request('orchestrator', 'finance-agent', {
232
+ task: 'calculate_budget',
233
+ params: { quarter: 'Q2' }
234
+ });
235
+
236
+ // Respond to a request
237
+ InterAgentBus.respond(requestId, 'finance-agent', { result: 45000 });
238
+
239
+ // Get messages for an agent
240
+ const msgs = InterAgentBus.getMessages('finance-agent', { limit: 50 });
241
+ ```
242
+
243
+ ### Agent Creator
244
+
245
+ Creates agents from natural language text or markdown definitions.
246
+
247
+ ```javascript
248
+ const { AgentCreator } = require('pacs-core');
249
+
250
+ // From natural language (German or English)
251
+ const agent = AgentCreator.createFromText(
252
+ 'Erstelle einen Agenten für Finanzen, der Analysen und Planung kann'
253
+ );
254
+
255
+ // From markdown definition
256
+ const agent2 = AgentCreator.createFromMD(`
257
+ ---
258
+ name: marketing-agent
259
+ domain: marketing
260
+ status: active
261
+ ---
262
+ This agent handles marketing campaigns, social media, and CRM.
263
+ `);
264
+ ```
265
+
266
+ ### Agent Object Schema
267
+
268
+ ```javascript
269
+ {
270
+ id: 'm1abc2def3', // Unique ID
271
+ name: 'finance-agent', // Unique name
272
+ domain: 'finance', // Domain category
273
+ capabilities: [], // List of capabilities
274
+ status: 'active', // 'active' | 'sleep'
275
+ lastActive: 'ISO8601', // Last activity timestamp
276
+ createdAt: 'ISO8601', // Creation timestamp
277
+ description: '', // Human-readable description
278
+ metadata: {} // Custom metadata
279
+ }
280
+ ```
281
+
282
+ ### Message Schema
283
+
284
+ ```javascript
285
+ {
286
+ id: 'msg_id',
287
+ from: 'orchestrator',
288
+ to: 'finance-agent', // or '*' for broadcast
289
+ type: 'message', // 'message' | 'request' | 'response'
290
+ payload: '...', // string or JSON string
291
+ timestamp: 'ISO8601',
292
+ inReplyTo: 'msg_id' // only for response type
293
+ }
294
+ ```
295
+
296
+ ### Storage
297
+
298
+ Agent definitions are stored in `~/.openclaw/pacs/agents.enc` and messages in `messages.enc`, both AES-256-GCM encrypted.
299
+
300
+ ## Routing Engine
301
+
302
+ Routes incoming user tasks to the correct agent(s) using capability matching and scoring.
303
+
304
+ ```javascript
305
+ const { RoutingEngine } = require('pacs-core');
306
+
307
+ // Route to best matching agents
308
+ const result = RoutingEngine.route('Organisiere meine Finanzen');
309
+ // → { task: 'Organisiere meine Finanzen', plan: [{ agent: 'finance', mode: 'parallel', score: 0.85 }], confidence: 0.85 }
310
+
311
+ // Get agents for parallel execution
312
+ const parallel = RoutingEngine.routeParallel('Analyze Q1 AND plan marketing campaign');
313
+
314
+ // Get agents for sequential execution
315
+ const sequential = RoutingEngine.routeSequential('Plan my week and send emails');
316
+
317
+ // Find who handles a topic
318
+ const handlers = RoutingEngine.whoHandles('Steuererklärung');
319
+ // → ['finance']
320
+ ```
321
+
322
+ **Special queries:**
323
+ - `"alle Agenten"` / `"alle agenten"` — returns all registered agents
324
+ - `"wer ist für X zuständig?"` — returns the best agent for topic X
325
+
326
+ **Scoring:** 0.0–1.0 based on domain keywords, capabilities, description match, and stored routing hints.
327
+
328
+ ## Learning Loop
329
+
330
+ Handles SAFE learning mode with "Soll ich mir das merken?" confirmation flow.
331
+
332
+ ```javascript
333
+ const { LearningLoop } = require('pacs-core');
334
+
335
+ // Check if a message should be remembered
336
+ const result = LearningLoop.shouldRemember('Ich spreche lieber Deutsch');
337
+ // → { should: true, reason: 'safe-detect', fact: 'Ich spreche lieber Deutsch' }
338
+
339
+ // Get the confirmation prompt in user's language
340
+ const prompt = LearningLoop.promptConfirmation('Ich spreche lieber Deutsch');
341
+ // → 'Soll ich mir das merken? "Ich spreche lieber Deutsch"'
342
+
343
+ // After user confirms, store the fact
344
+ LearningLoop.storeConfirmed('user123', 'Ich sprebe lieber Deutsch');
345
+
346
+ // If user rejects, mark as ignored
347
+ LearningLoop.rejectLearning('user123', 'some-fact');
348
+ ```
349
+
350
+ **Supported learn modes:**
351
+ - `safe` — AI asks before storing ("Soll ich mir das merken?") **default**
352
+ - `explicit` — Only store when explicitly commanded via `MERKE:`/`LEARN:`
353
+ - `auto` — Auto-store and confirm after the fact
354
+
355
+ ### Learn Mode Manager
356
+
357
+ ```javascript
358
+ const { LearnMode } = require('pacs-core');
359
+
360
+ LearnMode.getMode(); // → 'safe'
361
+ LearnMode.setMode('auto'); // → 'auto'
362
+ LearnMode.getModeDescription(); // → human-readable description
363
+ ```
364
+
365
+ Stored in `~/.openclaw/pacs/settings.enc`.
366
+
367
+ ## Phase 2 (Planned)
368
+
369
+ - [x] Agent routing engine with match scoring
370
+ - [x] Learning loop with confirmation prompts
371
+ - [x] OpenClaw integration bridge
372
+ - [x] CLI tool for management
373
+ - Export/import functionality
374
+
375
+ ---
376
+
377
+ ## OpenClaw Bridge
378
+
379
+ The OpenClaw Bridge integrates PACS into the OpenClaw agent framework.
380
+
381
+ ```javascript
382
+ const { OpenClawBridge } = require('pacs-core');
383
+
384
+ // Initialize with OpenClaw config
385
+ const result = OpenClawBridge.init({
386
+ pacs: {
387
+ enabled: true,
388
+ mode: 'integrated' // 'integrated' | 'standalone'
389
+ }
390
+ }, openClawAgentApi); // optional OpenClaw agent API for fallback
391
+ ```
392
+
393
+ ### Modes
394
+
395
+ | Mode | Description |
396
+ |------|-------------|
397
+ | `integrated` | PACS and OpenClaw agents coexist. PACS processes messages first; falls back to OpenClaw agents if no PACS handler matches. |
398
+ | `standalone` | PACS runs independently. OpenClaw is used only as the UI layer. |
399
+
400
+ ### API
401
+
402
+ ```javascript
403
+ // Process a user message through PACS
404
+ const result = await OpenClawBridge.query(userMessage);
405
+ // → { response, routedTo, fallback }
406
+
407
+ // Check if a message is a PACS command
408
+ const isPACS = OpenClawBridge.isPACSQuery('MERKE: Ich spreche Deutsch');
409
+ // → true
410
+
411
+ // Check bridge status
412
+ const status = OpenClawBridge.status();
413
+ // → { initialized, mode, enabled, openClawConnected }
414
+ ```
415
+
416
+ ### How Routing Works
417
+
418
+ 1. `isPACSQuery()` checks for PACS keywords (MERKE, SUCHE, LERNE, AGENT, ROUTING, REGELN, MEMORY) or trigger patterns
419
+ 2. If matched: PACS handles it → routes to memory, agent registry, or learn mode
420
+ 3. If not matched in `integrated` mode → delegates to OpenClaw agents via `fallbackToOpenClawAgents()`
421
+ 4. If not matched in `standalone` mode → returns "no handler found" response
422
+
423
+ ---
424
+
425
+ ## CLI Reference
426
+
427
+ PACS includes a full command-line interface for managing agents, memory, and settings.
428
+
429
+ ### Installation
430
+
431
+ ```bash
432
+ npm install # install dependencies
433
+ npm link # make `pacs` command available globally
434
+ ```
435
+
436
+ Or run directly:
437
+ ```bash
438
+ node src/cli.js <command>
439
+ ```
440
+
441
+ ### Commands
442
+
443
+ #### `pacs --help`
444
+ Show all available commands.
445
+
446
+ #### `pacs init`
447
+ Initialize the PACS storage directory (`~/.openclaw/pacs/`).
448
+
449
+ ```bash
450
+ pacs init
451
+ ```
452
+
453
+ #### `pacs status`
454
+ Show PACS system status.
455
+
456
+ ```bash
457
+ pacs status
458
+ # === PACS Status ===
459
+ # Bridge initialisiert : ja/nein
460
+ # Bridge Mode : integrated/standalone
461
+ # Agenten registriert : 3
462
+ # Memory Facts : 12
463
+ ```
464
+
465
+ #### `pacs agents list`
466
+ List all registered agents.
467
+
468
+ ```bash
469
+ pacs agents list
470
+ ```
471
+
472
+ #### `pacs agents add <name>`
473
+ Register a new agent.
474
+
475
+ ```bash
476
+ pacs agents add finbot --text "Finance and invoicing agent"
477
+ pacs agents add devbot --md ./agent-definition.md
478
+ ```
479
+
480
+ #### `pacs agents remove <name>`
481
+ Remove an agent by name.
482
+
483
+ ```bash
484
+ pacs agents remove finbot
485
+ ```
486
+
487
+ #### `pacs agents get <name>`
488
+ Show full details for a specific agent.
489
+
490
+ ```bash
491
+ pacs agents get finbot
492
+ ```
493
+
494
+ #### `pacs memory list`
495
+ List all stored memory facts.
496
+
497
+ ```bash
498
+ pacs memory list
499
+ ```
500
+
501
+ #### `pacs memory search <query>`
502
+ Search memory facts.
503
+
504
+ ```bash
505
+ pacs memory search "preferences"
506
+ ```
507
+
508
+ #### `pacs memory add "<fact>"`
509
+ Add a new memory fact.
510
+
511
+ ```bash
512
+ pacs memory add "Lech prefers German in the morning"
513
+ ```
514
+
515
+ #### `pacs memory forget "<fact>"`
516
+ Remove a memory fact by content match.
517
+
518
+ ```bash
519
+ pacs memory forget "Lech prefers German in the morning"
520
+ ```
521
+
522
+ #### `pacs learn-mode get`
523
+ Show the current learn mode.
524
+
525
+ ```bash
526
+ pacs learn-mode get
527
+ # Learn-Mode: safe
528
+ ```
529
+
530
+ #### `pacs learn-mode set <mode>`
531
+ Set the learn mode.
532
+
533
+ ```bash
534
+ pacs learn-mode set explicit
535
+ # Valid modes: safe | explicit | auto
536
+ ```
537
+
538
+ #### `pacs messages <agent>`
539
+ Show message history for an agent.
540
+
541
+ ```bash
542
+ pacs messages finbot
543
+ ```
544
+
545
+ ### Environment Variables
546
+
547
+ | Variable | Required | Description |
548
+ |----------|----------|-------------|
549
+ | `PACS_ENCRYPTION_KEY` | Yes | 256-bit encryption key (required for all encrypted operations) |
550
+
551
+ Generate a key:
552
+ ```bash
553
+ openssl rand -hex 32
554
+ ```
555
+
556
+ Set permanently (Linux/macOS):
557
+ ```bash
558
+ echo 'export PACS_ENCRYPTION_KEY=$(openssl rand -hex 32)' >> ~/.bashrc
559
+ ```
560
+
561
+ Set permanently (Windows PowerShell):
562
+ ```powershell
563
+ [System.Environment]::SetEnvironmentVariable("PACS_ENCRYPTION_KEY", $(openssl rand -hex 32), "User")
564
+ ```
565
+
566
+ ### File Structure
567
+
568
+ ```
569
+ pacs-core/
570
+ ├── bin/
571
+ │ └── pacs-cli.js # CLI executable entry point
572
+ ├── src/
573
+ │ ├── index.js # Main entry point + all exports
574
+ │ ├── cli.js # CLI implementation
575
+ │ ├── openclaw-bridge.cjs # OpenClaw integration
576
+ │ ├── agent-registry.js # Agent management
577
+ │ ├── memory-store.js # Encrypted storage
578
+ │ ├── crypto.js # AES-256-GCM
579
+ │ ├── trigger-parser.js # Command parsing
580
+ │ ├── routing-engine.js # Task routing
581
+ │ ├── learn-mode.js # Learn mode settings
582
+ │ ├── learning-loop.js # Learning confirmation flow
583
+ │ ├── inter-agent-bus.js # Agent messaging
584
+ │ └── agent-creator.js # Agent creation
585
+ └── package.json # "bin": { "pacs": "./bin/pacs-cli.js" }
586
+
587
+ ~/.openclaw/pacs/ # Created at runtime
588
+ ├── memory.enc # Encrypted user facts
589
+ ├── routing.enc # Encrypted routing hints
590
+ ├── core-rules.enc # Encrypted AI rules
591
+ ├── agents.enc # Encrypted agent registry
592
+ ├── settings.enc # Encrypted settings (learn mode)
593
+ └── messages.enc # Encrypted inter-agent messages
594
+ ```
595
+
596
+ ## License
597
+
598
+ MIT — see [LICENSE](LICENSE)
599
+
600
+ ## Contributing
601
+
602
+ Contributions welcome. Open an issue first for major changes.
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PACS CLI — Executable entry point
4
+ * Usage: pacs <command>
5
+ */
6
+
7
+ require('../src/cli.js');
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "pacs-core",
3
+ "version": "0.1.0",
4
+ "description": "PACS — Personal AI Control System. Encrypted memory, routing, and learn mode for AI assistants.",
5
+
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "pacs": "./bin/pacs-cli.js"
9
+ },
10
+ "scripts": {
11
+ "bootstrap": "node src/bootstrap.js",
12
+ "test": "node src/test.js"
13
+ },
14
+ "keywords": [
15
+ "ai",
16
+ "memory",
17
+ "encrypted",
18
+ "personal-ai",
19
+ "pacs",
20
+ "agent",
21
+ "openclaw"
22
+ ],
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/yourusername/pacs-core"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ }
31
+ }