@lmzhen/dsh-evolution-ui 0.32.5 → 0.33.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.
@@ -22,6 +22,9 @@ export interface PanelFace extends Copy {
22
22
  readonly loadDiff: (name: string, v: number) => Promise<VersionDiffRow>;
23
23
  readonly loadBody: (name: string, v: number) => Promise<VersionBodyRow>;
24
24
  readonly undo: (name: string, v?: number, unitId?: string) => Promise<string>;
25
+ /** One explicit navigation request: select this skill when the revision is new. */
26
+ readonly focusSkill?: string | undefined;
27
+ readonly focusRevision?: number | undefined;
25
28
  }
26
29
  export declare function SkillHistoryPanel(face: PanelFace): ReactNode;
27
30
  //# sourceMappingURL=Panel.d.ts.map
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The family's one task page. G3 owns the history view; later groups add health
3
+ * without creating another page or a second navigation registry.
4
+ * @module @lmzhen/dsh-evolution-ui/panels/history/client
5
+ */
6
+ import { type ReactNode } from 'react';
7
+ import { type PanelFace } from './Panel.ts';
8
+ import { type PendingCardFace } from '../../settings/PendingCard.ts';
9
+ import { type DiagnosticsCardFace } from '../../settings/DiagnosticsCard.ts';
10
+ /** Stable page id used by the sidebar row, the page slot key, and navigation params. */
11
+ export declare const WORKBENCH_ID = "evolution.workbench";
12
+ /** Injected face: copy plus the history view's data callbacks. */
13
+ export interface WorkbenchFace {
14
+ readonly t: (key: string) => string;
15
+ readonly history: PanelFace;
16
+ readonly pending: PendingCardFace;
17
+ readonly diagnostics: DiagnosticsCardFace;
18
+ /** Whether a feature view is actually mounted (health is disabled by default). */
19
+ readonly hasView?: (view: 'merge' | 'health') => boolean;
20
+ }
21
+ /** The two views the workbench owns today. */
22
+ export type WorkbenchView = 'history' | 'pending' | 'merge' | 'health' | 'diagnostics';
23
+ /** Sidebar row injected face. */
24
+ export interface WorkbenchNavFace {
25
+ readonly t: (key: string) => string;
26
+ }
27
+ /**
28
+ * Render the workbench page. The platform keeps it mounted; this component only
29
+ * consumes a new explicit revision exactly once.
30
+ * @param props - page owner props plus the injected history face.
31
+ * @returns the page surface.
32
+ */
33
+ export declare function WorkbenchPage(props: WorkbenchFace & {
34
+ readonly renderSlot?: (name: string, owner: Record<string, unknown>) => ReactNode;
35
+ }): ReactNode;
36
+ /** The sidebar icon; the platform renders the row label, tooltip and active state. */
37
+ export declare function WorkbenchIcon(props: {
38
+ size?: number;
39
+ active?: boolean;
40
+ }): ReactNode;
41
+ /** Workbench shell and sidebar row; colours come from the platform tokens. */
42
+ export declare const WORKBENCH_CSS: string;
43
+ //# sourceMappingURL=Workbench.d.ts.map
@@ -1,11 +1,15 @@
1
+ /**
2
+ * Browser half: the family workbench page, starting with the history view.
3
+ * @module @lmzhen/dsh-evolution-ui/panels/history/client
4
+ */
1
5
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
6
+ import { PANEL_ORDER } from './ids.ts';
7
+ export { PANEL_ORDER };
2
8
  /** Required client services: the slot registry and the locale seat. */
3
9
  export declare const inject: string[];
4
- /** Row order inside the global panel list (beside the platform's own rows). */
5
- export declare const PANEL_ORDER = 35;
6
10
  /**
7
- * Register the locale namespace, the panel row and the panel body.
8
- * @param ctx - the client cordis context.
11
+ * Register the locale namespace, the workbench main occupant and its sidebar row.
12
+ * @param ctx - client cordis context.
9
13
  */
10
14
  export declare function apply(ctx: ClientContext): void;
11
15
  //# sourceMappingURL=index.d.ts.map
@@ -16,7 +16,7 @@
16
16
  import { type ReactNode } from 'react';
17
17
  import type { ClientParamField } from './generated-params.ts';
18
18
  import { type MessageKey } from './messages.ts';
19
- import type { ParamSectionSnapshot, ParamSectionSource, SettingsPathOpLike } from './seam.ts';
19
+ import type { ParamSectionSnapshot, ParamSectionSource, SettingsPathOpLike, SettingsSaveResult } from './seam.ts';
20
20
  /**
21
21
  * Injected face: plain data and callbacks, plus the hook seat.
22
22
  *
@@ -29,9 +29,13 @@ export interface ParamCardFace {
29
29
  namespace: string;
30
30
  fields: readonly ClientParamField[];
31
31
  t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
32
+ /** Current UI language for generated labels; omitted defaults to zh. */
33
+ lang?: () => ParamLanguage;
32
34
  /** ONE call per save, carrying every dirty field as one op list (T5-01/A56). The returned boolean IS
33
35
  * the Host's verdict (contract C2/G5): `true` = accepted, `false` = refused after its recovery read. */
34
36
  mutateOnce: (ops: readonly SettingsParamOp[]) => Promise<boolean>;
37
+ /** Structured write result; when present the card distinguishes acceptance from readback. */
38
+ saveOnce?: (ops: readonly SettingsParamOp[]) => Promise<SettingsSaveResult>;
35
39
  clear: (field: string) => Promise<boolean>;
36
40
  hooks: {
37
41
  paramSection: ParamSectionSource;
@@ -46,6 +50,8 @@ export type ParamCardProps = Omit<ParamCardFace, 'hooks'> & {
46
50
  /** Bound from \`hooks.paramSection\` by the renderer. */
47
51
  readonly useParamSection: <T>(selector: (state: ParamSectionSnapshot) => T) => T;
48
52
  };
53
+ /** Generated-copy language. */
54
+ export type ParamLanguage = 'zh' | 'en';
49
55
  /** The op list a save hands to the seat — the seam's own shape, never a second vocabulary. */
50
56
  export type SettingsParamOp = SettingsPathOpLike;
51
57
  /**
@@ -83,8 +89,11 @@ export interface ParamCardViewProps {
83
89
  namespace: string;
84
90
  fields: readonly ClientParamField[];
85
91
  t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
92
+ /** Current UI language for generated labels; omitted defaults to zh. */
93
+ lang?: () => ParamLanguage;
86
94
  /** ONE call per save, carrying every dirty field as one op list (T5-01/A56). */
87
95
  mutateOnce: (ops: readonly SettingsParamOp[]) => Promise<boolean>;
96
+ saveOnce?: (ops: readonly SettingsParamOp[]) => Promise<SettingsSaveResult>;
88
97
  /** Ask the scope to drop one override; resolves when the scope answered, not when it landed. */
89
98
  clear: (field: string) => Promise<boolean>;
90
99
  /** The current row state, from whichever source owns it (the bound hook or the page). */
@@ -96,12 +105,6 @@ export interface ParamCardViewProps {
96
105
  * @returns the card.
97
106
  */
98
107
  export declare function ParamCardView(props: ParamCardViewProps): ReactNode;
99
- /**
100
- * The card as our own section renders it: the row state comes from the hook seat the
101
- * renderer binds out of the inject face's `hooks` compartment (components never hold a
102
- * subscription of their own).
103
- * @param props - the card data, its callbacks, and the bound row hook.
104
- * @returns the card.
105
- */
108
+ export declare function PluginParamCard(props: ParamCardFace): ReactNode;
106
109
  export declare function ParamCard(props: ParamCardProps): ReactNode;
107
110
  //# sourceMappingURL=ParamCard.d.ts.map
@@ -12,6 +12,11 @@ export interface PendingRow {
12
12
  };
13
13
  readonly status: 'pending' | 'executing' | 'approved' | 'rejected';
14
14
  readonly claimedBy?: string | undefined;
15
+ /** Structured summary from the host; absent on older rows. */
16
+ readonly verb?: string | undefined;
17
+ readonly target?: string | undefined;
18
+ readonly operationCount?: number | undefined;
19
+ readonly actions?: readonly string[] | undefined;
15
20
  }
16
21
  /** One windowed hunk of a previewed change: the region the write would touch. */
17
22
  export interface PreviewHunk {
@@ -52,6 +57,8 @@ export interface ApprovalApi {
52
57
  approve: (id: string) => Promise<ApprovalAnswer<unknown>>;
53
58
  /** Close one staged write without replaying it. */
54
59
  reject: (id: string) => Promise<ApprovalAnswer<unknown>>;
60
+ /** Put an EXECUTING claim back into the pending window without replaying it. */
61
+ release: (id: string) => Promise<ApprovalAnswer<unknown>>;
55
62
  /** What that staged write would store, resolved by the host without running it. */
56
63
  preview: (id: string) => Promise<ApprovalAnswer<PreviewAnswer>>;
57
64
  }
@@ -5,7 +5,7 @@
5
5
  * description, so the settings surface can state both without a hand-written copy.
6
6
  */
7
7
  /** The family version this surface belongs to. */
8
- export declare const FAMILY_VERSION = "0.32.5";
8
+ export declare const FAMILY_VERSION = "0.33.0";
9
9
  /** What this surface is for, in one line. */
10
10
  export declare const PACKAGE_PURPOSE = "Web UI umbrella for the evolution family: settings and skill-history panels";
11
11
  //# sourceMappingURL=generated-about.d.ts.map
@@ -8,22 +8,34 @@
8
8
  export interface ClientParamField {
9
9
  id: string;
10
10
  group: string;
11
+ /** User-language group heading. */
12
+ groupLabel: string;
13
+ /** English group heading. */
14
+ groupLabelEn: string;
11
15
  /** U-4: the sibling id this field may not go below (an empty string when the row declares no relation). */
12
16
  atLeast: string;
13
17
  /** The registry summary (English), kept for parity with PARAMETERS.md. */
14
18
  doc: string;
15
19
  /** Card label, from the registry UI tail (Chinese). */
16
20
  label: string;
21
+ /** English card label (the registry UI tail is Chinese). */
22
+ labelEn: string;
17
23
  /** Card help text, from the registry UI tail (Chinese). */
18
24
  hint: string;
25
+ /** English help text. */
26
+ hintEn: string;
19
27
  /** Which control the card renders. */
20
28
  control: 'number' | 'switch' | 'select' | 'text';
21
29
  /** Unit suffix for a number field ('' when it carries none). */
22
30
  unit: string;
31
+ /** English unit suffix. */
32
+ unitEn: string;
23
33
  /** Allowed values for a select field ([] otherwise). */
24
34
  values: readonly string[];
25
35
  /** Display names for `values`, same order ([] shows the raw value). */
26
36
  valueLabels: readonly string[];
37
+ /** English display names for `values`, same order. */
38
+ valueLabelsEn: readonly string[];
27
39
  }
28
40
  /** One card: the settings namespace it writes through, the SEAT key its source is looked up by,
29
41
  * and the fields it exposes. A73 (`ClientParamSection.namespace` 一名字两义): the two roles are
@@ -37,15 +49,4 @@ export interface ClientParamSection {
37
49
  fields: readonly ClientParamField[];
38
50
  }
39
51
  export declare const CLIENT_PARAM_SECTIONS: readonly ClientParamSection[];
40
- /**
41
- * One bundle that mounts family rows: the plugins.row.config key of a row is
42
- * <bundle package name>#<row id>. The names are the SOURCE-plane spellings -
43
- * the release rescopes them with every other package literal.
44
- */
45
- export interface ClientRowSeat {
46
- bundle: string;
47
- rows: readonly string[];
48
- }
49
- /** Every (bundle, row) pair the Plugins page can open a configuration page for. */
50
- export declare const CLIENT_ROW_SEATS: readonly ClientRowSeat[];
51
52
  //# sourceMappingURL=generated-params.d.ts.map
@@ -1,29 +1,14 @@
1
1
  /**
2
- * Browser half: one settings section ("自进化") hosting one card per family row, plus the
3
- * Plugins page's per-row configuration entry for each of those rows.
2
+ * Browser half: parameter cards register on the platform's Plugins surface
3
+ * (`settings.plugin.item`); the family-owned `settings.section` is now only the
4
+ * diagnostics card. Pending decisions live in `evolution.workbench`.
4
5
  *
5
- * Until 0.7.0 the cards lived inside the platform's own 插件 section, because
6
- * this bundle injected `@deepseek-ai/dsh-client-ui-settings-plugins` and claimed
7
- * its keyed `settings.plugin.item` slot. The parameters are not a plugin
8
- * inventory though — the other feature areas (market, skins, Web plugins, side
9
- * cards) each register their OWN section, so this bundle does the same: inject
10
- * the settings shell, register `settings.section`, and host the cards in a keyed
11
- * child slot of that section.
6
+ * The join key is the row's ENTRY ID — the platform derives a settings namespace from
7
+ * the Loader entry id, and that id is the registry's owner name — so the card, the
8
+ * seat lookup and the page key all spell one id. The legacy namespace strings in the
9
+ * registry (`evolution-memory`, …) are the G3 migration source, never a live lookup key.
12
10
  *
13
- * Since G2 that section is one of TWO render sites for the same card body. The other is
14
- * the platform's Plugins page: each family row can be opened there, and the page renders
15
- * whatever a plugin registered under key `<bundle package name>#<row id>`
16
- * (`plugins.row.config`). The page owns that entry's subscription and hands the row's form
17
- * in, so that path needs no seat of ours; our own section binds the same card to the
18
- * client settings seat (`configForms`).
19
- *
20
- * The join key is the row's ENTRY ID — the platform derives a settings namespace from the
21
- * Loader entry id, and that id is the registry's owner name — so the card, the seat lookup
22
- * and the page key all spell one id. The legacy namespace strings in the registry
23
- * (`evolution-memory`, …) are the G3 migration source, never a live lookup key.
24
- *
25
- * A row the Host does not serve renders nothing, and a deployment that drops this row
26
- * shows no section at all: the pair carries no Host-side behaviour.
11
+ * A row the Host does not serve renders nothing.
27
12
  * @module @lmzhen/dsh-evolution-ui/panels/settings/client
28
13
  */
29
14
  import type { Context as ClientContext } from '@deepseek-ai/cordis';
@@ -14,6 +14,7 @@ export declare const NS = "evolution-settings";
14
14
  export declare const zh: {
15
15
  readonly title: "自进化";
16
16
  readonly subtitle: "待你决定的写入在最上面;下面按功能列出你能改的参数,没有列出的由安装时的配置决定。";
17
+ readonly aboutPurpose: "自进化设置与技能历史";
17
18
  readonly overridden: "已覆盖";
18
19
  readonly deployment: "默认";
19
20
  readonly loading: "正在读取设置…";
@@ -33,9 +34,14 @@ export declare const zh: {
33
34
  readonly invalidSelect: "不在允许的取值里";
34
35
  readonly invalidAtLeast: "不能小于同组的 {n}";
35
36
  readonly approvalConfirmNamed: "即将批准:{n}";
37
+ readonly approvalRawSummary: "原始摘要";
36
38
  readonly approvalConfirmYes: "确认批准";
37
39
  readonly approvalConfirmNo: "取消";
38
40
  readonly resetTo: "复位为 {value}";
41
+ readonly saved: "已保存。";
42
+ readonly saveReadbackFailed: "写入已被接受,但回读失败;点刷新重读后再确认。";
43
+ readonly saveConflict: "这个值没有被接受:设置已被其他页面修改。请重读后再保存。";
44
+ readonly resetDone: "已恢复默认值。";
39
45
  readonly refused: "这个值没有被接受(界面上保持原样)。想看原因:在对话里让它说明。";
40
46
  readonly resetRefused: "恢复默认值没有生效(这一行还是你的值)。想看原因:在对话里让它说明。";
41
47
  readonly cardReview: "会话回顾";
@@ -58,10 +64,22 @@ export declare const zh: {
58
64
  readonly approvalCount: "{n} 项待批";
59
65
  readonly approvalRunningCount: "{n} 项执行中";
60
66
  readonly approvalRefresh: "刷新";
61
- readonly approvalExecuting: "执行中:这条的写效果可能已经落地,不要重复批准;要清掉它请用拒绝。";
67
+ readonly approvalApproving: "批准中…";
68
+ readonly approvalRejecting: "拒绝中…";
69
+ readonly approvalExecuting: "执行中:写效果可能已经落地,不要重复批准。先核验效果,再用「放回待批」释放占用;释放不会停止或撤销在途写入。";
70
+ readonly approvalRelease: "放回待批";
71
+ readonly approvalReleasing: "释放中…";
62
72
  readonly approvalKindMemory: "记忆";
63
73
  readonly approvalKindSkill: "技能";
64
74
  readonly approvalKindCapability: "能力";
75
+ readonly approvalVerbAdd: "新增";
76
+ readonly approvalVerbCreate: "创建";
77
+ readonly approvalVerbUpdate: "更新";
78
+ readonly approvalVerbRemove: "移除";
79
+ readonly approvalVerbDelete: "删除";
80
+ readonly approvalVerbArchive: "归档";
81
+ readonly approvalVerbRestore: "恢复";
82
+ readonly approvalVerbMerge: "合并";
65
83
  readonly approvalAgeNow: "刚刚";
66
84
  readonly approvalAgeMinutes: "{n} 分钟前";
67
85
  readonly approvalAgeHours: "{n} 小时前";
@@ -71,6 +89,7 @@ export declare const zh: {
71
89
  readonly approvalPreviewClose: "收起";
72
90
  readonly approvalPreviewReading: "正在读取预览…";
73
91
  readonly approvalPreviewNone: "看不了预览:";
92
+ readonly approvalPreviewPath: "文件:{path}";
74
93
  readonly approvalDiffAdded: "{n} 行新增";
75
94
  readonly approvalDiffRemoved: "{n} 行删除";
76
95
  readonly approvalDiffCut: "改动区域已截断";
@@ -109,7 +128,7 @@ export type MessageKey = keyof typeof zh;
109
128
  /**
110
129
  * Resolve one message without the locale seat (tests and the fallback path).
111
130
  * @param key - the message key.
112
- * @param language - which dictionary to read; defaults to English (the platform FALLBACK_LOCALE).
131
+ * @param language - which dictionary to read; defaults to zh, matching the platform FALLBACK_LOCALE.
113
132
  * @returns the copy this bundle carries.
114
133
  */
115
134
  export declare function message(key: MessageKey, language?: 'zh' | 'en'): string;
@@ -41,6 +41,8 @@ export interface PendingState {
41
41
  readonly view: PendingView;
42
42
  readonly busy: readonly string[];
43
43
  readonly notice: string | null;
44
+ /** A background re-read is in flight; the previous rows stay on screen. */
45
+ readonly refreshing: boolean;
44
46
  /** The row whose preview is open, or null. One at a time: a preview is a thing being read. */
45
47
  readonly open: string | null;
46
48
  readonly preview: PreviewView | null;
@@ -5,28 +5,14 @@
5
5
  * seams it consumes instead of importing another plugin's values (forbidden by the
6
6
  * client bundle-purity rule) or its types (which would drag the platform sources
7
7
  * into this project). The shapes are the shell's contract: a `settings.section`
8
- * registration hosting a keyed card slot, the keyed `plugins.row.config` seat the
9
- * Plugins page opens per row, the client settings seat (`configForms`, one form per
10
- * Host plugin entry id), and the locale seat the section's copy resolves through.
8
+ * registration hosting a keyed card slot, the client settings seat (`configForms`,
9
+ * one form per Host plugin entry id), and the locale seat the section's copy resolves through.
11
10
  * @module @lmzhen/dsh-evolution-ui/panels/settings/client
12
11
  */
13
12
  import type { ReactNode } from 'react';
14
13
  import type { ConfigFormLike as KitConfigFormLike, ConfigFormSnapshotLike as KitConfigFormSnapshotLike, ConfigPathOpLike } from '@lmzhen/dsh-evolution-client-kit';
15
14
  /** Our card slot, hosted by the section this bundle registers. */
16
15
  export declare const CARD_SLOT = "evolution.namespace.card";
17
- /** The Plugins page's per-row configuration seat (declared by `ui-plugin-manager`). */
18
- export declare const ROW_CONFIG_SLOT = "plugins.row.config";
19
- /**
20
- * The key the Plugins page files a row's configuration under.
21
- *
22
- * Spelled here because the page's own helper cannot be imported (a value import from
23
- * another plugin's client half is forbidden):
24
- * `ui-plugin-manager`'s config-ledger module is the definition this mirrors.
25
- * @param bundle - the bundle package name that declares the row.
26
- * @param rowId - the row id that bundle's patch declares.
27
- * @returns the `plugins.row.config` key.
28
- */
29
- export declare function rowConfigKey(bundle: string, rowId: string): string;
30
16
  /**
31
17
  * The pending-window card's slot key.
32
18
  *
@@ -38,6 +24,13 @@ export declare function rowConfigKey(bundle: string, rowId: string): string;
38
24
  export declare const PENDING_CARD_KEY = "approval-pending";
39
25
  /** The diagnostics card's slot key: read-only, no settings namespace (its data comes from HOST_ROUTES.diagnostics). */
40
26
  export declare const DIAGNOSTICS_CARD_KEY = "diagnostics";
27
+ /** Structured result of one settings write, separating acceptance from readback. */
28
+ export interface SettingsSaveResult {
29
+ readonly written: boolean;
30
+ readonly readback: 'ok' | 'failed';
31
+ readonly kind?: 'conflict' | 'transport' | 'validation';
32
+ readonly failure?: unknown;
33
+ }
41
34
  /** Snapshot of one settings row, as the client seat reports it. */
42
35
  export interface ParamSectionSnapshot {
43
36
  status: 'loading' | 'ready' | 'unavailable';
@@ -82,7 +75,7 @@ export type ConfigFormLike<T = Record<string, unknown>> = KitConfigFormLike<T>;
82
75
  */
83
76
  export interface ConfigFormsSeat {
84
77
  /** One Host plugin entry id to its form. */
85
- get<T>(entryId: string): ConfigFormLike<T>;
78
+ get<T>(entryId: string): ConfigFormLike<T> | undefined;
86
79
  }
87
80
  /** Registration options the keyed card slot under our own section takes. */
88
81
  export interface SlotRegisterOptions {
@@ -91,11 +84,21 @@ export interface SlotRegisterOptions {
91
84
  key: string;
92
85
  inject: () => unknown;
93
86
  }
94
- /** Registration options the Plugins page's per-row config seat takes. */
95
- export interface RowSeatRegisterOptions {
96
- name: typeof ROW_CONFIG_SLOT;
97
- /** `<bundle package name>#<row id>`, as the page's ledger builds it. */
98
- key: string;
87
+ /** Registration options the platform's Plugins list takes for one parameter card. */
88
+ export interface PluginItemRegisterOptions {
89
+ name: 'settings.plugin.item';
90
+ id: string;
91
+ order: number;
92
+ locale: string;
93
+ inject: () => unknown;
94
+ }
95
+ /** Options a `settings.plugins.tab` contribution carries (rc.3 plugin settings page). */
96
+ export interface PluginsTabRegisterOptions {
97
+ name: 'settings.plugins.tab';
98
+ id: string;
99
+ order: number;
100
+ label: () => string;
101
+ locale: string;
99
102
  inject: () => unknown;
100
103
  }
101
104
  /** Options a `settings.section` registration carries (the shell's own shape). */
@@ -125,10 +128,8 @@ export interface SectionFace {
125
128
  renderSlot: (name: string, props?: Record<string, unknown>, filter?: Record<string, unknown>) => ReactNode;
126
129
  }
127
130
  /**
128
- * The values and commands the Plugins page passes to a `plugins.row.config` entry:
129
- * the page owns the subscription (it re-renders the entry), so the entry renders from
130
- * `state` and writes through `mutate`. Both views receive this face; `summary` uses it
131
- * only to say whether anything is overridden.
131
+ * The face the test helper uses to render a parameter card with a page-owned form:
132
+ * the helper renders from `state` and writes through `mutate`.
132
133
  */
133
134
  export interface RowConfigViewProps {
134
135
  /** `summary` is the row's one-line description fallback; `page` is the whole form. */
@@ -153,7 +154,7 @@ export interface LocaleSeat {
153
154
  export interface ClientSeam {
154
155
  slots: {
155
156
  inject(name: string, callback: () => Generator<unknown, void, unknown>): unknown;
156
- register(options: SlotRegisterOptions | RowSeatRegisterOptions | SectionRegisterOptions, component: (props: never) => unknown): () => void;
157
+ register(options: SlotRegisterOptions | PluginItemRegisterOptions | PluginsTabRegisterOptions | SectionRegisterOptions, component: (props: never) => unknown): () => void;
157
158
  };
158
159
  locale: LocaleSeat;
159
160
  }
@@ -22,7 +22,7 @@
22
22
  * apply time would capture `undefined` for the whole life of the fiber.
23
23
  * @module @lmzhen/dsh-evolution-ui/panels/settings/client
24
24
  */
25
- import type { ConfigFormLike, ConfigFormSnapshotLike, ConfigFormsSeat, ParamSectionSnapshot, ParamSectionSource, SettingsPathOpLike } from './seam.ts';
25
+ import type { ConfigFormLike, ConfigFormSnapshotLike, ConfigFormsSeat, ParamSectionSnapshot, ParamSectionSource, SettingsPathOpLike, SettingsSaveResult } from './seam.ts';
26
26
  /** What a card shows when this UI found no settings seat at all. */
27
27
  export declare const SEAT_MISSING: ParamSectionSnapshot;
28
28
  /** What a card shows when the seat served the row but projecting it failed. A frozen constant
@@ -67,6 +67,7 @@ export declare function sourceFor(probe: SeatProbe, namespace: string): ParamSec
67
67
  */
68
68
  export declare function writeFaceFor(probe: SeatProbe, namespace: string): {
69
69
  mutateOnce: (ops: readonly SettingsPathOpLike[]) => Promise<boolean>;
70
+ saveOnce: (ops: readonly SettingsPathOpLike[]) => Promise<SettingsSaveResult>;
70
71
  clear: (field: string) => Promise<boolean>;
71
72
  };
72
73
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-ui",
3
3
  "description": "Web UI umbrella for the evolution family: settings and skill-history panels (community build)",
4
- "version": "0.32.5",
4
+ "version": "0.33.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -45,9 +45,9 @@
45
45
  "react": "^18.2.0"
46
46
  },
47
47
  "dependencies": {
48
- "@lmzhen/dsh-evolution-client-kit": "^0.32.5",
49
- "@lmzhen/dsh-evolution-core": "^0.32.5",
50
- "@lmzhen/dsh-evolution-curator": "^0.32.5"
48
+ "@lmzhen/dsh-evolution-client-kit": "^0.33.0",
49
+ "@lmzhen/dsh-evolution-core": "^0.33.0",
50
+ "@lmzhen/dsh-evolution-curator": "^0.33.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/react": "~18.3.1",
@@ -1,30 +0,0 @@
1
- /**
2
- * The Plugins page's per-row configuration entry for a family row.
3
- *
4
- * The page owns the settings subscription — it re-renders the entry — and passes the row's
5
- * form in, so this component renders the SAME card body as our own section, fed by the
6
- * page's state instead of the bound hook and therefore holding no subscription of its own.
7
- * `summary` answers the page's one-line slot: a row's description fallback, which stays
8
- * empty until the row actually overrides something, exactly as the page expects.
9
- * @module @lmzhen/dsh-evolution-ui/panels/settings/client
10
- */
11
- import { type ReactNode } from 'react';
12
- import type { ClientParamField } from './generated-params.ts';
13
- import type { MessageKey } from './messages.ts';
14
- import type { RowConfigViewProps } from './seam.ts';
15
- /** The inject face every row registration carries (the page supplies `view` and `form`). */
16
- export interface RowConfigFace {
17
- /** The row's entry id, for the card title. */
18
- namespace: string;
19
- fields: readonly ClientParamField[];
20
- t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
21
- }
22
- /** Props one row entry is rendered with: the page's seat plus this row's own face. */
23
- export type RowConfigCardProps = RowConfigViewProps & RowConfigFace;
24
- /**
25
- * Render one row's configuration entry.
26
- * @param props - the page's view/form seat plus this row's face.
27
- * @returns the entry; `summary` renders nothing for an untouched row (the page then keeps the row's own description).
28
- */
29
- export declare function RowConfigCard(props: RowConfigCardProps): ReactNode;
30
- //# sourceMappingURL=RowConfigCard.d.ts.map