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 parent
7e6ed34f0d
commit
b5ebd07fa8
126 files changed
+157
-166
No files matched your search
@@ -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. */
|
||||
export interface AgentTurnService {
|
||||
runTurn(params: import("@zesdex/domain").AgentTurnParams): Promise<void>;
|
||||
runTurn(params: import("@zesdex/agent").AgentTurnParams): Promise<void>;
|
||||
}
|
||||
|
||||
export * from "./turn_service.ts";
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* Port traits (interfaces) to external services. Mirrors `apps/application/src/ports/`.
|
||||
* Concrete implementations live in the infrastructure layer.
|
||||
* Port traits (interfaces) that the Agent application layer exposes to
|
||||
* its infrastructure. Concrete implementations live in
|
||||
* `features/agent/infrastructure/`.
|
||||
*/
|
||||
import type { ChatMessage, StreamEvent, ToolDef } from "@zesdex/domain";
|
||||
|
||||
@@ -31,23 +32,3 @@ export interface ProviderService {
|
||||
signal?: AbortSignal,
|
||||
): 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];
|
||||
}
|
||||
File renamed without changes.
+7
-5
@@ -3,23 +3,25 @@
|
||||
* `apps/application/src/agent/turn_service.rs`.
|
||||
*/
|
||||
import {
|
||||
type AgentTurnParams,
|
||||
type ChatMessage,
|
||||
type StreamEvent,
|
||||
type ToolCall,
|
||||
type ToolDef,
|
||||
type TurnEventSink,
|
||||
type JsonValue,
|
||||
systemMessage,
|
||||
userMessage,
|
||||
assistantMessage,
|
||||
toolResultMessage,
|
||||
sanitizeToolArguments,
|
||||
} from "@zesdex/domain";
|
||||
import {
|
||||
type AgentTurnParams,
|
||||
type TurnEventSink,
|
||||
mainAgentPromptWithProjectContext,
|
||||
compactionPrompt,
|
||||
errorRecoveryNote,
|
||||
sanitizeToolArguments,
|
||||
} from "@zesdex/domain";
|
||||
import type { ProviderService } from "../ports/index.ts";
|
||||
} from "@zesdex/agent";
|
||||
import type { ProviderService } from "./ports.ts";
|
||||
import type { ToolExecutor } from "./index.ts";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
File renamed without changes.
File renamed without changes.
@@ -2,7 +2,7 @@
|
||||
* Domain types for agent lifecycle: turn events, session runtime, progress.
|
||||
* 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";
|
||||
|
||||
/** Which kind of caller (main agent vs subagent vs reviewer) is invoking a tool. */
|
||||
File renamed without changes.
File renamed without changes.
@@ -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";
|
||||
File renamed without changes.
+3
-5
@@ -8,14 +8,12 @@ import {
|
||||
type StreamEvent,
|
||||
type ToolCall,
|
||||
type ToolDef,
|
||||
type Settings,
|
||||
type AppConfig,
|
||||
SseParser,
|
||||
Roles,
|
||||
DEFAULT_API_BASE,
|
||||
DEFAULT_MODEL,
|
||||
} 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 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 Tool, type ToolCtx } from "./mod.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. */
|
||||
export class BashOutput implements Tool {
|
||||
File renamed without changes.
+2
-2
@@ -2,8 +2,8 @@
|
||||
* Built-in best-practice tools. Mirrors `tools/best_practice.rs`.
|
||||
*/
|
||||
import type { JsonValue } from "@zesdex/domain";
|
||||
import { type Tool, type ToolCtx } from "../tools/mod.ts";
|
||||
import { argStr, optStr } from "../tools/util.ts";
|
||||
import { type Tool, type ToolCtx } from "../mod.ts";
|
||||
import { argStr, optStr } from "../util.ts";
|
||||
import { BestPracticeEngine } from "./engine.ts";
|
||||
|
||||
const engine = new BestPracticeEngine();
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -2,7 +2,7 @@
|
||||
* Tool execution context — shared state passed to every `Tool.run` call.
|
||||
* 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. */
|
||||
export interface GraduatedCheck {
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
* Simple sink adapter that wraps a TurnEvent[] (array-based) into the
|
||||
* 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.
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -2,7 +2,7 @@
|
||||
* Delete a memory by name. Mirrors `tools/memory/forget.rs`.
|
||||
*/
|
||||
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 { argStr } from "../util.ts";
|
||||
import { resolveMemoryDir } from "./mod.ts";
|
||||
File renamed without changes.
+1
-1
@@ -2,7 +2,7 @@
|
||||
* Recall previously saved memories. Mirrors `tools/memory/recall.rs`.
|
||||
*/
|
||||
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 { optStr } from "../util.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`.
|
||||
*/
|
||||
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 { argStr, optStr } from "../util.ts";
|
||||
import { resolveMemoryDir } from "./mod.ts";
|
||||
File renamed without changes.
+1
-1
@@ -59,7 +59,7 @@ export class ParallelDelegate implements Tool {
|
||||
|
||||
// Delegate to subagent engine if available, else report the breakdown.
|
||||
try {
|
||||
const { runParallelDelegation } = await import("../subagent/delegate.ts");
|
||||
const { runParallelDelegation } = await import("../../../subagent/infrastructure/delegate.ts");
|
||||
return await runParallelDelegation(task, directives, synthesize, ctx);
|
||||
} catch (e) {
|
||||
const msg = (e as Error).message;
|
||||
@@ -1,7 +1,8 @@
|
||||
/** Plan management tools — enter and mark ready. Mirrors `tools/plan.rs`. */
|
||||
import * as fs from "node:fs";
|
||||
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 { argStr } from "./util.ts";
|
||||
|
||||
File renamed without changes.
+1
-1
@@ -25,7 +25,7 @@ import { Cd, DirList, DirCacheUpdate, Pong, Todowrite, Todofinish } from "./util
|
||||
import { WebSearch } from "./web_search.ts";
|
||||
import { SemanticSearch, RebuildIndex, ListSymbols } from "./semantic/index.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. */
|
||||
export function allTools(): Tool[] {
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -39,8 +39,8 @@ export class Bash implements Tool {
|
||||
|
||||
if (runInBackground) {
|
||||
// Background jobs handled via bgbash registry
|
||||
const { spawnBashJob } = await import("../../bgbash/job.ts");
|
||||
const { bashControl } = await import("../../bgbash/control.ts");
|
||||
const { spawnBashJob } = await import("../bgbash/job.ts");
|
||||
const { bashControl } = await import("../bgbash/control.ts");
|
||||
const job = spawnBashJob(cmd);
|
||||
bashControl().register(job);
|
||||
return `Background job: ${job.id}`;
|
||||
File renamed without changes.
File renamed without changes.
+2
-2
@@ -33,7 +33,7 @@ export class SpawnAgents implements Tool {
|
||||
async run(ctx: ToolCtx, args: JsonValue): Promise<string> {
|
||||
const agents = reqArray(args, "agents");
|
||||
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);
|
||||
} catch (e) {
|
||||
const msg = (e as Error).message;
|
||||
@@ -71,7 +71,7 @@ export class SpawnPipeline implements Tool {
|
||||
async run(ctx: ToolCtx, args: JsonValue): Promise<string> {
|
||||
const stages = reqArray(args, "stages");
|
||||
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);
|
||||
} catch (e) {
|
||||
const msg = (e as Error).message;
|
||||
Loaded 50 of 126 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user