@luziyang2026/dsh-question-nav 0.4.2 → 0.5.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.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Rail anchor-edge constants shared by the host schema and the browser
3
+ * settings scope. Pure data: no DSH imports, so the client bundle may inline
4
+ * this module (a Host import here would leak into the browser half).
5
+ *
6
+ * @module dsh-question-nav/align
7
+ */
8
+
9
+ /** Supported rail anchor edges. */
10
+ export const ALIGN_OPTIONS = ['left', 'right'] as const
11
+
12
+ /** Rail anchor edge preference. */
13
+ export type AlignPreference = typeof ALIGN_OPTIONS[number]
14
+
15
+ /** Default anchor edge when the user-settings document has no override. */
16
+ export const DEFAULT_ALIGN: AlignPreference = 'left'
17
+
18
+ /** Settings namespace owned by this plugin (spelled here rather than
19
+ * imported: the client bundle must not depend on a Host package). */
20
+ export const QUESTION_NAV_SETTINGS_NS = 'question-nav'
21
+
22
+ /** Field carrying the selected anchor edge. */
23
+ export const ALIGN_FIELD = 'align'
package/src/index.ts CHANGED
@@ -9,19 +9,24 @@
9
9
  */
10
10
  import type { Context } from '@deepseek-ai/cordis'
11
11
  import { questionIndexProjectionDefinition } from './projection.ts'
12
+ import { questionNavSettingsNamespace, QuestionNavSettingsSchema } from './settings.ts'
12
13
 
13
14
  /** Cordis plugin name. */
14
15
  export const name = 'dsh-question-nav'
15
16
 
16
17
  /**
17
- * Register the `questionIndex` unit. The registry is an optional capability
18
- * (absent in headless compositions), so registration rides `ctx.inject`:
19
- * without it the host half simply contributes nothing and the browser strip
20
- * falls back to live-window questions.
18
+ * Register the `questionIndex` unit and the plugin's durable settings
19
+ * namespace. Both registries are optional capabilities (absent in headless
20
+ * compositions), so each registration rides `ctx.inject`: without them the
21
+ * host half simply contributes nothing and the browser strip falls back to
22
+ * live-window questions and the default rail alignment.
21
23
  * @param ctx - plugin context.
22
24
  */
23
25
  export function apply(ctx: Context): void {
24
26
  ctx.inject(['sessionProjections'], (inner) => {
25
27
  inner.sessionProjections.register(questionIndexProjectionDefinition)
26
28
  })
29
+ ctx.inject(['settings'], (settingsCtx) => {
30
+ settingsCtx.settings.register(questionNavSettingsNamespace, QuestionNavSettingsSchema)
31
+ })
27
32
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Host-side durable settings for the question-nav plugin, registered into the
3
+ * DSH user-settings document. Currently one field: which edge of the
4
+ * conversation column the rail anchors to (`align`). The browser half reads
5
+ * the same namespace through the settings scope (`ctx.settingsScope.bind`)
6
+ * and routes the user's choice back through `scope.set`.
7
+ *
8
+ * @module dsh-question-nav/settings
9
+ */
10
+
11
+ import z from '@deepseek-ai/schemastery'
12
+ import type { SettingsNamespace } from '@deepseek-ai/dsh-settings'
13
+ import {
14
+ ALIGN_FIELD, ALIGN_OPTIONS, DEFAULT_ALIGN, QUESTION_NAV_SETTINGS_NS,
15
+ type AlignPreference,
16
+ } from './core/align.ts'
17
+
18
+ /** Durable settings section shared by the Host schema and the browser scope. */
19
+ export interface QuestionNavSettings {
20
+ /** Anchor edge of the rail. */
21
+ align: AlignPreference
22
+ }
23
+
24
+ /** Durable settings schema; also the wire envelope the browser scope validates against. */
25
+ export const QuestionNavSettingsSchema: z<QuestionNavSettings> = z.object({
26
+ [ALIGN_FIELD]: z.union([...ALIGN_OPTIONS]).default(DEFAULT_ALIGN),
27
+ })
28
+
29
+ /** The settings namespace this plugin owns, branded for the Host registry.
30
+ * `question-nav` matches the registry pattern (`^[a-z][a-z0-9-]*$`), so the
31
+ * constant needs no runtime validator — keeping this module type-only on the
32
+ * settings package avoids inlining it (and cosmokit) into the host bundle. */
33
+ export const questionNavSettingsNamespace = QUESTION_NAV_SETTINGS_NS as SettingsNamespace