scream-code 0.13.8 → 0.13.9

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.
@@ -4,8 +4,8 @@ import { dirname as __cjsShimDirname } from 'node:path';
4
4
  const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
- import { $t as isTodoItemShape, A as renderDiffLinesClustered, An as CLI_COMMAND_NAME, At as ENABLE_TERMINAL_FOCUS_REPORTING, B as BackgroundAgentStatusComponent, Bn as MemoryMemoStore, Bt as TERMINAL_THEME_LIGHT, Cn as loadTuiConfig, Ct as createThemeStyles, D as toggleEmptySessionHint, Dn as getInputHistoryFile, Dt as parseOsc11BackgroundTheme, E as isTurnElapsedEnabled, En as getDataDir, Et as detectTerminalTheme, F as estimateTokens, Fn as fetchCatalog, Ft as OSC11_RESPONSE_PREFIX_NO_ESC, G as getBreathingFrame, Gn as isOrphanedToolCallError, H as AgentGroupComponent, Hn as log, Ht as isStreaming, I as getSharedSpeedTracker, In as saveCatalogCache, It as QUERY_TERMINAL_THEME, J as refineGoal, Jt as printableChar, K as resetBreathingClock, Kn as ErrorCodes, L as SkillActivationComponent, Ln as ScreamHarness, Lt as TERMINAL_FOCUS_IN, M as langFromPath, Mn as CLI_USER_AGENT_PRODUCT, Mt as OSC11_QUERY, N as CachedContainer, Nn as PRODUCT_NAME, Nt as OSC11_RESPONSE, O as ToolCallComponent, On as getLogDir, Ot as DISABLE_TERMINAL_FOCUS_REPORTING, P as ThinkingComponent, Pn as DEFAULT_CATALOG_URL, Pt as OSC11_RESPONSE_PREFIX, Qt as formatErrorMessage, R as ReadGroupComponent, Rt as TERMINAL_FOCUS_OUT, S as getDaemonInstructions, Sn as TuiLikePreferencesSchema, St as createMarkdownTheme, T as isEmptySessionHintDismissed, Tn as detectShellEnvironment, Tt as getColorPalette, U as WelcomeComponent, Un as resolveGlobalLogPath, Ut as FooterComponent, V as AssistantMessageComponent, Vn as flushDiagnosticLogs, Vt as isBusy, W as BREATHE_CYCLE_MS, Wn as isScreamError, Xt as appendStreamingArgsPreview, Yt as STATUS_BULLET, Zt as argsRecord, _ as refreshUpdateCache, _n as isExperimentalFlagEnabled, _t as clearInfoPanelState, an as EMPTY_SESSION_HINT_URL, b as readJsonlFile, bn as PULSE_WAVE_FRAMES, bt as resolveThemeSync, c as hasDispose, cn as SESSION_TIPS, ct as handlePlanCommand, d as formatMemoryMemoForInjection, dn as getCtrlDHint, en as parseStreamingArgs, et as toTerminalHyperlink, fn as getLlmNotSetMessage, g as selectUpdateTarget, gn as sortSlashCommands, gt as supportsBalance, hn as BUILTIN_SLASH_COMMANDS, ht as refreshProviderBalance, i as buildRoleAdditionalText, in as CHARS_PER_TOKEN, j as highlightLines, jn as CLI_UI_MODE, jt as ENABLE_TERMINAL_THEME_REPORTING, k as renderDiffLines, kn as detectInstallSource, kt as DISABLE_TERMINAL_THEME_REPORTING, l as isPlanExpandable, ln as TIP_ROTATION_INTERVAL_MS, mn as buildSkillSlashCommands, n as clearEvalPanelState, nn as stringValue, nt as getModelCycleLevel, on as EXIT_CONFIRM_WINDOW_MS, ot as handleFusionPlanCommand, pn as getNoActiveSessionMessage, q as clearGoalState, qn as SCREAM_ERROR_INFO, r as openUrl, rn as truncateErrorMessage, s as disposeChildren, sn as MAIN_AGENT_ID, t as dispatchInput, tn as serializeToolResultOutput, tt as changeThinkingLevel, u as MoonLoader, un as getCtrlCHint, v as readUpdateCache, vn as setExperimentalFlags, w as UserMessageComponent, wn as saveTuiConfig, wt as contrastTextHex, xn as TuiConfigParseError, xt as createEditorTheme, y as appendJsonlLine, yn as PIXEL_PULSE_FRAMES, z as parseReadGroupOutput, zn as resolveScreamHome, zt as TERMINAL_THEME_DARK } from "./dispatch-DevL-OSj.mjs";
8
- import { a as setLocale, o as t } from "./text-input-dialog-B9Klg3re.mjs";
7
+ import { $t as isTodoItemShape, A as renderDiffLinesClustered, An as CLI_COMMAND_NAME, At as ENABLE_TERMINAL_FOCUS_REPORTING, B as BackgroundAgentStatusComponent, Bn as MemoryMemoStore, Bt as TERMINAL_THEME_LIGHT, Cn as loadTuiConfig, Ct as createThemeStyles, D as toggleEmptySessionHint, Dn as getInputHistoryFile, Dt as parseOsc11BackgroundTheme, E as isTurnElapsedEnabled, En as getDataDir, Et as detectTerminalTheme, F as estimateTokens, Fn as fetchCatalog, Ft as OSC11_RESPONSE_PREFIX_NO_ESC, G as getBreathingFrame, Gn as isOrphanedToolCallError, H as AgentGroupComponent, Hn as log, Ht as isStreaming, I as getSharedSpeedTracker, In as saveCatalogCache, It as QUERY_TERMINAL_THEME, J as refineGoal, Jt as printableChar, K as resetBreathingClock, Kn as ErrorCodes, L as SkillActivationComponent, Ln as ScreamHarness, Lt as TERMINAL_FOCUS_IN, M as langFromPath, Mn as CLI_USER_AGENT_PRODUCT, Mt as OSC11_QUERY, N as CachedContainer, Nn as PRODUCT_NAME, Nt as OSC11_RESPONSE, O as ToolCallComponent, On as getLogDir, Ot as DISABLE_TERMINAL_FOCUS_REPORTING, P as ThinkingComponent, Pn as DEFAULT_CATALOG_URL, Pt as OSC11_RESPONSE_PREFIX, Qt as formatErrorMessage, R as ReadGroupComponent, Rt as TERMINAL_FOCUS_OUT, S as getDaemonInstructions, Sn as TuiLikePreferencesSchema, St as createMarkdownTheme, T as isEmptySessionHintDismissed, Tn as detectShellEnvironment, Tt as getColorPalette, U as WelcomeComponent, Un as resolveGlobalLogPath, Ut as FooterComponent, V as AssistantMessageComponent, Vn as flushDiagnosticLogs, Vt as isBusy, W as BREATHE_CYCLE_MS, Wn as isScreamError, Xt as appendStreamingArgsPreview, Yt as STATUS_BULLET, Zt as argsRecord, _ as refreshUpdateCache, _n as isExperimentalFlagEnabled, _t as clearInfoPanelState, an as EMPTY_SESSION_HINT_URL, b as readJsonlFile, bn as PULSE_WAVE_FRAMES, bt as resolveThemeSync, c as hasDispose, cn as SESSION_TIPS, ct as handlePlanCommand, d as formatMemoryMemoForInjection, dn as getCtrlDHint, en as parseStreamingArgs, et as toTerminalHyperlink, fn as getLlmNotSetMessage, g as selectUpdateTarget, gn as sortSlashCommands, gt as supportsBalance, hn as BUILTIN_SLASH_COMMANDS, ht as refreshProviderBalance, i as buildRoleAdditionalText, in as CHARS_PER_TOKEN, j as highlightLines, jn as CLI_UI_MODE, jt as ENABLE_TERMINAL_THEME_REPORTING, k as renderDiffLines, kn as detectInstallSource, kt as DISABLE_TERMINAL_THEME_REPORTING, l as isPlanExpandable, ln as TIP_ROTATION_INTERVAL_MS, mn as buildSkillSlashCommands, n as clearEvalPanelState, nn as stringValue, nt as getModelCycleLevel, on as EXIT_CONFIRM_WINDOW_MS, ot as handleFusionPlanCommand, pn as getNoActiveSessionMessage, q as clearGoalState, qn as SCREAM_ERROR_INFO, r as openUrl, rn as truncateErrorMessage, s as disposeChildren, sn as MAIN_AGENT_ID, t as dispatchInput, tn as serializeToolResultOutput, tt as changeThinkingLevel, u as MoonLoader, un as getCtrlCHint, v as readUpdateCache, vn as setExperimentalFlags, w as UserMessageComponent, wn as saveTuiConfig, wt as contrastTextHex, xn as TuiConfigParseError, xt as createEditorTheme, y as appendJsonlLine, yn as PIXEL_PULSE_FRAMES, z as parseReadGroupOutput, zn as resolveScreamHome, zt as TERMINAL_THEME_DARK } from "./dispatch-DIJJXO0L.mjs";
8
+ import { a as setLocale, o as t } from "./text-input-dialog-BzVVVncg.mjs";
9
9
  import { createRequire } from "node:module";
10
10
  import { randomUUID } from "node:crypto";
11
11
  import { access, mkdir, mkdtemp, readFile, readdir, realpath, rm, unlink, writeFile } from "node:fs/promises";
@@ -30,7 +30,7 @@ function optionalBuildString(value) {
30
30
  return typeof value === "string" && value.length > 0 ? value : void 0;
31
31
  }
32
32
  const SCREAM_BUILD_INFO = {
33
- version: optionalBuildString("0.13.8"),
33
+ version: optionalBuildString("0.13.9"),
34
34
  channel: optionalBuildString(""),
35
35
  commit: optionalBuildString(""),
36
36
  buildTarget: optionalBuildString("darwin-arm64")
@@ -12192,7 +12192,7 @@ var ScreamTUI = class {
12192
12192
  const card = new OnboardingCardComponent({
12193
12193
  colors: this.state.theme.colors,
12194
12194
  onConfigure: () => {
12195
- import("./dispatch-D5doFUQU.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
12195
+ import("./dispatch-SbA6zFMd.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
12196
12196
  this.restoreEditor();
12197
12197
  });
12198
12198
  },
@@ -13257,8 +13257,27 @@ async function runStreamJson(opts) {
13257
13257
  }
13258
13258
  const streamSubagentModels = streamTuiConfig.subagentModels;
13259
13259
  harness.setSubagentModelBindings(() => streamSubagentModels);
13260
+ const handleStdoutClosed = () => {
13261
+ log.debug("stream-json: stdout closed (EPIPE), exiting");
13262
+ process.exit(0);
13263
+ };
13264
+ process.stdout.on("error", (error) => {
13265
+ if (error.code === "EPIPE") {
13266
+ handleStdoutClosed();
13267
+ return;
13268
+ }
13269
+ log.error("stream-json: stdout error", { error: String(error) });
13270
+ });
13260
13271
  const writer = new ClaudeStreamJsonWriter((line) => {
13261
- process.stdout.write(`${line}\n`);
13272
+ try {
13273
+ process.stdout.write(`${line}\n`);
13274
+ } catch (error) {
13275
+ if (error.code === "EPIPE") {
13276
+ handleStdoutClosed();
13277
+ return;
13278
+ }
13279
+ throw error;
13280
+ }
13262
13281
  });
13263
13282
  let session;
13264
13283
  let currentSessionId;
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./chunk-D90kvbyJ.mjs";
7
7
  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";
8
8
  import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
9
- import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-B9Klg3re.mjs";
9
+ import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-BzVVVncg.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
12
12
  import * as fs$1 from "node:fs/promises";
@@ -129417,7 +129417,7 @@ async function guidedGoalSetup(host) {
129417
129417
  host.showNotice(t("goal.storm_breaker"), t("goal.conflict_loop"));
129418
129418
  return;
129419
129419
  }
129420
- const { TextInputDialogComponent } = await import("./text-input-dialog-Bnu3s0gP.mjs");
129420
+ const { TextInputDialogComponent } = await import("./text-input-dialog-DVWsE7Gh.mjs");
129421
129421
  const initialDesc = await promptText(host, TextInputDialogComponent, {
129422
129422
  title: t("goal.setup_title_initial"),
129423
129423
  subtitle: t("goal.setup_desc_hint"),
@@ -129438,7 +129438,7 @@ async function guidedGoalSetup(host) {
129438
129438
  await showGoalConfigWizard(host, session, confirmed.trim() || objective, false);
129439
129439
  }
129440
129440
  async function showGoalConfigWizard(host, session, objective, replace) {
129441
- const { TextInputDialogComponent } = await import("./text-input-dialog-Bnu3s0gP.mjs");
129441
+ const { TextInputDialogComponent } = await import("./text-input-dialog-DVWsE7Gh.mjs");
129442
129442
  const turnInput = await promptNumber(host, TextInputDialogComponent, {
129443
129443
  title: t("goal.wizard_title", { objective }),
129444
129444
  subtitle: t("goal.budget_turns_hint"),
@@ -134037,7 +134037,7 @@ async function findCcConnectResidualPaths(excludePath) {
134037
134037
  existing.push(p);
134038
134038
  } catch {}
134039
134039
  }
134040
- return existing.sort();
134040
+ return existing.toSorted();
134041
134041
  }
134042
134042
  async function handleCcCommand(host) {
134043
134043
  const daemon = resolveDaemonMode();
@@ -134077,7 +134077,7 @@ function runLifecycleAction(host, daemon, action) {
134077
134077
  host.refreshCcStatus();
134078
134078
  } else host.showError(t("cc.start_failed", {
134079
134079
  label,
134080
- output: output || "未知错误"
134080
+ output: output || t("cc.unknown_error")
134081
134081
  }));
134082
134082
  })();
134083
134083
  }
@@ -134087,7 +134087,7 @@ function buildUninstallSummary(daemon, install, residualPaths = []) {
134087
134087
  t("cc.will_clean"),
134088
134088
  t("cc.clean_daemon", { label: daemon.method }),
134089
134089
  t("cc.clean_config", { detail: t("cc.clean_config.detail") }),
134090
- "· 执行 npm uninstall -g cc-connect"
134090
+ t("cc.uninstall_step_npm")
134091
134091
  ];
134092
134092
  if (install.version) lines.push(t("cc.current_version", { version: install.version }));
134093
134093
  if (install.entry) lines.push(t("cc.install_path", { path: install.entry }));
@@ -135034,9 +135034,92 @@ function getPlatforms() {
135034
135034
  type: "wecom",
135035
135035
  setupCmd: "wecom setup --project default",
135036
135036
  note: t("ccconnect.note_wecom")
135037
+ },
135038
+ {
135039
+ name: "QQ 官方 bot",
135040
+ type: "qqbot",
135041
+ setupCmd: "qqbot setup --project default"
135042
+ },
135043
+ {
135044
+ name: "LINE",
135045
+ type: "line",
135046
+ setupCmd: "line setup --project default"
135047
+ },
135048
+ {
135049
+ name: "微博",
135050
+ type: "weibo",
135051
+ setupCmd: "weibo setup --project default"
135052
+ },
135053
+ {
135054
+ name: "WPS 协作",
135055
+ type: "wps-xiezuo",
135056
+ setupCmd: "wps-xiezuo setup --project default"
135057
+ },
135058
+ {
135059
+ name: "Matrix",
135060
+ type: "matrix",
135061
+ setupCmd: "matrix setup --project default",
135062
+ note: t("ccconnect.note_matrix")
135063
+ },
135064
+ {
135065
+ name: "Cisco Webex",
135066
+ type: "webex",
135067
+ setupCmd: "webex setup --project default",
135068
+ note: t("ccconnect.note_webex")
135069
+ },
135070
+ {
135071
+ name: "MAX",
135072
+ type: "max",
135073
+ setupCmd: "max setup --project default",
135074
+ note: t("ccconnect.note_max")
135075
+ },
135076
+ {
135077
+ name: "Google Chat",
135078
+ type: "googlechat",
135079
+ setupCmd: "googlechat setup --project default",
135080
+ note: t("ccconnect.note_googlechat")
135081
+ },
135082
+ {
135083
+ name: "Cloud Web",
135084
+ type: "cloud_web",
135085
+ setupCmd: "cloud_web setup --project default",
135086
+ note: t("ccconnect.note_cloud_web")
135087
+ },
135088
+ {
135089
+ name: "腾讯元宝",
135090
+ type: "yuanbao",
135091
+ setupCmd: "yuanbao setup --project default",
135092
+ note: t("ccconnect.note_yuanbao")
135093
+ },
135094
+ {
135095
+ name: "Tuitui",
135096
+ type: "tuitui",
135097
+ setupCmd: "tuitui setup --project default",
135098
+ note: t("ccconnect.note_tuitui")
135099
+ },
135100
+ {
135101
+ name: "WPS 数字员工",
135102
+ type: "wps-agentspace",
135103
+ setupCmd: "wps-agentspace setup --project default",
135104
+ note: t("ccconnect.note_wps_agentspace")
135037
135105
  }
135038
135106
  ];
135039
135107
  }
135108
+ /**
135109
+ * Platform types introduced by cc-connect v1.4/v1.5. Older cc-connect
135110
+ * binaries do not recognise these, so the post-config notice tells the user
135111
+ * to update cc-connect first.
135112
+ */
135113
+ const NEW_PLATFORM_TYPES = new Set([
135114
+ "matrix",
135115
+ "webex",
135116
+ "max",
135117
+ "googlechat",
135118
+ "cloud_web",
135119
+ "yuanbao",
135120
+ "tuitui",
135121
+ "wps-agentspace"
135122
+ ]);
135040
135123
  const CONFIG_PATH = join(homedir(), ".cc-connect", "config.toml");
135041
135124
  function checkCcConnect() {
135042
135125
  try {
@@ -135051,43 +135134,80 @@ function checkCcConnect() {
135051
135134
  return { installed: false };
135052
135135
  }
135053
135136
  }
135137
+ /** Auto-detect the path to the scream binary, including the stream-json subcommand. */
135054
135138
  function detectScreamPath() {
135139
+ const execBase = process.execPath.toLowerCase();
135140
+ if (execBase.endsWith("/scream") || execBase.endsWith("\\scream") || execBase.endsWith("scream.exe")) return `${quoteShellPath(process.execPath)} stream-json`;
135141
+ if (execBase.includes("node") && process.argv[1]) {
135142
+ const arg1 = process.argv[1];
135143
+ if (arg1.includes("scream-code") || arg1.includes("scream")) return `node ${quoteShellPath(arg1)} stream-json`;
135144
+ }
135055
135145
  try {
135056
135146
  const first = execSync(process.platform === "win32" ? "where scream" : "which scream 2>/dev/null", {
135057
135147
  encoding: "utf-8",
135058
135148
  timeout: 3e3
135059
135149
  }).trim().split(/[\r\n]+/)[0]?.trim() ?? "";
135060
- if (first) return `${first} stream-json`;
135150
+ if (first) return `${quoteShellPath(first)} stream-json`;
135061
135151
  } catch {}
135062
135152
  return "scream stream-json";
135063
135153
  }
135064
- function readConfiguredType() {
135065
- if (!existsSync(CONFIG_PATH)) return void 0;
135066
- try {
135067
- const content = readFileSync(CONFIG_PATH, "utf-8");
135068
- let inPlatforms = false;
135069
- for (const line of content.split("\n")) {
135070
- const trimmed = line.trim();
135071
- if (trimmed === "[[projects.platforms]]") {
135072
- inPlatforms = true;
135073
- continue;
135074
- }
135075
- if (trimmed.startsWith("[[") && trimmed !== "[[projects.platforms]]") {
135076
- inPlatforms = false;
135077
- continue;
135078
- }
135079
- if (inPlatforms) {
135080
- const m = line.match(/^type\s*=\s*"(\S+)"/);
135081
- if (m) return m[1];
135082
- }
135154
+ /**
135155
+ * Double-quote a path for shell parsing. cc-connect runs `cmd` through a
135156
+ * shell, so an unquoted path containing spaces would be split apart.
135157
+ */
135158
+ function quoteShellPath(path) {
135159
+ return `"${path.replaceAll(/"/g, "\\\"")}"`;
135160
+ }
135161
+ /** Parse every configured platform type from config.toml content. */
135162
+ function parseConfiguredTypes(content) {
135163
+ const types = [];
135164
+ let inPlatforms = false;
135165
+ for (const line of content.split("\n")) {
135166
+ const trimmed = line.trim();
135167
+ if (trimmed.startsWith("[[projects.platforms]]")) {
135168
+ inPlatforms = true;
135169
+ continue;
135083
135170
  }
135084
- return;
135171
+ if (trimmed.startsWith("[")) {
135172
+ inPlatforms = false;
135173
+ continue;
135174
+ }
135175
+ if (inPlatforms) {
135176
+ const m = trimmed.match(/^type\s*=\s*["']([^"']+)["']/);
135177
+ if (m?.[1]) types.push(m[1]);
135178
+ }
135179
+ }
135180
+ return types;
135181
+ }
135182
+ function readConfiguredTypes() {
135183
+ if (!existsSync(CONFIG_PATH)) return [];
135184
+ try {
135185
+ return parseConfiguredTypes(readFileSync(CONFIG_PATH, "utf-8"));
135085
135186
  } catch {
135086
- return;
135187
+ return [];
135087
135188
  }
135088
135189
  }
135089
- function escapeSingleQuotes(str) {
135090
- return str.replaceAll("'", "\\'");
135190
+ /** True when config content already has an active (non-comment) platform of this type. */
135191
+ function hasPlatformConfigured(content, type) {
135192
+ const escaped = type.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
135193
+ return new RegExp(`^\\s*type\\s*=\\s*["']${escaped}["']`, "m").test(content);
135194
+ }
135195
+ /** Minimal semver-ish check: "1.5.0" >= "1.5.0". */
135196
+ function isVersionAtLeast(version, min) {
135197
+ if (!version) return false;
135198
+ const parse = (v) => v.split(".").map((n) => Number.parseInt(n, 10) || 0);
135199
+ const [a = 0, b = 0, c = 0] = parse(version);
135200
+ const [x = 0, y = 0, z = 0] = parse(min);
135201
+ return a > x || a === x && (b > y || b === y && c >= z);
135202
+ }
135203
+ /**
135204
+ * Quote a value for TOML. Literal strings ('...') cannot contain a single
135205
+ * quote at all (no escape mechanism), so values with one fall back to a
135206
+ * basic string ("...") where backslash and double-quote are escaped.
135207
+ */
135208
+ function tomlString(value) {
135209
+ if (!value.includes("'")) return `'${value}'`;
135210
+ return `"${value.replaceAll(/\\/g, "\\\\").replaceAll(/"/g, "\\\"")}"`;
135091
135211
  }
135092
135212
  function generateConfig(platform) {
135093
135213
  const dir = dirname$1(CONFIG_PATH);
@@ -135095,11 +135215,15 @@ function generateConfig(platform) {
135095
135215
  const platformBlock = `\n[[projects.platforms]]\ntype = "${platform.type}"\n`;
135096
135216
  if (existsSync(CONFIG_PATH)) {
135097
135217
  const existing = readFileSync(CONFIG_PATH, "utf-8");
135098
- if (existing.includes(`type = "${platform.type}"`)) return;
135218
+ if (hasPlatformConfigured(existing, platform.type)) return;
135099
135219
  writeFileSync(CONFIG_PATH, existing + platformBlock, "utf-8");
135100
135220
  return;
135101
135221
  }
135102
- writeFileSync(CONFIG_PATH, [
135222
+ writeFileSync(CONFIG_PATH, buildConfigContent(platform, detectScreamPath(), process.cwd()), "utf-8");
135223
+ }
135224
+ /** Build the full config.toml content for a fresh setup. */
135225
+ function buildConfigContent(platform, screamCmd, cwd) {
135226
+ return [
135103
135227
  t("ccconnect.config_comment_attachment"),
135104
135228
  "attachment_send = \"on\"",
135105
135229
  "",
@@ -135110,21 +135234,22 @@ function generateConfig(platform) {
135110
135234
  "type = \"claudecode\"",
135111
135235
  "",
135112
135236
  "[projects.agent.options]",
135113
- `cmd = '${escapeSingleQuotes(detectScreamPath())}'`,
135114
- `work_dir = '${escapeSingleQuotes(process.cwd())}'`,
135115
- "mode = \"default\"",
135237
+ `cmd = ${tomlString(screamCmd)}`,
135238
+ `work_dir = ${tomlString(cwd)}`,
135239
+ "# Permission mode: default (confirm each tool) | acceptEdits | plan | auto | bypassPermissions (yolo) | dontAsk",
135240
+ "mode = \"auto\"",
135116
135241
  "",
135117
135242
  "[[projects.platforms]]",
135118
135243
  `type = "${platform.type}"`,
135119
135244
  ""
135120
- ].join("\n"), "utf-8");
135245
+ ].join("\n");
135121
135246
  }
135122
135247
  const SEP = "──".repeat(20);
135123
135248
  /**
135124
135249
  * Build the full notice text shown after platform selection.
135125
135250
  * Common management commands come first; detailed setup steps follow.
135126
135251
  */
135127
- function buildNoticeText(platform, isReconfigure) {
135252
+ function buildNoticeText(platform, isReconfigure, installedVersion) {
135128
135253
  const daemon = getDaemonInstructions(dirname$1(CONFIG_PATH));
135129
135254
  const parts = [];
135130
135255
  if (isReconfigure) {
@@ -135136,6 +135261,10 @@ function buildNoticeText(platform, isReconfigure) {
135136
135261
  parts.push("");
135137
135262
  parts.push(t("ccconnect.config_written", { path: CONFIG_PATH }));
135138
135263
  }
135264
+ if (NEW_PLATFORM_TYPES.has(platform.type) && !isVersionAtLeast(installedVersion, "1.5.0")) {
135265
+ parts.push("");
135266
+ parts.push(t("ccconnect.new_platform_version_hint"));
135267
+ }
135139
135268
  parts.push("");
135140
135269
  parts.push(t("ccconnect.quick_ref"));
135141
135270
  parts.push("");
@@ -135189,13 +135318,14 @@ function buildNoticeText(platform, isReconfigure) {
135189
135318
  return parts.join("\n");
135190
135319
  }
135191
135320
  async function handleChannelCommand(host, _args) {
135192
- if (!checkCcConnect().installed) {
135321
+ const cc = checkCcConnect();
135322
+ if (!cc.installed) {
135193
135323
  host.showNotice(t("ccconnect.not_installed"), t("ccconnect.install_guide"));
135194
135324
  return;
135195
135325
  }
135196
- const configuredType = readConfiguredType();
135326
+ const configuredTypes = readConfiguredTypes();
135197
135327
  const options = getPlatforms().map((p) => {
135198
- const isConfigured = configuredType === p.type;
135328
+ const isConfigured = configuredTypes.includes(p.type);
135199
135329
  return {
135200
135330
  value: p.type,
135201
135331
  label: isConfigured ? t("ccconnect.already_configured", { name: p.name }) : p.name,
@@ -135206,7 +135336,7 @@ async function handleChannelCommand(host, _args) {
135206
135336
  title: t("ccconnect.picker_title"),
135207
135337
  hint: t("ccconnect.picker_hint"),
135208
135338
  options,
135209
- currentValue: configuredType,
135339
+ currentValue: configuredTypes[0],
135210
135340
  colors: host.state.theme.colors,
135211
135341
  onSelect: (value) => {
135212
135342
  host.restoreEditor();
@@ -135215,12 +135345,12 @@ async function handleChannelCommand(host, _args) {
135215
135345
  host.showError(t("error.internal"));
135216
135346
  return;
135217
135347
  }
135218
- if (configuredType === value) {
135219
- host.showNotice(t("ccconnect.reconfigured", { name: platform.name }), buildNoticeText(platform, true));
135348
+ if (configuredTypes.includes(value)) {
135349
+ host.showNotice(t("ccconnect.reconfigured", { name: platform.name }), buildNoticeText(platform, true, cc.version));
135220
135350
  return;
135221
135351
  }
135222
135352
  generateConfig(platform);
135223
- host.showNotice(t("ccconnect.config_done", { name: platform.name }), buildNoticeText(platform, false));
135353
+ host.showNotice(t("ccconnect.config_done", { name: platform.name }), buildNoticeText(platform, false, cc.version));
135224
135354
  },
135225
135355
  onCancel: () => {
135226
135356
  host.restoreEditor();
@@ -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 { Kt as handleConnectCommand } from "./dispatch-DevL-OSj.mjs";
6
+ import { Kt as handleConnectCommand } from "./dispatch-DIJJXO0L.mjs";
7
7
  export { handleConnectCommand };
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-CJGX8qct.mjs")).main();
9
+ (await import("./app-vcurmmh6.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);
@@ -410,6 +410,8 @@ const dictionaries = {
410
410
  "cc.confirm_uninstall": "确认彻底卸载 cc-connect?",
411
411
  "cc.uninstall_irreversible": "此操作不可撤销,所有 cc-connect 数据将被清除",
412
412
  "cc.confirm_uninstall_btn": "确认卸载",
413
+ "cc.uninstall_step_npm": "· 执行 npm uninstall -g cc-connect",
414
+ "cc.unknown_error": "未知错误",
413
415
  "auth.fetching_models": "正在拉取最新模型目录...",
414
416
  "auth.catalog_fetch_failed": "拉取远程模型目录失败: {error}。请检查网络(目录站点在你的网络环境下可能无法访问)后重试,或使用 /config diy 自行配置服务商。",
415
417
  "auth.no_providers": "没有已配置的模型商。",
@@ -959,6 +961,15 @@ const dictionaries = {
959
961
  "ccconnect.note_botfather": "需先在 @BotFather 创建 bot",
960
962
  "ccconnect.note_napcat": "需要 NapCat/OneBot",
961
963
  "ccconnect.note_wecom": "需要公网 IP",
964
+ "ccconnect.note_matrix": "E2EE 加密,需 homeserver + access token",
965
+ "ccconnect.note_webex": "需在 developer.webex.com 创建 Bot",
966
+ "ccconnect.note_max": "需通过 @MasterBot 创建 bot",
967
+ "ccconnect.note_googlechat": "需 GCP 服务账号 JSON",
968
+ "ccconnect.note_cloud_web": "自建 IM 网关",
969
+ "ccconnect.note_yuanbao": "腾讯元宝,需 app-key:app-secret",
970
+ "ccconnect.note_tuitui": "需 app_id + app_secret",
971
+ "ccconnect.note_wps_agentspace": "需 app_id + wps_sid",
972
+ "ccconnect.new_platform_version_hint": "⚠ 该平台需要 cc-connect v1.5.0 及以上,请先更新 cc-connect",
962
973
  "ccconnect.config_comment_attachment": "# 全局:允许/禁止图片和文件回传到聊天(on = 开启,off = 关闭)",
963
974
  "ccconnect.reconfigured": "{name} 已配置(配置不会丢失)",
964
975
  "ccconnect.config_path": "配置文件:{path}",
@@ -1490,6 +1501,8 @@ const dictionaries = {
1490
1501
  "cc.confirm_uninstall": "Completely uninstall cc-connect?",
1491
1502
  "cc.uninstall_irreversible": "This cannot be undone. All cc-connect data will be removed.",
1492
1503
  "cc.confirm_uninstall_btn": "Confirm Uninstall",
1504
+ "cc.uninstall_step_npm": "· Run npm uninstall -g cc-connect",
1505
+ "cc.unknown_error": "Unknown error",
1493
1506
  "auth.fetching_models": "Fetching latest model catalog...",
1494
1507
  "auth.catalog_fetch_failed": "Failed to fetch the remote model catalog: {error}. Check your network (the catalog host may be unreachable in your region) and retry, or use /config diy to set up a provider manually.",
1495
1508
  "auth.no_providers": "No model providers configured.",
@@ -2039,6 +2052,15 @@ const dictionaries = {
2039
2052
  "ccconnect.note_botfather": "Create a bot at @BotFather first",
2040
2053
  "ccconnect.note_napcat": "Requires NapCat/OneBot",
2041
2054
  "ccconnect.note_wecom": "Requires public IP",
2055
+ "ccconnect.note_matrix": "E2EE encrypted, needs homeserver + access token",
2056
+ "ccconnect.note_webex": "Create a bot at developer.webex.com",
2057
+ "ccconnect.note_max": "Create a bot via @MasterBot",
2058
+ "ccconnect.note_googlechat": "Requires GCP service account JSON",
2059
+ "ccconnect.note_cloud_web": "Self-hosted IM gateway",
2060
+ "ccconnect.note_yuanbao": "Tencent Yuanbao, needs app-key:app-secret",
2061
+ "ccconnect.note_tuitui": "Needs app_id + app_secret",
2062
+ "ccconnect.note_wps_agentspace": "Needs app_id + wps_sid",
2063
+ "ccconnect.new_platform_version_hint": "⚠ This platform requires cc-connect v1.5.0 or newer. Please update cc-connect first.",
2042
2064
  "ccconnect.config_comment_attachment": "# Global: allow/disallow image & file backhaul to chat (on = enabled, off = disabled)",
2043
2065
  "ccconnect.reconfigured": "{name} already configured (config preserved)",
2044
2066
  "ccconnect.config_path": "Config file: {path}",
@@ -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-B9Klg3re.mjs";
6
+ import { t as TextInputDialogComponent } from "./text-input-dialog-BzVVVncg.mjs";
7
7
  export { TextInputDialogComponent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scream-code",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "description": "A terminal-native AI agent for builders",
5
5
  "license": "MIT",
6
6
  "author": "ScreamCli",