refactor: rombak arsitektur file ke modular clean-arch (vertikal per-feature)
Organisasi ulang layer-first (domain/application/infrastructure) menjadi vertikal per-feature, behavior tidak berubah: - src/shared/domain/ -> fondasi bersama (ex-domain/core): message, provider, tool_call, tool_result, store, error, usage, conversation - src/features/agent/ -> LLM turn loop: domain (TurnEvent, AgentTurnParams) + application (turn_service, ports) + infrastructure (llm LlmClient + tools) - src/features/cms/ -> settings/conversation/memory persistence: domain + application (services) + infrastructure (persistence repos) - src/features/subagent/ -> orchestration: domain (AccessTier) + infrastructure (engine runner, context, provider, delegate, spawn_tools) - src/features/workflow/ -> multi-phase + hive-mind: domain + infrastructure - src/interfaces/ -> cli + tui (outer ring) tetap Subagent-runner (engine.ts runAgent, division.ts toolsFor) dipindah ke features/subagent (bukan agent tools) utk memutus coupling agent<->subagent. Alias tsconfig: @zesdex/domain -> shared/domain, + @zesdex/agent, @zesdex/agent-infra, @zesdex/cms, @zesdex/subagent, @zesdex/workflow, @zesdex/shared. Bersihkan dead: application/ports PasswordService/TokenService/AuthService. compose.ts (composition root) & bootstrap repoint ke barrel feature. Gates: tsc --noEmit 0 error, bun test 70 pass/0 fail, bun build 147 modules, ./dist/zesdex --headless -> real turn OK.
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
/**
|
|
||||||
* Zesdex Application Layer — port traits, use cases, turn service.
|
|
||||||
* Depends only on @zesdex/domain. Higher-level ports implemented by
|
|
||||||
* infrastructure adapters.
|
|
||||||
*/
|
|
||||||
export * from "./ports/index.ts";
|
|
||||||
export * from "./agent/index.ts";
|
|
||||||
export * from "./cms/index.ts";
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
/**
|
|
||||||
* Re-export of conversation types from core (matches Rust `cms/conversation.rs`).
|
|
||||||
*/
|
|
||||||
export type { Conversation } from "../core/conversation.ts";
|
|
||||||
export type { ChatMessage, Role } from "../core/message.ts";
|
|
||||||
export { newConversation, pushMessage, rebuildSystem, toApiMessages } from "../core/conversation.ts";
|
|
||||||
export { Roles } from "../core/message.ts";
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
/**
|
|
||||||
* Zesdex Domain Layer — pure types, value objects, and port interfaces.
|
|
||||||
* Zero framework dependencies, zero I/O. Mirrors the Rust `zesdex-domain` crate.
|
|
||||||
*/
|
|
||||||
export * from "./core/index.ts";
|
|
||||||
export * from "./cms/index.ts";
|
|
||||||
export * from "./agent/index.ts";
|
|
||||||
export * from "./subagent/mod.ts";
|
|
||||||
export * from "./workflow/mod.ts";
|
|
||||||
@@ -14,7 +14,7 @@ export interface ToolExecutor {
|
|||||||
|
|
||||||
/** Service for running agent turns asynchronously. */
|
/** Service for running agent turns asynchronously. */
|
||||||
export interface AgentTurnService {
|
export interface AgentTurnService {
|
||||||
runTurn(params: import("@zesdex/domain").AgentTurnParams): Promise<void>;
|
runTurn(params: import("@zesdex/agent").AgentTurnParams): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from "./turn_service.ts";
|
export * from "./turn_service.ts";
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Port traits (interfaces) to external services. Mirrors `apps/application/src/ports/`.
|
* Port traits (interfaces) that the Agent application layer exposes to
|
||||||
* Concrete implementations live in the infrastructure layer.
|
* its infrastructure. Concrete implementations live in
|
||||||
|
* `features/agent/infrastructure/`.
|
||||||
*/
|
*/
|
||||||
import type { ChatMessage, StreamEvent, ToolDef } from "@zesdex/domain";
|
import type { ChatMessage, StreamEvent, ToolDef } from "@zesdex/domain";
|
||||||
|
|
||||||
@@ -31,23 +32,3 @@ export interface ProviderService {
|
|||||||
signal?: AbortSignal,
|
signal?: AbortSignal,
|
||||||
): Promise<{ message: ChatMessage; usage: [number, number] | null }>;
|
): Promise<{ message: ChatMessage; usage: [number, number] | null }>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Abstraction for password hashing and verification. */
|
|
||||||
export interface PasswordService {
|
|
||||||
hash(password: string): Promise<string>;
|
|
||||||
verify(password: string, hash: string): Promise<boolean>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Abstraction for JWT-based token generation and verification. */
|
|
||||||
export interface TokenService {
|
|
||||||
/** Generate an `[access, refresh]` token pair for the given subject. */
|
|
||||||
generateTokens(sub: string): [string, string];
|
|
||||||
verifyAccessToken(token: string): string;
|
|
||||||
verifyRefreshToken(token: string): string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** High-level authentication service combining password + token issuance. */
|
|
||||||
export interface AuthService {
|
|
||||||
authenticate(password: string, hash: string): Promise<boolean>;
|
|
||||||
issueTokens(sub: string): [string, string];
|
|
||||||
}
|
|
||||||
+7
-5
@@ -3,23 +3,25 @@
|
|||||||
* `apps/application/src/agent/turn_service.rs`.
|
* `apps/application/src/agent/turn_service.rs`.
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
type AgentTurnParams,
|
|
||||||
type ChatMessage,
|
type ChatMessage,
|
||||||
type StreamEvent,
|
type StreamEvent,
|
||||||
type ToolCall,
|
type ToolCall,
|
||||||
type ToolDef,
|
type ToolDef,
|
||||||
type TurnEventSink,
|
|
||||||
type JsonValue,
|
type JsonValue,
|
||||||
systemMessage,
|
systemMessage,
|
||||||
userMessage,
|
userMessage,
|
||||||
assistantMessage,
|
assistantMessage,
|
||||||
toolResultMessage,
|
toolResultMessage,
|
||||||
|
sanitizeToolArguments,
|
||||||
|
} from "@zesdex/domain";
|
||||||
|
import {
|
||||||
|
type AgentTurnParams,
|
||||||
|
type TurnEventSink,
|
||||||
mainAgentPromptWithProjectContext,
|
mainAgentPromptWithProjectContext,
|
||||||
compactionPrompt,
|
compactionPrompt,
|
||||||
errorRecoveryNote,
|
errorRecoveryNote,
|
||||||
sanitizeToolArguments,
|
} from "@zesdex/agent";
|
||||||
} from "@zesdex/domain";
|
import type { ProviderService } from "./ports.ts";
|
||||||
import type { ProviderService } from "../ports/index.ts";
|
|
||||||
import type { ToolExecutor } from "./index.ts";
|
import type { ToolExecutor } from "./index.ts";
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* Domain types for agent lifecycle: turn events, session runtime, progress.
|
* Domain types for agent lifecycle: turn events, session runtime, progress.
|
||||||
* Mirrors `apps/domain/src/agent/mod.rs`.
|
* Mirrors `apps/domain/src/agent/mod.rs`.
|
||||||
*/
|
*/
|
||||||
import type { ChatMessage, JsonValue, ToolCallResult, UsageStats } from "../core/index.ts";
|
import type { ChatMessage, JsonValue, ToolCallResult, UsageStats } from "@zesdex/domain";
|
||||||
import type { AgentProgress } from "./progress.ts";
|
import type { AgentProgress } from "./progress.ts";
|
||||||
|
|
||||||
/** Which kind of caller (main agent vs subagent vs reviewer) is invoking a tool. */
|
/** Which kind of caller (main agent vs subagent vs reviewer) is invoking a tool. */
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/** Agent feature — LLM turn loop, tool-execution runtime, subagent-spawning tools.
|
||||||
|
* Vertical slice: domain (turn events/runtime) → application (turn service + ports)
|
||||||
|
* → infrastructure (LLM client + tool registry/executor). */
|
||||||
|
export * from "./domain/index.ts";
|
||||||
|
export * from "./application/index.ts";
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/** Agent infrastructure — concrete LLM client + tool-execution runtime.
|
||||||
|
* Consumed by the composition root. */
|
||||||
|
export { LlmClient, resolveApiKey } from "./llm/provider.ts";
|
||||||
|
export { InfrastructureToolExecutor } from "./tools/executor.ts";
|
||||||
|
export { allTools, toolDefs } from "./tools/registry.ts";
|
||||||
|
export { type ToolCtx } from "./tools/context.ts";
|
||||||
+3
-5
@@ -8,14 +8,12 @@ import {
|
|||||||
type StreamEvent,
|
type StreamEvent,
|
||||||
type ToolCall,
|
type ToolCall,
|
||||||
type ToolDef,
|
type ToolDef,
|
||||||
type Settings,
|
|
||||||
type AppConfig,
|
|
||||||
SseParser,
|
SseParser,
|
||||||
Roles,
|
Roles,
|
||||||
DEFAULT_API_BASE,
|
|
||||||
DEFAULT_MODEL,
|
|
||||||
} from "@zesdex/domain";
|
} from "@zesdex/domain";
|
||||||
import type { ProviderService } from "@zesdex/application";
|
import type { Settings, AppConfig } from "@zesdex/cms";
|
||||||
|
import { DEFAULT_API_BASE, DEFAULT_MODEL } from "@zesdex/agent";
|
||||||
|
import type { ProviderService } from "../../application/ports.ts";
|
||||||
|
|
||||||
const DEFAULT_BASE_URL = DEFAULT_API_BASE;
|
const DEFAULT_BASE_URL = DEFAULT_API_BASE;
|
||||||
const REQUEST_TIMEOUT_MS = 600_000;
|
const REQUEST_TIMEOUT_MS = 600_000;
|
||||||
+1
-1
@@ -7,7 +7,7 @@ import * as path from "node:path";
|
|||||||
import type { JsonValue } from "@zesdex/domain";
|
import type { JsonValue } from "@zesdex/domain";
|
||||||
import { type Tool, type ToolCtx } from "./mod.ts";
|
import { type Tool, type ToolCtx } from "./mod.ts";
|
||||||
import { argStr } from "./util.ts";
|
import { argStr } from "./util.ts";
|
||||||
import { bashControl } from "../bgbash/control.ts";
|
import { bashControl } from "./bgbash/control.ts";
|
||||||
|
|
||||||
/** Get the output of a background bash job by ID. */
|
/** Get the output of a background bash job by ID. */
|
||||||
export class BashOutput implements Tool {
|
export class BashOutput implements Tool {
|
||||||
+2
-2
@@ -2,8 +2,8 @@
|
|||||||
* Built-in best-practice tools. Mirrors `tools/best_practice.rs`.
|
* Built-in best-practice tools. Mirrors `tools/best_practice.rs`.
|
||||||
*/
|
*/
|
||||||
import type { JsonValue } from "@zesdex/domain";
|
import type { JsonValue } from "@zesdex/domain";
|
||||||
import { type Tool, type ToolCtx } from "../tools/mod.ts";
|
import { type Tool, type ToolCtx } from "../mod.ts";
|
||||||
import { argStr, optStr } from "../tools/util.ts";
|
import { argStr, optStr } from "../util.ts";
|
||||||
import { BestPracticeEngine } from "./engine.ts";
|
import { BestPracticeEngine } from "./engine.ts";
|
||||||
|
|
||||||
const engine = new BestPracticeEngine();
|
const engine = new BestPracticeEngine();
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* Tool execution context — shared state passed to every `Tool.run` call.
|
* Tool execution context — shared state passed to every `Tool.run` call.
|
||||||
* Mirrors `apps/infrastructure/src/tools/context.rs`.
|
* Mirrors `apps/infrastructure/src/tools/context.rs`.
|
||||||
*/
|
*/
|
||||||
import type { Origin, TurnEvent } from "@zesdex/domain";
|
import type { Origin, TurnEvent } from "@zesdex/agent";
|
||||||
|
|
||||||
/** Graduated check rule from project config. */
|
/** Graduated check rule from project config. */
|
||||||
export interface GraduatedCheck {
|
export interface GraduatedCheck {
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* Simple sink adapter that wraps a TurnEvent[] (array-based) into the
|
* Simple sink adapter that wraps a TurnEvent[] (array-based) into the
|
||||||
* TurnEventSink interface, providing a `push` method and a no-op `drain`.
|
* TurnEventSink interface, providing a `push` method and a no-op `drain`.
|
||||||
*/
|
*/
|
||||||
import type { TurnEvent, TurnEventSink } from "@zesdex/domain";
|
import type { TurnEvent, TurnEventSink } from "@zesdex/agent";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a TurnEventSink backed by a plain array.
|
* Create a TurnEventSink backed by a plain array.
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* Delete a memory by name. Mirrors `tools/memory/forget.rs`.
|
* Delete a memory by name. Mirrors `tools/memory/forget.rs`.
|
||||||
*/
|
*/
|
||||||
import type { JsonValue } from "@zesdex/domain";
|
import type { JsonValue } from "@zesdex/domain";
|
||||||
import { MarkdownMemoryRepository } from "../../persistence/cms/memory_repo.ts";
|
import { MarkdownMemoryRepository } from "@zesdex/cms";
|
||||||
import { type Tool, type ToolCtx } from "../mod.ts";
|
import { type Tool, type ToolCtx } from "../mod.ts";
|
||||||
import { argStr } from "../util.ts";
|
import { argStr } from "../util.ts";
|
||||||
import { resolveMemoryDir } from "./mod.ts";
|
import { resolveMemoryDir } from "./mod.ts";
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* Recall previously saved memories. Mirrors `tools/memory/recall.rs`.
|
* Recall previously saved memories. Mirrors `tools/memory/recall.rs`.
|
||||||
*/
|
*/
|
||||||
import type { JsonValue } from "@zesdex/domain";
|
import type { JsonValue } from "@zesdex/domain";
|
||||||
import { MarkdownMemoryRepository } from "../../persistence/cms/memory_repo.ts";
|
import { MarkdownMemoryRepository } from "@zesdex/cms";
|
||||||
import { type Tool, type ToolCtx } from "../mod.ts";
|
import { type Tool, type ToolCtx } from "../mod.ts";
|
||||||
import { optStr } from "../util.ts";
|
import { optStr } from "../util.ts";
|
||||||
import { resolveMemoryDir } from "./mod.ts";
|
import { resolveMemoryDir } from "./mod.ts";
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* Remember a lesson or fact as persistent memory. Mirrors `tools/memory/remember.rs`.
|
* Remember a lesson or fact as persistent memory. Mirrors `tools/memory/remember.rs`.
|
||||||
*/
|
*/
|
||||||
import type { JsonValue } from "@zesdex/domain";
|
import type { JsonValue } from "@zesdex/domain";
|
||||||
import { MarkdownMemoryRepository } from "../../persistence/cms/memory_repo.ts";
|
import { MarkdownMemoryRepository } from "@zesdex/cms";
|
||||||
import { type Tool, type ToolCtx } from "../mod.ts";
|
import { type Tool, type ToolCtx } from "../mod.ts";
|
||||||
import { argStr, optStr } from "../util.ts";
|
import { argStr, optStr } from "../util.ts";
|
||||||
import { resolveMemoryDir } from "./mod.ts";
|
import { resolveMemoryDir } from "./mod.ts";
|
||||||
+1
-1
@@ -59,7 +59,7 @@ export class ParallelDelegate implements Tool {
|
|||||||
|
|
||||||
// Delegate to subagent engine if available, else report the breakdown.
|
// Delegate to subagent engine if available, else report the breakdown.
|
||||||
try {
|
try {
|
||||||
const { runParallelDelegation } = await import("../subagent/delegate.ts");
|
const { runParallelDelegation } = await import("../../../subagent/infrastructure/delegate.ts");
|
||||||
return await runParallelDelegation(task, directives, synthesize, ctx);
|
return await runParallelDelegation(task, directives, synthesize, ctx);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const msg = (e as Error).message;
|
const msg = (e as Error).message;
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
/** Plan management tools — enter and mark ready. Mirrors `tools/plan.rs`. */
|
/** Plan management tools — enter and mark ready. Mirrors `tools/plan.rs`. */
|
||||||
import * as fs from "node:fs";
|
import * as fs from "node:fs";
|
||||||
import * as path from "node:path";
|
import * as path from "node:path";
|
||||||
import type { JsonValue, TurnEvent } from "@zesdex/domain";
|
import type { JsonValue } from "@zesdex/domain";
|
||||||
|
import type { TurnEvent } from "@zesdex/agent";
|
||||||
import { type Tool, type ToolCtx } from "./mod.ts";
|
import { type Tool, type ToolCtx } from "./mod.ts";
|
||||||
import { argStr } from "./util.ts";
|
import { argStr } from "./util.ts";
|
||||||
|
|
||||||
+1
-1
@@ -25,7 +25,7 @@ import { Cd, DirList, DirCacheUpdate, Pong, Todowrite, Todofinish } from "./util
|
|||||||
import { WebSearch } from "./web_search.ts";
|
import { WebSearch } from "./web_search.ts";
|
||||||
import { SemanticSearch, RebuildIndex, ListSymbols } from "./semantic/index.ts";
|
import { SemanticSearch, RebuildIndex, ListSymbols } from "./semantic/index.ts";
|
||||||
import { ParallelDelegate } from "./parallel_delegate.ts";
|
import { ParallelDelegate } from "./parallel_delegate.ts";
|
||||||
import { BestPractice, CommitConvention } from "../best_practice/tools.ts";
|
import { BestPractice, CommitConvention } from "./best_practice/tools.ts";
|
||||||
|
|
||||||
/** Construct one instance of every built-in tool. */
|
/** Construct one instance of every built-in tool. */
|
||||||
export function allTools(): Tool[] {
|
export function allTools(): Tool[] {
|
||||||
+2
-2
@@ -39,8 +39,8 @@ export class Bash implements Tool {
|
|||||||
|
|
||||||
if (runInBackground) {
|
if (runInBackground) {
|
||||||
// Background jobs handled via bgbash registry
|
// Background jobs handled via bgbash registry
|
||||||
const { spawnBashJob } = await import("../../bgbash/job.ts");
|
const { spawnBashJob } = await import("../bgbash/job.ts");
|
||||||
const { bashControl } = await import("../../bgbash/control.ts");
|
const { bashControl } = await import("../bgbash/control.ts");
|
||||||
const job = spawnBashJob(cmd);
|
const job = spawnBashJob(cmd);
|
||||||
bashControl().register(job);
|
bashControl().register(job);
|
||||||
return `Background job: ${job.id}`;
|
return `Background job: ${job.id}`;
|
||||||
+2
-2
@@ -33,7 +33,7 @@ export class SpawnAgents implements Tool {
|
|||||||
async run(ctx: ToolCtx, args: JsonValue): Promise<string> {
|
async run(ctx: ToolCtx, args: JsonValue): Promise<string> {
|
||||||
const agents = reqArray(args, "agents");
|
const agents = reqArray(args, "agents");
|
||||||
try {
|
try {
|
||||||
const { spawnAgents } = await import("../subagent/spawn_tools.ts");
|
const { spawnAgents } = await import("../../../subagent/infrastructure/spawn_tools.ts");
|
||||||
return await spawnAgents(agents as Array<{ directive: string; access: string }>, ctx);
|
return await spawnAgents(agents as Array<{ directive: string; access: string }>, ctx);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const msg = (e as Error).message;
|
const msg = (e as Error).message;
|
||||||
@@ -71,7 +71,7 @@ export class SpawnPipeline implements Tool {
|
|||||||
async run(ctx: ToolCtx, args: JsonValue): Promise<string> {
|
async run(ctx: ToolCtx, args: JsonValue): Promise<string> {
|
||||||
const stages = reqArray(args, "stages");
|
const stages = reqArray(args, "stages");
|
||||||
try {
|
try {
|
||||||
const { spawnPipeline } = await import("../subagent/spawn_tools.ts");
|
const { spawnPipeline } = await import("../../../subagent/infrastructure/spawn_tools.ts");
|
||||||
return await spawnPipeline(stages as Array<{ directive: string; access: string }>, ctx);
|
return await spawnPipeline(stages as Array<{ directive: string; access: string }>, ctx);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const msg = (e as Error).message;
|
const msg = (e as Error).message;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user