ankui 0.1.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 (270) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +369 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +192 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/access.d.ts +6 -0
  7. package/dist/commands/access.js +12 -0
  8. package/dist/commands/access.js.map +1 -0
  9. package/dist/commands/caps.d.ts +6 -0
  10. package/dist/commands/caps.js +12 -0
  11. package/dist/commands/caps.js.map +1 -0
  12. package/dist/commands/discover.d.ts +10 -0
  13. package/dist/commands/discover.js +120 -0
  14. package/dist/commands/discover.js.map +1 -0
  15. package/dist/commands/doctor.d.ts +6 -0
  16. package/dist/commands/doctor.js +12 -0
  17. package/dist/commands/doctor.js.map +1 -0
  18. package/dist/commands/launch-tui.d.ts +15 -0
  19. package/dist/commands/launch-tui.js +53 -0
  20. package/dist/commands/launch-tui.js.map +1 -0
  21. package/dist/commands/list.d.ts +11 -0
  22. package/dist/commands/list.js +51 -0
  23. package/dist/commands/list.js.map +1 -0
  24. package/dist/commands/mcp.d.ts +6 -0
  25. package/dist/commands/mcp.js +12 -0
  26. package/dist/commands/mcp.js.map +1 -0
  27. package/dist/commands/scan-all.d.ts +15 -0
  28. package/dist/commands/scan-all.js +32 -0
  29. package/dist/commands/scan-all.js.map +1 -0
  30. package/dist/commands/show.d.ts +7 -0
  31. package/dist/commands/show.js +12 -0
  32. package/dist/commands/show.js.map +1 -0
  33. package/dist/commands/watch.d.ts +32 -0
  34. package/dist/commands/watch.js +205 -0
  35. package/dist/commands/watch.js.map +1 -0
  36. package/dist/config/ankui-config.d.ts +13 -0
  37. package/dist/config/ankui-config.js +123 -0
  38. package/dist/config/ankui-config.js.map +1 -0
  39. package/dist/scanner/access-review.d.ts +2 -0
  40. package/dist/scanner/access-review.js +183 -0
  41. package/dist/scanner/access-review.js.map +1 -0
  42. package/dist/scanner/adapters/claude.d.ts +2 -0
  43. package/dist/scanner/adapters/claude.js +298 -0
  44. package/dist/scanner/adapters/claude.js.map +1 -0
  45. package/dist/scanner/adapters/codex.d.ts +2 -0
  46. package/dist/scanner/adapters/codex.js +152 -0
  47. package/dist/scanner/adapters/codex.js.map +1 -0
  48. package/dist/scanner/adapters/cursor.d.ts +2 -0
  49. package/dist/scanner/adapters/cursor.js +114 -0
  50. package/dist/scanner/adapters/cursor.js.map +1 -0
  51. package/dist/scanner/adapters/gemini.d.ts +2 -0
  52. package/dist/scanner/adapters/gemini.js +191 -0
  53. package/dist/scanner/adapters/gemini.js.map +1 -0
  54. package/dist/scanner/adapters/index.d.ts +35 -0
  55. package/dist/scanner/adapters/index.js +85 -0
  56. package/dist/scanner/adapters/index.js.map +1 -0
  57. package/dist/scanner/adapters/opencode.d.ts +2 -0
  58. package/dist/scanner/adapters/opencode.js +231 -0
  59. package/dist/scanner/adapters/opencode.js.map +1 -0
  60. package/dist/scanner/adapters/shared.d.ts +57 -0
  61. package/dist/scanner/adapters/shared.js +239 -0
  62. package/dist/scanner/adapters/shared.js.map +1 -0
  63. package/dist/scanner/adapters/skills-sh.d.ts +2 -0
  64. package/dist/scanner/adapters/skills-sh.js +71 -0
  65. package/dist/scanner/adapters/skills-sh.js.map +1 -0
  66. package/dist/scanner/capability-map.d.ts +8 -0
  67. package/dist/scanner/capability-map.js +57 -0
  68. package/dist/scanner/capability-map.js.map +1 -0
  69. package/dist/scanner/discovery.d.ts +31 -0
  70. package/dist/scanner/discovery.js +320 -0
  71. package/dist/scanner/discovery.js.map +1 -0
  72. package/dist/scanner/filesystem-crawler.d.ts +32 -0
  73. package/dist/scanner/filesystem-crawler.js +210 -0
  74. package/dist/scanner/filesystem-crawler.js.map +1 -0
  75. package/dist/scanner/index.d.ts +8 -0
  76. package/dist/scanner/index.js +120 -0
  77. package/dist/scanner/index.js.map +1 -0
  78. package/dist/scanner/multi-project.d.ts +31 -0
  79. package/dist/scanner/multi-project.js +227 -0
  80. package/dist/scanner/multi-project.js.map +1 -0
  81. package/dist/scanner/parallel.d.ts +4 -0
  82. package/dist/scanner/parallel.js +41 -0
  83. package/dist/scanner/parallel.js.map +1 -0
  84. package/dist/scanner/parsing.d.ts +9 -0
  85. package/dist/scanner/parsing.js +135 -0
  86. package/dist/scanner/parsing.js.map +1 -0
  87. package/dist/scanner/paths.d.ts +8 -0
  88. package/dist/scanner/paths.js +39 -0
  89. package/dist/scanner/paths.js.map +1 -0
  90. package/dist/scanner/preview.d.ts +12 -0
  91. package/dist/scanner/preview.js +29 -0
  92. package/dist/scanner/preview.js.map +1 -0
  93. package/dist/scanner/project-discovery.d.ts +11 -0
  94. package/dist/scanner/project-discovery.js +35 -0
  95. package/dist/scanner/project-discovery.js.map +1 -0
  96. package/dist/scanner/ripgrep.d.ts +11 -0
  97. package/dist/scanner/ripgrep.js +61 -0
  98. package/dist/scanner/ripgrep.js.map +1 -0
  99. package/dist/scanner/safety.d.ts +37 -0
  100. package/dist/scanner/safety.js +330 -0
  101. package/dist/scanner/safety.js.map +1 -0
  102. package/dist/scanner/skill-naming.d.ts +5 -0
  103. package/dist/scanner/skill-naming.js +53 -0
  104. package/dist/scanner/skill-naming.js.map +1 -0
  105. package/dist/scanner/watcher.d.ts +15 -0
  106. package/dist/scanner/watcher.js +71 -0
  107. package/dist/scanner/watcher.js.map +1 -0
  108. package/dist/tui/App.d.ts +33 -0
  109. package/dist/tui/App.js +201 -0
  110. package/dist/tui/App.js.map +1 -0
  111. package/dist/tui/components/Breadcrumb.d.ts +10 -0
  112. package/dist/tui/components/Breadcrumb.js +11 -0
  113. package/dist/tui/components/Breadcrumb.js.map +1 -0
  114. package/dist/tui/components/DisclosureRow.d.ts +17 -0
  115. package/dist/tui/components/DisclosureRow.js +13 -0
  116. package/dist/tui/components/DisclosureRow.js.map +1 -0
  117. package/dist/tui/components/DotLeaderRow.d.ts +17 -0
  118. package/dist/tui/components/DotLeaderRow.js +34 -0
  119. package/dist/tui/components/DotLeaderRow.js.map +1 -0
  120. package/dist/tui/components/EmptyStateWhisper.d.ts +5 -0
  121. package/dist/tui/components/EmptyStateWhisper.js +6 -0
  122. package/dist/tui/components/EmptyStateWhisper.js.map +1 -0
  123. package/dist/tui/components/Frame.d.ts +15 -0
  124. package/dist/tui/components/Frame.js +21 -0
  125. package/dist/tui/components/Frame.js.map +1 -0
  126. package/dist/tui/components/IdleWhisper.d.ts +11 -0
  127. package/dist/tui/components/IdleWhisper.js +12 -0
  128. package/dist/tui/components/IdleWhisper.js.map +1 -0
  129. package/dist/tui/components/KeyHint.d.ts +13 -0
  130. package/dist/tui/components/KeyHint.js +12 -0
  131. package/dist/tui/components/KeyHint.js.map +1 -0
  132. package/dist/tui/components/LoadingSplash.d.ts +12 -0
  133. package/dist/tui/components/LoadingSplash.js +55 -0
  134. package/dist/tui/components/LoadingSplash.js.map +1 -0
  135. package/dist/tui/components/ProgressBar.d.ts +16 -0
  136. package/dist/tui/components/ProgressBar.js +24 -0
  137. package/dist/tui/components/ProgressBar.js.map +1 -0
  138. package/dist/tui/components/SearchBox.d.ts +5 -0
  139. package/dist/tui/components/SearchBox.js +6 -0
  140. package/dist/tui/components/SearchBox.js.map +1 -0
  141. package/dist/tui/components/SectionHeader.d.ts +12 -0
  142. package/dist/tui/components/SectionHeader.js +14 -0
  143. package/dist/tui/components/SectionHeader.js.map +1 -0
  144. package/dist/tui/components/SkillViewport.d.ts +8 -0
  145. package/dist/tui/components/SkillViewport.js +42 -0
  146. package/dist/tui/components/SkillViewport.js.map +1 -0
  147. package/dist/tui/components/Spinner.d.ts +11 -0
  148. package/dist/tui/components/Spinner.js +13 -0
  149. package/dist/tui/components/Spinner.js.map +1 -0
  150. package/dist/tui/components/StatusPill.d.ts +13 -0
  151. package/dist/tui/components/StatusPill.js +15 -0
  152. package/dist/tui/components/StatusPill.js.map +1 -0
  153. package/dist/tui/components/TabBar.d.ts +20 -0
  154. package/dist/tui/components/TabBar.js +26 -0
  155. package/dist/tui/components/TabBar.js.map +1 -0
  156. package/dist/tui/components/TextInput.d.ts +13 -0
  157. package/dist/tui/components/TextInput.js +34 -0
  158. package/dist/tui/components/TextInput.js.map +1 -0
  159. package/dist/tui/hooks/use-idle-whisper.d.ts +17 -0
  160. package/dist/tui/hooks/use-idle-whisper.js +66 -0
  161. package/dist/tui/hooks/use-idle-whisper.js.map +1 -0
  162. package/dist/tui/hooks/use-rotating-message.d.ts +20 -0
  163. package/dist/tui/hooks/use-rotating-message.js +34 -0
  164. package/dist/tui/hooks/use-rotating-message.js.map +1 -0
  165. package/dist/tui/input/use-keys.d.ts +16 -0
  166. package/dist/tui/input/use-keys.js +32 -0
  167. package/dist/tui/input/use-keys.js.map +1 -0
  168. package/dist/tui/messages.d.ts +18 -0
  169. package/dist/tui/messages.js +59 -0
  170. package/dist/tui/messages.js.map +1 -0
  171. package/dist/tui/render.d.ts +12 -0
  172. package/dist/tui/render.js +112 -0
  173. package/dist/tui/render.js.map +1 -0
  174. package/dist/tui/screens/AccessTab.d.ts +6 -0
  175. package/dist/tui/screens/AccessTab.js +26 -0
  176. package/dist/tui/screens/AccessTab.js.map +1 -0
  177. package/dist/tui/screens/DoctorTab.d.ts +6 -0
  178. package/dist/tui/screens/DoctorTab.js +24 -0
  179. package/dist/tui/screens/DoctorTab.js.map +1 -0
  180. package/dist/tui/screens/FirstRunScan.d.ts +11 -0
  181. package/dist/tui/screens/FirstRunScan.js +128 -0
  182. package/dist/tui/screens/FirstRunScan.js.map +1 -0
  183. package/dist/tui/screens/McpsTab.d.ts +6 -0
  184. package/dist/tui/screens/McpsTab.js +30 -0
  185. package/dist/tui/screens/McpsTab.js.map +1 -0
  186. package/dist/tui/screens/Overview.d.ts +6 -0
  187. package/dist/tui/screens/Overview.js +75 -0
  188. package/dist/tui/screens/Overview.js.map +1 -0
  189. package/dist/tui/screens/ProjectDrillIn.d.ts +10 -0
  190. package/dist/tui/screens/ProjectDrillIn.js +16 -0
  191. package/dist/tui/screens/ProjectDrillIn.js.map +1 -0
  192. package/dist/tui/screens/Settings.d.ts +8 -0
  193. package/dist/tui/screens/Settings.js +71 -0
  194. package/dist/tui/screens/Settings.js.map +1 -0
  195. package/dist/tui/screens/ToolTab.d.ts +9 -0
  196. package/dist/tui/screens/ToolTab.js +38 -0
  197. package/dist/tui/screens/ToolTab.js.map +1 -0
  198. package/dist/tui/screens/UserScopeDrillIn.d.ts +13 -0
  199. package/dist/tui/screens/UserScopeDrillIn.js +15 -0
  200. package/dist/tui/screens/UserScopeDrillIn.js.map +1 -0
  201. package/dist/tui/state/navigation.d.ts +1 -0
  202. package/dist/tui/state/navigation.js +11 -0
  203. package/dist/tui/state/navigation.js.map +1 -0
  204. package/dist/tui/state/settings-state.d.ts +22 -0
  205. package/dist/tui/state/settings-state.js +30 -0
  206. package/dist/tui/state/settings-state.js.map +1 -0
  207. package/dist/tui/state/tui-state.d.ts +57 -0
  208. package/dist/tui/state/tui-state.js +86 -0
  209. package/dist/tui/state/tui-state.js.map +1 -0
  210. package/dist/tui/theme/borders.d.ts +20 -0
  211. package/dist/tui/theme/borders.js +25 -0
  212. package/dist/tui/theme/borders.js.map +1 -0
  213. package/dist/tui/theme/colors.d.ts +14 -0
  214. package/dist/tui/theme/colors.js +18 -0
  215. package/dist/tui/theme/colors.js.map +1 -0
  216. package/dist/tui/theme/icons.d.ts +30 -0
  217. package/dist/tui/theme/icons.js +51 -0
  218. package/dist/tui/theme/icons.js.map +1 -0
  219. package/dist/tui/util/doctor-grouping.d.ts +27 -0
  220. package/dist/tui/util/doctor-grouping.js +67 -0
  221. package/dist/tui/util/doctor-grouping.js.map +1 -0
  222. package/dist/tui/util/finding-grouping.d.ts +24 -0
  223. package/dist/tui/util/finding-grouping.js +43 -0
  224. package/dist/tui/util/finding-grouping.js.map +1 -0
  225. package/dist/tui/util/mcp-grouping.d.ts +27 -0
  226. package/dist/tui/util/mcp-grouping.js +96 -0
  227. package/dist/tui/util/mcp-grouping.js.map +1 -0
  228. package/dist/tui/util/scan-history.d.ts +15 -0
  229. package/dist/tui/util/scan-history.js +43 -0
  230. package/dist/tui/util/scan-history.js.map +1 -0
  231. package/dist/tui/util/skill-filter.d.ts +2 -0
  232. package/dist/tui/util/skill-filter.js +7 -0
  233. package/dist/tui/util/skill-filter.js.map +1 -0
  234. package/dist/tui/util/skill-grouping.d.ts +3 -0
  235. package/dist/tui/util/skill-grouping.js +31 -0
  236. package/dist/tui/util/skill-grouping.js.map +1 -0
  237. package/dist/types.d.ts +151 -0
  238. package/dist/types.js +143 -0
  239. package/dist/types.js.map +1 -0
  240. package/dist/utils/errors.d.ts +1 -0
  241. package/dist/utils/errors.js +7 -0
  242. package/dist/utils/errors.js.map +1 -0
  243. package/dist/utils/format-access.d.ts +3 -0
  244. package/dist/utils/format-access.js +94 -0
  245. package/dist/utils/format-access.js.map +1 -0
  246. package/dist/utils/format-caps.d.ts +3 -0
  247. package/dist/utils/format-caps.js +139 -0
  248. package/dist/utils/format-caps.js.map +1 -0
  249. package/dist/utils/format-doctor.d.ts +3 -0
  250. package/dist/utils/format-doctor.js +105 -0
  251. package/dist/utils/format-doctor.js.map +1 -0
  252. package/dist/utils/format-list.d.ts +7 -0
  253. package/dist/utils/format-list.js +112 -0
  254. package/dist/utils/format-list.js.map +1 -0
  255. package/dist/utils/format-mcp.d.ts +3 -0
  256. package/dist/utils/format-mcp.js +130 -0
  257. package/dist/utils/format-mcp.js.map +1 -0
  258. package/dist/utils/format-multi-project.d.ts +3 -0
  259. package/dist/utils/format-multi-project.js +100 -0
  260. package/dist/utils/format-multi-project.js.map +1 -0
  261. package/dist/utils/format-show.d.ts +6 -0
  262. package/dist/utils/format-show.js +143 -0
  263. package/dist/utils/format-show.js.map +1 -0
  264. package/dist/utils/format.d.ts +3 -0
  265. package/dist/utils/format.js +53 -0
  266. package/dist/utils/format.js.map +1 -0
  267. package/dist/utils/paths.d.ts +1 -0
  268. package/dist/utils/paths.js +10 -0
  269. package/dist/utils/paths.js.map +1 -0
  270. package/package.json +61 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Settings.js","sourceRoot":"","sources":["../../../src/tui/screens/Settings.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { MultiProjectScanResult, ToolId } from "../../types.js";
3
+ import type { TuiAction } from "../state/tui-state.js";
4
+ export interface ToolTabProps {
5
+ toolId: ToolId;
6
+ result: MultiProjectScanResult;
7
+ dispatch: React.Dispatch<TuiAction>;
8
+ }
9
+ export declare function ToolTab({ toolId, result, dispatch }: ToolTabProps): React.ReactElement;
@@ -0,0 +1,38 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { SectionHeader } from "../components/SectionHeader.js";
4
+ import { DotLeaderRow } from "../components/DotLeaderRow.js";
5
+ const ROW_WIDTH = 60;
6
+ export function ToolTab({ toolId, result, dispatch }) {
7
+ void dispatch;
8
+ const tool = result.userScope.tools.find((t) => t.id === toolId);
9
+ if (!tool || !tool.detected) {
10
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(SectionHeader, { label: toolId.toUpperCase() }), _jsx(Text, { children: "Not detected on this machine." })] }));
11
+ }
12
+ const projectsWithSkills = result.projects.filter((project) => {
13
+ const projectTool = project.scan.tools.find((t) => t.id === toolId);
14
+ return projectTool && projectTool.skills.length > 0;
15
+ });
16
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(SectionHeader, { label: toolId.toUpperCase() }), _jsx(Text, { children: formatSummary(tool, projectsWithSkills) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(SectionHeader, { label: "USER SCOPE" }), _jsx(Text, { dimColor: true, children: tool.detectedPaths.join(" · ") }), Object.entries(tool.stats)
17
+ .filter(([, count]) => typeof count === "number" && count > 0)
18
+ .map(([kind, count]) => (_jsx(DotLeaderRow, { label: kind, metadata: String(count), width: ROW_WIDTH }, kind)))] }), projectsWithSkills.length > 0 && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(SectionHeader, { label: "PROJECTS" }), projectsWithSkills.map((project) => (_jsx(DotLeaderRow, { label: project.displayPath, metadata: formatProjectMetadata(project, toolId), width: ROW_WIDTH }, project.projectPath)))] }))] }));
19
+ }
20
+ function formatSummary(tool, projectsWithSkills) {
21
+ const userSkills = tool.skills.length;
22
+ const projectConfigs = projectsWithSkills.length;
23
+ const userMcps = tool.stats.mcpServers;
24
+ const findings = tool.findings.length;
25
+ return `${userSkills} user skills · ${projectConfigs} project configs · ${userMcps} MCPs · ${findings} findings`;
26
+ }
27
+ function formatProjectMetadata(project, toolId) {
28
+ const projectTool = project.scan.tools.find((t) => t.id === toolId);
29
+ if (!projectTool)
30
+ return "0 skills";
31
+ const skillCount = projectTool.skills.length;
32
+ const mcpCount = projectTool.stats.mcpServers;
33
+ const parts = [`${skillCount} skills`];
34
+ if (mcpCount > 0)
35
+ parts.push(`${mcpCount} MCP${mcpCount === 1 ? "" : "s"}`);
36
+ return parts.join(" · ");
37
+ }
38
+ //# sourceMappingURL=ToolTab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolTab.js","sourceRoot":"","sources":["../../../src/tui/screens/ToolTab.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import type { MultiProjectScanResult, ToolId } from "../../types.js";
3
+ export interface UserScopeDrillInProps {
4
+ toolId: ToolId;
5
+ result: MultiProjectScanResult;
6
+ /** Cursor into the filtered, grouped skill list. */
7
+ cursor?: number;
8
+ /** When provided, filters skill names case-insensitively. */
9
+ searchQuery?: string;
10
+ /** When true, renders SearchBox above the skill list. */
11
+ searchOpen?: boolean;
12
+ }
13
+ export declare function UserScopeDrillIn({ toolId, result, cursor, searchQuery, searchOpen }: UserScopeDrillInProps): React.ReactElement;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Breadcrumb } from "../components/Breadcrumb.js";
4
+ import { SearchBox } from "../components/SearchBox.js";
5
+ import { SkillViewport } from "../components/SkillViewport.js";
6
+ import { filterSkillsByQuery } from "../util/skill-filter.js";
7
+ export function UserScopeDrillIn({ toolId, result, cursor = 0, searchQuery, searchOpen }) {
8
+ const tool = result.userScope.tools.find((t) => t.id === toolId);
9
+ const allSkills = tool?.skills ?? [];
10
+ const filtered = filterSkillsByQuery(allSkills, searchQuery);
11
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Breadcrumb, { parts: ["ankui", toolId, "user"] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { children: [toolId, " \u00B7 user scope"] }), tool && _jsx(Text, { dimColor: true, children: tool.detectedPaths.join(" · ") })] }), searchOpen && (_jsx(Box, { marginTop: 1, children: _jsx(SearchBox, { query: searchQuery ?? "" }) })), filtered.length === 0 ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: searchQuery && searchQuery.length > 0
12
+ ? "No skills match your filter."
13
+ : "No skills configured at user scope." }) })) : (_jsx(Box, { marginTop: 1, children: _jsx(SkillViewport, { skills: filtered, cursor: cursor }) }))] }));
14
+ }
15
+ //# sourceMappingURL=UserScopeDrillIn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserScopeDrillIn.js","sourceRoot":"","sources":["../../../src/tui/screens/UserScopeDrillIn.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAGhC,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAa9D,MAAM,UAAU,gBAAgB,CAAC,EAC/B,MAAM,EACN,MAAM,EACN,MAAM,GAAG,CAAC,EACV,WAAW,EACX,UAAU,EACY;IACtB,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC;IACrC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAE7D,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,UAAU,IAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,GAAI,EAEhD,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,aACvC,MAAC,IAAI,eAAE,MAAM,0BAAqB,EACjC,IAAI,IAAI,KAAC,IAAI,IAAC,QAAQ,kBAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAQ,IAC3D,EAEL,UAAU,IAAI,CACb,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,SAAS,IAAC,KAAK,EAAE,WAAW,IAAI,EAAE,GAAI,GACnC,CACP,EAEA,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACvB,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,IAAC,QAAQ,kBACX,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;wBACpC,CAAC,CAAC,8BAA8B;wBAChC,CAAC,CAAC,qCAAqC,GACpC,GACH,CACP,CAAC,CAAC,CAAC,CACF,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,aAAa,IAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAI,GAC/C,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function cycleTabId(current: string, direction: "next" | "prev", tabs: ReadonlyArray<string>): string;
@@ -0,0 +1,11 @@
1
+ export function cycleTabId(current, direction, tabs) {
2
+ if (tabs.length === 0)
3
+ return current;
4
+ const idx = tabs.indexOf(current);
5
+ if (idx === -1)
6
+ return tabs[0];
7
+ const step = direction === "next" ? 1 : -1;
8
+ const nextIdx = (idx + step + tabs.length) % tabs.length;
9
+ return tabs[nextIdx];
10
+ }
11
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../src/tui/state/navigation.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,SAA0B,EAC1B,IAA2B;IAE3B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,GAAG,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACzD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,22 @@
1
+ export interface SettingsState {
2
+ cursor: number;
3
+ addMode: boolean;
4
+ addBuffer: string;
5
+ }
6
+ export type SettingsAction = {
7
+ type: "moveCursor";
8
+ direction: "up" | "down";
9
+ rootCount: number;
10
+ } | {
11
+ type: "enterAddMode";
12
+ } | {
13
+ type: "setAddBuffer";
14
+ value: string;
15
+ } | {
16
+ type: "cancelAddMode";
17
+ } | {
18
+ type: "removeAtCursor";
19
+ newRootCount: number;
20
+ };
21
+ export declare const INITIAL_SETTINGS_STATE: SettingsState;
22
+ export declare function settingsReducer(state: SettingsState, action: SettingsAction): SettingsState;
@@ -0,0 +1,30 @@
1
+ export const INITIAL_SETTINGS_STATE = {
2
+ cursor: 0,
3
+ addMode: false,
4
+ addBuffer: ""
5
+ };
6
+ export function settingsReducer(state, action) {
7
+ switch (action.type) {
8
+ case "moveCursor": {
9
+ if (action.rootCount === 0)
10
+ return { ...state, cursor: 0 };
11
+ const max = action.rootCount - 1;
12
+ const step = action.direction === "down" ? 1 : -1;
13
+ const next = Math.max(0, Math.min(max, state.cursor + step));
14
+ return { ...state, cursor: next };
15
+ }
16
+ case "enterAddMode":
17
+ return { ...state, addMode: true, addBuffer: "" };
18
+ case "setAddBuffer":
19
+ return { ...state, addBuffer: action.value };
20
+ case "cancelAddMode":
21
+ return { ...state, addMode: false, addBuffer: "" };
22
+ case "removeAtCursor": {
23
+ const max = Math.max(0, action.newRootCount - 1);
24
+ return { ...state, cursor: Math.min(state.cursor, max) };
25
+ }
26
+ default:
27
+ return state;
28
+ }
29
+ }
30
+ //# sourceMappingURL=settings-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-state.js","sourceRoot":"","sources":["../../../src/tui/state/settings-state.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,EAAE;CACd,CAAC;AAEF,MAAM,UAAU,eAAe,CAC7B,KAAoB,EACpB,MAAsB;IAEtB,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,IAAI,MAAM,CAAC,SAAS,KAAK,CAAC;gBAAE,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;YAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;YAC7D,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACpC,CAAC;QACD,KAAK,cAAc;YACjB,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACpD,KAAK,cAAc;YACjB,OAAO,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;QAC/C,KAAK,eAAe;YAClB,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACrD,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;YACjD,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;QAC3D,CAAC;QACD;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -0,0 +1,57 @@
1
+ import type { MultiProjectScanResult, ToolId } from "../../types.js";
2
+ export type TabId = "overview" | ToolId | "mcps" | "access" | "doctor" | "settings";
3
+ export type DrillFrame = {
4
+ kind: "userScope";
5
+ toolId: ToolId;
6
+ } | {
7
+ kind: "project";
8
+ toolId: ToolId;
9
+ projectPath: string;
10
+ };
11
+ export interface TuiState {
12
+ activeTab: TabId;
13
+ drillStack: DrillFrame[];
14
+ /**
15
+ * The current scan result. Phase 10 (watch mode) replaces this in-place on
16
+ * filesystem change events; Settings (Phase 8f) reads `result.devRoots` and
17
+ * `result.scannedAt` directly.
18
+ */
19
+ result: MultiProjectScanResult;
20
+ /** Phase 8g: true while the `/`-key search overlay is open. */
21
+ searchOpen: boolean;
22
+ /** Phase 8g: current incremental search query (lowercased compare done by consumers). */
23
+ searchQuery: string;
24
+ /** Cursor for bounded drill-in skill lists. */
25
+ listCursor: number;
26
+ }
27
+ export type TuiAction = {
28
+ type: "setTab";
29
+ id: TabId;
30
+ } | {
31
+ type: "drillIn";
32
+ frame: DrillFrame;
33
+ } | {
34
+ type: "drillOut";
35
+ } | {
36
+ type: "cycleTab";
37
+ direction: "next" | "prev";
38
+ tabs: ReadonlyArray<TabId>;
39
+ } | {
40
+ type: "setResult";
41
+ result: MultiProjectScanResult;
42
+ } | {
43
+ type: "reset";
44
+ } | {
45
+ type: "searchOpen";
46
+ } | {
47
+ type: "searchClose";
48
+ } | {
49
+ type: "searchSetQuery";
50
+ query: string;
51
+ } | {
52
+ type: "listMove";
53
+ direction: "up" | "down";
54
+ max: number;
55
+ };
56
+ export declare function createInitialState(result: MultiProjectScanResult): TuiState;
57
+ export declare function tuiReducer(state: TuiState, action: TuiAction): TuiState;
@@ -0,0 +1,86 @@
1
+ import { cycleTabId } from "./navigation.js";
2
+ export function createInitialState(result) {
3
+ return {
4
+ activeTab: "overview",
5
+ drillStack: [],
6
+ result,
7
+ searchOpen: false,
8
+ searchQuery: "",
9
+ listCursor: 0
10
+ };
11
+ }
12
+ export function tuiReducer(state, action) {
13
+ switch (action.type) {
14
+ case "setTab":
15
+ return {
16
+ ...state,
17
+ activeTab: action.id,
18
+ drillStack: [],
19
+ searchOpen: false,
20
+ searchQuery: "",
21
+ listCursor: 0
22
+ };
23
+ case "drillIn":
24
+ return {
25
+ ...state,
26
+ drillStack: [...state.drillStack, action.frame],
27
+ listCursor: 0
28
+ };
29
+ case "drillOut":
30
+ if (state.drillStack.length === 0)
31
+ return state;
32
+ return {
33
+ ...state,
34
+ drillStack: state.drillStack.slice(0, -1),
35
+ listCursor: 0
36
+ };
37
+ case "cycleTab": {
38
+ const nextId = cycleTabId(state.activeTab, action.direction, action.tabs);
39
+ return {
40
+ ...state,
41
+ activeTab: nextId,
42
+ drillStack: [],
43
+ searchOpen: false,
44
+ searchQuery: "",
45
+ listCursor: 0
46
+ };
47
+ }
48
+ case "setResult": {
49
+ const trimmed = state.drillStack.filter((frame) => {
50
+ if (frame.kind === "userScope")
51
+ return true;
52
+ return action.result.projects.some((p) => p.projectPath === frame.projectPath);
53
+ });
54
+ return {
55
+ ...state,
56
+ result: action.result,
57
+ drillStack: trimmed,
58
+ listCursor: clampCursor(state.listCursor, Number.POSITIVE_INFINITY)
59
+ };
60
+ }
61
+ case "reset":
62
+ return createInitialState(state.result);
63
+ case "searchOpen":
64
+ return { ...state, searchOpen: true, searchQuery: "", listCursor: 0 };
65
+ case "searchClose":
66
+ return { ...state, searchOpen: false, searchQuery: "", listCursor: 0 };
67
+ case "searchSetQuery":
68
+ return { ...state, searchQuery: action.query, listCursor: 0 };
69
+ case "listMove": {
70
+ const max = Math.max(0, action.max);
71
+ const step = action.direction === "down" ? 1 : -1;
72
+ return {
73
+ ...state,
74
+ listCursor: clampCursor(state.listCursor + step, max)
75
+ };
76
+ }
77
+ default:
78
+ return state;
79
+ }
80
+ }
81
+ function clampCursor(cursor, max) {
82
+ if (max <= 0)
83
+ return 0;
84
+ return Math.max(0, Math.min(max - 1, cursor));
85
+ }
86
+ //# sourceMappingURL=tui-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui-state.js","sourceRoot":"","sources":["../../../src/tui/state/tui-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Box-drawing characters. Heavy is used for the outer Frame; light is used
3
+ * for inner separators (section dividers, etc.).
4
+ */
5
+ export declare const HEAVY: {
6
+ readonly topLeft: "┏";
7
+ readonly topRight: "┓";
8
+ readonly bottomLeft: "┗";
9
+ readonly bottomRight: "┛";
10
+ readonly horizontal: "━";
11
+ readonly vertical: "┃";
12
+ };
13
+ export declare const LIGHT: {
14
+ readonly horizontal: "─";
15
+ readonly vertical: "│";
16
+ readonly teeLeft: "┠";
17
+ readonly teeRight: "┨";
18
+ };
19
+ /** Repeats a glyph N times. Pure helper. */
20
+ export declare function repeat(glyph: string, n: number): string;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Box-drawing characters. Heavy is used for the outer Frame; light is used
3
+ * for inner separators (section dividers, etc.).
4
+ */
5
+ export const HEAVY = {
6
+ topLeft: "┏",
7
+ topRight: "┓",
8
+ bottomLeft: "┗",
9
+ bottomRight: "┛",
10
+ horizontal: "━",
11
+ vertical: "┃"
12
+ };
13
+ export const LIGHT = {
14
+ horizontal: "─",
15
+ vertical: "│",
16
+ teeLeft: "┠",
17
+ teeRight: "┨"
18
+ };
19
+ /** Repeats a glyph N times. Pure helper. */
20
+ export function repeat(glyph, n) {
21
+ if (n <= 0)
22
+ return "";
23
+ return glyph.repeat(n);
24
+ }
25
+ //# sourceMappingURL=borders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"borders.js","sourceRoot":"","sources":["../../../src/tui/theme/borders.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,GAAG;IACf,WAAW,EAAE,GAAG;IAChB,UAAU,EAAE,GAAG;IACf,QAAQ,EAAE,GAAG;CACL,CAAC;AAEX,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,UAAU,EAAE,GAAG;IACf,QAAQ,EAAE,GAAG;IACb,OAAO,EAAE,GAAG;IACZ,QAAQ,EAAE,GAAG;CACL,CAAC;AAEX,4CAA4C;AAC5C,MAAM,UAAU,MAAM,CAAC,KAAa,EAAE,CAAS;IAC7C,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { AccessLevel } from "../../types.js";
2
+ /**
3
+ * The fixed palette the Archive Inspector aesthetic uses.
4
+ *
5
+ * `undefined` = use the terminal's default foreground color. This is the
6
+ * intentional value for "Limited" access — we don't tint normal rows.
7
+ */
8
+ export type Color = "cyan" | "red" | "white" | "gray" | undefined;
9
+ export declare const ACCENT: Color;
10
+ export declare const STATUS_BROAD: Color;
11
+ export declare const STATUS_MODERATE: Color;
12
+ export declare const STATUS_LIMITED: Color;
13
+ export declare const STATUS_UNKNOWN: Color;
14
+ export declare function colorForAccessLevel(level: AccessLevel): Color;
@@ -0,0 +1,18 @@
1
+ export const ACCENT = "cyan";
2
+ export const STATUS_BROAD = "red";
3
+ export const STATUS_MODERATE = "cyan";
4
+ export const STATUS_LIMITED = undefined;
5
+ export const STATUS_UNKNOWN = "gray";
6
+ export function colorForAccessLevel(level) {
7
+ switch (level) {
8
+ case "broad":
9
+ return STATUS_BROAD;
10
+ case "moderate":
11
+ return STATUS_MODERATE;
12
+ case "limited":
13
+ return STATUS_LIMITED;
14
+ case "unknown":
15
+ return STATUS_UNKNOWN;
16
+ }
17
+ }
18
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../src/tui/theme/colors.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,MAAM,GAAU,MAAM,CAAC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAU,KAAK,CAAC;AACzC,MAAM,CAAC,MAAM,eAAe,GAAU,MAAM,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAU,SAAS,CAAC;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAU,MAAM,CAAC;AAE5C,MAAM,UAAU,mBAAmB,CAAC,KAAkB;IACpD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,OAAO,YAAY,CAAC;QACtB,KAAK,UAAU;YACb,OAAO,eAAe,CAAC;QACzB,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC;QACxB,KAAK,SAAS;YACZ,OAAO,cAAc,CAAC;IAC1B,CAAC;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Glyphs that carry semantic meaning in the Archive Inspector aesthetic.
3
+ * Components import from here so changing a symbol happens in one place.
4
+ */
5
+ /** Disclosure markers. */
6
+ export declare const DISCLOSURE_OPEN = "\u25C6";
7
+ export declare const DISCLOSURE_CLOSED = "\u25C7";
8
+ /** Active-row prefix used by drill-in lists. */
9
+ export declare const ACTIVE_PREFIX = "\u25B6";
10
+ /** First-run splash logo glyph. */
11
+ export declare const SPLASH_DOT = "\u25CC";
12
+ /** Editorial slash for the breadcrumb (NOT ASCII /). */
13
+ export declare const BREADCRUMB_SLASH = "\u2571";
14
+ /** Status pill bullet. */
15
+ export declare const STATUS_DOT = "\u25CF";
16
+ /** Dot-leader filler. Used between name and metadata in DotLeaderRow. */
17
+ export declare const DOT_LEADER = "\u00B7";
18
+ /** Section underline glyph (light horizontal). */
19
+ export declare const SECTION_UNDERLINE = "\u2500";
20
+ /** Spinner: ten braille frames, rotated by parent at ~100ms cadence. */
21
+ export declare const SPINNER_FRAMES: readonly ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
22
+ export type SpinnerFrame = (typeof SPINNER_FRAMES)[number];
23
+ /**
24
+ * Progress bar characters. Index = number of eighth-cells filled (0..8).
25
+ * `PROGRESS_FULL` is the spec-mandated dominant glyph (▊ = 6/8).
26
+ * Sub-cell rendering: total eighths = floor(value * width * 8).
27
+ */
28
+ export declare const PROGRESS_EIGHTHS: readonly ["░", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"];
29
+ export declare const PROGRESS_EMPTY: "░";
30
+ export declare const PROGRESS_FULL: "▊";
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Glyphs that carry semantic meaning in the Archive Inspector aesthetic.
3
+ * Components import from here so changing a symbol happens in one place.
4
+ */
5
+ /** Disclosure markers. */
6
+ export const DISCLOSURE_OPEN = "◆"; // ◆
7
+ export const DISCLOSURE_CLOSED = "◇"; // ◇
8
+ /** Active-row prefix used by drill-in lists. */
9
+ export const ACTIVE_PREFIX = "▶"; // ▶
10
+ /** First-run splash logo glyph. */
11
+ export const SPLASH_DOT = "◌"; // ◌
12
+ /** Editorial slash for the breadcrumb (NOT ASCII /). */
13
+ export const BREADCRUMB_SLASH = "╱"; // ╱
14
+ /** Status pill bullet. */
15
+ export const STATUS_DOT = "●"; // ●
16
+ /** Dot-leader filler. Used between name and metadata in DotLeaderRow. */
17
+ export const DOT_LEADER = "·"; // ·
18
+ /** Section underline glyph (light horizontal). */
19
+ export const SECTION_UNDERLINE = "─"; // ─
20
+ /** Spinner: ten braille frames, rotated by parent at ~100ms cadence. */
21
+ export const SPINNER_FRAMES = [
22
+ "⠋", // ⠋
23
+ "⠙", // ⠙
24
+ "⠹", // ⠹
25
+ "⠸", // ⠸
26
+ "⠼", // ⠼
27
+ "⠴", // ⠴
28
+ "⠦", // ⠦
29
+ "⠧", // ⠧
30
+ "⠇", // ⠇
31
+ "⠏" // ⠏
32
+ ];
33
+ /**
34
+ * Progress bar characters. Index = number of eighth-cells filled (0..8).
35
+ * `PROGRESS_FULL` is the spec-mandated dominant glyph (▊ = 6/8).
36
+ * Sub-cell rendering: total eighths = floor(value * width * 8).
37
+ */
38
+ export const PROGRESS_EIGHTHS = [
39
+ "░", // ░ 0/8 — empty
40
+ "▏", // ▏ 1/8
41
+ "▎", // ▎ 2/8
42
+ "▍", // ▍ 3/8
43
+ "▌", // ▌ 4/8
44
+ "▋", // ▋ 5/8
45
+ "▊", // ▊ 6/8
46
+ "▉", // ▉ 7/8
47
+ "█" // █ 8/8
48
+ ];
49
+ export const PROGRESS_EMPTY = PROGRESS_EIGHTHS[0]; // "░"
50
+ export const PROGRESS_FULL = PROGRESS_EIGHTHS[6]; // "▊" — spec-mandated dominant glyph
51
+ //# sourceMappingURL=icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../../src/tui/theme/icons.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,0BAA0B;AAC1B,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC,CAAC,IAAI;AACxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,IAAI;AAE1C,gDAAgD;AAChD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC,CAAC,IAAI;AAEtC,mCAAmC;AACnC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,IAAI;AAEnC,wDAAwD;AACxD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC,CAAC,IAAI;AAEzC,0BAA0B;AAC1B,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,IAAI;AAEnC,yEAAyE;AACzE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC,CAAC,IAAI;AAEnC,kDAAkD;AAClD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,IAAI;AAE1C,wEAAwE;AACxE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,GAAG,CAAE,IAAI;CACD,CAAC;AAIX;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,gBAAgB;IACrB,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,QAAQ;IACb,GAAG,CAAE,QAAQ;CACL,CAAC;AAEX,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,qCAAqC"}
@@ -0,0 +1,27 @@
1
+ import type { MultiProjectScanResult, ToolId, Warning } from "../../types.js";
2
+ export interface DoctorToolRow {
3
+ toolId: ToolId;
4
+ name: string;
5
+ detected: boolean;
6
+ /** Detected paths outside `cwd`, rendered home-relative (`~/.claude`). */
7
+ userPaths: ReadonlyArray<string>;
8
+ /** Detected paths inside `cwd`, rendered cwd-relative (`./.claude`, `.`). */
9
+ projectPaths: ReadonlyArray<string>;
10
+ }
11
+ export interface WarningGroup {
12
+ reason: Warning["reason"];
13
+ warnings: ReadonlyArray<Warning>;
14
+ }
15
+ /**
16
+ * One row per tool — order matches `TOOL_DEFINITIONS`. Detected paths are
17
+ * split into "user" (anything outside `cwd`, rendered home-relative) and
18
+ * "project" (anything inside `cwd`, rendered cwd-relative as `./…` or `.`).
19
+ *
20
+ * Mirrors `formatDoctor`'s `classifyAndRelativize`.
21
+ */
22
+ export declare function buildDoctorBoard(result: MultiProjectScanResult): DoctorToolRow[];
23
+ /**
24
+ * Groups `result.warnings` (multi-project orchestration warnings) by reason.
25
+ * Sorted by count desc, then reason asc — matches `formatDoctor`'s ordering.
26
+ */
27
+ export declare function groupWarningsByReason(result: MultiProjectScanResult): WarningGroup[];
@@ -0,0 +1,67 @@
1
+ import { relativizeHome } from "../../utils/paths.js";
2
+ /**
3
+ * One row per tool — order matches `TOOL_DEFINITIONS`. Detected paths are
4
+ * split into "user" (anything outside `cwd`, rendered home-relative) and
5
+ * "project" (anything inside `cwd`, rendered cwd-relative as `./…` or `.`).
6
+ *
7
+ * Mirrors `formatDoctor`'s `classifyAndRelativize`.
8
+ */
9
+ export function buildDoctorBoard(result) {
10
+ const { cwd, homeDir } = result;
11
+ return result.userScope.tools.map((tool) => classifyTool(tool, cwd, homeDir));
12
+ }
13
+ function classifyTool(tool, cwd, homeDir) {
14
+ const userPaths = [];
15
+ const projectPaths = [];
16
+ if (tool.detected) {
17
+ for (const filePath of tool.detectedPaths) {
18
+ const classified = classifyAndRelativize(filePath, cwd, homeDir);
19
+ if (classified.scope === "project") {
20
+ projectPaths.push(classified.display);
21
+ }
22
+ else {
23
+ userPaths.push(classified.display);
24
+ }
25
+ }
26
+ }
27
+ return {
28
+ toolId: tool.id,
29
+ name: tool.name,
30
+ detected: tool.detected,
31
+ userPaths,
32
+ projectPaths
33
+ };
34
+ }
35
+ function classifyAndRelativize(filePath, cwd, homeDir) {
36
+ if (cwd && (filePath === cwd || filePath.startsWith(cwd + "/"))) {
37
+ const rel = filePath.slice(cwd.length);
38
+ return { scope: "project", display: rel.length === 0 ? "." : `.${rel}` };
39
+ }
40
+ return { scope: "user", display: relativizeHome(filePath, homeDir) };
41
+ }
42
+ /**
43
+ * Groups `result.warnings` (multi-project orchestration warnings) by reason.
44
+ * Sorted by count desc, then reason asc — matches `formatDoctor`'s ordering.
45
+ */
46
+ export function groupWarningsByReason(result) {
47
+ if (result.warnings.length === 0)
48
+ return [];
49
+ const map = new Map();
50
+ for (const warning of result.warnings) {
51
+ const list = map.get(warning.reason) ?? [];
52
+ list.push(warning);
53
+ map.set(warning.reason, list);
54
+ }
55
+ const groups = [];
56
+ for (const [reason, warnings] of map.entries()) {
57
+ groups.push({ reason, warnings });
58
+ }
59
+ groups.sort((a, b) => {
60
+ if (a.warnings.length !== b.warnings.length) {
61
+ return b.warnings.length - a.warnings.length;
62
+ }
63
+ return a.reason.localeCompare(b.reason);
64
+ });
65
+ return groups;
66
+ }
67
+ //# sourceMappingURL=doctor-grouping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-grouping.js","sourceRoot":"","sources":["../../../src/tui/util/doctor-grouping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Finding, MultiProjectScanResult } from "../../types.js";
2
+ export type FindingCategory = Finding["category"];
3
+ export interface FindingCategorySpec {
4
+ category: FindingCategory;
5
+ label: string;
6
+ }
7
+ /**
8
+ * Priority order for cross-tool access findings — matches
9
+ * `src/utils/format-access.ts`'s `CATEGORY_ORDER`. Categories not present
10
+ * here (`skipped_sensitive_file`, `parse_issue`) are surfaced in Doctor,
11
+ * not Access.
12
+ */
13
+ export declare const FINDING_CATEGORY_ORDER: ReadonlyArray<FindingCategorySpec>;
14
+ export interface FindingSection {
15
+ category: FindingCategory;
16
+ label: string;
17
+ findings: ReadonlyArray<Finding>;
18
+ }
19
+ /**
20
+ * Aggregates findings from user-scope + every project. Groups by category
21
+ * in priority order. Returns only sections that have at least one finding.
22
+ * Within a section, findings are sorted by title (case-insensitive).
23
+ */
24
+ export declare function aggregateFindings(result: MultiProjectScanResult): FindingSection[];