threadwell 0.0.6 → 0.0.7

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 (93) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +4 -8
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +5 -7
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/cli/config-selector.d.ts.map +1 -1
  7. package/dist/cli/config-selector.js +4 -2
  8. package/dist/cli/config-selector.js.map +1 -1
  9. package/dist/core/settings-manager.d.ts +3 -0
  10. package/dist/core/settings-manager.d.ts.map +1 -1
  11. package/dist/core/settings-manager.js +5 -0
  12. package/dist/core/settings-manager.js.map +1 -1
  13. package/dist/core/slash-commands.d.ts.map +1 -1
  14. package/dist/core/slash-commands.js +1 -1
  15. package/dist/core/slash-commands.js.map +1 -1
  16. package/dist/core/tools/edit.d.ts.map +1 -1
  17. package/dist/core/tools/edit.js +7 -1
  18. package/dist/core/tools/edit.js.map +1 -1
  19. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  20. package/dist/modes/interactive/components/assistant-message.js +12 -4
  21. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  22. package/dist/modes/interactive/components/bash-execution.d.ts +2 -0
  23. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  24. package/dist/modes/interactive/components/bash-execution.js +43 -4
  25. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  26. package/dist/modes/interactive/components/branch-summary-message.d.ts +4 -3
  27. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  28. package/dist/modes/interactive/components/branch-summary-message.js +31 -8
  29. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  30. package/dist/modes/interactive/components/compaction-summary-message.d.ts +4 -3
  31. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  32. package/dist/modes/interactive/components/compaction-summary-message.js +32 -8
  33. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  34. package/dist/modes/interactive/components/config-selector.d.ts +1 -1
  35. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  36. package/dist/modes/interactive/components/config-selector.js +1 -9
  37. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  38. package/dist/modes/interactive/components/custom-message.d.ts +3 -0
  39. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  40. package/dist/modes/interactive/components/custom-message.js +33 -20
  41. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  42. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  43. package/dist/modes/interactive/components/diff.js +70 -0
  44. package/dist/modes/interactive/components/diff.js.map +1 -1
  45. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  46. package/dist/modes/interactive/components/footer.js +61 -49
  47. package/dist/modes/interactive/components/footer.js.map +1 -1
  48. package/dist/modes/interactive/components/framed-message.d.ts +17 -0
  49. package/dist/modes/interactive/components/framed-message.d.ts.map +1 -0
  50. package/dist/modes/interactive/components/framed-message.js +39 -0
  51. package/dist/modes/interactive/components/framed-message.js.map +1 -0
  52. package/dist/modes/interactive/components/settings-selector.d.ts +0 -4
  53. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  54. package/dist/modes/interactive/components/settings-selector.js +0 -20
  55. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  56. package/dist/modes/interactive/components/skill-invocation-message.d.ts +4 -3
  57. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/skill-invocation-message.js +31 -9
  59. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  60. package/dist/modes/interactive/components/split-info-card.d.ts.map +1 -1
  61. package/dist/modes/interactive/components/split-info-card.js +24 -17
  62. package/dist/modes/interactive/components/split-info-card.js.map +1 -1
  63. package/dist/modes/interactive/components/thinking-card.d.ts +6 -0
  64. package/dist/modes/interactive/components/thinking-card.d.ts.map +1 -0
  65. package/dist/modes/interactive/components/thinking-card.js +17 -0
  66. package/dist/modes/interactive/components/thinking-card.js.map +1 -0
  67. package/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  68. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  69. package/dist/modes/interactive/components/tool-execution.js +72 -2
  70. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  71. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  72. package/dist/modes/interactive/components/user-message.js +16 -0
  73. package/dist/modes/interactive/components/user-message.js.map +1 -1
  74. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  75. package/dist/modes/interactive/interactive-mode.js +86 -73
  76. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  77. package/dist/modes/interactive/theme/visual-profile.d.ts +69 -0
  78. package/dist/modes/interactive/theme/visual-profile.d.ts.map +1 -0
  79. package/dist/modes/interactive/theme/visual-profile.js +131 -0
  80. package/dist/modes/interactive/theme/visual-profile.js.map +1 -0
  81. package/dist/package-manager-cli.d.ts.map +1 -1
  82. package/dist/package-manager-cli.js +1 -1
  83. package/dist/package-manager-cli.js.map +1 -1
  84. package/docs/docs.json +1 -5
  85. package/docs/extensions.md +7 -16
  86. package/docs/index.md +6 -5
  87. package/docs/packages.md +8 -30
  88. package/docs/quickstart.md +1 -1
  89. package/docs/sdk.md +2 -3
  90. package/docs/settings.md +24 -7
  91. package/docs/themes.md +5 -295
  92. package/docs/usage.md +14 -17
  93. package/package.json +4 -4
@@ -1,16 +1,17 @@
1
- import { Box, Markdown, Spacer, Text } from "@threadwell/tui";
1
+ import { Box, Container, Markdown, Text } from "@threadwell/tui";
2
2
  import { getMarkdownTheme, theme } from "../theme/theme.js";
3
+ import { getVisualTokens } from "../theme/visual-profile.js";
4
+ import { FramedMessage } from "./framed-message.js";
3
5
  import { keyText } from "./keybinding-hints.js";
4
6
  /**
5
7
  * Component that renders a branch summary message with collapsed/expanded state.
6
- * Uses same background color as custom messages for visual consistency.
7
8
  */
8
- export class BranchSummaryMessageComponent extends Box {
9
+ export class BranchSummaryMessageComponent extends Container {
9
10
  expanded = false;
10
11
  message;
11
12
  markdownTheme;
12
13
  constructor(message, markdownTheme = getMarkdownTheme()) {
13
- super(1, 1, (t) => theme.bg("customMessageBg", t));
14
+ super();
14
15
  this.message = message;
15
16
  this.markdownTheme = markdownTheme;
16
17
  this.updateDisplay();
@@ -25,20 +26,42 @@ export class BranchSummaryMessageComponent extends Box {
25
26
  }
26
27
  updateDisplay() {
27
28
  this.clear();
29
+ if (getVisualTokens().enhanced) {
30
+ this.updateEnhancedDisplay();
31
+ return;
32
+ }
33
+ this.updateBaselineDisplay();
34
+ }
35
+ updateEnhancedDisplay() {
36
+ const visual = getVisualTokens();
37
+ const text = this.expanded
38
+ ? `**Branch Summary**\n\n${this.message.summary}`
39
+ : `Branch summary (${keyText("app.tools.expand")} to expand)`;
40
+ this.addChild(new FramedMessage({
41
+ title: `${visual.glyphs.branch} branch`,
42
+ text,
43
+ markdownTheme: this.markdownTheme,
44
+ borderColor: (content) => theme.fg("borderMuted", content),
45
+ titleColor: (content) => theme.fg("customMessageLabel", theme.bold(content)),
46
+ contentColor: (content) => theme.fg("customMessageText", content),
47
+ }));
48
+ }
49
+ updateBaselineDisplay() {
50
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
28
51
  const label = theme.fg("customMessageLabel", `\x1b[1m[branch]\x1b[22m`);
29
- this.addChild(new Text(label, 0, 0));
30
- this.addChild(new Spacer(1));
52
+ box.addChild(new Text(label, 0, 0));
31
53
  if (this.expanded) {
32
54
  const header = "**Branch Summary**\n\n";
33
- this.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
55
+ box.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
34
56
  color: (text) => theme.fg("customMessageText", text),
35
57
  }));
36
58
  }
37
59
  else {
38
- this.addChild(new Text(theme.fg("customMessageText", "Branch summary (") +
60
+ box.addChild(new Text(theme.fg("customMessageText", "Branch summary (") +
39
61
  theme.fg("dim", keyText("app.tools.expand")) +
40
62
  theme.fg("customMessageText", " to expand)"), 0, 0));
41
63
  }
64
+ this.addChild(box);
42
65
  }
43
66
  }
44
67
  //# sourceMappingURL=branch-summary-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"branch-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAsB,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAElF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,6BAA8B,SAAQ,GAAG;IAC7C,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,CAAuB;IAC9B,aAAa,CAAgB;IAErC,YAAY,OAA6B,EAAE,aAAa,GAAkB,gBAAgB,EAAE,EAAE;QAC7F,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,UAAU,GAAS;QAC3B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEO,aAAa,GAAS;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;QACxE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,wBAAwB,CAAC;YACxC,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CACZ,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;gBAChD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;gBAC5C,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IAAA,CACD;CACD","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@threadwell/tui\";\nimport type { BranchSummaryMessage } from \"../../../core/messages.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a branch summary message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class BranchSummaryMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate message: BranchSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: BranchSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[branch]\\x1b[22m`);\n\t\tthis.addChild(new Text(label, 0, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = \"**Branch Summary**\\n\\n\";\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", \"Branch summary (\") +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\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\t}\n}\n"]}
1
+ {"version":3,"file":"branch-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/branch-summary-message.ts"],"names":[],"mappings":"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","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme, Text } from \"@threadwell/tui\";\nimport type { BranchSummaryMessage } from \"../../../core/messages.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { getVisualTokens } from \"../theme/visual-profile.js\";\nimport { FramedMessage } from \"./framed-message.js\";\nimport { keyText } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a branch summary message with collapsed/expanded state.\n */\nexport class BranchSummaryMessageComponent extends Container {\n\tprivate expanded = false;\n\tprivate message: BranchSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: BranchSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\t\tif (getVisualTokens().enhanced) {\n\t\t\tthis.updateEnhancedDisplay();\n\t\t\treturn;\n\t\t}\n\t\tthis.updateBaselineDisplay();\n\t}\n\n\tprivate updateEnhancedDisplay(): void {\n\t\tconst visual = getVisualTokens();\n\t\tconst text = this.expanded\n\t\t\t? `**Branch Summary**\\n\\n${this.message.summary}`\n\t\t\t: `Branch summary (${keyText(\"app.tools.expand\")} to expand)`;\n\t\tthis.addChild(\n\t\t\tnew FramedMessage({\n\t\t\t\ttitle: `${visual.glyphs.branch} branch`,\n\t\t\t\ttext,\n\t\t\t\tmarkdownTheme: this.markdownTheme,\n\t\t\t\tborderColor: (content) => theme.fg(\"borderMuted\", content),\n\t\t\t\ttitleColor: (content) => theme.fg(\"customMessageLabel\", theme.bold(content)),\n\t\t\t\tcontentColor: (content) => theme.fg(\"customMessageText\", content),\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate updateBaselineDisplay(): void {\n\t\tconst box = new Box(1, 1, (text) => theme.bg(\"customMessageBg\", text));\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[branch]\\x1b[22m`);\n\t\tbox.addChild(new Text(label, 0, 0));\n\t\tif (this.expanded) {\n\t\t\tconst header = \"**Branch Summary**\\n\\n\";\n\t\t\tbox.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tbox.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", \"Branch summary (\") +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\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\t\tthis.addChild(box);\n\t}\n}\n"]}
@@ -1,10 +1,9 @@
1
- import { Box, type MarkdownTheme } from "@threadwell/tui";
1
+ import { Container, type MarkdownTheme } from "@threadwell/tui";
2
2
  import type { CompactionSummaryMessage } from "../../../core/messages.js";
3
3
  /**
4
4
  * Component that renders a compaction message with collapsed/expanded state.
5
- * Uses same background color as custom messages for visual consistency.
6
5
  */
7
- export declare class CompactionSummaryMessageComponent extends Box {
6
+ export declare class CompactionSummaryMessageComponent extends Container {
8
7
  private expanded;
9
8
  private message;
10
9
  private markdownTheme;
@@ -12,5 +11,7 @@ export declare class CompactionSummaryMessageComponent extends Box {
12
11
  setExpanded(expanded: boolean): void;
13
12
  invalidate(): void;
14
13
  private updateDisplay;
14
+ private updateEnhancedDisplay;
15
+ private updateBaselineDisplay;
15
16
  }
16
17
  //# sourceMappingURL=compaction-summary-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAY,KAAK,aAAa,EAAgB,MAAM,iBAAiB,CAAC;AAClF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAI1E;;;GAGG;AACH,qBAAa,iCAAkC,SAAQ,GAAG;IACzD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,aAAa,CAAgB;IAErC,YAAY,OAAO,EAAE,wBAAwB,EAAE,aAAa,GAAE,aAAkC,EAK/F;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,aAAa;CA2BrB","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@threadwell/tui\";\nimport type { CompactionSummaryMessage } from \"../../../core/messages.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a compaction message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class CompactionSummaryMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: CompactionSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[compaction]\\x1b[22m`);\n\t\tthis.addChild(new Text(label, 0, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", `Compacted from ${tokenStr} tokens (`) +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\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\t}\n}\n"]}
1
+ {"version":3,"file":"compaction-summary-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,SAAS,EAAY,KAAK,aAAa,EAAQ,MAAM,iBAAiB,CAAC;AACrF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAM1E;;GAEG;AACH,qBAAa,iCAAkC,SAAQ,SAAS;IAC/D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,aAAa,CAAgB;IAErC,YAAY,OAAO,EAAE,wBAAwB,EAAE,aAAa,GAAE,aAAkC,EAK/F;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,qBAAqB;CAyB7B","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme, Text } from \"@threadwell/tui\";\nimport type { CompactionSummaryMessage } from \"../../../core/messages.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { getVisualTokens } from \"../theme/visual-profile.js\";\nimport { FramedMessage } from \"./framed-message.js\";\nimport { keyText } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a compaction message with collapsed/expanded state.\n */\nexport class CompactionSummaryMessageComponent extends Container {\n\tprivate expanded = false;\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: CompactionSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\t\tif (getVisualTokens().enhanced) {\n\t\t\tthis.updateEnhancedDisplay();\n\t\t\treturn;\n\t\t}\n\t\tthis.updateBaselineDisplay();\n\t}\n\n\tprivate updateEnhancedDisplay(): void {\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst visual = getVisualTokens();\n\t\tconst text = this.expanded\n\t\t\t? `**Compacted from ${tokenStr} tokens**\\n\\n${this.message.summary}`\n\t\t\t: `Compacted from ${tokenStr} tokens (${keyText(\"app.tools.expand\")} to expand)`;\n\t\tthis.addChild(\n\t\t\tnew FramedMessage({\n\t\t\t\ttitle: `${visual.glyphs.memory} compaction`,\n\t\t\t\ttext,\n\t\t\t\tmarkdownTheme: this.markdownTheme,\n\t\t\t\tborderColor: (content) => theme.fg(\"borderMuted\", content),\n\t\t\t\ttitleColor: (content) => theme.fg(\"customMessageLabel\", theme.bold(content)),\n\t\t\t\tcontentColor: (content) => theme.fg(\"customMessageText\", content),\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate updateBaselineDisplay(): void {\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst box = new Box(1, 1, (text) => theme.bg(\"customMessageBg\", text));\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[compaction]\\x1b[22m`);\n\t\tbox.addChild(new Text(label, 0, 0));\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tbox.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tbox.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", `Compacted from ${tokenStr} tokens (`) +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\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\t\tthis.addChild(box);\n\t}\n}\n"]}
@@ -1,16 +1,17 @@
1
- import { Box, Markdown, Spacer, Text } from "@threadwell/tui";
1
+ import { Box, Container, Markdown, Text } from "@threadwell/tui";
2
2
  import { getMarkdownTheme, theme } from "../theme/theme.js";
3
+ import { getVisualTokens } from "../theme/visual-profile.js";
4
+ import { FramedMessage } from "./framed-message.js";
3
5
  import { keyText } from "./keybinding-hints.js";
4
6
  /**
5
7
  * Component that renders a compaction message with collapsed/expanded state.
6
- * Uses same background color as custom messages for visual consistency.
7
8
  */
8
- export class CompactionSummaryMessageComponent extends Box {
9
+ export class CompactionSummaryMessageComponent extends Container {
9
10
  expanded = false;
10
11
  message;
11
12
  markdownTheme;
12
13
  constructor(message, markdownTheme = getMarkdownTheme()) {
13
- super(1, 1, (t) => theme.bg("customMessageBg", t));
14
+ super();
14
15
  this.message = message;
15
16
  this.markdownTheme = markdownTheme;
16
17
  this.updateDisplay();
@@ -25,21 +26,44 @@ export class CompactionSummaryMessageComponent extends Box {
25
26
  }
26
27
  updateDisplay() {
27
28
  this.clear();
29
+ if (getVisualTokens().enhanced) {
30
+ this.updateEnhancedDisplay();
31
+ return;
32
+ }
33
+ this.updateBaselineDisplay();
34
+ }
35
+ updateEnhancedDisplay() {
36
+ const tokenStr = this.message.tokensBefore.toLocaleString();
37
+ const visual = getVisualTokens();
38
+ const text = this.expanded
39
+ ? `**Compacted from ${tokenStr} tokens**\n\n${this.message.summary}`
40
+ : `Compacted from ${tokenStr} tokens (${keyText("app.tools.expand")} to expand)`;
41
+ this.addChild(new FramedMessage({
42
+ title: `${visual.glyphs.memory} compaction`,
43
+ text,
44
+ markdownTheme: this.markdownTheme,
45
+ borderColor: (content) => theme.fg("borderMuted", content),
46
+ titleColor: (content) => theme.fg("customMessageLabel", theme.bold(content)),
47
+ contentColor: (content) => theme.fg("customMessageText", content),
48
+ }));
49
+ }
50
+ updateBaselineDisplay() {
28
51
  const tokenStr = this.message.tokensBefore.toLocaleString();
52
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
29
53
  const label = theme.fg("customMessageLabel", `\x1b[1m[compaction]\x1b[22m`);
30
- this.addChild(new Text(label, 0, 0));
31
- this.addChild(new Spacer(1));
54
+ box.addChild(new Text(label, 0, 0));
32
55
  if (this.expanded) {
33
56
  const header = `**Compacted from ${tokenStr} tokens**\n\n`;
34
- this.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
57
+ box.addChild(new Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {
35
58
  color: (text) => theme.fg("customMessageText", text),
36
59
  }));
37
60
  }
38
61
  else {
39
- this.addChild(new Text(theme.fg("customMessageText", `Compacted from ${tokenStr} tokens (`) +
62
+ box.addChild(new Text(theme.fg("customMessageText", `Compacted from ${tokenStr} tokens (`) +
40
63
  theme.fg("dim", keyText("app.tools.expand")) +
41
64
  theme.fg("customMessageText", " to expand)"), 0, 0));
42
65
  }
66
+ this.addChild(box);
43
67
  }
44
68
  }
45
69
  //# sourceMappingURL=compaction-summary-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAsB,MAAM,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAElF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,iCAAkC,SAAQ,GAAG;IACjD,QAAQ,GAAG,KAAK,CAAC;IACjB,OAAO,CAA2B;IAClC,aAAa,CAAgB;IAErC,YAAY,OAAiC,EAAE,aAAa,GAAkB,gBAAgB,EAAE,EAAE;QACjG,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,UAAU,GAAS;QAC3B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEO,aAAa,GAAS;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QAC5D,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,6BAA6B,CAAC,CAAC;QAC5E,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,oBAAoB,QAAQ,eAAe,CAAC;YAC3D,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACrE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,QAAQ,CACZ,IAAI,IAAI,CACP,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,kBAAkB,QAAQ,WAAW,CAAC;gBACnE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;gBAC5C,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,aAAa,CAAC,EAC7C,CAAC,EACD,CAAC,CACD,CACD,CAAC;QACH,CAAC;IAAA,CACD;CACD","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Spacer, Text } from \"@threadwell/tui\";\nimport type { CompactionSummaryMessage } from \"../../../core/messages.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { keyText } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a compaction message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n */\nexport class CompactionSummaryMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: CompactionSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[compaction]\\x1b[22m`);\n\t\tthis.addChild(new Text(label, 0, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tthis.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", `Compacted from ${tokenStr} tokens (`) +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\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\t}\n}\n"]}
1
+ {"version":3,"file":"compaction-summary-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/compaction-summary-message.ts"],"names":[],"mappings":"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","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme, Text } from \"@threadwell/tui\";\nimport type { CompactionSummaryMessage } from \"../../../core/messages.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { getVisualTokens } from \"../theme/visual-profile.js\";\nimport { FramedMessage } from \"./framed-message.js\";\nimport { keyText } from \"./keybinding-hints.js\";\n\n/**\n * Component that renders a compaction message with collapsed/expanded state.\n */\nexport class CompactionSummaryMessageComponent extends Container {\n\tprivate expanded = false;\n\tprivate message: CompactionSummaryMessage;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(message: CompactionSummaryMessage, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\t\tif (getVisualTokens().enhanced) {\n\t\t\tthis.updateEnhancedDisplay();\n\t\t\treturn;\n\t\t}\n\t\tthis.updateBaselineDisplay();\n\t}\n\n\tprivate updateEnhancedDisplay(): void {\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst visual = getVisualTokens();\n\t\tconst text = this.expanded\n\t\t\t? `**Compacted from ${tokenStr} tokens**\\n\\n${this.message.summary}`\n\t\t\t: `Compacted from ${tokenStr} tokens (${keyText(\"app.tools.expand\")} to expand)`;\n\t\tthis.addChild(\n\t\t\tnew FramedMessage({\n\t\t\t\ttitle: `${visual.glyphs.memory} compaction`,\n\t\t\t\ttext,\n\t\t\t\tmarkdownTheme: this.markdownTheme,\n\t\t\t\tborderColor: (content) => theme.fg(\"borderMuted\", content),\n\t\t\t\ttitleColor: (content) => theme.fg(\"customMessageLabel\", theme.bold(content)),\n\t\t\t\tcontentColor: (content) => theme.fg(\"customMessageText\", content),\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate updateBaselineDisplay(): void {\n\t\tconst tokenStr = this.message.tokensBefore.toLocaleString();\n\t\tconst box = new Box(1, 1, (text) => theme.bg(\"customMessageBg\", text));\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[compaction]\\x1b[22m`);\n\t\tbox.addChild(new Text(label, 0, 0));\n\t\tif (this.expanded) {\n\t\t\tconst header = `**Compacted from ${tokenStr} tokens**\\n\\n`;\n\t\t\tbox.addChild(\n\t\t\t\tnew Markdown(header + this.message.summary, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\tbox.addChild(\n\t\t\t\tnew Text(\n\t\t\t\t\ttheme.fg(\"customMessageText\", `Compacted from ${tokenStr} tokens (`) +\n\t\t\t\t\t\ttheme.fg(\"dim\", keyText(\"app.tools.expand\")) +\n\t\t\t\t\t\ttheme.fg(\"customMessageText\", \" to expand)\"),\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\t\tthis.addChild(box);\n\t}\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  import { type Component, Container, type Focusable } from "@threadwell/tui";
5
5
  import type { PathMetadata, ResolvedPaths } from "../../../core/package-manager.js";
6
6
  import type { SettingsManager } from "../../../core/settings-manager.js";
7
- type ResourceType = "extensions" | "skills" | "prompts" | "themes";
7
+ type ResourceType = "extensions" | "skills" | "prompts";
8
8
  interface ResourceItem {
9
9
  path: string;
10
10
  enabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TUI component for managing package resources (enable/disable)\n */\n\nimport { basename, dirname, join, relative } from \"node:path\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\tInput,\n\tmatchesKey,\n\tSpacer,\n\ttruncateToWidth,\n\tvisibleWidth,\n} from \"@threadwell/tui\";\nimport { CONFIG_DIR_NAME } from \"../../../config.js\";\nimport type { PathMetadata, ResolvedPaths, ResolvedResource } from \"../../../core/package-manager.js\";\nimport type { PackageSource, SettingsManager } from \"../../../core/settings-manager.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { rawKeyHint } from \"./keybinding-hints.js\";\n\ntype ResourceType = \"extensions\" | \"skills\" | \"prompts\" | \"themes\";\n\nconst RESOURCE_TYPE_LABELS: Record<ResourceType, string> = {\n\textensions: \"Extensions\",\n\tskills: \"Skills\",\n\tprompts: \"Prompts\",\n\tthemes: \"Themes\",\n};\n\ninterface ResourceItem {\n\tpath: string;\n\tenabled: boolean;\n\tmetadata: PathMetadata;\n\tresourceType: ResourceType;\n\tdisplayName: string;\n\tgroupKey: string;\n\tsubgroupKey: string;\n}\n\ninterface ResourceSubgroup {\n\ttype: ResourceType;\n\tlabel: string;\n\titems: ResourceItem[];\n}\n\ninterface ResourceGroup {\n\tkey: string;\n\tlabel: string;\n\tscope: \"user\" | \"project\" | \"temporary\";\n\torigin: \"package\" | \"top-level\";\n\tsource: string;\n\tsubgroups: ResourceSubgroup[];\n}\n\nfunction getGroupLabel(metadata: PathMetadata): string {\n\tif (metadata.origin === \"package\") {\n\t\treturn `${metadata.source} (${metadata.scope})`;\n\t}\n\t// Top-level resources\n\tif (metadata.source === \"auto\") {\n\t\treturn metadata.scope === \"user\" ? \"User (~/.threadwell/agent/)\" : \"Project (.threadwell/)\";\n\t}\n\treturn metadata.scope === \"user\" ? \"User settings\" : \"Project settings\";\n}\n\nfunction buildGroups(resolved: ResolvedPaths): ResourceGroup[] {\n\tconst groupMap = new Map<string, ResourceGroup>();\n\n\tconst addToGroup = (resources: ResolvedResource[], resourceType: ResourceType) => {\n\t\tfor (const res of resources) {\n\t\t\tconst { path, enabled, metadata } = res;\n\t\t\tconst groupKey = `${metadata.origin}:${metadata.scope}:${metadata.source}`;\n\n\t\t\tif (!groupMap.has(groupKey)) {\n\t\t\t\tgroupMap.set(groupKey, {\n\t\t\t\t\tkey: groupKey,\n\t\t\t\t\tlabel: getGroupLabel(metadata),\n\t\t\t\t\tscope: metadata.scope,\n\t\t\t\t\torigin: metadata.origin,\n\t\t\t\t\tsource: metadata.source,\n\t\t\t\t\tsubgroups: [],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst group = groupMap.get(groupKey)!;\n\t\t\tconst subgroupKey = `${groupKey}:${resourceType}`;\n\n\t\t\tlet subgroup = group.subgroups.find((sg) => sg.type === resourceType);\n\t\t\tif (!subgroup) {\n\t\t\t\tsubgroup = {\n\t\t\t\t\ttype: resourceType,\n\t\t\t\t\tlabel: RESOURCE_TYPE_LABELS[resourceType],\n\t\t\t\t\titems: [],\n\t\t\t\t};\n\t\t\t\tgroup.subgroups.push(subgroup);\n\t\t\t}\n\n\t\t\tconst fileName = basename(path);\n\t\t\tconst parentFolder = basename(dirname(path));\n\t\t\tlet displayName: string;\n\t\t\tif (resourceType === \"extensions\" && parentFolder !== \"extensions\") {\n\t\t\t\tdisplayName = `${parentFolder}/${fileName}`;\n\t\t\t} else if (resourceType === \"skills\" && fileName === \"SKILL.md\") {\n\t\t\t\tdisplayName = parentFolder;\n\t\t\t} else {\n\t\t\t\tdisplayName = fileName;\n\t\t\t}\n\t\t\tsubgroup.items.push({\n\t\t\t\tpath,\n\t\t\t\tenabled,\n\t\t\t\tmetadata,\n\t\t\t\tresourceType,\n\t\t\t\tdisplayName,\n\t\t\t\tgroupKey,\n\t\t\t\tsubgroupKey,\n\t\t\t});\n\t\t}\n\t};\n\n\taddToGroup(resolved.extensions, \"extensions\");\n\taddToGroup(resolved.skills, \"skills\");\n\taddToGroup(resolved.prompts, \"prompts\");\n\taddToGroup(resolved.themes, \"themes\");\n\n\t// Sort groups: packages first, then top-level; user before project\n\tconst groups = Array.from(groupMap.values());\n\tgroups.sort((a, b) => {\n\t\tif (a.origin !== b.origin) {\n\t\t\treturn a.origin === \"package\" ? -1 : 1;\n\t\t}\n\t\tif (a.scope !== b.scope) {\n\t\t\treturn a.scope === \"user\" ? -1 : 1;\n\t\t}\n\t\treturn a.source.localeCompare(b.source);\n\t});\n\n\t// Sort subgroups within each group by type order, and items by name\n\tconst typeOrder: Record<ResourceType, number> = { extensions: 0, skills: 1, prompts: 2, themes: 3 };\n\tfor (const group of groups) {\n\t\tgroup.subgroups.sort((a, b) => typeOrder[a.type] - typeOrder[b.type]);\n\t\tfor (const subgroup of group.subgroups) {\n\t\t\tsubgroup.items.sort((a, b) => a.displayName.localeCompare(b.displayName));\n\t\t}\n\t}\n\n\treturn groups;\n}\n\ntype FlatEntry =\n\t| { type: \"group\"; group: ResourceGroup }\n\t| { type: \"subgroup\"; subgroup: ResourceSubgroup; group: ResourceGroup }\n\t| { type: \"item\"; item: ResourceItem };\n\nclass ConfigSelectorHeader implements Component {\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst title = theme.bold(\"Resource Configuration\");\n\t\tconst sep = theme.fg(\"muted\", \" · \");\n\t\tconst hint = rawKeyHint(\"space\", \"toggle\") + sep + rawKeyHint(\"esc\", \"close\");\n\t\tconst hintWidth = visibleWidth(hint);\n\t\tconst titleWidth = visibleWidth(title);\n\t\tconst spacing = Math.max(1, width - titleWidth - hintWidth);\n\n\t\treturn [\n\t\t\ttruncateToWidth(`${title}${\" \".repeat(spacing)}${hint}`, width, \"\"),\n\t\t\ttheme.fg(\"muted\", \"Type to filter resources\"),\n\t\t];\n\t}\n}\n\nclass ResourceList implements Component, Focusable {\n\tprivate groups: ResourceGroup[];\n\tprivate flatItems: FlatEntry[] = [];\n\tprivate filteredItems: FlatEntry[] = [];\n\tprivate selectedIndex = 0;\n\tprivate searchInput: Input;\n\tprivate maxVisible = 15;\n\tprivate settingsManager: SettingsManager;\n\tprivate cwd: string;\n\tprivate agentDir: string;\n\n\tpublic onCancel?: () => void;\n\tpublic onExit?: () => void;\n\tpublic onToggle?: (item: ResourceItem, newEnabled: boolean) => void;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tconstructor(groups: ResourceGroup[], settingsManager: SettingsManager, cwd: string, agentDir: string) {\n\t\tthis.groups = groups;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.cwd = cwd;\n\t\tthis.agentDir = agentDir;\n\t\tthis.searchInput = new Input();\n\t\tthis.buildFlatList();\n\t\tthis.filteredItems = [...this.flatItems];\n\t}\n\n\tprivate buildFlatList(): void {\n\t\tthis.flatItems = [];\n\t\tfor (const group of this.groups) {\n\t\t\tthis.flatItems.push({ type: \"group\", group });\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tthis.flatItems.push({ type: \"subgroup\", subgroup, group });\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tthis.flatItems.push({ type: \"item\", item });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Start selection on first item (not header)\n\t\tthis.selectedIndex = this.flatItems.findIndex((e) => e.type === \"item\");\n\t\tif (this.selectedIndex < 0) this.selectedIndex = 0;\n\t}\n\n\tprivate findNextItem(fromIndex: number, direction: 1 | -1): number {\n\t\tlet idx = fromIndex + direction;\n\t\twhile (idx >= 0 && idx < this.filteredItems.length) {\n\t\t\tif (this.filteredItems[idx].type === \"item\") {\n\t\t\t\treturn idx;\n\t\t\t}\n\t\t\tidx += direction;\n\t\t}\n\t\treturn fromIndex; // Stay at current if no item found\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (!query.trim()) {\n\t\t\tthis.filteredItems = [...this.flatItems];\n\t\t\tthis.selectFirstItem();\n\t\t\treturn;\n\t\t}\n\n\t\tconst lowerQuery = query.toLowerCase();\n\t\tconst matchingItems = new Set<ResourceItem>();\n\t\tconst matchingSubgroups = new Set<ResourceSubgroup>();\n\t\tconst matchingGroups = new Set<ResourceGroup>();\n\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"item\") {\n\t\t\t\tconst item = entry.item;\n\t\t\t\tif (\n\t\t\t\t\titem.displayName.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.resourceType.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.path.toLowerCase().includes(lowerQuery)\n\t\t\t\t) {\n\t\t\t\t\tmatchingItems.add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find which subgroups and groups contain matching items\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tif (matchingItems.has(item)) {\n\t\t\t\t\t\tmatchingSubgroups.add(subgroup);\n\t\t\t\t\t\tmatchingGroups.add(group);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.filteredItems = [];\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"group\" && matchingGroups.has(entry.group)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"subgroup\" && matchingSubgroups.has(entry.subgroup)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"item\" && matchingItems.has(entry.item)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t}\n\t\t}\n\n\t\tthis.selectFirstItem();\n\t}\n\n\tprivate selectFirstItem(): void {\n\t\tconst firstItemIndex = this.filteredItems.findIndex((e) => e.type === \"item\");\n\t\tthis.selectedIndex = firstItemIndex >= 0 ? firstItemIndex : 0;\n\t}\n\n\tupdateItem(item: ResourceItem, enabled: boolean): void {\n\t\titem.enabled = enabled;\n\t\t// Update in groups too\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tconst found = subgroup.items.find((i) => i.path === item.path && i.resourceType === item.resourceType);\n\t\t\t\tif (found) {\n\t\t\t\t\tfound.enabled = enabled;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Search input\n\t\tlines.push(...this.searchInput.render(width));\n\t\tlines.push(\"\");\n\n\t\tif (this.filteredItems.length === 0) {\n\t\t\tlines.push(theme.fg(\"muted\", \" No resources found\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\t// Calculate visible range\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst entry = this.filteredItems[i];\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tif (entry.type === \"group\") {\n\t\t\t\t// Main group header (no cursor)\n\t\t\t\tconst groupLine = theme.fg(\"accent\", theme.bold(entry.group.label));\n\t\t\t\tlines.push(truncateToWidth(` ${groupLine}`, width, \"\"));\n\t\t\t} else if (entry.type === \"subgroup\") {\n\t\t\t\t// Subgroup header (indented, no cursor)\n\t\t\t\tconst subgroupLine = theme.fg(\"muted\", entry.subgroup.label);\n\t\t\t\tlines.push(truncateToWidth(` ${subgroupLine}`, width, \"\"));\n\t\t\t} else {\n\t\t\t\t// Resource item (cursor only on items)\n\t\t\t\tconst item = entry.item;\n\t\t\t\tconst cursor = isSelected ? \"> \" : \" \";\n\t\t\t\tconst checkbox = item.enabled ? theme.fg(\"success\", \"[x]\") : theme.fg(\"dim\", \"[ ]\");\n\t\t\t\tconst name = isSelected ? theme.bold(item.displayName) : item.displayName;\n\t\t\t\tlines.push(truncateToWidth(`${cursor} ${checkbox} ${name}`, width, \"...\"));\n\t\t\t}\n\t\t}\n\n\t\t// Scroll indicator\n\t\tif (startIndex > 0 || endIndex < this.filteredItems.length) {\n\t\t\tconst itemCount = this.filteredItems.filter((e) => e.type === \"item\").length;\n\t\t\tconst currentItemIndex =\n\t\t\t\tthis.filteredItems.slice(0, this.selectedIndex).filter((e) => e.type === \"item\").length + 1;\n\t\t\tlines.push(theme.fg(\"dim\", ` (${currentItemIndex}/${itemCount})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, -1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageUp\")) {\n\t\t\t// Jump up by maxVisible, then find nearest item\n\t\t\tlet target = Math.max(0, this.selectedIndex - this.maxVisible);\n\t\t\twhile (target < this.filteredItems.length && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget++;\n\t\t\t}\n\t\t\tif (target < this.filteredItems.length) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageDown\")) {\n\t\t\t// Jump down by maxVisible, then find nearest item\n\t\t\tlet target = Math.min(this.filteredItems.length - 1, this.selectedIndex + this.maxVisible);\n\t\t\twhile (target >= 0 && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget--;\n\t\t\t}\n\t\t\tif (target >= 0) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel?.();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \" \" || kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.filteredItems[this.selectedIndex];\n\t\t\tif (entry?.type === \"item\") {\n\t\t\t\tconst newEnabled = !entry.item.enabled;\n\t\t\t\tthis.toggleResource(entry.item, newEnabled);\n\t\t\t\tthis.updateItem(entry.item, newEnabled);\n\t\t\t\tthis.onToggle?.(entry.item, newEnabled);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass to search input\n\t\tthis.searchInput.handleInput(data);\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate toggleResource(item: ResourceItem, enabled: boolean): void {\n\t\tif (item.metadata.origin === \"top-level\") {\n\t\t\tthis.toggleTopLevelResource(item, enabled);\n\t\t} else {\n\t\t\tthis.togglePackageResource(item, enabled);\n\t\t}\n\t}\n\n\tprivate toggleTopLevelResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst arrayKey = item.resourceType as \"extensions\" | \"skills\" | \"prompts\" | \"themes\";\n\t\tconst current = (settings[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern for this resource\n\t\tconst pattern = this.getResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setProjectExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setProjectSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setProjectPromptTemplatePaths(updated);\n\t\t\t} else if (arrayKey === \"themes\") {\n\t\t\t\tthis.settingsManager.setProjectThemePaths(updated);\n\t\t\t}\n\t\t} else {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setPromptTemplatePaths(updated);\n\t\t\t} else if (arrayKey === \"themes\") {\n\t\t\t\tthis.settingsManager.setThemePaths(updated);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate togglePackageResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst packages = [...(settings.packages ?? [])] as PackageSource[];\n\t\tconst pkgIndex = packages.findIndex((pkg) => {\n\t\t\tconst source = typeof pkg === \"string\" ? pkg : pkg.source;\n\t\t\treturn source === item.metadata.source;\n\t\t});\n\n\t\tif (pkgIndex === -1) return;\n\n\t\tlet pkg = packages[pkgIndex];\n\n\t\t// Convert string to object form if needed\n\t\tif (typeof pkg === \"string\") {\n\t\t\tpkg = { source: pkg };\n\t\t\tpackages[pkgIndex] = pkg;\n\t\t}\n\n\t\t// Get the resource array for this type\n\t\tconst arrayKey = item.resourceType as \"extensions\" | \"skills\" | \"prompts\" | \"themes\";\n\t\tconst current = (pkg[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern relative to package root\n\t\tconst pattern = this.getPackageResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\t(pkg as Record<string, unknown>)[arrayKey] = updated.length > 0 ? updated : undefined;\n\n\t\t// Clean up empty filter object\n\t\tconst hasFilters = [\"extensions\", \"skills\", \"prompts\", \"themes\"].some(\n\t\t\t(k) => (pkg as Record<string, unknown>)[k] !== undefined,\n\t\t);\n\t\tif (!hasFilters) {\n\t\t\tpackages[pkgIndex] = (pkg as { source: string }).source;\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tthis.settingsManager.setProjectPackages(packages);\n\t\t} else {\n\t\t\tthis.settingsManager.setPackages(packages);\n\t\t}\n\t}\n\n\tprivate getTopLevelBaseDir(scope: \"user\" | \"project\"): string {\n\t\treturn scope === \"project\" ? join(this.cwd, CONFIG_DIR_NAME) : this.agentDir;\n\t}\n\n\tprivate getResourcePattern(item: ResourceItem): string {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst baseDir = this.getTopLevelBaseDir(scope);\n\t\treturn relative(baseDir, item.path);\n\t}\n\n\tprivate getPackageResourcePattern(item: ResourceItem): string {\n\t\tconst baseDir = item.metadata.baseDir ?? dirname(item.path);\n\t\treturn relative(baseDir, item.path);\n\t}\n}\n\nexport class ConfigSelectorComponent extends Container implements Focusable {\n\tprivate resourceList: ResourceList;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.resourceList.focused = value;\n\t}\n\n\tconstructor(\n\t\tresolvedPaths: ResolvedPaths,\n\t\tsettingsManager: SettingsManager,\n\t\tcwd: string,\n\t\tagentDir: string,\n\t\tonClose: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\n\t\tconst groups = buildGroups(resolvedPaths);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new ConfigSelectorHeader());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Resource list\n\t\tthis.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir);\n\t\tthis.resourceList.onCancel = onClose;\n\t\tthis.resourceList.onExit = onExit;\n\t\tthis.resourceList.onToggle = () => requestRender();\n\t\tthis.addChild(this.resourceList);\n\n\t\t// Bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tgetResourceList(): ResourceList {\n\t\treturn this.resourceList;\n\t}\n}\n"]}
1
+ {"version":3,"file":"config-selector.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TUI component for managing package resources (enable/disable)\n */\n\nimport { basename, dirname, join, relative } from \"node:path\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\tInput,\n\tmatchesKey,\n\tSpacer,\n\ttruncateToWidth,\n\tvisibleWidth,\n} from \"@threadwell/tui\";\nimport { CONFIG_DIR_NAME } from \"../../../config.js\";\nimport type { PathMetadata, ResolvedPaths, ResolvedResource } from \"../../../core/package-manager.js\";\nimport type { PackageSource, SettingsManager } from \"../../../core/settings-manager.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { rawKeyHint } from \"./keybinding-hints.js\";\n\ntype ResourceType = \"extensions\" | \"skills\" | \"prompts\";\n\nconst RESOURCE_TYPE_LABELS: Record<ResourceType, string> = {\n\textensions: \"Extensions\",\n\tskills: \"Skills\",\n\tprompts: \"Prompts\",\n};\n\ninterface ResourceItem {\n\tpath: string;\n\tenabled: boolean;\n\tmetadata: PathMetadata;\n\tresourceType: ResourceType;\n\tdisplayName: string;\n\tgroupKey: string;\n\tsubgroupKey: string;\n}\n\ninterface ResourceSubgroup {\n\ttype: ResourceType;\n\tlabel: string;\n\titems: ResourceItem[];\n}\n\ninterface ResourceGroup {\n\tkey: string;\n\tlabel: string;\n\tscope: \"user\" | \"project\" | \"temporary\";\n\torigin: \"package\" | \"top-level\";\n\tsource: string;\n\tsubgroups: ResourceSubgroup[];\n}\n\nfunction getGroupLabel(metadata: PathMetadata): string {\n\tif (metadata.origin === \"package\") {\n\t\treturn `${metadata.source} (${metadata.scope})`;\n\t}\n\t// Top-level resources\n\tif (metadata.source === \"auto\") {\n\t\treturn metadata.scope === \"user\" ? \"User (~/.threadwell/agent/)\" : \"Project (.threadwell/)\";\n\t}\n\treturn metadata.scope === \"user\" ? \"User settings\" : \"Project settings\";\n}\n\nfunction buildGroups(resolved: ResolvedPaths): ResourceGroup[] {\n\tconst groupMap = new Map<string, ResourceGroup>();\n\n\tconst addToGroup = (resources: ResolvedResource[], resourceType: ResourceType) => {\n\t\tfor (const res of resources) {\n\t\t\tconst { path, enabled, metadata } = res;\n\t\t\tconst groupKey = `${metadata.origin}:${metadata.scope}:${metadata.source}`;\n\n\t\t\tif (!groupMap.has(groupKey)) {\n\t\t\t\tgroupMap.set(groupKey, {\n\t\t\t\t\tkey: groupKey,\n\t\t\t\t\tlabel: getGroupLabel(metadata),\n\t\t\t\t\tscope: metadata.scope,\n\t\t\t\t\torigin: metadata.origin,\n\t\t\t\t\tsource: metadata.source,\n\t\t\t\t\tsubgroups: [],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst group = groupMap.get(groupKey)!;\n\t\t\tconst subgroupKey = `${groupKey}:${resourceType}`;\n\n\t\t\tlet subgroup = group.subgroups.find((sg) => sg.type === resourceType);\n\t\t\tif (!subgroup) {\n\t\t\t\tsubgroup = {\n\t\t\t\t\ttype: resourceType,\n\t\t\t\t\tlabel: RESOURCE_TYPE_LABELS[resourceType],\n\t\t\t\t\titems: [],\n\t\t\t\t};\n\t\t\t\tgroup.subgroups.push(subgroup);\n\t\t\t}\n\n\t\t\tconst fileName = basename(path);\n\t\t\tconst parentFolder = basename(dirname(path));\n\t\t\tlet displayName: string;\n\t\t\tif (resourceType === \"extensions\" && parentFolder !== \"extensions\") {\n\t\t\t\tdisplayName = `${parentFolder}/${fileName}`;\n\t\t\t} else if (resourceType === \"skills\" && fileName === \"SKILL.md\") {\n\t\t\t\tdisplayName = parentFolder;\n\t\t\t} else {\n\t\t\t\tdisplayName = fileName;\n\t\t\t}\n\t\t\tsubgroup.items.push({\n\t\t\t\tpath,\n\t\t\t\tenabled,\n\t\t\t\tmetadata,\n\t\t\t\tresourceType,\n\t\t\t\tdisplayName,\n\t\t\t\tgroupKey,\n\t\t\t\tsubgroupKey,\n\t\t\t});\n\t\t}\n\t};\n\n\taddToGroup(resolved.extensions, \"extensions\");\n\taddToGroup(resolved.skills, \"skills\");\n\taddToGroup(resolved.prompts, \"prompts\");\n\n\t// Sort groups: packages first, then top-level; user before project\n\tconst groups = Array.from(groupMap.values());\n\tgroups.sort((a, b) => {\n\t\tif (a.origin !== b.origin) {\n\t\t\treturn a.origin === \"package\" ? -1 : 1;\n\t\t}\n\t\tif (a.scope !== b.scope) {\n\t\t\treturn a.scope === \"user\" ? -1 : 1;\n\t\t}\n\t\treturn a.source.localeCompare(b.source);\n\t});\n\n\t// Sort subgroups within each group by type order, and items by name\n\tconst typeOrder: Record<ResourceType, number> = { extensions: 0, skills: 1, prompts: 2 };\n\tfor (const group of groups) {\n\t\tgroup.subgroups.sort((a, b) => typeOrder[a.type] - typeOrder[b.type]);\n\t\tfor (const subgroup of group.subgroups) {\n\t\t\tsubgroup.items.sort((a, b) => a.displayName.localeCompare(b.displayName));\n\t\t}\n\t}\n\n\treturn groups;\n}\n\ntype FlatEntry =\n\t| { type: \"group\"; group: ResourceGroup }\n\t| { type: \"subgroup\"; subgroup: ResourceSubgroup; group: ResourceGroup }\n\t| { type: \"item\"; item: ResourceItem };\n\nclass ConfigSelectorHeader implements Component {\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst title = theme.bold(\"Resource Configuration\");\n\t\tconst sep = theme.fg(\"muted\", \" · \");\n\t\tconst hint = rawKeyHint(\"space\", \"toggle\") + sep + rawKeyHint(\"esc\", \"close\");\n\t\tconst hintWidth = visibleWidth(hint);\n\t\tconst titleWidth = visibleWidth(title);\n\t\tconst spacing = Math.max(1, width - titleWidth - hintWidth);\n\n\t\treturn [\n\t\t\ttruncateToWidth(`${title}${\" \".repeat(spacing)}${hint}`, width, \"\"),\n\t\t\ttheme.fg(\"muted\", \"Type to filter resources\"),\n\t\t];\n\t}\n}\n\nclass ResourceList implements Component, Focusable {\n\tprivate groups: ResourceGroup[];\n\tprivate flatItems: FlatEntry[] = [];\n\tprivate filteredItems: FlatEntry[] = [];\n\tprivate selectedIndex = 0;\n\tprivate searchInput: Input;\n\tprivate maxVisible = 15;\n\tprivate settingsManager: SettingsManager;\n\tprivate cwd: string;\n\tprivate agentDir: string;\n\n\tpublic onCancel?: () => void;\n\tpublic onExit?: () => void;\n\tpublic onToggle?: (item: ResourceItem, newEnabled: boolean) => void;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tconstructor(groups: ResourceGroup[], settingsManager: SettingsManager, cwd: string, agentDir: string) {\n\t\tthis.groups = groups;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.cwd = cwd;\n\t\tthis.agentDir = agentDir;\n\t\tthis.searchInput = new Input();\n\t\tthis.buildFlatList();\n\t\tthis.filteredItems = [...this.flatItems];\n\t}\n\n\tprivate buildFlatList(): void {\n\t\tthis.flatItems = [];\n\t\tfor (const group of this.groups) {\n\t\t\tthis.flatItems.push({ type: \"group\", group });\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tthis.flatItems.push({ type: \"subgroup\", subgroup, group });\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tthis.flatItems.push({ type: \"item\", item });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Start selection on first item (not header)\n\t\tthis.selectedIndex = this.flatItems.findIndex((e) => e.type === \"item\");\n\t\tif (this.selectedIndex < 0) this.selectedIndex = 0;\n\t}\n\n\tprivate findNextItem(fromIndex: number, direction: 1 | -1): number {\n\t\tlet idx = fromIndex + direction;\n\t\twhile (idx >= 0 && idx < this.filteredItems.length) {\n\t\t\tif (this.filteredItems[idx].type === \"item\") {\n\t\t\t\treturn idx;\n\t\t\t}\n\t\t\tidx += direction;\n\t\t}\n\t\treturn fromIndex; // Stay at current if no item found\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (!query.trim()) {\n\t\t\tthis.filteredItems = [...this.flatItems];\n\t\t\tthis.selectFirstItem();\n\t\t\treturn;\n\t\t}\n\n\t\tconst lowerQuery = query.toLowerCase();\n\t\tconst matchingItems = new Set<ResourceItem>();\n\t\tconst matchingSubgroups = new Set<ResourceSubgroup>();\n\t\tconst matchingGroups = new Set<ResourceGroup>();\n\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"item\") {\n\t\t\t\tconst item = entry.item;\n\t\t\t\tif (\n\t\t\t\t\titem.displayName.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.resourceType.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.path.toLowerCase().includes(lowerQuery)\n\t\t\t\t) {\n\t\t\t\t\tmatchingItems.add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find which subgroups and groups contain matching items\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tif (matchingItems.has(item)) {\n\t\t\t\t\t\tmatchingSubgroups.add(subgroup);\n\t\t\t\t\t\tmatchingGroups.add(group);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.filteredItems = [];\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"group\" && matchingGroups.has(entry.group)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"subgroup\" && matchingSubgroups.has(entry.subgroup)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"item\" && matchingItems.has(entry.item)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t}\n\t\t}\n\n\t\tthis.selectFirstItem();\n\t}\n\n\tprivate selectFirstItem(): void {\n\t\tconst firstItemIndex = this.filteredItems.findIndex((e) => e.type === \"item\");\n\t\tthis.selectedIndex = firstItemIndex >= 0 ? firstItemIndex : 0;\n\t}\n\n\tupdateItem(item: ResourceItem, enabled: boolean): void {\n\t\titem.enabled = enabled;\n\t\t// Update in groups too\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tconst found = subgroup.items.find((i) => i.path === item.path && i.resourceType === item.resourceType);\n\t\t\t\tif (found) {\n\t\t\t\t\tfound.enabled = enabled;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Search input\n\t\tlines.push(...this.searchInput.render(width));\n\t\tlines.push(\"\");\n\n\t\tif (this.filteredItems.length === 0) {\n\t\t\tlines.push(theme.fg(\"muted\", \" No resources found\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\t// Calculate visible range\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst entry = this.filteredItems[i];\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tif (entry.type === \"group\") {\n\t\t\t\t// Main group header (no cursor)\n\t\t\t\tconst groupLine = theme.fg(\"accent\", theme.bold(entry.group.label));\n\t\t\t\tlines.push(truncateToWidth(` ${groupLine}`, width, \"\"));\n\t\t\t} else if (entry.type === \"subgroup\") {\n\t\t\t\t// Subgroup header (indented, no cursor)\n\t\t\t\tconst subgroupLine = theme.fg(\"muted\", entry.subgroup.label);\n\t\t\t\tlines.push(truncateToWidth(` ${subgroupLine}`, width, \"\"));\n\t\t\t} else {\n\t\t\t\t// Resource item (cursor only on items)\n\t\t\t\tconst item = entry.item;\n\t\t\t\tconst cursor = isSelected ? \"> \" : \" \";\n\t\t\t\tconst checkbox = item.enabled ? theme.fg(\"success\", \"[x]\") : theme.fg(\"dim\", \"[ ]\");\n\t\t\t\tconst name = isSelected ? theme.bold(item.displayName) : item.displayName;\n\t\t\t\tlines.push(truncateToWidth(`${cursor} ${checkbox} ${name}`, width, \"...\"));\n\t\t\t}\n\t\t}\n\n\t\t// Scroll indicator\n\t\tif (startIndex > 0 || endIndex < this.filteredItems.length) {\n\t\t\tconst itemCount = this.filteredItems.filter((e) => e.type === \"item\").length;\n\t\t\tconst currentItemIndex =\n\t\t\t\tthis.filteredItems.slice(0, this.selectedIndex).filter((e) => e.type === \"item\").length + 1;\n\t\t\tlines.push(theme.fg(\"dim\", ` (${currentItemIndex}/${itemCount})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, -1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageUp\")) {\n\t\t\t// Jump up by maxVisible, then find nearest item\n\t\t\tlet target = Math.max(0, this.selectedIndex - this.maxVisible);\n\t\t\twhile (target < this.filteredItems.length && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget++;\n\t\t\t}\n\t\t\tif (target < this.filteredItems.length) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageDown\")) {\n\t\t\t// Jump down by maxVisible, then find nearest item\n\t\t\tlet target = Math.min(this.filteredItems.length - 1, this.selectedIndex + this.maxVisible);\n\t\t\twhile (target >= 0 && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget--;\n\t\t\t}\n\t\t\tif (target >= 0) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel?.();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \" \" || kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.filteredItems[this.selectedIndex];\n\t\t\tif (entry?.type === \"item\") {\n\t\t\t\tconst newEnabled = !entry.item.enabled;\n\t\t\t\tthis.toggleResource(entry.item, newEnabled);\n\t\t\t\tthis.updateItem(entry.item, newEnabled);\n\t\t\t\tthis.onToggle?.(entry.item, newEnabled);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass to search input\n\t\tthis.searchInput.handleInput(data);\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate toggleResource(item: ResourceItem, enabled: boolean): void {\n\t\tif (item.metadata.origin === \"top-level\") {\n\t\t\tthis.toggleTopLevelResource(item, enabled);\n\t\t} else {\n\t\t\tthis.togglePackageResource(item, enabled);\n\t\t}\n\t}\n\n\tprivate toggleTopLevelResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst arrayKey = item.resourceType;\n\t\tconst current = (settings[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern for this resource\n\t\tconst pattern = this.getResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setProjectExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setProjectSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setProjectPromptTemplatePaths(updated);\n\t\t\t}\n\t\t} else {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setPromptTemplatePaths(updated);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate togglePackageResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst packages = [...(settings.packages ?? [])] as PackageSource[];\n\t\tconst pkgIndex = packages.findIndex((pkg) => {\n\t\t\tconst source = typeof pkg === \"string\" ? pkg : pkg.source;\n\t\t\treturn source === item.metadata.source;\n\t\t});\n\n\t\tif (pkgIndex === -1) return;\n\n\t\tlet pkg = packages[pkgIndex];\n\n\t\t// Convert string to object form if needed\n\t\tif (typeof pkg === \"string\") {\n\t\t\tpkg = { source: pkg };\n\t\t\tpackages[pkgIndex] = pkg;\n\t\t}\n\n\t\t// Get the resource array for this type\n\t\tconst arrayKey = item.resourceType;\n\t\tconst current = (pkg[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern relative to package root\n\t\tconst pattern = this.getPackageResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\t(pkg as Record<string, unknown>)[arrayKey] = updated.length > 0 ? updated : undefined;\n\n\t\t// Clean up empty filter object\n\t\tconst hasFilters = [\"extensions\", \"skills\", \"prompts\", \"themes\"].some(\n\t\t\t(k) => (pkg as Record<string, unknown>)[k] !== undefined,\n\t\t);\n\t\tif (!hasFilters) {\n\t\t\tpackages[pkgIndex] = (pkg as { source: string }).source;\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tthis.settingsManager.setProjectPackages(packages);\n\t\t} else {\n\t\t\tthis.settingsManager.setPackages(packages);\n\t\t}\n\t}\n\n\tprivate getTopLevelBaseDir(scope: \"user\" | \"project\"): string {\n\t\treturn scope === \"project\" ? join(this.cwd, CONFIG_DIR_NAME) : this.agentDir;\n\t}\n\n\tprivate getResourcePattern(item: ResourceItem): string {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst baseDir = this.getTopLevelBaseDir(scope);\n\t\treturn relative(baseDir, item.path);\n\t}\n\n\tprivate getPackageResourcePattern(item: ResourceItem): string {\n\t\tconst baseDir = item.metadata.baseDir ?? dirname(item.path);\n\t\treturn relative(baseDir, item.path);\n\t}\n}\n\nexport class ConfigSelectorComponent extends Container implements Focusable {\n\tprivate resourceList: ResourceList;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.resourceList.focused = value;\n\t}\n\n\tconstructor(\n\t\tresolvedPaths: ResolvedPaths,\n\t\tsettingsManager: SettingsManager,\n\t\tcwd: string,\n\t\tagentDir: string,\n\t\tonClose: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\n\t\tconst groups = buildGroups(resolvedPaths);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new ConfigSelectorHeader());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Resource list\n\t\tthis.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir);\n\t\tthis.resourceList.onCancel = onClose;\n\t\tthis.resourceList.onExit = onExit;\n\t\tthis.resourceList.onToggle = () => requestRender();\n\t\tthis.addChild(this.resourceList);\n\n\t\t// Bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tgetResourceList(): ResourceList {\n\t\treturn this.resourceList;\n\t}\n}\n"]}
@@ -11,7 +11,6 @@ const RESOURCE_TYPE_LABELS = {
11
11
  extensions: "Extensions",
12
12
  skills: "Skills",
13
13
  prompts: "Prompts",
14
- themes: "Themes",
15
14
  };
16
15
  function getGroupLabel(metadata) {
17
16
  if (metadata.origin === "package") {
@@ -76,7 +75,6 @@ function buildGroups(resolved) {
76
75
  addToGroup(resolved.extensions, "extensions");
77
76
  addToGroup(resolved.skills, "skills");
78
77
  addToGroup(resolved.prompts, "prompts");
79
- addToGroup(resolved.themes, "themes");
80
78
  // Sort groups: packages first, then top-level; user before project
81
79
  const groups = Array.from(groupMap.values());
82
80
  groups.sort((a, b) => {
@@ -89,7 +87,7 @@ function buildGroups(resolved) {
89
87
  return a.source.localeCompare(b.source);
90
88
  });
91
89
  // Sort subgroups within each group by type order, and items by name
92
- const typeOrder = { extensions: 0, skills: 1, prompts: 2, themes: 3 };
90
+ const typeOrder = { extensions: 0, skills: 1, prompts: 2 };
93
91
  for (const group of groups) {
94
92
  group.subgroups.sort((a, b) => typeOrder[a.type] - typeOrder[b.type]);
95
93
  for (const subgroup of group.subgroups) {
@@ -366,9 +364,6 @@ class ResourceList {
366
364
  else if (arrayKey === "prompts") {
367
365
  this.settingsManager.setProjectPromptTemplatePaths(updated);
368
366
  }
369
- else if (arrayKey === "themes") {
370
- this.settingsManager.setProjectThemePaths(updated);
371
- }
372
367
  }
373
368
  else {
374
369
  if (arrayKey === "extensions") {
@@ -380,9 +375,6 @@ class ResourceList {
380
375
  else if (arrayKey === "prompts") {
381
376
  this.settingsManager.setPromptTemplatePaths(updated);
382
377
  }
383
- else if (arrayKey === "themes") {
384
- this.settingsManager.setThemePaths(updated);
385
- }
386
378
  }
387
379
  }
388
380
  togglePackageResource(item, enabled) {
@@ -1 +1 @@
1
- {"version":3,"file":"config-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TUI component for managing package resources (enable/disable)\n */\n\nimport { basename, dirname, join, relative } from \"node:path\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\tInput,\n\tmatchesKey,\n\tSpacer,\n\ttruncateToWidth,\n\tvisibleWidth,\n} from \"@threadwell/tui\";\nimport { CONFIG_DIR_NAME } from \"../../../config.js\";\nimport type { PathMetadata, ResolvedPaths, ResolvedResource } from \"../../../core/package-manager.js\";\nimport type { PackageSource, SettingsManager } from \"../../../core/settings-manager.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { rawKeyHint } from \"./keybinding-hints.js\";\n\ntype ResourceType = \"extensions\" | \"skills\" | \"prompts\" | \"themes\";\n\nconst RESOURCE_TYPE_LABELS: Record<ResourceType, string> = {\n\textensions: \"Extensions\",\n\tskills: \"Skills\",\n\tprompts: \"Prompts\",\n\tthemes: \"Themes\",\n};\n\ninterface ResourceItem {\n\tpath: string;\n\tenabled: boolean;\n\tmetadata: PathMetadata;\n\tresourceType: ResourceType;\n\tdisplayName: string;\n\tgroupKey: string;\n\tsubgroupKey: string;\n}\n\ninterface ResourceSubgroup {\n\ttype: ResourceType;\n\tlabel: string;\n\titems: ResourceItem[];\n}\n\ninterface ResourceGroup {\n\tkey: string;\n\tlabel: string;\n\tscope: \"user\" | \"project\" | \"temporary\";\n\torigin: \"package\" | \"top-level\";\n\tsource: string;\n\tsubgroups: ResourceSubgroup[];\n}\n\nfunction getGroupLabel(metadata: PathMetadata): string {\n\tif (metadata.origin === \"package\") {\n\t\treturn `${metadata.source} (${metadata.scope})`;\n\t}\n\t// Top-level resources\n\tif (metadata.source === \"auto\") {\n\t\treturn metadata.scope === \"user\" ? \"User (~/.threadwell/agent/)\" : \"Project (.threadwell/)\";\n\t}\n\treturn metadata.scope === \"user\" ? \"User settings\" : \"Project settings\";\n}\n\nfunction buildGroups(resolved: ResolvedPaths): ResourceGroup[] {\n\tconst groupMap = new Map<string, ResourceGroup>();\n\n\tconst addToGroup = (resources: ResolvedResource[], resourceType: ResourceType) => {\n\t\tfor (const res of resources) {\n\t\t\tconst { path, enabled, metadata } = res;\n\t\t\tconst groupKey = `${metadata.origin}:${metadata.scope}:${metadata.source}`;\n\n\t\t\tif (!groupMap.has(groupKey)) {\n\t\t\t\tgroupMap.set(groupKey, {\n\t\t\t\t\tkey: groupKey,\n\t\t\t\t\tlabel: getGroupLabel(metadata),\n\t\t\t\t\tscope: metadata.scope,\n\t\t\t\t\torigin: metadata.origin,\n\t\t\t\t\tsource: metadata.source,\n\t\t\t\t\tsubgroups: [],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst group = groupMap.get(groupKey)!;\n\t\t\tconst subgroupKey = `${groupKey}:${resourceType}`;\n\n\t\t\tlet subgroup = group.subgroups.find((sg) => sg.type === resourceType);\n\t\t\tif (!subgroup) {\n\t\t\t\tsubgroup = {\n\t\t\t\t\ttype: resourceType,\n\t\t\t\t\tlabel: RESOURCE_TYPE_LABELS[resourceType],\n\t\t\t\t\titems: [],\n\t\t\t\t};\n\t\t\t\tgroup.subgroups.push(subgroup);\n\t\t\t}\n\n\t\t\tconst fileName = basename(path);\n\t\t\tconst parentFolder = basename(dirname(path));\n\t\t\tlet displayName: string;\n\t\t\tif (resourceType === \"extensions\" && parentFolder !== \"extensions\") {\n\t\t\t\tdisplayName = `${parentFolder}/${fileName}`;\n\t\t\t} else if (resourceType === \"skills\" && fileName === \"SKILL.md\") {\n\t\t\t\tdisplayName = parentFolder;\n\t\t\t} else {\n\t\t\t\tdisplayName = fileName;\n\t\t\t}\n\t\t\tsubgroup.items.push({\n\t\t\t\tpath,\n\t\t\t\tenabled,\n\t\t\t\tmetadata,\n\t\t\t\tresourceType,\n\t\t\t\tdisplayName,\n\t\t\t\tgroupKey,\n\t\t\t\tsubgroupKey,\n\t\t\t});\n\t\t}\n\t};\n\n\taddToGroup(resolved.extensions, \"extensions\");\n\taddToGroup(resolved.skills, \"skills\");\n\taddToGroup(resolved.prompts, \"prompts\");\n\taddToGroup(resolved.themes, \"themes\");\n\n\t// Sort groups: packages first, then top-level; user before project\n\tconst groups = Array.from(groupMap.values());\n\tgroups.sort((a, b) => {\n\t\tif (a.origin !== b.origin) {\n\t\t\treturn a.origin === \"package\" ? -1 : 1;\n\t\t}\n\t\tif (a.scope !== b.scope) {\n\t\t\treturn a.scope === \"user\" ? -1 : 1;\n\t\t}\n\t\treturn a.source.localeCompare(b.source);\n\t});\n\n\t// Sort subgroups within each group by type order, and items by name\n\tconst typeOrder: Record<ResourceType, number> = { extensions: 0, skills: 1, prompts: 2, themes: 3 };\n\tfor (const group of groups) {\n\t\tgroup.subgroups.sort((a, b) => typeOrder[a.type] - typeOrder[b.type]);\n\t\tfor (const subgroup of group.subgroups) {\n\t\t\tsubgroup.items.sort((a, b) => a.displayName.localeCompare(b.displayName));\n\t\t}\n\t}\n\n\treturn groups;\n}\n\ntype FlatEntry =\n\t| { type: \"group\"; group: ResourceGroup }\n\t| { type: \"subgroup\"; subgroup: ResourceSubgroup; group: ResourceGroup }\n\t| { type: \"item\"; item: ResourceItem };\n\nclass ConfigSelectorHeader implements Component {\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst title = theme.bold(\"Resource Configuration\");\n\t\tconst sep = theme.fg(\"muted\", \" · \");\n\t\tconst hint = rawKeyHint(\"space\", \"toggle\") + sep + rawKeyHint(\"esc\", \"close\");\n\t\tconst hintWidth = visibleWidth(hint);\n\t\tconst titleWidth = visibleWidth(title);\n\t\tconst spacing = Math.max(1, width - titleWidth - hintWidth);\n\n\t\treturn [\n\t\t\ttruncateToWidth(`${title}${\" \".repeat(spacing)}${hint}`, width, \"\"),\n\t\t\ttheme.fg(\"muted\", \"Type to filter resources\"),\n\t\t];\n\t}\n}\n\nclass ResourceList implements Component, Focusable {\n\tprivate groups: ResourceGroup[];\n\tprivate flatItems: FlatEntry[] = [];\n\tprivate filteredItems: FlatEntry[] = [];\n\tprivate selectedIndex = 0;\n\tprivate searchInput: Input;\n\tprivate maxVisible = 15;\n\tprivate settingsManager: SettingsManager;\n\tprivate cwd: string;\n\tprivate agentDir: string;\n\n\tpublic onCancel?: () => void;\n\tpublic onExit?: () => void;\n\tpublic onToggle?: (item: ResourceItem, newEnabled: boolean) => void;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tconstructor(groups: ResourceGroup[], settingsManager: SettingsManager, cwd: string, agentDir: string) {\n\t\tthis.groups = groups;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.cwd = cwd;\n\t\tthis.agentDir = agentDir;\n\t\tthis.searchInput = new Input();\n\t\tthis.buildFlatList();\n\t\tthis.filteredItems = [...this.flatItems];\n\t}\n\n\tprivate buildFlatList(): void {\n\t\tthis.flatItems = [];\n\t\tfor (const group of this.groups) {\n\t\t\tthis.flatItems.push({ type: \"group\", group });\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tthis.flatItems.push({ type: \"subgroup\", subgroup, group });\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tthis.flatItems.push({ type: \"item\", item });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Start selection on first item (not header)\n\t\tthis.selectedIndex = this.flatItems.findIndex((e) => e.type === \"item\");\n\t\tif (this.selectedIndex < 0) this.selectedIndex = 0;\n\t}\n\n\tprivate findNextItem(fromIndex: number, direction: 1 | -1): number {\n\t\tlet idx = fromIndex + direction;\n\t\twhile (idx >= 0 && idx < this.filteredItems.length) {\n\t\t\tif (this.filteredItems[idx].type === \"item\") {\n\t\t\t\treturn idx;\n\t\t\t}\n\t\t\tidx += direction;\n\t\t}\n\t\treturn fromIndex; // Stay at current if no item found\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (!query.trim()) {\n\t\t\tthis.filteredItems = [...this.flatItems];\n\t\t\tthis.selectFirstItem();\n\t\t\treturn;\n\t\t}\n\n\t\tconst lowerQuery = query.toLowerCase();\n\t\tconst matchingItems = new Set<ResourceItem>();\n\t\tconst matchingSubgroups = new Set<ResourceSubgroup>();\n\t\tconst matchingGroups = new Set<ResourceGroup>();\n\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"item\") {\n\t\t\t\tconst item = entry.item;\n\t\t\t\tif (\n\t\t\t\t\titem.displayName.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.resourceType.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.path.toLowerCase().includes(lowerQuery)\n\t\t\t\t) {\n\t\t\t\t\tmatchingItems.add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find which subgroups and groups contain matching items\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tif (matchingItems.has(item)) {\n\t\t\t\t\t\tmatchingSubgroups.add(subgroup);\n\t\t\t\t\t\tmatchingGroups.add(group);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.filteredItems = [];\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"group\" && matchingGroups.has(entry.group)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"subgroup\" && matchingSubgroups.has(entry.subgroup)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"item\" && matchingItems.has(entry.item)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t}\n\t\t}\n\n\t\tthis.selectFirstItem();\n\t}\n\n\tprivate selectFirstItem(): void {\n\t\tconst firstItemIndex = this.filteredItems.findIndex((e) => e.type === \"item\");\n\t\tthis.selectedIndex = firstItemIndex >= 0 ? firstItemIndex : 0;\n\t}\n\n\tupdateItem(item: ResourceItem, enabled: boolean): void {\n\t\titem.enabled = enabled;\n\t\t// Update in groups too\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tconst found = subgroup.items.find((i) => i.path === item.path && i.resourceType === item.resourceType);\n\t\t\t\tif (found) {\n\t\t\t\t\tfound.enabled = enabled;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Search input\n\t\tlines.push(...this.searchInput.render(width));\n\t\tlines.push(\"\");\n\n\t\tif (this.filteredItems.length === 0) {\n\t\t\tlines.push(theme.fg(\"muted\", \" No resources found\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\t// Calculate visible range\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst entry = this.filteredItems[i];\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tif (entry.type === \"group\") {\n\t\t\t\t// Main group header (no cursor)\n\t\t\t\tconst groupLine = theme.fg(\"accent\", theme.bold(entry.group.label));\n\t\t\t\tlines.push(truncateToWidth(` ${groupLine}`, width, \"\"));\n\t\t\t} else if (entry.type === \"subgroup\") {\n\t\t\t\t// Subgroup header (indented, no cursor)\n\t\t\t\tconst subgroupLine = theme.fg(\"muted\", entry.subgroup.label);\n\t\t\t\tlines.push(truncateToWidth(` ${subgroupLine}`, width, \"\"));\n\t\t\t} else {\n\t\t\t\t// Resource item (cursor only on items)\n\t\t\t\tconst item = entry.item;\n\t\t\t\tconst cursor = isSelected ? \"> \" : \" \";\n\t\t\t\tconst checkbox = item.enabled ? theme.fg(\"success\", \"[x]\") : theme.fg(\"dim\", \"[ ]\");\n\t\t\t\tconst name = isSelected ? theme.bold(item.displayName) : item.displayName;\n\t\t\t\tlines.push(truncateToWidth(`${cursor} ${checkbox} ${name}`, width, \"...\"));\n\t\t\t}\n\t\t}\n\n\t\t// Scroll indicator\n\t\tif (startIndex > 0 || endIndex < this.filteredItems.length) {\n\t\t\tconst itemCount = this.filteredItems.filter((e) => e.type === \"item\").length;\n\t\t\tconst currentItemIndex =\n\t\t\t\tthis.filteredItems.slice(0, this.selectedIndex).filter((e) => e.type === \"item\").length + 1;\n\t\t\tlines.push(theme.fg(\"dim\", ` (${currentItemIndex}/${itemCount})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, -1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageUp\")) {\n\t\t\t// Jump up by maxVisible, then find nearest item\n\t\t\tlet target = Math.max(0, this.selectedIndex - this.maxVisible);\n\t\t\twhile (target < this.filteredItems.length && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget++;\n\t\t\t}\n\t\t\tif (target < this.filteredItems.length) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageDown\")) {\n\t\t\t// Jump down by maxVisible, then find nearest item\n\t\t\tlet target = Math.min(this.filteredItems.length - 1, this.selectedIndex + this.maxVisible);\n\t\t\twhile (target >= 0 && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget--;\n\t\t\t}\n\t\t\tif (target >= 0) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel?.();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \" \" || kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.filteredItems[this.selectedIndex];\n\t\t\tif (entry?.type === \"item\") {\n\t\t\t\tconst newEnabled = !entry.item.enabled;\n\t\t\t\tthis.toggleResource(entry.item, newEnabled);\n\t\t\t\tthis.updateItem(entry.item, newEnabled);\n\t\t\t\tthis.onToggle?.(entry.item, newEnabled);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass to search input\n\t\tthis.searchInput.handleInput(data);\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate toggleResource(item: ResourceItem, enabled: boolean): void {\n\t\tif (item.metadata.origin === \"top-level\") {\n\t\t\tthis.toggleTopLevelResource(item, enabled);\n\t\t} else {\n\t\t\tthis.togglePackageResource(item, enabled);\n\t\t}\n\t}\n\n\tprivate toggleTopLevelResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst arrayKey = item.resourceType as \"extensions\" | \"skills\" | \"prompts\" | \"themes\";\n\t\tconst current = (settings[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern for this resource\n\t\tconst pattern = this.getResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setProjectExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setProjectSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setProjectPromptTemplatePaths(updated);\n\t\t\t} else if (arrayKey === \"themes\") {\n\t\t\t\tthis.settingsManager.setProjectThemePaths(updated);\n\t\t\t}\n\t\t} else {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setPromptTemplatePaths(updated);\n\t\t\t} else if (arrayKey === \"themes\") {\n\t\t\t\tthis.settingsManager.setThemePaths(updated);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate togglePackageResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst packages = [...(settings.packages ?? [])] as PackageSource[];\n\t\tconst pkgIndex = packages.findIndex((pkg) => {\n\t\t\tconst source = typeof pkg === \"string\" ? pkg : pkg.source;\n\t\t\treturn source === item.metadata.source;\n\t\t});\n\n\t\tif (pkgIndex === -1) return;\n\n\t\tlet pkg = packages[pkgIndex];\n\n\t\t// Convert string to object form if needed\n\t\tif (typeof pkg === \"string\") {\n\t\t\tpkg = { source: pkg };\n\t\t\tpackages[pkgIndex] = pkg;\n\t\t}\n\n\t\t// Get the resource array for this type\n\t\tconst arrayKey = item.resourceType as \"extensions\" | \"skills\" | \"prompts\" | \"themes\";\n\t\tconst current = (pkg[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern relative to package root\n\t\tconst pattern = this.getPackageResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\t(pkg as Record<string, unknown>)[arrayKey] = updated.length > 0 ? updated : undefined;\n\n\t\t// Clean up empty filter object\n\t\tconst hasFilters = [\"extensions\", \"skills\", \"prompts\", \"themes\"].some(\n\t\t\t(k) => (pkg as Record<string, unknown>)[k] !== undefined,\n\t\t);\n\t\tif (!hasFilters) {\n\t\t\tpackages[pkgIndex] = (pkg as { source: string }).source;\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tthis.settingsManager.setProjectPackages(packages);\n\t\t} else {\n\t\t\tthis.settingsManager.setPackages(packages);\n\t\t}\n\t}\n\n\tprivate getTopLevelBaseDir(scope: \"user\" | \"project\"): string {\n\t\treturn scope === \"project\" ? join(this.cwd, CONFIG_DIR_NAME) : this.agentDir;\n\t}\n\n\tprivate getResourcePattern(item: ResourceItem): string {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst baseDir = this.getTopLevelBaseDir(scope);\n\t\treturn relative(baseDir, item.path);\n\t}\n\n\tprivate getPackageResourcePattern(item: ResourceItem): string {\n\t\tconst baseDir = item.metadata.baseDir ?? dirname(item.path);\n\t\treturn relative(baseDir, item.path);\n\t}\n}\n\nexport class ConfigSelectorComponent extends Container implements Focusable {\n\tprivate resourceList: ResourceList;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.resourceList.focused = value;\n\t}\n\n\tconstructor(\n\t\tresolvedPaths: ResolvedPaths,\n\t\tsettingsManager: SettingsManager,\n\t\tcwd: string,\n\t\tagentDir: string,\n\t\tonClose: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\n\t\tconst groups = buildGroups(resolvedPaths);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new ConfigSelectorHeader());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Resource list\n\t\tthis.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir);\n\t\tthis.resourceList.onCancel = onClose;\n\t\tthis.resourceList.onExit = onExit;\n\t\tthis.resourceList.onToggle = () => requestRender();\n\t\tthis.addChild(this.resourceList);\n\n\t\t// Bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tgetResourceList(): ResourceList {\n\t\treturn this.resourceList;\n\t}\n}\n"]}
1
+ {"version":3,"file":"config-selector.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/config-selector.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TUI component for managing package resources (enable/disable)\n */\n\nimport { basename, dirname, join, relative } from \"node:path\";\nimport {\n\ttype Component,\n\tContainer,\n\ttype Focusable,\n\tgetKeybindings,\n\tInput,\n\tmatchesKey,\n\tSpacer,\n\ttruncateToWidth,\n\tvisibleWidth,\n} from \"@threadwell/tui\";\nimport { CONFIG_DIR_NAME } from \"../../../config.js\";\nimport type { PathMetadata, ResolvedPaths, ResolvedResource } from \"../../../core/package-manager.js\";\nimport type { PackageSource, SettingsManager } from \"../../../core/settings-manager.js\";\nimport { theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.js\";\nimport { rawKeyHint } from \"./keybinding-hints.js\";\n\ntype ResourceType = \"extensions\" | \"skills\" | \"prompts\";\n\nconst RESOURCE_TYPE_LABELS: Record<ResourceType, string> = {\n\textensions: \"Extensions\",\n\tskills: \"Skills\",\n\tprompts: \"Prompts\",\n};\n\ninterface ResourceItem {\n\tpath: string;\n\tenabled: boolean;\n\tmetadata: PathMetadata;\n\tresourceType: ResourceType;\n\tdisplayName: string;\n\tgroupKey: string;\n\tsubgroupKey: string;\n}\n\ninterface ResourceSubgroup {\n\ttype: ResourceType;\n\tlabel: string;\n\titems: ResourceItem[];\n}\n\ninterface ResourceGroup {\n\tkey: string;\n\tlabel: string;\n\tscope: \"user\" | \"project\" | \"temporary\";\n\torigin: \"package\" | \"top-level\";\n\tsource: string;\n\tsubgroups: ResourceSubgroup[];\n}\n\nfunction getGroupLabel(metadata: PathMetadata): string {\n\tif (metadata.origin === \"package\") {\n\t\treturn `${metadata.source} (${metadata.scope})`;\n\t}\n\t// Top-level resources\n\tif (metadata.source === \"auto\") {\n\t\treturn metadata.scope === \"user\" ? \"User (~/.threadwell/agent/)\" : \"Project (.threadwell/)\";\n\t}\n\treturn metadata.scope === \"user\" ? \"User settings\" : \"Project settings\";\n}\n\nfunction buildGroups(resolved: ResolvedPaths): ResourceGroup[] {\n\tconst groupMap = new Map<string, ResourceGroup>();\n\n\tconst addToGroup = (resources: ResolvedResource[], resourceType: ResourceType) => {\n\t\tfor (const res of resources) {\n\t\t\tconst { path, enabled, metadata } = res;\n\t\t\tconst groupKey = `${metadata.origin}:${metadata.scope}:${metadata.source}`;\n\n\t\t\tif (!groupMap.has(groupKey)) {\n\t\t\t\tgroupMap.set(groupKey, {\n\t\t\t\t\tkey: groupKey,\n\t\t\t\t\tlabel: getGroupLabel(metadata),\n\t\t\t\t\tscope: metadata.scope,\n\t\t\t\t\torigin: metadata.origin,\n\t\t\t\t\tsource: metadata.source,\n\t\t\t\t\tsubgroups: [],\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst group = groupMap.get(groupKey)!;\n\t\t\tconst subgroupKey = `${groupKey}:${resourceType}`;\n\n\t\t\tlet subgroup = group.subgroups.find((sg) => sg.type === resourceType);\n\t\t\tif (!subgroup) {\n\t\t\t\tsubgroup = {\n\t\t\t\t\ttype: resourceType,\n\t\t\t\t\tlabel: RESOURCE_TYPE_LABELS[resourceType],\n\t\t\t\t\titems: [],\n\t\t\t\t};\n\t\t\t\tgroup.subgroups.push(subgroup);\n\t\t\t}\n\n\t\t\tconst fileName = basename(path);\n\t\t\tconst parentFolder = basename(dirname(path));\n\t\t\tlet displayName: string;\n\t\t\tif (resourceType === \"extensions\" && parentFolder !== \"extensions\") {\n\t\t\t\tdisplayName = `${parentFolder}/${fileName}`;\n\t\t\t} else if (resourceType === \"skills\" && fileName === \"SKILL.md\") {\n\t\t\t\tdisplayName = parentFolder;\n\t\t\t} else {\n\t\t\t\tdisplayName = fileName;\n\t\t\t}\n\t\t\tsubgroup.items.push({\n\t\t\t\tpath,\n\t\t\t\tenabled,\n\t\t\t\tmetadata,\n\t\t\t\tresourceType,\n\t\t\t\tdisplayName,\n\t\t\t\tgroupKey,\n\t\t\t\tsubgroupKey,\n\t\t\t});\n\t\t}\n\t};\n\n\taddToGroup(resolved.extensions, \"extensions\");\n\taddToGroup(resolved.skills, \"skills\");\n\taddToGroup(resolved.prompts, \"prompts\");\n\n\t// Sort groups: packages first, then top-level; user before project\n\tconst groups = Array.from(groupMap.values());\n\tgroups.sort((a, b) => {\n\t\tif (a.origin !== b.origin) {\n\t\t\treturn a.origin === \"package\" ? -1 : 1;\n\t\t}\n\t\tif (a.scope !== b.scope) {\n\t\t\treturn a.scope === \"user\" ? -1 : 1;\n\t\t}\n\t\treturn a.source.localeCompare(b.source);\n\t});\n\n\t// Sort subgroups within each group by type order, and items by name\n\tconst typeOrder: Record<ResourceType, number> = { extensions: 0, skills: 1, prompts: 2 };\n\tfor (const group of groups) {\n\t\tgroup.subgroups.sort((a, b) => typeOrder[a.type] - typeOrder[b.type]);\n\t\tfor (const subgroup of group.subgroups) {\n\t\t\tsubgroup.items.sort((a, b) => a.displayName.localeCompare(b.displayName));\n\t\t}\n\t}\n\n\treturn groups;\n}\n\ntype FlatEntry =\n\t| { type: \"group\"; group: ResourceGroup }\n\t| { type: \"subgroup\"; subgroup: ResourceSubgroup; group: ResourceGroup }\n\t| { type: \"item\"; item: ResourceItem };\n\nclass ConfigSelectorHeader implements Component {\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst title = theme.bold(\"Resource Configuration\");\n\t\tconst sep = theme.fg(\"muted\", \" · \");\n\t\tconst hint = rawKeyHint(\"space\", \"toggle\") + sep + rawKeyHint(\"esc\", \"close\");\n\t\tconst hintWidth = visibleWidth(hint);\n\t\tconst titleWidth = visibleWidth(title);\n\t\tconst spacing = Math.max(1, width - titleWidth - hintWidth);\n\n\t\treturn [\n\t\t\ttruncateToWidth(`${title}${\" \".repeat(spacing)}${hint}`, width, \"\"),\n\t\t\ttheme.fg(\"muted\", \"Type to filter resources\"),\n\t\t];\n\t}\n}\n\nclass ResourceList implements Component, Focusable {\n\tprivate groups: ResourceGroup[];\n\tprivate flatItems: FlatEntry[] = [];\n\tprivate filteredItems: FlatEntry[] = [];\n\tprivate selectedIndex = 0;\n\tprivate searchInput: Input;\n\tprivate maxVisible = 15;\n\tprivate settingsManager: SettingsManager;\n\tprivate cwd: string;\n\tprivate agentDir: string;\n\n\tpublic onCancel?: () => void;\n\tpublic onExit?: () => void;\n\tpublic onToggle?: (item: ResourceItem, newEnabled: boolean) => void;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.searchInput.focused = value;\n\t}\n\n\tconstructor(groups: ResourceGroup[], settingsManager: SettingsManager, cwd: string, agentDir: string) {\n\t\tthis.groups = groups;\n\t\tthis.settingsManager = settingsManager;\n\t\tthis.cwd = cwd;\n\t\tthis.agentDir = agentDir;\n\t\tthis.searchInput = new Input();\n\t\tthis.buildFlatList();\n\t\tthis.filteredItems = [...this.flatItems];\n\t}\n\n\tprivate buildFlatList(): void {\n\t\tthis.flatItems = [];\n\t\tfor (const group of this.groups) {\n\t\t\tthis.flatItems.push({ type: \"group\", group });\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tthis.flatItems.push({ type: \"subgroup\", subgroup, group });\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tthis.flatItems.push({ type: \"item\", item });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Start selection on first item (not header)\n\t\tthis.selectedIndex = this.flatItems.findIndex((e) => e.type === \"item\");\n\t\tif (this.selectedIndex < 0) this.selectedIndex = 0;\n\t}\n\n\tprivate findNextItem(fromIndex: number, direction: 1 | -1): number {\n\t\tlet idx = fromIndex + direction;\n\t\twhile (idx >= 0 && idx < this.filteredItems.length) {\n\t\t\tif (this.filteredItems[idx].type === \"item\") {\n\t\t\t\treturn idx;\n\t\t\t}\n\t\t\tidx += direction;\n\t\t}\n\t\treturn fromIndex; // Stay at current if no item found\n\t}\n\n\tprivate filterItems(query: string): void {\n\t\tif (!query.trim()) {\n\t\t\tthis.filteredItems = [...this.flatItems];\n\t\t\tthis.selectFirstItem();\n\t\t\treturn;\n\t\t}\n\n\t\tconst lowerQuery = query.toLowerCase();\n\t\tconst matchingItems = new Set<ResourceItem>();\n\t\tconst matchingSubgroups = new Set<ResourceSubgroup>();\n\t\tconst matchingGroups = new Set<ResourceGroup>();\n\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"item\") {\n\t\t\t\tconst item = entry.item;\n\t\t\t\tif (\n\t\t\t\t\titem.displayName.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.resourceType.toLowerCase().includes(lowerQuery) ||\n\t\t\t\t\titem.path.toLowerCase().includes(lowerQuery)\n\t\t\t\t) {\n\t\t\t\t\tmatchingItems.add(item);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find which subgroups and groups contain matching items\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tfor (const item of subgroup.items) {\n\t\t\t\t\tif (matchingItems.has(item)) {\n\t\t\t\t\t\tmatchingSubgroups.add(subgroup);\n\t\t\t\t\t\tmatchingGroups.add(group);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.filteredItems = [];\n\t\tfor (const entry of this.flatItems) {\n\t\t\tif (entry.type === \"group\" && matchingGroups.has(entry.group)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"subgroup\" && matchingSubgroups.has(entry.subgroup)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t} else if (entry.type === \"item\" && matchingItems.has(entry.item)) {\n\t\t\t\tthis.filteredItems.push(entry);\n\t\t\t}\n\t\t}\n\n\t\tthis.selectFirstItem();\n\t}\n\n\tprivate selectFirstItem(): void {\n\t\tconst firstItemIndex = this.filteredItems.findIndex((e) => e.type === \"item\");\n\t\tthis.selectedIndex = firstItemIndex >= 0 ? firstItemIndex : 0;\n\t}\n\n\tupdateItem(item: ResourceItem, enabled: boolean): void {\n\t\titem.enabled = enabled;\n\t\t// Update in groups too\n\t\tfor (const group of this.groups) {\n\t\t\tfor (const subgroup of group.subgroups) {\n\t\t\t\tconst found = subgroup.items.find((i) => i.path === item.path && i.resourceType === item.resourceType);\n\t\t\t\tif (found) {\n\t\t\t\t\tfound.enabled = enabled;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tinvalidate(): void {}\n\n\trender(width: number): string[] {\n\t\tconst lines: string[] = [];\n\n\t\t// Search input\n\t\tlines.push(...this.searchInput.render(width));\n\t\tlines.push(\"\");\n\n\t\tif (this.filteredItems.length === 0) {\n\t\t\tlines.push(theme.fg(\"muted\", \" No resources found\"));\n\t\t\treturn lines;\n\t\t}\n\n\t\t// Calculate visible range\n\t\tconst startIndex = Math.max(\n\t\t\t0,\n\t\t\tMath.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible),\n\t\t);\n\t\tconst endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);\n\n\t\tfor (let i = startIndex; i < endIndex; i++) {\n\t\t\tconst entry = this.filteredItems[i];\n\t\t\tconst isSelected = i === this.selectedIndex;\n\n\t\t\tif (entry.type === \"group\") {\n\t\t\t\t// Main group header (no cursor)\n\t\t\t\tconst groupLine = theme.fg(\"accent\", theme.bold(entry.group.label));\n\t\t\t\tlines.push(truncateToWidth(` ${groupLine}`, width, \"\"));\n\t\t\t} else if (entry.type === \"subgroup\") {\n\t\t\t\t// Subgroup header (indented, no cursor)\n\t\t\t\tconst subgroupLine = theme.fg(\"muted\", entry.subgroup.label);\n\t\t\t\tlines.push(truncateToWidth(` ${subgroupLine}`, width, \"\"));\n\t\t\t} else {\n\t\t\t\t// Resource item (cursor only on items)\n\t\t\t\tconst item = entry.item;\n\t\t\t\tconst cursor = isSelected ? \"> \" : \" \";\n\t\t\t\tconst checkbox = item.enabled ? theme.fg(\"success\", \"[x]\") : theme.fg(\"dim\", \"[ ]\");\n\t\t\t\tconst name = isSelected ? theme.bold(item.displayName) : item.displayName;\n\t\t\t\tlines.push(truncateToWidth(`${cursor} ${checkbox} ${name}`, width, \"...\"));\n\t\t\t}\n\t\t}\n\n\t\t// Scroll indicator\n\t\tif (startIndex > 0 || endIndex < this.filteredItems.length) {\n\t\t\tconst itemCount = this.filteredItems.filter((e) => e.type === \"item\").length;\n\t\t\tconst currentItemIndex =\n\t\t\t\tthis.filteredItems.slice(0, this.selectedIndex).filter((e) => e.type === \"item\").length + 1;\n\t\t\tlines.push(theme.fg(\"dim\", ` (${currentItemIndex}/${itemCount})`));\n\t\t}\n\n\t\treturn lines;\n\t}\n\n\thandleInput(data: string): void {\n\t\tconst kb = getKeybindings();\n\n\t\tif (kb.matches(data, \"tui.select.up\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, -1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.down\")) {\n\t\t\tthis.selectedIndex = this.findNextItem(this.selectedIndex, 1);\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageUp\")) {\n\t\t\t// Jump up by maxVisible, then find nearest item\n\t\t\tlet target = Math.max(0, this.selectedIndex - this.maxVisible);\n\t\t\twhile (target < this.filteredItems.length && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget++;\n\t\t\t}\n\t\t\tif (target < this.filteredItems.length) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.pageDown\")) {\n\t\t\t// Jump down by maxVisible, then find nearest item\n\t\t\tlet target = Math.min(this.filteredItems.length - 1, this.selectedIndex + this.maxVisible);\n\t\t\twhile (target >= 0 && this.filteredItems[target].type !== \"item\") {\n\t\t\t\ttarget--;\n\t\t\t}\n\t\t\tif (target >= 0) {\n\t\t\t\tthis.selectedIndex = target;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.onCancel?.();\n\t\t\treturn;\n\t\t}\n\t\tif (matchesKey(data, \"ctrl+c\")) {\n\t\t\tthis.onExit?.();\n\t\t\treturn;\n\t\t}\n\t\tif (data === \" \" || kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tconst entry = this.filteredItems[this.selectedIndex];\n\t\t\tif (entry?.type === \"item\") {\n\t\t\t\tconst newEnabled = !entry.item.enabled;\n\t\t\t\tthis.toggleResource(entry.item, newEnabled);\n\t\t\t\tthis.updateItem(entry.item, newEnabled);\n\t\t\t\tthis.onToggle?.(entry.item, newEnabled);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// Pass to search input\n\t\tthis.searchInput.handleInput(data);\n\t\tthis.filterItems(this.searchInput.getValue());\n\t}\n\n\tprivate toggleResource(item: ResourceItem, enabled: boolean): void {\n\t\tif (item.metadata.origin === \"top-level\") {\n\t\t\tthis.toggleTopLevelResource(item, enabled);\n\t\t} else {\n\t\t\tthis.togglePackageResource(item, enabled);\n\t\t}\n\t}\n\n\tprivate toggleTopLevelResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst arrayKey = item.resourceType;\n\t\tconst current = (settings[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern for this resource\n\t\tconst pattern = this.getResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setProjectExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setProjectSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setProjectPromptTemplatePaths(updated);\n\t\t\t}\n\t\t} else {\n\t\t\tif (arrayKey === \"extensions\") {\n\t\t\t\tthis.settingsManager.setExtensionPaths(updated);\n\t\t\t} else if (arrayKey === \"skills\") {\n\t\t\t\tthis.settingsManager.setSkillPaths(updated);\n\t\t\t} else if (arrayKey === \"prompts\") {\n\t\t\t\tthis.settingsManager.setPromptTemplatePaths(updated);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate togglePackageResource(item: ResourceItem, enabled: boolean): void {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst settings =\n\t\t\tscope === \"project\" ? this.settingsManager.getProjectSettings() : this.settingsManager.getGlobalSettings();\n\n\t\tconst packages = [...(settings.packages ?? [])] as PackageSource[];\n\t\tconst pkgIndex = packages.findIndex((pkg) => {\n\t\t\tconst source = typeof pkg === \"string\" ? pkg : pkg.source;\n\t\t\treturn source === item.metadata.source;\n\t\t});\n\n\t\tif (pkgIndex === -1) return;\n\n\t\tlet pkg = packages[pkgIndex];\n\n\t\t// Convert string to object form if needed\n\t\tif (typeof pkg === \"string\") {\n\t\t\tpkg = { source: pkg };\n\t\t\tpackages[pkgIndex] = pkg;\n\t\t}\n\n\t\t// Get the resource array for this type\n\t\tconst arrayKey = item.resourceType;\n\t\tconst current = (pkg[arrayKey] ?? []) as string[];\n\n\t\t// Generate pattern relative to package root\n\t\tconst pattern = this.getPackageResourcePattern(item);\n\t\tconst disablePattern = `-${pattern}`;\n\t\tconst enablePattern = `+${pattern}`;\n\n\t\t// Filter out existing patterns for this resource\n\t\tconst updated = current.filter((p) => {\n\t\t\tconst stripped = p.startsWith(\"!\") || p.startsWith(\"+\") || p.startsWith(\"-\") ? p.slice(1) : p;\n\t\t\treturn stripped !== pattern;\n\t\t});\n\n\t\tif (enabled) {\n\t\t\tupdated.push(enablePattern);\n\t\t} else {\n\t\t\tupdated.push(disablePattern);\n\t\t}\n\n\t\t(pkg as Record<string, unknown>)[arrayKey] = updated.length > 0 ? updated : undefined;\n\n\t\t// Clean up empty filter object\n\t\tconst hasFilters = [\"extensions\", \"skills\", \"prompts\", \"themes\"].some(\n\t\t\t(k) => (pkg as Record<string, unknown>)[k] !== undefined,\n\t\t);\n\t\tif (!hasFilters) {\n\t\t\tpackages[pkgIndex] = (pkg as { source: string }).source;\n\t\t}\n\n\t\tif (scope === \"project\") {\n\t\t\tthis.settingsManager.setProjectPackages(packages);\n\t\t} else {\n\t\t\tthis.settingsManager.setPackages(packages);\n\t\t}\n\t}\n\n\tprivate getTopLevelBaseDir(scope: \"user\" | \"project\"): string {\n\t\treturn scope === \"project\" ? join(this.cwd, CONFIG_DIR_NAME) : this.agentDir;\n\t}\n\n\tprivate getResourcePattern(item: ResourceItem): string {\n\t\tconst scope = item.metadata.scope as \"user\" | \"project\";\n\t\tconst baseDir = this.getTopLevelBaseDir(scope);\n\t\treturn relative(baseDir, item.path);\n\t}\n\n\tprivate getPackageResourcePattern(item: ResourceItem): string {\n\t\tconst baseDir = item.metadata.baseDir ?? dirname(item.path);\n\t\treturn relative(baseDir, item.path);\n\t}\n}\n\nexport class ConfigSelectorComponent extends Container implements Focusable {\n\tprivate resourceList: ResourceList;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.resourceList.focused = value;\n\t}\n\n\tconstructor(\n\t\tresolvedPaths: ResolvedPaths,\n\t\tsettingsManager: SettingsManager,\n\t\tcwd: string,\n\t\tagentDir: string,\n\t\tonClose: () => void,\n\t\tonExit: () => void,\n\t\trequestRender: () => void,\n\t) {\n\t\tsuper();\n\n\t\tconst groups = buildGroups(resolvedPaths);\n\n\t\t// Add header\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new ConfigSelectorHeader());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Resource list\n\t\tthis.resourceList = new ResourceList(groups, settingsManager, cwd, agentDir);\n\t\tthis.resourceList.onCancel = onClose;\n\t\tthis.resourceList.onExit = onExit;\n\t\tthis.resourceList.onToggle = () => requestRender();\n\t\tthis.addChild(this.resourceList);\n\n\t\t// Bottom border\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\tgetResourceList(): ResourceList {\n\t\treturn this.resourceList;\n\t}\n}\n"]}
@@ -16,5 +16,8 @@ export declare class CustomMessageComponent extends Container {
16
16
  setExpanded(expanded: boolean): void;
17
17
  invalidate(): void;
18
18
  private rebuild;
19
+ private getTextContent;
20
+ private rebuildEnhancedFallback;
21
+ private rebuildBaselineFallback;
19
22
  }
20
23
  //# sourceMappingURL=custom-message.d.ts.map