@lenserfight/sdk 0.2.0-alpha.3 → 0.2.0-alpha.30

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 CHANGED
@@ -58,4 +58,4 @@ surface.
58
58
 
59
59
  For the deeper walkthrough see the [SDK quickstart](https://docs.lenserfight.com/how-to/integrations/sdk-quickstart) and the [reference docs](https://docs.lenserfight.com/reference/sdk).
60
60
 
61
- Apache-2.0.
61
+ MIT.
package/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=100;class l{constructor(t){this.rpcClient=t}rpcClient;async browse(t={},r,e=20){const n=Math.max(1,Math.min(e,h)),s={p_search:t.search??null,p_cursor_created_at:r?.created_at??null,p_cursor_id:r?.id??null,p_limit:n},{data:i,error:c}=await this.rpcClient.rpc("fn_sdk_browse_agents",s);if(c)throw new Error(`@lenserfight/sdk: fn_sdk_browse_agents failed — ${JSON.stringify(c)}`);return Array.isArray(i)?i:[]}async getById(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_agent_detail",{p_agent_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_agent_detail failed — ${JSON.stringify(e)}`);return r??null}async getLensBindings(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_agent_lens_bindings",{p_agent_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_agent_lens_bindings failed — ${JSON.stringify(e)}`);return Array.isArray(r)?r:[]}async getModelBindings(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_agent_model_bindings",{p_agent_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_agent_model_bindings failed — ${JSON.stringify(e)}`);return Array.isArray(r)?r:[]}}const u=100;class _{constructor(t){this.rpcClient=t}rpcClient;async browse(t={},r,e=20){const n=Math.max(1,Math.min(e,u)),s={p_search:t.search??null,p_category:t.category??null,p_status:t.status??null,p_cursor_created_at:r?.created_at??null,p_cursor_id:r?.id??null,p_limit:n},{data:i,error:c}=await this.rpcClient.rpc("fn_browse_battles",s);if(c)throw new Error(`@lenserfight/sdk: browse failed — ${JSON.stringify(c)}`);return Array.isArray(i)?i:[]}}function d(a){if(!a.url)throw new Error("@lenserfight/sdk: createClient requires `url`");if(!a.anonKey)throw new Error("@lenserfight/sdk: createClient requires `anonKey`");const t=a.fetch??globalThis.fetch;if(typeof t!="function")throw new Error("@lenserfight/sdk: global fetch unavailable — pass `fetch` in options");const r=a.url.replace(/\/+$/,"");return{async rpc(e,n){const s=await t(`${r}/rest/v1/rpc/${e}`,{method:"POST",headers:{apikey:a.anonKey,authorization:`Bearer ${a.anonKey}`,"content-type":"application/json"},body:JSON.stringify(n??{})});if(!s.ok){const c=await s.text().catch(()=>"");return{data:null,error:{status:s.status,message:c||s.statusText}}}return{data:await s.json().catch(()=>null),error:null}}}}const w=100;class p{constructor(t){this.rpcClient=t}rpcClient;async browse(t={},r,e=20){const n=Math.max(1,Math.min(e,w)),{data:s,error:i}=await this.rpcClient.rpc("fn_sdk_browse_lenses",{p_search:t.search??null,p_tag:t.tag??null,p_kind:t.kind??null,p_cursor_created_at:r?.created_at??null,p_cursor_id:r?.id??null,p_limit:n});if(i)throw new Error(`@lenserfight/sdk: fn_sdk_browse_lenses failed — ${JSON.stringify(i)}`);return Array.isArray(s)?s:[]}async search(t,r={},e,n=20){return this.browse({...r,search:t},e,n)}async getById(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_get_lens_detail_bootstrap",{p_lens_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_get_lens_detail_bootstrap failed — ${JSON.stringify(e)}`);return!r||r.error?null:r}async getVersion(t){const[r,e]=await Promise.all([this.rpcClient.rpc("fn_get_lens_version_detail",{p_version_id:t}),this.rpcClient.rpc("fn_get_lens_version_parameters",{p_version_id:t})]);if(r.error)throw new Error(`@lenserfight/sdk: fn_get_lens_version_detail failed — ${JSON.stringify(r.error)}`);if(!r.data)return null;const n=Array.isArray(r.data)?r.data[0]:r.data;return n?{...n,parameters:Array.isArray(e.data)?e.data:e.data??[]}:null}async getParameterContracts(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_get_version_contracts",{p_version_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_get_version_contracts failed — ${JSON.stringify(e)}`);if(!r)return[];const n=Array.isArray(r)?r[0]:r;if(!n)return[];const s=n.input_contract;if(!s)return[];const i=s.parameters??s.inputs;return Array.isArray(i)?i:[]}}class f{constructor(t){this.rpcClient=t}rpcClient;async getContractByVersion(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_contract",{p_version_id:t,p_content_hash:null});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_contract failed — ${JSON.stringify(e)}`);return r??null}async getContractByHash(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_contract",{p_version_id:null,p_content_hash:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_contract failed — ${JSON.stringify(e)}`);return r??null}async getManifest(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_manifest",{p_version_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_manifest failed — ${JSON.stringify(e)}`);return r??null}async getDependencies(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_dependencies",{p_content_hash:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_dependencies failed — ${JSON.stringify(e)}`);return Array.isArray(r)?r:[]}async checkCompatibility(t,r){const e=await this.getContractByHash(t);if(!e)return{compatible:!1,missingScopes:[],warnings:["Contract not found"]};const n=e.body.requiredScopes??[],s=r.filter(i=>!n.includes(i));return{compatible:s.length===0,missingScopes:s,warnings:[]}}}class g{constructor(t){this.rpcClient=t}rpcClient;async renderPrompt(t,r={}){const{data:e,error:n}=await this.rpcClient.rpc("fn_battles_render_prompt",{p_template_id:t,p_variables:r});if(n)throw new Error(`@lenserfight/sdk: renderPrompt failed — ${JSON.stringify(n)}`);return typeof e=="string"?e:""}}class o{battles;templates;lenses;agents;protocols;rpc;constructor(t){this.rpc=t,this.battles=new _(t),this.templates=new g(t),this.lenses=new p(t),this.agents=new l(t),this.protocols=new f(t)}async rpcCall(t,r){const{data:e,error:n}=await this.rpc.rpc(t,r);if(n)throw new Error(`@lenserfight/sdk: ${t} failed — ${JSON.stringify(n)}`);return e}}function y(a){const t=d(a);return new o(t)}function C(a){return new o(a)}const m="0.2.0-alpha.1";exports.AgentClient=l;exports.BattleClient=_;exports.LensClient=p;exports.LenserFightClient=o;exports.ProtocolClient=f;exports.SDK_VERSION=m;exports.TemplateClient=g;exports.createClient=y;exports.createClientFromRpc=C;exports.createFetchRpcClient=d;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=100;class f{constructor(t){this.rpcClient=t}async browse(t={},r,e=20){const n=Math.max(1,Math.min(e,p)),s={p_search:t.search??null,p_cursor_created_at:r?.created_at??null,p_cursor_id:r?.id??null,p_limit:n},{data:i,error:c}=await this.rpcClient.rpc("fn_sdk_browse_agents",s);if(c)throw new Error(`@lenserfight/sdk: fn_sdk_browse_agents failed — ${JSON.stringify(c)}`);return Array.isArray(i)?i:[]}async getById(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_agent_detail",{p_agent_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_agent_detail failed — ${JSON.stringify(e)}`);return r??null}async getLensBindings(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_agent_lens_bindings",{p_agent_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_agent_lens_bindings failed — ${JSON.stringify(e)}`);return Array.isArray(r)?r:[]}async getModelBindings(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_agent_model_bindings",{p_agent_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_agent_model_bindings failed — ${JSON.stringify(e)}`);return Array.isArray(r)?r:[]}}const h=100;class l{constructor(t){this.rpcClient=t}async browse(t={},r,e=20){const n=Math.max(1,Math.min(e,h)),s={p_search:t.search??null,p_category:t.category??null,p_status:t.status??null,p_cursor_created_at:r?.created_at??null,p_cursor_id:r?.id??null,p_limit:n},{data:i,error:c}=await this.rpcClient.rpc("fn_browse_battles",s);if(c)throw new Error(`@lenserfight/sdk: browse failed — ${JSON.stringify(c)}`);return Array.isArray(i)?i:[]}}function _(a){if(!a.url)throw new Error("@lenserfight/sdk: createClient requires `url`");if(!a.anonKey)throw new Error("@lenserfight/sdk: createClient requires `anonKey`");const t=a.fetch??globalThis.fetch;if(typeof t!="function")throw new Error("@lenserfight/sdk: global fetch unavailable — pass `fetch` in options");const r=a.url.replace(/\/+$/,"");return{async rpc(e,n){const s=await t(`${r}/rest/v1/rpc/${e}`,{method:"POST",headers:{apikey:a.anonKey,authorization:`Bearer ${a.anonKey}`,"content-type":"application/json"},body:JSON.stringify(n??{})});if(!s.ok){const c=await s.text().catch(()=>"");return{data:null,error:{status:s.status,message:c||s.statusText}}}return{data:await s.json().catch(()=>null),error:null}}}}const g=100;class u{constructor(t){this.rpcClient=t}async browse(t={},r,e=20){const n=Math.max(1,Math.min(e,g)),{data:s,error:i}=await this.rpcClient.rpc("fn_sdk_browse_lenses",{p_search:t.search??null,p_tag:t.tag??null,p_kind:t.kind??null,p_cursor_created_at:r?.created_at??null,p_cursor_id:r?.id??null,p_limit:n});if(i)throw new Error(`@lenserfight/sdk: fn_sdk_browse_lenses failed — ${JSON.stringify(i)}`);return Array.isArray(s)?s:[]}async search(t,r={},e,n=20){return this.browse({...r,search:t},e,n)}async getById(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_get_lens_detail_bootstrap",{p_lens_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_get_lens_detail_bootstrap failed — ${JSON.stringify(e)}`);return!r||r.error?null:r}async getVersion(t){const[r,e]=await Promise.all([this.rpcClient.rpc("fn_get_lens_version_detail",{p_version_id:t}),this.rpcClient.rpc("fn_get_lens_version_parameters",{p_version_id:t})]);if(r.error)throw new Error(`@lenserfight/sdk: fn_get_lens_version_detail failed — ${JSON.stringify(r.error)}`);if(!r.data)return null;const n=Array.isArray(r.data)?r.data[0]:r.data;return n?{...n,parameters:Array.isArray(e.data)?e.data:e.data??[]}:null}async getParameterContracts(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_get_version_contracts",{p_version_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_get_version_contracts failed — ${JSON.stringify(e)}`);if(!r)return[];const n=Array.isArray(r)?r[0]:r;if(!n)return[];const s=n.input_contract;if(!s)return[];const i=s.parameters??s.inputs;return Array.isArray(i)?i:[]}}class w{constructor(t){this.rpcClient=t}async getContractByVersion(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_contract",{p_version_id:t,p_content_hash:null});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_contract failed — ${JSON.stringify(e)}`);return r??null}async getContractByHash(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_contract",{p_version_id:null,p_content_hash:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_contract failed — ${JSON.stringify(e)}`);return r??null}async getManifest(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_manifest",{p_version_id:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_manifest failed — ${JSON.stringify(e)}`);return r??null}async getDependencies(t){const{data:r,error:e}=await this.rpcClient.rpc("fn_sdk_get_dependencies",{p_content_hash:t});if(e)throw new Error(`@lenserfight/sdk: fn_sdk_get_dependencies failed — ${JSON.stringify(e)}`);return Array.isArray(r)?r:[]}async checkCompatibility(t,r){const e=await this.getContractByHash(t);if(!e)return{compatible:!1,missingScopes:[],warnings:["Contract not found"]};const n=e.body.requiredScopes??[],s=r.filter(i=>!n.includes(i));return{compatible:s.length===0,missingScopes:s,warnings:[]}}}class d{constructor(t){this.rpcClient=t}async renderPrompt(t,r={}){const{data:e,error:n}=await this.rpcClient.rpc("fn_battles_render_prompt",{p_template_id:t,p_variables:r});if(n)throw new Error(`@lenserfight/sdk: renderPrompt failed — ${JSON.stringify(n)}`);return typeof e=="string"?e:""}}class o{agents;battles;lenses;protocols;templates;rpc;constructor(t){this.rpc=t,this.agents=new f(t),this.battles=new l(t),this.lenses=new u(t),this.protocols=new w(t),this.templates=new d(t)}async rpcCall(t,r){const{data:e,error:n}=await this.rpc.rpc(t,r);if(n)throw new Error(`@lenserfight/sdk: ${t} failed — ${JSON.stringify(n)}`);return e}}function y(a){const t=_(a);return new o(t)}function m(a){return new o(a)}const k="0.1.0-alpha.1";exports.BattleClient=l;exports.LenserFightClient=o;exports.SDK_VERSION=k;exports.TemplateClient=d;exports.createClient=y;exports.createClientFromRpc=m;exports.createFetchRpcClient=_;
package/index.d.ts CHANGED
@@ -1,13 +1,7 @@
1
1
  export { createClient, createClientFromRpc, LenserFightClient } from './lib/lenserfight-client';
2
2
  export { BattleClient } from './lib/battle-client';
3
3
  export { TemplateClient } from './lib/template-client';
4
- export { LensClient } from './lib/lens-client';
5
- export { AgentClient } from './lib/agent-client';
6
- export { ProtocolClient } from './lib/protocol-client';
7
4
  export { createFetchRpcClient } from './lib/client';
8
5
  export type { SupabaseLikeRpcClient } from './lib/client';
9
6
  export type { BattleLifecycleStatus, BrowseFilters, BrowseCursor, BrowseBattle, BattleTemplate, CreateClientOptions, } from './lib/types';
10
- export type { SdkLensKind, SdkVisibility, SdkContentStatus, SdkLensAuthor, SdkLensTag, SdkLensSummary, SdkLensDetail, SdkLensVersionSummary, SdkLensVersion, SdkLensParameter, SdkParameterTool, LensBrowseFilters, } from './lib/types/lenses';
11
- export type { SdkAgentRuntimePref, SdkAgentModelBindingMode, SdkAgentSummary, SdkAgentDetail, SdkAgentCapabilities, SdkAgentStats, SdkAgentOwner, SdkAgentLensBinding, SdkAgentModelBinding, AgentBrowseFilters, } from './lib/types/agents';
12
- export type { SdkContractKind, SdkChannel, SdkSignatureAlgorithm, SdkParameterClassification, SdkParameterKind, SdkParameterScope, SdkDependencyBinding, SdkParameterDefault, SdkParameterValidation, SdkParameterContract, SdkOutputDefinition, SdkDependencyReference, SdkLensContractBody, SdkLensContract, SdkContractSignature, SdkLensManifest, SdkDependencyEdge, SdkCompatibilityResult, } from './lib/types/protocols';
13
- export declare const SDK_VERSION = "0.2.0-alpha.1";
7
+ export declare const SDK_VERSION = "0.1.0-alpha.1";
package/index.mjs CHANGED
@@ -2,7 +2,6 @@ class l {
2
2
  constructor(r) {
3
3
  this.rpcClient = r;
4
4
  }
5
- rpcClient;
6
5
  /**
7
6
  * Browse public AI agents. Only agents with `is_public_policy = true` are visible.
8
7
  * Keyset pagination on (created_at DESC, id DESC).
@@ -13,9 +12,9 @@ class l {
13
12
  p_cursor_created_at: t?.created_at ?? null,
14
13
  p_cursor_id: t?.id ?? null,
15
14
  p_limit: n
16
- }, { data: i, error: c } = await this.rpcClient.rpc("fn_sdk_browse_agents", s);
17
- if (c)
18
- throw new Error(`@lenserfight/sdk: fn_sdk_browse_agents failed — ${JSON.stringify(c)}`);
15
+ }, { data: i, error: o } = await this.rpcClient.rpc("fn_sdk_browse_agents", s);
16
+ if (o)
17
+ throw new Error(`@lenserfight/sdk: fn_sdk_browse_agents failed — ${JSON.stringify(o)}`);
19
18
  return Array.isArray(i) ? i : [];
20
19
  }
21
20
  /**
@@ -63,7 +62,6 @@ class d {
63
62
  constructor(r) {
64
63
  this.rpcClient = r;
65
64
  }
66
- rpcClient;
67
65
  /**
68
66
  * Browse public battles. Calls `public.fn_browse_battles` (SECURITY DEFINER,
69
67
  * grants EXECUTE to anon + authenticated). Returns at most 100 rows per call
@@ -79,15 +77,15 @@ class d {
79
77
  p_cursor_created_at: t?.created_at ?? null,
80
78
  p_cursor_id: t?.id ?? null,
81
79
  p_limit: n
82
- }, { data: i, error: c } = await this.rpcClient.rpc("fn_browse_battles", s);
83
- if (c)
80
+ }, { data: i, error: o } = await this.rpcClient.rpc("fn_browse_battles", s);
81
+ if (o)
84
82
  throw new Error(
85
- `@lenserfight/sdk: browse failed — ${JSON.stringify(c)}`
83
+ `@lenserfight/sdk: browse failed — ${JSON.stringify(o)}`
86
84
  );
87
85
  return Array.isArray(i) ? i : [];
88
86
  }
89
87
  }
90
- function p(a) {
88
+ function f(a) {
91
89
  if (!a.url)
92
90
  throw new Error("@lenserfight/sdk: createClient requires `url`");
93
91
  if (!a.anonKey)
@@ -108,27 +106,26 @@ function p(a) {
108
106
  body: JSON.stringify(n ?? {})
109
107
  });
110
108
  if (!s.ok) {
111
- const c = await s.text().catch(() => "");
109
+ const o = await s.text().catch(() => "");
112
110
  return {
113
111
  data: null,
114
- error: { status: s.status, message: c || s.statusText }
112
+ error: { status: s.status, message: o || s.statusText }
115
113
  };
116
114
  }
117
115
  return { data: await s.json().catch(() => null), error: null };
118
116
  }
119
117
  };
120
118
  }
121
- const f = 100;
119
+ const p = 100;
122
120
  class h {
123
121
  constructor(r) {
124
122
  this.rpcClient = r;
125
123
  }
126
- rpcClient;
127
124
  /**
128
125
  * Browse public lenses. Keyset pagination on (created_at DESC, id DESC).
129
126
  */
130
127
  async browse(r = {}, t, e = 20) {
131
- const n = Math.max(1, Math.min(e, f)), { data: s, error: i } = await this.rpcClient.rpc("fn_sdk_browse_lenses", {
128
+ const n = Math.max(1, Math.min(e, p)), { data: s, error: i } = await this.rpcClient.rpc("fn_sdk_browse_lenses", {
132
129
  p_search: r.search ?? null,
133
130
  p_tag: r.tag ?? null,
134
131
  p_kind: r.kind ?? null,
@@ -198,7 +195,6 @@ class g {
198
195
  constructor(r) {
199
196
  this.rpcClient = r;
200
197
  }
201
- rpcClient;
202
198
  /**
203
199
  * Get the contract for a lens version (by version_id).
204
200
  * Uses `fn_sdk_get_contract(p_version_id)`.
@@ -263,7 +259,6 @@ class u {
263
259
  constructor(r) {
264
260
  this.rpcClient = r;
265
261
  }
266
- rpcClient;
267
262
  /**
268
263
  * Render a template's task_prompt with the supplied variable values.
269
264
  * Calls `public.fn_battles_render_prompt` (SECURITY DEFINER, EXEC granted
@@ -282,15 +277,15 @@ class u {
282
277
  return typeof e == "string" ? e : "";
283
278
  }
284
279
  }
285
- class o {
280
+ class c {
281
+ agents;
286
282
  battles;
287
- templates;
288
283
  lenses;
289
- agents;
290
284
  protocols;
285
+ templates;
291
286
  rpc;
292
287
  constructor(r) {
293
- this.rpc = r, this.battles = new d(r), this.templates = new u(r), this.lenses = new h(r), this.agents = new l(r), this.protocols = new g(r);
288
+ this.rpc = r, this.agents = new l(r), this.battles = new d(r), this.lenses = new h(r), this.protocols = new g(r), this.templates = new u(r);
294
289
  }
295
290
  /**
296
291
  * Direct RPC escape hatch. Use sparingly — anything that's part of the
@@ -305,22 +300,19 @@ class o {
305
300
  }
306
301
  }
307
302
  function w(a) {
308
- const r = p(a);
309
- return new o(r);
303
+ const r = f(a);
304
+ return new c(r);
310
305
  }
311
306
  function y(a) {
312
- return new o(a);
307
+ return new c(a);
313
308
  }
314
- const m = "0.2.0-alpha.1";
309
+ const m = "0.1.0-alpha.1";
315
310
  export {
316
- l as AgentClient,
317
311
  d as BattleClient,
318
- h as LensClient,
319
- o as LenserFightClient,
320
- g as ProtocolClient,
312
+ c as LenserFightClient,
321
313
  m as SDK_VERSION,
322
314
  u as TemplateClient,
323
315
  w as createClient,
324
316
  y as createClientFromRpc,
325
- p as createFetchRpcClient
317
+ f as createFetchRpcClient
326
318
  };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@lenserfight/sdk",
3
- "version": "0.2.0-alpha.3",
3
+ "version": "0.2.0-alpha.30",
4
4
  "description": "LenserFight public client SDK — read battles, lenses, agents, protocols, and templates from any Supabase-backed deployment",
5
- "license": "Apache-2.0",
5
+ "license": "MIT",
6
6
  "main": "./index.cjs",
7
7
  "module": "./index.mjs",
8
8
  "types": "./index.d.ts",
@@ -24,9 +24,7 @@
24
24
  "ai-agents",
25
25
  "supabase",
26
26
  "evaluation",
27
- "battles",
28
- "lenses",
29
- "protocols"
27
+ "battles"
30
28
  ],
31
29
  "repository": {
32
30
  "type": "git",