dsh-tender-workbench 0.5.10 → 0.5.11

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/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to `dsh-tender-workbench` are documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.5.11] - 2026-09-15
8
+
9
+ - 采用 UX-49:仅业务入口新建 Session 预填一次原生可编辑引导;双快照保护草稿、附件、IME 与晚到回调,不抢焦点、不自动发送/调用工具/开台,清空及历史恢复不补回。
10
+ - 以稳定模板 ID、版本和精确指纹区分未改系统引导与用户内容;缺项/未替换占位符由本业务澄清,空条件不能发起查询。
11
+ - 普通对话不实例化空业务 Projection;保留 UX-48 接纳后展开、只读 Profile 历史、来源归属、真实 progress、人工复核与不可变交付。
12
+ - 补原生宿主 present/absent、四插件草稿隔离及重启恢复回归,记录公开输入能力缺失时安全跳过的兼容边界。
13
+
7
14
  ## [0.5.10] - 2026-09-14
8
15
 
9
16
  - Open the current tender workbench once after Host-observed submission admission. Prompt draft fill, failed sends, restored history and later model events do not open it.
package/README.en.md CHANGED
@@ -10,9 +10,9 @@ Related agents: [数据清洗补全](https://github.com/duhu2000/dsh-data-cleani
10
10
 
11
11
  `dsh-tender-workbench` is an open-source DeepSeek Harness plugin for finding, screening, reviewing, and delivering tender opportunities. It combines authorized `qcc-tender` data, deterministic screening rules, bounded Agent analysis, explicit human decisions, and immutable Excel/PDF reports in one Session-scoped Better Sidebar workbench.
12
12
 
13
- Current stable version: **0.5.10** (stable release).
13
+ Current stable version: **0.5.11** (stable release).
14
14
 
15
- Version 0.5.10 opens the current workbench once after Host-observed submission admission. Draft fill and later progress never reopen it. Scoped home branding, Profile history and actual execution telemetry are retained. See the [release record](docs/RELEASE-0.5.10.md) for publication status and verification boundaries.
15
+ Version 0.5.11 adds a one-time native introductory draft for new tender Sessions. Existing text, attachments, IME composition and user-cleared drafts are protected; initialization never sends, calls tools or opens the workbench. UX-48 admission reveal, Profile history and actual execution telemetry are retained. See the [release record](docs/RELEASE-0.5.11.md) for publication status and verification boundaries.
16
16
 
17
17
  Base mode targets the full DSH 0.1.2-rc.1 distribution; Better Sidebar 0.18.1 is optional and only provides the visual workbench. Legacy hosts remain unsupported. Back up the complete Profile and verify dependencies before upgrading.
18
18
 
@@ -84,11 +84,11 @@ dsh web --no-open
84
84
 
85
85
  Optionally enable the visual workbench with `dsh plugin --profile web add dsh-better-sidebar@0.18.1`, enable the tender Tab and fully restart the Profile.
86
86
 
87
- To install the exact 0.5.10 release:
87
+ To install the exact 0.5.11 release:
88
88
 
89
89
  ```sh
90
90
  dsh plugin --profile web add 'dsh-mcp-connector@>=0.2.31'
91
- dsh plugin --profile web add dsh-tender-workbench@0.5.10
91
+ dsh plugin --profile web add dsh-tender-workbench@0.5.11
92
92
  ```
93
93
 
94
94
  To install base mode from an independent checkout:
@@ -105,7 +105,7 @@ To install a packed build:
105
105
 
106
106
  ```sh
107
107
  dsh plugin --profile web add 'dsh-mcp-connector@>=0.2.31'
108
- dsh plugin --profile web add ./dsh-tender-workbench-0.5.10.tgz
108
+ dsh plugin --profile web add ./dsh-tender-workbench-0.5.11.tgz
109
109
  dsh web --no-open
110
110
  ```
111
111
 
@@ -122,11 +122,11 @@ dsh plugin --profile web remove dsh-tender-workbench
122
122
  Upgrade an existing installation by installing the stable version and fully restarting the Web profile:
123
123
 
124
124
  ```sh
125
- dsh plugin --profile web add dsh-tender-workbench@0.5.10
125
+ dsh plugin --profile web add dsh-tender-workbench@0.5.11
126
126
  dsh web --no-open
127
127
  ```
128
128
 
129
- Version 0.5.10 retains Workspace ownership, the ordinary Session guard and the 0.5.6 snapshotEvents/turn-start authorization contract. Business state remains Session-local; Profile history stores metadata only, never writable projections or download capabilities. Existing unopened Sessions are not scanned: reopening indexes their current task, without restoring old snapshots. Back up the Profile's `.dsh-tender-workbench/history-v1.json` alongside task directories. Live MCP is not verified. Roll back the complete backed-up host/plugin combination, not an old plugin alone on the new host.
129
+ Version 0.5.11 retains Workspace ownership, the ordinary Session guard and the 0.5.6 snapshotEvents/turn-start authorization contract. Business state remains Session-local; Profile history stores metadata only, never writable projections or download capabilities. Existing unopened Sessions are not scanned: reopening indexes their current task, without restoring old snapshots. Back up the Profile's `.dsh-tender-workbench/history-v1.json` alongside task directories. Live MCP is not verified. Roll back the complete backed-up host/plugin combination, not an old plugin alone on the new host.
130
130
 
131
131
  ## Using the workbench
132
132
 
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  招投标智能体:支持招投标搜索、招标查询、投标查询、标讯查询、拟建项目与项目筛选,辅助商机发现、人工复核及 Excel/PDF 导出,使用客户自备授权的企查查 MCP。
8
8
 
9
9
  ```sh
10
- dsh plugin --profile web add dsh-tender-workbench@0.5.10
10
+ dsh plugin --profile web add dsh-tender-workbench@0.5.11
11
11
  ```
12
12
 
13
13
  请先满足下文的 DSH、连接器及侧边栏依赖要求;安装后完整停止并重启对应 Profile。
@@ -27,9 +27,9 @@ dsh plugin --profile web add dsh-tender-workbench@0.5.10
27
27
 
28
28
  > 面向国内招投标团队的 DeepSeek Harness 开源智能体插件:在一个会话级工作台内完成标讯与拟建项目查询、确定性规则初筛、限定范围智能分析、人工复核,以及 Excel/PDF 报告交付。
29
29
  >
30
- > 当前稳定版本:**0.5.10**(正式版本)
30
+ > 当前稳定版本:**0.5.11**(正式版本)
31
31
 
32
- 0.5.10 在任务提交被 Host 接纳后自动展开对应工作台;回填草稿不展开,手动收起后不会被后续进度反复拉开。保留首页品牌、Profile 历史和真实执行进度。发布状态及验收边界见 [发布记录](docs/RELEASE-0.5.10.md)。
32
+ 0.5.11 新增 UX-49 一次性原生首页引导,保护已有文字、附件、IME 输入和用户清空;不自动发送、调用工具或打开工作台。保留 UX-48 接纳后展开、Profile 历史和真实执行进度。发布状态及验收边界见 [发布记录](docs/RELEASE-0.5.11.md)。
33
33
 
34
34
  [![CI](https://github.com/duhu2000/dsh-tender-workbench/actions/workflows/ci.yml/badge.svg)](https://github.com/duhu2000/dsh-tender-workbench/actions/workflows/ci.yml)
35
35
  [![npm](https://img.shields.io/npm/v/dsh-tender-workbench)](https://www.npmjs.com/package/dsh-tender-workbench)
@@ -39,6 +39,8 @@ dsh plugin --profile web add dsh-tender-workbench@0.5.10
39
39
 
40
40
  ## 产品简介
41
41
 
42
+ UX-49 一次性原生首页引导只对本菜单新建的空业务 Session 生效,不覆盖已有文字/附件、IME 输入或清空后的草稿;不自动查询或打开工作台。依赖 DSH 0.1.2-rc.1 公开输入 shell、编辑器状态与可写浏览器存储,能力缺失时跳过预填。采用与验收边界见 [UX-49 采用记录](https://github.com/duhu2000/dsh-tender-workbench/blob/main/docs/UX49-INITIAL-DRAFT-ADOPTION.md)。
43
+
42
44
  `dsh-tender-workbench` 是 DeepSeek Harness 的 Host + Client 插件,适合需要持续发现、筛选、复核和交付招投标机会的国内业务团队。插件连接客户已安装并授权的 `qcc-tender` MCP,以结构化标讯事实为基础,将规则判断、Agent 建议和人工决策明确分开,形成可追溯的工作流。
43
45
 
44
46
  完整业务闭环为:
@@ -75,10 +77,10 @@ dsh web --no-open
75
77
 
76
78
  需要可视化工作台时,再自选安装 `dsh plugin --profile web add dsh-better-sidebar@0.18.1`、在宿主设置启用招投标 Tab,并完整重启。无需侧栏也可使用下方列明的基础功能。
77
79
 
78
- 安装指定的 `0.5.10` 版本:
80
+ 安装指定的 `0.5.11` 版本:
79
81
 
80
82
  ```sh
81
- dsh plugin --profile web add dsh-tender-workbench@0.5.10
83
+ dsh plugin --profile web add dsh-tender-workbench@0.5.11
82
84
  ```
83
85
 
84
86
  移除插件:
@@ -146,11 +148,11 @@ node scripts/check-host-compatibility.mjs --host-root /实际路径/node_modules
146
148
  从已有版本升级:
147
149
 
148
150
  ```sh
149
- dsh plugin --profile web add dsh-tender-workbench@0.5.10
151
+ dsh plugin --profile web add dsh-tender-workbench@0.5.11
150
152
  dsh web --no-open
151
153
  ```
152
154
 
153
- 0.5.10 保留 Workspace 归组、0.5.6 可选侧栏与 `snapshotEvents()` / `turn/start` 授权绑定。业务任务仍属于原 Session;Profile 历史只存摘要,不复制旧 projection,也不自动搬迁未分组任务。旧会话在重新打开后才补入当前任务摘要,历史页不恢复旧快照到当前任务。索引位于对应 Profile 的 `.dsh-tender-workbench/history-v1.json`,备份时一并保留。真实 MCP 连接未核验。回退应恢复备份的完整已验证宿主/插件组合,不能在新版宿主上单独安装原始 0.5.4 或更早版本。
155
+ 0.5.11 保留 Workspace 归组、0.5.6 可选侧栏与 `snapshotEvents()` / `turn/start` 授权绑定。业务任务仍属于原 Session;Profile 历史只存摘要,不复制旧 projection,也不自动搬迁未分组任务。旧会话在重新打开后才补入当前任务摘要,历史页不恢复旧快照到当前任务。索引位于对应 Profile 的 `.dsh-tender-workbench/history-v1.json`,备份时一并保留。真实 MCP 连接未核验。回退应恢复备份的完整已验证宿主/插件组合,不能在新版宿主上单独安装原始 0.5.4 或更早版本。
154
156
 
155
157
  ## 本地开发
156
158
 
@@ -165,7 +167,7 @@ corepack pnpm@11.7.0 run check
165
167
 
166
168
  `check` 会执行类型检查、完整 Vitest 测试、生产构建、README/发布状态校验以及 npm tarball 白名单预检。配置 npm Trusted Publishing 后,[发布工作流](.github/workflows/release.yml)可使用 OIDC 和 provenance;手工发布不得声称 provenance。
167
169
 
168
- 省、市、区数据源快照维护在 [resources/area.ts](resources/area.ts)。版本变更见 [CHANGELOG.md](CHANGELOG.md),发布检查见 [0.5.10 发布清单](docs/RELEASE-0.5.10.md)。
170
+ 省、市、区数据源快照维护在 [resources/area.ts](resources/area.ts)。版本变更见 [CHANGELOG.md](CHANGELOG.md),发布检查见 [0.5.11 发布清单](docs/RELEASE-0.5.11.md)。
169
171
 
170
172
  ## 界面演示与市场投稿
171
173
 
@@ -0,0 +1,25 @@
1
+ # 招投标 0.5.11 发布记录
2
+
3
+ Version: **0.5.11**
4
+ Status: **ready for release**
5
+
6
+ 本轮在用户明确授权 commit、push、tag、npm 后发布 UX-49(PR #8)。原实现提交 e4b3e4bf21f7f4f423128333a709460f53256f3f 已通过 PR CI;本次同步版本及资料,不修改业务实现。
7
+
8
+ ## 更新
9
+
10
+ - 仅本菜单新建的业务 Session 预填一次原生可编辑引导,采用第 11.1 节招投标文案。
11
+ - 双快照检查就绪状态、空草稿/附件、IME 与 Session;异步迟到、用户清空、刷新、重挂载及旧会话不覆盖或补回,不抢焦点。
12
+ - 稳定模板 ID、版本与精确指纹;修改后的内容按用户草稿处理。占位符或缺项先澄清,Host 查询防线拒绝无效条件,不调用 Provider。
13
+ - 不自动发送、创建任务或展开工作台,保留 UX-48 接纳后展开、只读 Profile 历史、origin、真实 progress、人工定案和不可变 Excel/PDF 快照。
14
+
15
+ ## 验证与边界
16
+
17
+ 实施门禁:311 passed / 1 平台条件 skipped,8 个 UI 场景通过。真实 DSH 0.1.2-rc.1 独立 Profile 下 Sidebar 0.18.1 present/absent、清空刷新、Host 重启及四插件隔离均通过;组合为清洗 0.9.15、尽调 0.1.35、填表 0.2.30。真实 Host 工具使用合成 Provider,验证了人工复核和 Excel/PDF 文件链路,不代表真实收费 MCP 或模型已验证。操作系统中文输入法候选交互仍需人工验收。
18
+
19
+ 公开 input shell/编辑器能力、可写浏览器存储缺失或 5 秒未就绪时安全跳过引导,不做 DOM 回退。Projection 缓存版本为 4,宿主从原日志重放;不迁移或重写 Profile 历史及交付文件。完整采用记录见仓库 docs/UX49-INITIAL-DRAFT-ADOPTION.md。
20
+
21
+ ## 发布与升级
22
+
23
+ 使用 v0.5.11 tag 触发 release.yml,Linux Node 24 执行完整门禁后通过 npm Trusted Publishing/OIDC 发布,附带 provenance;随后由既有工作流生成 GitHub Release。发布成功以 Actions 和 npm registry 的实际结果为准。
24
+
25
+ 升级前备份完整 Profile;执行 `dsh plugin --profile web add dsh-tender-workbench@0.5.11` 后完整重启对应 dsh web。既有会话不会补回初始模板,需从「招投标」菜单新建业务 Session 验证。回滚使用完整已验证 Profile 备份。
package/lib/client.js CHANGED
@@ -5125,8 +5125,27 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5125
5125
  rows: array(NormalizedProjectV1Schema).max(100)
5126
5126
  }).strict();
5127
5127
  //#endregion
5128
+ //#region src/contracts/initial-draft.ts
5129
+ /** UX-49: versioned copy, not a prompt, task, or query authorization. */
5130
+ const TENDER_INITIAL_DRAFT = {
5131
+ id: "dsh-initial-draft/dsh-tender-workbench/1",
5132
+ version: 1,
5133
+ fingerprint: "sha256:f2bf291eec74a12873fb6178362b61ed032f50389186bc82eec9462fd0e745ed",
5134
+ text: "请帮我查找并评估招投标机会。请填写行业、地区、时间范围和筛选条件,也可点击左上角「提示词生成」整理查询口径。例如:查找近 30 天【地区】软件和数据服务相关招标项目,排除已截止项目,形成候选清单。"
5135
+ };
5136
+ /** Exact bytes only: no trimming, fuzzy matching, or substring exclusion. */
5137
+ function isTenderInitialDraft(text) {
5138
+ return text === TENDER_INITIAL_DRAFT.text;
5139
+ }
5140
+ function hasUnresolvedTenderPlaceholder(value) {
5141
+ if (typeof value === "string") return /【[^】]*】/u.test(value);
5142
+ if (Array.isArray(value)) return value.some(hasUnresolvedTenderPlaceholder);
5143
+ if (typeof value === "object" && value !== null) return Object.values(value).some(hasUnresolvedTenderPlaceholder);
5144
+ return false;
5145
+ }
5146
+ //#endregion
5128
5147
  //#region src/contracts/query-schema.ts
5129
- const shortText = string$1().trim().min(1).max(128);
5148
+ const shortText = string$1().trim().min(1).max(128).refine((value) => !hasUnresolvedTenderPlaceholder(value), "请先替换【】占位符,再查询。");
5130
5149
  const dateText = string$1().regex(/^\d{4}-\d{2}-\d{2}$/u);
5131
5150
  const optionalAmount = number().finite().nonnegative().optional();
5132
5151
  const QccTenderSearchArgsSchema = object({
@@ -5160,7 +5179,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
5160
5179
  investmentMax: optionalAmount
5161
5180
  }).strict();
5162
5181
  function hasSupportedQueryFilter(value) {
5163
- return Object.keys(value).some((key) => key !== "smartSort");
5182
+ return Object.entries(value).some(([key, entry]) => key !== "smartSort" && (Array.isArray(entry) ? entry.length > 0 : entry !== void 0 && entry !== ""));
5164
5183
  }
5165
5184
  //#endregion
5166
5185
  //#region src/contracts/screening.ts
@@ -28730,6 +28749,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
28730
28749
  }
28731
28750
  /** Replace only an intact previous generated block; edited/manual text needs a choice. */
28732
28751
  function planTenderDraftFill(current, generated, previous) {
28752
+ if (isTenderInitialDraft(current)) return generated;
28733
28753
  if (!current.trim()) return generated;
28734
28754
  if (previous && current.includes(previous)) return current.replace(previous, generated);
28735
28755
  }
@@ -29039,6 +29059,133 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
29039
29059
  };
29040
29060
  }
29041
29061
  //#endregion
29062
+ //#region src/client/initial-draft.ts
29063
+ /** Entry-issued capability only. No mount/history observer may create a permit. */
29064
+ function initializeTenderDraft(sessionId, port, storage, schedule = queueMicrotask) {
29065
+ const key = `${TENDER_INITIAL_DRAFT.id}/session/${sessionId}`;
29066
+ let alive = true;
29067
+ let off = () => {};
29068
+ const stop = () => {
29069
+ alive = false;
29070
+ off();
29071
+ };
29072
+ if (!isTenderEntrySessionId(sessionId)) return stop;
29073
+ try {
29074
+ if (storage.getItem(key) !== null) return stop;
29075
+ storage.setItem(key, JSON.stringify({
29076
+ status: "reserved",
29077
+ ...TENDER_INITIAL_DRAFT,
29078
+ text: void 0
29079
+ }));
29080
+ } catch {
29081
+ return stop;
29082
+ }
29083
+ const safe = (s) => s.current === sessionId && !s.composing && s.draft === "" && s.revision === 0 && s.attachments === 0 && s.plain;
29084
+ const check = () => {
29085
+ if (!alive) return;
29086
+ let first;
29087
+ try {
29088
+ first = port.snapshot();
29089
+ } catch {
29090
+ stop();
29091
+ return;
29092
+ }
29093
+ if (!safe(first)) {
29094
+ stop();
29095
+ return;
29096
+ }
29097
+ if (!first.ready) return;
29098
+ schedule(() => {
29099
+ if (!alive) return;
29100
+ try {
29101
+ const latest = port.snapshot();
29102
+ if (!safe(latest) || !latest.ready || latest.revision !== first.revision) {
29103
+ stop();
29104
+ return;
29105
+ }
29106
+ stop();
29107
+ port.write(TENDER_INITIAL_DRAFT.text);
29108
+ storage.setItem(key, JSON.stringify({
29109
+ status: "initialized",
29110
+ id: TENDER_INITIAL_DRAFT.id,
29111
+ version: TENDER_INITIAL_DRAFT.version,
29112
+ fingerprint: TENDER_INITIAL_DRAFT.fingerprint
29113
+ }));
29114
+ } catch {
29115
+ stop();
29116
+ }
29117
+ });
29118
+ };
29119
+ off = port.subscribe(check, stop);
29120
+ if (!alive) off();
29121
+ check();
29122
+ return stop;
29123
+ }
29124
+ //#endregion
29125
+ //#region src/client/initial-draft-host.ts
29126
+ /** DSH 0.1.2-rc.1 public input shell + public Lexical lifecycle; no keyboard/private fields. */
29127
+ function initializeTenderHostDraft(ctx, id) {
29128
+ try {
29129
+ const input = ctx.conversation.input;
29130
+ if (typeof input.shell !== "function") return () => {};
29131
+ const shell = input.shell(id);
29132
+ const editor = shell.editor;
29133
+ if (!editor?.registerRootListener || !editor.isComposing || !editor.update) return () => {};
29134
+ const cleanup = initializeTenderDraft(id, {
29135
+ snapshot() {
29136
+ const state = shell.state.getSnapshot();
29137
+ return {
29138
+ current: ctx.sessions.list.getSnapshot().current,
29139
+ ready: editor.getRootElement()?.isConnected === true,
29140
+ composing: editor.isComposing(),
29141
+ draft: state.draft,
29142
+ revision: state.draftRev,
29143
+ plain: state.phase === "plain",
29144
+ attachments: state.imageIds.length + state.occurrences.length
29145
+ };
29146
+ },
29147
+ subscribe(check, cancel) {
29148
+ let detach = () => {};
29149
+ const rootOff = editor.registerRootListener((root) => {
29150
+ detach();
29151
+ if (root) {
29152
+ const events = [
29153
+ "beforeinput",
29154
+ "paste",
29155
+ "drop",
29156
+ "compositionstart"
29157
+ ];
29158
+ events.forEach((event) => root.addEventListener(event, cancel, true));
29159
+ detach = () => events.forEach((event) => root.removeEventListener(event, cancel, true));
29160
+ }
29161
+ check();
29162
+ });
29163
+ const stateOff = shell.state.subscribe(check);
29164
+ const sessionOff = ctx.sessions.list.subscribe(check);
29165
+ return () => {
29166
+ detach();
29167
+ rootOff();
29168
+ stateOff();
29169
+ sessionOff();
29170
+ };
29171
+ },
29172
+ write(text) {
29173
+ editor.update(() => shell.setDraft(text), {
29174
+ discrete: true,
29175
+ tag: "skip-dom-selection"
29176
+ });
29177
+ }
29178
+ }, window.localStorage);
29179
+ const timeout = setTimeout(cleanup, 5e3);
29180
+ return () => {
29181
+ clearTimeout(timeout);
29182
+ cleanup();
29183
+ };
29184
+ } catch {
29185
+ return () => {};
29186
+ }
29187
+ }
29188
+ //#endregion
29042
29189
  //#region src/client/skill-catalog.ts
29043
29190
  var TenderSkillPreflightError = class extends Error {
29044
29191
  code;
@@ -31537,6 +31684,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
31537
31684
  const projectionPort = createTenderProjectionPort(sessions);
31538
31685
  const promptMemory = /* @__PURE__ */ new Map();
31539
31686
  let active = true;
31687
+ let stopInitialDraft = () => {};
31688
+ let entryGeneration = 0;
31540
31689
  const sendIntent = (sessionId, intent) => sendSessionTenderWorkbenchIntent(sessions, connection, sessionId, intent);
31541
31690
  const openSession = (sessionId, phase) => {
31542
31691
  if (!active || sidebar === void 0 || reveal === void 0) return false;
@@ -31549,10 +31698,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
31549
31698
  return opened;
31550
31699
  };
31551
31700
  const startTenderSession = async () => {
31701
+ const generation = ++entryGeneration;
31702
+ const previousSession = sessions.list.getSnapshot().current;
31703
+ stopInitialDraft();
31552
31704
  try {
31553
31705
  const sessionId = await createTenderEntrySession(sessions, ctx.workspaces);
31554
- if (!active) return;
31706
+ if (!active || generation !== entryGeneration || sessions.list.getSnapshot().current !== previousSession) return;
31707
+ stopInitialDraft();
31555
31708
  sessions.open(sessionId);
31709
+ stopInitialDraft = initializeTenderHostDraft(ctx, sessionId);
31556
31710
  } catch (error) {
31557
31711
  if (error instanceof TenderSessionEntryError) {
31558
31712
  const key = error.code === "workspace-unavailable" ? "sidebar.workspaceRequired" : error.code === "create-unavailable" ? "sidebar.createUnavailable" : "sidebar.createFailed";
@@ -31646,6 +31800,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
31646
31800
  }, TenderSessionHeaderEntry));
31647
31801
  ctx.effect(() => () => {
31648
31802
  active = false;
31803
+ stopInitialDraft();
31649
31804
  reveal?.dispose();
31650
31805
  navigation.dispose();
31651
31806
  promptMemory.clear();