@iruidong/code 0.1.7 → 0.1.10

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.
package/QUICKSTART.md CHANGED
@@ -10,7 +10,7 @@ ruidong --version
10
10
  Expected output:
11
11
 
12
12
  ```bash
13
- Ruidong Code v0.1.7
13
+ Ruidong Code v0.1.10
14
14
  ```
15
15
 
16
16
  ## 2. Configure your shell
@@ -94,6 +94,12 @@ If an old `~/.ruidong-code/config.json` keeps interfering, remove it:
94
94
  rm -f ~/.ruidong-code/config.json
95
95
  ```
96
96
 
97
+ If you tested an old temporary setup flow before, also clear any config-dir override:
98
+
99
+ ```bash
100
+ unset RUIDONG_CONFIG_DIR CLAUDE_CONFIG_DIR
101
+ ```
102
+
97
103
  Need more debug output:
98
104
 
99
105
  ```bash
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // ruidong v0.1.7 (built from source)
2
+ // ruidong v0.1.10 (built from source)
3
3
  // Copyright (c) Anthropic PBC. All rights reserved.
4
4
  import { createRequire as __createRequire } from "module";const require=__createRequire(import.meta.url);
5
5
  var __defProp = Object.defineProperty;
@@ -81,8 +81,8 @@ var __callDispose = (stack, error, hasError) => {
81
81
  var PUBLIC_CLI_VERSION, BUILD_TIME, API_COMPAT_VERSION, API_COMPAT_VERSION_BASE;
82
82
  var init_version = __esm({
83
83
  "build-src/src/constants/version.ts"() {
84
- PUBLIC_CLI_VERSION = "0.1.7";
85
- BUILD_TIME = "2026-04-03T12:30:00.000Z";
84
+ PUBLIC_CLI_VERSION = "0.1.10";
85
+ BUILD_TIME = "2026-04-04T03:45:00.000Z";
86
86
  API_COMPAT_VERSION = "2.1.88";
87
87
  API_COMPAT_VERSION_BASE = API_COMPAT_VERSION.match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/)?.[0];
88
88
  }
@@ -13003,6 +13003,30 @@ import {
13003
13003
  } from "fs";
13004
13004
  import { join as join21 } from "path";
13005
13005
  import { z as z9 } from "zod/v4";
13006
+ function isPlaceholderUrl(rawUrl) {
13007
+ if (!rawUrl) {
13008
+ return false;
13009
+ }
13010
+ try {
13011
+ const { hostname: hostname3 } = new URL(rawUrl);
13012
+ return hostname3 === "example.com" || hostname3 === "example.org" || hostname3 === "example.net" || hostname3.endsWith(".example.com") || hostname3.endsWith(".example.org") || hostname3.endsWith(".example.net");
13013
+ } catch {
13014
+ return false;
13015
+ }
13016
+ }
13017
+ function sanitizeConfiguredUrl(rawUrl, label) {
13018
+ if (!rawUrl) {
13019
+ return void 0;
13020
+ }
13021
+ if (!isPlaceholderUrl(rawUrl)) {
13022
+ return rawUrl;
13023
+ }
13024
+ logForDebugging(
13025
+ `[Ruidong config] Ignoring placeholder ${label}: ${rawUrl}`,
13026
+ { level: "warn" }
13027
+ );
13028
+ return void 0;
13029
+ }
13006
13030
  function getRuidongConfigHomeDir() {
13007
13031
  return (getConfiguredClaudeConfigHomeDir() ?? getDefaultRuidongConfigHomeDir()).normalize("NFC");
13008
13032
  }
@@ -13033,9 +13057,13 @@ function getRuidongRuntimeProviderConfig() {
13033
13057
  if (!provider) {
13034
13058
  return null;
13035
13059
  }
13060
+ const baseUrl = sanitizeConfiguredUrl(provider.baseUrl, "provider.baseUrl");
13061
+ if (provider.id === "anthropic-compatible" && !baseUrl) {
13062
+ return null;
13063
+ }
13036
13064
  return {
13037
13065
  id: provider.id,
13038
- baseUrl: provider.baseUrl,
13066
+ baseUrl,
13039
13067
  apiKey: resolveSecretValue(provider.apiKey),
13040
13068
  authToken: resolveSecretValue(provider.authToken),
13041
13069
  authMode: provider.authMode ?? "auto",
@@ -13062,7 +13090,7 @@ function getResolvedRuidongVoiceConfig() {
13062
13090
  ...voice2.stt && {
13063
13091
  stt: {
13064
13092
  provider: voice2.stt.provider,
13065
- baseUrl: voice2.stt.baseUrl,
13093
+ baseUrl: sanitizeConfiguredUrl(voice2.stt.baseUrl, "voice.stt.baseUrl"),
13066
13094
  apiKey: resolveSecretValue(voice2.stt.apiKey),
13067
13095
  model: voice2.stt.model,
13068
13096
  language: voice2.stt.language,
@@ -13168,7 +13196,10 @@ function applyOfficialMarketplaceConfig(official) {
13168
13196
  );
13169
13197
  break;
13170
13198
  case "git":
13171
- setEnvIfUnset("RUIDONG_OFFICIAL_MARKETPLACE_GIT_URL", source.url);
13199
+ setEnvIfUnset(
13200
+ "RUIDONG_OFFICIAL_MARKETPLACE_GIT_URL",
13201
+ sanitizeConfiguredUrl(source.url, "marketplace.official.source.url")
13202
+ );
13172
13203
  setEnvIfUnset("RUIDONG_OFFICIAL_MARKETPLACE_REF", source.ref);
13173
13204
  setEnvIfUnset("RUIDONG_OFFICIAL_MARKETPLACE_PATH", source.path);
13174
13205
  setEnvIfUnset(
@@ -13177,7 +13208,10 @@ function applyOfficialMarketplaceConfig(official) {
13177
13208
  );
13178
13209
  break;
13179
13210
  case "url":
13180
- setEnvIfUnset("RUIDONG_OFFICIAL_MARKETPLACE_URL", source.url);
13211
+ setEnvIfUnset(
13212
+ "RUIDONG_OFFICIAL_MARKETPLACE_URL",
13213
+ sanitizeConfiguredUrl(source.url, "marketplace.official.source.url")
13214
+ );
13181
13215
  break;
13182
13216
  }
13183
13217
  }
@@ -13189,8 +13223,12 @@ function applyRuidongRuntimeConfig() {
13189
13223
  const provider = config2.provider;
13190
13224
  if (provider) {
13191
13225
  applyProviderFlags(provider.id);
13192
- if (provider.baseUrl !== void 0) {
13193
- setEnvIfUnset("ANTHROPIC_BASE_URL", provider.baseUrl);
13226
+ const providerBaseUrl = sanitizeConfiguredUrl(
13227
+ provider.baseUrl,
13228
+ "provider.baseUrl"
13229
+ );
13230
+ if (providerBaseUrl !== void 0) {
13231
+ setEnvIfUnset("ANTHROPIC_BASE_URL", providerBaseUrl);
13194
13232
  }
13195
13233
  applyProviderCredentialEnv(provider);
13196
13234
  if (provider.authMode !== void 0) {
@@ -13203,13 +13241,17 @@ function applyRuidongRuntimeConfig() {
13203
13241
  applyOfficialMarketplaceConfig(config2.marketplace?.official);
13204
13242
  setEnvIfUnset(
13205
13243
  "RUIDONG_OFFICIAL_MCP_REGISTRY_URL",
13206
- config2.mcp?.officialRegistryUrl
13244
+ sanitizeConfiguredUrl(
13245
+ config2.mcp?.officialRegistryUrl,
13246
+ "mcp.officialRegistryUrl"
13247
+ )
13207
13248
  );
13208
13249
  }
13209
13250
  var RuidongProviderIdSchema, RuidongAuthModeSchema, RuidongVoiceSttProviderSchema, OfficialMarketplaceSourceSchema, RuidongConfigSchema, configCache;
13210
13251
  var init_ruidongConfig = __esm({
13211
13252
  "build-src/src/utils/ruidongConfig.ts"() {
13212
13253
  init_envUtils();
13254
+ init_debug();
13213
13255
  init_env();
13214
13256
  RuidongProviderIdSchema = z9.enum([
13215
13257
  "anthropic",
@@ -24925,6 +24967,100 @@ var init_fullscreen = __esm({
24925
24967
  }
24926
24968
  });
24927
24969
 
24970
+ // build-src/src/utils/inputTrace.ts
24971
+ function isInputTraceEnabled() {
24972
+ return isEnvTruthy(process.env.RUIDONG_DEBUG_INPUT) || isEnvTruthy(process.env.CLAUDE_CODE_DEBUG_INPUT);
24973
+ }
24974
+ function ensureInputTraceLogging() {
24975
+ if (!isInputTraceEnabled() || inputTraceInitialized) {
24976
+ return;
24977
+ }
24978
+ inputTraceInitialized = true;
24979
+ enableDebugLogging();
24980
+ logForDebugging(
24981
+ `${INPUT_TRACE_PREFIX} enabled pid=${process.pid} term=${process.env.TERM ?? "unset"} termProgram=${process.env.TERM_PROGRAM ?? "unset"} ssh=${process.env.SSH_CONNECTION ? "yes" : "no"} debugLog=${getDebugLogPath()}`
24982
+ );
24983
+ }
24984
+ function logInputTrace(message) {
24985
+ if (!isInputTraceEnabled()) {
24986
+ return;
24987
+ }
24988
+ ensureInputTraceLogging();
24989
+ logForDebugging(`${INPUT_TRACE_PREFIX} ${message}`);
24990
+ }
24991
+ function previewTraceValue(value) {
24992
+ if (value == null) {
24993
+ return String(value);
24994
+ }
24995
+ if (value.length <= MAX_PREVIEW_CHARS) {
24996
+ return JSON.stringify(value);
24997
+ }
24998
+ const preview = JSON.stringify(value.slice(0, MAX_PREVIEW_CHARS));
24999
+ return `${preview}...(+${value.length - MAX_PREVIEW_CHARS} chars)`;
25000
+ }
25001
+ function formatHexBytes(input) {
25002
+ const values = Array.from(input.slice(0, MAX_HEX_BYTES)).map(
25003
+ (byte) => byte.toString(16).padStart(2, "0")
25004
+ );
25005
+ if (input.length > MAX_HEX_BYTES) {
25006
+ values.push(`...(+${input.length - MAX_HEX_BYTES} bytes)`);
25007
+ }
25008
+ return values.join(" ");
25009
+ }
25010
+ function formatChunkForTrace(input) {
25011
+ if (input === null) {
25012
+ return "flush";
25013
+ }
25014
+ const text = typeof input === "string" ? input : input.toString("utf8");
25015
+ const bytes = typeof input === "string" ? Buffer.from(input, "utf8") : input;
25016
+ return `text=${previewTraceValue(text)} hex=${formatHexBytes(bytes)}`;
25017
+ }
25018
+ function summarizeParsedKey(item) {
25019
+ const flags = [
25020
+ item.ctrl ? "ctrl" : null,
25021
+ item.shift ? "shift" : null,
25022
+ item.meta ? "meta" : null,
25023
+ item.option ? "option" : null,
25024
+ item.super ? "super" : null,
25025
+ item.fn ? "fn" : null,
25026
+ item.isPasted ? "pasted" : null
25027
+ ].filter(Boolean).join("+");
25028
+ return `key(name=${item.name ?? ""}, seq=${previewTraceValue(item.sequence)}, raw=${previewTraceValue(item.raw)}, flags=${flags || "plain"})`;
25029
+ }
25030
+ function summarizeParsedMouse(item) {
25031
+ return `mouse(button=${item.button}, col=${item.x}, row=${item.y}, seq=${previewTraceValue(item.sequence)})`;
25032
+ }
25033
+ function summarizeParsedInputs(items) {
25034
+ if (items.length === 0) {
25035
+ return "none";
25036
+ }
25037
+ return items.map((item) => {
25038
+ switch (item.kind) {
25039
+ case "key":
25040
+ return summarizeParsedKey(item);
25041
+ case "mouse":
25042
+ return summarizeParsedMouse(item);
25043
+ case "response":
25044
+ return `response(type=${item.response.type}, seq=${previewTraceValue(item.sequence)})`;
25045
+ }
25046
+ }).join(" | ");
25047
+ }
25048
+ function summarizeInputKey(key) {
25049
+ const active = Object.entries(key).filter(([, value]) => value).map(([name]) => name);
25050
+ return active.length > 0 ? active.join("+") : "plain";
25051
+ }
25052
+ var INPUT_TRACE_PREFIX, MAX_PREVIEW_CHARS, MAX_HEX_BYTES, inputTraceInitialized;
25053
+ var init_inputTrace = __esm({
25054
+ "build-src/src/utils/inputTrace.ts"() {
25055
+ init_debug();
25056
+ init_envUtils();
25057
+ INPUT_TRACE_PREFIX = "[input-trace]";
25058
+ MAX_PREVIEW_CHARS = 120;
25059
+ MAX_HEX_BYTES = 64;
25060
+ inputTraceInitialized = false;
25061
+ }
25062
+ });
25063
+
24928
25064
  // build-src/src/ink/termio/ansi.ts
24929
25065
  function isEscFinal(byte) {
24930
25066
  return byte >= 48 && byte <= 126;
@@ -30695,6 +30831,7 @@ var init_App = __esm({
30695
30831
  init_earlyInput();
30696
30832
  init_envUtils();
30697
30833
  init_fullscreen();
30834
+ init_inputTrace();
30698
30835
  init_log();
30699
30836
  init_emitter();
30700
30837
  init_input_event();
@@ -30785,6 +30922,7 @@ var init_App = __esm({
30785
30922
  }), children: this.state.error ? /* @__PURE__ */ jsx7(ErrorOverview, { error: this.state.error }) : this.props.children }) }) }) }) }) });
30786
30923
  }
30787
30924
  componentDidMount() {
30925
+ logInputTrace(`mount stdinTTY=${this.props.stdin.isTTY} stdoutTTY=${this.props.stdout.isTTY} columns=${this.props.terminalColumns} rows=${this.props.terminalRows}`);
30788
30926
  if (this.props.stdout.isTTY && !isEnvTruthy(process.env.CLAUDE_CODE_ACCESSIBILITY)) {
30789
30927
  this.props.stdout.write(HIDE_CURSOR);
30790
30928
  }
@@ -30821,11 +30959,13 @@ var init_App = __esm({
30821
30959
  }
30822
30960
  stdin.setEncoding("utf8");
30823
30961
  if (isEnabled2) {
30962
+ logInputTrace(`setRawMode(enable) count=${this.rawModeEnabledCount} listeners=${stdin.listenerCount("readable")}`);
30824
30963
  if (this.rawModeEnabledCount === 0) {
30825
30964
  stopCapturingEarlyInput();
30826
30965
  stdin.ref();
30827
30966
  stdin.setRawMode(true);
30828
30967
  stdin.addListener("readable", this.handleReadable);
30968
+ logInputTrace(`rawMode enabled listeners=${stdin.listenerCount("readable")}`);
30829
30969
  this.props.stdout.write(EBP);
30830
30970
  this.props.stdout.write(EFE);
30831
30971
  if (supportsExtendedKeys()) {
@@ -30847,6 +30987,7 @@ var init_App = __esm({
30847
30987
  return;
30848
30988
  }
30849
30989
  if (--this.rawModeEnabledCount === 0) {
30990
+ logInputTrace(`setRawMode(disable) listeners=${stdin.listenerCount("readable")}`);
30850
30991
  this.props.stdout.write(DISABLE_MODIFY_OTHER_KEYS);
30851
30992
  this.props.stdout.write(DISABLE_KITTY_KEYBOARD);
30852
30993
  this.props.stdout.write(DFE);
@@ -30868,8 +31009,10 @@ var init_App = __esm({
30868
31009
  };
30869
31010
  // Process input through the parser and handle the results
30870
31011
  processInput = (input) => {
31012
+ logInputTrace(`processInput raw=${formatChunkForTrace(input)} prevMode=${this.keyParseState.mode} prevIncomplete=${previewTraceValue(this.keyParseState.incomplete)}`);
30871
31013
  const [keys, newState] = parseMultipleKeypresses(this.keyParseState, input);
30872
31014
  this.keyParseState = newState;
31015
+ logInputTrace(`processInput parsed count=${keys.length} nextMode=${this.keyParseState.mode} incomplete=${previewTraceValue(this.keyParseState.incomplete)} items=${summarizeParsedInputs(keys)}`);
30873
31016
  if (keys.length > 0) {
30874
31017
  reconciler_default.discreteUpdates(processKeysInBatch, this, keys, void 0, void 0);
30875
31018
  }
@@ -30883,14 +31026,18 @@ var init_App = __esm({
30883
31026
  handleReadable = () => {
30884
31027
  const now = Date.now();
30885
31028
  if (now - this.lastStdinTime > STDIN_RESUME_GAP_MS) {
31029
+ logInputTrace(`stdin resume gap=${now - this.lastStdinTime}ms`);
30886
31030
  this.props.onStdinResume?.();
30887
31031
  }
30888
31032
  this.lastStdinTime = now;
30889
31033
  try {
31034
+ logInputTrace(`readable start buffered=${this.props.stdin.readableLength} listeners=${this.props.stdin.listenerCount("readable")}`);
30890
31035
  let chunk2;
30891
31036
  while ((chunk2 = this.props.stdin.read()) !== null) {
31037
+ logInputTrace(`readable chunk ${formatChunkForTrace(chunk2)}`);
30892
31038
  this.processInput(chunk2);
30893
31039
  }
31040
+ logInputTrace("readable drained");
30894
31041
  } catch (error) {
30895
31042
  logError(error);
30896
31043
  const {
@@ -30902,6 +31049,7 @@ var init_App = __esm({
30902
31049
  });
30903
31050
  stdin.addListener("readable", this.handleReadable);
30904
31051
  }
31052
+ logInputTrace(`readable error recovered listeners=${stdin.listenerCount("readable")}`);
30905
31053
  }
30906
31054
  };
30907
31055
  handleInput = (input) => {
@@ -75106,7 +75254,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
75106
75254
  {
75107
75255
  name: "ruidong-code",
75108
75256
  title: "ruidong",
75109
- version: "0.1.7",
75257
+ version: "0.1.10",
75110
75258
  description: "Ruidong Code agentic coding tool",
75111
75259
  websiteUrl: PRODUCT_URL
75112
75260
  },
@@ -75529,7 +75677,7 @@ var init_client3 = __esm({
75529
75677
  {
75530
75678
  name: "ruidong-code",
75531
75679
  title: "ruidong",
75532
- version: "0.1.7",
75680
+ version: "0.1.10",
75533
75681
  description: "Ruidong Code agentic coding tool",
75534
75682
  websiteUrl: PRODUCT_URL
75535
75683
  },
@@ -87228,7 +87376,7 @@ async function installGlobalPackage(specificVersion) {
87228
87376
  );
87229
87377
  logEvent("tengu_auto_updater_lock_contention", {
87230
87378
  pid: process.pid,
87231
- currentVersion: "0.1.7"
87379
+ currentVersion: "0.1.10"
87232
87380
  });
87233
87381
  return "in_progress";
87234
87382
  }
@@ -87237,7 +87385,7 @@ async function installGlobalPackage(specificVersion) {
87237
87385
  if (!env.isRunningWithBun() && env.isNpmFromWindowsPath()) {
87238
87386
  logError(new Error("Windows NPM detected in WSL environment"));
87239
87387
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
87240
- currentVersion: "0.1.7"
87388
+ currentVersion: "0.1.10"
87241
87389
  });
87242
87390
  console.error(`
87243
87391
  Error: Windows NPM detected in WSL
@@ -87581,7 +87729,7 @@ function detectProviderConfigWarnings() {
87581
87729
  if (usingThirdPartyEndpoint && !resolvedApiKey && !resolvedAuthToken) {
87582
87730
  warnings.push({
87583
87731
  issue: "Third-party endpoint is configured but no API credential is available",
87584
- fix: `Set ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN, or run: ${CLI_COMMAND2} init --force --endpoint <url> --key-env <ENV_NAME> --model <model>`
87732
+ fix: "Set ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN in your shell profile, then restart the terminal"
87585
87733
  });
87586
87734
  }
87587
87735
  if (requestedAuthMode === "auto" && resolvedApiKey && resolvedAuthToken) {
@@ -87904,7 +88052,7 @@ function detectLinuxGlobPatternWarnings() {
87904
88052
  }
87905
88053
  async function getDoctorDiagnostic() {
87906
88054
  const installationType = await getCurrentInstallationType();
87907
- const version2 = typeof MACRO !== "undefined" && "0.1.7" ? "0.1.7" : "unknown";
88055
+ const version2 = typeof MACRO !== "undefined" && "0.1.10" ? "0.1.10" : "unknown";
87908
88056
  const installationPath = await getInstallationPath();
87909
88057
  const invokedBinary = getInvokedBinary();
87910
88058
  const multipleInstallations = await detectMultipleInstallations();
@@ -88984,7 +89132,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
88984
89132
  version2 = maxVersion;
88985
89133
  }
88986
89134
  }
88987
- if (!forceReinstall && version2 === "0.1.7" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
89135
+ if (!forceReinstall && version2 === "0.1.10" && await versionIsAvailable(version2) && await isPossibleClaudeBinary(executablePath)) {
88988
89136
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
88989
89137
  logEvent("tengu_native_update_complete", {
88990
89138
  latency_ms: Date.now() - startTime,
@@ -170945,6 +171093,73 @@ import { writeFile as writeFile28 } from "fs/promises";
170945
171093
  import isEqual6 from "lodash-es/isEqual.js";
170946
171094
  import memoize55 from "lodash-es/memoize.js";
170947
171095
  import { basename as basename30, dirname as dirname37, isAbsolute as isAbsolute22, join as join94, resolve as resolve29, sep as sep20 } from "path";
171096
+ function isLegacyRuidongMarketplaceEntry(name, entry) {
171097
+ return name === LEGACY_RUIDONG_MARKETPLACE_NAME || entry.source.source === "github" && entry.source.repo === LEGACY_RUIDONG_MARKETPLACE_REPO;
171098
+ }
171099
+ function tryMigrateLegacyRuidongMarketplaceCache(entry) {
171100
+ const fs6 = getFsImplementation();
171101
+ const officialInstallLocation = join94(
171102
+ getMarketplacesCacheDir(),
171103
+ OFFICIAL_MARKETPLACE_NAME
171104
+ );
171105
+ const candidatePaths = [
171106
+ join94(entry.installLocation, ".claude-plugin", "marketplace.json"),
171107
+ entry.installLocation
171108
+ ];
171109
+ for (const sourcePath of candidatePaths) {
171110
+ if (!fs6.existsSync(sourcePath)) {
171111
+ continue;
171112
+ }
171113
+ try {
171114
+ fs6.mkdirSync(dirname37(officialInstallLocation));
171115
+ fs6.copyFileSync(sourcePath, officialInstallLocation);
171116
+ return officialInstallLocation;
171117
+ } catch (error) {
171118
+ logForDebugging(
171119
+ `Failed migrating legacy Ruidong marketplace cache from ${sourcePath}: ${errorMessage(error)}`,
171120
+ { level: "warn" }
171121
+ );
171122
+ }
171123
+ }
171124
+ return null;
171125
+ }
171126
+ async function normalizeKnownMarketplacesConfig(config2) {
171127
+ const legacyEntries = Object.entries(config2).filter(([
171128
+ name,
171129
+ entry
171130
+ ]) => isLegacyRuidongMarketplaceEntry(name, entry));
171131
+ if (legacyEntries.length === 0) {
171132
+ return config2;
171133
+ }
171134
+ const normalized = { ...config2 };
171135
+ let changed = false;
171136
+ if (!normalized[OFFICIAL_MARKETPLACE_NAME]) {
171137
+ const [, legacyEntry] = legacyEntries[0];
171138
+ const migratedInstallLocation = tryMigrateLegacyRuidongMarketplaceCache(legacyEntry) ?? join94(getMarketplacesCacheDir(), OFFICIAL_MARKETPLACE_NAME);
171139
+ normalized[OFFICIAL_MARKETPLACE_NAME] = {
171140
+ source: OFFICIAL_MARKETPLACE_SOURCE,
171141
+ installLocation: migratedInstallLocation,
171142
+ lastUpdated: legacyEntry.lastUpdated,
171143
+ autoUpdate: true
171144
+ };
171145
+ changed = true;
171146
+ logForDebugging(
171147
+ `Migrated legacy marketplace '${legacyEntries[0][0]}' to official source ${formatSourceForDisplay(OFFICIAL_MARKETPLACE_SOURCE)}`,
171148
+ { level: "info" }
171149
+ );
171150
+ }
171151
+ for (const [name] of legacyEntries) {
171152
+ if (name === OFFICIAL_MARKETPLACE_NAME) {
171153
+ continue;
171154
+ }
171155
+ delete normalized[name];
171156
+ changed = true;
171157
+ }
171158
+ if (changed) {
171159
+ await saveKnownMarketplacesConfig(normalized);
171160
+ }
171161
+ return normalized;
171162
+ }
170948
171163
  function getKnownMarketplacesFile() {
170949
171164
  return join94(getPluginsDirectory(), "known_marketplaces.json");
170950
171165
  }
@@ -171007,7 +171222,7 @@ async function loadKnownMarketplacesConfig() {
171007
171222
  });
171008
171223
  throw new ConfigParseError(errorMsg, configFile, data);
171009
171224
  }
171010
- return parsed.data;
171225
+ return await normalizeKnownMarketplacesConfig(parsed.data);
171011
171226
  } catch (error) {
171012
171227
  if (isENOENT(error)) {
171013
171228
  return {};
@@ -171300,6 +171515,8 @@ async function gitClone(gitUrl, targetPath, ref, sparsePaths) {
171300
171515
  const args = [
171301
171516
  "-c",
171302
171517
  "core.sshCommand=ssh -o BatchMode=yes -o StrictHostKeyChecking=yes",
171518
+ "-c",
171519
+ "credential.helper=",
171303
171520
  "clone",
171304
171521
  "--depth",
171305
171522
  "1"
@@ -172395,7 +172612,7 @@ async function setMarketplaceAutoUpdate(name, autoUpdate) {
172395
172612
  }
172396
172613
  logForDebugging(`Set autoUpdate=${autoUpdate} for marketplace: ${name}`);
172397
172614
  }
172398
- var GIT_NO_PROMPT_ENV, DEFAULT_PLUGIN_GIT_TIMEOUT_MS, getMarketplace;
172615
+ var LEGACY_RUIDONG_MARKETPLACE_NAME, LEGACY_RUIDONG_MARKETPLACE_REPO, GIT_NO_PROMPT_ENV, DEFAULT_PLUGIN_GIT_TIMEOUT_MS, getMarketplace;
172399
172616
  var init_marketplaceManager = __esm({
172400
172617
  "build-src/src/utils/plugins/marketplaceManager.ts"() {
172401
172618
  init_growthbook();
@@ -172419,6 +172636,8 @@ var init_marketplaceManager = __esm({
172419
172636
  init_pluginIdentifier();
172420
172637
  init_pluginOptionsStorage();
172421
172638
  init_schemas();
172639
+ LEGACY_RUIDONG_MARKETPLACE_NAME = "ruidong-marketplace-seed";
172640
+ LEGACY_RUIDONG_MARKETPLACE_REPO = "Jackwwg83/ruidong-marketplace-seed";
172422
172641
  GIT_NO_PROMPT_ENV = {
172423
172642
  GIT_TERMINAL_PROMPT: "0",
172424
172643
  // Prevent terminal credential prompts
@@ -185040,36 +185259,67 @@ var init_Cursor = __esm({
185040
185259
  });
185041
185260
 
185042
185261
  // build-src/src/utils/modifiers.ts
185262
+ function loadNativeModifiers() {
185263
+ if (process.platform !== "darwin") {
185264
+ return null;
185265
+ }
185266
+ if (nativeModuleAvailable === false) {
185267
+ return null;
185268
+ }
185269
+ try {
185270
+ const nativeModule4 = __require("modifiers-napi");
185271
+ nativeModuleAvailable = true;
185272
+ return nativeModule4;
185273
+ } catch (error) {
185274
+ nativeModuleAvailable = false;
185275
+ logForDebugging(
185276
+ `modifiers-napi unavailable; Apple Terminal modifier probing disabled: ${error instanceof Error ? error.message : String(error)}`,
185277
+ { level: "warn" }
185278
+ );
185279
+ return null;
185280
+ }
185281
+ }
185043
185282
  function prewarmModifiers() {
185044
185283
  if (prewarmed || process.platform !== "darwin") {
185045
185284
  return;
185046
185285
  }
185047
185286
  prewarmed = true;
185048
- try {
185049
- const { prewarm } = __require("modifiers-napi");
185050
- prewarm();
185051
- } catch {
185052
- }
185287
+ loadNativeModifiers()?.prewarm?.();
185053
185288
  }
185054
185289
  function isModifierPressed(modifier) {
185055
185290
  if (process.platform !== "darwin") {
185056
185291
  return false;
185057
185292
  }
185058
- const { isModifierPressed: nativeIsModifierPressed } = (
185059
- // eslint-disable-next-line @typescript-eslint/no-require-imports
185060
- __require("modifiers-napi")
185061
- );
185062
- return nativeIsModifierPressed(modifier);
185293
+ const nativeModule4 = loadNativeModifiers();
185294
+ if (!nativeModule4) {
185295
+ return false;
185296
+ }
185297
+ return nativeModule4.isModifierPressed(modifier);
185063
185298
  }
185064
- var prewarmed;
185299
+ var prewarmed, nativeModuleAvailable;
185065
185300
  var init_modifiers = __esm({
185066
185301
  "build-src/src/utils/modifiers.ts"() {
185302
+ init_debug();
185067
185303
  prewarmed = false;
185304
+ nativeModuleAvailable = null;
185068
185305
  }
185069
185306
  });
185070
185307
 
185071
185308
  // build-src/src/hooks/useTextInput.ts
185072
185309
  import stripAnsi6 from "strip-ansi";
185310
+ function getCoalescedSubmitSuffix(input) {
185311
+ const suffixes = ["\r\n", "\r", "\n"];
185312
+ for (const suffix of suffixes) {
185313
+ if (input.length > suffix.length && input.endsWith(suffix) && !input.slice(0, -suffix.length).includes("\r") && !input.slice(0, -suffix.length).includes("\n") && input[input.length - suffix.length - 1] !== "\\") {
185314
+ return suffix;
185315
+ }
185316
+ }
185317
+ return null;
185318
+ }
185319
+ function stripCoalescedSubmitSuffix(input) {
185320
+ const suffix = getCoalescedSubmitSuffix(input);
185321
+ return suffix ? input.slice(0, -suffix.length) : input;
185322
+ }
185073
185323
  function mapInput(input_map) {
185074
185324
  const map = new Map(input_map);
185075
185325
  return function(input) {
@@ -185168,6 +185418,9 @@ function useTextInput({
185168
185418
  return cursor.del();
185169
185419
  }
185170
185420
  function submitCurrentValue() {
185421
+ logInputTrace(
185422
+ `text-input submit reason=ctrl-submit text=${previewTraceValue(originalValue)}`
185423
+ );
185171
185424
  onSubmit?.(originalValue);
185172
185425
  return cursor;
185173
185426
  }
@@ -185237,14 +185490,22 @@ function useTextInput({
185237
185490
  function handleEnter(key) {
185238
185491
  if (multiline && cursor.offset > 0 && cursor.text[cursor.offset - 1] === "\\") {
185239
185492
  markBackslashReturnUsed();
185493
+ logInputTrace("text-input enter reason=backslash-return inserts-newline");
185240
185494
  return cursor.backspace().insert("\n");
185241
185495
  }
185242
185496
  if (key.meta || key.shift) {
185497
+ logInputTrace(
185498
+ `text-input enter reason=modifier-newline key=${summarizeInputKey(key)}`
185499
+ );
185243
185500
  return cursor.insert("\n");
185244
185501
  }
185245
185502
  if (env.terminal === "Apple_Terminal" && isModifierPressed("shift")) {
185503
+ logInputTrace("text-input enter reason=apple-terminal-shift-newline");
185246
185504
  return cursor.insert("\n");
185247
185505
  }
185506
+ logInputTrace(
185507
+ `text-input submit reason=enter key=${summarizeInputKey(key)} text=${previewTraceValue(originalValue)}`
185508
+ );
185248
185509
  onSubmit?.(originalValue);
185249
185510
  }
185250
185511
  function upOrHistoryUp() {
@@ -185342,7 +185603,10 @@ function useTextInput({
185342
185603
  case (input === "\x1B[F" || input === "\x1B[4~"):
185343
185604
  return cursor.endOfLine();
185344
185605
  default: {
185345
- const text = stripAnsi6(input).replace(/(?<=[^\\\r\n])\r$/, "").replace(/\r/g, "\n");
185606
+ const text = stripAnsi6(stripCoalescedSubmitSuffix(input)).replace(
185607
+ /\r/g,
185608
+ "\n"
185609
+ );
185346
185610
  if (cursor.isAtStart() && isInputModeCharacter(input)) {
185347
185611
  return cursor.insert(text).left();
185348
185612
  }
@@ -185367,14 +185631,23 @@ function useTextInput({
185367
185631
  }
185368
185632
  function onInput(input, key) {
185369
185633
  const filteredInput = inputFilter ? inputFilter(input, key) : input;
185634
+ logInputTrace(
185635
+ `text-input onInput raw=${previewTraceValue(input)} filtered=${previewTraceValue(filteredInput)} key=${summarizeInputKey(key)} before=${previewTraceValue(cursor.text)} offset=${cursor.offset}`
185636
+ );
185370
185637
  if (filteredInput === "" && input !== "") {
185638
+ logInputTrace("text-input filtered-out input event");
185371
185639
  return;
185372
185640
  }
185373
- if (!key.backspace && !key.delete && input.includes("\x7F")) {
185374
- const delCount = (input.match(/\x7f/g) || []).length;
185641
+ const coalescedSubmitSuffix = key.return ? null : getCoalescedSubmitSuffix(filteredInput);
185642
+ if (!key.backspace && !key.delete && /[\x08\x7f]/.test(stripCoalescedSubmitSuffix(filteredInput))) {
185643
+ const text = stripAnsi6(stripCoalescedSubmitSuffix(filteredInput));
185375
185644
  let currentCursor = cursor;
185376
- for (let i = 0; i < delCount; i++) {
185377
- currentCursor = currentCursor.deleteTokenBefore() ?? currentCursor.backspace();
185645
+ for (const char of text) {
185646
+ if (char === "\b" || char === "\x7F") {
185647
+ currentCursor = currentCursor.deleteTokenBefore() ?? currentCursor.backspace();
185648
+ continue;
185649
+ }
185650
+ currentCursor = currentCursor.insert(char === "\r" ? "\n" : char);
185378
185651
  }
185379
185652
  if (!cursor.equals(currentCursor)) {
185380
185653
  if (cursor.text !== currentCursor.text) {
@@ -185382,8 +185655,17 @@ function useTextInput({
185382
185655
  }
185383
185656
  setOffset(currentCursor.offset);
185384
185657
  }
185658
+ logInputTrace(
185659
+ `text-input coalesced-edit after=${previewTraceValue(currentCursor.text)} offset=${currentCursor.offset} submitSuffix=${coalescedSubmitSuffix ?? "none"}`
185660
+ );
185385
185661
  resetKillAccumulation();
185386
185662
  resetYankState();
185663
+ if (coalescedSubmitSuffix) {
185664
+ logInputTrace(
185665
+ `text-input submit reason=coalesced-suffix text=${previewTraceValue(currentCursor.text)}`
185666
+ );
185667
+ onSubmit?.(currentCursor.text);
185668
+ }
185387
185669
  return;
185388
185670
  }
185389
185671
  if (!isKillKey2(key, filteredInput)) {
@@ -185400,12 +185682,18 @@ function useTextInput({
185400
185682
  }
185401
185683
  setOffset(nextCursor.offset);
185402
185684
  }
185403
- if (filteredInput.length > 1 && filteredInput.endsWith("\r") && !filteredInput.slice(0, -1).includes("\r") && // Backslash+CR is a stale VS Code Shift+Enter binding, not
185404
- // coalesced Enter. See default handler above.
185405
- filteredInput[filteredInput.length - 2] !== "\\") {
185685
+ logInputTrace(
185686
+ `text-input nextCursor after=${previewTraceValue(nextCursor.text)} offset=${nextCursor.offset} submitSuffix=${coalescedSubmitSuffix ?? "none"}`
185687
+ );
185688
+ if (coalescedSubmitSuffix) {
185689
+ logInputTrace(
185690
+ `text-input submit reason=coalesced-suffix text=${previewTraceValue(nextCursor.text)}`
185691
+ );
185406
185692
  onSubmit?.(nextCursor.text);
185407
185693
  }
185694
+ return;
185408
185695
  }
185696
+ logInputTrace("text-input handled without cursor update");
185409
185697
  }
185410
185698
  const ghostTextForRender = inlineGhostText && dim && inlineGhostText.insertPosition === offset ? { text: inlineGhostText.text, dim } : void 0;
185411
185699
  const cursorPos = cursor.getPosition();
@@ -185436,6 +185724,7 @@ var init_useTextInput = __esm({
185436
185724
  init_Cursor();
185437
185725
  init_env();
185438
185726
  init_fullscreen();
185727
+ init_inputTrace();
185439
185728
  init_modifiers();
185440
185729
  init_useDoublePress();
185441
185730
  NOOP_HANDLER = () => {
@@ -187844,7 +188133,7 @@ ${sanitizedDescription}
187844
188133
  **Environment Info**
187845
188134
  - Platform: ${env.platform}
187846
188135
  - Terminal: ${env.terminal}
187847
- - Version: ${"0.1.7"}
188136
+ - Version: ${"0.1.10"}
187848
188137
  - Feedback ID: ${feedbackId}
187849
188138
 
187850
188139
  **Errors**
@@ -254158,7 +254447,7 @@ function generateHtmlReport(data, insights) {
254158
254447
  </html>`;
254159
254448
  }
254160
254449
  function buildExportData(data, insights, facets, remoteStats) {
254161
- const version2 = typeof MACRO !== "undefined" ? "0.1.7" : "unknown";
254450
+ const version2 = typeof MACRO !== "undefined" ? "0.1.10" : "unknown";
254162
254451
  const remote_hosts_collected = remoteStats?.hosts.filter((h) => h.sessionCount > 0).map((h) => h.name);
254163
254452
  const facets_summary = {
254164
254453
  total: facets.size,
@@ -257922,7 +258211,7 @@ var init_sessionStorage = __esm({
257922
258211
  init_settings2();
257923
258212
  init_slowOperations();
257924
258213
  init_uuid();
257925
- VERSION2 = typeof MACRO !== "undefined" ? "0.1.7" : "unknown";
258214
+ VERSION2 = typeof MACRO !== "undefined" ? "0.1.10" : "unknown";
257926
258215
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
257927
258216
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
257928
258217
  EPHEMERAL_PROGRESS_TYPES = /* @__PURE__ */ new Set([
@@ -267028,7 +267317,8 @@ async function verifyApiKey(apiKey, isNonInteractiveSession) {
267028
267317
  return true;
267029
267318
  }
267030
267319
  try {
267031
- const model = getSmallFastModel();
267320
+ const model = process.env.ANTHROPIC_MODEL?.trim() !== "" ? getMainLoopModel() : getSmallFastModel();
267321
+ const verificationTimeoutMs = parseInt(process.env.RUIDONG_VERIFY_API_TIMEOUT_MS || "", 10) || 15e3;
267032
267322
  const betas = getModelBetas(model);
267033
267323
  return await returnValue(
267034
267324
  withRetry(
@@ -267048,6 +267338,8 @@ async function verifyApiKey(apiKey, isNonInteractiveSession) {
267048
267338
  ...betas.length > 0 && { betas },
267049
267339
  metadata: getAPIMetadata(),
267050
267340
  ...getExtraBodyParams()
267341
+ }, {
267342
+ signal: AbortSignal.timeout(verificationTimeoutMs)
267051
267343
  });
267052
267344
  return true;
267053
267345
  },
@@ -267827,6 +268119,12 @@ ${deferredToolList}
267827
268119
  queryCheckpoint("query_response_headers_received");
267828
268120
  streamRequestId = result.request_id;
267829
268121
  streamResponse = result.response;
268122
+ const responseContentType = streamResponse.headers.get("content-type")?.toLowerCase();
268123
+ if (!isFirstPartyAnthropicBaseUrl() && responseContentType && !responseContentType.includes("text/event-stream")) {
268124
+ throw new Error(
268125
+ `Streaming endpoint returned non-SSE content-type: ${responseContentType}`
268126
+ );
268127
+ }
267830
268128
  return result.data;
267831
268129
  },
267832
268130
  {
@@ -267853,10 +268151,9 @@ ${deferredToolList}
267853
268151
  usage = EMPTY_USAGE;
267854
268152
  stopReason = null;
267855
268153
  isAdvisorInProgress = false;
267856
- const streamWatchdogEnabled = isEnvTruthy(
267857
- process.env.CLAUDE_ENABLE_STREAM_WATCHDOG
267858
- );
267859
- const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.CLAUDE_STREAM_IDLE_TIMEOUT_MS || "", 10) || 9e4;
268154
+ const isThirdPartyStreaming = !isFirstPartyAnthropicBaseUrl();
268155
+ const streamWatchdogEnabled = isThirdPartyStreaming || isEnvTruthy(process.env.CLAUDE_ENABLE_STREAM_WATCHDOG);
268156
+ const STREAM_IDLE_TIMEOUT_MS = parseInt(process.env.CLAUDE_STREAM_IDLE_TIMEOUT_MS || "", 10) || (isThirdPartyStreaming ? 3e4 : 9e4);
267860
268157
  const STREAM_IDLE_WARNING_MS = STREAM_IDLE_TIMEOUT_MS / 2;
267861
268158
  let streamIdleAborted = false;
267862
268159
  let streamWatchdogFiredAt = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iruidong/code",
3
- "version": "0.1.7",
3
+ "version": "0.1.10",
4
4
  "description": "Ruidong Code CLI for anthropic-compatible coding workflows",
5
5
  "type": "module",
6
6
  "private": false,