Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Thumbs.db
playwright-report/
test-results/
blob-report/
.playwright-mcp/

# Node modules (pnpm workspace hoists to root)
node_modules/
Expand Down
1 change: 1 addition & 0 deletions crates/sprout-acp/src/base_prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Run `sprout --help` or `sprout <group> --help` for full usage.
## Communication Patterns

- Address agents and humans with plain `@name` — do NOT bold or italicize mention text (formatting prevents alert delivery).
- Message content supports GitHub-flavored Markdown. Use fenced code blocks with a language tag (` ```python `, ` ```typescript `, etc.) for syntax-highlighted rendering on desktop and mobile. Omitting the language tag renders monochrome.
- Use `sprout messages thread` when responding in-thread; post new messages for new topics.
- No push notifications — poll with `sprout messages get --channel <UUID> --since <ts>`. When `since` is set without `before`, results are oldest-first (chronological).

Expand Down
7 changes: 5 additions & 2 deletions crates/sprout-mcp/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ async fn resolve_content_mentions(
pub struct SendMessageParams {
/// UUID of the channel to post to.
pub channel_id: String,
/// Message body text.
/// Message body text. Supports GitHub-flavored Markdown including fenced code
/// blocks with syntax highlighting.
pub content: String,
/// Nostr event kind. Defaults to KIND_STREAM_MESSAGE (NIP-29 group chat message).
#[serde(default = "default_kind")]
Expand Down Expand Up @@ -890,7 +891,9 @@ impl SproutMcpServer {
/// Send a message to a Sprout channel.
#[tool(
name = "send_message",
description = "Send a message to a Sprout channel. Include `parent_event_id` to reply in a thread. \
description = "Send a message to a Sprout channel. Content supports GitHub-flavored Markdown — \
use fenced code blocks with a language tag for syntax-highlighted rendering. \
Include `parent_event_id` to reply in a thread. \
Set `broadcast_to_channel` to also surface the reply in the main channel timeline. \
For forum channels, set `kind` to 45001 (post) or 45003 (comment with `parent_event_id`). \
Default kind is 9 (stream message)."
Expand Down
9 changes: 9 additions & 0 deletions desktop/src-tauri/src/managed_agents/nest_skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ Write commands are unaffected. `--format json` (default) returns full fields.

Other kind values are rejected. Use `messages vote --event <id> --direction up|down` to vote on forum posts.

## Message Formatting

Message content is rendered as GitHub-flavored Markdown on both desktop and mobile. Key formatting:

- **Fenced code blocks**: triple-backtick with a language tag for syntax highlighting (190+ languages supported). Omitting the language tag renders a styled monochrome block.
- **Inline code**: single backticks for inline monospace.
- **Mentions**: plain `@name` — do NOT bold or italicize (formatting prevents alert delivery).
- **Links, images, tables, blockquotes, headings**: standard GFM.

## Mem Patch Workflow

For safe concurrent writes, use hash-based conflict detection:
Expand Down
15 changes: 14 additions & 1 deletion desktop/src/features/messages/lib/codeBlockExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,20 @@ export function handleCodeFenceEnter(ed: Editor): boolean | undefined {
"",
);

if (FENCE_AT_START.test(textBefore)) return false;
const startMatch = textBefore.match(FENCE_AT_START);
if (startMatch) {
const { tr, schema } = ed.state;
const attrs = startMatch[1] ? { language: startMatch[1] } : {};
tr.delete($cursor.start(), $cursor.pos);
tr.setBlockType(
tr.mapping.map($cursor.start()),
tr.mapping.map($cursor.start()),
schema.nodes.codeBlock,
attrs,
);
ed.view.dispatch(tr);
return true;
}

const m = textBefore.match(FENCE_AFTER_BREAK);
if (!m) return undefined;
Expand Down
37 changes: 37 additions & 0 deletions desktop/src/shared/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,43 @@
}
}

/* ── Code block line numbers & diff ────────────────────────────────── */
.code-block-lines {
counter-reset: code-line;
}

.code-block-lines [data-line] {
display: block;
counter-increment: code-line;
}

.code-block-lines [data-line]::before {
content: counter(code-line);
display: inline-block;
width: 2.5ch;
margin-right: 1.5ch;
text-align: right;
color: hsl(var(--muted-foreground) / 0.4);
user-select: none;
pointer-events: none;
}

.code-line-diff-add {
background-color: hsl(120 40% 50% / 0.15);
}

.code-line-diff-remove {
background-color: hsl(0 60% 50% / 0.15);
}

.dark .code-line-diff-add {
background-color: hsl(120 40% 50% / 0.12);
}

.dark .code-line-diff-remove {
background-color: hsl(0 60% 50% / 0.12);
}

@layer base {
:root {
/* Catppuccin Latte (mauve accent) */
Expand Down
Loading