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:
asepharyana
2026-09-03 02:30:12 +07:00
parent 7e6ed34f0d
commit b5ebd07fa8
126 changed files with 157 additions and 166 deletions
-8
View File
@@ -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";
-7
View File
@@ -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";
-9
View File
@@ -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];
}
@@ -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. */
+5
View File
@@ -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";
@@ -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;
@@ -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,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();
@@ -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 {
@@ -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.
@@ -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";
@@ -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";
@@ -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";
@@ -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";
@@ -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[] {
@@ -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}`;
@@ -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