@deepseek-harness-tui/dsh-tui 0.7.2 → 0.8.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.
- package/README.md +3 -3
- package/bin/dsh-tui.js +24 -3
- package/cordis.patch.yml +24 -11
- package/cordis.yml +9 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +2 -1
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/GoalTodoPanel.js +6 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +5 -1
- package/lib/types/components/MessageList.d.ts +3 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +9 -5
- package/lib/types/components/PluginSceneBoundary.d.ts +31 -0
- package/lib/types/components/PluginSceneBoundary.d.ts.map +1 -0
- package/lib/types/components/PluginSceneBoundary.js +29 -0
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +52 -74
- package/lib/types/components/SearchBox.d.ts +4 -0
- package/lib/types/components/SearchBox.d.ts.map +1 -1
- package/lib/types/components/SearchBox.js +101 -2
- package/lib/types/components/SkillsPicker.d.ts +18 -0
- package/lib/types/components/SkillsPicker.d.ts.map +1 -0
- package/lib/types/components/SkillsPicker.js +50 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +4 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts.map +1 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +10 -5
- package/lib/types/components/SplitDiffView.d.ts +28 -0
- package/lib/types/components/SplitDiffView.d.ts.map +1 -0
- package/lib/types/components/SplitDiffView.js +417 -0
- package/lib/types/components/WorkingSpinner.d.ts +3 -1
- package/lib/types/components/WorkingSpinner.d.ts.map +1 -1
- package/lib/types/components/WorkingSpinner.js +2 -2
- package/lib/types/components/design-system/ThemedText.d.ts +7 -1
- package/lib/types/components/design-system/ThemedText.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemedText.js +2 -2
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +3 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +17 -7
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +52 -8
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +12 -3
- package/lib/types/dsh-adapter/channel.d.ts +78 -0
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +165 -14
- package/lib/types/dsh-adapter/contract.d.ts +1 -1
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +1 -0
- package/lib/types/dsh-adapter/index.d.ts +4 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +1 -0
- package/lib/types/dsh-adapter/packaged-presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/packaged-presets.js +5 -2
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +66 -3
- package/lib/types/dsh-adapter/promptDebug.d.ts +10 -0
- package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -0
- package/lib/types/dsh-adapter/promptDebug.js +148 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/providerWizard.js +3 -1
- package/lib/types/dsh-adapter/scenes.d.ts +75 -0
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -0
- package/lib/types/dsh-adapter/scenes.js +78 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts +116 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -0
- package/lib/types/dsh-adapter/settings-sections.js +63 -0
- package/lib/types/dsh-adapter/settingsEditor.d.ts +128 -0
- package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -0
- package/lib/types/dsh-adapter/settingsEditor.js +244 -0
- package/lib/types/i18n.d.ts +169 -18
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +45 -6
- package/lib/types/ink/components/Text.d.ts +9 -1
- package/lib/types/ink/components/Text.d.ts.map +1 -1
- package/lib/types/ink/components/Text.js +7 -6
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +4 -2
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +76 -9
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +4 -1
- package/lib/types/ink/terminal.d.ts +40 -4
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +57 -5
- package/lib/types/ink/termio/tokenize.d.ts +6 -0
- package/lib/types/ink/termio/tokenize.d.ts.map +1 -1
- package/lib/types/ink/termio/tokenize.js +18 -4
- package/lib/types/jsx-runtime.d.ts +2 -0
- package/lib/types/jsx-runtime.d.ts.map +1 -0
- package/lib/types/jsx-runtime.js +13 -0
- package/lib/types/modelRoute.d.ts +10 -2
- package/lib/types/modelRoute.d.ts.map +1 -1
- package/lib/types/modelRoute.js +33 -4
- package/lib/types/scenes.d.ts +3 -0
- package/lib/types/scenes.d.ts.map +1 -0
- package/lib/types/scenes.js +4 -0
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +182 -26
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +30 -15
- package/lib/types/screens/Settings.d.ts +20 -0
- package/lib/types/screens/Settings.d.ts.map +1 -0
- package/lib/types/screens/Settings.js +333 -0
- package/lib/types/screens/StatusLine.js +1 -1
- package/lib/types/sessions/view.d.ts.map +1 -1
- package/lib/types/sessions/view.js +13 -1
- package/lib/types/settings-sections.d.ts +3 -0
- package/lib/types/settings-sections.d.ts.map +1 -0
- package/lib/types/settings-sections.js +4 -0
- package/lib/types/theme.d.ts +12 -0
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +36 -0
- package/lib/types/update.d.ts +21 -7
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +66 -16
- package/lib/types/utils/paths.d.ts.map +1 -1
- package/lib/types/utils/paths.js +4 -1
- package/package.json +49 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerWizard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/providerWizard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAAoC,CAAA;AAElE,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,2EAIrB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,mEAAmE;AACnE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,oBAAoB,IAAI,SAAS,wBAAwB,EAAE,CAAA;IAC3D,kEAAkE;IAClE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IACnC,sEAAsE;IACtE,cAAc,CAAC,OAAO,EAAE;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,GAAG,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAA;IAC1C,0EAA0E;IAC1E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC;;;;OAIG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACxD,2EAA2E;IAC3E,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjE,yDAAyD;IACzD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7E;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,CACZ,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KACtE,IAAI,CAAA;IACT,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAA;IACrE,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAA;AAgDpE;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"providerWizard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/providerWizard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAAoC,CAAA;AAElE,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,2EAIrB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,mEAAmE;AACnE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,oBAAoB,IAAI,SAAS,wBAAwB,EAAE,CAAA;IAC3D,kEAAkE;IAClE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IACnC,sEAAsE;IACtE,cAAc,CAAC,OAAO,EAAE;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,GAAG,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAA;IAC1C,0EAA0E;IAC1E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC;;;;OAIG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACxD,2EAA2E;IAC3E,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjE,yDAAyD;IACzD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7E;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,CACZ,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KACtE,IAAI,CAAA;IACT,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAA;IACrE,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAA;AAgDpE;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,qBAAqB,CAAC,CA8MhC"}
|
|
@@ -86,7 +86,9 @@ export async function runProviderWizard(deps) {
|
|
|
86
86
|
questions: [optionQuestion('catalog', t('provider-q-catalog'), [
|
|
87
87
|
...candidates.map(candidate => ({
|
|
88
88
|
label: candidate.provider,
|
|
89
|
-
description: candidate.displayName
|
|
89
|
+
description: candidate.displayName === candidate.provider
|
|
90
|
+
? undefined
|
|
91
|
+
: candidate.displayName,
|
|
90
92
|
})),
|
|
91
93
|
{ label: otherLabel, description: t('provider-opt-other-route-desc') },
|
|
92
94
|
], { hideCustomInput: true })],
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** Provider-neutral full-screen scene registry for terminal front doors. */
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import { Context, Service } from '@deepseek-ai/cordis';
|
|
4
|
+
import type { Channel } from './channel.js';
|
|
5
|
+
/**
|
|
6
|
+
* Props every plugin scene receives. Both element creation and hooks must go
|
|
7
|
+
* through the HOST's React, never the plugin's own copy:
|
|
8
|
+
*
|
|
9
|
+
* - Hooks: a component rendered by this TUI's reconciler but calling hooks
|
|
10
|
+
* imported from a second React copy (the plugin's own node_modules) dies
|
|
11
|
+
* with an invalid-hook-call on first render. Use the injected `React`.
|
|
12
|
+
* - Elements: this app's reconciler (React 19) accepts only
|
|
13
|
+
* `Symbol.for('react.transitional.element')` elements. JSX compiled
|
|
14
|
+
* against a plugin-bundled older React emits `Symbol.for('react.element')`
|
|
15
|
+
* and throws on first render. Create elements with the injected `React`
|
|
16
|
+
* (`React.createElement`/`React.Fragment`), or compile JSX against the
|
|
17
|
+
* host runtime via tsconfig
|
|
18
|
+
* `"jsxImportSource": "@deepseek-harness-tui/dsh-tui"` (its `./jsx-runtime`
|
|
19
|
+
* subpath re-exports this app's own react/jsx-runtime). A plugin-owned
|
|
20
|
+
* React copy works ONLY if it is the same React 19 line — and its hooks
|
|
21
|
+
* remain off-limits regardless.
|
|
22
|
+
*/
|
|
23
|
+
export interface TuiSceneProps {
|
|
24
|
+
/** The TUI's React instance — use THIS for every hook and element. */
|
|
25
|
+
React: typeof React;
|
|
26
|
+
/** The TUI's ui kit (Box/Text/useInput/useTerminalSize/…). */
|
|
27
|
+
ui: typeof import('../ui.js');
|
|
28
|
+
/** Live session channel: rows, status, trace events, notifications. */
|
|
29
|
+
channel: Channel;
|
|
30
|
+
/** Leave the scene and return to whatever screen was up before. */
|
|
31
|
+
close(): void;
|
|
32
|
+
}
|
|
33
|
+
export interface TuiSceneDescriptor {
|
|
34
|
+
/** Unique scene id (kebab-case); the plugin's own commands open it by id. */
|
|
35
|
+
id: string;
|
|
36
|
+
/** Optional human label for logs/debugging; the scene renders its own header. */
|
|
37
|
+
title?: string;
|
|
38
|
+
component: React.ComponentType<TuiSceneProps>;
|
|
39
|
+
}
|
|
40
|
+
declare module '@deepseek-ai/cordis' {
|
|
41
|
+
interface Context {
|
|
42
|
+
tuiScenes: TuiSceneRuntime;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export declare const name = "dsh-tui-scenes";
|
|
46
|
+
/**
|
|
47
|
+
* Small host-only registry; command execution remains owned by dsh-commands.
|
|
48
|
+
*
|
|
49
|
+
* A plugin registers a scene once (`ctx.tuiScenes.register(...)`, keep the
|
|
50
|
+
* dispose) and opens it from anywhere host-side — typically its own
|
|
51
|
+
* dsh-commands handler: `ctx.tuiScenes.open('my-scene')` plus a silent
|
|
52
|
+
* `success` result, so the conversation stays untouched while the scene
|
|
53
|
+
* takes the whole terminal the way the trajectory scene does.
|
|
54
|
+
*/
|
|
55
|
+
export declare class TuiSceneRuntime extends Service {
|
|
56
|
+
private readonly scenes;
|
|
57
|
+
private readonly listeners;
|
|
58
|
+
private current;
|
|
59
|
+
constructor(ctx: Context);
|
|
60
|
+
register(descriptor: TuiSceneDescriptor): () => void;
|
|
61
|
+
/**
|
|
62
|
+
* Swap the conversation for the named scene. Returns false (and warns)
|
|
63
|
+
* when no plugin registered that id — a mistyped id must fail visibly in
|
|
64
|
+
* the log, not silently do nothing in the UI.
|
|
65
|
+
*/
|
|
66
|
+
open(id: string): boolean;
|
|
67
|
+
close(): void;
|
|
68
|
+
/** The scene currently replacing the conversation, if any. */
|
|
69
|
+
get active(): TuiSceneDescriptor | undefined;
|
|
70
|
+
/** UI-side change feed: fired after every open/close/dispose transition. */
|
|
71
|
+
subscribe(listener: () => void): () => void;
|
|
72
|
+
private notify;
|
|
73
|
+
}
|
|
74
|
+
export default TuiSceneRuntime;
|
|
75
|
+
//# sourceMappingURL=scenes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/scenes.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,8DAA8D;IAC9D,EAAE,EAAE,cAAc,UAAU,CAAC,CAAA;IAC7B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAChB,mEAAmE;IACnE,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAA;IACV,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC,CAAA;CAC9C;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,SAAS,EAAE,eAAe,CAAA;KAC3B;CACF;AAED,eAAO,MAAM,IAAI,mBAAmB,CAAA;AAEpC;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,OAAO;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,OAAO,CAAgC;gBAEnC,GAAG,EAAE,OAAO;IAIxB,QAAQ,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAiBpD;;;;OAIG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYzB,KAAK,IAAI,IAAI;IAMb,8DAA8D;IAC9D,IAAI,MAAM,IAAI,kBAAkB,GAAG,SAAS,CAE3C;IAED,4EAA4E;IAC5E,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C,OAAO,CAAC,MAAM;CAGf;AAED,eAAe,eAAe,CAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** Provider-neutral full-screen scene registry for terminal front doors. */
|
|
2
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
3
|
+
export const name = 'dsh-tui-scenes';
|
|
4
|
+
/**
|
|
5
|
+
* Small host-only registry; command execution remains owned by dsh-commands.
|
|
6
|
+
*
|
|
7
|
+
* A plugin registers a scene once (`ctx.tuiScenes.register(...)`, keep the
|
|
8
|
+
* dispose) and opens it from anywhere host-side — typically its own
|
|
9
|
+
* dsh-commands handler: `ctx.tuiScenes.open('my-scene')` plus a silent
|
|
10
|
+
* `success` result, so the conversation stays untouched while the scene
|
|
11
|
+
* takes the whole terminal the way the trajectory scene does.
|
|
12
|
+
*/
|
|
13
|
+
export class TuiSceneRuntime extends Service {
|
|
14
|
+
scenes = new Map();
|
|
15
|
+
listeners = new Set();
|
|
16
|
+
current;
|
|
17
|
+
constructor(ctx) {
|
|
18
|
+
super(ctx, 'tuiScenes');
|
|
19
|
+
}
|
|
20
|
+
register(descriptor) {
|
|
21
|
+
const id = descriptor.id.trim().toLowerCase();
|
|
22
|
+
if (!/^[a-z][a-z0-9_-]*$/u.test(id))
|
|
23
|
+
throw new TypeError(`invalid TUI scene id: ${descriptor.id}`);
|
|
24
|
+
if (this.scenes.has(id))
|
|
25
|
+
throw new Error(`TUI scene "${id}" is already registered`);
|
|
26
|
+
const normalized = { ...descriptor, id };
|
|
27
|
+
this.scenes.set(id, normalized);
|
|
28
|
+
return () => {
|
|
29
|
+
if (this.scenes.get(id) !== normalized)
|
|
30
|
+
return;
|
|
31
|
+
this.scenes.delete(id);
|
|
32
|
+
// Disposing the open scene must not strand the user on a dead screen.
|
|
33
|
+
if (this.current === normalized) {
|
|
34
|
+
this.current = undefined;
|
|
35
|
+
this.notify();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Swap the conversation for the named scene. Returns false (and warns)
|
|
41
|
+
* when no plugin registered that id — a mistyped id must fail visibly in
|
|
42
|
+
* the log, not silently do nothing in the UI.
|
|
43
|
+
*/
|
|
44
|
+
open(id) {
|
|
45
|
+
const scene = this.scenes.get(id.trim().toLowerCase());
|
|
46
|
+
if (scene === undefined) {
|
|
47
|
+
this.ctx.logger.warn(`dsh-tui: no TUI scene registered as "${id}"`);
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
if (scene === this.current)
|
|
51
|
+
return true;
|
|
52
|
+
this.current = scene;
|
|
53
|
+
this.notify();
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
close() {
|
|
57
|
+
if (this.current === undefined)
|
|
58
|
+
return;
|
|
59
|
+
this.current = undefined;
|
|
60
|
+
this.notify();
|
|
61
|
+
}
|
|
62
|
+
/** The scene currently replacing the conversation, if any. */
|
|
63
|
+
get active() {
|
|
64
|
+
return this.current;
|
|
65
|
+
}
|
|
66
|
+
/** UI-side change feed: fired after every open/close/dispose transition. */
|
|
67
|
+
subscribe(listener) {
|
|
68
|
+
this.listeners.add(listener);
|
|
69
|
+
return () => {
|
|
70
|
+
this.listeners.delete(listener);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
notify() {
|
|
74
|
+
for (const listener of this.listeners)
|
|
75
|
+
listener();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export default TuiSceneRuntime;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin settings-section extension seam for terminal front doors.
|
|
3
|
+
*
|
|
4
|
+
* The TUI owns the settings screen: rendering, staged editing, and the
|
|
5
|
+
* revision-fenced `settings.mutate` writes. Optional plugins declare WHAT is
|
|
6
|
+
* editable — a section over their settings namespace — without coupling the
|
|
7
|
+
* TUI to them, mirroring the web front door's `settings.plugin.item` slot
|
|
8
|
+
* (plugins ship cards; the host ships the chrome). Storage, validation and
|
|
9
|
+
* layering stay with the dsh settings service; this registry is display
|
|
10
|
+
* metadata only.
|
|
11
|
+
*/
|
|
12
|
+
import { Context, Service } from '@deepseek-ai/cordis';
|
|
13
|
+
import type { LocalizedDescriptions } from '../commands.js';
|
|
14
|
+
/** Control kinds the TUI settings screen knows how to render. */
|
|
15
|
+
export type TuiSettingsFieldKind = 'text' | 'number' | 'boolean' | 'select';
|
|
16
|
+
export interface TuiSettingsFieldOption {
|
|
17
|
+
/** Stored value. */
|
|
18
|
+
value: string;
|
|
19
|
+
/** Display label (English; also the fallback). */
|
|
20
|
+
label: string;
|
|
21
|
+
/** Provider-owned translations for the label. */
|
|
22
|
+
descriptions?: LocalizedDescriptions;
|
|
23
|
+
}
|
|
24
|
+
/** The write one field's draft stages when the section is saved. */
|
|
25
|
+
export type TuiSettingsFieldWrite = {
|
|
26
|
+
kind: 'set';
|
|
27
|
+
value: unknown;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'clear';
|
|
30
|
+
};
|
|
31
|
+
export interface TuiSettingsField {
|
|
32
|
+
/**
|
|
33
|
+
* Key path from the section root, in the settings service's `mutate` path
|
|
34
|
+
* vocabulary (object keys; dict keys name their entry directly).
|
|
35
|
+
*/
|
|
36
|
+
path: readonly string[];
|
|
37
|
+
/** Short field label (English; also the fallback). */
|
|
38
|
+
label: string;
|
|
39
|
+
/** Provider-owned translations for the label. */
|
|
40
|
+
descriptions?: LocalizedDescriptions;
|
|
41
|
+
/** Optional one-line help rendered under the field. */
|
|
42
|
+
hint?: string;
|
|
43
|
+
/** Provider-owned translations for the hint. */
|
|
44
|
+
hintDescriptions?: LocalizedDescriptions;
|
|
45
|
+
kind: TuiSettingsFieldKind;
|
|
46
|
+
/** Choices for `kind: 'select'` (ignored otherwise). */
|
|
47
|
+
options?: readonly TuiSettingsFieldOption[];
|
|
48
|
+
/** Input placeholder for `kind: 'text' | 'number'`. */
|
|
49
|
+
placeholder?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Credential control (mirrors the web cards' CardSecretSpec): the literal
|
|
52
|
+
* never rides the settings document — the draft starts blank on every
|
|
53
|
+
* open, a blank draft writes nothing, and a typed draft writes through the
|
|
54
|
+
* credentials seam under `ref`. The screen shows only whether a value is
|
|
55
|
+
* configured.
|
|
56
|
+
*/
|
|
57
|
+
secret?: {
|
|
58
|
+
ref: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Render a stored value as draft text. Defaults to the kind's conversion
|
|
62
|
+
* (strings verbatim, numbers via `String`, booleans/selects by value).
|
|
63
|
+
*/
|
|
64
|
+
format?(value: unknown): string;
|
|
65
|
+
/**
|
|
66
|
+
* The write this draft text stages, or `undefined` when the text is not a
|
|
67
|
+
* value this field accepts — an invalid draft blocks the save rather than
|
|
68
|
+
* being discarded. Defaults to the kind's conversion (an empty text/number
|
|
69
|
+
* draft stages a clear, letting the field re-inherit the composition
|
|
70
|
+
* layer).
|
|
71
|
+
*/
|
|
72
|
+
parse?(text: string): TuiSettingsFieldWrite | undefined;
|
|
73
|
+
}
|
|
74
|
+
/** One plugin's section inside the TUI settings screen. */
|
|
75
|
+
export interface TuiSettingsSection {
|
|
76
|
+
/**
|
|
77
|
+
* Settings namespace this section edits. Should match a namespace the
|
|
78
|
+
* plugin registers on the dsh settings service; the screen marks the
|
|
79
|
+
* section unavailable when the composition serves no such namespace.
|
|
80
|
+
*/
|
|
81
|
+
ns: string;
|
|
82
|
+
/** Section title (English; also the fallback). */
|
|
83
|
+
title: string;
|
|
84
|
+
/** Provider-owned translations for the title. */
|
|
85
|
+
descriptions?: LocalizedDescriptions;
|
|
86
|
+
/** Editable fields, in display order. */
|
|
87
|
+
fields: readonly TuiSettingsField[];
|
|
88
|
+
}
|
|
89
|
+
declare module '@deepseek-ai/cordis' {
|
|
90
|
+
interface Context {
|
|
91
|
+
tuiSettingsSections: TuiSettingsSectionsRuntime;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export declare const name = "dsh-tui-settings-sections";
|
|
95
|
+
/**
|
|
96
|
+
* Small host-only registry; settings storage and validation remain owned by
|
|
97
|
+
* the dsh settings service (`ctx.settings`).
|
|
98
|
+
*/
|
|
99
|
+
export declare class TuiSettingsSectionsRuntime extends Service {
|
|
100
|
+
private readonly sections;
|
|
101
|
+
private readonly listeners;
|
|
102
|
+
constructor(ctx: Context);
|
|
103
|
+
register(section: TuiSettingsSection): () => void;
|
|
104
|
+
/** Registered sections in registration order. */
|
|
105
|
+
list(): readonly TuiSettingsSection[];
|
|
106
|
+
/** The section registered for a namespace, if any. */
|
|
107
|
+
section(ns: string): TuiSettingsSection | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Subscribe to register/unregister events so an open settings screen can
|
|
110
|
+
* re-read the section list (a plugin (un)loading mid-session changes it).
|
|
111
|
+
*/
|
|
112
|
+
subscribe(listener: () => void): () => void;
|
|
113
|
+
private emit;
|
|
114
|
+
}
|
|
115
|
+
export default TuiSettingsSectionsRuntime;
|
|
116
|
+
//# sourceMappingURL=settings-sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/settings-sections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAE3D,iEAAiE;AACjE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3E,MAAM,WAAW,sBAAsB;IACrC,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,CAAA;CACrC;AAED,oEAAoE;AACpE,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAErB,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,qBAAqB,CAAA;IACxC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,wDAAwD;IACxD,OAAO,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC3C,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACxB;;;OAGG;IACH,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAA;IAC/B;;;;;;OAMG;IACH,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAA;CACxD;AAED,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,yCAAyC;IACzC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACpC;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,mBAAmB,EAAE,0BAA0B,CAAA;KAChD;CACF;AAED,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAE/C;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,OAAO;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;gBAEtC,GAAG,EAAE,OAAO;IAIxB,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI;IAejD,iDAAiD;IACjD,IAAI,IAAI,SAAS,kBAAkB,EAAE;IAIrC,sDAAsD;IACtD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAInD;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C,OAAO,CAAC,IAAI;CAGb;AAED,eAAe,0BAA0B,CAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin settings-section extension seam for terminal front doors.
|
|
3
|
+
*
|
|
4
|
+
* The TUI owns the settings screen: rendering, staged editing, and the
|
|
5
|
+
* revision-fenced `settings.mutate` writes. Optional plugins declare WHAT is
|
|
6
|
+
* editable — a section over their settings namespace — without coupling the
|
|
7
|
+
* TUI to them, mirroring the web front door's `settings.plugin.item` slot
|
|
8
|
+
* (plugins ship cards; the host ships the chrome). Storage, validation and
|
|
9
|
+
* layering stay with the dsh settings service; this registry is display
|
|
10
|
+
* metadata only.
|
|
11
|
+
*/
|
|
12
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
13
|
+
export const name = 'dsh-tui-settings-sections';
|
|
14
|
+
/**
|
|
15
|
+
* Small host-only registry; settings storage and validation remain owned by
|
|
16
|
+
* the dsh settings service (`ctx.settings`).
|
|
17
|
+
*/
|
|
18
|
+
export class TuiSettingsSectionsRuntime extends Service {
|
|
19
|
+
sections = new Map();
|
|
20
|
+
listeners = new Set();
|
|
21
|
+
constructor(ctx) {
|
|
22
|
+
super(ctx, 'tuiSettingsSections');
|
|
23
|
+
}
|
|
24
|
+
register(section) {
|
|
25
|
+
const ns = section.ns.trim();
|
|
26
|
+
if (!/^[a-z][a-z0-9_-]*$/u.test(ns))
|
|
27
|
+
throw new TypeError(`invalid TUI settings-section namespace: ${section.ns}`);
|
|
28
|
+
if (this.sections.has(ns))
|
|
29
|
+
throw new Error(`TUI settings section "${ns}" is already registered`);
|
|
30
|
+
const normalized = { ...section, ns };
|
|
31
|
+
this.sections.set(ns, normalized);
|
|
32
|
+
this.emit();
|
|
33
|
+
return () => {
|
|
34
|
+
if (this.sections.get(ns) === normalized) {
|
|
35
|
+
this.sections.delete(ns);
|
|
36
|
+
this.emit();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Registered sections in registration order. */
|
|
41
|
+
list() {
|
|
42
|
+
return [...this.sections.values()];
|
|
43
|
+
}
|
|
44
|
+
/** The section registered for a namespace, if any. */
|
|
45
|
+
section(ns) {
|
|
46
|
+
return this.sections.get(ns.trim());
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Subscribe to register/unregister events so an open settings screen can
|
|
50
|
+
* re-read the section list (a plugin (un)loading mid-session changes it).
|
|
51
|
+
*/
|
|
52
|
+
subscribe(listener) {
|
|
53
|
+
this.listeners.add(listener);
|
|
54
|
+
return () => {
|
|
55
|
+
this.listeners.delete(listener);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
emit() {
|
|
59
|
+
for (const listener of this.listeners)
|
|
60
|
+
listener();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export default TuiSettingsSectionsRuntime;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React-free form model behind the `/settings` screen (issue #165), mirroring
|
|
3
|
+
* the web front door's card-form.ts semantics: a section stages what the user
|
|
4
|
+
* types and writes it only on save — every settings write is a durable,
|
|
5
|
+
* revision-fenced `settings.mutate`, so a control that committed as it
|
|
6
|
+
* settled turned one edit into a write the user never asked for and could
|
|
7
|
+
* not preview; staged text makes what is on screen exactly what a save would
|
|
8
|
+
* store.
|
|
9
|
+
*
|
|
10
|
+
* A field shows its effective value — the user layer over the composition
|
|
11
|
+
* layer over the schema default — and whether the user layer carries it. That
|
|
12
|
+
* presence, not a value comparison, is what marks a field overridden: an
|
|
13
|
+
* override equal to the composition default is still an override.
|
|
14
|
+
*
|
|
15
|
+
* The kernel side (storage, schema validation, layering, revision fencing)
|
|
16
|
+
* stays with the dsh settings / credentials services; this module only
|
|
17
|
+
* translates between drafts and `mutate` path ops.
|
|
18
|
+
*/
|
|
19
|
+
import type { TuiSettingsField } from './settings-sections.js';
|
|
20
|
+
/** One settings namespace as the screen reads it (secrets redacted). */
|
|
21
|
+
export interface SettingsNamespaceView {
|
|
22
|
+
readonly ns: string;
|
|
23
|
+
/** Monotonic revision of the raw user section; fences writes. */
|
|
24
|
+
readonly revision: number;
|
|
25
|
+
/** 'live' applies immediately; 'restart' needs a relaunch. */
|
|
26
|
+
readonly applies: 'live' | 'restart';
|
|
27
|
+
/** Current resolved value (all layers composed). */
|
|
28
|
+
readonly value: unknown;
|
|
29
|
+
/** Raw user layer; a path present here is a user override. */
|
|
30
|
+
readonly user: unknown;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Runtime capabilities the settings screen needs, implemented by the channel
|
|
34
|
+
* over the dsh `settings` / `credentials` seams. `undefined` from
|
|
35
|
+
* `channel.settingsHost()` means the composition lacks them (bare cordis.yml
|
|
36
|
+
* start) and the screen shows namespaces read-only.
|
|
37
|
+
*/
|
|
38
|
+
export interface SettingsHost {
|
|
39
|
+
/** Every registered namespace, secrets redacted, in registration order. */
|
|
40
|
+
listNamespaces(): readonly SettingsNamespaceView[];
|
|
41
|
+
/** Write path ops against a namespace, fenced by its current revision. */
|
|
42
|
+
write(ns: string, ops: readonly SettingsPathOp[], expectedRevision?: number): Promise<void>;
|
|
43
|
+
/** Whether any layer supplies a credential under `ref`. */
|
|
44
|
+
credentialConfigured(ref: string): Promise<boolean>;
|
|
45
|
+
/** Persist a credential; rejects when env-shadowed or the store is read-only. */
|
|
46
|
+
writeCredential(ref: string, value: string): Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
export type SettingsPathOp = {
|
|
49
|
+
op: 'set';
|
|
50
|
+
path: readonly string[];
|
|
51
|
+
value: unknown;
|
|
52
|
+
} | {
|
|
53
|
+
op: 'unset';
|
|
54
|
+
path: readonly string[];
|
|
55
|
+
};
|
|
56
|
+
/** One field as the screen renders it. */
|
|
57
|
+
export interface SettingsFieldState {
|
|
58
|
+
/** Draft text the control renders. */
|
|
59
|
+
text: string;
|
|
60
|
+
/** Whether saving would leave a user-layer entry for this field. */
|
|
61
|
+
overridden: boolean;
|
|
62
|
+
/** Whether the draft is not a value this field accepts, blocking the save. */
|
|
63
|
+
invalid: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Form state every settings section shares. */
|
|
66
|
+
export interface SettingsSectionShell {
|
|
67
|
+
/** False while the settings service serves no such namespace. */
|
|
68
|
+
available: boolean;
|
|
69
|
+
/** Whether the form holds edits that a save would write. */
|
|
70
|
+
dirty: boolean;
|
|
71
|
+
/** Whether any staged draft is invalid, which blocks the save. */
|
|
72
|
+
invalid: boolean;
|
|
73
|
+
/** Whether a save is in flight. */
|
|
74
|
+
saving: boolean;
|
|
75
|
+
/** Whether the last save failed; cleared by the next edit or save. */
|
|
76
|
+
failed: boolean;
|
|
77
|
+
}
|
|
78
|
+
/** Read a nested value by path (array indexes as strings). */
|
|
79
|
+
export declare function getPath(value: unknown, path: readonly string[]): unknown;
|
|
80
|
+
/**
|
|
81
|
+
* Whether a value explicitly carries the path — its presence marks a user
|
|
82
|
+
* override, independent of the value stored there.
|
|
83
|
+
*/
|
|
84
|
+
export declare function hasPath(value: unknown, path: readonly string[]): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* The staged form over one settings namespace's declared fields. The screen
|
|
87
|
+
* re-seeds it from a fresh namespace view after every save and whenever the
|
|
88
|
+
* underlying document changes.
|
|
89
|
+
*/
|
|
90
|
+
export declare class SettingsForm {
|
|
91
|
+
private readonly host;
|
|
92
|
+
private readonly view;
|
|
93
|
+
private readonly fields;
|
|
94
|
+
private readonly edits;
|
|
95
|
+
saving: boolean;
|
|
96
|
+
failed: boolean;
|
|
97
|
+
constructor(host: SettingsHost, view: SettingsNamespaceView | undefined, fields: readonly TuiSettingsField[]);
|
|
98
|
+
get available(): boolean;
|
|
99
|
+
/** The namespace view the form was seeded from (undefined = not served). */
|
|
100
|
+
get namespace(): SettingsNamespaceView | undefined;
|
|
101
|
+
field(field: TuiSettingsField): SettingsFieldState;
|
|
102
|
+
shell(): SettingsSectionShell;
|
|
103
|
+
/** Whether the field holds a staged (unsaved) edit. */
|
|
104
|
+
isStaged(field: TuiSettingsField): boolean;
|
|
105
|
+
/** Stage draft text for one field. */
|
|
106
|
+
edit(field: TuiSettingsField, text: string): void;
|
|
107
|
+
/** Stage a clear, so saving lets the field re-inherit the composition layer. */
|
|
108
|
+
resetField(field: TuiSettingsField): void;
|
|
109
|
+
/** Drop every staged edit. */
|
|
110
|
+
discard(): void;
|
|
111
|
+
/** Whether any staged draft is invalid, which blocks the save. */
|
|
112
|
+
get invalid(): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Write every staged edit. Settings fields land as one revision-fenced
|
|
115
|
+
* `mutate` (one retry on a stale-revision conflict); credential fields
|
|
116
|
+
* write through the credentials seam. Resolves to whether every write
|
|
117
|
+
* landed — the caller re-seeds from a fresh namespace view afterwards.
|
|
118
|
+
*
|
|
119
|
+
* Only the edits THIS save snapshotted are cleared on success, and only
|
|
120
|
+
* when they are still the same edit: a draft typed while the write was in
|
|
121
|
+
* flight is a newer object and survives — it was never written, so it must
|
|
122
|
+
* not be silently dropped.
|
|
123
|
+
*/
|
|
124
|
+
save(): Promise<boolean>;
|
|
125
|
+
/** Whether any layer supplies the credential a secret field addresses. */
|
|
126
|
+
credentialConfigured(field: TuiSettingsField): Promise<boolean>;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=settingsEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settingsEditor.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/settingsEditor.ts"],"names":[],"mappings":"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"}
|