@hasna/coders 0.0.15 → 0.1.0
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/cli.mjs +1851 -1689
- package/dist/cli.mjs.map +4 -4
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -58441,7 +58441,7 @@ var init_client = __esm({
|
|
|
58441
58441
|
"Content-Type": "application/json",
|
|
58442
58442
|
"anthropic-version": "2023-06-01",
|
|
58443
58443
|
"anthropic-beta": BETA_HEADERS.join(","),
|
|
58444
|
-
"User-Agent": `coders/${"0.0
|
|
58444
|
+
"User-Agent": `coders/${"0.1.0"}`
|
|
58445
58445
|
};
|
|
58446
58446
|
if (key.isOAuth) {
|
|
58447
58447
|
headers["Authorization"] = `Bearer ${key.apiKey}`;
|
|
@@ -58639,237 +58639,680 @@ var init_client = __esm({
|
|
|
58639
58639
|
}
|
|
58640
58640
|
});
|
|
58641
58641
|
|
|
58642
|
-
// src/
|
|
58643
|
-
|
|
58644
|
-
|
|
58645
|
-
|
|
58646
|
-
|
|
58647
|
-
|
|
58648
|
-
|
|
58649
|
-
function detectTerminal() {
|
|
58650
|
-
const termProgram = process.env.TERM_PROGRAM ?? "";
|
|
58651
|
-
const term = process.env.TERM ?? "";
|
|
58652
|
-
const colorTerm = process.env.COLORTERM ?? "";
|
|
58653
|
-
const caps = {
|
|
58654
|
-
name: detectTerminalName(termProgram, term),
|
|
58655
|
-
colorDepth: detectColorDepth(termProgram, colorTerm, term),
|
|
58656
|
-
unicode: detectUnicode(),
|
|
58657
|
-
hyperlinks: detectHyperlinks(termProgram),
|
|
58658
|
-
kittyProtocol: detectKittyProtocol(termProgram),
|
|
58659
|
-
mouseSupport: true,
|
|
58660
|
-
// Most modern terminals support SGR mouse
|
|
58661
|
-
sixelGraphics: detectSixel(termProgram),
|
|
58662
|
-
iterm2Images: termProgram === "iTerm.app"
|
|
58663
|
-
};
|
|
58664
|
-
return caps;
|
|
58665
|
-
}
|
|
58666
|
-
function detectTerminalName(termProgram, term) {
|
|
58667
|
-
if (termProgram === "iTerm.app") return "iTerm2";
|
|
58668
|
-
if (termProgram === "WezTerm") return "WezTerm";
|
|
58669
|
-
if (termProgram === "vscode") return "VSCode";
|
|
58670
|
-
if (termProgram === "Alacritty") return "Alacritty";
|
|
58671
|
-
if (termProgram === "ghostty") return "Ghostty";
|
|
58672
|
-
if (termProgram === "contour") return "Contour";
|
|
58673
|
-
if (termProgram === "mintty") return "Mintty";
|
|
58674
|
-
if (process.env.KITTY_WINDOW_ID) return "Kitty";
|
|
58675
|
-
if (termProgram === "kitty") return "Kitty";
|
|
58676
|
-
if (term === "foot" || term === "foot-extra") return "foot";
|
|
58677
|
-
if (process.env.WARP_IS_LOCAL_SHELL_SESSION) return "Warp";
|
|
58678
|
-
if (termProgram === "Warp") return "Warp";
|
|
58679
|
-
if (process.env.WT_SESSION) return "Windows Terminal";
|
|
58680
|
-
if (process.env.ConEmuANSI || process.env.ConEmuPID) return "ConEmu";
|
|
58681
|
-
const vteVersion = process.env.VTE_VERSION;
|
|
58682
|
-
if (vteVersion) {
|
|
58683
|
-
const ver = parseInt(vteVersion, 10);
|
|
58684
|
-
if (ver >= 6800) return "VTE (modern)";
|
|
58685
|
-
return "VTE";
|
|
58686
|
-
}
|
|
58687
|
-
if (term.startsWith("xterm")) return "xterm";
|
|
58688
|
-
if (term.startsWith("screen")) return "screen";
|
|
58689
|
-
if (term.startsWith("tmux")) return "tmux";
|
|
58690
|
-
return "unknown";
|
|
58691
|
-
}
|
|
58692
|
-
function detectColorDepth(termProgram, colorTerm, term) {
|
|
58693
|
-
if (colorTerm === "truecolor" || colorTerm === "24bit") return 24;
|
|
58694
|
-
const truecolorTerminals = [
|
|
58695
|
-
"iTerm.app",
|
|
58696
|
-
"WezTerm",
|
|
58697
|
-
"Alacritty",
|
|
58698
|
-
"kitty",
|
|
58699
|
-
"ghostty",
|
|
58700
|
-
"contour",
|
|
58701
|
-
"foot"
|
|
58702
|
-
];
|
|
58703
|
-
if (truecolorTerminals.includes(termProgram)) return 24;
|
|
58704
|
-
if (process.env.KITTY_WINDOW_ID) return 24;
|
|
58705
|
-
if (process.env.WT_SESSION) return 24;
|
|
58706
|
-
if (termProgram === "vscode") return 24;
|
|
58707
|
-
if (term.includes("256color")) return 8;
|
|
58708
|
-
if (colorTerm) return 8;
|
|
58709
|
-
if (term.includes("color") || term.startsWith("xterm")) return 4;
|
|
58710
|
-
if (term === "dumb" || !process.stdout.isTTY) return 1;
|
|
58711
|
-
return 4;
|
|
58712
|
-
}
|
|
58713
|
-
function detectUnicode() {
|
|
58714
|
-
const lang = process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_CTYPE ?? "";
|
|
58715
|
-
return lang.toLowerCase().includes("utf");
|
|
58716
|
-
}
|
|
58717
|
-
function detectHyperlinks(termProgram) {
|
|
58718
|
-
const supported = [
|
|
58719
|
-
"iTerm.app",
|
|
58720
|
-
"WezTerm",
|
|
58721
|
-
"Alacritty",
|
|
58722
|
-
"kitty",
|
|
58723
|
-
"ghostty",
|
|
58724
|
-
"contour",
|
|
58725
|
-
"foot",
|
|
58726
|
-
"vscode"
|
|
58727
|
-
];
|
|
58728
|
-
if (supported.includes(termProgram)) return true;
|
|
58729
|
-
if (process.env.KITTY_WINDOW_ID) return true;
|
|
58730
|
-
if (process.env.WT_SESSION) return true;
|
|
58731
|
-
return false;
|
|
58732
|
-
}
|
|
58733
|
-
function detectKittyProtocol(termProgram) {
|
|
58734
|
-
if (process.env.KITTY_WINDOW_ID) return true;
|
|
58735
|
-
if (termProgram === "kitty") return true;
|
|
58736
|
-
if (termProgram === "ghostty") return true;
|
|
58737
|
-
if (termProgram === "foot") return true;
|
|
58738
|
-
if (termProgram === "WezTerm") return true;
|
|
58739
|
-
return false;
|
|
58740
|
-
}
|
|
58741
|
-
function detectSixel(termProgram) {
|
|
58742
|
-
if (termProgram === "WezTerm") return true;
|
|
58743
|
-
if (termProgram === "foot") return true;
|
|
58744
|
-
if (termProgram === "contour") return true;
|
|
58745
|
-
return false;
|
|
58746
|
-
}
|
|
58747
|
-
function getTerminalSize() {
|
|
58748
|
-
return {
|
|
58749
|
-
columns: process.stdout.columns ?? 80,
|
|
58750
|
-
rows: process.stdout.rows ?? 24
|
|
58751
|
-
};
|
|
58752
|
-
}
|
|
58753
|
-
function onResize(callback) {
|
|
58754
|
-
const handler = () => {
|
|
58755
|
-
const { columns, rows } = getTerminalSize();
|
|
58756
|
-
callback(columns, rows);
|
|
58757
|
-
};
|
|
58758
|
-
process.stdout.on("resize", handler);
|
|
58759
|
-
return () => process.stdout.removeListener("resize", handler);
|
|
58642
|
+
// src/db/index.ts
|
|
58643
|
+
import { join as join2 } from "path";
|
|
58644
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
58645
|
+
function getDbPath() {
|
|
58646
|
+
const dir = getConfigDir();
|
|
58647
|
+
if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true });
|
|
58648
|
+
return join2(dir, "coders.db");
|
|
58760
58649
|
}
|
|
58761
|
-
|
|
58762
|
-
|
|
58763
|
-
|
|
58650
|
+
function getDb() {
|
|
58651
|
+
if (_db) return _db;
|
|
58652
|
+
const dbPath = getDbPath();
|
|
58653
|
+
try {
|
|
58654
|
+
const { Database } = __require("bun:sqlite");
|
|
58655
|
+
_db = new Database(dbPath);
|
|
58656
|
+
} catch {
|
|
58657
|
+
try {
|
|
58658
|
+
const BetterSqlite3 = __require("better-sqlite3");
|
|
58659
|
+
_db = new BetterSqlite3(dbPath);
|
|
58660
|
+
} catch {
|
|
58661
|
+
_db = createJsonFileDb();
|
|
58662
|
+
initSchema(_db);
|
|
58663
|
+
return _db;
|
|
58664
|
+
}
|
|
58764
58665
|
}
|
|
58765
|
-
|
|
58766
|
-
|
|
58767
|
-
|
|
58768
|
-
function registerSlashCommand(cmd) {
|
|
58769
|
-
commands.set(cmd.name, cmd);
|
|
58770
|
-
if (cmd.aliases) {
|
|
58771
|
-
for (const alias of cmd.aliases) commands.set(alias, cmd);
|
|
58666
|
+
try {
|
|
58667
|
+
_db.exec("PRAGMA journal_mode=WAL");
|
|
58668
|
+
} catch {
|
|
58772
58669
|
}
|
|
58773
|
-
|
|
58774
|
-
|
|
58775
|
-
|
|
58776
|
-
const result = [];
|
|
58777
|
-
for (const cmd of commands.values()) {
|
|
58778
|
-
if (!seen.has(cmd.name)) {
|
|
58779
|
-
seen.add(cmd.name);
|
|
58780
|
-
result.push(cmd);
|
|
58781
|
-
}
|
|
58670
|
+
try {
|
|
58671
|
+
_db.exec("PRAGMA foreign_keys=ON");
|
|
58672
|
+
} catch {
|
|
58782
58673
|
}
|
|
58783
|
-
|
|
58784
|
-
|
|
58785
|
-
function isSlashCommand(input) {
|
|
58786
|
-
return input.startsWith("/") && commands.has(input.slice(1).split(/\s/)[0]);
|
|
58787
|
-
}
|
|
58788
|
-
async function executeSlashCommand(input) {
|
|
58789
|
-
const parts = input.replace(/^\//, "").split(/\s+/);
|
|
58790
|
-
const name = parts[0];
|
|
58791
|
-
const args = parts.slice(1).join(" ");
|
|
58792
|
-
const cmd = commands.get(name);
|
|
58793
|
-
if (!cmd) return { output: `Unknown command: /${name}. Type /help for available commands.` };
|
|
58794
|
-
return cmd.handler(args);
|
|
58674
|
+
initSchema(_db);
|
|
58675
|
+
return _db;
|
|
58795
58676
|
}
|
|
58796
|
-
function
|
|
58797
|
-
|
|
58798
|
-
|
|
58799
|
-
|
|
58800
|
-
|
|
58801
|
-
|
|
58802
|
-
|
|
58803
|
-
|
|
58804
|
-
|
|
58805
|
-
|
|
58806
|
-
|
|
58807
|
-
|
|
58808
|
-
|
|
58809
|
-
|
|
58810
|
-
|
|
58811
|
-
|
|
58812
|
-
|
|
58813
|
-
|
|
58814
|
-
|
|
58815
|
-
|
|
58816
|
-
|
|
58817
|
-
|
|
58818
|
-
|
|
58819
|
-
|
|
58820
|
-
|
|
58821
|
-
|
|
58822
|
-
|
|
58823
|
-
|
|
58824
|
-
|
|
58825
|
-
|
|
58826
|
-
|
|
58827
|
-
|
|
58828
|
-
|
|
58829
|
-
|
|
58830
|
-
|
|
58831
|
-
|
|
58832
|
-
|
|
58833
|
-
|
|
58834
|
-
|
|
58835
|
-
|
|
58836
|
-
|
|
58837
|
-
|
|
58838
|
-
|
|
58839
|
-
|
|
58840
|
-
|
|
58841
|
-
|
|
58842
|
-
|
|
58843
|
-
|
|
58844
|
-
|
|
58845
|
-
|
|
58846
|
-
|
|
58847
|
-
|
|
58848
|
-
|
|
58849
|
-
|
|
58850
|
-
|
|
58851
|
-
|
|
58852
|
-
|
|
58853
|
-
|
|
58854
|
-
|
|
58855
|
-
|
|
58856
|
-
|
|
58857
|
-
|
|
58858
|
-
|
|
58859
|
-
|
|
58860
|
-
|
|
58861
|
-
|
|
58862
|
-
|
|
58863
|
-
|
|
58864
|
-
|
|
58865
|
-
|
|
58866
|
-
|
|
58867
|
-
|
|
58868
|
-
|
|
58869
|
-
|
|
58870
|
-
|
|
58871
|
-
|
|
58872
|
-
|
|
58677
|
+
function initSchema(db) {
|
|
58678
|
+
db.exec(`
|
|
58679
|
+
-- Sessions
|
|
58680
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
58681
|
+
id TEXT PRIMARY KEY,
|
|
58682
|
+
device_id TEXT NOT NULL,
|
|
58683
|
+
project_dir TEXT,
|
|
58684
|
+
original_cwd TEXT,
|
|
58685
|
+
model TEXT,
|
|
58686
|
+
app_version TEXT,
|
|
58687
|
+
build_time TEXT,
|
|
58688
|
+
fingerprint TEXT, -- JSON
|
|
58689
|
+
metadata TEXT, -- JSON
|
|
58690
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
58691
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
58692
|
+
);
|
|
58693
|
+
|
|
58694
|
+
-- Messages (conversation history)
|
|
58695
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
58696
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58697
|
+
session_id TEXT NOT NULL REFERENCES sessions(id),
|
|
58698
|
+
role TEXT NOT NULL CHECK(role IN ('user','assistant','system')),
|
|
58699
|
+
content TEXT NOT NULL,
|
|
58700
|
+
tool_uses TEXT, -- JSON array of tool use displays
|
|
58701
|
+
thinking TEXT,
|
|
58702
|
+
duration_ms REAL,
|
|
58703
|
+
tokens_in INTEGER DEFAULT 0,
|
|
58704
|
+
tokens_out INTEGER DEFAULT 0,
|
|
58705
|
+
cost_usd REAL DEFAULT 0,
|
|
58706
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58707
|
+
);
|
|
58708
|
+
CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id);
|
|
58709
|
+
|
|
58710
|
+
-- File history (tracks reads per session)
|
|
58711
|
+
CREATE TABLE IF NOT EXISTS file_history (
|
|
58712
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58713
|
+
session_id TEXT NOT NULL,
|
|
58714
|
+
file_path TEXT NOT NULL,
|
|
58715
|
+
content_hash TEXT,
|
|
58716
|
+
byte_size INTEGER,
|
|
58717
|
+
line_count INTEGER,
|
|
58718
|
+
read_at TEXT DEFAULT (datetime('now')),
|
|
58719
|
+
UNIQUE(session_id, file_path)
|
|
58720
|
+
);
|
|
58721
|
+
|
|
58722
|
+
-- File checkpoints (for /rewind)
|
|
58723
|
+
CREATE TABLE IF NOT EXISTS checkpoints (
|
|
58724
|
+
id TEXT PRIMARY KEY,
|
|
58725
|
+
session_id TEXT NOT NULL,
|
|
58726
|
+
file_path TEXT NOT NULL,
|
|
58727
|
+
original_content TEXT NOT NULL,
|
|
58728
|
+
edit_operation TEXT, -- JSON {old_string, new_string}
|
|
58729
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58730
|
+
);
|
|
58731
|
+
CREATE INDEX IF NOT EXISTS idx_checkpoints_session_file ON checkpoints(session_id, file_path);
|
|
58732
|
+
|
|
58733
|
+
-- Tasks (replaces in-memory fallback for @hasna/todos)
|
|
58734
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
58735
|
+
id TEXT PRIMARY KEY,
|
|
58736
|
+
subject TEXT NOT NULL,
|
|
58737
|
+
description TEXT DEFAULT '',
|
|
58738
|
+
status TEXT DEFAULT 'pending' CHECK(status IN ('pending','in_progress','completed','failed','cancelled')),
|
|
58739
|
+
active_form TEXT,
|
|
58740
|
+
owner TEXT,
|
|
58741
|
+
blocks TEXT DEFAULT '[]', -- JSON array of task IDs
|
|
58742
|
+
blocked_by TEXT DEFAULT '[]', -- JSON array of task IDs
|
|
58743
|
+
metadata TEXT DEFAULT '{}', -- JSON
|
|
58744
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
58745
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
58746
|
+
);
|
|
58747
|
+
|
|
58748
|
+
-- Config (replaces JSON files)
|
|
58749
|
+
CREATE TABLE IF NOT EXISTS config (
|
|
58750
|
+
key TEXT PRIMARY KEY,
|
|
58751
|
+
value TEXT, -- JSON
|
|
58752
|
+
scope TEXT DEFAULT 'user' CHECK(scope IN ('user','project','local','global')),
|
|
58753
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
58754
|
+
);
|
|
58755
|
+
|
|
58756
|
+
-- Memories (replaces in-memory fallback for @hasna/mementos)
|
|
58757
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
58758
|
+
id TEXT PRIMARY KEY,
|
|
58759
|
+
key TEXT UNIQUE NOT NULL,
|
|
58760
|
+
value TEXT NOT NULL,
|
|
58761
|
+
scope TEXT DEFAULT 'shared' CHECK(scope IN ('global','shared','private')),
|
|
58762
|
+
category TEXT DEFAULT 'knowledge',
|
|
58763
|
+
importance INTEGER DEFAULT 5 CHECK(importance BETWEEN 1 AND 10),
|
|
58764
|
+
tags TEXT DEFAULT '[]', -- JSON array
|
|
58765
|
+
version INTEGER DEFAULT 1,
|
|
58766
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
58767
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
58768
|
+
);
|
|
58769
|
+
|
|
58770
|
+
-- Teams
|
|
58771
|
+
CREATE TABLE IF NOT EXISTS teams (
|
|
58772
|
+
name TEXT PRIMARY KEY,
|
|
58773
|
+
description TEXT,
|
|
58774
|
+
task_list_id TEXT,
|
|
58775
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58776
|
+
);
|
|
58777
|
+
|
|
58778
|
+
-- Team members
|
|
58779
|
+
CREATE TABLE IF NOT EXISTS team_members (
|
|
58780
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58781
|
+
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
58782
|
+
agent_name TEXT NOT NULL,
|
|
58783
|
+
role TEXT,
|
|
58784
|
+
status TEXT DEFAULT 'idle',
|
|
58785
|
+
current_task TEXT,
|
|
58786
|
+
UNIQUE(team_name, agent_name)
|
|
58787
|
+
);
|
|
58788
|
+
|
|
58789
|
+
-- Team messages
|
|
58790
|
+
CREATE TABLE IF NOT EXISTS team_messages (
|
|
58791
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58792
|
+
from_agent TEXT NOT NULL,
|
|
58793
|
+
to_agent TEXT NOT NULL,
|
|
58794
|
+
team_name TEXT,
|
|
58795
|
+
content TEXT NOT NULL,
|
|
58796
|
+
is_read INTEGER DEFAULT 0,
|
|
58797
|
+
is_blocking INTEGER DEFAULT 0,
|
|
58798
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58799
|
+
);
|
|
58800
|
+
CREATE INDEX IF NOT EXISTS idx_team_msgs_to ON team_messages(to_agent, is_read);
|
|
58801
|
+
|
|
58802
|
+
-- Permissions (persisted allow/deny rules)
|
|
58803
|
+
CREATE TABLE IF NOT EXISTS permissions (
|
|
58804
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58805
|
+
tool_name TEXT,
|
|
58806
|
+
command_pattern TEXT,
|
|
58807
|
+
path_pattern TEXT,
|
|
58808
|
+
behavior TEXT NOT NULL CHECK(behavior IN ('allow','deny')),
|
|
58809
|
+
scope TEXT DEFAULT 'session',
|
|
58810
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58811
|
+
);
|
|
58812
|
+
|
|
58813
|
+
-- MCP servers
|
|
58814
|
+
CREATE TABLE IF NOT EXISTS mcp_servers (
|
|
58815
|
+
name TEXT PRIMARY KEY,
|
|
58816
|
+
command TEXT,
|
|
58817
|
+
args TEXT, -- JSON array
|
|
58818
|
+
env TEXT, -- JSON object
|
|
58819
|
+
url TEXT,
|
|
58820
|
+
transport TEXT DEFAULT 'stdio',
|
|
58821
|
+
scope TEXT DEFAULT 'user',
|
|
58822
|
+
enabled INTEGER DEFAULT 1,
|
|
58823
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58824
|
+
);
|
|
58825
|
+
|
|
58826
|
+
-- Metrics (per-turn tracking)
|
|
58827
|
+
CREATE TABLE IF NOT EXISTS metrics (
|
|
58828
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58829
|
+
session_id TEXT NOT NULL,
|
|
58830
|
+
turn_index INTEGER,
|
|
58831
|
+
tokens_in INTEGER DEFAULT 0,
|
|
58832
|
+
tokens_out INTEGER DEFAULT 0,
|
|
58833
|
+
cost_usd REAL DEFAULT 0,
|
|
58834
|
+
api_duration_ms REAL DEFAULT 0,
|
|
58835
|
+
tool_duration_ms REAL DEFAULT 0,
|
|
58836
|
+
hook_duration_ms REAL DEFAULT 0,
|
|
58837
|
+
tool_count INTEGER DEFAULT 0,
|
|
58838
|
+
model TEXT,
|
|
58839
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58840
|
+
);
|
|
58841
|
+
|
|
58842
|
+
-- Audit log (for security \u2014 tracks all tool executions)
|
|
58843
|
+
CREATE TABLE IF NOT EXISTS audit_log (
|
|
58844
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
58845
|
+
session_id TEXT,
|
|
58846
|
+
tool_name TEXT NOT NULL,
|
|
58847
|
+
input_summary TEXT,
|
|
58848
|
+
result_summary TEXT,
|
|
58849
|
+
exit_code INTEGER,
|
|
58850
|
+
duration_ms REAL,
|
|
58851
|
+
was_allowed INTEGER DEFAULT 1,
|
|
58852
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
58853
|
+
);
|
|
58854
|
+
`);
|
|
58855
|
+
}
|
|
58856
|
+
function dbRun(sql, params = []) {
|
|
58857
|
+
const db = getDb();
|
|
58858
|
+
try {
|
|
58859
|
+
const stmt = db.prepare(sql);
|
|
58860
|
+
return stmt.run(...params);
|
|
58861
|
+
} catch (e) {
|
|
58862
|
+
try {
|
|
58863
|
+
return db.run(sql, params);
|
|
58864
|
+
} catch {
|
|
58865
|
+
throw e;
|
|
58866
|
+
}
|
|
58867
|
+
}
|
|
58868
|
+
}
|
|
58869
|
+
function dbGet(sql, params = []) {
|
|
58870
|
+
const db = getDb();
|
|
58871
|
+
try {
|
|
58872
|
+
const stmt = db.prepare(sql);
|
|
58873
|
+
return stmt.get(...params);
|
|
58874
|
+
} catch {
|
|
58875
|
+
try {
|
|
58876
|
+
return db.query(sql).get(...params);
|
|
58877
|
+
} catch {
|
|
58878
|
+
return void 0;
|
|
58879
|
+
}
|
|
58880
|
+
}
|
|
58881
|
+
}
|
|
58882
|
+
function dbAll(sql, params = []) {
|
|
58883
|
+
const db = getDb();
|
|
58884
|
+
try {
|
|
58885
|
+
const stmt = db.prepare(sql);
|
|
58886
|
+
return stmt.all(...params);
|
|
58887
|
+
} catch {
|
|
58888
|
+
try {
|
|
58889
|
+
return db.query(sql).all(...params);
|
|
58890
|
+
} catch {
|
|
58891
|
+
return [];
|
|
58892
|
+
}
|
|
58893
|
+
}
|
|
58894
|
+
}
|
|
58895
|
+
function createJsonFileDb() {
|
|
58896
|
+
const storePath = join2(getConfigDir(), "coders-fallback.json");
|
|
58897
|
+
let store = { tables: {}, autoInc: {} };
|
|
58898
|
+
try {
|
|
58899
|
+
if (existsSync4(storePath)) {
|
|
58900
|
+
store = JSON.parse(readFileSync3(storePath, "utf-8"));
|
|
58901
|
+
if (!store.tables) store.tables = {};
|
|
58902
|
+
if (!store.autoInc) store.autoInc = {};
|
|
58903
|
+
}
|
|
58904
|
+
} catch {
|
|
58905
|
+
}
|
|
58906
|
+
function flush() {
|
|
58907
|
+
try {
|
|
58908
|
+
writeFileSync2(storePath, JSON.stringify(store), "utf-8");
|
|
58909
|
+
} catch {
|
|
58910
|
+
}
|
|
58911
|
+
}
|
|
58912
|
+
function ensureTable(name) {
|
|
58913
|
+
if (!store.tables[name]) {
|
|
58914
|
+
store.tables[name] = [];
|
|
58915
|
+
store.autoInc[name] = 0;
|
|
58916
|
+
}
|
|
58917
|
+
}
|
|
58918
|
+
function now() {
|
|
58919
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").replace(/\.\d+Z$/, "");
|
|
58920
|
+
}
|
|
58921
|
+
function parseInsert(sql, params) {
|
|
58922
|
+
const m = sql.match(/INSERT\s+(?:OR\s+\w+\s+)?INTO\s+(\w+)\s*\(([^)]+)\)\s*VALUES\s*\(([^)]+)\)/i);
|
|
58923
|
+
if (!m) return { changes: 0, lastInsertRowid: 0 };
|
|
58924
|
+
const table = m[1];
|
|
58925
|
+
ensureTable(table);
|
|
58926
|
+
const cols = m[2].split(",").map((c) => c.trim());
|
|
58927
|
+
const valuePlaceholders = m[3].split(",").map((v) => v.trim());
|
|
58928
|
+
const row = {};
|
|
58929
|
+
let paramIdx = 0;
|
|
58930
|
+
for (let i = 0; i < cols.length; i++) {
|
|
58931
|
+
const ph = valuePlaceholders[i];
|
|
58932
|
+
if (ph === "?") {
|
|
58933
|
+
row[cols[i]] = params[paramIdx++];
|
|
58934
|
+
} else if (/^datetime\(/i.test(ph)) {
|
|
58935
|
+
row[cols[i]] = now();
|
|
58936
|
+
} else {
|
|
58937
|
+
row[cols[i]] = ph.replace(/^['"]|['"]$/g, "");
|
|
58938
|
+
}
|
|
58939
|
+
}
|
|
58940
|
+
if (!row["id"] && store.autoInc[table] !== void 0) {
|
|
58941
|
+
store.autoInc[table]++;
|
|
58942
|
+
row["id"] = store.autoInc[table];
|
|
58943
|
+
}
|
|
58944
|
+
store.tables[table].push(row);
|
|
58945
|
+
flush();
|
|
58946
|
+
return { changes: 1, lastInsertRowid: typeof row["id"] === "number" ? row["id"] : 0 };
|
|
58947
|
+
}
|
|
58948
|
+
function parseSelect(sql, params) {
|
|
58949
|
+
const m = sql.match(/SELECT\s+(.+?)\s+FROM\s+(\w+)(?:\s+WHERE\s+(.+?))?(?:\s+ORDER\s+BY\s+(.+?))?(?:\s+LIMIT\s+(\d+))?$/i);
|
|
58950
|
+
if (!m) return [];
|
|
58951
|
+
const table = m[2];
|
|
58952
|
+
if (!store.tables[table]) return [];
|
|
58953
|
+
let rows = [...store.tables[table]];
|
|
58954
|
+
if (m[3]) {
|
|
58955
|
+
const whereParts = m[3].trim();
|
|
58956
|
+
const wm = whereParts.match(/(\w+)\s*=\s*\?/);
|
|
58957
|
+
if (wm && params.length > 0) {
|
|
58958
|
+
const col = wm[1];
|
|
58959
|
+
const val = params[0];
|
|
58960
|
+
rows = rows.filter((r) => r[col] === val);
|
|
58961
|
+
}
|
|
58962
|
+
}
|
|
58963
|
+
if (m[5]) {
|
|
58964
|
+
rows = rows.slice(0, parseInt(m[5], 10));
|
|
58965
|
+
}
|
|
58966
|
+
return rows;
|
|
58967
|
+
}
|
|
58968
|
+
function parseUpdate(sql, params) {
|
|
58969
|
+
const m = sql.match(/UPDATE\s+(\w+)\s+SET\s+(.+?)\s+WHERE\s+(.+)/i);
|
|
58970
|
+
if (!m) return { changes: 0 };
|
|
58971
|
+
const table = m[1];
|
|
58972
|
+
if (!store.tables[table]) return { changes: 0 };
|
|
58973
|
+
const setClauses = m[2].split(",").map((s) => s.trim());
|
|
58974
|
+
const whereClause = m[3].trim();
|
|
58975
|
+
const setParamCount = setClauses.filter((c) => c.includes("?")).length;
|
|
58976
|
+
const wm = whereClause.match(/(\w+)\s*=\s*\?/);
|
|
58977
|
+
const whereCol = wm ? wm[1] : null;
|
|
58978
|
+
const whereVal = wm ? params[setParamCount] : null;
|
|
58979
|
+
let changes = 0;
|
|
58980
|
+
for (const row of store.tables[table]) {
|
|
58981
|
+
if (whereCol && row[whereCol] !== whereVal) continue;
|
|
58982
|
+
let paramIdx = 0;
|
|
58983
|
+
for (const clause of setClauses) {
|
|
58984
|
+
const cm = clause.match(/(\w+)\s*=\s*(.+)/);
|
|
58985
|
+
if (!cm) continue;
|
|
58986
|
+
const col = cm[1];
|
|
58987
|
+
const val = cm[2].trim();
|
|
58988
|
+
if (val === "?") {
|
|
58989
|
+
row[col] = params[paramIdx++];
|
|
58990
|
+
} else if (/^datetime\(/i.test(val)) {
|
|
58991
|
+
row[col] = now();
|
|
58992
|
+
}
|
|
58993
|
+
}
|
|
58994
|
+
changes++;
|
|
58995
|
+
}
|
|
58996
|
+
if (changes > 0) flush();
|
|
58997
|
+
return { changes };
|
|
58998
|
+
}
|
|
58999
|
+
function parseDelete(sql, params) {
|
|
59000
|
+
const m = sql.match(/DELETE\s+FROM\s+(\w+)(?:\s+WHERE\s+(.+))?/i);
|
|
59001
|
+
if (!m) return { changes: 0 };
|
|
59002
|
+
const table = m[1];
|
|
59003
|
+
if (!store.tables[table]) return { changes: 0 };
|
|
59004
|
+
if (!m[2]) {
|
|
59005
|
+
const count = store.tables[table].length;
|
|
59006
|
+
store.tables[table] = [];
|
|
59007
|
+
flush();
|
|
59008
|
+
return { changes: count };
|
|
59009
|
+
}
|
|
59010
|
+
const wm = m[2].match(/(\w+)\s*=\s*\?/);
|
|
59011
|
+
if (!wm) return { changes: 0 };
|
|
59012
|
+
const col = wm[1];
|
|
59013
|
+
const val = params[0];
|
|
59014
|
+
const before = store.tables[table].length;
|
|
59015
|
+
store.tables[table] = store.tables[table].filter((r) => r[col] !== val);
|
|
59016
|
+
const changes = before - store.tables[table].length;
|
|
59017
|
+
if (changes > 0) flush();
|
|
59018
|
+
return { changes };
|
|
59019
|
+
}
|
|
59020
|
+
function execSql(sql, params = []) {
|
|
59021
|
+
const trimmed = sql.trim();
|
|
59022
|
+
if (/^INSERT/i.test(trimmed)) return parseInsert(trimmed, params);
|
|
59023
|
+
if (/^SELECT/i.test(trimmed)) return parseSelect(trimmed, params);
|
|
59024
|
+
if (/^UPDATE/i.test(trimmed)) return parseUpdate(trimmed, params);
|
|
59025
|
+
if (/^DELETE/i.test(trimmed)) return parseDelete(trimmed, params);
|
|
59026
|
+
return { changes: 0 };
|
|
59027
|
+
}
|
|
59028
|
+
return {
|
|
59029
|
+
exec(sql) {
|
|
59030
|
+
const matches = sql.matchAll(/CREATE\s+TABLE\s+IF\s+NOT\s+EXISTS\s+(\w+)/gi);
|
|
59031
|
+
for (const m of matches) {
|
|
59032
|
+
ensureTable(m[1]);
|
|
59033
|
+
}
|
|
59034
|
+
},
|
|
59035
|
+
prepare(sql) {
|
|
59036
|
+
return {
|
|
59037
|
+
run(...params) {
|
|
59038
|
+
return execSql(sql, params);
|
|
59039
|
+
},
|
|
59040
|
+
get(...params) {
|
|
59041
|
+
const result = execSql(sql, params);
|
|
59042
|
+
if (Array.isArray(result)) return result[0];
|
|
59043
|
+
return void 0;
|
|
59044
|
+
},
|
|
59045
|
+
all(...params) {
|
|
59046
|
+
const result = execSql(sql, params);
|
|
59047
|
+
if (Array.isArray(result)) return result;
|
|
59048
|
+
return [];
|
|
59049
|
+
}
|
|
59050
|
+
};
|
|
59051
|
+
},
|
|
59052
|
+
// Bun-style API aliases
|
|
59053
|
+
run(sql, params = []) {
|
|
59054
|
+
return execSql(sql, params);
|
|
59055
|
+
},
|
|
59056
|
+
query(sql) {
|
|
59057
|
+
return {
|
|
59058
|
+
get(...params) {
|
|
59059
|
+
const result = execSql(sql, params);
|
|
59060
|
+
if (Array.isArray(result)) return result[0];
|
|
59061
|
+
return void 0;
|
|
59062
|
+
},
|
|
59063
|
+
all(...params) {
|
|
59064
|
+
const result = execSql(sql, params);
|
|
59065
|
+
if (Array.isArray(result)) return result;
|
|
59066
|
+
return [];
|
|
59067
|
+
}
|
|
59068
|
+
};
|
|
59069
|
+
},
|
|
59070
|
+
close() {
|
|
59071
|
+
flush();
|
|
59072
|
+
}
|
|
59073
|
+
};
|
|
59074
|
+
}
|
|
59075
|
+
var _db;
|
|
59076
|
+
var init_db = __esm({
|
|
59077
|
+
"src/db/index.ts"() {
|
|
59078
|
+
"use strict";
|
|
59079
|
+
init_paths();
|
|
59080
|
+
_db = null;
|
|
59081
|
+
}
|
|
59082
|
+
});
|
|
59083
|
+
|
|
59084
|
+
// src/ui/screen/terminal.ts
|
|
59085
|
+
var terminal_exports = {};
|
|
59086
|
+
__export(terminal_exports, {
|
|
59087
|
+
detectTerminal: () => detectTerminal,
|
|
59088
|
+
getTerminalSize: () => getTerminalSize,
|
|
59089
|
+
onResize: () => onResize
|
|
59090
|
+
});
|
|
59091
|
+
function detectTerminal() {
|
|
59092
|
+
const termProgram = process.env.TERM_PROGRAM ?? "";
|
|
59093
|
+
const term = process.env.TERM ?? "";
|
|
59094
|
+
const colorTerm = process.env.COLORTERM ?? "";
|
|
59095
|
+
const caps = {
|
|
59096
|
+
name: detectTerminalName(termProgram, term),
|
|
59097
|
+
colorDepth: detectColorDepth(termProgram, colorTerm, term),
|
|
59098
|
+
unicode: detectUnicode(),
|
|
59099
|
+
hyperlinks: detectHyperlinks(termProgram),
|
|
59100
|
+
kittyProtocol: detectKittyProtocol(termProgram),
|
|
59101
|
+
mouseSupport: true,
|
|
59102
|
+
// Most modern terminals support SGR mouse
|
|
59103
|
+
sixelGraphics: detectSixel(termProgram),
|
|
59104
|
+
iterm2Images: termProgram === "iTerm.app"
|
|
59105
|
+
};
|
|
59106
|
+
return caps;
|
|
59107
|
+
}
|
|
59108
|
+
function detectTerminalName(termProgram, term) {
|
|
59109
|
+
if (termProgram === "iTerm.app") return "iTerm2";
|
|
59110
|
+
if (termProgram === "WezTerm") return "WezTerm";
|
|
59111
|
+
if (termProgram === "vscode") return "VSCode";
|
|
59112
|
+
if (termProgram === "Alacritty") return "Alacritty";
|
|
59113
|
+
if (termProgram === "ghostty") return "Ghostty";
|
|
59114
|
+
if (termProgram === "contour") return "Contour";
|
|
59115
|
+
if (termProgram === "mintty") return "Mintty";
|
|
59116
|
+
if (process.env.KITTY_WINDOW_ID) return "Kitty";
|
|
59117
|
+
if (termProgram === "kitty") return "Kitty";
|
|
59118
|
+
if (term === "foot" || term === "foot-extra") return "foot";
|
|
59119
|
+
if (process.env.WARP_IS_LOCAL_SHELL_SESSION) return "Warp";
|
|
59120
|
+
if (termProgram === "Warp") return "Warp";
|
|
59121
|
+
if (process.env.WT_SESSION) return "Windows Terminal";
|
|
59122
|
+
if (process.env.ConEmuANSI || process.env.ConEmuPID) return "ConEmu";
|
|
59123
|
+
const vteVersion = process.env.VTE_VERSION;
|
|
59124
|
+
if (vteVersion) {
|
|
59125
|
+
const ver = parseInt(vteVersion, 10);
|
|
59126
|
+
if (ver >= 6800) return "VTE (modern)";
|
|
59127
|
+
return "VTE";
|
|
59128
|
+
}
|
|
59129
|
+
if (term.startsWith("xterm")) return "xterm";
|
|
59130
|
+
if (term.startsWith("screen")) return "screen";
|
|
59131
|
+
if (term.startsWith("tmux")) return "tmux";
|
|
59132
|
+
return "unknown";
|
|
59133
|
+
}
|
|
59134
|
+
function detectColorDepth(termProgram, colorTerm, term) {
|
|
59135
|
+
if (colorTerm === "truecolor" || colorTerm === "24bit") return 24;
|
|
59136
|
+
const truecolorTerminals = [
|
|
59137
|
+
"iTerm.app",
|
|
59138
|
+
"WezTerm",
|
|
59139
|
+
"Alacritty",
|
|
59140
|
+
"kitty",
|
|
59141
|
+
"ghostty",
|
|
59142
|
+
"contour",
|
|
59143
|
+
"foot"
|
|
59144
|
+
];
|
|
59145
|
+
if (truecolorTerminals.includes(termProgram)) return 24;
|
|
59146
|
+
if (process.env.KITTY_WINDOW_ID) return 24;
|
|
59147
|
+
if (process.env.WT_SESSION) return 24;
|
|
59148
|
+
if (termProgram === "vscode") return 24;
|
|
59149
|
+
if (term.includes("256color")) return 8;
|
|
59150
|
+
if (colorTerm) return 8;
|
|
59151
|
+
if (term.includes("color") || term.startsWith("xterm")) return 4;
|
|
59152
|
+
if (term === "dumb" || !process.stdout.isTTY) return 1;
|
|
59153
|
+
return 4;
|
|
59154
|
+
}
|
|
59155
|
+
function detectUnicode() {
|
|
59156
|
+
const lang = process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_CTYPE ?? "";
|
|
59157
|
+
return lang.toLowerCase().includes("utf");
|
|
59158
|
+
}
|
|
59159
|
+
function detectHyperlinks(termProgram) {
|
|
59160
|
+
const supported = [
|
|
59161
|
+
"iTerm.app",
|
|
59162
|
+
"WezTerm",
|
|
59163
|
+
"Alacritty",
|
|
59164
|
+
"kitty",
|
|
59165
|
+
"ghostty",
|
|
59166
|
+
"contour",
|
|
59167
|
+
"foot",
|
|
59168
|
+
"vscode"
|
|
59169
|
+
];
|
|
59170
|
+
if (supported.includes(termProgram)) return true;
|
|
59171
|
+
if (process.env.KITTY_WINDOW_ID) return true;
|
|
59172
|
+
if (process.env.WT_SESSION) return true;
|
|
59173
|
+
return false;
|
|
59174
|
+
}
|
|
59175
|
+
function detectKittyProtocol(termProgram) {
|
|
59176
|
+
if (process.env.KITTY_WINDOW_ID) return true;
|
|
59177
|
+
if (termProgram === "kitty") return true;
|
|
59178
|
+
if (termProgram === "ghostty") return true;
|
|
59179
|
+
if (termProgram === "foot") return true;
|
|
59180
|
+
if (termProgram === "WezTerm") return true;
|
|
59181
|
+
return false;
|
|
59182
|
+
}
|
|
59183
|
+
function detectSixel(termProgram) {
|
|
59184
|
+
if (termProgram === "WezTerm") return true;
|
|
59185
|
+
if (termProgram === "foot") return true;
|
|
59186
|
+
if (termProgram === "contour") return true;
|
|
59187
|
+
return false;
|
|
59188
|
+
}
|
|
59189
|
+
function getTerminalSize() {
|
|
59190
|
+
return {
|
|
59191
|
+
columns: process.stdout.columns ?? 80,
|
|
59192
|
+
rows: process.stdout.rows ?? 24
|
|
59193
|
+
};
|
|
59194
|
+
}
|
|
59195
|
+
function onResize(callback) {
|
|
59196
|
+
const handler = () => {
|
|
59197
|
+
const { columns, rows } = getTerminalSize();
|
|
59198
|
+
callback(columns, rows);
|
|
59199
|
+
};
|
|
59200
|
+
process.stdout.on("resize", handler);
|
|
59201
|
+
return () => process.stdout.removeListener("resize", handler);
|
|
59202
|
+
}
|
|
59203
|
+
var init_terminal = __esm({
|
|
59204
|
+
"src/ui/screen/terminal.ts"() {
|
|
59205
|
+
"use strict";
|
|
59206
|
+
}
|
|
59207
|
+
});
|
|
59208
|
+
|
|
59209
|
+
// src/core/slash-commands.ts
|
|
59210
|
+
import { writeFileSync as writeFileSync3 } from "fs";
|
|
59211
|
+
function registerSlashCommand(cmd) {
|
|
59212
|
+
commands.set(cmd.name, cmd);
|
|
59213
|
+
if (cmd.aliases) {
|
|
59214
|
+
for (const alias of cmd.aliases) commands.set(alias, cmd);
|
|
59215
|
+
}
|
|
59216
|
+
}
|
|
59217
|
+
function getAllSlashCommands() {
|
|
59218
|
+
const seen = /* @__PURE__ */ new Set();
|
|
59219
|
+
const result = [];
|
|
59220
|
+
for (const cmd of commands.values()) {
|
|
59221
|
+
if (!seen.has(cmd.name)) {
|
|
59222
|
+
seen.add(cmd.name);
|
|
59223
|
+
result.push(cmd);
|
|
59224
|
+
}
|
|
59225
|
+
}
|
|
59226
|
+
return result;
|
|
59227
|
+
}
|
|
59228
|
+
function isSlashCommand(input) {
|
|
59229
|
+
return input.startsWith("/") && commands.has(input.slice(1).split(/\s/)[0]);
|
|
59230
|
+
}
|
|
59231
|
+
async function executeSlashCommand(input) {
|
|
59232
|
+
const parts = input.replace(/^\//, "").split(/\s+/);
|
|
59233
|
+
const name = parts[0];
|
|
59234
|
+
const args = parts.slice(1).join(" ");
|
|
59235
|
+
const cmd = commands.get(name);
|
|
59236
|
+
if (!cmd) return { output: `Unknown command: /${name}. Type /help for available commands.` };
|
|
59237
|
+
return cmd.handler(args);
|
|
59238
|
+
}
|
|
59239
|
+
function registerDefaults() {
|
|
59240
|
+
registerSlashCommand({
|
|
59241
|
+
name: "help",
|
|
59242
|
+
aliases: ["h", "?"],
|
|
59243
|
+
category: "core",
|
|
59244
|
+
description: "Show available commands",
|
|
59245
|
+
handler: () => {
|
|
59246
|
+
const cmds = getAllSlashCommands().sort((a, b) => a.name.localeCompare(b.name));
|
|
59247
|
+
const lines = cmds.map((c) => ` /${c.name.padEnd(16)} ${c.description}`);
|
|
59248
|
+
return { output: `Available commands:
|
|
59249
|
+
${lines.join("\n")}` };
|
|
59250
|
+
}
|
|
59251
|
+
});
|
|
59252
|
+
registerSlashCommand({
|
|
59253
|
+
name: "clear",
|
|
59254
|
+
category: "core",
|
|
59255
|
+
description: "Clear conversation history",
|
|
59256
|
+
handler: () => ({ action: "clear", output: "Conversation cleared." })
|
|
59257
|
+
});
|
|
59258
|
+
registerSlashCommand({
|
|
59259
|
+
name: "compact",
|
|
59260
|
+
category: "core",
|
|
59261
|
+
description: "Compact conversation context",
|
|
59262
|
+
handler: () => ({ action: "compact", output: "Context compacted." })
|
|
59263
|
+
});
|
|
59264
|
+
registerSlashCommand({
|
|
59265
|
+
name: "exit",
|
|
59266
|
+
aliases: ["quit", "q"],
|
|
59267
|
+
category: "core",
|
|
59268
|
+
description: "Exit coders",
|
|
59269
|
+
handler: () => ({ action: "exit" })
|
|
59270
|
+
});
|
|
59271
|
+
registerSlashCommand({
|
|
59272
|
+
name: "plan",
|
|
59273
|
+
category: "core",
|
|
59274
|
+
description: "View or edit the current plan",
|
|
59275
|
+
handler: () => ({ output: "Plan mode \u2014 use EnterPlanMode tool to start planning." })
|
|
59276
|
+
});
|
|
59277
|
+
registerSlashCommand({
|
|
59278
|
+
name: "model",
|
|
59279
|
+
category: "mode",
|
|
59280
|
+
description: "View or change the current model",
|
|
59281
|
+
handler: (args) => {
|
|
59282
|
+
if (args) return { action: "setModel", data: args, output: `Model set to: ${args}` };
|
|
59283
|
+
return { output: "Current model \u2014 use /model <name> to change." };
|
|
59284
|
+
}
|
|
59285
|
+
});
|
|
59286
|
+
registerSlashCommand({
|
|
59287
|
+
name: "fast",
|
|
59288
|
+
category: "mode",
|
|
59289
|
+
description: "Toggle fast mode",
|
|
59290
|
+
handler: () => ({ output: "Fast mode toggled." })
|
|
59291
|
+
});
|
|
59292
|
+
registerSlashCommand({
|
|
59293
|
+
name: "verbose",
|
|
59294
|
+
category: "mode",
|
|
59295
|
+
description: "Toggle verbose output",
|
|
59296
|
+
handler: () => ({ output: "Verbose mode toggled." })
|
|
59297
|
+
});
|
|
59298
|
+
registerSlashCommand({
|
|
59299
|
+
name: "status",
|
|
59300
|
+
category: "system",
|
|
59301
|
+
description: "Show session status",
|
|
59302
|
+
handler: () => ({ output: "Session status \u2014 not yet wired." })
|
|
59303
|
+
});
|
|
59304
|
+
registerSlashCommand({
|
|
59305
|
+
name: "config",
|
|
59306
|
+
category: "system",
|
|
59307
|
+
description: "View or modify settings",
|
|
59308
|
+
handler: (args) => ({ output: args ? `Config: ${args}` : "Use /config <key> [value]" })
|
|
59309
|
+
});
|
|
59310
|
+
registerSlashCommand({
|
|
59311
|
+
name: "mcp",
|
|
59312
|
+
category: "system",
|
|
59313
|
+
description: "Show MCP server status",
|
|
59314
|
+
handler: () => ({ output: "MCP servers \u2014 use 'coders mcp list' for details." })
|
|
59315
|
+
});
|
|
58873
59316
|
registerSlashCommand({
|
|
58874
59317
|
name: "memory",
|
|
58875
59318
|
category: "core",
|
|
@@ -58937,11 +59380,78 @@ ${lines.join("\n")}` };
|
|
|
58937
59380
|
return { output: `Terminal: ${caps.name}, Color: ${caps.colorDepth}bit, Unicode: ${caps.unicode}` };
|
|
58938
59381
|
}
|
|
58939
59382
|
});
|
|
59383
|
+
registerSlashCommand({
|
|
59384
|
+
name: "rewind",
|
|
59385
|
+
category: "core",
|
|
59386
|
+
description: "List recent file checkpoints and restore one",
|
|
59387
|
+
handler: (args) => {
|
|
59388
|
+
const checkpoints = dbAll(
|
|
59389
|
+
"SELECT * FROM checkpoints ORDER BY created_at DESC LIMIT 10"
|
|
59390
|
+
);
|
|
59391
|
+
if (checkpoints.length === 0) {
|
|
59392
|
+
return { output: "No checkpoints found. Checkpoints are created when files are edited or overwritten." };
|
|
59393
|
+
}
|
|
59394
|
+
const choice = parseInt(args, 10);
|
|
59395
|
+
if (!isNaN(choice) && choice >= 1 && choice <= checkpoints.length) {
|
|
59396
|
+
const cp = checkpoints[choice - 1];
|
|
59397
|
+
try {
|
|
59398
|
+
writeFileSync3(cp.file_path, cp.original_content, "utf-8");
|
|
59399
|
+
const op = cp.edit_operation ? JSON.parse(cp.edit_operation) : null;
|
|
59400
|
+
const summary = op?.old_string ? `Reverted edit: "${truncate(op.old_string, 40)}" -> "${truncate(op.new_string, 40)}"` : "Restored original content";
|
|
59401
|
+
return { output: `Restored checkpoint #${choice}: ${cp.file_path}
|
|
59402
|
+
${summary}` };
|
|
59403
|
+
} catch (e) {
|
|
59404
|
+
return { output: `Failed to restore checkpoint: ${e instanceof Error ? e.message : String(e)}` };
|
|
59405
|
+
}
|
|
59406
|
+
}
|
|
59407
|
+
const lines = checkpoints.map((cp, i) => {
|
|
59408
|
+
const op = cp.edit_operation ? JSON.parse(cp.edit_operation) : null;
|
|
59409
|
+
const summary = op?.old_string ? `"${truncate(op.old_string, 30)}" -> "${truncate(op.new_string, 30)}"` : op?.type === "write_overwrite" ? "file overwrite" : "unknown operation";
|
|
59410
|
+
return ` ${i + 1}. [${cp.created_at}] ${cp.file_path}
|
|
59411
|
+
${summary}`;
|
|
59412
|
+
});
|
|
59413
|
+
return {
|
|
59414
|
+
output: `Recent checkpoints:
|
|
59415
|
+
${lines.join("\n")}
|
|
59416
|
+
|
|
59417
|
+
Use /rewind <number> to restore a checkpoint.`
|
|
59418
|
+
};
|
|
59419
|
+
}
|
|
59420
|
+
});
|
|
59421
|
+
registerSlashCommand({
|
|
59422
|
+
name: "undo",
|
|
59423
|
+
category: "core",
|
|
59424
|
+
description: "Revert the last file edit from the most recent checkpoint",
|
|
59425
|
+
handler: () => {
|
|
59426
|
+
const cp = dbGet(
|
|
59427
|
+
"SELECT * FROM checkpoints ORDER BY created_at DESC LIMIT 1"
|
|
59428
|
+
);
|
|
59429
|
+
if (!cp) {
|
|
59430
|
+
return { output: "No checkpoints found. Nothing to undo." };
|
|
59431
|
+
}
|
|
59432
|
+
try {
|
|
59433
|
+
writeFileSync3(cp.file_path, cp.original_content, "utf-8");
|
|
59434
|
+
const op = cp.edit_operation ? JSON.parse(cp.edit_operation) : null;
|
|
59435
|
+
const summary = op?.old_string ? `Reverted: "${truncate(op.old_string, 50)}" -> "${truncate(op.new_string, 50)}"` : op?.type === "write_overwrite" ? "Restored file before overwrite" : "Restored original content";
|
|
59436
|
+
return { output: `Undo successful: ${cp.file_path}
|
|
59437
|
+
${summary}
|
|
59438
|
+
[checkpoint: ${cp.id} at ${cp.created_at}]` };
|
|
59439
|
+
} catch (e) {
|
|
59440
|
+
return { output: `Failed to undo: ${e instanceof Error ? e.message : String(e)}` };
|
|
59441
|
+
}
|
|
59442
|
+
}
|
|
59443
|
+
});
|
|
59444
|
+
}
|
|
59445
|
+
function truncate(s, max) {
|
|
59446
|
+
if (!s) return "";
|
|
59447
|
+
const oneLine = s.replace(/\n/g, "\\n");
|
|
59448
|
+
return oneLine.length > max ? oneLine.slice(0, max) + "..." : oneLine;
|
|
58940
59449
|
}
|
|
58941
59450
|
var commands;
|
|
58942
59451
|
var init_slash_commands = __esm({
|
|
58943
59452
|
"src/core/slash-commands.ts"() {
|
|
58944
59453
|
"use strict";
|
|
59454
|
+
init_db();
|
|
58945
59455
|
commands = /* @__PURE__ */ new Map();
|
|
58946
59456
|
registerDefaults();
|
|
58947
59457
|
}
|
|
@@ -60378,1548 +60888,1144 @@ ${currentText}` : currentText;
|
|
|
60378
60888
|
}
|
|
60379
60889
|
blockquote({ tokens }) {
|
|
60380
60890
|
const body = this.parser.parse(tokens);
|
|
60381
|
-
return `<blockquote>
|
|
60382
|
-
${body}</blockquote>
|
|
60383
|
-
`;
|
|
60384
|
-
}
|
|
60385
|
-
html({ text }) {
|
|
60386
|
-
return text;
|
|
60387
|
-
}
|
|
60388
|
-
heading({ tokens, depth }) {
|
|
60389
|
-
return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>
|
|
60390
|
-
`;
|
|
60391
|
-
}
|
|
60392
|
-
hr(token) {
|
|
60393
|
-
return "<hr>\n";
|
|
60394
|
-
}
|
|
60395
|
-
list(token) {
|
|
60396
|
-
const ordered = token.ordered;
|
|
60397
|
-
const start = token.start;
|
|
60398
|
-
let body = "";
|
|
60399
|
-
for (let j = 0; j < token.items.length; j++) {
|
|
60400
|
-
const item = token.items[j];
|
|
60401
|
-
body += this.listitem(item);
|
|
60402
|
-
}
|
|
60403
|
-
const type = ordered ? "ol" : "ul";
|
|
60404
|
-
const startAttr = ordered && start !== 1 ? ' start="' + start + '"' : "";
|
|
60405
|
-
return "<" + type + startAttr + ">\n" + body + "</" + type + ">\n";
|
|
60406
|
-
}
|
|
60407
|
-
listitem(item) {
|
|
60408
|
-
let itemBody = "";
|
|
60409
|
-
if (item.task) {
|
|
60410
|
-
const checkbox = this.checkbox({ checked: !!item.checked });
|
|
60411
|
-
if (item.loose) {
|
|
60412
|
-
if (item.tokens[0]?.type === "paragraph") {
|
|
60413
|
-
item.tokens[0].text = checkbox + " " + item.tokens[0].text;
|
|
60414
|
-
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
|
|
60415
|
-
item.tokens[0].tokens[0].text = checkbox + " " + escape22(item.tokens[0].tokens[0].text);
|
|
60416
|
-
item.tokens[0].tokens[0].escaped = true;
|
|
60417
|
-
}
|
|
60418
|
-
} else {
|
|
60419
|
-
item.tokens.unshift({
|
|
60420
|
-
type: "text",
|
|
60421
|
-
raw: checkbox + " ",
|
|
60422
|
-
text: checkbox + " ",
|
|
60423
|
-
escaped: true
|
|
60424
|
-
});
|
|
60425
|
-
}
|
|
60426
|
-
} else {
|
|
60427
|
-
itemBody += checkbox + " ";
|
|
60428
|
-
}
|
|
60429
|
-
}
|
|
60430
|
-
itemBody += this.parser.parse(item.tokens, !!item.loose);
|
|
60431
|
-
return `<li>${itemBody}</li>
|
|
60432
|
-
`;
|
|
60433
|
-
}
|
|
60434
|
-
checkbox({ checked }) {
|
|
60435
|
-
return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
|
|
60436
|
-
}
|
|
60437
|
-
paragraph({ tokens }) {
|
|
60438
|
-
return `<p>${this.parser.parseInline(tokens)}</p>
|
|
60439
|
-
`;
|
|
60440
|
-
}
|
|
60441
|
-
table(token) {
|
|
60442
|
-
let header = "";
|
|
60443
|
-
let cell = "";
|
|
60444
|
-
for (let j = 0; j < token.header.length; j++) {
|
|
60445
|
-
cell += this.tablecell(token.header[j]);
|
|
60446
|
-
}
|
|
60447
|
-
header += this.tablerow({ text: cell });
|
|
60448
|
-
let body = "";
|
|
60449
|
-
for (let j = 0; j < token.rows.length; j++) {
|
|
60450
|
-
const row = token.rows[j];
|
|
60451
|
-
cell = "";
|
|
60452
|
-
for (let k = 0; k < row.length; k++) {
|
|
60453
|
-
cell += this.tablecell(row[k]);
|
|
60454
|
-
}
|
|
60455
|
-
body += this.tablerow({ text: cell });
|
|
60456
|
-
}
|
|
60457
|
-
if (body) body = `<tbody>${body}</tbody>`;
|
|
60458
|
-
return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
|
|
60459
|
-
}
|
|
60460
|
-
tablerow({ text }) {
|
|
60461
|
-
return `<tr>
|
|
60462
|
-
${text}</tr>
|
|
60463
|
-
`;
|
|
60464
|
-
}
|
|
60465
|
-
tablecell(token) {
|
|
60466
|
-
const content = this.parser.parseInline(token.tokens);
|
|
60467
|
-
const type = token.header ? "th" : "td";
|
|
60468
|
-
const tag2 = token.align ? `<${type} align="${token.align}">` : `<${type}>`;
|
|
60469
|
-
return tag2 + content + `</${type}>
|
|
60470
|
-
`;
|
|
60471
|
-
}
|
|
60472
|
-
/**
|
|
60473
|
-
* span level renderer
|
|
60474
|
-
*/
|
|
60475
|
-
strong({ tokens }) {
|
|
60476
|
-
return `<strong>${this.parser.parseInline(tokens)}</strong>`;
|
|
60477
|
-
}
|
|
60478
|
-
em({ tokens }) {
|
|
60479
|
-
return `<em>${this.parser.parseInline(tokens)}</em>`;
|
|
60480
|
-
}
|
|
60481
|
-
codespan({ text }) {
|
|
60482
|
-
return `<code>${escape22(text, true)}</code>`;
|
|
60483
|
-
}
|
|
60484
|
-
br(token) {
|
|
60485
|
-
return "<br>";
|
|
60486
|
-
}
|
|
60487
|
-
del({ tokens }) {
|
|
60488
|
-
return `<del>${this.parser.parseInline(tokens)}</del>`;
|
|
60489
|
-
}
|
|
60490
|
-
link({ href, title, tokens }) {
|
|
60491
|
-
const text = this.parser.parseInline(tokens);
|
|
60492
|
-
const cleanHref = cleanUrl(href);
|
|
60493
|
-
if (cleanHref === null) {
|
|
60494
|
-
return text;
|
|
60495
|
-
}
|
|
60496
|
-
href = cleanHref;
|
|
60497
|
-
let out = '<a href="' + href + '"';
|
|
60498
|
-
if (title) {
|
|
60499
|
-
out += ' title="' + escape22(title) + '"';
|
|
60500
|
-
}
|
|
60501
|
-
out += ">" + text + "</a>";
|
|
60502
|
-
return out;
|
|
60503
|
-
}
|
|
60504
|
-
image({ href, title, text, tokens }) {
|
|
60505
|
-
if (tokens) {
|
|
60506
|
-
text = this.parser.parseInline(tokens, this.parser.textRenderer);
|
|
60507
|
-
}
|
|
60508
|
-
const cleanHref = cleanUrl(href);
|
|
60509
|
-
if (cleanHref === null) {
|
|
60510
|
-
return escape22(text);
|
|
60511
|
-
}
|
|
60512
|
-
href = cleanHref;
|
|
60513
|
-
let out = `<img src="${href}" alt="${text}"`;
|
|
60514
|
-
if (title) {
|
|
60515
|
-
out += ` title="${escape22(title)}"`;
|
|
60516
|
-
}
|
|
60517
|
-
out += ">";
|
|
60518
|
-
return out;
|
|
60519
|
-
}
|
|
60520
|
-
text(token) {
|
|
60521
|
-
return "tokens" in token && token.tokens ? this.parser.parseInline(token.tokens) : "escaped" in token && token.escaped ? token.text : escape22(token.text);
|
|
60522
|
-
}
|
|
60523
|
-
};
|
|
60524
|
-
_TextRenderer = class {
|
|
60525
|
-
// no need for block level renderers
|
|
60526
|
-
strong({ text }) {
|
|
60527
|
-
return text;
|
|
60528
|
-
}
|
|
60529
|
-
em({ text }) {
|
|
60530
|
-
return text;
|
|
60531
|
-
}
|
|
60532
|
-
codespan({ text }) {
|
|
60533
|
-
return text;
|
|
60534
|
-
}
|
|
60535
|
-
del({ text }) {
|
|
60536
|
-
return text;
|
|
60891
|
+
return `<blockquote>
|
|
60892
|
+
${body}</blockquote>
|
|
60893
|
+
`;
|
|
60537
60894
|
}
|
|
60538
60895
|
html({ text }) {
|
|
60539
60896
|
return text;
|
|
60540
60897
|
}
|
|
60541
|
-
|
|
60542
|
-
return
|
|
60543
|
-
|
|
60544
|
-
link({ text }) {
|
|
60545
|
-
return "" + text;
|
|
60546
|
-
}
|
|
60547
|
-
image({ text }) {
|
|
60548
|
-
return "" + text;
|
|
60549
|
-
}
|
|
60550
|
-
br() {
|
|
60551
|
-
return "";
|
|
60552
|
-
}
|
|
60553
|
-
};
|
|
60554
|
-
_Parser = class __Parser {
|
|
60555
|
-
options;
|
|
60556
|
-
renderer;
|
|
60557
|
-
textRenderer;
|
|
60558
|
-
constructor(options2) {
|
|
60559
|
-
this.options = options2 || _defaults;
|
|
60560
|
-
this.options.renderer = this.options.renderer || new _Renderer();
|
|
60561
|
-
this.renderer = this.options.renderer;
|
|
60562
|
-
this.renderer.options = this.options;
|
|
60563
|
-
this.renderer.parser = this;
|
|
60564
|
-
this.textRenderer = new _TextRenderer();
|
|
60898
|
+
heading({ tokens, depth }) {
|
|
60899
|
+
return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>
|
|
60900
|
+
`;
|
|
60565
60901
|
}
|
|
60566
|
-
|
|
60567
|
-
|
|
60568
|
-
*/
|
|
60569
|
-
static parse(tokens, options2) {
|
|
60570
|
-
const parser2 = new __Parser(options2);
|
|
60571
|
-
return parser2.parse(tokens);
|
|
60902
|
+
hr(token) {
|
|
60903
|
+
return "<hr>\n";
|
|
60572
60904
|
}
|
|
60573
|
-
|
|
60574
|
-
|
|
60575
|
-
|
|
60576
|
-
|
|
60577
|
-
|
|
60578
|
-
|
|
60905
|
+
list(token) {
|
|
60906
|
+
const ordered = token.ordered;
|
|
60907
|
+
const start = token.start;
|
|
60908
|
+
let body = "";
|
|
60909
|
+
for (let j = 0; j < token.items.length; j++) {
|
|
60910
|
+
const item = token.items[j];
|
|
60911
|
+
body += this.listitem(item);
|
|
60912
|
+
}
|
|
60913
|
+
const type = ordered ? "ol" : "ul";
|
|
60914
|
+
const startAttr = ordered && start !== 1 ? ' start="' + start + '"' : "";
|
|
60915
|
+
return "<" + type + startAttr + ">\n" + body + "</" + type + ">\n";
|
|
60579
60916
|
}
|
|
60580
|
-
|
|
60581
|
-
|
|
60582
|
-
|
|
60583
|
-
|
|
60584
|
-
|
|
60585
|
-
|
|
60586
|
-
|
|
60587
|
-
|
|
60588
|
-
|
|
60589
|
-
|
|
60590
|
-
if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(genericToken.type)) {
|
|
60591
|
-
out += ret || "";
|
|
60592
|
-
continue;
|
|
60593
|
-
}
|
|
60594
|
-
}
|
|
60595
|
-
const token = anyToken;
|
|
60596
|
-
switch (token.type) {
|
|
60597
|
-
case "space": {
|
|
60598
|
-
out += this.renderer.space(token);
|
|
60599
|
-
continue;
|
|
60600
|
-
}
|
|
60601
|
-
case "hr": {
|
|
60602
|
-
out += this.renderer.hr(token);
|
|
60603
|
-
continue;
|
|
60604
|
-
}
|
|
60605
|
-
case "heading": {
|
|
60606
|
-
out += this.renderer.heading(token);
|
|
60607
|
-
continue;
|
|
60608
|
-
}
|
|
60609
|
-
case "code": {
|
|
60610
|
-
out += this.renderer.code(token);
|
|
60611
|
-
continue;
|
|
60612
|
-
}
|
|
60613
|
-
case "table": {
|
|
60614
|
-
out += this.renderer.table(token);
|
|
60615
|
-
continue;
|
|
60616
|
-
}
|
|
60617
|
-
case "blockquote": {
|
|
60618
|
-
out += this.renderer.blockquote(token);
|
|
60619
|
-
continue;
|
|
60620
|
-
}
|
|
60621
|
-
case "list": {
|
|
60622
|
-
out += this.renderer.list(token);
|
|
60623
|
-
continue;
|
|
60624
|
-
}
|
|
60625
|
-
case "html": {
|
|
60626
|
-
out += this.renderer.html(token);
|
|
60627
|
-
continue;
|
|
60628
|
-
}
|
|
60629
|
-
case "paragraph": {
|
|
60630
|
-
out += this.renderer.paragraph(token);
|
|
60631
|
-
continue;
|
|
60632
|
-
}
|
|
60633
|
-
case "text": {
|
|
60634
|
-
let textToken = token;
|
|
60635
|
-
let body = this.renderer.text(textToken);
|
|
60636
|
-
while (i + 1 < tokens.length && tokens[i + 1].type === "text") {
|
|
60637
|
-
textToken = tokens[++i];
|
|
60638
|
-
body += "\n" + this.renderer.text(textToken);
|
|
60639
|
-
}
|
|
60640
|
-
if (top) {
|
|
60641
|
-
out += this.renderer.paragraph({
|
|
60642
|
-
type: "paragraph",
|
|
60643
|
-
raw: body,
|
|
60644
|
-
text: body,
|
|
60645
|
-
tokens: [{ type: "text", raw: body, text: body, escaped: true }]
|
|
60646
|
-
});
|
|
60647
|
-
} else {
|
|
60648
|
-
out += body;
|
|
60649
|
-
}
|
|
60650
|
-
continue;
|
|
60651
|
-
}
|
|
60652
|
-
default: {
|
|
60653
|
-
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
60654
|
-
if (this.options.silent) {
|
|
60655
|
-
console.error(errMsg);
|
|
60656
|
-
return "";
|
|
60657
|
-
} else {
|
|
60658
|
-
throw new Error(errMsg);
|
|
60917
|
+
listitem(item) {
|
|
60918
|
+
let itemBody = "";
|
|
60919
|
+
if (item.task) {
|
|
60920
|
+
const checkbox = this.checkbox({ checked: !!item.checked });
|
|
60921
|
+
if (item.loose) {
|
|
60922
|
+
if (item.tokens[0]?.type === "paragraph") {
|
|
60923
|
+
item.tokens[0].text = checkbox + " " + item.tokens[0].text;
|
|
60924
|
+
if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === "text") {
|
|
60925
|
+
item.tokens[0].tokens[0].text = checkbox + " " + escape22(item.tokens[0].tokens[0].text);
|
|
60926
|
+
item.tokens[0].tokens[0].escaped = true;
|
|
60659
60927
|
}
|
|
60928
|
+
} else {
|
|
60929
|
+
item.tokens.unshift({
|
|
60930
|
+
type: "text",
|
|
60931
|
+
raw: checkbox + " ",
|
|
60932
|
+
text: checkbox + " ",
|
|
60933
|
+
escaped: true
|
|
60934
|
+
});
|
|
60660
60935
|
}
|
|
60936
|
+
} else {
|
|
60937
|
+
itemBody += checkbox + " ";
|
|
60661
60938
|
}
|
|
60662
60939
|
}
|
|
60663
|
-
|
|
60940
|
+
itemBody += this.parser.parse(item.tokens, !!item.loose);
|
|
60941
|
+
return `<li>${itemBody}</li>
|
|
60942
|
+
`;
|
|
60664
60943
|
}
|
|
60665
|
-
|
|
60666
|
-
|
|
60667
|
-
|
|
60668
|
-
|
|
60669
|
-
|
|
60670
|
-
|
|
60671
|
-
|
|
60672
|
-
|
|
60673
|
-
|
|
60674
|
-
|
|
60675
|
-
|
|
60676
|
-
|
|
60677
|
-
|
|
60678
|
-
|
|
60679
|
-
|
|
60680
|
-
|
|
60681
|
-
|
|
60682
|
-
|
|
60683
|
-
|
|
60684
|
-
|
|
60685
|
-
case "html": {
|
|
60686
|
-
out += renderer2.html(token);
|
|
60687
|
-
break;
|
|
60688
|
-
}
|
|
60689
|
-
case "link": {
|
|
60690
|
-
out += renderer2.link(token);
|
|
60691
|
-
break;
|
|
60692
|
-
}
|
|
60693
|
-
case "image": {
|
|
60694
|
-
out += renderer2.image(token);
|
|
60695
|
-
break;
|
|
60696
|
-
}
|
|
60697
|
-
case "strong": {
|
|
60698
|
-
out += renderer2.strong(token);
|
|
60699
|
-
break;
|
|
60700
|
-
}
|
|
60701
|
-
case "em": {
|
|
60702
|
-
out += renderer2.em(token);
|
|
60703
|
-
break;
|
|
60704
|
-
}
|
|
60705
|
-
case "codespan": {
|
|
60706
|
-
out += renderer2.codespan(token);
|
|
60707
|
-
break;
|
|
60708
|
-
}
|
|
60709
|
-
case "br": {
|
|
60710
|
-
out += renderer2.br(token);
|
|
60711
|
-
break;
|
|
60712
|
-
}
|
|
60713
|
-
case "del": {
|
|
60714
|
-
out += renderer2.del(token);
|
|
60715
|
-
break;
|
|
60716
|
-
}
|
|
60717
|
-
case "text": {
|
|
60718
|
-
out += renderer2.text(token);
|
|
60719
|
-
break;
|
|
60720
|
-
}
|
|
60721
|
-
default: {
|
|
60722
|
-
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
60723
|
-
if (this.options.silent) {
|
|
60724
|
-
console.error(errMsg);
|
|
60725
|
-
return "";
|
|
60726
|
-
} else {
|
|
60727
|
-
throw new Error(errMsg);
|
|
60728
|
-
}
|
|
60729
|
-
}
|
|
60944
|
+
checkbox({ checked }) {
|
|
60945
|
+
return "<input " + (checked ? 'checked="" ' : "") + 'disabled="" type="checkbox">';
|
|
60946
|
+
}
|
|
60947
|
+
paragraph({ tokens }) {
|
|
60948
|
+
return `<p>${this.parser.parseInline(tokens)}</p>
|
|
60949
|
+
`;
|
|
60950
|
+
}
|
|
60951
|
+
table(token) {
|
|
60952
|
+
let header = "";
|
|
60953
|
+
let cell = "";
|
|
60954
|
+
for (let j = 0; j < token.header.length; j++) {
|
|
60955
|
+
cell += this.tablecell(token.header[j]);
|
|
60956
|
+
}
|
|
60957
|
+
header += this.tablerow({ text: cell });
|
|
60958
|
+
let body = "";
|
|
60959
|
+
for (let j = 0; j < token.rows.length; j++) {
|
|
60960
|
+
const row = token.rows[j];
|
|
60961
|
+
cell = "";
|
|
60962
|
+
for (let k = 0; k < row.length; k++) {
|
|
60963
|
+
cell += this.tablecell(row[k]);
|
|
60730
60964
|
}
|
|
60965
|
+
body += this.tablerow({ text: cell });
|
|
60966
|
+
}
|
|
60967
|
+
if (body) body = `<tbody>${body}</tbody>`;
|
|
60968
|
+
return "<table>\n<thead>\n" + header + "</thead>\n" + body + "</table>\n";
|
|
60969
|
+
}
|
|
60970
|
+
tablerow({ text }) {
|
|
60971
|
+
return `<tr>
|
|
60972
|
+
${text}</tr>
|
|
60973
|
+
`;
|
|
60974
|
+
}
|
|
60975
|
+
tablecell(token) {
|
|
60976
|
+
const content = this.parser.parseInline(token.tokens);
|
|
60977
|
+
const type = token.header ? "th" : "td";
|
|
60978
|
+
const tag2 = token.align ? `<${type} align="${token.align}">` : `<${type}>`;
|
|
60979
|
+
return tag2 + content + `</${type}>
|
|
60980
|
+
`;
|
|
60981
|
+
}
|
|
60982
|
+
/**
|
|
60983
|
+
* span level renderer
|
|
60984
|
+
*/
|
|
60985
|
+
strong({ tokens }) {
|
|
60986
|
+
return `<strong>${this.parser.parseInline(tokens)}</strong>`;
|
|
60987
|
+
}
|
|
60988
|
+
em({ tokens }) {
|
|
60989
|
+
return `<em>${this.parser.parseInline(tokens)}</em>`;
|
|
60990
|
+
}
|
|
60991
|
+
codespan({ text }) {
|
|
60992
|
+
return `<code>${escape22(text, true)}</code>`;
|
|
60993
|
+
}
|
|
60994
|
+
br(token) {
|
|
60995
|
+
return "<br>";
|
|
60996
|
+
}
|
|
60997
|
+
del({ tokens }) {
|
|
60998
|
+
return `<del>${this.parser.parseInline(tokens)}</del>`;
|
|
60999
|
+
}
|
|
61000
|
+
link({ href, title, tokens }) {
|
|
61001
|
+
const text = this.parser.parseInline(tokens);
|
|
61002
|
+
const cleanHref = cleanUrl(href);
|
|
61003
|
+
if (cleanHref === null) {
|
|
61004
|
+
return text;
|
|
61005
|
+
}
|
|
61006
|
+
href = cleanHref;
|
|
61007
|
+
let out = '<a href="' + href + '"';
|
|
61008
|
+
if (title) {
|
|
61009
|
+
out += ' title="' + escape22(title) + '"';
|
|
61010
|
+
}
|
|
61011
|
+
out += ">" + text + "</a>";
|
|
61012
|
+
return out;
|
|
61013
|
+
}
|
|
61014
|
+
image({ href, title, text, tokens }) {
|
|
61015
|
+
if (tokens) {
|
|
61016
|
+
text = this.parser.parseInline(tokens, this.parser.textRenderer);
|
|
61017
|
+
}
|
|
61018
|
+
const cleanHref = cleanUrl(href);
|
|
61019
|
+
if (cleanHref === null) {
|
|
61020
|
+
return escape22(text);
|
|
61021
|
+
}
|
|
61022
|
+
href = cleanHref;
|
|
61023
|
+
let out = `<img src="${href}" alt="${text}"`;
|
|
61024
|
+
if (title) {
|
|
61025
|
+
out += ` title="${escape22(title)}"`;
|
|
60731
61026
|
}
|
|
61027
|
+
out += ">";
|
|
60732
61028
|
return out;
|
|
60733
61029
|
}
|
|
61030
|
+
text(token) {
|
|
61031
|
+
return "tokens" in token && token.tokens ? this.parser.parseInline(token.tokens) : "escaped" in token && token.escaped ? token.text : escape22(token.text);
|
|
61032
|
+
}
|
|
60734
61033
|
};
|
|
60735
|
-
|
|
60736
|
-
|
|
60737
|
-
|
|
60738
|
-
|
|
60739
|
-
this.options = options2 || _defaults;
|
|
61034
|
+
_TextRenderer = class {
|
|
61035
|
+
// no need for block level renderers
|
|
61036
|
+
strong({ text }) {
|
|
61037
|
+
return text;
|
|
60740
61038
|
}
|
|
60741
|
-
|
|
60742
|
-
|
|
60743
|
-
"postprocess",
|
|
60744
|
-
"processAllTokens"
|
|
60745
|
-
]);
|
|
60746
|
-
/**
|
|
60747
|
-
* Process markdown before marked
|
|
60748
|
-
*/
|
|
60749
|
-
preprocess(markdown) {
|
|
60750
|
-
return markdown;
|
|
61039
|
+
em({ text }) {
|
|
61040
|
+
return text;
|
|
60751
61041
|
}
|
|
60752
|
-
|
|
60753
|
-
|
|
60754
|
-
*/
|
|
60755
|
-
postprocess(html2) {
|
|
60756
|
-
return html2;
|
|
61042
|
+
codespan({ text }) {
|
|
61043
|
+
return text;
|
|
60757
61044
|
}
|
|
60758
|
-
|
|
60759
|
-
|
|
60760
|
-
*/
|
|
60761
|
-
processAllTokens(tokens) {
|
|
60762
|
-
return tokens;
|
|
61045
|
+
del({ text }) {
|
|
61046
|
+
return text;
|
|
60763
61047
|
}
|
|
60764
|
-
|
|
60765
|
-
|
|
60766
|
-
*/
|
|
60767
|
-
provideLexer() {
|
|
60768
|
-
return this.block ? _Lexer.lex : _Lexer.lexInline;
|
|
61048
|
+
html({ text }) {
|
|
61049
|
+
return text;
|
|
60769
61050
|
}
|
|
60770
|
-
|
|
60771
|
-
|
|
60772
|
-
|
|
60773
|
-
|
|
60774
|
-
return
|
|
61051
|
+
text({ text }) {
|
|
61052
|
+
return text;
|
|
61053
|
+
}
|
|
61054
|
+
link({ text }) {
|
|
61055
|
+
return "" + text;
|
|
61056
|
+
}
|
|
61057
|
+
image({ text }) {
|
|
61058
|
+
return "" + text;
|
|
61059
|
+
}
|
|
61060
|
+
br() {
|
|
61061
|
+
return "";
|
|
60775
61062
|
}
|
|
60776
61063
|
};
|
|
60777
|
-
|
|
60778
|
-
|
|
60779
|
-
|
|
60780
|
-
|
|
60781
|
-
|
|
60782
|
-
|
|
60783
|
-
|
|
60784
|
-
|
|
60785
|
-
|
|
60786
|
-
|
|
60787
|
-
|
|
60788
|
-
constructor(...args) {
|
|
60789
|
-
this.use(...args);
|
|
61064
|
+
_Parser = class __Parser {
|
|
61065
|
+
options;
|
|
61066
|
+
renderer;
|
|
61067
|
+
textRenderer;
|
|
61068
|
+
constructor(options2) {
|
|
61069
|
+
this.options = options2 || _defaults;
|
|
61070
|
+
this.options.renderer = this.options.renderer || new _Renderer();
|
|
61071
|
+
this.renderer = this.options.renderer;
|
|
61072
|
+
this.renderer.options = this.options;
|
|
61073
|
+
this.renderer.parser = this;
|
|
61074
|
+
this.textRenderer = new _TextRenderer();
|
|
60790
61075
|
}
|
|
60791
61076
|
/**
|
|
60792
|
-
*
|
|
61077
|
+
* Static Parse Method
|
|
60793
61078
|
*/
|
|
60794
|
-
|
|
60795
|
-
|
|
60796
|
-
|
|
60797
|
-
values = values.concat(callback.call(this, token));
|
|
60798
|
-
switch (token.type) {
|
|
60799
|
-
case "table": {
|
|
60800
|
-
const tableToken = token;
|
|
60801
|
-
for (const cell of tableToken.header) {
|
|
60802
|
-
values = values.concat(this.walkTokens(cell.tokens, callback));
|
|
60803
|
-
}
|
|
60804
|
-
for (const row of tableToken.rows) {
|
|
60805
|
-
for (const cell of row) {
|
|
60806
|
-
values = values.concat(this.walkTokens(cell.tokens, callback));
|
|
60807
|
-
}
|
|
60808
|
-
}
|
|
60809
|
-
break;
|
|
60810
|
-
}
|
|
60811
|
-
case "list": {
|
|
60812
|
-
const listToken = token;
|
|
60813
|
-
values = values.concat(this.walkTokens(listToken.items, callback));
|
|
60814
|
-
break;
|
|
60815
|
-
}
|
|
60816
|
-
default: {
|
|
60817
|
-
const genericToken = token;
|
|
60818
|
-
if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
|
|
60819
|
-
this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
|
|
60820
|
-
const tokens2 = genericToken[childTokens].flat(Infinity);
|
|
60821
|
-
values = values.concat(this.walkTokens(tokens2, callback));
|
|
60822
|
-
});
|
|
60823
|
-
} else if (genericToken.tokens) {
|
|
60824
|
-
values = values.concat(this.walkTokens(genericToken.tokens, callback));
|
|
60825
|
-
}
|
|
60826
|
-
}
|
|
60827
|
-
}
|
|
60828
|
-
}
|
|
60829
|
-
return values;
|
|
61079
|
+
static parse(tokens, options2) {
|
|
61080
|
+
const parser2 = new __Parser(options2);
|
|
61081
|
+
return parser2.parse(tokens);
|
|
60830
61082
|
}
|
|
60831
|
-
|
|
60832
|
-
|
|
60833
|
-
|
|
60834
|
-
|
|
60835
|
-
|
|
60836
|
-
|
|
60837
|
-
|
|
60838
|
-
|
|
60839
|
-
|
|
60840
|
-
|
|
60841
|
-
|
|
60842
|
-
|
|
60843
|
-
|
|
60844
|
-
|
|
60845
|
-
|
|
60846
|
-
|
|
60847
|
-
|
|
60848
|
-
|
|
60849
|
-
|
|
60850
|
-
|
|
60851
|
-
} else {
|
|
60852
|
-
extensions.renderers[ext.name] = ext.renderer;
|
|
60853
|
-
}
|
|
60854
|
-
}
|
|
60855
|
-
if ("tokenizer" in ext) {
|
|
60856
|
-
if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
|
|
60857
|
-
throw new Error("extension level must be 'block' or 'inline'");
|
|
60858
|
-
}
|
|
60859
|
-
const extLevel = extensions[ext.level];
|
|
60860
|
-
if (extLevel) {
|
|
60861
|
-
extLevel.unshift(ext.tokenizer);
|
|
60862
|
-
} else {
|
|
60863
|
-
extensions[ext.level] = [ext.tokenizer];
|
|
60864
|
-
}
|
|
60865
|
-
if (ext.start) {
|
|
60866
|
-
if (ext.level === "block") {
|
|
60867
|
-
if (extensions.startBlock) {
|
|
60868
|
-
extensions.startBlock.push(ext.start);
|
|
60869
|
-
} else {
|
|
60870
|
-
extensions.startBlock = [ext.start];
|
|
60871
|
-
}
|
|
60872
|
-
} else if (ext.level === "inline") {
|
|
60873
|
-
if (extensions.startInline) {
|
|
60874
|
-
extensions.startInline.push(ext.start);
|
|
60875
|
-
} else {
|
|
60876
|
-
extensions.startInline = [ext.start];
|
|
60877
|
-
}
|
|
60878
|
-
}
|
|
60879
|
-
}
|
|
60880
|
-
}
|
|
60881
|
-
if ("childTokens" in ext && ext.childTokens) {
|
|
60882
|
-
extensions.childTokens[ext.name] = ext.childTokens;
|
|
60883
|
-
}
|
|
60884
|
-
});
|
|
60885
|
-
opts.extensions = extensions;
|
|
60886
|
-
}
|
|
60887
|
-
if (pack.renderer) {
|
|
60888
|
-
const renderer2 = this.defaults.renderer || new _Renderer(this.defaults);
|
|
60889
|
-
for (const prop in pack.renderer) {
|
|
60890
|
-
if (!(prop in renderer2)) {
|
|
60891
|
-
throw new Error(`renderer '${prop}' does not exist`);
|
|
60892
|
-
}
|
|
60893
|
-
if (["options", "parser"].includes(prop)) {
|
|
60894
|
-
continue;
|
|
60895
|
-
}
|
|
60896
|
-
const rendererProp = prop;
|
|
60897
|
-
const rendererFunc = pack.renderer[rendererProp];
|
|
60898
|
-
const prevRenderer = renderer2[rendererProp];
|
|
60899
|
-
renderer2[rendererProp] = (...args2) => {
|
|
60900
|
-
let ret = rendererFunc.apply(renderer2, args2);
|
|
60901
|
-
if (ret === false) {
|
|
60902
|
-
ret = prevRenderer.apply(renderer2, args2);
|
|
60903
|
-
}
|
|
60904
|
-
return ret || "";
|
|
60905
|
-
};
|
|
61083
|
+
/**
|
|
61084
|
+
* Static Parse Inline Method
|
|
61085
|
+
*/
|
|
61086
|
+
static parseInline(tokens, options2) {
|
|
61087
|
+
const parser2 = new __Parser(options2);
|
|
61088
|
+
return parser2.parseInline(tokens);
|
|
61089
|
+
}
|
|
61090
|
+
/**
|
|
61091
|
+
* Parse Loop
|
|
61092
|
+
*/
|
|
61093
|
+
parse(tokens, top = true) {
|
|
61094
|
+
let out = "";
|
|
61095
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
61096
|
+
const anyToken = tokens[i];
|
|
61097
|
+
if (this.options.extensions?.renderers?.[anyToken.type]) {
|
|
61098
|
+
const genericToken = anyToken;
|
|
61099
|
+
const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);
|
|
61100
|
+
if (ret !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "paragraph", "text"].includes(genericToken.type)) {
|
|
61101
|
+
out += ret || "";
|
|
61102
|
+
continue;
|
|
60906
61103
|
}
|
|
60907
|
-
opts.renderer = renderer2;
|
|
60908
61104
|
}
|
|
60909
|
-
|
|
60910
|
-
|
|
60911
|
-
|
|
60912
|
-
|
|
60913
|
-
|
|
60914
|
-
}
|
|
60915
|
-
if (["options", "rules", "lexer"].includes(prop)) {
|
|
60916
|
-
continue;
|
|
60917
|
-
}
|
|
60918
|
-
const tokenizerProp = prop;
|
|
60919
|
-
const tokenizerFunc = pack.tokenizer[tokenizerProp];
|
|
60920
|
-
const prevTokenizer = tokenizer[tokenizerProp];
|
|
60921
|
-
tokenizer[tokenizerProp] = (...args2) => {
|
|
60922
|
-
let ret = tokenizerFunc.apply(tokenizer, args2);
|
|
60923
|
-
if (ret === false) {
|
|
60924
|
-
ret = prevTokenizer.apply(tokenizer, args2);
|
|
60925
|
-
}
|
|
60926
|
-
return ret;
|
|
60927
|
-
};
|
|
61105
|
+
const token = anyToken;
|
|
61106
|
+
switch (token.type) {
|
|
61107
|
+
case "space": {
|
|
61108
|
+
out += this.renderer.space(token);
|
|
61109
|
+
continue;
|
|
60928
61110
|
}
|
|
60929
|
-
|
|
60930
|
-
|
|
60931
|
-
|
|
60932
|
-
|
|
60933
|
-
|
|
60934
|
-
|
|
60935
|
-
|
|
60936
|
-
|
|
60937
|
-
|
|
60938
|
-
|
|
61111
|
+
case "hr": {
|
|
61112
|
+
out += this.renderer.hr(token);
|
|
61113
|
+
continue;
|
|
61114
|
+
}
|
|
61115
|
+
case "heading": {
|
|
61116
|
+
out += this.renderer.heading(token);
|
|
61117
|
+
continue;
|
|
61118
|
+
}
|
|
61119
|
+
case "code": {
|
|
61120
|
+
out += this.renderer.code(token);
|
|
61121
|
+
continue;
|
|
61122
|
+
}
|
|
61123
|
+
case "table": {
|
|
61124
|
+
out += this.renderer.table(token);
|
|
61125
|
+
continue;
|
|
61126
|
+
}
|
|
61127
|
+
case "blockquote": {
|
|
61128
|
+
out += this.renderer.blockquote(token);
|
|
61129
|
+
continue;
|
|
61130
|
+
}
|
|
61131
|
+
case "list": {
|
|
61132
|
+
out += this.renderer.list(token);
|
|
61133
|
+
continue;
|
|
61134
|
+
}
|
|
61135
|
+
case "html": {
|
|
61136
|
+
out += this.renderer.html(token);
|
|
61137
|
+
continue;
|
|
61138
|
+
}
|
|
61139
|
+
case "paragraph": {
|
|
61140
|
+
out += this.renderer.paragraph(token);
|
|
61141
|
+
continue;
|
|
61142
|
+
}
|
|
61143
|
+
case "text": {
|
|
61144
|
+
let textToken = token;
|
|
61145
|
+
let body = this.renderer.text(textToken);
|
|
61146
|
+
while (i + 1 < tokens.length && tokens[i + 1].type === "text") {
|
|
61147
|
+
textToken = tokens[++i];
|
|
61148
|
+
body += "\n" + this.renderer.text(textToken);
|
|
60939
61149
|
}
|
|
60940
|
-
|
|
60941
|
-
|
|
60942
|
-
|
|
60943
|
-
|
|
60944
|
-
|
|
60945
|
-
|
|
60946
|
-
|
|
60947
|
-
return prevHook.call(hooks, ret2);
|
|
60948
|
-
});
|
|
60949
|
-
}
|
|
60950
|
-
const ret = hooksFunc.call(hooks, arg);
|
|
60951
|
-
return prevHook.call(hooks, ret);
|
|
60952
|
-
};
|
|
61150
|
+
if (top) {
|
|
61151
|
+
out += this.renderer.paragraph({
|
|
61152
|
+
type: "paragraph",
|
|
61153
|
+
raw: body,
|
|
61154
|
+
text: body,
|
|
61155
|
+
tokens: [{ type: "text", raw: body, text: body, escaped: true }]
|
|
61156
|
+
});
|
|
60953
61157
|
} else {
|
|
60954
|
-
|
|
60955
|
-
let ret = hooksFunc.apply(hooks, args2);
|
|
60956
|
-
if (ret === false) {
|
|
60957
|
-
ret = prevHook.apply(hooks, args2);
|
|
60958
|
-
}
|
|
60959
|
-
return ret;
|
|
60960
|
-
};
|
|
61158
|
+
out += body;
|
|
60961
61159
|
}
|
|
61160
|
+
continue;
|
|
60962
61161
|
}
|
|
60963
|
-
|
|
60964
|
-
|
|
60965
|
-
|
|
60966
|
-
|
|
60967
|
-
|
|
60968
|
-
|
|
60969
|
-
|
|
60970
|
-
values.push(packWalktokens.call(this, token));
|
|
60971
|
-
if (walkTokens2) {
|
|
60972
|
-
values = values.concat(walkTokens2.call(this, token));
|
|
61162
|
+
default: {
|
|
61163
|
+
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
61164
|
+
if (this.options.silent) {
|
|
61165
|
+
console.error(errMsg);
|
|
61166
|
+
return "";
|
|
61167
|
+
} else {
|
|
61168
|
+
throw new Error(errMsg);
|
|
60973
61169
|
}
|
|
60974
|
-
|
|
60975
|
-
};
|
|
61170
|
+
}
|
|
60976
61171
|
}
|
|
60977
|
-
|
|
60978
|
-
|
|
60979
|
-
return this;
|
|
60980
|
-
}
|
|
60981
|
-
setOptions(opt) {
|
|
60982
|
-
this.defaults = { ...this.defaults, ...opt };
|
|
60983
|
-
return this;
|
|
60984
|
-
}
|
|
60985
|
-
lexer(src, options2) {
|
|
60986
|
-
return _Lexer.lex(src, options2 ?? this.defaults);
|
|
60987
|
-
}
|
|
60988
|
-
parser(tokens, options2) {
|
|
60989
|
-
return _Parser.parse(tokens, options2 ?? this.defaults);
|
|
61172
|
+
}
|
|
61173
|
+
return out;
|
|
60990
61174
|
}
|
|
60991
|
-
|
|
60992
|
-
|
|
60993
|
-
|
|
60994
|
-
|
|
60995
|
-
|
|
60996
|
-
|
|
60997
|
-
|
|
60998
|
-
|
|
60999
|
-
|
|
61000
|
-
|
|
61001
|
-
|
|
61002
|
-
|
|
61003
|
-
|
|
61004
|
-
}
|
|
61005
|
-
if (opt.hooks) {
|
|
61006
|
-
opt.hooks.options = opt;
|
|
61007
|
-
opt.hooks.block = blockType;
|
|
61008
|
-
}
|
|
61009
|
-
const lexer2 = opt.hooks ? opt.hooks.provideLexer() : blockType ? _Lexer.lex : _Lexer.lexInline;
|
|
61010
|
-
const parser2 = opt.hooks ? opt.hooks.provideParser() : blockType ? _Parser.parse : _Parser.parseInline;
|
|
61011
|
-
if (opt.async) {
|
|
61012
|
-
return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser2(tokens, opt)).then((html2) => opt.hooks ? opt.hooks.postprocess(html2) : html2).catch(throwError);
|
|
61175
|
+
/**
|
|
61176
|
+
* Parse Inline Tokens
|
|
61177
|
+
*/
|
|
61178
|
+
parseInline(tokens, renderer2 = this.renderer) {
|
|
61179
|
+
let out = "";
|
|
61180
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
61181
|
+
const anyToken = tokens[i];
|
|
61182
|
+
if (this.options.extensions?.renderers?.[anyToken.type]) {
|
|
61183
|
+
const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);
|
|
61184
|
+
if (ret !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(anyToken.type)) {
|
|
61185
|
+
out += ret || "";
|
|
61186
|
+
continue;
|
|
61187
|
+
}
|
|
61013
61188
|
}
|
|
61014
|
-
|
|
61015
|
-
|
|
61016
|
-
|
|
61189
|
+
const token = anyToken;
|
|
61190
|
+
switch (token.type) {
|
|
61191
|
+
case "escape": {
|
|
61192
|
+
out += renderer2.text(token);
|
|
61193
|
+
break;
|
|
61017
61194
|
}
|
|
61018
|
-
|
|
61019
|
-
|
|
61020
|
-
|
|
61195
|
+
case "html": {
|
|
61196
|
+
out += renderer2.html(token);
|
|
61197
|
+
break;
|
|
61021
61198
|
}
|
|
61022
|
-
|
|
61023
|
-
|
|
61199
|
+
case "link": {
|
|
61200
|
+
out += renderer2.link(token);
|
|
61201
|
+
break;
|
|
61024
61202
|
}
|
|
61025
|
-
|
|
61026
|
-
|
|
61027
|
-
|
|
61203
|
+
case "image": {
|
|
61204
|
+
out += renderer2.image(token);
|
|
61205
|
+
break;
|
|
61028
61206
|
}
|
|
61029
|
-
|
|
61030
|
-
|
|
61031
|
-
|
|
61032
|
-
|
|
61033
|
-
|
|
61034
|
-
|
|
61035
|
-
|
|
61036
|
-
|
|
61037
|
-
|
|
61038
|
-
|
|
61039
|
-
|
|
61040
|
-
|
|
61041
|
-
|
|
61042
|
-
|
|
61207
|
+
case "strong": {
|
|
61208
|
+
out += renderer2.strong(token);
|
|
61209
|
+
break;
|
|
61210
|
+
}
|
|
61211
|
+
case "em": {
|
|
61212
|
+
out += renderer2.em(token);
|
|
61213
|
+
break;
|
|
61214
|
+
}
|
|
61215
|
+
case "codespan": {
|
|
61216
|
+
out += renderer2.codespan(token);
|
|
61217
|
+
break;
|
|
61218
|
+
}
|
|
61219
|
+
case "br": {
|
|
61220
|
+
out += renderer2.br(token);
|
|
61221
|
+
break;
|
|
61222
|
+
}
|
|
61223
|
+
case "del": {
|
|
61224
|
+
out += renderer2.del(token);
|
|
61225
|
+
break;
|
|
61226
|
+
}
|
|
61227
|
+
case "text": {
|
|
61228
|
+
out += renderer2.text(token);
|
|
61229
|
+
break;
|
|
61230
|
+
}
|
|
61231
|
+
default: {
|
|
61232
|
+
const errMsg = 'Token with "' + token.type + '" type was not found.';
|
|
61233
|
+
if (this.options.silent) {
|
|
61234
|
+
console.error(errMsg);
|
|
61235
|
+
return "";
|
|
61236
|
+
} else {
|
|
61237
|
+
throw new Error(errMsg);
|
|
61238
|
+
}
|
|
61043
61239
|
}
|
|
61044
|
-
return msg;
|
|
61045
|
-
}
|
|
61046
|
-
if (async) {
|
|
61047
|
-
return Promise.reject(e);
|
|
61048
61240
|
}
|
|
61049
|
-
|
|
61050
|
-
|
|
61241
|
+
}
|
|
61242
|
+
return out;
|
|
61051
61243
|
}
|
|
61052
61244
|
};
|
|
61053
|
-
|
|
61054
|
-
|
|
61055
|
-
|
|
61056
|
-
|
|
61057
|
-
|
|
61058
|
-
|
|
61059
|
-
|
|
61060
|
-
|
|
61061
|
-
|
|
61062
|
-
|
|
61063
|
-
|
|
61064
|
-
|
|
61065
|
-
|
|
61066
|
-
|
|
61067
|
-
|
|
61068
|
-
|
|
61069
|
-
|
|
61070
|
-
|
|
61071
|
-
|
|
61072
|
-
|
|
61073
|
-
|
|
61074
|
-
|
|
61075
|
-
|
|
61076
|
-
|
|
61077
|
-
|
|
61078
|
-
|
|
61079
|
-
|
|
61080
|
-
|
|
61081
|
-
|
|
61082
|
-
|
|
61083
|
-
|
|
61084
|
-
|
|
61085
|
-
|
|
61086
|
-
|
|
61087
|
-
|
|
61088
|
-
|
|
61089
|
-
|
|
61090
|
-
|
|
61091
|
-
|
|
61092
|
-
|
|
61093
|
-
const lexer2 = new _Lexer();
|
|
61094
|
-
const tokens = lexer2.lex(markdown);
|
|
61095
|
-
return renderTokens(tokens, maxWidth);
|
|
61096
|
-
}
|
|
61097
|
-
function renderTokens(tokens, maxWidth) {
|
|
61098
|
-
const lines = [];
|
|
61099
|
-
for (const token of tokens) {
|
|
61100
|
-
switch (token.type) {
|
|
61101
|
-
case "heading":
|
|
61102
|
-
lines.push(renderHeading(token));
|
|
61103
|
-
lines.push("");
|
|
61104
|
-
break;
|
|
61105
|
-
case "paragraph":
|
|
61106
|
-
lines.push(renderInline(token.text));
|
|
61107
|
-
lines.push("");
|
|
61108
|
-
break;
|
|
61109
|
-
case "code":
|
|
61110
|
-
lines.push(...renderCodeBlock(token, maxWidth));
|
|
61111
|
-
lines.push("");
|
|
61112
|
-
break;
|
|
61113
|
-
case "list":
|
|
61114
|
-
lines.push(...renderList(token));
|
|
61115
|
-
lines.push("");
|
|
61116
|
-
break;
|
|
61117
|
-
case "blockquote":
|
|
61118
|
-
lines.push(...renderBlockquote(token));
|
|
61119
|
-
lines.push("");
|
|
61120
|
-
break;
|
|
61121
|
-
case "table":
|
|
61122
|
-
lines.push(...renderTable(token, maxWidth));
|
|
61123
|
-
lines.push("");
|
|
61124
|
-
break;
|
|
61125
|
-
case "hr":
|
|
61126
|
-
lines.push(`${FG_GRAY}${"\u2500".repeat(Math.min(maxWidth, 60))}${RESET}`);
|
|
61127
|
-
lines.push("");
|
|
61128
|
-
break;
|
|
61129
|
-
case "space":
|
|
61130
|
-
lines.push("");
|
|
61131
|
-
break;
|
|
61132
|
-
case "html":
|
|
61133
|
-
lines.push(renderInline(token.text.replace(/<[^>]+>/g, "")));
|
|
61134
|
-
break;
|
|
61135
|
-
default:
|
|
61136
|
-
if ("text" in token) {
|
|
61137
|
-
lines.push(renderInline(String(token.text)));
|
|
61138
|
-
}
|
|
61139
|
-
break;
|
|
61140
|
-
}
|
|
61141
|
-
}
|
|
61142
|
-
return lines.join("\n");
|
|
61143
|
-
}
|
|
61144
|
-
function renderHeading(token) {
|
|
61145
|
-
const prefix = token.depth <= 2 ? `${BOLD}${FG_CYAN}` : `${BOLD}${FG_BLUE}`;
|
|
61146
|
-
const marker = "#".repeat(token.depth);
|
|
61147
|
-
return `${prefix}${marker} ${renderInline(token.text)}${RESET}`;
|
|
61148
|
-
}
|
|
61149
|
-
function renderCodeBlock(token, maxWidth) {
|
|
61150
|
-
const lines = [];
|
|
61151
|
-
const lang = token.lang ?? "";
|
|
61152
|
-
if (lang) {
|
|
61153
|
-
lines.push(`${FG_GRAY}\u250C\u2500 ${lang} ${"\u2500".repeat(Math.max(0, Math.min(maxWidth, 60) - lang.length - 4))}${RESET}`);
|
|
61154
|
-
} else {
|
|
61155
|
-
lines.push(`${FG_GRAY}\u250C${"\u2500".repeat(Math.min(maxWidth, 60) - 1)}${RESET}`);
|
|
61156
|
-
}
|
|
61157
|
-
for (const line of token.text.split("\n")) {
|
|
61158
|
-
const highlighted = lang ? highlightSyntax(line, lang) : `${FG_GREEN}${line}${RESET}`;
|
|
61159
|
-
lines.push(`${FG_GRAY}\u2502${RESET} ${highlighted}`);
|
|
61160
|
-
}
|
|
61161
|
-
lines.push(`${FG_GRAY}\u2514${"\u2500".repeat(Math.min(maxWidth, 60) - 1)}${RESET}`);
|
|
61162
|
-
return lines;
|
|
61163
|
-
}
|
|
61164
|
-
function renderList(token) {
|
|
61165
|
-
const lines = [];
|
|
61166
|
-
const ordered = token.ordered;
|
|
61167
|
-
for (let i = 0; i < token.items.length; i++) {
|
|
61168
|
-
const item = token.items[i];
|
|
61169
|
-
const marker = ordered ? `${FG_YELLOW}${i + 1}.${RESET}` : `${FG_YELLOW}\u2022${RESET}`;
|
|
61170
|
-
const text = renderInline(item.text);
|
|
61171
|
-
lines.push(` ${marker} ${text}`);
|
|
61172
|
-
if (item.tokens) {
|
|
61173
|
-
for (const subToken of item.tokens) {
|
|
61174
|
-
if (subToken.type === "list") {
|
|
61175
|
-
const subLines = renderList(subToken);
|
|
61176
|
-
lines.push(...subLines.map((l) => ` ${l}`));
|
|
61177
|
-
}
|
|
61245
|
+
_Hooks = class {
|
|
61246
|
+
options;
|
|
61247
|
+
block;
|
|
61248
|
+
constructor(options2) {
|
|
61249
|
+
this.options = options2 || _defaults;
|
|
61250
|
+
}
|
|
61251
|
+
static passThroughHooks = /* @__PURE__ */ new Set([
|
|
61252
|
+
"preprocess",
|
|
61253
|
+
"postprocess",
|
|
61254
|
+
"processAllTokens"
|
|
61255
|
+
]);
|
|
61256
|
+
/**
|
|
61257
|
+
* Process markdown before marked
|
|
61258
|
+
*/
|
|
61259
|
+
preprocess(markdown) {
|
|
61260
|
+
return markdown;
|
|
61261
|
+
}
|
|
61262
|
+
/**
|
|
61263
|
+
* Process HTML after marked is finished
|
|
61264
|
+
*/
|
|
61265
|
+
postprocess(html2) {
|
|
61266
|
+
return html2;
|
|
61267
|
+
}
|
|
61268
|
+
/**
|
|
61269
|
+
* Process all tokens before walk tokens
|
|
61270
|
+
*/
|
|
61271
|
+
processAllTokens(tokens) {
|
|
61272
|
+
return tokens;
|
|
61273
|
+
}
|
|
61274
|
+
/**
|
|
61275
|
+
* Provide function to tokenize markdown
|
|
61276
|
+
*/
|
|
61277
|
+
provideLexer() {
|
|
61278
|
+
return this.block ? _Lexer.lex : _Lexer.lexInline;
|
|
61279
|
+
}
|
|
61280
|
+
/**
|
|
61281
|
+
* Provide function to parse tokens
|
|
61282
|
+
*/
|
|
61283
|
+
provideParser() {
|
|
61284
|
+
return this.block ? _Parser.parse : _Parser.parseInline;
|
|
61178
61285
|
}
|
|
61179
|
-
}
|
|
61180
|
-
}
|
|
61181
|
-
return lines;
|
|
61182
|
-
}
|
|
61183
|
-
function renderBlockquote(token) {
|
|
61184
|
-
const inner = renderTokens(token.tokens, 100);
|
|
61185
|
-
return inner.split("\n").map((line) => `${FG_GRAY}\u2502${RESET} ${DIM}${line}${RESET}`);
|
|
61186
|
-
}
|
|
61187
|
-
function renderTable(token, maxWidth) {
|
|
61188
|
-
const lines = [];
|
|
61189
|
-
const colWidths = token.header.map((h) => h.text.length);
|
|
61190
|
-
for (const row of token.rows) {
|
|
61191
|
-
for (let i = 0; i < row.length; i++) {
|
|
61192
|
-
colWidths[i] = Math.max(colWidths[i] ?? 0, row[i].text.length);
|
|
61193
|
-
}
|
|
61194
|
-
}
|
|
61195
|
-
const totalWidth = colWidths.reduce((a, b) => a + b, 0) + colWidths.length * 3 + 1;
|
|
61196
|
-
if (totalWidth > maxWidth) {
|
|
61197
|
-
const scale = maxWidth / totalWidth;
|
|
61198
|
-
for (let i = 0; i < colWidths.length; i++) {
|
|
61199
|
-
colWidths[i] = Math.max(3, Math.floor(colWidths[i] * scale));
|
|
61200
|
-
}
|
|
61201
|
-
}
|
|
61202
|
-
const headerLine = token.header.map((h, i) => pad(h.text, colWidths[i])).join(` ${FG_GRAY}\u2502${RESET} `);
|
|
61203
|
-
lines.push(`${BOLD}${headerLine}${RESET}`);
|
|
61204
|
-
const sepLine = colWidths.map((w) => "\u2500".repeat(w)).join(`\u2500\u253C\u2500`);
|
|
61205
|
-
lines.push(`${FG_GRAY}${sepLine}${RESET}`);
|
|
61206
|
-
for (const row of token.rows) {
|
|
61207
|
-
const rowLine = row.map((cell, i) => pad(cell.text, colWidths[i])).join(` ${FG_GRAY}\u2502${RESET} `);
|
|
61208
|
-
lines.push(rowLine);
|
|
61209
|
-
}
|
|
61210
|
-
return lines;
|
|
61211
|
-
}
|
|
61212
|
-
function renderInline(text) {
|
|
61213
|
-
return text.replace(/\*\*(.+?)\*\*/g, `${BOLD}$1${RESET}`).replace(/__(.+?)__/g, `${BOLD}$1${RESET}`).replace(/\*(.+?)\*/g, `${ITALIC}$1${RESET}`).replace(/_(.+?)_/g, `${ITALIC}$1${RESET}`).replace(/~~(.+?)~~/g, `${STRIKETHROUGH}$1${RESET}`).replace(/`([^`]+)`/g, `${BG_GRAY}${FG_GREEN} $1 ${RESET}`).replace(/\[([^\]]+)\]\(([^)]+)\)/g, `${UNDERLINE}${FG_BLUE}$1${RESET}${FG_GRAY} ($2)${RESET}`).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"');
|
|
61214
|
-
}
|
|
61215
|
-
function highlightSyntax(line, lang) {
|
|
61216
|
-
const keywords = {
|
|
61217
|
-
typescript: ["import", "export", "from", "const", "let", "var", "function", "class", "interface", "type", "return", "if", "else", "for", "while", "async", "await", "new", "this", "extends", "implements"],
|
|
61218
|
-
javascript: ["import", "export", "from", "const", "let", "var", "function", "class", "return", "if", "else", "for", "while", "async", "await", "new", "this"],
|
|
61219
|
-
python: ["import", "from", "def", "class", "return", "if", "elif", "else", "for", "while", "with", "as", "try", "except", "finally", "raise", "yield", "async", "await", "self"],
|
|
61220
|
-
rust: ["fn", "let", "mut", "pub", "struct", "enum", "impl", "trait", "use", "mod", "return", "if", "else", "for", "while", "match", "self", "super", "crate"],
|
|
61221
|
-
go: ["func", "var", "const", "type", "struct", "interface", "return", "if", "else", "for", "range", "switch", "case", "package", "import", "defer", "go", "chan"]
|
|
61222
|
-
};
|
|
61223
|
-
const ts = keywords.typescript ?? [];
|
|
61224
|
-
const kw = keywords[lang] ?? keywords[lang.replace(/x$/, "")] ?? ts;
|
|
61225
|
-
let result = line;
|
|
61226
|
-
result = result.replace(/(\/\/.*$)/gm, `${FG_GRAY}$1${RESET}`);
|
|
61227
|
-
result = result.replace(/(#.*$)/gm, `${FG_GRAY}$1${RESET}`);
|
|
61228
|
-
result = result.replace(/("[^"]*")/g, `${FG_GREEN}$1${RESET}`);
|
|
61229
|
-
result = result.replace(/('[^']*')/g, `${FG_GREEN}$1${RESET}`);
|
|
61230
|
-
result = result.replace(/(`[^`]*`)/g, `${FG_GREEN}$1${RESET}`);
|
|
61231
|
-
for (const kwd of kw) {
|
|
61232
|
-
result = result.replace(
|
|
61233
|
-
new RegExp(`\\b(${kwd})\\b`, "g"),
|
|
61234
|
-
`${FG_MAGENTA}$1${RESET}`
|
|
61235
|
-
);
|
|
61236
|
-
}
|
|
61237
|
-
result = result.replace(/\b(\d+\.?\d*)\b/g, `${FG_YELLOW}$1${RESET}`);
|
|
61238
|
-
return result;
|
|
61239
|
-
}
|
|
61240
|
-
function pad(text, width) {
|
|
61241
|
-
if (text.length >= width) return text.slice(0, width);
|
|
61242
|
-
return text + " ".repeat(width - text.length);
|
|
61243
|
-
}
|
|
61244
|
-
var ESC2, RESET, BOLD, DIM, ITALIC, UNDERLINE, STRIKETHROUGH, FG_CYAN, FG_YELLOW, FG_GREEN, FG_BLUE, FG_MAGENTA, FG_GRAY, BG_GRAY;
|
|
61245
|
-
var init_markdown = __esm({
|
|
61246
|
-
"src/ui/components/markdown.tsx"() {
|
|
61247
|
-
"use strict";
|
|
61248
|
-
init_marked_esm();
|
|
61249
|
-
ESC2 = "\x1B[";
|
|
61250
|
-
RESET = `${ESC2}0m`;
|
|
61251
|
-
BOLD = `${ESC2}1m`;
|
|
61252
|
-
DIM = `${ESC2}2m`;
|
|
61253
|
-
ITALIC = `${ESC2}3m`;
|
|
61254
|
-
UNDERLINE = `${ESC2}4m`;
|
|
61255
|
-
STRIKETHROUGH = `${ESC2}9m`;
|
|
61256
|
-
FG_CYAN = `${ESC2}36m`;
|
|
61257
|
-
FG_YELLOW = `${ESC2}33m`;
|
|
61258
|
-
FG_GREEN = `${ESC2}32m`;
|
|
61259
|
-
FG_BLUE = `${ESC2}34m`;
|
|
61260
|
-
FG_MAGENTA = `${ESC2}35m`;
|
|
61261
|
-
FG_GRAY = `${ESC2}90m`;
|
|
61262
|
-
BG_GRAY = `${ESC2}100m`;
|
|
61263
|
-
}
|
|
61264
|
-
});
|
|
61265
|
-
|
|
61266
|
-
// src/api/index.ts
|
|
61267
|
-
var init_api = __esm({
|
|
61268
|
-
"src/api/index.ts"() {
|
|
61269
|
-
"use strict";
|
|
61270
|
-
init_client();
|
|
61271
|
-
init_models();
|
|
61272
|
-
init_streaming();
|
|
61273
|
-
}
|
|
61274
|
-
});
|
|
61275
|
-
|
|
61276
|
-
// src/core/errors.ts
|
|
61277
|
-
function errorToString(err) {
|
|
61278
|
-
if (err instanceof Error) return err.message;
|
|
61279
|
-
if (typeof err === "string") return err;
|
|
61280
|
-
return String(err);
|
|
61281
|
-
}
|
|
61282
|
-
var init_errors2 = __esm({
|
|
61283
|
-
"src/core/errors.ts"() {
|
|
61284
|
-
"use strict";
|
|
61285
|
-
}
|
|
61286
|
-
});
|
|
61287
|
-
|
|
61288
|
-
// src/core/agent-loop.ts
|
|
61289
|
-
async function runAgentLoop(initialMessages, options2) {
|
|
61290
|
-
const client = options2.client ?? getApiClient();
|
|
61291
|
-
const messages = [...initialMessages];
|
|
61292
|
-
const maxTurns = options2.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
61293
|
-
let totalInputTokens = 0;
|
|
61294
|
-
let totalOutputTokens = 0;
|
|
61295
|
-
let turnIndex = 0;
|
|
61296
|
-
let aborted = false;
|
|
61297
|
-
const toolDefs = buildToolDefinitions(options2.tools);
|
|
61298
|
-
const toolMap = new Map(options2.tools.map((t) => [t.name, t]));
|
|
61299
|
-
while (turnIndex < maxTurns) {
|
|
61300
|
-
if (options2.signal?.aborted) {
|
|
61301
|
-
aborted = true;
|
|
61302
|
-
break;
|
|
61303
|
-
}
|
|
61304
|
-
options2.onProgress?.({ type: "turn_start", turnIndex });
|
|
61305
|
-
const request = {
|
|
61306
|
-
model: options2.model,
|
|
61307
|
-
messages,
|
|
61308
|
-
systemPrompt: options2.systemPrompt,
|
|
61309
|
-
tools: toolDefs.length > 0 ? toolDefs : void 0,
|
|
61310
|
-
thinkingConfig: options2.thinkingConfig,
|
|
61311
|
-
maxTokens: options2.maxTokens,
|
|
61312
|
-
stream: true,
|
|
61313
|
-
signal: options2.signal,
|
|
61314
|
-
querySource: options2.querySource
|
|
61315
61286
|
};
|
|
61316
|
-
|
|
61317
|
-
|
|
61318
|
-
|
|
61319
|
-
|
|
61320
|
-
|
|
61321
|
-
|
|
61322
|
-
|
|
61323
|
-
|
|
61287
|
+
Marked = class {
|
|
61288
|
+
defaults = _getDefaults();
|
|
61289
|
+
options = this.setOptions;
|
|
61290
|
+
parse = this.parseMarkdown(true);
|
|
61291
|
+
parseInline = this.parseMarkdown(false);
|
|
61292
|
+
Parser = _Parser;
|
|
61293
|
+
Renderer = _Renderer;
|
|
61294
|
+
TextRenderer = _TextRenderer;
|
|
61295
|
+
Lexer = _Lexer;
|
|
61296
|
+
Tokenizer = _Tokenizer;
|
|
61297
|
+
Hooks = _Hooks;
|
|
61298
|
+
constructor(...args) {
|
|
61299
|
+
this.use(...args);
|
|
61300
|
+
}
|
|
61301
|
+
/**
|
|
61302
|
+
* Run callback for every token
|
|
61303
|
+
*/
|
|
61304
|
+
walkTokens(tokens, callback) {
|
|
61305
|
+
let values = [];
|
|
61306
|
+
for (const token of tokens) {
|
|
61307
|
+
values = values.concat(callback.call(this, token));
|
|
61308
|
+
switch (token.type) {
|
|
61309
|
+
case "table": {
|
|
61310
|
+
const tableToken = token;
|
|
61311
|
+
for (const cell of tableToken.header) {
|
|
61312
|
+
values = values.concat(this.walkTokens(cell.tokens, callback));
|
|
61313
|
+
}
|
|
61314
|
+
for (const row of tableToken.rows) {
|
|
61315
|
+
for (const cell of row) {
|
|
61316
|
+
values = values.concat(this.walkTokens(cell.tokens, callback));
|
|
61317
|
+
}
|
|
61318
|
+
}
|
|
61319
|
+
break;
|
|
61320
|
+
}
|
|
61321
|
+
case "list": {
|
|
61322
|
+
const listToken = token;
|
|
61323
|
+
values = values.concat(this.walkTokens(listToken.items, callback));
|
|
61324
|
+
break;
|
|
61325
|
+
}
|
|
61326
|
+
default: {
|
|
61327
|
+
const genericToken = token;
|
|
61328
|
+
if (this.defaults.extensions?.childTokens?.[genericToken.type]) {
|
|
61329
|
+
this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {
|
|
61330
|
+
const tokens2 = genericToken[childTokens].flat(Infinity);
|
|
61331
|
+
values = values.concat(this.walkTokens(tokens2, callback));
|
|
61332
|
+
});
|
|
61333
|
+
} else if (genericToken.tokens) {
|
|
61334
|
+
values = values.concat(this.walkTokens(genericToken.tokens, callback));
|
|
61335
|
+
}
|
|
61336
|
+
}
|
|
61337
|
+
}
|
|
61324
61338
|
}
|
|
61325
|
-
|
|
61326
|
-
|
|
61327
|
-
|
|
61328
|
-
|
|
61329
|
-
|
|
61330
|
-
|
|
61339
|
+
return values;
|
|
61340
|
+
}
|
|
61341
|
+
use(...args) {
|
|
61342
|
+
const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };
|
|
61343
|
+
args.forEach((pack) => {
|
|
61344
|
+
const opts = { ...pack };
|
|
61345
|
+
opts.async = this.defaults.async || opts.async || false;
|
|
61346
|
+
if (pack.extensions) {
|
|
61347
|
+
pack.extensions.forEach((ext) => {
|
|
61348
|
+
if (!ext.name) {
|
|
61349
|
+
throw new Error("extension name required");
|
|
61350
|
+
}
|
|
61351
|
+
if ("renderer" in ext) {
|
|
61352
|
+
const prevRenderer = extensions.renderers[ext.name];
|
|
61353
|
+
if (prevRenderer) {
|
|
61354
|
+
extensions.renderers[ext.name] = function(...args2) {
|
|
61355
|
+
let ret = ext.renderer.apply(this, args2);
|
|
61356
|
+
if (ret === false) {
|
|
61357
|
+
ret = prevRenderer.apply(this, args2);
|
|
61358
|
+
}
|
|
61359
|
+
return ret;
|
|
61360
|
+
};
|
|
61361
|
+
} else {
|
|
61362
|
+
extensions.renderers[ext.name] = ext.renderer;
|
|
61363
|
+
}
|
|
61364
|
+
}
|
|
61365
|
+
if ("tokenizer" in ext) {
|
|
61366
|
+
if (!ext.level || ext.level !== "block" && ext.level !== "inline") {
|
|
61367
|
+
throw new Error("extension level must be 'block' or 'inline'");
|
|
61368
|
+
}
|
|
61369
|
+
const extLevel = extensions[ext.level];
|
|
61370
|
+
if (extLevel) {
|
|
61371
|
+
extLevel.unshift(ext.tokenizer);
|
|
61372
|
+
} else {
|
|
61373
|
+
extensions[ext.level] = [ext.tokenizer];
|
|
61374
|
+
}
|
|
61375
|
+
if (ext.start) {
|
|
61376
|
+
if (ext.level === "block") {
|
|
61377
|
+
if (extensions.startBlock) {
|
|
61378
|
+
extensions.startBlock.push(ext.start);
|
|
61379
|
+
} else {
|
|
61380
|
+
extensions.startBlock = [ext.start];
|
|
61381
|
+
}
|
|
61382
|
+
} else if (ext.level === "inline") {
|
|
61383
|
+
if (extensions.startInline) {
|
|
61384
|
+
extensions.startInline.push(ext.start);
|
|
61385
|
+
} else {
|
|
61386
|
+
extensions.startInline = [ext.start];
|
|
61387
|
+
}
|
|
61388
|
+
}
|
|
61389
|
+
}
|
|
61390
|
+
}
|
|
61391
|
+
if ("childTokens" in ext && ext.childTokens) {
|
|
61392
|
+
extensions.childTokens[ext.name] = ext.childTokens;
|
|
61393
|
+
}
|
|
61394
|
+
});
|
|
61395
|
+
opts.extensions = extensions;
|
|
61396
|
+
}
|
|
61397
|
+
if (pack.renderer) {
|
|
61398
|
+
const renderer2 = this.defaults.renderer || new _Renderer(this.defaults);
|
|
61399
|
+
for (const prop in pack.renderer) {
|
|
61400
|
+
if (!(prop in renderer2)) {
|
|
61401
|
+
throw new Error(`renderer '${prop}' does not exist`);
|
|
61402
|
+
}
|
|
61403
|
+
if (["options", "parser"].includes(prop)) {
|
|
61404
|
+
continue;
|
|
61405
|
+
}
|
|
61406
|
+
const rendererProp = prop;
|
|
61407
|
+
const rendererFunc = pack.renderer[rendererProp];
|
|
61408
|
+
const prevRenderer = renderer2[rendererProp];
|
|
61409
|
+
renderer2[rendererProp] = (...args2) => {
|
|
61410
|
+
let ret = rendererFunc.apply(renderer2, args2);
|
|
61411
|
+
if (ret === false) {
|
|
61412
|
+
ret = prevRenderer.apply(renderer2, args2);
|
|
61413
|
+
}
|
|
61414
|
+
return ret || "";
|
|
61415
|
+
};
|
|
61416
|
+
}
|
|
61417
|
+
opts.renderer = renderer2;
|
|
61418
|
+
}
|
|
61419
|
+
if (pack.tokenizer) {
|
|
61420
|
+
const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);
|
|
61421
|
+
for (const prop in pack.tokenizer) {
|
|
61422
|
+
if (!(prop in tokenizer)) {
|
|
61423
|
+
throw new Error(`tokenizer '${prop}' does not exist`);
|
|
61424
|
+
}
|
|
61425
|
+
if (["options", "rules", "lexer"].includes(prop)) {
|
|
61426
|
+
continue;
|
|
61427
|
+
}
|
|
61428
|
+
const tokenizerProp = prop;
|
|
61429
|
+
const tokenizerFunc = pack.tokenizer[tokenizerProp];
|
|
61430
|
+
const prevTokenizer = tokenizer[tokenizerProp];
|
|
61431
|
+
tokenizer[tokenizerProp] = (...args2) => {
|
|
61432
|
+
let ret = tokenizerFunc.apply(tokenizer, args2);
|
|
61433
|
+
if (ret === false) {
|
|
61434
|
+
ret = prevTokenizer.apply(tokenizer, args2);
|
|
61435
|
+
}
|
|
61436
|
+
return ret;
|
|
61437
|
+
};
|
|
61438
|
+
}
|
|
61439
|
+
opts.tokenizer = tokenizer;
|
|
61440
|
+
}
|
|
61441
|
+
if (pack.hooks) {
|
|
61442
|
+
const hooks = this.defaults.hooks || new _Hooks();
|
|
61443
|
+
for (const prop in pack.hooks) {
|
|
61444
|
+
if (!(prop in hooks)) {
|
|
61445
|
+
throw new Error(`hook '${prop}' does not exist`);
|
|
61446
|
+
}
|
|
61447
|
+
if (["options", "block"].includes(prop)) {
|
|
61448
|
+
continue;
|
|
61449
|
+
}
|
|
61450
|
+
const hooksProp = prop;
|
|
61451
|
+
const hooksFunc = pack.hooks[hooksProp];
|
|
61452
|
+
const prevHook = hooks[hooksProp];
|
|
61453
|
+
if (_Hooks.passThroughHooks.has(prop)) {
|
|
61454
|
+
hooks[hooksProp] = (arg) => {
|
|
61455
|
+
if (this.defaults.async) {
|
|
61456
|
+
return Promise.resolve(hooksFunc.call(hooks, arg)).then((ret2) => {
|
|
61457
|
+
return prevHook.call(hooks, ret2);
|
|
61458
|
+
});
|
|
61459
|
+
}
|
|
61460
|
+
const ret = hooksFunc.call(hooks, arg);
|
|
61461
|
+
return prevHook.call(hooks, ret);
|
|
61462
|
+
};
|
|
61463
|
+
} else {
|
|
61464
|
+
hooks[hooksProp] = (...args2) => {
|
|
61465
|
+
let ret = hooksFunc.apply(hooks, args2);
|
|
61466
|
+
if (ret === false) {
|
|
61467
|
+
ret = prevHook.apply(hooks, args2);
|
|
61468
|
+
}
|
|
61469
|
+
return ret;
|
|
61470
|
+
};
|
|
61471
|
+
}
|
|
61472
|
+
}
|
|
61473
|
+
opts.hooks = hooks;
|
|
61474
|
+
}
|
|
61475
|
+
if (pack.walkTokens) {
|
|
61476
|
+
const walkTokens2 = this.defaults.walkTokens;
|
|
61477
|
+
const packWalktokens = pack.walkTokens;
|
|
61478
|
+
opts.walkTokens = function(token) {
|
|
61479
|
+
let values = [];
|
|
61480
|
+
values.push(packWalktokens.call(this, token));
|
|
61481
|
+
if (walkTokens2) {
|
|
61482
|
+
values = values.concat(walkTokens2.call(this, token));
|
|
61483
|
+
}
|
|
61484
|
+
return values;
|
|
61485
|
+
};
|
|
61486
|
+
}
|
|
61487
|
+
this.defaults = { ...this.defaults, ...opts };
|
|
61488
|
+
});
|
|
61489
|
+
return this;
|
|
61490
|
+
}
|
|
61491
|
+
setOptions(opt) {
|
|
61492
|
+
this.defaults = { ...this.defaults, ...opt };
|
|
61493
|
+
return this;
|
|
61494
|
+
}
|
|
61495
|
+
lexer(src, options2) {
|
|
61496
|
+
return _Lexer.lex(src, options2 ?? this.defaults);
|
|
61497
|
+
}
|
|
61498
|
+
parser(tokens, options2) {
|
|
61499
|
+
return _Parser.parse(tokens, options2 ?? this.defaults);
|
|
61500
|
+
}
|
|
61501
|
+
parseMarkdown(blockType) {
|
|
61502
|
+
const parse2 = (src, options2) => {
|
|
61503
|
+
const origOpt = { ...options2 };
|
|
61504
|
+
const opt = { ...this.defaults, ...origOpt };
|
|
61505
|
+
const throwError = this.onError(!!opt.silent, !!opt.async);
|
|
61506
|
+
if (this.defaults.async === true && origOpt.async === false) {
|
|
61507
|
+
return throwError(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
|
|
61331
61508
|
}
|
|
61332
|
-
|
|
61333
|
-
|
|
61334
|
-
if (accumulated.content) {
|
|
61335
|
-
contentBlocks.length = 0;
|
|
61336
|
-
contentBlocks.push(...accumulated.content);
|
|
61509
|
+
if (typeof src === "undefined" || src === null) {
|
|
61510
|
+
return throwError(new Error("marked(): input parameter is undefined or null"));
|
|
61337
61511
|
}
|
|
61338
|
-
|
|
61339
|
-
|
|
61340
|
-
totalInputTokens += accumulated.usage.inputTokens;
|
|
61341
|
-
totalOutputTokens += accumulated.usage.outputTokens;
|
|
61512
|
+
if (typeof src !== "string") {
|
|
61513
|
+
return throwError(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(src) + ", string expected"));
|
|
61342
61514
|
}
|
|
61343
|
-
|
|
61515
|
+
if (opt.hooks) {
|
|
61516
|
+
opt.hooks.options = opt;
|
|
61517
|
+
opt.hooks.block = blockType;
|
|
61518
|
+
}
|
|
61519
|
+
const lexer2 = opt.hooks ? opt.hooks.provideLexer() : blockType ? _Lexer.lex : _Lexer.lexInline;
|
|
61520
|
+
const parser2 = opt.hooks ? opt.hooks.provideParser() : blockType ? _Parser.parse : _Parser.parseInline;
|
|
61521
|
+
if (opt.async) {
|
|
61522
|
+
return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src).then((src2) => lexer2(src2, opt)).then((tokens) => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens).then((tokens) => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens).then((tokens) => parser2(tokens, opt)).then((html2) => opt.hooks ? opt.hooks.postprocess(html2) : html2).catch(throwError);
|
|
61523
|
+
}
|
|
61524
|
+
try {
|
|
61525
|
+
if (opt.hooks) {
|
|
61526
|
+
src = opt.hooks.preprocess(src);
|
|
61527
|
+
}
|
|
61528
|
+
let tokens = lexer2(src, opt);
|
|
61529
|
+
if (opt.hooks) {
|
|
61530
|
+
tokens = opt.hooks.processAllTokens(tokens);
|
|
61531
|
+
}
|
|
61532
|
+
if (opt.walkTokens) {
|
|
61533
|
+
this.walkTokens(tokens, opt.walkTokens);
|
|
61534
|
+
}
|
|
61535
|
+
let html2 = parser2(tokens, opt);
|
|
61536
|
+
if (opt.hooks) {
|
|
61537
|
+
html2 = opt.hooks.postprocess(html2);
|
|
61538
|
+
}
|
|
61539
|
+
return html2;
|
|
61540
|
+
} catch (e) {
|
|
61541
|
+
return throwError(e);
|
|
61542
|
+
}
|
|
61543
|
+
};
|
|
61544
|
+
return parse2;
|
|
61344
61545
|
}
|
|
61345
|
-
|
|
61346
|
-
|
|
61347
|
-
|
|
61348
|
-
|
|
61546
|
+
onError(silent, async) {
|
|
61547
|
+
return (e) => {
|
|
61548
|
+
e.message += "\nPlease report this to https://github.com/markedjs/marked.";
|
|
61549
|
+
if (silent) {
|
|
61550
|
+
const msg = "<p>An error occurred:</p><pre>" + escape22(e.message + "", true) + "</pre>";
|
|
61551
|
+
if (async) {
|
|
61552
|
+
return Promise.resolve(msg);
|
|
61553
|
+
}
|
|
61554
|
+
return msg;
|
|
61555
|
+
}
|
|
61556
|
+
if (async) {
|
|
61557
|
+
return Promise.reject(e);
|
|
61558
|
+
}
|
|
61559
|
+
throw e;
|
|
61560
|
+
};
|
|
61349
61561
|
}
|
|
61350
|
-
throw error;
|
|
61351
|
-
}
|
|
61352
|
-
if (aborted) break;
|
|
61353
|
-
const assistantMessage = {
|
|
61354
|
-
role: "assistant",
|
|
61355
|
-
content: contentBlocks
|
|
61356
61562
|
};
|
|
61357
|
-
|
|
61358
|
-
|
|
61359
|
-
(
|
|
61360
|
-
|
|
61361
|
-
|
|
61362
|
-
|
|
61363
|
-
options2.onProgress?.({ type: "turn_end", turnIndex, stopReason });
|
|
61364
|
-
turnIndex++;
|
|
61365
|
-
break;
|
|
61366
|
-
}
|
|
61367
|
-
const toolResults = await executeTools(
|
|
61368
|
-
toolUseBlocks,
|
|
61369
|
-
toolMap,
|
|
61370
|
-
options2
|
|
61371
|
-
);
|
|
61372
|
-
const toolResultMessage = {
|
|
61373
|
-
role: "user",
|
|
61374
|
-
content: toolResults.map((r) => ({
|
|
61375
|
-
type: "tool_result",
|
|
61376
|
-
tool_use_id: r.toolUseId,
|
|
61377
|
-
content: r.error ?? (typeof r.data === "string" ? r.data : JSON.stringify(r.data)),
|
|
61378
|
-
is_error: r.isError
|
|
61379
|
-
}))
|
|
61563
|
+
markedInstance = new Marked();
|
|
61564
|
+
marked.options = marked.setOptions = function(options2) {
|
|
61565
|
+
markedInstance.setOptions(options2);
|
|
61566
|
+
marked.defaults = markedInstance.defaults;
|
|
61567
|
+
changeDefaults(marked.defaults);
|
|
61568
|
+
return marked;
|
|
61380
61569
|
};
|
|
61381
|
-
|
|
61382
|
-
|
|
61383
|
-
|
|
61384
|
-
|
|
61385
|
-
|
|
61386
|
-
|
|
61387
|
-
|
|
61388
|
-
|
|
61389
|
-
|
|
61390
|
-
|
|
61391
|
-
|
|
61392
|
-
|
|
61393
|
-
|
|
61394
|
-
|
|
61395
|
-
|
|
61396
|
-
|
|
61397
|
-
|
|
61398
|
-
|
|
61399
|
-
|
|
61400
|
-
|
|
61401
|
-
|
|
61402
|
-
|
|
61403
|
-
|
|
61404
|
-
|
|
61405
|
-
|
|
61406
|
-
|
|
61407
|
-
|
|
61408
|
-
|
|
61409
|
-
if (handler.isConcurrencySafe) {
|
|
61410
|
-
concurrentTools.push({ block: block2, handler });
|
|
61411
|
-
} else {
|
|
61412
|
-
sequentialTools.push({ block: block2, handler });
|
|
61413
|
-
}
|
|
61414
|
-
}
|
|
61415
|
-
if (concurrentTools.length > 0) {
|
|
61416
|
-
const concurrentResults = await Promise.all(
|
|
61417
|
-
concurrentTools.map(
|
|
61418
|
-
({ block: block2, handler }) => executeSingleTool(block2, handler, options2)
|
|
61419
|
-
)
|
|
61420
|
-
);
|
|
61421
|
-
results.push(...concurrentResults);
|
|
61422
|
-
}
|
|
61423
|
-
for (const { block: block2, handler } of sequentialTools) {
|
|
61424
|
-
if (options2.signal?.aborted) break;
|
|
61425
|
-
const result = await executeSingleTool(block2, handler, options2);
|
|
61426
|
-
results.push(result);
|
|
61427
|
-
}
|
|
61428
|
-
return results;
|
|
61429
|
-
}
|
|
61430
|
-
async function executeSingleTool(block2, handler, options2) {
|
|
61431
|
-
const { id: toolUseId, name: toolName, input } = block2;
|
|
61432
|
-
options2.onProgress?.({ type: "tool_execution", toolName, toolUseId });
|
|
61433
|
-
const parseFailed = block2._inputParseFailed;
|
|
61434
|
-
if (parseFailed) {
|
|
61435
|
-
const rawJson = block2._rawInputJson;
|
|
61436
|
-
const error = `Tool input not fully received \u2014 JSON parsing failed for ${toolName}. Partial input (${rawJson?.length ?? 0} chars) could not be parsed. This is a streaming issue; retrying the request should resolve it.`;
|
|
61437
|
-
options2.onToolUseRejected?.(toolName, toolUseId, error);
|
|
61438
|
-
return { toolUseId, toolName, error, isError: true };
|
|
61439
|
-
}
|
|
61440
|
-
if (input && Object.keys(input).length === 0 && handler.inputSchema && Array.isArray(handler.inputSchema.required) && (handler.inputSchema.required ?? []).length > 0) {
|
|
61441
|
-
const error = `Tool input not fully received \u2014 ${toolName} requires parameters (${(handler.inputSchema.required ?? []).join(", ")}) but received empty input {}. Skipping execution to prevent undefined behavior.`;
|
|
61442
|
-
options2.onToolUseRejected?.(toolName, toolUseId, error);
|
|
61443
|
-
return { toolUseId, toolName, error, isError: true };
|
|
61444
|
-
}
|
|
61445
|
-
options2.onToolUseStart?.(toolName, toolUseId, input);
|
|
61446
|
-
try {
|
|
61447
|
-
if (options2.onPermissionCheck) {
|
|
61448
|
-
const permResult = await options2.onPermissionCheck(toolName, input);
|
|
61449
|
-
if (permResult.behavior === "deny") {
|
|
61450
|
-
const reason = permResult.message ?? "Permission denied";
|
|
61451
|
-
options2.onToolUseRejected?.(toolName, toolUseId, reason);
|
|
61452
|
-
return { toolUseId, toolName, error: reason, isError: true };
|
|
61453
|
-
}
|
|
61454
|
-
}
|
|
61455
|
-
if (handler.validateInput) {
|
|
61456
|
-
const validation = await handler.validateInput(input);
|
|
61457
|
-
if (!validation.result) {
|
|
61458
|
-
const error = validation.message ?? "Invalid input";
|
|
61459
|
-
return { toolUseId, toolName, error, isError: true };
|
|
61460
|
-
}
|
|
61461
|
-
}
|
|
61462
|
-
const result = await handler.call(input, {
|
|
61463
|
-
abortSignal: options2.signal,
|
|
61464
|
-
agentId: options2.agentId,
|
|
61465
|
-
toolUseId
|
|
61466
|
-
});
|
|
61467
|
-
options2.onToolUseEnd?.(toolName, toolUseId, result);
|
|
61468
|
-
if (result.isError || result.error) {
|
|
61469
|
-
return { toolUseId, toolName, error: result.error, isError: true };
|
|
61470
|
-
}
|
|
61471
|
-
return { toolUseId, toolName, data: result.data };
|
|
61472
|
-
} catch (error) {
|
|
61473
|
-
const errorMsg = errorToString(error);
|
|
61474
|
-
options2.onToolUseEnd?.(toolName, toolUseId, { error: errorMsg, isError: true });
|
|
61475
|
-
return { toolUseId, toolName, error: errorMsg, isError: true };
|
|
61476
|
-
}
|
|
61477
|
-
}
|
|
61478
|
-
function buildToolDefinitions(tools) {
|
|
61479
|
-
return tools.map((t) => ({
|
|
61480
|
-
name: t.name,
|
|
61481
|
-
description: t.description,
|
|
61482
|
-
input_schema: t.inputSchema
|
|
61483
|
-
}));
|
|
61484
|
-
}
|
|
61485
|
-
var DEFAULT_MAX_TURNS;
|
|
61486
|
-
var init_agent_loop = __esm({
|
|
61487
|
-
"src/core/agent-loop.ts"() {
|
|
61488
|
-
"use strict";
|
|
61489
|
-
init_api();
|
|
61490
|
-
init_errors2();
|
|
61491
|
-
DEFAULT_MAX_TURNS = 100;
|
|
61492
|
-
}
|
|
61493
|
-
});
|
|
61494
|
-
|
|
61495
|
-
// src/config/permissions.ts
|
|
61496
|
-
function createDefaultPermissionContext(settings) {
|
|
61497
|
-
const defaultMode = settings?.permissions?.defaultMode ?? "default";
|
|
61498
|
-
return {
|
|
61499
|
-
mode: defaultMode,
|
|
61500
|
-
allowRules: settings?.permissions?.allow ?? [],
|
|
61501
|
-
denyRules: settings?.permissions?.deny ?? []
|
|
61502
|
-
};
|
|
61503
|
-
}
|
|
61504
|
-
var init_permissions = __esm({
|
|
61505
|
-
"src/config/permissions.ts"() {
|
|
61506
|
-
"use strict";
|
|
61570
|
+
marked.getDefaults = _getDefaults;
|
|
61571
|
+
marked.defaults = _defaults;
|
|
61572
|
+
marked.use = function(...args) {
|
|
61573
|
+
markedInstance.use(...args);
|
|
61574
|
+
marked.defaults = markedInstance.defaults;
|
|
61575
|
+
changeDefaults(marked.defaults);
|
|
61576
|
+
return marked;
|
|
61577
|
+
};
|
|
61578
|
+
marked.walkTokens = function(tokens, callback) {
|
|
61579
|
+
return markedInstance.walkTokens(tokens, callback);
|
|
61580
|
+
};
|
|
61581
|
+
marked.parseInline = markedInstance.parseInline;
|
|
61582
|
+
marked.Parser = _Parser;
|
|
61583
|
+
marked.parser = _Parser.parse;
|
|
61584
|
+
marked.Renderer = _Renderer;
|
|
61585
|
+
marked.TextRenderer = _TextRenderer;
|
|
61586
|
+
marked.Lexer = _Lexer;
|
|
61587
|
+
marked.lexer = _Lexer.lex;
|
|
61588
|
+
marked.Tokenizer = _Tokenizer;
|
|
61589
|
+
marked.Hooks = _Hooks;
|
|
61590
|
+
marked.parse = marked;
|
|
61591
|
+
options = marked.options;
|
|
61592
|
+
setOptions = marked.setOptions;
|
|
61593
|
+
use = marked.use;
|
|
61594
|
+
walkTokens = marked.walkTokens;
|
|
61595
|
+
parseInline = marked.parseInline;
|
|
61596
|
+
parser = _Parser.parse;
|
|
61597
|
+
lexer = _Lexer.lex;
|
|
61507
61598
|
}
|
|
61508
61599
|
});
|
|
61509
61600
|
|
|
61510
|
-
// src/
|
|
61511
|
-
|
|
61512
|
-
|
|
61513
|
-
|
|
61514
|
-
|
|
61515
|
-
if (!existsSync4(dir)) mkdirSync3(dir, { recursive: true });
|
|
61516
|
-
return join2(dir, "coders.db");
|
|
61601
|
+
// src/ui/components/markdown.tsx
|
|
61602
|
+
function renderMarkdown(markdown, maxWidth = 120) {
|
|
61603
|
+
const lexer2 = new _Lexer();
|
|
61604
|
+
const tokens = lexer2.lex(markdown);
|
|
61605
|
+
return renderTokens(tokens, maxWidth);
|
|
61517
61606
|
}
|
|
61518
|
-
function
|
|
61519
|
-
|
|
61520
|
-
const
|
|
61521
|
-
|
|
61522
|
-
|
|
61523
|
-
|
|
61524
|
-
|
|
61525
|
-
|
|
61526
|
-
|
|
61527
|
-
|
|
61528
|
-
|
|
61529
|
-
|
|
61530
|
-
|
|
61531
|
-
|
|
61607
|
+
function renderTokens(tokens, maxWidth) {
|
|
61608
|
+
const lines = [];
|
|
61609
|
+
for (const token of tokens) {
|
|
61610
|
+
switch (token.type) {
|
|
61611
|
+
case "heading":
|
|
61612
|
+
lines.push(renderHeading(token));
|
|
61613
|
+
lines.push("");
|
|
61614
|
+
break;
|
|
61615
|
+
case "paragraph":
|
|
61616
|
+
lines.push(renderInline(token.text));
|
|
61617
|
+
lines.push("");
|
|
61618
|
+
break;
|
|
61619
|
+
case "code":
|
|
61620
|
+
lines.push(...renderCodeBlock(token, maxWidth));
|
|
61621
|
+
lines.push("");
|
|
61622
|
+
break;
|
|
61623
|
+
case "list":
|
|
61624
|
+
lines.push(...renderList(token));
|
|
61625
|
+
lines.push("");
|
|
61626
|
+
break;
|
|
61627
|
+
case "blockquote":
|
|
61628
|
+
lines.push(...renderBlockquote(token));
|
|
61629
|
+
lines.push("");
|
|
61630
|
+
break;
|
|
61631
|
+
case "table":
|
|
61632
|
+
lines.push(...renderTable(token, maxWidth));
|
|
61633
|
+
lines.push("");
|
|
61634
|
+
break;
|
|
61635
|
+
case "hr":
|
|
61636
|
+
lines.push(`${FG_GRAY}${"\u2500".repeat(Math.min(maxWidth, 60))}${FG_DEFAULT}`);
|
|
61637
|
+
lines.push("");
|
|
61638
|
+
break;
|
|
61639
|
+
case "space":
|
|
61640
|
+
lines.push("");
|
|
61641
|
+
break;
|
|
61642
|
+
case "html":
|
|
61643
|
+
lines.push(renderInline(token.text.replace(/<[^>]+>/g, "")));
|
|
61644
|
+
break;
|
|
61645
|
+
default:
|
|
61646
|
+
if ("text" in token) {
|
|
61647
|
+
lines.push(renderInline(String(token.text)));
|
|
61648
|
+
}
|
|
61649
|
+
break;
|
|
61532
61650
|
}
|
|
61533
61651
|
}
|
|
61534
|
-
|
|
61535
|
-
|
|
61536
|
-
|
|
61652
|
+
return lines.join("\n");
|
|
61653
|
+
}
|
|
61654
|
+
function renderHeading(token) {
|
|
61655
|
+
const color = token.depth <= 2 ? FG_CYAN : FG_BLUE;
|
|
61656
|
+
const prefix = `${BOLD}${color}`;
|
|
61657
|
+
const marker = "#".repeat(token.depth);
|
|
61658
|
+
const inner = renderInlineWithRestore(token.text, prefix);
|
|
61659
|
+
return `${prefix}${marker} ${inner}${RESET}`;
|
|
61660
|
+
}
|
|
61661
|
+
function renderCodeBlock(token, maxWidth) {
|
|
61662
|
+
const lines = [];
|
|
61663
|
+
const lang = token.lang ?? "";
|
|
61664
|
+
if (lang) {
|
|
61665
|
+
lines.push(`${FG_GRAY}\u250C\u2500 ${lang} ${"\u2500".repeat(Math.max(0, Math.min(maxWidth, 60) - lang.length - 4))}${FG_DEFAULT}`);
|
|
61666
|
+
} else {
|
|
61667
|
+
lines.push(`${FG_GRAY}\u250C${"\u2500".repeat(Math.min(maxWidth, 60) - 1)}${FG_DEFAULT}`);
|
|
61537
61668
|
}
|
|
61538
|
-
|
|
61539
|
-
|
|
61540
|
-
|
|
61669
|
+
for (const line of token.text.split("\n")) {
|
|
61670
|
+
const highlighted = lang ? highlightSyntax(line, lang) : `${FG_GREEN}${line}${FG_DEFAULT}`;
|
|
61671
|
+
lines.push(`${FG_GRAY}\u2502${FG_DEFAULT} ${highlighted}`);
|
|
61541
61672
|
}
|
|
61542
|
-
|
|
61543
|
-
return
|
|
61673
|
+
lines.push(`${FG_GRAY}\u2514${"\u2500".repeat(Math.min(maxWidth, 60) - 1)}${FG_DEFAULT}`);
|
|
61674
|
+
return lines;
|
|
61544
61675
|
}
|
|
61545
|
-
function
|
|
61546
|
-
|
|
61547
|
-
|
|
61548
|
-
|
|
61549
|
-
|
|
61550
|
-
|
|
61551
|
-
|
|
61552
|
-
|
|
61553
|
-
|
|
61554
|
-
|
|
61555
|
-
|
|
61556
|
-
|
|
61557
|
-
|
|
61558
|
-
|
|
61559
|
-
|
|
61560
|
-
|
|
61561
|
-
|
|
61562
|
-
|
|
61563
|
-
|
|
61564
|
-
|
|
61565
|
-
|
|
61566
|
-
|
|
61567
|
-
|
|
61568
|
-
|
|
61569
|
-
|
|
61570
|
-
|
|
61571
|
-
|
|
61572
|
-
|
|
61573
|
-
|
|
61574
|
-
|
|
61575
|
-
|
|
61576
|
-
|
|
61577
|
-
|
|
61578
|
-
|
|
61579
|
-
|
|
61580
|
-
|
|
61581
|
-
|
|
61582
|
-
|
|
61583
|
-
|
|
61584
|
-
|
|
61585
|
-
|
|
61586
|
-
|
|
61587
|
-
|
|
61588
|
-
);
|
|
61589
|
-
|
|
61590
|
-
|
|
61591
|
-
|
|
61592
|
-
|
|
61593
|
-
|
|
61594
|
-
|
|
61595
|
-
|
|
61596
|
-
|
|
61597
|
-
|
|
61598
|
-
|
|
61599
|
-
|
|
61600
|
-
|
|
61601
|
-
|
|
61602
|
-
|
|
61603
|
-
|
|
61604
|
-
|
|
61605
|
-
|
|
61606
|
-
|
|
61607
|
-
|
|
61608
|
-
|
|
61609
|
-
|
|
61610
|
-
|
|
61611
|
-
|
|
61612
|
-
|
|
61613
|
-
|
|
61614
|
-
|
|
61615
|
-
|
|
61616
|
-
|
|
61617
|
-
|
|
61618
|
-
|
|
61619
|
-
value TEXT, -- JSON
|
|
61620
|
-
scope TEXT DEFAULT 'user' CHECK(scope IN ('user','project','local','global')),
|
|
61621
|
-
updated_at TEXT DEFAULT (datetime('now'))
|
|
61622
|
-
);
|
|
61623
|
-
|
|
61624
|
-
-- Memories (replaces in-memory fallback for @hasna/mementos)
|
|
61625
|
-
CREATE TABLE IF NOT EXISTS memories (
|
|
61626
|
-
id TEXT PRIMARY KEY,
|
|
61627
|
-
key TEXT UNIQUE NOT NULL,
|
|
61628
|
-
value TEXT NOT NULL,
|
|
61629
|
-
scope TEXT DEFAULT 'shared' CHECK(scope IN ('global','shared','private')),
|
|
61630
|
-
category TEXT DEFAULT 'knowledge',
|
|
61631
|
-
importance INTEGER DEFAULT 5 CHECK(importance BETWEEN 1 AND 10),
|
|
61632
|
-
tags TEXT DEFAULT '[]', -- JSON array
|
|
61633
|
-
version INTEGER DEFAULT 1,
|
|
61634
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
61635
|
-
updated_at TEXT DEFAULT (datetime('now'))
|
|
61636
|
-
);
|
|
61637
|
-
|
|
61638
|
-
-- Teams
|
|
61639
|
-
CREATE TABLE IF NOT EXISTS teams (
|
|
61640
|
-
name TEXT PRIMARY KEY,
|
|
61641
|
-
description TEXT,
|
|
61642
|
-
task_list_id TEXT,
|
|
61643
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
61644
|
-
);
|
|
61645
|
-
|
|
61646
|
-
-- Team members
|
|
61647
|
-
CREATE TABLE IF NOT EXISTS team_members (
|
|
61648
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
61649
|
-
team_name TEXT NOT NULL REFERENCES teams(name),
|
|
61650
|
-
agent_name TEXT NOT NULL,
|
|
61651
|
-
role TEXT,
|
|
61652
|
-
status TEXT DEFAULT 'idle',
|
|
61653
|
-
current_task TEXT,
|
|
61654
|
-
UNIQUE(team_name, agent_name)
|
|
61655
|
-
);
|
|
61656
|
-
|
|
61657
|
-
-- Team messages
|
|
61658
|
-
CREATE TABLE IF NOT EXISTS team_messages (
|
|
61659
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
61660
|
-
from_agent TEXT NOT NULL,
|
|
61661
|
-
to_agent TEXT NOT NULL,
|
|
61662
|
-
team_name TEXT,
|
|
61663
|
-
content TEXT NOT NULL,
|
|
61664
|
-
is_read INTEGER DEFAULT 0,
|
|
61665
|
-
is_blocking INTEGER DEFAULT 0,
|
|
61666
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
61667
|
-
);
|
|
61668
|
-
CREATE INDEX IF NOT EXISTS idx_team_msgs_to ON team_messages(to_agent, is_read);
|
|
61669
|
-
|
|
61670
|
-
-- Permissions (persisted allow/deny rules)
|
|
61671
|
-
CREATE TABLE IF NOT EXISTS permissions (
|
|
61672
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
61673
|
-
tool_name TEXT,
|
|
61674
|
-
command_pattern TEXT,
|
|
61675
|
-
path_pattern TEXT,
|
|
61676
|
-
behavior TEXT NOT NULL CHECK(behavior IN ('allow','deny')),
|
|
61677
|
-
scope TEXT DEFAULT 'session',
|
|
61678
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
61679
|
-
);
|
|
61680
|
-
|
|
61681
|
-
-- MCP servers
|
|
61682
|
-
CREATE TABLE IF NOT EXISTS mcp_servers (
|
|
61683
|
-
name TEXT PRIMARY KEY,
|
|
61684
|
-
command TEXT,
|
|
61685
|
-
args TEXT, -- JSON array
|
|
61686
|
-
env TEXT, -- JSON object
|
|
61687
|
-
url TEXT,
|
|
61688
|
-
transport TEXT DEFAULT 'stdio',
|
|
61689
|
-
scope TEXT DEFAULT 'user',
|
|
61690
|
-
enabled INTEGER DEFAULT 1,
|
|
61691
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
61676
|
+
function renderList(token) {
|
|
61677
|
+
const lines = [];
|
|
61678
|
+
const ordered = token.ordered;
|
|
61679
|
+
for (let i = 0; i < token.items.length; i++) {
|
|
61680
|
+
const item = token.items[i];
|
|
61681
|
+
const marker = ordered ? `${FG_YELLOW}${i + 1}.${FG_DEFAULT}` : `${FG_YELLOW}\u2022${FG_DEFAULT}`;
|
|
61682
|
+
const text = renderInline(item.text);
|
|
61683
|
+
lines.push(` ${marker} ${text}`);
|
|
61684
|
+
if (item.tokens) {
|
|
61685
|
+
for (const subToken of item.tokens) {
|
|
61686
|
+
if (subToken.type === "list") {
|
|
61687
|
+
const subLines = renderList(subToken);
|
|
61688
|
+
lines.push(...subLines.map((l) => ` ${l}`));
|
|
61689
|
+
}
|
|
61690
|
+
}
|
|
61691
|
+
}
|
|
61692
|
+
}
|
|
61693
|
+
return lines;
|
|
61694
|
+
}
|
|
61695
|
+
function renderBlockquote(token) {
|
|
61696
|
+
const inner = renderTokens(token.tokens, 100);
|
|
61697
|
+
return inner.split("\n").map((line) => `${FG_GRAY}\u2502${FG_DEFAULT} ${DIM}${line}${DIM_OFF}`);
|
|
61698
|
+
}
|
|
61699
|
+
function renderTable(token, maxWidth) {
|
|
61700
|
+
const lines = [];
|
|
61701
|
+
const colWidths = token.header.map((h) => h.text.length);
|
|
61702
|
+
for (const row of token.rows) {
|
|
61703
|
+
for (let i = 0; i < row.length; i++) {
|
|
61704
|
+
colWidths[i] = Math.max(colWidths[i] ?? 0, row[i].text.length);
|
|
61705
|
+
}
|
|
61706
|
+
}
|
|
61707
|
+
const totalWidth = colWidths.reduce((a, b) => a + b, 0) + colWidths.length * 3 + 1;
|
|
61708
|
+
if (totalWidth > maxWidth) {
|
|
61709
|
+
const scale = maxWidth / totalWidth;
|
|
61710
|
+
for (let i = 0; i < colWidths.length; i++) {
|
|
61711
|
+
colWidths[i] = Math.max(3, Math.floor(colWidths[i] * scale));
|
|
61712
|
+
}
|
|
61713
|
+
}
|
|
61714
|
+
const headerLine = token.header.map((h, i) => pad(h.text, colWidths[i])).join(` ${FG_GRAY}\u2502${FG_DEFAULT} `);
|
|
61715
|
+
lines.push(`${BOLD}${headerLine}${BOLD_OFF}`);
|
|
61716
|
+
const sepLine = colWidths.map((w) => "\u2500".repeat(w)).join(`\u2500\u253C\u2500`);
|
|
61717
|
+
lines.push(`${FG_GRAY}${sepLine}${FG_DEFAULT}`);
|
|
61718
|
+
for (const row of token.rows) {
|
|
61719
|
+
const rowLine = row.map((cell, i) => pad(cell.text, colWidths[i])).join(` ${FG_GRAY}\u2502${FG_DEFAULT} `);
|
|
61720
|
+
lines.push(rowLine);
|
|
61721
|
+
}
|
|
61722
|
+
return lines;
|
|
61723
|
+
}
|
|
61724
|
+
function renderInline(text) {
|
|
61725
|
+
return renderInlineWithRestore(text, "");
|
|
61726
|
+
}
|
|
61727
|
+
function renderInlineWithRestore(text, restore) {
|
|
61728
|
+
return text.replace(/\*\*(.+?)\*\*/g, `${BOLD}$1${BOLD_OFF}${restore}`).replace(/__(.+?)__/g, `${BOLD}$1${BOLD_OFF}${restore}`).replace(/\*(.+?)\*/g, `${ITALIC}$1${ITALIC_OFF}${restore}`).replace(/_(.+?)_/g, `${ITALIC}$1${ITALIC_OFF}${restore}`).replace(/~~(.+?)~~/g, `${STRIKETHROUGH}$1${STRIKE_OFF}${restore}`).replace(/`([^`]+)`/g, `${BG_GRAY}${FG_GREEN} $1 ${FG_DEFAULT}${BG_DEFAULT}${restore}`).replace(/\[([^\]]+)\]\(([^)]+)\)/g, `${UNDERLINE}${FG_BLUE}$1${UNDERLINE_OFF}${FG_DEFAULT}${FG_GRAY} ($2)${FG_DEFAULT}${restore}`).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"');
|
|
61729
|
+
}
|
|
61730
|
+
function highlightSyntax(line, lang) {
|
|
61731
|
+
const keywords = {
|
|
61732
|
+
typescript: ["import", "export", "from", "const", "let", "var", "function", "class", "interface", "type", "return", "if", "else", "for", "while", "async", "await", "new", "this", "extends", "implements"],
|
|
61733
|
+
javascript: ["import", "export", "from", "const", "let", "var", "function", "class", "return", "if", "else", "for", "while", "async", "await", "new", "this"],
|
|
61734
|
+
python: ["import", "from", "def", "class", "return", "if", "elif", "else", "for", "while", "with", "as", "try", "except", "finally", "raise", "yield", "async", "await", "self"],
|
|
61735
|
+
rust: ["fn", "let", "mut", "pub", "struct", "enum", "impl", "trait", "use", "mod", "return", "if", "else", "for", "while", "match", "self", "super", "crate"],
|
|
61736
|
+
go: ["func", "var", "const", "type", "struct", "interface", "return", "if", "else", "for", "range", "switch", "case", "package", "import", "defer", "go", "chan"]
|
|
61737
|
+
};
|
|
61738
|
+
const ts = keywords.typescript ?? [];
|
|
61739
|
+
const kw = keywords[lang] ?? keywords[lang.replace(/x$/, "")] ?? ts;
|
|
61740
|
+
let result = line;
|
|
61741
|
+
result = result.replace(/(\/\/.*$)/gm, `${FG_GRAY}$1${FG_DEFAULT}`);
|
|
61742
|
+
result = result.replace(/(#.*$)/gm, `${FG_GRAY}$1${FG_DEFAULT}`);
|
|
61743
|
+
result = result.replace(/("[^"]*")/g, `${FG_GREEN}$1${FG_DEFAULT}`);
|
|
61744
|
+
result = result.replace(/('[^']*')/g, `${FG_GREEN}$1${FG_DEFAULT}`);
|
|
61745
|
+
result = result.replace(/(`[^`]*`)/g, `${FG_GREEN}$1${FG_DEFAULT}`);
|
|
61746
|
+
for (const kwd of kw) {
|
|
61747
|
+
result = result.replace(
|
|
61748
|
+
new RegExp(`\\b(${kwd})\\b`, "g"),
|
|
61749
|
+
`${FG_MAGENTA}$1${FG_DEFAULT}`
|
|
61692
61750
|
);
|
|
61751
|
+
}
|
|
61752
|
+
result = result.replace(/\b(\d+\.?\d*)\b/g, `${FG_YELLOW}$1${FG_DEFAULT}`);
|
|
61753
|
+
return result;
|
|
61754
|
+
}
|
|
61755
|
+
function pad(text, width) {
|
|
61756
|
+
if (text.length >= width) return text.slice(0, width);
|
|
61757
|
+
return text + " ".repeat(width - text.length);
|
|
61758
|
+
}
|
|
61759
|
+
var ESC2, RESET, BOLD, BOLD_OFF, DIM, DIM_OFF, ITALIC, ITALIC_OFF, UNDERLINE, UNDERLINE_OFF, STRIKETHROUGH, STRIKE_OFF, FG_CYAN, FG_YELLOW, FG_GREEN, FG_BLUE, FG_MAGENTA, FG_GRAY, FG_DEFAULT, BG_GRAY, BG_DEFAULT;
|
|
61760
|
+
var init_markdown = __esm({
|
|
61761
|
+
"src/ui/components/markdown.tsx"() {
|
|
61762
|
+
"use strict";
|
|
61763
|
+
init_marked_esm();
|
|
61764
|
+
ESC2 = "\x1B[";
|
|
61765
|
+
RESET = `${ESC2}0m`;
|
|
61766
|
+
BOLD = `${ESC2}1m`;
|
|
61767
|
+
BOLD_OFF = `${ESC2}22m`;
|
|
61768
|
+
DIM = `${ESC2}2m`;
|
|
61769
|
+
DIM_OFF = `${ESC2}22m`;
|
|
61770
|
+
ITALIC = `${ESC2}3m`;
|
|
61771
|
+
ITALIC_OFF = `${ESC2}23m`;
|
|
61772
|
+
UNDERLINE = `${ESC2}4m`;
|
|
61773
|
+
UNDERLINE_OFF = `${ESC2}24m`;
|
|
61774
|
+
STRIKETHROUGH = `${ESC2}9m`;
|
|
61775
|
+
STRIKE_OFF = `${ESC2}29m`;
|
|
61776
|
+
FG_CYAN = `${ESC2}36m`;
|
|
61777
|
+
FG_YELLOW = `${ESC2}33m`;
|
|
61778
|
+
FG_GREEN = `${ESC2}32m`;
|
|
61779
|
+
FG_BLUE = `${ESC2}34m`;
|
|
61780
|
+
FG_MAGENTA = `${ESC2}35m`;
|
|
61781
|
+
FG_GRAY = `${ESC2}90m`;
|
|
61782
|
+
FG_DEFAULT = `${ESC2}39m`;
|
|
61783
|
+
BG_GRAY = `${ESC2}100m`;
|
|
61784
|
+
BG_DEFAULT = `${ESC2}49m`;
|
|
61785
|
+
}
|
|
61786
|
+
});
|
|
61693
61787
|
|
|
61694
|
-
|
|
61695
|
-
|
|
61696
|
-
|
|
61697
|
-
|
|
61698
|
-
|
|
61699
|
-
|
|
61700
|
-
|
|
61701
|
-
|
|
61702
|
-
|
|
61703
|
-
tool_duration_ms REAL DEFAULT 0,
|
|
61704
|
-
hook_duration_ms REAL DEFAULT 0,
|
|
61705
|
-
tool_count INTEGER DEFAULT 0,
|
|
61706
|
-
model TEXT,
|
|
61707
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
61708
|
-
);
|
|
61788
|
+
// src/api/index.ts
|
|
61789
|
+
var init_api = __esm({
|
|
61790
|
+
"src/api/index.ts"() {
|
|
61791
|
+
"use strict";
|
|
61792
|
+
init_client();
|
|
61793
|
+
init_models();
|
|
61794
|
+
init_streaming();
|
|
61795
|
+
}
|
|
61796
|
+
});
|
|
61709
61797
|
|
|
61710
|
-
|
|
61711
|
-
|
|
61712
|
-
|
|
61713
|
-
|
|
61714
|
-
|
|
61715
|
-
input_summary TEXT,
|
|
61716
|
-
result_summary TEXT,
|
|
61717
|
-
exit_code INTEGER,
|
|
61718
|
-
duration_ms REAL,
|
|
61719
|
-
was_allowed INTEGER DEFAULT 1,
|
|
61720
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
61721
|
-
);
|
|
61722
|
-
`);
|
|
61798
|
+
// src/core/errors.ts
|
|
61799
|
+
function errorToString(err) {
|
|
61800
|
+
if (err instanceof Error) return err.message;
|
|
61801
|
+
if (typeof err === "string") return err;
|
|
61802
|
+
return String(err);
|
|
61723
61803
|
}
|
|
61724
|
-
|
|
61725
|
-
|
|
61726
|
-
|
|
61727
|
-
|
|
61728
|
-
|
|
61729
|
-
|
|
61804
|
+
var init_errors2 = __esm({
|
|
61805
|
+
"src/core/errors.ts"() {
|
|
61806
|
+
"use strict";
|
|
61807
|
+
}
|
|
61808
|
+
});
|
|
61809
|
+
|
|
61810
|
+
// src/core/agent-loop.ts
|
|
61811
|
+
async function runAgentLoop(initialMessages, options2) {
|
|
61812
|
+
const client = options2.client ?? getApiClient();
|
|
61813
|
+
const messages = [...initialMessages];
|
|
61814
|
+
const maxTurns = options2.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
61815
|
+
let totalInputTokens = 0;
|
|
61816
|
+
let totalOutputTokens = 0;
|
|
61817
|
+
let turnIndex = 0;
|
|
61818
|
+
let aborted = false;
|
|
61819
|
+
const toolDefs = buildToolDefinitions(options2.tools);
|
|
61820
|
+
const toolMap = new Map(options2.tools.map((t) => [t.name, t]));
|
|
61821
|
+
while (turnIndex < maxTurns) {
|
|
61822
|
+
if (options2.signal?.aborted) {
|
|
61823
|
+
aborted = true;
|
|
61824
|
+
break;
|
|
61825
|
+
}
|
|
61826
|
+
options2.onProgress?.({ type: "turn_start", turnIndex });
|
|
61827
|
+
const request = {
|
|
61828
|
+
model: options2.model,
|
|
61829
|
+
messages,
|
|
61830
|
+
systemPrompt: options2.systemPrompt,
|
|
61831
|
+
tools: toolDefs.length > 0 ? toolDefs : void 0,
|
|
61832
|
+
thinkingConfig: options2.thinkingConfig,
|
|
61833
|
+
maxTokens: options2.maxTokens,
|
|
61834
|
+
stream: true,
|
|
61835
|
+
signal: options2.signal,
|
|
61836
|
+
querySource: options2.querySource
|
|
61837
|
+
};
|
|
61838
|
+
options2.onProgress?.({ type: "streaming", turnIndex });
|
|
61839
|
+
const contentBlocks = [];
|
|
61840
|
+
let stopReason = null;
|
|
61730
61841
|
try {
|
|
61731
|
-
|
|
61732
|
-
|
|
61733
|
-
|
|
61842
|
+
for await (const item of client.streamMessage(request)) {
|
|
61843
|
+
if (options2.signal?.aborted) {
|
|
61844
|
+
aborted = true;
|
|
61845
|
+
break;
|
|
61846
|
+
}
|
|
61847
|
+
const { event, accumulated } = item;
|
|
61848
|
+
if (event.type === "content_block_delta" && event.delta) {
|
|
61849
|
+
if (event.delta.type === "text_delta") {
|
|
61850
|
+
options2.onTextDelta?.(event.delta.text);
|
|
61851
|
+
} else if (event.delta.type === "thinking_delta") {
|
|
61852
|
+
options2.onThinkingDelta?.(event.delta.thinking);
|
|
61853
|
+
}
|
|
61854
|
+
}
|
|
61855
|
+
if (event.type === "message_stop" || event.type === "message_delta") {
|
|
61856
|
+
if (accumulated.content) {
|
|
61857
|
+
contentBlocks.length = 0;
|
|
61858
|
+
contentBlocks.push(...accumulated.content);
|
|
61859
|
+
}
|
|
61860
|
+
stopReason = accumulated.stopReason ?? null;
|
|
61861
|
+
if (accumulated.usage) {
|
|
61862
|
+
totalInputTokens += accumulated.usage.inputTokens;
|
|
61863
|
+
totalOutputTokens += accumulated.usage.outputTokens;
|
|
61864
|
+
}
|
|
61865
|
+
}
|
|
61866
|
+
}
|
|
61867
|
+
} catch (error) {
|
|
61868
|
+
if (error.name === "AbortError") {
|
|
61869
|
+
aborted = true;
|
|
61870
|
+
break;
|
|
61871
|
+
}
|
|
61872
|
+
throw error;
|
|
61873
|
+
}
|
|
61874
|
+
if (aborted) break;
|
|
61875
|
+
const assistantMessage = {
|
|
61876
|
+
role: "assistant",
|
|
61877
|
+
content: contentBlocks
|
|
61878
|
+
};
|
|
61879
|
+
messages.push(assistantMessage);
|
|
61880
|
+
const toolUseBlocks = contentBlocks.filter(
|
|
61881
|
+
(b) => b.type === "tool_use"
|
|
61882
|
+
);
|
|
61883
|
+
if (toolUseBlocks.length === 0 || stopReason === "end_turn") {
|
|
61884
|
+
options2.onTurnComplete?.(turnIndex, assistantMessage);
|
|
61885
|
+
options2.onProgress?.({ type: "turn_end", turnIndex, stopReason });
|
|
61886
|
+
turnIndex++;
|
|
61887
|
+
break;
|
|
61734
61888
|
}
|
|
61889
|
+
const toolResults = await executeTools(
|
|
61890
|
+
toolUseBlocks,
|
|
61891
|
+
toolMap,
|
|
61892
|
+
options2
|
|
61893
|
+
);
|
|
61894
|
+
const toolResultMessage = {
|
|
61895
|
+
role: "user",
|
|
61896
|
+
content: toolResults.map((r) => ({
|
|
61897
|
+
type: "tool_result",
|
|
61898
|
+
tool_use_id: r.toolUseId,
|
|
61899
|
+
content: r.error ?? (typeof r.data === "string" ? r.data : JSON.stringify(r.data)),
|
|
61900
|
+
is_error: r.isError
|
|
61901
|
+
}))
|
|
61902
|
+
};
|
|
61903
|
+
messages.push(toolResultMessage);
|
|
61904
|
+
options2.onTurnComplete?.(turnIndex, assistantMessage);
|
|
61905
|
+
options2.onProgress?.({ type: "turn_end", turnIndex, stopReason });
|
|
61906
|
+
turnIndex++;
|
|
61735
61907
|
}
|
|
61908
|
+
options2.onProgress?.({ type: "loop_end", totalTurns: turnIndex });
|
|
61909
|
+
return {
|
|
61910
|
+
messages,
|
|
61911
|
+
totalTurns: turnIndex,
|
|
61912
|
+
aborted,
|
|
61913
|
+
usage: { totalInputTokens, totalOutputTokens }
|
|
61914
|
+
};
|
|
61736
61915
|
}
|
|
61737
|
-
function
|
|
61738
|
-
const
|
|
61739
|
-
|
|
61740
|
-
|
|
61741
|
-
|
|
61742
|
-
|
|
61743
|
-
|
|
61744
|
-
|
|
61916
|
+
async function executeTools(toolUseBlocks, toolMap, options2) {
|
|
61917
|
+
const results = [];
|
|
61918
|
+
const concurrentTools = [];
|
|
61919
|
+
const sequentialTools = [];
|
|
61920
|
+
for (const block2 of toolUseBlocks) {
|
|
61921
|
+
const handler = toolMap.get(block2.name);
|
|
61922
|
+
if (!handler) {
|
|
61923
|
+
results.push({
|
|
61924
|
+
toolUseId: block2.id,
|
|
61925
|
+
toolName: block2.name,
|
|
61926
|
+
error: `Unknown tool: ${block2.name}`,
|
|
61927
|
+
isError: true
|
|
61928
|
+
});
|
|
61929
|
+
continue;
|
|
61745
61930
|
}
|
|
61746
|
-
|
|
61747
|
-
|
|
61748
|
-
|
|
61749
|
-
|
|
61750
|
-
writeFileSync2(storePath, JSON.stringify(store), "utf-8");
|
|
61751
|
-
} catch {
|
|
61931
|
+
if (handler.isConcurrencySafe) {
|
|
61932
|
+
concurrentTools.push({ block: block2, handler });
|
|
61933
|
+
} else {
|
|
61934
|
+
sequentialTools.push({ block: block2, handler });
|
|
61752
61935
|
}
|
|
61753
61936
|
}
|
|
61754
|
-
|
|
61755
|
-
|
|
61756
|
-
|
|
61757
|
-
|
|
61758
|
-
|
|
61937
|
+
if (concurrentTools.length > 0) {
|
|
61938
|
+
const concurrentResults = await Promise.all(
|
|
61939
|
+
concurrentTools.map(
|
|
61940
|
+
({ block: block2, handler }) => executeSingleTool(block2, handler, options2)
|
|
61941
|
+
)
|
|
61942
|
+
);
|
|
61943
|
+
results.push(...concurrentResults);
|
|
61759
61944
|
}
|
|
61760
|
-
|
|
61761
|
-
|
|
61945
|
+
for (const { block: block2, handler } of sequentialTools) {
|
|
61946
|
+
if (options2.signal?.aborted) break;
|
|
61947
|
+
const result = await executeSingleTool(block2, handler, options2);
|
|
61948
|
+
results.push(result);
|
|
61762
61949
|
}
|
|
61763
|
-
|
|
61764
|
-
|
|
61765
|
-
|
|
61766
|
-
|
|
61767
|
-
|
|
61768
|
-
|
|
61769
|
-
|
|
61770
|
-
const
|
|
61771
|
-
|
|
61772
|
-
|
|
61773
|
-
|
|
61774
|
-
if (ph === "?") {
|
|
61775
|
-
row[cols[i]] = params[paramIdx++];
|
|
61776
|
-
} else if (/^datetime\(/i.test(ph)) {
|
|
61777
|
-
row[cols[i]] = now();
|
|
61778
|
-
} else {
|
|
61779
|
-
row[cols[i]] = ph.replace(/^['"]|['"]$/g, "");
|
|
61780
|
-
}
|
|
61781
|
-
}
|
|
61782
|
-
if (!row["id"] && store.autoInc[table] !== void 0) {
|
|
61783
|
-
store.autoInc[table]++;
|
|
61784
|
-
row["id"] = store.autoInc[table];
|
|
61785
|
-
}
|
|
61786
|
-
store.tables[table].push(row);
|
|
61787
|
-
flush();
|
|
61788
|
-
return { changes: 1, lastInsertRowid: typeof row["id"] === "number" ? row["id"] : 0 };
|
|
61950
|
+
return results;
|
|
61951
|
+
}
|
|
61952
|
+
async function executeSingleTool(block2, handler, options2) {
|
|
61953
|
+
const { id: toolUseId, name: toolName, input } = block2;
|
|
61954
|
+
options2.onProgress?.({ type: "tool_execution", toolName, toolUseId });
|
|
61955
|
+
const parseFailed = block2._inputParseFailed;
|
|
61956
|
+
if (parseFailed) {
|
|
61957
|
+
const rawJson = block2._rawInputJson;
|
|
61958
|
+
const error = `Tool input not fully received \u2014 JSON parsing failed for ${toolName}. Partial input (${rawJson?.length ?? 0} chars) could not be parsed. This is a streaming issue; retrying the request should resolve it.`;
|
|
61959
|
+
options2.onToolUseRejected?.(toolName, toolUseId, error);
|
|
61960
|
+
return { toolUseId, toolName, error, isError: true };
|
|
61789
61961
|
}
|
|
61790
|
-
|
|
61791
|
-
const
|
|
61792
|
-
|
|
61793
|
-
|
|
61794
|
-
|
|
61795
|
-
|
|
61796
|
-
|
|
61797
|
-
|
|
61798
|
-
const
|
|
61799
|
-
if (
|
|
61800
|
-
const
|
|
61801
|
-
|
|
61802
|
-
|
|
61962
|
+
if (input && Object.keys(input).length === 0 && handler.inputSchema && Array.isArray(handler.inputSchema.required) && (handler.inputSchema.required ?? []).length > 0) {
|
|
61963
|
+
const error = `Tool input not fully received \u2014 ${toolName} requires parameters (${(handler.inputSchema.required ?? []).join(", ")}) but received empty input {}. Skipping execution to prevent undefined behavior.`;
|
|
61964
|
+
options2.onToolUseRejected?.(toolName, toolUseId, error);
|
|
61965
|
+
return { toolUseId, toolName, error, isError: true };
|
|
61966
|
+
}
|
|
61967
|
+
options2.onToolUseStart?.(toolName, toolUseId, input);
|
|
61968
|
+
try {
|
|
61969
|
+
if (options2.onPermissionCheck) {
|
|
61970
|
+
const permResult = await options2.onPermissionCheck(toolName, input);
|
|
61971
|
+
if (permResult.behavior === "deny") {
|
|
61972
|
+
const reason = permResult.message ?? "Permission denied";
|
|
61973
|
+
options2.onToolUseRejected?.(toolName, toolUseId, reason);
|
|
61974
|
+
return { toolUseId, toolName, error: reason, isError: true };
|
|
61803
61975
|
}
|
|
61804
61976
|
}
|
|
61805
|
-
if (
|
|
61806
|
-
|
|
61807
|
-
|
|
61808
|
-
|
|
61809
|
-
|
|
61810
|
-
function parseUpdate(sql, params) {
|
|
61811
|
-
const m = sql.match(/UPDATE\s+(\w+)\s+SET\s+(.+?)\s+WHERE\s+(.+)/i);
|
|
61812
|
-
if (!m) return { changes: 0 };
|
|
61813
|
-
const table = m[1];
|
|
61814
|
-
if (!store.tables[table]) return { changes: 0 };
|
|
61815
|
-
const setClauses = m[2].split(",").map((s) => s.trim());
|
|
61816
|
-
const whereClause = m[3].trim();
|
|
61817
|
-
const setParamCount = setClauses.filter((c) => c.includes("?")).length;
|
|
61818
|
-
const wm = whereClause.match(/(\w+)\s*=\s*\?/);
|
|
61819
|
-
const whereCol = wm ? wm[1] : null;
|
|
61820
|
-
const whereVal = wm ? params[setParamCount] : null;
|
|
61821
|
-
let changes = 0;
|
|
61822
|
-
for (const row of store.tables[table]) {
|
|
61823
|
-
if (whereCol && row[whereCol] !== whereVal) continue;
|
|
61824
|
-
let paramIdx = 0;
|
|
61825
|
-
for (const clause of setClauses) {
|
|
61826
|
-
const cm = clause.match(/(\w+)\s*=\s*(.+)/);
|
|
61827
|
-
if (!cm) continue;
|
|
61828
|
-
const col = cm[1];
|
|
61829
|
-
const val = cm[2].trim();
|
|
61830
|
-
if (val === "?") {
|
|
61831
|
-
row[col] = params[paramIdx++];
|
|
61832
|
-
} else if (/^datetime\(/i.test(val)) {
|
|
61833
|
-
row[col] = now();
|
|
61834
|
-
}
|
|
61977
|
+
if (handler.validateInput) {
|
|
61978
|
+
const validation = await handler.validateInput(input);
|
|
61979
|
+
if (!validation.result) {
|
|
61980
|
+
const error = validation.message ?? "Invalid input";
|
|
61981
|
+
return { toolUseId, toolName, error, isError: true };
|
|
61835
61982
|
}
|
|
61836
|
-
changes++;
|
|
61837
61983
|
}
|
|
61838
|
-
|
|
61839
|
-
|
|
61840
|
-
|
|
61841
|
-
|
|
61842
|
-
|
|
61843
|
-
|
|
61844
|
-
|
|
61845
|
-
|
|
61846
|
-
if (!m[2]) {
|
|
61847
|
-
const count = store.tables[table].length;
|
|
61848
|
-
store.tables[table] = [];
|
|
61849
|
-
flush();
|
|
61850
|
-
return { changes: count };
|
|
61984
|
+
const result = await handler.call(input, {
|
|
61985
|
+
abortSignal: options2.signal,
|
|
61986
|
+
agentId: options2.agentId,
|
|
61987
|
+
toolUseId
|
|
61988
|
+
});
|
|
61989
|
+
options2.onToolUseEnd?.(toolName, toolUseId, result);
|
|
61990
|
+
if (result.isError || result.error) {
|
|
61991
|
+
return { toolUseId, toolName, error: result.error, isError: true };
|
|
61851
61992
|
}
|
|
61852
|
-
|
|
61853
|
-
|
|
61854
|
-
const
|
|
61855
|
-
|
|
61856
|
-
|
|
61857
|
-
store.tables[table] = store.tables[table].filter((r) => r[col] !== val);
|
|
61858
|
-
const changes = before - store.tables[table].length;
|
|
61859
|
-
if (changes > 0) flush();
|
|
61860
|
-
return { changes };
|
|
61993
|
+
return { toolUseId, toolName, data: result.data };
|
|
61994
|
+
} catch (error) {
|
|
61995
|
+
const errorMsg = errorToString(error);
|
|
61996
|
+
options2.onToolUseEnd?.(toolName, toolUseId, { error: errorMsg, isError: true });
|
|
61997
|
+
return { toolUseId, toolName, error: errorMsg, isError: true };
|
|
61861
61998
|
}
|
|
61862
|
-
|
|
61863
|
-
|
|
61864
|
-
|
|
61865
|
-
|
|
61866
|
-
|
|
61867
|
-
|
|
61868
|
-
|
|
61999
|
+
}
|
|
62000
|
+
function buildToolDefinitions(tools) {
|
|
62001
|
+
return tools.map((t) => ({
|
|
62002
|
+
name: t.name,
|
|
62003
|
+
description: t.description,
|
|
62004
|
+
input_schema: t.inputSchema
|
|
62005
|
+
}));
|
|
62006
|
+
}
|
|
62007
|
+
var DEFAULT_MAX_TURNS;
|
|
62008
|
+
var init_agent_loop = __esm({
|
|
62009
|
+
"src/core/agent-loop.ts"() {
|
|
62010
|
+
"use strict";
|
|
62011
|
+
init_api();
|
|
62012
|
+
init_errors2();
|
|
62013
|
+
DEFAULT_MAX_TURNS = 100;
|
|
61869
62014
|
}
|
|
62015
|
+
});
|
|
62016
|
+
|
|
62017
|
+
// src/config/permissions.ts
|
|
62018
|
+
function createDefaultPermissionContext(settings) {
|
|
62019
|
+
const defaultMode = settings?.permissions?.defaultMode ?? "default";
|
|
61870
62020
|
return {
|
|
61871
|
-
|
|
61872
|
-
|
|
61873
|
-
|
|
61874
|
-
ensureTable(m[1]);
|
|
61875
|
-
}
|
|
61876
|
-
},
|
|
61877
|
-
prepare(sql) {
|
|
61878
|
-
return {
|
|
61879
|
-
run(...params) {
|
|
61880
|
-
return execSql(sql, params);
|
|
61881
|
-
},
|
|
61882
|
-
get(...params) {
|
|
61883
|
-
const result = execSql(sql, params);
|
|
61884
|
-
if (Array.isArray(result)) return result[0];
|
|
61885
|
-
return void 0;
|
|
61886
|
-
},
|
|
61887
|
-
all(...params) {
|
|
61888
|
-
const result = execSql(sql, params);
|
|
61889
|
-
if (Array.isArray(result)) return result;
|
|
61890
|
-
return [];
|
|
61891
|
-
}
|
|
61892
|
-
};
|
|
61893
|
-
},
|
|
61894
|
-
// Bun-style API aliases
|
|
61895
|
-
run(sql, params = []) {
|
|
61896
|
-
return execSql(sql, params);
|
|
61897
|
-
},
|
|
61898
|
-
query(sql) {
|
|
61899
|
-
return {
|
|
61900
|
-
get(...params) {
|
|
61901
|
-
const result = execSql(sql, params);
|
|
61902
|
-
if (Array.isArray(result)) return result[0];
|
|
61903
|
-
return void 0;
|
|
61904
|
-
},
|
|
61905
|
-
all(...params) {
|
|
61906
|
-
const result = execSql(sql, params);
|
|
61907
|
-
if (Array.isArray(result)) return result;
|
|
61908
|
-
return [];
|
|
61909
|
-
}
|
|
61910
|
-
};
|
|
61911
|
-
},
|
|
61912
|
-
close() {
|
|
61913
|
-
flush();
|
|
61914
|
-
}
|
|
62021
|
+
mode: defaultMode,
|
|
62022
|
+
allowRules: settings?.permissions?.allow ?? [],
|
|
62023
|
+
denyRules: settings?.permissions?.deny ?? []
|
|
61915
62024
|
};
|
|
61916
62025
|
}
|
|
61917
|
-
var
|
|
61918
|
-
|
|
61919
|
-
"src/db/index.ts"() {
|
|
62026
|
+
var init_permissions = __esm({
|
|
62027
|
+
"src/config/permissions.ts"() {
|
|
61920
62028
|
"use strict";
|
|
61921
|
-
init_paths();
|
|
61922
|
-
_db = null;
|
|
61923
62029
|
}
|
|
61924
62030
|
});
|
|
61925
62031
|
|
|
@@ -62210,7 +62316,7 @@ function getShell() {
|
|
|
62210
62316
|
}
|
|
62211
62317
|
return process.env.SHELL ?? "/bin/bash";
|
|
62212
62318
|
}
|
|
62213
|
-
function
|
|
62319
|
+
function truncate2(str, maxLen) {
|
|
62214
62320
|
if (str.length <= maxLen) return str;
|
|
62215
62321
|
return str.slice(0, maxLen - 3) + "...";
|
|
62216
62322
|
}
|
|
@@ -62455,7 +62561,7 @@ var init_bash = __esm({
|
|
|
62455
62561
|
return input.command;
|
|
62456
62562
|
},
|
|
62457
62563
|
getActivityDescription(input) {
|
|
62458
|
-
return input.description ?? `Running: ${
|
|
62564
|
+
return input.description ?? `Running: ${truncate2(input.command, 60)}`;
|
|
62459
62565
|
},
|
|
62460
62566
|
async validateInput(input) {
|
|
62461
62567
|
if (!input.command || !input.command.trim()) {
|
|
@@ -62481,7 +62587,7 @@ var init_bash = __esm({
|
|
|
62481
62587
|
}
|
|
62482
62588
|
return {
|
|
62483
62589
|
behavior: "passthrough",
|
|
62484
|
-
message: `Run command: ${
|
|
62590
|
+
message: `Run command: ${truncate2(cmd, 100)}`
|
|
62485
62591
|
};
|
|
62486
62592
|
},
|
|
62487
62593
|
async call(input, context) {
|
|
@@ -62858,7 +62964,7 @@ Usage:
|
|
|
62858
62964
|
});
|
|
62859
62965
|
|
|
62860
62966
|
// src/tools/builtin/edit.ts
|
|
62861
|
-
import { readFileSync as readFileSync6, writeFileSync as
|
|
62967
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync7 } from "fs";
|
|
62862
62968
|
import { resolve as resolve3, isAbsolute as isAbsolute2 } from "path";
|
|
62863
62969
|
import { randomUUID } from "crypto";
|
|
62864
62970
|
function resolvePath2(filePath) {
|
|
@@ -63068,7 +63174,7 @@ var init_edit = __esm({
|
|
|
63068
63174
|
);
|
|
63069
63175
|
} catch {
|
|
63070
63176
|
}
|
|
63071
|
-
|
|
63177
|
+
writeFileSync4(resolved, newContent, "utf-8");
|
|
63072
63178
|
markFileAsRead(resolved);
|
|
63073
63179
|
const gitDiff = generateUnifiedDiff(originalContent, newContent, input.file_path);
|
|
63074
63180
|
return {
|
|
@@ -63106,8 +63212,9 @@ Usage:
|
|
|
63106
63212
|
});
|
|
63107
63213
|
|
|
63108
63214
|
// src/tools/builtin/write.ts
|
|
63109
|
-
import { writeFileSync as
|
|
63215
|
+
import { writeFileSync as writeFileSync5, readFileSync as readFileSync7, existsSync as existsSync8, mkdirSync as mkdirSync4 } from "fs";
|
|
63110
63216
|
import { dirname as dirname3, resolve as resolve4, isAbsolute as isAbsolute3 } from "path";
|
|
63217
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
63111
63218
|
function resolvePath3(filePath) {
|
|
63112
63219
|
if (isAbsolute3(filePath)) return filePath;
|
|
63113
63220
|
return resolve4(process.cwd(), filePath);
|
|
@@ -63119,6 +63226,7 @@ var init_write = __esm({
|
|
|
63119
63226
|
init_zod();
|
|
63120
63227
|
init_constants();
|
|
63121
63228
|
init_read();
|
|
63229
|
+
init_db();
|
|
63122
63230
|
WriteInputSchema = external_exports.strictObject({
|
|
63123
63231
|
file_path: external_exports.string().describe("The absolute path to the file to write"),
|
|
63124
63232
|
content: external_exports.string().describe("The content to write to the file")
|
|
@@ -63182,7 +63290,18 @@ var init_write = __esm({
|
|
|
63182
63290
|
if (!existsSync8(dir)) {
|
|
63183
63291
|
mkdirSync4(dir, { recursive: true });
|
|
63184
63292
|
}
|
|
63185
|
-
|
|
63293
|
+
if (!created) {
|
|
63294
|
+
try {
|
|
63295
|
+
const originalContent = readFileSync7(resolved, "utf-8");
|
|
63296
|
+
const cpId = randomUUID2().slice(0, 8);
|
|
63297
|
+
dbRun(
|
|
63298
|
+
"INSERT INTO checkpoints (id, session_id, file_path, original_content, edit_operation) VALUES (?, ?, ?, ?, ?)",
|
|
63299
|
+
[cpId, "current", resolved, originalContent, JSON.stringify({ type: "write_overwrite" })]
|
|
63300
|
+
);
|
|
63301
|
+
} catch {
|
|
63302
|
+
}
|
|
63303
|
+
}
|
|
63304
|
+
writeFileSync5(resolved, input.content, "utf-8");
|
|
63186
63305
|
markFileAsRead(resolved);
|
|
63187
63306
|
return {
|
|
63188
63307
|
data: {
|
|
@@ -70270,6 +70389,11 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70270
70389
|
const activeToolsRef = import_react22.default.useRef([]);
|
|
70271
70390
|
activeToolsRef.current = activeTools;
|
|
70272
70391
|
const rows = stdout?.rows ?? 24;
|
|
70392
|
+
const [slashSelected, setSlashSelected] = (0, import_react22.useState)(0);
|
|
70393
|
+
const allCommands = getAllSlashCommands();
|
|
70394
|
+
const showSlashMenu = input.startsWith("/") && !busy;
|
|
70395
|
+
const slashFilter = input.slice(1).toLowerCase();
|
|
70396
|
+
const filteredCommands = showSlashMenu ? allCommands.filter((c) => c.name.toLowerCase().startsWith(slashFilter)).slice(0, 8) : [];
|
|
70273
70397
|
const [permissionPending, setPermissionPending] = (0, import_react22.useState)(null);
|
|
70274
70398
|
const requestPermission = (0, import_react22.useCallback)((toolName, summary) => {
|
|
70275
70399
|
return new Promise((resolve7) => {
|
|
@@ -70401,12 +70525,39 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70401
70525
|
}
|
|
70402
70526
|
return;
|
|
70403
70527
|
}
|
|
70528
|
+
if (showSlashMenu && filteredCommands.length > 0) {
|
|
70529
|
+
if (key.downArrow || key.tab && !key.shift) {
|
|
70530
|
+
setSlashSelected((s) => Math.min(s + 1, filteredCommands.length - 1));
|
|
70531
|
+
return;
|
|
70532
|
+
}
|
|
70533
|
+
if (key.upArrow || key.tab && key.shift) {
|
|
70534
|
+
setSlashSelected((s) => Math.max(s - 1, 0));
|
|
70535
|
+
return;
|
|
70536
|
+
}
|
|
70537
|
+
if (key.return) {
|
|
70538
|
+
const cmd = filteredCommands[slashSelected];
|
|
70539
|
+
if (cmd) {
|
|
70540
|
+
setInput("");
|
|
70541
|
+
setSlashSelected(0);
|
|
70542
|
+
submit(`/${cmd.name}`);
|
|
70543
|
+
return;
|
|
70544
|
+
}
|
|
70545
|
+
}
|
|
70546
|
+
if (key.escape) {
|
|
70547
|
+
setInput("");
|
|
70548
|
+
setSlashSelected(0);
|
|
70549
|
+
return;
|
|
70550
|
+
}
|
|
70551
|
+
}
|
|
70404
70552
|
if (key.return) {
|
|
70405
70553
|
const t = input;
|
|
70406
70554
|
setInput("");
|
|
70555
|
+
setSlashSelected(0);
|
|
70407
70556
|
submit(t);
|
|
70408
|
-
} else if (key.backspace || key.delete)
|
|
70409
|
-
|
|
70557
|
+
} else if (key.backspace || key.delete) {
|
|
70558
|
+
setInput((p) => p.slice(0, -1));
|
|
70559
|
+
setSlashSelected(0);
|
|
70560
|
+
} else if (key.ctrl && ch === "c") exit();
|
|
70410
70561
|
else if (key.ctrl && ch === "d") exit();
|
|
70411
70562
|
else if (key.ctrl && ch === "l") {
|
|
70412
70563
|
setMsgs([]);
|
|
@@ -70442,6 +70593,17 @@ function App2({ model, mode, initialPrompt }) {
|
|
|
70442
70593
|
input.startsWith("/") ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "magenta", children: input }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: input }),
|
|
70443
70594
|
!busy && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u258E" })
|
|
70444
70595
|
] }),
|
|
70596
|
+
showSlashMenu && filteredCommands.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, children: filteredCommands.map((cmd, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { children: [
|
|
70597
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: i === slashSelected ? "cyan" : void 0, bold: i === slashSelected, children: i === slashSelected ? "\u25B8 " : " " }),
|
|
70598
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: i === slashSelected ? "cyan" : "blue", children: [
|
|
70599
|
+
"/",
|
|
70600
|
+
cmd.name.padEnd(16)
|
|
70601
|
+
] }),
|
|
70602
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, children: [
|
|
70603
|
+
" ",
|
|
70604
|
+
cmd.description
|
|
70605
|
+
] })
|
|
70606
|
+
] }, cmd.name)) }),
|
|
70445
70607
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: sep }),
|
|
70446
70608
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(StatusBar, { model, mode, cost, tokens })
|
|
70447
70609
|
] })
|
|
@@ -70740,8 +70902,8 @@ async function bootstrap() {
|
|
|
70740
70902
|
var VERSION, BUILD_TIME, PACKAGE_NAME2, ISSUES_URL2, startupTimestamps, originalCwd, RESET_TERMINAL, cleanupHandlers, earlyInput, earlyInputCapturing;
|
|
70741
70903
|
var init_index = __esm({
|
|
70742
70904
|
"src/cli/index.ts"() {
|
|
70743
|
-
VERSION = "0.0
|
|
70744
|
-
BUILD_TIME = "2026-03-
|
|
70905
|
+
VERSION = "0.1.0";
|
|
70906
|
+
BUILD_TIME = "2026-03-20T12:44:32.414Z";
|
|
70745
70907
|
PACKAGE_NAME2 = "@hasna/coders";
|
|
70746
70908
|
ISSUES_URL2 = "https://github.com/hasnaxyz/open-coders/issues";
|
|
70747
70909
|
startupTimestamps = {};
|