@toddzheng024/dscode-bundle 0.1.0 → 0.2.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 (34) hide show
  1. package/THIRD_PARTY_NOTICES.md +3 -0
  2. package/cordis.patch.yml +6 -0
  3. package/package.json +5 -1
  4. package/plugins/dscode/index.mjs +1 -1
  5. package/plugins/memory/content.mjs +57 -0
  6. package/plugins/memory/index.mjs +123 -0
  7. package/plugins/memory/pipeline.mjs +78 -0
  8. package/plugins/memory/store.mjs +93 -0
  9. package/plugins/session-bridge/client.mjs +106 -0
  10. package/plugins/session-bridge/communication.mjs +217 -0
  11. package/plugins/session-bridge/index.mjs +61 -0
  12. package/plugins/session-bridge/mailbox.mjs +212 -0
  13. package/plugins/session-bridge/paths.mjs +21 -0
  14. package/plugins/session-bridge/server.mjs +169 -0
  15. package/plugins/session-cards/content.mjs +64 -0
  16. package/plugins/session-cards/index.mjs +31 -0
  17. package/plugins/session-cards/manager.mjs +131 -0
  18. package/plugins/session-metrics/view.mjs +3 -3
  19. package/plugins/tui-tools/index.mjs +2 -0
  20. package/plugins/tui-tools/shell.mjs +27 -0
  21. package/plugins/ultra/policy.mjs +7 -3
  22. package/presets/dscode/agent.cordis.yml +7 -5
  23. package/vendor/deepseek/index.js +1 -1
  24. package/vendor/subagent/LICENSE +21 -0
  25. package/vendor/subagent/index.js +664 -0
  26. package/vendor/subagent/invariant.js +52 -0
  27. package/vendor/subagent/model-selection-settings.js +94 -0
  28. package/vendor/subagent/types/index.d.ts +81 -0
  29. package/vendor/subagent/types/invariant.d.ts +16 -0
  30. package/vendor/subagent/types/list-models.d.ts +10 -0
  31. package/vendor/subagent/types/model-selection-settings.d.ts +43 -0
  32. package/vendor/subagent/types/model-selection-state.d.ts +48 -0
  33. package/vendor/subagent/types/model-selection.d.ts +81 -0
  34. package/vendor/tui/index.mjs +158 -100
@@ -1,3 +1,86 @@
1
+ // dscode-style-v1
2
+
3
+ function dscodeActivity(entries, streaming) {
4
+ const running = entries.filter(entry => entry.kind === "tool" && entry.state === "running");
5
+ const tool = running.at(-1);
6
+ if (!tool) return streaming ? "正在回复" : "正在思考";
7
+ let description = "";
8
+ try {
9
+ if (typeof tool.arguments === "string" && tool.arguments.length <= 4096) {
10
+ const args = JSON.parse(tool.arguments);
11
+ if (typeof args?.description === "string") description = args.description;
12
+ }
13
+ } catch {}
14
+ // No raw argument/command dump in the chat chrome. A supplied description
15
+ // is a task label, not a claim that the command succeeded.
16
+ return "正在执行 · " + singleLineText(tool.name) + (running.length > 1 ? " +" + (running.length - 1) : "") +
17
+ (description ? " · " + truncateColumns(singleLineText(description), 56) : "");
18
+ }
19
+ function DscodeActivityLine({ entries, streaming, since, animated = true }) {
20
+ const columns = useStdout().stdout?.columns ?? 80;
21
+ const tick = useFrames(animated ? 160 : 1000);
22
+ const elapsed = since > 0 ? Math.max(0, Date.now() - since) : 0;
23
+ const suffix = columns >= 48 ? " · 本轮 " + runClock(elapsed) + " · Esc 中断" : " · 本轮 " + runClock(elapsed);
24
+ const glyph = animated ? ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"][tick % 10] : "●";
25
+ const label = truncateColumns(dscodeActivity(entries, streaming), Math.max(1, columns - 6 - visibleColumns(suffix)));
26
+ return (0, import_react.createElement)(Box, { paddingX: 2 },
27
+ (0, import_react.createElement)(Text, { wrap: "truncate-end" },
28
+ (0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, glyph + " " + label),
29
+ (0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, suffix)));
30
+ }
31
+
32
+ // dscode-session-relay-v1
33
+ function dscodeVisibleRelay(message) {
34
+ return message.source.kind === "plugin" && message.source.plugin === "dscode-session-bridge" && message.source.form === "relay";
35
+ }
36
+ // dscode-ime-v1
37
+ const dscodeImeAnchors = new WeakMap();
38
+ function imePosition(anchor, height, columns) {
39
+ if (!anchor?.node || anchor.active === false || !Number.isFinite(height) || height < 1) return;
40
+ let x = anchor.column, y = anchor.row;
41
+ for (let node = anchor.node; node; node = node.parentNode) {
42
+ if (node.yogaNode) {
43
+ x += node.yogaNode.getComputedLeft();
44
+ y += node.yogaNode.getComputedTop();
45
+ }
46
+ }
47
+ if (y < 0 || y >= height) return;
48
+ return { up: height - Math.floor(y), column: Math.max(1, Math.min(columns || 80, Math.floor(x) + 1)) };
49
+ }
50
+ function imeWriter(stream, anchors) {
51
+ const write = stream.write;
52
+ let parked = false;
53
+ const restore = () => {
54
+ if (!parked) return;
55
+ parked = false;
56
+ write.call(stream, '\x1b8');
57
+ };
58
+ const wrapped = function (...args) { restore(); return write.apply(this, args); };
59
+ if (stream.isTTY) stream.write = wrapped;
60
+ return {
61
+ park(height) {
62
+ if (!stream.isTTY) return;
63
+ restore();
64
+ const target = imePosition(anchors.get(stream), height, stream.columns);
65
+ if (!target) return;
66
+ write.call(stream, `\x1b7\x1b[${target.up}A\x1b[${target.column}G`);
67
+ parked = true;
68
+ },
69
+ dispose() {
70
+ restore();
71
+ if (stream.write === wrapped) stream.write = write;
72
+ }
73
+ };
74
+ }
75
+ // dscode-interaction-v1
76
+ function dscodeChatLines(entry, columns) {
77
+ if (entry.kind === "tool") return [];
78
+ if (entry.kind === "assistant") {
79
+ if (!entry.text && !entry.interrupted) return [];
80
+ entry = { ...entry, reasoning: "" };
81
+ }
82
+ return transcriptEntryLines(entry, columns, false, false, false);
83
+ }
1
84
  // dscode-footer-v1
2
85
  import { footerFor as dscodeFooterFor } from "../../plugins/session-metrics/view.mjs";
3
86
  import { n as __require, r as __toESM, t as __commonJSMin } from "./rolldown-runtime-CMFfr-1z.mjs";
@@ -23204,6 +23287,7 @@ cliCursor.toggle = (force, writableStream) => {
23204
23287
  //#endregion
23205
23288
  //#region node_modules/.pnpm/ink@5.2.1_@types+react@18.3.31_react@18.3.1/node_modules/ink/build/log-update.js
23206
23289
  const create = (stream, { showCursor = false } = {}) => {
23290
+ const ime = imeWriter(stream, dscodeImeAnchors);
23207
23291
  let previousLineCount = 0;
23208
23292
  let previousOutput = "";
23209
23293
  let hasHiddenCursor = false;
@@ -23213,10 +23297,11 @@ const create = (stream, { showCursor = false } = {}) => {
23213
23297
  hasHiddenCursor = true;
23214
23298
  }
23215
23299
  const output = str + "\n";
23216
- if (output === previousOutput) return;
23300
+ if (output === previousOutput) { ime.park(output.split("\n").length - 1); return; }
23217
23301
  previousOutput = output;
23218
23302
  stream.write(eraseLines(previousLineCount) + output);
23219
23303
  previousLineCount = output.split("\n").length;
23304
+ ime.park(previousLineCount - 1);
23220
23305
  };
23221
23306
  render.clear = () => {
23222
23307
  stream.write(eraseLines(previousLineCount));
@@ -23224,6 +23309,7 @@ const create = (stream, { showCursor = false } = {}) => {
23224
23309
  previousLineCount = 0;
23225
23310
  };
23226
23311
  render.done = () => {
23312
+ ime.dispose();
23227
23313
  previousOutput = "";
23228
23314
  previousLineCount = 0;
23229
23315
  if (!showCursor) {
@@ -23881,7 +23967,7 @@ var Ink = class {
23881
23967
  this.options.stdout.write(staticOutput);
23882
23968
  this.log(output);
23883
23969
  }
23884
- if (!hasStaticOutput && output !== this.lastOutput) this.throttledLog(output);
23970
+ if (!hasStaticOutput) this.throttledLog(output);
23885
23971
  this.lastOutput = output;
23886
23972
  };
23887
23973
  render(node) {
@@ -25350,7 +25436,7 @@ function replayProjectEvent(acc, event) {
25350
25436
  const text = textOf(message.content);
25351
25437
  const images = imagesOf(message.content);
25352
25438
  const files = filesOf(message.content);
25353
- if (message.source.kind === "user") {
25439
+ if (message.source.kind === "user" || dscodeVisibleRelay(message)) {
25354
25440
  appendReplayEntry(acc, {
25355
25441
  kind: "user",
25356
25442
  text,
@@ -28263,7 +28349,7 @@ const STATUS_ITEMS = [
28263
28349
  * Default order: the whole catalog (matches the pre-customization bar).
28264
28350
  * The busy dot is not an item — it always leads the identity cluster.
28265
28351
  */
28266
- const DEFAULT_STATUSLINE_ITEMS = STATUS_ITEMS.map((item) => item.id);
28352
+ const DEFAULT_STATUSLINE_ITEMS = ["model", "permission", "title", "plan", "goal", "sandbox"];
28267
28353
  /**
28268
28354
  * Parse a persisted statusline item list. The stored value is the ordered
28269
28355
  * set of ENABLED items (the Codex /statusline contract): unknown ids and
@@ -28350,11 +28436,11 @@ function buildCandidates(facts, stats, busy, enabled, contextWidth) {
28350
28436
  if (identity.length > 1) identity.push(sep());
28351
28437
  identity.push(span);
28352
28438
  };
28353
- const model = safe(facts.model);
28439
+ const model = safe(facts.model).split("/").at(-1);
28354
28440
  if (model !== "" && enabled.has("model")) {
28355
- const effort = safe(stats.reasoningEffort);
28441
+ const effort = safe(facts.effort ?? stats.reasoningEffort);
28356
28442
  push({
28357
- text: effort === "" ? model : `${model}@${effort}`,
28443
+ text: effort === "" ? model : `${model} · ${effort}`,
28358
28444
  tone: "model"
28359
28445
  });
28360
28446
  }
@@ -28671,7 +28757,7 @@ function layoutStatusBar(facts, stats, columns, options = {}) {
28671
28757
  },
28672
28758
  row2: {
28673
28759
  left: row2Kept.map((entry) => entry.group),
28674
- right: facts.telemetry ? [{ text: facts.telemetry, tone: "value" }] : [],
28760
+ right: facts.telemetry ? [{ text: facts.telemetry, tone: "meta" }] : [],
28675
28761
  hint: false
28676
28762
  }
28677
28763
  };
@@ -28885,7 +28971,7 @@ function transcriptEntryLines(entry, columns, showReasoning = true, reasoningTog
28885
28971
  }
28886
28972
  /** Settled-history variant carrying the Ctrl+R reasoning fold. */
28887
28973
  function settledEntryLines(entry, columns, showReasoning) {
28888
- return transcriptEntryLines(entry, columns, showReasoning, false, showReasoning);
28974
+ return dscodeChatLines(entry, columns);
28889
28975
  }
28890
28976
  /**
28891
28977
  * Clamp the live-region allocation so the flexible dynamic rows never exceed
@@ -29474,7 +29560,7 @@ function legacyForKey(key) {
29474
29560
  const alt = (bits & 2) !== 0;
29475
29561
  const ctrl = (bits & 4) !== 0;
29476
29562
  if (key.code === 13) {
29477
- if (ctrl) return "\n";
29563
+ if (ctrl || shift) return "\n";
29478
29564
  if (alt) return "\x1B\r";
29479
29565
  return "\r";
29480
29566
  }
@@ -29519,6 +29605,7 @@ function legacyForKey(key) {
29519
29605
  * unaffected.
29520
29606
  */
29521
29607
  function normalizeKeyboardChunk(chunk) {
29608
+ chunk = chunk.replace(/\x1b\[27;2;13~/g, "\n");
29522
29609
  if (!chunk.includes("\x1B[") || !chunk.includes("u")) return chunk;
29523
29610
  const pattern = new RegExp(CSI_U_SOURCE, "g");
29524
29611
  return chunk.replace(pattern, (whole, code, mods, separator, third) => {
@@ -30155,7 +30242,7 @@ function HistoryPanel({ entries, fill, close }) {
30155
30242
  function StatuslinePanel({ enabled, change, close }) {
30156
30243
  const [order, setOrder] = (0, import_react.useState)(() => {
30157
30244
  const seen = new Set(enabled);
30158
- return [...enabled, ...DEFAULT_STATUSLINE_ITEMS.filter((id) => !seen.has(id))];
30245
+ return [...enabled, ...STATUS_ITEMS.map(item => item.id).filter((id) => !seen.has(id))];
30159
30246
  });
30160
30247
  const [on, setOn] = (0, import_react.useState)(() => new Set(enabled));
30161
30248
  const [cursor, setCursor] = (0, import_react.useState)(0);
@@ -31679,68 +31766,16 @@ function PanelGap({ visible }) {
31679
31766
  * keeps its historical three lines. Short or narrow terminals keep a one-line
31680
31767
  * form without the kernel line.
31681
31768
  */
31682
- function Header({ resumed }) {
31683
- const stdout = useStdout().stdout;
31684
- const rows = stdout?.rows ?? 40;
31685
- const columns = stdout?.columns ?? 80;
31686
- const kernelLine = (() => {
31687
- const version = dshKernelVersion();
31688
- return version === void 0 ? void 0 : `dsh-v${version}`;
31689
- })();
31690
- const title = `DeepSeek Harness · v${DSH_CODE_VERSION}`;
31691
- const slogan = "Into the Unknown 探索未至之境";
31692
- const hint = resumed ? "resumed · /help · Esc interrupt" : "/help · Esc interrupt · Ctrl+C quit";
31693
- const copyWidths = [
31694
- visibleColumns(title),
31695
- visibleColumns(slogan),
31696
- visibleColumns(hint)
31697
- ];
31698
- if (kernelLine !== void 0) copyWidths.push(visibleColumns(kernelLine));
31699
- const copyColumns = Math.max(...copyWidths);
31700
- const compact = `${title} · ${hint}`;
31701
- if (rows < 20 || columns < 26 + copyColumns + 10) return (0, import_react.createElement)(Box, {
31702
- width: Math.max(1, columns - 1),
31703
- borderStyle: "round",
31704
- borderColor: inkColor(getPalette().brand),
31705
- paddingX: 1
31706
- }, (0, import_react.createElement)(Text, {
31707
- color: inkColor(getPalette().brandBright),
31708
- bold: true,
31709
- wrap: "truncate-end"
31710
- }, truncateColumns(compact, Math.max(1, columns - 5))));
31711
- return (0, import_react.createElement)(Box, {
31712
- flexDirection: "row",
31713
- gap: 2,
31714
- borderStyle: "round",
31715
- borderColor: inkColor(getPalette().brand),
31716
- paddingX: 2,
31717
- alignSelf: "flex-start"
31718
- }, (0, import_react.createElement)(Box, {
31719
- flexDirection: "column",
31720
- width: 26,
31721
- justifyContent: "center"
31722
- }, ...WHALE_GLYPH.map((row, index) => (0, import_react.createElement)(Text, {
31723
- key: index,
31724
- color: inkColor(getPalette().brand)
31725
- }, row))), (0, import_react.createElement)(Box, {
31726
- flexDirection: "column",
31727
- width: copyColumns,
31728
- justifyContent: "center"
31729
- }, ...kernelLine === void 0 ? [] : [(0, import_react.createElement)(Text, {
31730
- color: inkColor(getPalette().dim),
31731
- wrap: "truncate-end"
31732
- }, kernelLine)], (0, import_react.createElement)(Text, {
31733
- color: inkColor(getPalette().brandBright),
31734
- bold: true,
31735
- wrap: "truncate-end"
31736
- }, title), (0, import_react.createElement)(Text, {
31737
- color: inkColor(getPalette().code),
31738
- wrap: "truncate-end"
31739
- }, (0, import_react.createElement)(Text, { bold: true }, "Into the Unknown"), " 探索未至之境"), (0, import_react.createElement)(Text, {
31740
- color: inkColor(getPalette().dim),
31741
- wrap: "truncate-end"
31742
- }, hint)));
31743
- }
31769
+ function Header({ resumed, cwd = "", branch = "", title = "" }) {
31770
+ const columns = useStdout().stdout?.columns ?? 80;
31771
+ const width = Math.max(1, columns - 4);
31772
+ const project = singleLineText(cwd).split(/[\\/]/).filter(Boolean).at(-1) || "workspace";
31773
+ const identity = "DSCODE · " + project + (branch ? " / " + singleLineText(branch) : "");
31774
+ const subtitle = title ? singleLineText(title) : resumed ? "Session resumed · /help" : "New session · /help";
31775
+ return (0, import_react.createElement)(Box, { flexDirection: "column", paddingX: 2, marginBottom: 1 },
31776
+ (0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright), bold: true, wrap: "truncate-end" }, truncateColumns(identity, width)),
31777
+ (0, import_react.createElement)(Text, { color: inkColor(getPalette().dim), wrap: "truncate-end" }, truncateColumns(subtitle, width)));
31778
+ }
31744
31779
  /** Todo status glyph: web TodoPanel's three-state marker. */
31745
31780
  function todoMark(status) {
31746
31781
  return status === "completed" ? "✓" : status === "in_progress" ? "●" : "○";
@@ -31753,16 +31788,19 @@ function todoMark(status) {
31753
31788
  * /agents panel.
31754
31789
  */
31755
31790
  function AgentsLine({ rows, total }) {
31756
- if (rows.length === 0) return void 0;
31757
- const running = rows.filter((row) => row.state !== "done").length;
31758
- const newest = [...rows].sort((left, right) => right.updatedAt - left.updatedAt)[0];
31759
- const mark = newest.state === "done" ? "✓" : newest.state === "idle" ? "⏸" : "●";
31760
- return (0, import_react.createElement)(Box, { paddingX: 1 }, (0, import_react.createElement)(Text, {
31761
- color: inkColor(getPalette().brand),
31762
- bold: true,
31763
- wrap: "truncate-end"
31764
- }, `agents ${running} live`, (0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, ` · ${total} total · /agents`), (0, import_react.createElement)(Text, { color: inkColor(getPalette().text) }, ` · ${mark} ${newest.label} ${newest.activity}`)));
31765
- }
31791
+ const columns = useStdout().stdout?.columns ?? 80;
31792
+ if (rows.length === 0) return void 0;
31793
+ const running = rows.filter(row => row.state === "running");
31794
+ const idle = rows.filter(row => row.state === "idle").length;
31795
+ const done = rows.filter(row => row.state === "done").length;
31796
+ const active = [...running].sort((a, b) => b.updatedAt - a.updatedAt)[0];
31797
+ const counts = [running.length + " running", idle ? idle + " idle" : "", done ? done + " done" : "", total > rows.length ? total + " total" : ""].filter(Boolean).join(" · ");
31798
+ const summary = "agents " + (columns < 60 ? running.length + " running" : counts) + " · /agents";
31799
+ const detail = active && columns >= 80 ? " — " + singleLineText(active.label) + " · " + singleLineText(active.activity) : "";
31800
+ return (0, import_react.createElement)(Box, { paddingX: 2 },
31801
+ (0, import_react.createElement)(Text, { color: inkColor(getPalette().dim), wrap: "truncate-end" },
31802
+ truncateColumns(summary + detail, Math.max(1, columns - 4))));
31803
+ }
31766
31804
  /** One-row todo summary: task count cannot grow the live Ink tree. */
31767
31805
  function TodoPanel({ todos }) {
31768
31806
  if (todos.length === 0) return void 0;
@@ -31845,8 +31883,8 @@ const MemoTodoListPanel = (0, import_react.memo)(TodoListPanel);
31845
31883
  function statusToneProps(tone) {
31846
31884
  switch (tone) {
31847
31885
  case "model": return {
31848
- color: inkColor(getPalette().code),
31849
- bold: true,
31886
+ color: void 0,
31887
+ bold: void 0,
31850
31888
  dimColor: void 0
31851
31889
  };
31852
31890
  case "live": return {
@@ -31946,7 +31984,7 @@ function deepseekWaveHues(tier) {
31946
31984
  function StatusLine({ facts, stats, busy, columns, items }) {
31947
31985
  const [, refreshMetrics] = (0, import_react.useState)(0);
31948
31986
  (0, import_react.useEffect)(() => { const timer = setInterval(() => refreshMetrics(n => n + 1), 1000); return () => clearInterval(timer); }, []);
31949
- facts = { ...facts, telemetry: dscodeFooterFor(facts.fullSessionId, stats, Math.max(1, columns - 6)) };
31987
+ facts = { ...facts, telemetry: columns >= 64 ? dscodeFooterFor(facts.fullSessionId, stats, Math.max(1, Math.floor(columns / 2) - 4)) : "" };
31950
31988
  const layout = (0, import_react.useMemo)(() => layoutStatusBar(facts, stats, Math.max(8, columns - 2), {
31951
31989
  busy,
31952
31990
  items,
@@ -31954,6 +31992,7 @@ function StatusLine({ facts, stats, busy, columns, items }) {
31954
31992
  }), [
31955
31993
  facts.telemetry,
31956
31994
  facts.model,
31995
+ facts.effort,
31957
31996
  facts.mode,
31958
31997
  facts.cwd,
31959
31998
  facts.branch,
@@ -33932,6 +33971,13 @@ function CompletionMenu({ active, mention, index, rows, error }) {
33932
33971
  function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, interrupt, quit, openModel, openEffort, openHelp, openMode, openPermission, openResume, openPlugin, openJobs, openStatusline, openTheme, openHistory, openAgents, openSubagent, openTodos, openDelete, openDiff, reviewChanges, deleteConfirm, confirmDelete, cancelDelete, createSession, forkSession, cancelSessionSwitch, notify, applyEditorKeys, hasNotice, dismissNotice, toggleReasoning, openVerbose, clearView, refresh, loadMentions, inspectImages, prepareImages, inspectFiles, prepareFiles, cyclePermission, exportTranscript, renameTitle, copyLastResponse, recallSpace, recordLocal, recordHistory, queued, cancelQueued, historyFill, historyConsumed, animations, applyAnimations, waveTier, waveStyle, maxRows, onEditorRows, onMenuRows, sessionKey }) {
33933
33972
  const columns = useStdout().stdout?.columns ?? 80;
33934
33973
  const inputTerminalRows = useStdout().stdout?.rows ?? 30;
33974
+ const dscodeImeStdout = useStdout().stdout;
33975
+ const dscodeImeState = (0, import_react.useRef)({});
33976
+ const dscodeImeRef = (0, import_react.useCallback)(node => {
33977
+ dscodeImeState.current.node = node;
33978
+ if (node) dscodeImeAnchors.set(dscodeImeStdout, dscodeImeState.current);
33979
+ else dscodeImeAnchors.delete(dscodeImeStdout);
33980
+ }, [dscodeImeStdout]);
33935
33981
  const editorColumns = Math.max(1, columns - 6);
33936
33982
  const stdin = useStdin().stdin;
33937
33983
  const focusReporting = isVsCodeTerminalEnv();
@@ -34430,6 +34476,10 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
34430
34476
  return;
34431
34477
  }
34432
34478
  }
34479
+ if (input === "\n" || key.ctrl && input === "j" || key.return && key.shift) {
34480
+ applyEdit(insertText(liveValue, liveCursor, "\n"));
34481
+ return;
34482
+ }
34433
34483
  if (key.return) {
34434
34484
  if (pasteBracketRef.current) {
34435
34485
  applyEdit(insertText(liveValue, liveCursor, "\n"));
@@ -34769,6 +34819,7 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
34769
34819
  const currentEditorScroll = Math.min(Math.max(0, editorScrollRef.current), maxEditorScroll);
34770
34820
  const editorWindowStart = caret.row < currentEditorScroll ? caret.row : caret.row >= currentEditorScroll + editorWindowRows ? caret.row - editorWindowRows + 1 : currentEditorScroll;
34771
34821
  editorScrollRef.current = editorWindowStart;
34822
+ Object.assign(dscodeImeState.current, { row: caret.row - editorWindowStart, column: 2 + caret.column, active: active && !frozen && !preparingImages });
34772
34823
  const editorRowCount = frozen ? 1 : editorWindowRows;
34773
34824
  (0, import_react.useEffect)(() => {
34774
34825
  onEditorRows(editorRowCount);
@@ -34828,7 +34879,7 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
34828
34879
  }, index === 0 ? preparingImages ? (0, import_react.createElement)(Text, {
34829
34880
  color: inkColor(getPalette().warn),
34830
34881
  bold: true
34831
- }, "… ") : busy ? (0, import_react.createElement)(BusyChase, { animated: animations }) : (0, import_react.createElement)(Text, {
34882
+ }, "… ") : busy ? (0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, "› ") : (0, import_react.createElement)(Text, {
34832
34883
  color: promptColor,
34833
34884
  bold: tierActive ? true : void 0
34834
34885
  }, `${promptGlyph} `) : " ", parts.before, parts.hasCaret ? (0, import_react.createElement)(Text, {
@@ -34836,12 +34887,15 @@ function Input({ active, frozen, busy, descriptors, skills, dispatch, steer, int
34836
34887
  inverse: cursorVisible || void 0
34837
34888
  }, parts.caret) : null, placeholder ? (0, import_react.createElement)(Text, { dimColor: true }, COMPOSER_PLACEHOLDER) : parts.after, bandFill(consumed)));
34838
34889
  }
34839
- const staticEditor = (0, import_react.createElement)(Box, { flexDirection: "column" }, ...editorRows);
34890
+ const staticEditor = (0, import_react.createElement)(Box, {
34891
+ flexDirection: "column",
34892
+ ref: dscodeImeRef
34893
+ }, ...editorRows);
34840
34894
  return (0, import_react.createElement)(Box, { flexDirection: "column" }, menu, (0, import_react.createElement)(ComposerWave, {
34841
34895
  key: waveKey ?? "static",
34842
34896
  tier: waveTier ?? "deepseek",
34843
34897
  style: waveStyle ?? "wave",
34844
- active: waveTier !== null && waveStyle !== null && !busy && !preparingImages && animations && waveArmed,
34898
+ active: false, // DSCODE keeps the input band stable
34845
34899
  onSettled: () => {
34846
34900
  if (waveKey !== null) setWavePlayedKey(waveKey);
34847
34901
  },
@@ -34918,7 +34972,7 @@ function settledTrimHint(droppedEntries, columns) {
34918
34972
  * While a turn is busy or streaming, Ctrl+R only flips the live region; rows
34919
34973
  * already emitted to native scrollback change exclusively through rebuilds.
34920
34974
  */
34921
- function computeSettledRows(previous, entries, settled, showReasoning, resumed, epoch, columns = 80, rowCap = SETTLED_ROW_CAP) {
34975
+ function computeSettledRows(previous, entries, settled, showReasoning, resumed, epoch, columns = 80, rowCap = SETTLED_ROW_CAP, headerFacts = {}) {
34922
34976
  if (previous === void 0 || previous.epoch !== epoch || previous.resumed !== resumed || settled < previous.entries.length) {
34923
34977
  const records = /* @__PURE__ */ new Map();
34924
34978
  const window = [];
@@ -34941,6 +34995,7 @@ function computeSettledRows(previous, entries, settled, showReasoning, resumed,
34941
34995
  }
34942
34996
  const header = (0, import_react.createElement)(Header, {
34943
34997
  key: "header",
34998
+ ...headerFacts,
34944
34999
  resumed
34945
35000
  });
34946
35001
  const flat = droppedEntries > 0 ? [
@@ -35272,7 +35327,7 @@ function App(props) {
35272
35327
  const terminalSizeRef = (0, import_react.useRef)(terminalSize);
35273
35328
  const settledRowsCache = (0, import_react.useRef)(void 0);
35274
35329
  const settledRows = (0, import_react.useMemo)(() => {
35275
- const result = computeSettledRows(settledRowsCache.current, view.entries, settled, showReasoning, props.resumed, refreshEpoch, terminalSize.columns);
35330
+ const result = computeSettledRows(settledRowsCache.current, view.entries, settled, showReasoning, props.resumed, refreshEpoch, terminalSize.columns, SETTLED_ROW_CAP, { cwd: props.cwd, branch: props.branch, title: view.title });
35276
35331
  settledRowsCache.current = result.cache;
35277
35332
  return result.cache.flat;
35278
35333
  }, [
@@ -35322,9 +35377,9 @@ function App(props) {
35322
35377
  const composerEditorCap = composerMaxRows(terminalRows);
35323
35378
  const MENU_RESERVE_ROWS = 5;
35324
35379
  const dynamicRows = Math.max(1, terminalRows - 8 - MENU_RESERVE_ROWS - composerGutterRows - (composerRows - 1) - Math.max(0, menuRows - MENU_RESERVE_ROWS));
35325
- const streamingActive = view.streaming !== "" || view.streamingReasoning !== "";
35326
- const deepDivingVisible = busy && !streamingActive;
35327
- const allLiveLines = (0, import_react.useMemo)(() => view.entries.slice(settled).flatMap((entry) => transcriptEntryLines(entry, Math.max(1, terminalColumns - 2), showReasoning)), [
35380
+ const streamingActive = view.streaming !== "";
35381
+ const deepDivingVisible = busy;
35382
+ const allLiveLines = (0, import_react.useMemo)(() => view.entries.slice(settled).flatMap((entry) => dscodeChatLines(entry, Math.max(1, terminalColumns - 2))), [
35328
35383
  view.entries,
35329
35384
  settled,
35330
35385
  terminalColumns,
@@ -35333,7 +35388,7 @@ function App(props) {
35333
35388
  const liveBudget = busy || streamingActive ? Math.max(1, Math.floor(dynamicRows / 3)) : Math.max(0, dynamicRows - (deepDivingVisible ? 1 : 0));
35334
35389
  const visibleLiveLines = liveBudget === 0 ? [] : allLiveLines.slice(-liveBudget);
35335
35390
  const streamRows = Math.max(1, dynamicRows - visibleLiveLines.length);
35336
- const reasoningRows = view.streamingReasoning === "" ? 0 : view.streaming === "" ? streamRows : streamRows <= 1 ? 0 : showReasoning ? Math.max(1, Math.floor(streamRows / 3)) : 1;
35391
+ const reasoningRows = 0;
35337
35392
  const answerRows = view.streaming === "" ? 0 : Math.max(1, streamRows - reasoningRows);
35338
35393
  const liveAudit = clampLiveAllocation({
35339
35394
  live: visibleLiveLines.length,
@@ -35607,7 +35662,7 @@ function App(props) {
35607
35662
  dim: true,
35608
35663
  maxRows: auditedReasoningRows
35609
35664
  }) : view.streaming === "" ? (0, import_react.createElement)(ShimmerLine, {
35610
- text: "✻ Thinking… (Ctrl/Alt+R to expand)",
35665
+ text: "Working…",
35611
35666
  animated: animations
35612
35667
  }) : (0, import_react.createElement)(StreamTail, {
35613
35668
  text: "Thinking… (Ctrl/Alt+R to expand)",
@@ -35620,10 +35675,7 @@ function App(props) {
35620
35675
  dim: false,
35621
35676
  maxRows: auditedAnswerRows,
35622
35677
  prefix: " "
35623
- }, busy ? (0, import_react.createElement)(Caret, { animated: animations }) : void 0) : void 0, deepDivingVisible ? (0, import_react.createElement)(DeepDivingLine, {
35624
- since: view.busySince,
35625
- animated: animations
35626
- }) : void 0) : void 0, transcriptVisible ? (0, import_react.createElement)(TodoPanel, { todos: view.todos }) : void 0, transcriptVisible ? (0, import_react.createElement)(AgentsLine, {
35678
+ }, busy ? (0, import_react.createElement)(Caret, { animated: animations }) : void 0) : void 0, void 0) : void 0, transcriptVisible && busy ? (0, import_react.createElement)(DscodeActivityLine, { entries: view.entries, streaming: view.streaming !== "", since: view.busySince, animated: animations }) : void 0, transcriptVisible ? (0, import_react.createElement)(AgentsLine, {
35627
35679
  rows: agentRows,
35628
35680
  total: props.subagents.getTotalSeen()
35629
35681
  }) : void 0, todosOpen && !approvalPending && !questionPending ? (0, import_react.createElement)(MemoTodoListPanel, {
@@ -35886,6 +35938,7 @@ function App(props) {
35886
35938
  facts: {
35887
35939
  fullSessionId: props.sessionKey,
35888
35940
  model: modelLabel,
35941
+ effort: effortLabel,
35889
35942
  mode: props.mode,
35890
35943
  cwd: props.cwd,
35891
35944
  branch: props.branch,
@@ -38273,6 +38326,7 @@ async function run(ctx, startup, io) {
38273
38326
  name: "flush",
38274
38327
  run: async () => {
38275
38328
  await sessions.flush(currentSession);
38329
+ internals.stderr.write("\nResume this session: dscode resume " + currentSession.id + "\n");
38276
38330
  }
38277
38331
  }, {
38278
38332
  name: "dispose",
@@ -38340,6 +38394,10 @@ async function run(ctx, startup, io) {
38340
38394
  const deliverLine = (line, mode, images = []) => {
38341
38395
  const currentAgent = agent;
38342
38396
  const currentMentions = mentions;
38397
+ if (images.length === 0 && line.startsWith("!")) {
38398
+ runSlash("/shell-exec " + line.slice(1));
38399
+ return;
38400
+ }
38343
38401
  if (images.length === 0 && isSlashLine(line) && mode === "followup") {
38344
38402
  runSlash(line);
38345
38403
  return;