omnius 1.0.323 → 1.0.324
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/dist/index.js +453 -38
- package/npm-shrinkwrap.json +8 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -595348,6 +595348,23 @@ __export(task_complete_box_exports, {
|
|
|
595348
595348
|
renderSessionHistoryBox: () => renderSessionHistoryBox,
|
|
595349
595349
|
renderTaskCompleteBox: () => renderTaskCompleteBox
|
|
595350
595350
|
});
|
|
595351
|
+
function refreshBoxPalette() {
|
|
595352
|
+
if (themeMode() === "system") {
|
|
595353
|
+
GREEN = DEFAULT_FG;
|
|
595354
|
+
FG_BORDER = DEFAULT_FG;
|
|
595355
|
+
FG_TITLE = DEFAULT_BOLD_FG;
|
|
595356
|
+
FG_METRIC = DEFAULT_FG;
|
|
595357
|
+
FG_LABEL = DEFAULT_FG;
|
|
595358
|
+
return;
|
|
595359
|
+
}
|
|
595360
|
+
const accent = tuiAccent();
|
|
595361
|
+
const borderColor = accent >= 0 ? accent : TASK_COMPLETE_GREEN_256;
|
|
595362
|
+
GREEN = `\x1B[38;5;${borderColor}m`;
|
|
595363
|
+
FG_BORDER = `\x1B[38;5;${borderColor}m`;
|
|
595364
|
+
FG_TITLE = `\x1B[1;38;5;${borderColor}m`;
|
|
595365
|
+
FG_METRIC = "\x1B[38;5;222m";
|
|
595366
|
+
FG_LABEL = "\x1B[38;5;147m";
|
|
595367
|
+
}
|
|
595351
595368
|
function deriveTitle(task) {
|
|
595352
595369
|
if (!task || !task.trim()) return "Task Complete";
|
|
595353
595370
|
const source = task.replace(/^[\s\S]*?\n---\s*\n\s*NEW TASK:\s*/i, "").replace(/^NEW TASK:\s*/i, "").replace(/<task-handoff>[\s\S]*?<\/task-handoff>/gi, " ").replace(/<session-recap>[\s\S]*?<\/session-recap>/gi, " ").replace(/^\[task_(?:boundary|summary)\][\s\S]*?(?=\n\n|$)/gim, " ");
|
|
@@ -595540,6 +595557,7 @@ function buildLabeledFooterLines(label, items, width) {
|
|
|
595540
595557
|
return lines;
|
|
595541
595558
|
}
|
|
595542
595559
|
function buildBoxLines(data, width) {
|
|
595560
|
+
refreshBoxPalette();
|
|
595543
595561
|
const w = Math.max(40, width);
|
|
595544
595562
|
const title = deriveTitle(data.task);
|
|
595545
595563
|
const metrics2 = buildMetricsChip(data);
|
|
@@ -595579,6 +595597,7 @@ function buildBoxLines(data, width) {
|
|
|
595579
595597
|
return lines;
|
|
595580
595598
|
}
|
|
595581
595599
|
function buildSessionHistoryBoxLines(data, width) {
|
|
595600
|
+
refreshBoxPalette();
|
|
595582
595601
|
const w = Math.max(40, width);
|
|
595583
595602
|
const title = deriveTitle(data.title || "Session History");
|
|
595584
595603
|
const metrics2 = buildSessionHistoryMetricsChip(data);
|
|
@@ -595710,11 +595729,12 @@ function detectProvenanceAnchors(toolOutputs) {
|
|
|
595710
595729
|
}
|
|
595711
595730
|
return [...out].slice(0, 16);
|
|
595712
595731
|
}
|
|
595713
|
-
var BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, BOX_TJ_L, BOX_TJ_R, RESET, TASK_COMPLETE_GREEN_256, GREEN, FG_BORDER, FG_TITLE, FG_METRIC, FG_LABEL;
|
|
595732
|
+
var BOX_TL, BOX_TR, BOX_BL, BOX_BR, BOX_H, BOX_V, BOX_TJ_L, BOX_TJ_R, RESET, TASK_COMPLETE_GREEN_256, DEFAULT_FG, DEFAULT_BOLD_FG, GREEN, FG_BORDER, FG_TITLE, FG_METRIC, FG_LABEL;
|
|
595714
595733
|
var init_task_complete_box = __esm({
|
|
595715
595734
|
"packages/cli/src/tui/task-complete-box.ts"() {
|
|
595716
595735
|
"use strict";
|
|
595717
595736
|
init_text_selection();
|
|
595737
|
+
init_theme();
|
|
595718
595738
|
BOX_TL = "╭";
|
|
595719
595739
|
BOX_TR = "╮";
|
|
595720
595740
|
BOX_BL = "╰";
|
|
@@ -595725,6 +595745,8 @@ var init_task_complete_box = __esm({
|
|
|
595725
595745
|
BOX_TJ_R = "┤";
|
|
595726
595746
|
RESET = "\x1B[0m";
|
|
595727
595747
|
TASK_COMPLETE_GREEN_256 = 154;
|
|
595748
|
+
DEFAULT_FG = "\x1B[39m";
|
|
595749
|
+
DEFAULT_BOLD_FG = "\x1B[1;39m";
|
|
595728
595750
|
GREEN = `\x1B[38;5;${TASK_COMPLETE_GREEN_256}m`;
|
|
595729
595751
|
FG_BORDER = `\x1B[38;5;${TASK_COMPLETE_GREEN_256}m`;
|
|
595730
595752
|
FG_TITLE = `\x1B[1;38;5;${TASK_COMPLETE_GREEN_256}m`;
|
|
@@ -605735,6 +605757,31 @@ function getLastTaskSummary(repoRoot) {
|
|
|
605735
605757
|
const clean5 = text2.replace(/^\[.*?\]\s*/, "").replace(/\s+/g, " ").trim();
|
|
605736
605758
|
return clean5.length > 40 ? clean5.slice(0, 37) + "..." : clean5;
|
|
605737
605759
|
}
|
|
605760
|
+
function cleanSessionHistoryDisplayLine(line) {
|
|
605761
|
+
return String(line || "").replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "").replace(/^[>❯▹∙•*+\-\s]+/, "").replace(/^\[.*?\]\s*/, "").replace(/^(?:User|Assistant|You|Open Agent|Omnius)\s*:\s*/i, "").replace(/\s+/g, " ").trim();
|
|
605762
|
+
}
|
|
605763
|
+
function isNoisySessionHistoryLine(line) {
|
|
605764
|
+
const clean5 = cleanSessionHistoryDisplayLine(line || "");
|
|
605765
|
+
if (!clean5) return true;
|
|
605766
|
+
return /^(?:Previous session found|REST API:|Nexus P2P network connected|No context to restore|Starting fresh|Use \/endpoint|Knowledge graph:|Zettelkasten:|Episodes captured:|Current OMNIUS_HOST:|Loaded TUI session|General session$|Chat tui:sess|i\s+)/i.test(clean5);
|
|
605767
|
+
}
|
|
605768
|
+
function firstMeaningfulSessionHistoryLine(lines) {
|
|
605769
|
+
for (const line of lines) {
|
|
605770
|
+
const clean5 = cleanSessionHistoryDisplayLine(line);
|
|
605771
|
+
if (!isNoisySessionHistoryLine(clean5)) return clean5;
|
|
605772
|
+
}
|
|
605773
|
+
return "";
|
|
605774
|
+
}
|
|
605775
|
+
function sanitizeSessionHistoryEntry(repoRoot, entry) {
|
|
605776
|
+
if (!isNoisySessionHistoryLine(entry.name) && !isNoisySessionHistoryLine(entry.description)) return entry;
|
|
605777
|
+
const lines = loadSessionHistory(repoRoot, entry.id) || [];
|
|
605778
|
+
const fallback = firstMeaningfulSessionHistoryLine(lines);
|
|
605779
|
+
return {
|
|
605780
|
+
...entry,
|
|
605781
|
+
name: isNoisySessionHistoryLine(entry.name) ? fallback ? fallback.length > 40 ? fallback.slice(0, 37) + "..." : fallback : entry.name : entry.name,
|
|
605782
|
+
description: isNoisySessionHistoryLine(entry.description) ? fallback || entry.description : entry.description
|
|
605783
|
+
};
|
|
605784
|
+
}
|
|
605738
605785
|
function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
605739
605786
|
const sessDir = join125(repoRoot, OMNIUS_DIR, SESSIONS_DIR);
|
|
605740
605787
|
mkdirSync66(sessDir, { recursive: true });
|
|
@@ -605782,7 +605829,7 @@ function listSessions(repoRoot) {
|
|
|
605782
605829
|
try {
|
|
605783
605830
|
if (!existsSync110(indexPath)) return [];
|
|
605784
605831
|
const index = JSON.parse(readFileSync89(indexPath, "utf-8"));
|
|
605785
|
-
return index.sort((a2, b) => b.updatedAt.localeCompare(a2.updatedAt));
|
|
605832
|
+
return index.map((entry) => sanitizeSessionHistoryEntry(repoRoot, entry)).sort((a2, b) => b.updatedAt.localeCompare(a2.updatedAt));
|
|
605786
605833
|
} catch {
|
|
605787
605834
|
return [];
|
|
605788
605835
|
}
|
|
@@ -605813,12 +605860,9 @@ function deleteSession(repoRoot, sessionId) {
|
|
|
605813
605860
|
}
|
|
605814
605861
|
}
|
|
605815
605862
|
function generateSessionName(lines) {
|
|
605816
|
-
|
|
605817
|
-
|
|
605818
|
-
|
|
605819
|
-
const phrase = clean5.replace(/^[>❯▹]\s*/, "").slice(0, 40);
|
|
605820
|
-
return phrase.length > 37 ? phrase.slice(0, 37) + "..." : phrase;
|
|
605821
|
-
}
|
|
605863
|
+
const phrase = firstMeaningfulSessionHistoryLine(lines.slice(0, 80));
|
|
605864
|
+
if (phrase.length > 10) {
|
|
605865
|
+
return phrase.length > 40 ? phrase.slice(0, 37) + "..." : phrase;
|
|
605822
605866
|
}
|
|
605823
605867
|
return `Session ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
605824
605868
|
}
|
|
@@ -605836,7 +605880,9 @@ function generateSessionDescription(lines) {
|
|
|
605836
605880
|
}
|
|
605837
605881
|
if (topics.length >= 3) break;
|
|
605838
605882
|
}
|
|
605839
|
-
|
|
605883
|
+
if (topics.length > 0) return topics.join(", ");
|
|
605884
|
+
const fallback = firstMeaningfulSessionHistoryLine(lines.slice(0, 120));
|
|
605885
|
+
return fallback || "General session";
|
|
605840
605886
|
}
|
|
605841
605887
|
function detectManifests(repoRoot) {
|
|
605842
605888
|
const manifests = [];
|
|
@@ -607403,6 +607449,25 @@ __export(status_bar_exports, {
|
|
|
607403
607449
|
unlockFooterRedraws: () => unlockFooterRedraws
|
|
607404
607450
|
});
|
|
607405
607451
|
import { readFileSync as readFileSync91 } from "node:fs";
|
|
607452
|
+
function headerButtonGlyphFg() {
|
|
607453
|
+
const a2 = tuiAccent();
|
|
607454
|
+
return a2 < 0 ? "\x1B[39m" : `\x1B[38;5;${a2}m`;
|
|
607455
|
+
}
|
|
607456
|
+
function headerButtonBg() {
|
|
607457
|
+
const a2 = tuiAccent();
|
|
607458
|
+
return a2 < 0 ? "\x1B[7m" : `\x1B[48;5;${a2}m`;
|
|
607459
|
+
}
|
|
607460
|
+
function headerButtonFg() {
|
|
607461
|
+
const a2 = tuiAccent();
|
|
607462
|
+
return a2 < 0 ? "" : `\x1B[38;5;${contrastTextColor(a2)}m`;
|
|
607463
|
+
}
|
|
607464
|
+
function headerAccentBoldFg() {
|
|
607465
|
+
const a2 = tuiAccent();
|
|
607466
|
+
return a2 < 0 ? "\x1B[1;39m" : `\x1B[1;38;5;${a2}m`;
|
|
607467
|
+
}
|
|
607468
|
+
function headerTelegramFg() {
|
|
607469
|
+
return themeMode() === "system" ? "\x1B[39m" : "\x1B[38;5;45m";
|
|
607470
|
+
}
|
|
607406
607471
|
function stripSubAgentPrefix(label) {
|
|
607407
607472
|
const stripped = label.replace(/^\s*sub[-\s]?agents?\b[\s:_–—-]*/i, "").trim();
|
|
607408
607473
|
return stripped.length > 0 ? stripped : label.trim();
|
|
@@ -607460,6 +607525,11 @@ function refreshThemeVars() {
|
|
|
607460
607525
|
BOX_FG = tuiBoxFg();
|
|
607461
607526
|
TEXT_PRIMARY = tuiTextPrimary() < 0 ? 252 : tuiTextPrimary();
|
|
607462
607527
|
TEXT_DIM = tuiTextDim();
|
|
607528
|
+
HEADER_BUTTON_GLYPH_FG = headerButtonGlyphFg();
|
|
607529
|
+
HEADER_BUTTON_BG = headerButtonBg();
|
|
607530
|
+
HEADER_BUTTON_FG = headerButtonFg();
|
|
607531
|
+
HEADER_ACCENT_BOLD_FG = headerAccentBoldFg();
|
|
607532
|
+
HEADER_TELEGRAM_FG = headerTelegramFg();
|
|
607463
607533
|
}
|
|
607464
607534
|
function sanitizeSponsorHeaderText(value2, max = SPONSOR_HEADER_LABEL_MAX) {
|
|
607465
607535
|
const cleaned = stripAnsi(String(value2 ?? "")).replace(/[\x00-\x1F\x7F]/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -607494,7 +607564,7 @@ function setTerminalTitle(task, version4) {
|
|
|
607494
607564
|
process.stdout.write(data);
|
|
607495
607565
|
}
|
|
607496
607566
|
}
|
|
607497
|
-
var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL,
|
|
607567
|
+
var EXPERT_TOOL_BASELINES, CONTEXT_SWITCH_OVERHEAD, TURN_PLANNING_OVERHEAD, DEFAULT_TOOL_BASELINE, CODE_READ_CHARS_PER_SEC, PROSE_READ_CHARS_PER_SEC, MIN_CONTENT_FOR_READING, CODE_CONTENT_TOOLS, PROSE_CONTENT_TOOLS, HumanSpeedTracker, PANEL_BG_SEQ, CONTENT_BG_SEQ, BOX_FG, TEXT_PRIMARY, TEXT_DIM, NO_SUB_AGENTS_HEADER_LABEL, HEADER_BUTTON_GLYPH_FG, HEADER_BUTTON_BG, HEADER_BUTTON_FG, HEADER_ACCENT_BOLD_FG, HEADER_TELEGRAM_FG, BOX_TL3, BOX_TR3, BOX_BL3, BOX_BR3, BOX_H3, BOX_V3, _globalFooterLock, RESET4, CURSOR_BLINK_BLOCK, _isWindows, SPONSOR_HEADER_LABEL_MAX, _termTitleWriter, StatusBar;
|
|
607498
607568
|
var init_status_bar = __esm({
|
|
607499
607569
|
"packages/cli/src/tui/status-bar.ts"() {
|
|
607500
607570
|
"use strict";
|
|
@@ -607674,10 +607744,11 @@ var init_status_bar = __esm({
|
|
|
607674
607744
|
TEXT_PRIMARY = tuiTextPrimary() < 0 ? 252 : tuiTextPrimary();
|
|
607675
607745
|
TEXT_DIM = tuiTextDim();
|
|
607676
607746
|
NO_SUB_AGENTS_HEADER_LABEL = " no agents ";
|
|
607677
|
-
|
|
607678
|
-
|
|
607679
|
-
|
|
607680
|
-
|
|
607747
|
+
HEADER_BUTTON_GLYPH_FG = headerButtonGlyphFg();
|
|
607748
|
+
HEADER_BUTTON_BG = headerButtonBg();
|
|
607749
|
+
HEADER_BUTTON_FG = headerButtonFg();
|
|
607750
|
+
HEADER_ACCENT_BOLD_FG = headerAccentBoldFg();
|
|
607751
|
+
HEADER_TELEGRAM_FG = headerTelegramFg();
|
|
607681
607752
|
BOX_TL3 = "╭";
|
|
607682
607753
|
BOX_TR3 = "╮";
|
|
607683
607754
|
BOX_BL3 = "╰";
|
|
@@ -608148,7 +608219,7 @@ var init_status_bar = __esm({
|
|
|
608148
608219
|
return fg2;
|
|
608149
608220
|
};
|
|
608150
608221
|
const decorateMenuButton = (cmd, label) => {
|
|
608151
|
-
return
|
|
608222
|
+
return `${HEADER_BUTTON_GLYPH_FG}🭁\x1B[0m${HEADER_BUTTON_BG}${HEADER_BUTTON_FG}${label}\x1B[0m${PANEL_BG_SEQ}${HEADER_BUTTON_GLYPH_FG}🭝\x1B[0m${PANEL_BG_SEQ}`;
|
|
608152
608223
|
};
|
|
608153
608224
|
const decorateAgentButton = (content, color, active) => {
|
|
608154
608225
|
const bg = `\x1B[48;5;${color}m`;
|
|
@@ -608282,7 +608353,7 @@ var init_status_bar = __esm({
|
|
|
608282
608353
|
sysItems.push({
|
|
608283
608354
|
render: () => renderBtn(
|
|
608284
608355
|
"telegram",
|
|
608285
|
-
|
|
608356
|
+
`${HEADER_TELEGRAM_FG}${telegramDot}${telegramLabel}\x1B[0m`
|
|
608286
608357
|
) + " ",
|
|
608287
608358
|
w: telegramLabel.length + 2
|
|
608288
608359
|
});
|
|
@@ -610719,8 +610790,8 @@ ${CONTENT_BG_SEQ}`);
|
|
|
610719
610790
|
const label = `✈ tg${suffix}`;
|
|
610720
610791
|
const compact3 = `✈${suffix}`;
|
|
610721
610792
|
sections.push({
|
|
610722
|
-
expanded:
|
|
610723
|
-
compact:
|
|
610793
|
+
expanded: `${HEADER_TELEGRAM_FG}${label}\x1B[0m`,
|
|
610794
|
+
compact: `${HEADER_TELEGRAM_FG}${compact3}\x1B[0m`,
|
|
610724
610795
|
expandedW: 2 + 3 + suffix.length,
|
|
610725
610796
|
compactW: 2 + suffix.length,
|
|
610726
610797
|
empty: false,
|
|
@@ -645238,22 +645309,51 @@ function normalizeRoot(root) {
|
|
|
645238
645309
|
}
|
|
645239
645310
|
}
|
|
645240
645311
|
function stripAnsi5(text2) {
|
|
645241
|
-
return String(text2 || "").replace(
|
|
645312
|
+
return String(text2 || "").replace(/\u001b\[[0-9;]*[a-zA-Z]/g, "");
|
|
645313
|
+
}
|
|
645314
|
+
function cleanSessionDisplayLine(line) {
|
|
645315
|
+
return stripAnsi5(line).replace(/^[>❯▹∙•*+\-\s]+/, "").replace(/^(?:User|Assistant|You|Open Agent|Omnius)\s*:\s*/i, "").replace(/\s+/g, " ").trim();
|
|
645316
|
+
}
|
|
645317
|
+
function isNoisySessionDisplayLine(line) {
|
|
645318
|
+
const clean5 = cleanSessionDisplayLine(line || "");
|
|
645319
|
+
if (!clean5) return true;
|
|
645320
|
+
return /^(?:Previous session found|REST API:|Nexus P2P network connected|No context to restore|Starting fresh|Use \/endpoint|Knowledge graph:|Zettelkasten:|Episodes captured:|Current OMNIUS_HOST:|Loaded TUI session|General session$|Chat tui:sess|\[Imported TUI session transcript\]|Title:|Description:|Project root:|i\s+)/i.test(clean5);
|
|
645321
|
+
}
|
|
645322
|
+
function bestSessionDisplayLine(text2) {
|
|
645323
|
+
const lines = stripAnsi5(text2).split(/\r?\n/);
|
|
645324
|
+
for (const line of lines) {
|
|
645325
|
+
const clean5 = cleanSessionDisplayLine(line);
|
|
645326
|
+
if (!isNoisySessionDisplayLine(clean5)) return clean5;
|
|
645327
|
+
}
|
|
645328
|
+
const fallback = stripAnsi5(text2).replace(/\s+/g, " ").trim();
|
|
645329
|
+
return isNoisySessionDisplayLine(fallback) ? "" : fallback;
|
|
645242
645330
|
}
|
|
645243
645331
|
function makeTitle(text2) {
|
|
645244
|
-
const clean5 =
|
|
645332
|
+
const clean5 = bestSessionDisplayLine(text2);
|
|
645245
645333
|
if (!clean5) return "Chat session";
|
|
645246
|
-
return clean5.length > 72 ?
|
|
645334
|
+
return clean5.length > 72 ? clean5.slice(0, 69) + "..." : clean5;
|
|
645247
645335
|
}
|
|
645248
645336
|
function makePreview(text2) {
|
|
645249
|
-
const clean5 =
|
|
645250
|
-
return clean5.length > 160 ?
|
|
645337
|
+
const clean5 = bestSessionDisplayLine(text2);
|
|
645338
|
+
return clean5.length > 160 ? clean5.slice(0, 157) + "..." : clean5;
|
|
645251
645339
|
}
|
|
645252
645340
|
function normalizeLoadedSession(parsed) {
|
|
645253
645341
|
if (!parsed.source) parsed.source = "web";
|
|
645254
645342
|
if (parsed.projectRoot) parsed.projectRoot = normalizeRoot(parsed.projectRoot);
|
|
645343
|
+
if (parsed.title && isNoisySessionDisplayLine(parsed.title)) parsed.title = void 0;
|
|
645344
|
+
if (parsed.preview && isNoisySessionDisplayLine(parsed.preview)) parsed.preview = "";
|
|
645345
|
+
const importedContext = (parsed.messages || []).find(
|
|
645346
|
+
(m2) => m2.role === "system" && m2.content.startsWith("[Imported TUI session transcript]")
|
|
645347
|
+
)?.content;
|
|
645348
|
+
if ((parsed.source === "tui" || parsed.id?.startsWith("tui:")) && importedContext) {
|
|
645349
|
+
const importedPreview = makePreview(importedContext);
|
|
645350
|
+
if (!parsed.preview && importedPreview) parsed.preview = importedPreview;
|
|
645351
|
+
if (!parsed.title && importedPreview) parsed.title = makeTitle(importedPreview);
|
|
645352
|
+
}
|
|
645255
645353
|
if (!parsed.preview) {
|
|
645256
|
-
const last2 = [...parsed.messages || []].reverse().find(
|
|
645354
|
+
const last2 = [...parsed.messages || []].reverse().find(
|
|
645355
|
+
(m2) => (m2.role === "user" || m2.role === "assistant") && !isNoisySessionDisplayLine(m2.content)
|
|
645356
|
+
);
|
|
645257
645357
|
parsed.preview = last2 ? makePreview(last2.content) : "";
|
|
645258
645358
|
}
|
|
645259
645359
|
if (!parsed.title && parsed.preview) parsed.title = makeTitle(parsed.preview);
|
|
@@ -645426,9 +645526,10 @@ function getSession2(sessionId, model, cwd4) {
|
|
|
645426
645526
|
function importTranscriptSession(opts) {
|
|
645427
645527
|
const projectRoot = normalizeRoot(opts.projectRoot) ?? process.cwd();
|
|
645428
645528
|
const id = opts.id;
|
|
645429
|
-
const title = opts.title || makeTitle(opts.description || id);
|
|
645430
|
-
const preview = makePreview(opts.description || opts.transcriptLines.slice(-8).join(" "));
|
|
645431
645529
|
const transcript = opts.transcriptLines.map(stripAnsi5).join("\n").trim();
|
|
645530
|
+
const metadataSource = [opts.title, opts.description, transcript].filter(Boolean).join("\n");
|
|
645531
|
+
const title = makeTitle(metadataSource || id);
|
|
645532
|
+
const preview = makePreview([opts.description, transcript].filter(Boolean).join("\n") || title);
|
|
645432
645533
|
const cappedTranscript = transcript.length > 32e3 ? `[earlier transcript truncated: ${transcript.length - 32e3} chars]
|
|
645433
645534
|
` + transcript.slice(-32e3) : transcript;
|
|
645434
645535
|
const importedContext = [
|
|
@@ -685535,6 +685636,44 @@ async function loadServerPrefs() {
|
|
|
685535
685636
|
} catch { return null; }
|
|
685536
685637
|
}
|
|
685537
685638
|
|
|
685639
|
+
function isNoisyChatSessionText(text) {
|
|
685640
|
+
const clean = String(text || '').replace(/\\s+/g, ' ').trim();
|
|
685641
|
+
if (!clean) return true;
|
|
685642
|
+
const t = clean.replace(/^[>❯▹∙•\\-\\s]+/, '');
|
|
685643
|
+
return /^(Previous session found|REST API:|Nexus P2P network connected|No context to restore|Starting fresh|Use \\/endpoint|General session$|Loaded TUI session|Chat tui:sess)/i.test(t);
|
|
685644
|
+
}
|
|
685645
|
+
|
|
685646
|
+
function isGenericChatTitle(id, title) {
|
|
685647
|
+
const t = String(title || '').trim();
|
|
685648
|
+
if (!t) return true;
|
|
685649
|
+
if (isNoisyChatSessionText(t)) return true;
|
|
685650
|
+
if (t === 'Chat ' + String(id || '').slice(0, 8)) return true;
|
|
685651
|
+
return /^Chat tui:sess/i.test(t);
|
|
685652
|
+
}
|
|
685653
|
+
|
|
685654
|
+
function sessionDisplayTitle(id, session) {
|
|
685655
|
+
const s = session || {};
|
|
685656
|
+
for (const candidate of [s.title, s.name, s.preview]) {
|
|
685657
|
+
if (!isGenericChatTitle(id, candidate)) return String(candidate).trim();
|
|
685658
|
+
}
|
|
685659
|
+
if (Array.isArray(s.messages)) {
|
|
685660
|
+
for (let i = s.messages.length - 1; i >= 0; i--) {
|
|
685661
|
+
const msg = s.messages[i];
|
|
685662
|
+
const content = msg && typeof msg.content === 'string' ? msg.content : '';
|
|
685663
|
+
if (!isGenericChatTitle(id, content)) return content.replace(/\\s+/g, ' ').trim().slice(0, 72);
|
|
685664
|
+
}
|
|
685665
|
+
}
|
|
685666
|
+
return String(id || '').startsWith('tui:') ? 'TUI session ' + String(id).slice(4, 16) : 'Chat ' + String(id || '').slice(0, 8);
|
|
685667
|
+
}
|
|
685668
|
+
|
|
685669
|
+
function sessionDisplayPreview(session) {
|
|
685670
|
+
const s = session || {};
|
|
685671
|
+
for (const candidate of [s.preview, s.title, s.name]) {
|
|
685672
|
+
if (!isNoisyChatSessionText(candidate)) return String(candidate).trim();
|
|
685673
|
+
}
|
|
685674
|
+
return '';
|
|
685675
|
+
}
|
|
685676
|
+
|
|
685538
685677
|
async function loadServerChatSessions() {
|
|
685539
685678
|
const root = $currentProject.get()?.root || '';
|
|
685540
685679
|
if (!root) return;
|
|
@@ -685547,16 +685686,24 @@ async function loadServerChatSessions() {
|
|
|
685547
685686
|
for (const sess of (data.sessions || [])) {
|
|
685548
685687
|
if (!sess || !sess.id) continue;
|
|
685549
685688
|
const existing = merged[sess.id] || {};
|
|
685689
|
+
const serverTitle = sess.title || sess.preview || '';
|
|
685690
|
+
const existingTitle = existing.title || existing.name || '';
|
|
685691
|
+
const title = !isGenericChatTitle(sess.id, existingTitle)
|
|
685692
|
+
? existingTitle
|
|
685693
|
+
: (!isGenericChatTitle(sess.id, serverTitle) ? serverTitle : sessionDisplayTitle(sess.id, sess));
|
|
685694
|
+
const preview = !isNoisyChatSessionText(existing.preview)
|
|
685695
|
+
? existing.preview
|
|
685696
|
+
: (!isNoisyChatSessionText(sess.preview) ? sess.preview : sessionDisplayPreview(sess));
|
|
685550
685697
|
merged[sess.id] = {
|
|
685551
685698
|
...existing,
|
|
685552
685699
|
id: sess.id,
|
|
685553
|
-
title
|
|
685554
|
-
name: existing.name
|
|
685555
|
-
preview
|
|
685700
|
+
title,
|
|
685701
|
+
name: !isGenericChatTitle(sess.id, existing.name) ? existing.name : title,
|
|
685702
|
+
preview,
|
|
685556
685703
|
model: existing.model || sess.model || '',
|
|
685557
685704
|
source: sess.source || existing.source || 'web',
|
|
685558
685705
|
projectRoot: sess.projectRoot || root,
|
|
685559
|
-
updatedAt:
|
|
685706
|
+
updatedAt: sess.lastActivity || sess.updatedAt || existing.updatedAt || '',
|
|
685560
685707
|
messages: existing.messages || [],
|
|
685561
685708
|
};
|
|
685562
685709
|
}
|
|
@@ -686085,6 +686232,7 @@ function addMessage(role, content) {
|
|
|
686085
686232
|
}
|
|
686086
686233
|
if (role === 'assistant' || (role === 'user' && looksLikeMarkdown(content))) {
|
|
686087
686234
|
host.innerHTML = renderMarkdown(content);
|
|
686235
|
+
appendArtifactsForText(host, content);
|
|
686088
686236
|
} else {
|
|
686089
686237
|
host.textContent = content;
|
|
686090
686238
|
}
|
|
@@ -686380,6 +686528,7 @@ function renderToolCallEvent(parent, chunkLike) {
|
|
|
686380
686528
|
argsDiv.appendChild(row);
|
|
686381
686529
|
}
|
|
686382
686530
|
}
|
|
686531
|
+
appendArtifactControls(argsDiv, extractArtifactsFromValue(a));
|
|
686383
686532
|
details.appendChild(argsDiv);
|
|
686384
686533
|
}
|
|
686385
686534
|
parent.appendChild(details);
|
|
@@ -686396,6 +686545,7 @@ function renderToolResultEvent(parent, chunkLike) {
|
|
|
686396
686545
|
: 'background:var(--color-bg-elevated);color:var(--color-fg-muted);';
|
|
686397
686546
|
resultEl.style.cssText = errStyle + 'padding:4px 8px 4px 18px;margin:0 0 2px 0;font-size:0.65rem';
|
|
686398
686547
|
appendExpandableContent(resultEl, chunkLike.output || '', { truncateAt: 150, baseStyle: 'color:inherit;' });
|
|
686548
|
+
appendArtifactControls(resultEl, extractArtifactsFromValue(chunkLike));
|
|
686399
686549
|
parent.appendChild(resultEl);
|
|
686400
686550
|
return resultEl;
|
|
686401
686551
|
}
|
|
@@ -686751,6 +686901,7 @@ async function sendMessage() {
|
|
|
686751
686901
|
fullContent += summaryText;
|
|
686752
686902
|
}
|
|
686753
686903
|
contentDiv.innerHTML = renderMarkdown(fullContent);
|
|
686904
|
+
appendArtifactsForText(contentDiv, fullContent);
|
|
686754
686905
|
hideStreamingIndicator(msgDiv);
|
|
686755
686906
|
maybeAutoScroll();
|
|
686756
686907
|
}
|
|
@@ -686862,6 +687013,7 @@ async function sendMessage() {
|
|
|
686862
687013
|
argsDiv.appendChild(row);
|
|
686863
687014
|
}
|
|
686864
687015
|
}
|
|
687016
|
+
appendArtifactControls(argsDiv, extractArtifactsFromValue(a));
|
|
686865
687017
|
details.appendChild(argsDiv);
|
|
686866
687018
|
}
|
|
686867
687019
|
toolsContainer.appendChild(details);
|
|
@@ -686874,10 +687026,8 @@ async function sendMessage() {
|
|
|
686874
687026
|
// 150 chars. The button sits underneath the result block.
|
|
686875
687027
|
if (chunk.type === 'tool_result') {
|
|
686876
687028
|
if (isInternalChatTool(chunk.tool || '')) continue;
|
|
686877
|
-
|
|
686878
|
-
|
|
686879
|
-
appendExpandableContent(resultEl, chunk.output || '', { truncateAt: 150, baseStyle: 'color:var(--color-fg-muted);' });
|
|
686880
|
-
toolsContainer.appendChild(resultEl);
|
|
687029
|
+
renderToolResultEvent(toolsContainer, chunk);
|
|
687030
|
+
maybeAutoScroll();
|
|
686881
687031
|
continue;
|
|
686882
687032
|
}
|
|
686883
687033
|
|
|
@@ -686893,6 +687043,7 @@ async function sendMessage() {
|
|
|
686893
687043
|
hideStreamingIndicator(msgDiv);
|
|
686894
687044
|
fullContent += delta;
|
|
686895
687045
|
contentDiv.innerHTML = renderMarkdown(fullContent);
|
|
687046
|
+
appendArtifactsForText(contentDiv, fullContent);
|
|
686896
687047
|
try { _highlightCodeBlocks(contentDiv); } catch {}
|
|
686897
687048
|
maybeAutoScroll();
|
|
686898
687049
|
}
|
|
@@ -686916,6 +687067,7 @@ async function sendMessage() {
|
|
|
686916
687067
|
|
|
686917
687068
|
// Final render: content + collapsible tools + metadata
|
|
686918
687069
|
contentDiv.innerHTML = renderMarkdown(fullContent);
|
|
687070
|
+
appendArtifactsForText(contentDiv, fullContent);
|
|
686919
687071
|
// OWUI-3: streaming complete — drop the pulsing dot.
|
|
686920
687072
|
hideStreamingIndicator(msgDiv);
|
|
686921
687073
|
try { _highlightCodeBlocks(contentDiv); } catch {}
|
|
@@ -688828,12 +688980,20 @@ async function loadJobs() {
|
|
|
688828
688980
|
function saveSessions() {
|
|
688829
688981
|
const saved = loadScopedSessions();
|
|
688830
688982
|
if (chatSessionId) {
|
|
688983
|
+
const existing = saved[chatSessionId] || (($chatSessions.get && $chatSessions.get()) || {})[chatSessionId] || {};
|
|
688984
|
+
const preview = messages.slice(-1)[0]?.content?.slice(0, 50) || sessionDisplayPreview(existing) || 'empty';
|
|
688985
|
+
const title = !isGenericChatTitle(chatSessionId, existing.title || existing.name)
|
|
688986
|
+
? (existing.title || existing.name)
|
|
688987
|
+
: sessionDisplayTitle(chatSessionId, { ...existing, preview, messages });
|
|
688831
688988
|
saved[chatSessionId] = {
|
|
688989
|
+
...existing,
|
|
688832
688990
|
id: chatSessionId,
|
|
688991
|
+
title,
|
|
688992
|
+
name: !isGenericChatTitle(chatSessionId, existing.name) ? existing.name : title,
|
|
688833
688993
|
messages: messages,
|
|
688834
688994
|
model: modelSelect.value,
|
|
688835
688995
|
updatedAt: new Date().toISOString(),
|
|
688836
|
-
preview
|
|
688996
|
+
preview,
|
|
688837
688997
|
};
|
|
688838
688998
|
}
|
|
688839
688999
|
saveScopedSessions(saved);
|
|
@@ -688859,7 +689019,7 @@ function updateSessionSelect() {
|
|
|
688859
689019
|
for (const [id, s] of entries) {
|
|
688860
689020
|
const opt = document.createElement('option');
|
|
688861
689021
|
opt.value = id;
|
|
688862
|
-
opt.textContent = (s
|
|
689022
|
+
opt.textContent = sessionDisplayTitle(id, s).slice(0, 40);
|
|
688863
689023
|
if (id === chatSessionId) opt.selected = true;
|
|
688864
689024
|
sel.appendChild(opt);
|
|
688865
689025
|
}
|
|
@@ -689668,6 +689828,255 @@ function rawFileUrl(path) {
|
|
|
689668
689828
|
return '/v1/files/raw?path=' + encodeURIComponent(path);
|
|
689669
689829
|
}
|
|
689670
689830
|
|
|
689831
|
+
function cleanArtifactPathCandidate(value) {
|
|
689832
|
+
let s = String(value || '').trim();
|
|
689833
|
+
s = s.replace(/^["'(<]+/, '').replace(/[)"'>,.;:]+$/, '');
|
|
689834
|
+
return s;
|
|
689835
|
+
}
|
|
689836
|
+
|
|
689837
|
+
function isPreviewableArtifactInfo(info) {
|
|
689838
|
+
return info && (info.kind === 'audio' || info.kind === 'video' || info.kind === 'image' || info.kind === 'pdf' || isTextPreviewable(info));
|
|
689839
|
+
}
|
|
689840
|
+
|
|
689841
|
+
function mediaUrlForStoredPath(path) {
|
|
689842
|
+
const normalized = String(path || '').split(String.fromCharCode(92)).join('/');
|
|
689843
|
+
const marker = '/.omnius/media/';
|
|
689844
|
+
const idx = normalized.indexOf(marker);
|
|
689845
|
+
if (idx < 0) return null;
|
|
689846
|
+
const rest = normalized.slice(idx + marker.length);
|
|
689847
|
+
const parts = rest.split('/').filter(Boolean);
|
|
689848
|
+
if (parts.length < 2) return null;
|
|
689849
|
+
const group = parts[0];
|
|
689850
|
+
const name = parts[parts.length - 1];
|
|
689851
|
+
const kind = group === 'images' ? 'image'
|
|
689852
|
+
: group === 'videos' ? 'video'
|
|
689853
|
+
: group === 'audio' ? 'audio'
|
|
689854
|
+
: group === 'music' ? 'music'
|
|
689855
|
+
: null;
|
|
689856
|
+
if (!kind || !name) return null;
|
|
689857
|
+
return '/v1/media/file?kind=' + encodeURIComponent(kind) + '&name=' + encodeURIComponent(name);
|
|
689858
|
+
}
|
|
689859
|
+
|
|
689860
|
+
function artifactFromPath(path, hint) {
|
|
689861
|
+
const clean = cleanArtifactPathCandidate(path);
|
|
689862
|
+
if (!clean) return null;
|
|
689863
|
+
const info = fileInfoFor(null, clean);
|
|
689864
|
+
if (info.kind === 'binary' || info.kind === 'archive') return null;
|
|
689865
|
+
const mediaUrl = mediaUrlForStoredPath(clean);
|
|
689866
|
+
return {
|
|
689867
|
+
path: clean,
|
|
689868
|
+
url: mediaUrl || rawFileUrl(clean),
|
|
689869
|
+
name: baseNameForPath(clean),
|
|
689870
|
+
kind: hint || info.kind,
|
|
689871
|
+
mime: info.mime,
|
|
689872
|
+
info,
|
|
689873
|
+
};
|
|
689874
|
+
}
|
|
689875
|
+
|
|
689876
|
+
function artifactFromUrl(url, hint) {
|
|
689877
|
+
const clean = cleanArtifactPathCandidate(url);
|
|
689878
|
+
if (!clean) return null;
|
|
689879
|
+
if (!/^\\/v1\\/media\\/file\\?/.test(clean) && !/^\\/v1\\/files\\/raw\\?/.test(clean) && !/^https?:\\/\\//i.test(clean)) return null;
|
|
689880
|
+
let name = clean;
|
|
689881
|
+
let kind = hint || '';
|
|
689882
|
+
let path = '';
|
|
689883
|
+
try {
|
|
689884
|
+
const u = new URL(clean, window.location.origin);
|
|
689885
|
+
path = u.searchParams.get('path') || '';
|
|
689886
|
+
name = u.searchParams.get('name') || (path ? baseNameForPath(path) : '') || baseNameForPath(u.pathname) || clean;
|
|
689887
|
+
kind = kind || u.searchParams.get('kind') || '';
|
|
689888
|
+
if (kind === 'music') kind = 'audio';
|
|
689889
|
+
} catch {}
|
|
689890
|
+
const info = fileInfoFor({ name, kind }, path || name);
|
|
689891
|
+
return { path, url: clean, name, kind: kind || info.kind, mime: info.mime, info };
|
|
689892
|
+
}
|
|
689893
|
+
|
|
689894
|
+
function uniqueArtifacts(items) {
|
|
689895
|
+
const seen = new Set();
|
|
689896
|
+
const out = [];
|
|
689897
|
+
for (const item of items || []) {
|
|
689898
|
+
if (!item) continue;
|
|
689899
|
+
const key = (item.url || '') + '|' + (item.path || '');
|
|
689900
|
+
if (!key.trim() || seen.has(key)) continue;
|
|
689901
|
+
seen.add(key);
|
|
689902
|
+
out.push(item);
|
|
689903
|
+
}
|
|
689904
|
+
return out;
|
|
689905
|
+
}
|
|
689906
|
+
|
|
689907
|
+
function extractArtifactsFromText(text) {
|
|
689908
|
+
const raw = String(text || '');
|
|
689909
|
+
if (!raw.trim()) return [];
|
|
689910
|
+
const out = [];
|
|
689911
|
+
|
|
689912
|
+
const urlRe = /\\/v1\\/(?:media\\/file|files\\/raw)\\?[^\\s"'<>]+/g;
|
|
689913
|
+
for (const match of raw.matchAll(urlRe)) {
|
|
689914
|
+
out.push(artifactFromUrl(match[0]));
|
|
689915
|
+
}
|
|
689916
|
+
|
|
689917
|
+
const pathRe = /(?:~|\\/|[A-Za-z]:[\\\\/])[^\\s"'<>]+/g;
|
|
689918
|
+
for (const match of raw.matchAll(pathRe)) {
|
|
689919
|
+
const candidate = cleanArtifactPathCandidate(match[0]);
|
|
689920
|
+
if (/^\\/v1\\/(?:media\\/file|files\\/raw)\\?/i.test(candidate)) continue;
|
|
689921
|
+
const info = fileInfoFor(null, candidate);
|
|
689922
|
+
if (isPreviewableArtifactInfo(info)) out.push(artifactFromPath(candidate));
|
|
689923
|
+
}
|
|
689924
|
+
|
|
689925
|
+
const trimmed = raw.trim();
|
|
689926
|
+
if ((trimmed.startsWith('{') && trimmed.endsWith('}')) || (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
|
|
689927
|
+
try {
|
|
689928
|
+
out.push(...extractArtifactsFromValue(JSON.parse(trimmed)));
|
|
689929
|
+
} catch {}
|
|
689930
|
+
}
|
|
689931
|
+
|
|
689932
|
+
return uniqueArtifacts(out);
|
|
689933
|
+
}
|
|
689934
|
+
|
|
689935
|
+
function extractArtifactsFromValue(value) {
|
|
689936
|
+
const out = [];
|
|
689937
|
+
const walk = (v, key) => {
|
|
689938
|
+
if (v == null) return;
|
|
689939
|
+
if (typeof v === 'string') {
|
|
689940
|
+
const lowerKey = String(key || '').toLowerCase();
|
|
689941
|
+
if (/^(path|file|filename|output|url|href|src|artifact|download)$/.test(lowerKey)) {
|
|
689942
|
+
out.push(artifactFromUrl(v) || artifactFromPath(v));
|
|
689943
|
+
}
|
|
689944
|
+
out.push(...extractArtifactsFromText(v));
|
|
689945
|
+
return;
|
|
689946
|
+
}
|
|
689947
|
+
if (Array.isArray(v)) {
|
|
689948
|
+
for (const item of v.slice(0, 20)) walk(item, key);
|
|
689949
|
+
return;
|
|
689950
|
+
}
|
|
689951
|
+
if (typeof v === 'object') {
|
|
689952
|
+
const obj = v;
|
|
689953
|
+
const kind = typeof obj.kind === 'string' ? obj.kind : '';
|
|
689954
|
+
const direct = obj.url || obj.href || obj.src || obj.path || obj.output || obj.file || obj.filename;
|
|
689955
|
+
if (typeof direct === 'string') out.push(artifactFromUrl(direct, kind) || artifactFromPath(direct, kind));
|
|
689956
|
+
for (const [k, child] of Object.entries(obj).slice(0, 30)) walk(child, k);
|
|
689957
|
+
}
|
|
689958
|
+
};
|
|
689959
|
+
walk(value, '');
|
|
689960
|
+
return uniqueArtifacts(out);
|
|
689961
|
+
}
|
|
689962
|
+
|
|
689963
|
+
async function downloadArtifact(artifact) {
|
|
689964
|
+
const url = artifact.url || (artifact.path ? rawFileUrl(artifact.path) : '');
|
|
689965
|
+
if (!url) return;
|
|
689966
|
+
try {
|
|
689967
|
+
const r = await fetch(url, { headers: headers() });
|
|
689968
|
+
if (!r.ok) throw new Error('HTTP ' + r.status);
|
|
689969
|
+
const blob = await r.blob();
|
|
689970
|
+
const href = URL.createObjectURL(blob);
|
|
689971
|
+
const a = document.createElement('a');
|
|
689972
|
+
a.href = href;
|
|
689973
|
+
a.download = artifact.name || baseNameForPath(artifact.path || url) || 'artifact';
|
|
689974
|
+
document.body.appendChild(a);
|
|
689975
|
+
a.click();
|
|
689976
|
+
a.remove();
|
|
689977
|
+
setTimeout(() => URL.revokeObjectURL(href), 5000);
|
|
689978
|
+
} catch (e) {
|
|
689979
|
+
const s = document.getElementById('status');
|
|
689980
|
+
if (s) {
|
|
689981
|
+
const old = s.textContent;
|
|
689982
|
+
s.textContent = 'download failed: ' + (e && e.message ? e.message : String(e));
|
|
689983
|
+
setTimeout(() => { s.textContent = old; }, 2500);
|
|
689984
|
+
}
|
|
689985
|
+
}
|
|
689986
|
+
}
|
|
689987
|
+
|
|
689988
|
+
function previewArtifact(artifact) {
|
|
689989
|
+
if (artifact.path) {
|
|
689990
|
+
previewFile(artifact.path);
|
|
689991
|
+
return;
|
|
689992
|
+
}
|
|
689993
|
+
const info = artifact.info || fileInfoFor({ name: artifact.name, kind: artifact.kind }, artifact.name || artifact.url);
|
|
689994
|
+
const shell = createFilePreviewShell(artifact.name || artifact.url, info);
|
|
689995
|
+
const src = artifact.url;
|
|
689996
|
+
const openLink = shell.card.querySelector('a');
|
|
689997
|
+
if (openLink) openLink.href = src;
|
|
689998
|
+
if (info.kind === 'audio') {
|
|
689999
|
+
const audio = document.createElement('audio');
|
|
690000
|
+
audio.controls = true;
|
|
690001
|
+
audio.preload = 'metadata';
|
|
690002
|
+
audio.src = src;
|
|
690003
|
+
audio.style.cssText = 'width:min(680px,82vw);display:block';
|
|
690004
|
+
shell.body.appendChild(audio);
|
|
690005
|
+
} else if (info.kind === 'video') {
|
|
690006
|
+
const video = document.createElement('video');
|
|
690007
|
+
video.controls = true;
|
|
690008
|
+
video.preload = 'metadata';
|
|
690009
|
+
video.src = src;
|
|
690010
|
+
video.style.cssText = 'max-width:86vw;max-height:76vh;background:#000;display:block';
|
|
690011
|
+
shell.body.appendChild(video);
|
|
690012
|
+
} else if (info.kind === 'image') {
|
|
690013
|
+
const img = document.createElement('img');
|
|
690014
|
+
img.src = src;
|
|
690015
|
+
img.alt = artifact.name || 'artifact';
|
|
690016
|
+
img.style.cssText = 'max-width:86vw;max-height:76vh;object-fit:contain;display:block';
|
|
690017
|
+
shell.body.appendChild(img);
|
|
690018
|
+
} else {
|
|
690019
|
+
const link = document.createElement('a');
|
|
690020
|
+
link.href = src;
|
|
690021
|
+
link.target = '_blank';
|
|
690022
|
+
link.rel = 'noopener noreferrer';
|
|
690023
|
+
link.textContent = 'open artifact';
|
|
690024
|
+
link.style.cssText = 'color:var(--color-brand);border:1px solid var(--color-border);border-radius:3px;padding:6px 10px;text-decoration:none';
|
|
690025
|
+
shell.body.appendChild(link);
|
|
690026
|
+
}
|
|
690027
|
+
document.body.appendChild(shell.modal);
|
|
690028
|
+
}
|
|
690029
|
+
|
|
690030
|
+
function appendArtifactControls(parent, artifacts) {
|
|
690031
|
+
const items = uniqueArtifacts(artifacts);
|
|
690032
|
+
if (!parent || items.length === 0) return null;
|
|
690033
|
+
const wrap = document.createElement('div');
|
|
690034
|
+
wrap.className = 'artifact-controls';
|
|
690035
|
+
wrap.style.cssText = 'display:flex;flex-direction:column;gap:6px;margin:6px 0 2px 0';
|
|
690036
|
+
for (const artifact of items) {
|
|
690037
|
+
const info = artifact.info || fileInfoFor({ name: artifact.name, kind: artifact.kind }, artifact.path || artifact.name || artifact.url);
|
|
690038
|
+
const row = document.createElement('div');
|
|
690039
|
+
row.style.cssText = 'display:flex;align-items:center;gap:8px;min-width:0;background:var(--color-bg);border:1px solid var(--color-border);border-left:2px solid var(--color-brand);border-radius:4px;padding:6px 8px;color:var(--color-fg);font-size:0.68rem';
|
|
690040
|
+
const label = document.createElement('span');
|
|
690041
|
+
label.textContent = (info.icon || '◇') + ' ' + (artifact.name || baseNameForPath(artifact.path || artifact.url || 'artifact'));
|
|
690042
|
+
label.title = artifact.path || artifact.url || '';
|
|
690043
|
+
label.style.cssText = 'min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1';
|
|
690044
|
+
row.appendChild(label);
|
|
690045
|
+
|
|
690046
|
+
if (info.kind === 'audio') {
|
|
690047
|
+
const audio = document.createElement('audio');
|
|
690048
|
+
audio.controls = true;
|
|
690049
|
+
audio.preload = 'metadata';
|
|
690050
|
+
audio.src = artifact.url || rawFileUrl(artifact.path);
|
|
690051
|
+
audio.style.cssText = 'width:min(320px,40vw);height:28px;flex:0 1 320px';
|
|
690052
|
+
row.appendChild(audio);
|
|
690053
|
+
} else if (isPreviewableArtifactInfo(info)) {
|
|
690054
|
+
const view = document.createElement('button');
|
|
690055
|
+
view.type = 'button';
|
|
690056
|
+
view.textContent = 'view';
|
|
690057
|
+
view.title = 'View ' + info.label;
|
|
690058
|
+
view.style.cssText = 'background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);border-radius:3px;padding:3px 8px;cursor:pointer;font:inherit;font-size:0.64rem;flex-shrink:0';
|
|
690059
|
+
view.onclick = (e) => { e.stopPropagation(); previewArtifact(artifact); };
|
|
690060
|
+
row.appendChild(view);
|
|
690061
|
+
}
|
|
690062
|
+
|
|
690063
|
+
const download = document.createElement('button');
|
|
690064
|
+
download.type = 'button';
|
|
690065
|
+
download.textContent = 'download';
|
|
690066
|
+
download.title = 'Download ' + (artifact.name || 'artifact');
|
|
690067
|
+
download.style.cssText = 'background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-brand);border-radius:3px;padding:3px 8px;cursor:pointer;font:inherit;font-size:0.64rem;flex-shrink:0';
|
|
690068
|
+
download.onclick = (e) => { e.stopPropagation(); downloadArtifact(artifact); };
|
|
690069
|
+
row.appendChild(download);
|
|
690070
|
+
wrap.appendChild(row);
|
|
690071
|
+
}
|
|
690072
|
+
parent.appendChild(wrap);
|
|
690073
|
+
return wrap;
|
|
690074
|
+
}
|
|
690075
|
+
|
|
690076
|
+
function appendArtifactsForText(parent, text) {
|
|
690077
|
+
return appendArtifactControls(parent, extractArtifactsFromText(text));
|
|
690078
|
+
}
|
|
690079
|
+
|
|
689671
690080
|
function appendFileKindBadge(row, info) {
|
|
689672
690081
|
if (!info || info.kind === 'text') return;
|
|
689673
690082
|
const badge = document.createElement('span');
|
|
@@ -690446,7 +690855,9 @@ async function restoreChatSession() {
|
|
|
690446
690855
|
messages: messages,
|
|
690447
690856
|
model: data.model || modelSelect.value,
|
|
690448
690857
|
updatedAt: data.updated_at || data.updatedAt || new Date().toISOString(),
|
|
690449
|
-
|
|
690858
|
+
title: data.title || (($chatSessions.get && $chatSessions.get()) || {})[data.id]?.title || sessionDisplayTitle(data.id, { messages }),
|
|
690859
|
+
name: data.title || (($chatSessions.get && $chatSessions.get()) || {})[data.id]?.name || sessionDisplayTitle(data.id, { messages }),
|
|
690860
|
+
preview: data.preview || messages.slice(-1)[0]?.content?.slice(0, 50) || 'empty',
|
|
690450
690861
|
};
|
|
690451
690862
|
saveScopedSessions(saved);
|
|
690452
690863
|
$chatSessions.set({ ...(($chatSessions.get && $chatSessions.get()) || {}), ...saved });
|
|
@@ -691633,7 +692044,7 @@ function _renderSidebarChats(filter) {
|
|
|
691633
692044
|
|
|
691634
692045
|
const renderRow = (id) => {
|
|
691635
692046
|
const s = sessions[id] || {};
|
|
691636
|
-
const title = (
|
|
692047
|
+
const title = sessionDisplayTitle(id, s).toString();
|
|
691637
692048
|
const cls = 'sb-chat' + (id === activeId ? ' active' : '');
|
|
691638
692049
|
const safeId = String(id).replace(/'/g, "\\\\'");
|
|
691639
692050
|
const safeTitle = title.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
@@ -701804,6 +702215,10 @@ ${historyLines}
|
|
|
701804
702215
|
jsonResponse(res, 200, {
|
|
701805
702216
|
id: session.id,
|
|
701806
702217
|
model: session.model,
|
|
702218
|
+
title: session.title ?? null,
|
|
702219
|
+
preview: session.preview ?? null,
|
|
702220
|
+
source: session.source ?? "web",
|
|
702221
|
+
projectRoot: session.projectRoot ?? null,
|
|
701807
702222
|
messages: publicMessages,
|
|
701808
702223
|
message_count: publicMessages.length,
|
|
701809
702224
|
tokens_in: session.tokensIn,
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.324",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.324",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
|
@@ -5239,9 +5239,9 @@
|
|
|
5239
5239
|
"license": "Apache-2.0 OR MIT"
|
|
5240
5240
|
},
|
|
5241
5241
|
"node_modules/nanoid": {
|
|
5242
|
-
"version": "5.1.
|
|
5243
|
-
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.
|
|
5244
|
-
"integrity": "sha512-
|
|
5242
|
+
"version": "5.1.15",
|
|
5243
|
+
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.15.tgz",
|
|
5244
|
+
"integrity": "sha512-kBg3RpGtIe+RpTbyXwoI6pk5yD7KUiI3sygUqgeBMRst42KmhB4RZC7eiO9Wa1HIpaCCtpE2DJ6OI4Wi5ebwFw==",
|
|
5245
5245
|
"funding": [
|
|
5246
5246
|
{
|
|
5247
5247
|
"type": "github",
|
|
@@ -6484,9 +6484,9 @@
|
|
|
6484
6484
|
"license": "MIT"
|
|
6485
6485
|
},
|
|
6486
6486
|
"node_modules/semver": {
|
|
6487
|
-
"version": "7.8.
|
|
6488
|
-
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.
|
|
6489
|
-
"integrity": "sha512-
|
|
6487
|
+
"version": "7.8.5",
|
|
6488
|
+
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
|
|
6489
|
+
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
|
|
6490
6490
|
"license": "ISC",
|
|
6491
6491
|
"bin": {
|
|
6492
6492
|
"semver": "bin/semver.js"
|
package/package.json
CHANGED