diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index a582da1..6acba75 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -24,6 +24,7 @@ import { saveAttachments as _saveAttachments, type AttachmentResult } from "./at import { handleStreaming as _handleStream } from "./streaming"; import { handleNew, handleRestart, handleUpdate, handleCompact, handleStatus, handleStop, handleVerbose, handleDoctor, handleCrons, type CommandContext } from "./commands"; import { handleModel } from "./model-command"; +import { handleLater } from "./later-command"; import { TelegramAdapter } from "../transports"; import type { TransportAdapter } from "../transports"; import { hostname } from "node:os"; @@ -271,6 +272,12 @@ export class Gateway { return; } + // Handle /later command + if (isCommandWithArgs(userText.trim(), "/later") || isCommand(userText.trim(), "/later")) { + await handleLater({ thread, text: userText.trim(), postWithFallback: (t, txt) => this.postWithFallback(t, txt) }); + return; + } + // Dispatch to agent turn handler await this.handleAgentTurn(thread, agentThreadId, userText, rawAttachments, verboseThreads, threadLocks, abortControllers); }; diff --git a/src/gateway/later-command.ts b/src/gateway/later-command.ts new file mode 100644 index 0000000..8e4dc70 --- /dev/null +++ b/src/gateway/later-command.ts @@ -0,0 +1,57 @@ +/** + * gateway/later-command.ts — Handle the /later command + * + * Quickly capture ideas/notes to ~/.roundhouse/workspace/later.md + * without interrupting the current conversation flow. + */ + +import { homedir } from "node:os"; +import { join } from "node:path"; +import { appendFileSync, mkdirSync, existsSync, readFileSync } from "node:fs"; + +const WORKSPACE_DIR = join(homedir(), ".roundhouse", "workspace"); +const LATER_PATH = join(WORKSPACE_DIR, "later.md"); + +export interface LaterCommandContext { + thread: any; + text: string; + postWithFallback: (thread: any, text: string) => Promise; +} + +function ensureWorkspace(): void { + if (!existsSync(WORKSPACE_DIR)) { + mkdirSync(WORKSPACE_DIR, { recursive: true }); + } +} + +function ensureLaterFile(): void { + ensureWorkspace(); + if (!existsSync(LATER_PATH)) { + appendFileSync(LATER_PATH, "# Later\n\nIdeas, reminders, and things to get back to.\n\n"); + } +} + +export async function handleLater(ctx: LaterCommandContext): Promise { + const { thread, text, postWithFallback } = ctx; + const idea = text.replace(/^\/later\s*/i, "").trim(); + + // No argument: show contents + if (!idea) { + ensureLaterFile(); + const contents = readFileSync(LATER_PATH, "utf8").trim(); + const lines = contents.split("\n").filter(l => l.startsWith("- ")); + if (lines.length === 0) { + await postWithFallback(thread, "📋 *Later list is empty.*\n\n_Usage:_ `/later buy more coffee`"); + } else { + await postWithFallback(thread, `📋 *Later* (${lines.length} items):\n\n${lines.join("\n")}\n\n_File:_ \`~/.roundhouse/workspace/later.md\``); + } + return; + } + + // Append the idea + ensureLaterFile(); + const timestamp = new Date().toISOString().slice(0, 10); + appendFileSync(LATER_PATH, `- ${idea} _(${timestamp})_\n`); + + await postWithFallback(thread, `✅ Saved: "${idea}"`); +} diff --git a/src/gateway/tools.md b/src/gateway/tools.md index 0726716..5bc820a 100644 --- a/src/gateway/tools.md +++ b/src/gateway/tools.md @@ -2,6 +2,14 @@ Available tools that can be invoked via shell commands during agent turns. +## Workspace Directory + +**All new files, scratch work, downloads, and artifacts you create go under `~/.roundhouse/workspace/`.** +Do NOT create files directly in `~/` or pollute the home directory. Use subdirectories as needed: +- `~/.roundhouse/workspace/` — default working directory for any task output +- `~/.roundhouse/workspace/later.md` — ideas saved via `/later` +- `~/.roundhouse/workspace//` — project-specific files if needed + ## roundhouse cron add Schedule recurring or one-shot jobs. The user may ask you to "remind me", "check every X", "do Y later", or "schedule Z". diff --git a/src/transports/telegram/bot-commands.ts b/src/transports/telegram/bot-commands.ts index e1763fa..d6558e4 100644 --- a/src/transports/telegram/bot-commands.ts +++ b/src/transports/telegram/bot-commands.ts @@ -14,6 +14,7 @@ export const BOT_COMMANDS: BotCommand[] = [ { command: "new", description: "Start a fresh conversation" }, { command: "compact", description: "Compact context window" }, { command: "model", description: "Show or switch AI model" }, + { command: "later", description: "Save an idea for later" }, { command: "verbose", description: "Toggle verbose tool output" }, { command: "stop", description: "Stop the current agent run" }, { command: "restart", description: "Restart agent process" },