@agimon-ai/doompi-ui 0.0.1-alpha.0

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 (176) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  4. package/dist/_virtual/_rolldown/runtime.mjs +1 -0
  5. package/dist/components/configOverlay.cjs +0 -0
  6. package/dist/components/configOverlay.cjs.map +1 -0
  7. package/dist/components/configOverlay.d.cts +0 -0
  8. package/dist/components/configOverlay.d.cts.map +1 -0
  9. package/dist/components/configOverlay.d.mts +0 -0
  10. package/dist/components/configOverlay.d.mts.map +1 -0
  11. package/dist/components/configOverlay.mjs +0 -0
  12. package/dist/components/configOverlay.mjs.map +1 -0
  13. package/dist/components/doomEditor.cjs +2 -0
  14. package/dist/components/doomEditor.cjs.map +1 -0
  15. package/dist/components/doomEditor.d.cts +59 -0
  16. package/dist/components/doomEditor.d.cts.map +1 -0
  17. package/dist/components/doomEditor.d.mts +59 -0
  18. package/dist/components/doomEditor.d.mts.map +1 -0
  19. package/dist/components/doomEditor.mjs +2 -0
  20. package/dist/components/doomEditor.mjs.map +1 -0
  21. package/dist/components/doomFooter.cjs +2 -0
  22. package/dist/components/doomFooter.cjs.map +1 -0
  23. package/dist/components/doomFooter.d.cts +32 -0
  24. package/dist/components/doomFooter.d.cts.map +1 -0
  25. package/dist/components/doomFooter.d.mts +32 -0
  26. package/dist/components/doomFooter.d.mts.map +1 -0
  27. package/dist/components/doomFooter.mjs +2 -0
  28. package/dist/components/doomFooter.mjs.map +1 -0
  29. package/dist/components/doomHeader.cjs +2 -0
  30. package/dist/components/doomHeader.cjs.map +1 -0
  31. package/dist/components/doomHeader.d.cts +34 -0
  32. package/dist/components/doomHeader.d.cts.map +1 -0
  33. package/dist/components/doomHeader.d.mts +34 -0
  34. package/dist/components/doomHeader.d.mts.map +1 -0
  35. package/dist/components/doomHeader.mjs +2 -0
  36. package/dist/components/doomHeader.mjs.map +1 -0
  37. package/dist/components/doomOverlay.cjs +2 -0
  38. package/dist/components/doomOverlay.cjs.map +1 -0
  39. package/dist/components/doomOverlay.d.cts +79 -0
  40. package/dist/components/doomOverlay.d.cts.map +1 -0
  41. package/dist/components/doomOverlay.d.mts +79 -0
  42. package/dist/components/doomOverlay.d.mts.map +1 -0
  43. package/dist/components/doomOverlay.mjs +2 -0
  44. package/dist/components/doomOverlay.mjs.map +1 -0
  45. package/dist/components/leaderHints.cjs +2 -0
  46. package/dist/components/leaderHints.cjs.map +1 -0
  47. package/dist/components/leaderHints.d.cts +37 -0
  48. package/dist/components/leaderHints.d.cts.map +1 -0
  49. package/dist/components/leaderHints.d.mts +37 -0
  50. package/dist/components/leaderHints.d.mts.map +1 -0
  51. package/dist/components/leaderHints.mjs +2 -0
  52. package/dist/components/leaderHints.mjs.map +1 -0
  53. package/dist/components/toolsOverlay.cjs +2 -0
  54. package/dist/components/toolsOverlay.cjs.map +1 -0
  55. package/dist/components/toolsOverlay.d.cts +29 -0
  56. package/dist/components/toolsOverlay.d.cts.map +1 -0
  57. package/dist/components/toolsOverlay.d.mts +29 -0
  58. package/dist/components/toolsOverlay.d.mts.map +1 -0
  59. package/dist/components/toolsOverlay.mjs +2 -0
  60. package/dist/components/toolsOverlay.mjs.map +1 -0
  61. package/dist/config.cjs +2 -0
  62. package/dist/config.cjs.map +1 -0
  63. package/dist/config.d.cts +5 -0
  64. package/dist/config.d.cts.map +1 -0
  65. package/dist/config.d.mts +5 -0
  66. package/dist/config.d.mts.map +1 -0
  67. package/dist/config.mjs +2 -0
  68. package/dist/config.mjs.map +1 -0
  69. package/dist/extension.cjs +2 -0
  70. package/dist/extension.cjs.map +1 -0
  71. package/dist/extension.d.cts +7 -0
  72. package/dist/extension.d.cts.map +1 -0
  73. package/dist/extension.d.mts +7 -0
  74. package/dist/extension.d.mts.map +1 -0
  75. package/dist/extension.mjs +2 -0
  76. package/dist/extension.mjs.map +1 -0
  77. package/dist/extensionName.cjs +2 -0
  78. package/dist/extensionName.cjs.map +1 -0
  79. package/dist/extensionName.d.cts +5 -0
  80. package/dist/extensionName.d.cts.map +1 -0
  81. package/dist/extensionName.d.mts +5 -0
  82. package/dist/extensionName.d.mts.map +1 -0
  83. package/dist/extensionName.mjs +2 -0
  84. package/dist/extensionName.mjs.map +1 -0
  85. package/dist/extensions/pi.cjs +2 -0
  86. package/dist/extensions/pi.cjs.map +1 -0
  87. package/dist/extensions/pi.d.cts +2 -0
  88. package/dist/extensions/pi.d.mts +2 -0
  89. package/dist/extensions/pi.mjs +2 -0
  90. package/dist/extensions/pi.mjs.map +1 -0
  91. package/dist/footer.cjs +2 -0
  92. package/dist/footer.cjs.map +1 -0
  93. package/dist/footer.d.cts +5 -0
  94. package/dist/footer.d.cts.map +1 -0
  95. package/dist/footer.d.mts +5 -0
  96. package/dist/footer.d.mts.map +1 -0
  97. package/dist/footer.mjs +2 -0
  98. package/dist/footer.mjs.map +1 -0
  99. package/dist/harnessMetadata.cjs +2 -0
  100. package/dist/harnessMetadata.cjs.map +1 -0
  101. package/dist/harnessMetadata.d.cts +21 -0
  102. package/dist/harnessMetadata.d.cts.map +1 -0
  103. package/dist/harnessMetadata.d.mts +21 -0
  104. package/dist/harnessMetadata.d.mts.map +1 -0
  105. package/dist/harnessMetadata.mjs +2 -0
  106. package/dist/harnessMetadata.mjs.map +1 -0
  107. package/dist/index.cjs +1 -0
  108. package/dist/index.d.cts +25 -0
  109. package/dist/index.d.mts +25 -0
  110. package/dist/index.mjs +1 -0
  111. package/dist/leader.cjs +1 -0
  112. package/dist/leader.d.cts +2 -0
  113. package/dist/leader.d.mts +2 -0
  114. package/dist/leader.mjs +1 -0
  115. package/dist/leaderRegistry.cjs +2 -0
  116. package/dist/leaderRegistry.cjs.map +1 -0
  117. package/dist/leaderRegistry.d.cts +52 -0
  118. package/dist/leaderRegistry.d.cts.map +1 -0
  119. package/dist/leaderRegistry.d.mts +52 -0
  120. package/dist/leaderRegistry.d.mts.map +1 -0
  121. package/dist/leaderRegistry.mjs +2 -0
  122. package/dist/leaderRegistry.mjs.map +1 -0
  123. package/dist/logSinkTelemetry.cjs +2 -0
  124. package/dist/logSinkTelemetry.cjs.map +1 -0
  125. package/dist/logSinkTelemetry.d.cts +29 -0
  126. package/dist/logSinkTelemetry.d.cts.map +1 -0
  127. package/dist/logSinkTelemetry.d.mts +29 -0
  128. package/dist/logSinkTelemetry.d.mts.map +1 -0
  129. package/dist/logSinkTelemetry.mjs +2 -0
  130. package/dist/logSinkTelemetry.mjs.map +1 -0
  131. package/dist/mode.cjs +2 -0
  132. package/dist/mode.cjs.map +1 -0
  133. package/dist/mode.d.cts +5 -0
  134. package/dist/mode.d.cts.map +1 -0
  135. package/dist/mode.d.mts +5 -0
  136. package/dist/mode.d.mts.map +1 -0
  137. package/dist/mode.mjs +2 -0
  138. package/dist/mode.mjs.map +1 -0
  139. package/dist/rendering.cjs +2 -0
  140. package/dist/rendering.cjs.map +1 -0
  141. package/dist/rendering.d.cts +11 -0
  142. package/dist/rendering.d.cts.map +1 -0
  143. package/dist/rendering.d.mts +11 -0
  144. package/dist/rendering.d.mts.map +1 -0
  145. package/dist/rendering.mjs +2 -0
  146. package/dist/rendering.mjs.map +1 -0
  147. package/dist/skills.cjs +1 -0
  148. package/dist/skills.d.cts +1 -0
  149. package/dist/skills.d.mts +1 -0
  150. package/dist/skills.mjs +1 -0
  151. package/dist/theme.cjs +2 -0
  152. package/dist/theme.cjs.map +1 -0
  153. package/dist/theme.d.cts +95 -0
  154. package/dist/theme.d.cts.map +1 -0
  155. package/dist/theme.d.mts +95 -0
  156. package/dist/theme.d.mts.map +1 -0
  157. package/dist/theme.mjs +2 -0
  158. package/dist/theme.mjs.map +1 -0
  159. package/dist/toolInventory.cjs +2 -0
  160. package/dist/toolInventory.cjs.map +1 -0
  161. package/dist/toolInventory.d.cts +40 -0
  162. package/dist/toolInventory.d.cts.map +1 -0
  163. package/dist/toolInventory.d.mts +40 -0
  164. package/dist/toolInventory.d.mts.map +1 -0
  165. package/dist/toolInventory.mjs +2 -0
  166. package/dist/toolInventory.mjs.map +1 -0
  167. package/dist/uiState.cjs +2 -0
  168. package/dist/uiState.cjs.map +1 -0
  169. package/dist/uiState.d.cts +37 -0
  170. package/dist/uiState.d.cts.map +1 -0
  171. package/dist/uiState.d.mts +37 -0
  172. package/dist/uiState.d.mts.map +1 -0
  173. package/dist/uiState.mjs +2 -0
  174. package/dist/uiState.mjs.map +1 -0
  175. package/package.json +171 -0
  176. package/themes/doom-pi-dark.json +86 -0
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@earendil-works/pi-tui");const t=1e3,n=1e6;function r(e){return e<t?String(e):e<n?`${(e/t).toFixed(+(e<1e4))}k`:`${(e/n).toFixed(1)}M`}function i(t,n){return(0,e.truncateToWidth)(t,Math.max(0,n),``)}function a(t,n){let r=Math.max(0,n),a=i(t,r);return`${a}${` `.repeat(Math.max(0,r-(0,e.visibleWidth)(a)))}`}function o(t,n,r){let a=Math.max(0,r),o=(0,e.visibleWidth)(n);if(!n||o>=a)return i(n||t,a);let s=i(t,Math.max(0,a-o-1));return i(`${s}${` `.repeat(Math.max(1,a-(0,e.visibleWidth)(s)-o))}${n}`,a)}function s(t,n,r=`│`,o=`│`){let s=Math.max(0,n),c=(0,e.visibleWidth)(r)+(0,e.visibleWidth)(o);return s<=c?i(`${r}${o}`,s):`${r}${a(t,s-c)}${o}`}function c(t,n,r=` `){let a=Math.max(0,n);if(a===0)return[];let o=[],s=``;for(let n of t){let t=s?`${s}${r}${n}`:n;if((0,e.visibleWidth)(t)<=a){s=t;continue}s&&o.push(i(s,a)),s=i(n,a)}return s&&o.push(s),o}exports.alignLine=o,exports.fitLine=i,exports.formatTokens=r,exports.frameLine=s,exports.packSegments=c,exports.padLine=a;
2
+ //# sourceMappingURL=rendering.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.cjs","names":["truncateToWidth","visibleWidth"],"sources":["../src/rendering.ts"],"sourcesContent":["import { truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';\n\nconst THOUSAND = 1000;\nconst MILLION = 1_000_000;\n/** Below this many tokens the \"k\" form keeps a decimal, above it rounds. */\nconst K_DECIMAL_LIMIT = 10_000;\n\n/** Compact token count, e.g. `812`, `4.2k`, `186k`, `1.3M`. */\nexport function formatTokens(value: number): string {\n if (value < THOUSAND) return String(value);\n if (value < MILLION) return `${(value / THOUSAND).toFixed(value < K_DECIMAL_LIMIT ? 1 : 0)}k`;\n return `${(value / MILLION).toFixed(1)}M`;\n}\n\nexport function fitLine(text: string, width: number): string {\n return truncateToWidth(text, Math.max(0, width), '');\n}\n\nexport function padLine(text: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const fitted = fitLine(text, safeWidth);\n return `${fitted}${' '.repeat(Math.max(0, safeWidth - visibleWidth(fitted)))}`;\n}\n\nexport function alignLine(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (!right || rightWidth >= safeWidth) return fitLine(right || left, safeWidth);\n\n const maxLeftWidth = Math.max(0, safeWidth - rightWidth - 1);\n const fittedLeft = fitLine(left, maxLeftWidth);\n const gap = ' '.repeat(Math.max(1, safeWidth - visibleWidth(fittedLeft) - rightWidth));\n return fitLine(`${fittedLeft}${gap}${right}`, safeWidth);\n}\n\nexport function frameLine(content: string, width: number, left = '│', right = '│'): string {\n const safeWidth = Math.max(0, width);\n const frameWidth = visibleWidth(left) + visibleWidth(right);\n if (safeWidth <= frameWidth) return fitLine(`${left}${right}`, safeWidth);\n return `${left}${padLine(content, safeWidth - frameWidth)}${right}`;\n}\n\nexport function packSegments(segments: string[], width: number, separator = ' '): string[] {\n const safeWidth = Math.max(0, width);\n if (safeWidth === 0) return [];\n\n const lines: string[] = [];\n let current = '';\n for (const segment of segments) {\n const candidate = current ? `${current}${separator}${segment}` : segment;\n if (visibleWidth(candidate) <= safeWidth) {\n current = candidate;\n continue;\n }\n if (current) lines.push(fitLine(current, safeWidth));\n current = fitLine(segment, safeWidth);\n }\n if (current) lines.push(current);\n return lines;\n}\n"],"mappings":"2GAEA,MAAM,EAAW,IACX,EAAU,IAKhB,SAAgB,EAAa,EAAuB,CAGlD,OAFI,EAAQ,EAAiB,OAAO,CAAK,EACrC,EAAQ,EAAgB,IAAI,EAAQ,EAAA,CAAU,QAAQ,IAAQ,IAAuB,EAAE,GACpF,IAAI,EAAQ,EAAA,CAAS,QAAQ,CAAC,EAAE,EACzC,CAEA,SAAgB,EAAQ,EAAc,EAAuB,CAC3D,OAAA,EAAOA,EAAAA,gBAAAA,CAAgB,EAAM,KAAK,IAAI,EAAG,CAAK,EAAG,EAAE,CACrD,CAEA,SAAgB,EAAQ,EAAc,EAAuB,CAC3D,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EAC7B,EAAS,EAAQ,EAAM,CAAS,EACtC,MAAO,GAAG,IAAS,IAAI,OAAO,KAAK,IAAI,EAAG,GAAA,EAAYC,EAAAA,aAAAA,CAAa,CAAM,CAAC,CAAC,GAC7E,CAEA,SAAgB,EAAU,EAAc,EAAe,EAAuB,CAC5E,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EAC7B,GAAA,EAAaA,EAAAA,aAAAA,CAAa,CAAK,EACrC,GAAI,CAAC,GAAS,GAAc,EAAW,OAAO,EAAQ,GAAS,EAAM,CAAS,EAG9E,IAAM,EAAa,EAAQ,EADN,KAAK,IAAI,EAAG,EAAY,EAAa,CACd,CAAC,EAE7C,OAAO,EAAQ,GAAG,IADN,IAAI,OAAO,KAAK,IAAI,EAAG,GAAA,EAAYA,EAAAA,aAAAA,CAAa,CAAU,EAAI,CAAU,CACnD,IAAI,IAAS,CAAS,CACzD,CAEA,SAAgB,EAAU,EAAiB,EAAe,EAAO,IAAK,EAAQ,IAAa,CACzF,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EAC7B,GAAA,EAAaA,EAAAA,aAAAA,CAAa,CAAI,GAAA,EAAIA,EAAAA,aAAAA,CAAa,CAAK,EAE1D,OADI,GAAa,EAAmB,EAAQ,GAAG,IAAO,IAAS,CAAS,EACjE,GAAG,IAAO,EAAQ,EAAS,EAAY,CAAU,IAAI,GAC9D,CAEA,SAAgB,EAAa,EAAoB,EAAe,EAAY,KAAgB,CAC1F,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EACnC,GAAI,IAAc,EAAG,MAAO,CAAC,EAE7B,IAAM,EAAkB,CAAC,EACrB,EAAU,GACd,IAAK,IAAM,KAAW,EAAU,CAC9B,IAAM,EAAY,EAAU,GAAG,IAAU,IAAY,IAAY,EACjE,IAAA,EAAIA,EAAAA,aAAAA,CAAa,CAAS,GAAK,EAAW,CACxC,EAAU,EACV,QACF,CACI,GAAS,EAAM,KAAK,EAAQ,EAAS,CAAS,CAAC,EACnD,EAAU,EAAQ,EAAS,CAAS,CACtC,CAEA,OADI,GAAS,EAAM,KAAK,CAAO,EACxB,CACT"}
@@ -0,0 +1,11 @@
1
+ //#region src/rendering.d.ts
2
+ /** Compact token count, e.g. `812`, `4.2k`, `186k`, `1.3M`. */
3
+ declare function formatTokens(value: number): string;
4
+ declare function fitLine(text: string, width: number): string;
5
+ declare function padLine(text: string, width: number): string;
6
+ declare function alignLine(left: string, right: string, width: number): string;
7
+ declare function frameLine(content: string, width: number, left?: string, right?: string): string;
8
+ declare function packSegments(segments: string[], width: number, separator?: string): string[];
9
+ //#endregion
10
+ export { alignLine, fitLine, formatTokens, frameLine, packSegments, padLine };
11
+ //# sourceMappingURL=rendering.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.d.cts","names":[],"sources":["../src/rendering.ts"],"mappings":";;iBAQgB,aAAa;iBAMb,QAAQ,cAAc;iBAItB,QAAQ,cAAc;iBAMtB,UAAU,cAAc,eAAe;iBAWvC,UAAU,iBAAiB,eAAe,eAAY;iBAOtD,aAAa,oBAAoB,eAAe"}
@@ -0,0 +1,11 @@
1
+ //#region src/rendering.d.ts
2
+ /** Compact token count, e.g. `812`, `4.2k`, `186k`, `1.3M`. */
3
+ declare function formatTokens(value: number): string;
4
+ declare function fitLine(text: string, width: number): string;
5
+ declare function padLine(text: string, width: number): string;
6
+ declare function alignLine(left: string, right: string, width: number): string;
7
+ declare function frameLine(content: string, width: number, left?: string, right?: string): string;
8
+ declare function packSegments(segments: string[], width: number, separator?: string): string[];
9
+ //#endregion
10
+ export { alignLine, fitLine, formatTokens, frameLine, packSegments, padLine };
11
+ //# sourceMappingURL=rendering.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.d.mts","names":[],"sources":["../src/rendering.ts"],"mappings":";;iBAQgB,aAAa;iBAMb,QAAQ,cAAc;iBAItB,QAAQ,cAAc;iBAMtB,UAAU,cAAc,eAAe;iBAWvC,UAAU,iBAAiB,eAAe,eAAY;iBAOtD,aAAa,oBAAoB,eAAe"}
@@ -0,0 +1,2 @@
1
+ import{truncateToWidth as e,visibleWidth as t}from"@earendil-works/pi-tui";const n=1e3,r=1e6;function i(e){return e<n?String(e):e<r?`${(e/n).toFixed(+(e<1e4))}k`:`${(e/r).toFixed(1)}M`}function a(t,n){return e(t,Math.max(0,n),``)}function o(e,n){let r=Math.max(0,n),i=a(e,r);return`${i}${` `.repeat(Math.max(0,r-t(i)))}`}function s(e,n,r){let i=Math.max(0,r),o=t(n);if(!n||o>=i)return a(n||e,i);let s=a(e,Math.max(0,i-o-1));return a(`${s}${` `.repeat(Math.max(1,i-t(s)-o))}${n}`,i)}function c(e,n,r=`│`,i=`│`){let s=Math.max(0,n),c=t(r)+t(i);return s<=c?a(`${r}${i}`,s):`${r}${o(e,s-c)}${i}`}function l(e,n,r=` `){let i=Math.max(0,n);if(i===0)return[];let o=[],s=``;for(let n of e){let e=s?`${s}${r}${n}`:n;if(t(e)<=i){s=e;continue}s&&o.push(a(s,i)),s=a(n,i)}return s&&o.push(s),o}export{s as alignLine,a as fitLine,i as formatTokens,c as frameLine,l as packSegments,o as padLine};
2
+ //# sourceMappingURL=rendering.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rendering.mjs","names":[],"sources":["../src/rendering.ts"],"sourcesContent":["import { truncateToWidth, visibleWidth } from '@earendil-works/pi-tui';\n\nconst THOUSAND = 1000;\nconst MILLION = 1_000_000;\n/** Below this many tokens the \"k\" form keeps a decimal, above it rounds. */\nconst K_DECIMAL_LIMIT = 10_000;\n\n/** Compact token count, e.g. `812`, `4.2k`, `186k`, `1.3M`. */\nexport function formatTokens(value: number): string {\n if (value < THOUSAND) return String(value);\n if (value < MILLION) return `${(value / THOUSAND).toFixed(value < K_DECIMAL_LIMIT ? 1 : 0)}k`;\n return `${(value / MILLION).toFixed(1)}M`;\n}\n\nexport function fitLine(text: string, width: number): string {\n return truncateToWidth(text, Math.max(0, width), '');\n}\n\nexport function padLine(text: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const fitted = fitLine(text, safeWidth);\n return `${fitted}${' '.repeat(Math.max(0, safeWidth - visibleWidth(fitted)))}`;\n}\n\nexport function alignLine(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (!right || rightWidth >= safeWidth) return fitLine(right || left, safeWidth);\n\n const maxLeftWidth = Math.max(0, safeWidth - rightWidth - 1);\n const fittedLeft = fitLine(left, maxLeftWidth);\n const gap = ' '.repeat(Math.max(1, safeWidth - visibleWidth(fittedLeft) - rightWidth));\n return fitLine(`${fittedLeft}${gap}${right}`, safeWidth);\n}\n\nexport function frameLine(content: string, width: number, left = '│', right = '│'): string {\n const safeWidth = Math.max(0, width);\n const frameWidth = visibleWidth(left) + visibleWidth(right);\n if (safeWidth <= frameWidth) return fitLine(`${left}${right}`, safeWidth);\n return `${left}${padLine(content, safeWidth - frameWidth)}${right}`;\n}\n\nexport function packSegments(segments: string[], width: number, separator = ' '): string[] {\n const safeWidth = Math.max(0, width);\n if (safeWidth === 0) return [];\n\n const lines: string[] = [];\n let current = '';\n for (const segment of segments) {\n const candidate = current ? `${current}${separator}${segment}` : segment;\n if (visibleWidth(candidate) <= safeWidth) {\n current = candidate;\n continue;\n }\n if (current) lines.push(fitLine(current, safeWidth));\n current = fitLine(segment, safeWidth);\n }\n if (current) lines.push(current);\n return lines;\n}\n"],"mappings":"2EAEA,MAAM,EAAW,IACX,EAAU,IAKhB,SAAgB,EAAa,EAAuB,CAGlD,OAFI,EAAQ,EAAiB,OAAO,CAAK,EACrC,EAAQ,EAAgB,IAAI,EAAQ,EAAA,CAAU,QAAQ,IAAQ,IAAuB,EAAE,GACpF,IAAI,EAAQ,EAAA,CAAS,QAAQ,CAAC,EAAE,EACzC,CAEA,SAAgB,EAAQ,EAAc,EAAuB,CAC3D,OAAO,EAAgB,EAAM,KAAK,IAAI,EAAG,CAAK,EAAG,EAAE,CACrD,CAEA,SAAgB,EAAQ,EAAc,EAAuB,CAC3D,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EAC7B,EAAS,EAAQ,EAAM,CAAS,EACtC,MAAO,GAAG,IAAS,IAAI,OAAO,KAAK,IAAI,EAAG,EAAY,EAAa,CAAM,CAAC,CAAC,GAC7E,CAEA,SAAgB,EAAU,EAAc,EAAe,EAAuB,CAC5E,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EAC7B,EAAa,EAAa,CAAK,EACrC,GAAI,CAAC,GAAS,GAAc,EAAW,OAAO,EAAQ,GAAS,EAAM,CAAS,EAG9E,IAAM,EAAa,EAAQ,EADN,KAAK,IAAI,EAAG,EAAY,EAAa,CACd,CAAC,EAE7C,OAAO,EAAQ,GAAG,IADN,IAAI,OAAO,KAAK,IAAI,EAAG,EAAY,EAAa,CAAU,EAAI,CAAU,CACnD,IAAI,IAAS,CAAS,CACzD,CAEA,SAAgB,EAAU,EAAiB,EAAe,EAAO,IAAK,EAAQ,IAAa,CACzF,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EAC7B,EAAa,EAAa,CAAI,EAAI,EAAa,CAAK,EAE1D,OADI,GAAa,EAAmB,EAAQ,GAAG,IAAO,IAAS,CAAS,EACjE,GAAG,IAAO,EAAQ,EAAS,EAAY,CAAU,IAAI,GAC9D,CAEA,SAAgB,EAAa,EAAoB,EAAe,EAAY,KAAgB,CAC1F,IAAM,EAAY,KAAK,IAAI,EAAG,CAAK,EACnC,GAAI,IAAc,EAAG,MAAO,CAAC,EAE7B,IAAM,EAAkB,CAAC,EACrB,EAAU,GACd,IAAK,IAAM,KAAW,EAAU,CAC9B,IAAM,EAAY,EAAU,GAAG,IAAU,IAAY,IAAY,EACjE,GAAI,EAAa,CAAS,GAAK,EAAW,CACxC,EAAU,EACV,QACF,CACI,GAAS,EAAM,KAAK,EAAQ,EAAS,CAAS,CAAC,EACnD,EAAU,EAAQ,EAAS,CAAS,CACtC,CAEA,OADI,GAAS,EAAM,KAAK,CAAO,EACxB,CACT"}
@@ -0,0 +1 @@
1
+ var e=require("@agimon-ai/doompi-extension-contracts/skills");Object.keys(e).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:function(){return e[t]}})});
@@ -0,0 +1 @@
1
+ export * from "@agimon-ai/doompi-extension-contracts/skills";
@@ -0,0 +1 @@
1
+ export * from "@agimon-ai/doompi-extension-contracts/skills";
@@ -0,0 +1 @@
1
+ export*from"@agimon-ai/doompi-extension-contracts/skills";export{};
package/dist/theme.cjs ADDED
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_virtual/_rolldown/runtime.cjs");let t=require("node:path");t=e.__toESM(t,1);let n=require("node:fs");n=e.__toESM(n,1);const r=`doom-pi-dark`,i=[`accent`,`mdCode`,`toolDiffAdded`,`warning`,`mdHeading`,`syntaxNumber`];function a(e){let t=2166136261;for(let n of e)t^=n.charCodeAt(0),t=Math.imul(t,16777619);return i[(t>>>0)%i.length]}const o={$schema:`https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json`,name:r,vars:{bg:`#191919`,bgAlt:`#121212`,bgActive:`#252526`,bgHover:`#3d3d3d`,fg:`#d4d4d4`,fgAlt:`#aeafad`,grey:`#4b474c`,greyAlt:`#515151`,blue:`#8cdaff`,darkBlue:`#6699cc`,cyan:`#85ddff`,green:`#468800`,lightGreen:`#b5cea8`,teal:`#35cdaf`,orange:`#fc9354`,red:`#ff5e5e`,violet:`#bb80b3`,magenta:`#c586c0`,yellow:`#e9fdac`,lightYellow:`#fbe3bf`,comment:`#6d6d6d`},colors:{accent:`blue`,border:`greyAlt`,borderAccent:`blue`,borderMuted:`grey`,success:`green`,error:`red`,warning:`yellow`,muted:`fgAlt`,dim:`comment`,text:`fg`,thinkingText:`fgAlt`,selectedBg:`bgHover`,userMessageBg:`bgActive`,userMessageText:`fg`,customMessageBg:`#2a1b2f`,customMessageText:`fg`,customMessageLabel:`violet`,toolPendingBg:`bgAlt`,toolSuccessBg:`#1e2a16`,toolErrorBg:`#331d1d`,toolTitle:`blue`,toolOutput:`fg`,mdHeading:`magenta`,mdLink:`blue`,mdLinkUrl:`comment`,mdCode:`cyan`,mdCodeBlock:`lightYellow`,mdCodeBlockBorder:`greyAlt`,mdQuote:`fgAlt`,mdQuoteBorder:`greyAlt`,mdHr:`greyAlt`,mdListBullet:`blue`,toolDiffAdded:`lightGreen`,toolDiffRemoved:`red`,toolDiffContext:`fgAlt`,syntaxComment:`comment`,syntaxKeyword:`red`,syntaxFunction:`blue`,syntaxVariable:`yellow`,syntaxString:`lightYellow`,syntaxNumber:`orange`,syntaxType:`yellow`,syntaxOperator:`red`,syntaxPunctuation:`fgAlt`,thinkingOff:`grey`,thinkingMinimal:`fgAlt`,thinkingLow:`darkBlue`,thinkingMedium:`blue`,thinkingHigh:`teal`,thinkingXhigh:`magenta`,thinkingMax:`red`,bashMode:`lightGreen`},export:{pageBg:`bg`,cardBg:`bgAlt`,infoBg:`#26261c`}};async function s(e){let i=t.default.join(e,`${r}.json`);return await n.default.promises.writeFile(i,`${JSON.stringify(o,null,2)}\n`,{mode:384}),i}exports.DEFAULT_THEME=o,exports.DEFAULT_THEME_NAME=r,exports.agentIdentityColor=a,exports.writeDefaultTheme=s;
2
+ //# sourceMappingURL=theme.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.cjs","names":["path","fs"],"sources":["../src/theme.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport type { FooterTextColor } from '@agimon-ai/doompi-extension-contracts/footer';\nimport type { ThemeColor } from '@earendil-works/pi-coding-agent';\n\nexport const DEFAULT_THEME_NAME = 'doom-pi-dark';\n\nconst AGENT_IDENTITY_COLORS = [\n 'accent',\n 'mdCode',\n 'toolDiffAdded',\n 'warning',\n 'mdHeading',\n 'syntaxNumber',\n] as const satisfies readonly (FooterTextColor & ThemeColor)[];\n\n/** Stable semantic color shared by every UI surface that identifies an agent. */\nexport function agentIdentityColor(agentName: string): FooterTextColor {\n let hash = 2_166_136_261;\n for (const character of agentName) {\n hash ^= character.charCodeAt(0);\n hash = Math.imul(hash, 16_777_619);\n }\n return AGENT_IDENTITY_COLORS[(hash >>> 0) % AGENT_IDENTITY_COLORS.length]!;\n}\n\nexport const DEFAULT_THEME = {\n $schema:\n 'https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json',\n name: DEFAULT_THEME_NAME,\n // Palette ported from doom-emacs' doom-1337 theme, itself a port of VSCode's\n // 1337 theme. Variable names follow this file's own scheme rather than the\n // upstream base0..base8 ladder; the upstream name is noted where it differs.\n vars: {\n bg: '#191919',\n bgAlt: '#121212', // base2\n bgActive: '#252526', // bg-alt upstream, the current-selection background\n bgHover: '#3d3d3d', // base3\n fg: '#d4d4d4',\n fgAlt: '#aeafad',\n grey: '#4b474c', // base4, one step above bgHover so muted borders stay visible\n greyAlt: '#515151', // base5, upstream `selection`\n blue: '#8cdaff',\n darkBlue: '#6699cc', // upstream `builtin` and `methods`\n cyan: '#85ddff',\n green: '#468800',\n lightGreen: '#b5cea8',\n teal: '#35cdaf',\n orange: '#fc9354',\n red: '#ff5e5e',\n violet: '#bb80b3',\n magenta: '#c586c0',\n yellow: '#e9fdac',\n lightYellow: '#fbe3bf', // upstream `strings`\n comment: '#6d6d6d', // base6\n },\n colors: {\n accent: 'blue',\n border: 'greyAlt',\n borderAccent: 'blue',\n borderMuted: 'grey',\n success: 'green',\n error: 'red',\n warning: 'yellow',\n muted: 'fgAlt',\n dim: 'comment',\n text: 'fg',\n thinkingText: 'fgAlt',\n\n selectedBg: 'bgHover',\n userMessageBg: 'bgActive',\n userMessageText: 'fg',\n customMessageBg: '#2a1b2f', // tinted toward upstream dark-violet #68217a\n customMessageText: 'fg',\n customMessageLabel: 'violet',\n toolPendingBg: 'bgAlt',\n toolSuccessBg: '#1e2a16',\n toolErrorBg: '#331d1d',\n toolTitle: 'blue',\n toolOutput: 'fg',\n\n mdHeading: 'magenta',\n mdLink: 'blue',\n mdLinkUrl: 'comment',\n mdCode: 'cyan',\n mdCodeBlock: 'lightYellow',\n mdCodeBlockBorder: 'greyAlt',\n mdQuote: 'fgAlt',\n mdQuoteBorder: 'greyAlt',\n mdHr: 'greyAlt',\n mdListBullet: 'blue',\n\n // Upstream vc-added is the dark `green`, which is too dim to read as diff\n // body text, so added lines use the palette's light-green instead.\n toolDiffAdded: 'lightGreen',\n toolDiffRemoved: 'red',\n toolDiffContext: 'fgAlt',\n\n // Straight from doom-1337's face categories.\n syntaxComment: 'comment',\n syntaxKeyword: 'red',\n syntaxFunction: 'blue',\n syntaxVariable: 'yellow',\n syntaxString: 'lightYellow',\n syntaxNumber: 'orange',\n syntaxType: 'yellow',\n syntaxOperator: 'red',\n syntaxPunctuation: 'fgAlt',\n\n // A rising ramp. Upstream's blue and cyan are nearly the same hue, so the\n // low end starts at dark-blue to keep the steps distinguishable.\n thinkingOff: 'grey',\n thinkingMinimal: 'fgAlt',\n thinkingLow: 'darkBlue',\n thinkingMedium: 'blue',\n thinkingHigh: 'teal',\n thinkingXhigh: 'magenta',\n thinkingMax: 'red',\n\n // Upstream `green` is reserved for success; the prompt indicator needs to\n // stay legible against the near-black background.\n bashMode: 'lightGreen',\n },\n export: {\n pageBg: 'bg',\n cardBg: 'bgAlt',\n infoBg: '#26261c',\n },\n} as const;\n\nexport async function writeDefaultTheme(temporaryDirectory: string): Promise<string> {\n const themePath = path.join(temporaryDirectory, `${DEFAULT_THEME_NAME}.json`);\n await fs.promises.writeFile(themePath, `${JSON.stringify(DEFAULT_THEME, null, 2)}\\n`, { mode: 0o600 });\n return themePath;\n}\n"],"mappings":"6MAKA,MAAa,EAAqB,eAE5B,EAAwB,CAC5B,SACA,SACA,gBACA,UACA,YACA,cACF,EAGA,SAAgB,EAAmB,EAAoC,CACrE,IAAI,EAAO,WACX,IAAK,IAAM,KAAa,EACtB,GAAQ,EAAU,WAAW,CAAC,EAC9B,EAAO,KAAK,KAAK,EAAM,QAAU,EAEnC,OAAO,GAAuB,IAAS,GAAK,EAAsB,OACpE,CAEA,MAAa,EAAgB,CAC3B,QACE,+HACF,KAAM,EAIN,KAAM,CACJ,GAAI,UACJ,MAAO,UACP,SAAU,UACV,QAAS,UACT,GAAI,UACJ,MAAO,UACP,KAAM,UACN,QAAS,UACT,KAAM,UACN,SAAU,UACV,KAAM,UACN,MAAO,UACP,WAAY,UACZ,KAAM,UACN,OAAQ,UACR,IAAK,UACL,OAAQ,UACR,QAAS,UACT,OAAQ,UACR,YAAa,UACb,QAAS,SACX,EACA,OAAQ,CACN,OAAQ,OACR,OAAQ,UACR,aAAc,OACd,YAAa,OACb,QAAS,QACT,MAAO,MACP,QAAS,SACT,MAAO,QACP,IAAK,UACL,KAAM,KACN,aAAc,QAEd,WAAY,UACZ,cAAe,WACf,gBAAiB,KACjB,gBAAiB,UACjB,kBAAmB,KACnB,mBAAoB,SACpB,cAAe,QACf,cAAe,UACf,YAAa,UACb,UAAW,OACX,WAAY,KAEZ,UAAW,UACX,OAAQ,OACR,UAAW,UACX,OAAQ,OACR,YAAa,cACb,kBAAmB,UACnB,QAAS,QACT,cAAe,UACf,KAAM,UACN,aAAc,OAId,cAAe,aACf,gBAAiB,MACjB,gBAAiB,QAGjB,cAAe,UACf,cAAe,MACf,eAAgB,OAChB,eAAgB,SAChB,aAAc,cACd,aAAc,SACd,WAAY,SACZ,eAAgB,MAChB,kBAAmB,QAInB,YAAa,OACb,gBAAiB,QACjB,YAAa,WACb,eAAgB,OAChB,aAAc,OACd,cAAe,UACf,YAAa,MAIb,SAAU,YACZ,EACA,OAAQ,CACN,OAAQ,KACR,OAAQ,QACR,OAAQ,SACV,CACF,EAEA,eAAsB,EAAkB,EAA6C,CACnF,IAAM,EAAYA,EAAAA,QAAK,KAAK,EAAoB,GAAG,EAAmB,MAAM,EAE5E,OADA,MAAMC,EAAAA,QAAG,SAAS,UAAU,EAAW,GAAG,KAAK,UAAU,EAAe,KAAM,CAAC,EAAE,IAAK,CAAE,KAAM,GAAM,CAAC,EAC9F,CACT"}
@@ -0,0 +1,95 @@
1
+ import { FooterTextColor } from "@agimon-ai/doompi-extension-contracts/footer";
2
+ //#region src/theme.d.ts
3
+ declare const DEFAULT_THEME_NAME = "doom-pi-dark";
4
+ /** Stable semantic color shared by every UI surface that identifies an agent. */
5
+ declare function agentIdentityColor(agentName: string): FooterTextColor;
6
+ declare const DEFAULT_THEME: {
7
+ readonly $schema: "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json";
8
+ readonly name: "doom-pi-dark";
9
+ readonly vars: {
10
+ readonly bg: "#191919";
11
+ readonly bgAlt: "#121212";
12
+ readonly bgActive: "#252526";
13
+ readonly bgHover: "#3d3d3d";
14
+ readonly fg: "#d4d4d4";
15
+ readonly fgAlt: "#aeafad";
16
+ readonly grey: "#4b474c";
17
+ readonly greyAlt: "#515151";
18
+ readonly blue: "#8cdaff";
19
+ readonly darkBlue: "#6699cc";
20
+ readonly cyan: "#85ddff";
21
+ readonly green: "#468800";
22
+ readonly lightGreen: "#b5cea8";
23
+ readonly teal: "#35cdaf";
24
+ readonly orange: "#fc9354";
25
+ readonly red: "#ff5e5e";
26
+ readonly violet: "#bb80b3";
27
+ readonly magenta: "#c586c0";
28
+ readonly yellow: "#e9fdac";
29
+ readonly lightYellow: "#fbe3bf";
30
+ readonly comment: "#6d6d6d";
31
+ };
32
+ readonly colors: {
33
+ readonly accent: "blue";
34
+ readonly border: "greyAlt";
35
+ readonly borderAccent: "blue";
36
+ readonly borderMuted: "grey";
37
+ readonly success: "green";
38
+ readonly error: "red";
39
+ readonly warning: "yellow";
40
+ readonly muted: "fgAlt";
41
+ readonly dim: "comment";
42
+ readonly text: "fg";
43
+ readonly thinkingText: "fgAlt";
44
+ readonly selectedBg: "bgHover";
45
+ readonly userMessageBg: "bgActive";
46
+ readonly userMessageText: "fg";
47
+ readonly customMessageBg: "#2a1b2f";
48
+ readonly customMessageText: "fg";
49
+ readonly customMessageLabel: "violet";
50
+ readonly toolPendingBg: "bgAlt";
51
+ readonly toolSuccessBg: "#1e2a16";
52
+ readonly toolErrorBg: "#331d1d";
53
+ readonly toolTitle: "blue";
54
+ readonly toolOutput: "fg";
55
+ readonly mdHeading: "magenta";
56
+ readonly mdLink: "blue";
57
+ readonly mdLinkUrl: "comment";
58
+ readonly mdCode: "cyan";
59
+ readonly mdCodeBlock: "lightYellow";
60
+ readonly mdCodeBlockBorder: "greyAlt";
61
+ readonly mdQuote: "fgAlt";
62
+ readonly mdQuoteBorder: "greyAlt";
63
+ readonly mdHr: "greyAlt";
64
+ readonly mdListBullet: "blue";
65
+ readonly toolDiffAdded: "lightGreen";
66
+ readonly toolDiffRemoved: "red";
67
+ readonly toolDiffContext: "fgAlt";
68
+ readonly syntaxComment: "comment";
69
+ readonly syntaxKeyword: "red";
70
+ readonly syntaxFunction: "blue";
71
+ readonly syntaxVariable: "yellow";
72
+ readonly syntaxString: "lightYellow";
73
+ readonly syntaxNumber: "orange";
74
+ readonly syntaxType: "yellow";
75
+ readonly syntaxOperator: "red";
76
+ readonly syntaxPunctuation: "fgAlt";
77
+ readonly thinkingOff: "grey";
78
+ readonly thinkingMinimal: "fgAlt";
79
+ readonly thinkingLow: "darkBlue";
80
+ readonly thinkingMedium: "blue";
81
+ readonly thinkingHigh: "teal";
82
+ readonly thinkingXhigh: "magenta";
83
+ readonly thinkingMax: "red";
84
+ readonly bashMode: "lightGreen";
85
+ };
86
+ readonly export: {
87
+ readonly pageBg: "bg";
88
+ readonly cardBg: "bgAlt";
89
+ readonly infoBg: "#26261c";
90
+ };
91
+ };
92
+ declare function writeDefaultTheme(temporaryDirectory: string): Promise<string>;
93
+ //#endregion
94
+ export { DEFAULT_THEME, DEFAULT_THEME_NAME, agentIdentityColor, writeDefaultTheme };
95
+ //# sourceMappingURL=theme.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.cts","names":[],"sources":["../src/theme.ts"],"mappings":";;cAKa;;iBAYG,mBAAmB,oBAAoB;cAS1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwGS,kBAAkB,6BAA6B"}
@@ -0,0 +1,95 @@
1
+ import { FooterTextColor } from "@agimon-ai/doompi-extension-contracts/footer";
2
+ //#region src/theme.d.ts
3
+ declare const DEFAULT_THEME_NAME = "doom-pi-dark";
4
+ /** Stable semantic color shared by every UI surface that identifies an agent. */
5
+ declare function agentIdentityColor(agentName: string): FooterTextColor;
6
+ declare const DEFAULT_THEME: {
7
+ readonly $schema: "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json";
8
+ readonly name: "doom-pi-dark";
9
+ readonly vars: {
10
+ readonly bg: "#191919";
11
+ readonly bgAlt: "#121212";
12
+ readonly bgActive: "#252526";
13
+ readonly bgHover: "#3d3d3d";
14
+ readonly fg: "#d4d4d4";
15
+ readonly fgAlt: "#aeafad";
16
+ readonly grey: "#4b474c";
17
+ readonly greyAlt: "#515151";
18
+ readonly blue: "#8cdaff";
19
+ readonly darkBlue: "#6699cc";
20
+ readonly cyan: "#85ddff";
21
+ readonly green: "#468800";
22
+ readonly lightGreen: "#b5cea8";
23
+ readonly teal: "#35cdaf";
24
+ readonly orange: "#fc9354";
25
+ readonly red: "#ff5e5e";
26
+ readonly violet: "#bb80b3";
27
+ readonly magenta: "#c586c0";
28
+ readonly yellow: "#e9fdac";
29
+ readonly lightYellow: "#fbe3bf";
30
+ readonly comment: "#6d6d6d";
31
+ };
32
+ readonly colors: {
33
+ readonly accent: "blue";
34
+ readonly border: "greyAlt";
35
+ readonly borderAccent: "blue";
36
+ readonly borderMuted: "grey";
37
+ readonly success: "green";
38
+ readonly error: "red";
39
+ readonly warning: "yellow";
40
+ readonly muted: "fgAlt";
41
+ readonly dim: "comment";
42
+ readonly text: "fg";
43
+ readonly thinkingText: "fgAlt";
44
+ readonly selectedBg: "bgHover";
45
+ readonly userMessageBg: "bgActive";
46
+ readonly userMessageText: "fg";
47
+ readonly customMessageBg: "#2a1b2f";
48
+ readonly customMessageText: "fg";
49
+ readonly customMessageLabel: "violet";
50
+ readonly toolPendingBg: "bgAlt";
51
+ readonly toolSuccessBg: "#1e2a16";
52
+ readonly toolErrorBg: "#331d1d";
53
+ readonly toolTitle: "blue";
54
+ readonly toolOutput: "fg";
55
+ readonly mdHeading: "magenta";
56
+ readonly mdLink: "blue";
57
+ readonly mdLinkUrl: "comment";
58
+ readonly mdCode: "cyan";
59
+ readonly mdCodeBlock: "lightYellow";
60
+ readonly mdCodeBlockBorder: "greyAlt";
61
+ readonly mdQuote: "fgAlt";
62
+ readonly mdQuoteBorder: "greyAlt";
63
+ readonly mdHr: "greyAlt";
64
+ readonly mdListBullet: "blue";
65
+ readonly toolDiffAdded: "lightGreen";
66
+ readonly toolDiffRemoved: "red";
67
+ readonly toolDiffContext: "fgAlt";
68
+ readonly syntaxComment: "comment";
69
+ readonly syntaxKeyword: "red";
70
+ readonly syntaxFunction: "blue";
71
+ readonly syntaxVariable: "yellow";
72
+ readonly syntaxString: "lightYellow";
73
+ readonly syntaxNumber: "orange";
74
+ readonly syntaxType: "yellow";
75
+ readonly syntaxOperator: "red";
76
+ readonly syntaxPunctuation: "fgAlt";
77
+ readonly thinkingOff: "grey";
78
+ readonly thinkingMinimal: "fgAlt";
79
+ readonly thinkingLow: "darkBlue";
80
+ readonly thinkingMedium: "blue";
81
+ readonly thinkingHigh: "teal";
82
+ readonly thinkingXhigh: "magenta";
83
+ readonly thinkingMax: "red";
84
+ readonly bashMode: "lightGreen";
85
+ };
86
+ readonly export: {
87
+ readonly pageBg: "bg";
88
+ readonly cardBg: "bgAlt";
89
+ readonly infoBg: "#26261c";
90
+ };
91
+ };
92
+ declare function writeDefaultTheme(temporaryDirectory: string): Promise<string>;
93
+ //#endregion
94
+ export { DEFAULT_THEME, DEFAULT_THEME_NAME, agentIdentityColor, writeDefaultTheme };
95
+ //# sourceMappingURL=theme.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.d.mts","names":[],"sources":["../src/theme.ts"],"mappings":";;cAKa;;iBAYG,mBAAmB,oBAAoB;cAS1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwGS,kBAAkB,6BAA6B"}
package/dist/theme.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import e from"node:path";import t from"node:fs";const n=`doom-pi-dark`,r=[`accent`,`mdCode`,`toolDiffAdded`,`warning`,`mdHeading`,`syntaxNumber`];function i(e){let t=2166136261;for(let n of e)t^=n.charCodeAt(0),t=Math.imul(t,16777619);return r[(t>>>0)%r.length]}const a={$schema:`https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json`,name:n,vars:{bg:`#191919`,bgAlt:`#121212`,bgActive:`#252526`,bgHover:`#3d3d3d`,fg:`#d4d4d4`,fgAlt:`#aeafad`,grey:`#4b474c`,greyAlt:`#515151`,blue:`#8cdaff`,darkBlue:`#6699cc`,cyan:`#85ddff`,green:`#468800`,lightGreen:`#b5cea8`,teal:`#35cdaf`,orange:`#fc9354`,red:`#ff5e5e`,violet:`#bb80b3`,magenta:`#c586c0`,yellow:`#e9fdac`,lightYellow:`#fbe3bf`,comment:`#6d6d6d`},colors:{accent:`blue`,border:`greyAlt`,borderAccent:`blue`,borderMuted:`grey`,success:`green`,error:`red`,warning:`yellow`,muted:`fgAlt`,dim:`comment`,text:`fg`,thinkingText:`fgAlt`,selectedBg:`bgHover`,userMessageBg:`bgActive`,userMessageText:`fg`,customMessageBg:`#2a1b2f`,customMessageText:`fg`,customMessageLabel:`violet`,toolPendingBg:`bgAlt`,toolSuccessBg:`#1e2a16`,toolErrorBg:`#331d1d`,toolTitle:`blue`,toolOutput:`fg`,mdHeading:`magenta`,mdLink:`blue`,mdLinkUrl:`comment`,mdCode:`cyan`,mdCodeBlock:`lightYellow`,mdCodeBlockBorder:`greyAlt`,mdQuote:`fgAlt`,mdQuoteBorder:`greyAlt`,mdHr:`greyAlt`,mdListBullet:`blue`,toolDiffAdded:`lightGreen`,toolDiffRemoved:`red`,toolDiffContext:`fgAlt`,syntaxComment:`comment`,syntaxKeyword:`red`,syntaxFunction:`blue`,syntaxVariable:`yellow`,syntaxString:`lightYellow`,syntaxNumber:`orange`,syntaxType:`yellow`,syntaxOperator:`red`,syntaxPunctuation:`fgAlt`,thinkingOff:`grey`,thinkingMinimal:`fgAlt`,thinkingLow:`darkBlue`,thinkingMedium:`blue`,thinkingHigh:`teal`,thinkingXhigh:`magenta`,thinkingMax:`red`,bashMode:`lightGreen`},export:{pageBg:`bg`,cardBg:`bgAlt`,infoBg:`#26261c`}};async function o(r){let i=e.join(r,`${n}.json`);return await t.promises.writeFile(i,`${JSON.stringify(a,null,2)}\n`,{mode:384}),i}export{a as DEFAULT_THEME,n as DEFAULT_THEME_NAME,i as agentIdentityColor,o as writeDefaultTheme};
2
+ //# sourceMappingURL=theme.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.mjs","names":[],"sources":["../src/theme.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport type { FooterTextColor } from '@agimon-ai/doompi-extension-contracts/footer';\nimport type { ThemeColor } from '@earendil-works/pi-coding-agent';\n\nexport const DEFAULT_THEME_NAME = 'doom-pi-dark';\n\nconst AGENT_IDENTITY_COLORS = [\n 'accent',\n 'mdCode',\n 'toolDiffAdded',\n 'warning',\n 'mdHeading',\n 'syntaxNumber',\n] as const satisfies readonly (FooterTextColor & ThemeColor)[];\n\n/** Stable semantic color shared by every UI surface that identifies an agent. */\nexport function agentIdentityColor(agentName: string): FooterTextColor {\n let hash = 2_166_136_261;\n for (const character of agentName) {\n hash ^= character.charCodeAt(0);\n hash = Math.imul(hash, 16_777_619);\n }\n return AGENT_IDENTITY_COLORS[(hash >>> 0) % AGENT_IDENTITY_COLORS.length]!;\n}\n\nexport const DEFAULT_THEME = {\n $schema:\n 'https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json',\n name: DEFAULT_THEME_NAME,\n // Palette ported from doom-emacs' doom-1337 theme, itself a port of VSCode's\n // 1337 theme. Variable names follow this file's own scheme rather than the\n // upstream base0..base8 ladder; the upstream name is noted where it differs.\n vars: {\n bg: '#191919',\n bgAlt: '#121212', // base2\n bgActive: '#252526', // bg-alt upstream, the current-selection background\n bgHover: '#3d3d3d', // base3\n fg: '#d4d4d4',\n fgAlt: '#aeafad',\n grey: '#4b474c', // base4, one step above bgHover so muted borders stay visible\n greyAlt: '#515151', // base5, upstream `selection`\n blue: '#8cdaff',\n darkBlue: '#6699cc', // upstream `builtin` and `methods`\n cyan: '#85ddff',\n green: '#468800',\n lightGreen: '#b5cea8',\n teal: '#35cdaf',\n orange: '#fc9354',\n red: '#ff5e5e',\n violet: '#bb80b3',\n magenta: '#c586c0',\n yellow: '#e9fdac',\n lightYellow: '#fbe3bf', // upstream `strings`\n comment: '#6d6d6d', // base6\n },\n colors: {\n accent: 'blue',\n border: 'greyAlt',\n borderAccent: 'blue',\n borderMuted: 'grey',\n success: 'green',\n error: 'red',\n warning: 'yellow',\n muted: 'fgAlt',\n dim: 'comment',\n text: 'fg',\n thinkingText: 'fgAlt',\n\n selectedBg: 'bgHover',\n userMessageBg: 'bgActive',\n userMessageText: 'fg',\n customMessageBg: '#2a1b2f', // tinted toward upstream dark-violet #68217a\n customMessageText: 'fg',\n customMessageLabel: 'violet',\n toolPendingBg: 'bgAlt',\n toolSuccessBg: '#1e2a16',\n toolErrorBg: '#331d1d',\n toolTitle: 'blue',\n toolOutput: 'fg',\n\n mdHeading: 'magenta',\n mdLink: 'blue',\n mdLinkUrl: 'comment',\n mdCode: 'cyan',\n mdCodeBlock: 'lightYellow',\n mdCodeBlockBorder: 'greyAlt',\n mdQuote: 'fgAlt',\n mdQuoteBorder: 'greyAlt',\n mdHr: 'greyAlt',\n mdListBullet: 'blue',\n\n // Upstream vc-added is the dark `green`, which is too dim to read as diff\n // body text, so added lines use the palette's light-green instead.\n toolDiffAdded: 'lightGreen',\n toolDiffRemoved: 'red',\n toolDiffContext: 'fgAlt',\n\n // Straight from doom-1337's face categories.\n syntaxComment: 'comment',\n syntaxKeyword: 'red',\n syntaxFunction: 'blue',\n syntaxVariable: 'yellow',\n syntaxString: 'lightYellow',\n syntaxNumber: 'orange',\n syntaxType: 'yellow',\n syntaxOperator: 'red',\n syntaxPunctuation: 'fgAlt',\n\n // A rising ramp. Upstream's blue and cyan are nearly the same hue, so the\n // low end starts at dark-blue to keep the steps distinguishable.\n thinkingOff: 'grey',\n thinkingMinimal: 'fgAlt',\n thinkingLow: 'darkBlue',\n thinkingMedium: 'blue',\n thinkingHigh: 'teal',\n thinkingXhigh: 'magenta',\n thinkingMax: 'red',\n\n // Upstream `green` is reserved for success; the prompt indicator needs to\n // stay legible against the near-black background.\n bashMode: 'lightGreen',\n },\n export: {\n pageBg: 'bg',\n cardBg: 'bgAlt',\n infoBg: '#26261c',\n },\n} as const;\n\nexport async function writeDefaultTheme(temporaryDirectory: string): Promise<string> {\n const themePath = path.join(temporaryDirectory, `${DEFAULT_THEME_NAME}.json`);\n await fs.promises.writeFile(themePath, `${JSON.stringify(DEFAULT_THEME, null, 2)}\\n`, { mode: 0o600 });\n return themePath;\n}\n"],"mappings":"gDAKA,MAAa,EAAqB,eAE5B,EAAwB,CAC5B,SACA,SACA,gBACA,UACA,YACA,cACF,EAGA,SAAgB,EAAmB,EAAoC,CACrE,IAAI,EAAO,WACX,IAAK,IAAM,KAAa,EACtB,GAAQ,EAAU,WAAW,CAAC,EAC9B,EAAO,KAAK,KAAK,EAAM,QAAU,EAEnC,OAAO,GAAuB,IAAS,GAAK,EAAsB,OACpE,CAEA,MAAa,EAAgB,CAC3B,QACE,+HACF,KAAM,EAIN,KAAM,CACJ,GAAI,UACJ,MAAO,UACP,SAAU,UACV,QAAS,UACT,GAAI,UACJ,MAAO,UACP,KAAM,UACN,QAAS,UACT,KAAM,UACN,SAAU,UACV,KAAM,UACN,MAAO,UACP,WAAY,UACZ,KAAM,UACN,OAAQ,UACR,IAAK,UACL,OAAQ,UACR,QAAS,UACT,OAAQ,UACR,YAAa,UACb,QAAS,SACX,EACA,OAAQ,CACN,OAAQ,OACR,OAAQ,UACR,aAAc,OACd,YAAa,OACb,QAAS,QACT,MAAO,MACP,QAAS,SACT,MAAO,QACP,IAAK,UACL,KAAM,KACN,aAAc,QAEd,WAAY,UACZ,cAAe,WACf,gBAAiB,KACjB,gBAAiB,UACjB,kBAAmB,KACnB,mBAAoB,SACpB,cAAe,QACf,cAAe,UACf,YAAa,UACb,UAAW,OACX,WAAY,KAEZ,UAAW,UACX,OAAQ,OACR,UAAW,UACX,OAAQ,OACR,YAAa,cACb,kBAAmB,UACnB,QAAS,QACT,cAAe,UACf,KAAM,UACN,aAAc,OAId,cAAe,aACf,gBAAiB,MACjB,gBAAiB,QAGjB,cAAe,UACf,cAAe,MACf,eAAgB,OAChB,eAAgB,SAChB,aAAc,cACd,aAAc,SACd,WAAY,SACZ,eAAgB,MAChB,kBAAmB,QAInB,YAAa,OACb,gBAAiB,QACjB,YAAa,WACb,eAAgB,OAChB,aAAc,OACd,cAAe,UACf,YAAa,MAIb,SAAU,YACZ,EACA,OAAQ,CACN,OAAQ,KACR,OAAQ,QACR,OAAQ,SACV,CACF,EAEA,eAAsB,EAAkB,EAA6C,CACnF,IAAM,EAAY,EAAK,KAAK,EAAoB,GAAG,EAAmB,MAAM,EAE5E,OADA,MAAM,EAAG,SAAS,UAAU,EAAW,GAAG,KAAK,UAAU,EAAe,KAAM,CAAC,EAAE,IAAK,CAAE,KAAM,GAAM,CAAC,EAC9F,CACT"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./extensionName.cjs"),t=`core`,n={core:`core`,mcp:`mcp`,extension:`cli`},r={core:0,mcp:1,extension:2};function i(e){return e.state===`connected`?void 0:e.state.replace(/-/g,` `)}function a(e,t){return{name:e.name,...e.description?{description:e.description}:{},...e.parameters===void 0?{}:{parameters:e.parameters},...e.promptGuidelines?.length?{promptGuidelines:e.promptGuidelines}:{},active:t.has(e.name)}}function o(e,t){return e.name.localeCompare(t.name)}function s(e,t){return`${e} · ${n[t]}`}function c(e){let t=new Map;for(let n of e)for(let e of n.tools)t.set(e,n);return t}function l(n){let l=new Set(n.activeTools),u=n.mcpServers??[],d=c(u),f=[],p=new Map,m=new Map;for(let t of n.tools){let n=a(t,l),r=d.get(t.name);if(r){let e=p.get(r.name);e?e.push(n):p.set(r.name,[n]);continue}if(t.sourceInfo.source===`builtin`){f.push(n);continue}let i=t.sourceInfo.path,o=m.get(i);if(o)o.tools.push(n);else{let r=t.sourceInfo.source===`cli`||!t.sourceInfo.source?e.extensionName(i):t.sourceInfo.source;m.set(i,{label:s(r,`extension`),detail:i,tools:[n]})}}let h=[];f.length>0&&h.push({key:t,label:s(`pi`,t),kind:t,tools:f.sort(o)});for(let e of u){let t=p.get(e.name)??[],n=i(e);h.push({key:`mcp:${e.name}`,label:s(e.name,`mcp`),kind:`mcp`,...n?{status:n}:{},tools:t.sort(o)})}for(let[e,t]of m)h.push({key:e,label:t.label,kind:`extension`,detail:t.detail,tools:t.tools.sort(o)});return h.sort((e,t)=>r[e.kind]-r[t.kind]||e.label.localeCompare(t.label))}exports.buildToolSources=l;
2
+ //# sourceMappingURL=toolInventory.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolInventory.cjs","names":["extensionName"],"sources":["../src/toolInventory.ts"],"sourcesContent":["import type { McpServerSnapshot } from '@agimon-ai/doompi-extension-contracts/mcp-status';\nimport type { ToolInfo } from '@earendil-works/pi-coding-agent';\nimport { extensionName } from './extensionName.ts';\n\nexport type ToolSourceKind = 'core' | 'mcp' | 'extension';\n\nexport interface ToolEntry {\n name: string;\n description?: string;\n parameters?: unknown;\n promptGuidelines?: readonly string[];\n active: boolean;\n}\n\nexport interface ToolSource {\n key: string;\n label: string;\n kind: ToolSourceKind;\n /** Server state for MCP sources, e.g. `disabled`; absent for core and extensions. */\n status?: string;\n /** The registering file for extension sources. */\n detail?: string;\n tools: readonly ToolEntry[];\n}\n\n/** One server row of the MCP status snapshot. */\nexport type McpServerStatus = McpServerSnapshot;\n\nexport interface ToolInventoryInput {\n tools: readonly ToolInfo[];\n activeTools: readonly string[];\n /** Absent when the MCP adapter is not loaded or has not published yet. */\n mcpServers?: readonly McpServerStatus[];\n}\n\n/** Pi tags its own tools with this source; everything else came from an extension. */\nconst BUILTIN_SOURCE = 'builtin';\n/** Pi's tag for an extension passed as a `--extension` argument, which carries no package name. */\nconst CLI_SOURCE = 'cli';\nconst CORE_KEY = 'core';\nconst CORE_NAME = 'pi';\nconst MCP_KEY_PREFIX = 'mcp:';\n/** Labels read name first, then kind, because the name is what the eye scans for. */\nconst KIND_SUFFIX: Record<ToolSourceKind, string> = { core: 'core', mcp: 'mcp', extension: 'cli' };\nconst CONNECTED_STATUS = 'connected';\nconst KIND_ORDER: Record<ToolSourceKind, number> = { core: 0, mcp: 1, extension: 2 };\n\n/**\n * Server state worth reporting, which takes the place of the tool count.\n *\n * A connected server is the unremarkable case, so it keeps its count rather\n * than spending the column on a word that says nothing went wrong.\n */\nfunction displayStatus(server: McpServerStatus): string | undefined {\n return server.state === CONNECTED_STATUS ? undefined : server.state.replace(/-/g, ' ');\n}\n\nfunction toEntry(tool: ToolInfo, activeTools: ReadonlySet<string>): ToolEntry {\n return {\n name: tool.name,\n ...(tool.description ? { description: tool.description } : {}),\n ...(tool.parameters === undefined ? {} : { parameters: tool.parameters }),\n ...(tool.promptGuidelines?.length ? { promptGuidelines: tool.promptGuidelines } : {}),\n active: activeTools.has(tool.name),\n };\n}\n\nfunction byName(left: ToolEntry, right: ToolEntry): number {\n return left.name.localeCompare(right.name);\n}\n\nfunction sourceLabel(name: string, kind: ToolSourceKind): string {\n return `${name} · ${KIND_SUFFIX[kind]}`;\n}\n\n/**\n * Indexes each server's declared tool names.\n *\n * The snapshot names its tools outright, so attribution is a lookup rather than a\n * guess at the naming scheme. A tool the snapshot does not claim falls through to\n * the extension that registered it.\n */\nfunction serverByTool(servers: readonly McpServerStatus[]): Map<string, McpServerStatus> {\n const index = new Map<string, McpServerStatus>();\n for (const server of servers) {\n for (const toolName of server.tools) index.set(toolName, server);\n }\n return index;\n}\n\n/**\n * Groups the session's tools by where they came from: Pi itself, one group per\n * MCP server, then one per extension that registered a tool.\n *\n * Every MCP tool is registered by one extension, so `sourceInfo` cannot separate\n * servers; the status snapshot supplies the tool-to-server mapping instead.\n */\nexport function buildToolSources(input: ToolInventoryInput): readonly ToolSource[] {\n const activeTools = new Set(input.activeTools);\n const servers = input.mcpServers ?? [];\n const owningServer = serverByTool(servers);\n const core: ToolEntry[] = [];\n const mcpTools = new Map<string, ToolEntry[]>();\n const extensions = new Map<string, { label: string; detail: string; tools: ToolEntry[] }>();\n\n for (const tool of input.tools) {\n const entry = toEntry(tool, activeTools);\n const server = owningServer.get(tool.name);\n if (server) {\n const bucket = mcpTools.get(server.name);\n if (bucket) bucket.push(entry);\n else mcpTools.set(server.name, [entry]);\n continue;\n }\n if (tool.sourceInfo.source === BUILTIN_SOURCE) {\n core.push(entry);\n continue;\n }\n const key = tool.sourceInfo.path;\n const group = extensions.get(key);\n if (group) group.tools.push(entry);\n else {\n // `cli` is Pi's tag for a `--extension` argument, not a name: recover one from the path.\n const name =\n tool.sourceInfo.source === CLI_SOURCE || !tool.sourceInfo.source ? extensionName(key) : tool.sourceInfo.source;\n extensions.set(key, { label: sourceLabel(name, 'extension'), detail: key, tools: [entry] });\n }\n }\n\n const sources: ToolSource[] = [];\n if (core.length > 0) {\n sources.push({ key: CORE_KEY, label: sourceLabel(CORE_NAME, CORE_KEY), kind: CORE_KEY, tools: core.sort(byName) });\n }\n for (const server of servers) {\n const tools = mcpTools.get(server.name) ?? [];\n const status = displayStatus(server);\n // Every configured server is listed, including one with no tools: attribution\n // is exact now, so an empty list is a fact about the server rather than a\n // failure to recognise its tool names.\n sources.push({\n key: `${MCP_KEY_PREFIX}${server.name}`,\n label: sourceLabel(server.name, 'mcp'),\n kind: 'mcp',\n ...(status ? { status } : {}),\n tools: tools.sort(byName),\n });\n }\n for (const [key, group] of extensions) {\n sources.push({\n key,\n label: group.label,\n kind: 'extension',\n detail: group.detail,\n tools: group.tools.sort(byName),\n });\n }\n\n return sources.sort(\n (left, right) => KIND_ORDER[left.kind] - KIND_ORDER[right.kind] || left.label.localeCompare(right.label),\n );\n}\n"],"mappings":"0GAuCM,EAAW,OAIX,EAA8C,CAAE,KAAM,OAAQ,IAAK,MAAO,UAAW,KAAM,EAE3F,EAA6C,CAAE,KAAM,EAAG,IAAK,EAAG,UAAW,CAAE,EAQnF,SAAS,EAAc,EAA6C,CAClE,OAAO,EAAO,QAAU,YAAmB,IAAA,GAAY,EAAO,MAAM,QAAQ,KAAM,GAAG,CACvF,CAEA,SAAS,EAAQ,EAAgB,EAA6C,CAC5E,MAAO,CACL,KAAM,EAAK,KACX,GAAI,EAAK,YAAc,CAAE,YAAa,EAAK,WAAY,EAAI,CAAC,EAC5D,GAAI,EAAK,aAAe,IAAA,GAAY,CAAC,EAAI,CAAE,WAAY,EAAK,UAAW,EACvE,GAAI,EAAK,kBAAkB,OAAS,CAAE,iBAAkB,EAAK,gBAAiB,EAAI,CAAC,EACnF,OAAQ,EAAY,IAAI,EAAK,IAAI,CACnC,CACF,CAEA,SAAS,EAAO,EAAiB,EAA0B,CACzD,OAAO,EAAK,KAAK,cAAc,EAAM,IAAI,CAC3C,CAEA,SAAS,EAAY,EAAc,EAA8B,CAC/D,MAAO,GAAG,EAAK,KAAK,EAAY,IAClC,CASA,SAAS,EAAa,EAAmE,CACvF,IAAM,EAAQ,IAAI,IAClB,IAAK,IAAM,KAAU,EACnB,IAAK,IAAM,KAAY,EAAO,MAAO,EAAM,IAAI,EAAU,CAAM,EAEjE,OAAO,CACT,CASA,SAAgB,EAAiB,EAAkD,CACjF,IAAM,EAAc,IAAI,IAAI,EAAM,WAAW,EACvC,EAAU,EAAM,YAAc,CAAC,EAC/B,EAAe,EAAa,CAAO,EACnC,EAAoB,CAAC,EACrB,EAAW,IAAI,IACf,EAAa,IAAI,IAEvB,IAAK,IAAM,KAAQ,EAAM,MAAO,CAC9B,IAAM,EAAQ,EAAQ,EAAM,CAAW,EACjC,EAAS,EAAa,IAAI,EAAK,IAAI,EACzC,GAAI,EAAQ,CACV,IAAM,EAAS,EAAS,IAAI,EAAO,IAAI,EACnC,EAAQ,EAAO,KAAK,CAAK,EACxB,EAAS,IAAI,EAAO,KAAM,CAAC,CAAK,CAAC,EACtC,QACF,CACA,GAAI,EAAK,WAAW,SAAW,UAAgB,CAC7C,EAAK,KAAK,CAAK,EACf,QACF,CACA,IAAM,EAAM,EAAK,WAAW,KACtB,EAAQ,EAAW,IAAI,CAAG,EAChC,GAAI,EAAO,EAAM,MAAM,KAAK,CAAK,MAC5B,CAEH,IAAM,EACJ,EAAK,WAAW,SAAW,OAAc,CAAC,EAAK,WAAW,OAASA,EAAAA,cAAc,CAAG,EAAI,EAAK,WAAW,OAC1G,EAAW,IAAI,EAAK,CAAE,MAAO,EAAY,EAAM,WAAW,EAAG,OAAQ,EAAK,MAAO,CAAC,CAAK,CAAE,CAAC,CAC5F,CACF,CAEA,IAAM,EAAwB,CAAC,EAC3B,EAAK,OAAS,GAChB,EAAQ,KAAK,CAAE,IAAK,EAAU,MAAO,EAAY,KAAW,CAAQ,EAAG,KAAM,EAAU,MAAO,EAAK,KAAK,CAAM,CAAE,CAAC,EAEnH,IAAK,IAAM,KAAU,EAAS,CAC5B,IAAM,EAAQ,EAAS,IAAI,EAAO,IAAI,GAAK,CAAC,EACtC,EAAS,EAAc,CAAM,EAInC,EAAQ,KAAK,CACX,IAAK,OAAoB,EAAO,OAChC,MAAO,EAAY,EAAO,KAAM,KAAK,EACrC,KAAM,MACN,GAAI,EAAS,CAAE,QAAO,EAAI,CAAC,EAC3B,MAAO,EAAM,KAAK,CAAM,CAC1B,CAAC,CACH,CACA,IAAK,GAAM,CAAC,EAAK,KAAU,EACzB,EAAQ,KAAK,CACX,MACA,MAAO,EAAM,MACb,KAAM,YACN,OAAQ,EAAM,OACd,MAAO,EAAM,MAAM,KAAK,CAAM,CAChC,CAAC,EAGH,OAAO,EAAQ,MACZ,EAAM,IAAU,EAAW,EAAK,MAAQ,EAAW,EAAM,OAAS,EAAK,MAAM,cAAc,EAAM,KAAK,CACzG,CACF"}
@@ -0,0 +1,40 @@
1
+ import { ToolInfo } from "@earendil-works/pi-coding-agent";
2
+ import { McpServerSnapshot } from "@agimon-ai/doompi-extension-contracts/mcp-status";
3
+ //#region src/toolInventory.d.ts
4
+ type ToolSourceKind = 'core' | 'mcp' | 'extension';
5
+ interface ToolEntry {
6
+ name: string;
7
+ description?: string;
8
+ parameters?: unknown;
9
+ promptGuidelines?: readonly string[];
10
+ active: boolean;
11
+ }
12
+ interface ToolSource {
13
+ key: string;
14
+ label: string;
15
+ kind: ToolSourceKind;
16
+ /** Server state for MCP sources, e.g. `disabled`; absent for core and extensions. */
17
+ status?: string;
18
+ /** The registering file for extension sources. */
19
+ detail?: string;
20
+ tools: readonly ToolEntry[];
21
+ }
22
+ /** One server row of the MCP status snapshot. */
23
+ type McpServerStatus = McpServerSnapshot;
24
+ interface ToolInventoryInput {
25
+ tools: readonly ToolInfo[];
26
+ activeTools: readonly string[];
27
+ /** Absent when the MCP adapter is not loaded or has not published yet. */
28
+ mcpServers?: readonly McpServerStatus[];
29
+ }
30
+ /**
31
+ * Groups the session's tools by where they came from: Pi itself, one group per
32
+ * MCP server, then one per extension that registered a tool.
33
+ *
34
+ * Every MCP tool is registered by one extension, so `sourceInfo` cannot separate
35
+ * servers; the status snapshot supplies the tool-to-server mapping instead.
36
+ */
37
+ declare function buildToolSources(input: ToolInventoryInput): readonly ToolSource[];
38
+ //#endregion
39
+ export { McpServerStatus, ToolEntry, ToolInventoryInput, ToolSource, ToolSourceKind, buildToolSources };
40
+ //# sourceMappingURL=toolInventory.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolInventory.d.cts","names":[],"sources":["../src/toolInventory.ts"],"mappings":";;;KAIY;UAEK;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA,MAAM;;EAEN;;EAEA;EACA,gBAAgB;;;KAIN,kBAAkB;UAEb;EACf,gBAAgB;EAChB;;EAEA,sBAAsB;;;;;;;;;iBAiER,iBAAiB,OAAO,8BAA8B"}
@@ -0,0 +1,40 @@
1
+ import { ToolInfo } from "@earendil-works/pi-coding-agent";
2
+ import { McpServerSnapshot } from "@agimon-ai/doompi-extension-contracts/mcp-status";
3
+ //#region src/toolInventory.d.ts
4
+ type ToolSourceKind = 'core' | 'mcp' | 'extension';
5
+ interface ToolEntry {
6
+ name: string;
7
+ description?: string;
8
+ parameters?: unknown;
9
+ promptGuidelines?: readonly string[];
10
+ active: boolean;
11
+ }
12
+ interface ToolSource {
13
+ key: string;
14
+ label: string;
15
+ kind: ToolSourceKind;
16
+ /** Server state for MCP sources, e.g. `disabled`; absent for core and extensions. */
17
+ status?: string;
18
+ /** The registering file for extension sources. */
19
+ detail?: string;
20
+ tools: readonly ToolEntry[];
21
+ }
22
+ /** One server row of the MCP status snapshot. */
23
+ type McpServerStatus = McpServerSnapshot;
24
+ interface ToolInventoryInput {
25
+ tools: readonly ToolInfo[];
26
+ activeTools: readonly string[];
27
+ /** Absent when the MCP adapter is not loaded or has not published yet. */
28
+ mcpServers?: readonly McpServerStatus[];
29
+ }
30
+ /**
31
+ * Groups the session's tools by where they came from: Pi itself, one group per
32
+ * MCP server, then one per extension that registered a tool.
33
+ *
34
+ * Every MCP tool is registered by one extension, so `sourceInfo` cannot separate
35
+ * servers; the status snapshot supplies the tool-to-server mapping instead.
36
+ */
37
+ declare function buildToolSources(input: ToolInventoryInput): readonly ToolSource[];
38
+ //#endregion
39
+ export { McpServerStatus, ToolEntry, ToolInventoryInput, ToolSource, ToolSourceKind, buildToolSources };
40
+ //# sourceMappingURL=toolInventory.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolInventory.d.mts","names":[],"sources":["../src/toolInventory.ts"],"mappings":";;;KAIY;UAEK;EACf;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA,MAAM;;EAEN;;EAEA;EACA,gBAAgB;;;KAIN,kBAAkB;UAEb;EACf,gBAAgB;EAChB;;EAEA,sBAAsB;;;;;;;;;iBAiER,iBAAiB,OAAO,8BAA8B"}
@@ -0,0 +1,2 @@
1
+ import{extensionName as e}from"./extensionName.mjs";const t=`core`,n={core:`core`,mcp:`mcp`,extension:`cli`},r={core:0,mcp:1,extension:2};function i(e){return e.state===`connected`?void 0:e.state.replace(/-/g,` `)}function a(e,t){return{name:e.name,...e.description?{description:e.description}:{},...e.parameters===void 0?{}:{parameters:e.parameters},...e.promptGuidelines?.length?{promptGuidelines:e.promptGuidelines}:{},active:t.has(e.name)}}function o(e,t){return e.name.localeCompare(t.name)}function s(e,t){return`${e} · ${n[t]}`}function c(e){let t=new Map;for(let n of e)for(let e of n.tools)t.set(e,n);return t}function l(n){let l=new Set(n.activeTools),u=n.mcpServers??[],d=c(u),f=[],p=new Map,m=new Map;for(let t of n.tools){let n=a(t,l),r=d.get(t.name);if(r){let e=p.get(r.name);e?e.push(n):p.set(r.name,[n]);continue}if(t.sourceInfo.source===`builtin`){f.push(n);continue}let i=t.sourceInfo.path,o=m.get(i);if(o)o.tools.push(n);else{let r=t.sourceInfo.source===`cli`||!t.sourceInfo.source?e(i):t.sourceInfo.source;m.set(i,{label:s(r,`extension`),detail:i,tools:[n]})}}let h=[];f.length>0&&h.push({key:t,label:s(`pi`,t),kind:t,tools:f.sort(o)});for(let e of u){let t=p.get(e.name)??[],n=i(e);h.push({key:`mcp:${e.name}`,label:s(e.name,`mcp`),kind:`mcp`,...n?{status:n}:{},tools:t.sort(o)})}for(let[e,t]of m)h.push({key:e,label:t.label,kind:`extension`,detail:t.detail,tools:t.tools.sort(o)});return h.sort((e,t)=>r[e.kind]-r[t.kind]||e.label.localeCompare(t.label))}export{l as buildToolSources};
2
+ //# sourceMappingURL=toolInventory.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolInventory.mjs","names":[],"sources":["../src/toolInventory.ts"],"sourcesContent":["import type { McpServerSnapshot } from '@agimon-ai/doompi-extension-contracts/mcp-status';\nimport type { ToolInfo } from '@earendil-works/pi-coding-agent';\nimport { extensionName } from './extensionName.ts';\n\nexport type ToolSourceKind = 'core' | 'mcp' | 'extension';\n\nexport interface ToolEntry {\n name: string;\n description?: string;\n parameters?: unknown;\n promptGuidelines?: readonly string[];\n active: boolean;\n}\n\nexport interface ToolSource {\n key: string;\n label: string;\n kind: ToolSourceKind;\n /** Server state for MCP sources, e.g. `disabled`; absent for core and extensions. */\n status?: string;\n /** The registering file for extension sources. */\n detail?: string;\n tools: readonly ToolEntry[];\n}\n\n/** One server row of the MCP status snapshot. */\nexport type McpServerStatus = McpServerSnapshot;\n\nexport interface ToolInventoryInput {\n tools: readonly ToolInfo[];\n activeTools: readonly string[];\n /** Absent when the MCP adapter is not loaded or has not published yet. */\n mcpServers?: readonly McpServerStatus[];\n}\n\n/** Pi tags its own tools with this source; everything else came from an extension. */\nconst BUILTIN_SOURCE = 'builtin';\n/** Pi's tag for an extension passed as a `--extension` argument, which carries no package name. */\nconst CLI_SOURCE = 'cli';\nconst CORE_KEY = 'core';\nconst CORE_NAME = 'pi';\nconst MCP_KEY_PREFIX = 'mcp:';\n/** Labels read name first, then kind, because the name is what the eye scans for. */\nconst KIND_SUFFIX: Record<ToolSourceKind, string> = { core: 'core', mcp: 'mcp', extension: 'cli' };\nconst CONNECTED_STATUS = 'connected';\nconst KIND_ORDER: Record<ToolSourceKind, number> = { core: 0, mcp: 1, extension: 2 };\n\n/**\n * Server state worth reporting, which takes the place of the tool count.\n *\n * A connected server is the unremarkable case, so it keeps its count rather\n * than spending the column on a word that says nothing went wrong.\n */\nfunction displayStatus(server: McpServerStatus): string | undefined {\n return server.state === CONNECTED_STATUS ? undefined : server.state.replace(/-/g, ' ');\n}\n\nfunction toEntry(tool: ToolInfo, activeTools: ReadonlySet<string>): ToolEntry {\n return {\n name: tool.name,\n ...(tool.description ? { description: tool.description } : {}),\n ...(tool.parameters === undefined ? {} : { parameters: tool.parameters }),\n ...(tool.promptGuidelines?.length ? { promptGuidelines: tool.promptGuidelines } : {}),\n active: activeTools.has(tool.name),\n };\n}\n\nfunction byName(left: ToolEntry, right: ToolEntry): number {\n return left.name.localeCompare(right.name);\n}\n\nfunction sourceLabel(name: string, kind: ToolSourceKind): string {\n return `${name} · ${KIND_SUFFIX[kind]}`;\n}\n\n/**\n * Indexes each server's declared tool names.\n *\n * The snapshot names its tools outright, so attribution is a lookup rather than a\n * guess at the naming scheme. A tool the snapshot does not claim falls through to\n * the extension that registered it.\n */\nfunction serverByTool(servers: readonly McpServerStatus[]): Map<string, McpServerStatus> {\n const index = new Map<string, McpServerStatus>();\n for (const server of servers) {\n for (const toolName of server.tools) index.set(toolName, server);\n }\n return index;\n}\n\n/**\n * Groups the session's tools by where they came from: Pi itself, one group per\n * MCP server, then one per extension that registered a tool.\n *\n * Every MCP tool is registered by one extension, so `sourceInfo` cannot separate\n * servers; the status snapshot supplies the tool-to-server mapping instead.\n */\nexport function buildToolSources(input: ToolInventoryInput): readonly ToolSource[] {\n const activeTools = new Set(input.activeTools);\n const servers = input.mcpServers ?? [];\n const owningServer = serverByTool(servers);\n const core: ToolEntry[] = [];\n const mcpTools = new Map<string, ToolEntry[]>();\n const extensions = new Map<string, { label: string; detail: string; tools: ToolEntry[] }>();\n\n for (const tool of input.tools) {\n const entry = toEntry(tool, activeTools);\n const server = owningServer.get(tool.name);\n if (server) {\n const bucket = mcpTools.get(server.name);\n if (bucket) bucket.push(entry);\n else mcpTools.set(server.name, [entry]);\n continue;\n }\n if (tool.sourceInfo.source === BUILTIN_SOURCE) {\n core.push(entry);\n continue;\n }\n const key = tool.sourceInfo.path;\n const group = extensions.get(key);\n if (group) group.tools.push(entry);\n else {\n // `cli` is Pi's tag for a `--extension` argument, not a name: recover one from the path.\n const name =\n tool.sourceInfo.source === CLI_SOURCE || !tool.sourceInfo.source ? extensionName(key) : tool.sourceInfo.source;\n extensions.set(key, { label: sourceLabel(name, 'extension'), detail: key, tools: [entry] });\n }\n }\n\n const sources: ToolSource[] = [];\n if (core.length > 0) {\n sources.push({ key: CORE_KEY, label: sourceLabel(CORE_NAME, CORE_KEY), kind: CORE_KEY, tools: core.sort(byName) });\n }\n for (const server of servers) {\n const tools = mcpTools.get(server.name) ?? [];\n const status = displayStatus(server);\n // Every configured server is listed, including one with no tools: attribution\n // is exact now, so an empty list is a fact about the server rather than a\n // failure to recognise its tool names.\n sources.push({\n key: `${MCP_KEY_PREFIX}${server.name}`,\n label: sourceLabel(server.name, 'mcp'),\n kind: 'mcp',\n ...(status ? { status } : {}),\n tools: tools.sort(byName),\n });\n }\n for (const [key, group] of extensions) {\n sources.push({\n key,\n label: group.label,\n kind: 'extension',\n detail: group.detail,\n tools: group.tools.sort(byName),\n });\n }\n\n return sources.sort(\n (left, right) => KIND_ORDER[left.kind] - KIND_ORDER[right.kind] || left.label.localeCompare(right.label),\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e={active:!1,prefix:[],label:``,options:[]};function t(e){return{active:e.active,prefix:[...e.prefix],label:e.label,options:e.options.map(e=>({...e})),...e.rootOptions?{rootOptions:e.rootOptions.map(e=>({...e}))}:{}}}var n=class{snapshot=e;modes=[];listeners=new Set;getSnapshot(){return t(this.snapshot)}getModes(){return this.modes}setModes(e){this.modes=e.map(e=>({...e}));for(let e of this.listeners)e(this.getSnapshot())}setLeader(e){this.snapshot=t(e);for(let e of this.listeners)e(this.getSnapshot())}reset(){this.modes=[],this.setLeader(e)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}};exports.DoomUiState=n;
2
+ //# sourceMappingURL=uiState.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uiState.cjs","names":[],"sources":["../src/uiState.ts"],"sourcesContent":["import type { DoomModeStatus } from './mode.ts';\n\nexport interface LeaderOption {\n key: string;\n label: string;\n detail?: string;\n}\n\nexport interface LeaderSnapshot {\n active: boolean;\n prefix: string[];\n label: string;\n options: LeaderOption[];\n rootOptions?: LeaderOption[];\n}\n\ntype StateListener = (snapshot: LeaderSnapshot) => void;\n\nconst INACTIVE_SNAPSHOT: LeaderSnapshot = {\n active: false,\n prefix: [],\n label: '',\n options: [],\n};\n\nfunction cloneSnapshot(snapshot: LeaderSnapshot): LeaderSnapshot {\n return {\n active: snapshot.active,\n prefix: [...snapshot.prefix],\n label: snapshot.label,\n options: snapshot.options.map((option) => ({ ...option })),\n ...(snapshot.rootOptions ? { rootOptions: snapshot.rootOptions.map((option) => ({ ...option })) } : {}),\n };\n}\n\nexport class DoomUiState {\n private snapshot = INACTIVE_SNAPSHOT;\n /**\n * The enabled modes, shown in two places at two levels of detail.\n *\n * Held here rather than read from the mode registry by each surface because\n * both readers already take this state: the editor prints the names beside\n * its mode badge, and the leader panel prints them with their detail. One\n * source, so the two can never disagree about what is on.\n */\n private modes: readonly DoomModeStatus[] = [];\n private readonly listeners = new Set<StateListener>();\n\n getSnapshot(): LeaderSnapshot {\n return cloneSnapshot(this.snapshot);\n }\n\n getModes(): readonly DoomModeStatus[] {\n return this.modes;\n }\n\n setModes(modes: readonly DoomModeStatus[]): void {\n this.modes = modes.map((mode) => ({ ...mode }));\n for (const listener of this.listeners) listener(this.getSnapshot());\n }\n\n setLeader(snapshot: LeaderSnapshot): void {\n this.snapshot = cloneSnapshot(snapshot);\n for (const listener of this.listeners) listener(this.getSnapshot());\n }\n\n reset(): void {\n this.modes = [];\n this.setLeader(INACTIVE_SNAPSHOT);\n }\n\n subscribe(listener: StateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n}\n"],"mappings":"mEAkBA,MAAM,EAAoC,CACxC,OAAQ,GACR,OAAQ,CAAC,EACT,MAAO,GACP,QAAS,CAAC,CACZ,EAEA,SAAS,EAAc,EAA0C,CAC/D,MAAO,CACL,OAAQ,EAAS,OACjB,OAAQ,CAAC,GAAG,EAAS,MAAM,EAC3B,MAAO,EAAS,MAChB,QAAS,EAAS,QAAQ,IAAK,IAAY,CAAE,GAAG,CAAO,EAAE,EACzD,GAAI,EAAS,YAAc,CAAE,YAAa,EAAS,YAAY,IAAK,IAAY,CAAE,GAAG,CAAO,EAAE,CAAE,EAAI,CAAC,CACvG,CACF,CAEA,IAAa,EAAb,KAAyB,CACvB,SAAmB,EASnB,MAA2C,CAAC,EAC5C,UAA6B,IAAI,IAEjC,aAA8B,CAC5B,OAAO,EAAc,KAAK,QAAQ,CACpC,CAEA,UAAsC,CACpC,OAAO,KAAK,KACd,CAEA,SAAS,EAAwC,CAC/C,KAAK,MAAQ,EAAM,IAAK,IAAU,CAAE,GAAG,CAAK,EAAE,EAC9C,IAAK,IAAM,KAAY,KAAK,UAAW,EAAS,KAAK,YAAY,CAAC,CACpE,CAEA,UAAU,EAAgC,CACxC,KAAK,SAAW,EAAc,CAAQ,EACtC,IAAK,IAAM,KAAY,KAAK,UAAW,EAAS,KAAK,YAAY,CAAC,CACpE,CAEA,OAAc,CACZ,KAAK,MAAQ,CAAC,EACd,KAAK,UAAU,CAAiB,CAClC,CAEA,UAAU,EAAqC,CAE7C,OADA,KAAK,UAAU,IAAI,CAAQ,MACd,KAAK,UAAU,OAAO,CAAQ,CAC7C,CACF"}
@@ -0,0 +1,37 @@
1
+ import { mode_d_exports } from "./mode.cjs";
2
+ //#region src/uiState.d.ts
3
+ interface LeaderOption {
4
+ key: string;
5
+ label: string;
6
+ detail?: string;
7
+ }
8
+ interface LeaderSnapshot {
9
+ active: boolean;
10
+ prefix: string[];
11
+ label: string;
12
+ options: LeaderOption[];
13
+ rootOptions?: LeaderOption[];
14
+ }
15
+ type StateListener = (snapshot: LeaderSnapshot) => void;
16
+ declare class DoomUiState {
17
+ private snapshot;
18
+ /**
19
+ * The enabled modes, shown in two places at two levels of detail.
20
+ *
21
+ * Held here rather than read from the mode registry by each surface because
22
+ * both readers already take this state: the editor prints the names beside
23
+ * its mode badge, and the leader panel prints them with their detail. One
24
+ * source, so the two can never disagree about what is on.
25
+ */
26
+ private modes;
27
+ private readonly listeners;
28
+ getSnapshot(): LeaderSnapshot;
29
+ getModes(): readonly mode_d_exports.DoomModeStatus[];
30
+ setModes(modes: readonly mode_d_exports.DoomModeStatus[]): void;
31
+ setLeader(snapshot: LeaderSnapshot): void;
32
+ reset(): void;
33
+ subscribe(listener: StateListener): () => void;
34
+ }
35
+ //#endregion
36
+ export { DoomUiState, LeaderOption, LeaderSnapshot };
37
+ //# sourceMappingURL=uiState.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uiState.d.cts","names":[],"sources":["../src/uiState.ts"],"mappings":";;UAEiB;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA,SAAS;EACT,cAAc;;KAGX,iBAAiB,UAAU;cAmBnB;UACH;;;;;;;;;UASA;mBACS;EAEjB,eAAe;EAIf,qBAAqB,eAAA;EAIrB,SAAS,gBAAgB,eAAA;EAKzB,UAAU,UAAU;EAKpB;EAKA,UAAU,UAAU"}
@@ -0,0 +1,37 @@
1
+ import { mode_d_exports } from "./mode.mjs";
2
+ //#region src/uiState.d.ts
3
+ interface LeaderOption {
4
+ key: string;
5
+ label: string;
6
+ detail?: string;
7
+ }
8
+ interface LeaderSnapshot {
9
+ active: boolean;
10
+ prefix: string[];
11
+ label: string;
12
+ options: LeaderOption[];
13
+ rootOptions?: LeaderOption[];
14
+ }
15
+ type StateListener = (snapshot: LeaderSnapshot) => void;
16
+ declare class DoomUiState {
17
+ private snapshot;
18
+ /**
19
+ * The enabled modes, shown in two places at two levels of detail.
20
+ *
21
+ * Held here rather than read from the mode registry by each surface because
22
+ * both readers already take this state: the editor prints the names beside
23
+ * its mode badge, and the leader panel prints them with their detail. One
24
+ * source, so the two can never disagree about what is on.
25
+ */
26
+ private modes;
27
+ private readonly listeners;
28
+ getSnapshot(): LeaderSnapshot;
29
+ getModes(): readonly mode_d_exports.DoomModeStatus[];
30
+ setModes(modes: readonly mode_d_exports.DoomModeStatus[]): void;
31
+ setLeader(snapshot: LeaderSnapshot): void;
32
+ reset(): void;
33
+ subscribe(listener: StateListener): () => void;
34
+ }
35
+ //#endregion
36
+ export { DoomUiState, LeaderOption, LeaderSnapshot };
37
+ //# sourceMappingURL=uiState.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uiState.d.mts","names":[],"sources":["../src/uiState.ts"],"mappings":";;UAEiB;EACf;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA,SAAS;EACT,cAAc;;KAGX,iBAAiB,UAAU;cAmBnB;UACH;;;;;;;;;UASA;mBACS;EAEjB,eAAe;EAIf,qBAAqB,eAAA;EAIrB,SAAS,gBAAgB,eAAA;EAKzB,UAAU,UAAU;EAKpB;EAKA,UAAU,UAAU"}
@@ -0,0 +1,2 @@
1
+ const e={active:!1,prefix:[],label:``,options:[]};function t(e){return{active:e.active,prefix:[...e.prefix],label:e.label,options:e.options.map(e=>({...e})),...e.rootOptions?{rootOptions:e.rootOptions.map(e=>({...e}))}:{}}}var n=class{snapshot=e;modes=[];listeners=new Set;getSnapshot(){return t(this.snapshot)}getModes(){return this.modes}setModes(e){this.modes=e.map(e=>({...e}));for(let e of this.listeners)e(this.getSnapshot())}setLeader(e){this.snapshot=t(e);for(let e of this.listeners)e(this.getSnapshot())}reset(){this.modes=[],this.setLeader(e)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}};export{n as DoomUiState};
2
+ //# sourceMappingURL=uiState.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uiState.mjs","names":[],"sources":["../src/uiState.ts"],"sourcesContent":["import type { DoomModeStatus } from './mode.ts';\n\nexport interface LeaderOption {\n key: string;\n label: string;\n detail?: string;\n}\n\nexport interface LeaderSnapshot {\n active: boolean;\n prefix: string[];\n label: string;\n options: LeaderOption[];\n rootOptions?: LeaderOption[];\n}\n\ntype StateListener = (snapshot: LeaderSnapshot) => void;\n\nconst INACTIVE_SNAPSHOT: LeaderSnapshot = {\n active: false,\n prefix: [],\n label: '',\n options: [],\n};\n\nfunction cloneSnapshot(snapshot: LeaderSnapshot): LeaderSnapshot {\n return {\n active: snapshot.active,\n prefix: [...snapshot.prefix],\n label: snapshot.label,\n options: snapshot.options.map((option) => ({ ...option })),\n ...(snapshot.rootOptions ? { rootOptions: snapshot.rootOptions.map((option) => ({ ...option })) } : {}),\n };\n}\n\nexport class DoomUiState {\n private snapshot = INACTIVE_SNAPSHOT;\n /**\n * The enabled modes, shown in two places at two levels of detail.\n *\n * Held here rather than read from the mode registry by each surface because\n * both readers already take this state: the editor prints the names beside\n * its mode badge, and the leader panel prints them with their detail. One\n * source, so the two can never disagree about what is on.\n */\n private modes: readonly DoomModeStatus[] = [];\n private readonly listeners = new Set<StateListener>();\n\n getSnapshot(): LeaderSnapshot {\n return cloneSnapshot(this.snapshot);\n }\n\n getModes(): readonly DoomModeStatus[] {\n return this.modes;\n }\n\n setModes(modes: readonly DoomModeStatus[]): void {\n this.modes = modes.map((mode) => ({ ...mode }));\n for (const listener of this.listeners) listener(this.getSnapshot());\n }\n\n setLeader(snapshot: LeaderSnapshot): void {\n this.snapshot = cloneSnapshot(snapshot);\n for (const listener of this.listeners) listener(this.getSnapshot());\n }\n\n reset(): void {\n this.modes = [];\n this.setLeader(INACTIVE_SNAPSHOT);\n }\n\n subscribe(listener: StateListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n}\n"],"mappings":"AAkBA,MAAM,EAAoC,CACxC,OAAQ,GACR,OAAQ,CAAC,EACT,MAAO,GACP,QAAS,CAAC,CACZ,EAEA,SAAS,EAAc,EAA0C,CAC/D,MAAO,CACL,OAAQ,EAAS,OACjB,OAAQ,CAAC,GAAG,EAAS,MAAM,EAC3B,MAAO,EAAS,MAChB,QAAS,EAAS,QAAQ,IAAK,IAAY,CAAE,GAAG,CAAO,EAAE,EACzD,GAAI,EAAS,YAAc,CAAE,YAAa,EAAS,YAAY,IAAK,IAAY,CAAE,GAAG,CAAO,EAAE,CAAE,EAAI,CAAC,CACvG,CACF,CAEA,IAAa,EAAb,KAAyB,CACvB,SAAmB,EASnB,MAA2C,CAAC,EAC5C,UAA6B,IAAI,IAEjC,aAA8B,CAC5B,OAAO,EAAc,KAAK,QAAQ,CACpC,CAEA,UAAsC,CACpC,OAAO,KAAK,KACd,CAEA,SAAS,EAAwC,CAC/C,KAAK,MAAQ,EAAM,IAAK,IAAU,CAAE,GAAG,CAAK,EAAE,EAC9C,IAAK,IAAM,KAAY,KAAK,UAAW,EAAS,KAAK,YAAY,CAAC,CACpE,CAEA,UAAU,EAAgC,CACxC,KAAK,SAAW,EAAc,CAAQ,EACtC,IAAK,IAAM,KAAY,KAAK,UAAW,EAAS,KAAK,YAAY,CAAC,CACpE,CAEA,OAAc,CACZ,KAAK,MAAQ,CAAC,EACd,KAAK,UAAU,CAAiB,CAClC,CAEA,UAAU,EAAqC,CAE7C,OADA,KAAK,UAAU,IAAI,CAAQ,MACd,KAAK,UAAU,OAAO,CAAQ,CAC7C,CACF"}