shabti 2.10.0 → 2.11.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/README.md CHANGED
@@ -60,6 +60,7 @@ shabti status
60
60
  | ----------------- | ----------------------------------- |
61
61
  | `store <content>` | Store a memory entry |
62
62
  | `search <query>` | Search memory entries |
63
+ | `get <id>` | Retrieve a memory entry by ID |
63
64
  | `delete <id>` | Delete a memory entry by ID |
64
65
  | `status` | Show engine status |
65
66
  | `export` | Export memories as JSONL |
@@ -92,6 +93,13 @@ shabti search "recent events" --min-score 0.5
92
93
  shabti search "query" --json # JSON output
93
94
  ```
94
95
 
96
+ ### get
97
+
98
+ ```bash
99
+ shabti get <uuid>
100
+ shabti get <uuid> --json
101
+ ```
102
+
95
103
  ### delete
96
104
 
97
105
  ```bash
@@ -247,6 +255,10 @@ Discoverable at `GET /.well-known/agent-card.json`.
247
255
  | `tasks/get` | Retrieve task status and results |
248
256
  | `tasks/cancel` | Cancel a running task |
249
257
 
258
+ ### CORS
259
+
260
+ The A2A server sets `Access-Control-Allow-Origin: *` to allow requests from any origin. This is intentional for local development and inter-agent communication where the caller's origin is not known in advance. For production deployments behind a reverse proxy, restrict the origin at the proxy level.
261
+
250
262
  ## Node.js API
251
263
 
252
264
  ```javascript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shabti",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "Agent Memory OS — semantic memory for AI agents",
5
5
  "type": "module",
6
6
  "main": "native.cjs",
@@ -77,6 +77,7 @@
77
77
  "@commitlint/config-conventional": "^20.4.1",
78
78
  "@eslint/js": "^10.0.1",
79
79
  "@napi-rs/cli": "^3.5.1",
80
+ "@semantic-release/changelog": "^6.0.3",
80
81
  "@vitest/coverage-v8": "^4.0.18",
81
82
  "eslint": "^10.0.0",
82
83
  "eslint-config-prettier": "^10.1.8",
package/src/a2a/server.js CHANGED
@@ -3,6 +3,7 @@ import { randomUUID } from "crypto";
3
3
  import { buildAgentCard } from "./agentCard.js";
4
4
  import { createEngine } from "../core/engine.js";
5
5
  import { logger } from "../utils/logger.js";
6
+ import { normalizeText } from "../utils/normalize.js";
6
7
 
7
8
  // ============================================================
8
9
  // Task Store (in-memory)
@@ -62,7 +63,7 @@ async function handleMemoryStore(engine, parts) {
62
63
  throw Object.assign(new Error("Missing content in message parts"), { code: -32602 });
63
64
  }
64
65
 
65
- const result = await engine.store(content, opts);
66
+ const result = await engine.store(normalizeText(content), opts);
66
67
  return {
67
68
  artifactId: randomUUID(),
68
69
  name: "store_result",
@@ -87,7 +88,7 @@ async function handleMemorySearch(engine, parts) {
87
88
  throw Object.assign(new Error("Missing query in message parts"), { code: -32602 });
88
89
  }
89
90
 
90
- const results = await engine.executeQuery({ text: query, limit });
91
+ const results = await engine.executeQuery({ text: normalizeText(query), limit });
91
92
  const formatted = results.map((r) => ({
92
93
  id: r.id,
93
94
  content: r.content,
@@ -0,0 +1,42 @@
1
+ import chalk from "chalk";
2
+ import { createEngine } from "../core/engine.js";
3
+ import { error, heading } from "../utils/style.js";
4
+
5
+ export function registerGet(program) {
6
+ program
7
+ .command("get")
8
+ .description("Retrieve a memory entry by ID")
9
+ .argument("<id>", "UUID of the memory entry to retrieve")
10
+ .option("-j, --json", "Output as JSON")
11
+ .action(async (id, opts) => {
12
+ try {
13
+ const engine = createEngine();
14
+ const entry = await engine.get(id);
15
+
16
+ if (opts.json) {
17
+ console.log(JSON.stringify(entry, null, 2));
18
+ } else {
19
+ heading(`Memory Entry`);
20
+ console.log();
21
+ console.log(` ${chalk.cyan("ID:")} ${entry.id}`);
22
+ console.log(` ${chalk.cyan("Content:")} ${entry.content}`);
23
+ console.log(` ${chalk.cyan("Namespace:")} ${entry.namespace}`);
24
+ console.log(` ${chalk.cyan("Score:")} ${entry.score}`);
25
+ console.log(
26
+ ` ${chalk.cyan("Created:")} ${new Date(entry.createdAt * 1000).toISOString()}`,
27
+ );
28
+ if (entry.expiresAt) {
29
+ console.log(
30
+ ` ${chalk.cyan("Expires:")} ${new Date(entry.expiresAt * 1000).toISOString()}`,
31
+ );
32
+ }
33
+ console.log();
34
+ }
35
+
36
+ await engine.shutdown();
37
+ } catch (err) {
38
+ error(err.message);
39
+ process.exitCode = 1;
40
+ }
41
+ });
42
+ }
package/src/index.js CHANGED
@@ -16,6 +16,7 @@ import { registerExport } from "./commands/export.js";
16
16
  import { registerImport } from "./commands/import.js";
17
17
  import { registerStore } from "./commands/store.js";
18
18
  import { registerDelete } from "./commands/delete.js";
19
+ import { registerGet } from "./commands/get.js";
19
20
  import { registerHealth } from "./commands/health.js";
20
21
 
21
22
  const { version } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
@@ -87,6 +88,7 @@ function buildProgram() {
87
88
  registerImport(program);
88
89
  registerStore(program);
89
90
  registerDelete(program);
91
+ registerGet(program);
90
92
  registerHealth(program);
91
93
 
92
94
  program