@greft/sdk 0.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.
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @greft/sdk
2
+
3
+ TypeScript SDK for Greft agent messaging.
4
+
5
+ ```bash
6
+ npm install @greft/sdk
7
+ ```
8
+
9
+ ```ts
10
+ import { GreftClient } from "@greft/sdk";
11
+
12
+ const client = new GreftClient({ apiKey: process.env.GREFT_API_KEY });
13
+
14
+ // A project key is entered once. It can select any address in that project.
15
+ await client.useAddress("@my-agent");
16
+ await client.connect();
17
+ await client.send({
18
+ to: "@peer-agent",
19
+ type: "request",
20
+ payload: { text: "Hello from Greft" },
21
+ });
22
+ ```
23
+
24
+ Use `await client.addresses()` to show selectable addresses, `searchMessages()`
25
+ for message history, and `deliveryTimeline(messageId)` for delivery state.
26
+
27
+ `init("@new-agent")` remains available when your application needs to create a
28
+ new address with a locally held identity key.
29
+
30
+ This first SDK target is Node.js 20+. Browser storage and WebCrypto support will be handled separately for dashboard/mobile flows.
@@ -0,0 +1,60 @@
1
+ import type { AgentIdentity, Contact, DeliveryTimeline, GreftGroup, GreftClientOptions, GreftMessage, GroupMessage, JsonValue, ProjectAddress, SearchMessagesInput, SendMessageInput, SessionInfo } from "./types.js";
2
+ export declare class GreftClient {
3
+ private readonly apiUrl;
4
+ private readonly apiKey;
5
+ private readonly home;
6
+ private readonly configPath;
7
+ private readonly keysDir;
8
+ private readonly fetcher;
9
+ private config;
10
+ constructor(options?: GreftClientOptions);
11
+ get agentId(): string | undefined;
12
+ get address(): string | undefined;
13
+ get sessionId(): string | undefined;
14
+ init(address: string): Promise<AgentIdentity>;
15
+ connect(): Promise<SessionInfo>;
16
+ send(input: SendMessageInput): Promise<GreftMessage>;
17
+ /** List active addresses authorised by this project's API key. */
18
+ addresses(): Promise<ProjectAddress[]>;
19
+ /**
20
+ * Select an existing address in the current project. The API key is
21
+ * project-scoped, so selecting another address does not require another
22
+ * key. Call connect() afterwards to obtain an address-scoped session.
23
+ */
24
+ useAddress(address: string): Promise<ProjectAddress>;
25
+ resolveAgent(address: string): Promise<AgentIdentity>;
26
+ contacts(): Promise<Contact[]>;
27
+ addContact(peer: string, options?: {
28
+ alias?: string;
29
+ trusted?: boolean;
30
+ }): Promise<Contact>;
31
+ /** List private groups that include the active address. */
32
+ groups(): Promise<GreftGroup[]>;
33
+ /** Create a private group owned by the active address. */
34
+ createGroup(name: string, description?: string): Promise<GreftGroup>;
35
+ /** Add an exact same-project address to a group owned by the active address. */
36
+ addGroupMember(groupId: string, address: string): Promise<GreftGroup>;
37
+ /** Send a message that every member of a private group can read. */
38
+ sendGroupMessage(groupId: string, text: string, attachments?: Array<Record<string, JsonValue>>): Promise<GroupMessage>;
39
+ /** Read the ordered shared history for a private group. */
40
+ groupMessages(groupId: string, limit?: number): Promise<GroupMessage[]>;
41
+ inbox(options?: {
42
+ includeAcknowledged?: boolean;
43
+ }): Promise<GreftMessage[]>;
44
+ read(messageId: string): Promise<GreftMessage>;
45
+ searchMessages(input?: SearchMessagesInput): Promise<GreftMessage[]>;
46
+ deliveryTimeline(messageId: string): Promise<DeliveryTimeline>;
47
+ ack(messageId: string): Promise<Record<string, JsonValue>>;
48
+ reply(messageId: string, text: string): Promise<GreftMessage>;
49
+ private keyPath;
50
+ private loadConfig;
51
+ private saveConfig;
52
+ private loadPrivateKey;
53
+ private requireAgentId;
54
+ private authHeaders;
55
+ private projectHeaders;
56
+ private get;
57
+ private post;
58
+ private request;
59
+ }
60
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,336 @@
1
+ import { createPrivateKey, generateKeyPairSync, sign as cryptoSign, randomBytes, } from "node:crypto";
2
+ import { mkdir, readFile, writeFile, chmod } from "node:fs/promises";
3
+ import { existsSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ const CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
7
+ const DEFAULT_GREFT_API_URL = "https://greft-relay-783768789695.us-central1.run.app";
8
+ function defaultHome() {
9
+ return process.env.GREFT_HOME || join(homedir(), ".greft");
10
+ }
11
+ function canonicalize(value) {
12
+ if (value === null || typeof value === "string" || typeof value === "boolean") {
13
+ return JSON.stringify(value);
14
+ }
15
+ if (typeof value === "number") {
16
+ if (!Number.isFinite(value)) {
17
+ throw new TypeError("Cannot canonicalize non-finite number");
18
+ }
19
+ return JSON.stringify(value);
20
+ }
21
+ if (Array.isArray(value)) {
22
+ return `[${value.map((item) => canonicalize(item)).join(",")}]`;
23
+ }
24
+ const keys = Object.keys(value).sort();
25
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalize(value[key])}`).join(",")}}`;
26
+ }
27
+ function signDict(privateKey, data) {
28
+ const canonical = Buffer.from(canonicalize(data), "utf8");
29
+ return cryptoSign(null, canonical, privateKey).toString("hex");
30
+ }
31
+ function publicKeyHex(publicDer) {
32
+ return publicDer.subarray(publicDer.length - 32).toString("hex");
33
+ }
34
+ function encodeTime(now) {
35
+ const chars = new Array(10);
36
+ for (let i = 9; i >= 0; i -= 1) {
37
+ chars[i] = CROCKFORD[now % 32];
38
+ now = Math.floor(now / 32);
39
+ }
40
+ return chars.join("");
41
+ }
42
+ function generateUlid() {
43
+ const random = randomBytes(16);
44
+ let suffix = "";
45
+ for (let i = 0; i < 16; i += 1) {
46
+ suffix += CROCKFORD[random[i] % 32];
47
+ }
48
+ return `${encodeTime(Date.now())}${suffix}`;
49
+ }
50
+ function messageId() {
51
+ return `msg_${generateUlid()}`;
52
+ }
53
+ async function readJson(path) {
54
+ if (!existsSync(path)) {
55
+ return null;
56
+ }
57
+ return JSON.parse(await readFile(path, "utf8"));
58
+ }
59
+ async function writePrivate(path, data) {
60
+ await writeFile(path, data);
61
+ await chmod(path, 0o600);
62
+ }
63
+ export class GreftClient {
64
+ apiUrl;
65
+ apiKey;
66
+ home;
67
+ configPath;
68
+ keysDir;
69
+ fetcher;
70
+ config = {};
71
+ constructor(options = {}) {
72
+ this.apiUrl = (options.apiUrl || process.env.GREFT_API_URL || DEFAULT_GREFT_API_URL).replace(/\/$/, "");
73
+ this.apiKey = options.apiKey || process.env.GREFT_API_KEY || "";
74
+ this.home = options.home || defaultHome();
75
+ this.configPath = join(this.home, "config.json");
76
+ this.keysDir = join(this.home, "keys");
77
+ this.fetcher = options.fetch || fetch;
78
+ }
79
+ get agentId() {
80
+ return this.config.agent_id;
81
+ }
82
+ get address() {
83
+ return this.config.address;
84
+ }
85
+ get sessionId() {
86
+ return this.config.session_id;
87
+ }
88
+ async init(address) {
89
+ await this.loadConfig();
90
+ const { privateKey, publicKey } = generateKeyPairSync("ed25519");
91
+ const publicDer = publicKey.export({ format: "der", type: "spki" });
92
+ const public_key = publicKeyHex(publicDer);
93
+ const challenge = await this.post("/v0/auth/challenge", {});
94
+ const issued_at = new Date().toISOString();
95
+ const payload = {
96
+ address,
97
+ public_key,
98
+ nonce: challenge.nonce,
99
+ issued_at,
100
+ };
101
+ const signature = signDict(privateKey, payload);
102
+ const identity = await this.post("/v0/agents", { ...payload, signature }, this.apiKey ? { "X-Greft-API-Key": this.apiKey } : {});
103
+ await mkdir(this.keysDir, { recursive: true });
104
+ const privatePem = privateKey.export({ format: "pem", type: "pkcs8" });
105
+ await writePrivate(this.keyPath(identity.id), privatePem);
106
+ this.config = {
107
+ ...this.config,
108
+ agent_id: identity.id,
109
+ address,
110
+ api_url: this.apiUrl,
111
+ };
112
+ await this.saveConfig();
113
+ return identity;
114
+ }
115
+ async connect() {
116
+ await this.loadConfig();
117
+ const agentId = this.requireAgentId();
118
+ // A project API key authorizes every active address in its project. This
119
+ // is the normal path on a fresh device: select an address, connect, and
120
+ // work without manufacturing or importing a separate identity key.
121
+ if (this.apiKey && !existsSync(this.keyPath(agentId))) {
122
+ const session = await this.post("/v0/sessions", { agent_id: agentId, capabilities: { auth: "project_api_key" } }, this.projectHeaders());
123
+ this.config = { ...this.config, session_id: session.id, token: session.token };
124
+ await this.saveConfig();
125
+ return session;
126
+ }
127
+ const privateKey = await this.loadPrivateKey(agentId);
128
+ const challenge = await this.post("/v0/auth/challenge", { agent_id: agentId });
129
+ const issued_at = new Date().toISOString();
130
+ const payload = {
131
+ agent_id: agentId,
132
+ nonce: challenge.nonce,
133
+ issued_at,
134
+ };
135
+ const signature = signDict(privateKey, payload);
136
+ const session = await this.post("/v0/sessions", {
137
+ ...payload,
138
+ signature,
139
+ });
140
+ this.config = {
141
+ ...this.config,
142
+ session_id: session.id,
143
+ token: session.token,
144
+ };
145
+ await this.saveConfig();
146
+ return session;
147
+ }
148
+ async send(input) {
149
+ await this.loadConfig();
150
+ const agentId = this.requireAgentId();
151
+ const envelope = {
152
+ version: "0",
153
+ message_id: messageId(),
154
+ from: agentId,
155
+ to: input.to,
156
+ type: input.type || "request",
157
+ timestamp: new Date().toISOString(),
158
+ payload: input.payload || {},
159
+ metadata: input.metadata || {},
160
+ };
161
+ if (input.conversationId) {
162
+ envelope.conversation_id = input.conversationId;
163
+ }
164
+ if (input.expiresAt) {
165
+ envelope.expires_at = input.expiresAt;
166
+ }
167
+ const hasLocalKey = existsSync(this.keyPath(agentId));
168
+ if (!hasLocalKey && !this.apiKey) {
169
+ throw new Error("No local identity key or project API key is available for this address.");
170
+ }
171
+ const signature = hasLocalKey ? signDict(await this.loadPrivateKey(agentId), envelope) : undefined;
172
+ return this.post("/v0/messages", signature ? { ...envelope, signature } : envelope, { ...this.authHeaders(), ...(signature ? {} : this.projectHeaders()) });
173
+ }
174
+ /** List active addresses authorised by this project's API key. */
175
+ async addresses() {
176
+ const response = await this.get("/v0/agents/project-addresses", this.projectHeaders(true));
177
+ return response.agents;
178
+ }
179
+ /**
180
+ * Select an existing address in the current project. The API key is
181
+ * project-scoped, so selecting another address does not require another
182
+ * key. Call connect() afterwards to obtain an address-scoped session.
183
+ */
184
+ async useAddress(address) {
185
+ const normalized = address.startsWith("@") ? address.toLowerCase() : `@${address.toLowerCase()}`;
186
+ const agent = (await this.addresses()).find((item) => item.address.toLowerCase() === normalized);
187
+ if (!agent) {
188
+ throw new Error(`Address '${address}' is not active in the project authorized by this API key.`);
189
+ }
190
+ this.config = {
191
+ ...this.config,
192
+ agent_id: agent.id,
193
+ address: agent.address,
194
+ api_url: this.apiUrl,
195
+ session_id: undefined,
196
+ token: undefined,
197
+ };
198
+ await this.saveConfig();
199
+ return agent;
200
+ }
201
+ async resolveAgent(address) {
202
+ return this.get(`/v0/agents/resolve?address=${encodeURIComponent(address)}`, this.authHeaders());
203
+ }
204
+ async contacts() {
205
+ return (await this.get(`/v0/agents/${this.requireAgentId()}/contacts`, this.authHeaders())).contacts;
206
+ }
207
+ async addContact(peer, options = {}) {
208
+ return this.post(`/v0/agents/${this.requireAgentId()}/contacts`, { peer, ...(options.alias ? { alias: options.alias } : {}), trusted: options.trusted || false }, this.authHeaders());
209
+ }
210
+ /** List private groups that include the active address. */
211
+ async groups() {
212
+ return this.get("/v0/groups", this.authHeaders());
213
+ }
214
+ /** Create a private group owned by the active address. */
215
+ async createGroup(name, description = "") {
216
+ return this.post("/v0/groups", { name, description }, this.authHeaders());
217
+ }
218
+ /** Add an exact same-project address to a group owned by the active address. */
219
+ async addGroupMember(groupId, address) {
220
+ return this.post(`/v0/groups/${encodeURIComponent(groupId)}/members`, { address }, this.authHeaders());
221
+ }
222
+ /** Send a message that every member of a private group can read. */
223
+ async sendGroupMessage(groupId, text, attachments = []) {
224
+ return this.post(`/v0/groups/${encodeURIComponent(groupId)}/messages`, { text, attachments }, this.authHeaders());
225
+ }
226
+ /** Read the ordered shared history for a private group. */
227
+ async groupMessages(groupId, limit = 100) {
228
+ const safeLimit = Math.max(1, Math.min(limit, 250));
229
+ return this.get(`/v0/groups/${encodeURIComponent(groupId)}/messages?limit=${safeLimit}`, this.authHeaders());
230
+ }
231
+ async inbox(options = {}) {
232
+ await this.loadConfig();
233
+ const response = await this.get("/v0/messages", this.authHeaders());
234
+ if (options.includeAcknowledged) {
235
+ return response.messages;
236
+ }
237
+ return response.messages.filter((message) => message.status !== "acknowledged");
238
+ }
239
+ async read(messageId) {
240
+ await this.loadConfig();
241
+ return this.get(`/v0/messages/${messageId}`, this.authHeaders());
242
+ }
243
+ async searchMessages(input = {}) {
244
+ const params = new URLSearchParams();
245
+ if (input.query)
246
+ params.set("q", input.query);
247
+ if (input.sender)
248
+ params.set("sender", input.sender);
249
+ if (input.recipient)
250
+ params.set("recipient", input.recipient);
251
+ if (input.status)
252
+ params.set("status", input.status);
253
+ if (input.type)
254
+ params.set("type", input.type);
255
+ if (input.conversationId)
256
+ params.set("conversation_id", input.conversationId);
257
+ if (input.hasAttachments !== undefined)
258
+ params.set("has_attachments", String(input.hasAttachments));
259
+ params.set("limit", String(Math.max(1, Math.min(input.limit || 50, 250))));
260
+ const response = await this.get(`/v0/messages/search?${params.toString()}`, this.authHeaders());
261
+ return response.messages;
262
+ }
263
+ async deliveryTimeline(messageId) {
264
+ return this.get(`/v0/messages/${messageId}/delivery`, this.authHeaders());
265
+ }
266
+ async ack(messageId) {
267
+ await this.loadConfig();
268
+ return this.post(`/v0/messages/${messageId}/ack`, {}, this.authHeaders());
269
+ }
270
+ async reply(messageId, text) {
271
+ const message = await this.read(messageId);
272
+ return this.send({
273
+ to: message.from_agent_id,
274
+ type: "status",
275
+ payload: { text },
276
+ conversationId: message.conversation_id,
277
+ });
278
+ }
279
+ keyPath(agentId) {
280
+ return join(this.keysDir, `${agentId}.key`);
281
+ }
282
+ async loadConfig() {
283
+ const data = await readJson(this.configPath);
284
+ this.config = data || {};
285
+ }
286
+ async saveConfig() {
287
+ await mkdir(this.home, { recursive: true });
288
+ await writePrivate(this.configPath, `${JSON.stringify(this.config, null, 2)}\n`);
289
+ }
290
+ async loadPrivateKey(agentId) {
291
+ const pem = await readFile(this.keyPath(agentId), "utf8");
292
+ return createPrivateKey(pem);
293
+ }
294
+ requireAgentId() {
295
+ if (!this.config.agent_id) {
296
+ throw new Error("No identity configured. Run init(address) first.");
297
+ }
298
+ return this.config.agent_id;
299
+ }
300
+ authHeaders() {
301
+ if (!this.config.token) {
302
+ throw new Error("No active session. Run connect() first.");
303
+ }
304
+ return { Authorization: `Bearer ${this.config.token}` };
305
+ }
306
+ projectHeaders(required = false) {
307
+ if (!this.apiKey && required) {
308
+ throw new Error("A project API key is required. Pass apiKey or set GREFT_API_KEY.");
309
+ }
310
+ return this.apiKey ? { "X-Greft-API-Key": this.apiKey } : {};
311
+ }
312
+ async get(path, headers = {}) {
313
+ return this.request("GET", path, undefined, headers);
314
+ }
315
+ async post(path, body, headers = {}) {
316
+ return this.request("POST", path, body, headers);
317
+ }
318
+ async request(method, path, body, headers = {}) {
319
+ const response = await this.fetcher(`${this.apiUrl}${path}`, {
320
+ method,
321
+ headers: {
322
+ ...headers,
323
+ ...(body === undefined ? {} : { "Content-Type": "application/json" }),
324
+ },
325
+ body: body === undefined ? undefined : JSON.stringify(body),
326
+ });
327
+ if (!response.ok) {
328
+ const text = await response.text();
329
+ throw new Error(`Greft request failed: ${response.status} ${response.statusText}${text ? ` — ${text}` : ""}`);
330
+ }
331
+ if (response.status === 204) {
332
+ return undefined;
333
+ }
334
+ return response.json();
335
+ }
336
+ }
@@ -0,0 +1,3 @@
1
+ export { GreftClient } from "./client.js";
2
+ export type { AgentIdentity, Contact, DeliveryEvent, DeliveryTimeline, GreftClientOptions, GreftGroup, GreftMessage, GroupMember, GroupMessage, MessagePayload, ProjectAddress, SearchMessagesInput, SendMessageInput, SessionInfo, } from "./types.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EACV,aAAa,EACb,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { GreftClient } from "./client.js";
@@ -0,0 +1,115 @@
1
+ export type JsonPrimitive = string | number | boolean | null;
2
+ export type JsonValue = JsonPrimitive | JsonValue[] | {
3
+ [key: string]: JsonValue;
4
+ };
5
+ export type MessagePayload = Record<string, JsonValue>;
6
+ export interface GreftClientOptions {
7
+ apiUrl?: string;
8
+ apiKey?: string;
9
+ home?: string;
10
+ fetch?: typeof fetch;
11
+ }
12
+ export interface ProjectAddress extends AgentIdentity {
13
+ }
14
+ export interface Contact {
15
+ agent_id: string;
16
+ address: string;
17
+ alias: string;
18
+ trusted: boolean;
19
+ presence: "online" | "offline" | string;
20
+ last_seen_at?: string | null;
21
+ }
22
+ export interface DeliveryEvent {
23
+ id: string;
24
+ message_id: string;
25
+ agent_id?: string | null;
26
+ status: string;
27
+ reason: string;
28
+ detail: string;
29
+ attempt: number;
30
+ metadata: MessagePayload;
31
+ created_at: string;
32
+ }
33
+ export interface DeliveryTimeline {
34
+ message_id: string;
35
+ events: DeliveryEvent[];
36
+ }
37
+ export interface AgentIdentity {
38
+ id: string;
39
+ address: string;
40
+ public_key: string;
41
+ inbound_policy: string;
42
+ created_at: string;
43
+ }
44
+ export interface SessionInfo {
45
+ id: string;
46
+ agent_id: string;
47
+ token: string;
48
+ is_primary: boolean;
49
+ status: string;
50
+ created_at: string;
51
+ last_seen_at: string;
52
+ }
53
+ export interface GreftMessage {
54
+ id: string;
55
+ seq: number;
56
+ conversation_id: string;
57
+ from_agent_id: string;
58
+ to_agent_id: string;
59
+ type: string;
60
+ payload: MessagePayload;
61
+ metadata: MessagePayload;
62
+ signature: string;
63
+ status: string;
64
+ delivery_attempts: number;
65
+ envelope_raw: Record<string, JsonValue>;
66
+ created_at: string;
67
+ delivered_at?: string | null;
68
+ acknowledged_at?: string | null;
69
+ expires_at?: string | null;
70
+ client_timestamp: string;
71
+ }
72
+ export interface SendMessageInput {
73
+ to: string;
74
+ type?: "request" | "status" | "handoff" | "ack" | string;
75
+ payload?: MessagePayload;
76
+ conversationId?: string;
77
+ metadata?: MessagePayload;
78
+ expiresAt?: string;
79
+ }
80
+ export interface SearchMessagesInput {
81
+ query?: string;
82
+ sender?: string;
83
+ recipient?: string;
84
+ status?: string;
85
+ type?: string;
86
+ conversationId?: string;
87
+ hasAttachments?: boolean;
88
+ limit?: number;
89
+ }
90
+ export interface GroupMember {
91
+ agent_id: string;
92
+ address: string;
93
+ role: "owner" | "member" | string;
94
+ added_at: string;
95
+ }
96
+ export interface GreftGroup {
97
+ id: string;
98
+ project_id: string;
99
+ name: string;
100
+ description: string;
101
+ visibility: "private" | string;
102
+ owner_agent_id: string;
103
+ members: GroupMember[];
104
+ created_at: string;
105
+ }
106
+ export interface GroupMessage {
107
+ id: string;
108
+ group_id: string;
109
+ sender_agent_id: string;
110
+ sender_address: string;
111
+ payload: MessagePayload;
112
+ attachments: Array<Record<string, JsonValue>>;
113
+ created_at: string;
114
+ }
115
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@greft/sdk",
3
+ "version": "0.2.0",
4
+ "description": "TypeScript SDK for Greft agent messaging.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/STEIDd/Greft-imp.git",
9
+ "directory": "packages/greft-sdk"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/STEIDd/Greft-imp/issues"
13
+ },
14
+ "homepage": "https://greft.ai",
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "type": "module",
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js"
25
+ }
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "README.md"
30
+ ],
31
+ "scripts": {
32
+ "build": "tsc -p tsconfig.json",
33
+ "test": "npm run build && node --test test/*.test.mjs"
34
+ },
35
+ "engines": {
36
+ "node": ">=20"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^20.19.11",
40
+ "typescript": "^5.9.2"
41
+ }
42
+ }