@blink-authority-com/claude-code-plugin 1.0.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -0
  3. package/dist/bsec-client.d.ts +35 -0
  4. package/dist/bsec-client.d.ts.map +1 -0
  5. package/dist/bsec-client.js +122 -0
  6. package/dist/bsec-client.js.map +1 -0
  7. package/dist/docs/cache.d.ts +19 -0
  8. package/dist/docs/cache.d.ts.map +1 -0
  9. package/dist/docs/cache.js +92 -0
  10. package/dist/docs/cache.js.map +1 -0
  11. package/dist/docs/fetcher.d.ts +19 -0
  12. package/dist/docs/fetcher.d.ts.map +1 -0
  13. package/dist/docs/fetcher.js +81 -0
  14. package/dist/docs/fetcher.js.map +1 -0
  15. package/dist/docs/parser.d.ts +33 -0
  16. package/dist/docs/parser.d.ts.map +1 -0
  17. package/dist/docs/parser.js +145 -0
  18. package/dist/docs/parser.js.map +1 -0
  19. package/dist/docs/search.d.ts +38 -0
  20. package/dist/docs/search.d.ts.map +1 -0
  21. package/dist/docs/search.js +180 -0
  22. package/dist/docs/search.js.map +1 -0
  23. package/dist/docs/tools/api.d.ts +12 -0
  24. package/dist/docs/tools/api.d.ts.map +1 -0
  25. package/dist/docs/tools/api.js +58 -0
  26. package/dist/docs/tools/api.js.map +1 -0
  27. package/dist/docs/tools/cli.d.ts +12 -0
  28. package/dist/docs/tools/cli.d.ts.map +1 -0
  29. package/dist/docs/tools/cli.js +56 -0
  30. package/dist/docs/tools/cli.js.map +1 -0
  31. package/dist/docs/tools/concepts.d.ts +18 -0
  32. package/dist/docs/tools/concepts.d.ts.map +1 -0
  33. package/dist/docs/tools/concepts.js +136 -0
  34. package/dist/docs/tools/concepts.js.map +1 -0
  35. package/dist/docs/tools/sdk.d.ts +12 -0
  36. package/dist/docs/tools/sdk.d.ts.map +1 -0
  37. package/dist/docs/tools/sdk.js +72 -0
  38. package/dist/docs/tools/sdk.js.map +1 -0
  39. package/dist/docs/tools/search.d.ts +11 -0
  40. package/dist/docs/tools/search.d.ts.map +1 -0
  41. package/dist/docs/tools/search.js +36 -0
  42. package/dist/docs/tools/search.js.map +1 -0
  43. package/dist/docs/types.d.ts +70 -0
  44. package/dist/docs/types.d.ts.map +1 -0
  45. package/dist/docs/types.js +8 -0
  46. package/dist/docs/types.js.map +1 -0
  47. package/dist/index.d.ts +9 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +622 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/prompts/debug.d.ts +16 -0
  52. package/dist/prompts/debug.d.ts.map +1 -0
  53. package/dist/prompts/debug.js +34 -0
  54. package/dist/prompts/debug.js.map +1 -0
  55. package/dist/prompts/integrate.d.ts +16 -0
  56. package/dist/prompts/integrate.d.ts.map +1 -0
  57. package/dist/prompts/integrate.js +30 -0
  58. package/dist/prompts/integrate.js.map +1 -0
  59. package/dist/prompts/review.d.ts +16 -0
  60. package/dist/prompts/review.d.ts.map +1 -0
  61. package/dist/prompts/review.js +28 -0
  62. package/dist/prompts/review.js.map +1 -0
  63. package/dist/resources/changelog.d.ts +22 -0
  64. package/dist/resources/changelog.d.ts.map +1 -0
  65. package/dist/resources/changelog.js +55 -0
  66. package/dist/resources/changelog.js.map +1 -0
  67. package/dist/resources/errors.d.ts +16 -0
  68. package/dist/resources/errors.d.ts.map +1 -0
  69. package/dist/resources/errors.js +103 -0
  70. package/dist/resources/errors.js.map +1 -0
  71. package/dist/resources/patterns.d.ts +16 -0
  72. package/dist/resources/patterns.d.ts.map +1 -0
  73. package/dist/resources/patterns.js +151 -0
  74. package/dist/resources/patterns.js.map +1 -0
  75. package/dist/templates/approval-workflow.d.ts +6 -0
  76. package/dist/templates/approval-workflow.d.ts.map +1 -0
  77. package/dist/templates/approval-workflow.js +467 -0
  78. package/dist/templates/approval-workflow.js.map +1 -0
  79. package/dist/templates/audit-trail.d.ts +6 -0
  80. package/dist/templates/audit-trail.d.ts.map +1 -0
  81. package/dist/templates/audit-trail.js +396 -0
  82. package/dist/templates/audit-trail.js.map +1 -0
  83. package/dist/templates/cli-tool.d.ts +6 -0
  84. package/dist/templates/cli-tool.d.ts.map +1 -0
  85. package/dist/templates/cli-tool.js +346 -0
  86. package/dist/templates/cli-tool.js.map +1 -0
  87. package/dist/templates/express-api.d.ts +6 -0
  88. package/dist/templates/express-api.d.ts.map +1 -0
  89. package/dist/templates/express-api.js +314 -0
  90. package/dist/templates/express-api.js.map +1 -0
  91. package/dist/templates/notary.d.ts +6 -0
  92. package/dist/templates/notary.d.ts.map +1 -0
  93. package/dist/templates/notary.js +360 -0
  94. package/dist/templates/notary.js.map +1 -0
  95. package/dist/test.d.ts +8 -0
  96. package/dist/test.d.ts.map +1 -0
  97. package/dist/test.js +140 -0
  98. package/dist/test.js.map +1 -0
  99. package/dist/tools/add-signing.d.ts +19 -0
  100. package/dist/tools/add-signing.d.ts.map +1 -0
  101. package/dist/tools/add-signing.js +317 -0
  102. package/dist/tools/add-signing.js.map +1 -0
  103. package/dist/tools/decode.d.ts +13 -0
  104. package/dist/tools/decode.d.ts.map +1 -0
  105. package/dist/tools/decode.js +262 -0
  106. package/dist/tools/decode.js.map +1 -0
  107. package/dist/tools/hierarchy.d.ts +13 -0
  108. package/dist/tools/hierarchy.d.ts.map +1 -0
  109. package/dist/tools/hierarchy.js +319 -0
  110. package/dist/tools/hierarchy.js.map +1 -0
  111. package/dist/tools/lint.d.ts +13 -0
  112. package/dist/tools/lint.d.ts.map +1 -0
  113. package/dist/tools/lint.js +323 -0
  114. package/dist/tools/lint.js.map +1 -0
  115. package/dist/tools/scaffold.d.ts +11 -0
  116. package/dist/tools/scaffold.d.ts.map +1 -0
  117. package/dist/tools/scaffold.js +84 -0
  118. package/dist/tools/scaffold.js.map +1 -0
  119. package/dist/tools/sign-test.d.ts +17 -0
  120. package/dist/tools/sign-test.d.ts.map +1 -0
  121. package/dist/tools/sign-test.js +126 -0
  122. package/dist/tools/sign-test.js.map +1 -0
  123. package/dist/tools/test-vectors.d.ts +13 -0
  124. package/dist/tools/test-vectors.d.ts.map +1 -0
  125. package/dist/tools/test-vectors.js +169 -0
  126. package/dist/tools/test-vectors.js.map +1 -0
  127. package/dist/tools/verify-local.d.ts +17 -0
  128. package/dist/tools/verify-local.d.ts.map +1 -0
  129. package/dist/tools/verify-local.js +233 -0
  130. package/dist/tools/verify-local.js.map +1 -0
  131. package/dist/tools/verify-test.d.ts +17 -0
  132. package/dist/tools/verify-test.d.ts.map +1 -0
  133. package/dist/tools/verify-test.js +107 -0
  134. package/dist/tools/verify-test.js.map +1 -0
  135. package/package.json +54 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * blink_generate_test_vectors tool handler.
3
+ *
4
+ * Generates deterministic mock BLINK envelopes for unit testing.
5
+ * Uses seed-based pseudorandom generation for reproducibility.
6
+ */
7
+ import { createHash } from 'node:crypto';
8
+ // ---------------------------------------------------------------------------
9
+ // Seeded PRNG (deterministic)
10
+ // ---------------------------------------------------------------------------
11
+ class SeededRandom {
12
+ state;
13
+ constructor(seed) {
14
+ // Simple hash-based seed
15
+ let h = 0;
16
+ for (let i = 0; i < seed.length; i++) {
17
+ h = ((h << 5) - h + seed.charCodeAt(i)) | 0;
18
+ }
19
+ this.state = Math.abs(h) || 1;
20
+ }
21
+ next() {
22
+ // xorshift32
23
+ this.state ^= this.state << 13;
24
+ this.state ^= this.state >> 17;
25
+ this.state ^= this.state << 5;
26
+ return (this.state >>> 0) / 0xFFFFFFFF;
27
+ }
28
+ bytes(n) {
29
+ const buf = Buffer.alloc(n);
30
+ for (let i = 0; i < n; i++) {
31
+ buf[i] = Math.floor(this.next() * 256);
32
+ }
33
+ return buf;
34
+ }
35
+ }
36
+ // ---------------------------------------------------------------------------
37
+ // Constants
38
+ // ---------------------------------------------------------------------------
39
+ const ALGO_SIZES = {
40
+ ed25519: { sig: 64, pubkey: 32, proof: 80, pderive: 32 },
41
+ 'ml-dsa-44': { sig: 2420, pubkey: 1312, proof: 80, pderive: 32 },
42
+ };
43
+ const ALGO_DISPLAY = {
44
+ ed25519: 'Ed25519',
45
+ 'ml-dsa-44': 'ML-DSA-44',
46
+ };
47
+ // ---------------------------------------------------------------------------
48
+ // Handler
49
+ // ---------------------------------------------------------------------------
50
+ export function handleGenerateTestVectors(args) {
51
+ const count = Math.min(Math.max(Number(args.count) || 3, 1), 20);
52
+ const algorithm = (args.algorithm || 'ed25519').toLowerCase().replace(/_/g, '-');
53
+ const scenario = (args.scenario || 'valid').toLowerCase();
54
+ if (!ALGO_SIZES[algorithm]) {
55
+ return {
56
+ content: [{
57
+ type: 'text',
58
+ text: JSON.stringify({
59
+ error: `Unsupported algorithm: "${algorithm}". Use "ed25519" or "ml-dsa-44".`,
60
+ }),
61
+ }],
62
+ };
63
+ }
64
+ if (!['valid', 'expired', 'tampered', 'wrong-key'].includes(scenario)) {
65
+ return {
66
+ content: [{
67
+ type: 'text',
68
+ text: JSON.stringify({
69
+ error: `Unknown scenario: "${scenario}". Use "valid", "expired", "tampered", or "wrong-key".`,
70
+ }),
71
+ }],
72
+ };
73
+ }
74
+ const sizes = ALGO_SIZES[algorithm];
75
+ const vectors = [];
76
+ for (let i = 0; i < count; i++) {
77
+ const seed = `blink-test-vector-${algorithm}-${scenario}-${i}`;
78
+ const rng = new SeededRandom(seed);
79
+ // Generate payload
80
+ const payload = `test-payload-${scenario}-${i}-${algorithm}`;
81
+ const payloadHash = createHash('sha256').update(payload).digest('hex');
82
+ // Generate mock cryptographic fields
83
+ const signature = rng.bytes(sizes.sig).toString('base64');
84
+ const ephemeralPublicKey = rng.bytes(sizes.pubkey).toString('base64');
85
+ const vrfProof = rng.bytes(sizes.proof).toString('base64');
86
+ const pDerive = rng.bytes(sizes.pderive).toString('base64');
87
+ // Build timestamp based on scenario
88
+ let timestamp;
89
+ const now = new Date();
90
+ switch (scenario) {
91
+ case 'expired':
92
+ timestamp = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString();
93
+ break;
94
+ default:
95
+ timestamp = now.toISOString();
96
+ break;
97
+ }
98
+ // Build domain_input
99
+ const domainInput = `signing:test-identity-${i}:${timestamp}`;
100
+ // Determine final payload_hash (tampered scenario modifies it)
101
+ let finalPayloadHash = payloadHash;
102
+ if (scenario === 'tampered') {
103
+ // Flip some characters to simulate tampering
104
+ finalPayloadHash = createHash('sha256').update(payload + '-tampered').digest('hex');
105
+ }
106
+ // For wrong-key scenario, use a different P_derive
107
+ let finalPDerive = pDerive;
108
+ if (scenario === 'wrong-key') {
109
+ const wrongRng = new SeededRandom(`wrong-key-${seed}`);
110
+ finalPDerive = wrongRng.bytes(sizes.pderive).toString('base64');
111
+ }
112
+ // Build envelope
113
+ const envelope = {
114
+ signature,
115
+ ephemeral_public_key: ephemeralPublicKey,
116
+ vrf_proof: vrfProof,
117
+ p_derive: scenario === 'wrong-key' ? pDerive : finalPDerive, // original in envelope
118
+ domain_input: domainInput,
119
+ timestamp,
120
+ algorithm: ALGO_DISPLAY[algorithm],
121
+ payload_hash: scenario === 'tampered' ? finalPayloadHash : payloadHash,
122
+ };
123
+ const envelopeB64 = Buffer.from(JSON.stringify(envelope)).toString('base64');
124
+ // Expected result
125
+ let expectedValid = true;
126
+ let expectedReason = 'All fields valid, timestamp fresh, format correct';
127
+ switch (scenario) {
128
+ case 'expired':
129
+ expectedValid = false;
130
+ expectedReason = 'Envelope timestamp is 7 days old — outside freshness window';
131
+ break;
132
+ case 'tampered':
133
+ expectedValid = false;
134
+ expectedReason =
135
+ 'payload_hash does not match the original payload — document was modified after signing';
136
+ break;
137
+ case 'wrong-key':
138
+ expectedValid = false;
139
+ expectedReason =
140
+ 'P_derive in the envelope does not match the signing key — signature was produced by a different identity';
141
+ break;
142
+ }
143
+ vectors.push({
144
+ id: `tv-${String(i + 1).padStart(3, '0')}`,
145
+ payload,
146
+ envelope_b64: envelopeB64,
147
+ p_derive_b64: finalPDerive,
148
+ expected_valid: expectedValid,
149
+ expected_reason: expectedReason,
150
+ algorithm: ALGO_DISPLAY[algorithm],
151
+ });
152
+ }
153
+ const usageHint = 'Use these test vectors in your unit tests:\n' +
154
+ '1. Decode envelope_b64 with Buffer.from(envelope_b64, "base64")\n' +
155
+ '2. JSON.parse the decoded buffer to get the envelope object\n' +
156
+ '3. Pass the envelope to your verification function\n' +
157
+ '4. Assert the result matches expected_valid\n\n' +
158
+ 'Note: These are mock vectors with random (but deterministic) cryptographic data. ' +
159
+ 'They are suitable for testing parsers and format validators, but the signatures ' +
160
+ 'are not cryptographically valid. For real signature testing, use blink_sign_test ' +
161
+ 'with a live BSEC instance.';
162
+ return {
163
+ content: [{
164
+ type: 'text',
165
+ text: JSON.stringify({ vectors, usage_hint: usageHint }, null, 2),
166
+ }],
167
+ };
168
+ }
169
+ //# sourceMappingURL=test-vectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-vectors.js","sourceRoot":"","sources":["../../src/tools/test-vectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * blink_verify_local tool handler.
3
+ *
4
+ * Offline format verification of a BLINK envelope.
5
+ * Validates structure, field formats, lengths, timestamp freshness,
6
+ * domain_input format, and algorithm support.
7
+ *
8
+ * Note: Full cryptographic VRF proof chain verification requires the
9
+ * BLINK Verifier SDK. This check validates envelope format and structure.
10
+ */
11
+ export declare function handleVerifyLocal(args: Record<string, unknown>): {
12
+ content: Array<{
13
+ type: string;
14
+ text: string;
15
+ }>;
16
+ };
17
+ //# sourceMappingURL=verify-local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-local.d.ts","sourceRoot":"","sources":["../../src/tools/verify-local.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgDH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAoMpD"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * blink_verify_local tool handler.
3
+ *
4
+ * Offline format verification of a BLINK envelope.
5
+ * Validates structure, field formats, lengths, timestamp freshness,
6
+ * domain_input format, and algorithm support.
7
+ *
8
+ * Note: Full cryptographic VRF proof chain verification requires the
9
+ * BLINK Verifier SDK. This check validates envelope format and structure.
10
+ */
11
+ // ---------------------------------------------------------------------------
12
+ // Constants
13
+ // ---------------------------------------------------------------------------
14
+ const REQUIRED_FIELDS = [
15
+ 'signature',
16
+ 'ephemeral_public_key',
17
+ 'vrf_proof',
18
+ 'p_derive',
19
+ 'domain_input',
20
+ 'timestamp',
21
+ 'algorithm',
22
+ 'payload_hash',
23
+ ];
24
+ const BINARY_FIELDS = ['signature', 'ephemeral_public_key', 'vrf_proof', 'p_derive'];
25
+ const EXPECTED_SIZES = {
26
+ ed25519: { signature: 64, ephemeral_public_key: 32, vrf_proof: 80, p_derive: 32 },
27
+ 'ml-dsa-44': { signature: 2420, ephemeral_public_key: 1312, vrf_proof: 80, p_derive: 32 },
28
+ };
29
+ const SUPPORTED_ALGORITHMS = ['ed25519', 'ml-dsa-44'];
30
+ // 5 minute freshness window
31
+ const FRESHNESS_MS = 5 * 60 * 1000;
32
+ // ---------------------------------------------------------------------------
33
+ // Helpers
34
+ // ---------------------------------------------------------------------------
35
+ function isValidBase64(s) {
36
+ if (typeof s !== 'string' || s.length === 0)
37
+ return false;
38
+ try {
39
+ const buf = Buffer.from(s, 'base64');
40
+ return buf.length > 0;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ function normaliseAlgo(algo) {
47
+ return algo.toLowerCase().replace(/[_\s]/g, '-');
48
+ }
49
+ // ---------------------------------------------------------------------------
50
+ // Handler
51
+ // ---------------------------------------------------------------------------
52
+ export function handleVerifyLocal(args) {
53
+ const envelopeB64 = args.envelope;
54
+ const pDeriveB64 = args.p_derive;
55
+ if (!envelopeB64 || typeof envelopeB64 !== 'string' || envelopeB64.trim() === '') {
56
+ return {
57
+ content: [{
58
+ type: 'text',
59
+ text: JSON.stringify({
60
+ format_valid: false,
61
+ error: 'Missing or empty "envelope" parameter.',
62
+ }),
63
+ }],
64
+ };
65
+ }
66
+ if (!pDeriveB64 || typeof pDeriveB64 !== 'string' || pDeriveB64.trim() === '') {
67
+ return {
68
+ content: [{
69
+ type: 'text',
70
+ text: JSON.stringify({
71
+ format_valid: false,
72
+ error: 'Missing or empty "p_derive" parameter.',
73
+ }),
74
+ }],
75
+ };
76
+ }
77
+ const notes = [];
78
+ // Step 1: Decode envelope
79
+ let decoded;
80
+ try {
81
+ decoded = Buffer.from(envelopeB64, 'base64').toString('utf-8');
82
+ }
83
+ catch {
84
+ return {
85
+ content: [{
86
+ type: 'text',
87
+ text: JSON.stringify({
88
+ format_valid: false,
89
+ error: 'Failed to base64-decode the envelope.',
90
+ }),
91
+ }],
92
+ };
93
+ }
94
+ let envelope;
95
+ try {
96
+ envelope = JSON.parse(decoded);
97
+ }
98
+ catch {
99
+ return {
100
+ content: [{
101
+ type: 'text',
102
+ text: JSON.stringify({
103
+ format_valid: false,
104
+ error: 'Decoded data is not valid JSON.',
105
+ }),
106
+ }],
107
+ };
108
+ }
109
+ // Step 2: Validate required fields present
110
+ const presentFields = [];
111
+ const missingFields = [];
112
+ for (const field of REQUIRED_FIELDS) {
113
+ if (envelope[field] !== undefined && envelope[field] !== null) {
114
+ presentFields.push(field);
115
+ }
116
+ else {
117
+ missingFields.push(field);
118
+ }
119
+ }
120
+ const fieldsPresent = missingFields.length === 0;
121
+ if (!fieldsPresent) {
122
+ notes.push(`Missing fields: ${missingFields.join(', ')}`);
123
+ }
124
+ // Step 3: Check field formats (base64 validity, correct lengths)
125
+ let fieldsValid = true;
126
+ const fieldDetails = {};
127
+ const algo = normaliseAlgo(envelope.algorithm || 'ed25519');
128
+ const expectedSizes = EXPECTED_SIZES[algo] || EXPECTED_SIZES['ed25519'];
129
+ for (const field of BINARY_FIELDS) {
130
+ const val = envelope[field];
131
+ if (!val || typeof val !== 'string') {
132
+ fieldDetails[field] = { valid: false, reason: 'Missing or not a string' };
133
+ fieldsValid = false;
134
+ continue;
135
+ }
136
+ if (!isValidBase64(val)) {
137
+ fieldDetails[field] = { valid: false, reason: 'Invalid base64 encoding' };
138
+ fieldsValid = false;
139
+ continue;
140
+ }
141
+ const bytes = Buffer.from(val, 'base64').length;
142
+ const expected = expectedSizes[field];
143
+ if (expected && bytes !== expected) {
144
+ fieldDetails[field] = {
145
+ valid: false,
146
+ reason: `Expected ${expected} bytes for ${algo}, got ${bytes}`,
147
+ };
148
+ fieldsValid = false;
149
+ }
150
+ else {
151
+ fieldDetails[field] = { valid: true };
152
+ }
153
+ }
154
+ // payload_hash: should be 64-char hex
155
+ const payloadHash = envelope.payload_hash;
156
+ if (payloadHash && typeof payloadHash === 'string') {
157
+ if (/^[0-9a-fA-F]{64}$/.test(payloadHash)) {
158
+ fieldDetails['payload_hash'] = { valid: true };
159
+ }
160
+ else {
161
+ fieldDetails['payload_hash'] = { valid: false, reason: 'Not a 64-character hex SHA-256 hash' };
162
+ fieldsValid = false;
163
+ }
164
+ }
165
+ // Step 4: Check timestamp freshness
166
+ let timestampValid = false;
167
+ const timestamp = envelope.timestamp;
168
+ if (timestamp && typeof timestamp === 'string') {
169
+ const parsed = new Date(timestamp);
170
+ if (isNaN(parsed.getTime())) {
171
+ notes.push('Timestamp is not a valid ISO 8601 date');
172
+ }
173
+ else {
174
+ const age = Math.abs(Date.now() - parsed.getTime());
175
+ timestampValid = age <= FRESHNESS_MS;
176
+ if (!timestampValid) {
177
+ notes.push(`Timestamp age: ${Math.round(age / 1000)}s (window: ${FRESHNESS_MS / 1000}s)`);
178
+ }
179
+ }
180
+ }
181
+ // Step 5: Validate domain_input format
182
+ let domainValid = false;
183
+ const domainInput = envelope.domain_input;
184
+ if (domainInput && typeof domainInput === 'string') {
185
+ const parts = domainInput.split(':');
186
+ domainValid = parts.length >= 3 && parts[0].length > 0 && parts[1].length > 0;
187
+ if (!domainValid) {
188
+ notes.push('domain_input should follow format "purpose:identity:timestamp"');
189
+ }
190
+ }
191
+ // Step 6: Check algorithm is supported
192
+ let algorithmValid = false;
193
+ const algorithmValue = envelope.algorithm;
194
+ if (algorithmValue && typeof algorithmValue === 'string') {
195
+ algorithmValid = SUPPORTED_ALGORITHMS.includes(normaliseAlgo(algorithmValue));
196
+ if (!algorithmValid) {
197
+ notes.push(`Unsupported algorithm: "${algorithmValue}". Supported: Ed25519, ML-DSA-44`);
198
+ }
199
+ }
200
+ // Step 7: Check P_derive match
201
+ let pDeriveMatch = false;
202
+ const envelopePDerive = envelope.p_derive;
203
+ if (envelopePDerive && pDeriveB64) {
204
+ pDeriveMatch = envelopePDerive === pDeriveB64;
205
+ if (!pDeriveMatch) {
206
+ notes.push('Provided P_derive does not match the P_derive in the envelope. ' +
207
+ 'This may indicate the envelope was signed by a different identity.');
208
+ }
209
+ }
210
+ // Add standard note
211
+ notes.push('Full cryptographic VRF proof chain verification requires the BLINK Verifier SDK. ' +
212
+ 'This check validates envelope format and structure only.');
213
+ const formatValid = fieldsPresent && fieldsValid && algorithmValid && domainValid;
214
+ const result = {
215
+ format_valid: formatValid,
216
+ fields_present: fieldsPresent,
217
+ fields_valid: fieldsValid,
218
+ field_details: fieldDetails,
219
+ timestamp_valid: timestampValid,
220
+ domain_valid: domainValid,
221
+ algorithm_valid: algorithmValid,
222
+ p_derive_match: pDeriveMatch,
223
+ missing_fields: missingFields.length > 0 ? missingFields : undefined,
224
+ notes,
225
+ };
226
+ return {
227
+ content: [{
228
+ type: 'text',
229
+ text: JSON.stringify(result, null, 2),
230
+ }],
231
+ };
232
+ }
233
+ //# sourceMappingURL=verify-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-local.js","sourceRoot":"","sources":["../../src/tools/verify-local.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAC9E,MAAM,eAAe,GAAG;IACtB,WAAW;IACX,sBAAsB;IACtB,WAAW;IACX,UAAU;IACV,cAAc;IACd,WAAW;IACX,WAAW;IACX,cAAc;CACf,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,sBAAsB,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;AAErF,MAAM,cAAc,GAA2C;IAC7D,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;IACjF,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;CAC1F,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAEtD,4BAA4B;AAC5B,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAC9E,SAAS,aAAa,CAAC,CAAS;IAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACrC,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAC/B,IAA6B;IAE7B,MAAM,WAAW,GAAG,IAAI,CAAC,QAA8B,CAAC;IACxD,MAAM,UAAU,GAAG,IAAI,CAAC,QAA8B,CAAC;IAEvD,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACjF,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,YAAY,EAAE,KAAK;wBACnB,KAAK,EAAE,wCAAwC;qBAChD,CAAC;iBACH,CAAC;SACH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC9E,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,YAAY,EAAE,KAAK;wBACnB,KAAK,EAAE,wCAAwC;qBAChD,CAAC;iBACH,CAAC;SACH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,0BAA0B;IAC1B,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,YAAY,EAAE,KAAK;wBACnB,KAAK,EAAE,uCAAuC;qBAC/C,CAAC;iBACH,CAAC;SACH,CAAC;IACJ,CAAC;IAED,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,YAAY,EAAE,KAAK;wBACnB,KAAK,EAAE,iCAAiC;qBACzC,CAAC;iBACH,CAAC;SACH,CAAC;IACJ,CAAC;IAED,2CAA2C;IAC3C,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9D,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC;IACjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CAAC,mBAAmB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,iEAAiE;IACjE,IAAI,WAAW,GAAG,IAAI,CAAC;IACvB,MAAM,YAAY,GAAwD,EAAE,CAAC;IAE7E,MAAM,IAAI,GAAG,aAAa,CAAE,QAAQ,CAAC,SAAoB,IAAI,SAAS,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;IAExE,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAuB,CAAC;QAClD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;YAC1E,WAAW,GAAG,KAAK,CAAC;YACpB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;YAC1E,WAAW,GAAG,KAAK,CAAC;YACpB,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;QAChD,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,QAAQ,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,YAAY,CAAC,KAAK,CAAC,GAAG;gBACpB,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,YAAY,QAAQ,cAAc,IAAI,SAAS,KAAK,EAAE;aAC/D,CAAC;YACF,WAAW,GAAG,KAAK,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAkC,CAAC;IAChE,IAAI,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnD,IAAI,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,YAAY,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;YAC/F,WAAW,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,SAAS,GAAG,QAAQ,CAAC,SAA+B,CAAC;IAC3D,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,cAAc,GAAG,GAAG,IAAI,YAAY,CAAC;YACrC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,cAAc,YAAY,GAAG,IAAI,IAAI,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAkC,CAAC;IAChE,IAAI,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,WAAW,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,MAAM,cAAc,GAAG,QAAQ,CAAC,SAA+B,CAAC;IAChE,IAAI,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;QACzD,cAAc,GAAG,oBAAoB,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;QAC9E,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,2BAA2B,cAAc,kCAAkC,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,eAAe,GAAG,QAAQ,CAAC,QAA8B,CAAC;IAChE,IAAI,eAAe,IAAI,UAAU,EAAE,CAAC;QAClC,YAAY,GAAG,eAAe,KAAK,UAAU,CAAC;QAC9C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CACR,iEAAiE;gBACjE,oEAAoE,CACrE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,KAAK,CAAC,IAAI,CACR,mFAAmF;QACnF,0DAA0D,CAC3D,CAAC;IAEF,MAAM,WAAW,GAAG,aAAa,IAAI,WAAW,IAAI,cAAc,IAAI,WAAW,CAAC;IAElF,MAAM,MAAM,GAAG;QACb,YAAY,EAAE,WAAW;QACzB,cAAc,EAAE,aAAa;QAC7B,YAAY,EAAE,WAAW;QACzB,aAAa,EAAE,YAAY;QAC3B,eAAe,EAAE,cAAc;QAC/B,YAAY,EAAE,WAAW;QACzB,eAAe,EAAE,cAAc;QAC/B,cAAc,EAAE,YAAY;QAC5B,cAAc,EAAE,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;QACpE,KAAK;KACN,CAAC;IAEF,OAAO;QACL,OAAO,EAAE,CAAC;gBACR,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;aACtC,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * blink_verify_test tool handler.
3
+ *
4
+ * Live verification against a BSEC instance (connected mode).
5
+ * Falls back to format-only verification when BSEC is unavailable.
6
+ */
7
+ import { PluginBsecClient } from '../bsec-client.js';
8
+ type ToolResult = {
9
+ content: Array<{
10
+ type: string;
11
+ text: string;
12
+ }>;
13
+ isError?: boolean;
14
+ };
15
+ export declare function handleVerifyTest(args: Record<string, unknown>, bsecClient: PluginBsecClient | null): ToolResult | Promise<ToolResult>;
16
+ export {};
17
+ //# sourceMappingURL=verify-test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-test.d.ts","sourceRoot":"","sources":["../../src/tools/verify-test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAmB,MAAM,mBAAmB,CAAC;AAMtE,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAKxF,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,gBAAgB,GAAG,IAAI,GAClC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CA8ClC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * blink_verify_test tool handler.
3
+ *
4
+ * Live verification against a BSEC instance (connected mode).
5
+ * Falls back to format-only verification when BSEC is unavailable.
6
+ */
7
+ import { BsecClientError } from '../bsec-client.js';
8
+ import { handleVerifyLocal } from './verify-local.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Handler
11
+ // ---------------------------------------------------------------------------
12
+ export function handleVerifyTest(args, bsecClient) {
13
+ const envelopeB64 = args.envelope;
14
+ const pDeriveB64 = args.p_derive;
15
+ if (!envelopeB64 || typeof envelopeB64 !== 'string' || envelopeB64.trim() === '') {
16
+ return {
17
+ content: [{
18
+ type: 'text',
19
+ text: JSON.stringify({ error: 'Missing or empty "envelope" parameter.' }),
20
+ }],
21
+ isError: true,
22
+ };
23
+ }
24
+ if (!pDeriveB64 || typeof pDeriveB64 !== 'string' || pDeriveB64.trim() === '') {
25
+ return {
26
+ content: [{
27
+ type: 'text',
28
+ text: JSON.stringify({ error: 'Missing or empty "p_derive" parameter.' }),
29
+ }],
30
+ isError: true,
31
+ };
32
+ }
33
+ // Step 1: Always run local format verification
34
+ const localResult = handleVerifyLocal({ envelope: envelopeB64, p_derive: pDeriveB64 });
35
+ const localData = JSON.parse(localResult.content[0].text);
36
+ // Step 2: If BSEC connected, attempt server-side verification
37
+ if (bsecClient) {
38
+ return doServerVerify(bsecClient, envelopeB64, pDeriveB64, localData);
39
+ }
40
+ // Step 3: No BSEC — return format-only result
41
+ return {
42
+ content: [{
43
+ type: 'text',
44
+ text: JSON.stringify({
45
+ mode: 'offline',
46
+ format_verification: localData,
47
+ cryptographic_verification: null,
48
+ note: 'Full cryptographic VRF proof chain verification requires a connected BSEC instance. ' +
49
+ 'Start the plugin with --bsec-url and --bsec-token to enable live verification.',
50
+ }, null, 2),
51
+ }],
52
+ };
53
+ }
54
+ // ---------------------------------------------------------------------------
55
+ // Server-side verification
56
+ // ---------------------------------------------------------------------------
57
+ async function doServerVerify(client, envelopeB64, pDeriveB64, localData) {
58
+ const startMs = Date.now();
59
+ try {
60
+ const serverResult = await client.verify(envelopeB64, pDeriveB64);
61
+ const elapsedMs = Date.now() - startMs;
62
+ return {
63
+ content: [{
64
+ type: 'text',
65
+ text: JSON.stringify({
66
+ warning: 'Data was sent to an external BSEC instance for verification.',
67
+ mode: 'connected',
68
+ format_verification: localData,
69
+ cryptographic_verification: {
70
+ valid: serverResult.valid,
71
+ details: serverResult.details,
72
+ },
73
+ timing: {
74
+ elapsed_ms: elapsedMs,
75
+ },
76
+ summary: serverResult.valid
77
+ ? 'Envelope is valid. Both format and cryptographic checks passed.'
78
+ : 'Cryptographic verification failed. The VRF proof chain could not be validated.',
79
+ }, null, 2),
80
+ }],
81
+ };
82
+ }
83
+ catch (err) {
84
+ const elapsedMs = Date.now() - startMs;
85
+ const errorMsg = err instanceof BsecClientError
86
+ ? `BSEC returned status ${err.status}`
87
+ : 'Failed to connect to BSEC instance for verification';
88
+ return {
89
+ content: [{
90
+ type: 'text',
91
+ text: JSON.stringify({
92
+ mode: 'connected-fallback',
93
+ format_verification: localData,
94
+ cryptographic_verification: {
95
+ valid: null,
96
+ error: errorMsg,
97
+ },
98
+ timing: {
99
+ elapsed_ms: elapsedMs,
100
+ },
101
+ note: 'Server-side verification failed. Format verification results are still valid.',
102
+ }, null, 2),
103
+ }],
104
+ };
105
+ }
106
+ }
107
+ //# sourceMappingURL=verify-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-test.js","sourceRoot":"","sources":["../../src/tools/verify-test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@blink-authority-com/claude-code-plugin",
3
+ "version": "1.0.0",
4
+ "description": "BLINK Authority Claude Code Plugin — AI-native BLINK integration tools for Claude",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "blink-claude-plugin": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "tsx src/index.ts",
14
+ "test": "node dist/test.js",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "blink",
19
+ "mcp",
20
+ "claude",
21
+ "claude-code",
22
+ "cryptography",
23
+ "vrf",
24
+ "signing",
25
+ "ephemeral-keys",
26
+ "bsec",
27
+ "model-context-protocol"
28
+ ],
29
+ "author": "BLINK Authority",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/blink-authority/claude-code-plugin"
34
+ },
35
+ "homepage": "https://blink-authority.com",
36
+ "bugs": {
37
+ "url": "https://github.com/blink-authority/claude-code-plugin/issues"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.12.1"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^22.15.2",
44
+ "typescript": "^5.8.3"
45
+ },
46
+ "engines": {
47
+ "node": ">=18.0.0"
48
+ },
49
+ "files": [
50
+ "dist/",
51
+ "README.md",
52
+ "LICENSE"
53
+ ]
54
+ }