@absolutejs/agent-memory 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 AbsoluteJS
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,12 @@
1
+ # @absolutejs/agent-memory
2
+
3
+ Durable, provider-neutral memory for agents with tenant/user/agent/run scopes,
4
+ mandatory provenance digests, taint-compatible metadata, per-operation policy,
5
+ expiration, deletion, subject erasure, optimistic versions, and idempotent writes.
6
+
7
+ Values pass through an injected codec so production deployments can use KMS or
8
+ envelope encryption. Retrieval indexes are adapters: pgvector, a vector service,
9
+ or custom search can rank IDs without becoming the source of record. Retrieved
10
+ records remain labeled memory data; this package never promotes them to trusted
11
+ instructions. Use `validateWrite` with `@absolutejs/agent-trust` to reject poisoned
12
+ or inappropriately sensitive memories before persistence.
@@ -0,0 +1,4 @@
1
+ export * from "./types";
2
+ export * from "./memory-store";
3
+ export * from "./postgres";
4
+ export * from "./service";
package/dist/index.js ADDED
@@ -0,0 +1,235 @@
1
+ // @bun
2
+ // src/memory-store.ts
3
+ var scopeKey = (scope) => JSON.stringify([
4
+ scope.tenantId,
5
+ scope.namespace,
6
+ scope.userId ?? "",
7
+ scope.agentId ?? "",
8
+ scope.runId ?? ""
9
+ ]);
10
+ var createMemoryAgentMemoryStore = () => {
11
+ const rows = new Map;
12
+ const requests = new Map;
13
+ const keyOf = (scope, key) => `${scopeKey(scope)}:${key}`;
14
+ return {
15
+ put: async ({ record, requestId, expectedVersion }) => {
16
+ const previousId = requests.get(requestId);
17
+ if (previousId)
18
+ return structuredClone([...rows.values()].find((row) => row.id === previousId));
19
+ const key = keyOf(record.scope, record.key);
20
+ const existing = rows.get(key);
21
+ if (expectedVersion !== undefined && existing?.version !== expectedVersion)
22
+ throw new Error("Agent memory version conflict");
23
+ if (existing && expectedVersion === undefined)
24
+ throw new Error("expectedVersion is required to replace memory");
25
+ rows.set(key, structuredClone(record));
26
+ requests.set(requestId, record.id);
27
+ return structuredClone(record);
28
+ },
29
+ get: async (scope, key) => structuredClone(rows.get(keyOf(scope, key))),
30
+ getByIds: async (ids) => [...rows.values()].filter((row) => ids.includes(row.id)).map((row) => structuredClone(row)),
31
+ list: async (scope, limit) => [...rows.values()].filter((row) => scopeKey(row.scope) === scopeKey(scope)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt)).slice(0, limit).map((row) => structuredClone(row)),
32
+ delete: async (scope, key) => rows.delete(keyOf(scope, key)),
33
+ eraseSubject: async ({ tenantId, userId }) => {
34
+ const matched = [...rows].filter(([, row]) => row.scope.tenantId === tenantId && (row.scope.userId === userId || row.createdBy.userId === userId));
35
+ for (const [key] of matched)
36
+ rows.delete(key);
37
+ return matched.length;
38
+ },
39
+ prune: async (now, limit) => {
40
+ const matched = [...rows].filter(([, row]) => row.expiresAt && row.expiresAt <= now).slice(0, limit);
41
+ for (const [key] of matched)
42
+ rows.delete(key);
43
+ return matched.length;
44
+ }
45
+ };
46
+ };
47
+ // src/postgres.ts
48
+ var safe = (value) => {
49
+ if (!/^[a-z_][a-z0-9_]*$/i.test(value))
50
+ throw new Error("Invalid SQL namespace");
51
+ return value;
52
+ };
53
+ var agentMemoryPostgresSchemaSql = (schema = "agent_memory") => {
54
+ const ns = safe(schema);
55
+ return `CREATE SCHEMA IF NOT EXISTS ${ns}; CREATE TABLE IF NOT EXISTS ${ns}.records (id text PRIMARY KEY, tenant_id text NOT NULL, namespace text NOT NULL, user_id text NOT NULL DEFAULT '', agent_id text NOT NULL DEFAULT '', run_id text NOT NULL DEFAULT '', memory_key text NOT NULL, version integer NOT NULL, expires_at timestamptz, document jsonb NOT NULL, updated_at timestamptz NOT NULL, UNIQUE (tenant_id,namespace,user_id,agent_id,run_id,memory_key)); CREATE INDEX IF NOT EXISTS agent_memory_expiry_idx ON ${ns}.records (expires_at) WHERE expires_at IS NOT NULL; CREATE INDEX IF NOT EXISTS agent_memory_subject_idx ON ${ns}.records (tenant_id,user_id); CREATE TABLE IF NOT EXISTS ${ns}.requests (request_id text PRIMARY KEY, record_id text NOT NULL REFERENCES ${ns}.records(id) ON DELETE CASCADE, created_at timestamptz NOT NULL DEFAULT now());`;
56
+ };
57
+ var parts = (scope) => [
58
+ scope.tenantId,
59
+ scope.namespace,
60
+ scope.userId ?? "",
61
+ scope.agentId ?? "",
62
+ scope.runId ?? ""
63
+ ];
64
+ var createPostgresAgentMemoryStore = ({
65
+ client,
66
+ schema = "agent_memory"
67
+ }) => {
68
+ const ns = safe(schema);
69
+ const document = (row) => row ? typeof row.document === "string" ? JSON.parse(row.document) : row.document : undefined;
70
+ return {
71
+ put: ({ record, requestId, expectedVersion }) => client.transaction(async (tx) => {
72
+ await tx.query(`SELECT pg_advisory_xact_lock(hashtextextended($1,0))`, [
73
+ requestId
74
+ ]);
75
+ const prior = document((await tx.query(`SELECT r.document FROM ${ns}.requests q JOIN ${ns}.records r ON r.id=q.record_id WHERE q.request_id=$1`, [requestId])).rows[0]);
76
+ if (prior)
77
+ return prior;
78
+ const values = [...parts(record.scope), record.key];
79
+ const result = expectedVersion === undefined ? await tx.query(`INSERT INTO ${ns}.records (id,tenant_id,namespace,user_id,agent_id,run_id,memory_key,version,expires_at,document,updated_at) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9::timestamptz,$10::jsonb,$11::timestamptz) RETURNING document`, [
80
+ record.id,
81
+ ...values,
82
+ record.version,
83
+ record.expiresAt ?? null,
84
+ JSON.stringify(record),
85
+ record.updatedAt
86
+ ]) : await tx.query(`UPDATE ${ns}.records SET version=$8,expires_at=$9::timestamptz,document=$10::jsonb,updated_at=$11::timestamptz WHERE tenant_id=$1 AND namespace=$2 AND user_id=$3 AND agent_id=$4 AND run_id=$5 AND memory_key=$6 AND version=$7 RETURNING document`, [
87
+ ...values,
88
+ expectedVersion,
89
+ record.version,
90
+ record.expiresAt ?? null,
91
+ JSON.stringify(record),
92
+ record.updatedAt
93
+ ]);
94
+ const saved = document(result.rows[0]);
95
+ if (!saved)
96
+ throw new Error("Agent memory version conflict");
97
+ await tx.query(`INSERT INTO ${ns}.requests (request_id,record_id) VALUES ($1,$2)`, [requestId, saved.id]);
98
+ return saved;
99
+ }),
100
+ get: async (scope, key) => document((await client.query(`SELECT document FROM ${ns}.records WHERE tenant_id=$1 AND namespace=$2 AND user_id=$3 AND agent_id=$4 AND run_id=$5 AND memory_key=$6`, [...parts(scope), key])).rows[0]),
101
+ getByIds: async (ids) => ids.length ? (await client.query(`SELECT document FROM ${ns}.records WHERE id = ANY($1::text[])`, [ids])).rows.map((row) => document(row)) : [],
102
+ list: async (scope, limit) => (await client.query(`SELECT document FROM ${ns}.records WHERE tenant_id=$1 AND namespace=$2 AND user_id=$3 AND agent_id=$4 AND run_id=$5 ORDER BY updated_at DESC LIMIT $6`, [...parts(scope), limit])).rows.map((row) => document(row)),
103
+ delete: async (scope, key) => (await client.query(`DELETE FROM ${ns}.records WHERE tenant_id=$1 AND namespace=$2 AND user_id=$3 AND agent_id=$4 AND run_id=$5 AND memory_key=$6 RETURNING id`, [...parts(scope), key])).rows.length === 1,
104
+ eraseSubject: async ({ tenantId, userId }) => (await client.query(`DELETE FROM ${ns}.records WHERE tenant_id=$1 AND (user_id=$2 OR document->'createdBy'->>'userId'=$2) RETURNING id`, [tenantId, userId])).rows.length,
105
+ prune: async (now, limit) => (await client.query(`DELETE FROM ${ns}.records WHERE id IN (SELECT id FROM ${ns}.records WHERE expires_at <= $1::timestamptz ORDER BY expires_at LIMIT $2 FOR UPDATE SKIP LOCKED) RETURNING id`, [now, limit])).rows.length
106
+ };
107
+ };
108
+ // src/service.ts
109
+ var identityCodec = {
110
+ encode: async (value) => structuredClone(value),
111
+ decode: async (value) => structuredClone(value)
112
+ };
113
+ var assertScope = (actor, scope) => {
114
+ if (actor.tenantId !== scope.tenantId)
115
+ throw new Error("Cross-tenant agent memory access denied");
116
+ };
117
+ var createAgentMemory = ({
118
+ store,
119
+ authorize,
120
+ codec = identityCodec,
121
+ index,
122
+ validateWrite,
123
+ now = Date.now,
124
+ id = () => crypto.randomUUID()
125
+ }) => {
126
+ const decode = async (stored) => ({
127
+ ...stored,
128
+ value: await codec.decode(stored.encodedValue, {
129
+ scope: stored.scope,
130
+ key: stored.key
131
+ })
132
+ });
133
+ const permitted = async (operation, actor, scope, record) => {
134
+ assertScope(actor, scope);
135
+ if (!await authorize({
136
+ operation,
137
+ actor,
138
+ scope,
139
+ ...record ? { record } : {}
140
+ }))
141
+ throw new Error(`Agent memory ${operation} denied`);
142
+ };
143
+ return {
144
+ put: async (input) => {
145
+ await permitted("write", input.actor, input.scope);
146
+ if (!input.provenance.digest)
147
+ throw new Error("Memory provenance digest is required");
148
+ if (input.expiresAt && !Number.isFinite(Date.parse(input.expiresAt)))
149
+ throw new Error("Invalid memory expiration");
150
+ const existing = await store.get(input.scope, input.key);
151
+ const timestamp = new Date(now()).toISOString();
152
+ const record = {
153
+ id: existing?.id ?? id(),
154
+ key: input.key,
155
+ scope: structuredClone(input.scope),
156
+ value: structuredClone(input.value),
157
+ provenance: structuredClone(input.provenance),
158
+ sensitivity: input.sensitivity ?? "internal",
159
+ version: (existing?.version ?? 0) + 1,
160
+ createdAt: existing?.createdAt ?? timestamp,
161
+ updatedAt: timestamp,
162
+ ...input.expiresAt ? { expiresAt: input.expiresAt } : {},
163
+ createdBy: structuredClone(input.actor)
164
+ };
165
+ if (validateWrite && !await validateWrite(record))
166
+ throw new Error("Agent memory write failed trust validation");
167
+ const stored = {
168
+ ...record,
169
+ encodedValue: await codec.encode(record.value, {
170
+ scope: record.scope,
171
+ key: record.key
172
+ })
173
+ };
174
+ delete stored.value;
175
+ const saved = await store.put({
176
+ record: stored,
177
+ requestId: input.requestId,
178
+ ...input.expectedVersion !== undefined ? { expectedVersion: input.expectedVersion } : {}
179
+ });
180
+ const decoded = await decode(saved);
181
+ await index?.upsert(decoded);
182
+ return decoded;
183
+ },
184
+ get: async (actor, scope, key) => {
185
+ await permitted("read", actor, scope);
186
+ const stored = await store.get(scope, key);
187
+ if (!stored || stored.expiresAt && stored.expiresAt <= new Date(now()).toISOString())
188
+ return;
189
+ const record = await decode(stored);
190
+ await permitted("read", actor, scope, record);
191
+ return record;
192
+ },
193
+ search: async (actor, scope, query, limit = 10) => {
194
+ await permitted("search", actor, scope);
195
+ const ranked = index ? await index.search({ scope, query, limit }) : (await store.list(scope, Math.min(limit, 100))).map((row, position) => ({ id: row.id, score: 1 / (position + 1) }));
196
+ const rows = await store.getByIds(ranked.map((item) => item.id));
197
+ const byId = new Map(rows.map((row) => [row.id, row]));
198
+ const output = [];
199
+ for (const item of ranked) {
200
+ const row = byId.get(item.id);
201
+ if (!row || row.expiresAt && row.expiresAt <= new Date(now()).toISOString())
202
+ continue;
203
+ const record = await decode(row);
204
+ await permitted("read", actor, scope, record);
205
+ output.push({ record, score: item.score });
206
+ }
207
+ return output;
208
+ },
209
+ delete: async (actor, scope, key) => {
210
+ await permitted("delete", actor, scope);
211
+ const row = await store.get(scope, key);
212
+ const removed = await store.delete(scope, key);
213
+ if (removed && row)
214
+ await index?.remove(row.id);
215
+ return removed;
216
+ },
217
+ eraseSubject: async (actor, userId) => {
218
+ const scope = { tenantId: actor.tenantId, namespace: "*", userId };
219
+ await permitted("erase", actor, scope);
220
+ const count = await store.eraseSubject({
221
+ tenantId: actor.tenantId,
222
+ userId
223
+ });
224
+ await index?.eraseSubject?.({ tenantId: actor.tenantId, userId });
225
+ return count;
226
+ },
227
+ prune: (limit = 1000) => store.prune(new Date(now()).toISOString(), limit)
228
+ };
229
+ };
230
+ export {
231
+ createPostgresAgentMemoryStore,
232
+ createMemoryAgentMemoryStore,
233
+ createAgentMemory,
234
+ agentMemoryPostgresSchemaSql
235
+ };
@@ -0,0 +1 @@
1
+ export declare const manifest: import("@absolutejs/manifest").PackageManifest<unknown, never>;
@@ -0,0 +1,23 @@
1
+ // @bun
2
+ // src/manifest.ts
3
+ import { defineManifest } from "@absolutejs/manifest";
4
+ import { Type } from "@sinclair/typebox";
5
+ var manifest = defineManifest()({
6
+ contract: 2,
7
+ identity: {
8
+ name: "@absolutejs/agent-memory",
9
+ category: "data",
10
+ tagline: "Give agents useful memory without giving memory authority.",
11
+ description: "Scoped durable provenance-aware agent memory with per-operation authorization, retention, subject erasure, encrypted codecs, trust validation, and pluggable retrieval indexes.",
12
+ docsUrl: "https://github.com/absolutejs/agent-memory",
13
+ accent: "#8b5cf6"
14
+ },
15
+ settings: Type.Object({}),
16
+ slots: {},
17
+ implements: [],
18
+ tools: {},
19
+ wiring: []
20
+ });
21
+ export {
22
+ manifest
23
+ };
@@ -0,0 +1,19 @@
1
+ {
2
+ "contract": 2,
3
+ "identity": {
4
+ "name": "@absolutejs/agent-memory",
5
+ "category": "data",
6
+ "tagline": "Give agents useful memory without giving memory authority.",
7
+ "description": "Scoped durable provenance-aware agent memory with per-operation authorization, retention, subject erasure, encrypted codecs, trust validation, and pluggable retrieval indexes.",
8
+ "docsUrl": "https://github.com/absolutejs/agent-memory",
9
+ "accent": "#8b5cf6"
10
+ },
11
+ "settings": {
12
+ "type": "object",
13
+ "properties": {}
14
+ },
15
+ "slots": {},
16
+ "implements": [],
17
+ "wiring": [],
18
+ "tools": {}
19
+ }
@@ -0,0 +1,2 @@
1
+ import type { AgentMemoryStore } from "./types";
2
+ export declare const createMemoryAgentMemoryStore: () => AgentMemoryStore;
@@ -0,0 +1,15 @@
1
+ import type { AgentMemoryStore } from "./types";
2
+ export type AgentMemorySqlResult<Row> = {
3
+ rows: Row[];
4
+ };
5
+ export type AgentMemorySqlTransaction = {
6
+ query<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<AgentMemorySqlResult<Row>>;
7
+ };
8
+ export type AgentMemorySqlClient = AgentMemorySqlTransaction & {
9
+ transaction<Value>(work: (tx: AgentMemorySqlTransaction) => Promise<Value>): Promise<Value>;
10
+ };
11
+ export declare const agentMemoryPostgresSchemaSql: (schema?: string) => string;
12
+ export declare const createPostgresAgentMemoryStore: ({ client, schema, }: {
13
+ client: AgentMemorySqlClient;
14
+ schema?: string;
15
+ }) => AgentMemoryStore;
@@ -0,0 +1,30 @@
1
+ import type { AgentMemoryActor, AgentMemoryAuthorizer, AgentMemoryCodec, AgentMemoryProvenance, AgentMemoryRecord, AgentMemoryScope, AgentMemorySearchIndex, AgentMemoryStore } from "./types";
2
+ export declare const createAgentMemory: ({ store, authorize, codec, index, validateWrite, now, id, }: {
3
+ store: AgentMemoryStore;
4
+ authorize: AgentMemoryAuthorizer;
5
+ codec?: AgentMemoryCodec;
6
+ index?: AgentMemorySearchIndex;
7
+ validateWrite?: (record: AgentMemoryRecord) => boolean | Promise<boolean>;
8
+ now?: () => number;
9
+ id?: () => string;
10
+ }) => {
11
+ put: (input: {
12
+ actor: AgentMemoryActor;
13
+ scope: AgentMemoryScope;
14
+ key: string;
15
+ value: unknown;
16
+ provenance: AgentMemoryProvenance;
17
+ sensitivity?: AgentMemoryRecord["sensitivity"];
18
+ expiresAt?: string;
19
+ requestId: string;
20
+ expectedVersion?: number;
21
+ }) => Promise<AgentMemoryRecord>;
22
+ get: (actor: AgentMemoryActor, scope: AgentMemoryScope, key: string) => Promise<AgentMemoryRecord | undefined>;
23
+ search: (actor: AgentMemoryActor, scope: AgentMemoryScope, query: string, limit?: number) => Promise<{
24
+ record: AgentMemoryRecord;
25
+ score: number;
26
+ }[]>;
27
+ delete: (actor: AgentMemoryActor, scope: AgentMemoryScope, key: string) => Promise<boolean>;
28
+ eraseSubject: (actor: AgentMemoryActor, userId: string) => Promise<number>;
29
+ prune: (limit?: number) => Promise<number>;
30
+ };
@@ -0,0 +1,87 @@
1
+ export type AgentMemoryScope = {
2
+ tenantId: string;
3
+ namespace: string;
4
+ userId?: string;
5
+ agentId?: string;
6
+ runId?: string;
7
+ };
8
+ export type AgentMemoryActor = {
9
+ tenantId: string;
10
+ userId: string;
11
+ agentId: string;
12
+ delegationId?: string;
13
+ };
14
+ export type AgentMemoryProvenance = {
15
+ source: string;
16
+ sourceType: "user" | "agent" | "tool" | "web" | "file" | "memory" | "system";
17
+ retrievedAt: string;
18
+ digest: string;
19
+ parentDigests?: string[];
20
+ proof?: unknown;
21
+ taints?: string[];
22
+ };
23
+ export type AgentMemoryRecord<Value = unknown> = {
24
+ id: string;
25
+ key: string;
26
+ scope: AgentMemoryScope;
27
+ value: Value;
28
+ provenance: AgentMemoryProvenance;
29
+ sensitivity: "public" | "internal" | "personal" | "secret";
30
+ version: number;
31
+ createdAt: string;
32
+ updatedAt: string;
33
+ expiresAt?: string;
34
+ createdBy: AgentMemoryActor;
35
+ };
36
+ export type StoredAgentMemoryRecord = Omit<AgentMemoryRecord, "value"> & {
37
+ encodedValue: unknown;
38
+ };
39
+ export type AgentMemoryOperation = "read" | "write" | "search" | "delete" | "erase";
40
+ export type AgentMemoryAuthorizer = (input: {
41
+ operation: AgentMemoryOperation;
42
+ actor: AgentMemoryActor;
43
+ scope: AgentMemoryScope;
44
+ record?: AgentMemoryRecord;
45
+ }) => boolean | Promise<boolean>;
46
+ export type AgentMemoryCodec = {
47
+ encode(value: unknown, context: {
48
+ scope: AgentMemoryScope;
49
+ key: string;
50
+ }): Promise<unknown>;
51
+ decode(value: unknown, context: {
52
+ scope: AgentMemoryScope;
53
+ key: string;
54
+ }): Promise<unknown>;
55
+ };
56
+ export type AgentMemoryStore = {
57
+ put(input: {
58
+ record: StoredAgentMemoryRecord;
59
+ requestId: string;
60
+ expectedVersion?: number;
61
+ }): Promise<StoredAgentMemoryRecord>;
62
+ get(scope: AgentMemoryScope, key: string): Promise<StoredAgentMemoryRecord | undefined>;
63
+ getByIds(ids: readonly string[]): Promise<StoredAgentMemoryRecord[]>;
64
+ list(scope: AgentMemoryScope, limit: number): Promise<StoredAgentMemoryRecord[]>;
65
+ delete(scope: AgentMemoryScope, key: string): Promise<boolean>;
66
+ eraseSubject(input: {
67
+ tenantId: string;
68
+ userId: string;
69
+ }): Promise<number>;
70
+ prune(now: string, limit: number): Promise<number>;
71
+ };
72
+ export type AgentMemorySearchIndex = {
73
+ upsert(record: AgentMemoryRecord): Promise<void>;
74
+ remove(id: string): Promise<void>;
75
+ search(input: {
76
+ scope: AgentMemoryScope;
77
+ query: string;
78
+ limit: number;
79
+ }): Promise<Array<{
80
+ id: string;
81
+ score: number;
82
+ }>>;
83
+ eraseSubject?(input: {
84
+ tenantId: string;
85
+ userId: string;
86
+ }): Promise<void>;
87
+ };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@absolutejs/agent-memory",
3
+ "version": "0.1.0",
4
+ "description": "Scoped durable provenance-aware memory with authorization, retention, erasure, encryption seams, and pluggable retrieval for AI agents.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/absolutejs/agent-memory.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "absolutejs": {
17
+ "manifestContract": 2
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ },
24
+ "./manifest": {
25
+ "types": "./dist/manifest.d.ts",
26
+ "import": "./dist/manifest.js"
27
+ },
28
+ "./manifest.json": "./dist/manifest.json"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "scripts": {
36
+ "format": "prettier --write \"./**/*.{ts,json,md,yml}\"",
37
+ "typecheck": "tsc --noEmit",
38
+ "test": "bun test",
39
+ "build": "rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --target=bun --external @absolutejs/manifest --external @sinclair/typebox && tsc -p tsconfig.build.json && absolute-manifest emit",
40
+ "check:package": "bun run typecheck && bun run test && bun run build"
41
+ },
42
+ "dependencies": {
43
+ "@absolutejs/manifest": "^0.2.0",
44
+ "@sinclair/typebox": "^0.34.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/bun": "^1.3.14",
48
+ "prettier": "3.5.3",
49
+ "typescript": "5.8.3"
50
+ }
51
+ }