homarus 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/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/agent-manager.d.ts +35 -0
- package/dist/agent-manager.js +127 -0
- package/dist/agent-worker.d.ts +2 -0
- package/dist/agent-worker.js +141 -0
- package/dist/agent.d.ts +33 -0
- package/dist/agent.js +197 -0
- package/dist/browser-manager.d.ts +33 -0
- package/dist/browser-manager.js +170 -0
- package/dist/channel-adapter.d.ts +29 -0
- package/dist/channel-adapter.js +94 -0
- package/dist/channel-manager.d.ts +17 -0
- package/dist/channel-manager.js +84 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +212 -0
- package/dist/config.d.ts +21 -0
- package/dist/config.js +185 -0
- package/dist/embedding-provider.d.ts +35 -0
- package/dist/embedding-provider.js +103 -0
- package/dist/event-bus.d.ts +18 -0
- package/dist/event-bus.js +46 -0
- package/dist/event-queue.d.ts +18 -0
- package/dist/event-queue.js +77 -0
- package/dist/execution-strategy.d.ts +26 -0
- package/dist/execution-strategy.js +20 -0
- package/dist/homarus.d.ts +36 -0
- package/dist/homarus.js +308 -0
- package/dist/http-api.d.ts +16 -0
- package/dist/http-api.js +82 -0
- package/dist/identity-manager.d.ts +28 -0
- package/dist/identity-manager.js +123 -0
- package/dist/memory-index.d.ts +52 -0
- package/dist/memory-index.js +286 -0
- package/dist/model-provider.d.ts +33 -0
- package/dist/model-provider.js +255 -0
- package/dist/model-router.d.ts +32 -0
- package/dist/model-router.js +148 -0
- package/dist/setup-wizard.d.ts +28 -0
- package/dist/setup-wizard.js +240 -0
- package/dist/skill-manager.d.ts +26 -0
- package/dist/skill-manager.js +171 -0
- package/dist/skill-transport.d.ts +51 -0
- package/dist/skill-transport.js +116 -0
- package/dist/skill.d.ts +22 -0
- package/dist/skill.js +118 -0
- package/dist/subprocess-strategy.d.ts +54 -0
- package/dist/subprocess-strategy.js +106 -0
- package/dist/telegram-adapter.d.ts +34 -0
- package/dist/telegram-adapter.js +165 -0
- package/dist/timer-service.d.ts +30 -0
- package/dist/timer-service.js +142 -0
- package/dist/tool-registry.d.ts +29 -0
- package/dist/tool-registry.js +100 -0
- package/dist/tools/bash.d.ts +3 -0
- package/dist/tools/bash.js +48 -0
- package/dist/tools/browser.d.ts +4 -0
- package/dist/tools/browser.js +47 -0
- package/dist/tools/edit.d.ts +3 -0
- package/dist/tools/edit.js +48 -0
- package/dist/tools/git.d.ts +3 -0
- package/dist/tools/git.js +109 -0
- package/dist/tools/glob.d.ts +3 -0
- package/dist/tools/glob.js +86 -0
- package/dist/tools/grep.d.ts +3 -0
- package/dist/tools/grep.js +169 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.js +46 -0
- package/dist/tools/lsp.d.ts +3 -0
- package/dist/tools/lsp.js +216 -0
- package/dist/tools/memory.d.ts +4 -0
- package/dist/tools/memory.js +64 -0
- package/dist/tools/read.d.ts +3 -0
- package/dist/tools/read.js +49 -0
- package/dist/tools/web-fetch.d.ts +3 -0
- package/dist/tools/web-fetch.js +51 -0
- package/dist/tools/web-search.d.ts +3 -0
- package/dist/tools/web-search.js +73 -0
- package/dist/tools/write.d.ts +3 -0
- package/dist/tools/write.js +31 -0
- package/dist/types.d.ts +240 -0
- package/dist/types.js +14 -0
- package/package.json +69 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Uses DuckDuckGo HTML search (no API key needed)
|
|
2
|
+
async function duckduckgoSearch(query, limit) {
|
|
3
|
+
const encoded = encodeURIComponent(query);
|
|
4
|
+
const url = `https://html.duckduckgo.com/html/?q=${encoded}`;
|
|
5
|
+
const response = await fetch(url, {
|
|
6
|
+
headers: {
|
|
7
|
+
"User-Agent": "Mozilla/5.0 (compatible; Homarus/1.0)",
|
|
8
|
+
},
|
|
9
|
+
signal: AbortSignal.timeout(15_000),
|
|
10
|
+
});
|
|
11
|
+
if (!response.ok) {
|
|
12
|
+
throw new Error(`Search failed: HTTP ${response.status}`);
|
|
13
|
+
}
|
|
14
|
+
const html = await response.text();
|
|
15
|
+
const results = [];
|
|
16
|
+
// Parse DuckDuckGo HTML results
|
|
17
|
+
// Results are in <a class="result__a"> with <a class="result__snippet">
|
|
18
|
+
const resultBlocks = html.split("class=\"result__body\"");
|
|
19
|
+
for (let i = 1; i < resultBlocks.length && results.length < limit; i++) {
|
|
20
|
+
const block = resultBlocks[i];
|
|
21
|
+
// Extract URL and title from result__a
|
|
22
|
+
const linkMatch = block.match(/class="result__a"[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/);
|
|
23
|
+
if (!linkMatch)
|
|
24
|
+
continue;
|
|
25
|
+
let resultUrl = linkMatch[1];
|
|
26
|
+
// DuckDuckGo wraps URLs in a redirect — extract the actual URL
|
|
27
|
+
const uddgMatch = resultUrl.match(/uddg=([^&]*)/);
|
|
28
|
+
if (uddgMatch) {
|
|
29
|
+
resultUrl = decodeURIComponent(uddgMatch[1]);
|
|
30
|
+
}
|
|
31
|
+
const title = linkMatch[2].replace(/<[^>]+>/g, "").trim();
|
|
32
|
+
// Extract snippet
|
|
33
|
+
const snippetMatch = block.match(/class="result__snippet"[^>]*>([\s\S]*?)<\/a>/);
|
|
34
|
+
const snippet = snippetMatch
|
|
35
|
+
? snippetMatch[1].replace(/<[^>]+>/g, "").trim()
|
|
36
|
+
: "";
|
|
37
|
+
if (title && resultUrl) {
|
|
38
|
+
results.push({ title, url: resultUrl, snippet });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return results;
|
|
42
|
+
}
|
|
43
|
+
export const webSearchTool = {
|
|
44
|
+
name: "web_search",
|
|
45
|
+
description: "Search the web and return results with titles, URLs, and snippets. Uses DuckDuckGo (no API key required).",
|
|
46
|
+
parameters: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
query: { type: "string", description: "The search query" },
|
|
50
|
+
limit: { type: "number", description: "Maximum number of results (default 10)" },
|
|
51
|
+
},
|
|
52
|
+
required: ["query"],
|
|
53
|
+
},
|
|
54
|
+
source: "builtin",
|
|
55
|
+
async execute(params, context) {
|
|
56
|
+
if (context.sandbox) {
|
|
57
|
+
return { output: "", error: "web_search tool is not available in sandbox mode" };
|
|
58
|
+
}
|
|
59
|
+
const { query, limit = 10 } = params;
|
|
60
|
+
try {
|
|
61
|
+
const results = await duckduckgoSearch(query, limit);
|
|
62
|
+
if (results.length === 0) {
|
|
63
|
+
return { output: "No results found." };
|
|
64
|
+
}
|
|
65
|
+
const formatted = results.map((r, i) => `[${i + 1}] ${r.title}\n ${r.url}\n ${r.snippet}`).join("\n\n");
|
|
66
|
+
return { output: formatted };
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
return { output: "", error: `Search failed: ${String(err.message ?? err)}` };
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=web-search.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Built-in tool: write — create or overwrite a file
|
|
2
|
+
import { writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
3
|
+
import { resolve, dirname } from "node:path";
|
|
4
|
+
export const writeTool = {
|
|
5
|
+
name: "write",
|
|
6
|
+
description: "Write content to a file, creating it if it doesn't exist. Creates parent directories as needed. Overwrites existing files.",
|
|
7
|
+
parameters: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
path: { type: "string", description: "Absolute or relative path to the file" },
|
|
11
|
+
content: { type: "string", description: "The content to write to the file" },
|
|
12
|
+
},
|
|
13
|
+
required: ["path", "content"],
|
|
14
|
+
},
|
|
15
|
+
source: "builtin",
|
|
16
|
+
async execute(params, context) {
|
|
17
|
+
const { path: filePath, content } = params;
|
|
18
|
+
const absPath = resolve(context.workingDir, filePath);
|
|
19
|
+
if (context.sandbox) {
|
|
20
|
+
return { output: "", error: "write tool is not available in sandbox mode" };
|
|
21
|
+
}
|
|
22
|
+
const dir = dirname(absPath);
|
|
23
|
+
if (!existsSync(dir)) {
|
|
24
|
+
mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
writeFileSync(absPath, content);
|
|
27
|
+
const lines = content.split("\n").length;
|
|
28
|
+
return { output: `Wrote ${lines} lines to ${absPath}` };
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=write.js.map
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
export interface Event {
|
|
2
|
+
id: string;
|
|
3
|
+
type: string;
|
|
4
|
+
source: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
payload: unknown;
|
|
7
|
+
replyTo?: string;
|
|
8
|
+
priority?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface MessagePayload {
|
|
11
|
+
from: string;
|
|
12
|
+
channel: string;
|
|
13
|
+
text: string;
|
|
14
|
+
attachments?: Attachment[];
|
|
15
|
+
replyTo?: string;
|
|
16
|
+
isGroup: boolean;
|
|
17
|
+
isMention: boolean;
|
|
18
|
+
raw: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface Attachment {
|
|
21
|
+
type: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
data?: Buffer;
|
|
24
|
+
mimeType?: string;
|
|
25
|
+
filename?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface OutboundMessage {
|
|
28
|
+
text: string;
|
|
29
|
+
attachments?: Attachment[];
|
|
30
|
+
replyTo?: string;
|
|
31
|
+
}
|
|
32
|
+
export type ExecutionStrategyType = "embedded" | "subprocess";
|
|
33
|
+
export interface AgentConfig {
|
|
34
|
+
prompt: string;
|
|
35
|
+
model?: string;
|
|
36
|
+
tools?: string[];
|
|
37
|
+
timeout?: number;
|
|
38
|
+
maxTurns?: number;
|
|
39
|
+
systemPrompt?: string;
|
|
40
|
+
memory?: boolean;
|
|
41
|
+
sandbox?: boolean;
|
|
42
|
+
channel?: string;
|
|
43
|
+
taskOverlay?: string;
|
|
44
|
+
replyTo?: string;
|
|
45
|
+
executionStrategy?: ExecutionStrategyType;
|
|
46
|
+
}
|
|
47
|
+
export type AgentState = "pending" | "running" | "complete" | "failed" | "cancelled";
|
|
48
|
+
export interface AgentResult {
|
|
49
|
+
output: string;
|
|
50
|
+
toolCalls: ToolCallRecord[];
|
|
51
|
+
usage: TokenUsage;
|
|
52
|
+
}
|
|
53
|
+
export interface ToolCallRecord {
|
|
54
|
+
tool: string;
|
|
55
|
+
params: unknown;
|
|
56
|
+
result: unknown;
|
|
57
|
+
durationMs: number;
|
|
58
|
+
}
|
|
59
|
+
export interface ChatRequest {
|
|
60
|
+
model: string;
|
|
61
|
+
messages: ChatMessage[];
|
|
62
|
+
tools?: ToolSchema[];
|
|
63
|
+
temperature?: number;
|
|
64
|
+
maxTokens?: number;
|
|
65
|
+
}
|
|
66
|
+
export interface ChatMessage {
|
|
67
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
68
|
+
content: string;
|
|
69
|
+
toolCallId?: string;
|
|
70
|
+
toolCalls?: ToolCall[];
|
|
71
|
+
}
|
|
72
|
+
export interface ToolCall {
|
|
73
|
+
id: string;
|
|
74
|
+
name: string;
|
|
75
|
+
arguments: string;
|
|
76
|
+
}
|
|
77
|
+
export interface ChatChunk {
|
|
78
|
+
content?: string;
|
|
79
|
+
toolCalls?: ToolCall[];
|
|
80
|
+
finishReason?: "stop" | "tool_calls" | "length" | "error";
|
|
81
|
+
usage?: TokenUsage;
|
|
82
|
+
}
|
|
83
|
+
export interface TokenUsage {
|
|
84
|
+
inputTokens: number;
|
|
85
|
+
outputTokens: number;
|
|
86
|
+
}
|
|
87
|
+
export interface ModelInfo {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
contextWindow?: number;
|
|
91
|
+
maxOutput?: number;
|
|
92
|
+
}
|
|
93
|
+
export interface AuthProfile {
|
|
94
|
+
apiKey: string;
|
|
95
|
+
cooldownUntil?: number;
|
|
96
|
+
failCount?: number;
|
|
97
|
+
}
|
|
98
|
+
export interface ToolSchema {
|
|
99
|
+
name: string;
|
|
100
|
+
description: string;
|
|
101
|
+
parameters: Record<string, unknown>;
|
|
102
|
+
}
|
|
103
|
+
export interface ToolDefinition {
|
|
104
|
+
name: string;
|
|
105
|
+
description: string;
|
|
106
|
+
parameters: Record<string, unknown>;
|
|
107
|
+
execute: (params: unknown, context: ToolContext) => Promise<ToolResult>;
|
|
108
|
+
source: string;
|
|
109
|
+
}
|
|
110
|
+
export interface ToolContext {
|
|
111
|
+
agentId: string;
|
|
112
|
+
sandbox: boolean;
|
|
113
|
+
workingDir: string;
|
|
114
|
+
}
|
|
115
|
+
export interface ToolResult {
|
|
116
|
+
output: string;
|
|
117
|
+
error?: string;
|
|
118
|
+
}
|
|
119
|
+
export interface SkillManifest {
|
|
120
|
+
name: string;
|
|
121
|
+
version: string;
|
|
122
|
+
description: string;
|
|
123
|
+
emits?: string[];
|
|
124
|
+
handles?: string[];
|
|
125
|
+
tools?: ToolSchema[];
|
|
126
|
+
process?: {
|
|
127
|
+
command: string;
|
|
128
|
+
args?: string[];
|
|
129
|
+
port?: number;
|
|
130
|
+
healthCheck?: string;
|
|
131
|
+
};
|
|
132
|
+
hooks?: {
|
|
133
|
+
onStart?: string;
|
|
134
|
+
onStop?: string;
|
|
135
|
+
onHealth?: string;
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
export type SkillState = "loaded" | "starting" | "running" | "stopping" | "stopped" | "error";
|
|
139
|
+
export type TransportType = "http" | "stdio" | "direct";
|
|
140
|
+
export type DmPolicy = "pairing" | "allowlist" | "open" | "disabled";
|
|
141
|
+
export type GroupPolicy = "mention_required" | "always_on" | "disabled";
|
|
142
|
+
export interface HealthStatus {
|
|
143
|
+
healthy: boolean;
|
|
144
|
+
message?: string;
|
|
145
|
+
lastCheck: number;
|
|
146
|
+
}
|
|
147
|
+
export interface BrowserConfig {
|
|
148
|
+
enabled?: boolean;
|
|
149
|
+
headless?: boolean;
|
|
150
|
+
executablePath?: string;
|
|
151
|
+
proxy?: string;
|
|
152
|
+
viewport?: {
|
|
153
|
+
width: number;
|
|
154
|
+
height: number;
|
|
155
|
+
};
|
|
156
|
+
timeout?: number;
|
|
157
|
+
}
|
|
158
|
+
export interface ConfigData {
|
|
159
|
+
models: ModelsConfig;
|
|
160
|
+
channels: Record<string, ChannelConfig>;
|
|
161
|
+
agents: AgentsConfig;
|
|
162
|
+
memory: MemoryConfig;
|
|
163
|
+
skills: SkillsConfig;
|
|
164
|
+
server: ServerConfig;
|
|
165
|
+
timers: TimersConfig;
|
|
166
|
+
identity: IdentityConfig;
|
|
167
|
+
browser?: BrowserConfig;
|
|
168
|
+
}
|
|
169
|
+
export interface ModelsConfig {
|
|
170
|
+
default: string;
|
|
171
|
+
fallback?: string[];
|
|
172
|
+
aliases?: Record<string, string>;
|
|
173
|
+
providers?: Record<string, ProviderConfig>;
|
|
174
|
+
}
|
|
175
|
+
export interface ProviderConfig {
|
|
176
|
+
apiKey?: string;
|
|
177
|
+
baseUrl?: string;
|
|
178
|
+
profiles?: AuthProfile[];
|
|
179
|
+
}
|
|
180
|
+
export interface ChannelConfig {
|
|
181
|
+
token?: string;
|
|
182
|
+
dmPolicy?: DmPolicy;
|
|
183
|
+
groupPolicy?: GroupPolicy;
|
|
184
|
+
[key: string]: unknown;
|
|
185
|
+
}
|
|
186
|
+
export interface AgentsConfig {
|
|
187
|
+
maxConcurrent?: number;
|
|
188
|
+
defaultTimeout?: number;
|
|
189
|
+
defaultMaxTurns?: number;
|
|
190
|
+
defaultExecutionStrategy?: ExecutionStrategyType;
|
|
191
|
+
}
|
|
192
|
+
export interface MemoryConfig {
|
|
193
|
+
embedding?: {
|
|
194
|
+
provider: string;
|
|
195
|
+
model: string;
|
|
196
|
+
baseUrl?: string;
|
|
197
|
+
apiKey?: string;
|
|
198
|
+
dimensions?: number;
|
|
199
|
+
};
|
|
200
|
+
search?: {
|
|
201
|
+
vectorWeight?: number;
|
|
202
|
+
ftsWeight?: number;
|
|
203
|
+
};
|
|
204
|
+
extraPaths?: string[];
|
|
205
|
+
}
|
|
206
|
+
export interface SkillsConfig {
|
|
207
|
+
paths?: string[];
|
|
208
|
+
}
|
|
209
|
+
export interface ServerConfig {
|
|
210
|
+
port?: number;
|
|
211
|
+
auth?: {
|
|
212
|
+
token: string;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
export interface TimersConfig {
|
|
216
|
+
enabled?: boolean;
|
|
217
|
+
store?: string;
|
|
218
|
+
}
|
|
219
|
+
export interface IdentityConfig {
|
|
220
|
+
dir?: string;
|
|
221
|
+
workspaceDir?: string;
|
|
222
|
+
}
|
|
223
|
+
export type DirectHandler = (event: Event) => void | Promise<void>;
|
|
224
|
+
export interface AgentHandlerConfig {
|
|
225
|
+
id: string;
|
|
226
|
+
agentConfig: Partial<AgentConfig>;
|
|
227
|
+
buildPrompt?: (event: Event) => string;
|
|
228
|
+
}
|
|
229
|
+
export interface Logger {
|
|
230
|
+
debug(msg: string, meta?: Record<string, unknown>): void;
|
|
231
|
+
info(msg: string, meta?: Record<string, unknown>): void;
|
|
232
|
+
warn(msg: string, meta?: Record<string, unknown>): void;
|
|
233
|
+
error(msg: string, meta?: Record<string, unknown>): void;
|
|
234
|
+
}
|
|
235
|
+
export declare class HomarusError extends Error {
|
|
236
|
+
readonly code: string;
|
|
237
|
+
readonly cause?: Error | undefined;
|
|
238
|
+
constructor(message: string, code: string, cause?: Error | undefined);
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Shared types for homarus
|
|
2
|
+
// CRC: crc-Homarus.md, crc-Agent.md, crc-Skill.md, crc-ModelProvider.md, crc-ChannelAdapter.md, crc-ToolRegistry.md
|
|
3
|
+
// --- Errors ---
|
|
4
|
+
export class HomarusError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
cause;
|
|
7
|
+
constructor(message, code, cause) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.cause = cause;
|
|
11
|
+
this.name = "HomarusError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "homarus",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Event-loop based AI agent coordinator",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cli.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"homarus": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**/*.js",
|
|
12
|
+
"dist/**/*.d.ts",
|
|
13
|
+
"!dist/**/*.test.*",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"start": "node dist/cli.js start",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"prepublishOnly": "npm run build && npm test"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/kcdjmaxx/HomarUS.git"
|
|
28
|
+
},
|
|
29
|
+
"author": "Max Ross",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"homepage": "https://github.com/kcdjmaxx/HomarUS#readme",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/kcdjmaxx/HomarUS/issues"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"ai",
|
|
37
|
+
"agent",
|
|
38
|
+
"coordinator",
|
|
39
|
+
"event-loop",
|
|
40
|
+
"llm",
|
|
41
|
+
"orchestration"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=22"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"ajv": "^8.17.0",
|
|
48
|
+
"better-sqlite3": "^11.7.0",
|
|
49
|
+
"croner": "^9.0.0",
|
|
50
|
+
"dotenv": "^16.4.0",
|
|
51
|
+
"express": "^4.21.0",
|
|
52
|
+
"sqlite-vec": "^0.1.0",
|
|
53
|
+
"uuid": "^11.0.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"playwright": "^1.50.0"
|
|
57
|
+
},
|
|
58
|
+
"peerDependenciesMeta": {
|
|
59
|
+
"playwright": { "optional": true }
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
63
|
+
"@types/express": "^5.0.0",
|
|
64
|
+
"@types/node": "^22.0.0",
|
|
65
|
+
"@types/uuid": "^10.0.0",
|
|
66
|
+
"typescript": "^5.7.0",
|
|
67
|
+
"vitest": "^3.0.0"
|
|
68
|
+
}
|
|
69
|
+
}
|