@funnycode/myclaude 0.1.22 → 0.1.25

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.23] - 2026-06-17
4
+
5
+ ### Fixed
6
+ - **Git Bash "no available terminals" fork error** — enhanced Windows spawn reliability (fixes #6)
7
+ - Reduced spawn semaphore concurrency from 24 → 8 to prevent MSYS2 pty pool exhaustion under heavy parallelism
8
+ - Skip login shell (`-l` flag) on Git Bash/Windows to reduce per-fork startup overhead
9
+ - Added automatic retry with exponential backoff (500ms, 1s, 2s) when pty exhaustion is detected
10
+ - Better error detection: identifies "no available terminals", "cannot fork", and "resource temporarily unavailable" errors
11
+ - Shared cleanup path ensures semaphore is always released, preventing deadlocks
12
+
3
13
  ## [0.1.22] - 2026-06-17
4
14
 
5
15
  ### Added
package/README.md CHANGED
@@ -142,8 +142,7 @@ npx @funnycode/myclaude --help # Show help
142
142
  | `/tag` | Tag current session |
143
143
  | `/export` | Export session |
144
144
  | `/upgrade` | Check for updates |
145
- | `/feedback` | Submit feedback |
146
- | `/summary` | Generate session summary |
145
+ | `/feedback` | Submit feedback (opens GitHub Issues) |
147
146
  | `/thinkback` | Think-back review |
148
147
 
149
148
  ---
@@ -232,6 +231,7 @@ The following features have been tested and confirmed working:
232
231
  - ✅ Keybinding customization
233
232
  - ✅ API key authentication (with any Anthropic-compatible provider)
234
233
  - ✅ Multi-model providers (Bedrock / Vertex / Foundry)
234
+ - ✅ Claude Code config compatibility — reads `~/.claude/settings.json`, skills, MCPs, plugins, and hooks shared with Claude Code
235
235
 
236
236
  ---
237
237
 
@@ -262,17 +262,17 @@ Supports both `MYCLAUDE_*` and `CLAUDE_CODE_*` names.
262
262
  ## Development
263
263
 
264
264
  ```bash
265
- git clone https://gitee.com/thomaslwq/myclaude.git
265
+ git clone https://github.com/thomaslwq/myclaude.git
266
266
  cd myclaude
267
267
  bun install
268
268
  bun run dev # Development mode
269
- bun run build # Build to dist/myclaude.js
269
+ bun run build # Build to dist/myclaude.mjs
270
270
  bun run version # Verify CLI boots
271
271
  ```
272
272
 
273
273
  ### Build Output
274
274
 
275
- The build script bundles `src/entrypoints/cli.tsx` into a single file `dist/myclaude.js`, injecting compile-time constants such as version number.
275
+ The build script bundles `src/entrypoints/cli.tsx` into a single file `dist/myclaude.mjs`, injecting compile-time constants such as version number.
276
276
 
277
277
  ### Directory Structure
278
278
 
@@ -318,8 +318,8 @@ Pull requests are welcome!
318
318
 
319
319
  ## Links
320
320
 
321
- - **Gitee**: [https://gitee.com/thomaslwq/myclaude](https://gitee.com/thomaslwq/myclaude)
322
321
  - **GitHub**: [https://github.com/thomaslwq/myclaude](https://github.com/thomaslwq/myclaude)
322
+ - **Gitee**: [https://gitee.com/thomaslwq/myclaude](https://gitee.com/thomaslwq/myclaude) (mirror)
323
323
  - **npm**: [https://www.npmjs.com/package/@funnycode/myclaude](https://www.npmjs.com/package/@funnycode/myclaude)
324
324
 
325
325
  ---
package/README.zh-CN.md CHANGED
@@ -142,8 +142,7 @@ npx @funnycode/myclaude --help # 查看帮助
142
142
  | `/tag` | 标记当前会话 |
143
143
  | `/export` | 导出会话 |
144
144
  | `/upgrade` | 检查更新 |
145
- | `/feedback` | 提交反馈 |
146
- | `/summary` | 生成会话摘要 |
145
+ | `/feedback` | 提交反馈(跳转 GitHub Issues) |
147
146
  | `/thinkback` | 回溯思考过程 |
148
147
 
149
148
  ---
@@ -260,17 +259,17 @@ myclaude 内置了一个终端电子宠物。每只宠物都根据你的用户 I
260
259
  ## 开发
261
260
 
262
261
  ```bash
263
- git clone https://gitee.com/thomaslwq/myclaude.git
262
+ git clone https://github.com/thomaslwq/myclaude.git
264
263
  cd myclaude
265
264
  bun install
266
265
  bun run dev # 开发模式
267
- bun run build # 构建到 dist/myclaude.js
266
+ bun run build # 构建到 dist/myclaude.mjs
268
267
  bun run version # 验证 CLI 启动
269
268
  ```
270
269
 
271
270
  ### 构建产物
272
271
 
273
- 构建脚本会将 `src/entrypoints/cli.tsx` 打包为单文件 `dist/myclaude.js`,并注入版本号等编译时常量。
272
+ 构建脚本会将 `src/entrypoints/cli.tsx` 打包为单文件 `dist/myclaude.mjs`,并注入版本号等编译时常量。
274
273
 
275
274
  ### 目录结构
276
275
 
@@ -316,8 +315,8 @@ src/
316
315
 
317
316
  ## 相关链接
318
317
 
319
- - **Gitee**: [https://gitee.com/thomaslwq/myclaude](https://gitee.com/thomaslwq/myclaude)
320
318
  - **GitHub**: [https://github.com/thomaslwq/myclaude](https://github.com/thomaslwq/myclaude)
319
+ - **Gitee**: [https://gitee.com/thomaslwq/myclaude](https://gitee.com/thomaslwq/myclaude)(镜像)
321
320
  - **npm**: [https://www.npmjs.com/package/@funnycode/myclaude](https://www.npmjs.com/package/@funnycode/myclaude)
322
321
 
323
322
  ---
package/dist/myclaude.js CHANGED
@@ -4,12 +4,12 @@
4
4
  // MACRO - build-time constants (injected by build.ts)
5
5
  // MACRO injected by build script
6
6
  globalThis.MACRO = {
7
- VERSION: "0.1.22",
8
- BUILD_TIME: "2026-06-16T12:51:32.359Z",
7
+ VERSION: "0.1.25",
8
+ BUILD_TIME: "2026-06-22T12:30:11.149Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
12
- ISSUES_EXPLAINER: 'file an issue at ' + "https://gitee.com/thomaslwq/myclaude/issues",
12
+ ISSUES_EXPLAINER: 'file an issue at ' + "https://github.com/thomaslwq/myclaude/issues",
13
13
  FEEDBACK_CHANNEL: 'github',
14
14
  };
15
15
 
@@ -274035,7 +274035,7 @@ function getRemoteSessionUrl(sessionId, ingressUrl) {
274035
274035
  const baseUrl = getClaudeAiBaseUrl(compatId, ingressUrl);
274036
274036
  return `${baseUrl}/code/${compatId}`;
274037
274037
  }
274038
- var PRODUCT_URL = "https://gitee.com/thomaslwq/myclaude", CLAUDE_AI_BASE_URL = "https://claude.ai", CLAUDE_AI_STAGING_BASE_URL = "https://claude-ai.staging.ant.dev", CLAUDE_AI_LOCAL_BASE_URL = "http://localhost:4000";
274038
+ var PRODUCT_URL = "https://github.com/thomaslwq/myclaude", CLAUDE_AI_BASE_URL = "https://claude.ai", CLAUDE_AI_STAGING_BASE_URL = "https://claude-ai.staging.ant.dev", CLAUDE_AI_LOCAL_BASE_URL = "http://localhost:4000";
274039
274039
 
274040
274040
  // src/keybindings/defaultBindings.ts
274041
274041
  var IMAGE_PASTE_KEY, SUPPORTS_TERMINAL_VT_MODE, MODE_CYCLE_KEY, DEFAULT_BINDINGS;
@@ -347542,10 +347542,17 @@ async function createBashShellProvider(shellPath, options) {
347542
347542
  },
347543
347543
  getSpawnArgs(commandString) {
347544
347544
  const skipLoginShell = lastSnapshotFilePath !== undefined;
347545
- if (skipLoginShell) {
347546
- logForDebugging("Spawning shell without login (-l flag skipped)");
347545
+ const onWindows = getPlatform() === "windows";
347546
+ if (skipLoginShell || onWindows) {
347547
+ if (!onWindows) {
347548
+ logForDebugging("Spawning shell without login (-l flag skipped)");
347549
+ }
347547
347550
  }
347548
- return ["-c", ...skipLoginShell ? [] : ["-l"], commandString];
347551
+ return [
347552
+ "-c",
347553
+ ...skipLoginShell || onWindows ? [] : ["-l"],
347554
+ commandString
347555
+ ];
347549
347556
  },
347550
347557
  async getEnvironmentOverrides(command) {
347551
347558
  const commandUsesTmux = command.includes("tmux");
@@ -347595,7 +347602,7 @@ var init_bashProvider = __esm(() => {
347595
347602
  init_sessionEnvVars();
347596
347603
  init_tmuxSocket();
347597
347604
  init_windowsPaths();
347598
- BASH_SPAWN_SEMAPHORE = createSpawnSemaphore(getPlatform() === "windows" ? 24 : Infinity);
347605
+ BASH_SPAWN_SEMAPHORE = createSpawnSemaphore(getPlatform() === "windows" ? 8 : Infinity);
347599
347606
  });
347600
347607
 
347601
347608
  // src/utils/shell/powershellDetection.ts
@@ -347823,6 +347830,12 @@ async function exec3(command, abortSignal, shellType, options) {
347823
347830
  const shellArgs = isSandboxedPowerShell ? ["-c", commandString] : provider.getSpawnArgs(commandString);
347824
347831
  const envOverrides = await provider.getEnvironmentOverrides(command);
347825
347832
  const isGitBash = shellType === "bash" && getPlatform() === "windows" && !isSandboxedPowerShell;
347833
+ const MAX_GITBASH_RETRIES = 3;
347834
+ const GITBASH_RETRY_BASE_MS = 500;
347835
+ function isGitBashPtyExhaustion(err2) {
347836
+ const msg = errorMessage(err2).toLowerCase();
347837
+ return msg.includes("no available terminals") || msg.includes("cannot fork") || msg.includes("resource temporarily unavailable");
347838
+ }
347826
347839
  if (isGitBash) {
347827
347840
  await getBashSpawnSemaphore().acquire();
347828
347841
  }
@@ -347866,14 +347879,14 @@ async function exec3(command, abortSignal, shellType, options) {
347866
347879
  onStdout(typeof chunk === "string" ? chunk : chunk.toString());
347867
347880
  });
347868
347881
  }
347869
- const nativeCwdFilePath = getPlatform() === "windows" ? posixPathToWindowsPath(cwdFilePath) : cwdFilePath;
347882
+ const nativeCwdFilePath2 = getPlatform() === "windows" ? posixPathToWindowsPath(cwdFilePath) : cwdFilePath;
347870
347883
  shellCommand.result.then(async (result) => {
347871
347884
  if (shouldUseSandbox) {
347872
347885
  SandboxManager2.cleanupAfterCommand();
347873
347886
  }
347874
347887
  if (result && !preventCwdChanges && !result.backgroundTaskId) {
347875
347888
  try {
347876
- let newCwd = readFileSync17(nativeCwdFilePath, {
347889
+ let newCwd = readFileSync17(nativeCwdFilePath2, {
347877
347890
  encoding: "utf8"
347878
347891
  }).trim();
347879
347892
  if (getPlatform() === "windows") {
@@ -347889,13 +347902,95 @@ async function exec3(command, abortSignal, shellType, options) {
347889
347902
  }
347890
347903
  }
347891
347904
  try {
347892
- unlinkSync3(nativeCwdFilePath);
347905
+ unlinkSync3(nativeCwdFilePath2);
347893
347906
  } catch {}
347894
347907
  });
347895
347908
  return shellCommand;
347896
347909
  } catch (error49) {
347897
- if (isGitBash) {
347910
+ if (isGitBash && isGitBashPtyExhaustion(error49)) {
347898
347911
  getBashSpawnSemaphore().release();
347912
+ for (let retry = 1;retry <= MAX_GITBASH_RETRIES; retry++) {
347913
+ const delay = GITBASH_RETRY_BASE_MS * Math.pow(2, retry - 1);
347914
+ logForDebugging(`Git Bash pty exhausted, retry ${retry}/${MAX_GITBASH_RETRIES} in ${delay}ms`);
347915
+ await new Promise((resolve30) => setTimeout(resolve30, delay));
347916
+ if (outputHandle !== undefined) {
347917
+ try {
347918
+ await outputHandle.close();
347919
+ } catch {}
347920
+ outputHandle = undefined;
347921
+ }
347922
+ taskOutput.clear();
347923
+ const retryTaskOutput = new TaskOutput(taskId, onProgress ?? null, !usePipeMode);
347924
+ if (!usePipeMode) {
347925
+ const O_NOFOLLOW = fsConstants4.O_NOFOLLOW ?? 0;
347926
+ try {
347927
+ outputHandle = await open8(taskOutput.path, process.platform === "win32" ? "w" : fsConstants4.O_WRONLY | fsConstants4.O_CREAT | fsConstants4.O_APPEND | O_NOFOLLOW);
347928
+ } catch {}
347929
+ }
347930
+ await getBashSpawnSemaphore().acquire();
347931
+ try {
347932
+ const childProcess = spawn8(spawnBinary, shellArgs, {
347933
+ env: {
347934
+ ...subprocessEnv(),
347935
+ SHELL: shellType === "bash" ? binShell : undefined,
347936
+ GIT_EDITOR: "true",
347937
+ CLAUDECODE: "1",
347938
+ ...envOverrides
347939
+ },
347940
+ cwd: cwd2,
347941
+ stdio: usePipeMode ? ["pipe", "pipe", "pipe"] : ["pipe", outputHandle?.fd, outputHandle?.fd],
347942
+ detached: provider.detached,
347943
+ windowsHide: true
347944
+ });
347945
+ childProcess.once("close", () => getBashSpawnSemaphore().release());
347946
+ const retryCmd = wrapSpawn(childProcess, abortSignal, commandTimeout, retryTaskOutput, shouldAutoBackground);
347947
+ if (outputHandle !== undefined) {
347948
+ try {
347949
+ await outputHandle.close();
347950
+ } catch {}
347951
+ }
347952
+ if (childProcess.stdout && onStdout) {
347953
+ childProcess.stdout.on("data", (chunk) => {
347954
+ onStdout(typeof chunk === "string" ? chunk : chunk.toString());
347955
+ });
347956
+ }
347957
+ retryCmd.result.then(async (result) => {
347958
+ if (shouldUseSandbox)
347959
+ SandboxManager2.cleanupAfterCommand();
347960
+ if (result && !preventCwdChanges && !result.backgroundTaskId) {
347961
+ try {
347962
+ let newCwd = readFileSync17(nativeCwdFilePath, { encoding: "utf8" }).trim();
347963
+ if (getPlatform() === "windows")
347964
+ newCwd = posixPathToWindowsPath(newCwd);
347965
+ if (newCwd.normalize("NFC") !== cwd2) {
347966
+ setCwd(newCwd, cwd2);
347967
+ invalidateSessionEnvCache();
347968
+ onCwdChangedForHooks(cwd2, newCwd);
347969
+ }
347970
+ } catch {
347971
+ logEvent("tengu_shell_set_cwd", { success: false });
347972
+ }
347973
+ }
347974
+ try {
347975
+ unlinkSync3(nativeCwdFilePath);
347976
+ } catch {}
347977
+ });
347978
+ return retryCmd;
347979
+ } catch (retryError) {
347980
+ getBashSpawnSemaphore().release();
347981
+ if (!isGitBashPtyExhaustion(retryError)) {
347982
+ logForDebugging(`Git Bash retry ${retry} failed with non-pty error: ${errorMessage(retryError)}`);
347983
+ break;
347984
+ }
347985
+ if (retry === MAX_GITBASH_RETRIES) {
347986
+ logForDebugging(`Git Bash all ${MAX_GITBASH_RETRIES} retries exhausted, giving up`);
347987
+ }
347988
+ }
347989
+ }
347990
+ } else {
347991
+ if (isGitBash) {
347992
+ getBashSpawnSemaphore().release();
347993
+ }
347899
347994
  }
347900
347995
  if (outputHandle !== undefined) {
347901
347996
  try {
@@ -405882,27 +405977,17 @@ function Feedback({
405882
405977
  rawTranscriptJsonl
405883
405978
  }
405884
405979
  };
405885
- const [result, t] = await Promise.all([submitFeedback(reportData, abortSignal), generateTitle(description, abortSignal)]);
405886
- setTitle(t);
405887
- if (result.success) {
405888
- if (result.feedbackId) {
405889
- setFeedbackId(result.feedbackId);
405890
- logEvent("tengu_bug_report_submitted", {
405891
- feedback_id: result.feedbackId,
405892
- last_assistant_message_id: lastAssistantMessageId
405893
- });
405894
- logEventTo1P("tengu_bug_report_description", {
405895
- feedback_id: result.feedbackId,
405896
- description: redactSensitiveInfo(description)
405897
- });
405898
- }
405980
+ const generatedTitle = await generateTitle(description, abortSignal).catch(() => createFallbackTitle(description));
405981
+ setTitle(generatedTitle);
405982
+ const fallbackId = `myclaude-${Date.now()}`;
405983
+ const url3 = createGitHubIssueUrl(fallbackId, generatedTitle, description, sanitizedErrors);
405984
+ try {
405985
+ await openBrowser(url3);
405986
+ setFeedbackId(fallbackId);
405899
405987
  setStep("done");
405900
- } else {
405901
- if (result.isZdrOrg) {
405902
- setError("Feedback collection is not available for organizations with custom data retention policies.");
405903
- } else {
405904
- setError("Could not submit feedback. Please try again later.");
405905
- }
405988
+ } catch {
405989
+ setError(`Could not open browser. Please manually create an issue at:
405990
+ ${url3}`);
405906
405991
  setStep("userInput");
405907
405992
  }
405908
405993
  }, [description, envInfo.isGit, messages]);
@@ -406256,101 +406341,19 @@ function createFallbackTitle(description) {
406256
406341
  }
406257
406342
  return truncated.length < 10 ? "Bug Report" : truncated;
406258
406343
  }
406259
- function sanitizeAndLogError(err2) {
406260
- if (err2 instanceof Error) {
406261
- const safeError = new Error(redactSensitiveInfo(err2.message));
406262
- if (err2.stack) {
406263
- safeError.stack = redactSensitiveInfo(err2.stack);
406264
- }
406265
- logError2(safeError);
406266
- } else {
406267
- const errorString = redactSensitiveInfo(String(err2));
406268
- logError2(new Error(errorString));
406269
- }
406270
- }
406271
- async function submitFeedback(data, signal) {
406272
- if (isEssentialTrafficOnly()) {
406273
- return {
406274
- success: false
406275
- };
406276
- }
406277
- try {
406278
- await checkAndRefreshOAuthTokenIfNeeded();
406279
- const authResult = getAuthHeaders();
406280
- if (authResult.error) {
406281
- return {
406282
- success: false
406283
- };
406284
- }
406285
- const headers = {
406286
- "Content-Type": "application/json",
406287
- "User-Agent": getUserAgent(),
406288
- ...authResult.headers
406289
- };
406290
- const response = await axios_default.post("https://api.anthropic.com/api/claude_cli_feedback", {
406291
- content: jsonStringify(data)
406292
- }, {
406293
- headers,
406294
- timeout: 30000,
406295
- signal
406296
- });
406297
- if (response.status === 200) {
406298
- const result = response.data;
406299
- if (result?.feedback_id) {
406300
- return {
406301
- success: true,
406302
- feedbackId: result.feedback_id
406303
- };
406304
- }
406305
- sanitizeAndLogError(new Error("Failed to submit feedback: request did not return feedback_id"));
406306
- return {
406307
- success: false
406308
- };
406309
- }
406310
- sanitizeAndLogError(new Error("Failed to submit feedback:" + response.status));
406311
- return {
406312
- success: false
406313
- };
406314
- } catch (err2) {
406315
- if (axios_default.isCancel(err2)) {
406316
- return {
406317
- success: false
406318
- };
406319
- }
406320
- if (axios_default.isAxiosError(err2) && err2.response?.status === 403) {
406321
- const errorData = err2.response.data;
406322
- if (errorData?.error?.type === "permission_error" && errorData?.error?.message?.includes("Custom data retention settings")) {
406323
- sanitizeAndLogError(new Error("Cannot submit feedback because custom data retention settings are enabled"));
406324
- return {
406325
- success: false,
406326
- isZdrOrg: true
406327
- };
406328
- }
406329
- }
406330
- sanitizeAndLogError(err2);
406331
- return {
406332
- success: false
406333
- };
406334
- }
406335
- }
406336
406344
  var import_react95, jsx_dev_runtime159, GITHUB_URL_LIMIT = 7250, GITHUB_ISSUES_REPO_URL = "https://github.com/thomaslwq/myclaude/issues";
406337
406345
  var init_Feedback = __esm(() => {
406338
- init_axios2();
406339
406346
  init_state();
406340
- init_firstPartyEventLogger();
406341
- init_analytics();
406342
406347
  init_messages3();
406343
406348
  init_useTerminalSize();
406344
406349
  init_ink2();
406345
406350
  init_useKeybinding();
406346
406351
  init_claude();
406347
406352
  init_errors8();
406348
- init_auth();
406349
406353
  init_browser();
406350
406354
  init_debug();
406351
406355
  init_env();
406352
406356
  init_git();
406353
- init_http2();
406354
406357
  init_log3();
406355
406358
  init_sessionStorage();
406356
406359
  init_slowOperations();
@@ -484769,10 +484772,10 @@ import {
484769
484772
  import { tmpdir as tmpdir12 } from "os";
484770
484773
  import { extname as extname14, join as join135 } from "path";
484771
484774
  function getAnalysisModel() {
484772
- return getDefaultOpusModel();
484775
+ return getDefaultSonnetModel();
484773
484776
  }
484774
484777
  function getInsightsModel() {
484775
- return getDefaultOpusModel();
484778
+ return getDefaultSonnetModel();
484776
484779
  }
484777
484780
  function getDataDir() {
484778
484781
  return join135(getClaudeConfigHomeDir(), "usage-data");
package/dist/myclaude.mjs CHANGED
@@ -4,12 +4,12 @@
4
4
  // MACRO - build-time constants (injected by build.ts)
5
5
  // MACRO injected by build script
6
6
  globalThis.MACRO = {
7
- VERSION: "0.1.22",
8
- BUILD_TIME: "2026-06-16T12:51:32.359Z",
7
+ VERSION: "0.1.25",
8
+ BUILD_TIME: "2026-06-22T12:30:11.149Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
12
- ISSUES_EXPLAINER: 'file an issue at ' + "https://gitee.com/thomaslwq/myclaude/issues",
12
+ ISSUES_EXPLAINER: 'file an issue at ' + "https://github.com/thomaslwq/myclaude/issues",
13
13
  FEEDBACK_CHANNEL: 'github',
14
14
  };
15
15
 
@@ -274035,7 +274035,7 @@ function getRemoteSessionUrl(sessionId, ingressUrl) {
274035
274035
  const baseUrl = getClaudeAiBaseUrl(compatId, ingressUrl);
274036
274036
  return `${baseUrl}/code/${compatId}`;
274037
274037
  }
274038
- var PRODUCT_URL = "https://gitee.com/thomaslwq/myclaude", CLAUDE_AI_BASE_URL = "https://claude.ai", CLAUDE_AI_STAGING_BASE_URL = "https://claude-ai.staging.ant.dev", CLAUDE_AI_LOCAL_BASE_URL = "http://localhost:4000";
274038
+ var PRODUCT_URL = "https://github.com/thomaslwq/myclaude", CLAUDE_AI_BASE_URL = "https://claude.ai", CLAUDE_AI_STAGING_BASE_URL = "https://claude-ai.staging.ant.dev", CLAUDE_AI_LOCAL_BASE_URL = "http://localhost:4000";
274039
274039
 
274040
274040
  // src/keybindings/defaultBindings.ts
274041
274041
  var IMAGE_PASTE_KEY, SUPPORTS_TERMINAL_VT_MODE, MODE_CYCLE_KEY, DEFAULT_BINDINGS;
@@ -347542,10 +347542,17 @@ async function createBashShellProvider(shellPath, options) {
347542
347542
  },
347543
347543
  getSpawnArgs(commandString) {
347544
347544
  const skipLoginShell = lastSnapshotFilePath !== undefined;
347545
- if (skipLoginShell) {
347546
- logForDebugging("Spawning shell without login (-l flag skipped)");
347545
+ const onWindows = getPlatform() === "windows";
347546
+ if (skipLoginShell || onWindows) {
347547
+ if (!onWindows) {
347548
+ logForDebugging("Spawning shell without login (-l flag skipped)");
347549
+ }
347547
347550
  }
347548
- return ["-c", ...skipLoginShell ? [] : ["-l"], commandString];
347551
+ return [
347552
+ "-c",
347553
+ ...skipLoginShell || onWindows ? [] : ["-l"],
347554
+ commandString
347555
+ ];
347549
347556
  },
347550
347557
  async getEnvironmentOverrides(command) {
347551
347558
  const commandUsesTmux = command.includes("tmux");
@@ -347595,7 +347602,7 @@ var init_bashProvider = __esm(() => {
347595
347602
  init_sessionEnvVars();
347596
347603
  init_tmuxSocket();
347597
347604
  init_windowsPaths();
347598
- BASH_SPAWN_SEMAPHORE = createSpawnSemaphore(getPlatform() === "windows" ? 24 : Infinity);
347605
+ BASH_SPAWN_SEMAPHORE = createSpawnSemaphore(getPlatform() === "windows" ? 8 : Infinity);
347599
347606
  });
347600
347607
 
347601
347608
  // src/utils/shell/powershellDetection.ts
@@ -347823,6 +347830,12 @@ async function exec3(command, abortSignal, shellType, options) {
347823
347830
  const shellArgs = isSandboxedPowerShell ? ["-c", commandString] : provider.getSpawnArgs(commandString);
347824
347831
  const envOverrides = await provider.getEnvironmentOverrides(command);
347825
347832
  const isGitBash = shellType === "bash" && getPlatform() === "windows" && !isSandboxedPowerShell;
347833
+ const MAX_GITBASH_RETRIES = 3;
347834
+ const GITBASH_RETRY_BASE_MS = 500;
347835
+ function isGitBashPtyExhaustion(err2) {
347836
+ const msg = errorMessage(err2).toLowerCase();
347837
+ return msg.includes("no available terminals") || msg.includes("cannot fork") || msg.includes("resource temporarily unavailable");
347838
+ }
347826
347839
  if (isGitBash) {
347827
347840
  await getBashSpawnSemaphore().acquire();
347828
347841
  }
@@ -347866,14 +347879,14 @@ async function exec3(command, abortSignal, shellType, options) {
347866
347879
  onStdout(typeof chunk === "string" ? chunk : chunk.toString());
347867
347880
  });
347868
347881
  }
347869
- const nativeCwdFilePath = getPlatform() === "windows" ? posixPathToWindowsPath(cwdFilePath) : cwdFilePath;
347882
+ const nativeCwdFilePath2 = getPlatform() === "windows" ? posixPathToWindowsPath(cwdFilePath) : cwdFilePath;
347870
347883
  shellCommand.result.then(async (result) => {
347871
347884
  if (shouldUseSandbox) {
347872
347885
  SandboxManager2.cleanupAfterCommand();
347873
347886
  }
347874
347887
  if (result && !preventCwdChanges && !result.backgroundTaskId) {
347875
347888
  try {
347876
- let newCwd = readFileSync17(nativeCwdFilePath, {
347889
+ let newCwd = readFileSync17(nativeCwdFilePath2, {
347877
347890
  encoding: "utf8"
347878
347891
  }).trim();
347879
347892
  if (getPlatform() === "windows") {
@@ -347889,13 +347902,95 @@ async function exec3(command, abortSignal, shellType, options) {
347889
347902
  }
347890
347903
  }
347891
347904
  try {
347892
- unlinkSync3(nativeCwdFilePath);
347905
+ unlinkSync3(nativeCwdFilePath2);
347893
347906
  } catch {}
347894
347907
  });
347895
347908
  return shellCommand;
347896
347909
  } catch (error49) {
347897
- if (isGitBash) {
347910
+ if (isGitBash && isGitBashPtyExhaustion(error49)) {
347898
347911
  getBashSpawnSemaphore().release();
347912
+ for (let retry = 1;retry <= MAX_GITBASH_RETRIES; retry++) {
347913
+ const delay = GITBASH_RETRY_BASE_MS * Math.pow(2, retry - 1);
347914
+ logForDebugging(`Git Bash pty exhausted, retry ${retry}/${MAX_GITBASH_RETRIES} in ${delay}ms`);
347915
+ await new Promise((resolve30) => setTimeout(resolve30, delay));
347916
+ if (outputHandle !== undefined) {
347917
+ try {
347918
+ await outputHandle.close();
347919
+ } catch {}
347920
+ outputHandle = undefined;
347921
+ }
347922
+ taskOutput.clear();
347923
+ const retryTaskOutput = new TaskOutput(taskId, onProgress ?? null, !usePipeMode);
347924
+ if (!usePipeMode) {
347925
+ const O_NOFOLLOW = fsConstants4.O_NOFOLLOW ?? 0;
347926
+ try {
347927
+ outputHandle = await open8(taskOutput.path, process.platform === "win32" ? "w" : fsConstants4.O_WRONLY | fsConstants4.O_CREAT | fsConstants4.O_APPEND | O_NOFOLLOW);
347928
+ } catch {}
347929
+ }
347930
+ await getBashSpawnSemaphore().acquire();
347931
+ try {
347932
+ const childProcess = spawn8(spawnBinary, shellArgs, {
347933
+ env: {
347934
+ ...subprocessEnv(),
347935
+ SHELL: shellType === "bash" ? binShell : undefined,
347936
+ GIT_EDITOR: "true",
347937
+ CLAUDECODE: "1",
347938
+ ...envOverrides
347939
+ },
347940
+ cwd: cwd2,
347941
+ stdio: usePipeMode ? ["pipe", "pipe", "pipe"] : ["pipe", outputHandle?.fd, outputHandle?.fd],
347942
+ detached: provider.detached,
347943
+ windowsHide: true
347944
+ });
347945
+ childProcess.once("close", () => getBashSpawnSemaphore().release());
347946
+ const retryCmd = wrapSpawn(childProcess, abortSignal, commandTimeout, retryTaskOutput, shouldAutoBackground);
347947
+ if (outputHandle !== undefined) {
347948
+ try {
347949
+ await outputHandle.close();
347950
+ } catch {}
347951
+ }
347952
+ if (childProcess.stdout && onStdout) {
347953
+ childProcess.stdout.on("data", (chunk) => {
347954
+ onStdout(typeof chunk === "string" ? chunk : chunk.toString());
347955
+ });
347956
+ }
347957
+ retryCmd.result.then(async (result) => {
347958
+ if (shouldUseSandbox)
347959
+ SandboxManager2.cleanupAfterCommand();
347960
+ if (result && !preventCwdChanges && !result.backgroundTaskId) {
347961
+ try {
347962
+ let newCwd = readFileSync17(nativeCwdFilePath, { encoding: "utf8" }).trim();
347963
+ if (getPlatform() === "windows")
347964
+ newCwd = posixPathToWindowsPath(newCwd);
347965
+ if (newCwd.normalize("NFC") !== cwd2) {
347966
+ setCwd(newCwd, cwd2);
347967
+ invalidateSessionEnvCache();
347968
+ onCwdChangedForHooks(cwd2, newCwd);
347969
+ }
347970
+ } catch {
347971
+ logEvent("tengu_shell_set_cwd", { success: false });
347972
+ }
347973
+ }
347974
+ try {
347975
+ unlinkSync3(nativeCwdFilePath);
347976
+ } catch {}
347977
+ });
347978
+ return retryCmd;
347979
+ } catch (retryError) {
347980
+ getBashSpawnSemaphore().release();
347981
+ if (!isGitBashPtyExhaustion(retryError)) {
347982
+ logForDebugging(`Git Bash retry ${retry} failed with non-pty error: ${errorMessage(retryError)}`);
347983
+ break;
347984
+ }
347985
+ if (retry === MAX_GITBASH_RETRIES) {
347986
+ logForDebugging(`Git Bash all ${MAX_GITBASH_RETRIES} retries exhausted, giving up`);
347987
+ }
347988
+ }
347989
+ }
347990
+ } else {
347991
+ if (isGitBash) {
347992
+ getBashSpawnSemaphore().release();
347993
+ }
347899
347994
  }
347900
347995
  if (outputHandle !== undefined) {
347901
347996
  try {
@@ -405882,27 +405977,17 @@ function Feedback({
405882
405977
  rawTranscriptJsonl
405883
405978
  }
405884
405979
  };
405885
- const [result, t] = await Promise.all([submitFeedback(reportData, abortSignal), generateTitle(description, abortSignal)]);
405886
- setTitle(t);
405887
- if (result.success) {
405888
- if (result.feedbackId) {
405889
- setFeedbackId(result.feedbackId);
405890
- logEvent("tengu_bug_report_submitted", {
405891
- feedback_id: result.feedbackId,
405892
- last_assistant_message_id: lastAssistantMessageId
405893
- });
405894
- logEventTo1P("tengu_bug_report_description", {
405895
- feedback_id: result.feedbackId,
405896
- description: redactSensitiveInfo(description)
405897
- });
405898
- }
405980
+ const generatedTitle = await generateTitle(description, abortSignal).catch(() => createFallbackTitle(description));
405981
+ setTitle(generatedTitle);
405982
+ const fallbackId = `myclaude-${Date.now()}`;
405983
+ const url3 = createGitHubIssueUrl(fallbackId, generatedTitle, description, sanitizedErrors);
405984
+ try {
405985
+ await openBrowser(url3);
405986
+ setFeedbackId(fallbackId);
405899
405987
  setStep("done");
405900
- } else {
405901
- if (result.isZdrOrg) {
405902
- setError("Feedback collection is not available for organizations with custom data retention policies.");
405903
- } else {
405904
- setError("Could not submit feedback. Please try again later.");
405905
- }
405988
+ } catch {
405989
+ setError(`Could not open browser. Please manually create an issue at:
405990
+ ${url3}`);
405906
405991
  setStep("userInput");
405907
405992
  }
405908
405993
  }, [description, envInfo.isGit, messages]);
@@ -406256,101 +406341,19 @@ function createFallbackTitle(description) {
406256
406341
  }
406257
406342
  return truncated.length < 10 ? "Bug Report" : truncated;
406258
406343
  }
406259
- function sanitizeAndLogError(err2) {
406260
- if (err2 instanceof Error) {
406261
- const safeError = new Error(redactSensitiveInfo(err2.message));
406262
- if (err2.stack) {
406263
- safeError.stack = redactSensitiveInfo(err2.stack);
406264
- }
406265
- logError2(safeError);
406266
- } else {
406267
- const errorString = redactSensitiveInfo(String(err2));
406268
- logError2(new Error(errorString));
406269
- }
406270
- }
406271
- async function submitFeedback(data, signal) {
406272
- if (isEssentialTrafficOnly()) {
406273
- return {
406274
- success: false
406275
- };
406276
- }
406277
- try {
406278
- await checkAndRefreshOAuthTokenIfNeeded();
406279
- const authResult = getAuthHeaders();
406280
- if (authResult.error) {
406281
- return {
406282
- success: false
406283
- };
406284
- }
406285
- const headers = {
406286
- "Content-Type": "application/json",
406287
- "User-Agent": getUserAgent(),
406288
- ...authResult.headers
406289
- };
406290
- const response = await axios_default.post("https://api.anthropic.com/api/claude_cli_feedback", {
406291
- content: jsonStringify(data)
406292
- }, {
406293
- headers,
406294
- timeout: 30000,
406295
- signal
406296
- });
406297
- if (response.status === 200) {
406298
- const result = response.data;
406299
- if (result?.feedback_id) {
406300
- return {
406301
- success: true,
406302
- feedbackId: result.feedback_id
406303
- };
406304
- }
406305
- sanitizeAndLogError(new Error("Failed to submit feedback: request did not return feedback_id"));
406306
- return {
406307
- success: false
406308
- };
406309
- }
406310
- sanitizeAndLogError(new Error("Failed to submit feedback:" + response.status));
406311
- return {
406312
- success: false
406313
- };
406314
- } catch (err2) {
406315
- if (axios_default.isCancel(err2)) {
406316
- return {
406317
- success: false
406318
- };
406319
- }
406320
- if (axios_default.isAxiosError(err2) && err2.response?.status === 403) {
406321
- const errorData = err2.response.data;
406322
- if (errorData?.error?.type === "permission_error" && errorData?.error?.message?.includes("Custom data retention settings")) {
406323
- sanitizeAndLogError(new Error("Cannot submit feedback because custom data retention settings are enabled"));
406324
- return {
406325
- success: false,
406326
- isZdrOrg: true
406327
- };
406328
- }
406329
- }
406330
- sanitizeAndLogError(err2);
406331
- return {
406332
- success: false
406333
- };
406334
- }
406335
- }
406336
406344
  var import_react95, jsx_dev_runtime159, GITHUB_URL_LIMIT = 7250, GITHUB_ISSUES_REPO_URL = "https://github.com/thomaslwq/myclaude/issues";
406337
406345
  var init_Feedback = __esm(() => {
406338
- init_axios2();
406339
406346
  init_state();
406340
- init_firstPartyEventLogger();
406341
- init_analytics();
406342
406347
  init_messages3();
406343
406348
  init_useTerminalSize();
406344
406349
  init_ink2();
406345
406350
  init_useKeybinding();
406346
406351
  init_claude();
406347
406352
  init_errors8();
406348
- init_auth();
406349
406353
  init_browser();
406350
406354
  init_debug();
406351
406355
  init_env();
406352
406356
  init_git();
406353
- init_http2();
406354
406357
  init_log3();
406355
406358
  init_sessionStorage();
406356
406359
  init_slowOperations();
@@ -484769,10 +484772,10 @@ import {
484769
484772
  import { tmpdir as tmpdir12 } from "os";
484770
484773
  import { extname as extname14, join as join135 } from "path";
484771
484774
  function getAnalysisModel() {
484772
- return getDefaultOpusModel();
484775
+ return getDefaultSonnetModel();
484773
484776
  }
484774
484777
  function getInsightsModel() {
484775
- return getDefaultOpusModel();
484778
+ return getDefaultSonnetModel();
484776
484779
  }
484777
484780
  function getDataDir() {
484778
484781
  return join135(getClaudeConfigHomeDir(), "usage-data");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnycode/myclaude",
3
- "version": "0.1.22",
3
+ "version": "0.1.25",
4
4
  "private": false,
5
5
  "description": "An open-source AI coding assistant in your terminal - powered by Claude",
6
6
  "license": "MIT",
@@ -8,12 +8,12 @@
8
8
  "packageManager": "bun@1.3.5",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://gitee.com/thomaslwq/myclaude.git"
11
+ "url": "https://github.com/thomaslwq/myclaude.git"
12
12
  },
13
13
  "bugs": {
14
- "url": "https://gitee.com/thomaslwq/myclaude/issues"
14
+ "url": "https://github.com/thomaslwq/myclaude/issues"
15
15
  },
16
- "homepage": "https://gitee.com/thomaslwq/myclaude",
16
+ "homepage": "https://github.com/thomaslwq/myclaude",
17
17
  "engines": {
18
18
  "bun": ">=1.3.5",
19
19
  "node": ">=18.0.0"