dsh-web-icon-indicator 0.5.0 → 0.5.1
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 +6 -0
- package/README.md +59 -43
- package/README.zh.md +43 -31
- package/lib/client.js +141 -32
- package/lib/index.js +171 -94
- package/lib/types/client/index.d.ts +13 -7
- package/lib/types/index.d.ts +14 -5
- package/package.json +3 -2
- package/test/verify.js +312 -65
package/lib/index.js
CHANGED
|
@@ -40,17 +40,17 @@
|
|
|
40
40
|
* Configuration object (all optional):
|
|
41
41
|
* iconsDir Absolute directory holding base.svg. Default `<package>/icons/`.
|
|
42
42
|
* statusPath JSON status endpoint path. Default `/dsh-web-icon-status.json`.
|
|
43
|
-
* Registration-time: composition entry only
|
|
43
|
+
* Registration-time (non-volatile): composition entry only.
|
|
44
44
|
* iconPathPrefix URL prefix for static icon files. Default `/dsh-web-icon-indicator`.
|
|
45
|
-
* Registration-time: composition entry only
|
|
45
|
+
* Registration-time (non-volatile): composition entry only.
|
|
46
46
|
* askingHoldMs Minimum visibility for the asking state (ms). Default 3500.
|
|
47
47
|
* doneHoldMs How long the done state stays before falling back to idle.
|
|
48
48
|
* Default 5000.
|
|
49
49
|
* defaultColor Default icon color — the idle whale's primary color, as
|
|
50
50
|
* `#rgb` / `#rrggbb`. Absent = the idle state's own colors[0]
|
|
51
51
|
* (today's behavior). Give each DSH instance (its own profile /
|
|
52
|
-
* settings
|
|
53
|
-
* apart. A value perceptually too close to another state's
|
|
52
|
+
* user settings layer) a different value to tell their browser
|
|
53
|
+
* tabs apart. A value perceptually too close to another state's
|
|
54
54
|
* color raises a WARNING — surfaced in the settings card, in
|
|
55
55
|
* the host log, and as `warnings` on the status endpoint — but
|
|
56
56
|
* is still honored.
|
|
@@ -67,12 +67,23 @@
|
|
|
67
67
|
* - speed: optional per-state cycle in ms (blink toggle interval too).
|
|
68
68
|
* Default 1200.
|
|
69
69
|
*
|
|
70
|
-
* The whole config surface is
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
70
|
+
* The whole config surface is the plugin's Cordis `Config` schema (exported as
|
|
71
|
+
* both `Config` and `CONFIG_SCHEMA`), and the same schema is registered with
|
|
72
|
+
* the LEGACY settings service when the running host still exposes
|
|
73
|
+
* `installSection` — one bundle serves every published host generation:
|
|
74
|
+
*
|
|
75
|
+
* - DSH ≥ 0.1.7: the settings service projects the schema's `.volatile()`
|
|
76
|
+
* fields into a live form, persisted into the profile patch
|
|
77
|
+
* (`~/.dsh/profiles/<profile>/cordis.patch.yml`); a write mutates the
|
|
78
|
+
* running plugin's config references in place and emits
|
|
79
|
+
* `loader/volatile-update` instead of restarting it.
|
|
80
|
+
* - DSH ≤ 0.1.6-alpha.1: the plugin registers the namespace itself under
|
|
81
|
+
* `web-icon-indicator` and the service drives it through
|
|
82
|
+
* `setSource`/`onChange`, persisted into `~/.dsh/settings.yaml`.
|
|
83
|
+
*
|
|
84
|
+
* `statusPath` / `iconPathPrefix` stay non-volatile in both. When the profile
|
|
85
|
+
* composes no settings service at all, the plugin keeps working on the
|
|
86
|
+
* composition entry + defaults it was mounted with.
|
|
76
87
|
*
|
|
77
88
|
* @module dsh-web-icon-indicator
|
|
78
89
|
*/
|
|
@@ -104,21 +115,54 @@ const EFFECT_NAMES = ["static", "blink", "breath", "rainbow", "heartbeat", "boun
|
|
|
104
115
|
const STATE_NAMES = ["idle", "running", "asking", "done"];
|
|
105
116
|
|
|
106
117
|
/**
|
|
107
|
-
* Settings namespace
|
|
108
|
-
*
|
|
109
|
-
*
|
|
118
|
+
* Settings namespace of this plugin on the MODERN host line (DSH ≥ 0.1.7):
|
|
119
|
+
* the settings namespace IS the profile entry id (`schema(entry)` reads
|
|
120
|
+
* `entry.fiber.runtime.Config` and `describe()` keys every form by
|
|
121
|
+
* `entry.options.id`), and this plugin's bundle patch declares exactly one row:
|
|
122
|
+
* `dsh-web-icon-indicator`. The browser half reads the same namespace through
|
|
123
|
+
* `ctx.configForms.get(...)`, so the two halves must keep this literal in sync
|
|
124
|
+
* (it is also the row id in `cordis.patch.yml`).
|
|
125
|
+
*/
|
|
126
|
+
const SETTINGS_NAMESPACE = "dsh-web-icon-indicator";
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Settings namespace on the LEGACY host line (DSH ≤ 0.1.6-alpha.1), where the
|
|
130
|
+
* consumer-owned namespace is an arbitrary string it passes to
|
|
131
|
+
* `settings.installSection` and the settings document section is named after
|
|
132
|
+
* it. Kept at the historical value so an existing 0.5.x user's
|
|
133
|
+
* `web-icon-indicator:` section keeps working after this upgrade; the browser
|
|
134
|
+
* half binds its legacy scope to the same string.
|
|
135
|
+
*/
|
|
136
|
+
const LEGACY_SETTINGS_NAMESPACE = "web-icon-indicator";
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Mark one field as LIVE when the resolved schemastery supports it.
|
|
110
140
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
141
|
+
* `.volatile()` exists since schemastery 3.18.3 and is what makes the modern
|
|
142
|
+
* settings service render a field at all (`volatileForm()` keeps volatile
|
|
143
|
+
* fields only) and what makes a settings write mutate the running plugin's
|
|
144
|
+
* references + emit `loader/volatile-update` instead of restarting it. On the
|
|
145
|
+
* legacy host line the installed schemastery (3.18.2) has no `.volatile()`,
|
|
146
|
+
* and the legacy settings service owns the whole live-form lifecycle through
|
|
147
|
+
* `installSection`/`setSource`/`onChange`, so the same schema object works
|
|
148
|
+
* unwrapped there.
|
|
114
149
|
*/
|
|
115
|
-
const
|
|
150
|
+
const LIVE = (schema) => (typeof schema.volatile === "function" ? schema.volatile() : schema);
|
|
116
151
|
|
|
117
152
|
/**
|
|
118
|
-
* Schemastery schema mirroring `DEFAULTS`.
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
153
|
+
* Schemastery schema mirroring `DEFAULTS`. Exported as the plugin's `Config`,
|
|
154
|
+
* which is what the Cordis loader validates the composition row against and
|
|
155
|
+
* what the modern host settings service projects into its live form
|
|
156
|
+
* (`volatileForm` keeps only `.volatile()` fields, so the settings page can
|
|
157
|
+
* never advertise a key it cannot honor).
|
|
158
|
+
*
|
|
159
|
+
* `.volatile()` marks a field as LIVE: the loader commits a settings write
|
|
160
|
+
* into the running fiber's references and emits `loader/volatile-update`
|
|
161
|
+
* instead of restarting the plugin (see `apply`). Ordinary (non-volatile)
|
|
162
|
+
* fields — `statusPath` / `iconPathPrefix` — are baked into the route table
|
|
163
|
+
* and the injected script at registration time, so a document change to them
|
|
164
|
+
* could never take effect; keeping them non-volatile removes them from the
|
|
165
|
+
* live form while still validating the composition entry.
|
|
122
166
|
*/
|
|
123
167
|
const STATE_CONFIG_SCHEMA = z.object({
|
|
124
168
|
effect: z.union(EFFECT_NAMES).default("static"),
|
|
@@ -129,24 +173,24 @@ const STATE_CONFIG_SCHEMA = z.object({
|
|
|
129
173
|
});
|
|
130
174
|
|
|
131
175
|
const CONFIG_SCHEMA = z.object({
|
|
132
|
-
askingHoldMs: z.number().min(0).default(DEFAULTS.askingHoldMs),
|
|
133
|
-
doneHoldMs: z.number().min(0).default(DEFAULTS.doneHoldMs),
|
|
176
|
+
askingHoldMs: LIVE(z.number().min(0).default(DEFAULTS.askingHoldMs)),
|
|
177
|
+
doneHoldMs: LIVE(z.number().min(0).default(DEFAULTS.doneHoldMs)),
|
|
134
178
|
// Default icon color (`#rgb` / `#rrggbb`). Deliberately WITHOUT a schema
|
|
135
179
|
// default: an absent value keeps the idle state's own colors[0], exactly as
|
|
136
180
|
// before this key existed. `resolveConfig` folds a valid value into
|
|
137
181
|
// `states.idle.colors[0]` and drops an invalid one with a warning.
|
|
138
|
-
defaultColor: z.string(),
|
|
139
|
-
|
|
140
|
-
// They are baked at registration time (the route table and the injected
|
|
141
|
-
// script's URLs are built in apply()), so a settings-document change to them
|
|
142
|
-
// could never take effect: the browser would poll the new path while the
|
|
143
|
-
// server still served the old one — a dead favicon. Keeping them out of the
|
|
144
|
-
// schema means the settings surface cannot advertise a key it cannot honor;
|
|
145
|
-
// they stay composition-entry only (see the README config table).
|
|
146
|
-
iconsDir: z.string(),
|
|
182
|
+
defaultColor: LIVE(z.string()),
|
|
183
|
+
iconsDir: LIVE(z.string()),
|
|
147
184
|
// dict (not a four-key object): the user layer may override only some
|
|
148
|
-
// states; the plugin merges the resolved value over DEFAULTS anyway.
|
|
149
|
-
|
|
185
|
+
// states; the plugin merges the resolved value over DEFAULTS anyway. The
|
|
186
|
+
// whole dict is one volatile field, so the custom card can stage and write
|
|
187
|
+
// it atomically through `scope.mutate([{ op: 'set', path: ['states'], … }])`.
|
|
188
|
+
states: LIVE(z.dict(STATE_CONFIG_SCHEMA).default(DEFAULTS.states)),
|
|
189
|
+
// Registration-time keys: route table + injected script URLs are built in
|
|
190
|
+
// apply(), so they are composition-entry only (non-volatile ⇒ absent from
|
|
191
|
+
// the live settings form). See the README config table.
|
|
192
|
+
statusPath: z.string().default(DEFAULTS.statusPath),
|
|
193
|
+
iconPathPrefix: z.string().default(DEFAULTS.iconPathPrefix),
|
|
150
194
|
});
|
|
151
195
|
|
|
152
196
|
/** Browser script injected into every served index.html response. */
|
|
@@ -695,34 +739,49 @@ function colorWarnings(states) {
|
|
|
695
739
|
}
|
|
696
740
|
|
|
697
741
|
/**
|
|
698
|
-
* Cordis plugin entry. Returns the standard `{ apply, inject,
|
|
699
|
-
* shape so the host composition can mount it once at startup.
|
|
742
|
+
* Cordis plugin entry. Returns the standard `{ apply, inject, Config }`
|
|
743
|
+
* shape so the host composition can mount it once at startup. `Config` (the
|
|
744
|
+
* schemastery schema) is what the loader validates the row against and what
|
|
745
|
+
* the host settings service projects into its live form — a plugin without it
|
|
746
|
+
* has no server-declared configuration surface at all. One bundle serves both
|
|
747
|
+
* host lines: the legacy `settings.installSection` path is feature-detected at
|
|
748
|
+
* runtime (see `apply`).
|
|
700
749
|
*/
|
|
701
750
|
export default {
|
|
702
751
|
name: "dsh-web-icon-indicator",
|
|
703
752
|
inject: ["webServer", "timer", "agents", "fs"],
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
doneHoldMs: DEFAULTS.doneHoldMs,
|
|
707
|
-
statusPath: DEFAULTS.statusPath,
|
|
708
|
-
iconPathPrefix: DEFAULTS.iconPathPrefix,
|
|
709
|
-
iconsDir: undefined,
|
|
710
|
-
defaultColor: undefined,
|
|
711
|
-
states: DEFAULTS.states,
|
|
712
|
-
},
|
|
713
|
-
/** Settings namespace + validation schema (exported for reuse/tooling). */
|
|
753
|
+
Config: CONFIG_SCHEMA,
|
|
754
|
+
/** Settings namespace (the profile entry id on ≥0.1.7) + schema, for tooling. */
|
|
714
755
|
SETTINGS_NAMESPACE,
|
|
756
|
+
/** Settings namespace used on the legacy (≤0.1.6-alpha.1) settings service. */
|
|
757
|
+
LEGACY_SETTINGS_NAMESPACE,
|
|
715
758
|
CONFIG_SCHEMA,
|
|
716
759
|
apply(ctx, config) {
|
|
717
|
-
// Cordis passes the resolved
|
|
718
|
-
// (`apply(ctx, config)`). `
|
|
719
|
-
//
|
|
720
|
-
//
|
|
721
|
-
//
|
|
722
|
-
//
|
|
723
|
-
//
|
|
724
|
-
|
|
725
|
-
|
|
760
|
+
// Cordis passes the schema-resolved config as the second argument
|
|
761
|
+
// (`apply(ctx, config)`). Every `.volatile()` field arrives as a live
|
|
762
|
+
// reference (`config.states.get()`), and the loader mutates those
|
|
763
|
+
// references in place when a settings write lands — that is what
|
|
764
|
+
// `loader/volatile-update` below reacts to. Unwrap the references once per
|
|
765
|
+
// read so the rest of this file keeps working on plain values. The
|
|
766
|
+
// `ctx.get("config")` fallback keeps the zero-dependency test harness (and
|
|
767
|
+
// any host that hands the row config through the service container) working.
|
|
768
|
+
const readRef = (value) =>
|
|
769
|
+
value !== null && typeof value === "object" && typeof value.get === "function" ? value.get() : value;
|
|
770
|
+
const readConfig = (raw) => {
|
|
771
|
+
const out = {};
|
|
772
|
+
for (const [key, value] of Object.entries(raw || {})) {
|
|
773
|
+
const plain = readRef(value);
|
|
774
|
+
if (plain !== undefined) out[key] = plain;
|
|
775
|
+
}
|
|
776
|
+
return out;
|
|
777
|
+
};
|
|
778
|
+
// Legacy host line (DSH ≤ 0.1.6-alpha.1): `settings.installSection` owns the
|
|
779
|
+
// namespace lifecycle and hands this plugin a live source through
|
|
780
|
+
// `setSource`. Until it does, the composition config passed to `apply` (or
|
|
781
|
+
// the zero-dep test harness's `ctx.get("config")`) is the source.
|
|
782
|
+
let legacySource = null;
|
|
783
|
+
const source = () =>
|
|
784
|
+
readConfig(legacySource ? legacySource() : config ?? ctx.get("config") ?? {});
|
|
726
785
|
// Merge each configured state over its default: { effect, colors, speed }.
|
|
727
786
|
// Idempotent on schema-resolved values, so it doubles as the fallback
|
|
728
787
|
// normalization when the profile composes no settings service.
|
|
@@ -806,54 +865,72 @@ export default {
|
|
|
806
865
|
}
|
|
807
866
|
} catch (e) {}
|
|
808
867
|
};
|
|
809
|
-
let cfg = resolveConfig(
|
|
868
|
+
let cfg = resolveConfig(source());
|
|
810
869
|
logWarnings(cfg.warnings);
|
|
811
870
|
// The injected script bakes config at injection time; rebuild it whenever
|
|
812
|
-
// the
|
|
813
|
-
//
|
|
871
|
+
// the live config changes so the NEXT page load picks the new values up
|
|
872
|
+
// (reload the tab — the running tab is already carried by the status poll's
|
|
873
|
+
// `states` echo).
|
|
814
874
|
const buildScript = (c) => INJECTED_SCRIPT
|
|
815
875
|
.replace("__STATUS_PATH__", c.statusPath)
|
|
816
876
|
.replace("__BASE_PATH__", c.iconPathPrefix + "/base.svg")
|
|
817
877
|
.replace("__CFG__", JSON.stringify({ states: c.states }));
|
|
818
878
|
let script = buildScript(cfg);
|
|
819
879
|
let iconsDir = resolveIconsDir(cfg.iconsDir);
|
|
820
|
-
//
|
|
821
|
-
//
|
|
822
|
-
//
|
|
823
|
-
// schema
|
|
824
|
-
//
|
|
825
|
-
//
|
|
826
|
-
//
|
|
827
|
-
//
|
|
828
|
-
//
|
|
829
|
-
//
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
880
|
+
// Live settings, modern line (DSH ≥ 0.1.7). The host owns the whole
|
|
881
|
+
// configuration lifecycle: the loader validates the composition row against
|
|
882
|
+
// `Config`, the `settings` service (`SettingsForms`) derives the live form
|
|
883
|
+
// from the schema's `.volatile()` fields and writes them into the profile
|
|
884
|
+
// patch, and a volatile-only write is committed into the running fiber's
|
|
885
|
+
// references with a `loader/volatile-update` event instead of a restart.
|
|
886
|
+
// This listener rebuilds the cached `cfg` and the injected script from the
|
|
887
|
+
// same references; the legacy line below drives it through `onChange`
|
|
888
|
+
// instead. `statusPath` / `iconPathPrefix` are NOT volatile: they are baked
|
|
889
|
+
// into the route table and the injected script at registration time, so a
|
|
890
|
+
// document change to them re-applies the whole plugin instead (they stay
|
|
891
|
+
// outside the live form — see CONFIG_SCHEMA).
|
|
892
|
+
const refreshFromConfig = () => {
|
|
893
|
+
const next = resolveConfig(source());
|
|
894
|
+
cfg.askingHoldMs = next.askingHoldMs;
|
|
895
|
+
cfg.doneHoldMs = next.doneHoldMs;
|
|
896
|
+
if (next.iconsDir !== undefined) cfg.iconsDir = next.iconsDir;
|
|
897
|
+
cfg.states = next.states;
|
|
898
|
+
// `defaultColor` / `warnings` ride along with `states`: the color is
|
|
899
|
+
// already folded into `states.idle.colors[0]`, so the browser needs no
|
|
900
|
+
// new key — they are kept for observability (status echo + log).
|
|
901
|
+
cfg.defaultColor = next.defaultColor;
|
|
902
|
+
cfg.warnings = next.warnings;
|
|
903
|
+
iconsDir = resolveIconsDir(cfg.iconsDir);
|
|
904
|
+
script = buildScript(cfg);
|
|
905
|
+
logWarnings(cfg.warnings);
|
|
906
|
+
};
|
|
907
|
+
// A plain `ctx.on` listener is enough: the loader emits this event on the
|
|
908
|
+
// owning fiber's context only, so a volatile write to another plugin's
|
|
909
|
+
// config never reaches here. Guard for the zero-dep test harness, whose
|
|
910
|
+
// fake ctx carries no event bus.
|
|
911
|
+
if (typeof ctx.on === "function") ctx.on("loader/volatile-update", refreshFromConfig);
|
|
912
|
+
// Legacy host line (DSH ≤ 0.1.6-alpha.1): the `settings` service exposes
|
|
913
|
+
// `installSection`, and the plugin must register its namespace itself —
|
|
914
|
+
// that service method was removed in 0.1.7, where the exported `Config`
|
|
915
|
+
// schema plus `loader/volatile-update` carry the same lifecycle. Feature-
|
|
916
|
+
// detect instead of switching on a version: whichever service the running
|
|
917
|
+
// host provides decides the path, so one bundle serves both lines.
|
|
918
|
+
// The base layer is a RESOLVED PLAIN COPY (`resolveConfig(source())`), not
|
|
919
|
+
// the raw `apply` config: the legacy loader deep-freezes the config it
|
|
920
|
+
// resolved against the exported `Config` schema, and the legacy settings
|
|
921
|
+
// service resolves the schema over the base IN PLACE (its `mergeLayers`
|
|
922
|
+
// returns the base unchanged when no user section exists) — handing it a
|
|
923
|
+
// frozen object throws "Cannot assign to read only property".
|
|
924
|
+
if (typeof ctx.inject === "function") {
|
|
925
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
926
|
+
const settings = settingsCtx.settings;
|
|
927
|
+
if (!settings || typeof settings.installSection !== "function") return;
|
|
928
|
+
settings.installSection(ctx, LEGACY_SETTINGS_NAMESPACE, CONFIG_SCHEMA, resolveConfig(source()), {
|
|
929
|
+
setSource: (next) => { legacySource = next; },
|
|
930
|
+
onChange: refreshFromConfig,
|
|
931
|
+
});
|
|
855
932
|
});
|
|
856
|
-
}
|
|
933
|
+
}
|
|
857
934
|
const webServer = ctx.webServer;
|
|
858
935
|
const agents = ctx.agents;
|
|
859
936
|
const fs = ctx.fs;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Browser half of dsh-web-icon-indicator (dsh.client bundle).
|
|
3
3
|
*
|
|
4
|
-
* Registers one
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* the
|
|
4
|
+
* Registers one configuration page and serves both host generations from one
|
|
5
|
+
* bundle: `plugins.row.config` (keyed `dsh-web-icon-indicator#dsh-web-icon-indicator`)
|
|
6
|
+
* bound through the modern `configForms` service on DSH ≥ 0.1.7, and
|
|
7
|
+
* `settings.plugin.item` (keyed by the legacy `web-icon-indicator` namespace)
|
|
8
|
+
* bound through the legacy `settingsScope` service on DSH ≤ 0.1.6-alpha.1.
|
|
9
|
+
* Neither settings provider appears in `inject`: both are read weakly at render
|
|
10
|
+
* time, so the fiber activates on either line.
|
|
8
11
|
*/
|
|
9
12
|
|
|
10
|
-
/**
|
|
11
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Cordis services this browser plugin injects. Only the two services every
|
|
15
|
+
* host generation provides; the settings providers are optional weak reads.
|
|
16
|
+
*/
|
|
17
|
+
export declare const inject: readonly ["slots", "locale"];
|
|
12
18
|
|
|
13
|
-
/** Mount the settings
|
|
19
|
+
/** Mount the settings page on whichever host generation is running. */
|
|
14
20
|
export declare function apply(ctx: unknown): void;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -163,17 +163,26 @@ export interface DshWebIconColorWarning {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
|
-
* Cordis plugin entry: `{ name, inject,
|
|
167
|
-
* CONFIG_SCHEMA }`. Mount once per profile through
|
|
168
|
-
* (`cordis.patch.yml`), never as a session-scoped agent
|
|
166
|
+
* Cordis plugin entry: `{ name, inject, Config, apply, SETTINGS_NAMESPACE,
|
|
167
|
+
* LEGACY_SETTINGS_NAMESPACE, CONFIG_SCHEMA }`. Mount once per profile through
|
|
168
|
+
* the bundle patch (`cordis.patch.yml`), never as a session-scoped agent
|
|
169
|
+
* preset.
|
|
170
|
+
*
|
|
171
|
+
* `Config` is the schemastery schema the loader validates the profile row
|
|
172
|
+
* against and the host settings service projects into its live form
|
|
173
|
+
* (`.volatile()` fields only); this entry has no `config` object. The same
|
|
174
|
+
* bundle serves the legacy host line through a feature-detected
|
|
175
|
+
* `settings.installSection` registration.
|
|
169
176
|
*/
|
|
170
177
|
declare const plugin: {
|
|
171
178
|
name: "dsh-web-icon-indicator";
|
|
172
179
|
inject: readonly ["webServer", "timer", "agents", "fs"];
|
|
173
|
-
|
|
180
|
+
Config: unknown;
|
|
174
181
|
apply(ctx: unknown, config?: unknown): void;
|
|
175
|
-
/** Settings namespace
|
|
182
|
+
/** Settings namespace on DSH ≥ 0.1.7 (= the profile entry id). */
|
|
176
183
|
SETTINGS_NAMESPACE: string;
|
|
184
|
+
/** Settings namespace on the legacy settings service (DSH ≤ 0.1.6-alpha.1). */
|
|
185
|
+
LEGACY_SETTINGS_NAMESPACE: string;
|
|
177
186
|
/** Schemastery schema validating the config surface. */
|
|
178
187
|
CONFIG_SCHEMA: unknown;
|
|
179
188
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-web-icon-indicator",
|
|
3
3
|
"description": "Browser tab favicon reflects the DSH session state: idle / running / asking / done, recolored and animated from one base SVG in the browser (fully configurable colors + effects). · 浏览器标签页 favicon 实时反映 DSH 会话状态:待机 / 运行中 / 提问 / 完成,由单个 base.svg 在浏览器中动态上色与动画(颜色与特效完全可配置)。",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"dsh": ">=0.1.2-rc.1"
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"@deepseek-ai/dsh-client-locale",
|
|
28
28
|
"@deepseek-ai/dsh-client-ui-renderer",
|
|
29
29
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
30
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins"
|
|
30
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins",
|
|
31
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager"
|
|
31
32
|
]
|
|
32
33
|
}
|
|
33
34
|
},
|