@permission-protocol/sdk 0.1.0-alpha.2 → 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/dist/index.js CHANGED
@@ -1,356 +1,239 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
1
+ // src/exceptions.ts
2
+ var PermissionProtocolError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "PermissionProtocolError";
15
6
  }
16
- return to;
17
7
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- PermissionProtocolError: () => PermissionProtocolError,
24
- PermissionRouter: () => PermissionRouter,
25
- buildHashablePayload: () => buildHashablePayload,
26
- canonicalize: () => canonicalize,
27
- computeHash: () => computeHash
28
- });
29
- module.exports = __toCommonJS(index_exports);
30
-
31
- // src/hash.ts
32
- var import_crypto = require("crypto");
33
- function canonicalize(obj) {
34
- if (obj === null) {
35
- return "null";
8
+ var PermissionDenied = class extends PermissionProtocolError {
9
+ constructor(message = "Permission was denied.") {
10
+ super(message);
11
+ this.name = "PermissionDenied";
36
12
  }
37
- if (typeof obj !== "object") {
38
- return JSON.stringify(obj);
39
- }
40
- if (Array.isArray(obj)) {
41
- return "[" + obj.map(canonicalize).join(",") + "]";
13
+ };
14
+ var ApprovalTimeout = class extends PermissionProtocolError {
15
+ constructor(message = "Approval request timed out.") {
16
+ super(message);
17
+ this.name = "ApprovalTimeout";
42
18
  }
43
- const record = obj;
44
- const sorted = Object.keys(record).filter((k) => record[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${canonicalize(record[k])}`);
45
- return "{" + sorted.join(",") + "}";
46
- }
47
- function computeHash(payload) {
48
- const canonical = canonicalize(payload);
49
- const hash = (0, import_crypto.createHash)("sha256").update(canonical, "utf8").digest("hex");
50
- return `sha256:${hash}`;
19
+ };
20
+
21
+ // src/config.ts
22
+ var DEFAULT_BASE_URL = "https://app.permissionprotocol.com";
23
+ var configuredApiKey;
24
+ var configuredBaseUrl;
25
+ function normalizeBaseUrl(value) {
26
+ return value.replace(/\/+$/, "");
51
27
  }
52
- function buildHashablePayload(opts) {
28
+ function configure(apiKey, baseUrl) {
29
+ const resolvedApiKey = apiKey ?? process.env.PP_API_KEY;
30
+ const resolvedBaseUrl = baseUrl ?? process.env.PP_BASE_URL ?? DEFAULT_BASE_URL;
31
+ if (!resolvedApiKey) {
32
+ throw new PermissionProtocolError("Permission Protocol API key is required.");
33
+ }
34
+ configuredApiKey = resolvedApiKey;
35
+ configuredBaseUrl = normalizeBaseUrl(resolvedBaseUrl);
53
36
  return {
54
- tool: opts.tool,
55
- operation: opts.operation,
56
- input: opts.input,
57
- metadata: opts.metadata ?? null
37
+ apiKey: configuredApiKey,
38
+ baseUrl: configuredBaseUrl
58
39
  };
59
40
  }
60
-
61
- // src/devApprovalMock.ts
62
- function devApprovalMock(opts) {
63
- console.warn(
64
- '\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557\n\u2551 PERMISSION PROTOCOL - DEV MODE \u2551\n\u2551 \u2551\n\u2551 This approval is NOT valid for production. \u2551\n\u2551 Real enforcement requires hosted Permission Protocol. \u2551\n\u2551 \u2551\n\u2551 Set mode: "hosted" for production use. \u2551\n\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D\n'
65
- );
66
- const hashablePayload = buildHashablePayload(opts);
67
- const inputHash = computeHash(hashablePayload);
68
- const receipt = {
69
- receiptId: `dev_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`,
70
- tenantId: opts.tenantId,
71
- agentId: opts.agentId,
72
- tool: opts.tool,
73
- operation: opts.operation,
74
- inputHash,
75
- decision: "APPROVED",
76
- reasonCodes: ["DEV_MODE_APPROVAL"],
77
- approver: "dev_mock",
78
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
79
- };
41
+ function getConfig() {
42
+ const apiKey = configuredApiKey ?? process.env.PP_API_KEY;
43
+ const baseUrl = configuredBaseUrl ?? process.env.PP_BASE_URL ?? DEFAULT_BASE_URL;
44
+ if (!apiKey) {
45
+ throw new PermissionProtocolError(
46
+ "Permission Protocol API key is not configured. Call configure(apiKey) or set PP_API_KEY."
47
+ );
48
+ }
80
49
  return {
81
- status: "APPROVED",
82
- receipt
50
+ apiKey,
51
+ baseUrl: normalizeBaseUrl(baseUrl)
83
52
  };
84
53
  }
85
54
 
86
- // src/errors.ts
87
- var PermissionProtocolError = class _PermissionProtocolError extends Error {
88
- /**
89
- * Error code for programmatic handling.
90
- */
91
- code;
92
- constructor(code, message) {
93
- super(`[PermissionProtocol:${code}] ${message}`);
94
- this.name = "PermissionProtocolError";
95
- this.code = code;
96
- Object.setPrototypeOf(this, _PermissionProtocolError.prototype);
55
+ // src/receipt.ts
56
+ var Receipt = class {
57
+ constructor(payload) {
58
+ this.payload = { ...payload };
59
+ this.id = payload.id;
60
+ this.status = payload.status;
61
+ this.action = payload.action;
62
+ this.resource = payload.resource;
63
+ this.actor = payload.actor;
64
+ this.approvedBy = payload.approved_by;
65
+ this.policy = payload.policy;
66
+ this.signature = payload.signature;
67
+ this.issuer = payload.issuer;
68
+ this.timestamp = payload.timestamp;
69
+ this.expiresAt = payload.expires_at;
70
+ this.url = payload.url;
71
+ this.isValid = Boolean(payload.valid);
72
+ }
73
+ get valid() {
74
+ return this.isValid;
75
+ }
76
+ json() {
77
+ return { ...this.payload, valid: this.isValid };
97
78
  }
98
79
  };
99
80
 
100
- // src/mapping.ts
101
- function mapHostedResponse(hosted, _opts) {
102
- if (!hosted.receipt || !hosted.hostedStatus) {
103
- throw new PermissionProtocolError(
104
- "INVALID_RECEIPT",
105
- "Hosted response missing required fields (receipt or hostedStatus)"
106
- );
81
+ // src/sdk.ts
82
+ import { hostname } from "os";
83
+
84
+ // src/client.ts
85
+ function createHeaders(apiKey) {
86
+ return {
87
+ "Content-Type": "application/json",
88
+ "X-PP-API-Key": apiKey
89
+ };
90
+ }
91
+ function getErrorMessage(status, fallback, body) {
92
+ if (body && typeof body === "object") {
93
+ const maybeErr = body;
94
+ if (maybeErr.error && typeof maybeErr.error === "string") {
95
+ return maybeErr.error;
96
+ }
97
+ if (maybeErr.message && typeof maybeErr.message === "string") {
98
+ return maybeErr.message;
99
+ }
100
+ }
101
+ return `${fallback} (HTTP ${status})`;
102
+ }
103
+ async function postAuthorize(payload) {
104
+ const { apiKey, baseUrl } = getConfig();
105
+ const response = await fetch(`${baseUrl}/api/v1/receipts/verify`, {
106
+ method: "POST",
107
+ headers: createHeaders(apiKey),
108
+ body: JSON.stringify({
109
+ scope: payload,
110
+ failOnMissing: true
111
+ })
112
+ });
113
+ const body = await response.json().catch(() => ({}));
114
+ if (!response.ok) {
115
+ throw new PermissionProtocolError(getErrorMessage(response.status, "Authorization failed", body));
107
116
  }
108
- if (!hosted.receipt.receiptId) {
117
+ return body;
118
+ }
119
+ async function getReceipt(receiptId) {
120
+ const { apiKey, baseUrl } = getConfig();
121
+ const response = await fetch(`${baseUrl}/api/v1/receipts/${encodeURIComponent(receiptId)}`, {
122
+ method: "GET",
123
+ headers: createHeaders(apiKey)
124
+ });
125
+ const body = await response.json().catch(() => ({}));
126
+ if (!response.ok) {
109
127
  throw new PermissionProtocolError(
110
- "INVALID_RECEIPT",
111
- "Hosted response receipt missing receiptId"
128
+ getErrorMessage(response.status, `Failed to fetch receipt ${receiptId}`, body)
112
129
  );
113
130
  }
114
- return mapStatus(hosted.hostedStatus, hosted.receipt, hosted.result);
115
- }
116
- function mapStatus(status, receipt, result) {
117
- switch (status) {
118
- // === APPROVED ===
119
- case "APPROVED":
120
- return {
121
- status: "APPROVED",
122
- receipt: { ...receipt, decision: "APPROVED" },
123
- result
124
- };
125
- // === REQUIRES_APPROVAL (direct) ===
126
- case "REQUIRES_APPROVAL":
127
- return {
128
- status: "REQUIRES_APPROVAL",
129
- receipt: { ...receipt, decision: "REQUIRES_APPROVAL" }
130
- };
131
- // === REQUIRES_FOUNDER_VETO -> REQUIRES_APPROVAL + reason code ===
132
- case "REQUIRES_FOUNDER_VETO":
133
- return {
134
- status: "REQUIRES_APPROVAL",
135
- receipt: {
136
- ...receipt,
137
- decision: "REQUIRES_APPROVAL",
138
- reasonCodes: ensureReasonCode(receipt.reasonCodes, "REQUIRES_FOUNDER_VETO")
139
- }
140
- };
141
- // === EXECUTING -> REQUIRES_APPROVAL + reason code ===
142
- case "EXECUTING":
143
- return {
144
- status: "REQUIRES_APPROVAL",
145
- receipt: {
146
- ...receipt,
147
- decision: "REQUIRES_APPROVAL",
148
- reasonCodes: ensureReasonCode(receipt.reasonCodes, "EXECUTING_PENDING_RESULT")
149
- }
150
- };
151
- // === PENDING_DECISION -> REQUIRES_APPROVAL + reason code ===
152
- case "PENDING_DECISION":
153
- return {
154
- status: "REQUIRES_APPROVAL",
155
- receipt: {
156
- ...receipt,
157
- decision: "REQUIRES_APPROVAL",
158
- reasonCodes: ensureReasonCode(receipt.reasonCodes, "PENDING_DECISION")
159
- }
160
- };
161
- // === DENIED (direct) ===
162
- case "DENIED":
163
- return {
164
- status: "DENIED",
165
- receipt: { ...receipt, decision: "DENIED" }
166
- };
167
- // === EXPIRED -> DENIED + reason code ===
168
- case "EXPIRED":
169
- return {
170
- status: "DENIED",
171
- receipt: {
172
- ...receipt,
173
- decision: "DENIED",
174
- reasonCodes: ensureReasonCode(receipt.reasonCodes, "APPROVAL_EXPIRED")
175
- }
176
- };
177
- // === ERROR -> DENIED + reason code ===
178
- case "ERROR":
179
- return {
180
- status: "DENIED",
181
- receipt: {
182
- ...receipt,
183
- decision: "DENIED",
184
- reasonCodes: ensureReasonCode(receipt.reasonCodes, "EXECUTION_ERROR")
185
- }
186
- };
187
- // === Unknown status -> fail closed ===
188
- default:
189
- throw new PermissionProtocolError(
190
- "EXECUTION_UNAUTHORIZED",
191
- `Unknown status from Permission Protocol: ${status}`
192
- );
131
+ if (body && typeof body === "object" && "receipt" in body) {
132
+ return body.receipt;
193
133
  }
134
+ return body;
194
135
  }
195
- function ensureReasonCode(codes, code) {
196
- if (codes.includes(code)) {
197
- return codes;
136
+ async function postVerify(receiptId) {
137
+ const { apiKey, baseUrl } = getConfig();
138
+ const response = await fetch(`${baseUrl}/api/v1/receipts/verify`, {
139
+ method: "POST",
140
+ headers: createHeaders(apiKey),
141
+ body: JSON.stringify({
142
+ receiptId
143
+ })
144
+ });
145
+ const body = await response.json().catch(() => ({}));
146
+ if (!response.ok) {
147
+ throw new PermissionProtocolError(getErrorMessage(response.status, "Verification failed", body));
198
148
  }
199
- return [...codes, code];
149
+ return body;
200
150
  }
201
151
 
202
- // src/client.ts
203
- var DEFAULT_TIMEOUT_MS = 1e4;
204
- var DEFAULT_SDK_VERSION = "0.1.0-alpha.1";
205
- var DEFAULT_PROTOCOL_VERSION = 1;
206
- async function fetchHostedPP(opts, body, headers) {
207
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
208
- const sdkVersion = opts.sdkVersion ?? DEFAULT_SDK_VERSION;
209
- const protocolVersion = opts.protocolVersion ?? DEFAULT_PROTOCOL_VERSION;
210
- const controller = new AbortController();
211
- const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
212
- try {
213
- const response = await fetch(`${opts.endpoint}/api/permission/v1/execute`, {
214
- method: "POST",
215
- headers: {
216
- "Content-Type": "application/json",
217
- "Authorization": `Bearer ${opts.apiKey}`,
218
- "X-PP-SDK-Version": sdkVersion,
219
- "X-PP-Protocol-Version": String(protocolVersion),
220
- "X-PP-Tenant-Id": headers.tenantId,
221
- "X-PP-Agent-Id": headers.agentId
222
- },
223
- body: JSON.stringify(body),
224
- signal: controller.signal
225
- });
226
- clearTimeout(timeoutId);
227
- if (!response.ok) {
228
- throw new PermissionProtocolError(
229
- "EXECUTION_UNAUTHORIZED",
230
- `Permission Protocol returned ${response.status}`
231
- );
232
- }
233
- let hosted;
234
- try {
235
- hosted = await response.json();
236
- } catch {
237
- throw new PermissionProtocolError(
238
- "EXECUTION_UNAUTHORIZED",
239
- "Permission Protocol returned malformed response"
240
- );
152
+ // src/sdk.ts
153
+ var DEFAULT_TIMEOUT_SECONDS = 300;
154
+ var DEFAULT_POLL_INTERVAL_MS = 2e3;
155
+ var MAX_POLL_INTERVAL_MS = 1e4;
156
+ function sleep(ms) {
157
+ return new Promise((resolve) => setTimeout(resolve, ms));
158
+ }
159
+ function asReceipt(data, fallbackId) {
160
+ if (!data?.id && !fallbackId) {
161
+ throw new PermissionProtocolError("Missing receipt data in API response.");
162
+ }
163
+ return new Receipt({
164
+ id: data?.id ?? fallbackId ?? "",
165
+ status: data?.status ?? "PENDING",
166
+ ...data
167
+ });
168
+ }
169
+ async function authorize(action, resource, actor, metadata, wait = true, timeout = DEFAULT_TIMEOUT_SECONDS) {
170
+ const params = { action, resource, actor, metadata, wait, timeout };
171
+ const resolvedActor = params.actor ?? hostname();
172
+ const response = await postAuthorize({
173
+ action: params.action,
174
+ resource: params.resource,
175
+ actor: resolvedActor,
176
+ metadata: params.metadata
177
+ });
178
+ const receipt = asReceipt(response.receipt, response.requestId);
179
+ if (response.approvalUrl) {
180
+ console.log(`Approval URL: ${response.approvalUrl}`);
181
+ }
182
+ if (!params.wait) {
183
+ return receipt;
184
+ }
185
+ const timeoutMs = Math.max(1, params.timeout ?? DEFAULT_TIMEOUT_SECONDS) * 1e3;
186
+ const deadline = Date.now() + timeoutMs;
187
+ let pollInterval = DEFAULT_POLL_INTERVAL_MS;
188
+ while (Date.now() < deadline) {
189
+ const current = await getReceipt(receipt.id);
190
+ const currentReceipt = asReceipt(current, receipt.id);
191
+ if (currentReceipt.status === "APPROVED") {
192
+ return currentReceipt;
241
193
  }
242
- return hosted;
243
- } catch (err) {
244
- clearTimeout(timeoutId);
245
- if (err instanceof PermissionProtocolError) {
246
- throw err;
194
+ if (currentReceipt.status === "DENIED" || currentReceipt.status === "EXPIRED") {
195
+ throw new PermissionDenied(`Approval request ${receipt.id} ended with status ${currentReceipt.status}.`);
247
196
  }
248
- const error = err;
249
- const message = error.name === "AbortError" ? "Permission Protocol request timed out" : "Permission Protocol unreachable";
250
- throw new PermissionProtocolError("EXECUTION_UNAUTHORIZED", message);
197
+ await sleep(pollInterval);
198
+ pollInterval = Math.min(MAX_POLL_INTERVAL_MS, Math.floor(pollInterval * 1.5));
251
199
  }
200
+ throw new ApprovalTimeout(
201
+ `Approval request ${receipt.id} was not approved within ${Math.floor(timeoutMs / 1e3)} seconds.`
202
+ );
252
203
  }
253
-
254
- // src/router.ts
255
- var config = null;
256
- var PermissionRouter = {
257
- /**
258
- * Configure the Permission Protocol client.
259
- *
260
- * Must be called before execute() in hosted mode.
261
- *
262
- * @param opts - Configuration options
263
- */
264
- configure(opts) {
265
- config = opts;
266
- },
267
- /**
268
- * Request authorization for an action.
269
- *
270
- * Returns a decision + receipt. Does NOT execute the action.
271
- *
272
- * @param opts - Execute options
273
- * @returns Promise resolving to decision (APPROVED, REQUIRES_APPROVAL, or DENIED) with receipt
274
- * @throws PermissionProtocolError on network failure, timeout, or invalid response
275
- */
276
- async execute(opts) {
277
- if (opts.mode === "dev") {
278
- return devApprovalMock(opts);
279
- }
280
- if (!config) {
281
- throw new PermissionProtocolError(
282
- "MISCONFIGURED",
283
- "Permission Protocol client not configured. Call PermissionRouter.configure() first."
204
+ async function verify(receiptId) {
205
+ const result = await postVerify(receiptId);
206
+ const payload = result.receipt ?? { id: receiptId, status: "PENDING" };
207
+ return new Receipt({
208
+ ...payload,
209
+ id: payload.id ?? receiptId,
210
+ valid: Boolean(result.valid)
211
+ });
212
+ }
213
+ function requireApproval(options) {
214
+ return function withApproval(fn) {
215
+ return async (...args) => {
216
+ const action = options.action ?? fn.name ?? "action";
217
+ await authorize(
218
+ action,
219
+ options.resource,
220
+ options.actor,
221
+ options.metadata,
222
+ options.wait ?? true,
223
+ options.timeout ?? DEFAULT_TIMEOUT_SECONDS
284
224
  );
285
- }
286
- const hashablePayload = buildHashablePayload(opts);
287
- const inputHash = computeHash(hashablePayload);
288
- const body = {
289
- tenantId: opts.tenantId,
290
- actor: { agentId: opts.agentId },
291
- intent: {
292
- name: `${opts.tool}:${opts.operation}`,
293
- summary: `${opts.tool} ${opts.operation}`,
294
- category: opts.tool
295
- },
296
- action: {
297
- tool: opts.tool,
298
- operation: opts.operation,
299
- parameters: opts.input
300
- },
301
- context: {
302
- environment: "production",
303
- reversibility: opts.reversibility ?? "UNKNOWN",
304
- metadata: opts.metadata
305
- },
306
- hashes: { inputHash }
225
+ return fn(...args);
307
226
  };
308
- const hosted = await fetchHostedPP(
309
- {
310
- endpoint: config.endpoint,
311
- apiKey: config.apiKey,
312
- timeoutMs: config.timeoutMs,
313
- protocolVersion: config.protocolVersion,
314
- sdkVersion: config.sdkVersion
315
- },
316
- body,
317
- {
318
- tenantId: opts.tenantId,
319
- agentId: opts.agentId
320
- }
321
- );
322
- const result = mapHostedResponse(hosted, opts);
323
- if (config.verifyReceipt) {
324
- const valid = await config.verifyReceipt(result.receipt);
325
- if (!valid) {
326
- throw new PermissionProtocolError(
327
- "INVALID_RECEIPT",
328
- "Receipt verification failed"
329
- );
330
- }
331
- }
332
- return result;
333
- },
334
- /**
335
- * Check if the client is configured.
336
- * Useful for testing and debugging.
337
- */
338
- isConfigured() {
339
- return config !== null;
340
- },
341
- /**
342
- * Reset configuration (for testing).
343
- * @internal
344
- */
345
- _reset() {
346
- config = null;
347
- }
348
- };
349
- // Annotate the CommonJS export names for ESM import in node:
350
- 0 && (module.exports = {
227
+ };
228
+ }
229
+ export {
230
+ ApprovalTimeout,
231
+ DEFAULT_BASE_URL,
232
+ PermissionDenied,
351
233
  PermissionProtocolError,
352
- PermissionRouter,
353
- buildHashablePayload,
354
- canonicalize,
355
- computeHash
356
- });
234
+ Receipt,
235
+ authorize,
236
+ configure,
237
+ requireApproval,
238
+ verify
239
+ };
package/package.json CHANGED
@@ -1,52 +1,47 @@
1
1
  {
2
2
  "name": "@permission-protocol/sdk",
3
- "version": "0.1.0-alpha.2",
4
- "description": "Standardized authorization and receipts for autonomous AI actions",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
3
+ "version": "0.1.0",
4
+ "description": "Official JavaScript/TypeScript SDK for Permission Protocol",
5
+ "license": "MIT",
6
+ "author": "Permission Protocol",
7
+ "repository": {
8
+ "type": "git"
9
+ },
10
+ "type": "module",
11
+ "main": "./dist/index.cjs",
12
+ "module": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
8
14
  "exports": {
9
15
  ".": {
10
16
  "types": "./dist/index.d.ts",
11
- "import": "./dist/index.mjs",
12
- "require": "./dist/index.js"
17
+ "import": "./dist/index.js",
18
+ "require": "./dist/index.cjs"
13
19
  }
14
20
  },
15
21
  "files": [
16
22
  "dist",
17
- "README.md"
18
- ],
19
- "license": "Apache-2.0",
20
- "homepage": "https://github.com/permission-protocol/permission-protocol",
21
- "repository": {
22
- "type": "git",
23
- "url": "https://github.com/permission-protocol/permission-protocol"
24
- },
25
- "keywords": [
26
- "ai",
27
- "agents",
28
- "authorization",
29
- "receipts",
30
- "audit",
31
- "human-in-the-loop",
32
- "ci",
33
- "governance"
23
+ "README.md",
24
+ "LICENSE"
34
25
  ],
26
+ "sideEffects": false,
35
27
  "engines": {
36
28
  "node": ">=18"
37
29
  },
38
30
  "scripts": {
39
- "build": "tsup src/index.ts --format cjs,esm --dts --clean",
40
- "test": "vitest run",
41
- "test:watch": "vitest",
42
- "test:golden": "vitest run -t 'HashablePayload v1 conformance'",
43
- "lint": "eslint src --ext .ts",
44
- "prepublishOnly": "npm run build"
31
+ "build": "tsup src/index.ts --dts --format cjs,esm --clean",
32
+ "typecheck": "tsc --noEmit",
33
+ "prepublishOnly": "npm run typecheck && npm run build"
45
34
  },
35
+ "keywords": [
36
+ "permission",
37
+ "authorization",
38
+ "approval",
39
+ "sdk",
40
+ "typescript"
41
+ ],
46
42
  "devDependencies": {
47
- "@types/node": "^20.0.0",
48
- "tsup": "^8.0.0",
49
- "typescript": "^5.0.0",
50
- "vitest": "^1.0.0"
43
+ "@types/node": "^25.3.3",
44
+ "tsup": "^8.2.4",
45
+ "typescript": "^5.6.3"
51
46
  }
52
- }
47
+ }