dsh-better-display 0.3.8 → 0.3.10
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 +11 -0
- package/DESIGN.md +43 -3
- package/README.en.md +10 -2
- package/README.md +10 -2
- package/compat/harness-rc2.json +17 -13
- package/docs/dependency-update-policy.md +9 -0
- package/docs/extension-points.md +172 -0
- package/docs/official-rendering-bridge.md +49 -20
- package/docs/openapi.yaml +147 -0
- package/docs/runbooks/blank-reader.md +39 -0
- package/lib/client.js +1802 -872
- package/lib/client.js.map +1 -1
- package/lib/dsh-better-display.js +376 -151
- package/lib/types/client/AssistantNode.d.ts +20 -0
- package/lib/types/client/AssistantNode.d.ts.map +1 -0
- package/lib/types/client/AssistantNode.js +46 -0
- package/lib/types/client/AssistantNode.js.map +1 -0
- package/lib/types/client/Blocks.d.ts.map +1 -1
- package/lib/types/client/Blocks.js +33 -10
- package/lib/types/client/Blocks.js.map +1 -1
- package/lib/types/client/ChoreographedFlow.d.ts.map +1 -1
- package/lib/types/client/ChoreographedFlow.js +2 -0
- package/lib/types/client/ChoreographedFlow.js.map +1 -1
- package/lib/types/client/ClosedProcessSummary.d.ts.map +1 -1
- package/lib/types/client/ClosedProcessSummary.js +3 -1
- package/lib/types/client/ClosedProcessSummary.js.map +1 -1
- package/lib/types/client/McpAppFrame.d.ts.map +1 -1
- package/lib/types/client/McpAppFrame.js +5 -11
- package/lib/types/client/McpAppFrame.js.map +1 -1
- package/lib/types/client/OfficialContent.d.ts +17 -3
- package/lib/types/client/OfficialContent.d.ts.map +1 -1
- package/lib/types/client/OfficialContent.js +37 -12
- package/lib/types/client/OfficialContent.js.map +1 -1
- package/lib/types/client/Reader.d.ts.map +1 -1
- package/lib/types/client/Reader.js +45 -77
- package/lib/types/client/Reader.js.map +1 -1
- package/lib/types/client/SettingsSection.d.ts.map +1 -1
- package/lib/types/client/SettingsSection.js +0 -5
- package/lib/types/client/SettingsSection.js.map +1 -1
- package/lib/types/client/StickyLane.d.ts +12 -0
- package/lib/types/client/StickyLane.d.ts.map +1 -1
- package/lib/types/client/StickyLane.js +78 -2
- package/lib/types/client/StickyLane.js.map +1 -1
- package/lib/types/client/ToolActivity.js.map +1 -1
- package/lib/types/client/index.d.ts +3 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +6 -0
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/live-turn.d.ts +17 -5
- package/lib/types/client/live-turn.d.ts.map +1 -1
- package/lib/types/client/live-turn.js +106 -76
- package/lib/types/client/live-turn.js.map +1 -1
- package/lib/types/client/motion.d.ts +26 -2
- package/lib/types/client/motion.d.ts.map +1 -1
- package/lib/types/client/motion.js +136 -10
- package/lib/types/client/motion.js.map +1 -1
- package/lib/types/client/official-slots.d.ts +24 -3
- package/lib/types/client/official-slots.d.ts.map +1 -1
- package/lib/types/client/official-slots.js +59 -11
- package/lib/types/client/official-slots.js.map +1 -1
- package/lib/types/client/primitive-labels.d.ts.map +1 -1
- package/lib/types/client/primitive-labels.js +1 -0
- package/lib/types/client/primitive-labels.js.map +1 -1
- package/lib/types/client/projection.d.ts +15 -2
- package/lib/types/client/projection.d.ts.map +1 -1
- package/lib/types/client/projection.js +16 -4
- package/lib/types/client/projection.js.map +1 -1
- package/lib/types/client/rewind-cut.d.ts +131 -0
- package/lib/types/client/rewind-cut.d.ts.map +1 -0
- package/lib/types/client/rewind-cut.js +321 -0
- package/lib/types/client/rewind-cut.js.map +1 -0
- package/lib/types/client/text-transform.d.ts +93 -0
- package/lib/types/client/text-transform.d.ts.map +1 -0
- package/lib/types/client/text-transform.js +183 -0
- package/lib/types/client/text-transform.js.map +1 -0
- package/lib/types/client/timeline.d.ts.map +1 -1
- package/lib/types/client/timeline.js.map +1 -1
- package/lib/types/client/tool-activity.d.ts +9 -2
- package/lib/types/client/tool-activity.d.ts.map +1 -1
- package/lib/types/client/tool-activity.js +42 -2
- package/lib/types/client/tool-activity.js.map +1 -1
- package/lib/types/client/turn-slots.d.ts +29 -0
- package/lib/types/client/turn-slots.d.ts.map +1 -0
- package/lib/types/client/turn-slots.js +62 -0
- package/lib/types/client/turn-slots.js.map +1 -0
- package/lib/types/client/types.d.ts +18 -0
- package/lib/types/client/types.d.ts.map +1 -1
- package/lib/types/dsh-better-display.d.ts +4 -1
- package/lib/types/dsh-better-display.d.ts.map +1 -1
- package/lib/types/dsh-better-display.js +56 -7
- package/lib/types/dsh-better-display.js.map +1 -1
- package/lib/types/flags.d.ts +7 -0
- package/lib/types/flags.d.ts.map +1 -0
- package/lib/types/flags.js +37 -0
- package/lib/types/flags.js.map +1 -0
- package/lib/types/log.d.ts +17 -0
- package/lib/types/log.d.ts.map +1 -0
- package/lib/types/log.js +122 -0
- package/lib/types/log.js.map +1 -0
- package/lib/types/metrics.d.ts +18 -0
- package/lib/types/metrics.d.ts.map +1 -0
- package/lib/types/metrics.js +35 -0
- package/lib/types/metrics.js.map +1 -0
- package/package.json +55 -23
- package/scripts/changelog.mjs +20 -0
- package/scripts/check-agents-md.mjs +67 -0
- package/scripts/check-bundle-size.mjs +38 -0
- package/scripts/check-dead-flags.mjs +55 -0
- package/scripts/check-harness-compat.mjs +4 -2
- package/scripts/check-todo-debt.mjs +69 -0
- package/scripts/link-harness-dependencies.mjs +48 -11
- package/scripts/security-audit-report.mjs +92 -0
- package/scripts/verify-commentary-visible.mjs +627 -0
- package/src/client/AssistantNode.tsx +72 -0
- package/src/client/Blocks.tsx +49 -10
- package/src/client/ChoreographedFlow.tsx +3 -1
- package/src/client/ClosedProcessSummary.tsx +3 -1
- package/src/client/McpAppFrame.tsx +5 -13
- package/src/client/OfficialContent.tsx +52 -14
- package/src/client/Reader.module.css +68 -18
- package/src/client/Reader.tsx +38 -82
- package/src/client/SettingsSection.tsx +1 -7
- package/src/client/StickyLane.tsx +81 -2
- package/src/client/ToolActivity.tsx +1 -1
- package/src/client/index.tsx +8 -1
- package/src/client/live-turn.ts +100 -69
- package/src/client/motion.tsx +135 -7
- package/src/client/official-slots.tsx +61 -12
- package/src/client/primitive-labels.ts +1 -0
- package/src/client/projection.ts +16 -4
- package/src/client/rewind-cut.ts +340 -0
- package/src/client/text-transform.ts +265 -0
- package/src/client/timeline.ts +0 -2
- package/src/client/tool-activity.ts +49 -2
- package/src/client/turn-slots.ts +80 -0
- package/src/client/types.ts +19 -0
- package/src/dsh-better-display.ts +58 -7
- package/src/flags.ts +40 -0
- package/src/log.ts +137 -0
- package/src/metrics.ts +50 -0
- package/tests/browser-commentary.tsx +191 -0
- package/tests/browser-official-bridge.tsx +2 -1
- package/tests/chat-flow-hook.test.ts +1 -1
- package/tests/cloud-gate.test.ts +1 -1
- package/tests/context-tool-update.test.ts +1 -1
- package/tests/conversation-scroll.test.ts +1 -1
- package/tests/deliverables.test.ts +1 -1
- package/tests/entry.test.ts +1 -1
- package/tests/fixtures/reader-lane-owners.tsx +46 -0
- package/tests/fixtures/reader-official-users.tsx +64 -0
- package/tests/fixtures/reader-theme-overlap.html +80 -0
- package/tests/fixtures/reader-user-bubble.tsx +244 -0
- package/tests/flags.test.ts +66 -0
- package/tests/fold-choreography.test.ts +32 -8
- package/tests/fold-intensity.test.ts +11 -6
- package/tests/footer-precedence.test.ts +1 -1
- package/tests/history-word-regression.test.ts +1 -1
- package/tests/live-turn.test.ts +125 -54
- package/tests/log.test.ts +99 -0
- package/tests/mcp-apps.test.ts +1 -1
- package/tests/message-chrome.test.ts +1 -1
- package/tests/metrics.test.ts +52 -0
- package/tests/official-slots.test.ts +41 -2
- package/tests/open-file.test.ts +1 -1
- package/tests/pending-submission.test.ts +12 -1
- package/tests/pinned-selection.test.ts +16 -0
- package/tests/platform-media.test.ts +1 -1
- package/tests/projection.test.ts +66 -3
- package/tests/reader-glass-css.test.ts +1 -1
- package/tests/reader-official-users.test.ts +11 -1
- package/tests/reader-sticky-surface.test.ts +377 -0
- package/tests/reader-theme-lanes.test.ts +54 -0
- package/tests/reader-theme-overlap.test.ts +151 -0
- package/tests/reader-user-bubble.test.ts +138 -0
- package/tests/reasoning-follow.test.ts +1 -1
- package/tests/retiring-content.test.ts +98 -6
- package/tests/reveal.test.ts +3 -3
- package/tests/rewind-cut.test.ts +1090 -0
- package/tests/settings-copy.test.ts +1 -1
- package/tests/skill-status.test.ts +1 -1
- package/tests/stock-install.test.ts +11 -7
- package/tests/stream-buffer.test.ts +1 -1
- package/tests/styles.test.ts +30 -3
- package/tests/terminal-input-preview.test.ts +1 -1
- package/tests/text-transform.test.ts +272 -0
- package/tests/timeline.test.ts +1 -1
- package/tests/tool-clock.test.ts +1 -1
- package/tests/tool-diff.test.ts +1 -1
- package/tests/waiting-clock.test.ts +1 -1
- package/tests/word-timeline.test.ts +1 -1
|
@@ -1,10 +1,328 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { homedir } from "node:os";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
2
|
import { dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
|
|
5
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
6
5
|
import { spawn } from "node:child_process";
|
|
7
|
-
|
|
6
|
+
import { access, readdir } from "node:fs/promises";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
// src/flags.ts
|
|
9
|
+
const defaultFlags = { readerEnabled: true };
|
|
10
|
+
function locateFlags(start = dirname(fileURLToPath(import.meta.url))) {
|
|
11
|
+
let dir = start;
|
|
12
|
+
for (let depth = 0; depth < 6; depth += 1) {
|
|
13
|
+
const candidate = resolve(dir, "flags.json");
|
|
14
|
+
if (existsSync(candidate)) return candidate;
|
|
15
|
+
const parent = dirname(dir);
|
|
16
|
+
if (parent === dir) return void 0;
|
|
17
|
+
dir = parent;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function normalize(value) {
|
|
21
|
+
const record = value !== null && typeof value === "object" ? value : {};
|
|
22
|
+
return { readerEnabled: typeof record.readerEnabled === "boolean" ? record.readerEnabled : defaultFlags.readerEnabled };
|
|
23
|
+
}
|
|
24
|
+
function loadFlags(source) {
|
|
25
|
+
if (source !== void 0 && typeof source !== "string") return normalize(source);
|
|
26
|
+
try {
|
|
27
|
+
const path = typeof source === "string" ? source : locateFlags();
|
|
28
|
+
if (path === void 0 || !existsSync(path)) return { ...defaultFlags };
|
|
29
|
+
return normalize(JSON.parse(readFileSync(path, "utf8")));
|
|
30
|
+
} catch {
|
|
31
|
+
return { ...defaultFlags };
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// src/log.ts
|
|
35
|
+
const REDACTED = "[REDACTED]";
|
|
36
|
+
const REQUEST_ID_HEADER = "x-request-id";
|
|
37
|
+
const REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,200}$/;
|
|
38
|
+
const SECRET_KEYS = /* @__PURE__ */ new Set([
|
|
39
|
+
"authorization",
|
|
40
|
+
"proxyauthorization",
|
|
41
|
+
"cookie",
|
|
42
|
+
"setcookie",
|
|
43
|
+
"token",
|
|
44
|
+
"accesstoken",
|
|
45
|
+
"refreshtoken",
|
|
46
|
+
"idtoken",
|
|
47
|
+
"apikey",
|
|
48
|
+
"apisecret",
|
|
49
|
+
"secret",
|
|
50
|
+
"clientsecret",
|
|
51
|
+
"password",
|
|
52
|
+
"passwd",
|
|
53
|
+
"credential",
|
|
54
|
+
"credentials",
|
|
55
|
+
"signature",
|
|
56
|
+
"sig",
|
|
57
|
+
"jwt",
|
|
58
|
+
"bearer",
|
|
59
|
+
"privatekey",
|
|
60
|
+
"xapikey",
|
|
61
|
+
"xauthtoken",
|
|
62
|
+
"xaccesstoken",
|
|
63
|
+
"auth"
|
|
64
|
+
]);
|
|
65
|
+
function normalizeKey(key) {
|
|
66
|
+
return key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
67
|
+
}
|
|
68
|
+
function isSecretKey(key) {
|
|
69
|
+
const normalized = normalizeKey(key);
|
|
70
|
+
if (SECRET_KEYS.has(normalized)) return true;
|
|
71
|
+
if (normalized === "requestid" || normalized === "xrequestid") return false;
|
|
72
|
+
return /(?:^|[^a-z])(?:token|secret|password|api[-_]?key)$/i.test(key);
|
|
73
|
+
}
|
|
74
|
+
function redactString(value) {
|
|
75
|
+
return value.replace(/([?&#])([^&#=]+)=([^&#]*)/g, (match, sep, rawKey) => {
|
|
76
|
+
let key;
|
|
77
|
+
try {
|
|
78
|
+
key = decodeURIComponent(rawKey.replace(/\+/g, " "));
|
|
79
|
+
} catch {
|
|
80
|
+
key = rawKey;
|
|
81
|
+
}
|
|
82
|
+
return isSecretKey(key) ? `${sep}${rawKey}=${REDACTED}` : match;
|
|
83
|
+
}).replace(/\b(Bearer|Basic)\s+\S+/gi, `$1 ${REDACTED}`).replace(/\b((?:access[_-]?token|refresh[_-]?token|id[_-]?token|api[_-]?key|client[_-]?secret|password|passwd|authorization|token|secret))(\s*[:=]\s*)([^\s&]+)/gi, `$1$2${REDACTED}`);
|
|
84
|
+
}
|
|
85
|
+
function redact(value) {
|
|
86
|
+
return redactValue(void 0, value, 0, /* @__PURE__ */ new WeakSet());
|
|
87
|
+
}
|
|
88
|
+
function redactValue(key, value, depth, seen) {
|
|
89
|
+
if (key !== void 0 && isSecretKey(key)) return REDACTED;
|
|
90
|
+
if (depth > 8) return REDACTED;
|
|
91
|
+
if (typeof value === "string") return redactString(value);
|
|
92
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) return value;
|
|
93
|
+
if (typeof value !== "object") return REDACTED;
|
|
94
|
+
if (value instanceof Date) return value.toISOString();
|
|
95
|
+
if (value instanceof Error) return redactValue(void 0, {
|
|
96
|
+
name: value.name,
|
|
97
|
+
message: value.message
|
|
98
|
+
}, depth + 1, seen);
|
|
99
|
+
if (seen.has(value)) return REDACTED;
|
|
100
|
+
seen.add(value);
|
|
101
|
+
if (Array.isArray(value)) return value.map((item) => redactValue(void 0, item, depth + 1, seen));
|
|
102
|
+
const output = {};
|
|
103
|
+
for (const [childKey, childValue] of Object.entries(value)) output[childKey] = redactValue(childKey, childValue, depth + 1, seen);
|
|
104
|
+
return output;
|
|
105
|
+
}
|
|
106
|
+
function createLogger(options = {}) {
|
|
107
|
+
const write = options.write ?? ((line) => {
|
|
108
|
+
console.log(line);
|
|
109
|
+
});
|
|
110
|
+
const clock = options.clock ?? (() => /* @__PURE__ */ new Date());
|
|
111
|
+
const emit = (level, msg, fields) => {
|
|
112
|
+
const details = redact({
|
|
113
|
+
...options.base,
|
|
114
|
+
...fields
|
|
115
|
+
});
|
|
116
|
+
const record = {
|
|
117
|
+
...details !== null && typeof details === "object" ? details : {},
|
|
118
|
+
time: clock().toISOString(),
|
|
119
|
+
level,
|
|
120
|
+
msg: redactString(msg)
|
|
121
|
+
};
|
|
122
|
+
try {
|
|
123
|
+
write(JSON.stringify(record));
|
|
124
|
+
} catch {
|
|
125
|
+
write(JSON.stringify({
|
|
126
|
+
time: record.time,
|
|
127
|
+
level,
|
|
128
|
+
msg: record.msg,
|
|
129
|
+
error: "log record was not serializable"
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
info: (msg, fields) => emit("info", msg, fields),
|
|
135
|
+
warn: (msg, fields) => emit("warn", msg, fields),
|
|
136
|
+
error: (msg, fields) => emit("error", msg, fields)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function requestIdOf(req) {
|
|
140
|
+
const raw = req.headers[REQUEST_ID_HEADER];
|
|
141
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
142
|
+
if (typeof value === "string" && REQUEST_ID_PATTERN.test(value)) return value;
|
|
143
|
+
return randomUUID();
|
|
144
|
+
}
|
|
145
|
+
// src/metrics.ts
|
|
146
|
+
const ROUTE_REVEAL = "/better-display/reveal";
|
|
147
|
+
const ROUTE_SKILL_STATUS = "/better-display/skill-status";
|
|
148
|
+
const ROUTE_METRICS = "/better-display/metrics";
|
|
149
|
+
const ROUTE_HITS = [
|
|
150
|
+
ROUTE_REVEAL,
|
|
151
|
+
ROUTE_SKILL_STATUS,
|
|
152
|
+
ROUTE_METRICS
|
|
153
|
+
];
|
|
154
|
+
const hits = new Map(ROUTE_HITS.map((route) => [route, 0]));
|
|
155
|
+
const timings = new Map(ROUTE_HITS.map((route) => [route, {
|
|
156
|
+
count: 0,
|
|
157
|
+
totalMs: 0,
|
|
158
|
+
maxMs: 0
|
|
159
|
+
}]));
|
|
160
|
+
function snapshotHits() {
|
|
161
|
+
return Object.fromEntries(hits);
|
|
162
|
+
}
|
|
163
|
+
function snapshotTimings() {
|
|
164
|
+
return Object.fromEntries([...timings].map(([route, timing]) => [route, { ...timing }]));
|
|
165
|
+
}
|
|
166
|
+
function recordRouteHit(route) {
|
|
167
|
+
const next = (hits.get(route) ?? 0) + 1;
|
|
168
|
+
hits.set(route, next);
|
|
169
|
+
return next;
|
|
170
|
+
}
|
|
171
|
+
function recordRouteDuration(route, elapsedMs) {
|
|
172
|
+
const ms = Number.isFinite(elapsedMs) && elapsedMs > 0 ? Math.round(elapsedMs) : 0;
|
|
173
|
+
const current = timings.get(route) ?? {
|
|
174
|
+
count: 0,
|
|
175
|
+
totalMs: 0,
|
|
176
|
+
maxMs: 0
|
|
177
|
+
};
|
|
178
|
+
const next = {
|
|
179
|
+
count: current.count + 1,
|
|
180
|
+
totalMs: current.totalMs + ms,
|
|
181
|
+
maxMs: Math.max(current.maxMs, ms)
|
|
182
|
+
};
|
|
183
|
+
timings.set(route, next);
|
|
184
|
+
return next;
|
|
185
|
+
}
|
|
186
|
+
function metricsPayload() {
|
|
187
|
+
return {
|
|
188
|
+
counters: { dsh_better_display_route_hits_total: snapshotHits() },
|
|
189
|
+
timingsMs: snapshotTimings()
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
// src/workspace-path.ts
|
|
193
|
+
/** Absolute paths accepted by both POSIX and Windows hosts. */
|
|
194
|
+
function isAbsoluteWorkspacePath(path) {
|
|
195
|
+
return /^(?:\/|[A-Za-z]:[/\\]|\\\\)/.test(path);
|
|
196
|
+
}
|
|
197
|
+
// \0@oxc-project+runtime@0.156.0/helpers/esm/usingCtx.js
|
|
198
|
+
function _usingCtx() {
|
|
199
|
+
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
200
|
+
var n = Error();
|
|
201
|
+
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
202
|
+
}, e = {}, n = [];
|
|
203
|
+
function using(r, e) {
|
|
204
|
+
if (null != e) {
|
|
205
|
+
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
206
|
+
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
207
|
+
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
208
|
+
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
209
|
+
t && (o = function o() {
|
|
210
|
+
try {
|
|
211
|
+
t.call(e);
|
|
212
|
+
} catch (r) {
|
|
213
|
+
return Promise.reject(r);
|
|
214
|
+
}
|
|
215
|
+
}), n.push({
|
|
216
|
+
v: e,
|
|
217
|
+
d: o,
|
|
218
|
+
a: r
|
|
219
|
+
});
|
|
220
|
+
} else r && n.push({
|
|
221
|
+
d: e,
|
|
222
|
+
a: r
|
|
223
|
+
});
|
|
224
|
+
return e;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
e,
|
|
228
|
+
u: using.bind(null, !1),
|
|
229
|
+
a: using.bind(null, !0),
|
|
230
|
+
d: function d() {
|
|
231
|
+
var o, t = this.e, s = 0;
|
|
232
|
+
function next() {
|
|
233
|
+
for (; o = n.pop();) try {
|
|
234
|
+
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
235
|
+
if (o.d) {
|
|
236
|
+
var r = o.d.call(o.v);
|
|
237
|
+
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
238
|
+
} else s |= 1;
|
|
239
|
+
} catch (r) {
|
|
240
|
+
return err(r);
|
|
241
|
+
}
|
|
242
|
+
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
243
|
+
if (t !== e) throw t;
|
|
244
|
+
}
|
|
245
|
+
function err(n) {
|
|
246
|
+
return t = t !== e ? new r(n, t) : n, next();
|
|
247
|
+
}
|
|
248
|
+
return next();
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
// src/reveal.ts
|
|
253
|
+
async function revealRoots(ctx, sessionId) {
|
|
254
|
+
if (sessionId !== void 0) {
|
|
255
|
+
const cwd = (ctx.get?.("sessions"))?.get(sessionId)?.header.cwd;
|
|
256
|
+
if (cwd) return [cwd];
|
|
257
|
+
const query = ctx.get?.("sessionQuery");
|
|
258
|
+
if (query) try {
|
|
259
|
+
var _usingCtx$1 = _usingCtx();
|
|
260
|
+
const observation = _usingCtx$1.u(await query.observeSession(sessionId, { projectionMode: "none" }));
|
|
261
|
+
if (observation.header.cwd) return [observation.header.cwd];
|
|
262
|
+
} catch (_) {
|
|
263
|
+
_usingCtx$1.e = _;
|
|
264
|
+
} finally {
|
|
265
|
+
_usingCtx$1.d();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return ((ctx.get?.("workspaceRegistry"))?.list() ?? []).filter((workspace) => sessionId === void 0 || workspace.sessionIds.includes(sessionId)).map((workspace) => workspace.path);
|
|
269
|
+
}
|
|
270
|
+
function resolveRevealPath(path, roots, exists = existsSync) {
|
|
271
|
+
if (isAbsoluteWorkspacePath(path)) return path;
|
|
272
|
+
if (/^[A-Za-z]:|^\\/.test(path)) throw new Error("Path is not workspace-relative");
|
|
273
|
+
const matches = /* @__PURE__ */ new Set();
|
|
274
|
+
for (const root of roots) {
|
|
275
|
+
if (!isAbsoluteWorkspacePath(root)) continue;
|
|
276
|
+
const candidate = (/^[A-Za-z]:[/\\]|^\\\\/.test(root) ? win32 : posix).resolve(root, path);
|
|
277
|
+
if (exists(candidate)) matches.add(candidate);
|
|
278
|
+
}
|
|
279
|
+
if (matches.size !== 1) throw new Error(matches.size === 0 ? "Workspace path not found" : "Workspace path is ambiguous");
|
|
280
|
+
return [...matches][0];
|
|
281
|
+
}
|
|
282
|
+
function revealPath(path, platform = process.platform, spawnProcess = spawn) {
|
|
283
|
+
const options = {
|
|
284
|
+
detached: true,
|
|
285
|
+
stdio: "ignore"
|
|
286
|
+
};
|
|
287
|
+
if (platform === "darwin") spawnProcess("open", ["-R", path], options);
|
|
288
|
+
else if (platform === "win32") spawnProcess("explorer.exe", [`/select,"${path}"`], {
|
|
289
|
+
...options,
|
|
290
|
+
windowsVerbatimArguments: true
|
|
291
|
+
});
|
|
292
|
+
else spawnProcess("xdg-open", [path], options);
|
|
293
|
+
}
|
|
294
|
+
function createRevealHandler({ roots, reveal = revealPath }) {
|
|
295
|
+
return (req, res) => {
|
|
296
|
+
if (req.method !== "POST") {
|
|
297
|
+
res.statusCode = 405;
|
|
298
|
+
res.end();
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
let body = "";
|
|
302
|
+
req.on("data", (chunk) => {
|
|
303
|
+
body += chunk;
|
|
304
|
+
});
|
|
305
|
+
req.on("end", async () => {
|
|
306
|
+
res.setHeader("Content-Type", "application/json");
|
|
307
|
+
try {
|
|
308
|
+
const data = JSON.parse(body);
|
|
309
|
+
const path = typeof data === "object" && data !== null && "path" in data && typeof data.path === "string" ? data.path.trim() : "";
|
|
310
|
+
if (!path) throw new Error("Empty path");
|
|
311
|
+
const sessionId = typeof data === "object" && data !== null && "sessionId" in data && typeof data.sessionId === "string" ? data.sessionId : void 0;
|
|
312
|
+
reveal(resolveRevealPath(path, isAbsoluteWorkspacePath(path) ? [] : await roots(sessionId)));
|
|
313
|
+
res.statusCode = 200;
|
|
314
|
+
res.end(JSON.stringify({ ok: true }));
|
|
315
|
+
} catch (err) {
|
|
316
|
+
res.statusCode = 400;
|
|
317
|
+
res.end(JSON.stringify({
|
|
318
|
+
ok: false,
|
|
319
|
+
error: String(err)
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
// src/skill-status.ts
|
|
8
326
|
/** Shared generative-mcpapps identity. Plugin-tree presence is not installation. */
|
|
9
327
|
const GENERATIVE_MCPAPPS_SKILL = "generative-mcpapps";
|
|
10
328
|
/** Conventional relative roots only. Never expand $HOME or dump host `root.path`. */
|
|
@@ -50,8 +368,7 @@ function toPublicSkillStatus(status) {
|
|
|
50
368
|
roots: publicSkillRoots()
|
|
51
369
|
};
|
|
52
370
|
}
|
|
53
|
-
|
|
54
|
-
//#region src/skill-roots.ts
|
|
371
|
+
// src/skill-roots.ts
|
|
55
372
|
function expandHomePath(path, home = homedir()) {
|
|
56
373
|
if (path === "~") return home;
|
|
57
374
|
if (path.startsWith("~/") || path.startsWith("~\\")) return join(home, path.slice(2));
|
|
@@ -155,146 +472,10 @@ async function scanGenerativeMcpappsStatus(options = {}) {
|
|
|
155
472
|
...packPath !== void 0 ? { packPath } : {}
|
|
156
473
|
};
|
|
157
474
|
}
|
|
158
|
-
|
|
159
|
-
//#region src/workspace-path.ts
|
|
160
|
-
/** Absolute paths accepted by both POSIX and Windows hosts. */
|
|
161
|
-
function isAbsoluteWorkspacePath(path) {
|
|
162
|
-
return /^(?:\/|[A-Za-z]:[/\\]|\\\\)/.test(path);
|
|
163
|
-
}
|
|
164
|
-
//#endregion
|
|
165
|
-
//#region \0@oxc-project+runtime@0.153.0/helpers/esm/usingCtx.js
|
|
166
|
-
function _usingCtx() {
|
|
167
|
-
var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
|
|
168
|
-
var n = Error();
|
|
169
|
-
return n.name = "SuppressedError", n.error = r, n.suppressed = e, n;
|
|
170
|
-
}, e = {}, n = [];
|
|
171
|
-
function using(r, e) {
|
|
172
|
-
if (null != e) {
|
|
173
|
-
if (Object(e) !== e) throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
|
|
174
|
-
if (r) var o = e[Symbol.asyncDispose || Symbol["for"]("Symbol.asyncDispose")];
|
|
175
|
-
if (void 0 === o && (o = e[Symbol.dispose || Symbol["for"]("Symbol.dispose")], r)) var t = o;
|
|
176
|
-
if ("function" != typeof o) throw new TypeError("Object is not disposable.");
|
|
177
|
-
t && (o = function o() {
|
|
178
|
-
try {
|
|
179
|
-
t.call(e);
|
|
180
|
-
} catch (r) {
|
|
181
|
-
return Promise.reject(r);
|
|
182
|
-
}
|
|
183
|
-
}), n.push({
|
|
184
|
-
v: e,
|
|
185
|
-
d: o,
|
|
186
|
-
a: r
|
|
187
|
-
});
|
|
188
|
-
} else r && n.push({
|
|
189
|
-
d: e,
|
|
190
|
-
a: r
|
|
191
|
-
});
|
|
192
|
-
return e;
|
|
193
|
-
}
|
|
194
|
-
return {
|
|
195
|
-
e,
|
|
196
|
-
u: using.bind(null, !1),
|
|
197
|
-
a: using.bind(null, !0),
|
|
198
|
-
d: function d() {
|
|
199
|
-
var o, t = this.e, s = 0;
|
|
200
|
-
function next() {
|
|
201
|
-
for (; o = n.pop();) try {
|
|
202
|
-
if (!o.a && 1 === s) return s = 0, n.push(o), Promise.resolve().then(next);
|
|
203
|
-
if (o.d) {
|
|
204
|
-
var r = o.d.call(o.v);
|
|
205
|
-
if (o.a) return s |= 2, Promise.resolve(r).then(next, err);
|
|
206
|
-
} else s |= 1;
|
|
207
|
-
} catch (r) {
|
|
208
|
-
return err(r);
|
|
209
|
-
}
|
|
210
|
-
if (1 === s) return t !== e ? Promise.reject(t) : Promise.resolve();
|
|
211
|
-
if (t !== e) throw t;
|
|
212
|
-
}
|
|
213
|
-
function err(n) {
|
|
214
|
-
return t = t !== e ? new r(n, t) : n, next();
|
|
215
|
-
}
|
|
216
|
-
return next();
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
//#endregion
|
|
221
|
-
//#region src/reveal.ts
|
|
222
|
-
async function revealRoots(ctx, sessionId) {
|
|
223
|
-
if (sessionId !== void 0) {
|
|
224
|
-
const cwd = (ctx.get?.("sessions"))?.get(sessionId)?.header.cwd;
|
|
225
|
-
if (cwd) return [cwd];
|
|
226
|
-
const query = ctx.get?.("sessionQuery");
|
|
227
|
-
if (query) try {
|
|
228
|
-
var _usingCtx$1 = _usingCtx();
|
|
229
|
-
const observation = _usingCtx$1.u(await query.observeSession(sessionId, { projectionMode: "none" }));
|
|
230
|
-
if (observation.header.cwd) return [observation.header.cwd];
|
|
231
|
-
} catch (_) {
|
|
232
|
-
_usingCtx$1.e = _;
|
|
233
|
-
} finally {
|
|
234
|
-
_usingCtx$1.d();
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return ((ctx.get?.("workspaceRegistry"))?.list() ?? []).filter((workspace) => sessionId === void 0 || workspace.sessionIds.includes(sessionId)).map((workspace) => workspace.path);
|
|
238
|
-
}
|
|
239
|
-
function resolveRevealPath(path, roots, exists = existsSync) {
|
|
240
|
-
if (isAbsoluteWorkspacePath(path)) return path;
|
|
241
|
-
if (/^[A-Za-z]:|^\\/.test(path)) throw new Error("Path is not workspace-relative");
|
|
242
|
-
const matches = /* @__PURE__ */ new Set();
|
|
243
|
-
for (const root of roots) {
|
|
244
|
-
if (!isAbsoluteWorkspacePath(root)) continue;
|
|
245
|
-
const candidate = (/^[A-Za-z]:[/\\]|^\\\\/.test(root) ? win32 : posix).resolve(root, path);
|
|
246
|
-
if (exists(candidate)) matches.add(candidate);
|
|
247
|
-
}
|
|
248
|
-
if (matches.size !== 1) throw new Error(matches.size === 0 ? "Workspace path not found" : "Workspace path is ambiguous");
|
|
249
|
-
return [...matches][0];
|
|
250
|
-
}
|
|
251
|
-
function revealPath(path, platform = process.platform, spawnProcess = spawn) {
|
|
252
|
-
const options = {
|
|
253
|
-
detached: true,
|
|
254
|
-
stdio: "ignore"
|
|
255
|
-
};
|
|
256
|
-
if (platform === "darwin") spawnProcess("open", ["-R", path], options);
|
|
257
|
-
else if (platform === "win32") spawnProcess("explorer.exe", [`/select,"${path}"`], {
|
|
258
|
-
...options,
|
|
259
|
-
windowsVerbatimArguments: true
|
|
260
|
-
});
|
|
261
|
-
else spawnProcess("xdg-open", [path], options);
|
|
262
|
-
}
|
|
263
|
-
function createRevealHandler({ roots, reveal = revealPath }) {
|
|
264
|
-
return (req, res) => {
|
|
265
|
-
if (req.method !== "POST") {
|
|
266
|
-
res.statusCode = 405;
|
|
267
|
-
res.end();
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
let body = "";
|
|
271
|
-
req.on("data", (chunk) => {
|
|
272
|
-
body += chunk;
|
|
273
|
-
});
|
|
274
|
-
req.on("end", async () => {
|
|
275
|
-
res.setHeader("Content-Type", "application/json");
|
|
276
|
-
try {
|
|
277
|
-
const data = JSON.parse(body);
|
|
278
|
-
const path = typeof data === "object" && data !== null && "path" in data && typeof data.path === "string" ? data.path.trim() : "";
|
|
279
|
-
if (!path) throw new Error("Empty path");
|
|
280
|
-
const sessionId = typeof data === "object" && data !== null && "sessionId" in data && typeof data.sessionId === "string" ? data.sessionId : void 0;
|
|
281
|
-
reveal(resolveRevealPath(path, isAbsoluteWorkspacePath(path) ? [] : await roots(sessionId)));
|
|
282
|
-
res.statusCode = 200;
|
|
283
|
-
res.end(JSON.stringify({ ok: true }));
|
|
284
|
-
} catch (err) {
|
|
285
|
-
res.statusCode = 400;
|
|
286
|
-
res.end(JSON.stringify({
|
|
287
|
-
ok: false,
|
|
288
|
-
error: String(err)
|
|
289
|
-
}));
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
//#endregion
|
|
295
|
-
//#region src/dsh-better-display.ts
|
|
475
|
+
// src/dsh-better-display.ts
|
|
296
476
|
const name = "dsh-better-display";
|
|
297
477
|
const inject = ["webServer"];
|
|
478
|
+
const log = createLogger({ base: { plugin: name } });
|
|
298
479
|
function writeJson(res, status, body) {
|
|
299
480
|
res.setHeader("Content-Type", "application/json");
|
|
300
481
|
res.statusCode = status;
|
|
@@ -305,18 +486,45 @@ function skillLister(ctx) {
|
|
|
305
486
|
if (typeof skills?.list !== "function") return void 0;
|
|
306
487
|
return async () => skillsFromListResult(await skills.list({}));
|
|
307
488
|
}
|
|
308
|
-
function
|
|
309
|
-
|
|
489
|
+
function beginRequest(req, res, route) {
|
|
490
|
+
const requestId = requestIdOf(req);
|
|
491
|
+
res.setHeader("X-Request-ID", requestId);
|
|
492
|
+
recordRouteHit(route);
|
|
493
|
+
const started = performance.now();
|
|
494
|
+
res.on("finish", () => {
|
|
495
|
+
recordRouteDuration(route, performance.now() - started);
|
|
496
|
+
});
|
|
497
|
+
log.info("http request", {
|
|
498
|
+
requestId,
|
|
499
|
+
route,
|
|
500
|
+
method: req.method ?? "",
|
|
501
|
+
url: req.url ?? "",
|
|
502
|
+
headers: req.headers
|
|
503
|
+
});
|
|
504
|
+
return requestId;
|
|
505
|
+
}
|
|
506
|
+
function apply(ctx, options) {
|
|
507
|
+
const flags = options?.flags ?? loadFlags();
|
|
508
|
+
log.info("[my-plugins/dsh-better-display] loaded", { readerEnabled: flags.readerEnabled });
|
|
509
|
+
if (!flags.readerEnabled) {
|
|
510
|
+
log.info("route registration skipped", { readerEnabled: false });
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
310
513
|
if (ctx.webServer) ctx.effect(() => {
|
|
514
|
+
const reveal = createRevealHandler({ roots: (sessionId) => revealRoots(ctx, sessionId) });
|
|
311
515
|
const disposeReveal = ctx.webServer.register({
|
|
312
516
|
kind: "exact",
|
|
313
|
-
path:
|
|
314
|
-
handler:
|
|
517
|
+
path: ROUTE_REVEAL,
|
|
518
|
+
handler: (req, res) => {
|
|
519
|
+
beginRequest(req, res, ROUTE_REVEAL);
|
|
520
|
+
reveal(req, res);
|
|
521
|
+
}
|
|
315
522
|
});
|
|
316
523
|
const disposeSkill = ctx.webServer.register({
|
|
317
524
|
kind: "exact",
|
|
318
|
-
path:
|
|
525
|
+
path: ROUTE_SKILL_STATUS,
|
|
319
526
|
handler: async (req, res) => {
|
|
527
|
+
const requestId = beginRequest(req, res, ROUTE_SKILL_STATUS);
|
|
320
528
|
if (req.method !== "GET") {
|
|
321
529
|
res.statusCode = 405;
|
|
322
530
|
res.end();
|
|
@@ -328,6 +536,10 @@ function apply(ctx) {
|
|
|
328
536
|
listSkills: skillLister(ctx)
|
|
329
537
|
})));
|
|
330
538
|
} catch (err) {
|
|
539
|
+
log.error("skill-status failed", {
|
|
540
|
+
requestId,
|
|
541
|
+
error: err instanceof Error ? err.message : String(err)
|
|
542
|
+
});
|
|
331
543
|
writeJson(res, 500, {
|
|
332
544
|
ok: false,
|
|
333
545
|
error: String(err)
|
|
@@ -335,11 +547,24 @@ function apply(ctx) {
|
|
|
335
547
|
}
|
|
336
548
|
}
|
|
337
549
|
});
|
|
550
|
+
const disposeMetrics = ctx.webServer.register({
|
|
551
|
+
kind: "exact",
|
|
552
|
+
path: ROUTE_METRICS,
|
|
553
|
+
handler: (req, res) => {
|
|
554
|
+
beginRequest(req, res, ROUTE_METRICS);
|
|
555
|
+
if (req.method !== "GET") {
|
|
556
|
+
res.statusCode = 405;
|
|
557
|
+
res.end();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
writeJson(res, 200, metricsPayload());
|
|
561
|
+
}
|
|
562
|
+
});
|
|
338
563
|
return () => {
|
|
339
564
|
disposeReveal();
|
|
340
565
|
disposeSkill();
|
|
566
|
+
disposeMetrics();
|
|
341
567
|
};
|
|
342
|
-
}, "dsh-better-display: reveal
|
|
568
|
+
}, "dsh-better-display: reveal, skill-status, and metrics routes");
|
|
343
569
|
}
|
|
344
|
-
//#endregion
|
|
345
570
|
export { apply, inject, name };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
import type { TurnBoundary } from './projection.js';
|
|
3
|
+
import type { BlockRenderProps, ReaderProps } from './types.js';
|
|
4
|
+
type SeatProps = BlockRenderProps & Pick<ReaderProps, 'useChat' | 'sessionId'> & {
|
|
5
|
+
nodeKey: string;
|
|
6
|
+
boundary: TurnBoundary;
|
|
7
|
+
pinned?: boolean;
|
|
8
|
+
processOpen?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare const AssistantNode: import("react").MemoExoticComponent<({ useChat, nodeKey, boundary, processOpen, pinned, folded, partStart, seamSummary, seamAfter, motion, onRead, returnFocusTo, ...render }: SeatProps & {
|
|
11
|
+
motion: boolean;
|
|
12
|
+
onRead: () => void;
|
|
13
|
+
returnFocusTo: RefObject<HTMLButtonElement>;
|
|
14
|
+
partStart?: number;
|
|
15
|
+
folded?: boolean;
|
|
16
|
+
seamSummary?: string;
|
|
17
|
+
seamAfter?: boolean;
|
|
18
|
+
}) => import("react").JSX.Element | null>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=AssistantNode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantNode.d.ts","sourceRoot":"","sources":["../../../src/client/AssistantNode.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAOhE,KAAK,SAAS,GAAG,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC,GAAG;IAC/E,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAClF,CAAC;AAEF,eAAO,MAAM,aAAa,iLAAyM,SAAS,GAAG;IAC7O,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAC;IAAC,aAAa,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACvH,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC3C,wCA+CC,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, memo } from 'react';
|
|
3
|
+
import { Blocks, CopyAnswer } from './Blocks.js';
|
|
4
|
+
import { ReasoningCard } from './ReasoningCard.js';
|
|
5
|
+
import { OfficialActions, OfficialAssistantBody } from './OfficialContent.js';
|
|
6
|
+
import { Disclosure, ProcessFragment } from './motion.js';
|
|
7
|
+
import { FoldSummaryText } from './LiveFold.js';
|
|
8
|
+
import { assistantSegments, forkAnchorSeq, hasVisibleBody, isEarlierNarration } from './projection.js';
|
|
9
|
+
import css from './Reader.module.css';
|
|
10
|
+
function isNode(node, kind) {
|
|
11
|
+
return node.kind === kind;
|
|
12
|
+
}
|
|
13
|
+
export const AssistantNode = memo(function AssistantNode({ useChat, nodeKey, boundary, processOpen = false, pinned = false, folded = false, partStart, seamSummary, seamAfter = false, motion, onRead, returnFocusTo, ...render }) {
|
|
14
|
+
const node = useChat(snapshot => snapshot.nodes.get(nodeKey));
|
|
15
|
+
if (!node || node.visibility === 'hidden' || !isNode(node, 'assistant-step'))
|
|
16
|
+
return null;
|
|
17
|
+
const data = node.data;
|
|
18
|
+
const parts = assistantSegments(data.blocks);
|
|
19
|
+
const earlier = isEarlierNarration(data, boundary);
|
|
20
|
+
const hasToolCalls = data.blocks.some(block => block.kind === 'tool-call');
|
|
21
|
+
const isProcessStep = earlier || folded || hasToolCalls || (boundary.latestStep > 0 && data.step < boundary.latestStep);
|
|
22
|
+
const body = data.blocks.filter(block => block.kind !== 'reasoning' && block.kind !== 'tool-call');
|
|
23
|
+
const visible = partStart === undefined ? parts : parts.filter(part => part.start === partStart);
|
|
24
|
+
const bodyProps = { streaming: data.status === 'running', holdFormatting: pinned, startedAt: data.time, interrupted: data.status === 'interrupted', liveText: true };
|
|
25
|
+
return _jsx(_Fragment, { children: visible.map(part => {
|
|
26
|
+
const index = parts.findIndex(item => item.start === part.start);
|
|
27
|
+
const last = index === parts.length - 1;
|
|
28
|
+
if (part.kind === 'reasoning')
|
|
29
|
+
return _jsx(ProcessFragment, { open: processOpen, motion: motion, onRead: onRead, returnFocusTo: returnFocusTo, nodeKey: nodeKey, framed: true, children: _jsx(ReasoningCard, { step: data.step, active: processOpen && boundary.status === 'open' && data.step === boundary.latestStep, motion: motion, selected: pinned, onRead: onRead, children: _jsx(Blocks, { ...render, blocks: part.blocks, streaming: data.status === 'running' && last && data.blocks.at(-1)?.kind === 'reasoning', holdFormatting: pinned, startedAt: data.time, interrupted: data.status === 'interrupted', liveText: true }) }) }, part.start);
|
|
30
|
+
if (!hasVisibleBody(part.blocks))
|
|
31
|
+
return null;
|
|
32
|
+
// Narration stays body prose and never enters a disclosure. The seam in
|
|
33
|
+
// the gap summarises folded process between two body blocks. A foreign
|
|
34
|
+
// assistant-step renderer receives these original blocks; Reader markdown,
|
|
35
|
+
// including the text transform, is only the fallback.
|
|
36
|
+
const isFinalAnswer = !isProcessStep;
|
|
37
|
+
return _jsxs(Fragment, { children: [seamSummary && _jsx("div", { className: css.processSeamRow, "data-reader-process-seam": true, "data-reader-process-seam-summary": seamSummary, children: _jsx(Disclosure, { open: false, onChange: () => onRead(), ariaLabel: "\u88AB\u6298\u53E0\u7684\u8FC7\u7A0B", label: _jsx(FoldSummaryText, { summary: seamSummary, motion: false }) }) }), _jsxs("article", { className: css.answer, "data-reader-body": true, "data-reader-anchor": true, "data-reader-key": nodeKey, "data-reader-source-start": part.start, "data-reader-seam-after": seamAfter || undefined, "data-answer-status": data.status, "data-answer-phase": isFinalAnswer ? 'body' : 'process', children: [_jsx(OfficialAssistantBody, { ...render, node: node, blocks: part.blocks, ...bodyProps }), isFinalAnswer && last && data.status === 'interrupted' && _jsx("span", { className: css.stopped, children: "\u5DF2\u505C\u6B62" }), isFinalAnswer && last && data.status !== 'running' && boundary.status === 'closed' && (_jsx(CopyAnswer, { blocks: body, onFork: (() => {
|
|
38
|
+
// The fork anchor must be the durable closing message seq (same as
|
|
39
|
+
// the official turn-tail branch). AssistantChatData carries no seq
|
|
40
|
+
// of its own; passing it would fork the whole session instead.
|
|
41
|
+
const anchor = forkAnchorSeq([data.finalNode, { seq: render.forkSeq }]);
|
|
42
|
+
return render.forkAt && anchor !== undefined ? () => render.forkAt(anchor) : undefined;
|
|
43
|
+
})(), metrics: render.metrics, extraActions: _jsx(OfficialActions, { official: render.official, messageId: data.finalNode?.messageId }) }))] })] }, part.start);
|
|
44
|
+
}) });
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=AssistantNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantNode.js","sourceRoot":"","sources":["../../../src/client/AssistantNode.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Blocks.d.ts","sourceRoot":"","sources":["../../../src/client/Blocks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"Blocks.d.ts","sourceRoot":"","sources":["../../../src/client/Blocks.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAuE,MAAM,OAAO,CAAC;AACvG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AAKtG,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AASrE,qBAAa,aAAc,SAAQ,SAAS,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;IACxG,KAAK;;;MAAiC;IAGtC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO;;;;IAI9C,MAAM;CAKP;AAED,eAAO,MAAM,UAAU,kEAAuD;IAC5E,UAAU,EAAE,kBAAkB,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;CAC1E,iCAwCC,CAAC;AAEH,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,GAAG,cAAc,EAAE,CAMnF;AAED,KAAK,gBAAgB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAkF1F,eAAO,MAAM,MAAM,gLAA+L,gBAAgB,GAAG,gBAAgB,GAAG;IACtP,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACvH,iCASC,CAAC;AAyBH,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE;IAAE,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,CAAA;CAAE,sCAkChM;AAED,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,sCAajF"}
|