@openspecui/web 2.0.1 → 2.1.0

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.
Files changed (60) hide show
  1. package/dist/assets/{BufferResource-Cipj3hQ5.js → BufferResource-WPSrP4iZ.js} +1 -1
  2. package/dist/assets/{CanvasRenderer-C151fKcy.js → CanvasRenderer-yL0hHLLA.js} +1 -1
  3. package/dist/assets/{Filter-BpxymkGv.js → Filter-MPAI5-Oj.js} +1 -1
  4. package/dist/assets/{RenderTargetSystem-C0zk81Mh.js → RenderTargetSystem-D4qtRaUW.js} +1 -1
  5. package/dist/assets/{WebGLRenderer-De3GrxdN.js → WebGLRenderer-BHfrXEBc.js} +1 -1
  6. package/dist/assets/{WebGPURenderer-BkpejvST.js → WebGPURenderer-DE5Q1Ilu.js} +1 -1
  7. package/dist/assets/{browserAll-B8KqF-Xa.js → browserAll-qg0ACMg1.js} +1 -1
  8. package/dist/assets/{ghostty-web-BO5ww0eG.js → ghostty-web-D1cPLYOq.js} +1 -1
  9. package/dist/assets/{index-Nl7iD8Yi.js → index-B2AIdjev.js} +1 -1
  10. package/dist/assets/{index-CDX9fioY.js → index-BEpMDdcu.js} +1 -1
  11. package/dist/assets/{index-B-vvVL83.js → index-BLmH2_gh.js} +197 -193
  12. package/dist/assets/{index-Bp2dpDFJ.js → index-BM_5Tg9c.js} +1 -1
  13. package/dist/assets/{index-Cj_nv8ue.js → index-BQWvXpvf.js} +1 -1
  14. package/dist/assets/{index-a8osabOh.js → index-BTEmB46j.js} +1 -1
  15. package/dist/assets/{index-CxDip8xJ.js → index-C8igR5_C.js} +1 -1
  16. package/dist/assets/{index-DL08rl2O.js → index-CQRaC2Gn.js} +1 -1
  17. package/dist/assets/{index-2DXouwnE.js → index-CSledjj-.js} +1 -1
  18. package/dist/assets/index-D1IhiEyy.css +1 -0
  19. package/dist/assets/{index-CwA_uPvf.js → index-D7oe-Hg-.js} +1 -1
  20. package/dist/assets/{index-Cv-LON1K.js → index-DBI0U-_m.js} +1 -1
  21. package/dist/assets/{index-CFAzjIVm.js → index-DMpt0Kcu.js} +1 -1
  22. package/dist/assets/{index-iROJdLzk.js → index-DYz8XhtF.js} +1 -1
  23. package/dist/assets/{index-DtTSWBHJ.js → index-DfNI0fNY.js} +1 -1
  24. package/dist/assets/{index-Bxm-n0do.js → index-DlK0frtF.js} +1 -1
  25. package/dist/assets/{index-DzK6gT7C.js → index-Gknjn7E7.js} +1 -1
  26. package/dist/assets/{webworkerAll-DPcI1cDK.js → webworkerAll-iHUuedbL.js} +1 -1
  27. package/dist/index.html +2 -2
  28. package/dist-ssg/client/.vite/ssr-manifest.json +228 -225
  29. package/dist-ssg/client/assets/{BufferResource-Djy-vqXo.js → BufferResource-D81lYMLT.js} +1 -1
  30. package/dist-ssg/client/assets/{CanvasRenderer-KFsP4iAw.js → CanvasRenderer-BYIOuB-u.js} +1 -1
  31. package/dist-ssg/client/assets/{Filter-3xK-3KVh.js → Filter-CeoA-Hyu.js} +1 -1
  32. package/dist-ssg/client/assets/{RenderTargetSystem-BAJ5M6Aj.js → RenderTargetSystem-DXG3rON5.js} +1 -1
  33. package/dist-ssg/client/assets/{WebGLRenderer-DezzkAy6.js → WebGLRenderer-C8QtcPPE.js} +1 -1
  34. package/dist-ssg/client/assets/{WebGPURenderer-ZzdUU8jb.js → WebGPURenderer-TSulBBlS.js} +1 -1
  35. package/dist-ssg/client/assets/{browserAll-CbpHY1zT.js → browserAll-wG5chgko.js} +1 -1
  36. package/dist-ssg/client/assets/{index-DY7da1s-.js → index-BGCX0p5r.js} +1 -1
  37. package/dist-ssg/client/assets/{index-BwBOsQe8.js → index-BPcWtlCR.js} +1 -1
  38. package/dist-ssg/client/assets/{index-Csq0Slx9.js → index-BRKO5Axs.js} +1 -1
  39. package/dist-ssg/client/assets/{index-CckipaE4.js → index-BW2CaBe9.js} +1 -1
  40. package/dist-ssg/client/assets/{index-yIXrbgDj.js → index-C8IGL6vM.js} +1 -1
  41. package/dist-ssg/client/assets/{index-C23IRugh.js → index-Cj5wOcC4.js} +1 -1
  42. package/dist-ssg/client/assets/index-CjyblKoL.css +1 -0
  43. package/dist-ssg/client/assets/{index-B5xZnlc2.js → index-CtoDt3iY.js} +1 -1
  44. package/dist-ssg/client/assets/{index-D5ENxVE5.js → index-D4YbeFcQ.js} +1 -1
  45. package/dist-ssg/client/assets/{index-DHzU_xY8.js → index-DK_U1_Lh.js} +1 -1
  46. package/dist-ssg/client/assets/{index-Cmce45ci.js → index-DMCE4Kkm.js} +1 -1
  47. package/dist-ssg/client/assets/{index-DaL9PO7O.js → index-DRGqIcc0.js} +1 -1
  48. package/dist-ssg/client/assets/{index-YHr5vAyz.js → index-DqMkjeUD.js} +1 -1
  49. package/dist-ssg/client/assets/{index-Z0tLCpB3.js → index-DuZ0AKLC.js} +1 -1
  50. package/dist-ssg/client/assets/{index-DEEhv4xj.js → index-bGllGkV0.js} +1 -1
  51. package/dist-ssg/client/assets/{index-ChvVJs5U.js → index-rbH3brrb.js} +1 -1
  52. package/dist-ssg/client/assets/{index.ssg-CYPPqc3Y.js → index.ssg-BCAZPCWG.js} +172 -168
  53. package/dist-ssg/client/assets/{webworkerAll-Ds7nVNhd.js → webworkerAll-DisB_v8s.js} +1 -1
  54. package/dist-ssg/client/index.ssg.html +2 -2
  55. package/dist-ssg/server/entry-server.js +173 -45
  56. package/dist-ssg/ssg-cli.mjs +0 -0
  57. package/package.json +25 -20
  58. package/LICENSE +0 -21
  59. package/dist/assets/index-aWxXp1oO.css +0 -1
  60. package/dist-ssg/client/assets/index-CR6zSaLm.css +0 -1
@@ -1,4 +1,4 @@
1
- import{G as R,u as S,T as b,R as P,af as I,ab as B,aq as T,V as _,aJ as O,a1 as A,y as C,ap as E,a2 as k}from"./index.ssg-CYPPqc3Y.js";import{F as z}from"./Filter-3xK-3KVh.js";var U=`in vec2 aPosition;
1
+ import{G as R,u as S,T as b,R as P,af as I,ab as B,aq as T,V as _,aJ as O,a1 as A,y as C,ap as E,a2 as k}from"./index.ssg-BCAZPCWG.js";import{F as z}from"./Filter-CeoA-Hyu.js";var U=`in vec2 aPosition;
2
2
  out vec2 vTextureCoord;
3
3
 
4
4
  uniform vec4 uInputSize;
@@ -35,8 +35,8 @@
35
35
  document.head.append(preconnectApi, preconnectStatic, stylesheet)
36
36
  })()
37
37
  </script>
38
- <script type="module" crossorigin src="/assets/index.ssg-CYPPqc3Y.js"></script>
39
- <link rel="stylesheet" crossorigin href="/assets/index-CR6zSaLm.css">
38
+ <script type="module" crossorigin src="/assets/index.ssg-BCAZPCWG.js"></script>
39
+ <link rel="stylesheet" crossorigin href="/assets/index-CjyblKoL.css">
40
40
  </head>
41
41
  <body>
42
42
  <div id="root"><!--app-html--></div>
@@ -36081,6 +36081,43 @@ function requireServer_node() {
36081
36081
  return server_node;
36082
36082
  }
36083
36083
  var server_nodeExports = requireServer_node();
36084
+ const HOSTED_VERSION_PATH_RE = /^\/versions\/[^/]+(?:\/|$)/;
36085
+ function normalizeApiBaseUrl(input) {
36086
+ const trimmed = input.trim();
36087
+ if (!trimmed) return null;
36088
+ let url;
36089
+ try {
36090
+ url = new URL(trimmed);
36091
+ } catch {
36092
+ return null;
36093
+ }
36094
+ url.hash = "";
36095
+ url.search = "";
36096
+ const pathname = url.pathname.replace(/\/+$/, "");
36097
+ url.pathname = pathname.length > 0 ? pathname : "/";
36098
+ return url.toString().replace(/\/$/, url.pathname === "/" ? "" : "");
36099
+ }
36100
+ function getSearchParam(search2, key2) {
36101
+ const value = new URLSearchParams(search2).get(key2)?.trim();
36102
+ return value ? value : null;
36103
+ }
36104
+ function isHostedVersionEntryPath(pathname) {
36105
+ return HOSTED_VERSION_PATH_RE.test(pathname);
36106
+ }
36107
+ function getHostedApiBootstrapState(locationLike) {
36108
+ const hosted = isHostedVersionEntryPath(locationLike.pathname);
36109
+ const apiBaseUrl = normalizeApiBaseUrl(getSearchParam(locationLike.search, "api") ?? "");
36110
+ const sessionId = hosted ? getSearchParam(locationLike.search, "session") : null;
36111
+ return {
36112
+ hosted,
36113
+ apiBaseUrl,
36114
+ sessionId
36115
+ };
36116
+ }
36117
+ function getHostedScopedStorageKey(baseKey, locationLike) {
36118
+ const state = getHostedApiBootstrapState(locationLike);
36119
+ return state.hosted && state.sessionId ? `hosted-session:${state.sessionId}:${baseKey}` : baseKey;
36120
+ }
36084
36121
  let staticModeDetected = null;
36085
36122
  if (typeof window !== "undefined" && window.__OPENSPEC_STATIC_MODE__ === true && true) {
36086
36123
  staticModeDetected = true;
@@ -36136,8 +36173,12 @@ const POP_ROUTES = [
36136
36173
  "/opsx-verify",
36137
36174
  "/opsx-compose"
36138
36175
  ];
36139
- const KV_KEY = "nav-layout";
36140
- const LS_KEY = "nav-layout";
36176
+ function getRemoteStorageKey() {
36177
+ return getHostedScopedStorageKey("nav-layout", window.location);
36178
+ }
36179
+ function getLocalStorageKey() {
36180
+ return getHostedScopedStorageKey("nav-layout", window.location);
36181
+ }
36141
36182
  const PERSIST_DEBOUNCE = 300;
36142
36183
  function isTabId(value) {
36143
36184
  return ALL_TABS.includes(value);
@@ -36183,6 +36224,41 @@ function parseHref(href, state) {
36183
36224
  state: toParsedHistoryState(state, key2)
36184
36225
  };
36185
36226
  }
36227
+ function normalizeBasePath(basePath) {
36228
+ const trimmed = basePath.trim();
36229
+ if (!trimmed || trimmed === "./" || trimmed === ".") return "/";
36230
+ const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
36231
+ const normalized = withLeadingSlash.endsWith("/") ? withLeadingSlash : `${withLeadingSlash}/`;
36232
+ return normalized.replace(/\/+/g, "/");
36233
+ }
36234
+ function stripBasePath(pathname, basePath) {
36235
+ if (basePath === "/") return pathname || "/";
36236
+ if (pathname === basePath.slice(0, -1)) return "/";
36237
+ if (!pathname.startsWith(basePath)) return pathname || "/";
36238
+ const stripped = pathname.slice(basePath.length - 1);
36239
+ return stripped || "/";
36240
+ }
36241
+ function applyBasePath(pathname, basePath) {
36242
+ if (basePath === "/") return pathname || "/";
36243
+ const normalizedPath = pathname.startsWith("/") ? pathname : `/${pathname}`;
36244
+ if (normalizedPath === "/") return basePath.slice(0, -1) || "/";
36245
+ return `${basePath.slice(0, -1)}${normalizedPath}`;
36246
+ }
36247
+ function normalizeNavigationHref(href) {
36248
+ if (typeof window === "undefined") return href;
36249
+ const url = new URL(href, window.location.origin);
36250
+ const basePath = normalizeBasePath(getBasePath());
36251
+ url.pathname = stripBasePath(url.pathname, basePath);
36252
+ return `${url.pathname}${url.search}${url.hash}`;
36253
+ }
36254
+ function preserveHostedSearchParams(target, source) {
36255
+ for (const key2 of ["api", "session"]) {
36256
+ const value = source.searchParams.get(key2);
36257
+ if (value && !target.searchParams.has(key2)) {
36258
+ target.searchParams.set(key2, value);
36259
+ }
36260
+ }
36261
+ }
36186
36262
  function pathToTabId(path2) {
36187
36263
  for (const tab2 of ALL_TABS) {
36188
36264
  if (path2 === tab2 || path2.startsWith(tab2 + "/")) {
@@ -36270,6 +36346,8 @@ function normalizeState(state) {
36270
36346
  }
36271
36347
  function parseBrowserLocation(loc, layout) {
36272
36348
  const url = new URL(loc.href);
36349
+ const basePath = normalizeBasePath(getBasePath());
36350
+ url.pathname = stripBasePath(url.pathname, basePath);
36273
36351
  const rawBottomHref = url.searchParams.get("_b");
36274
36352
  const rawPopHref = url.searchParams.get("_p");
36275
36353
  url.searchParams.delete("_b");
@@ -36285,7 +36363,11 @@ function parseBrowserLocation(loc, layout) {
36285
36363
  };
36286
36364
  }
36287
36365
  function buildCanonicalUrl(state) {
36366
+ const currentUrl = new URL(window.location.href);
36288
36367
  const url = new URL(state.mainLocation.href, window.location.origin);
36368
+ const basePath = normalizeBasePath(getBasePath());
36369
+ url.pathname = applyBasePath(url.pathname, basePath);
36370
+ preserveHostedSearchParams(url, currentUrl);
36289
36371
  url.searchParams.delete("_b");
36290
36372
  url.searchParams.delete("_p");
36291
36373
  if (state.bottomTabs.length > 0) {
@@ -36312,7 +36394,7 @@ function createInitialState() {
36312
36394
  }
36313
36395
  function readLocalStorage() {
36314
36396
  try {
36315
- const raw2 = localStorage.getItem(LS_KEY);
36397
+ const raw2 = localStorage.getItem(getLocalStorageKey());
36316
36398
  if (!raw2) return null;
36317
36399
  return parsePersistedLayout(JSON.parse(raw2));
36318
36400
  } catch {
@@ -36321,7 +36403,7 @@ function readLocalStorage() {
36321
36403
  }
36322
36404
  function writeLocalStorage(layout) {
36323
36405
  try {
36324
- localStorage.setItem(LS_KEY, JSON.stringify(layout));
36406
+ localStorage.setItem(getLocalStorageKey(), JSON.stringify(layout));
36325
36407
  } catch {
36326
36408
  }
36327
36409
  }
@@ -36615,7 +36697,7 @@ class NavController {
36615
36697
  type: "NAVIGATE",
36616
36698
  sourceArea: area2,
36617
36699
  action: "PUSH",
36618
- location: parseHref(path2, state)
36700
+ location: parseHref(normalizeNavigationHref(path2), state)
36619
36701
  });
36620
36702
  }
36621
36703
  replace(area2, path2, state) {
@@ -36623,8 +36705,18 @@ class NavController {
36623
36705
  type: "NAVIGATE",
36624
36706
  sourceArea: area2,
36625
36707
  action: "REPLACE",
36626
- location: parseHref(path2, state)
36708
+ location: parseHref(normalizeNavigationHref(path2), state)
36709
+ });
36710
+ }
36711
+ createHref(area2, path2, state) {
36712
+ if (typeof window === "undefined") return path2;
36713
+ const { nextState } = this.computeTransition({
36714
+ type: "NAVIGATE",
36715
+ sourceArea: area2,
36716
+ action: "PUSH",
36717
+ location: parseHref(normalizeNavigationHref(path2), state)
36627
36718
  });
36719
+ return buildCanonicalUrl(nextState);
36628
36720
  }
36629
36721
  get mainTabs() {
36630
36722
  return this.state.mainTabs;
@@ -36681,13 +36773,15 @@ class NavController {
36681
36773
  this.initialized = true;
36682
36774
  try {
36683
36775
  const { trpcClient: trpcClient2 } = await Promise.resolve().then(() => trpc$1);
36684
- const remote = parsePersistedLayout(await trpcClient2.kv.get.query({ key: KV_KEY }));
36776
+ const remote = parsePersistedLayout(
36777
+ await trpcClient2.kv.get.query({ key: getRemoteStorageKey() })
36778
+ );
36685
36779
  if (remote) {
36686
36780
  if (remote.updatedAt > this.state.updatedAt) {
36687
36781
  this.dispatch({ type: "APPLY_LAYOUT", layout: remote });
36688
36782
  } else if (this.state.updatedAt > remote.updatedAt) {
36689
36783
  trpcClient2.kv.set.mutate({
36690
- key: KV_KEY,
36784
+ key: getRemoteStorageKey(),
36691
36785
  value: {
36692
36786
  mainTabs: this.state.mainTabs,
36693
36787
  bottomTabs: this.state.bottomTabs,
@@ -36698,7 +36792,7 @@ class NavController {
36698
36792
  }
36699
36793
  } else if (this.state.updatedAt > 0) {
36700
36794
  trpcClient2.kv.set.mutate({
36701
- key: KV_KEY,
36795
+ key: getRemoteStorageKey(),
36702
36796
  value: {
36703
36797
  mainTabs: this.state.mainTabs,
36704
36798
  bottomTabs: this.state.bottomTabs,
@@ -36708,7 +36802,7 @@ class NavController {
36708
36802
  });
36709
36803
  }
36710
36804
  const subscription = trpcClient2.kv.subscribe.subscribe(
36711
- { key: KV_KEY },
36805
+ { key: getRemoteStorageKey() },
36712
36806
  {
36713
36807
  onData: (data2) => {
36714
36808
  const incoming = parsePersistedLayout(data2);
@@ -36740,6 +36834,15 @@ class NavController {
36740
36834
  popLocation: parsed.pop
36741
36835
  });
36742
36836
  };
36837
+ computeTransition(event) {
36838
+ const transition = reduceKernel(this.state, event);
36839
+ if (!transition.changed) {
36840
+ return { transition, nextState: this.state };
36841
+ }
36842
+ let nextState = applyBehaviorPlugins(this.state, transition.nextState, event);
36843
+ nextState = normalizeState(nextState);
36844
+ return { transition, nextState };
36845
+ }
36743
36846
  dispatch(event) {
36744
36847
  if (typeof window !== "undefined" && event.type !== "POPSTATE" && this.mainHistory == null) {
36745
36848
  const parsed = parseBrowserLocation(window.location, this.state);
@@ -36830,7 +36933,7 @@ class NavController {
36830
36933
  this.persistTimer = null;
36831
36934
  Promise.resolve().then(() => trpc$1).then(
36832
36935
  ({ trpcClient: trpcClient2 }) => trpcClient2.kv.set.mutate({
36833
- key: KV_KEY,
36936
+ key: getRemoteStorageKey(),
36834
36937
  value: {
36835
36938
  mainTabs: this.state.mainTabs,
36836
36939
  bottomTabs: this.state.bottomTabs,
@@ -39831,18 +39934,23 @@ function createTRPCOptionsProxy(opts) {
39831
39934
  function isBrowser$1() {
39832
39935
  return typeof window !== "undefined" && typeof window.location !== "undefined";
39833
39936
  }
39937
+ function getHostedApiState() {
39938
+ if (!isBrowser$1()) {
39939
+ return {
39940
+ hosted: false,
39941
+ apiBaseUrl: null,
39942
+ sessionId: null
39943
+ };
39944
+ }
39945
+ return getHostedApiBootstrapState(window.location);
39946
+ }
39834
39947
  function getApiBaseUrl() {
39835
39948
  if (!isBrowser$1()) {
39836
39949
  return "";
39837
39950
  }
39838
- const params = new URLSearchParams(window.location.search);
39839
- const apiUrl = params.get("api");
39840
- if (apiUrl) {
39841
- return apiUrl.replace(/\/$/, "");
39842
- }
39843
- return "";
39951
+ return getHostedApiState().apiBaseUrl ?? "";
39844
39952
  }
39845
- function getWsUrl() {
39953
+ function buildWebSocketUrl(pathname) {
39846
39954
  if (!isBrowser$1()) {
39847
39955
  return "";
39848
39956
  }
@@ -39850,10 +39958,13 @@ function getWsUrl() {
39850
39958
  if (baseUrl) {
39851
39959
  const url = new URL(baseUrl);
39852
39960
  const wsProtocol = url.protocol === "https:" ? "wss:" : "ws:";
39853
- return `${wsProtocol}//${url.host}/trpc`;
39961
+ return `${wsProtocol}//${url.host}${pathname}`;
39854
39962
  }
39855
39963
  const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
39856
- return `${protocol}//${window.location.host}/trpc`;
39964
+ return `${protocol}//${window.location.host}${pathname}`;
39965
+ }
39966
+ function getWsUrl() {
39967
+ return buildWebSocketUrl("/trpc");
39857
39968
  }
39858
39969
  function getTrpcUrl() {
39859
39970
  const baseUrl = getApiBaseUrl();
@@ -48130,6 +48241,7 @@ async function getConfig$1() {
48130
48241
  codeEditor: {
48131
48242
  theme: "github"
48132
48243
  },
48244
+ appBaseUrl: "",
48133
48245
  dashboard: {
48134
48246
  trendPointLimit: 100
48135
48247
  },
@@ -72356,7 +72468,11 @@ const tabsStyle = (id2) => {
72356
72468
  & > button {
72357
72469
  scroll-snap-align: start;
72358
72470
  text-align: center;
72359
- &.tab-selected {
72471
+ }
72472
+ }
72473
+ &[data-tabs-variant='default'] {
72474
+ .tabs-button {
72475
+ & > button.tab-selected {
72360
72476
  background-image: linear-gradient(
72361
72477
  to bottom,
72362
72478
  transparent,
@@ -72409,7 +72525,8 @@ function Tabs({
72409
72525
  onTabClose,
72410
72526
  actions,
72411
72527
  onTabBarDoubleClick,
72412
- className = ""
72528
+ className = "",
72529
+ variant = "default"
72413
72530
  }) {
72414
72531
  const [uncontrolled, setUncontrolled] = reactExports.useState(tabs[0]?.id ?? "");
72415
72532
  const activeTab = controlled ?? uncontrolled;
@@ -72422,25 +72539,33 @@ function Tabs({
72422
72539
  if (tabs.length === 0) return null;
72423
72540
  const id2 = reactExports.useId();
72424
72541
  const style = reactExports.useMemo(() => tabsStyle(id2), [id2]);
72542
+ const headerClassName = variant === "terminal" ? "tabs-header z-2 bg-terminal text-terminal-foreground sticky top-0 flex min-w-0 items-stretch" : "tabs-header z-2 bg-background sticky top-0 flex min-w-0 items-stretch";
72543
+ const stripClassName = variant === "terminal" ? "tabs-strip min-w-0 flex-1 bg-terminal px-4" : "tabs-strip min-w-0 flex-1 px-4";
72544
+ const listClassName = "tabs-button scrollbar-none flex min-w-0 gap-1 overflow-x-auto";
72545
+ const buttonBaseClassName = `m-0 flex h-full shrink-0 items-center gap-2 px-2 py-2 text-sm font-medium transition-colors ${variant === "terminal" ? "rounded-t-[8px]" : ""}`;
72546
+ const activeButtonClassName = variant === "terminal" ? "tab-selected bg-background text-foreground" : "tab-selected text-foreground";
72547
+ const inactiveButtonClassName = variant === "terminal" ? "bg-terminal text-terminal-foreground hover:bg-background hover:text-foreground" : "text-muted-foreground hover:text-foreground";
72548
+ const actionsClassName = variant === "terminal" ? "tabs-actions border-border bg-terminal text-terminal-foreground flex shrink-0 items-center border-b px-1" : "tabs-actions border-border bg-background flex shrink-0 items-center border-b px-1";
72425
72549
  const handleTabBarDoubleClick = (e2) => {
72426
72550
  if (!onTabBarDoubleClick) return;
72427
72551
  if (e2.target.closest('[data-tab-item="true"]')) return;
72428
72552
  onTabBarDoubleClick();
72429
72553
  };
72430
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { id: id2, className: `flex min-h-0 min-w-0 flex-1 flex-col ${className}`, children: [
72431
- style,
72432
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "z-2 bg-background sticky top-0 flex min-w-0 items-stretch", children: [
72433
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tabs-strip min-w-0 flex-1 px-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
72434
- "div",
72435
- {
72436
- className: "tabs-button scrollbar-none flex min-w-0 gap-1 overflow-x-auto",
72437
- onDoubleClick: handleTabBarDoubleClick,
72438
- children: tabs.map((tab2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
72554
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
72555
+ "div",
72556
+ {
72557
+ id: id2,
72558
+ "data-tabs-variant": variant,
72559
+ className: `flex min-h-0 min-w-0 flex-1 flex-col ${className}`,
72560
+ children: [
72561
+ style,
72562
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: headerClassName, children: [
72563
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: stripClassName, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: listClassName, onDoubleClick: handleTabBarDoubleClick, children: tabs.map((tab2) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
72439
72564
  "button",
72440
72565
  {
72441
72566
  "data-tab-item": "true",
72442
72567
  onClick: () => handleChange(tab2.id),
72443
- className: `m-0 flex h-full shrink-0 items-center gap-2 px-2 py-2 text-sm font-medium transition-colors ${activeTab === tab2.id ? "tab-selected text-foreground" : "text-muted-foreground hover:text-foreground"}`,
72568
+ className: `${buttonBaseClassName} ${activeTab === tab2.id ? activeButtonClassName : inactiveButtonClassName}`,
72444
72569
  children: [
72445
72570
  tab2.icon,
72446
72571
  tab2.label,
@@ -72459,22 +72584,22 @@ function Tabs({
72459
72584
  onTabClose(tab2.id);
72460
72585
  }
72461
72586
  },
72462
- className: `text-muted-foreground hover:text-foreground -mr-1 rounded p-0.5 transition ${tab2.closeButtonVisibility === "always" ? "opacity-100" : "opacity-0 group-hover:opacity-100 [button:hover>&]:opacity-100"}`,
72587
+ className: `hover:text-foreground -mr-1 rounded p-0.5 transition ${tab2.closeButtonVisibility === "always" ? "opacity-100" : "opacity-0 group-hover:opacity-100 [button:hover>&]:opacity-100"} ${activeTab === tab2.id ? "text-current/80" : "text-muted-foreground"}`,
72463
72588
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(X$2, { className: "h-3 w-3" })
72464
72589
  }
72465
72590
  )
72466
72591
  ]
72467
72592
  },
72468
72593
  tab2.id
72469
- ))
72470
- }
72471
- ) }),
72472
- actions && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-border bg-background flex shrink-0 items-center border-b px-1", children: actions })
72473
- ] }),
72474
- tabs.map(
72475
- (tab2) => tab2.unmountOnHide ? activeTab === tab2.id && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: tab2.content }, tab2.id) : /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Activity, { mode: activeTab === tab2.id ? "visible" : "hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: tab2.content }) }, tab2.id)
72476
- )
72477
- ] });
72594
+ )) }) }),
72595
+ actions && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { "data-tabs-actions": "true", className: actionsClassName, children: actions })
72596
+ ] }),
72597
+ tabs.map(
72598
+ (tab2) => tab2.unmountOnHide ? activeTab === tab2.id && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: tab2.content }, tab2.id) : /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Activity, { mode: activeTab === tab2.id ? "visible" : "hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex min-h-0 flex-1 flex-col", children: tab2.content }) }, tab2.id)
72599
+ )
72600
+ ]
72601
+ }
72602
+ );
72478
72603
  }
72479
72604
  function operationBadgeClass(operation) {
72480
72605
  switch (operation) {
@@ -111812,14 +111937,17 @@ function ButtonGroup({
111812
111937
  value,
111813
111938
  options,
111814
111939
  onChange,
111815
- className = ""
111940
+ className = "",
111941
+ tone = "default"
111816
111942
  }) {
111943
+ const containerClassName = tone === "terminal" ? "border-terminal-foreground/25 bg-terminal/70 text-terminal-foreground" : "border-border bg-card";
111817
111944
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
111818
111945
  "div",
111819
111946
  {
111820
- className: `border-border bg-card inline-flex overflow-hidden rounded-md border ${className}`,
111947
+ className: `inline-flex overflow-hidden rounded-md border ${containerClassName} ${className}`,
111821
111948
  children: options.map((option2, index2) => {
111822
111949
  const active = option2.value === value;
111950
+ const stateClassName = active ? "bg-primary text-primary-foreground" : tone === "terminal" ? "text-terminal-foreground/72 hover:bg-terminal-foreground/10 hover:text-terminal-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground";
111823
111951
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
111824
111952
  "button",
111825
111953
  {
@@ -111827,7 +111955,7 @@ function ButtonGroup({
111827
111955
  disabled: option2.disabled,
111828
111956
  onClick: () => onChange(option2.value),
111829
111957
  "aria-pressed": active,
111830
- className: `px-3 py-1.5 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${index2 > 0 ? "border-border border-l" : ""} ${active ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground"}`,
111958
+ className: `px-3 py-1.5 text-xs font-medium transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${index2 > 0 ? tone === "terminal" ? "border-terminal-foreground/20 border-l" : "border-border border-l" : ""} ${stateClassName}`,
111831
111959
  children: option2.label
111832
111960
  },
111833
111961
  option2.value
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openspecui/web",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "openspecui-ssg": "./dist-ssg/ssg-cli.mjs"
@@ -9,6 +9,22 @@
9
9
  "dist",
10
10
  "dist-ssg"
11
11
  ],
12
+ "scripts": {
13
+ "dev": "vite --host=0.0.0.0",
14
+ "build": "tsc && vite build && pnpm run build:ssg && pnpm run build:ssg-cli",
15
+ "build:ssg": "pnpm build:ssg-client && pnpm build:ssg-server",
16
+ "build:ssg-client": "vite build --config vite.ssg-client.config.ts --ssrManifest .vite/ssr-manifest.json --outDir dist-ssg/client",
17
+ "build:ssg-server": "vite build --ssr src/ssg/entry-server.tsx --outDir dist-ssg/server",
18
+ "build:ssg-cli": "vite build --config vite.ssg-cli.config.ts --outDir dist-ssg",
19
+ "typecheck": "tsc --noEmit",
20
+ "preview": "vite preview",
21
+ "test": "vitest run --project unit",
22
+ "test:watch": "vitest --project unit",
23
+ "test:browser": "vitest --retry 2 --project storybook",
24
+ "storybook": "storybook dev -p 6006",
25
+ "build-storybook": "storybook build",
26
+ "test:browser:ci": "vitest run --retry 2 --project storybook"
27
+ },
12
28
  "devDependencies": {
13
29
  "@codemirror/commands": "^6.10.0",
14
30
  "@codemirror/lang-javascript": "^6.2.4",
@@ -21,6 +37,8 @@
21
37
  "@codemirror/view": "^6.38.8",
22
38
  "@lezer/common": "^1.4.0",
23
39
  "@lezer/highlight": "^1.2.3",
40
+ "@openspecui/search": "workspace:*",
41
+ "@openspecui/server": "workspace:*",
24
42
  "@storybook/addon-vitest": "^10.2.8",
25
43
  "@storybook/web-components": "^10.2.8",
26
44
  "@storybook/web-components-vite": "^10.2.8",
@@ -60,28 +78,15 @@
60
78
  "typescript": "^5.7.2",
61
79
  "vite": "^7.3.1",
62
80
  "vitest": "^4.0.18",
81
+ "xterm-input-panel": "workspace:*",
63
82
  "yaml": "^2.8.0",
64
- "yargs": "^18.0.0",
65
- "@openspecui/search": "1.1.0",
66
- "@openspecui/server": "2.0.0",
67
- "xterm-input-panel": "1.2.1"
83
+ "yargs": "^18.0.0"
68
84
  },
69
85
  "dependencies": {
70
86
  "@fsegurai/codemirror-theme-bundle": "^6.3.1"
71
87
  },
72
- "scripts": {
73
- "dev": "vite --host=0.0.0.0",
74
- "build": "tsc && vite build && pnpm run build:ssg && pnpm run build:ssg-cli",
75
- "build:ssg": "pnpm build:ssg-client && pnpm build:ssg-server",
76
- "build:ssg-client": "vite build --config vite.ssg-client.config.ts --ssrManifest .vite/ssr-manifest.json --outDir dist-ssg/client",
77
- "build:ssg-server": "vite build --ssr src/ssg/entry-server.tsx --outDir dist-ssg/server",
78
- "build:ssg-cli": "vite build --config vite.ssg-cli.config.ts --outDir dist-ssg",
79
- "typecheck": "tsc --noEmit",
80
- "preview": "vite preview",
81
- "test": "vitest run --project unit",
82
- "test:watch": "vitest --project unit",
83
- "test:browser": "vitest --retry 2 --project storybook",
84
- "storybook": "storybook dev -p 6006",
85
- "build-storybook": "storybook build"
88
+ "repository": {
89
+ "type": "git",
90
+ "url": "https://github.com/jixoai/openspecui"
86
91
  }
87
- }
92
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 OpenSpecUI Contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.