lsd-pi 1.3.7 → 1.3.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +82 -0
  2. package/dist/resources/extensions/mcp-client/index.js +230 -54
  3. package/dist/resources/extensions/mcp-client/mcp-manager-component.js +220 -0
  4. package/dist/resources/extensions/slash-commands/plan.js +72 -18
  5. package/dist/resources/extensions/subagent/agents.js +7 -0
  6. package/dist/resources/extensions/subagent/index.js +25 -8
  7. package/dist/resources/extensions/subagent/model-resolution.js +1 -0
  8. package/dist/resources/extensions/usage/index.js +34 -2
  9. package/dist/resources/extensions/voice/index.js +1 -0
  10. package/dist/resources/extensions/voice/push-to-talk.js +2 -0
  11. package/package.json +1 -1
  12. package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.d.ts +2 -0
  13. package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.d.ts.map +1 -0
  14. package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.js +72 -0
  15. package/packages/pi-coding-agent/dist/core/agent-session.context-usage.test.js.map +1 -0
  16. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  17. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  18. package/packages/pi-coding-agent/dist/core/agent-session.js +29 -2
  19. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  20. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  21. package/packages/pi-coding-agent/dist/core/extensions/runner.js +1 -0
  22. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  23. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
  24. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  25. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  26. package/packages/pi-coding-agent/dist/core/tool-priority.js +1 -1
  27. package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -1
  28. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  29. package/packages/pi-coding-agent/dist/main.js +1 -0
  30. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  31. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +104 -2
  32. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -1
  33. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +39 -2
  34. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  35. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +135 -18
  36. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  37. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  38. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  39. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +17 -1
  40. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  41. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +21 -2
  42. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -1
  43. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +147 -9
  44. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -1
  45. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +51 -13
  46. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -1
  47. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  48. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +112 -18
  49. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  50. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -1
  51. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +1 -0
  52. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  53. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  54. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  55. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  56. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  57. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  58. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -4
  59. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  60. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  61. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +3 -0
  62. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  63. package/packages/pi-coding-agent/package.json +1 -1
  64. package/packages/pi-coding-agent/src/core/agent-session.context-usage.test.ts +87 -0
  65. package/packages/pi-coding-agent/src/core/agent-session.ts +40 -2
  66. package/packages/pi-coding-agent/src/core/extensions/runner.ts +1 -0
  67. package/packages/pi-coding-agent/src/core/extensions/types.ts +3 -0
  68. package/packages/pi-coding-agent/src/core/tool-priority.ts +1 -1
  69. package/packages/pi-coding-agent/src/main.ts +1 -0
  70. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +129 -2
  71. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +158 -18
  72. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +18 -1
  73. package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +164 -10
  74. package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +60 -13
  75. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +123 -20
  76. package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -0
  77. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -0
  78. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +34 -4
  79. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +4 -0
  80. package/pkg/package.json +1 -1
  81. package/src/resources/extensions/mcp-client/index.ts +259 -58
  82. package/src/resources/extensions/mcp-client/mcp-manager-component.ts +256 -0
  83. package/src/resources/extensions/mcp-client/tests/mcp-manager-component.test.ts +141 -0
  84. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +32 -0
  85. package/src/resources/extensions/slash-commands/plan.ts +76 -19
  86. package/src/resources/extensions/subagent/agents.ts +9 -0
  87. package/src/resources/extensions/subagent/index.ts +30 -8
  88. package/src/resources/extensions/subagent/model-resolution.ts +1 -0
  89. package/src/resources/extensions/usage/index.ts +40 -2
  90. package/src/resources/extensions/voice/index.ts +1 -0
  91. package/src/resources/extensions/voice/push-to-talk.ts +3 -0
  92. package/src/resources/extensions/voice/tests/push-to-talk.test.ts +6 -0
@@ -492,6 +492,10 @@ interface SubagentDetails {
492
492
  agentScope: AgentScope;
493
493
  projectAgentsDir: string | null;
494
494
  results: SingleResult[];
495
+ /** Total planned steps for chain mode (undefined for single/parallel). */
496
+ totalChainSteps?: number;
497
+ /** Currently executing chain step (1-indexed, undefined if chain completed). */
498
+ currentChainStep?: number;
495
499
  }
496
500
 
497
501
  function getFinalOutput(messages: Message[]): string {
@@ -1254,11 +1258,13 @@ export default function(pi: ExtensionAPI) {
1254
1258
 
1255
1259
  const makeDetails =
1256
1260
  (mode: "single" | "parallel" | "chain") =>
1257
- (results: SingleResult[]): SubagentDetails => ({
1261
+ (results: SingleResult[], opts?: { totalSteps?: number; currentStep?: number }): SubagentDetails => ({
1258
1262
  mode,
1259
1263
  agentScope,
1260
1264
  projectAgentsDir: discovery.projectAgentsDir,
1261
1265
  results,
1266
+ totalChainSteps: opts?.totalSteps,
1267
+ currentChainStep: opts?.currentStep,
1262
1268
  });
1263
1269
 
1264
1270
  const trackInProcessDepth = (
@@ -1362,7 +1368,8 @@ export default function(pi: ExtensionAPI) {
1362
1368
  const step = params.chain[i];
1363
1369
  const taskWithContext = step.task.replace(/\{previous\}/g, previousOutput);
1364
1370
 
1365
- // Create update callback that includes all previous results
1371
+ // Create update callback that includes all previous results + chain progress
1372
+ const chainTotalSteps = params.chain.length;
1366
1373
  const chainUpdate: OnUpdateCallback | undefined = onUpdate
1367
1374
  ? (partial) => {
1368
1375
  // Combine completed results with current streaming result
@@ -1371,7 +1378,10 @@ export default function(pi: ExtensionAPI) {
1371
1378
  const allResults = [...results, currentResult];
1372
1379
  onUpdate({
1373
1380
  content: partial.content,
1374
- details: makeDetails("chain")(allResults),
1381
+ details: makeDetails("chain")(allResults, {
1382
+ totalSteps: chainTotalSteps,
1383
+ currentStep: i + 1,
1384
+ }),
1375
1385
  });
1376
1386
  }
1377
1387
  }
@@ -1425,7 +1435,7 @@ export default function(pi: ExtensionAPI) {
1425
1435
  result.errorMessage || result.stderr || getFinalOutput(result.messages) || "(no output)";
1426
1436
  return {
1427
1437
  content: [{ type: "text", text: `Chain stopped at step ${i + 1} (${step.agent}): ${errorMsg}` }],
1428
- details: makeDetails("chain")(results),
1438
+ details: makeDetails("chain")(results, { totalSteps: params.chain.length }),
1429
1439
  isError: true,
1430
1440
  };
1431
1441
  }
@@ -1433,7 +1443,7 @@ export default function(pi: ExtensionAPI) {
1433
1443
  }
1434
1444
  return {
1435
1445
  content: [{ type: "text", text: getFinalOutput(results[results.length - 1].messages) || "(no output)" }],
1436
- details: makeDetails("chain")(results),
1446
+ details: makeDetails("chain")(results, { totalSteps: params.chain.length }),
1437
1447
  };
1438
1448
  }
1439
1449
 
@@ -2109,7 +2119,19 @@ export default function(pi: ExtensionAPI) {
2109
2119
 
2110
2120
  if (details.mode === "chain") {
2111
2121
  const successCount = details.results.filter((r) => r.exitCode === 0).length;
2112
- const icon = successCount === details.results.length ? theme.fg("success", "✓") : theme.fg("error", "✗");
2122
+ const isRunning = details.currentChainStep != null;
2123
+ const icon = !isRunning && successCount === details.results.length
2124
+ ? theme.fg("success", "✓")
2125
+ : isRunning
2126
+ ? theme.fg("accent", "◉")
2127
+ : theme.fg("error", "✗");
2128
+
2129
+ const totalLabel = details.totalChainSteps != null
2130
+ ? `${details.results.length}/${details.totalChainSteps} steps`
2131
+ : `${details.results.length} steps`;
2132
+ const progressLabel = isRunning
2133
+ ? ` (step ${details.currentChainStep} running)`
2134
+ : "";
2113
2135
 
2114
2136
  if (expanded) {
2115
2137
  const container = new Container();
@@ -2118,7 +2140,7 @@ export default function(pi: ExtensionAPI) {
2118
2140
  icon +
2119
2141
  " " +
2120
2142
  theme.fg("toolTitle", theme.bold("chain ")) +
2121
- theme.fg("accent", `${successCount}/${details.results.length} steps`),
2143
+ theme.fg("accent", `${totalLabel}${progressLabel}`),
2122
2144
  0,
2123
2145
  0,
2124
2146
  ),
@@ -2175,7 +2197,7 @@ export default function(pi: ExtensionAPI) {
2175
2197
  icon +
2176
2198
  " " +
2177
2199
  theme.fg("toolTitle", theme.bold("chain ")) +
2178
- theme.fg("accent", `${successCount}/${details.results.length} steps`);
2200
+ theme.fg("accent", `${totalLabel}${progressLabel}`);
2179
2201
  for (const r of details.results) {
2180
2202
  const rIcon = r.exitCode === 0 ? theme.fg("success", "✓") : theme.fg("error", "✗");
2181
2203
  const displayItems = getDisplayItems(r.messages);
@@ -21,6 +21,7 @@ const BARE_MODEL_PROVIDER_RULES: Array<{ provider: string; matches: (modelId: st
21
21
  matches: (modelId) => /^(mistral-|ministral-|codestral-)/.test(modelId),
22
22
  },
23
23
  { provider: "groq", matches: (modelId) => modelId.startsWith("llama-") || modelId.startsWith("mixtral-") },
24
+ { provider: "zhipu", matches: (modelId) => modelId.startsWith("glm-") },
24
25
  ];
25
26
 
26
27
  export function inferProviderForBareModel(modelId: string): string | undefined {
@@ -75,6 +75,8 @@ type UsageRow = {
75
75
  cacheWrite: number;
76
76
  total: number;
77
77
  cost: number;
78
+ totalDurationMs: number;
79
+ totalOutputForSpeed: number;
78
80
  };
79
81
 
80
82
  type UsageReport = {
@@ -313,6 +315,7 @@ function collectUsage(sessionFiles: string[], startMs: number, endMs: number, sc
313
315
  let projectLabel = basename(file);
314
316
  let headerResolved = false;
315
317
  let currentModel = "";
318
+ let lastUserTimestamp = 0;
316
319
 
317
320
  const raw = readFileSync(file, "utf-8");
318
321
  for (const line of raw.split("\n")) {
@@ -367,6 +370,8 @@ function collectUsage(sessionFiles: string[], startMs: number, endMs: number, sc
367
370
  cacheWrite: 0,
368
371
  total: 0,
369
372
  cost: 0,
373
+ totalDurationMs: 0,
374
+ totalOutputForSpeed: 0,
370
375
  };
371
376
 
372
377
  existing.messages += 1;
@@ -376,10 +381,27 @@ function collectUsage(sessionFiles: string[], startMs: number, endMs: number, sc
376
381
  existing.cacheWrite += cacheWrite;
377
382
  existing.total += total;
378
383
  existing.cost += cost;
384
+
385
+ // Track tok/sec: use preceding user message timestamp
386
+ if (output > 0 && lastUserTimestamp > 0) {
387
+ const durationMs = timestamp - lastUserTimestamp;
388
+ if (durationMs > 0) {
389
+ existing.totalDurationMs += durationMs;
390
+ existing.totalOutputForSpeed += output;
391
+ }
392
+ }
393
+
379
394
  rows.set(key, existing);
380
395
  } else if (message.role === "user") {
381
396
  const timestamp = Number(message.timestamp ?? 0);
382
- if (!timestamp || timestamp < startMs || timestamp >= endMs) continue;
397
+ if (!timestamp) continue;
398
+
399
+ // Always track last user timestamp for tok/sec calculation,
400
+ // even if this user message is outside the time range
401
+ // (the assistant response may still be within range).
402
+ lastUserTimestamp = timestamp;
403
+
404
+ if (timestamp < startMs || timestamp >= endMs) continue;
383
405
 
384
406
  matchedUserPrompts++;
385
407
  const model = currentModel;
@@ -397,6 +419,8 @@ function collectUsage(sessionFiles: string[], startMs: number, endMs: number, sc
397
419
  cacheWrite: 0,
398
420
  total: 0,
399
421
  cost: 0,
422
+ totalDurationMs: 0,
423
+ totalOutputForSpeed: 0,
400
424
  };
401
425
 
402
426
  existing.userPrompts += 1;
@@ -431,9 +455,11 @@ function collectUsage(sessionFiles: string[], startMs: number, endMs: number, sc
431
455
  acc.cacheWrite += row.cacheWrite;
432
456
  acc.total += row.total;
433
457
  acc.cost += row.cost;
458
+ acc.totalDurationMs += row.totalDurationMs;
459
+ acc.totalOutputForSpeed += row.totalOutputForSpeed;
434
460
  return acc;
435
461
  },
436
- { messages: 0, userPrompts: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0, cost: 0 },
462
+ { messages: 0, userPrompts: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0, cost: 0, totalDurationMs: 0, totalOutputForSpeed: 0 },
437
463
  );
438
464
 
439
465
  return {
@@ -448,6 +474,11 @@ function collectUsage(sessionFiles: string[], startMs: number, endMs: number, sc
448
474
  };
449
475
  }
450
476
 
477
+ function formatSpeed(totalDurationMs: number, totalOutputForSpeed: number): string {
478
+ if (totalDurationMs <= 0) return "—";
479
+ return Math.round(totalOutputForSpeed / (totalDurationMs / 1000)).toLocaleString();
480
+ }
481
+
451
482
  function renderTable(report: UsageReport): string {
452
483
  const firstColumnHeader = report.groupBy === "project"
453
484
  ? "project"
@@ -465,8 +496,11 @@ function renderTable(report: UsageReport): string {
465
496
  write: formatInt(row.cacheWrite),
466
497
  total: formatInt(row.total),
467
498
  cost: formatCost(row.cost),
499
+ speed: formatSpeed(row.totalDurationMs, row.totalOutputForSpeed),
468
500
  }));
469
501
 
502
+ const totalsSpeed = formatSpeed(report.totals.totalDurationMs, report.totals.totalOutputForSpeed);
503
+
470
504
  const widths = {
471
505
  label: Math.max(firstColumnHeader.length, ...displayRows.map((row) => row.label.length), 5),
472
506
  userPrompts: Math.max(11, ...displayRows.map((row) => row.userPrompts.length), String(report.totals.userPrompts).length),
@@ -477,6 +511,7 @@ function renderTable(report: UsageReport): string {
477
511
  write: Math.max(5, ...displayRows.map((row) => row.write.length), formatInt(report.totals.cacheWrite).length),
478
512
  total: Math.max(5, ...displayRows.map((row) => row.total.length), formatInt(report.totals.total).length),
479
513
  cost: Math.max(7, ...displayRows.map((row) => row.cost.length), formatCost(report.totals.cost).length),
514
+ speed: Math.max(5, ...displayRows.map((row) => row.speed.length), totalsSpeed.length),
480
515
  };
481
516
 
482
517
  const header = [
@@ -489,6 +524,7 @@ function renderTable(report: UsageReport): string {
489
524
  "write".padStart(widths.write),
490
525
  "total".padStart(widths.total),
491
526
  "cost".padStart(widths.cost),
527
+ "tok/s".padStart(widths.speed),
492
528
  ].join(" ");
493
529
 
494
530
  const divider = "-".repeat(header.length);
@@ -502,6 +538,7 @@ function renderTable(report: UsageReport): string {
502
538
  row.write.padStart(widths.write),
503
539
  row.total.padStart(widths.total),
504
540
  row.cost.padStart(widths.cost),
541
+ row.speed.padStart(widths.speed),
505
542
  ].join(" "));
506
543
 
507
544
  const totalsLine = [
@@ -514,6 +551,7 @@ function renderTable(report: UsageReport): string {
514
551
  formatInt(report.totals.cacheWrite).padStart(widths.write),
515
552
  formatInt(report.totals.total).padStart(widths.total),
516
553
  formatCost(report.totals.cost).padStart(widths.cost),
554
+ totalsSpeed.padStart(widths.speed),
517
555
  ].join(" ");
518
556
 
519
557
  return [header, divider, ...body, divider, totalsLine].join("\n");
@@ -303,6 +303,7 @@ export default function(pi: ExtensionAPI) {
303
303
  activationMode,
304
304
  editorText: ctx.ui.getEditorText(),
305
305
  holdToTalkSupported: isKittyProtocolActive(),
306
+ isEditorFocused: ctx.ui.isEditorFocused(),
306
307
  onUnsupported: () => {
307
308
  if (holdToTalkUnsupportedNotified) return;
308
309
  holdToTalkUnsupportedNotified = true;
@@ -8,6 +8,7 @@ export interface PushToTalkState {
8
8
  activationMode: VoiceActivationMode | null;
9
9
  editorText: string;
10
10
  holdToTalkSupported: boolean;
11
+ isEditorFocused: boolean;
11
12
  onUnsupported?(): void;
12
13
  startPushToTalk(): void | Promise<void>;
13
14
  stopVoice(): void | Promise<void>;
@@ -16,6 +17,8 @@ export interface PushToTalkState {
16
17
  export function handlePushToTalkInput(data: string, state: PushToTalkState): ReturnType<TerminalInputHandler> {
17
18
  if (!matchesKey(data, Key.space)) return undefined;
18
19
 
20
+ if (!state.isEditorFocused) return undefined;
21
+
19
22
  if (isKeyRelease(data)) {
20
23
  if (state.activationMode === "push-to-talk") {
21
24
  void Promise.resolve(state.stopVoice());
@@ -15,6 +15,7 @@ describe("voice push-to-talk handler", () => {
15
15
  activationMode: null,
16
16
  editorText: "",
17
17
  holdToTalkSupported: true,
18
+ isEditorFocused: true,
18
19
  startPushToTalk: () => { startCalls += 1; },
19
20
  stopVoice: () => { stopCalls += 1; },
20
21
  });
@@ -32,6 +33,7 @@ describe("voice push-to-talk handler", () => {
32
33
  activationMode: null,
33
34
  editorText: "hello",
34
35
  holdToTalkSupported: true,
36
+ isEditorFocused: true,
35
37
  startPushToTalk: () => { startCalls += 1; },
36
38
  stopVoice: () => { },
37
39
  });
@@ -48,6 +50,7 @@ describe("voice push-to-talk handler", () => {
48
50
  activationMode: "push-to-talk",
49
51
  editorText: "",
50
52
  holdToTalkSupported: true,
53
+ isEditorFocused: true,
51
54
  startPushToTalk: () => { startCalls += 1; },
52
55
  stopVoice: () => { },
53
56
  });
@@ -64,6 +67,7 @@ describe("voice push-to-talk handler", () => {
64
67
  activationMode: "push-to-talk",
65
68
  editorText: "",
66
69
  holdToTalkSupported: true,
70
+ isEditorFocused: true,
67
71
  startPushToTalk: () => { },
68
72
  stopVoice: () => { stopCalls += 1; },
69
73
  });
@@ -80,6 +84,7 @@ describe("voice push-to-talk handler", () => {
80
84
  activationMode: "toggle",
81
85
  editorText: "",
82
86
  holdToTalkSupported: true,
87
+ isEditorFocused: true,
83
88
  startPushToTalk: () => { },
84
89
  stopVoice: () => { stopCalls += 1; },
85
90
  });
@@ -97,6 +102,7 @@ describe("voice push-to-talk handler", () => {
97
102
  activationMode: null,
98
103
  editorText: "",
99
104
  holdToTalkSupported: false,
105
+ isEditorFocused: true,
100
106
  onUnsupported: () => { notifyCalls += 1; },
101
107
  startPushToTalk: () => { startCalls += 1; },
102
108
  stopVoice: () => { },