localdeck 1.2.0 → 1.2.1

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.
@@ -0,0 +1 @@
1
+ @font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2) format("woff2"),url(/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff) format("woff")}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2) format("woff2"),url(/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff) format("woff")}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2) format("woff2"),url(/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff) format("woff")}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2) format("woff2"),url(/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff) format("woff")}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2) format("woff2"),url(/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff) format("woff")}:root{color-scheme:light;--bg: #f2f0eb;--bg-2: #e9e7e1;--bg-3: #e1dfd8;--border: #d2d0c9;--text: #23231f;--muted: #62625b;--accent: #bd3c16;--orange: #f26538;--ok: #46633b;--warn: #8a5f19;--err: #bd3c16;--share: #815123;--chrome: #191917;--chrome-border: #3b3b36;--chrome-text: #eeede7;--chrome-muted: #a4a49a;--mono: "IBM Plex Mono", ui-monospace, monospace;--sans: "IBM Plex Sans", system-ui, sans-serif;--text-small: .8125rem;--text-body: .875rem;--text-label: 1rem;--text-section: 1.25rem;--text-title: 2rem;--control-height: 2.5rem}*{box-sizing:border-box}html{font-size:100%}html,body{margin:0;min-width:320px;height:100%;background:var(--chrome);color:var(--text);font-family:var(--sans);line-height:1.5}body{font-size:var(--text-body)}#app{height:100%}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}button{display:inline-flex;align-items:center;justify-content:center;text-align:center;gap:6px;font:500 var(--text-body)/1.4 var(--sans);color:var(--text);background:transparent;border:1px solid var(--border);border-radius:0;padding:7px 12px;min-height:var(--control-height);cursor:pointer;white-space:nowrap}button:hover{background:var(--bg-2);border-color:var(--muted)}button.primary{background:var(--text);border-color:var(--text);color:var(--bg)}button.primary:hover{background:#41413a;border-color:#41413a}button.danger:hover{color:var(--err);border-color:var(--err)}button:disabled{opacity:.45;cursor:default}input,select,textarea{font:inherit;color:var(--text);background:transparent;border:1px solid var(--border);border-radius:0;padding:8px 10px}input:not([type=checkbox]):not([type=radio]),select{min-height:var(--control-height)}input,select,textarea{font-size:var(--text-body);border-color:#8b8b81}input[type=checkbox]{accent-color:var(--accent)}button:focus-visible,a:focus-visible,summary:focus-visible{outline:2px solid var(--muted);outline-offset:3px}code,.mono{font-family:var(--mono);font-size:var(--text-small)}::-webkit-scrollbar{width:7px;height:7px}::-webkit-scrollbar-thumb{background:#8f8f8560}[hidden]{display:none!important}summary{cursor:pointer}pre{overflow:auto}@media(prefers-reduced-motion:reduce){*,*:before,*:after{scroll-behavior:auto!important;transition:none!important}}@media(pointer:coarse),(max-width:760px){:root{--control-height: 2.75rem}input:not([type=checkbox]):not([type=radio]),select,textarea{font-size:1rem}}label:has(input[type=checkbox]){min-height:var(--control-height)}input:focus,input:focus-visible,select:focus,select:focus-visible,textarea:focus,textarea:focus-visible{outline:none!important;box-shadow:none!important}dialog.svelte-vw7b2v{width:min(640px,calc(100vw - 32px));max-height:min(620px,80dvh);margin:12dvh auto auto;padding:0;border:1px solid var(--border);background:var(--bg);color:var(--text);box-shadow:0 24px 80px #0005;overflow:hidden}dialog[open].svelte-vw7b2v{display:flex;flex-direction:column}dialog.svelte-vw7b2v::backdrop{background:#1119}.search-row.svelte-vw7b2v{display:flex;align-items:center;gap:12px;padding:14px 18px;border-bottom:1px solid var(--border);flex-shrink:0}.search-row.svelte-vw7b2v svg{flex-shrink:0;color:var(--muted)}input.svelte-vw7b2v{flex:1;min-width:0;border:0;padding:8px 0}.close.svelte-vw7b2v{min-height:28px;padding:3px 6px;font:12px var(--mono);color:var(--muted)}.results.svelte-vw7b2v{overflow:auto;min-height:0;padding:6px}.results.svelte-vw7b2v button:where(.svelte-vw7b2v){width:100%;justify-content:space-between;gap:16px;border:0;padding:12px;text-align:left;white-space:normal}.results.svelte-vw7b2v button.chosen:where(.svelte-vw7b2v){background:var(--bg-3);box-shadow:inset 3px 0 var(--accent)}.results.svelte-vw7b2v button[aria-disabled=true]:where(.svelte-vw7b2v){color:var(--muted)}strong.svelte-vw7b2v,small.svelte-vw7b2v{display:block}strong.svelte-vw7b2v{font-weight:500}small.svelte-vw7b2v{font-size:var(--text-small);color:var(--muted);overflow-wrap:anywhere}footer.svelte-vw7b2v{display:flex;justify-content:space-between;gap:12px;padding:12px 18px;border-top:1px solid var(--border);font-size:var(--text-small);color:var(--muted);flex-shrink:0}.separator.svelte-vw7b2v{margin:0 6px}.empty.svelte-vw7b2v,.error.svelte-vw7b2v{padding:16px 18px;margin:0}.empty.svelte-vw7b2v{color:var(--muted)}.error.svelte-vw7b2v{color:var(--err)}.load-error.svelte-vw7b2v{display:flex;align-items:center;gap:12px;padding:12px 18px;color:var(--err);border-top:1px solid var(--border);font-size:var(--text-small)}@media(max-width:480px){dialog.svelte-vw7b2v{margin-top:6dvh;max-height:88dvh}.search-row.svelte-vw7b2v{gap:8px;padding:10px}footer.svelte-vw7b2v{flex-wrap:wrap}}section.svelte-1hauwfi{margin-top:32px}h3.svelte-1hauwfi{margin:0 0 12px;font:500 var(--text-section)/1.4 var(--sans)}p.svelte-1hauwfi,li.svelte-1hauwfi{line-height:1.7}p.svelte-1hauwfi{color:var(--muted)}ul.svelte-1hauwfi{padding-left:20px}li.svelte-1hauwfi+li:where(.svelte-1hauwfi){margin-top:8px}.about.svelte-1vwaeio{width:100%;max-width:880px;padding:48px 40px 64px}header.svelte-1vwaeio{max-width:65ch}header.svelte-1vwaeio img:where(.svelte-1vwaeio){display:block;margin:-12px 0 20px -12px}.eyebrow.svelte-1vwaeio{color:var(--muted);margin:0 0 8px}h1.svelte-1vwaeio{font-size:var(--text-title);line-height:1.2;margin:0 0 16px;font-weight:600}h2.svelte-1vwaeio{font-size:var(--text-section);line-height:1.4;margin:0 0 12px;font-weight:600}p.svelte-1vwaeio{line-height:1.6;margin:0 0 16px;max-width:65ch}.intro.svelte-1vwaeio{font-size:var(--text-label)}.about.svelte-1vwaeio>section:where(.svelte-1vwaeio){margin-top:40px;padding-top:28px;border-top:1px solid var(--border)}.steps.svelte-1vwaeio{padding-left:24px;margin:20px 0}.steps.svelte-1vwaeio li:where(.svelte-1vwaeio){padding-left:8px;margin-bottom:16px}.steps.svelte-1vwaeio span:where(.svelte-1vwaeio){display:block;margin-top:4px;color:var(--muted)}.note.svelte-1vwaeio{color:var(--muted);font-size:var(--text-small)}code.svelte-1vwaeio{overflow-wrap:anywhere}.command-groups.svelte-1vwaeio{margin:24px 0;border-top:1px solid var(--border)}details.svelte-1vwaeio{border-bottom:1px solid var(--border)}summary.svelte-1vwaeio{padding:16px 0;min-height:var(--control-height);font-weight:500}summary.svelte-1vwaeio span:where(.svelte-1vwaeio){color:var(--muted);font-size:var(--text-small);font-weight:400;margin-left:12px;white-space:nowrap}dl.svelte-1vwaeio{margin:0 0 16px}dl.svelte-1vwaeio>div:where(.svelte-1vwaeio){padding:16px 0}dl.svelte-1vwaeio>div:where(.svelte-1vwaeio)+div:where(.svelte-1vwaeio){border-top:1px solid var(--border)}dt.svelte-1vwaeio{margin-bottom:8px}dd.svelte-1vwaeio{margin:0;color:var(--muted);line-height:1.6;max-width:65ch}@media(max-width:760px){.about.svelte-1vwaeio{padding:24px 16px 40px}header.svelte-1vwaeio img:where(.svelte-1vwaeio){width:112px;height:112px;margin-left:-8px}summary.svelte-1vwaeio span:where(.svelte-1vwaeio){display:block;margin:4px 0 0 18px}}h3.svelte-1offp6a{margin-top:32px;font:500 var(--text-section)/1.4 var(--sans)}label.svelte-1offp6a{display:block;margin-bottom:8px}.controls.svelte-1offp6a{display:flex;align-items:center;gap:8px}input.svelte-1offp6a{width:160px}input.svelte-1offp6a:focus-visible{outline:none;border-color:var(--text)}p.svelte-1offp6a{color:var(--muted);line-height:1.6}.current.svelte-1offp6a{font-size:var(--text-small)}.changelog.svelte-1tl5wtp{padding:48px 40px}header.svelte-1tl5wtp{padding-bottom:24px;border-bottom:1px solid var(--border)}h1.svelte-1tl5wtp{margin:0 0 12px;font:600 var(--text-title)/1.2 var(--sans)}header.svelte-1tl5wtp p:where(.svelte-1tl5wtp){margin:0;color:var(--muted)}article.svelte-1tl5wtp{padding:28px 0;border-bottom:1px solid var(--border)}h2.svelte-1tl5wtp{margin:0 0 16px;font:500 var(--text-section)/1.4 var(--sans)}h2.svelte-1tl5wtp span:where(.svelte-1tl5wtp){color:var(--muted);margin-left:12px;font-size:var(--text-label)}h3.svelte-1tl5wtp{font-size:var(--text-label);font-weight:500;margin:0 0 10px}.release-section.svelte-1tl5wtp{max-width:100ch;margin-top:28px}li.svelte-1tl5wtp+li:where(.svelte-1tl5wtp){margin-top:8px}ul.svelte-1tl5wtp{margin:0;padding-left:20px;line-height:1.8}@media(max-width:760px){.changelog.svelte-1tl5wtp{padding:24px 16px}}.secrets.svelte-sh54s5{margin-top:28px}h2.svelte-sh54s5{font-size:18px;margin:0;font-weight:500}.section-heading.svelte-sh54s5{display:flex;align-items:center;justify-content:space-between;gap:16px}.count.svelte-sh54s5,.section-note.svelte-sh54s5{font-size:var(--text-small);color:var(--muted)}.section-note.svelte-sh54s5{margin:8px 0 22px;line-height:1.6}ul.svelte-sh54s5{padding:0;margin:0;list-style:none}.list-heading.svelte-sh54s5,li.svelte-sh54s5{display:grid;grid-template-columns:minmax(0,1fr) 130px minmax(124px,auto);gap:16px;align-items:center}.list-heading.svelte-sh54s5{padding:0 0 10px;border-bottom:1px solid var(--border);color:var(--muted);font-size:var(--text-small)}li.svelte-sh54s5{min-height:66px;padding:12px 0;border-bottom:1px solid var(--border)}code.svelte-sh54s5{overflow-wrap:anywhere;font-size:var(--text-small)}.secret-status.svelte-sh54s5{display:flex;gap:7px;align-items:center;font-size:var(--text-small);color:var(--muted)}.secret-status.svelte-sh54s5 i:where(.svelte-sh54s5){width:6px;height:6px;flex-shrink:0;background:currentColor}.secret-status.configured.svelte-sh54s5{color:var(--ok)}.actions.svelte-sh54s5{display:flex;justify-content:flex-end;gap:14px}.text-action.svelte-sh54s5{padding:4px 0;min-height:32px;border:0;background:transparent;font-size:var(--text-small);text-decoration:underline;text-underline-offset:4px}.text-action.svelte-sh54s5:hover{text-decoration-thickness:2px}.remove.svelte-sh54s5{color:var(--muted)}.count.svelte-sh54s5{display:block;margin-top:6px}.secret-editor.svelte-sh54s5{position:relative}summary.svelte-sh54s5{cursor:pointer;list-style:none;display:inline-flex;gap:7px;align-items:center;justify-content:center}summary.svelte-sh54s5::-webkit-details-marker{display:none}summary[aria-disabled=true].svelte-sh54s5{opacity:.5;cursor:default}.add-secret.svelte-sh54s5{padding:7px 12px;min-height:var(--control-height);border:1px solid var(--border);font-weight:500}.add-secret.svelte-sh54s5:hover{background:var(--bg-2)}.editor-popover.svelte-sh54s5{position:absolute;top:calc(100% + 8px);right:0;z-index:40;width:min(340px,calc(100vw - 110px));padding:20px;background:var(--bg);border:1px solid var(--border);box-shadow:0 8px 24px #0002;text-align:left}.editor-popover.svelte-sh54s5 h2:where(.svelte-sh54s5){margin-bottom:20px}.editor-popover.svelte-sh54s5 .section-note:where(.svelte-sh54s5){margin:14px 0}.editor-popover.svelte-sh54s5 .primary:where(.svelte-sh54s5){width:100%}.fields.svelte-sh54s5{display:grid;grid-template-columns:1fr;gap:16px}label.svelte-sh54s5{display:grid;gap:8px;font-size:var(--text-small);font-weight:500;min-width:0}input.svelte-sh54s5{width:100%;min-width:0;background:var(--bg)}.storage-note.svelte-sh54s5{margin-top:28px;padding-left:14px;border-left:2px solid var(--border);max-width:680px;font-size:var(--text-small);color:var(--muted)}.storage-note.svelte-sh54s5 strong:where(.svelte-sh54s5){font-weight:500;color:var(--text)}.storage-note.svelte-sh54s5 p:where(.svelte-sh54s5){margin:6px 0 0;line-height:1.6}.error.svelte-sh54s5{color:var(--err)}.saved.svelte-sh54s5{color:var(--ok)}.empty.svelte-sh54s5{padding:22px 0;border-block:1px solid var(--border);color:var(--muted)}@media(max-width:1000px){.list-heading.svelte-sh54s5{display:none}li.svelte-sh54s5{grid-template-columns:minmax(0,1fr) auto;gap:8px 16px}.secret-status.svelte-sh54s5{grid-column:1;grid-row:2}.actions.svelte-sh54s5{grid-column:2;grid-row:1 / 3}}@media(max-width:650px){.fields.svelte-sh54s5{grid-template-columns:1fr;gap:16px}form.svelte-sh54s5{padding:18px}}.share-line.svelte-iodvty{display:flex;align-items:center;flex-wrap:wrap;gap:8px 16px;min-width:0}.slow-hint.svelte-iodvty{flex-basis:100%;color:var(--muted);font-size:var(--text-small)}.slow-hint.svelte-iodvty a:where(.svelte-iodvty){text-decoration:underline}.password.svelte-iodvty{display:inline-flex;flex-wrap:wrap;align-items:center;gap:7px;color:var(--muted);font-size:var(--text-small);overflow-wrap:anywhere}.password.svelte-iodvty button:where(.svelte-iodvty){padding:0;min-height:0;border:0;background:transparent;text-decoration:underline;color:inherit}a.svelte-iodvty{width:fit-content;max-width:100%;overflow-wrap:anywhere;color:var(--share);font-size:var(--text-small)}.connecting.svelte-iodvty,.error.svelte-iodvty{display:flex;align-items:center;gap:7px;font-size:var(--text-small)}.connecting.svelte-iodvty{flex-wrap:wrap;color:var(--muted)}.error.svelte-iodvty{color:var(--err);align-items:flex-start;overflow-wrap:anywhere}.error.svelte-iodvty svg{flex-shrink:0;margin-top:3px}.spinner.svelte-iodvty{display:inline-flex;animation:svelte-iodvty-spin 1s linear infinite}@keyframes svelte-iodvty-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.spinner.svelte-iodvty{animation:none}}.menu-item.svelte-1u7hpyn>summary:where(.svelte-1u7hpyn){justify-content:flex-start;gap:10px;border:0;font-weight:400;padding:10px 12px}.menu-item.svelte-1u7hpyn .share-popover:where(.svelte-1u7hpyn){position:static;width:100%;box-shadow:none;border:0;padding:12px}.share-control.svelte-1u7hpyn{position:relative}summary.svelte-1u7hpyn{display:flex;align-items:center;justify-content:center;gap:7px;padding:7px 12px;min-height:var(--control-height);border:1px solid var(--border);list-style:none;font-weight:500}summary.svelte-1u7hpyn::-webkit-details-marker{display:none}summary.svelte-1u7hpyn:hover{background:var(--bg-2);border-color:var(--muted)}.share-popover.svelte-1u7hpyn{position:absolute;right:0;top:calc(100% + 8px);z-index:30;width:min(340px,calc(100vw - 96px));padding:18px;border:1px solid var(--border);background:var(--bg);box-shadow:0 8px 24px #0002;text-align:left}.share-url.svelte-1u7hpyn{display:block;margin-top:12px;overflow-wrap:anywhere}p.svelte-1u7hpyn{font-size:var(--text-small);color:var(--muted);line-height:1.6;overflow-wrap:anywhere}label.svelte-1u7hpyn{display:grid;gap:6px;font-size:var(--text-small)}input.svelte-1u7hpyn{width:100%;min-width:0}.actions.svelte-1u7hpyn{display:flex;flex-wrap:wrap;gap:8px}.error.svelte-1u7hpyn{color:var(--err)}.service-options.svelte-m918bk{position:relative}summary.svelte-m918bk{display:flex;align-items:center;justify-content:center;gap:8px;padding:7px 12px;min-height:var(--control-height);border:1px solid var(--border);list-style:none;font-weight:500;cursor:pointer}summary.svelte-m918bk::-webkit-details-marker{display:none}summary.svelte-m918bk:hover,.service-options[open].svelte-m918bk>summary:where(.svelte-m918bk){background:var(--bg-2);border-color:var(--muted)}.options-popover.svelte-m918bk{position:absolute;z-index:40;right:0;top:calc(100% + 6px);width:min(300px,calc(100vw - 100px));padding:6px;background:var(--bg);border:1px solid var(--border);box-shadow:0 8px 24px #0002}.options-popover.svelte-m918bk>button:where(.svelte-m918bk){width:100%;border:0;background:transparent;display:flex;gap:10px;justify-content:flex-start;padding:10px 12px;text-align:left;font-weight:400}.options-popover.svelte-m918bk>button:where(.svelte-m918bk):hover{background:var(--bg-2)}.share-action.svelte-m918bk{border-top:1px solid var(--border);margin-top:4px;padding-top:4px}.service-error.svelte-13pnhk8{padding:12px 0;font-size:var(--text-small);overflow-wrap:anywhere}strong.svelte-13pnhk8,p.svelte-13pnhk8{color:var(--err)}p.svelte-13pnhk8{margin:0;white-space:pre-wrap}ul.svelte-13pnhk8{margin:8px 0 12px;padding-left:20px;color:var(--text);line-height:1.7}li.svelte-13pnhk8+li:where(.svelte-13pnhk8){margin-top:6px}summary.svelte-13pnhk8{width:fit-content;color:var(--muted)}pre.svelte-13pnhk8{margin:8px 0 0;white-space:pre-wrap;font:inherit;font-family:var(--mono);color:var(--muted)}.diagnostics.svelte-1xk5qw3{margin:16px 0;padding:12px;border:1px solid var(--border);border-radius:0}summary.svelte-1xk5qw3{cursor:pointer}p.svelte-1xk5qw3{color:var(--muted);font-size:var(--text-small)}textarea.svelte-1xk5qw3{display:block;width:100%;box-sizing:border-box;margin:8px 0;background:var(--bg-2);color:var(--text);border:1px solid var(--border);font:var(--text-small)/1.5 var(--mono)}form.svelte-1gn57ev{width:100%;min-width:0;padding:20px 0 8px}fieldset.svelte-1gn57ev{border:0;padding:0;margin:0;min-width:0}.fields.svelte-1gn57ev{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}label.svelte-1gn57ev{display:flex;flex-direction:column;gap:6px;font-size:var(--text-body);color:var(--text)}input.svelte-1gn57ev,select.svelte-1gn57ev{width:100%;min-width:0;background:var(--bg)}.dependencies.svelte-1gn57ev{margin:20px 0;font-size:var(--text-small)}.dependencies.svelte-1gn57ev>div:where(.svelte-1gn57ev){display:flex;flex-wrap:wrap;gap:16px;margin-top:8px}.dependencies.svelte-1gn57ev label:where(.svelte-1gn57ev){flex-direction:row;align-items:center}.dependencies.svelte-1gn57ev input:where(.svelte-1gn57ev){width:auto}p.svelte-1gn57ev{color:var(--muted);font-size:var(--text-small)}.error.svelte-1gn57ev{color:var(--err)}@media(max-width:600px){.fields.svelte-1gn57ev{grid-template-columns:1fr}}form.svelte-ruqv4s{margin:24px 0 40px;max-width:480px}label.svelte-ruqv4s{font-weight:600}p.svelte-ruqv4s{font-size:var(--text-small);color:var(--muted);line-height:1.6}.controls.svelte-ruqv4s{display:flex;gap:8px;margin-top:8px}input.svelte-ruqv4s{flex:1;width:180px;min-width:0}.error.svelte-ruqv4s{color:var(--err);margin-bottom:0}.notice.svelte-ruqv4s{color:var(--ok);margin-bottom:0}.hint.svelte-ruqv4s{font-size:var(--text-small)}.service-port.svelte-1poq4pf{display:flex;flex-wrap:wrap;gap:4px 16px;color:var(--muted);font-size:var(--text-small);line-height:1.5}strong.svelte-1poq4pf{color:var(--text);font-weight:500}.project-overview.svelte-l7un4l{min-height:100%;padding:48px 40px 40px;width:100%;max-width:1500px;margin:0 auto;display:flex;flex-direction:column}header.svelte-l7un4l{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:20px}.heading.svelte-l7un4l{min-width:0}.eyebrow.svelte-l7un4l{margin:0 0 3px;color:var(--muted);font-size:var(--text-small);font-weight:600;letter-spacing:.1em;text-transform:none}h1.svelte-l7un4l,h2.svelte-l7un4l,p.svelte-l7un4l{margin-top:0}h1.svelte-l7un4l{margin:0 0 18px;font:600 var(--text-title)/1.4 var(--sans);letter-spacing:0;line-height:1.2;overflow-wrap:anywhere}h2.svelte-l7un4l{margin-bottom:8px;font-size:var(--text-section)}.project-actions.svelte-l7un4l,.service-actions.svelte-l7un4l,.recovery-actions.svelte-l7un4l{display:flex;align-items:center;gap:8px}.summary-row.svelte-l7un4l{display:flex;flex-wrap:wrap;gap:14px;padding:4px 0;color:var(--muted);font-size:var(--text-small)}.summary-row.svelte-l7un4l strong:where(.svelte-l7un4l){color:var(--text);font-variant-numeric:tabular-nums}.bulk-actions.svelte-l7un4l{margin-bottom:24px}.bulk-summary.svelte-l7un4l{margin:0 0 10px;color:var(--muted)}.service-grid.svelte-l7un4l{display:grid;grid-template-columns:1fr;gap:0}.service-card.svelte-l7un4l{min-width:0;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:16px;padding:22px 0;border-bottom:1px solid var(--border)}.service-card.failed.svelte-l7un4l{border-color:#f87171a6}.service-main.svelte-l7un4l{display:grid;grid-template-columns:minmax(0,1fr);justify-content:stretch;width:100%;padding:0;border:0;background:transparent;text-align:left;white-space:normal}.service-main.svelte-l7un4l:hover{background:transparent}.service-heading.svelte-l7un4l{display:flex;align-items:center;gap:8px}.status-dot.svelte-l7un4l{width:7px;height:7px;border-radius:0;background:var(--muted)}.status-dot.running.svelte-l7un4l{background:var(--ok)}.status-dot.waiting.svelte-l7un4l{background:var(--warn)}.status-text.svelte-l7un4l{margin-left:8px;color:var(--muted);font-size:var(--text-small);background:var(--bg-3);border-radius:0;padding:2px 7px}.ownership.svelte-l7un4l{margin:4px 0 8px 15px;color:var(--muted);font-size:var(--text-small)}.service-url.svelte-l7un4l{color:var(--accent);overflow:hidden;text-overflow:ellipsis}.command.svelte-l7un4l{margin-top:7px;color:var(--text);overflow:hidden;text-overflow:ellipsis}.dependency-summary.svelte-l7un4l{margin-top:7px;color:var(--accent);font-size:var(--text-small)}.dependency-summary.svelte-l7un4l span:where(.svelte-l7un4l){color:var(--muted)}.dependency-editor.svelte-l7un4l{margin-top:10px;padding-top:9px;border-top:1px solid var(--border)}.dependency-editor.svelte-l7un4l summary:where(.svelte-l7un4l){color:var(--muted);cursor:pointer;font-size:var(--text-small)}.dependency-editor.svelte-l7un4l form:where(.svelte-l7un4l){margin-top:9px}.dependency-editor.svelte-l7un4l fieldset:where(.svelte-l7un4l){display:flex;flex-wrap:wrap;gap:7px 12px;margin:0;padding:0;border:0}.dependency-editor.svelte-l7un4l legend:where(.svelte-l7un4l){width:100%;margin-bottom:6px;color:var(--muted);font-size:var(--text-small)}.dependency-editor.svelte-l7un4l label:where(.svelte-l7un4l){display:inline-flex;align-items:center;gap:5px;font-size:var(--text-small)}.dependency-actions.svelte-l7un4l{display:flex;gap:7px;margin-top:10px}.no-dependencies.svelte-l7un4l{color:var(--muted);font-size:var(--text-small)}.inline-error.svelte-l7un4l{margin:9px 0 0;color:var(--err);font-size:var(--text-small);overflow-wrap:anywhere}.unavailable.svelte-l7un4l{display:flex;justify-content:space-between;align-items:center;gap:20px;margin-top:16px;padding:16px;border:1px solid rgba(248,113,113,.55);border-radius:0;background:var(--bg-2)}.unavailable.svelte-l7un4l p:where(.svelte-l7un4l),.empty-services.svelte-l7un4l p:where(.svelte-l7un4l){margin-bottom:0;color:var(--muted)}.active-services.svelte-l7un4l{margin-top:18px}.active-services.svelte-l7un4l>h2:where(.svelte-l7un4l){margin-bottom:3px}.active-services.svelte-l7un4l>p:where(.svelte-l7un4l){margin-bottom:10px;color:var(--muted)}.empty-services.svelte-l7un4l{grid-column:1 / -1;padding:24px;border:1px dashed var(--border);border-radius:0;text-align:center}.launch-panel.svelte-l7un4l{padding:20px;background:var(--bg-2);border:1px solid var(--err);border-radius:0;margin-bottom:32px}.launch-panel.svelte-l7un4l h2:where(.svelte-l7un4l){font-size:var(--text-section);letter-spacing:-.025em;margin:7px 0}.launch-panel.svelte-l7un4l p:where(.svelte-l7un4l):last-child{color:var(--muted);margin-bottom:0;font-size:var(--text-small)}.open-app.svelte-l7un4l{display:inline-flex;align-items:center;gap:10px;padding:7px 12px;min-height:var(--control-height);font-family:var(--sans);line-height:1.4;border-radius:0;background:var(--text);color:var(--bg);font-weight:600;white-space:nowrap;font-size:var(--text-body)}.open-app.svelte-l7un4l:hover{background:#41413a;text-decoration:none}.list-heading.svelte-l7un4l{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:18px}.list-heading.svelte-l7un4l h2:where(.svelte-l7un4l){font-size:var(--text-section);margin:0;font-weight:600}.service-search.svelte-l7un4l span:where(.svelte-l7un4l){display:block;color:var(--muted);font-size:var(--text-small);margin-bottom:4px}.service-search.svelte-l7un4l input:where(.svelte-l7un4l){background:var(--bg-2);width:220px}.service-heading.svelte-l7un4l strong:where(.svelte-l7un4l){font-size:var(--text-body)}.service-settings.svelte-l7un4l{grid-column:1 / -1;margin-top:14px;border-top:1px solid var(--border);padding-top:9px;color:var(--muted);font-size:var(--text-small)}.service-settings[open].svelte-l7un4l{padding-bottom:12px}.service-open.svelte-l7un4l{font-weight:600;padding:8px;white-space:nowrap}.service-actions.svelte-l7un4l{flex-wrap:wrap;justify-content:flex-end}.copy.svelte-l7un4l{background:transparent}.service-links.svelte-l7un4l{display:grid;gap:5px;margin-top:8px;min-width:0}.service-links.svelte-l7un4l a:where(.svelte-l7un4l){width:fit-content;max-width:100%;overflow-wrap:anywhere;font-size:var(--text-small)}.inline-error.svelte-l7un4l{grid-column:1 / -1}.settings-panel.svelte-l7un4l{width:100%;min-width:0}.settings-title.svelte-l7un4l{margin:28px 0 8px}.settings-project.svelte-l7un4l,.settings-note.svelte-l7un4l{color:var(--muted);font-size:var(--text-small)}.config-list.svelte-l7un4l{width:100%;min-width:0;margin:20px 0 32px;border-top:1px solid var(--border)}.config-list.svelte-l7un4l>details:where(.svelte-l7un4l){min-width:0;border-bottom:1px solid var(--border);padding:16px 0}.config-list.svelte-l7un4l summary:where(.svelte-l7un4l){min-height:var(--control-height);display:flex;gap:20px;align-items:center;list-style:none}.config-list.svelte-l7un4l summary:where(.svelte-l7un4l)::-webkit-details-marker{display:none}.config-list.svelte-l7un4l summary:where(.svelte-l7un4l) strong:where(.svelte-l7un4l){min-width:80px;font:500 var(--text-label)/1.4 var(--sans)}.config-list.svelte-l7un4l summary:where(.svelte-l7un4l) span:where(.svelte-l7un4l){color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-small)}.config-list.svelte-l7un4l summary:where(.svelte-l7un4l) .edit-label:where(.svelte-l7un4l){margin-left:auto;flex-shrink:0;color:var(--text)}.settings-tools.svelte-l7un4l{padding:12px 0;color:var(--muted)}.settings-panel.svelte-l7un4l h2:where(.svelte-l7un4l){margin-top:24px}.project-health.svelte-l7un4l{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:var(--text-label);margin-bottom:0}.project-health.svelte-l7un4l:has(.running:where(.svelte-l7un4l)){color:var(--ok)}.project-address.svelte-l7un4l{display:flex;align-items:center;gap:12px;min-width:0;color:var(--muted);padding:24px 0;border-bottom:1px solid var(--border);margin-bottom:28px}.project-address.svelte-l7un4l a:where(.svelte-l7un4l){color:var(--muted);overflow-wrap:anywhere;font-size:var(--text-body)}.project-address.svelte-l7un4l button:where(.svelte-l7un4l),.manage-button.svelte-l7un4l{display:inline-flex;align-items:center;border:0;background:transparent;color:var(--muted);padding:10px}.manage-button.svelte-l7un4l{text-decoration:none;border:1px solid var(--border);min-height:var(--control-height);gap:8px;padding:7px 12px;justify-content:center}.overview-row.svelte-l7un4l{display:grid;grid-template-columns:36px minmax(90px,1fr) minmax(60px,.8fr) minmax(90px,1fr);gap:16px;align-items:center;width:100%;font-size:var(--text-body)}.overview-row.svelte-l7un4l strong:where(.svelte-l7un4l){font-size:var(--text-label);font-weight:500;overflow-wrap:anywhere}.service-icon.svelte-l7un4l{width:36px;height:36px;display:grid;place-items:center;border:1px solid var(--border);border-radius:0;background:var(--bg-2);color:var(--muted)}.technical-name.svelte-l7un4l{color:var(--muted);font-weight:400;overflow-wrap:anywhere}.row-health.svelte-l7un4l{display:flex;align-items:center;gap:9px;color:var(--muted);font-weight:400}.row-health.svelte-l7un4l .status-dot:where(.svelte-l7un4l){background:currentColor;flex-shrink:0}.row-health.ready.svelte-l7un4l{color:var(--ok)}.row-health.errored.svelte-l7un4l{color:var(--err)}.row-health.svelte-l7un4l{text-transform:capitalize}.readiness-summary.svelte-l7un4l{color:var(--muted);font-size:var(--text-body);margin:24px 0 48px}.managing.svelte-l7un4l{margin-top:32px}.muted.svelte-l7un4l{color:var(--muted)}.profiles.svelte-l7un4l{padding:18px;border:1px solid var(--border);border-radius:0;background:var(--bg-2)}.profiles[open].svelte-l7un4l summary:where(.svelte-l7un4l){margin-bottom:16px}@media(min-width:801px)and (max-width:1100px){.project-overview.svelte-l7un4l{padding:48px 28px}.overview-row.svelte-l7un4l{grid-template-columns:48px minmax(0,1fr) auto;gap:16px}.technical-name.svelte-l7un4l{white-space:nowrap;display:none}.managing.svelte-l7un4l .service-card:where(.svelte-l7un4l){grid-template-columns:1fr}.managing.svelte-l7un4l .service-actions:where(.svelte-l7un4l){justify-content:flex-start;margin-top:16px}}@media(max-width:800px){.project-overview.svelte-l7un4l{padding:16px}header.svelte-l7un4l,.unavailable.svelte-l7un4l{align-items:stretch;flex-direction:column}.project-actions.svelte-l7un4l button:where(.svelte-l7un4l),.recovery-actions.svelte-l7un4l button:where(.svelte-l7un4l){flex:1}.service-grid.svelte-l7un4l{grid-template-columns:1fr}.service-card.svelte-l7un4l{grid-template-columns:1fr;padding:18px}.service-actions.svelte-l7un4l{justify-content:flex-start;margin-top:16px;gap:6px}.service-actions.svelte-l7un4l button:where(.svelte-l7un4l){padding:8px 10px}.launch-panel.svelte-l7un4l{align-items:flex-start;flex-direction:column;padding:20px}.list-heading.svelte-l7un4l{align-items:stretch;flex-direction:column}.service-search.svelte-l7un4l input:where(.svelte-l7un4l){width:100%}.project-actions.svelte-l7un4l{flex-wrap:wrap}header.svelte-l7un4l{flex-direction:row;align-items:flex-start;gap:12px}h1.svelte-l7un4l{font-size:1.5rem}.open-app.svelte-l7un4l{padding:7px 12px;font-size:var(--text-small)}.project-actions.svelte-l7un4l{gap:8px;flex-shrink:0}.manage-button.svelte-l7un4l{min-height:var(--control-height)}.project-address.svelte-l7un4l{padding:24px 0;margin-bottom:28px}.overview-row.svelte-l7un4l{grid-template-columns:40px minmax(0,1fr) auto;gap:12px}.service-icon.svelte-l7un4l{width:40px;height:40px}.technical-name.svelte-l7un4l{white-space:nowrap;display:none}.overview-row.svelte-l7un4l strong:where(.svelte-l7un4l){font-size:var(--text-label)}.row-health.svelte-l7un4l{font-size:var(--text-small)}.service-card.svelte-l7un4l{padding:18px 0}}.service-row.svelte-1h3c7zm{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px 24px;padding:20px 0;border-bottom:1px solid var(--border)}.service-info.svelte-1h3c7zm{display:grid;gap:5px;min-width:0}.service-heading.svelte-1h3c7zm{display:flex;align-items:center;gap:9px}strong.svelte-1h3c7zm{font-size:var(--text-label);font-weight:500}.status-dot.svelte-1h3c7zm{width:7px;height:7px;background:var(--muted);flex-shrink:0}.status-dot.running.svelte-1h3c7zm{background:var(--ok)}.service-status.svelte-1h3c7zm,.project-name.svelte-1h3c7zm{color:var(--muted);font-size:var(--text-small)}.service-status.svelte-1h3c7zm{margin-left:6px}.service-address.svelte-1h3c7zm{width:fit-content;max-width:100%;overflow-wrap:anywhere;color:var(--text)}.service-controls.svelte-1h3c7zm{display:flex;align-items:center;gap:8px;flex-wrap:wrap}button.svelte-1h3c7zm{display:inline-flex;justify-content:center;align-items:center;gap:7px}.action-error.svelte-1h3c7zm{grid-column:1 / -1;margin:0;color:var(--err);font-size:var(--text-small)}@media(max-width:900px){.service-row.svelte-1h3c7zm{grid-template-columns:minmax(0,1fr)}.service-controls.svelte-1h3c7zm{justify-content:flex-start}}.metadata.svelte-s74nzf{display:flex;flex-direction:column;margin:16px 0}details.svelte-s74nzf{min-width:0;border-bottom:1px solid var(--chrome-border)}summary.svelte-s74nzf{display:flex;align-items:center;justify-content:space-between;padding:10px 0;list-style:none;cursor:pointer;font-weight:600;color:var(--chrome-text)}summary.svelte-s74nzf::-webkit-details-marker{display:none}summary.svelte-s74nzf:after{content:"›";font-size:1rem}details[open].svelte-s74nzf>summary:where(.svelte-s74nzf):after{transform:rotate(90deg)}summary.svelte-s74nzf:hover{color:#fff}pre.svelte-s74nzf{white-space:pre-wrap;overflow-wrap:anywhere;font:.75rem/1.6 var(--mono)}dl.svelte-s74nzf{margin:8px 0;font-family:var(--mono)}dl.svelte-s74nzf>div:where(.svelte-s74nzf){display:grid;grid-template-columns:minmax(90px,1fr) minmax(0,2fr);gap:12px;padding:5px 0;border-bottom:1px solid var(--chrome-border)}dt.svelte-s74nzf,dd.svelte-s74nzf{overflow-wrap:anywhere;white-space:pre-wrap}dd.svelte-s74nzf{margin:0;color:var(--chrome-muted)}h4.svelte-s74nzf{font-size:inherit;margin:12px 0 6px}p.svelte-s74nzf{color:var(--chrome-muted)}.requests-panel.svelte-tqqrb7{flex:1;min-height:0;overflow:auto;font-size:.75rem}.request-list.svelte-tqqrb7{min-height:80px}table.svelte-tqqrb7{width:100%;border-collapse:collapse;text-align:left}th.svelte-tqqrb7,td.svelte-tqqrb7{padding:6px 14px;border-bottom:1px solid var(--chrome-border)}th.svelte-tqqrb7{position:sticky;top:0;background:var(--chrome);color:var(--chrome-muted)}.request-row.svelte-tqqrb7{cursor:pointer;transition:background-color .12s ease}.request-row.selected.svelte-tqqrb7{background:#ffffff0b}.request-row.svelte-tqqrb7:hover,.request-row.svelte-tqqrb7:focus-within{background:#ffffff18}@media(prefers-reduced-motion:reduce){.request-row.svelte-tqqrb7{transition:none}}button.svelte-tqqrb7{font:inherit;color:var(--chrome-text);background:transparent;min-height:0}td.svelte-tqqrb7 button:where(.svelte-tqqrb7){padding:0;border:0;text-decoration:underline;text-align:left;white-space:normal;overflow-wrap:anywhere}.inspector.svelte-tqqrb7{padding:12px 14px;overflow-wrap:anywhere}p.svelte-tqqrb7,span.svelte-tqqrb7{color:var(--chrome-muted)}.replay.svelte-tqqrb7{border:1px solid var(--chrome-border);padding:6px 10px}.error.svelte-tqqrb7{color:#ff9c92}.empty.svelte-tqqrb7{padding:14px}.request-filter-bar.svelte-147la1m{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;padding:8px 14px;color:var(--chrome-muted);font-size:.75rem;border-bottom:1px solid var(--chrome-border)}.request-filter-bar.svelte-147la1m label:where(.svelte-147la1m){display:flex;align-items:center;gap:6px;cursor:pointer}.logs-dock.svelte-147la1m{position:relative;display:flex;flex-direction:column;min-height:0;min-width:0;color:var(--chrome-text);background:var(--chrome);border-top:1px solid var(--chrome-border)}.resize-handle.svelte-147la1m{position:absolute;top:-4px;left:0;right:0;height:8px;cursor:ns-resize;touch-action:none;z-index:31}.resize-handle.svelte-147la1m:hover,.resize-handle.svelte-147la1m:focus-visible{background:var(--chrome-muted);outline:none}.logs-toolbar.svelte-147la1m{display:flex;align-items:center;gap:8px;padding:8px 14px;flex:0 0 auto}h2.svelte-147la1m{display:flex;align-items:center;gap:8px;margin:0 10px 0 0;font-size:.875rem;font-weight:500}button.svelte-147la1m,summary.svelte-147la1m{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;color:var(--chrome-text);border-color:var(--chrome-border);font-size:.75rem;padding:5px 9px}button.svelte-147la1m:hover,summary.svelte-147la1m:hover{background:#ffffff0b;border-color:var(--chrome-muted)}button.svelte-147la1m:focus-visible,summary.svelte-147la1m:focus-visible,input.svelte-147la1m:focus-visible,.log-output.svelte-147la1m:focus-visible{outline:2px solid var(--chrome-muted);outline-offset:-2px}.source-picker.svelte-147la1m{position:relative;flex-shrink:0}summary.svelte-147la1m{list-style:none;border:1px solid var(--chrome-border)}summary.svelte-147la1m::-webkit-details-marker{display:none}.count.svelte-147la1m{color:var(--chrome-muted)}.source-options.svelte-147la1m{position:absolute;top:calc(100% + 8px);left:0;z-index:30;width:min(300px,calc(100vw - 40px));max-height:min(260px,calc(var(--logs-height) - 100px));overflow:auto;border:1px solid var(--chrome-border);padding:8px;background:var(--chrome);box-shadow:0 8px 24px #0005}.picker-label.svelte-147la1m{color:var(--chrome-muted);padding:5px 8px 8px;font-size:.75rem}.source-options.svelte-147la1m label:where(.svelte-147la1m){display:flex;align-items:center;gap:9px;padding:6px 8px;cursor:pointer;font-size:.8125rem}.source-options.svelte-147la1m label:where(.svelte-147la1m):hover{background:#ffffff0b}.source-options.svelte-147la1m small:where(.svelte-147la1m){display:block;color:var(--chrome-muted)}.source-options.svelte-147la1m input:where(.svelte-147la1m){accent-color:var(--chrome-muted)}.filter.svelte-147la1m{display:flex;align-items:center;gap:7px;flex:1;min-width:110px;max-width:360px;color:var(--chrome-muted);border:1px solid var(--chrome-border);padding-left:9px}.filter.svelte-147la1m input:where(.svelte-147la1m){min-width:0;width:100%;min-height:30px;border:0;padding:4px 8px 4px 0;font-size:.75rem;color:var(--chrome-text)}.filter.svelte-147la1m input:where(.svelte-147la1m)::placeholder{color:var(--chrome-muted)}.close.svelte-147la1m{margin-left:auto;width:32px;padding:0;flex-shrink:0;border:0;background:transparent;color:var(--chrome-muted)}.close.svelte-147la1m:hover{background:transparent;color:var(--chrome-text)}.source-tabs.svelte-147la1m{display:flex;gap:0;flex-shrink:0;overflow-x:auto;border-bottom:1px solid var(--chrome-border);padding:0 14px}.source-tabs.svelte-147la1m button:where(.svelte-147la1m){border:0;border-bottom:2px solid transparent;color:var(--chrome-muted);padding:5px 12px}.source-tabs.svelte-147la1m button.active:where(.svelte-147la1m){border-bottom-color:var(--chrome-text);color:var(--chrome-text)}.source-tab.svelte-147la1m{display:flex;flex-shrink:0;align-items:center}.source-tabs.svelte-147la1m .clear-source:where(.svelte-147la1m){padding:5px}.clear-source.svelte-147la1m:disabled{opacity:.4;cursor:wait}.project-name.svelte-147la1m{opacity:.7}.log-output.svelte-147la1m{flex:1;overflow:auto;min-height:0;padding:8px 14px;font:.75rem/1.7 var(--mono)}.log-row.svelte-147la1m{display:flex;gap:14px;width:max-content;min-width:100%}time.svelte-147la1m{color:var(--chrome-muted);flex:0 0 8ch}.source.svelte-147la1m{color:#bcbcb1;width:24ch;flex-shrink:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.stream.svelte-147la1m{width:6ch;flex-shrink:0;color:var(--chrome-muted)}.line.svelte-147la1m{white-space:pre}.shared.svelte-147la1m{color:#91c7c4}.shared.svelte-147la1m .stream:where(.svelte-147la1m){color:#91c7c4;font-weight:500}.stderr.svelte-147la1m .stream:where(.svelte-147la1m){color:#d1b78d}.empty.svelte-147la1m{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:100%;gap:4px;text-align:center;font-family:var(--sans)}.empty.svelte-147la1m strong:where(.svelte-147la1m){font-weight:500;font-size:.8125rem}.empty.svelte-147la1m span:where(.svelte-147la1m){color:var(--chrome-muted)}.history-error.svelte-147la1m{padding:8px 14px;color:var(--chrome-text);display:flex;align-items:center;gap:12px}.logs-status.svelte-147la1m{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-shrink:0;min-height:30px;padding:0 14px;border-top:1px solid var(--chrome-border);color:var(--chrome-muted);font-size:.6875rem}.logs-status.svelte-147la1m button:where(.svelte-147la1m){border:0;min-height:28px;font-size:.6875rem;padding:2px 5px}@media(max-width:680px){.logs-toolbar.svelte-147la1m{flex-wrap:wrap;gap:6px;padding:6px 10px}h2.svelte-147la1m{margin-right:0}.filter.svelte-147la1m{order:5;flex-basis:100%;max-width:none}.record-count.svelte-147la1m{display:none}.source.svelte-147la1m{width:18ch}}.secrets-page.svelte-1n46o8q{padding:36px 40px 56px;width:100%;max-width:1080px}.secrets-page-heading.svelte-1n46o8q{margin-top:28px;padding-bottom:24px;border-bottom:1px solid var(--border)}.secrets-page-heading.svelte-1n46o8q h1:where(.svelte-1n46o8q){margin:6px 0 0}.secrets-page-heading.svelte-1n46o8q p:where(.svelte-1n46o8q){margin:0;font:var(--text-small)/1.5 var(--mono)}@media(max-width:700px){.secrets-page.svelte-1n46o8q{padding:24px 20px}}.secrets-page-heading.svelte-1n46o8q p:where(.svelte-1n46o8q){color:var(--muted)}.layout.svelte-1n46o8q{position:relative;display:grid;grid-template-columns:var(--sidebar-width) minmax(0,1fr);grid-template-rows:minmax(0,1fr) auto auto;height:100dvh;min-height:0;background:var(--chrome)}.app-rail.svelte-1n46o8q{position:relative;grid-row:1 / 3;min-height:0;border-right:1px solid var(--chrome-border);display:flex;flex-direction:column;color:var(--chrome-text)}.brand.svelte-1n46o8q{letter-spacing:-.03em;display:flex;align-items:center;justify-content:space-between;padding:20px 16px;font:500 var(--text-section)/1.2 var(--sans);text-transform:none}.brand-identity.svelte-1n46o8q{display:flex;align-items:center;gap:10px;min-width:0}.brand-identity.svelte-1n46o8q img:where(.svelte-1n46o8q){display:block;flex-shrink:0}.brand-name.svelte-1n46o8q{font-size:var(--text-label)}.collapsed.svelte-1n46o8q .brand-name:where(.svelte-1n46o8q){display:none}.app-rail.svelte-1n46o8q nav:where(.svelte-1n46o8q){display:grid;gap:4px;padding:0 8px}.app-rail.svelte-1n46o8q :is(button:where(.svelte-1n46o8q),a:where(.svelte-1n46o8q)){display:flex;align-items:center;gap:10px;width:100%;min-height:44px;padding:12px 16px;font:500 var(--text-body)/1.4 var(--sans);text-transform:none;color:var(--chrome-muted);background:transparent;border:0;border-left:3px solid transparent;text-align:left}.app-rail.svelte-1n46o8q :where(.svelte-1n46o8q):is(button:where(.svelte-1n46o8q),a:where(.svelte-1n46o8q)):hover{color:var(--chrome-text);background:#ffffff0c}.app-rail.svelte-1n46o8q a:where(.svelte-1n46o8q){text-decoration:none}.app-rail.svelte-1n46o8q a.active:where(.svelte-1n46o8q){color:var(--chrome-text);border-left-color:var(--orange)}.app-rail.svelte-1n46o8q :is(button:where(.svelte-1n46o8q),a:where(.svelte-1n46o8q)) svg{flex-shrink:0}main.svelte-1n46o8q{grid-column:2;grid-row:1;min-width:0;min-height:0;overflow:auto;display:flex;flex-direction:column;background:var(--bg);color:var(--text)}.logs-slot.svelte-1n46o8q{grid-column:2;grid-row:2;min-width:0}.statusbar.svelte-1n46o8q{grid-column:1 / -1;grid-row:3;min-height:40px;display:flex;align-items:center;gap:24px;border-top:1px solid var(--chrome-border);color:var(--chrome-muted);font-size:var(--text-small)}.runtime-label.svelte-1n46o8q{width:var(--sidebar-width);align-self:stretch;display:flex;align-items:center;flex-shrink:0;padding:0 20px;border-right:1px solid var(--chrome-border)}.collapsed.svelte-1n46o8q .runtime-label:where(.svelte-1n46o8q){width:64px;padding:0 8px;font-size:11px}.panel-controls.svelte-1n46o8q{display:flex;align-items:center;gap:8px;margin-left:auto;margin-right:16px}.statusbar.svelte-1n46o8q .logs-toggle:where(.svelte-1n46o8q){min-height:30px;color:var(--chrome-muted);border:0;background:transparent;text-decoration:underline;text-underline-offset:4px}.statusbar.svelte-1n46o8q .logs-toggle:where(.svelte-1n46o8q):hover,.statusbar.svelte-1n46o8q .logs-toggle[aria-expanded=true]:where(.svelte-1n46o8q){background:transparent;color:var(--chrome-text);text-decoration-thickness:2px}.connection.svelte-1n46o8q{display:flex;align-items:center;gap:14px}.connection.svelte-1n46o8q i:where(.svelte-1n46o8q){display:block;width:11px;height:11px;background:#76766e}.connection.connected.svelte-1n46o8q i:where(.svelte-1n46o8q){background:var(--orange)}.port-status.svelte-1n46o8q{padding-left:30px;border-left:1px solid var(--chrome-border)}.catalog-error.svelte-1n46o8q{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 24px;color:var(--err);background:var(--bg-2)}.all-services.svelte-1n46o8q{padding:48px 40px}.all-services.svelte-1n46o8q header:where(.svelte-1n46o8q){display:flex;flex-wrap:wrap;gap:12px;align-items:center;justify-content:space-between;padding-bottom:24px;border-bottom:1px solid var(--border)}.eyebrow.svelte-1n46o8q{color:var(--muted);font:var(--text-small)/1.4 var(--sans);text-transform:none;letter-spacing:.06em}h1.svelte-1n46o8q{margin:0 0 12px;font:600 var(--text-title)/1.2 var(--sans)}h2.svelte-1n46o8q{font:500 var(--text-section)/1.4 var(--sans)}.runtime-count.svelte-1n46o8q{color:var(--muted);font-size:var(--text-body)}.all-service-grid.svelte-1n46o8q{display:grid;margin-top:14px}.all-service-card.svelte-1n46o8q{display:grid;justify-content:stretch;min-width:0;padding:14px 0;gap:4px;text-align:left;white-space:normal;background:transparent;border:0;border-bottom:1px solid var(--border)}.service-heading.svelte-1n46o8q strong:where(.svelte-1n46o8q){font:500 var(--text-label)/1.4 var(--sans)}.service-heading.svelte-1n46o8q{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.service-status.svelte-1n46o8q{margin-left:auto;color:var(--muted);font:var(--text-small)/1.4 var(--sans);text-transform:none}.project-name.svelte-1n46o8q{color:var(--muted);font-size:var(--text-small)}.empty-state.svelte-1n46o8q,.load-state.svelte-1n46o8q{width:100%;padding:48px 32px;text-align:center;color:var(--muted)}.empty-state.svelte-1n46o8q h2:where(.svelte-1n46o8q),.load-state.svelte-1n46o8q h1:where(.svelte-1n46o8q){color:var(--text)}.global-settings.svelte-1n46o8q{padding:50px 40px;max-width:800px;font-size:var(--text-body);line-height:1.8}.global-settings.svelte-1n46o8q h3:where(.svelte-1n46o8q){margin-top:40px;font:500 var(--text-section)/1.4 var(--sans)}.global-settings.svelte-1n46o8q label:where(.svelte-1n46o8q){display:flex;gap:12px;align-items:center}.forwarder-error.svelte-1n46o8q{color:var(--err)}.collapsed.svelte-1n46o8q{grid-template-columns:64px minmax(0,1fr)}.app-rail.svelte-1n46o8q .collapse-toggle:where(.svelte-1n46o8q){width:36px;min-height:44px;flex-shrink:0;padding:4px;border:0;justify-content:center}.collapsed.svelte-1n46o8q .brand:where(.svelte-1n46o8q){flex-direction:column;gap:12px;padding:16px 4px}.collapsed.svelte-1n46o8q nav:where(.svelte-1n46o8q) a:where(.svelte-1n46o8q){justify-content:center;padding:12px 0}.collapsed.svelte-1n46o8q nav:where(.svelte-1n46o8q) a:where(.svelte-1n46o8q) span:where(.svelte-1n46o8q){display:none}.palette-trigger.svelte-1n46o8q kbd:where(.svelte-1n46o8q){margin-left:auto;font:11px var(--mono)}.collapsed.svelte-1n46o8q .palette-trigger:where(.svelte-1n46o8q){justify-content:center;padding:12px 0}.collapsed.svelte-1n46o8q .palette-trigger:where(.svelte-1n46o8q) span:where(.svelte-1n46o8q),.collapsed.svelte-1n46o8q .palette-trigger:where(.svelte-1n46o8q) kbd:where(.svelte-1n46o8q){display:none}.app-rail.svelte-1n46o8q .clean-urls-warning:where(.svelte-1n46o8q){margin-top:auto;border:0;border-top:1px solid var(--chrome-border);padding:16px 20px;color:#d1b78d;flex-shrink:0;justify-content:flex-start;white-space:normal}.app-rail.svelte-1n46o8q .clean-urls-warning:where(.svelte-1n46o8q):hover{color:#ead5ac;background:#ffffff0c;text-decoration:none}.clean-urls-warning.svelte-1n46o8q strong:where(.svelte-1n46o8q),.clean-urls-warning.svelte-1n46o8q small:where(.svelte-1n46o8q){display:block}.clean-urls-warning.svelte-1n46o8q strong:where(.svelte-1n46o8q){font-size:var(--text-small);font-weight:500}.clean-urls-warning.svelte-1n46o8q small:where(.svelte-1n46o8q){color:var(--chrome-muted);font-size:var(--text-small)}.collapsed.svelte-1n46o8q .clean-urls-warning:where(.svelte-1n46o8q){justify-content:center;padding:16px 0}.collapsed.svelte-1n46o8q .clean-urls-warning:where(.svelte-1n46o8q) span:where(.svelte-1n46o8q){display:none}.project-shortcuts.svelte-1n46o8q{overflow:auto;padding:24px 8px}.project-shortcuts.svelte-1n46o8q p:where(.svelte-1n46o8q){padding:0 12px;color:var(--chrome-muted);font:var(--text-small)/1.4 var(--sans);text-transform:none}.project-shortcuts.svelte-1n46o8q button:where(.svelte-1n46o8q){text-transform:none;overflow:hidden;text-overflow:ellipsis;display:block;min-height:36px;padding:8px 12px}.project-shortcuts.svelte-1n46o8q button.current:where(.svelte-1n46o8q){color:var(--chrome-text);background:#ffffff0c}.sidebar-resizer.svelte-1n46o8q{position:absolute;right:-3px;top:0;bottom:0;width:7px;cursor:col-resize;touch-action:none;z-index:10}.sidebar-resizer.svelte-1n46o8q:hover,.sidebar-resizer.svelte-1n46o8q:focus-visible{background:var(--orange)}.all-search.svelte-1n46o8q{display:flex;align-items:center;gap:16px;margin-top:24px;color:var(--muted)}.all-search.svelte-1n46o8q input:where(.svelte-1n46o8q){width:min(360px,100%)}@media(max-width:760px){.layout.svelte-1n46o8q,.layout.collapsed.svelte-1n46o8q{grid-template-columns:64px minmax(0,1fr)}.layout.svelte-1n46o8q:not(.collapsed) .app-rail:where(.svelte-1n46o8q){position:absolute;inset:0 auto 0 0;width:min(var(--sidebar-width),calc(100vw - 64px));z-index:20;background:var(--chrome)}.sidebar-resizer.svelte-1n46o8q{display:none}.statusbar.svelte-1n46o8q{gap:10px;font-size:11px}.runtime-label.svelte-1n46o8q{width:64px;padding:0 8px;font-size:11px}.panel-controls.svelte-1n46o8q{gap:0;margin-right:8px}.statusbar.svelte-1n46o8q .logs-toggle:where(.svelte-1n46o8q){padding:4px 8px}.port-status.svelte-1n46o8q{padding-left:10px}.connection.svelte-1n46o8q{gap:6px}.connection.svelte-1n46o8q i:where(.svelte-1n46o8q){width:6px;height:6px}.global-settings.svelte-1n46o8q,.all-services.svelte-1n46o8q{padding:24px 16px}.all-search.svelte-1n46o8q{align-items:stretch;flex-direction:column;gap:6px}}
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>LocalDeck</title>
7
7
  <link rel="icon" type="image/png" href="/localdeck-icon.png" />
8
- <script type="module" crossorigin src="/assets/index-B2HB87hg.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-Tp7Rr3xY.css">
8
+ <script type="module" crossorigin src="/assets/index-BzX_uJtU.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-DbQzubLF.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="app"></div>
@@ -3409,9 +3409,9 @@ function stopOrder(commands) {
3409
3409
  }
3410
3410
 
3411
3411
  // ../daemon/src/index.ts
3412
- import fs9 from "node:fs";
3412
+ import fs10 from "node:fs";
3413
3413
  import crypto2 from "node:crypto";
3414
- import path10 from "node:path";
3414
+ import path11 from "node:path";
3415
3415
 
3416
3416
  // ../daemon/src/api.ts
3417
3417
  import http5 from "node:http";
@@ -6986,8 +6986,8 @@ function settlesWithin2(promise, timeoutMs) {
6986
6986
 
6987
6987
  // ../daemon/src/supervisor.ts
6988
6988
  import { spawn as spawn3 } from "node:child_process";
6989
- import path9 from "node:path";
6990
- import fs8 from "node:fs";
6989
+ import path10 from "node:path";
6990
+ import fs9 from "node:fs";
6991
6991
 
6992
6992
  // ../daemon/src/startup-guidance.ts
6993
6993
  function startupGuidance(message) {
@@ -7011,6 +7011,154 @@ function startupGuidance(message) {
7011
7011
  };
7012
7012
  }
7013
7013
 
7014
+ // ../daemon/src/port-environment.ts
7015
+ import fs8 from "node:fs";
7016
+ import path9 from "node:path";
7017
+ function inferPortEnvironment(command, cwd, port) {
7018
+ const visited = new Set;
7019
+ const inspect = (input, directory) => {
7020
+ if (visited.size >= 16)
7021
+ return;
7022
+ const words = typeof input === "string" ? shellWords(input) : input;
7023
+ if (!words?.length)
7024
+ return;
7025
+ const executable = path9.basename(words[0]).replace(/\.cmd$/, "");
7026
+ if (words[0].includes("=") || ["echo", "printf"].includes(executable))
7027
+ return;
7028
+ if (["npm", "pnpm", "yarn", "bun"].includes(executable)) {
7029
+ let target = directory;
7030
+ let workspace;
7031
+ let script;
7032
+ for (let i = 1;i < words.length; i++) {
7033
+ const word = words[i];
7034
+ if (word === "--")
7035
+ break;
7036
+ if (word === "run" || word === "run-script")
7037
+ continue;
7038
+ const option = /^(--prefix|--cwd|--dir|-C|--workspace|-w)(?:=(.*))?$/.exec(word);
7039
+ if (option) {
7040
+ const value = option[2] ?? words[++i];
7041
+ if (!value || /[$`]/.test(value))
7042
+ return;
7043
+ if (option[1] === "--workspace" || option[1] === "-w") {
7044
+ if (workspace)
7045
+ return;
7046
+ workspace = value;
7047
+ } else
7048
+ target = path9.resolve(directory, value);
7049
+ } else if (word.startsWith("-") || script)
7050
+ return;
7051
+ else
7052
+ script = word;
7053
+ }
7054
+ if (!script || /[$`]/.test(script))
7055
+ return;
7056
+ if (workspace) {
7057
+ const resolved = workspaceDirectory(target, workspace);
7058
+ if (!resolved)
7059
+ return;
7060
+ target = resolved;
7061
+ }
7062
+ const key = `${target}\x00${script}`;
7063
+ if (visited.has(key))
7064
+ return;
7065
+ visited.add(key);
7066
+ const pkg = manifest(target);
7067
+ const run = pkg?.scripts?.[script];
7068
+ return typeof run === "string" ? inspect(run, target) : undefined;
7069
+ }
7070
+ const arguments_ = words.slice(1).flatMap((word, i) => word === "--port" ? [words[i + 2] ?? ""] : word.startsWith("--port=") ? [word.slice(7)] : []);
7071
+ if (arguments_.length !== 1)
7072
+ return;
7073
+ const match = /^(?:\$([A-Za-z_][A-Za-z0-9_]*)|\$\{([A-Za-z_][A-Za-z0-9_]*)(?::?-\d+)?\})$/.exec(arguments_[0]);
7074
+ const name2 = match?.[1] ?? match?.[2];
7075
+ if (name2 && name2 !== "PORT" && !name2.startsWith("LOCALDECK_"))
7076
+ return name2;
7077
+ };
7078
+ const name = inspect(command, path9.resolve(cwd));
7079
+ return name ? { [name]: String(port) } : {};
7080
+ }
7081
+ function shellWords(command) {
7082
+ const words = [];
7083
+ let word = "";
7084
+ let quote = "";
7085
+ let started = false;
7086
+ for (let i = 0;i < command.length; i++) {
7087
+ const char = command[i];
7088
+ if (char === "`" || char === "\\" || char === `
7089
+ ` || command.slice(i, i + 2) === "$(")
7090
+ return;
7091
+ if (quote) {
7092
+ if (char === quote)
7093
+ quote = "";
7094
+ else
7095
+ word += quote === "'" && char === "$" ? "\x00" : char;
7096
+ } else if (char === '"' || char === "'") {
7097
+ quote = char;
7098
+ started = true;
7099
+ } else if (/\s/.test(char)) {
7100
+ if (started)
7101
+ words.push(word);
7102
+ word = "";
7103
+ started = false;
7104
+ } else {
7105
+ if (/[;&|<>()#]/.test(char))
7106
+ return;
7107
+ word += char;
7108
+ started = true;
7109
+ }
7110
+ }
7111
+ if (quote)
7112
+ return;
7113
+ if (started)
7114
+ words.push(word);
7115
+ return words;
7116
+ }
7117
+ function manifest(directory) {
7118
+ try {
7119
+ const value = JSON.parse(fs8.readFileSync(path9.join(directory, "package.json"), "utf8"));
7120
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
7121
+ } catch {
7122
+ return;
7123
+ }
7124
+ }
7125
+ function workspaceDirectory(root, selector) {
7126
+ const workspaces = manifest(root)?.workspaces;
7127
+ const patterns = Array.isArray(workspaces) ? workspaces : workspaces?.packages;
7128
+ if (!Array.isArray(patterns))
7129
+ return;
7130
+ const directories = new Set;
7131
+ for (const pattern of patterns.slice(0, 100)) {
7132
+ if (typeof pattern !== "string" || path9.isAbsolute(pattern))
7133
+ continue;
7134
+ const parts = pattern.replace(/^\.\//, "").replace(/\/$/, "").split("/");
7135
+ if (parts.some((part) => !part || part === ".." || /[^\w@.*-]/.test(part) || part.includes("**")))
7136
+ continue;
7137
+ let candidates = [root];
7138
+ for (const part of parts) {
7139
+ const matcher = new RegExp(`^${part.replace(/\./g, "\\.").replace(/\*/g, ".*")}$`);
7140
+ const next = [];
7141
+ for (const candidate of candidates) {
7142
+ try {
7143
+ for (const entry of fs8.readdirSync(candidate, { withFileTypes: true })) {
7144
+ if (entry.isDirectory() && !["node_modules", ".git"].includes(entry.name) && matcher.test(entry.name))
7145
+ next.push(path9.join(candidate, entry.name));
7146
+ if (next.length > 100)
7147
+ return;
7148
+ }
7149
+ } catch {}
7150
+ }
7151
+ candidates = next;
7152
+ }
7153
+ for (const candidate of candidates) {
7154
+ const pkg = manifest(candidate);
7155
+ if (pkg && (candidate === path9.resolve(root, selector) || pkg.name === selector))
7156
+ directories.add(candidate);
7157
+ }
7158
+ }
7159
+ return directories.size === 1 ? [...directories][0] : undefined;
7160
+ }
7161
+
7014
7162
  // ../daemon/src/readiness.ts
7015
7163
  import http7 from "node:http";
7016
7164
  import { spawn as spawn2 } from "node:child_process";
@@ -7041,7 +7189,7 @@ async function waitForReadiness(command, getService, options = {}) {
7041
7189
  await delay2(Math.min(command.ready.intervalMs, afterProbe), command.name, options.signal);
7042
7190
  }
7043
7191
  }
7044
- function probeHttp(service, path9, expectedStatus, remainingMs, signal) {
7192
+ function probeHttp(service, path10, expectedStatus, remainingMs, signal) {
7045
7193
  return new Promise((resolve, reject) => {
7046
7194
  if (signal?.aborted)
7047
7195
  return reject(new Error(`${service.name} readiness cancelled`));
@@ -7059,7 +7207,7 @@ function probeHttp(service, path9, expectedStatus, remainingMs, signal) {
7059
7207
  const request = http7.request({
7060
7208
  host: service.upstreamHost,
7061
7209
  port: service.upstreamPort,
7062
- path: path9,
7210
+ path: path10,
7063
7211
  method: "GET",
7064
7212
  timeout: Math.max(1, Math.min(remainingMs, 2000))
7065
7213
  }, (response) => {
@@ -7334,11 +7482,11 @@ class ProcessSupervisor {
7334
7482
  return started;
7335
7483
  const hasDependents = project.commands.some((candidate) => candidate.after.includes(command.name));
7336
7484
  if (command.ready.type === "tcp" && !hasDependents) {
7337
- const cwd2 = command.cwd ? path9.resolve(project.directory, command.cwd) : project.directory;
7485
+ const cwd2 = command.cwd ? path10.resolve(project.directory, command.cwd) : project.directory;
7338
7486
  this.verifyReadiness(command, key, cwd2);
7339
7487
  return started;
7340
7488
  }
7341
- const cwd = command.cwd ? path9.resolve(project.directory, command.cwd) : project.directory;
7489
+ const cwd = command.cwd ? path10.resolve(project.directory, command.cwd) : project.directory;
7342
7490
  return this.verifyReadiness(command, key, cwd, started);
7343
7491
  })();
7344
7492
  attempts.set(command.name, attempt);
@@ -7484,9 +7632,9 @@ class ProcessSupervisor {
7484
7632
  const project = this.projects.details(projectId2);
7485
7633
  if (!project.available)
7486
7634
  throw new ProjectError("invalid", project.error);
7487
- const cwd = command.cwd ? path9.resolve(project.directory, command.cwd) : project.directory;
7635
+ const cwd = command.cwd ? path10.resolve(project.directory, command.cwd) : project.directory;
7488
7636
  try {
7489
- if (!fs8.statSync(cwd).isDirectory())
7637
+ if (!fs9.statSync(cwd).isDirectory())
7490
7638
  throw new Error("not a directory");
7491
7639
  } catch {
7492
7640
  throw new ProjectError("invalid", `configured working directory does not exist or is not a directory: ${cwd}`);
@@ -7535,6 +7683,12 @@ class ProcessSupervisor {
7535
7683
  }
7536
7684
  const argv = shellCommand(command.run.replaceAll("{port}", String(upstreamPort)));
7537
7685
  const database = service.serviceType !== undefined && service.serviceType !== "http";
7686
+ const portEnv = database ? {} : inferPortEnvironment(command.run, cwd, upstreamPort);
7687
+ commandEnv = { ...portEnv, ...commandEnv };
7688
+ for (const name2 of Object.keys(portEnv)) {
7689
+ if (commandEnv[name2] === portEnv[name2])
7690
+ this.store.log({ ts: Date.now(), service: key, stream: "system", line: `LocalDeck: supplying assigned port ${upstreamPort} through ${name2}` });
7691
+ }
7538
7692
  const env = {
7539
7693
  ...process.env,
7540
7694
  ...commandEnv,
@@ -7713,7 +7867,7 @@ class ProcessSupervisor {
7713
7867
  else {
7714
7868
  const command = this.projects.resolve(projectId2, name);
7715
7869
  const project = this.projects.details(projectId2);
7716
- const cwd = command.cwd ? path9.resolve(project.directory, command.cwd) : project.directory;
7870
+ const cwd = command.cwd ? path10.resolve(project.directory, command.cwd) : project.directory;
7717
7871
  this.verifyReadiness(command, key, cwd);
7718
7872
  }
7719
7873
  return result;
@@ -7989,7 +8143,7 @@ async function waitForProcessGroupExit(groupId, timeoutMs) {
7989
8143
  return true;
7990
8144
  }
7991
8145
  // ../daemon/package.json
7992
- var version = "1.2.0";
8146
+ var version = "1.2.1";
7993
8147
 
7994
8148
  // ../daemon/src/index.ts
7995
8149
  var VERSION = version;
@@ -8005,8 +8159,8 @@ async function startDaemon(opts = {}) {
8005
8159
  writePrivateState: writePrivateJson,
8006
8160
  ...opts.dependencies
8007
8161
  };
8008
- const stateFile = opts.homeDir ? path10.join(opts.homeDir, "daemon.json") : STATE_FILE;
8009
- const projectsFile = opts.homeDir ? path10.join(opts.homeDir, "projects.json") : PROJECTS_FILE;
8162
+ const stateFile = opts.homeDir ? path11.join(opts.homeDir, "daemon.json") : STATE_FILE;
8163
+ const projectsFile = opts.homeDir ? path11.join(opts.homeDir, "projects.json") : PROJECTS_FILE;
8010
8164
  const apiPort = opts.apiPort ?? DEFAULT_API_PORT;
8011
8165
  const store = dependencies.createStore();
8012
8166
  const registry = dependencies.createRegistry(store, apiPort);
@@ -8066,16 +8220,16 @@ async function startDaemon(opts = {}) {
8066
8220
  if (stateCleanup === "failed-write") {
8067
8221
  if (!stateWriteAttempted)
8068
8222
  return;
8069
- fs9.rmSync(`${stateFile}.${process.pid}.tmp`, { force: true });
8223
+ fs10.rmSync(`${stateFile}.${process.pid}.tmp`, { force: true });
8070
8224
  if (priorState)
8071
8225
  restorePrivateState(stateFile, priorState.contents, priorState.mode);
8072
8226
  else
8073
- fs9.rmSync(stateFile, { force: true });
8227
+ fs10.rmSync(stateFile, { force: true });
8074
8228
  return;
8075
8229
  }
8076
8230
  const state = readJson(stateFile, null);
8077
8231
  if (state?.pid === process.pid)
8078
- fs9.unlinkSync(stateFile);
8232
+ fs10.unlinkSync(stateFile);
8079
8233
  }));
8080
8234
  return errors;
8081
8235
  })();
@@ -8097,9 +8251,9 @@ async function startDaemon(opts = {}) {
8097
8251
  server.once("error", reject);
8098
8252
  server.listen(apiPort, "127.0.0.1", resolve);
8099
8253
  });
8100
- if (fs9.existsSync(stateFile)) {
8101
- const stat = fs9.statSync(stateFile);
8102
- priorState = { contents: fs9.readFileSync(stateFile), mode: stat.mode & 511 };
8254
+ if (fs10.existsSync(stateFile)) {
8255
+ const stat = fs10.statSync(stateFile);
8256
+ priorState = { contents: fs10.readFileSync(stateFile), mode: stat.mode & 511 };
8103
8257
  }
8104
8258
  stateWriteAttempted = true;
8105
8259
  dependencies.writePrivateState(stateFile, {
@@ -8120,9 +8274,9 @@ async function startDaemon(opts = {}) {
8120
8274
  }
8121
8275
  function restorePrivateState(file, contents, mode) {
8122
8276
  const temporary = `${file}.${process.pid}.restore.tmp`;
8123
- fs9.writeFileSync(temporary, contents, { mode });
8124
- fs9.chmodSync(temporary, mode);
8125
- fs9.renameSync(temporary, file);
8277
+ fs10.writeFileSync(temporary, contents, { mode });
8278
+ fs10.chmodSync(temporary, mode);
8279
+ fs10.renameSync(temporary, file);
8126
8280
  }
8127
8281
  function toError3(error) {
8128
8282
  return error instanceof Error ? error : new Error(String(error));
@@ -8157,24 +8311,24 @@ async function findDaemon() {
8157
8311
 
8158
8312
  // src/client.ts
8159
8313
  import { spawn as spawn4, spawnSync } from "node:child_process";
8160
- import fs10 from "node:fs";
8161
- import path11 from "node:path";
8314
+ import fs11 from "node:fs";
8315
+ import path12 from "node:path";
8162
8316
  import { fileURLToPath } from "node:url";
8163
8317
  function dashboardDir() {
8164
- const here = path11.dirname(fileURLToPath(import.meta.url));
8318
+ const here = path12.dirname(fileURLToPath(import.meta.url));
8165
8319
  const candidates = [
8166
- path11.resolve(here, "../dashboard"),
8167
- path11.resolve(here, "../../dashboard/dist")
8320
+ path12.resolve(here, "../dashboard"),
8321
+ path12.resolve(here, "../../dashboard/dist")
8168
8322
  ];
8169
- return candidates.find((d) => fs10.existsSync(path11.join(d, "index.html")));
8323
+ return candidates.find((d) => fs11.existsSync(path12.join(d, "index.html")));
8170
8324
  }
8171
8325
  function daemonCommand() {
8172
8326
  const entry = process.argv[1];
8173
8327
  const runningUnderBun = Boolean(process.versions.bun);
8174
8328
  if (runningUnderBun) {
8175
- const dist = path11.resolve(path11.dirname(fileURLToPath(import.meta.url)), "../dist/index.js");
8329
+ const dist = path12.resolve(path12.dirname(fileURLToPath(import.meta.url)), "../dist/index.js");
8176
8330
  const hasNode = spawnSync("node", ["--version"], { stdio: "ignore" }).status === 0;
8177
- if (fs10.existsSync(dist) && hasNode)
8331
+ if (fs11.existsSync(dist) && hasNode)
8178
8332
  return ["node", [dist, "daemon", "run"]];
8179
8333
  console.warn("LocalDeck: starting daemon under Bun — WebSocket proxying (HMR) will not work. Run `bun run build` and make sure `node` is on PATH.");
8180
8334
  }
@@ -8186,8 +8340,8 @@ async function ensureDaemon() {
8186
8340
  const running = await findDaemon();
8187
8341
  if (running)
8188
8342
  return running;
8189
- fs10.mkdirSync(path11.dirname(DAEMON_LOG), { recursive: true });
8190
- const out = fs10.openSync(DAEMON_LOG, "a");
8343
+ fs11.mkdirSync(path12.dirname(DAEMON_LOG), { recursive: true });
8344
+ const out = fs11.openSync(DAEMON_LOG, "a");
8191
8345
  const [cmd, args] = daemonCommand();
8192
8346
  const child = spawn4(cmd, args, { detached: true, stdio: ["ignore", out, out], env: process.env });
8193
8347
  child.unref();
@@ -8256,4 +8410,4 @@ class Api {
8256
8410
  shutdown = () => this.call("POST", "/api/shutdown");
8257
8411
  }
8258
8412
 
8259
- export { __toESM, __commonJS, __export, __require, wrapper_default, startForwarder, HOME_DIR, STATE_FILE, DEFAULT_API_PORT, findProjectFile, loadProject, loadProjectFile, shellCommand, isPortFree, getFreePort, serviceKey, processTree, listeningPorts, chooseUpstream, connectHost, streamLines, killProcessTree, stripAnsi, redactDiagnostic, environmentValues, listProjectSecrets, resolveProjectSecrets, startupGuidance, startupLayers, waitForReadiness, secretOutput, VERSION, startDaemon, findDaemon, dashboardDir, ensureDaemon, Api };
8413
+ export { __toESM, __commonJS, __export, __require, wrapper_default, startForwarder, HOME_DIR, STATE_FILE, DEFAULT_API_PORT, findProjectFile, loadProject, loadProjectFile, shellCommand, isPortFree, getFreePort, serviceKey, processTree, listeningPorts, chooseUpstream, connectHost, streamLines, killProcessTree, stripAnsi, redactDiagnostic, environmentValues, listProjectSecrets, resolveProjectSecrets, startupGuidance, inferPortEnvironment, startupLayers, waitForReadiness, secretOutput, VERSION, startDaemon, findDaemon, dashboardDir, ensureDaemon, Api };
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  findDaemon,
12
12
  findProjectFile,
13
13
  getFreePort,
14
+ inferPortEnvironment,
14
15
  isPortFree,
15
16
  killProcessTree,
16
17
  listeningPorts,
@@ -29,7 +30,7 @@ import {
29
30
  stripAnsi,
30
31
  waitForReadiness,
31
32
  wrapper_default
32
- } from "./index-zmpw8b4a.js";
33
+ } from "./index-19n321tr.js";
33
34
 
34
35
  // src/index.ts
35
36
  import { spawn as spawn2 } from "node:child_process";
@@ -167,6 +168,15 @@ async function startService(opts, overrides = {}) {
167
168
  });
168
169
  const argv = opts.command.map((a) => a.replaceAll("{port}", String(upstreamPort)));
169
170
  const database = service.serviceType !== undefined && service.serviceType !== "http";
171
+ const portEnv = database ? {} : inferPortEnvironment(opts.displayCommand ?? opts.command, cwd, upstreamPort);
172
+ commandEnv = { ...portEnv, ...commandEnv };
173
+ for (const name of Object.keys(portEnv)) {
174
+ if (commandEnv[name] === portEnv[name]) {
175
+ const line = `LocalDeck: supplying assigned port ${upstreamPort} through ${name}`;
176
+ console.log(`${tag}${c.dim(line)}`);
177
+ send({ type: "log", stream: "stdout", line });
178
+ }
179
+ }
170
180
  let env = {
171
181
  ...process.env,
172
182
  ...commandEnv,
@@ -897,13 +907,13 @@ async function main(argv, overrides = {}) {
897
907
  case "--update":
898
908
  if (rest.length)
899
909
  throw new Error("Usage: localdeck --update");
900
- return (await import("./update-sfxqqdjp.js")).updateLocalDeck();
910
+ return (await import("./update-nx00r38m.js")).updateLocalDeck();
901
911
  case "up":
902
912
  return cmdUp(rest, dependencies);
903
913
  case "init":
904
914
  return cmdInit(rest, dependencies);
905
915
  case "mcp":
906
- return (await import("./mcp-dwx4ja4k.js")).runMcp(rest);
916
+ return (await import("./mcp-vkez9mq7.js")).runMcp(rest);
907
917
  case "doctor":
908
918
  return cmdDoctor(rest);
909
919
  case "forward":
@@ -9,7 +9,7 @@ import {
9
9
  listProjectSecrets,
10
10
  redactDiagnostic,
11
11
  resolveProjectSecrets
12
- } from "./index-zmpw8b4a.js";
12
+ } from "./index-19n321tr.js";
13
13
 
14
14
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js
15
15
  var require_code = __commonJS((exports) => {
@@ -2,7 +2,7 @@ import {
2
2
  Api,
3
3
  STATE_FILE,
4
4
  findDaemon
5
- } from "./index-zmpw8b4a.js";
5
+ } from "./index-19n321tr.js";
6
6
 
7
7
  // src/update.ts
8
8
  import { spawn } from "node:child_process";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "localdeck",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "description": "Stable ports, shareable HTTPS links and request logs for your local dev servers",
6
6
  "bin": {