dsh-bettertaskgraphs 0.3.1-rc.34 → 0.3.1-rc.35

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.
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "schema": 1,
3
3
  "updateRound": 3,
4
- "slot": 4,
5
- "branch": "0.2.1-alpha.4",
6
- "host": "0.2.1-alpha.4",
4
+ "slot": 5,
5
+ "branch": "0.2.1-alpha.2",
6
+ "host": "0.2.1-alpha.2",
7
7
  "hosts": [
8
- "0.2.1-alpha.4",
9
- "0.2.1-alpha.3"
8
+ "0.2.1-alpha.2"
10
9
  ],
11
- "channel": "dsh-0.2.1-alpha.4",
12
- "taskgraph": "0.3.1-rc.34",
13
- "dynamicContext": "0.1.1-rc.34"
10
+ "channel": "dsh-0.2.1-alpha.2",
11
+ "taskgraph": "0.3.1-rc.35",
12
+ "dynamicContext": "0.1.1-rc.35"
14
13
  }
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-bettertaskgraphs
2
2
 
3
- 本构建版本为 `0.3.1-rc.34`。适用宿主和配套版本见 [兼容清单](DSH-COMPATIBILITY.json)。
3
+ 本构建版本为 `0.3.1-rc.35`。适用宿主和配套版本见 [兼容清单](DSH-COMPATIBILITY.json)。
4
4
 
5
5
  独立运行保留动态上下文开发前 `0.2.3` 的五个工具、初始指引与事务语义;通用扩展接口供其他插件登记工作流和会话策略。动态上下文装配、修改审批及其提示词由扩展插件实现。
6
6
 
@@ -12,9 +12,9 @@ DeepSeek Harness 的事务型任务图 Bundle,包含模型侧的任务图工
12
12
 
13
13
  ## 兼容范围
14
14
 
15
- 分支 `0.2.1-alpha.4` 采用 npm 标签 `dsh-0.2.1-alpha.4`。配套动态上下文版本为 `0.1.1-rc.34`。
15
+ 分支 `0.2.1-alpha.2` 采用 npm 标签 `dsh-0.2.1-alpha.2`。配套动态上下文版本为 `0.1.1-rc.35`。
16
16
 
17
- - DSH `0.2.1-alpha.4`、`0.2.1-alpha.3`,使用 Web profile。
17
+ - DSH `0.2.1-alpha.2`,使用 Web profile。
18
18
  - Node.js `^22.19.0 || >=24.0.0`,开发用 npm。此包与 DSH 共享会话、工具和远程调用接口,升级 DSH 时需要重新验证这些接口。
19
19
 
20
20
  ## 构建和打包
@@ -26,7 +26,7 @@ npm test
26
26
  npm run pack:bundle
27
27
  ```
28
28
 
29
- `build` 从前端源码生成可由 DSH Web 加载的 `client.js`。`check` 校验生成物与源码一致,`pack:bundle` 会重新构建前端并生成 `dist/dsh-bettertaskgraphs-0.3.1-rc.34.tgz`。包内包含服务端模块、Web 构建产物、对应源码和构建脚本,以及 Bundle 配置补丁。
29
+ `build` 从前端源码生成可由 DSH Web 加载的 `client.js`。`check` 校验生成物与源码一致,`pack:bundle` 会重新构建前端并生成 `dist/dsh-bettertaskgraphs-0.3.1-rc.35.tgz`。包内包含服务端模块、Web 构建产物、对应源码和构建脚本,以及 Bundle 配置补丁。
30
30
 
31
31
  ## 安装到独立 Web profile
32
32
 
@@ -34,7 +34,7 @@ npm run pack:bundle
34
34
 
35
35
  ```sh
36
36
  dsh --profile bettertaskgraphs --from-default-profile web --dump-config
37
- dsh plugin --profile bettertaskgraphs add "$PWD/dist/dsh-bettertaskgraphs-0.3.1-rc.34.tgz"
37
+ dsh plugin --profile bettertaskgraphs add "$PWD/dist/dsh-bettertaskgraphs-0.3.1-rc.35.tgz"
38
38
  dsh --profile bettertaskgraphs --dump-config
39
39
  dsh --profile bettertaskgraphs
40
40
  ```
package/VALIDATION.md CHANGED
@@ -1,4 +1,4 @@
1
- # Candidate 0.3.1-rc.34
1
+ # Candidate 0.3.1-rc.35
2
2
 
3
3
  See [the compatibility manifest](DSH-COMPATIBILITY.json) for the exact host versions and package pairing.
4
4
 
package/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: GPL-3.0-only
2
- // Corresponding source: https://github.com/oldcitynight/dsh-bettertaskgraphs/tree/v0.3.1-rc.34
2
+ // Corresponding source: https://github.com/oldcitynight/dsh-bettertaskgraphs/tree/v0.3.1-rc.35
3
3
  // Generated by scripts/build-client.mjs.
4
4
  window.__ModuleLoader__.load({id:"dsh-bettertaskgraphs",factory(require){
5
5
  // SPDX-License-Identifier: GPL-3.0-only
@@ -7,7 +7,6 @@ window.__ModuleLoader__.load({id:"dsh-bettertaskgraphs",factory(require){
7
7
  function createRemoteContribution(z) {
8
8
  const packageName = 'dsh-bettertaskgraphs'
9
9
  const id = z.string().min(1).max(128)
10
- const input = z.object({ sessionId: id }).strict()
11
10
  const node = z.object({
12
11
  id, label: z.string().min(1).max(512), kind: z.enum(['container', 'leaf']),
13
12
  parent: id.nullable(),
@@ -44,9 +43,8 @@ function createRemoteContribution(z) {
44
43
  id: `${packageName}#transactionGraphView/status`,
45
44
  service: 'transactionGraph', namespace: 'transactionGraphView', method: 'status', invocation: { kind: 'direct' },
46
45
  parameters: [{
47
- name: 'request', wire: 'request', source: 'json',
48
- codec: codec('TransactionGraphStatusRequest', input),
49
- strictCodec: codec('TransactionGraphStatusStrictRequest', input),
46
+ name: 'session', wire: 'sessionId', source: 'lookup', lookup: 'session',
47
+ codec: { mode: 'strict', typeSymbol: '@deepseek-ai/dsh-session/types#SessionId', create: () => id },
50
48
  }],
51
49
  cancellation: { parameter: 'signal' },
52
50
  result: codec('TransactionGraphStatusResult', output),
@@ -477,15 +475,14 @@ function createClientPlugin(React, z, createRemoteContribution, graphPresentatio
477
475
  }
478
476
 
479
477
  function makeDock(api) {
480
- return function TransactionGraphDock({ sessionId, useSession, useAccess, t }) {
481
- const canRead = useAccess('transactionGraphView/status')
478
+ return function TransactionGraphDock({ sessionId, useSession, t }) {
482
479
  const opened = useSession(session => session.openState === 'open' && !session.removed)
483
480
  const running = useSession(session => session.running)
484
481
  const [result, setResult] = useState(null)
485
482
  const [refreshCount, requestRefresh] = useState(0)
486
483
  const refresh = () => requestRefresh(value => value + 1)
487
484
  useEffect(() => {
488
- if (!canRead || !opened) return
485
+ if (!opened) return
489
486
  const controller = new AbortController()
490
487
  let timer
491
488
  async function refreshStatus() {
@@ -495,7 +492,7 @@ function createClientPlugin(React, z, createRemoteContribution, graphPresentatio
495
492
  busy: true, failed: value?.sessionId === sessionId && value.failed,
496
493
  }))
497
494
  try {
498
- const response = await api.status({ sessionId }, signal)
495
+ const response = await api.status(sessionId, signal)
499
496
  if (controller.signal.aborted) return
500
497
  const parsed = response?.ok ? statusResult.safeParse(response.value) : null
501
498
  if (!parsed?.success || parsed.data.sessionId !== sessionId || parsed.data.status === 'unavailable') throw new Error('Unavailable')
@@ -509,8 +506,8 @@ function createClientPlugin(React, z, createRemoteContribution, graphPresentatio
509
506
  }
510
507
  void refreshStatus()
511
508
  return () => { controller.abort(); clearTimeout(timer) }
512
- }, [canRead, opened, running, sessionId, refreshCount])
513
- if (!canRead || !opened || result?.sessionId !== sessionId || !result.graph) return null
509
+ }, [opened, running, sessionId, refreshCount])
510
+ if (!opened || result?.sessionId !== sessionId || !result.graph) return null
514
511
  return h(GraphPanel, { key: sessionId, graph: result.graph, t, busy: result.busy, failed: result.failed, refresh })
515
512
  }
516
513
  }
package/client.source.mjs CHANGED
@@ -263,15 +263,14 @@ export function createClientPlugin(React, z, createRemoteContribution, graphPres
263
263
  }
264
264
 
265
265
  function makeDock(api) {
266
- return function TransactionGraphDock({ sessionId, useSession, useAccess, t }) {
267
- const canRead = useAccess('transactionGraphView/status')
266
+ return function TransactionGraphDock({ sessionId, useSession, t }) {
268
267
  const opened = useSession(session => session.openState === 'open' && !session.removed)
269
268
  const running = useSession(session => session.running)
270
269
  const [result, setResult] = useState(null)
271
270
  const [refreshCount, requestRefresh] = useState(0)
272
271
  const refresh = () => requestRefresh(value => value + 1)
273
272
  useEffect(() => {
274
- if (!canRead || !opened) return
273
+ if (!opened) return
275
274
  const controller = new AbortController()
276
275
  let timer
277
276
  async function refreshStatus() {
@@ -281,7 +280,7 @@ export function createClientPlugin(React, z, createRemoteContribution, graphPres
281
280
  busy: true, failed: value?.sessionId === sessionId && value.failed,
282
281
  }))
283
282
  try {
284
- const response = await api.status({ sessionId }, signal)
283
+ const response = await api.status(sessionId, signal)
285
284
  if (controller.signal.aborted) return
286
285
  const parsed = response?.ok ? statusResult.safeParse(response.value) : null
287
286
  if (!parsed?.success || parsed.data.sessionId !== sessionId || parsed.data.status === 'unavailable') throw new Error('Unavailable')
@@ -295,8 +294,8 @@ export function createClientPlugin(React, z, createRemoteContribution, graphPres
295
294
  }
296
295
  void refreshStatus()
297
296
  return () => { controller.abort(); clearTimeout(timer) }
298
- }, [canRead, opened, running, sessionId, refreshCount])
299
- if (!canRead || !opened || result?.sessionId !== sessionId || !result.graph) return null
297
+ }, [opened, running, sessionId, refreshCount])
298
+ if (!opened || result?.sessionId !== sessionId || !result.graph) return null
300
299
  return h(GraphPanel, { key: sessionId, graph: result.graph, t, busy: result.busy, failed: result.failed, refresh })
301
300
  }
302
301
  }
package/index.mjs CHANGED
@@ -13,7 +13,7 @@ import { FileGraphStore } from './store.mjs'
13
13
 
14
14
  export const name = 'dsh-bettertaskgraphs'
15
15
  let bindSessionResource
16
- Remote({ resources: { session: ({ sessionId }) => sessionId } })(undefined, {
16
+ Remote('status')(undefined, {
17
17
  kind: 'method', name: 'status', addInitializer: callback => { bindSessionResource = callback },
18
18
  })
19
19
  const guidance = 'For work the user asks to track in a transaction graph, read the program-generated revision and choices before creating or resuming it. One leaf may be active. Begin must commit before work starts. Pending or UNKNOWN work blocks finish and dependent work. Never replay blindly. Complete requires a qualified successful tool result after begin. Incomplete requires known failure, confirmed non-execution, or an unsatisfied outcome. Wait for the enclosing tool call to finish and read the committed state before continuing. Containers aggregate. Transaction completion does not complete Goal.'
@@ -43,7 +43,7 @@ export default class TransactionGraphPlugin extends TypertRemoteService {
43
43
  text: ({ agent }) => this.host.inProject(agent?.session) && this.sessionPolicies.allowClassic(agent) ? this.host.context(agent) : '' })
44
44
  ctx.inject(['typert', 'sessionController'], remoteCtx => {
45
45
  const typert = remoteCtx.typert
46
- if (typert.resources.get('session')?.field !== 'sessionId') throw new Error('Transaction graph requires the native Session RPC resource')
46
+ if (typert.lookups.get('session')?.wire !== 'sessionId') throw new Error('Transaction graph requires the native Session RPC lookup')
47
47
  const contribution = createRemoteContribution(z)
48
48
  remoteCtx.effect(() => typert.register({ package: contribution.package, face: 'host', schemas: [],
49
49
  model: { services: [], events: [], objects: [] }, invocations: contribution.descriptors }))
@@ -64,14 +64,10 @@ export default class TransactionGraphPlugin extends TypertRemoteService {
64
64
  })
65
65
  ctx.effect(() => () => { this.workflows.close(); this.sessionPolicies.close(); return this.host.close() })
66
66
  }
67
- async status({ sessionId }, signal) {
67
+ async status(session, signal) {
68
68
  signal?.throwIfAborted()
69
- const controller = this.ctx.get('sessionController')
70
- if (!controller) throw new RemoteError('session/not-found', 'Session controller unavailable', { sessionId })
71
- const result = await controller.resolveAgent(sessionId)
72
- if (result.error) throw result.error
73
- signal?.throwIfAborted()
74
- return this.host.snapshot(result.agent.session)
69
+ if (!this.host.inProject(session)) throw new RemoteError('session/not-found', 'Session unavailable')
70
+ return this.host.snapshot(session)
75
71
  }
76
72
  registerRecoveryVerifier(adapter) { return this.host.registerRecoveryVerifier(adapter) }
77
73
  recoverInterrupted(agent, request) { return this.host.recoverInterrupted(agent, request) }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-bettertaskgraphs",
3
- "version": "0.3.1-rc.34",
3
+ "version": "0.3.1-rc.35",
4
4
  "description": "Transactional task graphs with a conversation panel for DeepSeek Harness",
5
5
  "license": "GPL-3.0-only",
6
6
  "keywords": [
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "engines": {
52
52
  "node": "^22.19.0 || >=24.0.0",
53
- "dsh": "0.2.1-alpha.4 || 0.2.1-alpha.3"
53
+ "dsh": "0.2.1-alpha.2"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "node scripts/build-client.mjs",
@@ -62,23 +62,23 @@
62
62
  },
63
63
  "publishConfig": {
64
64
  "access": "public",
65
- "tag": "dsh-0.2.1-alpha.4",
65
+ "tag": "dsh-0.2.1-alpha.2",
66
66
  "registry": "https://registry.npmjs.org/"
67
67
  },
68
68
  "dependencies": {
69
69
  "zod": "4.6.7"
70
70
  },
71
71
  "peerDependencies": {
72
- "@deepseek-ai/dsh-session": "0.2.1-alpha.4 || 0.2.1-alpha.3",
73
- "@deepseek-ai/dsh-tools": "0.2.1-alpha.4 || 0.2.1-alpha.3",
74
- "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4 || 0.2.1-alpha.3"
72
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
73
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
74
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@deepseek-ai/cordis": "4.0.5",
78
- "@deepseek-ai/dsh-session": "0.2.1-alpha.4",
79
- "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.4",
80
- "@deepseek-ai/dsh-tools": "0.2.1-alpha.4",
81
- "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.4"
78
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
79
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
80
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
81
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2"
82
82
  },
83
83
  "dsh": {
84
84
  "bundle": {
package/projection.mjs CHANGED
@@ -59,7 +59,14 @@ export function outcomeOfContent(content = []) {
59
59
  }
60
60
  function toolOutcome(state, tool, rootCallId, callId, content) {
61
61
  const outcome = outcomeOfContent(content)
62
- if (tool !== 'bash' || !state.bashFailures.some(row => row.rootCallId === rootCallId && row.callId === callId)) return outcome
62
+ if (tool !== 'bash') return outcome
63
+ // These DSH hosts deliver the native Bash status as renderer suffixes.
64
+ const text = content?.length === 1 && content[0].type === 'text' ? content[0].text.trimEnd() : ''
65
+ if (/(?:^|\n)started background job [^\n]+$|\[still running after \d+ms; moved to background job [^\]\n]+\]/.test(text))
66
+ return 'UNKNOWN'
67
+ const nativeFailure = /(?:^|\n)\[(?:timed out after \d+ms|stopped: [^\]\n]+|sandbox: file access denied under [^\]\n]+ mode)\](?:\n|$)/.test(text)
68
+ || /(?:^|\n)\[(?:exit code: (?!0\])-?\d+|killed by signal: [^\]\n]+)\]$/.test(text)
69
+ if (!nativeFailure && !state.bashFailures.some(row => row.rootCallId === rootCallId && row.callId === callId)) return outcome
63
70
  return outcome === 'UNKNOWN' || outcome === 'NOT_RUN' ? 'UNKNOWN' : 'FAIL'
64
71
  }
65
72
  export function chainQualification(start, root, dispatches) {
package/remote.mjs CHANGED
@@ -3,7 +3,6 @@
3
3
  export function createRemoteContribution(z) {
4
4
  const packageName = 'dsh-bettertaskgraphs'
5
5
  const id = z.string().min(1).max(128)
6
- const input = z.object({ sessionId: id }).strict()
7
6
  const node = z.object({
8
7
  id, label: z.string().min(1).max(512), kind: z.enum(['container', 'leaf']),
9
8
  parent: id.nullable(),
@@ -40,9 +39,8 @@ export function createRemoteContribution(z) {
40
39
  id: `${packageName}#transactionGraphView/status`,
41
40
  service: 'transactionGraph', namespace: 'transactionGraphView', method: 'status', invocation: { kind: 'direct' },
42
41
  parameters: [{
43
- name: 'request', wire: 'request', source: 'json',
44
- codec: codec('TransactionGraphStatusRequest', input),
45
- strictCodec: codec('TransactionGraphStatusStrictRequest', input),
42
+ name: 'session', wire: 'sessionId', source: 'lookup', lookup: 'session',
43
+ codec: { mode: 'strict', typeSymbol: '@deepseek-ai/dsh-session/types#SessionId', create: () => id },
46
44
  }],
47
45
  cancellation: { parameter: 'signal' },
48
46
  result: codec('TransactionGraphStatusResult', output),