@c4ccz/zero 1.0.0 → 1.0.1

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.
Files changed (47) hide show
  1. package/package.json +10 -7
  2. package/packages/core/src/agent/config-loader.ts +174 -0
  3. package/packages/core/src/agent/engine.ts +266 -0
  4. package/packages/core/src/agent/registry-tools.ts +58 -0
  5. package/packages/core/src/agent/registry.ts +213 -0
  6. package/packages/core/src/commands/index.ts +116 -0
  7. package/packages/core/src/config/index.ts +139 -0
  8. package/packages/core/src/confirmation/message-bus.ts +206 -0
  9. package/packages/core/src/diff/index.ts +232 -0
  10. package/packages/core/src/diff-detect/index.ts +207 -0
  11. package/packages/core/src/edit-coder/index.ts +194 -0
  12. package/packages/core/src/events/index.ts +151 -0
  13. package/packages/core/src/file-tracker/index.ts +183 -0
  14. package/packages/core/src/git/index.ts +305 -0
  15. package/packages/core/src/history/index.ts +236 -0
  16. package/packages/core/src/image/index.ts +131 -0
  17. package/packages/core/src/index.ts +131 -0
  18. package/packages/core/src/lsp/index.ts +251 -0
  19. package/packages/core/src/mcp/index.ts +186 -0
  20. package/packages/core/src/memory/index.ts +141 -0
  21. package/packages/core/src/memory/prompts.ts +52 -0
  22. package/packages/core/src/orchestrator/protocol.ts +140 -0
  23. package/packages/core/src/orchestrator/server.ts +319 -0
  24. package/packages/core/src/output/index.ts +164 -0
  25. package/packages/core/src/permissions/index.ts +126 -0
  26. package/packages/core/src/prompts/engine.ts +188 -0
  27. package/packages/core/src/providers/extended.ts +8 -0
  28. package/packages/core/src/providers/registry.ts +687 -0
  29. package/packages/core/src/routing/model-router.ts +160 -0
  30. package/packages/core/src/server/index.ts +232 -0
  31. package/packages/core/src/session/index.ts +174 -0
  32. package/packages/core/src/session/service.ts +322 -0
  33. package/packages/core/src/skills/index.ts +205 -0
  34. package/packages/core/src/streaming/index.ts +166 -0
  35. package/packages/core/src/sub-agent/index.ts +179 -0
  36. package/packages/core/src/tools/builtin.ts +568 -0
  37. package/packages/core/src/tools/linter.ts +26 -0
  38. package/packages/core/src/tools/repo-map.ts +11 -0
  39. package/packages/core/src/types.ts +356 -0
  40. package/packages/sdk/src/index.ts +247 -0
  41. package/packages/tui/src/index.ts +141 -0
  42. package/bun.lock +0 -35
  43. package/bunfig.toml +0 -6
  44. package/packages/cli/package.json +0 -23
  45. package/packages/core/package.json +0 -41
  46. package/packages/sdk/package.json +0 -16
  47. package/packages/tui/package.json +0 -19
@@ -0,0 +1,356 @@
1
+ /**
2
+ * ZERO Core - Type Definitions
3
+ * Unified types used across all ZERO modules
4
+ */
5
+
6
+ import { z } from "zod";
7
+
8
+ // ============================================================================
9
+ // Message Types
10
+ // ============================================================================
11
+
12
+ export type MessageRole = "user" | "assistant" | "system" | "tool";
13
+
14
+ export interface TextContent {
15
+ type: "text";
16
+ text: string;
17
+ }
18
+
19
+ export interface ImageContent {
20
+ type: "image";
21
+ data: string;
22
+ mimeType: string;
23
+ }
24
+
25
+ export interface ToolCallContent {
26
+ type: "tool_call";
27
+ id: string;
28
+ name: string;
29
+ arguments: Record<string, unknown>;
30
+ }
31
+
32
+ export interface ToolResultContent {
33
+ type: "tool_result";
34
+ id: string;
35
+ name: string;
36
+ result: unknown;
37
+ error?: string;
38
+ }
39
+
40
+ export type MessageContent = TextContent | ImageContent | ToolCallContent | ToolResultContent;
41
+
42
+ export interface Message {
43
+ id: string;
44
+ role: MessageRole;
45
+ content: MessageContent[];
46
+ timestamp: number;
47
+ metadata?: Record<string, unknown>;
48
+ }
49
+
50
+ // ============================================================================
51
+ // Tool Types
52
+ // ============================================================================
53
+
54
+ export const ToolParameterSchema = z.object({
55
+ type: z.enum(["string", "number", "boolean", "array", "object"]),
56
+ description: z.string(),
57
+ required: z.boolean().optional(),
58
+ default: z.unknown().optional(),
59
+ enum: z.array(z.string()).optional(),
60
+ items: z.lazy(() => ToolParameterSchema).optional(),
61
+ properties: z.record(z.lazy(() => ToolParameterSchema)).optional(),
62
+ });
63
+
64
+ export type ToolParameter = z.infer<typeof ToolParameterSchema>;
65
+
66
+ export interface ToolDefinition {
67
+ name: string;
68
+ description: string;
69
+ parameters: Record<string, ToolParameter>;
70
+ category: ToolCategory;
71
+ requiresApproval: boolean;
72
+ handler: (args: Record<string, unknown>, context: ToolContext) => Promise<ToolResult>;
73
+ }
74
+
75
+ export type ToolCategory =
76
+ | "file"
77
+ | "shell"
78
+ | "search"
79
+ | "web"
80
+ | "memory"
81
+ | "git"
82
+ | "system"
83
+ | "mcp";
84
+
85
+ export interface ToolContext {
86
+ sessionId: string;
87
+ workingDirectory: string;
88
+ permissions: PermissionSet;
89
+ abortSignal?: AbortSignal;
90
+ }
91
+
92
+ export interface ToolResult {
93
+ success: boolean;
94
+ output: string;
95
+ data?: unknown;
96
+ error?: string;
97
+ }
98
+
99
+ // ============================================================================
100
+ // Provider Types
101
+ // ============================================================================
102
+
103
+ export interface LLMProvider {
104
+ id: string;
105
+ name: string;
106
+ type: ProviderType;
107
+ models: ModelConfig[];
108
+ createClient(config: ProviderConfig): LLMClient;
109
+ }
110
+
111
+ export type ProviderType =
112
+ | "openai"
113
+ | "anthropic"
114
+ | "google"
115
+ | "azure"
116
+ | "ollama"
117
+ | "custom"
118
+ | "bedrock"
119
+ | "vertex";
120
+
121
+ export interface ModelConfig {
122
+ id: string;
123
+ name: string;
124
+ contextWindow: number;
125
+ maxOutputTokens: number;
126
+ supportsImages: boolean;
127
+ supportsToolUse: boolean;
128
+ supportsStreaming: boolean;
129
+ costPerInputToken?: number;
130
+ costPerOutputToken?: number;
131
+ }
132
+
133
+ export interface ProviderConfig {
134
+ apiKey?: string;
135
+ baseUrl?: string;
136
+ model: string;
137
+ temperature?: number;
138
+ maxTokens?: number;
139
+ topP?: number;
140
+ headers?: Record<string, string>;
141
+ }
142
+
143
+ export interface LLMClient {
144
+ chat(messages: Message[], options?: ChatOptions): Promise<ChatResponse>;
145
+ stream(messages: Message[], options?: ChatOptions): AsyncIterable<StreamChunk>;
146
+ }
147
+
148
+ export interface ChatOptions {
149
+ tools?: ToolDefinition[];
150
+ systemPrompt?: string;
151
+ maxTokens?: number;
152
+ temperature?: number;
153
+ stopSequences?: string[];
154
+ }
155
+
156
+ export interface ChatResponse {
157
+ id: string;
158
+ content: MessageContent[];
159
+ usage: TokenUsage;
160
+ stopReason: StopReason;
161
+ model: string;
162
+ }
163
+
164
+ export interface TokenUsage {
165
+ inputTokens: number;
166
+ outputTokens: number;
167
+ cacheReadTokens?: number;
168
+ cacheWriteTokens?: number;
169
+ totalCost?: number;
170
+ }
171
+
172
+ export type StopReason = "end_turn" | "max_tokens" | "tool_use" | "stop_sequence";
173
+
174
+ export type StreamChunk =
175
+ | { type: "text_delta"; text: string }
176
+ | { type: "tool_call_start"; id: string; name: string }
177
+ | { type: "tool_call_delta"; id: string; arguments: string }
178
+ | { type: "tool_call_end"; id: string }
179
+ | { type: "usage"; usage: TokenUsage }
180
+ | { type: "done"; stopReason: StopReason };
181
+
182
+ // ============================================================================
183
+ // Permission Types
184
+ // ============================================================================
185
+
186
+ export interface PermissionSet {
187
+ fileRead: PermissionLevel;
188
+ fileWrite: PermissionLevel;
189
+ shellExecution: PermissionLevel;
190
+ networkAccess: PermissionLevel;
191
+ mcpAccess: PermissionLevel;
192
+ }
193
+
194
+ export type PermissionLevel = "allow" | "ask" | "deny";
195
+
196
+ export interface PermissionRequest {
197
+ type: "file_read" | "file_write" | "shell" | "network" | "mcp";
198
+ resource: string;
199
+ details?: string;
200
+ }
201
+
202
+ export type PermissionDecision = "allow" | "deny" | "allow_always";
203
+
204
+ export type PermissionHandler = (request: PermissionRequest) => Promise<PermissionDecision>;
205
+
206
+ // ============================================================================
207
+ // Session Types
208
+ // ============================================================================
209
+
210
+ export interface Session {
211
+ id: string;
212
+ name: string;
213
+ createdAt: number;
214
+ updatedAt: number;
215
+ messages: Message[];
216
+ config: SessionConfig;
217
+ state: SessionState;
218
+ }
219
+
220
+ export interface SessionConfig {
221
+ provider: string;
222
+ model: string;
223
+ systemPrompt: string;
224
+ workingDirectory: string;
225
+ permissions: PermissionSet;
226
+ tools: string[];
227
+ mcpServers: MCPServerConfig[];
228
+ }
229
+
230
+ export interface SessionState {
231
+ status: "idle" | "running" | "waiting_approval" | "error" | "completed";
232
+ currentAgent?: string;
233
+ tokenUsage: TokenUsage;
234
+ error?: string;
235
+ }
236
+
237
+ // ============================================================================
238
+ // MCP Types
239
+ // ============================================================================
240
+
241
+ export interface MCPServerConfig {
242
+ id: string;
243
+ name: string;
244
+ command: string;
245
+ args?: string[];
246
+ env?: Record<string, string>;
247
+ enabled: boolean;
248
+ }
249
+
250
+ export interface MCPTool {
251
+ name: string;
252
+ description: string;
253
+ inputSchema: Record<string, unknown>;
254
+ serverId: string;
255
+ }
256
+
257
+ export interface MCPResource {
258
+ uri: string;
259
+ name: string;
260
+ description?: string;
261
+ mimeType?: string;
262
+ serverId: string;
263
+ }
264
+
265
+ // ============================================================================
266
+ // Agent Types
267
+ // ============================================================================
268
+
269
+ export interface AgentConfig {
270
+ id: string;
271
+ name: string;
272
+ description: string;
273
+ systemPrompt: string;
274
+ tools: string[];
275
+ maxTurns: number;
276
+ model: string;
277
+ subAgents?: string[];
278
+ hooks?: AgentHooks;
279
+ }
280
+
281
+ export interface AgentHooks {
282
+ onToolCall?: (tool: string, args: Record<string, unknown>) => Promise<boolean>;
283
+ onToolResult?: (tool: string, result: ToolResult) => Promise<void>;
284
+ onMessage?: (message: Message) => Promise<void>;
285
+ onError?: (error: Error) => Promise<void>;
286
+ onComplete?: (result: AgentResult) => Promise<void>;
287
+ }
288
+
289
+ export interface AgentResult {
290
+ success: boolean;
291
+ messages: Message[];
292
+ tokenUsage: TokenUsage;
293
+ duration: number;
294
+ error?: string;
295
+ }
296
+
297
+ // ============================================================================
298
+ // Memory Types
299
+ // ============================================================================
300
+
301
+ export interface MemoryEntry {
302
+ id: string;
303
+ type: "fact" | "preference" | "context" | "file_context";
304
+ content: string;
305
+ relevance: number;
306
+ createdAt: number;
307
+ expiresAt?: number;
308
+ tags: string[];
309
+ metadata?: Record<string, unknown>;
310
+ }
311
+
312
+ export interface MemoryStore {
313
+ save(entry: MemoryEntry): Promise<void>;
314
+ search(query: string, limit?: number): Promise<MemoryEntry[]>;
315
+ delete(id: string): Promise<void>;
316
+ getAll(): Promise<MemoryEntry[]>;
317
+ }
318
+
319
+ // ============================================================================
320
+ // Config Schema
321
+ // ============================================================================
322
+
323
+ export const ZeroConfigSchema = z.object({
324
+ version: z.literal(1),
325
+ defaultProvider: z.string(),
326
+ defaultModel: z.string(),
327
+ providers: z.record(z.object({
328
+ type: z.string(),
329
+ apiKey: z.string().optional(),
330
+ baseUrl: z.string().optional(),
331
+ models: z.array(z.string()).optional(),
332
+ })),
333
+ permissions: z.object({
334
+ fileRead: z.enum(["allow", "ask", "deny"]).default("allow"),
335
+ fileWrite: z.enum(["allow", "ask", "deny"]).default("ask"),
336
+ shellExecution: z.enum(["allow", "ask", "deny"]).default("ask"),
337
+ networkAccess: z.enum(["allow", "ask", "deny"]).default("ask"),
338
+ mcpAccess: z.enum(["allow", "ask", "deny"]).default("allow"),
339
+ }).default({}),
340
+ agents: z.record(z.object({
341
+ systemPrompt: z.string(),
342
+ tools: z.array(z.string()),
343
+ maxTurns: z.number().default(50),
344
+ model: z.string().optional(),
345
+ })).optional(),
346
+ mcpServers: z.array(z.object({
347
+ id: z.string(),
348
+ name: z.string(),
349
+ command: z.string(),
350
+ args: z.array(z.string()).optional(),
351
+ env: z.record(z.string()).optional(),
352
+ enabled: z.boolean().default(true),
353
+ })).optional(),
354
+ });
355
+
356
+ export type ZeroConfig = z.infer<typeof ZeroConfigSchema>;
@@ -0,0 +1,247 @@
1
+ /**
2
+ * ZERO SDK - Programmatic API
3
+ *
4
+ * Use ZERO programmatically in your own applications.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Zero } from "@zero/sdk";
9
+ *
10
+ * const zero = new Zero({
11
+ * provider: "openai",
12
+ * model: "gpt-4o",
13
+ * apiKey: process.env.OPENAI_API_KEY,
14
+ * });
15
+ *
16
+ * const result = await zero.chat("Create a hello world in Python");
17
+ * console.log(result.text);
18
+ * ```
19
+ */
20
+
21
+ import {
22
+ AgentEngine,
23
+ AgentRegistry,
24
+ DEFAULT_AGENTS,
25
+ ProviderRegistry,
26
+ ToolRegistry,
27
+ SessionManager,
28
+ FileMemoryStore,
29
+ ContextManager,
30
+ MCPManager,
31
+ createAutoPermissionHandler,
32
+ getAllBuiltinTools,
33
+ } from "@zero/core";
34
+ import type {
35
+ AgentResult,
36
+ Message,
37
+ ProviderConfig,
38
+ ToolDefinition,
39
+ AgentConfig,
40
+ MCPServerConfig,
41
+ TokenUsage,
42
+ } from "@zero/core";
43
+
44
+ export interface ZeroOptions {
45
+ provider?: string;
46
+ model?: string;
47
+ apiKey?: string;
48
+ baseUrl?: string;
49
+ workingDirectory?: string;
50
+ systemPrompt?: string;
51
+ autoApprove?: boolean;
52
+ mcpServers?: MCPServerConfig[];
53
+ customTools?: ToolDefinition[];
54
+ customAgents?: AgentConfig[];
55
+ }
56
+
57
+ export interface ZeroChatResult {
58
+ text: string;
59
+ messages: Message[];
60
+ usage: TokenUsage;
61
+ duration: number;
62
+ success: boolean;
63
+ error?: string;
64
+ }
65
+
66
+ export class Zero {
67
+ private providerRegistry: ProviderRegistry;
68
+ private toolRegistry: ToolRegistry;
69
+ private agentRegistry: AgentRegistry;
70
+ private sessionManager: SessionManager;
71
+ private memory: FileMemoryStore;
72
+ private contextManager: ContextManager;
73
+ private mcpManager: MCPManager;
74
+ private options: ZeroOptions;
75
+ private initialized = false;
76
+
77
+ constructor(options: ZeroOptions = {}) {
78
+ this.options = {
79
+ provider: options.provider || "openai",
80
+ model: options.model || "gpt-4o",
81
+ workingDirectory: options.workingDirectory || process.cwd(),
82
+ autoApprove: options.autoApprove ?? false,
83
+ ...options,
84
+ };
85
+
86
+ this.providerRegistry = new ProviderRegistry();
87
+ this.toolRegistry = new ToolRegistry();
88
+ this.agentRegistry = null as any;
89
+ this.sessionManager = null as any;
90
+ this.memory = null as any;
91
+ this.contextManager = null as any;
92
+ this.mcpManager = new MCPManager();
93
+ }
94
+
95
+ /**
96
+ * Initialize ZERO (must be called before use)
97
+ */
98
+ async init(): Promise<void> {
99
+ if (this.initialized) return;
100
+
101
+ // Load providers
102
+ this.providerRegistry.loadBuiltins();
103
+
104
+ // Load tools
105
+ for (const tool of getAllBuiltinTools()) {
106
+ this.toolRegistry.register(tool);
107
+ }
108
+
109
+ // Add custom tools
110
+ if (this.options.customTools) {
111
+ for (const tool of this.options.customTools) {
112
+ this.toolRegistry.register(tool);
113
+ }
114
+ }
115
+
116
+ // Initialize session manager
117
+ const tmpDir = `/tmp/.zero-${Date.now()}`;
118
+ this.sessionManager = new SessionManager({
119
+ storagePath: `${tmpDir}/sessions`,
120
+ defaultConfig: {
121
+ provider: this.options.provider,
122
+ model: this.options.model,
123
+ workingDirectory: this.options.workingDirectory,
124
+ },
125
+ });
126
+
127
+ // Initialize memory
128
+ this.memory = new FileMemoryStore(`${tmpDir}/memory`);
129
+ await this.memory.init();
130
+ this.contextManager = new ContextManager(this.memory);
131
+
132
+ // Initialize agent registry
133
+ const session = await this.sessionManager.create("SDK Session");
134
+ this.agentRegistry = new AgentRegistry({
135
+ clientFactory: (model) => {
136
+ const modelId = model === "default" ? this.options.model! : model;
137
+ return this.providerRegistry.createClient(this.options.provider!, {
138
+ model: modelId,
139
+ apiKey: this.options.apiKey,
140
+ baseUrl: this.options.baseUrl,
141
+ });
142
+ },
143
+ tools: this.toolRegistry.getMap(),
144
+ permissionHandler: this.options.autoApprove
145
+ ? async () => "allow"
146
+ : createAutoPermissionHandler(),
147
+ workingDirectory: this.options.workingDirectory!,
148
+ sessionId: session.id,
149
+ });
150
+
151
+ // Register agents
152
+ const agents = [...DEFAULT_AGENTS, ...(this.options.customAgents || [])];
153
+ for (const agent of agents) {
154
+ this.agentRegistry.register(agent);
155
+ }
156
+
157
+ // Connect MCP servers
158
+ if (this.options.mcpServers) {
159
+ for (const server of this.options.mcpServers) {
160
+ await this.mcpManager.connect(server);
161
+ }
162
+ }
163
+
164
+ this.initialized = true;
165
+ }
166
+
167
+ /**
168
+ * Send a chat message and get a response
169
+ */
170
+ async chat(prompt: string, options?: { agent?: string }): Promise<ZeroChatResult> {
171
+ if (!this.initialized) await this.init();
172
+
173
+ const agentId = options?.agent || "coder";
174
+ const engine = this.agentRegistry.createEngine(agentId);
175
+
176
+ // Add memory context
177
+ const context = await this.contextManager.buildContext(prompt);
178
+ const fullPrompt = context ? `${prompt}\n\n${context}` : prompt;
179
+
180
+ const result = await engine.run(fullPrompt);
181
+
182
+ // Extract text from response
183
+ const text = result.messages
184
+ .filter((m) => m.role === "assistant")
185
+ .flatMap((m) => m.content)
186
+ .filter((c) => c.type === "text")
187
+ .map((c) => (c as any).text)
188
+ .join("\n");
189
+
190
+ return {
191
+ text,
192
+ messages: result.messages,
193
+ usage: result.tokenUsage,
194
+ duration: result.duration,
195
+ success: result.success,
196
+ error: result.error,
197
+ };
198
+ }
199
+
200
+ /**
201
+ * Stream a chat response
202
+ */
203
+ async *stream(prompt: string): AsyncGenerator<string> {
204
+ if (!this.initialized) await this.init();
205
+
206
+ const client = this.providerRegistry.createClient(this.options.provider!, {
207
+ model: this.options.model!,
208
+ apiKey: this.options.apiKey,
209
+ baseUrl: this.options.baseUrl,
210
+ });
211
+
212
+ const messages: Message[] = [
213
+ {
214
+ id: `msg_${Date.now()}`,
215
+ role: "user",
216
+ content: [{ type: "text", text: prompt }],
217
+ timestamp: Date.now(),
218
+ },
219
+ ];
220
+
221
+ for await (const chunk of client.stream(messages, {
222
+ systemPrompt: DEFAULT_AGENTS[0].systemPrompt,
223
+ })) {
224
+ if (chunk.type === "text_delta") {
225
+ yield chunk.text;
226
+ }
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Clean up resources
232
+ */
233
+ async close(): Promise<void> {
234
+ await this.mcpManager.disconnectAll();
235
+ }
236
+ }
237
+
238
+ // Re-export types
239
+ export type {
240
+ AgentResult,
241
+ Message,
242
+ ProviderConfig,
243
+ ToolDefinition,
244
+ AgentConfig,
245
+ MCPServerConfig,
246
+ TokenUsage,
247
+ };