dsh-plugin-lookatstudy 0.12.3 → 0.12.4
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/lib/client.js +29 -14
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -298,10 +298,10 @@ window.__ModuleLoader__.load({
|
|
|
298
298
|
* ic_ds_* glyphs vendored from @deepseek-ai/dsh-client-ui-primitives
|
|
299
299
|
* (src/icons/index.tsx, same figma source as the host's icon set) so the
|
|
300
300
|
* plugin's client bundle stays self-contained per the dsh client-bundle
|
|
301
|
-
* contract — only react
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
*
|
|
301
|
+
* contract — only react is runtime-external; importing the host package
|
|
302
|
+
* root would drag its CSS modules into the inlined bundle. Re-sync these
|
|
303
|
+
* three paths if the host icon set redesigns them; scripts/verify.mjs
|
|
304
|
+
* pins the path data.
|
|
305
305
|
*
|
|
306
306
|
* 2026-09-01 critique round: seven more ic_ds glyphs vendored (play/plus/
|
|
307
307
|
* trash/refresh/globe/goal/warning) plus plugin-original learning-domain
|
|
@@ -2045,10 +2045,10 @@ window.__ModuleLoader__.load({
|
|
|
2045
2045
|
return runs.at(-1) ?? [];
|
|
2046
2046
|
}
|
|
2047
2047
|
function textOf(blocks) {
|
|
2048
|
-
return blocks.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n\n").trim();
|
|
2048
|
+
return (blocks ?? []).filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n\n").trim();
|
|
2049
2049
|
}
|
|
2050
2050
|
function assistantText(blocks) {
|
|
2051
|
-
return blocks.filter((b) => b.kind === "text").map((b) => b.text).join("\n\n").trim();
|
|
2051
|
+
return (blocks ?? []).filter((b) => b.kind === "text").map((b) => b.text ?? "").join("\n\n").trim();
|
|
2052
2052
|
}
|
|
2053
2053
|
/**
|
|
2054
2054
|
* Fold conversation nodes (plus the streaming partial) into render rows.
|
|
@@ -2088,7 +2088,7 @@ window.__ModuleLoader__.load({
|
|
|
2088
2088
|
case "turn-error": rows.push({
|
|
2089
2089
|
key: `e${node.seq}`,
|
|
2090
2090
|
role: "error",
|
|
2091
|
-
text: node.message
|
|
2091
|
+
text: node.message ?? ""
|
|
2092
2092
|
});
|
|
2093
2093
|
}
|
|
2094
2094
|
if (partial != null) {
|
|
@@ -2111,6 +2111,17 @@ window.__ModuleLoader__.load({
|
|
|
2111
2111
|
if (error === null) return null;
|
|
2112
2112
|
return (0, react.createElement)("div", { className: "lks-propcard-err" }, error);
|
|
2113
2113
|
}
|
|
2114
|
+
/**
|
|
2115
|
+
* Resolve the transcript across host generations. 0.1.3+ hosts expose the
|
|
2116
|
+
* node array as the Chat target's `legacy` slice; pre-0.1.3 hosts hand the
|
|
2117
|
+
* whole conversation snapshot (nodes + partial) through `useSession`, whose
|
|
2118
|
+
* 0.1.3+ successor returns the session MACHINE (no node array). The array
|
|
2119
|
+
* check tells those two `useSession` shapes apart. Pure.
|
|
2120
|
+
*/
|
|
2121
|
+
function pickTranscript(chatLegacy, sessionSnapshot) {
|
|
2122
|
+
if (chatLegacy !== void 0) return chatLegacy;
|
|
2123
|
+
return sessionSnapshot !== void 0 && Array.isArray(sessionSnapshot.nodes) ? sessionSnapshot : void 0;
|
|
2124
|
+
}
|
|
2114
2125
|
/** sessionStorage key keeping the narrow-mode pane across view remounts (tab switches) and reloads. */
|
|
2115
2126
|
const PANE_KEY = "dsh-plugin-lookatstudy:pane";
|
|
2116
2127
|
/** Narrow the stored value back to a pane id; anything else (or nothing stored) falls back to 导师. Pure, unit-testable. */
|
|
@@ -2137,9 +2148,12 @@ window.__ModuleLoader__.load({
|
|
|
2137
2148
|
};
|
|
2138
2149
|
}
|
|
2139
2150
|
/** Tab body: the factory-bound ctx carries workspaces/sessions for the per-lesson session jumps. */
|
|
2140
|
-
function StudyTab({
|
|
2151
|
+
function StudyTab({ inputActions, ctx, ...standard }) {
|
|
2141
2152
|
const { data, activate, setMode, setFocus, searchLessons, deleteCourse, bindLessonSession } = useStudy();
|
|
2142
|
-
const
|
|
2153
|
+
const chatLegacy = standard.useChat?.((s) => s.legacy);
|
|
2154
|
+
const sessionSnapshot = standard.useSession?.((s) => s);
|
|
2155
|
+
const snapshot = pickTranscript(chatLegacy, sessionSnapshot);
|
|
2156
|
+
const currentSessionId = standard.sessionId ?? snapshot?.sessionId ?? "";
|
|
2143
2157
|
const [pane, setPane] = (0, react.useState)(storedPane);
|
|
2144
2158
|
const rootRef = (0, react.useRef)(null);
|
|
2145
2159
|
(0, react.useEffect)(() => {
|
|
@@ -2237,7 +2251,7 @@ window.__ModuleLoader__.load({
|
|
|
2237
2251
|
bindLessonSession,
|
|
2238
2252
|
send,
|
|
2239
2253
|
ctx,
|
|
2240
|
-
currentSessionId
|
|
2254
|
+
currentSessionId
|
|
2241
2255
|
}), (0, react.createElement)(TutorColumn, {
|
|
2242
2256
|
data,
|
|
2243
2257
|
setMode,
|
|
@@ -2268,7 +2282,7 @@ window.__ModuleLoader__.load({
|
|
|
2268
2282
|
if (!area.ok) throw new Error(`study area unavailable (HTTP ${area.status})`);
|
|
2269
2283
|
const { path } = await area.json();
|
|
2270
2284
|
const workspace = await ctx.workspaces.create({ path });
|
|
2271
|
-
const sessionId = await ctx.workspaces.connectWorkspace(workspace.workspaceId);
|
|
2285
|
+
const sessionId = ctx.workspaces.connectWorkspace !== void 0 ? await ctx.workspaces.connectWorkspace(workspace.workspaceId) : await ctx.sessions.create({ workspaceId: workspace.workspaceId });
|
|
2272
2286
|
const actx = ctx.sessions.scope(sessionId);
|
|
2273
2287
|
const face = actx === void 0 ? void 0 : ctx.sessions.sessionOf(actx);
|
|
2274
2288
|
if (face === void 0) throw new Error("lesson session is not addressable yet");
|
|
@@ -2669,8 +2683,9 @@ window.__ModuleLoader__.load({
|
|
|
2669
2683
|
* @returns the component for `conversation.input.left`.
|
|
2670
2684
|
*/
|
|
2671
2685
|
function studyStartButton(ctx) {
|
|
2672
|
-
return function StudyStartButton(
|
|
2673
|
-
|
|
2686
|
+
return function StudyStartButton(props) {
|
|
2687
|
+
const machine = props.useSession?.((s) => s);
|
|
2688
|
+
if ((props.session?.blank ?? machine?.blank) !== true) return null;
|
|
2674
2689
|
return (0, react.createElement)(Inner, {
|
|
2675
2690
|
key: "inner",
|
|
2676
2691
|
ctx
|
|
@@ -2693,7 +2708,7 @@ window.__ModuleLoader__.load({
|
|
|
2693
2708
|
if (!area.ok) throw new Error(`study area unavailable (HTTP ${area.status})`);
|
|
2694
2709
|
const { path } = await area.json();
|
|
2695
2710
|
const workspace = await ctx.workspaces.create({ path });
|
|
2696
|
-
const sessionId = await ctx.workspaces.connectWorkspace(workspace.workspaceId);
|
|
2711
|
+
const sessionId = ctx.workspaces.connectWorkspace !== void 0 ? await ctx.workspaces.connectWorkspace(workspace.workspaceId) : await ctx.sessions.create({ workspaceId: workspace.workspaceId });
|
|
2697
2712
|
const actx = ctx.sessions.scope(sessionId);
|
|
2698
2713
|
const face = actx === void 0 ? void 0 : ctx.sessions.sessionOf(actx);
|
|
2699
2714
|
if (face === void 0) throw new Error("study session is not addressable yet");
|