diff --git a/docs/config-catalog.md b/docs/config-catalog.md index b7d8e9edd6..30c448ba03 100644 --- a/docs/config-catalog.md +++ b/docs/config-catalog.md @@ -71,7 +71,7 @@ export interface Config { Depends on: [`agentCore`](../packages/examples/agent-spine-demo/src/index.ts) · [`ToolsConfig`](#deepseek-aidsh-tools) -Source: [`packages/examples/acp-demo/src/index.ts:32`](../packages/examples/acp-demo/src/index.ts) +Source: [`packages/examples/acp-demo/src/index.ts:33`](../packages/examples/acp-demo/src/index.ts) ## `@deepseek-ai/dsh-agent-loop` @@ -827,7 +827,7 @@ export interface Config { Depends on: [`agentCore`](../packages/examples/agent-spine-demo/src/index.ts) · [`ToolsConfig`](#deepseek-aidsh-tools) -Source: [`packages/examples/stdio-demo/src/index.ts:38`](../packages/examples/stdio-demo/src/index.ts) +Source: [`packages/examples/stdio-demo/src/index.ts:40`](../packages/examples/stdio-demo/src/index.ts) ## `@deepseek-ai/dsh-subagent-acp` diff --git a/packages/examples/acp-demo/src/index.ts b/packages/examples/acp-demo/src/index.ts index caa6ffd582..6785e5f957 100644 --- a/packages/examples/acp-demo/src/index.ts +++ b/packages/examples/acp-demo/src/index.ts @@ -19,6 +19,7 @@ import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' import UserInteractionService from '@deepseek-ai/dsh-user-interaction' export const name = 'acp-demo' +const DEFAULT_PERSISTENCE_ROOT = './.sessions' /** * App config: the swappable per-deployment values. `provider` and `model` configure the @@ -70,9 +71,7 @@ export const Config: z = z.object({ toolOrder: z.array(z.string()).default(undefined as unknown as string[]), tools: ToolRegistry.Config, dshHome: z.string(), - // TODO(single-default-literal): share this schema default and the defensive - // apply() fallback through one named constant while retaining both boundaries. - persistenceRoot: z.string().default('./.sessions'), + persistenceRoot: z.string().default(DEFAULT_PERSISTENCE_ROOT), workspaceContext: z.union([z.const(false), workspaceContext.Config]).required(), skills: agentCore.SkillConfigSchema, toolBash: agentCore.ToolBashConfigSchema, @@ -90,6 +89,6 @@ export const Config: z = z.object({ export function apply(ctx: Context, config: Config): void { ctx.plugin(agentCore, agentCore.pickSpineConfig(config)) ctx.plugin(UserInteractionService) - ctx.plugin(SessionPersistenceJsonl, { root: config.persistenceRoot ?? './.sessions' }) + ctx.plugin(SessionPersistenceJsonl, { root: config.persistenceRoot ?? DEFAULT_PERSISTENCE_ROOT }) ctx.plugin(acp, { provider: config.provider, model: config.model }) } diff --git a/packages/examples/acp-demo/tests/acp-agent.spec.ts b/packages/examples/acp-demo/tests/acp-agent.spec.ts index c033056f12..10ee749f8c 100644 --- a/packages/examples/acp-demo/tests/acp-agent.spec.ts +++ b/packages/examples/acp-demo/tests/acp-agent.spec.ts @@ -83,7 +83,7 @@ describe('dsh-acp-demo composition', () => { }) it('defaults the persistence root when omitted', async () => { - // Exercises the `?? './.sessions'` fallback for a direct-apply caller that + // Exercises the `DEFAULT_PERSISTENCE_ROOT` fallback for a direct-apply caller that // bypasses the schema's `.default(...)`: call `apply` directly (not via // `ctx.plugin`, which validates+defaults the config first) with no // persistenceRoot, so the runtime fallback is the one that fires. diff --git a/packages/examples/stdio-demo/src/index.ts b/packages/examples/stdio-demo/src/index.ts index 71196ed647..0fb43cdff1 100644 --- a/packages/examples/stdio-demo/src/index.ts +++ b/packages/examples/stdio-demo/src/index.ts @@ -24,6 +24,8 @@ import * as toolAskUser from '@deepseek-ai/dsh-tool-ask-user' import * as uiStdio from '@deepseek-ai/dsh-stdio' export const name = 'stdio-demo' +const DEFAULT_PERSISTENCE_ROOT = './.sessions' +const DEFAULT_WELCOME = 'ready.' /** * App config: the swappable per-demo values, each routed to where the app wires @@ -81,10 +83,8 @@ export const Config: z = z.object({ toolOrder: z.array(z.string()).default(undefined as unknown as string[]), tools: ToolRegistry.Config, dshHome: z.string(), - // TODO(single-default-literal): share these schema defaults and defensive - // apply() fallbacks through named constants while retaining both boundaries. - persistenceRoot: z.string().default('./.sessions'), - welcome: z.string().default('ready.'), + persistenceRoot: z.string().default(DEFAULT_PERSISTENCE_ROOT), + welcome: z.string().default(DEFAULT_WELCOME), skills: agentCore.SkillConfigSchema, toolBash: agentCore.ToolBashConfigSchema, toolTasks: agentCore.ToolTasksConfigSchema, @@ -104,10 +104,10 @@ export function apply(ctx: Context, config: Config): void { const resumeSessionId = config.resumeSessionId === '' ? undefined : config.resumeSessionId const sessionId = SessionId(resumeSessionId ?? `main-session-${randomUUID()}`) ctx.plugin(ConsoleExporter) - ctx.plugin(SessionPersistenceJsonl, { root: config.persistenceRoot ?? './.sessions' }) + ctx.plugin(SessionPersistenceJsonl, { root: config.persistenceRoot ?? DEFAULT_PERSISTENCE_ROOT }) ctx.plugin(UserInteractionService) ctx.plugin(uiStdio, { - welcome: config.welcome ?? 'ready.', + welcome: config.welcome ?? DEFAULT_WELCOME, sessionId, }) ctx.plugin(agentCore, { diff --git a/packages/examples/stdio-demo/tests/stdio-agent.spec.ts b/packages/examples/stdio-demo/tests/stdio-agent.spec.ts index ddfc0ec95d..7ef169ff06 100644 --- a/packages/examples/stdio-demo/tests/stdio-agent.spec.ts +++ b/packages/examples/stdio-demo/tests/stdio-agent.spec.ts @@ -103,7 +103,7 @@ describe('dsh-stdio-demo app', () => { it('defaults persistenceRoot and welcome when omitted', async () => { // Direct apply (NOT via ctx.plugin, which validates+defaults the config - // first) so the runtime `?? './.sessions'` / `?? 'ready.'` fallbacks on + // first) so the runtime `DEFAULT_PERSISTENCE_ROOT` / `DEFAULT_WELCOME` fallbacks on // apply()'s last two lines are the ones that fire — covering a // schema-bypassing direct-mount caller. const ctx = new Context()