@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 +10 -0
- package/README.md +6 -6
- package/README.zh-CN.md +5 -6
- package/dist/myclaude.js +119 -116
- package/dist/myclaude.mjs +119 -116
- package/package.json +4 -4
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://
|
|
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.
|
|
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.
|
|
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://
|
|
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.
|
|
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.
|
|
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.
|
|
8
|
-
BUILD_TIME: "2026-06-
|
|
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://
|
|
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://
|
|
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
|
-
|
|
347546
|
-
|
|
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 [
|
|
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" ?
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
405886
|
-
setTitle(
|
|
405887
|
-
|
|
405888
|
-
|
|
405889
|
-
|
|
405890
|
-
|
|
405891
|
-
|
|
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
|
-
}
|
|
405901
|
-
|
|
405902
|
-
|
|
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
|
|
484775
|
+
return getDefaultSonnetModel();
|
|
484773
484776
|
}
|
|
484774
484777
|
function getInsightsModel() {
|
|
484775
|
-
return
|
|
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.
|
|
8
|
-
BUILD_TIME: "2026-06-
|
|
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://
|
|
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://
|
|
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
|
-
|
|
347546
|
-
|
|
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 [
|
|
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" ?
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
405886
|
-
setTitle(
|
|
405887
|
-
|
|
405888
|
-
|
|
405889
|
-
|
|
405890
|
-
|
|
405891
|
-
|
|
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
|
-
}
|
|
405901
|
-
|
|
405902
|
-
|
|
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
|
|
484775
|
+
return getDefaultSonnetModel();
|
|
484773
484776
|
}
|
|
484774
484777
|
function getInsightsModel() {
|
|
484775
|
-
return
|
|
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.
|
|
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://
|
|
11
|
+
"url": "https://github.com/thomaslwq/myclaude.git"
|
|
12
12
|
},
|
|
13
13
|
"bugs": {
|
|
14
|
-
"url": "https://
|
|
14
|
+
"url": "https://github.com/thomaslwq/myclaude/issues"
|
|
15
15
|
},
|
|
16
|
-
"homepage": "https://
|
|
16
|
+
"homepage": "https://github.com/thomaslwq/myclaude",
|
|
17
17
|
"engines": {
|
|
18
18
|
"bun": ">=1.3.5",
|
|
19
19
|
"node": ">=18.0.0"
|