@deepseek-ai/dsh-goal 0.1.3-alpha.2 → 0.1.5-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/goal/goal/README.md
5
- README.md: 119c5e246494c7cb14c84b18e03ca04155f2158c
6
- README.zh.md: f17d9fa6b84fff50c3c7263c92725959bde99775
5
+ README.md: 7810fbb5f78aab73b2959538f1dc8fe64b2b5d62
6
+ README.zh.md: 0852254f4bb6a7e239f3dd8b0134e0170567e1a7
package/README.md CHANGED
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- `dsh-goal` keeps one durable completion objective per agent session: the goal's text, phase, round count, and revision history live in the session log, so they survive session resume, fork, and process restarts. You can create, edit, pause, resume, complete, block, and clear a goal, and every mutation is compare-and-set, so a stale view cannot clobber newer state. A goal carries a round cap (default 256) that bounds automatic continuation, and a blocked goal keeps a stable policy code plus a human explanation. It is state, not a scheduler: the service decides nothing about when work continues, and continuation permission is process-local and never persisted. Choose it when one long-running objective should span many turns; skip it for routine single-turn work.
12
+ `dsh-goal` lets one long-running completion objective persist across turns, session resume, fork, and process restarts. Users and agents can create, edit, pause, resume, complete, block, or clear it; compare-and-set updates reject stale views. A configurable round cap (256 by default) bounds automatic continuation, and blocked goals retain a stable policy code with a human-readable explanation. The package stores goal state but does not schedule work, and continuation permission remains process-local rather than durable. Choose it for one objective spanning many turns; skip it for routine single-turn work or parallel objectives.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -106,14 +106,14 @@ This section explains how the service realizes the behavior above; the observabl
106
106
  |---|---|
107
107
  | [`src/index.ts`](src/index.ts) | Plugin entry: `GoalService`, config schema, mutations, activation cache, projection unit |
108
108
  | [`src/domain.ts`](src/domain.ts) | Durable change payloads, `goal/changed` event, goal message-source attribution |
109
- | [`src/types.ts`](src/types.ts) | Pure client-safe types: `GoalView`, `GoalSnapshot`, projection-key declaration |
109
+ | [`src/types.ts`](src/types.ts) | Pure client-safe types: `GoalView`, `GoalSnapshot`, `GoalActivationChanged`, projection-key declaration |
110
110
  | [`src/fold.ts`](src/fold.ts) | Strict replay fold and decoder for durable goal changes |
111
111
  | [`src/runtime.ts`](src/runtime.ts) | `GoalId` brand, `GoalError` codes, change-version constant |
112
112
  | [`src/invariant.ts`](src/invariant.ts) | Invariant companion: independent incremental fold over every attached session |
113
113
 
114
114
  ### Events and attribution
115
115
 
116
- `goal/changed` fires after the durable event commits, with listener failures contained; the payload carries the operation, the exact ref, and the fresh view (absent for a clear tombstone). Admitted continuation rounds are attributed through `GoalMessageSource { goalId, revision, round }` on the `user/message` event, which the strict fold validates as the next admitted round of the current goal.
116
+ `goal/changed` fires after the durable event commits, with listener failures contained; the payload carries the operation, the exact ref, and the fresh view (absent for a clear tombstone). `goal/activation-changed` forwards a process-local `armed`/`disarmed` edge with the exact current ref, or no goal after a clear, without changing durable state. Admitted continuation rounds are attributed through `GoalMessageSource { goalId, revision, round }` on the `user/message` event, which the strict fold validates as the next admitted round of the current goal.
117
117
 
118
118
  </details>
119
119
 
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- `dsh-goal` 为每个 agent 会话保留一个持久的完成目标:目标的文本、phase、Round 数量与 revision 历史都保存在会话日志中,因此会话 resume(恢复)、fork 与进程重启后依然存在。你可以 create、edit、pause、resume、complete、block 和 clear 一个 goal,且每次变更都是比较并设置,陈旧的视图不会覆盖更新的状态。goal 带有 Round 上限(默认 256)以约束自动续行,被阻塞的 goal 会保留稳定的策略代码和面向人的说明。它是状态而非调度器:服务不决定工作何时继续,续行权限是进程本地的且绝不持久化。当单个长期目标需要横跨多轮时选择它;常规单轮工作不要使用。
12
+ `dsh-goal` 让一个长期完成目标在多轮、会话 resume(恢复)、fork 与进程重启后持续存在。用户与 agent 可以 create、edit、pause、resume、complete、block 或 clear 该目标;比较并设置的更新会拒绝陈旧视图。可配置的 Round 上限(默认 256)约束自动续行,被阻塞的 goal 会保留稳定的策略代码和面向人的说明。本包存储 goal 状态但不调度工作,续行权限是进程本地的而非持久状态。单个目标需要横跨多轮时选择本包;常规单轮工作或并行目标不要使用。
13
13
 
14
14
  ## 目录
15
15
 
@@ -106,14 +106,14 @@ view.activation // 'armed' | 'disarmed' — not persisted
106
106
  |---|---|
107
107
  | [`src/index.ts`](src/index.ts) | 插件入口:`GoalService`、config schema、变更、续行启用缓存、投影单元 |
108
108
  | [`src/domain.ts`](src/domain.ts) | 持久变更载荷、`goal/changed` 事件、goal 消息来源归属 |
109
- | [`src/types.ts`](src/types.ts) | 纯客户端安全类型:`GoalView`、`GoalSnapshot`、投影键声明 |
109
+ | [`src/types.ts`](src/types.ts) | 纯客户端安全类型:`GoalView`、`GoalSnapshot`、`GoalActivationChanged`、投影键声明 |
110
110
  | [`src/fold.ts`](src/fold.ts) | 持久 goal 变更的严格回放折叠与解码器 |
111
111
  | [`src/runtime.ts`](src/runtime.ts) | `GoalId` 品牌、`GoalError` 代码、变更版本常量 |
112
112
  | [`src/invariant.ts`](src/invariant.ts) | 不变式伴生:对每个已挂接会话的独立增量折叠 |
113
113
 
114
114
  ### 事件与归属
115
115
 
116
- `goal/changed` 在持久事件提交后触发,监听器失败会被隔离;载荷携带操作、精确 ref 与最新视图(clear tombstone 时省略)。已准入的续行 Round 通过 `user/message` 事件上的 `GoalMessageSource { goalId, revision, round }` 归属,严格折叠会将其验证为当前 goal 的下一个已准入 Round。
116
+ `goal/changed` 在持久事件提交后触发,监听器失败会被隔离;载荷携带操作、精确 ref 与最新视图(clear tombstone 时省略)。`goal/activation-changed` 在不改变持久状态的情况下,转发携带精确当前 ref 的进程本地 `armed`/`disarmed` 边界;clear 后则不携带 goal。已准入的续行 Round 通过 `user/message` 事件上的 `GoalMessageSource { goalId, revision, round }` 归属,严格折叠会将其验证为当前 goal 的下一个已准入 Round。
117
117
 
118
118
  </details>
119
119
 
package/lib/index.js CHANGED
@@ -483,6 +483,7 @@ function resolveBlockReason(reason) {
483
483
  let GoalService = (() => {
484
484
  let _classSuper = TypertRemoteService;
485
485
  let _instanceExtraInitializers = [];
486
+ let _get_decorators;
486
487
  let _edit_decorators;
487
488
  let _pause_decorators;
488
489
  let _resume_decorators;
@@ -492,12 +493,24 @@ let GoalService = (() => {
492
493
  return class GoalService extends _classSuper {
493
494
  static {
494
495
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
496
+ _get_decorators = [Remote("get")];
495
497
  _edit_decorators = [Remote("edit")];
496
498
  _pause_decorators = [Remote("pause")];
497
499
  _resume_decorators = [Remote("resume")];
498
500
  _complete_decorators = [Remote("complete")];
499
501
  _clear_decorators = [Remote("clear")];
500
502
  _remoteExportCreate_decorators = [Remote("create")];
503
+ __esDecorate(this, null, _get_decorators, {
504
+ kind: "method",
505
+ name: "get",
506
+ static: false,
507
+ private: false,
508
+ access: {
509
+ has: (obj) => "get" in obj,
510
+ get: (obj) => obj.get
511
+ },
512
+ metadata: _metadata
513
+ }, null, _instanceExtraInitializers);
501
514
  __esDecorate(this, null, _edit_decorators, {
502
515
  kind: "method",
503
516
  name: "edit",
@@ -579,13 +592,14 @@ let GoalService = (() => {
579
592
  super(ctx, "goals");
580
593
  this.resolved = { defaultMaxGoalRounds: resolveMaxGoalRounds(config.defaultMaxGoalRounds ?? 256) };
581
594
  ctx.on("agent/session-start", ({ agent }) => {
582
- this.runtimeState(agent.session).activation = "disarmed";
595
+ this.setActivation(agent.session, "disarmed");
583
596
  });
584
597
  ctx.sessionProjections.register(goalProjectionDefinition);
585
598
  ctx.on("session/event", (session, event) => {
586
599
  if (event.type !== "goal/change") return;
587
600
  const runtime = this.runtimeState(session);
588
- runtime.activation = runtime.pendingActivation !== void 0 && SessionSeq(runtime.pendingActivation.offset) === event.seq ? runtime.pendingActivation.activation : "disarmed";
601
+ const activation = runtime.pendingActivation !== void 0 && SessionSeq(runtime.pendingActivation.offset) === event.seq ? runtime.pendingActivation.activation : "disarmed";
602
+ this.setActivation(session, activation);
589
603
  });
590
604
  }
591
605
  /**
@@ -607,8 +621,8 @@ let GoalService = (() => {
607
621
  */
608
622
  disarm(agent) {
609
623
  this.assertLive(agent);
624
+ this.setActivation(agent.session, "disarmed");
610
625
  const runtime = this.runtimeState(agent.session);
611
- runtime.activation = "disarmed";
612
626
  return this.view(this.state(agent.session), runtime);
613
627
  }
614
628
  /**
@@ -771,6 +785,25 @@ let GoalService = (() => {
771
785
  this.runtimeStates.set(session, runtime);
772
786
  return runtime;
773
787
  }
788
+ /** Publish one process-local activation edge when it actually changes. */
789
+ setActivation(session, activation) {
790
+ const runtime = this.runtimeState(session);
791
+ if (runtime.activation === activation) return;
792
+ runtime.activation = activation;
793
+ const state = this.ctx.sessionProjections.stateOf(session, "goal");
794
+ /* v8 ignore next -- static inject requires the projection registry before this service activates. */
795
+ if (state === void 0) return;
796
+ if (state.failure !== null) return;
797
+ const goal = this.view(state.current, runtime);
798
+ this.ctx.emit("goal/activation-changed", {
799
+ sessionId: session.id,
800
+ ...goal === void 0 ? {} : { goal: {
801
+ id: goal.id,
802
+ revision: goal.revision,
803
+ activation: goal.activation
804
+ } }
805
+ });
806
+ }
774
807
  /** Build a new revision with one replacement phase. */
775
808
  withPhase(current, phase) {
776
809
  return {
@@ -65,6 +65,22 @@ const _deepseek_ai_dsh_goal_goals_edit_result$schema = z.object({
65
65
  'id': z.intersection(z.string(), z.unknown()).readonly(),
66
66
  'revision': z.number().readonly(),
67
67
  })
68
+ const _deepseek_ai_dsh_goal_goals_get_parameter_0$schema = z.intersection(z.string(), z.unknown())
69
+ const _deepseek_ai_dsh_goal_goals_get_result$schema = z.union([z.undefined(), z.object({
70
+ 'roundsStarted': z.number().readonly(),
71
+ 'createdAt': z.number().readonly(),
72
+ 'updatedAt': z.number().readonly(),
73
+ 'activation': z.union([z.literal("armed"), z.literal("disarmed")]).readonly(),
74
+ 'objective': z.string().readonly(),
75
+ 'phase': z.union([z.literal("active"), z.literal("paused"), z.literal("blocked"), z.literal("complete")]).readonly(),
76
+ 'blockedReason': z.object({
77
+ 'code': z.string().readonly(),
78
+ 'message': z.string().readonly(),
79
+ }).readonly().optional(),
80
+ 'maxGoalRounds': z.number().readonly(),
81
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
82
+ 'revision': z.number().readonly(),
83
+ })])
68
84
  const _deepseek_ai_dsh_goal_goals_pause_parameter_0$schema = z.intersection(z.string(), z.unknown())
69
85
  const _deepseek_ai_dsh_goal_goals_pause_parameter_1$schema = z.object({
70
86
  'id': z.intersection(z.string(), z.unknown()).readonly(),
@@ -150,7 +166,7 @@ export const TYPERT = {
150
166
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalRef',
151
167
  schema: _deepseek_ai_dsh_goal_goals_clear_result$schema,
152
168
  },
153
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":431,"column":3},
169
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":433,"column":3},
154
170
  },
155
171
  {
156
172
  id: '@deepseek-ai/dsh-goal#goals/complete',
@@ -190,7 +206,7 @@ export const TYPERT = {
190
206
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
191
207
  schema: _deepseek_ai_dsh_goal_goals_complete_result$schema,
192
208
  },
193
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":389,"column":3},
209
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":391,"column":3},
194
210
  },
195
211
  {
196
212
  id: '@deepseek-ai/dsh-goal#goals/create',
@@ -231,7 +247,7 @@ export const TYPERT = {
231
247
  typeSymbol: '@deepseek-ai/dsh-goal/client#CreateGoalResult',
232
248
  schema: _deepseek_ai_dsh_goal_goals_create_result$schema,
233
249
  },
234
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":623,"column":3},
250
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":647,"column":3},
235
251
  },
236
252
  {
237
253
  id: '@deepseek-ai/dsh-goal#goals/edit',
@@ -281,7 +297,37 @@ export const TYPERT = {
281
297
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
282
298
  schema: _deepseek_ai_dsh_goal_goals_edit_result$schema,
283
299
  },
284
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":327,"column":3},
300
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":329,"column":3},
301
+ },
302
+ {
303
+ id: '@deepseek-ai/dsh-goal#goals/get',
304
+ service: 'goals',
305
+ namespace: 'goals',
306
+ method: 'get',
307
+ invocation: { kind: 'direct' },
308
+ scope: {
309
+ context: 'agent',
310
+ wire: 'agentId',
311
+ },
312
+ parameters: [
313
+ {
314
+ name: 'agent',
315
+ wire: 'agentId',
316
+ source: 'lookup',
317
+ lookup: 'agent',
318
+ codec: {
319
+ mode: 'strict',
320
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
321
+ schema: _deepseek_ai_dsh_goal_goals_get_parameter_0$schema,
322
+ },
323
+ },
324
+ ],
325
+ result: {
326
+ mode: 'strict',
327
+ typeSymbol: '@deepseek-ai/dsh-goal#goals/get:result',
328
+ schema: _deepseek_ai_dsh_goal_goals_get_result$schema,
329
+ },
330
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":277,"column":3},
285
331
  },
286
332
  {
287
333
  id: '@deepseek-ai/dsh-goal#goals/pause',
@@ -321,7 +367,7 @@ export const TYPERT = {
321
367
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
322
368
  schema: _deepseek_ai_dsh_goal_goals_pause_result$schema,
323
369
  },
324
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":350,"column":3},
370
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":352,"column":3},
325
371
  },
326
372
  {
327
373
  id: '@deepseek-ai/dsh-goal#goals/resume',
@@ -361,7 +407,7 @@ export const TYPERT = {
361
407
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
362
408
  schema: _deepseek_ai_dsh_goal_goals_resume_result$schema,
363
409
  },
364
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":362,"column":3},
410
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":364,"column":3},
365
411
  },
366
412
  ],
367
413
  model: {
@@ -377,7 +423,7 @@ export const TYPERT = {
377
423
  {
378
424
  "kind": "method",
379
425
  "name": "get",
380
- "signature": "get(agent: Agent): GoalView | undefined",
426
+ "signature": "@Remote('get') get(agent: Agent): GoalView | undefined",
381
427
  "summary": "Read the current goal for one exact live agent.",
382
428
  "jsDoc": "/**\n * Read the current goal for one exact live agent.\n * @param agent - owning live agent.\n * @returns a fresh view or `undefined` when no goal is current.\n * @throws {@link GoalError} when the agent is not the registry's live instance.\n */"
383
429
  },
@@ -560,7 +606,7 @@ export const TYPERT = {
560
606
  },
561
607
  {
562
608
  "name": "EpochHeader",
563
- "declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n system?: string;\n tools?: ToolSchema[];\n}"
609
+ "declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n}"
564
610
  },
565
611
  {
566
612
  "name": "FileAttachmentRef",
@@ -640,7 +686,7 @@ export const TYPERT = {
640
686
  },
641
687
  {
642
688
  "name": "Inbox",
643
- "declaration": "export class Inbox {\n get nextTurn(): readonly UserMessage[];\n get nextStep(): readonly UserMessage[];\n get hasPending(): boolean;\n clear(): void;\n claim(target: InboxTarget, turn: number): UserMessage[];\n append(target: InboxTarget, message: UserMessage): void;\n prepend(target: InboxTarget, message: UserMessage): void;\n replace(messageId: MessageId, newMessage: UserMessage): boolean;\n remove(messageId: MessageId): boolean;\n splice(target: InboxTarget, start: number, deleteCount: number, inserted: UserMessage[]): UserMessage[];\n}"
689
+ "declaration": "export interface Inbox {\n readonly nextTurn: readonly UserMessage[];\n readonly nextStep: readonly UserMessage[];\n clear(): void;\n append(target: InboxTarget, message: UserMessage): void;\n prepend(target: InboxTarget, message: UserMessage): void;\n replace(messageId: MessageId, newMessage: UserMessage): boolean;\n remove(messageId: MessageId): boolean;\n splice(target: InboxTarget, start: number, deleteCount: number, inserted: UserMessage[]): UserMessage[];\n}"
644
690
  },
645
691
  {
646
692
  "name": "InboxTarget",
@@ -740,7 +786,7 @@ export const TYPERT = {
740
786
  },
741
787
  {
742
788
  "name": "RequestContext",
743
- "declaration": "export interface RequestContext {\n provider: string;\n model: string;\n contextWindow?: number;\n}"
789
+ "declaration": "export interface RequestContext {\n provider: string;\n model: string;\n contextWindow?: number;\n systemPromptUpdate?: SystemPromptUpdate;\n}"
744
790
  },
745
791
  {
746
792
  "name": "RequestHeaderReason",
@@ -756,11 +802,11 @@ export const TYPERT = {
756
802
  },
757
803
  {
758
804
  "name": "SessionEvent",
759
- "declaration": "export type SessionEvent<T extends SessionEventType = SessionEventType> = { [K in SessionEventType]: { type: K; seq: SessionSeq; time: number; data: SessionEventMap[K]; ignorable?: true; } & (K extends SurfaceEventType ? { sourceEventSeqs?: SessionSeq[]; surfaceOp?: SurfaceOp; } : object) }[T];"
805
+ "declaration": "export type SessionEvent<T extends SessionEventType = SessionEventType> = { [K in SessionEventType]: { type: K; seq: SessionSeq; time: number; data: SessionEventMap[K]; ignorable?: true; } & (K extends SurfaceEventType ? SurfaceIntent<K> : { surfaceOp?: never; sourceEventSeqs?: never; }) }[T];"
760
806
  },
761
807
  {
762
808
  "name": "SessionEventMap",
763
- "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/code-dispatch-start': PtcDispatchStartEventData;\n 'tool/code-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
809
+ "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
764
810
  },
765
811
  {
766
812
  "name": "SessionEventType",
@@ -832,7 +878,7 @@ export const TYPERT = {
832
878
  },
833
879
  {
834
880
  "name": "SurfaceEventType",
835
- "declaration": "export type SurfaceEventType = 'user/message' | 'assistant/message' | 'tool/result';"
881
+ "declaration": "export type SurfaceEventType = 'system/message' | 'user/message' | 'assistant/message' | 'tool/result';"
836
882
  },
837
883
  {
838
884
  "name": "SurfaceIntent",
@@ -840,7 +886,15 @@ export const TYPERT = {
840
886
  },
841
887
  {
842
888
  "name": "SurfaceOp",
843
- "declaration": "export type SurfaceOp = 'append' | { op: 'replace'; start: SessionSeq; end: SessionSeq; };"
889
+ "declaration": "export type SurfaceOp = 'append' | { op: 'replace'; startSeq: SessionSeq; endSeq: SessionSeq; };"
890
+ },
891
+ {
892
+ "name": "SystemMessage",
893
+ "declaration": "export interface SystemMessage extends Message {\n readonly role: 'system';\n readonly source: MessageSourceMap['plugin'];\n}"
894
+ },
895
+ {
896
+ "name": "SystemPromptUpdate",
897
+ "declaration": "export type SystemPromptUpdate = 'in-history';"
844
898
  },
845
899
  {
846
900
  "name": "TeamId",
@@ -938,6 +992,27 @@ export const TYPERT = {
938
992
  }
939
993
  ],
940
994
  "events": [
995
+ {
996
+ "description": "Process-local goal activation changed for one session.",
997
+ "summary": "Process-local goal activation changed for one session.",
998
+ "tags": [
999
+ {
1000
+ "name": "mode",
1001
+ "comment": "emit",
1002
+ "text": "@mode emit\n *"
1003
+ },
1004
+ {
1005
+ "name": "param",
1006
+ "argument": "payload",
1007
+ "comment": "- session id and the exact current goal activation, or no goal after a clear.",
1008
+ "text": "@param payload - session id and the exact current goal activation, or no goal after a clear."
1009
+ }
1010
+ ],
1011
+ "jsDoc": "/**\n * Process-local goal activation changed for one session.\n * @mode emit\n * @param payload - session id and the exact current goal activation, or no goal after a clear.\n */",
1012
+ "name": "goal/activation-changed",
1013
+ "mode": "emit",
1014
+ "signature": "'goal/activation-changed'(payload: GoalActivationChanged): void"
1015
+ },
941
1016
  {
942
1017
  "description": "Goal mutation accepted by one live agent. The matching `goal/change` session event has already committed. Listener failures are contained. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): agent-scoped listeners receive only that agent.",
943
1018
  "summary": "Goal mutation accepted by one live agent.",
@@ -12,6 +12,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
12
12
  complete: (agentId: SessionId, ref: GoalRef) => Promise<RemoteResult<GoalView>>
13
13
  create: (agentId: SessionId, request: CreateGoalRequest) => Promise<RemoteResult<CreateGoalResult>>
14
14
  edit: (agentId: SessionId, ref: GoalRef, request: EditGoalRequest) => Promise<RemoteResult<GoalView>>
15
+ get: (agentId: SessionId) => Promise<RemoteResult<GoalView | undefined>>
15
16
  pause: (agentId: SessionId, ref: GoalRef) => Promise<RemoteResult<GoalView>>
16
17
  resume: (agentId: SessionId, ref: GoalRef) => Promise<RemoteResult<GoalView>>
17
18
  }
@@ -20,6 +21,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
20
21
  'goals/complete': (agentId: SessionId, ref: GoalRef) => Promise<RemoteResult<GoalView>>
21
22
  'goals/create': (agentId: SessionId, request: CreateGoalRequest) => Promise<RemoteResult<CreateGoalResult>>
22
23
  'goals/edit': (agentId: SessionId, ref: GoalRef, request: EditGoalRequest) => Promise<RemoteResult<GoalView>>
24
+ 'goals/get': (agentId: SessionId) => Promise<RemoteResult<GoalView | undefined>>
23
25
  'goals/pause': (agentId: SessionId, ref: GoalRef) => Promise<RemoteResult<GoalView>>
24
26
  'goals/resume': (agentId: SessionId, ref: GoalRef) => Promise<RemoteResult<GoalView>>
25
27
  }
@@ -31,6 +33,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
31
33
  'agent:goals/complete': (ref: GoalRef) => Promise<RemoteResult<GoalView>>
32
34
  'agent:goals/create': (request: CreateGoalRequest) => Promise<RemoteResult<CreateGoalResult>>
33
35
  'agent:goals/edit': (ref: GoalRef, request: EditGoalRequest) => Promise<RemoteResult<GoalView>>
36
+ 'agent:goals/get': () => Promise<RemoteResult<GoalView | undefined>>
34
37
  'agent:goals/pause': (ref: GoalRef) => Promise<RemoteResult<GoalView>>
35
38
  'agent:goals/resume': (ref: GoalRef) => Promise<RemoteResult<GoalView>>
36
39
  }
@@ -65,6 +65,22 @@ const _deepseek_ai_dsh_goal_goals_edit_result$schema = z.object({
65
65
  'id': z.intersection(z.string(), z.unknown()).readonly(),
66
66
  'revision': z.number().readonly(),
67
67
  })
68
+ const _deepseek_ai_dsh_goal_goals_get_parameter_0$schema = z.intersection(z.string(), z.unknown())
69
+ const _deepseek_ai_dsh_goal_goals_get_result$schema = z.union([z.undefined(), z.object({
70
+ 'roundsStarted': z.number().readonly(),
71
+ 'createdAt': z.number().readonly(),
72
+ 'updatedAt': z.number().readonly(),
73
+ 'activation': z.union([z.literal("armed"), z.literal("disarmed")]).readonly(),
74
+ 'objective': z.string().readonly(),
75
+ 'phase': z.union([z.literal("active"), z.literal("paused"), z.literal("blocked"), z.literal("complete")]).readonly(),
76
+ 'blockedReason': z.object({
77
+ 'code': z.string().readonly(),
78
+ 'message': z.string().readonly(),
79
+ }).readonly().optional(),
80
+ 'maxGoalRounds': z.number().readonly(),
81
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
82
+ 'revision': z.number().readonly(),
83
+ })])
68
84
  const _deepseek_ai_dsh_goal_goals_pause_parameter_0$schema = z.intersection(z.string(), z.unknown())
69
85
  const _deepseek_ai_dsh_goal_goals_pause_parameter_1$schema = z.object({
70
86
  'id': z.intersection(z.string(), z.unknown()).readonly(),
@@ -147,7 +163,7 @@ export const TYPERT_REMOTE = {
147
163
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalRef',
148
164
  schema: _deepseek_ai_dsh_goal_goals_clear_result$schema,
149
165
  },
150
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":431,"column":3},
166
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":433,"column":3},
151
167
  },
152
168
  {
153
169
  id: '@deepseek-ai/dsh-goal#goals/complete',
@@ -187,7 +203,7 @@ export const TYPERT_REMOTE = {
187
203
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
188
204
  schema: _deepseek_ai_dsh_goal_goals_complete_result$schema,
189
205
  },
190
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":389,"column":3},
206
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":391,"column":3},
191
207
  },
192
208
  {
193
209
  id: '@deepseek-ai/dsh-goal#goals/create',
@@ -228,7 +244,7 @@ export const TYPERT_REMOTE = {
228
244
  typeSymbol: '@deepseek-ai/dsh-goal/client#CreateGoalResult',
229
245
  schema: _deepseek_ai_dsh_goal_goals_create_result$schema,
230
246
  },
231
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":623,"column":3},
247
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":647,"column":3},
232
248
  },
233
249
  {
234
250
  id: '@deepseek-ai/dsh-goal#goals/edit',
@@ -278,7 +294,37 @@ export const TYPERT_REMOTE = {
278
294
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
279
295
  schema: _deepseek_ai_dsh_goal_goals_edit_result$schema,
280
296
  },
281
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":327,"column":3},
297
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":329,"column":3},
298
+ },
299
+ {
300
+ id: '@deepseek-ai/dsh-goal#goals/get',
301
+ service: 'goals',
302
+ namespace: 'goals',
303
+ method: 'get',
304
+ invocation: { kind: 'direct' },
305
+ scope: {
306
+ context: 'agent',
307
+ wire: 'agentId',
308
+ },
309
+ parameters: [
310
+ {
311
+ name: 'agent',
312
+ wire: 'agentId',
313
+ source: 'lookup',
314
+ lookup: 'agent',
315
+ codec: {
316
+ mode: 'strict',
317
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
318
+ schema: _deepseek_ai_dsh_goal_goals_get_parameter_0$schema,
319
+ },
320
+ },
321
+ ],
322
+ result: {
323
+ mode: 'strict',
324
+ typeSymbol: '@deepseek-ai/dsh-goal#goals/get:result',
325
+ schema: _deepseek_ai_dsh_goal_goals_get_result$schema,
326
+ },
327
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":277,"column":3},
282
328
  },
283
329
  {
284
330
  id: '@deepseek-ai/dsh-goal#goals/pause',
@@ -318,7 +364,7 @@ export const TYPERT_REMOTE = {
318
364
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
319
365
  schema: _deepseek_ai_dsh_goal_goals_pause_result$schema,
320
366
  },
321
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":350,"column":3},
367
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":352,"column":3},
322
368
  },
323
369
  {
324
370
  id: '@deepseek-ai/dsh-goal#goals/resume',
@@ -358,7 +404,7 @@ export const TYPERT_REMOTE = {
358
404
  typeSymbol: '@deepseek-ai/dsh-goal/client#GoalView',
359
405
  schema: _deepseek_ai_dsh_goal_goals_resume_result$schema,
360
406
  },
361
- sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":362,"column":3},
407
+ sourceLocation: {"file":"packages/goal/goal/src/index.ts","line":364,"column":3},
362
408
  },
363
409
  ],
364
410
  }
@@ -136,6 +136,8 @@ export declare class GoalService extends TypertRemoteService {
136
136
  private state;
137
137
  /** Return the process-local activation state, initially disarmed. */
138
138
  private runtimeState;
139
+ /** Publish one process-local activation edge when it actually changes. */
140
+ private setActivation;
139
141
  /** Build a new revision with one replacement phase. */
140
142
  private withPhase;
141
143
  /** Shared validated phase transition. */
@@ -186,6 +186,7 @@ function resolveBlockReason(reason) {
186
186
  let GoalService = (() => {
187
187
  let _classSuper = TypertRemoteService;
188
188
  let _instanceExtraInitializers = [];
189
+ let _get_decorators;
189
190
  let _edit_decorators;
190
191
  let _pause_decorators;
191
192
  let _resume_decorators;
@@ -195,12 +196,14 @@ let GoalService = (() => {
195
196
  return class GoalService extends _classSuper {
196
197
  static {
197
198
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
199
+ _get_decorators = [Remote('get')];
198
200
  _edit_decorators = [Remote('edit')];
199
201
  _pause_decorators = [Remote('pause')];
200
202
  _resume_decorators = [Remote('resume')];
201
203
  _complete_decorators = [Remote('complete')];
202
204
  _clear_decorators = [Remote('clear')];
203
205
  _remoteExportCreate_decorators = [Remote('create')];
206
+ __esDecorate(this, null, _get_decorators, { kind: "method", name: "get", static: false, private: false, access: { has: obj => "get" in obj, get: obj => obj.get }, metadata: _metadata }, null, _instanceExtraInitializers);
204
207
  __esDecorate(this, null, _edit_decorators, { kind: "method", name: "edit", static: false, private: false, access: { has: obj => "edit" in obj, get: obj => obj.edit }, metadata: _metadata }, null, _instanceExtraInitializers);
205
208
  __esDecorate(this, null, _pause_decorators, { kind: "method", name: "pause", static: false, private: false, access: { has: obj => "pause" in obj, get: obj => obj.pause }, metadata: _metadata }, null, _instanceExtraInitializers);
206
209
  __esDecorate(this, null, _resume_decorators, { kind: "method", name: "resume", static: false, private: false, access: { has: obj => "resume" in obj, get: obj => obj.resume }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -221,17 +224,18 @@ let GoalService = (() => {
221
224
  defaultMaxGoalRounds: resolveMaxGoalRounds(config.defaultMaxGoalRounds ?? 256),
222
225
  };
223
226
  ctx.on('agent/session-start', ({ agent }) => {
224
- this.runtimeState(agent.session).activation = 'disarmed';
227
+ this.setActivation(agent.session, 'disarmed');
225
228
  });
226
229
  ctx.sessionProjections.register(goalProjectionDefinition);
227
230
  ctx.on('session/event', (session, event) => {
228
231
  if (event.type !== 'goal/change')
229
232
  return;
230
233
  const runtime = this.runtimeState(session);
231
- runtime.activation = runtime.pendingActivation !== undefined
234
+ const activation = runtime.pendingActivation !== undefined
232
235
  && SessionSeq(runtime.pendingActivation.offset) === event.seq
233
236
  ? runtime.pendingActivation.activation
234
237
  : 'disarmed';
238
+ this.setActivation(session, activation);
235
239
  });
236
240
  }
237
241
  /**
@@ -253,8 +257,8 @@ let GoalService = (() => {
253
257
  */
254
258
  disarm(agent) {
255
259
  this.assertLive(agent);
260
+ this.setActivation(agent.session, 'disarmed');
256
261
  const runtime = this.runtimeState(agent.session);
257
- runtime.activation = 'disarmed';
258
262
  return this.view(this.state(agent.session), runtime);
259
263
  }
260
264
  /**
@@ -423,6 +427,30 @@ let GoalService = (() => {
423
427
  this.runtimeStates.set(session, runtime);
424
428
  return runtime;
425
429
  }
430
+ /** Publish one process-local activation edge when it actually changes. */
431
+ setActivation(session, activation) {
432
+ const runtime = this.runtimeState(session);
433
+ if (runtime.activation === activation)
434
+ return;
435
+ runtime.activation = activation;
436
+ const state = this.ctx.sessionProjections.stateOf(session, 'goal');
437
+ /* v8 ignore next -- static inject requires the projection registry before this service activates. */
438
+ if (state === undefined)
439
+ return;
440
+ if (state.failure !== null)
441
+ return;
442
+ const goal = this.view(state.current, runtime);
443
+ this.ctx.emit('goal/activation-changed', {
444
+ sessionId: session.id,
445
+ ...goal === undefined ? {} : {
446
+ goal: {
447
+ id: goal.id,
448
+ revision: goal.revision,
449
+ activation: goal.activation,
450
+ },
451
+ },
452
+ });
453
+ }
426
454
  /** Build a new revision with one replacement phase. */
427
455
  withPhase(current, phase) {
428
456
  return {
@@ -10,6 +10,7 @@
10
10
  * @module @deepseek-ai/dsh-goal/types
11
11
  */
12
12
  import type { Branded } from '@deepseek-ai/dsh-brand';
13
+ import type { SessionId } from '@deepseek-ai/dsh-session/types';
13
14
  /** Identifies one goal across its durable revisions. */
14
15
  export type GoalId = Branded<'GoalId'>;
15
16
  /** Compare-and-set identity for one exact goal revision. */
@@ -55,6 +56,20 @@ export interface GoalSnapshot extends GoalRef {
55
56
  }
56
57
  /** Whether this live process may automatically continue an active goal. */
57
58
  export type GoalActivation = 'armed' | 'disarmed';
59
+ /** Live process-local activation update forwarded to UI clients. */
60
+ export interface GoalActivationChanged {
61
+ /** Session whose live goal activation changed. */
62
+ readonly sessionId: SessionId;
63
+ /** Current exact activation, absent when no goal is current. */
64
+ readonly goal?: {
65
+ /** Exact current goal identity. */
66
+ readonly id: GoalId;
67
+ /** Exact current goal revision. */
68
+ readonly revision: number;
69
+ /** Current process-local continuation state. */
70
+ readonly activation: GoalActivation;
71
+ };
72
+ }
58
73
  /** Current goal projection, including values derived from the session log. */
59
74
  export interface GoalView extends GoalSnapshot {
60
75
  /** Highest admitted round number for this goal. */
@@ -105,4 +120,14 @@ declare module '@deepseek-ai/dsh-session-projection/types' {
105
120
  goal: GoalProjection | null;
106
121
  }
107
122
  }
123
+ declare module '@deepseek-ai/cordis' {
124
+ interface Events {
125
+ /**
126
+ * Process-local goal activation changed for one session.
127
+ * @mode emit
128
+ * @param payload - session id and the exact current goal activation, or no goal after a clear.
129
+ */
130
+ 'goal/activation-changed'(payload: GoalActivationChanged): void;
131
+ }
132
+ }
108
133
  //# sourceMappingURL=types.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-goal",
3
3
  "description": "Event-sourced same-session goal state and lifecycle service for the DeepSeek Harness",
4
- "version": "0.1.3-alpha.2",
4
+ "version": "0.1.5-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -53,34 +53,36 @@
53
53
  ],
54
54
  "license": "MIT",
55
55
  "peerDependencies": {
56
- "@deepseek-ai/dsh-session-projection": "^0.1.3-alpha.2",
57
- "@deepseek-ai/dsh-brand": "^0.1.3-alpha.2",
58
- "@deepseek-ai/dsh-invariants": "^0.1.3-alpha.2",
59
- "@deepseek-ai/dsh-agent": "^0.1.3-alpha.2",
60
- "@deepseek-ai/dsh-llm": "^0.1.3-alpha.2",
61
- "@deepseek-ai/dsh-scope": "^0.1.3-alpha.2",
62
- "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
63
- "@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
64
- "@deepseek-ai/cordis": "^4.0.2"
56
+ "@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.1",
57
+ "@deepseek-ai/dsh-agent": "^0.1.5-alpha.1",
58
+ "@deepseek-ai/dsh-brand": "^0.1.5-alpha.1",
59
+ "@deepseek-ai/dsh-llm": "^0.1.5-alpha.1",
60
+ "@deepseek-ai/dsh-scope": "^0.1.5-alpha.1",
61
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
62
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.1",
63
+ "@deepseek-ai/cordis": "^4.0.2",
64
+ "@deepseek-ai/dsh-invariants": "^0.1.5-alpha.1"
65
65
  },
66
66
  "dependencies": {
67
67
  "zod": "^4.4.3",
68
68
  "@deepseek-ai/schemastery": "^3.18.2"
69
69
  },
70
70
  "devDependencies": {
71
- "@deepseek-ai/dsh-agent": "^0.1.3-alpha.2",
72
- "@deepseek-ai/dsh-bash-local": "^0.1.3-alpha.2",
73
- "@deepseek-ai/dsh-session-projection": "^0.1.3-alpha.2",
74
- "@deepseek-ai/dsh-brand": "^0.1.3-alpha.2",
75
- "@deepseek-ai/dsh-invariants": "^0.1.3-alpha.2",
76
- "@deepseek-ai/dsh-loader-smoke": "^0.1.3-alpha.2",
77
- "@deepseek-ai/dsh-session": "^0.1.3-alpha.2",
78
- "@deepseek-ai/dsh-scope": "^0.1.3-alpha.2",
79
- "@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.3-alpha.2",
80
- "@deepseek-ai/dsh-llm": "^0.1.3-alpha.2",
81
- "@deepseek-ai/dsh-subprocess-local": "^0.1.3-alpha.2",
82
- "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.3-alpha.2",
83
- "@deepseek-ai/dsh-typert-protocol": "^0.1.3-alpha.2",
84
- "@deepseek-ai/cordis": "^4.0.2"
71
+ "@deepseek-ai/dsh-agent": "^0.1.5-alpha.1",
72
+ "@deepseek-ai/dsh-agent-loop": "^0.1.5-alpha.1",
73
+ "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-alpha.1",
74
+ "@deepseek-ai/dsh-bash-local": "^0.1.5-alpha.1",
75
+ "@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.1",
76
+ "@deepseek-ai/dsh-llm": "^0.1.5-alpha.1",
77
+ "@deepseek-ai/dsh-invariants": "^0.1.5-alpha.1",
78
+ "@deepseek-ai/dsh-loader-smoke": "^0.1.5-alpha.1",
79
+ "@deepseek-ai/dsh-scope": "^0.1.5-alpha.1",
80
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
81
+ "@deepseek-ai/dsh-session-checkpoint-policy": "^0.1.5-alpha.1",
82
+ "@deepseek-ai/dsh-session-persistence-jsonl": "^0.1.5-alpha.1",
83
+ "@deepseek-ai/dsh-subprocess-local": "^0.1.5-alpha.1",
84
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.1",
85
+ "@deepseek-ai/cordis": "^4.0.2",
86
+ "@deepseek-ai/dsh-brand": "^0.1.5-alpha.1"
85
87
  }
86
88
  }