redmine-context 1.0.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 (229) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +449 -0
  3. package/dist/bundle/index.d.ts +5 -0
  4. package/dist/bundle/index.js +5 -0
  5. package/dist/bundle/json.d.ts +90 -0
  6. package/dist/bundle/json.js +266 -0
  7. package/dist/bundle/markdown.d.ts +75 -0
  8. package/dist/bundle/markdown.js +294 -0
  9. package/dist/bundle/search-list.d.ts +43 -0
  10. package/dist/bundle/search-list.js +53 -0
  11. package/dist/bundle/stable-stringify.d.ts +26 -0
  12. package/dist/bundle/stable-stringify.js +50 -0
  13. package/dist/cache/contract.d.ts +157 -0
  14. package/dist/cache/contract.js +0 -0
  15. package/dist/cache/disk-index.d.ts +82 -0
  16. package/dist/cache/disk-index.js +220 -0
  17. package/dist/cache/disk.d.ts +133 -0
  18. package/dist/cache/disk.js +313 -0
  19. package/dist/cache/gc.d.ts +78 -0
  20. package/dist/cache/gc.js +123 -0
  21. package/dist/cache/get-or-compute.d.ts +36 -0
  22. package/dist/cache/get-or-compute.js +52 -0
  23. package/dist/cache/index.d.ts +9 -0
  24. package/dist/cache/index.js +8 -0
  25. package/dist/cache/keys.d.ts +76 -0
  26. package/dist/cache/keys.js +78 -0
  27. package/dist/cache/memory.d.ts +48 -0
  28. package/dist/cache/memory.js +110 -0
  29. package/dist/cache-first.d.ts +127 -0
  30. package/dist/cache-first.js +227 -0
  31. package/dist/client/errors.d.ts +33 -0
  32. package/dist/client/errors.js +49 -0
  33. package/dist/client/http.d.ts +110 -0
  34. package/dist/client/http.js +207 -0
  35. package/dist/client/index.d.ts +5 -0
  36. package/dist/client/index.js +5 -0
  37. package/dist/client/issues.d.ts +71 -0
  38. package/dist/client/issues.js +100 -0
  39. package/dist/client/search.d.ts +58 -0
  40. package/dist/client/search.js +81 -0
  41. package/dist/config/credentials.d.ts +247 -0
  42. package/dist/config/credentials.js +427 -0
  43. package/dist/config/doctor.d.ts +123 -0
  44. package/dist/config/doctor.js +260 -0
  45. package/dist/config/index.d.ts +6 -0
  46. package/dist/config/index.js +6 -0
  47. package/dist/config/keyring.d.ts +96 -0
  48. package/dist/config/keyring.js +158 -0
  49. package/dist/config/login.d.ts +97 -0
  50. package/dist/config/login.js +189 -0
  51. package/dist/config/settings.d.ts +94 -0
  52. package/dist/config/settings.js +140 -0
  53. package/dist/contract.d.ts +173 -0
  54. package/dist/contract.js +27 -0
  55. package/dist/core.d.ts +1 -0
  56. package/dist/core.js +8 -0
  57. package/dist/extract/audio-extractor.d.ts +105 -0
  58. package/dist/extract/audio-extractor.js +156 -0
  59. package/dist/extract/audio.d.ts +126 -0
  60. package/dist/extract/audio.js +184 -0
  61. package/dist/extract/dispatcher.d.ts +132 -0
  62. package/dist/extract/dispatcher.js +115 -0
  63. package/dist/extract/download.d.ts +111 -0
  64. package/dist/extract/download.js +261 -0
  65. package/dist/extract/duration.d.ts +106 -0
  66. package/dist/extract/duration.js +148 -0
  67. package/dist/extract/ffmpeg.d.ts +56 -0
  68. package/dist/extract/ffmpeg.js +95 -0
  69. package/dist/extract/gguf.d.ts +137 -0
  70. package/dist/extract/gguf.js +215 -0
  71. package/dist/extract/index.d.ts +19 -0
  72. package/dist/extract/index.js +19 -0
  73. package/dist/extract/magic.d.ts +80 -0
  74. package/dist/extract/magic.js +282 -0
  75. package/dist/extract/ooxml.d.ts +131 -0
  76. package/dist/extract/ooxml.js +336 -0
  77. package/dist/extract/pdf.d.ts +147 -0
  78. package/dist/extract/pdf.js +322 -0
  79. package/dist/extract/queue.d.ts +167 -0
  80. package/dist/extract/queue.js +217 -0
  81. package/dist/extract/subprocess.d.ts +145 -0
  82. package/dist/extract/subprocess.js +181 -0
  83. package/dist/extract/tesseract.d.ts +153 -0
  84. package/dist/extract/tesseract.js +321 -0
  85. package/dist/extract/video-extractor.d.ts +84 -0
  86. package/dist/extract/video-extractor.js +89 -0
  87. package/dist/extract/video.d.ts +198 -0
  88. package/dist/extract/video.js +418 -0
  89. package/dist/extract/which.d.ts +63 -0
  90. package/dist/extract/which.js +72 -0
  91. package/dist/extract/whisper-extract.d.ts +211 -0
  92. package/dist/extract/whisper-extract.js +323 -0
  93. package/dist/extract/whisper.d.ts +50 -0
  94. package/dist/extract/whisper.js +67 -0
  95. package/dist/extract/zip.d.ts +50 -0
  96. package/dist/extract/zip.js +165 -0
  97. package/dist/extract-issue-attachments.d.ts +82 -0
  98. package/dist/extract-issue-attachments.js +156 -0
  99. package/dist/fetch-attachment-text.d.ts +113 -0
  100. package/dist/fetch-attachment-text.js +155 -0
  101. package/dist/fetch-issue-bundle.d.ts +81 -0
  102. package/dist/fetch-issue-bundle.js +93 -0
  103. package/dist/fetch-issue-search.d.ts +74 -0
  104. package/dist/fetch-issue-search.js +120 -0
  105. package/dist/index.d.ts +21 -0
  106. package/dist/index.js +67 -0
  107. package/dist/normalize/collections.d.ts +52 -0
  108. package/dist/normalize/collections.js +170 -0
  109. package/dist/normalize/helpers.d.ts +35 -0
  110. package/dist/normalize/helpers.js +59 -0
  111. package/dist/normalize/index.d.ts +2 -0
  112. package/dist/normalize/index.js +2 -0
  113. package/dist/normalize/issue.d.ts +34 -0
  114. package/dist/normalize/issue.js +154 -0
  115. package/dist/surfaces/cli/commands.d.ts +61 -0
  116. package/dist/surfaces/cli/commands.js +262 -0
  117. package/dist/surfaces/cli/main.d.ts +32 -0
  118. package/dist/surfaces/cli/main.js +210 -0
  119. package/dist/surfaces/cli/prompts.d.ts +66 -0
  120. package/dist/surfaces/cli/prompts.js +147 -0
  121. package/dist/surfaces/cli/tty.d.ts +27 -0
  122. package/dist/surfaces/cli/tty.js +35 -0
  123. package/dist/surfaces/cli/types.d.ts +39 -0
  124. package/dist/surfaces/cli/types.js +7 -0
  125. package/dist/surfaces/mcp/server.d.ts +171 -0
  126. package/dist/surfaces/mcp/server.js +427 -0
  127. package/dist/surfaces/tui/app.d.ts +55 -0
  128. package/dist/surfaces/tui/app.js +180 -0
  129. package/dist/surfaces/tui/attachment-status.d.ts +79 -0
  130. package/dist/surfaces/tui/attachment-status.js +113 -0
  131. package/dist/surfaces/tui/components/breadcrumb.d.ts +7 -0
  132. package/dist/surfaces/tui/components/breadcrumb.js +31 -0
  133. package/dist/surfaces/tui/components/gradient-text.d.ts +23 -0
  134. package/dist/surfaces/tui/components/gradient-text.js +75 -0
  135. package/dist/surfaces/tui/components/scroll-view.d.ts +25 -0
  136. package/dist/surfaces/tui/components/scroll-view.js +77 -0
  137. package/dist/surfaces/tui/components/spinner.d.ts +12 -0
  138. package/dist/surfaces/tui/components/spinner.js +39 -0
  139. package/dist/surfaces/tui/components/text-input.d.ts +45 -0
  140. package/dist/surfaces/tui/components/text-input.js +114 -0
  141. package/dist/surfaces/tui/format-file-size.d.ts +24 -0
  142. package/dist/surfaces/tui/format-file-size.js +43 -0
  143. package/dist/surfaces/tui/glyphs.d.ts +47 -0
  144. package/dist/surfaces/tui/glyphs.js +84 -0
  145. package/dist/surfaces/tui/hooks/use-auth-guard.d.ts +39 -0
  146. package/dist/surfaces/tui/hooks/use-auth-guard.js +135 -0
  147. package/dist/surfaces/tui/hooks/use-doctor-status.d.ts +64 -0
  148. package/dist/surfaces/tui/hooks/use-doctor-status.js +123 -0
  149. package/dist/surfaces/tui/hooks/use-escape-interceptor.d.ts +25 -0
  150. package/dist/surfaces/tui/hooks/use-escape-interceptor.js +65 -0
  151. package/dist/surfaces/tui/hooks/use-exit-guard.d.ts +18 -0
  152. package/dist/surfaces/tui/hooks/use-exit-guard.js +66 -0
  153. package/dist/surfaces/tui/hooks/use-export-bundle.d.ts +62 -0
  154. package/dist/surfaces/tui/hooks/use-export-bundle.js +100 -0
  155. package/dist/surfaces/tui/hooks/use-issue-detail.d.ts +61 -0
  156. package/dist/surfaces/tui/hooks/use-issue-detail.js +132 -0
  157. package/dist/surfaces/tui/hooks/use-issue-search.d.ts +71 -0
  158. package/dist/surfaces/tui/hooks/use-issue-search.js +168 -0
  159. package/dist/surfaces/tui/hooks/use-list-navigation.d.ts +44 -0
  160. package/dist/surfaces/tui/hooks/use-list-navigation.js +82 -0
  161. package/dist/surfaces/tui/hooks/use-media-binaries.d.ts +24 -0
  162. package/dist/surfaces/tui/hooks/use-media-binaries.js +44 -0
  163. package/dist/surfaces/tui/hooks/use-my-issues.d.ts +66 -0
  164. package/dist/surfaces/tui/hooks/use-my-issues.js +151 -0
  165. package/dist/surfaces/tui/hooks/use-onboarding-callbacks.d.ts +11 -0
  166. package/dist/surfaces/tui/hooks/use-onboarding-callbacks.js +104 -0
  167. package/dist/surfaces/tui/hooks/use-terminal-width.d.ts +52 -0
  168. package/dist/surfaces/tui/hooks/use-terminal-width.js +90 -0
  169. package/dist/surfaces/tui/index.d.ts +50 -0
  170. package/dist/surfaces/tui/index.js +158 -0
  171. package/dist/surfaces/tui/instance.d.ts +37 -0
  172. package/dist/surfaces/tui/instance.js +36 -0
  173. package/dist/surfaces/tui/job-registry.d.ts +113 -0
  174. package/dist/surfaces/tui/job-registry.js +123 -0
  175. package/dist/surfaces/tui/job-status.d.ts +45 -0
  176. package/dist/surfaces/tui/job-status.js +81 -0
  177. package/dist/surfaces/tui/navigation.d.ts +74 -0
  178. package/dist/surfaces/tui/navigation.js +87 -0
  179. package/dist/surfaces/tui/palettes.d.ts +38 -0
  180. package/dist/surfaces/tui/palettes.js +244 -0
  181. package/dist/surfaces/tui/screen.d.ts +30 -0
  182. package/dist/surfaces/tui/screen.js +51 -0
  183. package/dist/surfaces/tui/screens/about.d.ts +2 -0
  184. package/dist/surfaces/tui/screens/about.js +35 -0
  185. package/dist/surfaces/tui/screens/appearance.d.ts +2 -0
  186. package/dist/surfaces/tui/screens/appearance.js +74 -0
  187. package/dist/surfaces/tui/screens/config.d.ts +2 -0
  188. package/dist/surfaces/tui/screens/config.js +82 -0
  189. package/dist/surfaces/tui/screens/doctor.d.ts +2 -0
  190. package/dist/surfaces/tui/screens/doctor.js +109 -0
  191. package/dist/surfaces/tui/screens/export.d.ts +2 -0
  192. package/dist/surfaces/tui/screens/export.js +168 -0
  193. package/dist/surfaces/tui/screens/home-selection.d.ts +70 -0
  194. package/dist/surfaces/tui/screens/home-selection.js +80 -0
  195. package/dist/surfaces/tui/screens/home.d.ts +2 -0
  196. package/dist/surfaces/tui/screens/home.js +200 -0
  197. package/dist/surfaces/tui/screens/issue-detail.d.ts +6 -0
  198. package/dist/surfaces/tui/screens/issue-detail.js +182 -0
  199. package/dist/surfaces/tui/screens/jobs.d.ts +7 -0
  200. package/dist/surfaces/tui/screens/jobs.js +89 -0
  201. package/dist/surfaces/tui/screens/loaded-issue-context.d.ts +49 -0
  202. package/dist/surfaces/tui/screens/loaded-issue-context.js +57 -0
  203. package/dist/surfaces/tui/screens/onboarding/api-key.d.ts +2 -0
  204. package/dist/surfaces/tui/screens/onboarding/api-key.js +69 -0
  205. package/dist/surfaces/tui/screens/onboarding/login.d.ts +2 -0
  206. package/dist/surfaces/tui/screens/onboarding/login.js +50 -0
  207. package/dist/surfaces/tui/screens/onboarding/mode.d.ts +2 -0
  208. package/dist/surfaces/tui/screens/onboarding/mode.js +42 -0
  209. package/dist/surfaces/tui/screens/onboarding/onboarding-context.d.ts +221 -0
  210. package/dist/surfaces/tui/screens/onboarding/onboarding-context.js +131 -0
  211. package/dist/surfaces/tui/screens/onboarding/success.d.ts +2 -0
  212. package/dist/surfaces/tui/screens/onboarding/success.js +41 -0
  213. package/dist/surfaces/tui/screens/onboarding/url.d.ts +24 -0
  214. package/dist/surfaces/tui/screens/onboarding/url.js +84 -0
  215. package/dist/surfaces/tui/screens/onboarding/validating.d.ts +1 -0
  216. package/dist/surfaces/tui/screens/onboarding/validating.js +86 -0
  217. package/dist/surfaces/tui/screens/welcome.d.ts +6 -0
  218. package/dist/surfaces/tui/screens/welcome.js +95 -0
  219. package/dist/surfaces/tui/status-color.d.ts +21 -0
  220. package/dist/surfaces/tui/status-color.js +23 -0
  221. package/dist/surfaces/tui/symbols.d.ts +231 -0
  222. package/dist/surfaces/tui/symbols.js +14 -0
  223. package/dist/surfaces/tui/terminal-colors.d.ts +29 -0
  224. package/dist/surfaces/tui/terminal-colors.js +39 -0
  225. package/dist/surfaces/tui/theme.d.ts +156 -0
  226. package/dist/surfaces/tui/theme.js +86 -0
  227. package/dist/surfaces/tui/truncate.d.ts +31 -0
  228. package/dist/surfaces/tui/truncate.js +81 -0
  229. package/package.json +93 -0
@@ -0,0 +1,95 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Tela de boas-vindas da TUI — scaffold M2-01, com hints de doctor/config
4
+ * (M2-12, #35), o ponto de entrada do onboarding (M2-05.1, #27) e o desvio
5
+ * direto para a home quando já há credencial salva (M2-06, #29).
6
+ *
7
+ * Mostra nome do produto + versão (via a superfície pública do core,
8
+ * `../../../index.js`, ADR-005) e a dica de teclas. Cores vêm do tema
9
+ * central (M2-02, `useTheme()`) — nenhum literal de cor aqui, ver
10
+ * `theme.ts` para o guideline de uso de cada token.
11
+ *
12
+ * `Enter` checa a cascata de credenciais (`resolveApiKey`, mesma convenção
13
+ * de instância — `REDMINE_URL` — usada pelo doctor/CLI/MCP): com credencial
14
+ * já resolvida, pula direto para `home` (#29); sem ela (ou sem
15
+ * `REDMINE_URL` configurada, ou se a cascata falhar), segue o fluxo de
16
+ * onboarding de sempre. A checagem é assíncrona; `checkingRef` evita
17
+ * disparar mais de uma em paralelo se `Enter` for pressionado repetidas
18
+ * vezes antes da primeira resolver.
19
+ */
20
+ import { useCallback, useRef, useState } from 'react';
21
+ import { Box, Text, useInput } from 'ink';
22
+ import { resolveApiKey, TOOL_NAME, TOOL_VERSION } from '../../../index.js';
23
+ import { GradientText } from '../components/gradient-text.js';
24
+ import { useEnvFallbackAllowed } from '../instance.js';
25
+ import { useNavigation } from '../navigation.js';
26
+ import { useTheme } from '../theme.js';
27
+ /** Lê `REDMINE_URL` do ambiente, tratando string vazia como ausente (mesma convenção do doctor). */
28
+ function instanceFromEnv(env) {
29
+ const value = env.REDMINE_URL;
30
+ return value !== undefined && value.length > 0 ? value : undefined;
31
+ }
32
+ /**
33
+ * Tela inicial do roteador: `Enter` vai para `home` (credencial já salva) ou
34
+ * inicia o onboarding (M2-05.1), `?` atalhos, `d` doctor, `c` config, `q`
35
+ * sai (ver `app.tsx`).
36
+ */
37
+ export function WelcomeScreen() {
38
+ const { navigate } = useNavigation();
39
+ const theme = useTheme();
40
+ const [checking, setChecking] = useState(false);
41
+ // Handlers ESTÁVEIS (useCallback+refs) — mesmo padrão do TextInput/app.tsx:
42
+ // identidade nova por render des/re-subscreve o useInput e perde teclas.
43
+ const navigateRef = useRef(navigate);
44
+ navigateRef.current = navigate;
45
+ const checkingRef = useRef(checking);
46
+ checkingRef.current = checking;
47
+ // SEGURANÇA (#187): instância de origem `config` (URL persistida) não pode usar a
48
+ // env-key instance-agnóstica. Ref pelo padrão de handler estável desta tela.
49
+ const allowEnvFallbackRef = useRef(true);
50
+ allowEnvFallbackRef.current = useEnvFallbackAllowed();
51
+ const handleInput = useCallback((input, key) => {
52
+ // Reason: o Ink reporta Ctrl+<letra> com o MESMO `input` da letra solta
53
+ // (ex.: Ctrl+C chega como `input === 'c'`, `key.ctrl === true`) — sem essa
54
+ // guarda, o atalho global de sair (duplo Ctrl+C, `app.tsx`) navegaria
55
+ // para `config` por engano a cada Ctrl+C pressionado nesta tela.
56
+ if (key.ctrl) {
57
+ return;
58
+ }
59
+ if (input === '?') {
60
+ navigateRef.current('about');
61
+ return;
62
+ }
63
+ if (key.return) {
64
+ if (checkingRef.current) {
65
+ return;
66
+ }
67
+ const instanceUrl = instanceFromEnv(process.env);
68
+ if (instanceUrl === undefined) {
69
+ navigateRef.current('onboarding-url');
70
+ return;
71
+ }
72
+ setChecking(true);
73
+ void (async () => {
74
+ const apiKey = await resolveApiKey(instanceUrl, {
75
+ env: process.env,
76
+ allowEnvFallback: allowEnvFallbackRef.current,
77
+ }).catch(() => undefined);
78
+ setChecking(false);
79
+ navigateRef.current(apiKey !== undefined ? 'home' : 'onboarding-url');
80
+ })();
81
+ return;
82
+ }
83
+ if (input === 'd') {
84
+ navigateRef.current('doctor');
85
+ }
86
+ if (input === 'c') {
87
+ navigateRef.current('config');
88
+ }
89
+ if (input === 'a') {
90
+ navigateRef.current('appearance');
91
+ }
92
+ }, []);
93
+ useInput(handleInput);
94
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [_jsx(GradientText, { colors: theme.gradient ?? [theme.primary], children: TOOL_NAME }), _jsxs(Text, { color: theme.muted, children: ["v", TOOL_VERSION] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "Contexto completo de issues do Redmine, pronto para qualquer LLM." }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.muted, children: ["Pressione ", _jsx(Text, { color: theme.accent, children: "Enter" }), " para continuar,", ' ', _jsx(Text, { color: theme.accent, children: "?" }), " para atalhos,", ' ', _jsx(Text, { color: theme.accent, children: "d" }), " para o doctor,", ' ', _jsx(Text, { color: theme.accent, children: "c" }), " para configura\u00E7\u00E3o,", ' ', _jsx(Text, { color: theme.accent, children: "a" }), " para apar\u00EAncia,", ' ', _jsx(Text, { color: theme.accent, children: "q" }), " para sair."] }) })] }));
95
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Heurística de cor de status compartilhada entre telas de issue (M2-06/#29,
3
+ * extraída na #31 para ser reaproveitada por `screens/issue-detail.tsx` sem
4
+ * duplicar a lógica antes privada de `screens/home.tsx`).
5
+ *
6
+ * Sempre devolve um token do tema (nunca um literal de cor) — a varredura
7
+ * anti-hardcode (`tests/surfaces/tui/no-hardcoded-colors.test.ts`) cobre
8
+ * qualquer arquivo desta árvore.
9
+ */
10
+ import type { Theme } from './theme.js';
11
+ /**
12
+ * Cor do badge de status: heurística por nome do status. `theme.primary` é o
13
+ * fallback para status sem correspondência (ex.: "Nova", "Em espera").
14
+ *
15
+ * @param theme - Tema ativo (via `useTheme()` no chamador).
16
+ * @param statusName - Nome do status vindo do Redmine (`issue.status.name`).
17
+ * @returns O token de cor do tema mais adequado ao status.
18
+ * @example
19
+ * statusColor(theme, 'Fechado') // theme.success
20
+ */
21
+ export declare function statusColor(theme: Theme, statusName: string): string;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Cor do badge de status: heurística por nome do status. `theme.primary` é o
3
+ * fallback para status sem correspondência (ex.: "Nova", "Em espera").
4
+ *
5
+ * @param theme - Tema ativo (via `useTheme()` no chamador).
6
+ * @param statusName - Nome do status vindo do Redmine (`issue.status.name`).
7
+ * @returns O token de cor do tema mais adequado ao status.
8
+ * @example
9
+ * statusColor(theme, 'Fechado') // theme.success
10
+ */
11
+ export function statusColor(theme, statusName) {
12
+ const normalized = statusName.toLowerCase();
13
+ if (/fechad|closed|resolvid|resolved|conclu[ií]d/.test(normalized)) {
14
+ return theme.success;
15
+ }
16
+ if (/cancel/.test(normalized)) {
17
+ return theme.danger;
18
+ }
19
+ if (/andamento|progress|curso/.test(normalized)) {
20
+ return theme.warning;
21
+ }
22
+ return theme.primary;
23
+ }
@@ -0,0 +1,231 @@
1
+ /** Conjunto de símbolos disponível às telas da TUI (tick, cross, pointer, etc.). */
2
+ export declare const symbols: {
3
+ readonly tick: string;
4
+ readonly info: string;
5
+ readonly warning: string;
6
+ readonly cross: string;
7
+ readonly square: string;
8
+ readonly squareSmall: string;
9
+ readonly squareSmallFilled: string;
10
+ readonly squareDarkShade: string;
11
+ readonly squareMediumShade: string;
12
+ readonly squareLightShade: string;
13
+ readonly squareTop: string;
14
+ readonly squareBottom: string;
15
+ readonly squareLeft: string;
16
+ readonly squareRight: string;
17
+ readonly squareCenter: string;
18
+ readonly circle: string;
19
+ readonly circleFilled: string;
20
+ readonly circleDotted: string;
21
+ readonly circleDouble: string;
22
+ readonly circleCircle: string;
23
+ readonly circleCross: string;
24
+ readonly circlePipe: string;
25
+ readonly circleQuestionMark: string;
26
+ readonly radioOn: string;
27
+ readonly radioOff: string;
28
+ readonly checkboxOn: string;
29
+ readonly checkboxOff: string;
30
+ readonly checkboxCircleOn: string;
31
+ readonly checkboxCircleOff: string;
32
+ readonly questionMarkPrefix: string;
33
+ readonly bullet: string;
34
+ readonly dot: string;
35
+ readonly ellipsis: string;
36
+ readonly pointer: string;
37
+ readonly pointerSmall: string;
38
+ readonly triangleUp: string;
39
+ readonly triangleUpSmall: string;
40
+ readonly triangleUpOutline: string;
41
+ readonly triangleDown: string;
42
+ readonly triangleDownSmall: string;
43
+ readonly triangleLeft: string;
44
+ readonly triangleLeftSmall: string;
45
+ readonly triangleRight: string;
46
+ readonly triangleRightSmall: string;
47
+ readonly lozenge: string;
48
+ readonly lozengeOutline: string;
49
+ readonly home: string;
50
+ readonly hamburger: string;
51
+ readonly smiley: string;
52
+ readonly mustache: string;
53
+ readonly heart: string;
54
+ readonly star: string;
55
+ readonly play: string;
56
+ readonly musicNote: string;
57
+ readonly musicNoteBeamed: string;
58
+ readonly nodejs: string;
59
+ readonly arrowUp: string;
60
+ readonly arrowDown: string;
61
+ readonly arrowLeft: string;
62
+ readonly arrowRight: string;
63
+ readonly arrowLeftRight: string;
64
+ readonly arrowUpDown: string;
65
+ readonly almostEqual: string;
66
+ readonly notEqual: string;
67
+ readonly lessOrEqual: string;
68
+ readonly greaterOrEqual: string;
69
+ readonly identical: string;
70
+ readonly infinity: string;
71
+ readonly subscriptZero: string;
72
+ readonly subscriptOne: string;
73
+ readonly subscriptTwo: string;
74
+ readonly subscriptThree: string;
75
+ readonly subscriptFour: string;
76
+ readonly subscriptFive: string;
77
+ readonly subscriptSix: string;
78
+ readonly subscriptSeven: string;
79
+ readonly subscriptEight: string;
80
+ readonly subscriptNine: string;
81
+ readonly oneHalf: string;
82
+ readonly oneThird: string;
83
+ readonly oneQuarter: string;
84
+ readonly oneFifth: string;
85
+ readonly oneSixth: string;
86
+ readonly oneSeventh: string;
87
+ readonly oneEighth: string;
88
+ readonly oneNinth: string;
89
+ readonly oneTenth: string;
90
+ readonly twoThirds: string;
91
+ readonly twoFifths: string;
92
+ readonly threeQuarters: string;
93
+ readonly threeFifths: string;
94
+ readonly threeEighths: string;
95
+ readonly fourFifths: string;
96
+ readonly fiveSixths: string;
97
+ readonly fiveEighths: string;
98
+ readonly sevenEighth: string;
99
+ readonly line: string;
100
+ readonly lineBold: string;
101
+ readonly lineDouble: string;
102
+ readonly lineDashed0: string;
103
+ readonly lineDashed1: string;
104
+ readonly lineDashed2: string;
105
+ readonly lineDashed3: string;
106
+ readonly lineDashed4: string;
107
+ readonly lineDashed5: string;
108
+ readonly lineDashed6: string;
109
+ readonly lineDashed7: string;
110
+ readonly lineDashed8: string;
111
+ readonly lineDashed9: string;
112
+ readonly lineDashed10: string;
113
+ readonly lineDashed11: string;
114
+ readonly lineDashed12: string;
115
+ readonly lineDashed13: string;
116
+ readonly lineDashed14: string;
117
+ readonly lineDashed15: string;
118
+ readonly lineVertical: string;
119
+ readonly lineVerticalBold: string;
120
+ readonly lineVerticalDouble: string;
121
+ readonly lineVerticalDashed0: string;
122
+ readonly lineVerticalDashed1: string;
123
+ readonly lineVerticalDashed2: string;
124
+ readonly lineVerticalDashed3: string;
125
+ readonly lineVerticalDashed4: string;
126
+ readonly lineVerticalDashed5: string;
127
+ readonly lineVerticalDashed6: string;
128
+ readonly lineVerticalDashed7: string;
129
+ readonly lineVerticalDashed8: string;
130
+ readonly lineVerticalDashed9: string;
131
+ readonly lineVerticalDashed10: string;
132
+ readonly lineVerticalDashed11: string;
133
+ readonly lineDownLeft: string;
134
+ readonly lineDownLeftArc: string;
135
+ readonly lineDownBoldLeftBold: string;
136
+ readonly lineDownBoldLeft: string;
137
+ readonly lineDownLeftBold: string;
138
+ readonly lineDownDoubleLeftDouble: string;
139
+ readonly lineDownDoubleLeft: string;
140
+ readonly lineDownLeftDouble: string;
141
+ readonly lineDownRight: string;
142
+ readonly lineDownRightArc: string;
143
+ readonly lineDownBoldRightBold: string;
144
+ readonly lineDownBoldRight: string;
145
+ readonly lineDownRightBold: string;
146
+ readonly lineDownDoubleRightDouble: string;
147
+ readonly lineDownDoubleRight: string;
148
+ readonly lineDownRightDouble: string;
149
+ readonly lineUpLeft: string;
150
+ readonly lineUpLeftArc: string;
151
+ readonly lineUpBoldLeftBold: string;
152
+ readonly lineUpBoldLeft: string;
153
+ readonly lineUpLeftBold: string;
154
+ readonly lineUpDoubleLeftDouble: string;
155
+ readonly lineUpDoubleLeft: string;
156
+ readonly lineUpLeftDouble: string;
157
+ readonly lineUpRight: string;
158
+ readonly lineUpRightArc: string;
159
+ readonly lineUpBoldRightBold: string;
160
+ readonly lineUpBoldRight: string;
161
+ readonly lineUpRightBold: string;
162
+ readonly lineUpDoubleRightDouble: string;
163
+ readonly lineUpDoubleRight: string;
164
+ readonly lineUpRightDouble: string;
165
+ readonly lineUpDownLeft: string;
166
+ readonly lineUpBoldDownBoldLeftBold: string;
167
+ readonly lineUpBoldDownBoldLeft: string;
168
+ readonly lineUpDownLeftBold: string;
169
+ readonly lineUpBoldDownLeftBold: string;
170
+ readonly lineUpDownBoldLeftBold: string;
171
+ readonly lineUpDownBoldLeft: string;
172
+ readonly lineUpBoldDownLeft: string;
173
+ readonly lineUpDoubleDownDoubleLeftDouble: string;
174
+ readonly lineUpDoubleDownDoubleLeft: string;
175
+ readonly lineUpDownLeftDouble: string;
176
+ readonly lineUpDownRight: string;
177
+ readonly lineUpBoldDownBoldRightBold: string;
178
+ readonly lineUpBoldDownBoldRight: string;
179
+ readonly lineUpDownRightBold: string;
180
+ readonly lineUpBoldDownRightBold: string;
181
+ readonly lineUpDownBoldRightBold: string;
182
+ readonly lineUpDownBoldRight: string;
183
+ readonly lineUpBoldDownRight: string;
184
+ readonly lineUpDoubleDownDoubleRightDouble: string;
185
+ readonly lineUpDoubleDownDoubleRight: string;
186
+ readonly lineUpDownRightDouble: string;
187
+ readonly lineDownLeftRight: string;
188
+ readonly lineDownBoldLeftBoldRightBold: string;
189
+ readonly lineDownLeftBoldRightBold: string;
190
+ readonly lineDownBoldLeftRight: string;
191
+ readonly lineDownBoldLeftBoldRight: string;
192
+ readonly lineDownBoldLeftRightBold: string;
193
+ readonly lineDownLeftRightBold: string;
194
+ readonly lineDownLeftBoldRight: string;
195
+ readonly lineDownDoubleLeftDoubleRightDouble: string;
196
+ readonly lineDownDoubleLeftRight: string;
197
+ readonly lineDownLeftDoubleRightDouble: string;
198
+ readonly lineUpLeftRight: string;
199
+ readonly lineUpBoldLeftBoldRightBold: string;
200
+ readonly lineUpLeftBoldRightBold: string;
201
+ readonly lineUpBoldLeftRight: string;
202
+ readonly lineUpBoldLeftBoldRight: string;
203
+ readonly lineUpBoldLeftRightBold: string;
204
+ readonly lineUpLeftRightBold: string;
205
+ readonly lineUpLeftBoldRight: string;
206
+ readonly lineUpDoubleLeftDoubleRightDouble: string;
207
+ readonly lineUpDoubleLeftRight: string;
208
+ readonly lineUpLeftDoubleRightDouble: string;
209
+ readonly lineUpDownLeftRight: string;
210
+ readonly lineUpBoldDownBoldLeftBoldRightBold: string;
211
+ readonly lineUpDownBoldLeftBoldRightBold: string;
212
+ readonly lineUpBoldDownLeftBoldRightBold: string;
213
+ readonly lineUpBoldDownBoldLeftRightBold: string;
214
+ readonly lineUpBoldDownBoldLeftBoldRight: string;
215
+ readonly lineUpBoldDownLeftRight: string;
216
+ readonly lineUpDownBoldLeftRight: string;
217
+ readonly lineUpDownLeftBoldRight: string;
218
+ readonly lineUpDownLeftRightBold: string;
219
+ readonly lineUpBoldDownBoldLeftRight: string;
220
+ readonly lineUpDownLeftBoldRightBold: string;
221
+ readonly lineUpBoldDownLeftBoldRight: string;
222
+ readonly lineUpBoldDownLeftRightBold: string;
223
+ readonly lineUpDownBoldLeftBoldRight: string;
224
+ readonly lineUpDownBoldLeftRightBold: string;
225
+ readonly lineUpDoubleDownDoubleLeftDoubleRightDouble: string;
226
+ readonly lineUpDoubleDownDoubleLeftRight: string;
227
+ readonly lineUpDownLeftDoubleRightDouble: string;
228
+ readonly lineCross: string;
229
+ readonly lineBackslash: string;
230
+ readonly lineSlash: string;
231
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Símbolos da TUI (M2-03).
3
+ *
4
+ * Fonte única de símbolos para as telas — nada de caracteres Unicode
5
+ * hardcoded (ex.: `'✔'`, `'✖'`) espalhados pelo código das telas. Reexporta o
6
+ * conjunto padrão de `figures`, que já detecta o suporte a Unicode do
7
+ * terminal e degrada sozinho para ASCII quando necessário (principalmente no
8
+ * Windows/cmd.exe — ver AC da issue M2-03).
9
+ *
10
+ * As telas importam daqui: `import { symbols } from '../symbols.js'`.
11
+ */
12
+ import figures from 'figures';
13
+ /** Conjunto de símbolos disponível às telas da TUI (tick, cross, pointer, etc.). */
14
+ export const symbols = figures;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Aplica as cores da paleta como DEFAULT do terminal via OSC (#190).
3
+ *
4
+ * Em vez de pintar um Box de fundo (que deixava emenda e não cobria a tela toda),
5
+ * setamos o fundo (OSC 11) e o texto (OSC 10) DEFAULT do terminal para os da
6
+ * paleta. Efeito: o buffer inteiro (inclusive áreas vazias) ganha o fundo temático,
7
+ * e todo texto SEM cor explícita usa a cor de texto da paleta — legível em qualquer
8
+ * terminal (claro ou escuro). Ao sair, {@link resetTerminalColors} restaura o padrão.
9
+ *
10
+ * OSC = "Operating System Command": `ESC ] <n> ; <valor> BEL`. Suportado pelos
11
+ * emuladores modernos (iTerm2, Terminal.app, etc.); onde não houver suporte, os
12
+ * códigos são ignorados — as paletas CLARAS ainda ficam legíveis sobre o fundo
13
+ * claro do terminal (degradação graciosa).
14
+ */
15
+ import type { Theme } from './theme.js';
16
+ /**
17
+ * Escreve OSC 11 (fundo) e OSC 10 (texto) com as cores da paleta, quando definidas.
18
+ *
19
+ * @param out - Stream do terminal.
20
+ * @param theme - Tema/paleta ativa (usa `background`/`text`).
21
+ */
22
+ export declare function applyTerminalColors(out: NodeJS.WriteStream, theme: Theme): void;
23
+ /**
24
+ * Restaura o fundo (OSC 111) e o texto (OSC 110) DEFAULT do terminal ao valor
25
+ * original — chamado ao sair do full-screen (inclusive em sinal, via alt-screen).
26
+ *
27
+ * @param out - Stream do terminal.
28
+ */
29
+ export declare function resetTerminalColors(out: NodeJS.WriteStream): void;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Aplica as cores da paleta como DEFAULT do terminal via OSC (#190).
3
+ *
4
+ * Em vez de pintar um Box de fundo (que deixava emenda e não cobria a tela toda),
5
+ * setamos o fundo (OSC 11) e o texto (OSC 10) DEFAULT do terminal para os da
6
+ * paleta. Efeito: o buffer inteiro (inclusive áreas vazias) ganha o fundo temático,
7
+ * e todo texto SEM cor explícita usa a cor de texto da paleta — legível em qualquer
8
+ * terminal (claro ou escuro). Ao sair, {@link resetTerminalColors} restaura o padrão.
9
+ *
10
+ * OSC = "Operating System Command": `ESC ] <n> ; <valor> BEL`. Suportado pelos
11
+ * emuladores modernos (iTerm2, Terminal.app, etc.); onde não houver suporte, os
12
+ * códigos são ignorados — as paletas CLARAS ainda ficam legíveis sobre o fundo
13
+ * claro do terminal (degradação graciosa).
14
+ */
15
+ const BEL = '\x07';
16
+ /**
17
+ * Escreve OSC 11 (fundo) e OSC 10 (texto) com as cores da paleta, quando definidas.
18
+ *
19
+ * @param out - Stream do terminal.
20
+ * @param theme - Tema/paleta ativa (usa `background`/`text`).
21
+ */
22
+ export function applyTerminalColors(out, theme) {
23
+ let seq = '';
24
+ if (theme.background !== undefined)
25
+ seq += `\x1b]11;${theme.background}${BEL}`;
26
+ if (theme.text !== undefined)
27
+ seq += `\x1b]10;${theme.text}${BEL}`;
28
+ if (seq.length > 0)
29
+ out.write(seq);
30
+ }
31
+ /**
32
+ * Restaura o fundo (OSC 111) e o texto (OSC 110) DEFAULT do terminal ao valor
33
+ * original — chamado ao sair do full-screen (inclusive em sinal, via alt-screen).
34
+ *
35
+ * @param out - Stream do terminal.
36
+ */
37
+ export function resetTerminalColors(out) {
38
+ out.write(`\x1b]110${BEL}\x1b]111${BEL}`);
39
+ }
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Tema central da TUI (M2-02).
3
+ *
4
+ * Fonte de literais de cor da TUI (junto de `palettes.ts`, #190, que guarda os
5
+ * hex das paletas como DADOS de objeto, não como props JSX): toda tela consome
6
+ * cores via {@link useTheme}, nunca com `color="magenta"` direto no JSX — a
7
+ * varredura `tests/surfaces/tui/no-hardcoded-colors.test.ts` garante isso em CI
8
+ * (ela pega `color=`/`backgroundColor=` com literal; as chaves `primary:` de
9
+ * `palettes.ts` não são props, por isso passam). Centralizar aqui/em `palettes.ts`
10
+ * torna trocar a paleta uma mudança localizada.
11
+ *
12
+ * ## Paleta e guideline de uso
13
+ *
14
+ * Combinação sóbria sobre fundo escuro (a paleta padrão de 16 cores do
15
+ * terminal, resolvida pelo próprio emulador — sem hex fixo, para respeitar o
16
+ * esquema de cores do usuário):
17
+ *
18
+ * - **primary** (`cyan`) — cor de identidade/foco: títulos, item selecionado,
19
+ * estado ativo. É a cor mais usada na TUI; se uma tela parece "sem cor
20
+ * nenhuma", provavelmente falta um `primary` nela.
21
+ * - **accent** (`magenta`) — destaque raro: uma call-to-action pontual (ex.:
22
+ * a tecla que o usuário deve apertar agora). Usar com moderação — se
23
+ * `accent` aparece em toda linha da tela, ele deixou de ser um destaque.
24
+ * - **muted** (`gray`) — texto secundário/de apoio: dicas, timestamps,
25
+ * metadados. Substitui o uso solto de `dimColor` por um tom deliberado.
26
+ * - **success** (`green`) / **warning** (`yellow`) / **danger** (`red`) —
27
+ * reservadas para *estado*, nunca para decoração: resultado de uma
28
+ * operação (sucesso/erro) ou um alerta acionável. Não usar `danger` só
29
+ * porque "fica bonito" — é reservada para sinalizar problema real.
30
+ *
31
+ * Reaproveita os nomes de cor nativos do Ink/chalk (paleta ANSI de 16 cores),
32
+ * então funciona em qualquer terminal sem depender de suporte a true color.
33
+ */
34
+ import { type ReactNode } from 'react';
35
+ /**
36
+ * Tokens semânticos de cor da TUI.
37
+ *
38
+ * Os valores são nomes de cor aceitos por `color`/`backgroundColor` do Ink
39
+ * (ver guideline de uso no topo do arquivo).
40
+ */
41
+ export interface Theme {
42
+ /** Identidade/foco: títulos, seleção, estado ativo. */
43
+ primary: string;
44
+ /** Destaque raro: uma call-to-action pontual por tela. */
45
+ accent: string;
46
+ /** Texto secundário/de apoio: dicas, metadados. */
47
+ muted: string;
48
+ /** Resultado positivo de uma operação. */
49
+ success: string;
50
+ /** Alerta acionável, não bloqueante. */
51
+ warning: string;
52
+ /** Erro ou operação que falhou. */
53
+ danger: string;
54
+ /** Bordas de Box (painéis, cards, modais). Discreta por padrão. */
55
+ border: string;
56
+ /**
57
+ * Segunda cor de identidade (opcional) — variedade em listas/cabeçalhos sem
58
+ * abusar do `accent`. Ausente ⇒ cai em {@link Theme.primary}.
59
+ */
60
+ secondary?: string;
61
+ /**
62
+ * Cor de FUNDO da paleta (opcional, #190). Aplicada como fundo DEFAULT do
63
+ * terminal (OSC 11) ao entrar em full-screen — cobre a tela inteira sem pintar
64
+ * um Box (evita emenda/altura fixa). Ausente ⇒ herda o fundo do terminal.
65
+ */
66
+ background?: string;
67
+ /**
68
+ * Cor de TEXTO padrão da paleta (opcional, #190). Aplicada como foreground
69
+ * DEFAULT do terminal (OSC 10) ao entrar em full-screen — assim TODO texto sem
70
+ * cor explícita (ex.: o assunto da issue) fica legível sobre o {@link background}
71
+ * (nada de "preto sobre escuro" no terminal claro do usuário). Ausente ⇒ herda o
72
+ * foreground do terminal.
73
+ */
74
+ text?: string;
75
+ /**
76
+ * Ramp de cores (2+ hex) para efeitos de GRADIENTE em títulos/breadcrumb
77
+ * (opcional, #190). Ausente ⇒ texto sólido em {@link Theme.primary}.
78
+ */
79
+ gradient?: readonly string[];
80
+ }
81
+ /** Tema padrão da TUI — ver guideline de uso na documentação do arquivo. */
82
+ export declare const DEFAULT_THEME: Theme;
83
+ /**
84
+ * Provider do tema — envolve toda a árvore da TUI em `app.tsx`.
85
+ *
86
+ * Aceita um `theme` customizado (para testes ou temas alternativos
87
+ * futuros); sem ele, usa {@link DEFAULT_THEME}.
88
+ */
89
+ export declare function ThemeProvider({ theme, children, }: {
90
+ theme?: Theme;
91
+ children: ReactNode;
92
+ }): import("react").JSX.Element;
93
+ /**
94
+ * Hook de tema consumido pelas telas — única forma permitida de obter uma
95
+ * cor na TUI (ver varredura anti-hardcode).
96
+ *
97
+ * @throws {Error} Se chamado fora de um `<ThemeProvider>` — indica erro de
98
+ * composição (tela renderizada sem passar pelo roteador/`app.tsx`).
99
+ */
100
+ export declare function useTheme(): Theme;
101
+ /**
102
+ * Controlador de PALETA (#190) — permite ao seletor de tema trocar a paleta ao
103
+ * vivo (preview ao navegar) e confirmar (persistindo). Fornecido pelo `App`, que
104
+ * mantém o estado da paleta ativa e o repassa ao {@link ThemeProvider}.
105
+ */
106
+ export interface ThemeController {
107
+ /** Id da paleta atualmente ativa. */
108
+ readonly paletteId: string;
109
+ /** Aplica uma paleta AO VIVO, sem persistir (preview ao navegar no seletor). */
110
+ preview(id: string): void;
111
+ /** Aplica E persiste a paleta (Enter no seletor). */
112
+ select(id: string): Promise<void>;
113
+ }
114
+ /** Provider do controlador de paleta — montado pelo `App`. */
115
+ export declare function ThemeControllerProvider({ value, children, }: {
116
+ value: ThemeController;
117
+ children: ReactNode;
118
+ }): import("react").JSX.Element;
119
+ /**
120
+ * Hook do controlador de paleta — usado pelo seletor de tema.
121
+ *
122
+ * @throws {Error} Se chamado fora de um `<ThemeControllerProvider>`.
123
+ */
124
+ export declare function useThemeController(): ThemeController;
125
+ /**
126
+ * Mapeamento previsto para `@inkjs/ui` (dependência já presente no projeto,
127
+ * ainda não consumida por nenhuma tela — nada é importado daqui, isso é só o
128
+ * plano de integração para quando o primeiro componente entrar).
129
+ *
130
+ * `@inkjs/ui` recebe cores por `extendTheme(defaultTheme, { components })`
131
+ * (ver docs da lib). Quando isso acontecer, a extensão deve ler os tokens
132
+ * daqui em vez de duplicar paleta:
133
+ *
134
+ * ```tsx
135
+ * import { extendTheme, defaultTheme } from '@inkjs/ui';
136
+ * import { DEFAULT_THEME } from './theme.js';
137
+ *
138
+ * const inkUiTheme = extendTheme(defaultTheme, {
139
+ * components: {
140
+ * Spinner: { styles: { frame: () => ({ color: DEFAULT_THEME.primary }) } },
141
+ * Select: {
142
+ * styles: {
143
+ * focusIndicator: () => ({ color: DEFAULT_THEME.primary }),
144
+ * highlightedText: () => ({ color: DEFAULT_THEME.accent }),
145
+ * },
146
+ * },
147
+ * // ...demais componentes do @inkjs/ui conforme forem adotados.
148
+ * },
149
+ * });
150
+ * ```
151
+ *
152
+ * Se `@inkjs/ui` ganhar suporte a um tema dinâmico (não apenas estático no
153
+ * módulo), essa extensão deve ser recalculada dentro de um hook que chame
154
+ * {@link useTheme} — hoje o tema é estático, então o esboço acima já é
155
+ * suficiente como referência.
156
+ */