@scopeblind/passport 0.3.0 → 0.4.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 +77 -128
- package/dist/chunk-LEODYLAY.mjs +401 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +834 -0
- package/dist/cli.mjs +708 -0
- package/dist/index.mjs +41 -385
- package/package.json +11 -5
package/dist/index.mjs
CHANGED
|
@@ -1,275 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
secretKey.set(publicKey, 32);
|
|
30
|
-
const kid = derivePassportId(publicKey, role);
|
|
31
|
-
return {
|
|
32
|
-
publicKey,
|
|
33
|
-
secretKey,
|
|
34
|
-
kid,
|
|
35
|
-
role,
|
|
36
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function getSigningKey(keyPair) {
|
|
40
|
-
return bytesToHex(keyPair.secretKey.slice(0, 32));
|
|
41
|
-
}
|
|
42
|
-
function getVerifyKey(keyPair) {
|
|
43
|
-
return bytesToHex(keyPair.publicKey);
|
|
44
|
-
}
|
|
45
|
-
function hashString(value) {
|
|
46
|
-
const encoder = new TextEncoder();
|
|
47
|
-
return bytesToHex(sha256(encoder.encode(value)));
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// src/manifest.ts
|
|
51
|
-
import { ed25519 as ed255192 } from "@noble/curves/ed25519";
|
|
52
|
-
import { sha256 as sha2562 } from "@noble/hashes/sha256";
|
|
53
|
-
import { bytesToHex as bytesToHex2, utf8ToBytes } from "@noble/hashes/utils";
|
|
54
|
-
function canonicalize(obj) {
|
|
55
|
-
return JSON.stringify(obj, (_key, value) => {
|
|
56
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
57
|
-
const sorted = {};
|
|
58
|
-
for (const k of Object.keys(value).sort()) {
|
|
59
|
-
sorted[k] = value[k];
|
|
60
|
-
}
|
|
61
|
-
return sorted;
|
|
62
|
-
}
|
|
63
|
-
return value;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
function canonicalHash(obj) {
|
|
67
|
-
return bytesToHex2(sha2562(utf8ToBytes(canonicalize(obj))));
|
|
68
|
-
}
|
|
69
|
-
function signPayload(payload, keyPair) {
|
|
70
|
-
const message = utf8ToBytes(canonicalize(payload));
|
|
71
|
-
const sigBytes = ed255192.sign(message, keyPair.secretKey.slice(0, 32));
|
|
72
|
-
return {
|
|
73
|
-
payload,
|
|
74
|
-
signature: {
|
|
75
|
-
alg: "EdDSA",
|
|
76
|
-
kid: keyPair.kid,
|
|
77
|
-
sig: bytesToHex2(sigBytes)
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function createCoachManifest(keyPair, input, previousVersion, version) {
|
|
82
|
-
const manifest = {
|
|
83
|
-
type: "scopeblind:coach-manifest",
|
|
84
|
-
id: keyPair.kid,
|
|
85
|
-
version: version || "1.0.0",
|
|
86
|
-
previous_version: previousVersion ?? null,
|
|
87
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
88
|
-
public_key: base58Encode(keyPair.publicKey),
|
|
89
|
-
display_name: input.display_name.trim().slice(0, 32)
|
|
90
|
-
};
|
|
91
|
-
return signPayload(manifest, keyPair);
|
|
92
|
-
}
|
|
93
|
-
function createAgentManifest(keyPair, input, previousVersion, version) {
|
|
94
|
-
const promptHash = hashString(input.configuration_attestations.system_prompt);
|
|
95
|
-
const manifest = {
|
|
96
|
-
type: "scopeblind:agent-manifest",
|
|
97
|
-
id: keyPair.kid,
|
|
98
|
-
version: version || "1.0.0",
|
|
99
|
-
previous_version: previousVersion ?? null,
|
|
100
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
101
|
-
public_key: base58Encode(keyPair.publicKey),
|
|
102
|
-
public_profile: input.public_profile,
|
|
103
|
-
configuration_attestations: {
|
|
104
|
-
model_family_hash: input.configuration_attestations.model_family_hash,
|
|
105
|
-
memory_mode: input.configuration_attestations.memory_mode,
|
|
106
|
-
prompt_hash: promptHash
|
|
107
|
-
},
|
|
108
|
-
capability_declarations: input.capability_declarations,
|
|
109
|
-
evidence_pointers: input.evidence_pointers || {}
|
|
110
|
-
};
|
|
111
|
-
return signPayload(manifest, keyPair);
|
|
112
|
-
}
|
|
113
|
-
function createOwnershipAttestation(coachKeyPair, agentId, agentManifestVersion) {
|
|
114
|
-
const attestation = {
|
|
115
|
-
type: "scopeblind:ownership-attestation",
|
|
116
|
-
coach_id: coachKeyPair.kid,
|
|
117
|
-
agent_id: agentId,
|
|
118
|
-
agent_manifest_version: agentManifestVersion,
|
|
119
|
-
granted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
120
|
-
};
|
|
121
|
-
return signPayload(attestation, coachKeyPair);
|
|
122
|
-
}
|
|
123
|
-
function createStatusRecord(signerKeyPair, targetId, status, reason) {
|
|
124
|
-
const record = {
|
|
125
|
-
type: "scopeblind:status-record",
|
|
126
|
-
target_id: targetId,
|
|
127
|
-
status,
|
|
128
|
-
changed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
129
|
-
issuer_id: signerKeyPair.kid,
|
|
130
|
-
...reason ? { reason } : {}
|
|
131
|
-
};
|
|
132
|
-
return signPayload(record, signerKeyPair);
|
|
133
|
-
}
|
|
134
|
-
function createCoachContribution(coachKeyPair, battleId, coachedSide, noteHash, noteLength, upliftVerdict) {
|
|
135
|
-
const contribution = {
|
|
136
|
-
type: "scopeblind:coach-contribution",
|
|
137
|
-
battle_id: battleId,
|
|
138
|
-
coach_id: coachKeyPair.kid,
|
|
139
|
-
coached_side: coachedSide,
|
|
140
|
-
note_hash: noteHash,
|
|
141
|
-
note_length: noteLength,
|
|
142
|
-
...upliftVerdict ? { uplift_verdict: upliftVerdict } : {}
|
|
143
|
-
};
|
|
144
|
-
return signPayload(contribution, coachKeyPair);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// src/verify.ts
|
|
148
|
-
import { ed25519 as ed255193 } from "@noble/curves/ed25519";
|
|
149
|
-
import { hexToBytes as hexToBytes2, utf8ToBytes as utf8ToBytes2 } from "@noble/hashes/utils";
|
|
150
|
-
function verifyEnvelope(envelope, expectedPublicKey) {
|
|
151
|
-
try {
|
|
152
|
-
if (!envelope.signature?.sig || !envelope.signature?.kid) {
|
|
153
|
-
return { valid: false, error: "missing_signature" };
|
|
154
|
-
}
|
|
155
|
-
const message = utf8ToBytes2(canonicalize(envelope.payload));
|
|
156
|
-
const hash = canonicalHash(envelope.payload);
|
|
157
|
-
const payload = envelope.payload;
|
|
158
|
-
let publicKeyBytes;
|
|
159
|
-
if (expectedPublicKey) {
|
|
160
|
-
publicKeyBytes = expectedPublicKey;
|
|
161
|
-
} else if (typeof payload.public_key === "string") {
|
|
162
|
-
publicKeyBytes = base58Decode(payload.public_key);
|
|
163
|
-
} else {
|
|
164
|
-
return { valid: false, error: "no_public_key_available" };
|
|
165
|
-
}
|
|
166
|
-
if (expectedPublicKey) {
|
|
167
|
-
const expectedKid = base58Encode(expectedPublicKey);
|
|
168
|
-
const signerFingerprint = envelope.signature.kid.split(":")[2];
|
|
169
|
-
const expectedFingerprint = expectedKid.slice(0, 12);
|
|
170
|
-
if (signerFingerprint !== expectedFingerprint) {
|
|
171
|
-
return { valid: false, hash, error: "kid_mismatch" };
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
const valid = ed255193.verify(
|
|
175
|
-
hexToBytes2(envelope.signature.sig),
|
|
176
|
-
message,
|
|
177
|
-
publicKeyBytes
|
|
178
|
-
);
|
|
179
|
-
return valid ? { valid: true, hash } : { valid: false, hash, error: "invalid_signature" };
|
|
180
|
-
} catch (err) {
|
|
181
|
-
return {
|
|
182
|
-
valid: false,
|
|
183
|
-
error: `verification_error: ${err instanceof Error ? err.message : "unknown"}`
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
function verifyManifest(envelope) {
|
|
188
|
-
return verifyEnvelope(envelope);
|
|
189
|
-
}
|
|
190
|
-
function verifyOwnership(attestation, coachPublicKey) {
|
|
191
|
-
const result = verifyEnvelope(attestation, coachPublicKey);
|
|
192
|
-
if (!result.valid) return result;
|
|
193
|
-
return result;
|
|
194
|
-
}
|
|
195
|
-
function base58Decode(str) {
|
|
196
|
-
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
197
|
-
let num = 0n;
|
|
198
|
-
for (const char of str) {
|
|
199
|
-
const idx = ALPHABET.indexOf(char);
|
|
200
|
-
if (idx === -1) throw new Error(`Invalid base58 character: ${char}`);
|
|
201
|
-
num = num * 58n + BigInt(idx);
|
|
202
|
-
}
|
|
203
|
-
const hex = num.toString(16).padStart(64, "0");
|
|
204
|
-
const bytes = new Uint8Array(32);
|
|
205
|
-
for (let i = 0; i < 32; i++) {
|
|
206
|
-
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
207
|
-
}
|
|
208
|
-
return bytes;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// src/display.ts
|
|
212
|
-
function formatKidShort(kid) {
|
|
213
|
-
const parts = kid.split(":");
|
|
214
|
-
const fingerprint = parts[2] || kid;
|
|
215
|
-
if (fingerprint.length <= 8) return fingerprint;
|
|
216
|
-
return `${fingerprint.slice(0, 4)}\u2026${fingerprint.slice(-4)}`;
|
|
217
|
-
}
|
|
218
|
-
function formatKidLabeled(kid) {
|
|
219
|
-
const parts = kid.split(":");
|
|
220
|
-
const role = parts[1] === "coach" ? "Coach" : parts[1] === "agent" ? "Agent" : "Unknown";
|
|
221
|
-
return `${role} ${formatKidShort(kid)}`;
|
|
222
|
-
}
|
|
223
|
-
function getCoachSummary(envelope) {
|
|
224
|
-
const m = envelope.payload;
|
|
225
|
-
return {
|
|
226
|
-
kid: m.id,
|
|
227
|
-
displayName: m.display_name,
|
|
228
|
-
shortId: formatKidShort(m.id),
|
|
229
|
-
version: m.version,
|
|
230
|
-
createdAt: m.created_at
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function getAgentSummary(envelope) {
|
|
234
|
-
const m = envelope.payload;
|
|
235
|
-
return {
|
|
236
|
-
kid: m.id,
|
|
237
|
-
name: m.public_profile.name,
|
|
238
|
-
shortId: formatKidShort(m.id),
|
|
239
|
-
version: m.version,
|
|
240
|
-
domainLanes: m.public_profile.domain_lanes,
|
|
241
|
-
createdAt: m.created_at
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
function isCoachManifest(manifest) {
|
|
245
|
-
return manifest.type === "scopeblind:coach-manifest";
|
|
246
|
-
}
|
|
247
|
-
function isAgentManifest(manifest) {
|
|
248
|
-
return manifest.type === "scopeblind:agent-manifest";
|
|
249
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
base58Encode,
|
|
3
|
+
canonicalHash,
|
|
4
|
+
canonicalize,
|
|
5
|
+
createAgentManifest,
|
|
6
|
+
createCoachContribution,
|
|
7
|
+
createCoachManifest,
|
|
8
|
+
createOwnershipAttestation,
|
|
9
|
+
createStatusRecord,
|
|
10
|
+
derivePassportId,
|
|
11
|
+
exportPassportBundle,
|
|
12
|
+
formatKidLabeled,
|
|
13
|
+
formatKidShort,
|
|
14
|
+
generatePassportKey,
|
|
15
|
+
getAgentSummary,
|
|
16
|
+
getCoachSummary,
|
|
17
|
+
getSigningKey,
|
|
18
|
+
getVerifyKey,
|
|
19
|
+
hashString,
|
|
20
|
+
importPassportBundle,
|
|
21
|
+
isAgentManifest,
|
|
22
|
+
isCoachManifest,
|
|
23
|
+
serializeBundle,
|
|
24
|
+
signPayload,
|
|
25
|
+
verifyEnvelope,
|
|
26
|
+
verifyManifest,
|
|
27
|
+
verifyOwnership
|
|
28
|
+
} from "./chunk-LEODYLAY.mjs";
|
|
250
29
|
|
|
251
30
|
// src/issuer.ts
|
|
252
|
-
import { ed25519
|
|
253
|
-
import { bytesToHex
|
|
31
|
+
import { ed25519 } from "@noble/curves/ed25519";
|
|
32
|
+
import { bytesToHex, hexToBytes, utf8ToBytes } from "@noble/hashes/utils";
|
|
254
33
|
function generateIssuerKey() {
|
|
255
|
-
const secretKeyRaw =
|
|
256
|
-
const publicKey =
|
|
34
|
+
const secretKeyRaw = ed25519.utils.randomPrivateKey();
|
|
35
|
+
const publicKey = ed25519.getPublicKey(secretKeyRaw);
|
|
257
36
|
const fingerprint = base58Encode(publicKey).slice(0, 12);
|
|
258
37
|
return {
|
|
259
|
-
publicKeyHex:
|
|
260
|
-
secretKeyHex:
|
|
38
|
+
publicKeyHex: bytesToHex(publicKey),
|
|
39
|
+
secretKeyHex: bytesToHex(secretKeyRaw),
|
|
261
40
|
issuerId: `sb:issuer:${fingerprint}`
|
|
262
41
|
};
|
|
263
42
|
}
|
|
264
43
|
function signReceipt(payload, issuerSecretKeyHex, issuerId) {
|
|
265
|
-
const message =
|
|
266
|
-
const sigBytes =
|
|
44
|
+
const message = utf8ToBytes(canonicalize(payload));
|
|
45
|
+
const sigBytes = ed25519.sign(message, hexToBytes(issuerSecretKeyHex));
|
|
267
46
|
return {
|
|
268
47
|
payload,
|
|
269
48
|
signature: {
|
|
270
49
|
alg: "EdDSA",
|
|
271
50
|
kid: issuerId,
|
|
272
|
-
sig:
|
|
51
|
+
sig: bytesToHex(sigBytes)
|
|
273
52
|
}
|
|
274
53
|
};
|
|
275
54
|
}
|
|
@@ -318,7 +97,7 @@ function createFormalDebateReceipt(input, issuerSecretKeyHex, issuerId) {
|
|
|
318
97
|
return signReceipt(receipt, issuerSecretKeyHex, issuerId);
|
|
319
98
|
}
|
|
320
99
|
function hexToBase64url(hex) {
|
|
321
|
-
const bytes =
|
|
100
|
+
const bytes = hexToBytes(hex);
|
|
322
101
|
const binary = String.fromCharCode(...bytes);
|
|
323
102
|
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
324
103
|
}
|
|
@@ -336,139 +115,16 @@ function buildPublicKeyEndpoint(issuerPublicKeyHex, issuerId) {
|
|
|
336
115
|
};
|
|
337
116
|
}
|
|
338
117
|
function deriveIssuerFromSeed(secretKeyHex) {
|
|
339
|
-
const secretKeyBytes =
|
|
340
|
-
const publicKey =
|
|
118
|
+
const secretKeyBytes = hexToBytes(secretKeyHex);
|
|
119
|
+
const publicKey = ed25519.getPublicKey(secretKeyBytes);
|
|
341
120
|
const fingerprint = base58Encode(publicKey).slice(0, 12);
|
|
342
121
|
return {
|
|
343
|
-
publicKeyHex:
|
|
122
|
+
publicKeyHex: bytesToHex(publicKey),
|
|
344
123
|
secretKeyHex,
|
|
345
124
|
issuerId: `sb:issuer:${fingerprint}`
|
|
346
125
|
};
|
|
347
126
|
}
|
|
348
127
|
|
|
349
|
-
// src/portable.ts
|
|
350
|
-
import { bytesToHex as bytesToHex4, hexToBytes as hexToBytes4 } from "@noble/hashes/utils";
|
|
351
|
-
import { ed25519 as ed255195 } from "@noble/curves/ed25519";
|
|
352
|
-
function exportPassportBundle(bundle) {
|
|
353
|
-
return {
|
|
354
|
-
v: 1,
|
|
355
|
-
exported_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
356
|
-
passport: {
|
|
357
|
-
kid: bundle.key.kid,
|
|
358
|
-
role: bundle.key.role,
|
|
359
|
-
created_at: bundle.key.created_at,
|
|
360
|
-
publicKeyHex: bytesToHex4(bundle.key.publicKey),
|
|
361
|
-
secretKeyHex: bytesToHex4(bundle.key.secretKey)
|
|
362
|
-
},
|
|
363
|
-
manifests: bundle.manifests,
|
|
364
|
-
ownership_attestations: bundle.ownership_attestations,
|
|
365
|
-
status_records: bundle.status_records
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
function serializeBundle(bundle) {
|
|
369
|
-
return JSON.stringify(bundle, null, 2);
|
|
370
|
-
}
|
|
371
|
-
function importPassportBundle(json) {
|
|
372
|
-
const errors = [];
|
|
373
|
-
const warnings = [];
|
|
374
|
-
let raw;
|
|
375
|
-
try {
|
|
376
|
-
raw = JSON.parse(json);
|
|
377
|
-
} catch {
|
|
378
|
-
return { valid: false, errors: ["Invalid JSON"], warnings };
|
|
379
|
-
}
|
|
380
|
-
const data = raw;
|
|
381
|
-
if (data.v !== 1) {
|
|
382
|
-
errors.push(`Unsupported bundle version: ${data.v}`);
|
|
383
|
-
return { valid: false, errors, warnings };
|
|
384
|
-
}
|
|
385
|
-
const passport = data.passport;
|
|
386
|
-
if (!passport) {
|
|
387
|
-
errors.push("Missing passport field");
|
|
388
|
-
return { valid: false, errors, warnings };
|
|
389
|
-
}
|
|
390
|
-
if (typeof passport.publicKeyHex !== "string" || typeof passport.secretKeyHex !== "string") {
|
|
391
|
-
errors.push("Missing or invalid key hex values");
|
|
392
|
-
return { valid: false, errors, warnings };
|
|
393
|
-
}
|
|
394
|
-
if (typeof passport.kid !== "string" || !passport.kid.startsWith("sb:")) {
|
|
395
|
-
errors.push("Invalid passport kid format");
|
|
396
|
-
return { valid: false, errors, warnings };
|
|
397
|
-
}
|
|
398
|
-
const role = passport.role;
|
|
399
|
-
if (role !== "coach" && role !== "agent") {
|
|
400
|
-
errors.push(`Invalid role: ${role}`);
|
|
401
|
-
return { valid: false, errors, warnings };
|
|
402
|
-
}
|
|
403
|
-
let publicKey;
|
|
404
|
-
let secretKey;
|
|
405
|
-
try {
|
|
406
|
-
publicKey = hexToBytes4(passport.publicKeyHex);
|
|
407
|
-
secretKey = hexToBytes4(passport.secretKeyHex);
|
|
408
|
-
} catch {
|
|
409
|
-
errors.push("Failed to decode key hex values");
|
|
410
|
-
return { valid: false, errors, warnings };
|
|
411
|
-
}
|
|
412
|
-
if (publicKey.length !== 32) {
|
|
413
|
-
errors.push(`Invalid public key length: ${publicKey.length} (expected 32)`);
|
|
414
|
-
return { valid: false, errors, warnings };
|
|
415
|
-
}
|
|
416
|
-
if (secretKey.length !== 64) {
|
|
417
|
-
errors.push(`Invalid secret key length: ${secretKey.length} (expected 64)`);
|
|
418
|
-
return { valid: false, errors, warnings };
|
|
419
|
-
}
|
|
420
|
-
const seed = secretKey.slice(0, 32);
|
|
421
|
-
let derivedPublicKey;
|
|
422
|
-
try {
|
|
423
|
-
derivedPublicKey = ed255195.getPublicKey(seed);
|
|
424
|
-
} catch {
|
|
425
|
-
errors.push("Secret key seed is not a valid Ed25519 private key");
|
|
426
|
-
return { valid: false, errors, warnings };
|
|
427
|
-
}
|
|
428
|
-
if (bytesToHex4(derivedPublicKey) !== bytesToHex4(publicKey)) {
|
|
429
|
-
errors.push("Key coherence failure: secret key does not derive to the claimed public key");
|
|
430
|
-
return { valid: false, errors, warnings };
|
|
431
|
-
}
|
|
432
|
-
const expectedKid = derivePassportId(publicKey, role);
|
|
433
|
-
if (passport.kid !== expectedKid) {
|
|
434
|
-
errors.push(`Kid mismatch: bundle claims ${passport.kid} but public key derives to ${expectedKid}`);
|
|
435
|
-
return { valid: false, errors, warnings };
|
|
436
|
-
}
|
|
437
|
-
const key = {
|
|
438
|
-
publicKey,
|
|
439
|
-
secretKey,
|
|
440
|
-
kid: passport.kid,
|
|
441
|
-
role,
|
|
442
|
-
created_at: passport.created_at || (/* @__PURE__ */ new Date()).toISOString()
|
|
443
|
-
};
|
|
444
|
-
const rawManifests = Array.isArray(data.manifests) ? data.manifests : [];
|
|
445
|
-
const validManifests = [];
|
|
446
|
-
for (const m of rawManifests) {
|
|
447
|
-
const result = verifyManifest(m);
|
|
448
|
-
if (!result.valid) {
|
|
449
|
-
errors.push(`Manifest ${m.payload?.id || "unknown"} has invalid signature: ${result.error}`);
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
452
|
-
if (m.payload?.id && m.payload.id !== key.kid) {
|
|
453
|
-
warnings.push(`Dropped manifest ${m.payload.id}: does not belong to passport ${key.kid}`);
|
|
454
|
-
continue;
|
|
455
|
-
}
|
|
456
|
-
validManifests.push(m);
|
|
457
|
-
}
|
|
458
|
-
const bundle = {
|
|
459
|
-
key,
|
|
460
|
-
manifests: validManifests,
|
|
461
|
-
ownership_attestations: Array.isArray(data.ownership_attestations) ? data.ownership_attestations : [],
|
|
462
|
-
status_records: Array.isArray(data.status_records) ? data.status_records : []
|
|
463
|
-
};
|
|
464
|
-
return {
|
|
465
|
-
valid: errors.length === 0,
|
|
466
|
-
bundle,
|
|
467
|
-
errors,
|
|
468
|
-
warnings
|
|
469
|
-
};
|
|
470
|
-
}
|
|
471
|
-
|
|
472
128
|
// src/artifact-bridge.ts
|
|
473
129
|
function passportToArtifact(envelope, options) {
|
|
474
130
|
return {
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scopeblind/passport",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Portable cryptographic identity for AI agents and
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "Portable cryptographic identity and local pack builder for AI agents and MCP runtimes. Ed25519 passports, signed manifests, export bundles, and create/wrap CLI flows.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
8
|
+
"bin": {
|
|
9
|
+
"passport": "dist/cli.js"
|
|
10
|
+
},
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
13
|
"types": "./dist/index.d.ts",
|
|
@@ -18,7 +21,7 @@
|
|
|
18
21
|
}
|
|
19
22
|
},
|
|
20
23
|
"scripts": {
|
|
21
|
-
"build": "tsup src/index.ts src/browser.ts --format cjs,esm --dts --clean --external @noble/curves --external @noble/hashes",
|
|
24
|
+
"build": "tsup src/index.ts src/browser.ts src/cli.ts --format cjs,esm --dts --clean --external @noble/curves --external @noble/hashes",
|
|
22
25
|
"test": "vitest run",
|
|
23
26
|
"smoke": "vite --config vite.smoke.config.ts",
|
|
24
27
|
"pack:fresh": "npm run build && npm pack",
|
|
@@ -37,14 +40,17 @@
|
|
|
37
40
|
"verifiable-credentials",
|
|
38
41
|
"ai-agent",
|
|
39
42
|
"coach",
|
|
40
|
-
"portable-identity"
|
|
43
|
+
"portable-identity",
|
|
44
|
+
"mcp",
|
|
45
|
+
"openclaw",
|
|
46
|
+
"agent-pack"
|
|
41
47
|
],
|
|
42
48
|
"author": "Tom Farley <tommy@scopeblind.com>",
|
|
43
49
|
"license": "FSL-1.1-MIT",
|
|
44
50
|
"homepage": "https://www.scopeblind.com",
|
|
45
51
|
"repository": {
|
|
46
52
|
"type": "git",
|
|
47
|
-
"url": "https://github.com/tomjwxf/scopeblind-gateway"
|
|
53
|
+
"url": "git+https://github.com/tomjwxf/scopeblind-gateway.git"
|
|
48
54
|
},
|
|
49
55
|
"dependencies": {
|
|
50
56
|
"@noble/curves": "^1.8.0",
|