feat(goal): split the pure type outlet and register the 'goal' projection unit

dsh-goal/types becomes the client-safe pure outlet (tool-todo dual-outlet
shape): GoalId/GoalRef/GoalPhase/GoalBlockReason/GoalSnapshot, the new
GoalProjection payload, and the SessionProjectionMap 'goal' key merge — zero
host imports. Host-coupled vocabulary (GoalView/activation, change metas,
message source, folds, GoalError codes, the scoped goal/changed event) moves
to src/domain.ts, re-exported from the package root. ./client re-exports the
outlet for client aggregates.

GoalService registers the projection unit under ctx.inject(['sessionProjections']):
applyGoalProjection is a projection-grade last-wins fold — plain-JSON state,
same-reference return on non-goal or malformed events (a throwing apply
would tear down the registry drive; strict validation stays with the write
side and foldGoal). Activation is process-local and deliberately absent from
the projection value.
This commit is contained in:
imccyu
2026-07-28 21:31:30 +08:00
parent 1c2923c84f
commit c991f76cef
12 changed files with 442 additions and 130 deletions
+2
View File
@@ -46,6 +46,8 @@
"@deepseek-ai/dsh-tool-todo/client": ["./packages/todo/tool-todo/src/client.ts"],
"@deepseek-ai/dsh-session-title/types": ["./packages/session-title/session-title/src/types.ts"],
"@deepseek-ai/dsh-session-title/client": ["./packages/session-title/session-title/src/client.ts"],
"@deepseek-ai/dsh-goal/types": ["./packages/goal/goal/src/types.ts"],
"@deepseek-ai/dsh-goal/client": ["./packages/goal/goal/src/client.ts"],
"@deepseek-ai/dsh-llm/types": ["./packages/llm/llm/src/types.ts"],
"@deepseek-ai/dsh-llm/brand": ["./packages/llm/llm/src/brand.ts"],
"@deepseek-ai/dsh-llm/message": ["./packages/llm/llm/src/message.ts"],