scream-code 0.10.5 → 0.10.7

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.
@@ -7,7 +7,7 @@ import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } fr
7
7
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
8
8
  import { C as join$1, D as resolve$1, E as relative$1, S as isAbsolute$1, T as parse$7, a as isSupportedFile, b as basename$1, i as ingestFile, r as ingestDirectory, t as multiSearch, w as normalize, x as dirname$2, y as KnowledgeStore } from "./src-BH9W5k24.mjs";
9
9
  import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
10
- import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-pClOx34t.mjs";
10
+ import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-BWp39mq8.mjs";
11
11
  import { createRequire } from "node:module";
12
12
  import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
13
13
  import * as fs$1 from "node:fs/promises";
@@ -55788,6 +55788,8 @@ function formatBudget(value, unit) {
55788
55788
  */
55789
55789
  /** Maximum objective length in characters. */
55790
55790
  const MAX_GOAL_OBJECTIVE_LENGTH = 4e3;
55791
+ /** Consecutive markBlocked calls with the same reason required before blocking. */
55792
+ const BLOCKED_STREAK_THRESHOLD = 3;
55791
55793
  /** Maximum number of working notes kept per goal. */
55792
55794
  const MAX_GOAL_NOTES = 30;
55793
55795
  /** Maximum characters per note. */
@@ -55835,7 +55837,8 @@ var GoalMode = class {
55835
55837
  tokensUsed: 0,
55836
55838
  wallClockMs: 0,
55837
55839
  budgetLimits: {},
55838
- notes: []
55840
+ notes: [],
55841
+ blockedStreak: 0
55839
55842
  };
55840
55843
  this.state = state;
55841
55844
  }
@@ -55887,7 +55890,8 @@ var GoalMode = class {
55887
55890
  wallClockMs: 0,
55888
55891
  wallClockResumedAt: Date.now(),
55889
55892
  budgetLimits: {},
55890
- notes: []
55893
+ notes: [],
55894
+ blockedStreak: 0
55891
55895
  };
55892
55896
  this.persistState(state);
55893
55897
  this.agent.records.logRecord({
@@ -55932,6 +55936,8 @@ var GoalMode = class {
55932
55936
  if (state.status === "active") return this.toSnapshot(state);
55933
55937
  if (state.status !== "paused" && state.status !== "blocked") throw new ScreamError(ErrorCodes.GOAL_NOT_RESUMABLE, `Cannot resume a goal in status "${state.status}"`);
55934
55938
  state.terminalReason = void 0;
55939
+ state.blockedStreak = 0;
55940
+ state.lastBlockedReason = void 0;
55935
55941
  this.applyStatus(state, "active");
55936
55942
  this.persistState(state, { change: {
55937
55943
  kind: "lifecycle",
@@ -55965,8 +55971,22 @@ var GoalMode = class {
55965
55971
  async markBlocked(input = {}, actor = "runtime") {
55966
55972
  const state = this.state;
55967
55973
  if (state === void 0 || state.status !== "active") return null;
55974
+ if (actor === "model") {
55975
+ const reason = input.reason ?? "";
55976
+ if (reason === (state.lastBlockedReason ?? "")) state.blockedStreak += 1;
55977
+ else {
55978
+ state.blockedStreak = 1;
55979
+ state.lastBlockedReason = reason;
55980
+ }
55981
+ if (state.blockedStreak < BLOCKED_STREAK_THRESHOLD) {
55982
+ this.persistState(state, { silent: true });
55983
+ return null;
55984
+ }
55985
+ }
55968
55986
  this.applyStatus(state, "blocked");
55969
55987
  state.terminalReason = input.reason;
55988
+ state.blockedStreak = 0;
55989
+ state.lastBlockedReason = void 0;
55970
55990
  this.persistState(state, { change: {
55971
55991
  kind: "lifecycle",
55972
55992
  status: "blocked",
@@ -56168,12 +56188,15 @@ function formatTokens$2(tokens) {
56168
56188
  }
56169
56189
  //#endregion
56170
56190
  //#region ../../packages/agent-core/src/tools/builtin/goal/update-goal.ts
56171
- const UpdateGoalToolInputSchema = z.object({ status: z.enum([
56172
- "active",
56173
- "complete",
56174
- "paused",
56175
- "blocked"
56176
- ]).describe("The lifecycle status to set for the current goal.") }).strict();
56191
+ const UpdateGoalToolInputSchema = z.object({
56192
+ status: z.enum([
56193
+ "active",
56194
+ "complete",
56195
+ "paused",
56196
+ "blocked"
56197
+ ]).describe("The lifecycle status to set for the current goal."),
56198
+ reason: z.string().optional().describe("Optional reason for the status change, especially for blocked.")
56199
+ }).strict();
56177
56200
  const MAX_GRADER_OUTPUT_CHARS = 4e3;
56178
56201
  function extractRecentOutput(history) {
56179
56202
  const parts = [];
@@ -56209,15 +56232,18 @@ var UpdateGoalTool = class {
56209
56232
  }
56210
56233
  if (args.status === "complete") return this.handleComplete(goal);
56211
56234
  if (args.status === "blocked") {
56212
- const blocked = await goal.markBlocked({}, "model");
56213
- if (blocked !== null) this.agent.context.appendSystemReminder(buildGoalBlockedReasonPrompt(blocked), {
56214
- kind: "system_trigger",
56215
- name: GOAL_BLOCKED_REMINDER_NAME
56216
- });
56217
- return {
56218
- output: "Goal marked blocked.",
56219
- stopTurn: true
56220
- };
56235
+ const blocked = await goal.markBlocked(args.reason !== void 0 ? { reason: args.reason } : {}, "model");
56236
+ if (blocked !== null) {
56237
+ this.agent.context.appendSystemReminder(buildGoalBlockedReasonPrompt(blocked), {
56238
+ kind: "system_trigger",
56239
+ name: GOAL_BLOCKED_REMINDER_NAME
56240
+ });
56241
+ return {
56242
+ output: "Goal marked blocked.",
56243
+ stopTurn: true
56244
+ };
56245
+ }
56246
+ return { output: "Goal remains active. Report the same blocker in subsequent turns to confirm it cannot be resolved. Continue working on the goal in the meantime." };
56221
56247
  }
56222
56248
  await goal.pauseGoal({}, "model");
56223
56249
  return {
@@ -97983,9 +98009,11 @@ const GOAL_CONTINUATION_PROMPT = [
97983
98009
  "reassess. Call UpdateGoal with `complete` only when all required work is done, any stated",
97984
98010
  "validation has passed, and there is no useful next action. Do not mark complete after only",
97985
98011
  "producing a plan, summary, first pass, or partial result. If an external condition or required",
97986
- "user input prevents progress, or the objective cannot be completed as stated, call UpdateGoal",
97987
- "with `blocked`. Otherwise keep going use the existing conversation context and your tools,",
97988
- "and do not ask the user for input unless a real blocker prevents progress."
98012
+ "user input prevents progress, call UpdateGoal with `blocked` and include a `reason`. The goal",
98013
+ "will only be marked blocked after you report the same blocker for at least 3 consecutive",
98014
+ "turns, so first try alternative approaches. Otherwise keep going use the existing",
98015
+ "conversation context and your tools, and do not ask the user for input unless a real blocker",
98016
+ "prevents progress."
97989
98017
  ].join(" ");
97990
98018
  const GOAL_CONTINUATION_ORIGIN = {
97991
98019
  kind: "system_trigger",
@@ -98875,6 +98903,7 @@ var LtodLLM = class {
98875
98903
  this.obfuscator = config.obfuscator;
98876
98904
  }
98877
98905
  async chat(params) {
98906
+ const chatStartedAt = Date.now();
98878
98907
  let requestStartedAt = Date.now();
98879
98908
  let firstChunkAt;
98880
98909
  let streamEndedAt;
@@ -98894,13 +98923,22 @@ var LtodLLM = class {
98894
98923
  capability: this.capability
98895
98924
  });
98896
98925
  const outboundMessages = this.obfuscator && this.obfuscator.hasSecrets() ? obfuscateMessages(this.obfuscator, params.messages) : params.messages;
98897
- const result = await this.generate(effectiveProvider, this.systemPrompt, [...params.tools], outboundMessages, callbacks, generateOptions(params, {
98926
+ const runGenerate = (messages) => this.generate(effectiveProvider, this.systemPrompt, [...params.tools], messages, callbacks, generateOptions(params, {
98898
98927
  onRequestStart: markRequestStart,
98899
98928
  onStreamEnd: () => {
98900
98929
  markStreamEnd();
98901
98930
  flushPending();
98902
98931
  }
98903
98932
  }));
98933
+ let result;
98934
+ try {
98935
+ result = await runGenerate(outboundMessages);
98936
+ } catch (error) {
98937
+ if (!(error instanceof APIContextOverflowError)) throw error;
98938
+ const strippedMessages = stripMediaFromMessages(outboundMessages);
98939
+ if (strippedMessages === null) throw error;
98940
+ result = await runGenerate(strippedMessages);
98941
+ }
98904
98942
  if (params.onTextPart !== void 0 || params.onThinkPart !== void 0) {
98905
98943
  for (const part of result.message.content) if (part.type === "text" && params.onTextPart !== void 0) await params.onTextPart(part);
98906
98944
  else if (part.type === "think" && params.onThinkPart !== void 0) await params.onThinkPart(part);
@@ -98910,18 +98948,21 @@ var LtodLLM = class {
98910
98948
  providerFinishReason: result.finishReason ?? void 0,
98911
98949
  rawFinishReason: result.rawFinishReason ?? void 0,
98912
98950
  usage: result.usage ?? emptyUsage(),
98913
- streamTiming: firstChunkAt === void 0 ? void 0 : buildStreamTiming(requestStartedAt, firstChunkAt, streamEndedAt)
98951
+ streamTiming: firstChunkAt === void 0 ? void 0 : buildStreamTiming(chatStartedAt, requestStartedAt, firstChunkAt, streamEndedAt)
98914
98952
  };
98915
98953
  }
98916
98954
  isRetryableError(error) {
98917
98955
  return isRetryableGenerateError(error);
98918
98956
  }
98919
98957
  };
98920
- function buildStreamTiming(requestStartedAt, firstChunkAt, streamEndedAt) {
98958
+ function buildStreamTiming(chatStartedAt, requestStartedAt, firstChunkAt, streamEndedAt) {
98921
98959
  const outputEndedAt = streamEndedAt ?? Date.now();
98922
98960
  return {
98923
98961
  firstTokenLatencyMs: Math.max(0, firstChunkAt - requestStartedAt),
98924
- streamDurationMs: Math.max(0, outputEndedAt - firstChunkAt)
98962
+ streamDurationMs: Math.max(0, outputEndedAt - firstChunkAt),
98963
+ requestBuildMs: Math.max(0, requestStartedAt - chatStartedAt),
98964
+ serverFirstTokenMs: Math.max(0, firstChunkAt - requestStartedAt),
98965
+ serverDecodeMs: Math.max(0, outputEndedAt - firstChunkAt)
98925
98966
  };
98926
98967
  }
98927
98968
  function generateOptions(params, hooks) {
@@ -99056,6 +99097,27 @@ function buildLtodCallbacks(params, markStreamOutput, obfuscator) {
99056
99097
  }
99057
99098
  };
99058
99099
  }
99100
+ /**
99101
+ * Remove image parts from messages for context-overflow retry.
99102
+ * Returns null when no media was found (no point retrying without media).
99103
+ */
99104
+ function stripMediaFromMessages(messages) {
99105
+ let hasMedia = false;
99106
+ const stripped = messages.map((msg) => {
99107
+ const newContent = msg.content.filter((part) => {
99108
+ if (part.type !== "text" && part.type !== "think") {
99109
+ hasMedia = true;
99110
+ return false;
99111
+ }
99112
+ return true;
99113
+ });
99114
+ return {
99115
+ ...msg,
99116
+ content: newContent
99117
+ };
99118
+ });
99119
+ return hasMedia ? stripped : null;
99120
+ }
99059
99121
  //#endregion
99060
99122
  //#region ../../packages/agent-core/src/agent/usage/index.ts
99061
99123
  function copyUsage(usage) {
@@ -122917,7 +122979,7 @@ function optionalBuildString(value) {
122917
122979
  return typeof value === "string" && value.length > 0 ? value : void 0;
122918
122980
  }
122919
122981
  const SCREAM_BUILD_INFO = {
122920
- version: optionalBuildString("0.10.5"),
122982
+ version: optionalBuildString("0.10.7"),
122921
122983
  channel: optionalBuildString(""),
122922
122984
  commit: optionalBuildString(""),
122923
122985
  buildTarget: optionalBuildString("darwin-arm64")
@@ -123910,6 +123972,7 @@ const BUILTIN_SLASH_COMMANDS = [
123910
123972
  name: "goal",
123911
123973
  aliases: ["goaloff"],
123912
123974
  description: "registry.goal_desc",
123975
+ argumentHint: "[objective]",
123913
123976
  priority: 122,
123914
123977
  availability: (args) => {
123915
123978
  const trimmed = args.trim();
@@ -123920,6 +123983,7 @@ const BUILTIN_SLASH_COMMANDS = [
123920
123983
  name: "memory",
123921
123984
  aliases: ["memo", "mem"],
123922
123985
  description: "registry.memory_desc",
123986
+ argumentHint: "[query]",
123923
123987
  priority: 120,
123924
123988
  availability: "always"
123925
123989
  },
@@ -123927,6 +123991,7 @@ const BUILTIN_SLASH_COMMANDS = [
123927
123991
  name: "knowledge",
123928
123992
  aliases: ["know"],
123929
123993
  description: "registry.knowledge_desc",
123994
+ argumentHint: "[query]",
123930
123995
  priority: 119,
123931
123996
  availability: "always"
123932
123997
  },
@@ -123940,6 +124005,7 @@ const BUILTIN_SLASH_COMMANDS = [
123940
124005
  name: "model",
123941
124006
  aliases: [],
123942
124007
  description: "registry.model_desc",
124008
+ argumentHint: "[alias]",
123943
124009
  priority: 120
123944
124010
  },
123945
124011
  {
@@ -126123,6 +126189,18 @@ function formatContextStatus(usage, tokens, maxTokens) {
126123
126189
  });
126124
126190
  return t("footer.context_short", { pct });
126125
126191
  }
126192
+ /** Format goal wall-clock duration compactly: `3m`, `1m30s`, `45s`. */
126193
+ function formatGoalDuration(ms) {
126194
+ const totalSeconds = Math.floor(ms / 1e3);
126195
+ if (totalSeconds < 60) return `${totalSeconds}s`;
126196
+ const minutes = Math.floor(totalSeconds / 60);
126197
+ const seconds = totalSeconds % 60;
126198
+ return seconds > 0 ? `${minutes}m${seconds}s` : `${minutes}m`;
126199
+ }
126200
+ /** Build the footer goal badge: `GOAL 3m · 7 turns`. */
126201
+ function formatGoalBadge(wallClockMs, turnsUsed) {
126202
+ return `GOAL ${formatGoalDuration(wallClockMs)} · ${turnsUsed} turns`;
126203
+ }
126126
126204
  const CONTEXT_WARNING_PERCENT_THRESHOLD = 60;
126127
126205
  const CONTEXT_ERROR_PERCENT_THRESHOLD = 90;
126128
126206
  function pickContextColor(usage, colors) {
@@ -126148,7 +126226,7 @@ const SPINNER_FRAMES$1 = [
126148
126226
  "◎",
126149
126227
  "◉"
126150
126228
  ];
126151
- const SPINNER_TICK_MS = 120;
126229
+ const SPINNER_TICK_MS = 60;
126152
126230
  function hexToRgb$2(hex) {
126153
126231
  const v = parseInt(hex.slice(1), 16);
126154
126232
  return [
@@ -126172,7 +126250,7 @@ function lerpGradient(t) {
126172
126250
  }
126173
126251
  function buildStatusLine(streamingPhase, streamingStartTime, reconnectAttempt) {
126174
126252
  if (streamingPhase === "idle") return t("status.idle");
126175
- if (reconnectAttempt > 0) return chalk.hex("#E85454").bold("◎") + " " + chalk.hex("#E85454")(`${t("status.reconnecting")} ${String(reconnectAttempt)}`);
126253
+ if (reconnectAttempt > 0 && streamingPhase === "waiting") return chalk.hex("#E85454").bold("◎") + " " + chalk.hex("#E85454")(`${t("status.reconnecting")} ${String(reconnectAttempt)}`);
126176
126254
  let label;
126177
126255
  if (streamingPhase === "tool") label = t("status.tool");
126178
126256
  else if (streamingPhase === "waiting") label = t("status.waiting");
@@ -126256,7 +126334,7 @@ var FooterComponent = class {
126256
126334
  #restartStatusTimer(phase) {
126257
126335
  this.#stopStatusTimer();
126258
126336
  if (phase === "idle") return;
126259
- const intervalMs = phase === "thinking" ? 1e3 / 30 : SPINNER_TICK_MS;
126337
+ const intervalMs = 1e3 / 60;
126260
126338
  this.statusTimer = setInterval(() => {
126261
126339
  this.ui.requestRender();
126262
126340
  }, intervalMs);
@@ -126275,7 +126353,11 @@ var FooterComponent = class {
126275
126353
  left.push(chalk.hex(isFusion ? colors.fusionPlanMode : colors.planMode).bold(isFusion ? t("badge.fusion") : t("badge.plan")));
126276
126354
  }
126277
126355
  if (state.wolfpackMode) left.push(chalk.hex(colors.wolfpackMode).bold(t("badge.wolfpack")));
126278
- if (state.goalActive) left.push(chalk.hex(colors.primary).bold(t("badge.goal")));
126356
+ if (state.goalActive && state.goal) {
126357
+ const g = state.goal;
126358
+ const goalLabel = formatGoalBadge(g.wallClockMs, g.turnsUsed);
126359
+ left.push(chalk.hex(colors.primary).bold(goalLabel));
126360
+ }
126279
126361
  const model = shortenModel(modelDisplayName(state));
126280
126362
  if (model) if (state.streamingPhase === "thinking") left.push(shimmerText(model, colors));
126281
126363
  else left.push(chalk.hex(colors.textDim)(model));
@@ -128221,7 +128303,7 @@ async function createGoal(host, parsed) {
128221
128303
  await showGoalConfigWizard(host, session, parsed.objective, parsed.replace);
128222
128304
  }
128223
128305
  async function showGoalConfigWizard(host, session, objective, replace) {
128224
- const { TextInputDialogComponent } = await import("./text-input-dialog-zZlNFEk3.mjs");
128306
+ const { TextInputDialogComponent } = await import("./text-input-dialog-DqBy9bEe.mjs");
128225
128307
  const turnInput = await promptNumber(host, TextInputDialogComponent, {
128226
128308
  title: t("goal.wizard_title", { objective }),
128227
128309
  subtitle: t("goal.budget_turns_hint"),
@@ -129375,14 +129457,14 @@ var ThinkingComponent = class {
129375
129457
  cachedWidth;
129376
129458
  cachedLines;
129377
129459
  constructor(text, colors, showMarker = true, mode = "finalized", ui) {
129378
- this.text = text;
129460
+ this.text = text.replace(/^\n+/, "");
129379
129461
  this.color = colors.roleThinking;
129380
129462
  this.dimColor = colors.textDim;
129381
129463
  this.accentColor = colors.primary;
129382
129464
  this.showMarker = showMarker;
129383
129465
  this.mode = mode;
129384
129466
  this.ui = ui;
129385
- this.textComponent = new Text(this.styled(text), 0, 0);
129467
+ this.textComponent = new Text(this.styled(this.text), 0, 0);
129386
129468
  if (mode === "live") this.startSpinner();
129387
129469
  }
129388
129470
  invalidate() {
@@ -129390,11 +129472,12 @@ var ThinkingComponent = class {
129390
129472
  this.cachedLines = void 0;
129391
129473
  }
129392
129474
  setText(text) {
129393
- if (this.text === text) return;
129394
- this.text = text;
129475
+ const trimmed = text.replace(/^\n+/, "");
129476
+ if (this.text === trimmed) return;
129477
+ this.text = trimmed;
129395
129478
  this.cachedWidth = void 0;
129396
129479
  this.cachedLines = void 0;
129397
- this.textComponent.setText(this.styled(text));
129480
+ this.textComponent.setText(this.styled(trimmed));
129398
129481
  }
129399
129482
  styled(text) {
129400
129483
  return chalk.hex(this.color).italic(text);
@@ -138265,7 +138348,10 @@ var SessionEventHandler = class {
138265
138348
  pendingApproval: null,
138266
138349
  pendingQuestion: null
138267
138350
  });
138268
- this.host.setAppState({ streamingPhase: "waiting" });
138351
+ this.host.setAppState({
138352
+ streamingPhase: "waiting",
138353
+ reconnectAttempt: 0
138354
+ });
138269
138355
  }
138270
138356
  handleStepCompleted(event) {
138271
138357
  this.host.streamingUI.flushNow();
@@ -138563,7 +138649,11 @@ var SessionEventHandler = class {
138563
138649
  goalActive: false
138564
138650
  });
138565
138651
  else this.host.setAppState({
138566
- goal: snapshot.objective,
138652
+ goal: {
138653
+ objective: snapshot.objective,
138654
+ turnsUsed: snapshot.turnsUsed ?? 0,
138655
+ wallClockMs: snapshot.wallClockMs ?? 0
138656
+ },
138567
138657
  goalActive: snapshot.status === "active"
138568
138658
  });
138569
138659
  }
@@ -141997,7 +142087,7 @@ var PulseWaveLoader = class extends Text {
141997
142087
  2
141998
142088
  ].map((idx) => this.renderCell(idx, step.active, step.forward));
141999
142089
  this.setText(cells.join(" "));
142000
- this.ui.requestComponentRender(this);
142090
+ this.ui.requestRender();
142001
142091
  }
142002
142092
  renderCell(index, active, forward) {
142003
142093
  const distance = forward ? active - index : index - active;
@@ -142382,9 +142472,10 @@ var FileMentionProvider = class {
142382
142472
  const name = ac.value ?? ac.name ?? "";
142383
142473
  const desc = ac.description ?? "";
142384
142474
  const resolvedDesc = desc ? t(desc) : "";
142475
+ const aliases = cmd.aliases;
142385
142476
  return {
142386
142477
  value: name,
142387
- label: `/${name}${resolvedDesc ? ` — ${resolvedDesc}` : ""}`
142478
+ label: `/${name}${aliases && aliases.length > 0 ? ` (${aliases.join(", ")})` : ""}${resolvedDesc ? ` — ${resolvedDesc}` : ""}`
142388
142479
  };
142389
142480
  });
142390
142481
  this.inner = new CombinedAutocompleteProvider(slashCommands, workDir, fdPath);
@@ -142739,10 +142830,18 @@ var InputController = class InputController {
142739
142830
  this.host = host;
142740
142831
  }
142741
142832
  setupAutocomplete() {
142742
- const slashCommands = this.host.getSlashCommands().filter((cmd) => !cmd.name.startsWith("skill:")).map((cmd) => cmd);
142833
+ const visible = this.host.getSlashCommands().filter((cmd) => !cmd.name.startsWith("skill:"));
142834
+ const slashCommands = visible.map((cmd) => cmd);
142743
142835
  const { state } = this.host;
142744
142836
  const provider = new FileMentionProvider(slashCommands, state.appState.workDir, state.fdPath, state.gitLsFilesCache);
142745
142837
  state.editor.setAutocompleteProvider(provider);
142838
+ const argumentHints = /* @__PURE__ */ new Map();
142839
+ for (const cmd of visible) {
142840
+ if (cmd.argumentHint === void 0) continue;
142841
+ argumentHints.set(cmd.name, cmd.argumentHint);
142842
+ for (const alias of cmd.aliases) argumentHints.set(alias, cmd.argumentHint);
142843
+ }
142844
+ state.editor.setArgumentHints(argumentHints);
142746
142845
  state.editor.onFirstInput = () => {
142747
142846
  this.host.stopWelcomeBreathing();
142748
142847
  this.#permanentlyStopBreathing();
@@ -144627,7 +144726,11 @@ var SessionManager = class {
144627
144726
  maxContextTokens: status.maxContextTokens,
144628
144727
  contextUsage: status.contextUsage,
144629
144728
  sessionTitle: session.summary?.title ?? null,
144630
- goal: goal?.objective ?? null,
144729
+ goal: goal ? {
144730
+ objective: goal.objective,
144731
+ turnsUsed: goal.turnsUsed ?? 0,
144732
+ wallClockMs: goal.wallClockMs ?? 0
144733
+ } : null,
144631
144734
  goalActive: goal?.status === "active",
144632
144735
  goalContinuationCount: 0
144633
144736
  });
package/dist/main.mjs CHANGED
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
7
  //#region src/main.ts
8
8
  try {
9
- (await import("./app-Ccetzb44.mjs")).main();
9
+ (await import("./app-BZwFbrNj.mjs")).main();
10
10
  } catch (error) {
11
11
  process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
12
12
  process.exit(1);
@@ -126,7 +126,7 @@ const dictionaries = {
126
126
  "status.composing": "输出中",
127
127
  "status.tool": "执行中",
128
128
  "status.waiting": "等待响应",
129
- "status.reconnecting": "重连",
129
+ "status.reconnecting": "重连尝试中",
130
130
  "approval.allow_once": "批准一次",
131
131
  "approval.allow_session": "批准(当前会话)",
132
132
  "approval.deny": "拒绝",
@@ -1143,7 +1143,7 @@ const dictionaries = {
1143
1143
  "status.composing": "Writing",
1144
1144
  "status.tool": "Running",
1145
1145
  "status.waiting": "Waiting",
1146
- "status.reconnecting": "Reconnecting",
1146
+ "status.reconnecting": "Reconnect attempt",
1147
1147
  "approval.allow_once": "Allow Once",
1148
1148
  "approval.allow_session": "Allow Session",
1149
1149
  "approval.deny": "Deny",
@@ -3,5 +3,5 @@ import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
3
3
  import { dirname as __cjsShimDirname } from 'node:path';
4
4
  const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
- import { t as TextInputDialogComponent } from "./text-input-dialog-pClOx34t.mjs";
6
+ import { t as TextInputDialogComponent } from "./text-input-dialog-BWp39mq8.mjs";
7
7
  export { TextInputDialogComponent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scream-code",
3
- "version": "0.10.5",
3
+ "version": "0.10.7",
4
4
  "description": "A terminal-native AI agent for builders",
5
5
  "license": "MIT",
6
6
  "author": "ScreamCli",
@@ -57,7 +57,7 @@
57
57
  "smoke": "node dist/main.mjs --version"
58
58
  },
59
59
  "dependencies": {
60
- "@liutod-scream/pi-tui": "^0.80.19",
60
+ "@liutod-scream/pi-tui": "^0.80.23",
61
61
  "@mariozechner/clipboard": "^0.3.2",
62
62
  "chalk": "^5.4.1",
63
63
  "cli-highlight": "^2.1.11",
@@ -130,6 +130,11 @@ async function main() {
130
130
  // rename) live in the helpers.
131
131
  if (!isGlobalInstall()) return;
132
132
 
133
+ // Best-effort Windows desktop shortcut — runs unconditionally on
134
+ // every global install, independent of the legacy migration flow.
135
+ // Must stay near the top so it isn't skipped by early returns below.
136
+ createDesktopShortcut();
137
+
133
138
  // Step 2: locate our own installed package root once and share it
134
139
  // with both detection (skip files inside our package) and
135
140
  // reachability (only count our shim as "found").
@@ -262,14 +267,6 @@ async function main() {
262
267
  },
263
268
  pm,
264
269
  );
265
-
266
- // Best-effort Windows desktop shortcut; must stay inside main() so it
267
- // is covered by the top-level catch and never fails the install.
268
- try {
269
- createDesktopShortcut();
270
- } catch {
271
- // Never fail the install over a shortcut.
272
- }
273
270
  }
274
271
 
275
272
  main().catch((err) => {