dsh-openwrite 0.2.25 → 0.2.27

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.
Files changed (32) hide show
  1. package/README.md +18 -5
  2. package/docs/CLOSED_ISSUE_FOLLOWUPS.md +33 -0
  3. package/docs/DSH_STORE.md +7 -1
  4. package/docs/GITEE_EMBEDDING_FIX.md +40 -0
  5. package/docs/INSTALL.md +21 -1
  6. package/docs/ISSUES_105_113.md +18 -0
  7. package/docs/ISSUES_98_100.md +8 -6
  8. package/docs/ISSUE_109_REPAIRS.md +40 -0
  9. package/docs/OPENCODE_GO.md +37 -0
  10. package/docs/PLUGIN_MAINTENANCE.md +1 -1
  11. package/docs/RELEASE_ACCEPTANCE.md +26 -0
  12. package/package.json +7 -6
  13. package/packages/openwrite-bridge/lib/client.js +4 -0
  14. package/packages/openwrite-bridge/lib/contracts-generated.js +9 -0
  15. package/packages/openwrite-bridge/lib/domain.js +8 -2
  16. package/packages/openwrite-bridge/lib/index.d.ts +2 -0
  17. package/packages/openwrite-bridge/lib/index.js +3 -1
  18. package/packages/openwrite-bridge/lib/managed-runtime.d.ts +7 -0
  19. package/packages/openwrite-bridge/lib/managed-runtime.js +30 -2
  20. package/packages/openwrite-bridge/lib/tools.js +7 -3
  21. package/packages/openwrite-bridge/package.json +6 -5
  22. package/packages/studio-panel/lib/client.js +724 -552
  23. package/packages/studio-panel/lib/client.js.map +1 -1
  24. package/packages/studio-panel/lib/types/client/dto.d.ts +4 -0
  25. package/packages/studio-panel/lib/types/client/locales.d.ts +1 -1
  26. package/packages/studio-panel/package.json +4 -3
  27. package/plugin.mjs +20 -10
  28. package/preset-definition.mjs +7 -1
  29. package/release/{openwrite-5.8.12-py3-none-any.whl → openwrite-5.8.16-py3-none-any.whl} +0 -0
  30. package/release/runtime-manifest.json +5 -5
  31. package/release/source.json +3 -3
  32. package/vendor/dsh-dog/package.json +10 -9
@@ -8,6 +8,16 @@ import { createInterface } from 'node:readline';
8
8
  import { x as untar } from 'tar';
9
9
  import { unzipSync } from 'fflate';
10
10
  import { lock as acquireLock } from 'proper-lockfile';
11
+ export class UnsupportedRuntimePlatformError extends Error {
12
+ platform;
13
+ code = 'RUNTIME_PLATFORM_UNSUPPORTED';
14
+ status = 503;
15
+ constructor(platform) {
16
+ super(`OpenWrite Studio managed runtime is unavailable on ${platform}. Configure the bridge with mode: external and baseUrl pointing to a supported Studio server; see docs/INSTALL.md#external-studio. File tools that do not require Studio remain available.`);
17
+ this.platform = platform;
18
+ this.name = 'UnsupportedRuntimePlatformError';
19
+ }
20
+ }
11
21
  export const DEFAULT_RESTART_LIMIT = 5;
12
22
  export const DEFAULT_BACKOFF_MS = [1_000, 2_000, 4_000, 8_000, 16_000];
13
23
  /** Budget for the per-request liveness probe of a previously-ready backend. */
@@ -163,6 +173,7 @@ export class ManagedRuntime {
163
173
  connection;
164
174
  closed = false;
165
175
  allowRevive = true;
176
+ cancelEpoch = 0;
166
177
  generation = 0;
167
178
  restartAttempts = 0;
168
179
  recovered = false;
@@ -187,8 +198,24 @@ export class ManagedRuntime {
187
198
  return Promise.reject(new Error('OpenWrite was removed'));
188
199
  if (this.connection)
189
200
  return this.verifyConnection(this.connection);
190
- if (this.pending)
201
+ if (this.pending) {
202
+ if (['error', 'cancelled', 'stopped'].includes(this.state.phase)) {
203
+ // A ready child can exit while prepare is still saving active.json.
204
+ // The terminal state is visible before that promise settles; returning
205
+ // it would hand a manual retry the dead connection or its old error.
206
+ const prior = this.pending;
207
+ const epoch = this.cancelEpoch;
208
+ const retry = () => {
209
+ if (epoch !== this.cancelEpoch)
210
+ throw new Error('Setup was cancelled; retry when ready');
211
+ if (this.pending === prior)
212
+ this.pending = undefined;
213
+ return this.ensure();
214
+ };
215
+ return prior.then(retry, retry);
216
+ }
191
217
  return this.pending;
218
+ }
192
219
  this.allowRevive = true;
193
220
  if (this.state.phase === 'error' || this.state.phase === 'cancelled' || this.state.phase === 'stopped') {
194
221
  this.restartAttempts = 0;
@@ -251,6 +278,7 @@ export class ManagedRuntime {
251
278
  }
252
279
  }
253
280
  async cancel() {
281
+ this.cancelEpoch += 1;
254
282
  this.allowRevive = false;
255
283
  this.controller?.abort();
256
284
  await this.pending?.catch(() => { });
@@ -538,7 +566,7 @@ export class ManagedRuntime {
538
566
  const manifest = JSON.parse(await readFile(join(this.artifacts, 'runtime-manifest.json'), 'utf8'));
539
567
  const platform = manifest.platforms[`${process.platform}-${process.arch}`];
540
568
  if (!platform)
541
- throw new Error(`Unsupported platform: ${process.platform}/${process.arch}`);
569
+ throw new UnsupportedRuntimePlatformError(`${process.platform}/${process.arch}`);
542
570
  if (!manifest.wheel || !manifest.requirements)
543
571
  throw new Error('The package is missing Core or dependency checksums');
544
572
  const wheel = join(this.artifacts, manifest.wheel.file);
@@ -350,16 +350,17 @@ export function registerNovelTools(ctx, clientFactory, options) {
350
350
  }));
351
351
  ctx.tools.register(defineTool({
352
352
  name: 'novel_context_preview',
353
- description: 'Preview the context packet OpenWrite would assemble for writing a chapter (relevant outline, assets, foreshadowing, and prior-chapter memory).',
353
+ description: 'Preview the context packet OpenWrite would assemble for writing a chapter (relevant outline, assets, foreshadowing, and prior-chapter memory). Set include_agent_payload to inspect canonical writer inputs and document inclusion without calling a model.',
354
354
  parameters: {
355
355
  chapter: { type: 'string', description: 'Chapter id (e.g. "ch_0007"); omit or pass "next" for the next chapter to write.' },
356
+ include_agent_payload: { type: 'boolean', description: 'Include the full writer payload, rendered initial messages and document inventory. Later segment/retry messages depend on the write request.' },
356
357
  },
357
358
  output: { schema: JSON_OUTPUT_SCHEMA, render: (_args, value) => renderJson(value) },
358
359
  timeoutMs,
359
360
  isConcurrencySafe: () => true,
360
361
  async execute(args, exec) {
361
362
  const client = clientFor(exec);
362
- return await client.getJson('/api/context', { chapter: args.chapter?.trim() || 'next' }, exec.signal);
363
+ return await client.getJson('/api/context', { chapter: args.chapter?.trim() || 'next', ...(args.include_agent_payload ? { include_agent_payload: 'true' } : {}) }, exec.signal);
363
364
  },
364
365
  }));
365
366
  ctx.tools.register(defineTool({
@@ -803,6 +804,7 @@ export function registerNovelTools(ctx, clientFactory, options) {
803
804
  data: { type: 'json', description: 'Object of asset fields to merge (e.g. name, summary, aliases).' },
804
805
  body_markdown: { type: 'string', description: 'Replacement markdown body (character/world assets).' },
805
806
  raw_text: { type: 'string', description: 'Full replacement document text, validated by the server.' },
807
+ related_mode: { type: 'string', enum: ['merge', 'replace'], description: 'Preserve and merge existing related entries by default; replace explicitly clears or replaces relations.' },
806
808
  },
807
809
  output: { schema: JSON_OUTPUT_SCHEMA, render: (_args, value) => renderJson(value) },
808
810
  timeoutMs,
@@ -815,6 +817,8 @@ export function registerNovelTools(ctx, clientFactory, options) {
815
817
  body['body_markdown'] = args.body_markdown;
816
818
  if (args.raw_text !== undefined)
817
819
  body['raw_text'] = args.raw_text;
820
+ if (args.related_mode !== undefined)
821
+ body['related_mode'] = args.related_mode;
818
822
  return await client.postJson('/api/assets/update', body, exec.signal);
819
823
  },
820
824
  }));
@@ -888,7 +892,7 @@ export function registerNovelTools(ctx, clientFactory, options) {
888
892
  action: { type: 'string', required: true, enum: ['preview', 'apply', 'reject', 'retry', 'undo'], description: 'Plan lifecycle action.' },
889
893
  confirm: { type: 'boolean', description: 'Required true for apply and undo after author acceptance.' },
890
894
  path: { type: 'string', description: 'Existing document path for preview, relative to the novel root.' },
891
- edits: { type: 'json', description: 'Preview edits: [{old_text,new_text}] or [{start_text,end_text,new_text}].' },
895
+ edits: { type: 'json', description: 'Preview edits: [{old_text,new_text}] or [{start_text,end_text,new_text,end_inclusive}]. Range end defaults to inclusive for compatibility; end_inclusive:false preserves the end anchor (e.g. the next heading).' },
892
896
  preview_token: { type: 'string', description: 'Immutable preview or undo token for apply/reject/retry/undo.' },
893
897
  },
894
898
  output: { schema: JSON_OUTPUT_SCHEMA, render: (_args, value) => renderJson(value) },
@@ -28,12 +28,13 @@
28
28
  "patch": "./cordis.patch.yml"
29
29
  },
30
30
  "compatibility": {
31
- "dsh": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2",
31
+ "dsh": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3",
32
32
  "dshReleases": {
33
33
  "0.1.2-rc.1": "compatible",
34
34
  "0.1.5-alpha.1": "compatible",
35
35
  "0.2.0-rc.2": "compatible",
36
- "0.2.1-rc.2": "compatible"
36
+ "0.2.1-rc.2": "compatible",
37
+ "0.2.1-rc.3": "compatible"
37
38
  }
38
39
  }
39
40
  },
@@ -45,9 +46,9 @@
45
46
  },
46
47
  "peerDependencies": {
47
48
  "@deepseek-ai/cordis": "4.0.2 || ~4.0.4",
48
- "@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2",
49
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2",
50
- "@deepseek-ai/dsh-workspace": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2"
49
+ "@deepseek-ai/dsh-host-webserver": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3",
50
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3",
51
+ "@deepseek-ai/dsh-workspace": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.2.0-rc.2 || 0.2.1-rc.2 || 0.2.1-rc.3"
51
52
  },
52
53
  "peerDependenciesMeta": {
53
54
  "@deepseek-ai/dsh-host-webserver": {