@kolisachint/hoocode-agent 0.4.113 → 0.4.115

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 (147) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/core/agent-session.d.ts.map +1 -1
  3. package/dist/core/agent-session.js +1 -1
  4. package/dist/core/agent-session.js.map +1 -1
  5. package/dist/core/extensions/plugins/authoring.d.ts +51 -0
  6. package/dist/core/extensions/plugins/authoring.d.ts.map +1 -0
  7. package/dist/core/extensions/plugins/authoring.js +91 -0
  8. package/dist/core/extensions/plugins/authoring.js.map +1 -0
  9. package/dist/core/extensions/plugins/default-marketplace/.agents-plugin/marketplace.json +12 -0
  10. package/dist/core/extensions/plugins/default-marketplace/plugins/hello-world/.agents-plugin/plugin.json +6 -0
  11. package/dist/core/extensions/plugins/default-marketplace/plugins/hello-world/commands/hello.md +5 -0
  12. package/dist/core/extensions/plugins/default-marketplace/plugins/hello-world/skills/greet/SKILL.md +7 -0
  13. package/dist/core/extensions/plugins/formats/agents.d.ts +7 -0
  14. package/dist/core/extensions/plugins/formats/agents.d.ts.map +1 -0
  15. package/dist/core/extensions/plugins/formats/agents.js +14 -0
  16. package/dist/core/extensions/plugins/formats/agents.js.map +1 -0
  17. package/dist/core/extensions/plugins/formats/claude.d.ts +10 -0
  18. package/dist/core/extensions/plugins/formats/claude.d.ts.map +1 -0
  19. package/dist/core/extensions/plugins/formats/claude.js +17 -0
  20. package/dist/core/extensions/plugins/formats/claude.js.map +1 -0
  21. package/dist/core/extensions/plugins/formats/copilot.d.ts +23 -0
  22. package/dist/core/extensions/plugins/formats/copilot.d.ts.map +1 -0
  23. package/dist/core/extensions/plugins/formats/copilot.js +130 -0
  24. package/dist/core/extensions/plugins/formats/copilot.js.map +1 -0
  25. package/dist/core/extensions/plugins/formats/index.d.ts +41 -0
  26. package/dist/core/extensions/plugins/formats/index.d.ts.map +1 -0
  27. package/dist/core/extensions/plugins/formats/index.js +76 -0
  28. package/dist/core/extensions/plugins/formats/index.js.map +1 -0
  29. package/dist/core/extensions/plugins/formats/jsonManifest.d.ts +21 -0
  30. package/dist/core/extensions/plugins/formats/jsonManifest.d.ts.map +1 -0
  31. package/dist/core/extensions/plugins/formats/jsonManifest.js +97 -0
  32. package/dist/core/extensions/plugins/formats/jsonManifest.js.map +1 -0
  33. package/dist/core/extensions/plugins/formats/shared.d.ts +44 -0
  34. package/dist/core/extensions/plugins/formats/shared.d.ts.map +1 -0
  35. package/dist/core/extensions/plugins/formats/shared.js +107 -0
  36. package/dist/core/extensions/plugins/formats/shared.js.map +1 -0
  37. package/dist/core/extensions/plugins/formats/types.d.ts +118 -0
  38. package/dist/core/extensions/plugins/formats/types.d.ts.map +1 -0
  39. package/dist/core/extensions/plugins/formats/types.js +19 -0
  40. package/dist/core/extensions/plugins/formats/types.js.map +1 -0
  41. package/dist/core/extensions/plugins/install.d.ts +73 -0
  42. package/dist/core/extensions/plugins/install.d.ts.map +1 -0
  43. package/dist/core/extensions/plugins/install.js +173 -0
  44. package/dist/core/extensions/plugins/install.js.map +1 -0
  45. package/dist/core/extensions/plugins/manifest.d.ts +25 -7
  46. package/dist/core/extensions/plugins/manifest.d.ts.map +1 -1
  47. package/dist/core/extensions/plugins/manifest.js +16 -91
  48. package/dist/core/extensions/plugins/manifest.js.map +1 -1
  49. package/dist/core/extensions/plugins/marketplace.d.ts +5 -4
  50. package/dist/core/extensions/plugins/marketplace.d.ts.map +1 -1
  51. package/dist/core/extensions/plugins/marketplace.js +8 -13
  52. package/dist/core/extensions/plugins/marketplace.js.map +1 -1
  53. package/dist/core/settings-defaults.d.ts +2 -0
  54. package/dist/core/settings-defaults.d.ts.map +1 -1
  55. package/dist/core/settings-defaults.js +2 -0
  56. package/dist/core/settings-defaults.js.map +1 -1
  57. package/dist/core/settings-manager.d.ts +4 -0
  58. package/dist/core/settings-manager.d.ts.map +1 -1
  59. package/dist/core/settings-manager.js +16 -0
  60. package/dist/core/settings-manager.js.map +1 -1
  61. package/dist/core/settings-types.d.ts +2 -0
  62. package/dist/core/settings-types.d.ts.map +1 -1
  63. package/dist/core/settings-types.js.map +1 -1
  64. package/dist/core/subagent-depth.d.ts +13 -0
  65. package/dist/core/subagent-depth.d.ts.map +1 -1
  66. package/dist/core/subagent-depth.js +15 -0
  67. package/dist/core/subagent-depth.js.map +1 -1
  68. package/dist/core/subagent-pool.d.ts.map +1 -1
  69. package/dist/core/subagent-pool.js +4 -1
  70. package/dist/core/subagent-pool.js.map +1 -1
  71. package/dist/core/tools/find.d.ts +8 -3
  72. package/dist/core/tools/find.d.ts.map +1 -1
  73. package/dist/core/tools/find.js +189 -122
  74. package/dist/core/tools/find.js.map +1 -1
  75. package/dist/core/tools/index.d.ts +0 -4
  76. package/dist/core/tools/index.d.ts.map +1 -1
  77. package/dist/core/tools/index.js +2 -5
  78. package/dist/core/tools/index.js.map +1 -1
  79. package/dist/core/tools/plugin-tool-names.d.ts +21 -0
  80. package/dist/core/tools/plugin-tool-names.d.ts.map +1 -0
  81. package/dist/core/tools/plugin-tool-names.js +31 -0
  82. package/dist/core/tools/plugin-tool-names.js.map +1 -0
  83. package/dist/core/tools/plugins.d.ts +49 -0
  84. package/dist/core/tools/plugins.d.ts.map +1 -0
  85. package/dist/core/tools/plugins.js +186 -0
  86. package/dist/core/tools/plugins.js.map +1 -0
  87. package/dist/core/tools/propose-plugin.d.ts +36 -0
  88. package/dist/core/tools/propose-plugin.d.ts.map +1 -0
  89. package/dist/core/tools/propose-plugin.js +219 -0
  90. package/dist/core/tools/propose-plugin.js.map +1 -0
  91. package/dist/core/tools/subagent.d.ts.map +1 -1
  92. package/dist/core/tools/subagent.js +29 -3
  93. package/dist/core/tools/subagent.js.map +1 -1
  94. package/dist/core/warm-subagent-pool.d.ts.map +1 -1
  95. package/dist/core/warm-subagent-pool.js +4 -1
  96. package/dist/core/warm-subagent-pool.js.map +1 -1
  97. package/dist/extensions/core/marketplace.d.ts +7 -3
  98. package/dist/extensions/core/marketplace.d.ts.map +1 -1
  99. package/dist/extensions/core/marketplace.js +23 -67
  100. package/dist/extensions/core/marketplace.js.map +1 -1
  101. package/dist/extensions/core/mcp-deferred.d.ts +28 -0
  102. package/dist/extensions/core/mcp-deferred.d.ts.map +1 -0
  103. package/dist/extensions/core/mcp-deferred.js +53 -0
  104. package/dist/extensions/core/mcp-deferred.js.map +1 -0
  105. package/dist/extensions/core/mcp-loader.d.ts.map +1 -1
  106. package/dist/extensions/core/mcp-loader.js +132 -78
  107. package/dist/extensions/core/mcp-loader.js.map +1 -1
  108. package/dist/main.d.ts.map +1 -1
  109. package/dist/main.js +19 -1
  110. package/dist/main.js.map +1 -1
  111. package/dist/modes/interactive/brand.d.ts +41 -0
  112. package/dist/modes/interactive/brand.d.ts.map +1 -0
  113. package/dist/modes/interactive/brand.js +40 -0
  114. package/dist/modes/interactive/brand.js.map +1 -0
  115. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  116. package/dist/modes/interactive/components/footer.js +102 -131
  117. package/dist/modes/interactive/components/footer.js.map +1 -1
  118. package/dist/modes/interactive/components/task-panel.d.ts +6 -5
  119. package/dist/modes/interactive/components/task-panel.d.ts.map +1 -1
  120. package/dist/modes/interactive/components/task-panel.js +13 -9
  121. package/dist/modes/interactive/components/task-panel.js.map +1 -1
  122. package/dist/modes/interactive/resource-display.d.ts.map +1 -1
  123. package/dist/modes/interactive/resource-display.js +131 -86
  124. package/dist/modes/interactive/resource-display.js.map +1 -1
  125. package/dist/modes/interactive/theme/dark.json +1 -1
  126. package/dist/modes/interactive/theme/light.json +1 -1
  127. package/dist/modes/interactive/voice/voice-controller.d.ts.map +1 -1
  128. package/dist/modes/interactive/voice/voice-controller.js +15 -7
  129. package/dist/modes/interactive/voice/voice-controller.js.map +1 -1
  130. package/dist/modes/interactive/voice/voice-panel.d.ts +27 -8
  131. package/dist/modes/interactive/voice/voice-panel.d.ts.map +1 -1
  132. package/dist/modes/interactive/voice/voice-panel.js +89 -27
  133. package/dist/modes/interactive/voice/voice-panel.js.map +1 -1
  134. package/dist/utils/tools-manager.d.ts +8 -2
  135. package/dist/utils/tools-manager.d.ts.map +1 -1
  136. package/dist/utils/tools-manager.js +15 -6
  137. package/dist/utils/tools-manager.js.map +1 -1
  138. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  139. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  140. package/examples/extensions/minimal-mode.ts +1 -1
  141. package/examples/extensions/sandbox/package.json +1 -1
  142. package/examples/extensions/with-deps/package.json +1 -1
  143. package/package.json +5 -5
  144. package/dist/core/tools/glob.d.ts +0 -42
  145. package/dist/core/tools/glob.d.ts.map +0 -1
  146. package/dist/core/tools/glob.js +0 -432
  147. package/dist/core/tools/glob.js.map +0 -1
@@ -6,9 +6,12 @@
6
6
  */
7
7
  import * as os from "node:os";
8
8
  import * as path from "node:path";
9
- import { Spacer, Text } from "@kolisachint/hoocode-tui";
9
+ import { Spacer, Text, visibleWidth } from "@kolisachint/hoocode-tui";
10
+ import { getExtensionMcpServers } from "../../core/extension-mcp-servers.js";
10
11
  import { parseGitUrl } from "../../utils/git.js";
11
12
  import { getCwdRelativePath } from "../../utils/paths.js";
13
+ import { BRAND_MARK, BRAND_NAME, CATEGORY_GLYPH } from "./brand.js";
14
+ import { appKeyLabel } from "./components/keybinding-hints.js";
12
15
  import { theme } from "./theme/theme.js";
13
16
  export function isExpandable(obj) {
14
17
  return typeof obj === "object" && obj !== null && "setExpanded" in obj;
@@ -321,11 +324,6 @@ export function showLoadedResources(deps, options) {
321
324
  }
322
325
  return theme.fg("dim", ` ${labels.join(", ")}`);
323
326
  };
324
- const addLoadedSection = (name, collapsedBody, expandedBody = collapsedBody, color = "mdHeading") => {
325
- const section = new ExpandableText(() => `${sectionHeader(name, color)}\n${collapsedBody}`, () => `${sectionHeader(name, color)}\n${expandedBody}`, deps.isExpanded(), 0, 0);
326
- chatContainer.addChild(section);
327
- chatContainer.addChild(new Spacer(1));
328
- };
329
327
  const skillsResult = resourceLoader.getSkills();
330
328
  const promptsResult = resourceLoader.getPrompts();
331
329
  const themesResult = resourceLoader.getThemes();
@@ -366,90 +364,137 @@ export function showLoadedResources(deps, options) {
366
364
  const templates = deps.getPromptTemplates();
367
365
  const loadedThemes = themesResult.themes;
368
366
  const customThemes = loadedThemes.filter((t) => t.sourcePath);
369
- const totalItems = contextFiles.length + skills.length + templates.length + extensions.length + customThemes.length;
370
- // Meta items: active mode and subagent system prompt (always shown)
371
- const metaItems = [];
367
+ const agentPaths = resourceLoader.getAgentPaths();
368
+ const mcpServerCount = getExtensionMcpServers().reduce((n, e) => n + Object.keys(e.mcpServers).length, 0);
369
+ // Plugins register their synthetic extension factory as `plugin:<id>`;
370
+ // split them out so plugins and code extensions each get their own count.
371
+ // (displayName is absent from the options-provided extension shape, so read
372
+ // it structurally.)
373
+ const displayNameOf = (e) => {
374
+ const value = e.displayName;
375
+ return typeof value === "string" ? value : undefined;
376
+ };
377
+ const pluginCount = extensions.filter((e) => displayNameOf(e)?.startsWith("plugin:")).length;
378
+ const codeExtensionCount = extensions.length - pluginCount;
379
+ // ── Ready header: brand mark + product + active mode ────────────────────
380
+ // Answers "what session is this" in one line; the old mode/<x> +
381
+ // subagent_system_prompt meta jargon lives in the expanded details.
372
382
  const rawMode = deps.getActiveMode().replace(" + subagent", "");
373
- metaItems.push(`mode/${rawMode}`);
374
- if (deps.getSubagentEnabled()) {
375
- metaItems.push("subagent_system_prompt");
376
- }
377
- if (totalItems > 0 && totalItems <= 5) {
378
- const allCompactItems = [...metaItems];
379
- if (contextFiles.length > 0) {
380
- allCompactItems.push(...contextFiles.map((contextFile) => formatContextPath(contextFile.path, deps.getCwd())));
381
- }
382
- if (skills.length > 0) {
383
- allCompactItems.push(...skills.map((skill) => skill.name));
384
- }
385
- if (templates.length > 0) {
386
- allCompactItems.push(...templates.map((template) => `/${template.name}`));
387
- }
388
- if (extensions.length > 0) {
389
- allCompactItems.push(...getCompactExtensionLabels(extensions));
383
+ const headerLine = `${theme.bold(theme.fg("accent", BRAND_MARK))} ` +
384
+ `${theme.bold(`${BRAND_NAME.toLowerCase()} ready`)} ` +
385
+ `${theme.fg("dim", "·")} ${theme.bold(theme.fg("accent", rawMode.toUpperCase()))}` +
386
+ (deps.getSubagentEnabled() ? theme.fg("dim", " · subagents on") : "");
387
+ chatContainer.addChild(new Text(headerLine, 0, 0));
388
+ // ── Counted capability grid ──────────────────────────────────────────────
389
+ // One cell per loaded capability class (glyph + count + label), so "what
390
+ // can this session do" reads at a glance; names/paths sit one keypress
391
+ // away in the details below. Cells pad to a common width, four per row.
392
+ const plural = (n, s) => (n === 1 ? s : `${s}s`);
393
+ const cells = [];
394
+ if (skills.length > 0)
395
+ cells.push({ key: "skills", count: skills.length, label: plural(skills.length, "skill") });
396
+ if (templates.length > 0) {
397
+ cells.push({ key: "commands", count: templates.length, label: plural(templates.length, "command") });
398
+ }
399
+ if (agentPaths.length > 0) {
400
+ cells.push({ key: "agents", count: agentPaths.length, label: plural(agentPaths.length, "agent") });
401
+ }
402
+ if (mcpServerCount > 0)
403
+ cells.push({ key: "mcp", count: mcpServerCount, label: "MCP" });
404
+ if (pluginCount > 0)
405
+ cells.push({ key: "plugins", count: pluginCount, label: plural(pluginCount, "plugin") });
406
+ if (codeExtensionCount > 0) {
407
+ cells.push({
408
+ key: "extensions",
409
+ count: codeExtensionCount,
410
+ label: plural(codeExtensionCount, "extension"),
411
+ });
412
+ }
413
+ if (customThemes.length > 0) {
414
+ cells.push({ key: "themes", count: customThemes.length, label: plural(customThemes.length, "theme") });
415
+ }
416
+ if (cells.length > 0) {
417
+ const cellPlain = (c) => `${CATEGORY_GLYPH[c.key]} ${c.count} ${c.label}`;
418
+ const cellWidth = Math.max(...cells.map((c) => visibleWidth(cellPlain(c)))) + 3;
419
+ const styledCell = (c) => {
420
+ const pad = " ".repeat(Math.max(0, cellWidth - visibleWidth(cellPlain(c))));
421
+ return (`${theme.fg("accent", CATEGORY_GLYPH[c.key])} ` +
422
+ `${theme.bold(String(c.count))} ${theme.fg("muted", c.label)}${pad}`);
423
+ };
424
+ const PER_ROW = 4;
425
+ const rows = [];
426
+ for (let i = 0; i < cells.length; i += PER_ROW) {
427
+ rows.push(` ${cells
428
+ .slice(i, i + PER_ROW)
429
+ .map(styledCell)
430
+ .join("")}`.trimEnd());
390
431
  }
391
- if (customThemes.length > 0) {
392
- allCompactItems.push(...customThemes.map((loadedTheme) => loadedTheme.name ?? getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
393
- }
394
- chatContainer.addChild(new Text(`${theme.fg("mdHeading", "[Resources]")} ${theme.fg("dim", allCompactItems.join(", "))}`, 0, 0));
395
- }
396
- else if (totalItems === 0) {
397
- chatContainer.addChild(new Text(`${theme.fg("mdHeading", "[Resources]")} ${theme.fg("dim", metaItems.join(", "))}`, 0, 0));
432
+ chatContainer.addChild(new Text(rows.join("\n"), 0, 0));
398
433
  }
399
434
  else {
400
- addLoadedSection("Resources", formatCompactList(metaItems), formatCompactList(metaItems));
401
- if (contextFiles.length > 0) {
402
- chatContainer.addChild(new Spacer(1));
403
- const contextList = contextFiles.map((f) => theme.fg("dim", ` ${formatDisplayPath(f.path)}`)).join("\n");
404
- const contextCompactList = formatCompactList(contextFiles.map((contextFile) => formatContextPath(contextFile.path, deps.getCwd())), { sort: false });
405
- addLoadedSection("Context", contextCompactList, contextList);
406
- }
407
- if (skills.length > 0) {
408
- const groups = buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
409
- const skillList = formatScopeGroups(groups, {
410
- formatPath: (item) => formatDisplayPath(item.path),
411
- formatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),
412
- });
413
- const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
414
- addLoadedSection("Skills", skillCompactList, skillList);
415
- }
416
- if (templates.length > 0) {
417
- const groups = buildScopeGroups(templates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })));
418
- const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
419
- const templateList = formatScopeGroups(groups, {
420
- formatPath: (item) => {
421
- const template = templateByPath.get(item.path);
422
- return template ? `/${template.name}` : formatDisplayPath(item.path);
423
- },
424
- formatPackagePath: (item) => {
425
- const template = templateByPath.get(item.path);
426
- return template ? `/${template.name}` : formatDisplayPath(item.path);
427
- },
428
- });
429
- const promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));
430
- addLoadedSection("Prompts", promptCompactList, templateList);
431
- }
432
- if (extensions.length > 0) {
433
- const groups = buildScopeGroups(extensions);
434
- const extList = formatScopeGroups(groups, {
435
- formatPath: (item) => item.displayName ?? formatExtensionDisplayPath(item.path),
436
- formatPackagePath: (item) => item.displayName ?? formatExtensionDisplayPath(getShortPath(item.path, item.sourceInfo)),
437
- });
438
- const extensionCompactList = formatCompactList(getCompactExtensionLabels(extensions));
439
- addLoadedSection("Extensions", extensionCompactList, extList, "mdHeading");
440
- }
441
- if (customThemes.length > 0) {
442
- const groups = buildScopeGroups(customThemes.map((loadedTheme) => ({
443
- path: loadedTheme.sourcePath,
444
- sourceInfo: loadedTheme.sourceInfo,
445
- })));
446
- const themeList = formatScopeGroups(groups, {
447
- formatPath: (item) => formatDisplayPath(item.path),
448
- formatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),
449
- });
450
- const themeCompactList = formatCompactList(customThemes.map((loadedTheme) => loadedTheme.name ?? getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
451
- addLoadedSection("Themes", themeCompactList, themeList);
452
- }
435
+ chatContainer.addChild(new Text(theme.fg("dim", " no project resources loaded"), 0, 0));
436
+ }
437
+ // Context files stay visible in the summary — they shape every reply.
438
+ if (contextFiles.length > 0) {
439
+ const names = contextFiles.map((f) => formatContextPath(f.path, deps.getCwd())).join(", ");
440
+ chatContainer.addChild(new Text(` ${theme.fg("accent", CATEGORY_GLYPH.context)} ${theme.fg("muted", "context")} ${names}`, 0, 0));
441
+ }
442
+ // ── Details: names + scope-grouped paths, one keypress away ─────────────
443
+ // A single expandable holds every per-category listing; collapsed it is
444
+ // just the hint line, so a resource-heavy project no longer buries the
445
+ // prompt under a wall of names at launch.
446
+ const detailSections = [];
447
+ const metaItems = [`mode/${rawMode}`];
448
+ if (deps.getSubagentEnabled())
449
+ metaItems.push("subagent_system_prompt");
450
+ detailSections.push(`${sectionHeader("Resources")}\n${formatCompactList(metaItems)}`);
451
+ if (contextFiles.length > 0) {
452
+ const contextList = contextFiles.map((f) => theme.fg("dim", ` ${formatDisplayPath(f.path)}`)).join("\n");
453
+ detailSections.push(`${sectionHeader("Context")}\n${contextList}`);
454
+ }
455
+ if (skills.length > 0) {
456
+ const groups = buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
457
+ const skillList = formatScopeGroups(groups, {
458
+ formatPath: (item) => formatDisplayPath(item.path),
459
+ formatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),
460
+ });
461
+ detailSections.push(`${sectionHeader("Skills")}\n${formatCompactList(skills.map((skill) => skill.name))}\n${skillList}`);
462
+ }
463
+ if (templates.length > 0) {
464
+ const groups = buildScopeGroups(templates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })));
465
+ const templateByPath = new Map(templates.map((t) => [t.filePath, t]));
466
+ const formatTemplate = (item) => {
467
+ const template = templateByPath.get(item.path);
468
+ return template ? `/${template.name}` : formatDisplayPath(item.path);
469
+ };
470
+ const templateList = formatScopeGroups(groups, {
471
+ formatPath: formatTemplate,
472
+ formatPackagePath: formatTemplate,
473
+ });
474
+ detailSections.push(`${sectionHeader("Prompts")}\n${formatCompactList(templates.map((t) => `/${t.name}`))}\n${templateList}`);
475
+ }
476
+ if (extensions.length > 0) {
477
+ const groups = buildScopeGroups(extensions);
478
+ const extList = formatScopeGroups(groups, {
479
+ formatPath: (item) => item.displayName ?? formatExtensionDisplayPath(item.path),
480
+ formatPackagePath: (item) => item.displayName ?? formatExtensionDisplayPath(getShortPath(item.path, item.sourceInfo)),
481
+ });
482
+ detailSections.push(`${sectionHeader("Extensions")}\n${formatCompactList(getCompactExtensionLabels(extensions))}\n${extList}`);
483
+ }
484
+ if (customThemes.length > 0) {
485
+ const groups = buildScopeGroups(customThemes.map((loadedTheme) => ({
486
+ path: loadedTheme.sourcePath,
487
+ sourceInfo: loadedTheme.sourceInfo,
488
+ })));
489
+ const themeList = formatScopeGroups(groups, {
490
+ formatPath: (item) => formatDisplayPath(item.path),
491
+ formatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),
492
+ });
493
+ detailSections.push(`${sectionHeader("Themes")}\n${themeList}`);
494
+ }
495
+ if (detailSections.length > 0) {
496
+ const expandHint = theme.fg("dim", ` ${appKeyLabel("app.tools.expand")} details`);
497
+ chatContainer.addChild(new ExpandableText(() => expandHint, () => detailSections.join("\n\n"), deps.isExpanded(), 0, 0));
453
498
  }
454
499
  if (contextWarnings.length > 0) {
455
500
  for (const warning of contextWarnings) {
@@ -1 +1 @@
1
- {"version":3,"file":"resource-display.js","sourceRoot":"","sources":["../../../src/modes/interactive/resource-display.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAkB,MAAM,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAKxE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAmB,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAU1D,MAAM,UAAU,YAAY,CAAC,GAAY,EAAqB;IAC7D,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,aAAa,IAAI,GAAG,CAAC;AAAA,CACvE;AAED,MAAM,OAAO,cAAe,SAAQ,IAAI;IAE9B,SAAS;IACT,QAAQ;IAFjB,YACS,SAAuB,EACvB,QAAsB,EAC9B,iBAA0B,EAC1B,QAAgB,EAChB,QAAgB,EACf;QACD,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;yBANhE,SAAS;wBACT,QAAQ;IAKwD,CACxE;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAAA,CAC5D;CACD;AAED,+EAA+E;AAC/E,mCAAmC;AACnC,+EAA+E;AAE/E,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAU;IACpD,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,gCAAgC;IAChC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1C,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd;AAED,MAAM,UAAU,0BAA0B,CAAC,aAAqB,EAAU;IACzE,IAAI,MAAM,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAC9C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC;AAAA,CACd;AAED,MAAM,UAAU,iBAAiB,CAAC,CAAS,EAAE,GAAW,EAAU;IACjE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACzF,MAAM,YAAY,GAAG,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IACnE,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,YAAY,CAAC;IACrB,CAAC;IAED,OAAO,iBAAiB,CAAC,YAAY,CAAC,CAAC;AAAA,CACvC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,UAAuB,EAAU;IAC/E,MAAM,OAAO,GAAG,UAAU,EAAE,OAAO,CAAC;IACpC,IAAI,OAAO,IAAI,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClF,IACC,YAAY;YACZ,YAAY,KAAK,GAAG;YACpB,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;YAC9B,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YACzC,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAC7B,CAAC;YACF,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACF,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC7E,IAAI,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3C,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC3D,IAAI,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3C,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC;AAAA,CACnC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAoB,EAAE,UAAuB,EAAU;IAC1F,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACzD,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC;IACtG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IACvC,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,4BAA4B,CAAC,UAAuB,EAAU;IACtE,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;IACxC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;IAC9C,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC;IACjC,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,wBAAwB,CAAC,YAAoB,EAAE,UAAuB,EAAU;IACxF,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO,mBAAmB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,WAAW,GAAG,4BAA4B,CAAC,UAAU,CAAC,CAAC;IAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;QAClB,OAAO,mBAAmB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7E,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5G,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;IACrG,CAAC;IAED,OAAO,GAAG,WAAW,IAAI,WAAW,EAAE,CAAC;AAAA,CACvC;AAED,SAAS,6BAA6B,CAAC,YAAoB,EAAY;IACtE,OAAO,iBAAiB,CAAC,YAAY,CAAC;SACpC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC;AAAA,CAC7D;AAED,SAAS,kCAAkC,CAC1C,YAAoB,EACpB,KAAa,EACb,QAAqD,EAC5C;IACT,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAC3C,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,IAAI,QAAQ,CAAC,MAAM,EAAE,YAAY,IAAI,CAAC,EAAE,CAAC;QAC/E,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;YACpD,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC;YACb,CAAC;YACD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;QAAA,CAClE,CAAC,CAAC;QAEH,IAAI,QAAQ,EAAE,CAAC;YACd,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAA,CAC1B;AAED,MAAM,UAAU,yBAAyB,CACxC,UAAkF,EACvE;IACX,MAAM,oBAAoB,GAAG,UAAU;SACrC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,6BAA6B,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAClD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,KAAK,UAAU,IAAI,WAAW,KAAK,UAAU,CAAC,EAAE,CAAC;YACvF,QAAQ,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;QACD,OAAO;YACN,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,QAAQ;SACR,CAAC;IAAA,CACF,CAAC;SACD,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IAEhE,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC;QACpC,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;YAC3B,OAAO,SAAS,CAAC,WAAW,CAAC;QAC9B,CAAC;QAED,IAAI,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3C,OAAO,wBAAwB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,eAAe,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/F,IAAI,eAAe,KAAK,CAAC,CAAC,EAAE,CAAC;YAC5B,OAAO,mBAAmB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QAClE,CAAC;QAED,OAAO,kCAAkC,CAAC,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,oBAAoB,CAAC,CAAC;IAAA,CACjG,CAAC,CAAC;AAAA,CACH;AAED,SAAS,oBAAoB,CAAC,UAAuB,EAInD;IACD,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,OAAO,CAAC;IAC7C,MAAM,KAAK,GAAG,UAAU,EAAE,KAAK,IAAI,SAAS,CAAC;IAC7C,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACxB,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC1C,CAAC;QACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;YAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC9D,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC1C,CAAC;IAED,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAClG,CAAC;IAED,MAAM,UAAU,GACf,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1G,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAAA,CACtD;AAED,SAAS,aAAa,CAAC,UAAuB,EAA+B;IAC5E,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,OAAO,CAAC;IAC7C,MAAM,KAAK,GAAG,UAAU,EAAE,KAAK,IAAI,SAAS,CAAC;IAC7C,IAAI,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,WAAW;QAAE,OAAO,MAAM,CAAC;IAC7D,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACpC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,eAAe,CAAC,UAAuB,EAAW;IAC1D,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAAA,CAC9D;AAkBD,SAAS,gBAAgB,CAAC,KAAmB,EAAgB;IAC5D,MAAM,MAAM,GAAoD;QAC/D,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE;QACvD,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE;QAC7D,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,GAAG,EAAE,EAAE;KACvD,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,IAAI,OAAO,CAAC;QAElD,IAAI,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACF,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CACvD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAC5D,CAAC;AAAA,CACF;AAED,SAAS,iBAAiB,CACzB,MAAoB,EACpB,OAGC,EACQ;IACT,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAEnD,MAAM,WAAW,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAClF,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACnG,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,cAAc,EAAE,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,kBAAkB,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACnF,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;gBACvC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,OAAO,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YACjF,CAAC;QACF,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CACxB;AAED,SAAS,qBAAqB,CAAC,CAAS,EAAE,WAAoC,EAA0B;IACvG,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACjC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC3B,CAAC;IAED,OAAO,SAAS,CAAC;AAAA,CACjB;AAED,SAAS,oBAAoB,CAAC,CAAS,EAAE,UAAuB,EAAU;IACzE,IAAI,UAAU,EAAE,CAAC;QAChB,MAAM,SAAS,GAAG,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QAC9C,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAC/D,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QAClE,OAAO,GAAG,SAAS,IAAI,SAAS,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAAA,CAC5B;AAED,MAAM,UAAU,iBAAiB,CAChC,WAA0C,EAC1C,WAAoC,EAC3B;IACT,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,sCAAsC;IACtC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAgC,CAAC;IAC3D,MAAM,gBAAgB,GAAyB,EAAE,CAAC;IAElD,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACb,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACP,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;IACF,CAAC;IAED,+CAA+C;IAC/C,KAAK,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,UAAU,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;QAC1C,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC;QAC1D,KAAK,CAAC,IAAI,CACT,KAAK,CAAC,EAAE,CACP,KAAK,EACL,OAAO,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,KAAG,CAAC,IAAI,oBAAoB,CAAC,KAAK,CAAC,UAAU,EAAE,qBAAqB,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,EAAE,CACjI,CACD,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;gBACjB,KAAK,CAAC,IAAI,CACT,KAAK,CAAC,EAAE,CACP,KAAK,EACL,OAAO,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,KAAG,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,YAAY,CACrJ,CACD,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACZ,MAAM,aAAa,GAAG,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;YAC/F,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,aAAa,EAAE,CAAC,CAAC,CAAC;YACrF,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpF,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClF,CAAC;IACF,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CACxB;AAsBD,MAAM,UAAU,mBAAmB,CAClC,IAAyB,EACzB,OAIC,EACM;IACP,MAAM,WAAW,GAAG,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IAC3E,MAAM,eAAe,GAAG,WAAW,IAAI,OAAO,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAClF,IAAI,CAAC,WAAW,IAAI,CAAC,eAAe,EAAE,CAAC;QACtC,OAAO;IACR,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAChD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IAEzC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,KAAK,GAAe,WAAW,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;IACtG,MAAM,iBAAiB,GAAG,CAAC,KAAe,EAAE,WAAgC,EAAU,EAAE,CAAC;QACxF,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAClF,IAAI,WAAW,EAAE,IAAI,KAAK,KAAK,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAAA,CACjD,CAAC;IACF,MAAM,gBAAgB,GAAG,CACxB,IAAY,EACZ,aAAqB,EACrB,YAAY,GAAG,aAAa,EAC5B,KAAK,GAAe,WAAW,EACxB,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,IAAI,cAAc,CACjC,GAAG,EAAE,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,aAAa,EAAE,EACvD,GAAG,EAAE,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,YAAY,EAAE,EACtD,IAAI,CAAC,UAAU,EAAE,EACjB,CAAC,EACD,CAAC,CACD,CAAC;QACF,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAChC,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAAA,CACtC,CAAC;IAEF,MAAM,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;IAChD,MAAM,aAAa,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC;IAClD,MAAM,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;IAChD,MAAM,UAAU,GACf,OAAO,EAAE,UAAU;QACnB,cAAc;aACZ,aAAa,EAAE;aACf,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC;aACrD,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;YACpB,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,WAAW,EAAE,SAAS,CAAC,WAAW;SAClC,CAAC,CAAC,CAAC;IACN,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;IAClD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACpC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YAC1B,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;QACvD,CAAC;IACF,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACtB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QACnD,CAAC;IACF,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;QAC5C,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACvB,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;IACD,KAAK,MAAM,WAAW,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QAC/C,IAAI,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;YACtD,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;QACjE,CAAC;IACF,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QACjB,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtC,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,cAAc,CAAC,cAAc,EAAE,CAAC;QACjG,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC;QACzC,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QAE9D,MAAM,UAAU,GACf,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;QAElG,oEAAoE;QACpE,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAChE,SAAS,CAAC,IAAI,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;YAC/B,SAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,eAAe,GAAa,CAAC,GAAG,SAAS,CAAC,CAAC;YACjD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,eAAe,CAAC,IAAI,CACnB,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CACxF,CAAC;YACH,CAAC;YACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,eAAe,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,eAAe,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,eAAe,CAAC,IAAI,CAAC,GAAG,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC;YAChE,CAAC;YACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,eAAe,CAAC,IAAI,CACnB,GAAG,YAAY,CAAC,GAAG,CAClB,CAAC,WAAW,EAAE,EAAE,CACf,WAAW,CAAC,IAAI,IAAI,mBAAmB,CAAC,WAAW,CAAC,UAAW,EAAE,WAAW,CAAC,UAAU,CAAC,CACzF,CACD,CAAC;YACH,CAAC;YACD,aAAa,CAAC,QAAQ,CACrB,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CACxG,CAAC;QACH,CAAC;aAAM,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YAC7B,aAAa,CAAC,QAAQ,CACrB,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAClG,CAAC;QACH,CAAC;aAAM,CAAC;YACP,gBAAgB,CAAC,WAAW,EAAE,iBAAiB,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;YAC1F,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtC,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1G,MAAM,kBAAkB,GAAG,iBAAiB,CAC3C,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EACrF,EAAE,IAAI,EAAE,KAAK,EAAE,CACf,CAAC;gBACF,gBAAgB,CAAC,SAAS,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;YAC9D,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,MAAM,GAAG,gBAAgB,CAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAC/E,CAAC;gBACF,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,EAAE;oBAC3C,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;oBAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC;iBACrE,CAAC,CAAC;gBACH,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC9E,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC;YACzD,CAAC;YAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,gBAAgB,CAC9B,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAC3F,CAAC;gBACF,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtE,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,EAAE;oBAC9C,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;wBACrB,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC/C,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAAA,CACrE;oBACD,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;wBAC5B,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC/C,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAAA,CACrE;iBACD,CAAC,CAAC;gBACH,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC9F,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,EAAE,YAAY,CAAC,CAAC;YAC9D,CAAC;YAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;gBAC5C,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,EAAE;oBACzC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,IAAI,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC/E,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAC3B,IAAI,CAAC,WAAW,IAAI,0BAA0B,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;iBACzF,CAAC,CAAC;gBACH,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC;gBACtF,gBAAgB,CAAC,YAAY,EAAE,oBAAoB,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;YAC5E,CAAC;YAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,gBAAgB,CAC9B,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;oBAClC,IAAI,EAAE,WAAW,CAAC,UAAW;oBAC7B,UAAU,EAAE,WAAW,CAAC,UAAU;iBAClC,CAAC,CAAC,CACH,CAAC;gBACF,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,EAAE;oBAC3C,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;oBAClD,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC;iBACrE,CAAC,CAAC;gBACH,MAAM,gBAAgB,GAAG,iBAAiB,CACzC,YAAY,CAAC,GAAG,CACf,CAAC,WAAW,EAAE,EAAE,CACf,WAAW,CAAC,IAAI,IAAI,mBAAmB,CAAC,WAAW,CAAC,UAAW,EAAE,WAAW,CAAC,UAAU,CAAC,CACzF,CACD,CAAC;gBACF,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC;YACzD,CAAC;QACF,CAAC;QAED,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;gBACvC,aAAa,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtE,CAAC;QACF,CAAC;IACF,CAAC;IAED,IAAI,eAAe,EAAE,CAAC;QACrB,MAAM,gBAAgB,GAAG,YAAY,CAAC,WAAW,CAAC;QAClD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YACtE,aAAa,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC,KAAK,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvG,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,iBAAiB,GAAG,aAAa,CAAC,WAAW,CAAC;QACpD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,YAAY,GAAG,iBAAiB,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;YACvE,aAAa,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC,KAAK,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACxG,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,oBAAoB,GAAyB,EAAE,CAAC;QACtD,MAAM,eAAe,GAAG,cAAc,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC;QAC9D,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;gBACrC,oBAAoB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACtF,CAAC;QACF,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAClD,MAAM,kBAAkB,GAAG,eAAe,CAAC,qBAAqB,EAAE,CAAC;QACnE,oBAAoB,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;QACjD,oBAAoB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,oCAAoC,CAAC,eAAe,CAAC,CAAC,CAAC;QAEzF,MAAM,mBAAmB,GAAG,eAAe,CAAC,sBAAsB,EAAE,CAAC;QACrE,oBAAoB,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,CAAC;QAElD,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,YAAY,GAAG,iBAAiB,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;YAC1E,aAAa,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,oBAAoB,CAAC,KAAK,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACxG,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,gBAAgB,GAAG,YAAY,CAAC,WAAW,CAAC;QAClD,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YACtE,aAAa,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC,KAAK,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACvG,aAAa,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;IACF,CAAC;AAAA,CACD","sourcesContent":["/**\n * Startup/reload resource listing: path and source-label formatting, scope\n * grouping, diagnostics rendering, and the [Resources]/[Skills]/… sections\n * shown in the chat. Extracted from interactive-mode.ts; everything here is\n * either pure formatting or rendering into a container passed via deps.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { type Container, Spacer, Text } from \"@kolisachint/hoocode-tui\";\nimport type { ExtensionRunner } from \"../../core/extensions/index.js\";\nimport type { PromptTemplate } from \"../../core/prompt-templates.js\";\nimport type { ResourceDiagnostic, ResourceLoader } from \"../../core/resource-loader.js\";\nimport type { SourceInfo } from \"../../core/source-info.js\";\nimport { parseGitUrl } from \"../../utils/git.js\";\nimport { getCwdRelativePath } from \"../../utils/paths.js\";\nimport { type ThemeColor, theme } from \"./theme/theme.js\";\n\n// ============================================================================\n// Expandable sections\n// ============================================================================\n\nexport interface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj;\n}\n\nexport class ExpandableText extends Text implements Expandable {\n\tconstructor(\n\t\tprivate collapsed: () => string,\n\t\tprivate expanded: () => string,\n\t\tinitiallyExpanded: boolean,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t) {\n\t\tsuper(initiallyExpanded ? expanded() : collapsed(), paddingX, paddingY);\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.setText(expanded ? this.expanded() : this.collapsed());\n\t}\n}\n\n// ============================================================================\n// Path and source-label formatting\n// ============================================================================\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t}\n\n\treturn result;\n}\n\nexport function formatExtensionDisplayPath(extensionPath: string): string {\n\tlet result = formatDisplayPath(extensionPath);\n\tresult = result.replace(/\\/index\\.ts$/, \"\").replace(/\\/index\\.js$/, \"\");\n\treturn result;\n}\n\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = fullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = fullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nfunction getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nfunction getCompactExtensionLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tif (!isPackageSource(sourceInfo)) {\n\t\treturn getCompactPathLabel(resourcePath, sourceInfo);\n\t}\n\n\tconst sourceLabel = getCompactPackageSourceLabel(sourceInfo);\n\tif (!sourceLabel) {\n\t\treturn getCompactPathLabel(resourcePath, sourceInfo);\n\t}\n\n\tconst shortPath = getShortPath(resourcePath, sourceInfo).replace(/\\\\/g, \"/\");\n\tconst packagePath = shortPath.startsWith(\"extensions/\") ? shortPath.slice(\"extensions/\".length) : shortPath;\n\tconst parsedPath = path.posix.parse(packagePath);\n\n\tif (parsedPath.name === \"index\") {\n\t\treturn !parsedPath.dir || parsedPath.dir === \".\" ? sourceLabel : `${sourceLabel}:${parsedPath.dir}`;\n\t}\n\n\treturn `${sourceLabel}:${packagePath}`;\n}\n\nfunction getCompactDisplayPathSegments(resourcePath: string): string[] {\n\treturn formatDisplayPath(resourcePath)\n\t\t.replace(/\\\\/g, \"/\")\n\t\t.split(\"/\")\n\t\t.filter((segment) => segment.length > 0 && segment !== \"~\");\n}\n\nfunction getCompactNonPackageExtensionLabel(\n\tresourcePath: string,\n\tindex: number,\n\tallPaths: Array<{ path: string; segments: string[] }>,\n): string {\n\tconst segments = allPaths[index]?.segments;\n\tif (!segments || segments.length === 0) {\n\t\treturn getCompactPathLabel(resourcePath);\n\t}\n\n\tfor (let segmentCount = 1; segmentCount <= segments.length; segmentCount += 1) {\n\t\tconst candidate = segments.slice(-segmentCount).join(\"/\");\n\t\tconst isUnique = allPaths.every((item, itemIndex) => {\n\t\t\tif (itemIndex === index) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn item.segments.slice(-segmentCount).join(\"/\") !== candidate;\n\t\t});\n\n\t\tif (isUnique) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\n\treturn segments.join(\"/\");\n}\n\nexport function getCompactExtensionLabels(\n\textensions: Array<{ path: string; sourceInfo?: SourceInfo; displayName?: string }>,\n): string[] {\n\tconst nonPackageExtensions = extensions\n\t\t.map((extension) => {\n\t\t\tconst segments = getCompactDisplayPathSegments(extension.path);\n\t\t\tconst lastSegment = segments[segments.length - 1];\n\t\t\tif (segments.length > 1 && (lastSegment === \"index.ts\" || lastSegment === \"index.js\")) {\n\t\t\t\tsegments.pop();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpath: extension.path,\n\t\t\t\tsourceInfo: extension.sourceInfo,\n\t\t\t\tsegments,\n\t\t\t};\n\t\t})\n\t\t.filter((extension) => !isPackageSource(extension.sourceInfo));\n\n\treturn extensions.map((extension) => {\n\t\tif (extension.displayName) {\n\t\t\treturn extension.displayName;\n\t\t}\n\n\t\tif (isPackageSource(extension.sourceInfo)) {\n\t\t\treturn getCompactExtensionLabel(extension.path, extension.sourceInfo);\n\t\t}\n\n\t\tconst nonPackageIndex = nonPackageExtensions.findIndex((item) => item.path === extension.path);\n\t\tif (nonPackageIndex === -1) {\n\t\t\treturn getCompactPathLabel(extension.path, extension.sourceInfo);\n\t\t}\n\n\t\treturn getCompactNonPackageExtensionLabel(extension.path, nonPackageIndex, nonPackageExtensions);\n\t});\n}\n\nfunction getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nfunction getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nfunction isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n// ============================================================================\n// Scope grouping and diagnostics\n// ============================================================================\n\ninterface ScopedItem {\n\tpath: string;\n\tsourceInfo?: SourceInfo;\n\tdisplayName?: string;\n}\n\ninterface ScopeGroup {\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: ScopedItem[];\n\tpackages: Map<string, ScopedItem[]>;\n}\n\nfunction buildScopeGroups(items: ScopedItem[]): ScopeGroup[] {\n\tconst groups: Record<\"user\" | \"project\" | \"path\", ScopeGroup> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nfunction formatScopeGroups(\n\tgroups: ScopeGroup[],\n\toptions: {\n\t\tformatPath: (item: ScopedItem) => string;\n\t\tformatPackagePath: (item: ScopedItem, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nfunction formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` \"${name}\" collision:`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Loaded-resources listing\n// ============================================================================\n\n/** The slice of the interactive mode the resource listing renders into. */\nexport interface ResourceDisplayDeps {\n\tchatContainer: Container;\n\tgetCwd(): string;\n\tgetResourceLoader(): ResourceLoader;\n\tgetPromptTemplates(): ReadonlyArray<PromptTemplate>;\n\tgetExtensionRunner(): ExtensionRunner;\n\tgetActiveMode(): string;\n\tgetSubagentEnabled(): boolean;\n\tquietStartup(): boolean;\n\tverbose: boolean;\n\t/** Startup expansion state for the collapsible sections. */\n\tisExpanded(): boolean;\n\tgetBuiltInCommandConflictDiagnostics(extensionRunner: ExtensionRunner): ResourceDiagnostic[];\n}\n\nexport function showLoadedResources(\n\tdeps: ResourceDisplayDeps,\n\toptions?: {\n\t\textensions?: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tforce?: boolean;\n\t\tshowDiagnosticsWhenQuiet?: boolean;\n\t},\n): void {\n\tconst showListing = options?.force || deps.verbose || !deps.quietStartup();\n\tconst showDiagnostics = showListing || options?.showDiagnosticsWhenQuiet === true;\n\tif (!showListing && !showDiagnostics) {\n\t\treturn;\n\t}\n\n\tconst resourceLoader = deps.getResourceLoader();\n\tconst chatContainer = deps.chatContainer;\n\n\tconst sectionHeader = (name: string, color: ThemeColor = \"mdHeading\") => theme.fg(color, `[${name}]`);\n\tconst formatCompactList = (items: string[], listOptions?: { sort?: boolean }): string => {\n\t\tconst labels = items.map((item) => item.trim()).filter((item) => item.length > 0);\n\t\tif (listOptions?.sort !== false) {\n\t\t\tlabels.sort((a, b) => a.localeCompare(b));\n\t\t}\n\t\treturn theme.fg(\"dim\", ` ${labels.join(\", \")}`);\n\t};\n\tconst addLoadedSection = (\n\t\tname: string,\n\t\tcollapsedBody: string,\n\t\texpandedBody = collapsedBody,\n\t\tcolor: ThemeColor = \"mdHeading\",\n\t): void => {\n\t\tconst section = new ExpandableText(\n\t\t\t() => `${sectionHeader(name, color)}\\n${collapsedBody}`,\n\t\t\t() => `${sectionHeader(name, color)}\\n${expandedBody}`,\n\t\t\tdeps.isExpanded(),\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t\tchatContainer.addChild(section);\n\t\tchatContainer.addChild(new Spacer(1));\n\t};\n\n\tconst skillsResult = resourceLoader.getSkills();\n\tconst promptsResult = resourceLoader.getPrompts();\n\tconst themesResult = resourceLoader.getThemes();\n\tconst extensions =\n\t\toptions?.extensions ??\n\t\tresourceLoader\n\t\t\t.getExtensions()\n\t\t\t.extensions.filter((extension) => !extension.internal)\n\t\t\t.map((extension) => ({\n\t\t\t\tpath: extension.path,\n\t\t\t\tsourceInfo: extension.sourceInfo,\n\t\t\t\tdisplayName: extension.displayName,\n\t\t\t}));\n\tconst sourceInfos = new Map<string, SourceInfo>();\n\tfor (const extension of extensions) {\n\t\tif (extension.sourceInfo) {\n\t\t\tsourceInfos.set(extension.path, extension.sourceInfo);\n\t\t}\n\t}\n\tfor (const skill of skillsResult.skills) {\n\t\tif (skill.sourceInfo) {\n\t\t\tsourceInfos.set(skill.filePath, skill.sourceInfo);\n\t\t}\n\t}\n\tfor (const prompt of promptsResult.prompts) {\n\t\tif (prompt.sourceInfo) {\n\t\t\tsourceInfos.set(prompt.filePath, prompt.sourceInfo);\n\t\t}\n\t}\n\tfor (const loadedTheme of themesResult.themes) {\n\t\tif (loadedTheme.sourcePath && loadedTheme.sourceInfo) {\n\t\t\tsourceInfos.set(loadedTheme.sourcePath, loadedTheme.sourceInfo);\n\t\t}\n\t}\n\n\tif (showListing) {\n\t\tchatContainer.addChild(new Spacer(1));\n\n\t\tconst { agentsFiles: contextFiles, warnings: contextWarnings } = resourceLoader.getAgentsFiles();\n\t\tconst skills = skillsResult.skills;\n\t\tconst templates = deps.getPromptTemplates();\n\t\tconst loadedThemes = themesResult.themes;\n\t\tconst customThemes = loadedThemes.filter((t) => t.sourcePath);\n\n\t\tconst totalItems =\n\t\t\tcontextFiles.length + skills.length + templates.length + extensions.length + customThemes.length;\n\n\t\t// Meta items: active mode and subagent system prompt (always shown)\n\t\tconst metaItems: string[] = [];\n\t\tconst rawMode = deps.getActiveMode().replace(\" + subagent\", \"\");\n\t\tmetaItems.push(`mode/${rawMode}`);\n\t\tif (deps.getSubagentEnabled()) {\n\t\t\tmetaItems.push(\"subagent_system_prompt\");\n\t\t}\n\n\t\tif (totalItems > 0 && totalItems <= 5) {\n\t\t\tconst allCompactItems: string[] = [...metaItems];\n\t\t\tif (contextFiles.length > 0) {\n\t\t\t\tallCompactItems.push(\n\t\t\t\t\t...contextFiles.map((contextFile) => formatContextPath(contextFile.path, deps.getCwd())),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (skills.length > 0) {\n\t\t\t\tallCompactItems.push(...skills.map((skill) => skill.name));\n\t\t\t}\n\t\t\tif (templates.length > 0) {\n\t\t\t\tallCompactItems.push(...templates.map((template) => `/${template.name}`));\n\t\t\t}\n\t\t\tif (extensions.length > 0) {\n\t\t\t\tallCompactItems.push(...getCompactExtensionLabels(extensions));\n\t\t\t}\n\t\t\tif (customThemes.length > 0) {\n\t\t\t\tallCompactItems.push(\n\t\t\t\t\t...customThemes.map(\n\t\t\t\t\t\t(loadedTheme) =>\n\t\t\t\t\t\t\tloadedTheme.name ?? getCompactPathLabel(loadedTheme.sourcePath!, loadedTheme.sourceInfo),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tchatContainer.addChild(\n\t\t\t\tnew Text(`${theme.fg(\"mdHeading\", \"[Resources]\")} ${theme.fg(\"dim\", allCompactItems.join(\", \"))}`, 0, 0),\n\t\t\t);\n\t\t} else if (totalItems === 0) {\n\t\t\tchatContainer.addChild(\n\t\t\t\tnew Text(`${theme.fg(\"mdHeading\", \"[Resources]\")} ${theme.fg(\"dim\", metaItems.join(\", \"))}`, 0, 0),\n\t\t\t);\n\t\t} else {\n\t\t\taddLoadedSection(\"Resources\", formatCompactList(metaItems), formatCompactList(metaItems));\n\t\t\tif (contextFiles.length > 0) {\n\t\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t\t\tconst contextList = contextFiles.map((f) => theme.fg(\"dim\", ` ${formatDisplayPath(f.path)}`)).join(\"\\n\");\n\t\t\t\tconst contextCompactList = formatCompactList(\n\t\t\t\t\tcontextFiles.map((contextFile) => formatContextPath(contextFile.path, deps.getCwd())),\n\t\t\t\t\t{ sort: false },\n\t\t\t\t);\n\t\t\t\taddLoadedSection(\"Context\", contextCompactList, contextList);\n\t\t\t}\n\n\t\t\tif (skills.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(\n\t\t\t\t\tskills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })),\n\t\t\t\t);\n\t\t\t\tconst skillList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => formatDisplayPath(item.path),\n\t\t\t\t\tformatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),\n\t\t\t\t});\n\t\t\t\tconst skillCompactList = formatCompactList(skills.map((skill) => skill.name));\n\t\t\t\taddLoadedSection(\"Skills\", skillCompactList, skillList);\n\t\t\t}\n\n\t\t\tif (templates.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(\n\t\t\t\t\ttemplates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })),\n\t\t\t\t);\n\t\t\t\tconst templateByPath = new Map(templates.map((t) => [t.filePath, t]));\n\t\t\t\tconst templateList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => {\n\t\t\t\t\t\tconst template = templateByPath.get(item.path);\n\t\t\t\t\t\treturn template ? `/${template.name}` : formatDisplayPath(item.path);\n\t\t\t\t\t},\n\t\t\t\t\tformatPackagePath: (item) => {\n\t\t\t\t\t\tconst template = templateByPath.get(item.path);\n\t\t\t\t\t\treturn template ? `/${template.name}` : formatDisplayPath(item.path);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tconst promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));\n\t\t\t\taddLoadedSection(\"Prompts\", promptCompactList, templateList);\n\t\t\t}\n\n\t\t\tif (extensions.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(extensions);\n\t\t\t\tconst extList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => item.displayName ?? formatExtensionDisplayPath(item.path),\n\t\t\t\t\tformatPackagePath: (item) =>\n\t\t\t\t\t\titem.displayName ?? formatExtensionDisplayPath(getShortPath(item.path, item.sourceInfo)),\n\t\t\t\t});\n\t\t\t\tconst extensionCompactList = formatCompactList(getCompactExtensionLabels(extensions));\n\t\t\t\taddLoadedSection(\"Extensions\", extensionCompactList, extList, \"mdHeading\");\n\t\t\t}\n\n\t\t\tif (customThemes.length > 0) {\n\t\t\t\tconst groups = buildScopeGroups(\n\t\t\t\t\tcustomThemes.map((loadedTheme) => ({\n\t\t\t\t\t\tpath: loadedTheme.sourcePath!,\n\t\t\t\t\t\tsourceInfo: loadedTheme.sourceInfo,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t\tconst themeList = formatScopeGroups(groups, {\n\t\t\t\t\tformatPath: (item) => formatDisplayPath(item.path),\n\t\t\t\t\tformatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),\n\t\t\t\t});\n\t\t\t\tconst themeCompactList = formatCompactList(\n\t\t\t\t\tcustomThemes.map(\n\t\t\t\t\t\t(loadedTheme) =>\n\t\t\t\t\t\t\tloadedTheme.name ?? getCompactPathLabel(loadedTheme.sourcePath!, loadedTheme.sourceInfo),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\taddLoadedSection(\"Themes\", themeCompactList, themeList);\n\t\t\t}\n\t\t}\n\n\t\tif (contextWarnings.length > 0) {\n\t\t\tfor (const warning of contextWarnings) {\n\t\t\t\tchatContainer.addChild(new Text(theme.fg(\"warning\", warning), 0, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tif (showDiagnostics) {\n\t\tconst skillDiagnostics = skillsResult.diagnostics;\n\t\tif (skillDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(skillDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Skill conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst promptDiagnostics = promptsResult.diagnostics;\n\t\tif (promptDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(promptDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Prompt conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst extensionDiagnostics: ResourceDiagnostic[] = [];\n\t\tconst extensionErrors = resourceLoader.getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tfor (const error of extensionErrors) {\n\t\t\t\textensionDiagnostics.push({ type: \"error\", message: error.error, path: error.path });\n\t\t\t}\n\t\t}\n\n\t\tconst extensionRunner = deps.getExtensionRunner();\n\t\tconst commandDiagnostics = extensionRunner.getCommandDiagnostics();\n\t\textensionDiagnostics.push(...commandDiagnostics);\n\t\textensionDiagnostics.push(...deps.getBuiltInCommandConflictDiagnostics(extensionRunner));\n\n\t\tconst shortcutDiagnostics = extensionRunner.getShortcutDiagnostics();\n\t\textensionDiagnostics.push(...shortcutDiagnostics);\n\n\t\tif (extensionDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(extensionDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Extension issues]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst themeDiagnostics = themesResult.diagnostics;\n\t\tif (themeDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(themeDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Theme conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"resource-display.js","sourceRoot":"","sources":["../../../src/modes/interactive/resource-display.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Startup/reload resource listing: path and source-label formatting, scope\n * grouping, diagnostics rendering, and the [Resources]/[Skills]/… sections\n * shown in the chat. Extracted from interactive-mode.ts; everything here is\n * either pure formatting or rendering into a container passed via deps.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { type Container, Spacer, Text, visibleWidth } from \"@kolisachint/hoocode-tui\";\nimport { getExtensionMcpServers } from \"../../core/extension-mcp-servers.js\";\nimport type { ExtensionRunner } from \"../../core/extensions/index.js\";\nimport type { PromptTemplate } from \"../../core/prompt-templates.js\";\nimport type { ResourceDiagnostic, ResourceLoader } from \"../../core/resource-loader.js\";\nimport type { SourceInfo } from \"../../core/source-info.js\";\nimport { parseGitUrl } from \"../../utils/git.js\";\nimport { getCwdRelativePath } from \"../../utils/paths.js\";\nimport { BRAND_MARK, BRAND_NAME, CATEGORY_GLYPH, type CategoryKey } from \"./brand.js\";\nimport { appKeyLabel } from \"./components/keybinding-hints.js\";\nimport { type ThemeColor, theme } from \"./theme/theme.js\";\n\n// ============================================================================\n// Expandable sections\n// ============================================================================\n\nexport interface Expandable {\n\tsetExpanded(expanded: boolean): void;\n}\n\nexport function isExpandable(obj: unknown): obj is Expandable {\n\treturn typeof obj === \"object\" && obj !== null && \"setExpanded\" in obj;\n}\n\nexport class ExpandableText extends Text implements Expandable {\n\tconstructor(\n\t\tprivate collapsed: () => string,\n\t\tprivate expanded: () => string,\n\t\tinitiallyExpanded: boolean,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t) {\n\t\tsuper(initiallyExpanded ? expanded() : collapsed(), paddingX, paddingY);\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.setText(expanded ? this.expanded() : this.collapsed());\n\t}\n}\n\n// ============================================================================\n// Path and source-label formatting\n// ============================================================================\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t}\n\n\treturn result;\n}\n\nexport function formatExtensionDisplayPath(extensionPath: string): string {\n\tlet result = formatDisplayPath(extensionPath);\n\tresult = result.replace(/\\/index\\.ts$/, \"\").replace(/\\/index\\.js$/, \"\");\n\treturn result;\n}\n\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = fullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = fullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nfunction getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nfunction getCompactExtensionLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tif (!isPackageSource(sourceInfo)) {\n\t\treturn getCompactPathLabel(resourcePath, sourceInfo);\n\t}\n\n\tconst sourceLabel = getCompactPackageSourceLabel(sourceInfo);\n\tif (!sourceLabel) {\n\t\treturn getCompactPathLabel(resourcePath, sourceInfo);\n\t}\n\n\tconst shortPath = getShortPath(resourcePath, sourceInfo).replace(/\\\\/g, \"/\");\n\tconst packagePath = shortPath.startsWith(\"extensions/\") ? shortPath.slice(\"extensions/\".length) : shortPath;\n\tconst parsedPath = path.posix.parse(packagePath);\n\n\tif (parsedPath.name === \"index\") {\n\t\treturn !parsedPath.dir || parsedPath.dir === \".\" ? sourceLabel : `${sourceLabel}:${parsedPath.dir}`;\n\t}\n\n\treturn `${sourceLabel}:${packagePath}`;\n}\n\nfunction getCompactDisplayPathSegments(resourcePath: string): string[] {\n\treturn formatDisplayPath(resourcePath)\n\t\t.replace(/\\\\/g, \"/\")\n\t\t.split(\"/\")\n\t\t.filter((segment) => segment.length > 0 && segment !== \"~\");\n}\n\nfunction getCompactNonPackageExtensionLabel(\n\tresourcePath: string,\n\tindex: number,\n\tallPaths: Array<{ path: string; segments: string[] }>,\n): string {\n\tconst segments = allPaths[index]?.segments;\n\tif (!segments || segments.length === 0) {\n\t\treturn getCompactPathLabel(resourcePath);\n\t}\n\n\tfor (let segmentCount = 1; segmentCount <= segments.length; segmentCount += 1) {\n\t\tconst candidate = segments.slice(-segmentCount).join(\"/\");\n\t\tconst isUnique = allPaths.every((item, itemIndex) => {\n\t\t\tif (itemIndex === index) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn item.segments.slice(-segmentCount).join(\"/\") !== candidate;\n\t\t});\n\n\t\tif (isUnique) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\n\treturn segments.join(\"/\");\n}\n\nexport function getCompactExtensionLabels(\n\textensions: Array<{ path: string; sourceInfo?: SourceInfo; displayName?: string }>,\n): string[] {\n\tconst nonPackageExtensions = extensions\n\t\t.map((extension) => {\n\t\t\tconst segments = getCompactDisplayPathSegments(extension.path);\n\t\t\tconst lastSegment = segments[segments.length - 1];\n\t\t\tif (segments.length > 1 && (lastSegment === \"index.ts\" || lastSegment === \"index.js\")) {\n\t\t\t\tsegments.pop();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tpath: extension.path,\n\t\t\t\tsourceInfo: extension.sourceInfo,\n\t\t\t\tsegments,\n\t\t\t};\n\t\t})\n\t\t.filter((extension) => !isPackageSource(extension.sourceInfo));\n\n\treturn extensions.map((extension) => {\n\t\tif (extension.displayName) {\n\t\t\treturn extension.displayName;\n\t\t}\n\n\t\tif (isPackageSource(extension.sourceInfo)) {\n\t\t\treturn getCompactExtensionLabel(extension.path, extension.sourceInfo);\n\t\t}\n\n\t\tconst nonPackageIndex = nonPackageExtensions.findIndex((item) => item.path === extension.path);\n\t\tif (nonPackageIndex === -1) {\n\t\t\treturn getCompactPathLabel(extension.path, extension.sourceInfo);\n\t\t}\n\n\t\treturn getCompactNonPackageExtensionLabel(extension.path, nonPackageIndex, nonPackageExtensions);\n\t});\n}\n\nfunction getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nfunction getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nfunction isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n// ============================================================================\n// Scope grouping and diagnostics\n// ============================================================================\n\ninterface ScopedItem {\n\tpath: string;\n\tsourceInfo?: SourceInfo;\n\tdisplayName?: string;\n}\n\ninterface ScopeGroup {\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: ScopedItem[];\n\tpackages: Map<string, ScopedItem[]>;\n}\n\nfunction buildScopeGroups(items: ScopedItem[]): ScopeGroup[] {\n\tconst groups: Record<\"user\" | \"project\" | \"path\", ScopeGroup> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nfunction formatScopeGroups(\n\tgroups: ScopeGroup[],\n\toptions: {\n\t\tformatPath: (item: ScopedItem) => string;\n\t\tformatPackagePath: (item: ScopedItem, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nfunction formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` \"${name}\" collision:`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Loaded-resources listing\n// ============================================================================\n\n/** The slice of the interactive mode the resource listing renders into. */\nexport interface ResourceDisplayDeps {\n\tchatContainer: Container;\n\tgetCwd(): string;\n\tgetResourceLoader(): ResourceLoader;\n\tgetPromptTemplates(): ReadonlyArray<PromptTemplate>;\n\tgetExtensionRunner(): ExtensionRunner;\n\tgetActiveMode(): string;\n\tgetSubagentEnabled(): boolean;\n\tquietStartup(): boolean;\n\tverbose: boolean;\n\t/** Startup expansion state for the collapsible sections. */\n\tisExpanded(): boolean;\n\tgetBuiltInCommandConflictDiagnostics(extensionRunner: ExtensionRunner): ResourceDiagnostic[];\n}\n\nexport function showLoadedResources(\n\tdeps: ResourceDisplayDeps,\n\toptions?: {\n\t\textensions?: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tforce?: boolean;\n\t\tshowDiagnosticsWhenQuiet?: boolean;\n\t},\n): void {\n\tconst showListing = options?.force || deps.verbose || !deps.quietStartup();\n\tconst showDiagnostics = showListing || options?.showDiagnosticsWhenQuiet === true;\n\tif (!showListing && !showDiagnostics) {\n\t\treturn;\n\t}\n\n\tconst resourceLoader = deps.getResourceLoader();\n\tconst chatContainer = deps.chatContainer;\n\n\tconst sectionHeader = (name: string, color: ThemeColor = \"mdHeading\") => theme.fg(color, `[${name}]`);\n\tconst formatCompactList = (items: string[], listOptions?: { sort?: boolean }): string => {\n\t\tconst labels = items.map((item) => item.trim()).filter((item) => item.length > 0);\n\t\tif (listOptions?.sort !== false) {\n\t\t\tlabels.sort((a, b) => a.localeCompare(b));\n\t\t}\n\t\treturn theme.fg(\"dim\", ` ${labels.join(\", \")}`);\n\t};\n\n\tconst skillsResult = resourceLoader.getSkills();\n\tconst promptsResult = resourceLoader.getPrompts();\n\tconst themesResult = resourceLoader.getThemes();\n\tconst extensions =\n\t\toptions?.extensions ??\n\t\tresourceLoader\n\t\t\t.getExtensions()\n\t\t\t.extensions.filter((extension) => !extension.internal)\n\t\t\t.map((extension) => ({\n\t\t\t\tpath: extension.path,\n\t\t\t\tsourceInfo: extension.sourceInfo,\n\t\t\t\tdisplayName: extension.displayName,\n\t\t\t}));\n\tconst sourceInfos = new Map<string, SourceInfo>();\n\tfor (const extension of extensions) {\n\t\tif (extension.sourceInfo) {\n\t\t\tsourceInfos.set(extension.path, extension.sourceInfo);\n\t\t}\n\t}\n\tfor (const skill of skillsResult.skills) {\n\t\tif (skill.sourceInfo) {\n\t\t\tsourceInfos.set(skill.filePath, skill.sourceInfo);\n\t\t}\n\t}\n\tfor (const prompt of promptsResult.prompts) {\n\t\tif (prompt.sourceInfo) {\n\t\t\tsourceInfos.set(prompt.filePath, prompt.sourceInfo);\n\t\t}\n\t}\n\tfor (const loadedTheme of themesResult.themes) {\n\t\tif (loadedTheme.sourcePath && loadedTheme.sourceInfo) {\n\t\t\tsourceInfos.set(loadedTheme.sourcePath, loadedTheme.sourceInfo);\n\t\t}\n\t}\n\n\tif (showListing) {\n\t\tchatContainer.addChild(new Spacer(1));\n\n\t\tconst { agentsFiles: contextFiles, warnings: contextWarnings } = resourceLoader.getAgentsFiles();\n\t\tconst skills = skillsResult.skills;\n\t\tconst templates = deps.getPromptTemplates();\n\t\tconst loadedThemes = themesResult.themes;\n\t\tconst customThemes = loadedThemes.filter((t) => t.sourcePath);\n\t\tconst agentPaths = resourceLoader.getAgentPaths();\n\t\tconst mcpServerCount = getExtensionMcpServers().reduce((n, e) => n + Object.keys(e.mcpServers).length, 0);\n\t\t// Plugins register their synthetic extension factory as `plugin:<id>`;\n\t\t// split them out so plugins and code extensions each get their own count.\n\t\t// (displayName is absent from the options-provided extension shape, so read\n\t\t// it structurally.)\n\t\tconst displayNameOf = (e: object): string | undefined => {\n\t\t\tconst value = (e as { displayName?: unknown }).displayName;\n\t\t\treturn typeof value === \"string\" ? value : undefined;\n\t\t};\n\t\tconst pluginCount = extensions.filter((e) => displayNameOf(e)?.startsWith(\"plugin:\")).length;\n\t\tconst codeExtensionCount = extensions.length - pluginCount;\n\n\t\t// ── Ready header: brand mark + product + active mode ────────────────────\n\t\t// Answers \"what session is this\" in one line; the old mode/<x> +\n\t\t// subagent_system_prompt meta jargon lives in the expanded details.\n\t\tconst rawMode = deps.getActiveMode().replace(\" + subagent\", \"\");\n\t\tconst headerLine =\n\t\t\t`${theme.bold(theme.fg(\"accent\", BRAND_MARK))} ` +\n\t\t\t`${theme.bold(`${BRAND_NAME.toLowerCase()} ready`)} ` +\n\t\t\t`${theme.fg(\"dim\", \"·\")} ${theme.bold(theme.fg(\"accent\", rawMode.toUpperCase()))}` +\n\t\t\t(deps.getSubagentEnabled() ? theme.fg(\"dim\", \" · subagents on\") : \"\");\n\t\tchatContainer.addChild(new Text(headerLine, 0, 0));\n\n\t\t// ── Counted capability grid ──────────────────────────────────────────────\n\t\t// One cell per loaded capability class (glyph + count + label), so \"what\n\t\t// can this session do\" reads at a glance; names/paths sit one keypress\n\t\t// away in the details below. Cells pad to a common width, four per row.\n\t\tconst plural = (n: number, s: string) => (n === 1 ? s : `${s}s`);\n\t\tconst cells: Array<{ key: CategoryKey; count: number; label: string }> = [];\n\t\tif (skills.length > 0) cells.push({ key: \"skills\", count: skills.length, label: plural(skills.length, \"skill\") });\n\t\tif (templates.length > 0) {\n\t\t\tcells.push({ key: \"commands\", count: templates.length, label: plural(templates.length, \"command\") });\n\t\t}\n\t\tif (agentPaths.length > 0) {\n\t\t\tcells.push({ key: \"agents\", count: agentPaths.length, label: plural(agentPaths.length, \"agent\") });\n\t\t}\n\t\tif (mcpServerCount > 0) cells.push({ key: \"mcp\", count: mcpServerCount, label: \"MCP\" });\n\t\tif (pluginCount > 0) cells.push({ key: \"plugins\", count: pluginCount, label: plural(pluginCount, \"plugin\") });\n\t\tif (codeExtensionCount > 0) {\n\t\t\tcells.push({\n\t\t\t\tkey: \"extensions\",\n\t\t\t\tcount: codeExtensionCount,\n\t\t\t\tlabel: plural(codeExtensionCount, \"extension\"),\n\t\t\t});\n\t\t}\n\t\tif (customThemes.length > 0) {\n\t\t\tcells.push({ key: \"themes\", count: customThemes.length, label: plural(customThemes.length, \"theme\") });\n\t\t}\n\n\t\tif (cells.length > 0) {\n\t\t\tconst cellPlain = (c: (typeof cells)[number]) => `${CATEGORY_GLYPH[c.key]} ${c.count} ${c.label}`;\n\t\t\tconst cellWidth = Math.max(...cells.map((c) => visibleWidth(cellPlain(c)))) + 3;\n\t\t\tconst styledCell = (c: (typeof cells)[number]) => {\n\t\t\t\tconst pad = \" \".repeat(Math.max(0, cellWidth - visibleWidth(cellPlain(c))));\n\t\t\t\treturn (\n\t\t\t\t\t`${theme.fg(\"accent\", CATEGORY_GLYPH[c.key])} ` +\n\t\t\t\t\t`${theme.bold(String(c.count))} ${theme.fg(\"muted\", c.label)}${pad}`\n\t\t\t\t);\n\t\t\t};\n\t\t\tconst PER_ROW = 4;\n\t\t\tconst rows: string[] = [];\n\t\t\tfor (let i = 0; i < cells.length; i += PER_ROW) {\n\t\t\t\trows.push(\n\t\t\t\t\t` ${cells\n\t\t\t\t\t\t.slice(i, i + PER_ROW)\n\t\t\t\t\t\t.map(styledCell)\n\t\t\t\t\t\t.join(\"\")}`.trimEnd(),\n\t\t\t\t);\n\t\t\t}\n\t\t\tchatContainer.addChild(new Text(rows.join(\"\\n\"), 0, 0));\n\t\t} else {\n\t\t\tchatContainer.addChild(new Text(theme.fg(\"dim\", \" no project resources loaded\"), 0, 0));\n\t\t}\n\n\t\t// Context files stay visible in the summary — they shape every reply.\n\t\tif (contextFiles.length > 0) {\n\t\t\tconst names = contextFiles.map((f) => formatContextPath(f.path, deps.getCwd())).join(\", \");\n\t\t\tchatContainer.addChild(\n\t\t\t\tnew Text(` ${theme.fg(\"accent\", CATEGORY_GLYPH.context)} ${theme.fg(\"muted\", \"context\")} ${names}`, 0, 0),\n\t\t\t);\n\t\t}\n\n\t\t// ── Details: names + scope-grouped paths, one keypress away ─────────────\n\t\t// A single expandable holds every per-category listing; collapsed it is\n\t\t// just the hint line, so a resource-heavy project no longer buries the\n\t\t// prompt under a wall of names at launch.\n\t\tconst detailSections: string[] = [];\n\t\tconst metaItems = [`mode/${rawMode}`];\n\t\tif (deps.getSubagentEnabled()) metaItems.push(\"subagent_system_prompt\");\n\t\tdetailSections.push(`${sectionHeader(\"Resources\")}\\n${formatCompactList(metaItems)}`);\n\n\t\tif (contextFiles.length > 0) {\n\t\t\tconst contextList = contextFiles.map((f) => theme.fg(\"dim\", ` ${formatDisplayPath(f.path)}`)).join(\"\\n\");\n\t\t\tdetailSections.push(`${sectionHeader(\"Context\")}\\n${contextList}`);\n\t\t}\n\t\tif (skills.length > 0) {\n\t\t\tconst groups = buildScopeGroups(\n\t\t\t\tskills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })),\n\t\t\t);\n\t\t\tconst skillList = formatScopeGroups(groups, {\n\t\t\t\tformatPath: (item) => formatDisplayPath(item.path),\n\t\t\t\tformatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),\n\t\t\t});\n\t\t\tdetailSections.push(\n\t\t\t\t`${sectionHeader(\"Skills\")}\\n${formatCompactList(skills.map((skill) => skill.name))}\\n${skillList}`,\n\t\t\t);\n\t\t}\n\t\tif (templates.length > 0) {\n\t\t\tconst groups = buildScopeGroups(\n\t\t\t\ttemplates.map((template) => ({ path: template.filePath, sourceInfo: template.sourceInfo })),\n\t\t\t);\n\t\t\tconst templateByPath = new Map(templates.map((t) => [t.filePath, t]));\n\t\t\tconst formatTemplate = (item: { path: string }) => {\n\t\t\t\tconst template = templateByPath.get(item.path);\n\t\t\t\treturn template ? `/${template.name}` : formatDisplayPath(item.path);\n\t\t\t};\n\t\t\tconst templateList = formatScopeGroups(groups, {\n\t\t\t\tformatPath: formatTemplate,\n\t\t\t\tformatPackagePath: formatTemplate,\n\t\t\t});\n\t\t\tdetailSections.push(\n\t\t\t\t`${sectionHeader(\"Prompts\")}\\n${formatCompactList(templates.map((t) => `/${t.name}`))}\\n${templateList}`,\n\t\t\t);\n\t\t}\n\t\tif (extensions.length > 0) {\n\t\t\tconst groups = buildScopeGroups(extensions);\n\t\t\tconst extList = formatScopeGroups(groups, {\n\t\t\t\tformatPath: (item) => item.displayName ?? formatExtensionDisplayPath(item.path),\n\t\t\t\tformatPackagePath: (item) =>\n\t\t\t\t\titem.displayName ?? formatExtensionDisplayPath(getShortPath(item.path, item.sourceInfo)),\n\t\t\t});\n\t\t\tdetailSections.push(\n\t\t\t\t`${sectionHeader(\"Extensions\")}\\n${formatCompactList(getCompactExtensionLabels(extensions))}\\n${extList}`,\n\t\t\t);\n\t\t}\n\t\tif (customThemes.length > 0) {\n\t\t\tconst groups = buildScopeGroups(\n\t\t\t\tcustomThemes.map((loadedTheme) => ({\n\t\t\t\t\tpath: loadedTheme.sourcePath!,\n\t\t\t\t\tsourceInfo: loadedTheme.sourceInfo,\n\t\t\t\t})),\n\t\t\t);\n\t\t\tconst themeList = formatScopeGroups(groups, {\n\t\t\t\tformatPath: (item) => formatDisplayPath(item.path),\n\t\t\t\tformatPackagePath: (item) => getShortPath(item.path, item.sourceInfo),\n\t\t\t});\n\t\t\tdetailSections.push(`${sectionHeader(\"Themes\")}\\n${themeList}`);\n\t\t}\n\n\t\tif (detailSections.length > 0) {\n\t\t\tconst expandHint = theme.fg(\"dim\", ` ${appKeyLabel(\"app.tools.expand\")} details`);\n\t\t\tchatContainer.addChild(\n\t\t\t\tnew ExpandableText(\n\t\t\t\t\t() => expandHint,\n\t\t\t\t\t() => detailSections.join(\"\\n\\n\"),\n\t\t\t\t\tdeps.isExpanded(),\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (contextWarnings.length > 0) {\n\t\t\tfor (const warning of contextWarnings) {\n\t\t\t\tchatContainer.addChild(new Text(theme.fg(\"warning\", warning), 0, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\tif (showDiagnostics) {\n\t\tconst skillDiagnostics = skillsResult.diagnostics;\n\t\tif (skillDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(skillDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Skill conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst promptDiagnostics = promptsResult.diagnostics;\n\t\tif (promptDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(promptDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Prompt conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst extensionDiagnostics: ResourceDiagnostic[] = [];\n\t\tconst extensionErrors = resourceLoader.getExtensions().errors;\n\t\tif (extensionErrors.length > 0) {\n\t\t\tfor (const error of extensionErrors) {\n\t\t\t\textensionDiagnostics.push({ type: \"error\", message: error.error, path: error.path });\n\t\t\t}\n\t\t}\n\n\t\tconst extensionRunner = deps.getExtensionRunner();\n\t\tconst commandDiagnostics = extensionRunner.getCommandDiagnostics();\n\t\textensionDiagnostics.push(...commandDiagnostics);\n\t\textensionDiagnostics.push(...deps.getBuiltInCommandConflictDiagnostics(extensionRunner));\n\n\t\tconst shortcutDiagnostics = extensionRunner.getShortcutDiagnostics();\n\t\textensionDiagnostics.push(...shortcutDiagnostics);\n\n\t\tif (extensionDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(extensionDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Extension issues]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\n\t\tconst themeDiagnostics = themesResult.diagnostics;\n\t\tif (themeDiagnostics.length > 0) {\n\t\t\tconst warningLines = formatDiagnostics(themeDiagnostics, sourceInfos);\n\t\t\tchatContainer.addChild(new Text(`${theme.fg(\"warning\", \"[Theme conflicts]\")}\\n${warningLines}`, 0, 0));\n\t\t\tchatContainer.addChild(new Spacer(1));\n\t\t}\n\t}\n}\n"]}
@@ -10,7 +10,7 @@
10
10
  "gray": "#808080",
11
11
  "dimGray": "#666666",
12
12
  "darkGray": "#505050",
13
- "accent": "#8abeb7",
13
+ "accent": "#5cc8bb",
14
14
  "selectedBg": "#3a3a4a",
15
15
  "userMsgBg": "#1c1c26",
16
16
  "toolPendingBg": "#1a1a24",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://raw.githubusercontent.com/kolisachint/hoocode/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
3
  "name": "light",
4
4
  "vars": {
5
- "teal": "#5a8080",
5
+ "teal": "#0e857a",
6
6
  "blue": "#547da7",
7
7
  "green": "#588458",
8
8
  "red": "#aa5555",
@@ -1 +1 @@
1
- {"version":3,"file":"voice-controller.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/voice/voice-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAwB/D,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,GAAG,CAAC;IACR,mEAAmE;IACnE,eAAe,EAAE,SAAS,CAAC;IAC3B,6DAA6D;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,qBAAa,eAAe;IAef,OAAO,CAAC,QAAQ,CAAC,IAAI;IAdjC,0DAA0D;IAC1D,OAAO,CAAC,OAAO,CAA2B;IAG1C,OAAO,CAAC,MAAM,CAA0B;IACxC,gFAAgF;IAChF,OAAO,CAAC,iBAAiB,CAAS;IAClC,6FAA6F;IAC7F,OAAO,CAAC,QAAQ,CAAS;IACzB,kEAAkE;IAClE,OAAO,CAAC,MAAM,CAAS;IACvB,oDAAoD;IACpD,OAAO,CAAC,KAAK,CAAyB;IAEtC,YAA6B,IAAI,EAAE,mBAAmB,EAAI;IAE1D,oCAAoC;IACpC,MAAM,IAAI,IAAI,CAmGb;IAED,kEAAkE;IAClE,OAAO,IAAI,IAAI,CAad;IAED;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,mBAAmB;IA2D3B,uFAAuF;IACvF,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,kBAAkB;YAgCZ,UAAU;IAMxB,8EAA8E;IAC9E,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,WAAW;IAInB,8EAA8E;IAC9E,OAAO,CAAC,OAAO;CAQf","sourcesContent":["/**\n * Voice-to-text capture control (ctrl+r / app.input.voiceTranscribe).\n *\n * Prefers a persistent `voicetools serve` daemon: the first press probes for\n * support and (if found) loads models once, showing a \"warming up\" spinner;\n * every later press reuses the already-warm daemon and jumps straight to\n * Listening. Binaries without `serve` support fall back to spawning\n * `voicetools transcribe` per press. Pressing the shortcut again while\n * listening (or while still warming up) cancels.\n */\n\nimport type { Container, TUI } from \"@kolisachint/hoocode-tui\";\nimport { ensureTool } from \"../../../utils/tools-manager.js\";\nimport { keyHint } from \"../components/keybinding-hints.js\";\nimport { VoicePanel } from \"./voice-panel.js\";\nimport { startVoiceTranscribe, VoiceDaemon, type VoiceDaemonHandlers, type VoiceSession } from \"./voice-transcribe.js\";\n\n// Trailing-silence window: how long a pause while speaking lasts before the\n// capture auto-stops. Passed to `voicetools serve` via `--silence-ms` (see\n// VoiceDaemon.spawn) so the binary's real cutoff matches the on-screen\n// countdown this same value drives. Every utterance pays this in full before\n// finalization can start, so keep it close to the binary's 600ms default —\n// a slightly longer window tolerates brief mid-sentence pauses without\n// taxing every dictation with seconds of dead air.\nconst VOICE_SILENCE_MS = 800;\n/** How long to keep the warm voice model in memory after the last capture\n * completes. The daemon auto-shuts down after this window, releasing the\n * ~900 MB resident model; the next ctrl+r pays a cold-start respawn cost.\n * Kept long enough that normal pacing between dictations (reading a reply,\n * typing) doesn't repeatedly hit the multi-second cold start. */\nconst VOICE_IDLE_TIMEOUT_MS = 300_000;\nconst VOICE_UNAVAILABLE_MESSAGE =\n\t\"Voice input failed: voicetools binary unavailable and could not be downloaded. \" +\n\t\"Install it, set VOICETOOLS_BIN, or ensure a published release exists for this platform.\";\n\n/** The slice of the interactive mode the voice feature needs. */\nexport interface VoiceControllerDeps {\n\tui: TUI;\n\t/** The status area below the chat; the voice panel mounts here. */\n\tstatusContainer: Container;\n\t/** Feed raw input (bracketed paste) to the prompt editor. */\n\tsendEditorInput(data: string): void;\n\tshowError(message: string): void;\n}\n\nexport class VoiceController {\n\t/** In-flight legacy (`voicetools transcribe`) capture. */\n\tprivate session: VoiceSession | undefined;\n\t// Persistent `voicetools serve` process, once probed successfully. Stays alive\n\t// between captures so the model stays warm.\n\tprivate daemon: VoiceDaemon | undefined;\n\t/** Set when the binary rejected `serve`; future presses use the legacy path. */\n\tprivate daemonUnsupported = false;\n\t/** True while the voicetools binary is being resolved/downloaded before a session starts. */\n\tprivate starting = false;\n\t/** True while a capture is active (listening or transcribing). */\n\tprivate active = false;\n\t/** The status panel while voice input is active. */\n\tprivate panel: VoicePanel | undefined;\n\n\tconstructor(private readonly deps: VoiceControllerDeps) {}\n\n\t/** Toggle voice-to-text capture. */\n\ttoggle(): void {\n\t\tif (this.active) {\n\t\t\tif (this.daemon?.isReady) {\n\t\t\t\tthis.daemon.cancel();\n\t\t\t} else {\n\t\t\t\tthis.session?.stop();\n\t\t\t}\n\t\t\tthis.session = undefined;\n\t\t\tthis.active = false;\n\t\t\tthis.resetUI();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.starting) {\n\t\t\t// A second press while resolving/warming up: honour the cancel. Any\n\t\t\t// daemon that finishes loading afterwards is kept warm for next time.\n\t\t\tthis.starting = false;\n\t\t\tthis.resetUI();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.daemonUnsupported) {\n\t\t\tthis.starting = true;\n\t\t\tthis.showWarming(\"Starting voice input...\");\n\t\t\tvoid this.resolveBin()\n\t\t\t\t.then((bin) => {\n\t\t\t\t\tif (!this.starting) return;\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tif (!bin) {\n\t\t\t\t\t\tthis.resetUI();\n\t\t\t\t\t\tthis.deps.showError(VOICE_UNAVAILABLE_MESSAGE);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.beginLegacyCapture(bin);\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\tthis.deps.showError(`Voice input failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.daemon?.isReady) {\n\t\t\tthis.beginDaemonCapture();\n\t\t\treturn;\n\t\t}\n\n\t\t// No daemon yet: resolve the binary, then probe for `serve` support by\n\t\t// spawning it. `VoiceDaemon.spawn` doubles as the probe: it resolves to a\n\t\t// live daemon once READY arrives, to \"unsupported\" if the process exits\n\t\t// with no output at all (an old binary rejecting the unrecognized `serve`\n\t\t// subcommand), or to \"error\" if it printed a real ERROR first (e.g. no\n\t\t// model installed yet) — already surfaced via onError, so that case skips\n\t\t// the legacy fallback (it would just hit the same error) but leaves\n\t\t// daemon mode available to retry on the next press.\n\t\tthis.starting = true;\n\t\tthis.showWarming(\"Warming up voice input...\");\n\t\tvoid this.resolveBin()\n\t\t\t.then(async (bin) => {\n\t\t\t\tif (!bin) {\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\tthis.deps.showError(VOICE_UNAVAILABLE_MESSAGE);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = await VoiceDaemon.spawn(bin, this.buildDaemonHandlers(), {\n\t\t\t\t\tsilenceMs: VOICE_SILENCE_MS,\n\t\t\t\t\tidleTimeoutMs: VOICE_IDLE_TIMEOUT_MS,\n\t\t\t\t});\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\tif (result.reason === \"unsupported\") {\n\t\t\t\t\t\tthis.daemonUnsupported = true;\n\t\t\t\t\t\tif (!this.starting) {\n\t\t\t\t\t\t\tthis.resetUI();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.starting = false;\n\t\t\t\t\t\tthis.beginLegacyCapture(bin);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.daemon = result.daemon;\n\t\t\t\tif (!this.starting) {\n\t\t\t\t\t// Cancelled while warming up: keep the loaded daemon warm for next time.\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.starting = false;\n\t\t\t\tthis.beginDaemonCapture();\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tthis.starting = false;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t});\n\t}\n\n\t/** Stop any capture, shut down the daemon, and drop the panel. */\n\tdispose(): void {\n\t\tif (this.session?.running) {\n\t\t\tthis.session.stop();\n\t\t\tthis.session = undefined;\n\t\t}\n\t\tthis.daemon?.shutdown();\n\t\tthis.daemon = undefined;\n\t\tif (this.panel) {\n\t\t\tthis.panel.dispose();\n\t\t\tthis.panel = undefined;\n\t\t}\n\t\tthis.active = false;\n\t\tthis.starting = false;\n\t}\n\n\t/**\n\t * Build the (stable, reused-across-captures) handlers for the daemon.\n\t *\n\t * Every handler bails out once `active` is false: CANCEL is a soft\n\t * request (unlike the legacy path's `proc.kill()`, it doesn't sever the\n\t * pipe), so the daemon can still have a trailing PARTIAL/FINAL/DONE for the\n\t * just-cancelled capture in flight when the user presses cancel. Without\n\t * this guard that stale text would land in the editor after the panel had\n\t * already collapsed.\n\t *\n\t * v0.1.4 serve streams `PARTIAL <full growing hypothesis>` (live preview,\n\t * never committed) and ends with a single `FINAL <complete text>` (the one\n\t * commit to the editor). `SEGMENT` is still handled for the legacy\n\t * transcribe path and any binary that streams committed chunks directly.\n\t */\n\tprivate buildDaemonHandlers(): VoiceDaemonHandlers {\n\t\treturn {\n\t\t\tonSegment: (text) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.commitText(text);\n\t\t\t},\n\t\t\tonPartial: (text) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.panel?.setPartial(text);\n\t\t\t},\n\t\t\tonFinal: (text) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.commitText(text);\n\t\t\t},\n\t\t\tonStatus: (status) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tif (status === \"done\") {\n\t\t\t\t\tthis.active = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (status === \"transcribing\") {\n\t\t\t\t\tthis.panel?.setTranscribing();\n\t\t\t\t} else if (status === \"listening\") {\n\t\t\t\t\tthis.panel?.startListening();\n\t\t\t\t}\n\t\t\t},\n\t\t\tonLevel: (rms) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.panel?.pushLevel(rms);\n\t\t\t},\n\t\t\tonPhase: (phase) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tif (phase === \"silence\") {\n\t\t\t\t\tthis.panel?.beginSilence(VOICE_SILENCE_MS);\n\t\t\t\t} else {\n\t\t\t\t\tthis.panel?.endSilence();\n\t\t\t\t}\n\t\t\t},\n\t\t\tonError: (message) => {\n\t\t\t\tthis.active = false;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input failed: ${message}`);\n\t\t\t},\n\t\t\tonCrash: (message) => {\n\t\t\t\tthis.active = false;\n\t\t\t\tthis.daemon = undefined;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input daemon crashed: ${message}. It will restart on next use.`);\n\t\t\t},\n\t\t\tonIdle: () => {\n\t\t\t\t// Daemon auto-shut down after idle timeout: drop the reference so the\n\t\t\t\t// next ctrl+r respawns (cold start). No user-facing message — this is\n\t\t\t\t// an expected memory-reclamation event, not an error.\n\t\t\t\tthis.daemon = undefined;\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Inject decoded text into the editor via bracketed paste (with a trailing space). */\n\tprivate commitText(text: string): void {\n\t\tthis.deps.sendEditorInput(`\\x1b[200~${text} \\x1b[201~`);\n\t}\n\n\tprivate beginDaemonCapture(): void {\n\t\tif (!this.daemon?.isReady) return;\n\t\tthis.active = true;\n\t\tthis.showPanel().startListening();\n\t\tthis.daemon.startCapture();\n\t}\n\n\tprivate beginLegacyCapture(bin: string): void {\n\t\tthis.active = true;\n\t\tconst panel = this.showPanel();\n\t\tpanel.startListening();\n\t\tthis.session = startVoiceTranscribe(bin, {\n\t\t\tonStatus: (status) => {\n\t\t\t\tif (status === \"done\") {\n\t\t\t\t\tthis.active = false;\n\t\t\t\t\tthis.session = undefined;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Old binaries emit no LEVEL/PARTIAL, so the panel shows a spinner\n\t\t\t\t// for the batch phases; committed words still stream into the editor.\n\t\t\t\tif (status === \"transcribing\") panel.setTranscribing();\n\t\t\t},\n\t\t\tonSegment: (text) => {\n\t\t\t\tthis.commitText(text);\n\t\t\t},\n\t\t\tonError: (message) => {\n\t\t\t\tthis.active = false;\n\t\t\t\tthis.session = undefined;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input failed: ${message}`);\n\t\t\t},\n\t\t});\n\t}\n\n\t/** Resolve the `voicetools` binary path. Prefers an explicit VOICETOOLS_BIN\n\t * override, otherwise resolves via the managed tools manager (bin dir / PATH /\n\t * download from the published release). Returns undefined when unavailable.\n\t */\n\tprivate async resolveBin(): Promise<string | undefined> {\n\t\tconst override = process.env.VOICETOOLS_BIN?.trim();\n\t\tif (override) return override;\n\t\treturn ensureTool(\"voicetools\", true);\n\t}\n\n\t/** Create (or reuse) the voice panel and mount it in the status container. */\n\tprivate showPanel(): VoicePanel {\n\t\tif (!this.panel) {\n\t\t\tthis.deps.statusContainer.clear();\n\t\t\tthis.panel = new VoicePanel(this.deps.ui, keyHint(\"app.input.voiceTranscribe\", \"cancel\"));\n\t\t\tthis.deps.statusContainer.addChild(this.panel);\n\t\t}\n\t\tthis.deps.ui.requestRender();\n\t\treturn this.panel;\n\t}\n\n\tprivate showWarming(message: string): void {\n\t\tthis.showPanel().setWarming(message);\n\t}\n\n\t/** Collapse the voice panel back to nothing (idle) and stop its animation. */\n\tprivate resetUI(): void {\n\t\tif (this.panel) {\n\t\t\tthis.panel.dispose();\n\t\t\tthis.panel = undefined;\n\t\t}\n\t\tthis.deps.statusContainer.clear();\n\t\tthis.deps.ui.requestRender();\n\t}\n}\n"]}
1
+ {"version":3,"file":"voice-controller.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/voice/voice-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AA0B/D,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,GAAG,CAAC;IACR,mEAAmE;IACnE,eAAe,EAAE,SAAS,CAAC;IAC3B,6DAA6D;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,qBAAa,eAAe;IAef,OAAO,CAAC,QAAQ,CAAC,IAAI;IAdjC,0DAA0D;IAC1D,OAAO,CAAC,OAAO,CAA2B;IAG1C,OAAO,CAAC,MAAM,CAA0B;IACxC,gFAAgF;IAChF,OAAO,CAAC,iBAAiB,CAAS;IAClC,6FAA6F;IAC7F,OAAO,CAAC,QAAQ,CAAS;IACzB,kEAAkE;IAClE,OAAO,CAAC,MAAM,CAAS;IACvB,oDAAoD;IACpD,OAAO,CAAC,KAAK,CAAyB;IAEtC,YAA6B,IAAI,EAAE,mBAAmB,EAAI;IAE1D,oCAAoC;IACpC,MAAM,IAAI,IAAI,CAmGb;IAED,kEAAkE;IAClE,OAAO,IAAI,IAAI,CAad;IAED;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,mBAAmB;IA2D3B,uFAAuF;IACvF,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,kBAAkB;YAgCZ,UAAU;IAUxB,8EAA8E;IAC9E,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,WAAW;IAInB,8EAA8E;IAC9E,OAAO,CAAC,OAAO;CAQf","sourcesContent":["/**\n * Voice-to-text capture control (ctrl+r / app.input.voiceTranscribe).\n *\n * Prefers a persistent `voicetools serve` daemon: the first press probes for\n * support and (if found) loads models once, showing a \"warming up\" spinner;\n * every later press reuses the already-warm daemon and jumps straight to\n * Listening. Binaries without `serve` support fall back to spawning\n * `voicetools transcribe` per press. Pressing the shortcut again while\n * listening (or while still warming up) cancels.\n */\n\nimport type { Container, TUI } from \"@kolisachint/hoocode-tui\";\nimport { ensureTool } from \"../../../utils/tools-manager.js\";\nimport { keyHint } from \"../components/keybinding-hints.js\";\nimport { VoicePanel } from \"./voice-panel.js\";\nimport { startVoiceTranscribe, VoiceDaemon, type VoiceDaemonHandlers, type VoiceSession } from \"./voice-transcribe.js\";\n\n// Trailing-silence window: how long a pause while speaking lasts before the\n// capture auto-stops. Passed to `voicetools serve` via `--silence-ms` (see\n// VoiceDaemon.spawn) so the binary's real cutoff matches the on-screen\n// countdown this same value drives. Every utterance pays this in full before\n// finalization can start, so keep it close to the binary's 600ms default —\n// a slightly longer window tolerates brief mid-sentence pauses without\n// taxing every dictation with seconds of dead air.\nconst VOICE_SILENCE_MS = 800;\n/** How long to keep the warm voice model in memory after the last capture\n * completes. The daemon auto-shuts down after this window, releasing the\n * ~900 MB resident model; the next ctrl+r pays a cold-start respawn cost.\n * Kept long enough that normal pacing between dictations (reading a reply,\n * typing) doesn't repeatedly hit the multi-second cold start. */\nconst VOICE_IDLE_TIMEOUT_MS = 300_000;\nconst VOICE_UNAVAILABLE_MESSAGE = [\n\t`Voice unavailable — no voicetools binary for ${process.platform}-${process.arch} (and download failed).`,\n\t\" fix: set VOICETOOLS_BIN=/path/to/voicetools\",\n\t\" or: install voicetools from its published release, then press the voice key again\",\n].join(\"\\n\");\n\n/** The slice of the interactive mode the voice feature needs. */\nexport interface VoiceControllerDeps {\n\tui: TUI;\n\t/** The status area below the chat; the voice panel mounts here. */\n\tstatusContainer: Container;\n\t/** Feed raw input (bracketed paste) to the prompt editor. */\n\tsendEditorInput(data: string): void;\n\tshowError(message: string): void;\n}\n\nexport class VoiceController {\n\t/** In-flight legacy (`voicetools transcribe`) capture. */\n\tprivate session: VoiceSession | undefined;\n\t// Persistent `voicetools serve` process, once probed successfully. Stays alive\n\t// between captures so the model stays warm.\n\tprivate daemon: VoiceDaemon | undefined;\n\t/** Set when the binary rejected `serve`; future presses use the legacy path. */\n\tprivate daemonUnsupported = false;\n\t/** True while the voicetools binary is being resolved/downloaded before a session starts. */\n\tprivate starting = false;\n\t/** True while a capture is active (listening or transcribing). */\n\tprivate active = false;\n\t/** The status panel while voice input is active. */\n\tprivate panel: VoicePanel | undefined;\n\n\tconstructor(private readonly deps: VoiceControllerDeps) {}\n\n\t/** Toggle voice-to-text capture. */\n\ttoggle(): void {\n\t\tif (this.active) {\n\t\t\tif (this.daemon?.isReady) {\n\t\t\t\tthis.daemon.cancel();\n\t\t\t} else {\n\t\t\t\tthis.session?.stop();\n\t\t\t}\n\t\t\tthis.session = undefined;\n\t\t\tthis.active = false;\n\t\t\tthis.resetUI();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.starting) {\n\t\t\t// A second press while resolving/warming up: honour the cancel. Any\n\t\t\t// daemon that finishes loading afterwards is kept warm for next time.\n\t\t\tthis.starting = false;\n\t\t\tthis.resetUI();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.daemonUnsupported) {\n\t\t\tthis.starting = true;\n\t\t\tthis.showWarming(\"Starting voice input…\", \"first run downloads the voicetools binary and speech model\");\n\t\t\tvoid this.resolveBin()\n\t\t\t\t.then((bin) => {\n\t\t\t\t\tif (!this.starting) return;\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tif (!bin) {\n\t\t\t\t\t\tthis.resetUI();\n\t\t\t\t\t\tthis.deps.showError(VOICE_UNAVAILABLE_MESSAGE);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.beginLegacyCapture(bin);\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\tthis.deps.showError(`Voice input failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.daemon?.isReady) {\n\t\t\tthis.beginDaemonCapture();\n\t\t\treturn;\n\t\t}\n\n\t\t// No daemon yet: resolve the binary, then probe for `serve` support by\n\t\t// spawning it. `VoiceDaemon.spawn` doubles as the probe: it resolves to a\n\t\t// live daemon once READY arrives, to \"unsupported\" if the process exits\n\t\t// with no output at all (an old binary rejecting the unrecognized `serve`\n\t\t// subcommand), or to \"error\" if it printed a real ERROR first (e.g. no\n\t\t// model installed yet) — already surfaced via onError, so that case skips\n\t\t// the legacy fallback (it would just hit the same error) but leaves\n\t\t// daemon mode available to retry on the next press.\n\t\tthis.starting = true;\n\t\tthis.showWarming(\"Warming up voice input…\", \"first run downloads the voicetools binary and speech model\");\n\t\tvoid this.resolveBin()\n\t\t\t.then(async (bin) => {\n\t\t\t\tif (!bin) {\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\tthis.deps.showError(VOICE_UNAVAILABLE_MESSAGE);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst result = await VoiceDaemon.spawn(bin, this.buildDaemonHandlers(), {\n\t\t\t\t\tsilenceMs: VOICE_SILENCE_MS,\n\t\t\t\t\tidleTimeoutMs: VOICE_IDLE_TIMEOUT_MS,\n\t\t\t\t});\n\t\t\t\tif (!result.ok) {\n\t\t\t\t\tif (result.reason === \"unsupported\") {\n\t\t\t\t\t\tthis.daemonUnsupported = true;\n\t\t\t\t\t\tif (!this.starting) {\n\t\t\t\t\t\t\tthis.resetUI();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.starting = false;\n\t\t\t\t\t\tthis.beginLegacyCapture(bin);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.starting = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.daemon = result.daemon;\n\t\t\t\tif (!this.starting) {\n\t\t\t\t\t// Cancelled while warming up: keep the loaded daemon warm for next time.\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.starting = false;\n\t\t\t\tthis.beginDaemonCapture();\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tthis.starting = false;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input failed: ${err instanceof Error ? err.message : String(err)}`);\n\t\t\t});\n\t}\n\n\t/** Stop any capture, shut down the daemon, and drop the panel. */\n\tdispose(): void {\n\t\tif (this.session?.running) {\n\t\t\tthis.session.stop();\n\t\t\tthis.session = undefined;\n\t\t}\n\t\tthis.daemon?.shutdown();\n\t\tthis.daemon = undefined;\n\t\tif (this.panel) {\n\t\t\tthis.panel.dispose();\n\t\t\tthis.panel = undefined;\n\t\t}\n\t\tthis.active = false;\n\t\tthis.starting = false;\n\t}\n\n\t/**\n\t * Build the (stable, reused-across-captures) handlers for the daemon.\n\t *\n\t * Every handler bails out once `active` is false: CANCEL is a soft\n\t * request (unlike the legacy path's `proc.kill()`, it doesn't sever the\n\t * pipe), so the daemon can still have a trailing PARTIAL/FINAL/DONE for the\n\t * just-cancelled capture in flight when the user presses cancel. Without\n\t * this guard that stale text would land in the editor after the panel had\n\t * already collapsed.\n\t *\n\t * v0.1.4 serve streams `PARTIAL <full growing hypothesis>` (live preview,\n\t * never committed) and ends with a single `FINAL <complete text>` (the one\n\t * commit to the editor). `SEGMENT` is still handled for the legacy\n\t * transcribe path and any binary that streams committed chunks directly.\n\t */\n\tprivate buildDaemonHandlers(): VoiceDaemonHandlers {\n\t\treturn {\n\t\t\tonSegment: (text) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.commitText(text);\n\t\t\t},\n\t\t\tonPartial: (text) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.panel?.setPartial(text);\n\t\t\t},\n\t\t\tonFinal: (text) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.commitText(text);\n\t\t\t},\n\t\t\tonStatus: (status) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tif (status === \"done\") {\n\t\t\t\t\tthis.active = false;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (status === \"transcribing\") {\n\t\t\t\t\tthis.panel?.setTranscribing();\n\t\t\t\t} else if (status === \"listening\") {\n\t\t\t\t\tthis.panel?.startListening();\n\t\t\t\t}\n\t\t\t},\n\t\t\tonLevel: (rms) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tthis.panel?.pushLevel(rms);\n\t\t\t},\n\t\t\tonPhase: (phase) => {\n\t\t\t\tif (!this.active) return;\n\t\t\t\tif (phase === \"silence\") {\n\t\t\t\t\tthis.panel?.beginSilence(VOICE_SILENCE_MS);\n\t\t\t\t} else {\n\t\t\t\t\tthis.panel?.endSilence();\n\t\t\t\t}\n\t\t\t},\n\t\t\tonError: (message) => {\n\t\t\t\tthis.active = false;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input failed: ${message}`);\n\t\t\t},\n\t\t\tonCrash: (message) => {\n\t\t\t\tthis.active = false;\n\t\t\t\tthis.daemon = undefined;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input daemon crashed: ${message}. It will restart on next use.`);\n\t\t\t},\n\t\t\tonIdle: () => {\n\t\t\t\t// Daemon auto-shut down after idle timeout: drop the reference so the\n\t\t\t\t// next ctrl+r respawns (cold start). No user-facing message — this is\n\t\t\t\t// an expected memory-reclamation event, not an error.\n\t\t\t\tthis.daemon = undefined;\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Inject decoded text into the editor via bracketed paste (with a trailing space). */\n\tprivate commitText(text: string): void {\n\t\tthis.deps.sendEditorInput(`\\x1b[200~${text} \\x1b[201~`);\n\t}\n\n\tprivate beginDaemonCapture(): void {\n\t\tif (!this.daemon?.isReady) return;\n\t\tthis.active = true;\n\t\tthis.showPanel().startListening();\n\t\tthis.daemon.startCapture();\n\t}\n\n\tprivate beginLegacyCapture(bin: string): void {\n\t\tthis.active = true;\n\t\tconst panel = this.showPanel();\n\t\tpanel.startListening();\n\t\tthis.session = startVoiceTranscribe(bin, {\n\t\t\tonStatus: (status) => {\n\t\t\t\tif (status === \"done\") {\n\t\t\t\t\tthis.active = false;\n\t\t\t\t\tthis.session = undefined;\n\t\t\t\t\tthis.resetUI();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Old binaries emit no LEVEL/PARTIAL, so the panel shows a spinner\n\t\t\t\t// for the batch phases; committed words still stream into the editor.\n\t\t\t\tif (status === \"transcribing\") panel.setTranscribing();\n\t\t\t},\n\t\t\tonSegment: (text) => {\n\t\t\t\tthis.commitText(text);\n\t\t\t},\n\t\t\tonError: (message) => {\n\t\t\t\tthis.active = false;\n\t\t\t\tthis.session = undefined;\n\t\t\t\tthis.resetUI();\n\t\t\t\tthis.deps.showError(`Voice input failed: ${message}`);\n\t\t\t},\n\t\t});\n\t}\n\n\t/** Resolve the `voicetools` binary path. Prefers an explicit VOICETOOLS_BIN\n\t * override, otherwise resolves via the managed tools manager (bin dir / PATH /\n\t * download from the published release). Returns undefined when unavailable.\n\t */\n\tprivate async resolveBin(): Promise<string | undefined> {\n\t\tconst override = process.env.VOICETOOLS_BIN?.trim();\n\t\tif (override) return override;\n\t\t// First run downloads the voicetools release archive; stream the byte counts\n\t\t// into the panel so the wait shows a determinate progress bar, not a spinner.\n\t\treturn ensureTool(\"voicetools\", true, (received, total) => {\n\t\t\tif (this.starting) this.panel?.setDownloadProgress(received, total);\n\t\t});\n\t}\n\n\t/** Create (or reuse) the voice panel and mount it in the status container. */\n\tprivate showPanel(): VoicePanel {\n\t\tif (!this.panel) {\n\t\t\tthis.deps.statusContainer.clear();\n\t\t\tthis.panel = new VoicePanel(this.deps.ui, keyHint(\"app.input.voiceTranscribe\", \"cancel\"));\n\t\t\tthis.deps.statusContainer.addChild(this.panel);\n\t\t}\n\t\tthis.deps.ui.requestRender();\n\t\treturn this.panel;\n\t}\n\n\tprivate showWarming(message: string, detail?: string): void {\n\t\tthis.showPanel().setWarming(message, detail);\n\t}\n\n\t/** Collapse the voice panel back to nothing (idle) and stop its animation. */\n\tprivate resetUI(): void {\n\t\tif (this.panel) {\n\t\t\tthis.panel.dispose();\n\t\t\tthis.panel = undefined;\n\t\t}\n\t\tthis.deps.statusContainer.clear();\n\t\tthis.deps.ui.requestRender();\n\t}\n}\n"]}