Ctrl K
ComunidadGuías…

assets/mcp-cards/connect-card-v2.html.txt

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Chickpea connect card</title>
<style>/*
 * Framework-free MCP App styles.
 */

@layer base {
  :root {
    color-scheme: light dark;
    --background: var(
      --color-background-primary,
      light-dark(rgb(255 255 255), rgb(24 24 24))
    );
    --foreground: var(
      --color-text-primary,
      light-dark(rgb(26 28 31), rgb(255 255 255))
    );
    --card: color-mix(in oklab, var(--foreground) 5%, var(--background));
    --card-foreground: var(--color-text-primary, var(--foreground));
    --primary: var(
      --color-text-info,
      light-dark(rgb(51 156 255), rgb(131 195 255))
    );
    --primary-foreground: var(
      --color-text-inverse,
      light-dark(rgb(255 255 255), rgb(13 13 13))
    );
    --secondary: var(
      --color-background-secondary,
      light-dark(rgb(255 255 255 / 96%), rgb(54 54 54 / 96%))
    );
    --secondary-foreground: var(--color-text-primary, var(--foreground));
    --muted: color-mix(in srgb, var(--foreground) 10%, transparent);
    --muted-foreground: var(
      --color-text-secondary,
      light-dark(rgb(26 28 31 / 49.4%), rgb(255 255 255 / 49.8%))
    );
    --accent: var(
      --color-background-info,
      light-dark(rgb(229 242 255), rgb(13 39 63))
    );
    --accent-foreground: var(--color-text-info, var(--primary));
    --destructive: var(
      --color-text-warning,
      light-dark(rgb(226 85 7), rgb(255 133 73))
    );
    --border: var(
      --color-border-secondary,
      light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))
    );
    --input: var(
      --color-border-primary,
      light-dark(rgb(26 28 31 / 11.8%), rgb(255 255 255 / 12%))
    );
    --ring: var(--color-ring-primary, var(--primary));
    --font-size-base: var(--font-text-md-size, 14px);
    --radius: var(--border-radius-lg, 12.5px);
  }

  :root[data-theme="light"] {
    color-scheme: light;
  }

  :root[data-theme="dark"] {
    color-scheme: dark;
  }

  body {
    margin: 0;
    color: var(--foreground);
    background: var(--background);
    font-size: max(11px, var(--font-size-base));
    font-weight: var(--font-weight-normal, 430);
    line-height: 1.5;
  }

  /* MCP sandboxes can force their own font on body, so restore the host font below it. */
  body,
  body > * {
    font-family: var(
      --font-sans,
      -apple-system,
      system-ui,
      "Segoe UI",
      sans-serif
    );
  }

  h1,
  h2,
  h3,
  p {
    margin-block: 0;
  }

  h1,
  h2,
  h3 {
    font-weight: var(--font-weight-medium, 500);
    line-height: 1.25;
  }

  h1 {
    font-size: calc(var(--font-size-base) * 1.7142857143);
  }

  h2 {
    font-size: calc(var(--font-size-base) * 1.4285714286);
  }

  h3 {
    font-size: calc(var(--font-size-base) * 1.2857142857);
  }
}

@layer components {
  .cursor-interaction {
    cursor: var(--cursor-interaction, pointer);
  }

  .card {
    min-width: 0;
    padding: 12px;
    overflow-wrap: break-word;
    border-radius: calc(var(--radius) * 1.6);
    corner-shape: superellipse(1.5);
    color: var(--card-foreground);
    background: var(--card);
  }

  .btn,
  .form-check-input,
  .form-control,
  .form-select {
    box-sizing: border-box;
    font: inherit;
  }

  .btn {
    appearance: button;
    display: inline-flex;
    inline-size: fit-content;
    max-inline-size: 100%;
    min-height: 28px;
    align-items: center;
    justify-content: center;
    gap: 4px;
    margin: 0;
    padding: 0 8px;
    border: 1px solid var(--input);
    border-radius: var(--radius);
    corner-shape: superellipse(1.5);
    color: var(--secondary-foreground);
    background: var(--secondary);
    cursor: var(--cursor-interaction, pointer);
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    user-select: none;
  }

  .btn:not(:disabled):hover {
    background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
  }

  .btn-primary {
    border-color: transparent;
    color: var(--primary-foreground);
    background: var(--foreground);
    background-clip: padding-box;
  }

  .btn-primary:not(:disabled):hover {
    background: color-mix(in srgb, var(--foreground) 80%, transparent);
    background-clip: padding-box;
  }

  .btn-ghost {
    border-color: transparent;
    color: var(--muted-foreground);
    background: transparent;
  }

  .btn-ghost:not(:disabled):hover {
    color: var(--foreground);
    background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
  }

  .btn:not(.btn-primary):is([aria-pressed="true"], [aria-selected="true"]) {
    border-color: var(--primary);
    color: var(--primary-foreground);
    background: var(--primary);
  }

  .btn:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
  }

  .btn:disabled,
  .form-check-input:disabled,
  .form-control:disabled,
  .form-select:disabled {
    cursor: not-allowed;
    opacity: 0.4;
  }

  .form-label {
    display: block;
    margin-bottom: 6px;
    color: var(--foreground);
  }

  .form-control,
  .form-select {
    display: block;
    width: 100%;
    min-height: 28px;
    padding: 0 8px;
    outline: none;
    border: 1px solid var(--input);
    border-radius: var(--radius);
    corner-shape: superellipse(1.5);
    color: var(--foreground);
    background: var(--secondary);
  }

  .form-control::placeholder {
    color: var(--muted-foreground);
  }

  .form-select {
    appearance: none;
    padding-right: 32px;
    background-image:
      linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),
      linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);
    background-position:
      calc(100% - 14px) 50%,
      calc(100% - 10px) 50%;
    background-repeat: no-repeat;
    background-size: 4px 4px;
    cursor: var(--cursor-interaction, pointer);
  }

  .form-select:not(:disabled):hover {
    background-color: color-mix(
      in srgb,
      var(--foreground) 6%,
      var(--secondary)
    );
  }

  textarea.form-control {
    min-height: 72px;
    padding: 8px 10px;
    resize: vertical;
  }

  .form-control:focus-visible,
  .form-select:focus-visible {
    border-color: var(--ring);
    box-shadow: inset 0 0 0 1px var(--ring);
  }

  .form-check {
    display: flex;
    min-height: 20px;
    align-items: center;
    gap: 8px;
  }

  .form-check-input {
    appearance: none;
    display: grid;
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    place-items: center;
    margin: 0;
    border: 1px solid var(--input);
    border-radius: 5px;
    corner-shape: superellipse(1.5);
    color: var(--primary-foreground);
    background: var(--secondary);
    cursor: var(--cursor-interaction, pointer);
  }

  .form-check-input:checked {
    border-color: var(--primary);
    background: var(--primary);
  }

  .form-check-input:checked::after {
    width: 7px;
    height: 4px;
    border-bottom: 2px solid currentColor;
    border-left: 2px solid currentColor;
    content: "";
    transform: translateY(-1px) rotate(-45deg);
  }

  .form-check-input:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 2px;
  }

  .form-check-label {
    color: var(--foreground);
  }

  svg.lucide {
    display: block;
    width: 16px;
    height: 16px;
    flex: none;
    stroke-width: 1.6;
  }

  .text-small {
    font-size: max(11px, calc(var(--font-size-base) - 2px));
  }

  .text-muted {
    color: var(--muted-foreground);
  }

  .text-destructive {
    color: var(--destructive);
  }

  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/*
 * The Agent card in ChatGPT's own look: its type, colors and black primary
 * buttons, from the host's style variables. Chickpea shows only in the avatar
 * and the quote accent. Without host variables the colors fall back to the
 * mockup's palette, and without a host theme to light.
 */

:root:not([data-theme]) {
  color-scheme: light;
}

:root {
  --cp-bg: var(--color-background-primary, light-dark(#ffffff, #181818));
  --cp-fg: var(--color-text-primary, light-dark(#0d0d0d, #ededed));
  /* Secondary text stays at AA contrast; the host's tertiary text does not. */
  --cp-muted: var(--color-text-secondary, light-dark(#5d5d5d, #cdcdcd));
  --cp-line: var(--color-border-primary, light-dark(#e5e5e5, rgb(255 255 255 / 20%)));
  --cp-soft: light-dark(#f7f7f7, rgb(255 255 255 / 6%));
  --cp-ok: light-dark(#1a7f37, #40c977);
  --cp-warn: light-dark(#a15c00, #f0a050);
  --cp-danger: #c62828;
  --cp-danger-hover: #a31f1f;
  --cp-accent: #e8901a;
  --cp-size: var(--font-text-md-size, 14px);
}

html,
body {
  background: var(--cp-bg);
  color: var(--cp-fg);
}

body {
  font-size: var(--cp-size);
  line-height: 1.45;
}

.cp-card {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 16px;
  overflow-wrap: anywhere;
}

.cp-hdr {
  display: flex;
  gap: 12px;
  align-items: center;
}

.cp-avatar {
  flex: none;
  display: block;
}

.cp-avatar svg,
.cp-avatar img {
  display: block;
  width: 100%;
  height: 100%;
}

/* Slack's rounded square, cropped as Admin and the setup page crop it. */
.cp-avatar img {
  object-fit: cover;
}

.cp-avatar-lg {
  width: 44px;
  height: 44px;
}

.cp-avatar-lg img {
  border-radius: 12px;
}

.cp-avatar-sm {
  width: 26px;
  height: 26px;
}

.cp-avatar-sm img {
  border-radius: 7px;
}

/* On an alert card, an Agent's picture keeps the alert art's red. */
.cp-avatar-alert img {
  outline: 2px solid var(--cp-danger);
  outline-offset: 1px;
}

.cp-heading {
  min-width: 0;
}

.cp-title {
  margin: 0;
  font-size: calc(var(--cp-size) * 1.143);
  font-weight: 600;
  line-height: 1.25;
}

/* Focus lands here after a redraw only so the keyboard stays on the card. */
.cp-title:focus {
  outline: none;
}

.cp-sub {
  margin: 2px 0 0;
  color: var(--cp-muted);
  font-size: calc(var(--cp-size) * 0.93);
}

.cp-ok {
  color: var(--cp-ok);
}

.cp-warn {
  color: var(--cp-warn);
}

.cp-text {
  margin: 12px 0 0;
  white-space: pre-line;
}

.cp-sect {
  margin: 14px 0 6px;
  color: var(--cp-muted);
  font-size: calc(var(--cp-size) * 0.79);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.cp-sect + .cp-text {
  margin-top: 0;
}

.cp-quote {
  margin: 6px 0;
  padding: 2px 0 2px 10px;
  border-left: 3px solid var(--cp-accent);
  white-space: pre-line;
}

.cp-note {
  margin: 6px 0 0;
  color: var(--cp-muted);
  font-size: calc(var(--cp-size) * 0.93);
}

.cp-note.cp-warn {
  color: var(--cp-warn);
}

.cp-thread {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 10px 12px;
  border: 1px solid var(--cp-line);
  border-radius: 12px;
  background: var(--cp-soft);
}

.cp-msg {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 8px;
  font-size: calc(var(--cp-size) * 0.964);
}

/* A host may pass an example's line breaks as they are; they show as written. */
.cp-said {
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.cp-who {
  font-weight: 600;
  font-size: calc(var(--cp-size) * 0.93);
}

.cp-who-note {
  margin-left: 4px;
  color: var(--cp-muted);
  font-weight: 400;
}

.cp-init {
  display: grid;
  width: 26px;
  height: 26px;
  place-items: center;
  border-radius: 7px;
  background: #4a6cc4;
  color: #ffffff;
  font-size: calc(var(--cp-size) * 0.86);
  font-weight: 600;
}

.cp-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 12px;
  margin: 12px 0 0;
  font-size: calc(var(--cp-size) * 0.964);
}

.cp-facts dt {
  color: var(--cp-muted);
}

.cp-facts dd {
  margin: 0;
}

.cp-chip {
  display: inline-flex;
  padding: 0 9px;
  border: 1px solid var(--cp-line);
  border-radius: 999px;
  background: var(--cp-soft);
  font-size: calc(var(--cp-size) * 0.9);
}

.cp-faint {
  color: var(--cp-muted);
  font-size: calc(var(--cp-size) * 0.86);
}

.cp-foot {
  margin: 14px 0 0;
  color: var(--cp-muted);
  font-size: calc(var(--cp-size) * 0.93);
}

.cp-steps {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
  font-size: calc(var(--cp-size) * 0.964);
}

.cp-steps li {
  display: flex;
  gap: 8px;
  align-items: center;
}

.cp-ic {
  display: inline-grid;
  flex: none;
  width: 18px;
  height: 18px;
  box-sizing: border-box;
  place-items: center;
  border-radius: 50%;
  font-size: 11px;
}

.cp-ic-done {
  background: color-mix(in srgb, var(--cp-ok) 14%, transparent);
  color: var(--cp-ok);
}

.cp-ic-now {
  border: 2px solid var(--cp-accent);
  border-right-color: transparent;
  animation: cp-spin 0.9s linear infinite;
}

.cp-ic-todo {
  border: 1.5px solid var(--cp-line);
}

.cp-ic-failed {
  background: color-mix(in srgb, var(--cp-danger) 14%, transparent);
  color: light-dark(var(--cp-danger), #ff8a80);
  font-weight: 700;
}

@keyframes cp-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cp-ic-now {
    animation: none;
  }
}

.cp-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 14px;
}

.cp-card .btn {
  min-height: 34px;
  padding: 0 14px;
  border-radius: 999px;
  font-size: calc(var(--cp-size) * 0.964);
  font-weight: 600;
}

.cp-btn-primary {
  border-color: transparent;
  color: var(--color-text-inverse, light-dark(#ffffff, #0d0d0d));
  background: var(--cp-fg);
}

.cp-btn-primary:not(:disabled):hover {
  background: color-mix(in srgb, var(--cp-fg) 82%, var(--cp-bg));
}

.cp-btn-danger {
  border-color: transparent;
  color: #ffffff;
  background: var(--cp-danger);
}

.cp-btn-danger:not(:disabled):hover {
  background: var(--cp-danger-hover);
}

.cp-btn-secondary {
  border-color: var(--cp-line);
  color: var(--cp-fg);
  background: var(--cp-bg);
}

.cp-card .btn:focus-visible {
  outline: 2px solid var(--color-ring-primary, light-dark(#0169cc, #ffffff));
  outline-offset: 2px;
}

.cp-acts[hidden],
.cp-error[hidden] {
  display: none;
}

.cp-error {
  margin: 10px 0 0;
  color: light-dark(#b42318, #ff8a80);
  font-size: calc(var(--cp-size) * 0.93);
}

.cp-rows {
  display: flex;
  flex-direction: column;
  container-type: inline-size;
  margin: 12px 0 0;
  padding: 0;
  border: 1px solid var(--cp-line);
  border-radius: 14px;
  list-style: none;
}

.cp-row {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  border-top: 1px solid var(--cp-line);
  font-size: calc(var(--cp-size) * 0.964);
}

.cp-row:first-child {
  border-top: 0;
}

/* A narrow card puts a row's link under its words instead of squeezing them. */
@container (max-width: 520px) {
  .cp-row:has(> .cp-link-go) {
    grid-template-columns: 22px minmax(0, 1fr);
    row-gap: 2px;
  }

  .cp-row > .cp-link-go {
    grid-column: 2;
    justify-self: start;
    white-space: normal;
    text-align: start;
  }
}

.cp-row-detail {
  color: var(--cp-muted);
  font-size: calc(var(--cp-size) * 0.893);
  white-space: pre-line;
}

.cp-row-detail.cp-warn {
  color: var(--cp-warn);
}

.cp-tile {
  display: grid;
  width: 22px;
  height: 22px;
  place-items: center;
  border-radius: 6px;
  background: var(--cp-fg);
  color: var(--cp-bg);
  font-size: calc(var(--cp-size) * 0.86);
  font-weight: 700;
}

.cp-ic-warning {
  background: color-mix(in srgb, var(--cp-warn) 16%, transparent);
  color: var(--cp-warn);
  font-weight: 700;
}

.cp-ic-unknown {
  border: 1.5px solid var(--cp-line);
  color: var(--cp-muted);
  font-weight: 700;
}

.cp-card .btn-sm {
  min-height: 30px;
  padding: 0 12px;
  font-size: calc(var(--cp-size) * 0.893);
  white-space: nowrap;
}

.cp-link {
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--cp-fg);
  font: inherit;
  font-size: calc(var(--cp-size) * 0.93);
  font-weight: 600;
  white-space: nowrap;
  cursor: var(--cursor-interaction, pointer);
}

.cp-link-go::after {
  content: " →" / "";
}

.cp-link:not(:disabled):hover {
  text-decoration: underline;
}

.cp-link:disabled {
  color: var(--cp-muted);
}

.cp-link:focus-visible {
  border-radius: 4px;
  outline: 2px solid var(--color-ring-primary, light-dark(#0169cc, #ffffff));
  outline-offset: 2px;
}
</style></head>
<body><div id="card"></div><script>"use strict";(()=>{var ge="2026-01-26";var v=class{constructor(n){this.appInfo=n;window.addEventListener("message",t=>{t.source===window.parent&&this.#i(t.data)}),this.on("ui/notifications/host-context-changed",t=>{let o=t,{styles:r,...i}=this.hostContext??{},c=o.theme!==void 0&&o.theme!==i.theme&&!o.styles;this.hostContext={...i,...r&&!c?{styles:r}:{},...o}})}appInfo;#r=1;#e=new Map;#t=new Map;hostContext;hostCapabilities;on(n,t){this.#t.set(n,[...this.#t.get(n)??[],t])}async connect(){let n=await this.#n("ui/initialize",{appInfo:this.appInfo,appCapabilities:{availableDisplayModes:["inline"]},protocolVersion:ge});this.hostContext=n?.hostContext,this.hostCapabilities=n?.hostCapabilities,this.#o("ui/notifications/initialized",{}),new ResizeObserver(()=>this.#o("ui/notifications/size-changed",{height:Math.ceil(document.body.getBoundingClientRect().height)})).observe(document.body)}async callTool(n,t,o){return await this.#n("tools/call",{name:n,arguments:t},o)}async sendMessage(n){let t=this.hostCapabilities?.experimental?.["openai/message"]?.draft!==void 0,o=n.draft!==void 0&&t?n.draft:n.sent;_(await this.#n("ui/message",{role:"user",content:[{type:"text",text:o}],...o===n.draft?{_meta:{"openai/message":{target:"active",send:!1}}}:{}}))}async updateModelContext(n){_(await this.#n("ui/update-model-context",{content:[{type:"text",text:n}]}))}async openLink(n){if(window.openai?.openExternal)try{await window.openai.openExternal({href:n,redirectUrl:!1});return}catch{}_(await this.#n("ui/open-link",{url:n}))}#o(n,t){window.parent.postMessage({jsonrpc:"2.0",method:n,params:t},"*")}#n(n,t,o){let r=this.#r++;return new Promise((i,c)=>{let p=setTimeout(()=>{o?this.#e.set(r,{resolve:o,reject:()=>{}}):this.#e.delete(r),c(new Error(`${n} timed out`))},6e4);this.#e.set(r,{resolve:l=>{clearTimeout(p),i(l)},reject:l=>{clearTimeout(p),c(l)}}),window.parent.postMessage({jsonrpc:"2.0",id:r,method:n,params:t},"*")})}#i(n){if(!(!n||n.jsonrpc!=="2.0")){if(n.method===void 0){let t=typeof n.id=="number"?this.#e.get(n.id):void 0;if(!t)return;this.#e.delete(n.id),n.error?t.reject(n.error):t.resolve(n.result);return}for(let t of this.#t.get(n.method)??[])t(n.params);n.id!==void 0&&window.parent.postMessage({jsonrpc:"2.0",id:n.id,result:{}},"*")}}};function _(e){if(e?.isError===!0)throw new Error("The host refused it")}function he(e){document.documentElement.setAttribute("data-theme",e),document.documentElement.style.colorScheme=e}function we(e){for(let[n,t]of Object.entries(e))t!==void 0&&document.documentElement.style.setProperty(n,t)}var D=[];function L(e){e?.theme&&he(e.theme);let n=e?.["openai/interactionCursor"],t={...e?.styles?.variables,"--cursor-interaction":typeof n=="string"&&/^[a-z-]+$/.test(n)?n:void 0};for(let o of D)t[o]===void 0&&document.documentElement.style.removeProperty(o);we(t),D=Object.keys(t).filter(o=>t[o]!==void 0)}var B=(e,n,t)=>`<svg viewBox="0 0 44 44" aria-hidden="true" focusable="false"><rect width="44" height="44" rx="12" fill="${e}"/><path d="M22 6c-9 0-14 8-14 18v14h28V24C36 14 31 6 22 6z" fill="${n}"/><path d="M22 12c-6 0-9.5 6-9.5 13.5S16 38 22 38s9.5-5 9.5-12.5S28 12 22 12z" fill="${t}"/><circle cx="18.5" cy="26" r="1.3" fill="#3a2a1e"/><circle cx="25.5" cy="26" r="1.3" fill="#3a2a1e"/><path d="M20.5 30.2q1.5 1.2 3 0" stroke="#3a2a1e" stroke-width="1.1" fill="none" stroke-linecap="round"/></svg>`,ke={agent:B("#3a2a1e","#E8901A","#f3d9b1"),alert:B("#2a1f2e","#c2453a","#f1d3b8")},ye={done:"done",now:"in progress",todo:"to do",failed:"failed"},F={done:{glyph:"\u2713",words:"done"},now:{glyph:"",words:"in progress"},failed:{glyph:"!",words:"needs attention"},warning:{glyph:"!",words:"warning"},unknown:{glyph:"?",words:"unknown"}};function s(e,n,t){let o=document.createElement(e);return n&&(o.className=n),t!==void 0&&(o.textContent=t),o}var j=new Set;function z(e,n,t){let o=s("span",`cp-avatar cp-avatar-${n}`),r=()=>{o.innerHTML=ke[e]};if(!t||j.has(t))return r(),o;e==="alert"&&o.classList.add("cp-avatar-alert");let i=s("img");return i.alt="",i.decoding="async",i.addEventListener("error",()=>{j.add(t),r()},{once:!0}),i.src=t,o.append(i),o}function me(e){let n=s("p","cp-sub");for(let t of e)n.append(t.tone?s("span",`cp-${t.tone}`,t.text):t.text);return n}function be(e,n,t){switch(e.kind){case"text":return s("p","cp-text",e.text);case"quote":return s("blockquote","cp-quote",e.text);case"section":return s("h3","cp-sect",e.label);case"note":return s("p",`cp-note${e.tone?` cp-${e.tone}`:""}`,e.text);case"exchange":{let o=s("div","cp-thread"),r=s("div","cp-msg"),i=s("div","cp-who","You");i.append(s("span","cp-who-note","example"));let c=s("div");c.append(i,s("div","cp-said",e.ask)),r.append(s("span","cp-init","Y"),c);let p=s("div","cp-msg"),l=s("div");return l.append(s("div","cp-who",e.agent),s("div","cp-said",e.answer)),p.append(z(n,"sm",t),l),o.append(r,p),o}case"facts":{let o=s("dl","cp-facts");for(let r of e.rows){let i=s("dd",void 0,r.value);for(let c of r.chips??[])i.append(s("span","cp-chip",c)," ");r.note&&i.append(s("span","cp-faint",r.note)),o.append(s("dt",void 0,r.label),i)}return o}case"steps":{let o=s("ul","cp-steps");for(let{label:r,state:i}of e.steps){let c=s("li"),p=s("span",`cp-ic cp-ic-${i}`,i==="done"?"\u2713":i==="failed"?"!":"");p.setAttribute("aria-hidden","true"),c.append(p,r,s("span","sr-only",` (${ye[i]})`)),o.append(c)}return o}case"rows":{let o=s("ul","cp-rows");return o.append(...e.rows.map(xe)),o}}}function xe(e){let n=s("li","cp-row");if(e.icon==="tile"){let r=s("span","cp-tile",e.tile??"");r.setAttribute("aria-hidden","true"),n.append(r)}else{let r=F[e.icon],i=s("span",`cp-ic cp-ic-${e.icon}`,r.glyph);i.setAttribute("aria-hidden","true"),n.append(i)}let t=s("div","cp-row-body"),o=s("div","cp-row-title",e.title);if(e.icon!=="tile"&&o.append(s("span","sr-only",` (${F[e.icon].words})`)),t.append(o),e.detail&&t.append(s("div",`cp-row-detail${e.tone?` cp-${e.tone}`:""}`,e.detail)),n.append(t),e.control){let{label:r,action:i,style:c}=e.control;n.append(G(r,i,c==="link"?"cp-link cp-link-go":c==="toggle"?"cp-link":`btn btn-sm cp-btn-${c}`))}return n}function G(e,n,t){let o=s("button",`${t} cursor-interaction`,e);return o.type="button",o.dataset.action=n,o}function W(e,n){let t=s("p","sr-only");t.setAttribute("aria-live","polite");let o=s("main","cp-card"),r=s("div","cp-content"),i=s("div","cp-acts"),c=s("p","cp-error");c.setAttribute("role","alert"),o.append(r,i,c),e.replaceChildren(t,o),o.addEventListener("click",d=>{let a=d.target?.closest("button[data-action]");a instanceof HTMLButtonElement&&!a.disabled&&n(a.dataset.action)});let p="",l="",k=new Map;return{render(d){let a=JSON.stringify(d);if(a===p)return;p=a;let h=o.contains(document.activeElement),y=d.announce??d.title;t.textContent!==y&&(t.textContent=y);let m=s("header","cp-hdr"),H=d.avatar==="none"?"agent":d.avatar,{avatarUrl:T}=d;d.avatar!=="none"&&m.append(z(d.avatar,"lg",T));let V=s("div","cp-heading"),b=s("h2","cp-title");if(b.tabIndex=-1,d.done){let g=s("span","cp-ok","\u2713 ");g.setAttribute("aria-hidden","true"),b.append(g)}b.append(d.title),V.append(b),d.subtitle&&V.append(me(d.subtitle)),m.append(V);let x=new Map,fe=d.blocks.map(g=>{let C=JSON.stringify([g,H,T]),q=!x.has(C)&&k.get(C)||be(g,H,T);return x.has(C)||x.set(C,q),q});k=x,r.replaceChildren(m,...fe,...d.foot?[s("p","cp-foot",d.foot)]:[]);let U=JSON.stringify(d.buttons);U!==l&&(l=U,i.replaceChildren(...d.buttons.map(g=>G(g.label,g.action,`btn cp-btn-${g.tone}`)))),i.hidden=d.buttons.length===0;for(let g of o.querySelectorAll("button"))g.disabled=d.busy,g.toggleAttribute("aria-busy",d.busy);c.textContent=d.error??"",c.hidden=!d.error,h&&!o.contains(document.activeElement)&&b.focus({preventScroll:!0})}}}var Ce=1e3;function K(e,n){let t=new v({name:e,version:String(2)}),o=Se(),r=o?{view:o.view,busy:!1,seq:o.seq}:n.initial,i,c=0,p=W(document.getElementById("card"),a=>l({type:"press",action:a,now:Date.now()}));function l(a){let h=n.step(r,a),y=h.state.view!==r.view;r=h.state,y&&Re(r),p.render(n.present(r));for(let m of h.effects)k(m)}function k(a){switch(a.type){case"call":{let h=y=>l({type:"reply",call:a.call,result:y,now:Date.now()});t.callTool(a.call.tool,a.call.args,h).then(h,()=>l({type:"unreachable",call:a.call,now:Date.now()}));return}case"timer":clearTimeout(i),i=setTimeout(()=>l({type:"tick",now:Date.now()}),a.inMs);return;case"message":t.sendMessage(a).catch(()=>l({type:"refused",effect:a,now:Date.now()}));return;case"open":t.openLink(a.url).catch(()=>l({type:"refused",effect:a,now:Date.now()}));return;case"context":t.updateModelContext(a.text).catch(()=>{});return}}function d(){let a=Date.now();a-c<Ce||r.view.kind==="waiting"||(c=a,l({type:"reread",now:a}))}t.on("ui/notifications/tool-result",a=>{o||r.view.kind!=="waiting"||(l({type:"result",result:ve(a),now:Date.now()}),d())}),t.on("ui/notifications/tool-cancelled",()=>l({type:"no_result",now:Date.now()})),t.on("ui/notifications/host-context-changed",()=>L(t.hostContext)),window.addEventListener("focus",d),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&d()}),p.render(n.present(r)),t.connect().then(()=>{L(t.hostContext),o&&d()},()=>l({type:"no_result",now:Date.now()}))}function ve(e){let n=window.openai?.toolResponseMetadata;return e._meta||typeof n!="object"||n===null||Array.isArray(n)?e:{...e,_meta:n}}function Se(){let n=window.openai?.widgetState?.privateContent?.card,t=n?.view;return n?.version===2&&t&&typeof t.kind=="string"?{view:t,seq:n.seq??0}:void 0}function Re({view:e,seq:n}){if(e.kind==="waiting")return;let t={version:2,view:e,seq:n};Promise.resolve(window.openai?.setWidgetState?.({privateContent:{card:t}})).catch(()=>{})}function Y(e=0){return Math.min(2e3*2**e,16e3)}var u=(e,n=[])=>({state:e,effects:n}),f=(e,n=[])=>({state:{view:e,busy:!1},effects:n}),N=(e,n)=>({type:"call",call:{tool:e,args:n}}),I=(e,n)=>({...e,effects:[{type:"context",text:n},...e.effects]});function X(e){return(n,t)=>{let o=e(n,t.type==="result"||t.type==="reply"?{...t,result:Ae(t.result)}:t),r=o.state.view===n.view?n.seq:n.seq+1;return{state:{...o.state,seq:r},effects:o.effects.map(i=>i.type==="call"?{...i,call:{...i.call,seq:r}}:i)}}}function M(e,n){return n.seq!==e.seq}function Ae(e){let n=e._meta?.["chickpea/held"],t=e.structuredContent;if(!w(n)||!w(t))return e;let o=typeof n.confirmToken=="string"?n.confirmToken:void 0,r=typeof n.undoToken=="string"?n.undoToken:void 0;return{...e,structuredContent:{...t,...r?{undoToken:r}:{},...o&&w(t.confirmation)?{confirmation:{...t.confirmation,confirmToken:o}}:{}}}}var S="That did not work. Try again.";var R={kind:"notice",title:"Nothing to show here."};function A(e){return typeof e=="string"&&URL.parse(e)?.protocol==="https:"?e:void 0}var J=60;function Q(e,n){let t=e.length>J?`${e.slice(0,J-1)}\u2026`:e;return`the Agent ${JSON.stringify(t)}${n?` (@${n})`:""}`}function Z(e,n){if(n.length===0)return`Try it: message @${e} in Slack.`;let t=n.length<=2?n.join(" or "):`${n.slice(0,-1).join(", ")} or ${n.at(-1)}`;return`Try it: mention @${e} in ${t}.`}function w(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function $(e){if(!e.isError)return;let n=w(e.structuredContent)?e.structuredContent.error:void 0;return w(n)&&typeof n.message=="string"?n.message:S}function ee(e){let n=e._meta?.["chickpea/tool"];return typeof n=="string"?n:void 0}function ne(e){return n=>{try{return e(n)}catch{return{busy:n.busy,error:n.error,avatar:"none",title:R.title,blocks:[],buttons:[]}}}}function te(e){let n=e.flatMap(({name:o})=>o?[`#${o.replace(/^#/,"")}`]:[]),t=e.length-n.length;return t===0?n:[...n,t===1?"a private Channel":`${t} private Channels`]}function oe(e){return typeof e.plain=="string"&&e.plain!==""?e.plain:Ee[e.part][e.status]}var Ee={connection:{ok:"Connected.",warning:"Connected, but something needs a look.",failing:"It is not working.",unknown:"The check could not tell whether it works."},model:{ok:"It can run.",warning:"It may not run as expected.",failing:"It cannot run now.",unknown:"The check could not tell whether it can run."},slack:{ok:"Ready in Slack.",warning:"Not ready in Slack yet.",failing:"It has a problem in Slack.",unknown:"The check could not tell whether it is ready in Slack."},channel:{ok:"Answers here.",warning:"Not answering here yet.",failing:"It cannot answer here.",unknown:"The check could not tell whether it answers here."},schedule:{ok:"On schedule.",warning:"Some of its runs need a look.",failing:"Its runs are failing.",unknown:"The check could not tell whether it runs."},repository:{ok:"GitHub access is installed.",warning:"GitHub access needs a look.",failing:"It cannot reach this repository.",unknown:"The check could not tell whether it can reach this repository."},website_login:{ok:"Ready to sign in.",warning:"This login needs a look.",failing:"It cannot sign in.",unknown:"The check could not tell whether it can sign in."},admission:{ok:"A message reaches it.",warning:"A message may not reach it.",failing:"A message does not reach it.",unknown:"Slack decides when the message arrives."}};var ae={view:{kind:"waiting"},busy:!1,seq:0},ce=X(_e);function _e(e,n){switch(n.type){case"result":return Le(n.result);case"press":return e.busy?u(e):Ne(e,n.action,n.now);case"reply":return M(e,n.call)?u(e):Ie(e,n.call.tool,n.result,n.now);case"unreachable":return M(e,n.call)?u(e):e.view.kind==="finishing"?E(e,{...e.view,failures:(e.view.failures??0)+1},n.now):e.view.kind==="connected"&&e.view.check==="checking"?f(O(e.view)):u(e);case"refused":return Ue(e,n.effect);case"no_result":return e.view.kind==="waiting"?f(R):u(e);case"tick":return e.view.kind==="finishing"&&!e.view.slow?u(e,[le(e.view)]):u(e);case"reread":return de(e)}}function Le(e){let n=$(e);if(n)return f({kind:"notice",title:n});let t=e.structuredContent;if(!De(t))return f(R);let o=ee(e)==="reconnect_service"?"reconnect":"connect",r=t.agent&&{agentId:t.agent.agentId,name:t.agent.name,handle:t.agent.handle,slackUrl:A(t.agent.links?.slack),avatarUrl:A(t.agent.avatarUrl),channels:te(t.agent.channels??[])},{setup:i}=t;return t.status!=="needs_setup"||!Be(i)?f({kind:"notice",title:t.summary.replace(/\.$/,"")}):f({kind:i.setupToken&&A(i.url)?"start":"elsewhere",flow:o,agent:r,setup:i})}function Ne(e,n,t){let{view:o}=e;switch(n){case"connect":return o.kind==="start"?f({...P(o),kind:"finishing",startedAt:t},[{type:"open",url:o.setup.url},ue(2e3)]):u(e);case"done":return o.kind==="finishing"?de(e):u(e);case"open_slack":return o.kind==="connected"&&o.agent?.slackUrl?u(e,[{type:"open",url:o.agent.slackUrl}]):u(e);case"new_link":return o.kind==="ended"?u(e,[{type:"message",sent:qe(o)}]):u(e)}}function Ie(e,n,t,o){let{view:r}=e,i=$(t);if(n==="get_setup_status"){let c=i?void 0:t.structuredContent;return r.kind!=="start"&&r.kind!=="finishing"&&r.kind!=="ended"?u(e):Fe(c)?$e(e,r,c,o):r.kind==="finishing"?E(e,{...r,failures:(r.failures??0)+1},o):u(e)}if(n==="check_agent"&&r.kind==="connected"&&r.check==="checking"){let c=i?[]:t.structuredContent?.checks,p=Array.isArray(c)?c.find(l=>w(l)&&l.part==="connection"&&l.connectionId===r.connectionId&&typeof l.status=="string"&&Me.has(l.status)):void 0;return f(p?{...r,check:{status:p.status,words:oe(p)}}:O(r))}return u(e)}var Me=new Set(["ok","warning","failing","unknown"]);function O({check:e,...n}){return n}function $e(e,n,t,o){let{connection:r}=t,i=n.flow==="reconnect"?n.before??r?.status??"none":void 0,c=r?.status==="ready"&&(n.flow==="connect"||i!=="ready"),p=n.setup.what,l=n.agent?` ${n.flow==="reconnect"?"for":"to"} ${Q(n.agent.name)}`:"";if(t.status==="done"||c){let a=Pe(n,r);return n.kind==="finishing"?I(a,n.flow==="reconnect"?`${p} is signed in again${l}.`:`${p} is connected${l} now.`):a}let k={...P(n),...i?{before:i}:{}};if(t.status==="failed"||t.status==="cancelled"||t.status==="expired"){if(n.kind==="ended"&&n.why===t.status&&n.before===i)return u(e);let a=f({...k,kind:"ended",why:t.status});return n.kind==="finishing"?I(a,`${p} did not connect${l}: the link ${Oe[t.status]}. Nothing changed.`):a}let d=t.status!=="waiting"||n.kind==="finishing"&&n.opened?{opened:!0}:{};if(n.kind==="finishing"){let{failures:a,...h}=n;return E(e,{...h,...k,...d},o)}return n.kind==="start"&&t.status!=="waiting"?E(e,{...k,...d,kind:"finishing",startedAt:o},o):n.before===i?u(e):f({...n,...k})}var Oe={failed:"failed",cancelled:"was cancelled",expired:"expired"};function Pe(e,n){let t=n&&n.kind!=="service"&&e.agent,o={kind:"connected",flow:e.flow,agent:e.agent,service:e.setup.what,...n?{connectionId:n.connectionId}:{},...t?{check:"checking"}:{}};return f(o,t?[N("check_agent",{agentId:e.agent.agentId})]:[])}function E(e,n,t){let o=t-n.startedAt>=12e4?{...n,slow:!0}:n,r=o.slow?[]:[ue(Y(o.failures))];return e.view.kind==="finishing"&&!e.error&&He(e.view,o)?u(e,r):f(o,r)}function He(e,n){let t={...e},o={...n};return Object.keys({...t,...o}).every(r=>t[r]===o[r])}function de(e){let{view:n}=e;switch(n.kind){case"finishing":case"start":case"ended":return u(e,[le(n)]);case"connected":return n.check==="checking"?f(O(n)):u(e);default:return u(e)}}function Ue(e,n){let{view:t}=e;return t.kind==="finishing"&&n.type==="open"&&n.url===t.setup.url?t.opened?u(e):u({view:{...P(t),kind:"start"},busy:!1,error:S}):(t.kind==="connected"?n.type==="open"&&n.url===t.agent?.slackUrl:t.kind==="ended"&&n.type==="message")?u({...e,error:S}):u(e)}function le(e){return N("get_setup_status",{setupToken:e.setup.setupToken})}function ue(e){return{type:"timer",inMs:e}}function P(e){return{flow:e.flow,agent:e.agent,setup:e.setup,...e.before?{before:e.before}:{}}}function qe(e){let n=e.setup.what,t=e.agent?.name;return e.flow==="reconnect"?`Send me a new link to sign ${n} in again${t?` for ${t}`:""}.`:`Send me a new link to connect ${n}${t?` to ${t}`:""}.`}function De(e){return w(e)&&typeof e.status=="string"&&typeof e.summary=="string"}function Be(e){return w(e)&&typeof e.url=="string"&&typeof e.what=="string"}function Fe(e){return w(e)&&typeof e.status=="string"}var je="You sign in on Chickpea's page, never in this chat.",pe=ne(ze);function ze(e){let n={busy:e.busy,error:e.error},{view:t}=e;switch(t.kind){case"waiting":return{...n,avatar:"none",title:"Loading\u2026",blocks:[],buttons:[]};case"notice":return{...n,avatar:"none",title:t.title,blocks:[],buttons:[]};case"connected":{let o=We(t);return{...n,...ie(t.flow,t.service,t.agent),announce:re(o),blocks:[{kind:"rows",rows:[o]}],...!t.agent?.slackUrl&&t.agent?.handle?{foot:Z(t.agent.handle,t.agent.channels??[])}:{},buttons:[]}}default:{let o=Ge(t);return{...n,...ie(t.flow,t.setup.what,t.agent),...t.kind==="finishing"||t.kind==="ended"?{announce:re(o)}:{},subtitle:[{text:je}],blocks:[{kind:"rows",rows:[o]}],buttons:[]}}}}function re(e){return e.detail?`${e.title}. ${e.detail}`:e.title}function ie(e,n,t){return{avatar:"agent",avatarUrl:t?.avatarUrl,title:e==="reconnect"?`Sign ${n} in again`:t?`Connect ${n} to ${t.name}`:`Connect ${n}`}}function Ge(e){let n=e.setup.what;switch(e.kind){case"start":return{icon:"tile",tile:se(n),title:n,detail:Je(e),control:{label:e.flow==="reconnect"?"Reconnect":"Connect",action:"connect",style:"primary"}};case"finishing":return{icon:"now",title:`Waiting for ${n}`,detail:e.slow?"Finish on the Chickpea page that opened, then press I'm done.":"Finish on the Chickpea page that opened, then come back.",control:{label:"I'm done",action:"done",style:"secondary"}};case"ended":return{icon:"failed",title:e.why==="expired"?"This link expired":e.why==="cancelled"?"This link was cancelled":`${n} did not connect`,detail:"Ask for a new link to try again.",control:{label:"Get a new link",action:"new_link",style:"secondary"}};case"elsewhere":return{icon:"tile",tile:se(n),title:n,detail:"Chickpea can't connect it from this card. Use the link in the chat."}}}function We(e){let{check:n}=e;return{icon:"done",title:`${e.service} is connected`,...n==="checking"?{detail:"Chickpea is checking it\u2026"}:n?{detail:`Chickpea checked it. ${n.words}`,...n.status==="ok"||n.status==="unknown"?{}:{tone:"warn"}}:{},...Ke(e)}}function Ke(e){return e.agent?.slackUrl?{control:{label:"Open in Slack",action:"open_slack",style:"secondary"}}:{}}function Je(e){if(e.setup.owner==="member")return"Your own account";if(e.setup.owner==="team")return e.agent?`For everyone who uses ${e.agent.name}`:"For everyone who uses it"}function se(e){return[...e.trim()][0]?.toUpperCase()??"?"}K("chickpea-connect-card",{initial:ae,step:ce,present:pe});})();
</script></body>
</html>