@harborclient/sdk 1.6.0 → 1.6.2

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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 1.6.2 - 2026-08-04
8
+
9
+ - docs(sdk): enhance API index formatting for improved readability. (`52517d89`)
10
+ - feat(docs): add hc_sdk_manifest.json for comprehensive SDK action and command documentation. (`39adb007`)
11
+ - docs(sdk): update AGENTS.md to include additional sync script details. (`61daf83a`)
12
+ - docs(sdk): clean up API index documentation by removing empty entries. (`d6cfb700`)
13
+ - refactor(sdk): replace installReact with setHostReact for improved plugin integration. (`3acb19dd`)
14
+ - feat(docs): update SDK documentation and improve manifest guidelines. (`a85afcea`)
15
+
16
+ ## 1.6.1 - 2026-08-03
17
+
18
+ - feat(docs): enhance SDK documentation and update API references. (`6331350c`)
19
+ - feat(docs): update SDK documentation and enhance plugin API guidelines. (`46a2a29e`)
20
+ - refactor(ResponseEditor): simplify split pane wrapping and adjust padding. (`4b480786`)
21
+ - feat(settings): enhance deep link handling for settings navigation. (`3d03652e`)
22
+ - feat(gui): add response editor split functionality. (`bd1aaaba`)
23
+
7
24
  ## 1.6.0 - 2026-08-03
8
25
 
9
26
  - feat(sse): enhance import functionality for Server-Sent Events (SSE). (`e26fa155`)
package/README.md CHANGED
@@ -4,7 +4,7 @@ TypeScript definitions, utility modules, and React runtime helpers for [HarborCl
4
4
 
5
5
  **Documentation:** [https://harborclient.github.io/harborclient/sdk/](https://harborclient.github.io/harborclient/sdk/)
6
6
 
7
- Install as a **dev dependency** in your plugin project. The package ships type declarations, HTTP/storage/UI helpers, and a JSX runtime that forwards to the host's React instance via `installReact(hc.react)`.
7
+ Install as a **dev dependency** in your plugin project. The package ships type declarations, HTTP/storage/UI helpers, and a JSX runtime that forwards to the host's React instance (HarborClient installs `hc.react` before `activate(hc)` — no plugin-side setup call is required).
8
8
 
9
9
  Requires HarborClient **>=1.9.0** when using `hc.pluginId`, renderer HTTP lifecycle events, typed IPC invoke, and host request commands.
10
10
 
@@ -19,11 +19,9 @@ See the [install guide](https://harborclient.github.io/harborclient/sdk/install)
19
19
  ## Quick start
20
20
 
21
21
  ```tsx
22
- import { installReact } from '@harborclient/sdk';
23
22
  import type { PluginContext } from '@harborclient/sdk';
24
23
 
25
24
  export function activate(hc: PluginContext): void {
26
- installReact(hc.react);
27
25
  // register contributions…
28
26
  }
29
27
  ```
@@ -26,7 +26,7 @@ export function getCodeEditorConfigStore() {
26
26
  * Returns the CodeEditor React context, creating it on first access.
27
27
  *
28
28
  * Deferred so importing CodeEditor in a plugin bundle does not call requireHostReact()
29
- * before activate() runs installReact(hc.react).
29
+ * before the host installs React for the plugin view.
30
30
  */
31
31
  function getCodeEditorContext() {
32
32
  if (codeEditorContext == null) {
@@ -1,4 +1,4 @@
1
- import type { ComponentPropsWithoutRef, JSX } from 'react';
1
+ import type { ComponentPropsWithoutRef, JSX, MouseEvent } from 'react';
2
2
  import type { TabItem } from './types.js';
3
3
  export { SegmentedTabsGroup } from './SegmentedTabsGroup.js';
4
4
  export { SegmentedTabPanel } from './SegmentedTabPanel.js';
@@ -53,10 +53,15 @@ interface Props<T extends string> extends Omit<ComponentPropsWithoutRef<'div'>,
53
53
  * `SegmentedTabsGroup`.
54
54
  */
55
55
  ariaLabel?: string;
56
+ /**
57
+ * Called when the user right-clicks a tab button. The browser context menu is
58
+ * suppressed so hosts can show a custom menu.
59
+ */
60
+ onTabContextMenu?: (value: T, event: MouseEvent<HTMLButtonElement>) => void;
56
61
  }
57
62
  /**
58
63
  * macOS-style segmented tab control with WAI-ARIA tabs or radiogroup semantics.
59
64
  * The tab strip wraps to additional rows when tabs exceed the container width.
60
65
  */
61
- export declare function SegmentedTabs<T extends string>({ tabs, value: valueProp, onChange: onChangeProp, editable, visibleTabValues: visibleTabValuesProp, defaultVisibleTabValues, onVisibleTabValuesChange, fullWidth, className, pattern, ariaLabel: ariaLabelProp, ...props }: Props<T>): JSX.Element;
66
+ export declare function SegmentedTabs<T extends string>({ tabs, value: valueProp, onChange: onChangeProp, editable, visibleTabValues: visibleTabValuesProp, defaultVisibleTabValues, onVisibleTabValuesChange, fullWidth, className, pattern, ariaLabel: ariaLabelProp, onTabContextMenu, ...props }: Props<T>): JSX.Element;
62
67
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SegmentedTabs/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAiB,MAAM,OAAO,CAAC;AAM1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAgD1C,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,IAAI,CAC5C,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,CACrD;IACC;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC;IAEvB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC;IAE9B;;OAEG;IACH,wBAAwB,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAEhC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,EAC9C,IAAI,EACJ,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,YAAY,EACtB,QAAe,EACf,gBAAgB,EAAE,oBAAoB,EACtC,uBAAuB,EACvB,wBAAwB,EACxB,SAAiB,EACjB,SAAS,EACT,OAAgB,EAChB,SAAS,EAAE,aAAa,EACxB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CA4PxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SegmentedTabs/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAiB,UAAU,EAAE,MAAM,OAAO,CAAC;AAMtF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAgD1C,UAAU,KAAK,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,IAAI,CAC5C,wBAAwB,CAAC,KAAK,CAAC,EAC/B,UAAU,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,CACrD;IACC;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,CAAC;IAEV;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,EAAE,CAAC;IAEvB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,CAAC,EAAE,CAAC;IAE9B;;OAEG;IACH,wBAAwB,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IAEhC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CAC7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,EAC9C,IAAI,EACJ,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,YAAY,EACtB,QAAe,EACf,gBAAgB,EAAE,oBAAoB,EACtC,uBAAuB,EACvB,wBAAwB,EACxB,SAAiB,EACjB,SAAS,EACT,OAAgB,EAChB,SAAS,EAAE,aAAa,EACxB,gBAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAqQxB"}
@@ -49,7 +49,7 @@ function focusFirstFocusableInPanel(panel) {
49
49
  * macOS-style segmented tab control with WAI-ARIA tabs or radiogroup semantics.
50
50
  * The tab strip wraps to additional rows when tabs exceed the container width.
51
51
  */
52
- export function SegmentedTabs({ tabs, value: valueProp, onChange: onChangeProp, editable = true, visibleTabValues: visibleTabValuesProp, defaultVisibleTabValues, onVisibleTabValuesChange, fullWidth = false, className, pattern = 'tabs', ariaLabel: ariaLabelProp, ...props }) {
52
+ export function SegmentedTabs({ tabs, value: valueProp, onChange: onChangeProp, editable = true, visibleTabValues: visibleTabValuesProp, defaultVisibleTabValues, onVisibleTabValuesChange, fullWidth = false, className, pattern = 'tabs', ariaLabel: ariaLabelProp, onTabContextMenu, ...props }) {
53
53
  const context = useContext(SegmentedTabsContext);
54
54
  const standaloneId = useId();
55
55
  const tabRefs = useRef(new Map());
@@ -197,7 +197,12 @@ export function SegmentedTabs({ tabs, value: valueProp, onChange: onChangeProp,
197
197
  tabRefs.current.set(tab.value, element);
198
198
  else
199
199
  tabRefs.current.delete(tab.value);
200
- }, type: "button", className: tabClassName, disabled: tab.disabled, tabIndex: tab.disabled ? -1 : 0, onClick: () => onChange(tab.value), ...(isRadiogroup
200
+ }, type: "button", className: tabClassName, disabled: tab.disabled, tabIndex: tab.disabled ? -1 : 0, "data-tab-value": tab.value, onClick: () => onChange(tab.value), onContextMenu: onTabContextMenu
201
+ ? (event) => {
202
+ event.preventDefault();
203
+ onTabContextMenu(tab.value, event);
204
+ }
205
+ : undefined, ...(isRadiogroup
201
206
  ? { role: 'radio', 'aria-checked': selected }
202
207
  : {
203
208
  role: 'tab',
@@ -8,9 +8,16 @@ export interface Props {
8
8
  * Stable setting id shown on hover and keyboard focus.
9
9
  */
10
10
  settingId: string;
11
+ /**
12
+ * Optional content between the label and the setting id (e.g. a cog actions menu).
13
+ */
14
+ afterLabel?: ReactNode;
11
15
  }
12
16
  /**
13
17
  * Setting label with a VS Code-style id affordance revealed on hover and focus.
18
+ *
19
+ * Renders as `<label> [afterLabel] <setting id>` so actions sit after the title
20
+ * and before the hover-revealed id.
14
21
  */
15
- export declare function SettingIdLabel({ children, settingId }: Props): JSX.Element;
22
+ export declare function SettingIdLabel({ children, settingId, afterLabel }: Props): JSX.Element;
16
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SettingIdLabel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CAa1E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/SettingIdLabel/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,KAAK,GAAG,GAAG,CAAC,OAAO,CActF"}
@@ -1,7 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "@harborclient/sdk/jsx-runtime";
2
2
  /**
3
3
  * Setting label with a VS Code-style id affordance revealed on hover and focus.
4
+ *
5
+ * Renders as `<label> [afterLabel] <setting id>` so actions sit after the title
6
+ * and before the hover-revealed id.
4
7
  */
5
- export function SettingIdLabel({ children, settingId }) {
6
- return (_jsxs("span", { className: "group/setting-label inline-flex items-baseline gap-2", children: [_jsx("span", { children: children }), _jsx("span", { className: "pointer-events-none font-mono text-[14px] text-muted opacity-0 transition-opacity select-none group-focus-within/setting-label:opacity-100 group-hover/setting-label:opacity-100", title: settingId, "aria-label": `Setting id: ${settingId}`, children: settingId })] }));
8
+ export function SettingIdLabel({ children, settingId, afterLabel }) {
9
+ return (_jsxs("span", { className: "group/setting-label inline-flex min-w-0 items-center gap-2", children: [_jsx("span", { children: children }), afterLabel, _jsx("span", { className: "pointer-events-none font-mono text-[14px] text-muted opacity-0 transition-opacity select-none group-focus-within/setting-label:opacity-100 group-hover/setting-label:opacity-100", title: settingId, "aria-label": `Setting id: ${settingId}`, children: settingId })] }));
7
10
  }
@@ -1,15 +1,6 @@
1
1
  import type * as React from 'react';
2
2
  import type { Disposable, ImportHandler, PluginContext, ThemeContribution } from '../types.js';
3
3
 
4
- /**
5
- * Installs the HarborClient renderer React instance for plugin JSX and hooks.
6
- *
7
- * Call once at the start of `activate(hc)` before registering UI contributions.
8
- *
9
- * @param react - React namespace from `hc.react`.
10
- */
11
- export function installReact(react: typeof React): void;
12
-
13
4
  /**
14
5
  * Creates a React component from a factory that receives the host React namespace.
15
6
  *
@@ -1,15 +1,4 @@
1
- import { requireHostReact, setHostReact } from './reactHost.js';
2
-
3
- /**
4
- * Installs the HarborClient renderer React instance for plugin JSX and hooks.
5
- *
6
- * Call once at the start of `activate(hc)` before registering UI contributions.
7
- *
8
- * @param {typeof import('react')} react - React namespace from `hc.react`.
9
- */
10
- export function installReact(react) {
11
- setHostReact(react);
12
- }
1
+ import { requireHostReact } from './reactHost.js';
13
2
 
14
3
  /**
15
4
  * Creates a React component from a factory that receives the host React namespace.
@@ -26,7 +15,7 @@ export function createPluginComponent(factory) {
26
15
  let Component = null;
27
16
 
28
17
  /**
29
- * Lazily builds the component on first render after installReact().
18
+ * Lazily builds the component on first render after the host installs React.
30
19
  *
31
20
  * @param {P} props - Component props.
32
21
  * @returns {import('react').ReactElement | null}
@@ -8,7 +8,7 @@ export const Fragment = React.Fragment;
8
8
  * Used when bundling third-party deps (e.g. @uiw/react-codemirror,
9
9
  * @fortawesome/react-fontawesome) that import `react/jsx-runtime`. Aliasing
10
10
  * those imports to this module keeps them on the same host React instance as
11
- * the plugin shell without requiring installReact() to have run first.
11
+ * the plugin shell without requiring the host React install to have run first.
12
12
  *
13
13
  * @param {import('react').ElementType} type - Element type or Fragment.
14
14
  * @param {Record<string, unknown> | null | undefined} props - Element props.
@@ -53,7 +53,7 @@ export function requireHostReact() {
53
53
  }
54
54
  if (hostReact == null) {
55
55
  throw new Error(
56
- 'Plugin React host is not installed. Call installReact(hc.react) at the start of activate().'
56
+ 'Plugin React host is not installed. The view host must call setHostReact() before activate().'
57
57
  );
58
58
  }
59
59
  return hostReact;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harborclient/sdk",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "TypeScript SDK for HarborClient development.",
5
5
  "keywords": [
6
6
  "harborclient",
@@ -229,6 +229,7 @@
229
229
  "debug": "^4.4.3",
230
230
  "eslint": "^10.5.0",
231
231
  "jsdom": "^26.1.0",
232
+ "markdown-it": "^15.0.0",
232
233
  "mermaid": "^11.15.0",
233
234
  "overlayscrollbars": "^2.16.0",
234
235
  "overlayscrollbars-react": "^0.5.6",
@@ -238,6 +239,7 @@
238
239
  "react-dom": "^19.2.7",
239
240
  "react-markdown": "^10.1.0",
240
241
  "remark-gfm": "^4.0.1",
242
+ "shiki": "^4.4.1",
241
243
  "storybook": "^10.4.6",
242
244
  "tailwindcss": "^4.3.1",
243
245
  "typescript": "^5.8.3",
@@ -265,7 +267,7 @@
265
267
  "storybook": "storybook dev -p 6006",
266
268
  "build-storybook": "storybook build -o docs/.vitepress/static/storybook",
267
269
  "docs:build": "pnpm docs:build:nav && pnpm build-storybook && vitepress build docs",
268
- "docs:build:nav": "node scripts/build-docs-nav.mjs && node scripts/assert-docs-slugs.mjs",
270
+ "docs:build:nav": "node scripts/build-hc-api-docs.mjs && node scripts/build-docs-nav.mjs && node scripts/assert-docs-slugs.mjs",
269
271
  "docs:preview": "pnpm docs:build && vitepress preview docs",
270
272
  "docs:serve": "pnpm docs:build:nav && concurrently --kill-others --prefixColors=auto -n nav,vp \"node scripts/watch-docs-nav.mjs\" \"vitepress dev docs\"",
271
273
  "plugin:sign": "pnpm build && node dist/signing/cli-sign.js",