Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91699a382e |
No files matched your search
+17
-1
@@ -223,7 +223,12 @@ function stamped(messages: HistoryMessage[]): HistoryMessage[] {
|
||||
|
||||
const HISTORY: Record<string, HistoryMessage[]> = {
|
||||
[MASTER]: [
|
||||
{ content: "с утра: дневник приехал? что в хендауте", role: "user" },
|
||||
{
|
||||
content: "с утра: дневник приехал? что в хендауте",
|
||||
role: "user",
|
||||
service:
|
||||
"[envelope - background signal, not a message; react only if it bears on the question]\ntime: 2026-08-29 06:04 (Warsaw)\nvault, changed since 05:09: 📅 дни/2026-08-29.md (+4)\n--- 📅 дни/2026-08-29.md, added lines only ---\n+ # планы\n+ просрочены:\n+ ```tasks\n+ not done\n+ 06:04 - пожалуй пойду спать",
|
||||
},
|
||||
{
|
||||
content:
|
||||
"Приехал. В [[2026-08-28|хендауте]] два хвоста: **бластер** ждёт выбора модели, и **ufw на dell** - порт 62990 снаружи молчит. Ветка по ufw открыта, см. [[ufw на dell]].",
|
||||
@@ -232,6 +237,11 @@ const HISTORY: Record<string, HistoryMessage[]> = {
|
||||
{ content: "ок, гони ufw", role: "user" },
|
||||
{
|
||||
content: [
|
||||
{
|
||||
thinking:
|
||||
"The firewall rule and the proxy config can disagree in two ways: the port is closed, or nothing listens behind it. Reading the Caddy site first tells me which port the outside is supposed to reach at all.",
|
||||
type: "thinking",
|
||||
},
|
||||
{
|
||||
text: "Смотрю правила через `ssh dell` и сверяю с `site.caddy`.",
|
||||
type: "text",
|
||||
@@ -242,6 +252,12 @@ const HISTORY: Record<string, HistoryMessage[]> = {
|
||||
name: "Bash",
|
||||
type: "tool_use",
|
||||
},
|
||||
{
|
||||
id: "tu_say",
|
||||
input: { text: "Нашёл: снаружи должен отвечать 443, не 62990." },
|
||||
name: "mcp__gateway__say",
|
||||
type: "tool_use",
|
||||
},
|
||||
],
|
||||
role: "assistant",
|
||||
},
|
||||
|
||||
+15
-3
@@ -1,5 +1,6 @@
|
||||
import type { App, Component } from "obsidian";
|
||||
import { MarkdownRenderer, Platform } from "obsidian";
|
||||
import { MarkdownPreviewRenderer, MarkdownRenderer, Platform } from "obsidian";
|
||||
import { inertFences } from "$lib/panel/fences";
|
||||
import type { PanelHost } from "$lib/panel/host";
|
||||
|
||||
export interface HostOptions {
|
||||
@@ -12,17 +13,28 @@ export interface HostOptions {
|
||||
sourcePath: () => string;
|
||||
}
|
||||
|
||||
const QUERY_LANGUAGES = new Set(["tasks", "dataview", "dataviewjs", "query"]);
|
||||
|
||||
function runs(language: string): boolean {
|
||||
const registered = (
|
||||
MarkdownPreviewRenderer as unknown as {
|
||||
codeBlockPostProcessors?: Record<string, unknown>;
|
||||
}
|
||||
).codeBlockPostProcessors;
|
||||
return QUERY_LANGUAGES.has(language) || language in (registered ?? {});
|
||||
}
|
||||
|
||||
// The Obsidian side of the panel: markdown through the app's own renderer,
|
||||
// [[links]] opened in place, a conversation's note opened by its binding.
|
||||
export function obsidianHost(options: HostOptions): PanelHost {
|
||||
const { app, component } = options;
|
||||
return {
|
||||
markdown(node, text) {
|
||||
markdown(node, text, { inert = false } = {}) {
|
||||
let alive = true;
|
||||
const staging = document.createElement("div");
|
||||
MarkdownRenderer.render(
|
||||
app,
|
||||
text,
|
||||
inert ? inertFences(text, runs) : text,
|
||||
staging,
|
||||
options.sourcePath(),
|
||||
component
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { inertFences } from "$lib/panel/fences";
|
||||
|
||||
const runs = (language: string) => ["tasks", "dataview"].includes(language);
|
||||
|
||||
describe("inertFences", () => {
|
||||
it("turns a query block into code", () => {
|
||||
expect(inertFences("```tasks\nnot done\n```", runs)).toBe(
|
||||
"```text\nnot done\n```"
|
||||
);
|
||||
expect(inertFences("~~~Dataview\nlist\n~~~", runs)).toBe(
|
||||
"~~~text\nlist\n~~~"
|
||||
);
|
||||
});
|
||||
|
||||
it("reaches a block opened inside a list item or a quote", () => {
|
||||
expect(inertFences("+ ```tasks\n+ not done", runs)).toBe(
|
||||
"+ ```text\n+ not done"
|
||||
);
|
||||
expect(inertFences("> 1. ````tasks {x}", runs)).toBe("> 1. ````text {x}");
|
||||
});
|
||||
|
||||
it("leaves ordinary code and closing fences alone", () => {
|
||||
const text = "```python\nprint(1)\n```\ninline `tasks` stays";
|
||||
expect(inertFences(text, runs)).toBe(text);
|
||||
});
|
||||
});
|
||||
@@ -34,6 +34,12 @@ export const moment = () => undefined;
|
||||
export const requestUrl = () =>
|
||||
Promise.reject(new Error("no network in the stub"));
|
||||
export const setIcon = () => undefined;
|
||||
export const MarkdownPreviewRenderer = {
|
||||
codeBlockPostProcessors: { tasks: () => undefined } as Record<
|
||||
string,
|
||||
unknown
|
||||
>,
|
||||
};
|
||||
|
||||
function escapeHtml(value: string): string {
|
||||
return value
|
||||
|
||||
@@ -3,6 +3,7 @@ import { defineConfig } from "vitest/config";
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
$lib: new URL("../beaver-gateway/ui/src/lib", import.meta.url).pathname,
|
||||
obsidian: new URL("./tests/obsidian-stub.ts", import.meta.url).pathname,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user