@codexhost/cli-darwin-x64 0.16.0 → 0.17.0

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 (38) hide show
  1. package/README.md +2 -2
  2. package/THIRD_PARTY_NOTICES.txt +6 -2
  3. package/app/codexhost-distribution.json +1 -1
  4. package/app/console-server.mjs +59 -21
  5. package/app/console-web.js +49 -18
  6. package/app/desktop-controller.mjs +554 -34
  7. package/app/host-runtime.mjs +3436 -1846
  8. package/app/plugins/antigravity/plugin.mjs +39 -3
  9. package/app/plugins/claude-code/plugin.mjs +16 -7
  10. package/app/plugins/codebuddy/plugin.mjs +14 -1
  11. package/app/plugins/codex-usage/plugin.mjs +4 -1
  12. package/app/plugins/copilot/plugin.mjs +4 -1
  13. package/app/plugins/cursor-cli/plugin.mjs +13 -6
  14. package/app/plugins/deepseek-harness/plugin.mjs +463 -47
  15. package/app/plugins/devin/assets/icon.svg +1 -0
  16. package/app/plugins/devin/manifest.json +30 -0
  17. package/app/plugins/devin/plugin.mjs +23363 -0
  18. package/app/plugins/enabled.json +2 -0
  19. package/app/plugins/grok/plugin.mjs +476 -392
  20. package/app/plugins/hermes/plugin.mjs +457 -197
  21. package/app/plugins/kimi-code/plugin.mjs +4 -1
  22. package/app/plugins/kiro-cli/plugin.mjs +4 -1
  23. package/app/plugins/omp/plugin.mjs +4 -1
  24. package/app/plugins/opencode/plugin.mjs +4 -1
  25. package/app/plugins/pi/plugin.mjs +1464 -412
  26. package/app/plugins/qoder/plugin.mjs +9528 -8655
  27. package/app/plugins/qoder-cn/plugin.mjs +9528 -8655
  28. package/app/plugins/qwen-code/assets/icon.svg +1 -0
  29. package/app/plugins/qwen-code/manifest.json +29 -0
  30. package/app/plugins/qwen-code/plugin.mjs +29298 -0
  31. package/app/plugins/workbuddy/plugin.mjs +14 -1
  32. package/app/plugins/zcode/plugin.mjs +4 -1
  33. package/app/renderer-extension.js +510 -114
  34. package/bin/codexhost +0 -0
  35. package/libexec/codexhost-shim +0 -0
  36. package/libexec/codexhost-updater +0 -0
  37. package/licenses/Qwen-Code-SDK-LICENSE.txt +203 -0
  38. package/package.json +2 -2
@@ -5018,10 +5018,10 @@ function mergeDefs(...defs) {
5018
5018
  function cloneDef(schema) {
5019
5019
  return mergeDefs(schema._zod.def);
5020
5020
  }
5021
- function getElementAtPath(obj, path9) {
5022
- if (!path9)
5021
+ function getElementAtPath(obj, path11) {
5022
+ if (!path11)
5023
5023
  return obj;
5024
- return path9.reduce((acc, key) => acc?.[key], obj);
5024
+ return path11.reduce((acc, key) => acc?.[key], obj);
5025
5025
  }
5026
5026
  function promiseAllObject(promisesObj) {
5027
5027
  const keys = Object.keys(promisesObj);
@@ -5430,11 +5430,11 @@ function explicitlyAborted(x, startIndex = 0) {
5430
5430
  }
5431
5431
  return false;
5432
5432
  }
5433
- function prefixIssues(path9, issues) {
5433
+ function prefixIssues(path11, issues) {
5434
5434
  return issues.map((iss) => {
5435
5435
  var _a3;
5436
5436
  (_a3 = iss).path ?? (_a3.path = []);
5437
- iss.path.unshift(path9);
5437
+ iss.path.unshift(path11);
5438
5438
  return iss;
5439
5439
  });
5440
5440
  }
@@ -5581,16 +5581,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
5581
5581
  }
5582
5582
  function formatError(error51, mapper = (issue2) => issue2.message) {
5583
5583
  const fieldErrors = { _errors: [] };
5584
- const processError = (error52, path9 = []) => {
5584
+ const processError = (error52, path11 = []) => {
5585
5585
  for (const issue2 of error52.issues) {
5586
5586
  if (issue2.code === "invalid_union" && issue2.errors.length) {
5587
- issue2.errors.map((issues) => processError({ issues }, [...path9, ...issue2.path]));
5587
+ issue2.errors.map((issues) => processError({ issues }, [...path11, ...issue2.path]));
5588
5588
  } else if (issue2.code === "invalid_key") {
5589
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
5589
+ processError({ issues: issue2.issues }, [...path11, ...issue2.path]);
5590
5590
  } else if (issue2.code === "invalid_element") {
5591
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
5591
+ processError({ issues: issue2.issues }, [...path11, ...issue2.path]);
5592
5592
  } else {
5593
- const fullpath = [...path9, ...issue2.path];
5593
+ const fullpath = [...path11, ...issue2.path];
5594
5594
  if (fullpath.length === 0) {
5595
5595
  fieldErrors._errors.push(mapper(issue2));
5596
5596
  } else {
@@ -5617,17 +5617,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
5617
5617
  }
5618
5618
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
5619
5619
  const result = { errors: [] };
5620
- const processError = (error52, path9 = []) => {
5620
+ const processError = (error52, path11 = []) => {
5621
5621
  var _a3, _b;
5622
5622
  for (const issue2 of error52.issues) {
5623
5623
  if (issue2.code === "invalid_union" && issue2.errors.length) {
5624
- issue2.errors.map((issues) => processError({ issues }, [...path9, ...issue2.path]));
5624
+ issue2.errors.map((issues) => processError({ issues }, [...path11, ...issue2.path]));
5625
5625
  } else if (issue2.code === "invalid_key") {
5626
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
5626
+ processError({ issues: issue2.issues }, [...path11, ...issue2.path]);
5627
5627
  } else if (issue2.code === "invalid_element") {
5628
- processError({ issues: issue2.issues }, [...path9, ...issue2.path]);
5628
+ processError({ issues: issue2.issues }, [...path11, ...issue2.path]);
5629
5629
  } else {
5630
- const fullpath = [...path9, ...issue2.path];
5630
+ const fullpath = [...path11, ...issue2.path];
5631
5631
  if (fullpath.length === 0) {
5632
5632
  result.errors.push(mapper(issue2));
5633
5633
  continue;
@@ -5659,8 +5659,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
5659
5659
  }
5660
5660
  function toDotPath(_path) {
5661
5661
  const segs = [];
5662
- const path9 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
5663
- for (const seg of path9) {
5662
+ const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
5663
+ for (const seg of path11) {
5664
5664
  if (typeof seg === "number")
5665
5665
  segs.push(`[${seg}]`);
5666
5666
  else if (typeof seg === "symbol")
@@ -18352,13 +18352,13 @@ function resolveRef(ref, ctx) {
18352
18352
  if (!ref.startsWith("#")) {
18353
18353
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
18354
18354
  }
18355
- const path9 = ref.slice(1).split("/").filter(Boolean);
18356
- if (path9.length === 0) {
18355
+ const path11 = ref.slice(1).split("/").filter(Boolean);
18356
+ if (path11.length === 0) {
18357
18357
  return ctx.rootSchema;
18358
18358
  }
18359
18359
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
18360
- if (path9[0] === defsKey) {
18361
- const key = path9[1];
18360
+ if (path11[0] === defsKey) {
18361
+ const key = path11[1];
18362
18362
  if (!key || !ctx.defs[key]) {
18363
18363
  throw new Error(`Reference not found: ${ref}`);
18364
18364
  }
@@ -19812,7 +19812,10 @@ var harnessPluginRouteSchema = external_exports.object({
19812
19812
  harnessId: harnessPluginIdSchema,
19813
19813
  model: harnessModelRefSchema.optional(),
19814
19814
  thinkingOptionId: harnessThinkingOptionIdSchema.optional(),
19815
- permissionModeId: harnessPermissionModeIdSchema.optional()
19815
+ permissionModeId: harnessPermissionModeIdSchema.optional(),
19816
+ /** A draft prewarm create: stays unsubmitted until the user's first Turn.
19817
+ * Desktop forwards only the Model of a main-process prewarm to thread/start. */
19818
+ prewarm: external_exports.literal(true).optional()
19816
19819
  }).strict();
19817
19820
 
19818
19821
  // ../../shared-contracts/dist/harness-launch-settings.js
@@ -20950,16 +20953,16 @@ var Diff = class {
20950
20953
  }
20951
20954
  }
20952
20955
  }
20953
- addToPath(path9, added, removed, oldPosInc, options) {
20954
- const last = path9.lastComponent;
20956
+ addToPath(path11, added, removed, oldPosInc, options) {
20957
+ const last = path11.lastComponent;
20955
20958
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
20956
20959
  return {
20957
- oldPos: path9.oldPos + oldPosInc,
20960
+ oldPos: path11.oldPos + oldPosInc,
20958
20961
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
20959
20962
  };
20960
20963
  } else {
20961
20964
  return {
20962
- oldPos: path9.oldPos + oldPosInc,
20965
+ oldPos: path11.oldPos + oldPosInc,
20963
20966
  lastComponent: { count: 1, added, removed, previousComponent: last }
20964
20967
  };
20965
20968
  }
@@ -22566,7 +22569,7 @@ var DeepSeekGenerationProbeError = class extends Error {
22566
22569
  this.stderrTail = options.stderrTail;
22567
22570
  }
22568
22571
  };
22569
- var DEFAULT_TIMEOUT_MS = 5e3;
22572
+ var DEFAULT_TIMEOUT_MS = 15e3;
22570
22573
  var DEFAULT_CLEANUP_TIMEOUT_MS = 1e3;
22571
22574
  var DEFAULT_OUTPUT_LIMIT_BYTES = 16 * 1024;
22572
22575
  var DIAGNOSTIC_RAW_TAIL_BYTES = 16 * 1024;
@@ -22876,7 +22879,7 @@ async function probeDeepSeekExecutableGeneration(options = {}, dependencies = {
22876
22879
 
22877
22880
  // dist/modern/deepseek-harness-adapter.js
22878
22881
  import { randomUUID as randomUUID2 } from "node:crypto";
22879
- import path8 from "node:path";
22882
+ import path10 from "node:path";
22880
22883
 
22881
22884
  // dist/modern/catalog.js
22882
22885
  import { Buffer as Buffer3 } from "node:buffer";
@@ -22997,7 +23000,7 @@ var ModernRemoteConnectionError = class extends Error {
22997
23000
  this.remoteFailure = sanitizeModernRemoteFailure(remoteFailure3);
22998
23001
  }
22999
23002
  };
23000
- var DEFAULT_STARTUP_TIMEOUT_MS = 2e4;
23003
+ var DEFAULT_STARTUP_TIMEOUT_MS = 9e4;
23001
23004
  var DEFAULT_UNARY_TIMEOUT_MS = 1e4;
23002
23005
  var DEFAULT_STREAM_OPEN_TIMEOUT_MS = 1e4;
23003
23006
  var DEFAULT_CLOSE_TIMEOUT_MS = 3e3;
@@ -27093,8 +27096,369 @@ function invalidInbox() {
27093
27096
  }
27094
27097
 
27095
27098
  // dist/modern/history.js
27099
+ import path8 from "node:path";
27096
27100
  import { isDeepStrictEqual as isDeepStrictEqual5 } from "node:util";
27097
27101
 
27102
+ // ../../harness-adapter/dist/local-media-markdown.js
27103
+ import { existsSync, statSync as statSync2 } from "node:fs";
27104
+ import path7 from "node:path";
27105
+ import { fileURLToPath } from "node:url";
27106
+ var MEDIA_EXTENSIONS = /* @__PURE__ */ new Set([
27107
+ ".aac",
27108
+ ".gif",
27109
+ ".jpeg",
27110
+ ".jpg",
27111
+ ".m4a",
27112
+ ".m4v",
27113
+ ".mov",
27114
+ ".mp3",
27115
+ ".mp4",
27116
+ ".ogg",
27117
+ ".png",
27118
+ ".svg",
27119
+ ".wav",
27120
+ ".webm",
27121
+ ".webp"
27122
+ ]);
27123
+ function rewriteLocalMediaMarkdown(text, roots, options = {}) {
27124
+ return projectLocalMedia(text, roots, options.exists ?? mediaFileExists, options.holdIncomplete === true, options.relativeImagesOnly === true).text;
27125
+ }
27126
+ var LocalMediaMarkdownStream = class {
27127
+ #roots;
27128
+ #exists;
27129
+ #relativeImagesOnly;
27130
+ #native = "";
27131
+ #text = "";
27132
+ /** Native text length represented by `#text`; the rest is held. */
27133
+ #consumed = 0;
27134
+ #verbatim = false;
27135
+ constructor(roots, exists = mediaFileExists, options = {}) {
27136
+ this.#roots = [...roots];
27137
+ this.#relativeImagesOnly = options.relativeImagesOnly === true;
27138
+ const known = /* @__PURE__ */ new Map();
27139
+ this.#exists = (absolutePath) => {
27140
+ let found = known.get(absolutePath);
27141
+ if (found === void 0) {
27142
+ found = exists(absolutePath);
27143
+ known.set(absolutePath, found);
27144
+ }
27145
+ return found;
27146
+ };
27147
+ }
27148
+ /** Projected text published so far: every returned delta, concatenated. */
27149
+ get text() {
27150
+ return this.#text;
27151
+ }
27152
+ /** Add native text and return the projected text it makes publishable, possibly empty. */
27153
+ append(text) {
27154
+ this.#native += text;
27155
+ return this.#advance(true);
27156
+ }
27157
+ /** Return the projected text still held at the end of the stream. */
27158
+ flush() {
27159
+ return this.#advance(false);
27160
+ }
27161
+ #advance(holdIncomplete) {
27162
+ const next = this.#verbatim ? void 0 : projectLocalMedia(this.#native, this.#roots, this.#exists, holdIncomplete, this.#relativeImagesOnly);
27163
+ let delta;
27164
+ if (next?.text.startsWith(this.#text)) {
27165
+ delta = next.text.slice(this.#text.length);
27166
+ this.#consumed = next.consumed;
27167
+ } else {
27168
+ this.#verbatim = true;
27169
+ delta = this.#native.slice(this.#consumed);
27170
+ this.#consumed = this.#native.length;
27171
+ }
27172
+ this.#text += delta;
27173
+ return delta;
27174
+ }
27175
+ };
27176
+ function projectLocalMedia(text, roots, exists, holdIncomplete, relativeImagesOnly) {
27177
+ let output = "";
27178
+ let index = 0;
27179
+ let fence = null;
27180
+ while (index < text.length) {
27181
+ if (fence) {
27182
+ const close = closingFenceEnd(text, index, fence.marker, fence.length);
27183
+ if (close === -1)
27184
+ break;
27185
+ output += text.slice(index, close);
27186
+ index = close;
27187
+ fence = null;
27188
+ continue;
27189
+ }
27190
+ const next = earliestIndex([
27191
+ text.indexOf("![", index),
27192
+ text.indexOf("`", index),
27193
+ indexOfLineStartTilde(text, index)
27194
+ ]);
27195
+ if (next === -1)
27196
+ break;
27197
+ output += text.slice(index, next);
27198
+ index = next;
27199
+ const marker = text[next];
27200
+ let markerLength = 1;
27201
+ if (marker === "`" || marker === "~") {
27202
+ let runEnd = next;
27203
+ while (text[runEnd] === marker)
27204
+ runEnd += 1;
27205
+ markerLength = runEnd - next;
27206
+ if (runEnd === text.length && holdIncomplete) {
27207
+ return { text: output, consumed: next };
27208
+ }
27209
+ if (runEnd - next >= 3) {
27210
+ const kind = fenceLineKind(text, next);
27211
+ if (kind === "opaque")
27212
+ break;
27213
+ if (kind === "flat") {
27214
+ fence = { marker, length: runEnd - next };
27215
+ output += text.slice(next, runEnd);
27216
+ index = runEnd;
27217
+ continue;
27218
+ }
27219
+ }
27220
+ if (marker === "~") {
27221
+ output += text.slice(next, runEnd);
27222
+ index = runEnd;
27223
+ continue;
27224
+ }
27225
+ }
27226
+ if (text.startsWith("![", next)) {
27227
+ const image = parseMarkdownImage(text, next);
27228
+ if (image.kind === "text") {
27229
+ output += text.slice(next, image.end);
27230
+ index = image.end;
27231
+ continue;
27232
+ }
27233
+ if (image.kind === "open") {
27234
+ if (!holdIncomplete)
27235
+ break;
27236
+ return { text: output + text.slice(next, image.holdFrom), consumed: image.holdFrom };
27237
+ }
27238
+ const resolved2 = relativeImagesOnly && /^(?:[\\/]|[a-z][a-z\d+.-]*:)/i.test(image.destination.trim()) ? null : resolveLocalMediaPath(image.destination, roots, exists);
27239
+ output += resolved2 === null ? text.slice(next, image.end) : text.slice(next, image.destinationStart) + markdownDestination(resolved2, image.bracketed) + text.slice(image.destinationEnd, image.end);
27240
+ index = image.end;
27241
+ continue;
27242
+ }
27243
+ const code = parseInlineCode(text, next, markerLength);
27244
+ if (code.kind !== "code" || holdIncomplete && code.end === text.length) {
27245
+ if (holdIncomplete && code.kind !== "text")
27246
+ return { text: output, consumed: next };
27247
+ output += text.slice(next, next + markerLength);
27248
+ index = next + markerLength;
27249
+ continue;
27250
+ }
27251
+ const resolved = relativeImagesOnly || markerLength !== 1 || /[\r\n]/u.test(code.content) ? null : resolveLocalMediaPath(code.content, roots, exists);
27252
+ output += resolved === null ? text.slice(next, code.end) : mediaMarkdownImage(resolved);
27253
+ index = code.end;
27254
+ }
27255
+ return { text: output + text.slice(index), consumed: text.length };
27256
+ }
27257
+ function fenceLineKind(text, index) {
27258
+ const prefix = text.slice(text.lastIndexOf("\n", index - 1) + 1, index);
27259
+ if (prefix === "")
27260
+ return "flat";
27261
+ let remaining = prefix.replace(/^[ \t]+/u, "");
27262
+ while (remaining) {
27263
+ const marker = /^(?:>|(?:[-+*]|\d{1,9}[.)])(?=[ \t]))[ \t]*/u.exec(remaining);
27264
+ if (!marker)
27265
+ return null;
27266
+ remaining = remaining.slice(marker[0].length);
27267
+ }
27268
+ return "opaque";
27269
+ }
27270
+ function indexOfLineStartTilde(text, start) {
27271
+ for (let tilde = text.indexOf("~", start); tilde !== -1; tilde = text.indexOf("~", tilde + 1)) {
27272
+ if (fenceLineKind(text, tilde) !== null)
27273
+ return tilde;
27274
+ }
27275
+ return -1;
27276
+ }
27277
+ function closingFenceEnd(text, start, marker, length) {
27278
+ const closing = new RegExp(`^ {0,3}${marker === "`" ? "`" : "~"}{${length},}[ \\t]*\\r?$`, "u");
27279
+ let lineStart = text.indexOf("\n", start);
27280
+ while (lineStart !== -1) {
27281
+ lineStart += 1;
27282
+ const newline = text.indexOf("\n", lineStart);
27283
+ const lineEnd = newline === -1 ? text.length : newline;
27284
+ if (closing.test(text.slice(lineStart, lineEnd)))
27285
+ return lineEnd;
27286
+ lineStart = newline;
27287
+ }
27288
+ return -1;
27289
+ }
27290
+ function earliestIndex(candidates) {
27291
+ let next = -1;
27292
+ for (const candidate of candidates) {
27293
+ if (candidate === -1)
27294
+ continue;
27295
+ if (next === -1 || candidate < next)
27296
+ next = candidate;
27297
+ }
27298
+ return next;
27299
+ }
27300
+ function parseInlineCode(text, start, length) {
27301
+ let index = start + length;
27302
+ while (index < text.length) {
27303
+ const tick = text.indexOf("`", index);
27304
+ if (/\n[^\S\n]*\n/u.test(text.slice(index, tick < 0 ? text.length : tick))) {
27305
+ return { kind: "text" };
27306
+ }
27307
+ if (tick === -1)
27308
+ break;
27309
+ let end = tick + 1;
27310
+ while (text[end] === "`")
27311
+ end += 1;
27312
+ if (end - tick === length) {
27313
+ return { kind: "code", content: text.slice(start + length, tick), end };
27314
+ }
27315
+ index = end;
27316
+ }
27317
+ return { kind: "open" };
27318
+ }
27319
+ function parseMarkdownImage(text, start) {
27320
+ const openLabel = { kind: "open", holdFrom: start + 2 };
27321
+ let index = start + 2;
27322
+ while (index < text.length) {
27323
+ const character = text[index];
27324
+ if (character === "\n")
27325
+ return { kind: "text", end: start + 1 };
27326
+ if (character === "\\") {
27327
+ index += 2;
27328
+ continue;
27329
+ }
27330
+ if (character === "]")
27331
+ break;
27332
+ index += 1;
27333
+ }
27334
+ if (index + 1 >= text.length)
27335
+ return openLabel;
27336
+ if (text[index + 1] !== "(")
27337
+ return { kind: "text", end: start + 1 };
27338
+ const destinationStart = index + 2;
27339
+ const open = { kind: "open", holdFrom: destinationStart };
27340
+ const malformed = { kind: "text", end: destinationStart };
27341
+ index = skipBlanks(text, destinationStart);
27342
+ if (index >= text.length)
27343
+ return open;
27344
+ let destination;
27345
+ let destinationEnd;
27346
+ let bracketed = false;
27347
+ if (text[index] === "<") {
27348
+ bracketed = true;
27349
+ let close = index + 1;
27350
+ while (close < text.length && text[close] !== ">" && text[close] !== "\n")
27351
+ close += 1;
27352
+ if (close >= text.length)
27353
+ return open;
27354
+ if (text[close] === "\n")
27355
+ return malformed;
27356
+ destination = text.slice(index + 1, close);
27357
+ destinationEnd = close + 1;
27358
+ index = destinationEnd;
27359
+ } else {
27360
+ const begin = index;
27361
+ while (index < text.length) {
27362
+ const character = text[index];
27363
+ if (character === "\n" || character === " " || character === " " || character === ")")
27364
+ break;
27365
+ index += character === "\\" ? 2 : 1;
27366
+ }
27367
+ if (index >= text.length)
27368
+ return open;
27369
+ destination = unescapeMarkdown(text.slice(begin, index));
27370
+ destinationEnd = index;
27371
+ }
27372
+ index = skipBlanks(text, index);
27373
+ if (index >= text.length)
27374
+ return open;
27375
+ const opener = text[index];
27376
+ if (opener === '"' || opener === "'" || opener === "(") {
27377
+ const closer = opener === "(" ? ")" : opener;
27378
+ index += 1;
27379
+ while (index < text.length && text[index] !== closer && text[index] !== "\n")
27380
+ index += 1;
27381
+ if (index >= text.length)
27382
+ return open;
27383
+ if (text[index] === "\n")
27384
+ return malformed;
27385
+ index = skipBlanks(text, index + 1);
27386
+ if (index >= text.length)
27387
+ return open;
27388
+ }
27389
+ if (text[index] !== ")")
27390
+ return malformed;
27391
+ return {
27392
+ kind: "image",
27393
+ destination,
27394
+ destinationStart,
27395
+ destinationEnd,
27396
+ end: index + 1,
27397
+ bracketed
27398
+ };
27399
+ }
27400
+ function skipBlanks(text, start) {
27401
+ let index = start;
27402
+ while (text[index] === " " || text[index] === " ")
27403
+ index += 1;
27404
+ return index;
27405
+ }
27406
+ function mediaMarkdownImage(absolutePath) {
27407
+ const name = path7.basename(absolutePath).replaceAll("]", "\\]");
27408
+ return `![${name}](${markdownDestination(absolutePath, false)})`;
27409
+ }
27410
+ function markdownDestination(absolutePath, bracketed) {
27411
+ const encoded = absolutePath.replaceAll("%", "%2525");
27412
+ const destination = /^[A-Za-z]:\\/.test(encoded) ? encoded.replaceAll("\\", "/") : encoded.replaceAll("\\", "\\\\");
27413
+ return bracketed || /[\s()]/.test(destination) ? `<${destination}>` : destination;
27414
+ }
27415
+ function unescapeMarkdown(value) {
27416
+ return value.replace(/\\([\\()])/g, "$1");
27417
+ }
27418
+ function resolveLocalMediaPath(raw, roots, exists = mediaFileExists) {
27419
+ const trimmed = raw.trim();
27420
+ if (trimmed.length === 0 || isRemoteMediaUrl(trimmed))
27421
+ return null;
27422
+ const stripped = stripFileUrl(trimmed);
27423
+ if (stripped === null)
27424
+ return null;
27425
+ if (isAbsoluteMediaPath(stripped)) {
27426
+ const absolute = path7.resolve(stripped);
27427
+ return hasMediaExtension(absolute) && exists(absolute) ? absolute : null;
27428
+ }
27429
+ for (const root of roots) {
27430
+ const absolute = path7.resolve(root, stripped);
27431
+ if (hasMediaExtension(absolute) && exists(absolute))
27432
+ return absolute;
27433
+ }
27434
+ return null;
27435
+ }
27436
+ function isRemoteMediaUrl(value) {
27437
+ return /^(?:https?:|data:|app:|blob:)/i.test(value);
27438
+ }
27439
+ function stripFileUrl(value) {
27440
+ if (!value.toLowerCase().startsWith("file:"))
27441
+ return value;
27442
+ try {
27443
+ return fileURLToPath(value);
27444
+ } catch {
27445
+ return null;
27446
+ }
27447
+ }
27448
+ function isAbsoluteMediaPath(value) {
27449
+ return path7.isAbsolute(value) || /^[a-zA-Z]:[\\/]/.test(value);
27450
+ }
27451
+ function hasMediaExtension(value) {
27452
+ return MEDIA_EXTENSIONS.has(path7.extname(value).toLowerCase());
27453
+ }
27454
+ function mediaFileExists(absolutePath) {
27455
+ try {
27456
+ return existsSync(absolutePath) && statSync2(absolutePath).isFile();
27457
+ } catch {
27458
+ return false;
27459
+ }
27460
+ }
27461
+
27098
27462
  // dist/modern/compaction.js
27099
27463
  var MODERN_CONTEXT_PRESSURE_KEY = "contextPressure";
27100
27464
  function modernCompactionOutcome(data) {
@@ -27712,6 +28076,8 @@ function projectModernHistory(input) {
27712
28076
  let effectiveThinkingOptionId = input.fallbackThinkingOptionId;
27713
28077
  let contextWindowTokens;
27714
28078
  let usage = null;
28079
+ let workingDirectory = input.cwd;
28080
+ const media = input.media ?? input.cwd !== void 0;
27715
28081
  const rawUsageByStep = /* @__PURE__ */ new Map();
27716
28082
  const rebuildUsage = () => {
27717
28083
  usage = null;
@@ -27733,6 +28099,7 @@ function projectModernHistory(input) {
27733
28099
  if (!KNOWN_EVENT_TYPES.has(event.type) || !isRecord4(event.data))
27734
28100
  continue;
27735
28101
  const data = event.data;
28102
+ workingDirectory = modernWorkingDirectory(workingDirectory, event);
27736
28103
  switch (event.type) {
27737
28104
  case "turn/start":
27738
28105
  active = {
@@ -27777,8 +28144,9 @@ function projectModernHistory(input) {
27777
28144
  case "assistant/message":
27778
28145
  if (event.surfaceOp === "append") {
27779
28146
  recordSettlementUsage(data, event.seq);
27780
- if (active)
27781
- projectAssistantMessage(active, input.sessionId, data);
28147
+ if (active) {
28148
+ projectAssistantMessage(active, input.sessionId, data, media ? modernMediaRoots(workingDirectory, input.cwd) : void 0);
28149
+ }
27782
28150
  }
27783
28151
  break;
27784
28152
  case "compaction/start":
@@ -27899,7 +28267,21 @@ function modernCheckpointRef(harnessId, sessionId, seq, profile = DEEPSEEK_V4_PR
27899
28267
  function modernItemId(sessionId, key) {
27900
28268
  return hostItemIdSchema.parse(`dsh-modern:${sessionId}:${key}`);
27901
28269
  }
27902
- function projectAssistantMessage(turn, sessionId, data) {
28270
+ function modernWorkingDirectory(current, event) {
28271
+ if (event.type !== "working-directory/change" || !isRecord4(event.data) || typeof event.data.cwd !== "string") {
28272
+ return current;
28273
+ }
28274
+ const next = event.data.cwd;
28275
+ if (path8.isAbsolute(next))
28276
+ return path8.resolve(next);
28277
+ return current === void 0 ? void 0 : path8.resolve(current, next);
28278
+ }
28279
+ function modernMediaRoots(workingDirectory, sessionDirectory) {
28280
+ return [
28281
+ ...new Set([workingDirectory ?? sessionDirectory, sessionDirectory].filter((root) => root !== void 0))
28282
+ ];
28283
+ }
28284
+ function projectAssistantMessage(turn, sessionId, data, mediaRoots) {
27903
28285
  const message = data.message;
27904
28286
  if (Array.isArray(message.content)) {
27905
28287
  for (const block of message.content) {
@@ -27922,7 +28304,7 @@ function projectAssistantMessage(turn, sessionId, data) {
27922
28304
  const item = {
27923
28305
  type: "agentMessage",
27924
28306
  itemId: modernItemId(sessionId, `turn:${turn.turn}:step:${String(data.step)}:assistant`),
27925
- text
28307
+ text: mediaRoots ? rewriteLocalMediaMarkdown(text, mediaRoots) : text
27926
28308
  };
27927
28309
  turn.items.push({ item, outcome: { status: "succeeded" } });
27928
28310
  }
@@ -28741,6 +29123,8 @@ var ModernHarnessSession = class {
28741
29123
  #flushSession;
28742
29124
  #fallbackModel;
28743
29125
  #fallbackThinkingOptionId;
29126
+ #sessionDirectory;
29127
+ #workingDirectory;
28744
29128
  #channel = new HarnessOutputChannel();
28745
29129
  #validator;
28746
29130
  #events;
@@ -28807,8 +29191,12 @@ var ModernHarnessSession = class {
28807
29191
  this.#events = [...options.journal.events];
28808
29192
  this.#historyBytes = journalHistoryBytes(this.#events, this.#maxHistoryBytes);
28809
29193
  this.#validator = new ModernEventValidator(this.#maxEvents, this.#profile);
28810
- for (const event of this.#events)
29194
+ this.#sessionDirectory = options.journal.header.cwd;
29195
+ this.#workingDirectory = this.#sessionDirectory;
29196
+ for (const event of this.#events) {
28811
29197
  this.#validator.accept(event);
29198
+ this.#workingDirectory = modernWorkingDirectory(this.#workingDirectory, event);
29199
+ }
28812
29200
  const projection = projectModernHistory({
28813
29201
  harnessId: this.harnessId,
28814
29202
  sessionId: this.#sessionId,
@@ -28843,12 +29231,18 @@ var ModernHarnessSession = class {
28843
29231
  };
28844
29232
  let resumedAutonomousBuffer;
28845
29233
  if (projection.incompleteTurn) {
29234
+ let workingDirectory = this.#sessionDirectory;
29235
+ const turnStart = this.#events.length - projection.incompleteTurn.events.length;
29236
+ for (const event of this.#events.slice(0, turnStart)) {
29237
+ workingDirectory = modernWorkingDirectory(workingDirectory, event);
29238
+ }
28846
29239
  const buffer = {
28847
29240
  nativeTurn: projection.incompleteTurn.turn,
28848
29241
  events: [...projection.incompleteTurn.events],
28849
29242
  input: [],
28850
29243
  initialResume: true,
28851
29244
  replayed: 0,
29245
+ workingDirectory,
28852
29246
  sawUserMessage: false,
28853
29247
  reachedCorrelationBoundary: false
28854
29248
  };
@@ -28890,7 +29284,7 @@ var ModernHarnessSession = class {
28890
29284
  return Promise.resolve({ ok: false, error: busyError("read history") });
28891
29285
  this.#reading = true;
28892
29286
  try {
28893
- const projection = this.#project();
29287
+ const projection = this.#project(true);
28894
29288
  const configuration = this.#readConfiguration();
28895
29289
  return Promise.resolve({
28896
29290
  ok: true,
@@ -29824,6 +30218,7 @@ ${question.detail}` : question.question;
29824
30218
  this.#validator.accept(event);
29825
30219
  this.#observeAssistantSettlement(event);
29826
30220
  this.#events.push(event);
30221
+ this.#workingDirectory = modernWorkingDirectory(this.#workingDirectory, event);
29827
30222
  this.#meterUsage(event);
29828
30223
  this.#historyBytes += bytes;
29829
30224
  this.#receive(event);
@@ -29949,8 +30344,8 @@ ${question.detail}` : question.question;
29949
30344
  const agent = active.agent;
29950
30345
  if (!agent)
29951
30346
  return;
29952
- agent.text += CANCELLED_ASSISTANT_ATTEMPT_SUFFIX;
29953
- agent.item = { ...agent.item, text: agent.text };
30347
+ this.#flushAgent(active, agent);
30348
+ agent.item = { ...agent.item, text: agent.item.text + CANCELLED_ASSISTANT_ATTEMPT_SUFFIX };
29954
30349
  this.#emit({
29955
30350
  type: "item.updated",
29956
30351
  turnId: active.turnId,
@@ -30073,6 +30468,7 @@ ${question.detail}` : question.question;
30073
30468
  input: [],
30074
30469
  initialResume: false,
30075
30470
  replayed: 0,
30471
+ workingDirectory: this.#workingDirectory,
30076
30472
  sawUserMessage: false,
30077
30473
  reachedCorrelationBoundary: false
30078
30474
  };
@@ -30251,6 +30647,7 @@ ${question.detail}` : question.question;
30251
30647
  while (!this.#closed && buffer.replayed < buffer.events.length) {
30252
30648
  const event = buffer.events[buffer.replayed];
30253
30649
  buffer.replayed += 1;
30650
+ buffer.workingDirectory = modernWorkingDirectory(buffer.workingDirectory, event);
30254
30651
  this.#projectLiveEvent(buffer, event, initialReplay);
30255
30652
  }
30256
30653
  this.#projectAssistantLiveChunks();
@@ -30355,16 +30752,28 @@ ${question.detail}` : question.question;
30355
30752
  itemId: modernItemId(this.#sessionId, `turn:${active.nativeTurn}:step:${step}:${attemptId ? `attempt:${attemptId}:` : ""}assistant`),
30356
30753
  text: ""
30357
30754
  };
30358
- active.agent = { item, text: "" };
30755
+ const buffer = this.#buffer;
30756
+ const workingDirectory = buffer?.active === active ? buffer.workingDirectory : this.#workingDirectory;
30757
+ const roots = modernMediaRoots(workingDirectory, this.#sessionDirectory);
30758
+ active.agent = { item, text: "", media: new LocalMediaMarkdownStream(roots) };
30359
30759
  this.#emit({ type: "item.started", turnId: active.turnId, item });
30360
30760
  }
30361
30761
  active.agent.text += text;
30362
- active.agent.item = { ...active.agent.item, text: active.agent.text };
30762
+ this.#publishAgent(active, active.agent, active.agent.media.append(text));
30763
+ }
30764
+ /** Publish text the media projection held for a trailing construct before the Item ends. */
30765
+ #flushAgent(active, agent) {
30766
+ this.#publishAgent(active, agent, agent.media.flush());
30767
+ }
30768
+ #publishAgent(active, agent, delta) {
30769
+ if (!delta)
30770
+ return;
30771
+ agent.item = { ...agent.item, text: agent.media.text };
30363
30772
  this.#emit({
30364
30773
  type: "item.updated",
30365
30774
  turnId: active.turnId,
30366
- itemId: active.agent.item.itemId,
30367
- update: { type: "text.append", text }
30775
+ itemId: agent.item.itemId,
30776
+ update: { type: "text.append", text: delta }
30368
30777
  });
30369
30778
  }
30370
30779
  #startReasoning(active, step, provisional, attemptId) {
@@ -30452,6 +30861,7 @@ ${question.detail}` : question.question;
30452
30861
  }
30453
30862
  if (!current)
30454
30863
  return;
30864
+ this.#flushAgent(active, current);
30455
30865
  delete active.agent;
30456
30866
  this.#completeItem(active, current.item, { status: "succeeded" });
30457
30867
  }
@@ -30593,9 +31003,10 @@ ${question.detail}` : question.question;
30593
31003
  this.#completeItem(active, item, outcome);
30594
31004
  }
30595
31005
  if (active.agent) {
30596
- const item = active.agent.item;
31006
+ const agent = active.agent;
31007
+ this.#flushAgent(active, agent);
30597
31008
  delete active.agent;
30598
- this.#completeItem(active, item, outcome);
31009
+ this.#completeItem(active, agent.item, outcome);
30599
31010
  }
30600
31011
  for (const tool of active.tools.values())
30601
31012
  this.#completeItem(active, tool.item, outcome);
@@ -30622,12 +31033,17 @@ ${question.detail}` : question.question;
30622
31033
  });
30623
31034
  }
30624
31035
  }
30625
- #project() {
31036
+ /** `media` also resolves local media paths, which only displayed history needs. */
31037
+ #project(media = false) {
30626
31038
  return projectModernHistory({
30627
31039
  harnessId: this.harnessId,
30628
31040
  sessionId: this.#sessionId,
30629
31041
  events: this.#events,
30630
31042
  profile: this.#profile,
31043
+ ...media ? {
31044
+ media: true,
31045
+ ...this.#sessionDirectory !== void 0 ? { cwd: this.#sessionDirectory } : {}
31046
+ } : {},
30631
31047
  ...this.#fallbackModel ? { fallbackModel: this.#fallbackModel } : {},
30632
31048
  ...this.#fallbackThinkingOptionId ? { fallbackThinkingOptionId: this.#fallbackThinkingOptionId } : {},
30633
31049
  toolOutputLimit: this.#toolOutputLimit,
@@ -31206,7 +31622,7 @@ function safeTimerDelay(value, name) {
31206
31622
 
31207
31623
  // dist/modern/session-list.js
31208
31624
  import { Buffer as Buffer5 } from "node:buffer";
31209
- import path7 from "node:path";
31625
+ import path9 from "node:path";
31210
31626
  var MAX_SESSION_LIST_BYTES = 32 * 1024 * 1024;
31211
31627
  var MAX_SESSION_LIST_DEPTH = 64;
31212
31628
  var MAX_SESSION_LIST_NODES = 2e5;
@@ -31326,7 +31742,7 @@ function parseSummary(value) {
31326
31742
  };
31327
31743
  }
31328
31744
  function isCanonicalAbsoluteCwd(value) {
31329
- return value !== void 0 && value.trim().length > 0 && !value.includes("\0") && path7.isAbsolute(value) && path7.resolve(value) === value;
31745
+ return value !== void 0 && value.trim().length > 0 && !value.includes("\0") && path9.isAbsolute(value) && path9.resolve(value) === value;
31330
31746
  }
31331
31747
  function parseModernSessionCandidates(value) {
31332
31748
  assertBoundedJson4(value);
@@ -31524,7 +31940,7 @@ var ModernDeepSeekHarnessAdapter = class {
31524
31940
  let session;
31525
31941
  let forkExpectation;
31526
31942
  try {
31527
- const cwd = path8.resolve(input.cwd);
31943
+ const cwd = path10.resolve(input.cwd);
31528
31944
  let forkInput = input.kind === "fork" ? parseModernForkInput(input, this.#profile) : void 0;
31529
31945
  const rollbackSourceSessionId = input.kind === "rollbackLastTurn" ? modernSessionId(input.sourceRef, "roll back") : void 0;
31530
31946
  let rollbackPlan;