@funnycode/myclaude 0.1.276 → 0.1.285

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.
Files changed (3) hide show
  1. package/dist/myclaude.js +205 -35
  2. package/dist/myclaude.mjs +205 -35
  3. package/package.json +131 -131
package/dist/myclaude.js CHANGED
@@ -4,8 +4,8 @@
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.276",
8
- BUILD_TIME: "2026-08-18T07:55:40.831Z",
7
+ VERSION: "0.1.285",
8
+ BUILD_TIME: "2026-08-21T08:33:09.704Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
@@ -120027,7 +120027,7 @@ var package_default;
120027
120027
  var init_package = __esm(() => {
120028
120028
  package_default = {
120029
120029
  name: "@funnycode/myclaude",
120030
- version: "0.1.276",
120030
+ version: "0.1.285",
120031
120031
  private: false,
120032
120032
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
120033
120033
  license: "MIT",
@@ -282574,18 +282574,20 @@ __export(exports_sessionIdCompat, {
282574
282574
  resetCseShimGateForTesting: () => resetCseShimGateForTesting,
282575
282575
  getCseShimGate: () => getCseShimGate
282576
282576
  });
282577
- function setCseShimGate(gate) {
282578
- if (_gateLocked)
282579
- return;
282580
- _gateLocked = true;
282581
- _isCseShimEnabled = gate;
282577
+ async function setCseShimGate(gate) {
282578
+ await _gateMutex.runExclusive(() => {
282579
+ if (_isCseShimEnabled === undefined) {
282580
+ _isCseShimEnabled = gate;
282581
+ }
282582
+ });
282582
282583
  }
282583
282584
  function getCseShimGate() {
282584
282585
  return _isCseShimEnabled;
282585
282586
  }
282586
- function resetCseShimGateForTesting() {
282587
- _isCseShimEnabled = undefined;
282588
- _gateLocked = false;
282587
+ async function resetCseShimGateForTesting() {
282588
+ await _gateMutex.runExclusive(() => {
282589
+ _isCseShimEnabled = undefined;
282590
+ });
282589
282591
  }
282590
282592
  function toCompatSessionId(id) {
282591
282593
  if (!id.startsWith("cse_"))
@@ -282601,7 +282603,11 @@ function toInfraSessionId(id) {
282601
282603
  return id;
282602
282604
  return "cse_" + id.slice("session_".length);
282603
282605
  }
282604
- var _isCseShimEnabled, _gateLocked = false;
282606
+ var _isCseShimEnabled, _gateMutex;
282607
+ var init_sessionIdCompat = __esm(() => {
282608
+ init_async_mutex();
282609
+ _gateMutex = new Mutex;
282610
+ });
282605
282611
 
282606
282612
  // src/constants/product.ts
282607
282613
  function isRemoteSessionStaging(sessionId, ingressUrl) {
@@ -282620,7 +282626,7 @@ function getClaudeAiBaseUrl(sessionId, ingressUrl) {
282620
282626
  return CLAUDE_AI_BASE_URL;
282621
282627
  }
282622
282628
  function getRemoteSessionUrl(sessionId, ingressUrl) {
282623
- const { toCompatSessionId: toCompatSessionId2 } = __toCommonJS(exports_sessionIdCompat);
282629
+ const { toCompatSessionId: toCompatSessionId2 } = (init_sessionIdCompat(), __toCommonJS(exports_sessionIdCompat));
282624
282630
  const compatId = toCompatSessionId2(sessionId);
282625
282631
  const baseUrl = getClaudeAiBaseUrl(compatId, ingressUrl);
282626
282632
  return `${baseUrl}/code/${compatId}`;
@@ -387583,6 +387589,7 @@ var init_concurrentSessions = __esm(() => {
387583
387589
  // src/bridge/replBridgeHandle.ts
387584
387590
  var init_replBridgeHandle = __esm(() => {
387585
387591
  init_concurrentSessions();
387592
+ init_sessionIdCompat();
387586
387593
  });
387587
387594
 
387588
387595
  // src/tasks/LocalMainSessionTask.ts
@@ -464039,6 +464046,7 @@ var init_createSession = __esm(() => {
464039
464046
  init_debug();
464040
464047
  init_errors();
464041
464048
  init_debugUtils();
464049
+ init_sessionIdCompat();
464042
464050
  });
464043
464051
 
464044
464052
  // src/commands/rename/rename.ts
@@ -480190,34 +480198,84 @@ function sanitizeCommand(command6) {
480190
480198
  for (const node of parsed) {
480191
480199
  if (typeof node === "string") {
480192
480200
  if (/[`$<>|;&\\\n\r]/.test(node)) {
480193
- throw new Error(`Invalid command: shell metacharacter in token "${node}" is not allowed: "${command6}"`);
480201
+ throw new Error("Invalid command: shell metacharacter in token is not allowed (input omitted for security)");
480194
480202
  }
480195
480203
  argv.push(node);
480196
480204
  continue;
480197
480205
  }
480198
480206
  if (node && typeof node === "object") {
480199
480207
  const kind = node.op || node.pattern || "shell metacharacter";
480200
- throw new Error(`Invalid command: shell metacharacter/operator (${kind}) is not allowed: "${command6}"`);
480208
+ throw new Error(`Invalid command: shell metacharacter/operator (${kind}) is not allowed (input omitted for security)`);
480201
480209
  }
480202
- throw new Error(`Invalid command: unexpected token in command: "${command6}"`);
480210
+ throw new Error("Invalid command: unexpected token in command (input omitted for security)");
480203
480211
  }
480204
480212
  if (argv.length === 0) {
480205
480213
  throw new Error("Invalid command: no program specified");
480206
480214
  }
480207
480215
  const program = argv[0];
480208
480216
  if (!ALLOWED_COMMANDS.has(program)) {
480209
- throw new Error(`Invalid command: program "${program}" is not on the allowlist of permitted commands`);
480217
+ throw new Error("Invalid command: program is not on the allowlist of permitted commands (input omitted for security)");
480210
480218
  }
480211
480219
  return argv;
480212
480220
  }
480213
- async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFail, onComplete) {
480221
+ function escapeCodeSpan(text2) {
480222
+ const maxRun = (text2.match(/`+/g) || []).reduce((m2, s) => Math.max(m2, s.length), 0);
480223
+ const delim = "`".repeat(maxRun + 1);
480224
+ const pad = text2.startsWith("`") || text2.endsWith("`") ? " " : "";
480225
+ return `${delim}${pad}${text2}${pad}${delim}`;
480226
+ }
480227
+ function escapeMarkdown(text2) {
480228
+ return text2.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\*/g, "\\*").replace(/_/g, "\\_").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/#/g, "\\#").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/!/g, "\\!").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
480229
+ }
480230
+ function generateDiffPreview(flow) {
480231
+ const lines2 = [];
480232
+ lines2.push(`## Diff Preview: ${escapeMarkdown(flow.name)}`);
480233
+ lines2.push(``);
480234
+ lines2.push(`**Description**: ${escapeMarkdown(flow.description)}`);
480235
+ lines2.push(``);
480236
+ lines2.push(`**Steps (${flow.steps.length}):**`);
480237
+ lines2.push(``);
480238
+ for (let i3 = 0;i3 < flow.steps.length; i3++) {
480239
+ const step = flow.steps[i3];
480240
+ lines2.push(`### Step ${i3 + 1}: ${escapeMarkdown(step.description)}`);
480241
+ if (step.reasoning) {
480242
+ lines2.push(`- **Reasoning**: ${escapeMarkdown(step.reasoning)}`);
480243
+ }
480244
+ if (step.command) {
480245
+ lines2.push(`- **Command**: ${escapeCodeSpan(step.command)}`);
480246
+ }
480247
+ if (step.files && step.files.length > 0) {
480248
+ lines2.push(`- **Files**: ${step.files.map((f2) => escapeCodeSpan(f2)).join(", ")}`);
480249
+ }
480250
+ lines2.push(``);
480251
+ }
480252
+ lines2.push(`---`);
480253
+ lines2.push(`Review the above changes carefully before approving.`);
480254
+ return lines2.join(`
480255
+ `);
480256
+ }
480257
+ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFail, onComplete, options) {
480258
+ const ids = flow.steps.map((s) => s.id);
480259
+ if (new Set(ids).size !== ids.length) {
480260
+ throw new Error("Flow definition contains duplicate step IDs");
480261
+ }
480214
480262
  const state = {
480215
480263
  currentStepIndex: 0,
480216
480264
  completedSteps: [],
480217
480265
  failedSteps: [],
480218
480266
  totalSteps: flow.steps.length,
480219
- startTime: Date.now()
480220
- };
480267
+ startTime: Date.now(),
480268
+ aborted: false
480269
+ };
480270
+ const callbackErrors = [];
480271
+ if (options?.preview && options?.onPreview) {
480272
+ const preview = generateDiffPreview(flow);
480273
+ const approved = await options.onPreview(preview);
480274
+ if (!approved) {
480275
+ state.aborted = true;
480276
+ return state;
480277
+ }
480278
+ }
480221
480279
  for (let i3 = 0;i3 < flow.steps.length; i3++) {
480222
480280
  const step = flow.steps[i3];
480223
480281
  state.currentStepIndex = i3;
@@ -480239,6 +480297,7 @@ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFa
480239
480297
  await onStepComplete(step, state);
480240
480298
  } catch (callbackError) {
480241
480299
  console.error(`onStepComplete callback failed for step "${step.id}":`, callbackError);
480300
+ callbackErrors.push(callbackError);
480242
480301
  }
480243
480302
  }
480244
480303
  } catch (error52) {
@@ -480248,10 +480307,12 @@ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFa
480248
480307
  await onStepFail(step, state, error52);
480249
480308
  } catch (callbackError) {
480250
480309
  console.error(`onStepFail callback failed for step "${step.id}":`, callbackError);
480310
+ callbackErrors.push(callbackError);
480251
480311
  }
480252
480312
  }
480253
480313
  const shouldContinue = await shouldContinueOnError(error52, step);
480254
480314
  if (!shouldContinue) {
480315
+ state.aborted = true;
480255
480316
  break;
480256
480317
  }
480257
480318
  }
@@ -480261,7 +480322,14 @@ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFa
480261
480322
  await onComplete(state);
480262
480323
  } catch (callbackError) {
480263
480324
  console.error("onComplete callback failed:", callbackError);
480325
+ callbackErrors.push(callbackError);
480326
+ }
480327
+ }
480328
+ if (callbackErrors.length > 0) {
480329
+ if (callbackErrors.length === 1) {
480330
+ throw callbackErrors[0];
480264
480331
  }
480332
+ throw new AggregateError(callbackErrors, "Multiple callback errors occurred during flow execution");
480265
480333
  }
480266
480334
  return state;
480267
480335
  }
@@ -480271,26 +480339,51 @@ async function executeCommand(command6, context2) {
480271
480339
  await context2.bridge.runCommand(argv);
480272
480340
  return;
480273
480341
  }
480274
- throw new Error("No bridge.runCommand available to execute: " + command6);
480342
+ throw new Error("No bridge.runCommand available to execute command (input omitted for security)");
480275
480343
  }
480276
480344
  async function executeFileOperation(file2, context2) {
480345
+ if (typeof file2 !== "string") {
480346
+ throw new Error("Invalid file path: must be a string");
480347
+ }
480348
+ if (file2.includes("\x00")) {
480349
+ throw new Error("Invalid file path: NUL byte detected");
480350
+ }
480351
+ const normalized = file2.replace(/\\/g, "/");
480352
+ if (normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized)) {
480353
+ throw new Error("Invalid file path: absolute paths are not allowed");
480354
+ }
480355
+ const parts = normalized.split("/");
480356
+ for (const part of parts) {
480357
+ if (part === "..") {
480358
+ throw new Error("Invalid file path: path traversal (..) is not allowed");
480359
+ }
480360
+ }
480277
480361
  if (context2?.bridge?.editFile) {
480278
480362
  await context2.bridge.editFile(file2);
480279
480363
  return;
480280
480364
  }
480281
- throw new Error("No bridge.editFile available to edit: " + file2);
480365
+ throw new Error("No bridge.editFile available to edit file (input omitted for security)");
480282
480366
  }
480283
480367
  async function shouldContinueOnError(error52, step) {
480284
- const transientCodes = ["ETIMEDOUT"];
480368
+ const transientCodes = [
480369
+ "ETIMEDOUT",
480370
+ "ECONNRESET",
480371
+ "ENETUNREACH",
480372
+ "EPIPE",
480373
+ "EAI_AGAIN",
480374
+ "ENOTFOUND",
480375
+ "ECONNREFUSED"
480376
+ ];
480285
480377
  const err2 = error52;
480286
- if (err2.code && transientCodes.includes(err2.code)) {
480378
+ const codeFromProps = typeof err2.code === "string" ? err2.code : typeof err2.errno === "string" ? err2.errno : null;
480379
+ if (codeFromProps && transientCodes.includes(codeFromProps)) {
480287
480380
  return true;
480288
480381
  }
480289
- if (transientCodes.some((code) => error52.message.includes(code))) {
480382
+ if (transientCodes.some((code) => new RegExp(`(^|:\\s*)${code}\\b`).test(error52.message))) {
480290
480383
  return true;
480291
480384
  }
480292
- if (error52.message.includes("No bridge")) {
480293
- return true;
480385
+ if (/^No bridge\.(runCommand|editFile) available/.test(error52.message)) {
480386
+ return false;
480294
480387
  }
480295
480388
  return false;
480296
480389
  }
@@ -480298,18 +480391,11 @@ var import_shell_quote4, ALLOWED_COMMANDS;
480298
480391
  var init_executor = __esm(() => {
480299
480392
  import_shell_quote4 = __toESM(require_shell_quote(), 1);
480300
480393
  ALLOWED_COMMANDS = new Set([
480301
- "npm",
480302
- "npx",
480303
- "node",
480304
- "bun",
480305
- "yarn",
480306
- "pnpm",
480307
480394
  "mkdir",
480308
480395
  "touch",
480309
480396
  "cp",
480310
480397
  "mv",
480311
480398
  "echo",
480312
- "git",
480313
480399
  "tsc",
480314
480400
  "vitest"
480315
480401
  ]);
@@ -480395,6 +480481,22 @@ var init_flow = __esm(() => {
480395
480481
  if (!flow) {
480396
480482
  throw new Error(`Flow not found: ${args}`);
480397
480483
  }
480484
+ if (context2?.preview !== false) {
480485
+ const preview = generateDiffPreview(flow);
480486
+ console.log(preview);
480487
+ const approved = context2?.onPreview ? await context2.onPreview(preview) : true;
480488
+ if (!approved) {
480489
+ console.log("Flow execution aborted by user.");
480490
+ return {
480491
+ currentStepIndex: 0,
480492
+ completedSteps: [],
480493
+ failedSteps: [],
480494
+ totalSteps: flow.steps.length,
480495
+ startTime: Date.now(),
480496
+ aborted: true
480497
+ };
480498
+ }
480499
+ }
480398
480500
  const state = await executeFlow(flow, context2, async (step, state2) => {
480399
480501
  console.log(`
480400
480502
  ▶️ Starting step ${state2.currentStepIndex + 1}/${state2.totalSteps}: ${step.description}`);
@@ -497326,6 +497428,69 @@ Wait for user confirmation before executing the first step.
497326
497428
  agent_default = agent;
497327
497429
  });
497328
497430
 
497431
+ // src/commands/composer.ts
497432
+ function getComposerPrompt(args) {
497433
+ const featureDesc = args.trim() || "(no description provided)";
497434
+ return `You are in **Composer Mode** — a multi-file editing workflow inspired by Cursor's Composer.
497435
+
497436
+ ## User's Request
497437
+
497438
+ ${featureDesc}
497439
+
497440
+ ## Your Task
497441
+
497442
+ You will implement this feature across multiple files in a single turn. Follow this workflow:
497443
+
497444
+ ### 1. Analyze & Plan
497445
+ - Understand the feature request and identify all files that need to be created or modified
497446
+ - Create a plan listing every file that will be touched, with a brief description of changes for each
497447
+ - Consider dependencies between files (imports, types, shared utilities)
497448
+ - Identify test files that need to be created or updated
497449
+
497450
+ ### 2. Execute Multi-File Edits
497451
+ - Edit all necessary files to implement the feature
497452
+ - Work through files in dependency order (shared types/utils first, then consumers)
497453
+ - Ensure imports and exports are consistent across all files
497454
+ - Keep changes focused — only modify what's needed for this feature
497455
+
497456
+ ### 3. Verify
497457
+ - Run the test suite to verify the implementation works
497458
+ - Run the build to ensure no type or compile errors
497459
+ - If tests fail, fix the issues and re-verify
497460
+
497461
+ ## Multi-File Editing Guidelines
497462
+
497463
+ - **Coordinate changes**: When editing a shared type or utility, update all consumers in the same turn
497464
+ - **Consistent naming**: Follow existing project conventions for file names, exports, and patterns
497465
+ - **Minimal diffs**: Make surgical edits — avoid rewriting entire files when small changes suffice
497466
+ - **Test coverage**: Add or update tests for all new functionality
497467
+ - **Error handling**: Add appropriate error handling for new code paths
497468
+
497469
+ ## Important Rules
497470
+
497471
+ - Edit all files needed to complete the feature in a single turn
497472
+ - Do not ask for confirmation between file edits — proceed autonomously
497473
+ - After all edits are complete, run tests and build to verify
497474
+ - If verification fails, fix issues and re-run until green
497475
+ - Report a summary of all files changed at the end`;
497476
+ }
497477
+ var composer, composer_default;
497478
+ var init_composer = __esm(() => {
497479
+ composer = {
497480
+ type: "prompt",
497481
+ name: "composer",
497482
+ description: "Composer mode — edit multiple files simultaneously to implement a feature across the codebase",
497483
+ argumentHint: "<feature description>",
497484
+ progressMessage: "composer mode executing",
497485
+ contentLength: 0,
497486
+ source: "builtin",
497487
+ async getPromptForCommand(args) {
497488
+ return [{ type: "text", text: getComposerPrompt(args) }];
497489
+ }
497490
+ };
497491
+ composer_default = composer;
497492
+ });
497493
+
497329
497494
  // src/commands/remember.ts
497330
497495
  import { appendFile as appendFile5, mkdir as mkdir36 } from "fs/promises";
497331
497496
  import { join as join133 } from "path";
@@ -506039,6 +506204,7 @@ var init_commands2 = __esm(() => {
506039
506204
  init_frontend_tdd();
506040
506205
  init_agentic_tdd();
506041
506206
  init_agent2();
506207
+ init_composer();
506042
506208
  init_remember();
506043
506209
  init_log3();
506044
506210
  init_errors();
@@ -506172,6 +506338,7 @@ var init_commands2 = __esm(() => {
506172
506338
  frontend_tdd_default,
506173
506339
  agentic_tdd_default,
506174
506340
  agent_default,
506341
+ composer_default,
506175
506342
  tag_default,
506176
506343
  theme_default,
506177
506344
  feedback_default,
@@ -582136,6 +582303,7 @@ var init_replBridge = __esm(() => {
582136
582303
  init_cleanupRegistry();
582137
582304
  init_bridgeMessaging();
582138
582305
  init_workSecret();
582306
+ init_sessionIdCompat();
582139
582307
  init_concurrentSessions();
582140
582308
  init_trustedDevice();
582141
582309
  init_HybridTransport();
@@ -582716,6 +582884,7 @@ var init_remoteBridgeCore = __esm(() => {
582716
582884
  init_axios2();
582717
582885
  init_replBridgeTransport();
582718
582886
  init_workSecret();
582887
+ init_sessionIdCompat();
582719
582888
  init_jwtUtils();
582720
582889
  init_trustedDevice();
582721
582890
  init_envLessBridgeConfig();
@@ -582755,7 +582924,7 @@ async function initReplBridge(options) {
582755
582924
  outboundOnly,
582756
582925
  tags
582757
582926
  } = options ?? {};
582758
- setCseShimGate(isCseShimEnabled);
582927
+ await setCseShimGate(isCseShimEnabled);
582759
582928
  const [
582760
582929
  { getFeatureValue_CACHED_WITH_REFRESH: getFeatureValue_CACHED_WITH_REFRESH4 },
582761
582930
  { getOrganizationUUID: getOrganizationUUID2 },
@@ -583006,6 +583175,7 @@ var init_initReplBridge = __esm(() => {
583006
583175
  init_envLessBridgeConfig();
583007
583176
  init_pollConfig();
583008
583177
  init_replBridge();
583178
+ init_sessionIdCompat();
583009
583179
  });
583010
583180
 
583011
583181
  // src/cli/print.ts
package/dist/myclaude.mjs CHANGED
@@ -4,8 +4,8 @@
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.276",
8
- BUILD_TIME: "2026-08-18T07:55:40.831Z",
7
+ VERSION: "0.1.285",
8
+ BUILD_TIME: "2026-08-21T08:33:09.704Z",
9
9
  PACKAGE_URL: "@funnycode/myclaude",
10
10
  NATIVE_PACKAGE_URL: "@funnycode/myclaude",
11
11
  VERSION_CHANGELOG: '',
@@ -120027,7 +120027,7 @@ var package_default;
120027
120027
  var init_package = __esm(() => {
120028
120028
  package_default = {
120029
120029
  name: "@funnycode/myclaude",
120030
- version: "0.1.276",
120030
+ version: "0.1.285",
120031
120031
  private: false,
120032
120032
  description: "An open-source AI coding assistant in your terminal - powered by Claude",
120033
120033
  license: "MIT",
@@ -282574,18 +282574,20 @@ __export(exports_sessionIdCompat, {
282574
282574
  resetCseShimGateForTesting: () => resetCseShimGateForTesting,
282575
282575
  getCseShimGate: () => getCseShimGate
282576
282576
  });
282577
- function setCseShimGate(gate) {
282578
- if (_gateLocked)
282579
- return;
282580
- _gateLocked = true;
282581
- _isCseShimEnabled = gate;
282577
+ async function setCseShimGate(gate) {
282578
+ await _gateMutex.runExclusive(() => {
282579
+ if (_isCseShimEnabled === undefined) {
282580
+ _isCseShimEnabled = gate;
282581
+ }
282582
+ });
282582
282583
  }
282583
282584
  function getCseShimGate() {
282584
282585
  return _isCseShimEnabled;
282585
282586
  }
282586
- function resetCseShimGateForTesting() {
282587
- _isCseShimEnabled = undefined;
282588
- _gateLocked = false;
282587
+ async function resetCseShimGateForTesting() {
282588
+ await _gateMutex.runExclusive(() => {
282589
+ _isCseShimEnabled = undefined;
282590
+ });
282589
282591
  }
282590
282592
  function toCompatSessionId(id) {
282591
282593
  if (!id.startsWith("cse_"))
@@ -282601,7 +282603,11 @@ function toInfraSessionId(id) {
282601
282603
  return id;
282602
282604
  return "cse_" + id.slice("session_".length);
282603
282605
  }
282604
- var _isCseShimEnabled, _gateLocked = false;
282606
+ var _isCseShimEnabled, _gateMutex;
282607
+ var init_sessionIdCompat = __esm(() => {
282608
+ init_async_mutex();
282609
+ _gateMutex = new Mutex;
282610
+ });
282605
282611
 
282606
282612
  // src/constants/product.ts
282607
282613
  function isRemoteSessionStaging(sessionId, ingressUrl) {
@@ -282620,7 +282626,7 @@ function getClaudeAiBaseUrl(sessionId, ingressUrl) {
282620
282626
  return CLAUDE_AI_BASE_URL;
282621
282627
  }
282622
282628
  function getRemoteSessionUrl(sessionId, ingressUrl) {
282623
- const { toCompatSessionId: toCompatSessionId2 } = __toCommonJS(exports_sessionIdCompat);
282629
+ const { toCompatSessionId: toCompatSessionId2 } = (init_sessionIdCompat(), __toCommonJS(exports_sessionIdCompat));
282624
282630
  const compatId = toCompatSessionId2(sessionId);
282625
282631
  const baseUrl = getClaudeAiBaseUrl(compatId, ingressUrl);
282626
282632
  return `${baseUrl}/code/${compatId}`;
@@ -387583,6 +387589,7 @@ var init_concurrentSessions = __esm(() => {
387583
387589
  // src/bridge/replBridgeHandle.ts
387584
387590
  var init_replBridgeHandle = __esm(() => {
387585
387591
  init_concurrentSessions();
387592
+ init_sessionIdCompat();
387586
387593
  });
387587
387594
 
387588
387595
  // src/tasks/LocalMainSessionTask.ts
@@ -464039,6 +464046,7 @@ var init_createSession = __esm(() => {
464039
464046
  init_debug();
464040
464047
  init_errors();
464041
464048
  init_debugUtils();
464049
+ init_sessionIdCompat();
464042
464050
  });
464043
464051
 
464044
464052
  // src/commands/rename/rename.ts
@@ -480190,34 +480198,84 @@ function sanitizeCommand(command6) {
480190
480198
  for (const node of parsed) {
480191
480199
  if (typeof node === "string") {
480192
480200
  if (/[`$<>|;&\\\n\r]/.test(node)) {
480193
- throw new Error(`Invalid command: shell metacharacter in token "${node}" is not allowed: "${command6}"`);
480201
+ throw new Error("Invalid command: shell metacharacter in token is not allowed (input omitted for security)");
480194
480202
  }
480195
480203
  argv.push(node);
480196
480204
  continue;
480197
480205
  }
480198
480206
  if (node && typeof node === "object") {
480199
480207
  const kind = node.op || node.pattern || "shell metacharacter";
480200
- throw new Error(`Invalid command: shell metacharacter/operator (${kind}) is not allowed: "${command6}"`);
480208
+ throw new Error(`Invalid command: shell metacharacter/operator (${kind}) is not allowed (input omitted for security)`);
480201
480209
  }
480202
- throw new Error(`Invalid command: unexpected token in command: "${command6}"`);
480210
+ throw new Error("Invalid command: unexpected token in command (input omitted for security)");
480203
480211
  }
480204
480212
  if (argv.length === 0) {
480205
480213
  throw new Error("Invalid command: no program specified");
480206
480214
  }
480207
480215
  const program = argv[0];
480208
480216
  if (!ALLOWED_COMMANDS.has(program)) {
480209
- throw new Error(`Invalid command: program "${program}" is not on the allowlist of permitted commands`);
480217
+ throw new Error("Invalid command: program is not on the allowlist of permitted commands (input omitted for security)");
480210
480218
  }
480211
480219
  return argv;
480212
480220
  }
480213
- async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFail, onComplete) {
480221
+ function escapeCodeSpan(text2) {
480222
+ const maxRun = (text2.match(/`+/g) || []).reduce((m2, s) => Math.max(m2, s.length), 0);
480223
+ const delim = "`".repeat(maxRun + 1);
480224
+ const pad = text2.startsWith("`") || text2.endsWith("`") ? " " : "";
480225
+ return `${delim}${pad}${text2}${pad}${delim}`;
480226
+ }
480227
+ function escapeMarkdown(text2) {
480228
+ return text2.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\*/g, "\\*").replace(/_/g, "\\_").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/#/g, "\\#").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/!/g, "\\!").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
480229
+ }
480230
+ function generateDiffPreview(flow) {
480231
+ const lines2 = [];
480232
+ lines2.push(`## Diff Preview: ${escapeMarkdown(flow.name)}`);
480233
+ lines2.push(``);
480234
+ lines2.push(`**Description**: ${escapeMarkdown(flow.description)}`);
480235
+ lines2.push(``);
480236
+ lines2.push(`**Steps (${flow.steps.length}):**`);
480237
+ lines2.push(``);
480238
+ for (let i3 = 0;i3 < flow.steps.length; i3++) {
480239
+ const step = flow.steps[i3];
480240
+ lines2.push(`### Step ${i3 + 1}: ${escapeMarkdown(step.description)}`);
480241
+ if (step.reasoning) {
480242
+ lines2.push(`- **Reasoning**: ${escapeMarkdown(step.reasoning)}`);
480243
+ }
480244
+ if (step.command) {
480245
+ lines2.push(`- **Command**: ${escapeCodeSpan(step.command)}`);
480246
+ }
480247
+ if (step.files && step.files.length > 0) {
480248
+ lines2.push(`- **Files**: ${step.files.map((f2) => escapeCodeSpan(f2)).join(", ")}`);
480249
+ }
480250
+ lines2.push(``);
480251
+ }
480252
+ lines2.push(`---`);
480253
+ lines2.push(`Review the above changes carefully before approving.`);
480254
+ return lines2.join(`
480255
+ `);
480256
+ }
480257
+ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFail, onComplete, options) {
480258
+ const ids = flow.steps.map((s) => s.id);
480259
+ if (new Set(ids).size !== ids.length) {
480260
+ throw new Error("Flow definition contains duplicate step IDs");
480261
+ }
480214
480262
  const state = {
480215
480263
  currentStepIndex: 0,
480216
480264
  completedSteps: [],
480217
480265
  failedSteps: [],
480218
480266
  totalSteps: flow.steps.length,
480219
- startTime: Date.now()
480220
- };
480267
+ startTime: Date.now(),
480268
+ aborted: false
480269
+ };
480270
+ const callbackErrors = [];
480271
+ if (options?.preview && options?.onPreview) {
480272
+ const preview = generateDiffPreview(flow);
480273
+ const approved = await options.onPreview(preview);
480274
+ if (!approved) {
480275
+ state.aborted = true;
480276
+ return state;
480277
+ }
480278
+ }
480221
480279
  for (let i3 = 0;i3 < flow.steps.length; i3++) {
480222
480280
  const step = flow.steps[i3];
480223
480281
  state.currentStepIndex = i3;
@@ -480239,6 +480297,7 @@ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFa
480239
480297
  await onStepComplete(step, state);
480240
480298
  } catch (callbackError) {
480241
480299
  console.error(`onStepComplete callback failed for step "${step.id}":`, callbackError);
480300
+ callbackErrors.push(callbackError);
480242
480301
  }
480243
480302
  }
480244
480303
  } catch (error52) {
@@ -480248,10 +480307,12 @@ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFa
480248
480307
  await onStepFail(step, state, error52);
480249
480308
  } catch (callbackError) {
480250
480309
  console.error(`onStepFail callback failed for step "${step.id}":`, callbackError);
480310
+ callbackErrors.push(callbackError);
480251
480311
  }
480252
480312
  }
480253
480313
  const shouldContinue = await shouldContinueOnError(error52, step);
480254
480314
  if (!shouldContinue) {
480315
+ state.aborted = true;
480255
480316
  break;
480256
480317
  }
480257
480318
  }
@@ -480261,7 +480322,14 @@ async function executeFlow(flow, context2, onStepStart, onStepComplete, onStepFa
480261
480322
  await onComplete(state);
480262
480323
  } catch (callbackError) {
480263
480324
  console.error("onComplete callback failed:", callbackError);
480325
+ callbackErrors.push(callbackError);
480326
+ }
480327
+ }
480328
+ if (callbackErrors.length > 0) {
480329
+ if (callbackErrors.length === 1) {
480330
+ throw callbackErrors[0];
480264
480331
  }
480332
+ throw new AggregateError(callbackErrors, "Multiple callback errors occurred during flow execution");
480265
480333
  }
480266
480334
  return state;
480267
480335
  }
@@ -480271,26 +480339,51 @@ async function executeCommand(command6, context2) {
480271
480339
  await context2.bridge.runCommand(argv);
480272
480340
  return;
480273
480341
  }
480274
- throw new Error("No bridge.runCommand available to execute: " + command6);
480342
+ throw new Error("No bridge.runCommand available to execute command (input omitted for security)");
480275
480343
  }
480276
480344
  async function executeFileOperation(file2, context2) {
480345
+ if (typeof file2 !== "string") {
480346
+ throw new Error("Invalid file path: must be a string");
480347
+ }
480348
+ if (file2.includes("\x00")) {
480349
+ throw new Error("Invalid file path: NUL byte detected");
480350
+ }
480351
+ const normalized = file2.replace(/\\/g, "/");
480352
+ if (normalized.startsWith("/") || /^[A-Za-z]:\//.test(normalized)) {
480353
+ throw new Error("Invalid file path: absolute paths are not allowed");
480354
+ }
480355
+ const parts = normalized.split("/");
480356
+ for (const part of parts) {
480357
+ if (part === "..") {
480358
+ throw new Error("Invalid file path: path traversal (..) is not allowed");
480359
+ }
480360
+ }
480277
480361
  if (context2?.bridge?.editFile) {
480278
480362
  await context2.bridge.editFile(file2);
480279
480363
  return;
480280
480364
  }
480281
- throw new Error("No bridge.editFile available to edit: " + file2);
480365
+ throw new Error("No bridge.editFile available to edit file (input omitted for security)");
480282
480366
  }
480283
480367
  async function shouldContinueOnError(error52, step) {
480284
- const transientCodes = ["ETIMEDOUT"];
480368
+ const transientCodes = [
480369
+ "ETIMEDOUT",
480370
+ "ECONNRESET",
480371
+ "ENETUNREACH",
480372
+ "EPIPE",
480373
+ "EAI_AGAIN",
480374
+ "ENOTFOUND",
480375
+ "ECONNREFUSED"
480376
+ ];
480285
480377
  const err2 = error52;
480286
- if (err2.code && transientCodes.includes(err2.code)) {
480378
+ const codeFromProps = typeof err2.code === "string" ? err2.code : typeof err2.errno === "string" ? err2.errno : null;
480379
+ if (codeFromProps && transientCodes.includes(codeFromProps)) {
480287
480380
  return true;
480288
480381
  }
480289
- if (transientCodes.some((code) => error52.message.includes(code))) {
480382
+ if (transientCodes.some((code) => new RegExp(`(^|:\\s*)${code}\\b`).test(error52.message))) {
480290
480383
  return true;
480291
480384
  }
480292
- if (error52.message.includes("No bridge")) {
480293
- return true;
480385
+ if (/^No bridge\.(runCommand|editFile) available/.test(error52.message)) {
480386
+ return false;
480294
480387
  }
480295
480388
  return false;
480296
480389
  }
@@ -480298,18 +480391,11 @@ var import_shell_quote4, ALLOWED_COMMANDS;
480298
480391
  var init_executor = __esm(() => {
480299
480392
  import_shell_quote4 = __toESM(require_shell_quote(), 1);
480300
480393
  ALLOWED_COMMANDS = new Set([
480301
- "npm",
480302
- "npx",
480303
- "node",
480304
- "bun",
480305
- "yarn",
480306
- "pnpm",
480307
480394
  "mkdir",
480308
480395
  "touch",
480309
480396
  "cp",
480310
480397
  "mv",
480311
480398
  "echo",
480312
- "git",
480313
480399
  "tsc",
480314
480400
  "vitest"
480315
480401
  ]);
@@ -480395,6 +480481,22 @@ var init_flow = __esm(() => {
480395
480481
  if (!flow) {
480396
480482
  throw new Error(`Flow not found: ${args}`);
480397
480483
  }
480484
+ if (context2?.preview !== false) {
480485
+ const preview = generateDiffPreview(flow);
480486
+ console.log(preview);
480487
+ const approved = context2?.onPreview ? await context2.onPreview(preview) : true;
480488
+ if (!approved) {
480489
+ console.log("Flow execution aborted by user.");
480490
+ return {
480491
+ currentStepIndex: 0,
480492
+ completedSteps: [],
480493
+ failedSteps: [],
480494
+ totalSteps: flow.steps.length,
480495
+ startTime: Date.now(),
480496
+ aborted: true
480497
+ };
480498
+ }
480499
+ }
480398
480500
  const state = await executeFlow(flow, context2, async (step, state2) => {
480399
480501
  console.log(`
480400
480502
  ▶️ Starting step ${state2.currentStepIndex + 1}/${state2.totalSteps}: ${step.description}`);
@@ -497326,6 +497428,69 @@ Wait for user confirmation before executing the first step.
497326
497428
  agent_default = agent;
497327
497429
  });
497328
497430
 
497431
+ // src/commands/composer.ts
497432
+ function getComposerPrompt(args) {
497433
+ const featureDesc = args.trim() || "(no description provided)";
497434
+ return `You are in **Composer Mode** — a multi-file editing workflow inspired by Cursor's Composer.
497435
+
497436
+ ## User's Request
497437
+
497438
+ ${featureDesc}
497439
+
497440
+ ## Your Task
497441
+
497442
+ You will implement this feature across multiple files in a single turn. Follow this workflow:
497443
+
497444
+ ### 1. Analyze & Plan
497445
+ - Understand the feature request and identify all files that need to be created or modified
497446
+ - Create a plan listing every file that will be touched, with a brief description of changes for each
497447
+ - Consider dependencies between files (imports, types, shared utilities)
497448
+ - Identify test files that need to be created or updated
497449
+
497450
+ ### 2. Execute Multi-File Edits
497451
+ - Edit all necessary files to implement the feature
497452
+ - Work through files in dependency order (shared types/utils first, then consumers)
497453
+ - Ensure imports and exports are consistent across all files
497454
+ - Keep changes focused — only modify what's needed for this feature
497455
+
497456
+ ### 3. Verify
497457
+ - Run the test suite to verify the implementation works
497458
+ - Run the build to ensure no type or compile errors
497459
+ - If tests fail, fix the issues and re-verify
497460
+
497461
+ ## Multi-File Editing Guidelines
497462
+
497463
+ - **Coordinate changes**: When editing a shared type or utility, update all consumers in the same turn
497464
+ - **Consistent naming**: Follow existing project conventions for file names, exports, and patterns
497465
+ - **Minimal diffs**: Make surgical edits — avoid rewriting entire files when small changes suffice
497466
+ - **Test coverage**: Add or update tests for all new functionality
497467
+ - **Error handling**: Add appropriate error handling for new code paths
497468
+
497469
+ ## Important Rules
497470
+
497471
+ - Edit all files needed to complete the feature in a single turn
497472
+ - Do not ask for confirmation between file edits — proceed autonomously
497473
+ - After all edits are complete, run tests and build to verify
497474
+ - If verification fails, fix issues and re-run until green
497475
+ - Report a summary of all files changed at the end`;
497476
+ }
497477
+ var composer, composer_default;
497478
+ var init_composer = __esm(() => {
497479
+ composer = {
497480
+ type: "prompt",
497481
+ name: "composer",
497482
+ description: "Composer mode — edit multiple files simultaneously to implement a feature across the codebase",
497483
+ argumentHint: "<feature description>",
497484
+ progressMessage: "composer mode executing",
497485
+ contentLength: 0,
497486
+ source: "builtin",
497487
+ async getPromptForCommand(args) {
497488
+ return [{ type: "text", text: getComposerPrompt(args) }];
497489
+ }
497490
+ };
497491
+ composer_default = composer;
497492
+ });
497493
+
497329
497494
  // src/commands/remember.ts
497330
497495
  import { appendFile as appendFile5, mkdir as mkdir36 } from "fs/promises";
497331
497496
  import { join as join133 } from "path";
@@ -506039,6 +506204,7 @@ var init_commands2 = __esm(() => {
506039
506204
  init_frontend_tdd();
506040
506205
  init_agentic_tdd();
506041
506206
  init_agent2();
506207
+ init_composer();
506042
506208
  init_remember();
506043
506209
  init_log3();
506044
506210
  init_errors();
@@ -506172,6 +506338,7 @@ var init_commands2 = __esm(() => {
506172
506338
  frontend_tdd_default,
506173
506339
  agentic_tdd_default,
506174
506340
  agent_default,
506341
+ composer_default,
506175
506342
  tag_default,
506176
506343
  theme_default,
506177
506344
  feedback_default,
@@ -582136,6 +582303,7 @@ var init_replBridge = __esm(() => {
582136
582303
  init_cleanupRegistry();
582137
582304
  init_bridgeMessaging();
582138
582305
  init_workSecret();
582306
+ init_sessionIdCompat();
582139
582307
  init_concurrentSessions();
582140
582308
  init_trustedDevice();
582141
582309
  init_HybridTransport();
@@ -582716,6 +582884,7 @@ var init_remoteBridgeCore = __esm(() => {
582716
582884
  init_axios2();
582717
582885
  init_replBridgeTransport();
582718
582886
  init_workSecret();
582887
+ init_sessionIdCompat();
582719
582888
  init_jwtUtils();
582720
582889
  init_trustedDevice();
582721
582890
  init_envLessBridgeConfig();
@@ -582755,7 +582924,7 @@ async function initReplBridge(options) {
582755
582924
  outboundOnly,
582756
582925
  tags
582757
582926
  } = options ?? {};
582758
- setCseShimGate(isCseShimEnabled);
582927
+ await setCseShimGate(isCseShimEnabled);
582759
582928
  const [
582760
582929
  { getFeatureValue_CACHED_WITH_REFRESH: getFeatureValue_CACHED_WITH_REFRESH4 },
582761
582930
  { getOrganizationUUID: getOrganizationUUID2 },
@@ -583006,6 +583175,7 @@ var init_initReplBridge = __esm(() => {
583006
583175
  init_envLessBridgeConfig();
583007
583176
  init_pollConfig();
583008
583177
  init_replBridge();
583178
+ init_sessionIdCompat();
583009
583179
  });
583010
583180
 
583011
583181
  // src/cli/print.ts
package/package.json CHANGED
@@ -1,131 +1,131 @@
1
- {
2
- "name": "@funnycode/myclaude",
3
- "version": "0.1.276",
4
- "private": false,
5
- "description": "An open-source AI coding assistant in your terminal - powered by Claude",
6
- "license": "MIT",
7
- "type": "module",
8
- "packageManager": "bun@1.3.5",
9
- "repository": {
10
- "type": "git",
11
- "url": "https://github.com/thomaslwq/myclaude.git"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/thomaslwq/myclaude/issues"
15
- },
16
- "homepage": "https://github.com/thomaslwq/myclaude",
17
- "engines": {
18
- "bun": ">=1.3.5",
19
- "node": ">=18.17.0"
20
- },
21
- "scripts": {
22
- "dev": "bun run ./src/dev-entry.ts",
23
- "start": "bun run ./src/dev-entry.ts",
24
- "test": "bun test",
25
- "test:watch": "bun test --watch",
26
- "test:perf": "bun test src/tests/performance-regression.test.ts",
27
- "build": "bun run ./scripts/build.ts",
28
- "prepublishOnly": "bun run build",
29
- "version": "bun run ./src/dev-entry.ts --version"
30
- },
31
- "bin": {
32
- "myclaude": "bin/myclaude.cjs"
33
- },
34
- "files": [
35
- "dist/",
36
- "seed/",
37
- "bin/",
38
- "LICENSE",
39
- "README.md",
40
- "README.zh-CN.md",
41
- "CHANGELOG.md",
42
- "docs/funnycode.png",
43
- "shims/node-domexception/"
44
- ],
45
- "publishConfig": {
46
- "access": "public"
47
- },
48
- "dependencies": {
49
- "@alcalzone/ansi-tokenize": "0.3.0",
50
- "@anthropic-ai/claude-agent-sdk": "0.3.207",
51
- "@anthropic-ai/mcpb": "2.1.2",
52
- "@anthropic-ai/sandbox-runtime": "0.0.44",
53
- "@anthropic-ai/sdk": "0.111.0",
54
- "@aws-sdk/client-bedrock-runtime": "3.1020.0",
55
- "@commander-js/extra-typings": "14.0.0",
56
- "@growthbook/growthbook": "1.6.5",
57
- "@modelcontextprotocol/sdk": "1.29.0",
58
- "@opentelemetry/api": "1.9.1",
59
- "@opentelemetry/api-logs": "0.221.0",
60
- "@opentelemetry/core": "1.28.0",
61
- "@opentelemetry/resources": "1.28.0",
62
- "@opentelemetry/sdk-logs": "0.52.0",
63
- "@opentelemetry/sdk-metrics": "1.28.0",
64
- "@opentelemetry/sdk-trace-base": "1.28.0",
65
- "@opentelemetry/semantic-conventions": "1.43.0",
66
- "ajv": "8.18.0",
67
- "asciichart": "1.5.25",
68
- "async-mutex": "0.5.0",
69
- "auto-bind": "5.0.1",
70
- "axios": "1.19.0",
71
- "bidi-js": "1.0.3",
72
- "chalk": "5.6.2",
73
- "chokidar": "5.0.0",
74
- "cli-boxes": "4.0.1",
75
- "code-excerpt": "4.0.0",
76
- "diff": "8.0.4",
77
- "emoji-regex": "10.6.0",
78
- "env-paths": "4.0.0",
79
- "execa": "9.6.1",
80
- "figures": "6.1.0",
81
- "fuse.js": "7.1.0",
82
- "get-east-asian-width": "1.5.0",
83
- "google-auth-library": "10.6.2",
84
- "highlight.js": "11.11.1",
85
- "https-proxy-agent": "8.0.0",
86
- "ignore": "7.0.5",
87
- "indent-string": "5.0.0",
88
- "ink": "6.8.0",
89
- "jsonc-parser": "3.3.1",
90
- "lodash-es": "4.17.23",
91
- "lru-cache": "11.5.2",
92
- "marked": "18.0.9",
93
- "p-map": "7.0.4",
94
- "picomatch": "4.0.4",
95
- "proper-lockfile": "4.1.2",
96
- "qrcode": "1.5.4",
97
- "react": "19.2.8",
98
- "react-reconciler": "0.33.0",
99
- "semver": "7.8.5",
100
- "shell-quote": "1.8.3",
101
- "signal-exit": "4.1.0",
102
- "stack-utils": "2.0.6",
103
- "strip-ansi": "7.2.0",
104
- "supports-hyperlinks": "4.4.0",
105
- "tree-kill": "1.2.2",
106
- "type-fest": "5.5.0",
107
- "undici": "7.24.6",
108
- "usehooks-ts": "3.1.1",
109
- "vscode-jsonrpc": "8.2.1",
110
- "vscode-languageserver-protocol": "3.17.5",
111
- "vscode-languageserver-types": "3.17.5",
112
- "wrap-ansi": "10.0.0",
113
- "ws": "8.20.0",
114
- "xss": "1.0.15",
115
- "yaml": "2.8.3",
116
- "zod": "4.4.3"
117
- },
118
- "optionalDependencies": {
119
- "@ant/claude-for-chrome-mcp": "file:./shims/ant-claude-for-chrome-mcp",
120
- "@ant/computer-use-input": "file:./shims/ant-computer-use-input",
121
- "@ant/computer-use-mcp": "file:./shims/ant-computer-use-mcp",
122
- "@ant/computer-use-swift": "file:./shims/ant-computer-use-swift",
123
- "color-diff-napi": "file:./shims/color-diff-napi",
124
- "modifiers-napi": "file:./shims/modifiers-napi",
125
- "node-domexception": "file:./shims/node-domexception",
126
- "url-handler-napi": "file:./shims/url-handler-napi"
127
- },
128
- "overrides": {
129
- "node-domexception": "file:./shims/node-domexception"
130
- }
131
- }
1
+ {
2
+ "name": "@funnycode/myclaude",
3
+ "version": "0.1.285",
4
+ "private": false,
5
+ "description": "An open-source AI coding assistant in your terminal - powered by Claude",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "packageManager": "bun@1.3.5",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/thomaslwq/myclaude.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/thomaslwq/myclaude/issues"
15
+ },
16
+ "homepage": "https://github.com/thomaslwq/myclaude",
17
+ "engines": {
18
+ "bun": ">=1.3.5",
19
+ "node": ">=18.17.0"
20
+ },
21
+ "scripts": {
22
+ "dev": "bun run ./src/dev-entry.ts",
23
+ "start": "bun run ./src/dev-entry.ts",
24
+ "test": "bun test",
25
+ "test:watch": "bun test --watch",
26
+ "test:perf": "bun test src/tests/performance-regression.test.ts",
27
+ "build": "bun run ./scripts/build.ts",
28
+ "prepublishOnly": "bun run build",
29
+ "version": "bun run ./src/dev-entry.ts --version"
30
+ },
31
+ "bin": {
32
+ "myclaude": "bin/myclaude.cjs"
33
+ },
34
+ "files": [
35
+ "dist/",
36
+ "seed/",
37
+ "bin/",
38
+ "LICENSE",
39
+ "README.md",
40
+ "README.zh-CN.md",
41
+ "CHANGELOG.md",
42
+ "docs/funnycode.png",
43
+ "shims/node-domexception/"
44
+ ],
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "@alcalzone/ansi-tokenize": "0.3.0",
50
+ "@anthropic-ai/claude-agent-sdk": "0.3.207",
51
+ "@anthropic-ai/mcpb": "2.1.2",
52
+ "@anthropic-ai/sandbox-runtime": "0.0.44",
53
+ "@anthropic-ai/sdk": "0.111.0",
54
+ "@aws-sdk/client-bedrock-runtime": "3.1020.0",
55
+ "@commander-js/extra-typings": "14.0.0",
56
+ "@growthbook/growthbook": "1.6.5",
57
+ "@modelcontextprotocol/sdk": "1.29.0",
58
+ "@opentelemetry/api": "1.9.1",
59
+ "@opentelemetry/api-logs": "0.221.0",
60
+ "@opentelemetry/core": "1.28.0",
61
+ "@opentelemetry/resources": "1.28.0",
62
+ "@opentelemetry/sdk-logs": "0.52.0",
63
+ "@opentelemetry/sdk-metrics": "1.28.0",
64
+ "@opentelemetry/sdk-trace-base": "1.28.0",
65
+ "@opentelemetry/semantic-conventions": "1.43.0",
66
+ "ajv": "8.18.0",
67
+ "asciichart": "1.5.25",
68
+ "async-mutex": "0.5.0",
69
+ "auto-bind": "5.0.1",
70
+ "axios": "1.19.0",
71
+ "bidi-js": "1.0.3",
72
+ "chalk": "5.6.2",
73
+ "chokidar": "5.0.0",
74
+ "cli-boxes": "4.0.1",
75
+ "code-excerpt": "4.0.0",
76
+ "diff": "8.0.4",
77
+ "emoji-regex": "10.6.0",
78
+ "env-paths": "4.0.0",
79
+ "execa": "9.6.1",
80
+ "figures": "6.1.0",
81
+ "fuse.js": "7.1.0",
82
+ "get-east-asian-width": "1.5.0",
83
+ "google-auth-library": "10.6.2",
84
+ "highlight.js": "11.11.1",
85
+ "https-proxy-agent": "8.0.0",
86
+ "ignore": "7.0.5",
87
+ "indent-string": "5.0.0",
88
+ "ink": "6.8.0",
89
+ "jsonc-parser": "3.3.1",
90
+ "lodash-es": "4.17.23",
91
+ "lru-cache": "11.5.2",
92
+ "marked": "18.0.9",
93
+ "p-map": "7.0.4",
94
+ "picomatch": "4.0.4",
95
+ "proper-lockfile": "4.1.2",
96
+ "qrcode": "1.5.4",
97
+ "react": "19.2.8",
98
+ "react-reconciler": "0.33.0",
99
+ "semver": "7.8.5",
100
+ "shell-quote": "1.8.3",
101
+ "signal-exit": "4.1.0",
102
+ "stack-utils": "2.0.6",
103
+ "strip-ansi": "7.2.0",
104
+ "supports-hyperlinks": "4.4.0",
105
+ "tree-kill": "1.2.2",
106
+ "type-fest": "5.5.0",
107
+ "undici": "7.24.6",
108
+ "usehooks-ts": "3.1.1",
109
+ "vscode-jsonrpc": "8.2.1",
110
+ "vscode-languageserver-protocol": "3.17.5",
111
+ "vscode-languageserver-types": "3.17.5",
112
+ "wrap-ansi": "10.0.0",
113
+ "ws": "8.20.0",
114
+ "xss": "1.0.15",
115
+ "yaml": "2.8.3",
116
+ "zod": "4.4.3"
117
+ },
118
+ "optionalDependencies": {
119
+ "@ant/claude-for-chrome-mcp": "file:./shims/ant-claude-for-chrome-mcp",
120
+ "@ant/computer-use-input": "file:./shims/ant-computer-use-input",
121
+ "@ant/computer-use-mcp": "file:./shims/ant-computer-use-mcp",
122
+ "@ant/computer-use-swift": "file:./shims/ant-computer-use-swift",
123
+ "color-diff-napi": "file:./shims/color-diff-napi",
124
+ "modifiers-napi": "file:./shims/modifiers-napi",
125
+ "node-domexception": "file:./shims/node-domexception",
126
+ "url-handler-napi": "file:./shims/url-handler-napi"
127
+ },
128
+ "overrides": {
129
+ "node-domexception": "file:./shims/node-domexception"
130
+ }
131
+ }