@goodandready/dsh-tts 0.4.16 → 0.4.17

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 ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ Notable changes to `@goodandready/dsh-tts`.
4
+
5
+ ## 0.4.17
6
+
7
+ ### Added
8
+
9
+ - Settings now register into the Plugins page's row seat, `plugins.row.config`,
10
+ keyed `@goodandready/dsh-tts#dsh-tts` (row id as `cordis.patch.yml` declares
11
+ it): the plugin's row on the Plugins page gains a configure control whose page
12
+ is the same settings form (`view: 'page'`), with a one-line state under the row
13
+ title (`view: 'summary'`). The previous seat, `settings.plugin.item`, stays as
14
+ a fallback for older cores, so settings never become unreachable (#127).
15
+
16
+ ### Fixed
17
+
18
+ - The row-seat page renders the settings form **bare**: the host page already
19
+ draws the title, icon and crumb and provides the content padding, so our own
20
+ card chrome would double the border and shift the form out of the content area.
21
+
22
+ ### Tests
23
+
24
+ - `test/row-config-seat.test.mjs` guards the row-seat key, the row id against
25
+ `cordis.patch.yml`, the fallback seats, and the bare view-aware rendering.
@@ -15,6 +15,10 @@ window.__ModuleLoader__.load({
15
15
  ChevronIcon = null
16
16
  }
17
17
  const NS = 'dsh-tts'
18
+ // Plugins page row seat: key = '<package name>#<row id>', row id as cordis.patch.yml declares it.
19
+ const PKG = '@goodandready/dsh-tts'
20
+ const ROW_ID = 'dsh-tts'
21
+ const ROW_CONFIG_KEY = PKG + '#' + ROW_ID
18
22
  const PROVIDERS = [
19
23
  'openai', 'elevenlabs', 'google', 'azure', 'groq', 'deepgram', 'openrouter',
20
24
  'edge', 'piper', 'espeak',
@@ -2,6 +2,7 @@
2
2
  const SET_CSS =
3
3
  '.dts-wrap{display:flex;flex-direction:column;gap:18px;padding:4px 0 24px;max-width:900px}' +
4
4
  '.dts-header{display:flex;flex-direction:column;gap:8px;padding-bottom:14px;border-bottom:1px solid var(--dsw-alias-border-l2)}' +
5
+ '.dts-page{padding:0}' +
5
6
  '.dts-page-title{font-size:20px;font-weight:700;color:var(--dsw-alias-label-primary);display:flex;align-items:center;gap:10px}' +
6
7
  '.dts-page-sub{font-size:13px;color:var(--dsw-alias-label-secondary);line-height:1.5}' +
7
8
  '.dts-block{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:16px 18px;display:flex;flex-direction:column;gap:12px}' +
@@ -118,6 +118,26 @@
118
118
  ))
119
119
  }
120
120
 
121
+ /**
122
+ * Plugins page row seat (`plugins.row.config`, current core).
123
+ *
124
+ * The host page draws the title, icon and crumb and provides the content
125
+ * padding, so the page view renders the settings form bare: our own card
126
+ * chrome would double the border and shift the form out of the content
127
+ * area. The summary view feeds the one-liner under the row title.
128
+ */
129
+ function TtsRowConfig(props) {
130
+ const t = (props && props.t) || ((key) => key)
131
+ if (props && props.view === 'summary') {
132
+ return React.createElement('div', { className: 'dts-sub' }, t('subtitle'))
133
+ }
134
+ return React.createElement('div', { className: 'dts-page' },
135
+ React.createElement(ErrorBoundary, null,
136
+ React.createElement(TtsSection, Object.assign({}, props, { ctx: props && props.ctx })),
137
+ ),
138
+ )
139
+ }
140
+
121
141
  function registerSettings(ctx) {
122
142
  // Dictionary packages may also register languages for other namespaces.
123
143
  // Core throws on duplicate namespace+language; an unguarded call used to
@@ -137,9 +157,25 @@
137
157
  // The sidebar draws the section label, not our component: props.t never
138
158
  // reaches it, so bind the translator to the namespace ourselves.
139
159
  const t = ctx.locale.bind(NS)
140
- // Primary settings home is the plugin-settings tab card. The tab looks up
141
- // a slot by entryKey equal to the namespace name: key must equal NS or
142
- // the card never appears, with no log error.
160
+ // Current core: settings live on the plugin's own row on the Plugins page
161
+ // (`plugins.row.config`). Key = '<package name>#<row id>'; the row gains a
162
+ // configure control that asks for view:'summary' and view:'page'.
163
+ try {
164
+ ctx.slots.inject('plugins.row.config', () => ctx.slots.register(
165
+ {
166
+ name: 'plugins.row.config',
167
+ key: ROW_CONFIG_KEY,
168
+ locale: NS,
169
+ inject: () => ({ ctx: ctx }),
170
+ },
171
+ TtsRowConfig,
172
+ ))
173
+ } catch (rowSeatUnavailable) {
174
+ console.warn('[dsh-tts] row seat plugins.row.config not available:', rowSeatUnavailable && rowSeatUnavailable.message)
175
+ }
176
+ // Fallback for hosts that render the older plugin-settings tab card. The tab
177
+ // looks up a slot by entryKey equal to the namespace name: key must equal NS
178
+ // or the card never appears, with no log error.
143
179
  ctx.slots.inject('settings.plugin.item', () => ctx.slots.register(
144
180
  {
145
181
  name: 'settings.plugin.item',
package/lib/client.js CHANGED
@@ -15,6 +15,10 @@ window.__ModuleLoader__.load({
15
15
  ChevronIcon = null
16
16
  }
17
17
  const NS = 'dsh-tts'
18
+ // Plugins page row seat: key = '<package name>#<row id>', row id as cordis.patch.yml declares it.
19
+ const PKG = '@goodandready/dsh-tts'
20
+ const ROW_ID = 'dsh-tts'
21
+ const ROW_CONFIG_KEY = PKG + '#' + ROW_ID
18
22
  const PROVIDERS = [
19
23
  'openai', 'elevenlabs', 'google', 'azure', 'groq', 'deepgram', 'openrouter',
20
24
  'edge', 'piper', 'espeak',
@@ -87,6 +91,7 @@ window.__ModuleLoader__.load({
87
91
  const SET_CSS =
88
92
  '.dts-wrap{display:flex;flex-direction:column;gap:18px;padding:4px 0 24px;max-width:900px}' +
89
93
  '.dts-header{display:flex;flex-direction:column;gap:8px;padding-bottom:14px;border-bottom:1px solid var(--dsw-alias-border-l2)}' +
94
+ '.dts-page{padding:0}' +
90
95
  '.dts-page-title{font-size:20px;font-weight:700;color:var(--dsw-alias-label-primary);display:flex;align-items:center;gap:10px}' +
91
96
  '.dts-page-sub{font-size:13px;color:var(--dsw-alias-label-secondary);line-height:1.5}' +
92
97
  '.dts-block{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:16px 18px;display:flex;flex-direction:column;gap:12px}' +
@@ -1876,6 +1881,26 @@ async function pollPending() {
1876
1881
  ))
1877
1882
  }
1878
1883
 
1884
+ /**
1885
+ * Plugins page row seat (`plugins.row.config`, current core).
1886
+ *
1887
+ * The host page draws the title, icon and crumb and provides the content
1888
+ * padding, so the page view renders the settings form bare: our own card
1889
+ * chrome would double the border and shift the form out of the content
1890
+ * area. The summary view feeds the one-liner under the row title.
1891
+ */
1892
+ function TtsRowConfig(props) {
1893
+ const t = (props && props.t) || ((key) => key)
1894
+ if (props && props.view === 'summary') {
1895
+ return React.createElement('div', { className: 'dts-sub' }, t('subtitle'))
1896
+ }
1897
+ return React.createElement('div', { className: 'dts-page' },
1898
+ React.createElement(ErrorBoundary, null,
1899
+ React.createElement(TtsSection, Object.assign({}, props, { ctx: props && props.ctx })),
1900
+ ),
1901
+ )
1902
+ }
1903
+
1879
1904
  function registerSettings(ctx) {
1880
1905
  // Dictionary packages may also register languages for other namespaces.
1881
1906
  // Core throws on duplicate namespace+language; an unguarded call used to
@@ -1895,9 +1920,25 @@ async function pollPending() {
1895
1920
  // The sidebar draws the section label, not our component: props.t never
1896
1921
  // reaches it, so bind the translator to the namespace ourselves.
1897
1922
  const t = ctx.locale.bind(NS)
1898
- // Primary settings home is the plugin-settings tab card. The tab looks up
1899
- // a slot by entryKey equal to the namespace name: key must equal NS or
1900
- // the card never appears, with no log error.
1923
+ // Current core: settings live on the plugin's own row on the Plugins page
1924
+ // (`plugins.row.config`). Key = '<package name>#<row id>'; the row gains a
1925
+ // configure control that asks for view:'summary' and view:'page'.
1926
+ try {
1927
+ ctx.slots.inject('plugins.row.config', () => ctx.slots.register(
1928
+ {
1929
+ name: 'plugins.row.config',
1930
+ key: ROW_CONFIG_KEY,
1931
+ locale: NS,
1932
+ inject: () => ({ ctx: ctx }),
1933
+ },
1934
+ TtsRowConfig,
1935
+ ))
1936
+ } catch (rowSeatUnavailable) {
1937
+ console.warn('[dsh-tts] row seat plugins.row.config not available:', rowSeatUnavailable && rowSeatUnavailable.message)
1938
+ }
1939
+ // Fallback for hosts that render the older plugin-settings tab card. The tab
1940
+ // looks up a slot by entryKey equal to the namespace name: key must equal NS
1941
+ // or the card never appears, with no log error.
1901
1942
  ctx.slots.inject('settings.plugin.item', () => ctx.slots.register(
1902
1943
  {
1903
1944
  name: 'settings.plugin.item',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-tts",
3
- "version": "0.4.16",
3
+ "version": "0.4.17",
4
4
  "description": "Text-to-speech for DeepSeek Harness: speak agent replies in the Web UI with a provider fallback chain (OpenAI, ElevenLabs, Google, Azure, Groq, Deepgram, OpenRouter, Edge, Piper, eSpeak).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,6 +15,7 @@
15
15
  "lib/",
16
16
  "scripts/",
17
17
  "cordis.patch.yml",
18
+ "CHANGELOG.md",
18
19
  "README.md",
19
20
  "LICENSE",
20
21
  "README.ru.md",