@huanlin/dsh-plugin-preface-context 0.1.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.
Files changed (38) hide show
  1. package/README.md +113 -0
  2. package/cordis.patch.yml +11 -0
  3. package/lib/client.js +794 -0
  4. package/lib/client.js.map +1 -0
  5. package/lib/index.js +127 -0
  6. package/lib/types/client/bind-snapshot-selector.d.ts +7 -0
  7. package/lib/types/client/bind-snapshot-selector.js +19 -0
  8. package/lib/types/client/client/bind-snapshot-selector.d.ts +7 -0
  9. package/lib/types/client/client/bind-snapshot-selector.js +19 -0
  10. package/lib/types/client/client/index.d.ts +39 -0
  11. package/lib/types/client/client/index.js +50 -0
  12. package/lib/types/client/client/locales.d.ts +7 -0
  13. package/lib/types/client/client/locales.js +41 -0
  14. package/lib/types/client/client/preface-card-controller.d.ts +94 -0
  15. package/lib/types/client/client/preface-card-controller.js +181 -0
  16. package/lib/types/client/client/preface-card.css.d.ts +53 -0
  17. package/lib/types/client/client/preface-card.css.js +327 -0
  18. package/lib/types/client/client/preface-card.d.ts +27 -0
  19. package/lib/types/client/client/preface-card.js +41 -0
  20. package/lib/types/client/config.d.ts +41 -0
  21. package/lib/types/client/config.js +42 -0
  22. package/lib/types/client/index.d.ts +39 -0
  23. package/lib/types/client/index.js +50 -0
  24. package/lib/types/client/locales.d.ts +7 -0
  25. package/lib/types/client/locales.js +41 -0
  26. package/lib/types/client/preface-card-controller.d.ts +94 -0
  27. package/lib/types/client/preface-card-controller.js +181 -0
  28. package/lib/types/client/preface-card.css.d.ts +53 -0
  29. package/lib/types/client/preface-card.css.js +327 -0
  30. package/lib/types/client/preface-card.d.ts +27 -0
  31. package/lib/types/client/preface-card.js +41 -0
  32. package/lib/types/config.d.ts +40 -0
  33. package/lib/types/config.js +42 -0
  34. package/lib/types/index.d.ts +46 -0
  35. package/lib/types/index.js +64 -0
  36. package/lib/types/settings.d.ts +50 -0
  37. package/lib/types/settings.js +85 -0
  38. package/package.json +130 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Host-side `preface-context` settings namespace + live source wiring.
3
+ *
4
+ * The plugin-row config (the `entry` passed to the plugin's `apply`) is the
5
+ * composition BASE of the `preface-context` settings namespace: when a dsh
6
+ * settings service is mounted, its user layer is layered on top (schema
7
+ * defaults → base → user layer) and the runtime reads the live resolved
8
+ * value through the bridge's `source` thunk. Without a settings service the
9
+ * conditional `ctx.inject(['settings'], ...)` child never activates and the
10
+ * source is exactly the entry: behavior identical to a no-settings build.
11
+ *
12
+ * The namespace reaches the web configuration boundary directly: the
13
+ * apiproxy `settings.mutate` / `settings.describe` RPCs accept any
14
+ * registered namespace (no allowlist gate in current upstream dsh), so the
15
+ * client card reads/writes through `ctx.settingsScope.bind({ namespace })`
16
+ * — no gateway channel is needed.
17
+ *
18
+ * @module @huanlin/dsh-plugin-preface-context/settings
19
+ */
20
+ import { Config } from "./config.js";
21
+ /** The `preface-context` settings namespace (registered when a settings service exists). */
22
+ export const PREFACE_SETTINGS_NAMESPACE = 'preface-context';
23
+ /**
24
+ * Mirror of @deepseek-ai/dsh-settings' `isUnloading` guard (its
25
+ * `installSettingsSection` skips source/listener work while the plugin fiber
26
+ * is unloading or disposed). The library compares `ctx.fiber.state` against
27
+ * `FiberState.DISPOSED` / `FiberState.UNLOADING`; the const enum is erased at
28
+ * runtime, so the vendored numeric values (4 / 5) are mirrored here.
29
+ */
30
+ function isUnloading(ctx) {
31
+ const state = ctx.fiber?.state;
32
+ return state === 4 || state === 5;
33
+ }
34
+ /**
35
+ * Install the `preface-context` settings namespace and wire the live source.
36
+ *
37
+ * Mirrors the dsh `installSettingsSection` pattern. The registration rides a
38
+ * conditional `ctx.inject(['settings'], ...)` child, so with no settings
39
+ * service the source stays the entry config. Multi-fiber dedupe: the host
40
+ * may compose several preface-context fibers, and `settings.register` fails
41
+ * loud on a duplicate namespace — the catch lets the first registration own
42
+ * the live namespace while later instances fall back to the entry source.
43
+ * @param ctx - consumer plugin context owning the wiring.
44
+ * @param entry - the composition entry config, used as `base`.
45
+ * @returns the bridge the runtime and gateway read through.
46
+ */
47
+ export function installPrefaceSettings(ctx, entry) {
48
+ const listeners = new Set();
49
+ let source = () => entry;
50
+ const notify = () => {
51
+ for (const listener of [...listeners])
52
+ listener();
53
+ };
54
+ ctx.inject(['settings'], (sctx) => {
55
+ let scope;
56
+ try {
57
+ scope = sctx.settings.register(PREFACE_SETTINGS_NAMESPACE, Config, { base: entry });
58
+ }
59
+ catch (error) {
60
+ if (!(error instanceof Error) || !error.message.includes('already registered'))
61
+ throw error;
62
+ ctx.logger('preface-context').debug('settings namespace already registered — entry-source fallback (multi-fiber dedupe)');
63
+ return;
64
+ }
65
+ source = () => scope.get();
66
+ sctx.effect(() => () => {
67
+ if (isUnloading(ctx))
68
+ return;
69
+ source = () => entry;
70
+ notify();
71
+ });
72
+ notify();
73
+ scope.watch(() => {
74
+ if (isUnloading(ctx))
75
+ return;
76
+ notify();
77
+ });
78
+ });
79
+ return {
80
+ source: () => source(),
81
+ onChange: (callback) => {
82
+ listeners.add(callback);
83
+ },
84
+ };
85
+ }
package/package.json ADDED
@@ -0,0 +1,130 @@
1
+ {
2
+ "name": "@huanlin/dsh-plugin-preface-context",
3
+ "version": "0.1.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "keywords": [
8
+ "dsh-plugin"
9
+ ],
10
+ "description": "在每次会话开头固定注入一段用户配置的文本上下文(设置页输入框可编辑),作为模型可见的 instructions 注入第一轮请求。 | Injects a user-configured text block as model-visible instructions context at the start of every DSH session (editable from the settings page).",
11
+ "type": "module",
12
+ "license": "AGPL-3.0",
13
+ "main": "./lib/index.js",
14
+ "types": "./lib/types/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./lib/types/index.d.ts",
18
+ "import": "./lib/index.js"
19
+ },
20
+ "./client": {
21
+ "types": "./lib/types/client/index.d.ts",
22
+ "default": "./lib/client.js"
23
+ },
24
+ "./src/*": "./src/*",
25
+ "./package.json": "./package.json"
26
+ },
27
+ "files": [
28
+ "lib/",
29
+ "cordis.patch.yml"
30
+ ],
31
+ "dsh": {
32
+ "bundle": {
33
+ "patch": "./cordis.patch.yml"
34
+ },
35
+ "client": {
36
+ "inject": [
37
+ "@deepseek-ai/dsh-client-locale",
38
+ "@deepseek-ai/dsh-client-ui-settings",
39
+ "@deepseek-ai/dsh-client-ui-settings-plugins",
40
+ "@deepseek-ai/dsh-client-ui-renderer"
41
+ ],
42
+ "platform": "web"
43
+ }
44
+ },
45
+ "peerDependencies": {
46
+ "@deepseek-ai/cordis": "^4.0.1",
47
+ "@deepseek-ai/dsh-client-connection": "^0.1.2-rc.1",
48
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-rc.1",
49
+ "@deepseek-ai/dsh-client-store": "^0.1.2-rc.1",
50
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
51
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.1.2-rc.1",
52
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-rc.1",
53
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.2-rc.1",
54
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-rc.1",
55
+ "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
56
+ "@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
57
+ "react": "^18.2.0",
58
+ "react-dom": "^18.2.0",
59
+ "schemastery": "^3.18.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "@deepseek-ai/cordis": {
63
+ "optional": true
64
+ },
65
+ "@deepseek-ai/dsh-client-connection": {
66
+ "optional": true
67
+ },
68
+ "@deepseek-ai/dsh-client-locale": {
69
+ "optional": true
70
+ },
71
+ "@deepseek-ai/dsh-client-store": {
72
+ "optional": true
73
+ },
74
+ "@deepseek-ai/dsh-client-ui-primitives": {
75
+ "optional": true
76
+ },
77
+ "@deepseek-ai/dsh-client-ui-renderer": {
78
+ "optional": true
79
+ },
80
+ "@deepseek-ai/dsh-client-ui-settings": {
81
+ "optional": true
82
+ },
83
+ "@deepseek-ai/dsh-client-ui-settings-plugins": {
84
+ "optional": true
85
+ },
86
+ "@deepseek-ai/dsh-client-ui-slots": {
87
+ "optional": true
88
+ },
89
+ "@deepseek-ai/dsh-llm": {
90
+ "optional": true
91
+ },
92
+ "@deepseek-ai/dsh-settings": {
93
+ "optional": true
94
+ },
95
+ "react": {
96
+ "optional": true
97
+ },
98
+ "react-dom": {
99
+ "optional": true
100
+ },
101
+ "schemastery": {
102
+ "optional": true
103
+ }
104
+ },
105
+ "devDependencies": {
106
+ "@testing-library/dom": "^10.4.1",
107
+ "@testing-library/react": "^16.3.2",
108
+ "@types/node": "^22.20.1",
109
+ "@types/react": "~18.3.31",
110
+ "@types/react-dom": "~18.3.0",
111
+ "clsx": "^2.1.1",
112
+ "jsdom": "^25.0.1",
113
+ "react": "^18.2.0",
114
+ "react-dom": "^18.2.0",
115
+ "schemastery": "^3.18.0",
116
+ "tsdown": "^0.15.0",
117
+ "typescript": "^5.9.2",
118
+ "use-sync-external-store": "^1.2.0",
119
+ "vitest": "^3.2.7"
120
+ },
121
+ "engines": {
122
+ "node": ">=22.0.0"
123
+ },
124
+ "scripts": {
125
+ "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.client.json",
126
+ "test": "vitest run",
127
+ "build": "tsdown -c tsdown.config.ts && tsc -p tsconfig.json && tsc -p tsconfig.client.json",
128
+ "bundle:client": "tsdown -c tsdown.config.ts"
129
+ }
130
+ }