@oscharko-dev/keiko 0.1.5 → 0.1.6

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.
@@ -4,5 +4,7 @@ export interface GatewayFetchOptions extends RequestInit {
4
4
  readonly useCaFallback?: boolean | undefined;
5
5
  }
6
6
  export declare function isMissingIssuerError(error: unknown): boolean;
7
+ export declare function isRecoverableTlsTrustError(error: unknown): boolean;
8
+ export declare function gatewayTrustedCaCertificates(): readonly string[];
7
9
  export declare function gatewayFetch(url: string, options?: GatewayFetchOptions): Promise<Response>;
8
10
  export declare function readJsonCapped(response: Response, maxBytes?: number): Promise<unknown>;
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { request as httpsRequest } from "node:https";
3
- import { rootCertificates } from "node:tls";
3
+ import * as tls from "node:tls";
4
4
  // Caps a single gateway response at 10 MB; real chat completions are far smaller.
5
5
  export const MAX_RESPONSE_BYTES = 10_000_000;
6
6
  function headersFromNode(headers) {
@@ -36,6 +36,21 @@ export function isMissingIssuerError(error) {
36
36
  return item.code === "UNABLE_TO_GET_ISSUER_CERT_LOCALLY";
37
37
  });
38
38
  }
39
+ const RECOVERABLE_TLS_TRUST_ERROR_CODES = new Set([
40
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
41
+ "SELF_SIGNED_CERT_IN_CHAIN",
42
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
43
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
44
+ ]);
45
+ export function isRecoverableTlsTrustError(error) {
46
+ const cause = isRecord(error) ? error.cause : undefined;
47
+ const candidates = [error, cause];
48
+ return candidates.some((item) => {
49
+ if (!isRecord(item) || typeof item.code !== "string")
50
+ return false;
51
+ return RECOVERABLE_TLS_TRUST_ERROR_CODES.has(item.code);
52
+ });
53
+ }
39
54
  function usesHttps(url) {
40
55
  try {
41
56
  return new URL(url).protocol === "https:";
@@ -56,8 +71,26 @@ function extraCaCertificates() {
56
71
  return [];
57
72
  }
58
73
  }
59
- function caBundle() {
60
- return [...rootCertificates, ...extraCaCertificates()];
74
+ function nodeCaCertificates(source) {
75
+ const getter = tls.getCACertificates;
76
+ if (typeof getter !== "function") {
77
+ return [];
78
+ }
79
+ try {
80
+ return getter(source);
81
+ }
82
+ catch {
83
+ return [];
84
+ }
85
+ }
86
+ export function gatewayTrustedCaCertificates() {
87
+ return Array.from(new Set([
88
+ ...nodeCaCertificates("default"),
89
+ ...tls.rootCertificates,
90
+ ...nodeCaCertificates("system"),
91
+ ...nodeCaCertificates("extra"),
92
+ ...extraCaCertificates(),
93
+ ]));
61
94
  }
62
95
  function bodyToString(body) {
63
96
  if (body === undefined || body === null) {
@@ -78,7 +111,7 @@ function fetchWithCaBundle(url, init) {
78
111
  const req = httpsRequest(url, {
79
112
  method: init.method ?? "GET",
80
113
  headers,
81
- ca: [...caBundle()],
114
+ ca: [...gatewayTrustedCaCertificates()],
82
115
  signal: init.signal ?? undefined,
83
116
  }, (res) => {
84
117
  const chunks = [];
@@ -112,7 +145,7 @@ export async function gatewayFetch(url, options = {}) {
112
145
  return await doFetch(url, init);
113
146
  }
114
147
  catch (error) {
115
- if (useCaFallback && usesHttps(url) && isMissingIssuerError(error)) {
148
+ if (useCaFallback && usesHttps(url) && isRecoverableTlsTrustError(error)) {
116
149
  return fetchWithCaBundle(url, init);
117
150
  }
118
151
  throw error;
@@ -1,7 +1,7 @@
1
1
  import type { Clock } from "../gateway/types.js";
2
2
  import type { EventSink, Fingerprinter, IdSource, ModelPort, ToolPort } from "./ports.js";
3
3
  import { type HarnessLimits, type RunResult, type TaskInput } from "./types.js";
4
- export declare const HARNESS_VERSION = "0.1.5";
4
+ export declare const HARNESS_VERSION = "0.1.6";
5
5
  export interface AgentConfig {
6
6
  readonly model: string;
7
7
  readonly workingDirectory: string;
@@ -10,7 +10,7 @@ import { runLoop } from "./loop.js";
10
10
  import { MemoryEventSink } from "./sinks.js";
11
11
  import { resolveTaskPlan } from "./tasks/policy.js";
12
12
  import { DEFAULT_LIMITS, } from "./types.js";
13
- export const HARNESS_VERSION = "0.1.5";
13
+ export const HARNESS_VERSION = "0.1.6";
14
14
  function resolveLimits(config) {
15
15
  return { ...DEFAULT_LIMITS, ...config.limits };
16
16
  }
@@ -1,4 +1,4 @@
1
- export declare const SDK_VERSION = "0.1.5";
1
+ export declare const SDK_VERSION = "0.1.6";
2
2
  export { createSession, type AgentConfig, type AgentSession, type HarnessDeps, type RunResult, type TaskInput, type TaskType, } from "../harness/index.js";
3
3
  export { runAgent, type SdkAgentConfig, type SdkEvidenceOptions } from "./run-agent.js";
4
4
  export { buildWorkspaceSummary, detectWorkspace, summarizeForAudit, type AuditEntry, type AuditSummary, type ContextEntrySummary, type ContextPackSummary, type WorkspaceInfo, type WorkspaceSummary, } from "../workspace/index.js";
package/dist/sdk/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Single-sourced package version; CLI and SDK both read this to avoid drift.
2
- export const SDK_VERSION = "0.1.5";
2
+ export const SDK_VERSION = "0.1.6";
3
3
  // The typed agent surface. AgentConfig, the session factory, the run result, and the
4
4
  // session handle all live in the harness module (ADR-0004); the SDK re-exports them so
5
5
  // callers import the agent API from one place.
@@ -1,17 +1,17 @@
1
1
  [
2
+ "'sha256-2RZA1N+nLgvl8WcE8JsSdNjQ5MQUhxR2msRW7usAVlM='",
2
3
  "'sha256-6JBR+C4qigE40tMbninopqoSguR9H/AhsfWgllRr6y0='",
4
+ "'sha256-C8fp9ZeiwdGAbedIsOvEa2BMkNdJdGys5/hhETqHGL4='",
3
5
  "'sha256-FhLHRUQz4c4ntLU9VkfEesX7PnzNLENSe/16Hi523Kk='",
4
6
  "'sha256-NMmsYxPlvKu6BMNDUuiUA/0HWXXhODWSkUJ3CrerHAI='",
5
7
  "'sha256-OBTN3RiyCV4Bq7dFqZ5a2pAXjnCcCYeTJMO2I/LYKeo='",
6
- "'sha256-RgGBVXhSba32fqKyKK1LJ4hBlUyuzsh4X4Wz8X/2ViQ='",
7
8
  "'sha256-U9W+ZoRW19rf6ohEfUh2oSN8UmJ8mZjCoxp31AbEGYM='",
8
- "'sha256-Zh9WKxSpBbdbuXpYaiD8KL+3eIzvCyeUVc9aNk+MlSs='",
9
+ "'sha256-WS6pJFhpUaJbGkmmJZnnoqzb3ZD6Hp3TSAsAkiW/1JA='",
10
+ "'sha256-aWdClXArxjcSI0zen9sFWmTTb6X31A25YJP9LyQG2ZI='",
9
11
  "'sha256-bg+CWjI8RppcgHYH6RuW4z4OnLAUEUPDXRoYUo9Tyok='",
12
+ "'sha256-gZGxfXq2015S5Q+DB4YqyrPelc2Pxtxzxpv6HBl/Ogg='",
10
13
  "'sha256-qBQ7RdQKJEJuW7Fj1MbGjDbF6lnRdfu+KV0V4A5MTRg='",
11
14
  "'sha256-qjuzziE6xLU3Cras89VlShlRYHgYZuOxceXUDmuvClo='",
12
- "'sha256-t76xM9aAYbelOV2iEJQ/BU9dEqpvvktljSu14Uyvvd4='",
13
- "'sha256-uOX/uiQI1VZtrqlMRTLtY3W15cHbKX4Aeibg+uXF+sI='",
14
15
  "'sha256-xLP5QIbvR88RAxDKoSWqs6CVxNIRu17hhr7S/Q6hlU0='",
15
- "'sha256-xz80fPjhAczg/tByXnm3xfZrdAUWODPmQtD4solyj1c='",
16
- "'sha256-y0tT9cT5l9EPcFOld+ed41V7GuZjHHO53TGAT/8F/PU='"
16
+ "'sha256-xz80fPjhAczg/tByXnm3xfZrdAUWODPmQtD4solyj1c='"
17
17
  ]
@@ -1 +1 @@
1
- <!DOCTYPE html><!--iY8U2g5uZ5O_y0YMPoJO5--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/3f36649d8ca8f3e7.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-4a462cecab786e93.js"/><script src="/_next/static/chunks/4bd1b696-c023c6e3521b1417.js" async=""></script><script src="/_next/static/chunks/255-d47fd57964443afe.js" async=""></script><script src="/_next/static/chunks/main-app-e8144a306630b76d.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Keiko</title><meta name="description" content="Keiko local developer-assist workspace."/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-4a462cecab786e93.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[9766,[],\"\"]\n3:I[8924,[],\"\"]\n4:I[4431,[],\"OutletBoundary\"]\n6:I[5278,[],\"AsyncMetadataOutlet\"]\n8:I[4431,[],\"ViewportBoundary\"]\na:I[4431,[],\"MetadataBoundary\"]\nb:\"$Sreact.suspense\"\nd:I[7150,[],\"\"]\n:HL[\"/_next/static/css/3f36649d8ca8f3e7.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"iY8U2g5uZ5O_y0YMPoJO5\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/3f36649d8ca8f3e7.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",[\"$\",\"$L6\",null,{\"promise\":\"$@7\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],null],[\"$\",\"$La\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$b\",null,{\"fallback\":null,\"children\":\"$Lc\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"7:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Keiko\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Keiko local developer-assist workspace.\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"c:\"$7:metadata\"\n"])</script></body></html>
1
+ <!DOCTYPE html><!--vHP365Z8U38dG6vdAzGnl--><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/3f36649d8ca8f3e7.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-4a462cecab786e93.js"/><script src="/_next/static/chunks/4bd1b696-c023c6e3521b1417.js" async=""></script><script src="/_next/static/chunks/255-d47fd57964443afe.js" async=""></script><script src="/_next/static/chunks/main-app-e8144a306630b76d.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>Keiko</title><meta name="description" content="Keiko local developer-assist workspace."/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-4a462cecab786e93.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[9766,[],\"\"]\n3:I[8924,[],\"\"]\n4:I[4431,[],\"OutletBoundary\"]\n6:I[5278,[],\"AsyncMetadataOutlet\"]\n8:I[4431,[],\"ViewportBoundary\"]\na:I[4431,[],\"MetadataBoundary\"]\nb:\"$Sreact.suspense\"\nd:I[7150,[],\"\"]\n:HL[\"/_next/static/css/3f36649d8ca8f3e7.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"vHP365Z8U38dG6vdAzGnl\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/3f36649d8ca8f3e7.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L4\",null,{\"children\":[\"$L5\",[\"$\",\"$L6\",null,{\"promise\":\"$@7\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],null],[\"$\",\"$La\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$b\",null,{\"fallback\":null,\"children\":\"$Lc\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$d\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n5:null\n"])</script><script>self.__next_f.push([1,"7:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"Keiko\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Keiko local developer-assist workspace.\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"c:\"$7:metadata\"\n"])</script></body></html>