forge-cw 0.1.3 → 0.1.5
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.
|
@@ -29,4 +29,4 @@
|
|
|
29
29
|
* The original design remains. The terminal itself
|
|
30
30
|
* has been extended to include xterm CSI codes, among
|
|
31
31
|
* other features.
|
|
32
|
-
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}:root,[data-theme=dark]{--bg: #161618;--bg-2: #1f1f22;--card: #26262a;--card-2: #2e2e33;--elev: rgba(255,255,255,.04);--hair: rgba(255,255,255,.1);--hair-2: rgba(255,255,255,.16);--ink: #f5f5f7;--ink-2: #a1a1a8;--ink-3: #6e6e76;--blue: #0a84ff;--blue-2: #409cff;--green: #30d158;--orange: #ff9f0a;--red: #ff453a;--purple: #bf5af2;--teal: #40c8e0;--glass: rgba(28,28,30,.72);--shadow-s: 0 1px 2px rgba(0,0,0,.4);--shadow-m: 0 6px 20px rgba(0,0,0,.42);--shadow-l: 0 24px 60px rgba(0,0,0,.55);--term: #0e0e10;--sel: rgba(10,132,255,.18);--forge-harness-claude: #e08a68;--forge-harness-codex: #2fbf97;--forge-harness-pi: #6b9bff;--forge-harness-opencode: #e8b44a;--font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Helvetica, sans-serif;--mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;--ease: cubic-bezier(.32,.72,0,1);color-scheme:dark}[data-theme=light]{--bg: #f2f2f5;--bg-2: #f8f8fa;--card: #ffffff;--card-2: #ffffff;--elev: rgba(0,0,0,.02);--hair: rgba(0,0,0,.09);--hair-2: rgba(0,0,0,.16);--ink: #1d1d1f;--ink-2: #6e6e73;--ink-3: #8e8e93;--blue: #007aff;--blue-2: #0a6cff;--green: #28a745;--orange: #e08600;--red: #e0352b;--purple: #8944ab;--teal: #0d9bb5;--glass: rgba(248,248,250,.78);--shadow-s: 0 1px 2px rgba(0,0,0,.06);--shadow-m: 0 6px 18px rgba(0,0,0,.09);--shadow-l: 0 24px 60px rgba(0,0,0,.14);--term: #1c1c1e;--sel: rgba(0,122,255,.14);--forge-harness-claude: #c9633f;--forge-harness-codex: #0f8f6f;--forge-harness-pi: #2f6fe0;--forge-harness-opencode: #c98a12;color-scheme:light}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font);font-size:13.5px;line-height:1.45;letter-spacing:-.003em;background:var(--bg);color:var(--ink);-webkit-font-smoothing:antialiased}input,textarea,select,button{font-family:inherit;letter-spacing:inherit}input::placeholder,textarea::placeholder{color:var(--ink-3)}a{color:var(--blue);text-decoration:none}a:hover{color:var(--blue-2)}::selection{background:var(--sel)}.mono,code,pre,kbd{font-family:var(--mono);font-variant-numeric:tabular-nums}select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8e93' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:28px}:focus-visible{outline:3px solid color-mix(in srgb,var(--blue) 55%,transparent);outline-offset:2px;border-radius:8px}input:focus-visible,textarea:focus-visible,select:focus-visible{outline:none}.field{width:100%;height:38px;padding:0 12px;border-radius:11px;border:1px solid var(--hair);background-color:var(--card);color:var(--ink);font-size:13.5px;outline:none;transition:border-color .18s var(--ease),box-shadow .18s var(--ease)}textarea.field{height:auto;padding:10px 12px;resize:none;line-height:1.45}select.field{padding-right:28px}.field:focus,.field:focus-within{border-color:var(--blue)!important;box-shadow:0 0 0 4px var(--sel)!important}@keyframes riseIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}@keyframes slideIn{0%{transform:translate(24px);opacity:0}to{transform:none;opacity:1}}@keyframes popIn{0%{transform:scale(.96);opacity:0}to{transform:none;opacity:1}}@keyframes breathe{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.82)}}@keyframes sweep{0%{transform:translate(-100%)}to{transform:translate(320%)}}.sb-toggle,.sb-scrim{display:none}@media(max-width:900px){.forge-shell{grid-template-columns:56px minmax(0,1fr)!important}.forge-sidebar{padding:14px 8px 12px!important;align-items:stretch}.forge-sidebar .sb-label,.forge-sidebar .sb-section{display:none!important}.forge-sidebar nav button,.forge-sidebar>[role=button],.forge-sidebar>button{justify-content:center;padding:0!important}.forge-sidebar>button{height:32px}.task-row .harness-pill{display:none}}@media(max-width:700px){.forge-shell{grid-template-columns:minmax(0,1fr)!important}.forge-sidebar{position:fixed!important;z-index:65;left:0;width:min(272px,86vw);padding:14px 10px 12px!important;box-shadow:var(--shadow-l);transform:translate(-105%);transition:transform .3s var(--ease)}.forge-sidebar.open{transform:none}.forge-sidebar .sb-label,.forge-sidebar .sb-section{display:revert!important}.forge-sidebar .sb-section{display:flex!important}.forge-sidebar nav button,.forge-sidebar>[role=button],.forge-sidebar>button{justify-content:flex-start;padding:0 9px!important}.forge-sidebar>button{padding:6px 9px!important;height:auto}.sb-scrim.open{display:block;position:fixed;top:0;right:0;bottom:0;left:0;z-index:64;background:#00000061;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}.sb-toggle{display:grid}.task-row .task-meta,.task-row .task-chip,.task-row .task-done{display:none}.task-row{gap:10px!important}.skills-page{grid-template-columns:minmax(0,1fr)!important;grid-template-rows:auto minmax(0,1fr);height:auto!important;min-height:100vh}.skills-rail{max-height:42vh;border-right:0!important;border-bottom:1px solid var(--hair)}.task-terminal{margin:0 12px 12px!important}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.i-lucide-check{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-chevron-down{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m6 9l6 6l6-6'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-chevron-right{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18l6-6l-6-6'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-chevrons-up-down{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m7 15l5 5l5-5M7 9l5-5l5 5'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-clock{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-copy{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-external-link{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15 3h6v6m-11 5L21 3m-3 10v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-folder{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-frame{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M22 6H2m20 12H2M6 2v20M18 2v20'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-loader-2{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 12a9 9 0 1 1-6.219-8.56'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-menu{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 5h16M4 12h16M4 19h16'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-package{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73zm1 .27V12'/%3E%3Cpath d='M3.29 7L12 12l8.71-5M7.5 4.27l9 5.15'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-plus{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 12h14m-7-7v14'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-search{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='m21 21l-4.34-4.34'/%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-x{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M18 6L6 18M6 6l12 12'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.right-0{right:0}.right-4{right:1rem}.top-0{top:0}.top-full{top:100%}.z-\[55\]{z-index:55}.z-\[60\]{z-index:60}.z-\[70\]{z-index:70}.z-1{z-index:1}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.grid{display:grid}.mx-auto{margin-left:auto;margin-right:auto}.my{margin-top:1rem;margin-bottom:1rem}.me{margin-inline-end:1rem}.ml-3{margin-left:.75rem}.ms{margin-inline-start:1rem}.block{display:block}.contents{display:contents}.hidden{display:none}.h-0\.5{height:.125rem}.h-16{height:4rem}.h-full{height:100%}.max-w-full{max-width:100%}.min-h-0{min-height:0}.min-w-0{min-width:0}.w-1{width:.25rem}.w-full{width:100%}.flex{display:flex}.inline-flex{display:inline-flex}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.hover\:-translate-y-px:hover{--un-translate-y:-1px;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.transform{transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.disabled\:cursor-wait:disabled{cursor:wait}.cursor-not-allowed{cursor:not-allowed}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.cursor-col-resize{cursor:col-resize}.resize{resize:both}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-center{align-items:center}.self-start{align-self:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.space-y-1>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(.25rem * var(--un-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(.5rem * var(--un-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(1rem * var(--un-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.b,.border{border-width:1px}.hover\:border-hair2:hover{border-color:var(--hair-2)}.hover\:bg-blue:hover{background-color:var(--blue)}.hover\:bg-elev:hover{background-color:var(--elev)}.px{padding-left:1rem;padding-right:1rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-20{padding-top:5rem;padding-bottom:5rem}.pb-3{padding-bottom:.75rem}.pt-1{padding-top:.25rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.indent{text-indent:1.5rem}.text-ink2{color:var(--ink-2)}.text-ink3{color:var(--ink-3)}.hover\:text-green:hover{color:var(--green)}.hover\:text-ink:hover{color:var(--ink)}.hover\:text-red:hover{color:var(--red)}.uppercase{text-transform:uppercase}.hover\:underline:hover{text-decoration-line:underline}.tab{-moz-tab-size:4;-o-tab-size:4;tab-size:4}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.group:hover .group-hover\:opacity-100{opacity:1}.focus-visible\:opacity-100:focus-visible{opacity:1}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-60:disabled{opacity:.6}.outline{outline-style:solid}.hover\:brightness-106:hover{--un-brightness:brightness(1.06);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.filter{filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-140{transition-duration:.14s}.duration-160{transition-duration:.16s}.duration-180{transition-duration:.18s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:shadow-m:hover{box-shadow:var(--shadow-m)}.ease-spring{transition-timing-function:var(--ease)}.glass{background:var(--glass);backdrop-filter:blur(22px) saturate(180%);-webkit-backdrop-filter:blur(22px) saturate(180%)}.popover{background:var(--glass);backdrop-filter:blur(30px) saturate(180%);-webkit-backdrop-filter:blur(30px) saturate(180%);border:1px solid var(--hair-2);box-shadow:var(--shadow-l);animation:popIn .2s var(--ease) both}.breathe{animation:breathe 2.4s ease-in-out infinite}
|
|
32
|
+
*/.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm .xterm-scroll-area{visibility:hidden}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{-webkit-user-select:text;user-select:text;white-space:pre}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}:root,[data-theme=dark]{--bg: #161618;--bg-2: #1f1f22;--card: #26262a;--card-2: #2e2e33;--elev: rgba(255,255,255,.04);--hair: rgba(255,255,255,.1);--hair-2: rgba(255,255,255,.16);--ink: #f5f5f7;--ink-2: #a1a1a8;--ink-3: #6e6e76;--blue: #0a84ff;--blue-2: #409cff;--green: #30d158;--orange: #ff9f0a;--red: #ff453a;--purple: #bf5af2;--teal: #40c8e0;--glass: rgba(28,28,30,.72);--shadow-s: 0 1px 2px rgba(0,0,0,.4);--shadow-m: 0 6px 20px rgba(0,0,0,.42);--shadow-l: 0 24px 60px rgba(0,0,0,.55);--term: #0e0e10;--sel: rgba(10,132,255,.18);--forge-harness-claude: #e08a68;--forge-harness-codex: #2fbf97;--forge-harness-pi: #6b9bff;--forge-harness-opencode: #e8b44a;--font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Helvetica, sans-serif;--mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;--ease: cubic-bezier(.32,.72,0,1);color-scheme:dark}[data-theme=light]{--bg: #f2f2f5;--bg-2: #f8f8fa;--card: #ffffff;--card-2: #ffffff;--elev: rgba(0,0,0,.02);--hair: rgba(0,0,0,.09);--hair-2: rgba(0,0,0,.16);--ink: #1d1d1f;--ink-2: #6e6e73;--ink-3: #8e8e93;--blue: #007aff;--blue-2: #0a6cff;--green: #28a745;--orange: #e08600;--red: #e0352b;--purple: #8944ab;--teal: #0d9bb5;--glass: rgba(248,248,250,.78);--shadow-s: 0 1px 2px rgba(0,0,0,.06);--shadow-m: 0 6px 18px rgba(0,0,0,.09);--shadow-l: 0 24px 60px rgba(0,0,0,.14);--term: #1c1c1e;--sel: rgba(0,122,255,.14);--forge-harness-claude: #c9633f;--forge-harness-codex: #0f8f6f;--forge-harness-pi: #2f6fe0;--forge-harness-opencode: #c98a12;color-scheme:light}*{box-sizing:border-box;margin:0;padding:0}body{font-family:var(--font);font-size:13.5px;line-height:1.45;letter-spacing:-.003em;background:var(--bg);color:var(--ink);-webkit-font-smoothing:antialiased}input,textarea,select,button{font-family:inherit;letter-spacing:inherit}input::placeholder,textarea::placeholder{color:var(--ink-3)}a{color:var(--blue);text-decoration:none}a:hover{color:var(--blue-2)}::selection{background:var(--sel)}.mono,code,pre,kbd{font-family:var(--mono);font-variant-numeric:tabular-nums}select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8e93' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:28px}:focus-visible{outline:3px solid color-mix(in srgb,var(--blue) 55%,transparent);outline-offset:2px;border-radius:8px}input:focus-visible,textarea:focus-visible,select:focus-visible{outline:none}.field{width:100%;height:38px;padding:0 12px;border-radius:11px;border:1px solid var(--hair);background-color:var(--card);color:var(--ink);font-size:13.5px;outline:none;transition:border-color .18s var(--ease),box-shadow .18s var(--ease)}textarea.field{height:auto;padding:10px 12px;resize:none;line-height:1.45}select.field{padding-right:28px}.field:focus,.field:focus-within{border-color:var(--blue)!important;box-shadow:0 0 0 4px var(--sel)!important}@keyframes riseIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}@keyframes slideIn{0%{transform:translate(24px);opacity:0}to{transform:none;opacity:1}}@keyframes popIn{0%{transform:scale(.96);opacity:0}to{transform:none;opacity:1}}@keyframes breathe{0%,to{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.82)}}@keyframes sweep{0%{transform:translate(-100%)}to{transform:translate(320%)}}.sb-toggle,.sb-scrim{display:none}@media(max-width:900px){.forge-shell{grid-template-columns:56px minmax(0,1fr)!important}.forge-sidebar{padding:14px 8px 12px!important;align-items:stretch}.forge-sidebar .sb-label,.forge-sidebar .sb-section{display:none!important}.forge-sidebar nav button,.forge-sidebar>[role=button],.forge-sidebar>button{justify-content:center;padding:0!important}.forge-sidebar>button{height:32px}.task-row .harness-pill{display:none}}@media(max-width:700px){.forge-shell{grid-template-columns:minmax(0,1fr)!important}.forge-sidebar{position:fixed!important;z-index:65;left:0;width:min(272px,86vw);padding:14px 10px 12px!important;box-shadow:var(--shadow-l);transform:translate(-105%);transition:transform .3s var(--ease)}.forge-sidebar.open{transform:none}.forge-sidebar .sb-label,.forge-sidebar .sb-section{display:revert!important}.forge-sidebar .sb-section{display:flex!important}.forge-sidebar nav button,.forge-sidebar>[role=button],.forge-sidebar>button{justify-content:flex-start;padding:0 9px!important}.forge-sidebar>button{padding:6px 9px!important;height:auto}.sb-scrim.open{display:block;position:fixed;top:0;right:0;bottom:0;left:0;z-index:64;background:#00000061;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}.sb-toggle{display:grid}.task-row .task-meta,.task-row .task-chip,.task-row .task-done{display:none}.task-row{gap:10px!important}.skills-page{grid-template-columns:minmax(0,1fr)!important;grid-template-rows:auto minmax(0,1fr);height:auto!important;min-height:100vh}.skills-rail{max-height:42vh;border-right:0!important;border-bottom:1px solid var(--hair)}.task-terminal{margin:0 12px 12px!important}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.i-lucide-check{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-chevron-down{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m6 9l6 6l6-6'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-chevron-right{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18l6-6l-6-6'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-chevrons-up-down{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m7 15l5 5l5-5M7 9l5-5l5 5'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-clock{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-copy{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-external-link{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M15 3h6v6m-11 5L21 3m-3 10v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-folder{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-frame{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M22 6H2m20 12H2M6 2v20M18 2v20'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-loader-2{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M21 12a9 9 0 1 1-6.219-8.56'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-menu{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 5h16M4 12h16M4 19h16'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-package{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73zm1 .27V12'/%3E%3Cpath d='M3.29 7L12 12l8.71-5M7.5 4.27l9 5.15'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-plus{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 12h14m-7-7v14'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-search{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Cpath d='m21 21l-4.34-4.34'/%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.i-lucide-x{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M18 6L6 18M6 6l12 12'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;width:1.2em;height:1.2em}.container{width:100%}@media(min-width:640px){.container{max-width:640px}}@media(min-width:768px){.container{max-width:768px}}@media(min-width:1024px){.container{max-width:1024px}}@media(min-width:1280px){.container{max-width:1280px}}@media(min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.inset-y-0{top:0;bottom:0}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.left-0{left:0}.right-0{right:0}.right-4{right:1rem}.top-0{top:0}.top-full{top:100%}.z-\[55\]{z-index:55}.z-\[60\]{z-index:60}.z-\[70\]{z-index:70}.z-1{z-index:1}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.grid{display:grid}.mx-auto{margin-left:auto;margin-right:auto}.my{margin-top:1rem;margin-bottom:1rem}.me{margin-inline-end:1rem}.ml-3{margin-left:.75rem}.ms{margin-inline-start:1rem}.block{display:block}.contents{display:contents}.hidden{display:none}.h-0\.5{height:.125rem}.h-16{height:4rem}.h-full{height:100%}.max-w-full{max-width:100%}.min-h-0{min-height:0}.min-w-0{min-width:0}.w-1{width:.25rem}.w-full{width:100%}.flex{display:flex}.inline-flex{display:inline-flex}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.hover\:-translate-y-px:hover{--un-translate-y:-1px;transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.transform{transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.animate-spin{animation:spin 1s linear infinite}.cursor-pointer{cursor:pointer}.disabled\:cursor-wait:disabled{cursor:wait}.cursor-copy{cursor:copy}.cursor-not-allowed{cursor:not-allowed}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.cursor-col-resize{cursor:col-resize}.resize{resize:both}.place-items-center{place-items:center}.items-start{align-items:flex-start}.items-center{align-items:center}.self-start{align-self:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.space-y-1>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(.25rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(.25rem * var(--un-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(.5rem * var(--un-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--un-space-y-reverse:0;margin-top:calc(1rem * calc(1 - var(--un-space-y-reverse)));margin-bottom:calc(1rem * var(--un-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.b,.border{border-width:1px}.hover\:border-hair2:hover{border-color:var(--hair-2)}.hover\:bg-blue:hover{background-color:var(--blue)}.hover\:bg-elev:hover{background-color:var(--elev)}.px{padding-left:1rem;padding-right:1rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-20{padding-top:5rem;padding-bottom:5rem}.pb-3{padding-bottom:.75rem}.pt-1{padding-top:.25rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.indent{text-indent:1.5rem}.text-ink2{color:var(--ink-2)}.text-ink3{color:var(--ink-3)}.hover\:text-green:hover{color:var(--green)}.hover\:text-ink:hover{color:var(--ink)}.hover\:text-red:hover{color:var(--red)}.uppercase{text-transform:uppercase}.hover\:underline:hover{text-decoration-line:underline}.tab{-moz-tab-size:4;-o-tab-size:4;tab-size:4}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.group:hover .group-hover\:opacity-100{opacity:1}.focus-visible\:opacity-100:focus-visible{opacity:1}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-60:disabled{opacity:.6}.outline{outline-style:solid}.hover\:brightness-106:hover{--un-brightness:brightness(1.06);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.filter{filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia);backdrop-filter:var(--un-backdrop-blur) var(--un-backdrop-brightness) var(--un-backdrop-contrast) var(--un-backdrop-grayscale) var(--un-backdrop-hue-rotate) var(--un-backdrop-invert) var(--un-backdrop-opacity) var(--un-backdrop-saturate) var(--un-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-140{transition-duration:.14s}.duration-160{transition-duration:.16s}.duration-180{transition-duration:.18s}.duration-200{transition-duration:.2s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.hover\:shadow-m:hover{box-shadow:var(--shadow-m)}.ease-spring{transition-timing-function:var(--ease)}.glass{background:var(--glass);backdrop-filter:blur(22px) saturate(180%);-webkit-backdrop-filter:blur(22px) saturate(180%)}.popover{background:var(--glass);backdrop-filter:blur(30px) saturate(180%);-webkit-backdrop-filter:blur(30px) saturate(180%);border:1px solid var(--hair-2);box-shadow:var(--shadow-l);animation:popIn .2s var(--ease) both}.breathe{animation:breathe 2.4s ease-in-out infinite}
|
package/console/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Forge Console</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-CER8DSNM.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-D_58OQhA.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="app"></div>
|
package/dist/index.js
CHANGED
|
@@ -2441,14 +2441,17 @@ function manifestRepo(manifest) {
|
|
|
2441
2441
|
return repo["url"];
|
|
2442
2442
|
return void 0;
|
|
2443
2443
|
}
|
|
2444
|
-
function
|
|
2445
|
-
const entry = marketplaces[marketplace];
|
|
2444
|
+
function marketplaceSource(entry) {
|
|
2446
2445
|
const source = isRecord(entry) ? entry["source"] : void 0;
|
|
2447
2446
|
if (!isRecord(source))
|
|
2448
2447
|
return void 0;
|
|
2449
|
-
const value = source["repo"] ?? source["url"];
|
|
2448
|
+
const value = source["repo"] ?? source["url"] ?? source["path"];
|
|
2450
2449
|
return typeof value === "string" ? value : void 0;
|
|
2451
2450
|
}
|
|
2451
|
+
function splitPluginId(id) {
|
|
2452
|
+
const at = id.lastIndexOf("@");
|
|
2453
|
+
return { name: id.slice(0, at), marketplace: id.slice(at + 1) };
|
|
2454
|
+
}
|
|
2452
2455
|
function projectSkillNames(projectPath) {
|
|
2453
2456
|
const dir = join8(projectPath, ".claude", "skills");
|
|
2454
2457
|
if (!existsSync6(dir))
|
|
@@ -2456,17 +2459,13 @@ function projectSkillNames(projectPath) {
|
|
|
2456
2459
|
return readdirSync4(dir, { withFileTypes: true }).filter((e) => e.isDirectory() && existsSync6(join8(dir, e.name, "SKILL.md"))).map((e) => e.name).sort();
|
|
2457
2460
|
}
|
|
2458
2461
|
async function listPlugins(reader, remoteOf) {
|
|
2459
|
-
const scopes = [
|
|
2460
|
-
{ scope: "global", scopeRef: "global" },
|
|
2461
|
-
...reader.getAccounts().map((a) => ({ scope: "account", scopeRef: a }))
|
|
2462
|
-
];
|
|
2463
2462
|
const found = /* @__PURE__ */ new Map();
|
|
2464
|
-
for (const { scope, scopeRef } of
|
|
2463
|
+
for (const { scope, scopeRef } of pluginScopes(reader)) {
|
|
2465
2464
|
const configDir = reader.getSkillConfigDir(scope, scopeRef);
|
|
2466
2465
|
const installed = readJson(join8(configDir, "plugins", "installed_plugins.json"))["plugins"];
|
|
2467
2466
|
if (!isRecord(installed))
|
|
2468
2467
|
continue;
|
|
2469
|
-
const marketplaces =
|
|
2468
|
+
const marketplaces = knownMarketplaces(configDir);
|
|
2470
2469
|
const enabledPlugins = readJson(join8(configDir, "settings.json"))["enabledPlugins"];
|
|
2471
2470
|
for (const [id, entries] of Object.entries(installed)) {
|
|
2472
2471
|
if (!Array.isArray(entries))
|
|
@@ -2474,7 +2473,6 @@ async function listPlugins(reader, remoteOf) {
|
|
|
2474
2473
|
const user = entries.find((e) => isRecord(e) && e["scope"] === "user" && typeof e["installPath"] === "string");
|
|
2475
2474
|
if (!user)
|
|
2476
2475
|
continue;
|
|
2477
|
-
const marketplace = id.slice(id.lastIndexOf("@") + 1);
|
|
2478
2476
|
const install = {
|
|
2479
2477
|
scope,
|
|
2480
2478
|
scopeRef,
|
|
@@ -2484,7 +2482,7 @@ async function listPlugins(reader, remoteOf) {
|
|
|
2484
2482
|
lastUpdated: typeof user["lastUpdated"] === "string" ? user["lastUpdated"] : void 0
|
|
2485
2483
|
};
|
|
2486
2484
|
const list = found.get(id) ?? [];
|
|
2487
|
-
list.push({ install, repo:
|
|
2485
|
+
list.push({ install, repo: marketplaceSource(marketplaces[splitPluginId(id).marketplace]) });
|
|
2488
2486
|
found.set(id, list);
|
|
2489
2487
|
}
|
|
2490
2488
|
}
|
|
@@ -2498,8 +2496,7 @@ async function listPlugins(reader, remoteOf) {
|
|
|
2498
2496
|
const match = repo ? remotes.find((r) => r.repo === repo) : void 0;
|
|
2499
2497
|
plugins.push({
|
|
2500
2498
|
id,
|
|
2501
|
-
|
|
2502
|
-
marketplace: id.slice(id.lastIndexOf("@") + 1),
|
|
2499
|
+
...splitPluginId(id),
|
|
2503
2500
|
description: String(manifest["description"] ?? ""),
|
|
2504
2501
|
repo,
|
|
2505
2502
|
installs: list.map((f) => f.install),
|
|
@@ -2521,7 +2518,41 @@ function readPluginSkill(plugin, name) {
|
|
|
2521
2518
|
return null;
|
|
2522
2519
|
}
|
|
2523
2520
|
}
|
|
2524
|
-
|
|
2521
|
+
function readCatalog(location, marketplace) {
|
|
2522
|
+
const listed = readJson(join8(location, ".claude-plugin", "marketplace.json"))["plugins"];
|
|
2523
|
+
return (Array.isArray(listed) ? listed : []).filter((p) => isRecord(p) && typeof p["name"] === "string").map((p) => ({
|
|
2524
|
+
id: `${String(p["name"])}@${marketplace}`,
|
|
2525
|
+
name: String(p["name"]),
|
|
2526
|
+
description: String(p["description"] ?? ""),
|
|
2527
|
+
category: typeof p["category"] === "string" ? p["category"] : void 0
|
|
2528
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
2529
|
+
}
|
|
2530
|
+
function listMarketplaces(reader) {
|
|
2531
|
+
const byName = /* @__PURE__ */ new Map();
|
|
2532
|
+
for (const target of pluginScopes(reader)) {
|
|
2533
|
+
for (const [name, entry] of Object.entries(knownMarketplaces(reader.getSkillConfigDir(target.scope, target.scopeRef)))) {
|
|
2534
|
+
const source = marketplaceSource(entry);
|
|
2535
|
+
if (!source)
|
|
2536
|
+
continue;
|
|
2537
|
+
const known = byName.get(name) ?? { name, source, scopes: [], plugins: [] };
|
|
2538
|
+
known.scopes.push(target);
|
|
2539
|
+
const location = isRecord(entry) ? entry["installLocation"] : void 0;
|
|
2540
|
+
if (known.plugins.length === 0 && typeof location === "string")
|
|
2541
|
+
known.plugins = readCatalog(location, name);
|
|
2542
|
+
byName.set(name, known);
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2545
|
+
return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
2546
|
+
}
|
|
2547
|
+
function marketplaceSourceOf(reader, marketplace) {
|
|
2548
|
+
for (const { scope, scopeRef } of pluginScopes(reader)) {
|
|
2549
|
+
const source = marketplaceSource(knownMarketplaces(reader.getSkillConfigDir(scope, scopeRef))[marketplace]);
|
|
2550
|
+
if (source)
|
|
2551
|
+
return source;
|
|
2552
|
+
}
|
|
2553
|
+
return void 0;
|
|
2554
|
+
}
|
|
2555
|
+
var isRecord, inside, pluginScopes, knownMarketplaces, knowsMarketplace;
|
|
2525
2556
|
var init_plugins = __esm({
|
|
2526
2557
|
"../core/dist/plugins.js"() {
|
|
2527
2558
|
"use strict";
|
|
@@ -2531,6 +2562,12 @@ var init_plugins = __esm({
|
|
|
2531
2562
|
const p = resolve2(path);
|
|
2532
2563
|
return p === r || p.startsWith(r + sep);
|
|
2533
2564
|
};
|
|
2565
|
+
pluginScopes = (reader) => [
|
|
2566
|
+
{ scope: "global", scopeRef: "global" },
|
|
2567
|
+
...reader.getAccounts().map((a) => ({ scope: "account", scopeRef: a }))
|
|
2568
|
+
];
|
|
2569
|
+
knownMarketplaces = (configDir) => readJson(join8(configDir, "plugins", "known_marketplaces.json"));
|
|
2570
|
+
knowsMarketplace = (configDir, marketplace) => isRecord(knownMarketplaces(configDir)[marketplace]);
|
|
2534
2571
|
}
|
|
2535
2572
|
});
|
|
2536
2573
|
|
|
@@ -2559,7 +2596,26 @@ function skillRoutes(reader, options = {}) {
|
|
|
2559
2596
|
const runnerFor = options.runnerFor ?? ((env) => createRunner(env, INSTALL_TIMEOUT_MS));
|
|
2560
2597
|
const remoteOf = options.remoteOf ?? createRemoteLookup(runCommand);
|
|
2561
2598
|
const app = new Hono2();
|
|
2562
|
-
const
|
|
2599
|
+
const busy = /* @__PURE__ */ new Set();
|
|
2600
|
+
const runClaude = async (scope, ref, commands, failure) => {
|
|
2601
|
+
const configDir = reader.getSkillConfigDir(scope, ref);
|
|
2602
|
+
if (busy.has(configDir))
|
|
2603
|
+
return { error: `A plugin command is already running for ${ref}`, status: 409 };
|
|
2604
|
+
busy.add(configDir);
|
|
2605
|
+
try {
|
|
2606
|
+
const { CLAUDE_CONFIG_DIR: _ignored, ...base } = envWithoutHarness();
|
|
2607
|
+
const run = runnerFor(scope === "global" ? base : { ...base, CLAUDE_CONFIG_DIR: configDir });
|
|
2608
|
+
for (const args of commands) {
|
|
2609
|
+
const result2 = await run("claude", args, configDir);
|
|
2610
|
+
if (result2.code !== 0)
|
|
2611
|
+
return { error: `${failure}: ${commandFailure(result2)}`, status: 500 };
|
|
2612
|
+
}
|
|
2613
|
+
return null;
|
|
2614
|
+
} finally {
|
|
2615
|
+
busy.delete(configDir);
|
|
2616
|
+
}
|
|
2617
|
+
};
|
|
2618
|
+
const knownAccount = (account) => account && reader.getAccounts().includes(account) ? account : null;
|
|
2563
2619
|
const refOf = (scope, scopeRef) => scope === "global" ? "global" : scopeRef ?? "";
|
|
2564
2620
|
const knownScope = (scope, ref) => scope === "global" || (scope === "account" ? reader.getAccounts().includes(ref) : scope === "project" && ref in reader.getProjects());
|
|
2565
2621
|
app.get("/", (c) => c.json(reader.getSkills()));
|
|
@@ -2763,27 +2819,50 @@ function skillRoutes(reader, options = {}) {
|
|
|
2763
2819
|
const install = plugin?.installs.find((i) => i.scope === scope && i.scopeRef === ref);
|
|
2764
2820
|
if (!plugin || !install)
|
|
2765
2821
|
return c.json({ error: `${id} is not installed in ${ref || "that scope"}` }, 404);
|
|
2766
|
-
const
|
|
2767
|
-
if (
|
|
2768
|
-
return c.json({ error:
|
|
2769
|
-
updating.add(configDir);
|
|
2770
|
-
try {
|
|
2771
|
-
const { CLAUDE_CONFIG_DIR: _ignored, ...base } = envWithoutHarness();
|
|
2772
|
-
const run = runnerFor(install.scope === "global" ? base : { ...base, CLAUDE_CONFIG_DIR: configDir });
|
|
2773
|
-
for (const args of [["plugin", "marketplace", "update", plugin.marketplace], ["plugin", "update", plugin.id]]) {
|
|
2774
|
-
const result2 = await run("claude", args, configDir);
|
|
2775
|
-
if (result2.code !== 0)
|
|
2776
|
-
return c.json({ error: `Failed to update ${plugin.name}: ${commandFailure(result2)}` }, 500);
|
|
2777
|
-
}
|
|
2778
|
-
} finally {
|
|
2779
|
-
updating.delete(configDir);
|
|
2780
|
-
}
|
|
2822
|
+
const failed = await runClaude(install.scope, ref, [["plugin", "marketplace", "update", plugin.marketplace], ["plugin", "update", plugin.id]], `Failed to update ${plugin.name}`);
|
|
2823
|
+
if (failed)
|
|
2824
|
+
return c.json({ error: failed.error }, failed.status);
|
|
2781
2825
|
const version = (await find())?.installs.find((i) => i.scope === install.scope && i.scopeRef === ref)?.version ?? install.version;
|
|
2782
2826
|
return c.json({ ok: true, version });
|
|
2783
2827
|
});
|
|
2828
|
+
app.get("/marketplaces", (c) => c.json(listMarketplaces(reader)));
|
|
2829
|
+
app.post("/marketplaces", async (c) => {
|
|
2830
|
+
const body = await c.req.json().catch(() => ({}));
|
|
2831
|
+
const source = body.source?.trim() ?? "";
|
|
2832
|
+
if (!source || source.startsWith("-"))
|
|
2833
|
+
return c.json({ error: "A GitHub repo, URL or path is required" }, 400);
|
|
2834
|
+
const account = knownAccount(body.account);
|
|
2835
|
+
if (!account)
|
|
2836
|
+
return c.json({ error: "Unknown account" }, 404);
|
|
2837
|
+
const failed = await runClaude("account", account, [["plugin", "marketplace", "add", source]], `Failed to add ${source}`);
|
|
2838
|
+
if (failed)
|
|
2839
|
+
return c.json({ error: failed.error }, failed.status);
|
|
2840
|
+
return c.json({ ok: true });
|
|
2841
|
+
});
|
|
2842
|
+
app.post("/plugins/install", async (c) => {
|
|
2843
|
+
const body = await c.req.json().catch(() => ({}));
|
|
2844
|
+
const id = body.id ?? "";
|
|
2845
|
+
if (!PLUGIN_ID_RE.test(id))
|
|
2846
|
+
return c.json({ error: "Invalid plugin id" }, 400);
|
|
2847
|
+
const account = knownAccount(body.account);
|
|
2848
|
+
if (!account)
|
|
2849
|
+
return c.json({ error: "Unknown account" }, 404);
|
|
2850
|
+
const { name, marketplace } = splitPluginId(id);
|
|
2851
|
+
const commands = [["plugin", "install", id]];
|
|
2852
|
+
if (!knowsMarketplace(reader.getSkillConfigDir("account", account), marketplace)) {
|
|
2853
|
+
const source = marketplaceSourceOf(reader, marketplace);
|
|
2854
|
+
if (!source)
|
|
2855
|
+
return c.json({ error: `Unknown marketplace ${marketplace}` }, 404);
|
|
2856
|
+
commands.unshift(["plugin", "marketplace", "add", source]);
|
|
2857
|
+
}
|
|
2858
|
+
const failed = await runClaude("account", account, commands, `Failed to install ${name}`);
|
|
2859
|
+
if (failed)
|
|
2860
|
+
return c.json({ error: failed.error }, failed.status);
|
|
2861
|
+
return c.json({ ok: true });
|
|
2862
|
+
});
|
|
2784
2863
|
return app;
|
|
2785
2864
|
}
|
|
2786
|
-
var INSTALL_TIMEOUT_MS, SKILL_NAME_RE;
|
|
2865
|
+
var INSTALL_TIMEOUT_MS, SKILL_NAME_RE, PLUGIN_ID_RE;
|
|
2787
2866
|
var init_skill_routes = __esm({
|
|
2788
2867
|
"../core/dist/skill-routes.js"() {
|
|
2789
2868
|
"use strict";
|
|
@@ -2792,6 +2871,7 @@ var init_skill_routes = __esm({
|
|
|
2792
2871
|
init_plugins();
|
|
2793
2872
|
INSTALL_TIMEOUT_MS = 12e4;
|
|
2794
2873
|
SKILL_NAME_RE = /^\w[\w.-]*$/;
|
|
2874
|
+
PLUGIN_ID_RE = /^\w[\w.-]*@\w[\w.-]*$/;
|
|
2795
2875
|
}
|
|
2796
2876
|
});
|
|
2797
2877
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forge-cw",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "A visual dashboard for your coding agents on Claude Code, Codex, Pi or OpenCode. Installs CW for you.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"@types/node": "^22.0.0",
|
|
40
40
|
"esbuild": "^0.25.0",
|
|
41
41
|
"typescript": "^5.8.0",
|
|
42
|
-
"@forge-dev/
|
|
43
|
-
"@forge-dev/
|
|
42
|
+
"@forge-dev/console": "0.1.0",
|
|
43
|
+
"@forge-dev/core": "0.1.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsc",
|