@absolutejs/voice 0.0.22-beta.183 → 0.0.22-beta.184

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.d.ts CHANGED
@@ -105,7 +105,7 @@ export type { VoicePhoneAgentCarrier, VoicePhoneAgentCarrierSummary, VoicePhoneA
105
105
  export type { VoicePhoneAgentProductionSmokeIssue, VoicePhoneAgentProductionSmokeHandlerOptions, VoicePhoneAgentProductionSmokeHTMLHandlerOptions, VoicePhoneAgentProductionSmokeOptions, VoicePhoneAgentProductionSmokeReport, VoicePhoneAgentProductionSmokeRoutesOptions, VoicePhoneAgentProductionSmokeRequirement } from './phoneAgentProductionSmoke';
106
106
  export type { VoiceOpsConsoleLink, VoiceOpsConsoleReport, VoiceOpsConsoleRoutesOptions } from './opsConsoleRoutes';
107
107
  export type { VoiceOpsStatus, VoiceOpsStatusLink, VoiceOpsStatusOptions, VoiceOpsStatusReport, VoiceOpsStatusRoutesOptions } from './opsStatus';
108
- export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateProfile, VoiceProductionReadinessGateProfileSurface, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessProfileExplanation, VoiceProductionReadinessProfileSurface, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
108
+ export type { VoiceProductionReadinessAction, VoiceProductionReadinessAuditOptions, VoiceProductionReadinessAuditRequirement, VoiceProductionReadinessAuditSummary, VoiceProductionReadinessCheck, VoiceProductionReadinessGateIssue, VoiceProductionReadinessGateOptions, VoiceProductionReadinessGateProfile, VoiceProductionReadinessGateProfileSurface, VoiceProductionReadinessGateReport, VoiceProductionReadinessOpsActionHistoryOptions, VoiceProductionReadinessOpsActionHistorySummary, VoiceProductionReadinessOperationsRecordLink, VoiceProductionReadinessOperationsRecordLinks, VoiceProductionReadinessProfileExplanation, VoiceProductionReadinessProfileSurface, VoiceProductionReadinessProofSource, VoiceProductionReadinessReport, VoiceProductionReadinessRoutesOptions, VoiceProductionReadinessTraceDeliverySummary, VoiceProductionReadinessAuditDeliveryOptions, VoiceProductionReadinessAuditDeliverySummary, VoiceProductionReadinessTraceDeliveryOptions, VoiceProductionReadinessStatus } from './productionReadiness';
109
109
  export type { VoiceReadinessProfileName, VoiceReadinessProfileOptions, VoiceReadinessProfileRecommendation, VoiceReadinessProfileRecommendationScore, VoiceReadinessProfileRoutesOptions } from './readinessProfiles';
110
110
  export type { VoiceProviderStackChoice, VoiceProviderStackCapabilities, VoiceProviderStackCapabilityGap, VoiceProviderStackCapabilityGapInput, VoiceProviderStackCapabilityGapReport, VoiceProviderContractCheck, VoiceProviderContractCheckStatus, VoiceProviderContractDefinition, VoiceProviderContractMatrixHandlerOptions, VoiceProviderContractMatrixHTMLHandlerOptions, VoiceProviderContractMatrixInput, VoiceProviderContractMatrixPresetOptions, VoiceProviderContractMatrixReport, VoiceProviderContractMatrixRoutesOptions, VoiceProviderContractMatrixRow, VoiceProviderStackInput, VoiceProviderStackKind, VoiceProviderStackRecommendation } from './providerStackRecommendations';
111
111
  export type { VoiceOperationsRecord, VoiceOperationsRecordAgentHandoff, VoiceOperationsRecordAuditSummary, VoiceOperationsRecordOptions, VoiceOperationsRecordOutcome, VoiceOperationsRecordRoutesOptions, VoiceOperationsRecordStatus, VoiceOperationsRecordTool } from './operationsRecord';
package/dist/index.js CHANGED
@@ -20482,6 +20482,7 @@ var readinessGateCodes = {
20482
20482
  "Delivery runtime": "voice.readiness.delivery_runtime",
20483
20483
  "Handoff delivery": "voice.readiness.handoff_delivery",
20484
20484
  "Live latency proof": "voice.readiness.live_latency",
20485
+ "Operations records": "voice.readiness.operations_records",
20485
20486
  "Operator action history": "voice.readiness.operator_action_history",
20486
20487
  "Phone agent production smoke": "voice.readiness.phone_agent_smoke",
20487
20488
  "Provider contract matrix": "voice.readiness.provider_contract_matrix",
@@ -20810,6 +20811,46 @@ var summarizeLiveLatency = (events, options) => {
20810
20811
  warnings
20811
20812
  };
20812
20813
  };
20814
+ var getString12 = (value) => typeof value === "string" ? value : undefined;
20815
+ var getNumber7 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
20816
+ var voiceOperationsRecordHref = (base, sessionId) => {
20817
+ const encoded = encodeURIComponent(sessionId);
20818
+ if (base.includes(":sessionId")) {
20819
+ return base.replace(":sessionId", encoded);
20820
+ }
20821
+ return `${base.replace(/\/+$/, "")}/${encoded}`;
20822
+ };
20823
+ var buildOperationsRecordLinks = (input) => {
20824
+ const failedSessionSet = new Set(input.failedSessionIds);
20825
+ const providerErrors = input.events.filter((event) => event.type === "session.error" && (event.payload.providerStatus === "error" || typeof event.payload.error === "string")).map((event) => ({
20826
+ detail: getString12(event.payload.error),
20827
+ href: voiceOperationsRecordHref(input.base, event.sessionId),
20828
+ label: "Open provider error operations record",
20829
+ sessionId: event.sessionId,
20830
+ status: "fail"
20831
+ }));
20832
+ const failingLatency = input.events.filter((event) => event.type === "client.live_latency").map((event) => ({
20833
+ event,
20834
+ latencyMs: getNumber7(event.payload.latencyMs) ?? getNumber7(event.payload.elapsedMs)
20835
+ })).filter((entry) => entry.latencyMs !== undefined && entry.latencyMs > input.liveLatencyWarnAfterMs).map(({ event, latencyMs }) => ({
20836
+ detail: `${latencyMs}ms live latency`,
20837
+ href: voiceOperationsRecordHref(input.base, event.sessionId),
20838
+ label: "Open latency operations record",
20839
+ sessionId: event.sessionId,
20840
+ status: latencyMs > input.liveLatencyFailAfterMs ? "fail" : "warn"
20841
+ }));
20842
+ return {
20843
+ failedSessions: input.failedSessionIds.map((sessionId) => ({
20844
+ href: voiceOperationsRecordHref(input.base, sessionId),
20845
+ label: "Open failed session operations record",
20846
+ sessionId,
20847
+ status: failedSessionSet.has(sessionId) ? "fail" : "warn"
20848
+ })),
20849
+ failingLatency,
20850
+ providerErrors
20851
+ };
20852
+ };
20853
+ var firstOperationsRecordHref = (links) => links[0]?.href;
20813
20854
  var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20814
20855
  const request = input.request ?? new Request("http://localhost/");
20815
20856
  const query = input.query ?? {};
@@ -20873,6 +20914,14 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20873
20914
  const deliveryRuntime = summarizeDeliveryRuntime(deliveryRuntimeSummary);
20874
20915
  const degradedProviders = providers.filter((provider) => provider.status === "degraded" || provider.status === "rate-limited" || provider.status === "suppressed").length;
20875
20916
  const failedSessions = sessions.filter((session) => session.status === "failed").length;
20917
+ const failedSessionItems = sessions.filter((session) => session.status === "failed");
20918
+ const operationsRecords = buildOperationsRecordLinks({
20919
+ base: options.links?.operationsRecords ?? "/voice-operations",
20920
+ events,
20921
+ failedSessionIds: failedSessionItems.map((session) => session.sessionId),
20922
+ liveLatencyFailAfterMs: options.liveLatencyFailAfterMs ?? 3200,
20923
+ liveLatencyWarnAfterMs: options.liveLatencyWarnAfterMs ?? 1800
20924
+ });
20876
20925
  const checks = [
20877
20926
  {
20878
20927
  detail: quality.status === "pass" ? "Quality gates are passing." : "Quality gates need attention.",
@@ -20904,11 +20953,18 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20904
20953
  },
20905
20954
  {
20906
20955
  detail: providerRecovery.unresolvedErrors > 0 ? `${providerRecovery.unresolvedErrors} provider error(s) have no recovered fallback evidence.` : providerRecovery.recovered > 0 ? `${providerRecovery.recovered} provider fallback recovery event(s) kept sessions healthy.` : "No provider fallback recovery was needed in the current trace window.",
20907
- href: options.links?.resilience ?? "/resilience",
20956
+ href: firstOperationsRecordHref(operationsRecords.providerErrors) ?? options.links?.resilience ?? "/resilience",
20908
20957
  label: "Provider fallback recovery",
20909
20958
  status: providerRecovery.status,
20910
20959
  value: providerRecovery.total === 0 ? "0 events" : `${providerRecovery.recovered}/${providerRecovery.total}`,
20911
20960
  actions: providerRecovery.status === "pass" ? [] : [
20961
+ ...firstOperationsRecordHref(operationsRecords.providerErrors) ? [
20962
+ {
20963
+ description: "Open the exact call/session operations record for the first unresolved provider error.",
20964
+ href: firstOperationsRecordHref(operationsRecords.providerErrors),
20965
+ label: "Open failing operations record"
20966
+ }
20967
+ ] : [],
20912
20968
  {
20913
20969
  description: "Open provider resilience traces and inspect unresolved provider errors.",
20914
20970
  href: options.links?.resilience ?? "/resilience",
@@ -20918,11 +20974,18 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20918
20974
  },
20919
20975
  {
20920
20976
  detail: failedSessions === 0 ? sessions.length > 0 ? "Recent sessions have no recorded provider/session failures." : "No sessions have been recorded yet; run a smoke or live session for proof." : `${failedSessions} recent session(s) have failures.`,
20921
- href: options.links?.sessions ?? "/sessions",
20977
+ href: firstOperationsRecordHref(operationsRecords.failedSessions) ?? options.links?.sessions ?? "/sessions",
20922
20978
  label: "Session health",
20923
20979
  status: failedSessions > 0 ? "fail" : sessions.length === 0 ? "warn" : "pass",
20924
20980
  value: `${sessions.length - failedSessions}/${sessions.length}`,
20925
20981
  actions: failedSessions > 0 ? [
20982
+ ...firstOperationsRecordHref(operationsRecords.failedSessions) ? [
20983
+ {
20984
+ description: "Open the exact failed call/session operations record.",
20985
+ href: firstOperationsRecordHref(operationsRecords.failedSessions),
20986
+ label: "Open failed operations record"
20987
+ }
20988
+ ] : [],
20926
20989
  {
20927
20990
  description: "Open failed sessions and replay traces.",
20928
20991
  href: `${options.links?.sessions ?? "/sessions"}?status=failed`,
@@ -20974,12 +21037,19 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
20974
21037
  const proofSource = (...keys) => keys.map((key) => proofSources?.[key]).find((source) => source !== undefined);
20975
21038
  checks.push({
20976
21039
  detail: liveLatency.total === 0 ? "No browser live-latency measurements are recorded yet." : liveLatency.status === "pass" ? `Live browser turn latency averages ${liveLatency.averageLatencyMs}ms.` : `${liveLatency.failed} failed and ${liveLatency.warnings} warned live-latency measurement(s).`,
20977
- href: options.links?.liveLatency ?? "/traces",
21040
+ href: firstOperationsRecordHref(operationsRecords.failingLatency) ?? options.links?.liveLatency ?? "/traces",
20978
21041
  label: "Live latency proof",
20979
21042
  proofSource: proofSource("liveLatency", "liveLatencyProof"),
20980
21043
  status: liveLatency.status,
20981
21044
  value: liveLatency.averageLatencyMs === undefined ? `${liveLatency.total} samples` : `${liveLatency.averageLatencyMs}ms avg`,
20982
21045
  actions: liveLatency.status === "pass" ? [] : [
21046
+ ...firstOperationsRecordHref(operationsRecords.failingLatency) ? [
21047
+ {
21048
+ description: "Open the exact call/session operations record for the slow live turn.",
21049
+ href: firstOperationsRecordHref(operationsRecords.failingLatency),
21050
+ label: "Open latency operations record"
21051
+ }
21052
+ ] : [],
20983
21053
  {
20984
21054
  description: "Run a live browser voice turn and inspect the persisted latency trace.",
20985
21055
  href: options.links?.liveLatency ?? "/traces",
@@ -21260,6 +21330,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
21260
21330
  handoffs: "/handoffs",
21261
21331
  handoffRetry: "/api/voice-handoffs/retry",
21262
21332
  liveLatency: "/traces",
21333
+ operationsRecords: "/voice-operations",
21263
21334
  opsActions: "/voice/ops-actions",
21264
21335
  phoneAgentSmoke: "/sessions",
21265
21336
  providerContracts: "/provider-contracts",
@@ -21272,6 +21343,7 @@ var buildVoiceProductionReadinessReport = async (options, input = {}) => {
21272
21343
  ...options.links
21273
21344
  },
21274
21345
  profile: options.profile || undefined,
21346
+ operationsRecords,
21275
21347
  proofSources,
21276
21348
  status: rollupStatus2(checks),
21277
21349
  summary: {
@@ -22193,11 +22265,11 @@ import { Elysia as Elysia37 } from "elysia";
22193
22265
  // src/traceTimeline.ts
22194
22266
  import { Elysia as Elysia36 } from "elysia";
22195
22267
  var escapeHtml38 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
22196
- var getString12 = (value) => typeof value === "string" && value.trim() ? value : undefined;
22197
- var getNumber7 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
22268
+ var getString13 = (value) => typeof value === "string" && value.trim() ? value : undefined;
22269
+ var getNumber8 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
22198
22270
  var firstString3 = (payload, keys) => {
22199
22271
  for (const key of keys) {
22200
- const value = getString12(payload[key]);
22272
+ const value = getString13(payload[key]);
22201
22273
  if (value) {
22202
22274
  return value;
22203
22275
  }
@@ -22206,7 +22278,7 @@ var firstString3 = (payload, keys) => {
22206
22278
  };
22207
22279
  var firstNumber3 = (payload, keys) => {
22208
22280
  for (const key of keys) {
22209
- const value = getNumber7(payload[key]);
22281
+ const value = getNumber8(payload[key]);
22210
22282
  if (value !== undefined) {
22211
22283
  return value;
22212
22284
  }
@@ -22234,15 +22306,15 @@ var timelineLabel = (event) => {
22234
22306
  case "turn.transcript":
22235
22307
  return event.payload.isFinal === true ? "Final transcript" : "Partial transcript";
22236
22308
  case "turn.committed":
22237
- return `Committed turn${getString12(event.payload.reason) ? ` (${getString12(event.payload.reason)})` : ""}`;
22309
+ return `Committed turn${getString13(event.payload.reason) ? ` (${getString13(event.payload.reason)})` : ""}`;
22238
22310
  case "turn.assistant":
22239
22311
  return "Assistant reply";
22240
22312
  case "agent.model":
22241
22313
  return `Model call${eventProvider(event) ? ` via ${eventProvider(event)}` : ""}`;
22242
22314
  case "agent.tool":
22243
- return `Tool ${getString12(event.payload.toolName) ?? "call"}`;
22315
+ return `Tool ${getString13(event.payload.toolName) ?? "call"}`;
22244
22316
  case "agent.handoff":
22245
- return `Agent handoff${getString12(event.payload.targetAgentId) ? ` to ${getString12(event.payload.targetAgentId)}` : ""}`;
22317
+ return `Agent handoff${getString13(event.payload.targetAgentId) ? ` to ${getString13(event.payload.targetAgentId)}` : ""}`;
22246
22318
  case "assistant.run":
22247
22319
  return `Assistant run${eventProvider(event) ? ` via ${eventProvider(event)}` : ""}`;
22248
22320
  case "assistant.guardrail":
@@ -22252,11 +22324,11 @@ var timelineLabel = (event) => {
22252
22324
  case "client.live_latency":
22253
22325
  return `Live latency${eventElapsedMs(event) !== undefined ? ` ${eventElapsedMs(event)}ms` : ""}`;
22254
22326
  case "session.error":
22255
- return `Error${getString12(event.payload.error) ? `: ${getString12(event.payload.error)}` : ""}`;
22327
+ return `Error${getString13(event.payload.error) ? `: ${getString13(event.payload.error)}` : ""}`;
22256
22328
  case "turn.cost":
22257
22329
  return "Cost telemetry";
22258
22330
  case "turn_latency.stage":
22259
- return `Latency ${getString12(event.payload.stage) ?? "stage"}`;
22331
+ return `Latency ${getString13(event.payload.stage) ?? "stage"}`;
22260
22332
  case "workflow.contract":
22261
22333
  return `Workflow contract ${eventStatus(event) ?? ""}`.trim();
22262
22334
  default:
@@ -22449,26 +22521,26 @@ var createVoiceTraceTimelineRoutes = (options) => {
22449
22521
  };
22450
22522
 
22451
22523
  // src/operationsRecord.ts
22452
- var getString13 = (value) => typeof value === "string" ? value : undefined;
22453
- var getNumber8 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
22524
+ var getString14 = (value) => typeof value === "string" ? value : undefined;
22525
+ var getNumber9 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
22454
22526
  var countOutcome = (events, outcome) => events.filter((event) => event.outcome === outcome).length;
22455
22527
  var toHandoff = (event) => ({
22456
22528
  at: event.at,
22457
- fromAgentId: getString13(event.payload.fromAgentId),
22529
+ fromAgentId: getString14(event.payload.fromAgentId),
22458
22530
  metadata: event.payload.metadata && typeof event.payload.metadata === "object" && !Array.isArray(event.payload.metadata) ? event.payload.metadata : undefined,
22459
- reason: getString13(event.payload.reason),
22460
- status: getString13(event.payload.status),
22461
- summary: getString13(event.payload.summary),
22462
- targetAgentId: getString13(event.payload.targetAgentId),
22531
+ reason: getString14(event.payload.reason),
22532
+ status: getString14(event.payload.status),
22533
+ summary: getString14(event.payload.summary),
22534
+ targetAgentId: getString14(event.payload.targetAgentId),
22463
22535
  turnId: event.turnId
22464
22536
  });
22465
22537
  var toTool = (event) => ({
22466
22538
  at: event.at,
22467
- elapsedMs: getNumber8(event.payload.elapsedMs),
22468
- error: getString13(event.payload.error),
22469
- status: getString13(event.payload.status),
22470
- toolCallId: getString13(event.payload.toolCallId),
22471
- toolName: getString13(event.payload.toolName),
22539
+ elapsedMs: getNumber9(event.payload.elapsedMs),
22540
+ error: getString14(event.payload.error),
22541
+ status: getString14(event.payload.status),
22542
+ toolCallId: getString14(event.payload.toolCallId),
22543
+ toolName: getString14(event.payload.toolName),
22472
22544
  turnId: event.turnId
22473
22545
  });
22474
22546
  var resolveOutcome4 = (events) => {
@@ -23191,8 +23263,8 @@ var createVoiceTTSProviderRouter = (options) => {
23191
23263
  // src/traceDeliveryRoutes.ts
23192
23264
  import { Elysia as Elysia39 } from "elysia";
23193
23265
  var escapeHtml41 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
23194
- var getString14 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
23195
- var getNumber9 = (value) => {
23266
+ var getString15 = (value) => typeof value === "string" && value.trim() ? value.trim() : undefined;
23267
+ var getNumber10 = (value) => {
23196
23268
  if (typeof value === "number" && Number.isFinite(value)) {
23197
23269
  return value;
23198
23270
  }
@@ -23203,13 +23275,13 @@ var getNumber9 = (value) => {
23203
23275
  return;
23204
23276
  };
23205
23277
  var parseStatus2 = (value) => {
23206
- const text = getString14(value);
23278
+ const text = getString15(value);
23207
23279
  return text === "pending" || text === "delivered" || text === "failed" || text === "skipped" || text === "all" ? text : undefined;
23208
23280
  };
23209
23281
  var resolveVoiceTraceDeliveryFilter = (query = {}, base = {}) => ({
23210
23282
  ...base,
23211
- limit: getNumber9(query.limit) ?? base.limit,
23212
- q: getString14(query.q) ?? base.q,
23283
+ limit: getNumber10(query.limit) ?? base.limit,
23284
+ q: getString15(query.q) ?? base.q,
23213
23285
  status: parseStatus2(query.status) ?? base.status
23214
23286
  });
23215
23287
  var deliverySearchText2 = (delivery) => [
@@ -86,6 +86,7 @@ export type VoiceProductionReadinessReport = {
86
86
  handoffs?: string;
87
87
  handoffRetry?: string;
88
88
  liveLatency?: string;
89
+ operationsRecords?: string;
89
90
  opsActions?: string;
90
91
  phoneAgentSmoke?: string;
91
92
  providerContracts?: string;
@@ -98,6 +99,7 @@ export type VoiceProductionReadinessReport = {
98
99
  };
99
100
  profile?: VoiceProductionReadinessProfileExplanation;
100
101
  proofSources?: Record<string, VoiceProductionReadinessProofSource>;
102
+ operationsRecords?: VoiceProductionReadinessOperationsRecordLinks;
101
103
  status: VoiceProductionReadinessStatus;
102
104
  summary: {
103
105
  agentSquadContracts?: {
@@ -174,6 +176,18 @@ export type VoiceProductionReadinessReport = {
174
176
  traceDeliveries?: VoiceProductionReadinessTraceDeliverySummary;
175
177
  };
176
178
  };
179
+ export type VoiceProductionReadinessOperationsRecordLink = {
180
+ detail?: string;
181
+ href: string;
182
+ label: string;
183
+ sessionId: string;
184
+ status: VoiceProductionReadinessStatus;
185
+ };
186
+ export type VoiceProductionReadinessOperationsRecordLinks = {
187
+ failedSessions: VoiceProductionReadinessOperationsRecordLink[];
188
+ failingLatency: VoiceProductionReadinessOperationsRecordLink[];
189
+ providerErrors: VoiceProductionReadinessOperationsRecordLink[];
190
+ };
177
191
  export type VoiceProductionReadinessAuditRequirement = {
178
192
  label?: string;
179
193
  maxAgeMs?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.183",
3
+ "version": "0.0.22-beta.184",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",