@codemieai/code 0.1.0 → 0.2.1

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 (426) hide show
  1. package/README.md +30 -6
  2. package/bin/codebase-memory-ui-daemon.js +10 -0
  3. package/bin/codemie-codex.js +18 -0
  4. package/dist/agents/core/AgentCLI.d.ts +1 -0
  5. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  6. package/dist/agents/core/AgentCLI.js +29 -4
  7. package/dist/agents/core/AgentCLI.js.map +1 -1
  8. package/dist/agents/core/session/sync-state-utils.d.ts +11 -0
  9. package/dist/agents/core/session/sync-state-utils.d.ts.map +1 -0
  10. package/dist/agents/core/session/sync-state-utils.js +99 -0
  11. package/dist/agents/core/session/sync-state-utils.js.map +1 -0
  12. package/dist/agents/core/session/types.d.ts +8 -0
  13. package/dist/agents/core/session/types.d.ts.map +1 -1
  14. package/dist/agents/core/session/utils/jsonl-reader.d.ts +8 -0
  15. package/dist/agents/core/session/utils/jsonl-reader.d.ts.map +1 -1
  16. package/dist/agents/core/session/utils/jsonl-reader.js +37 -0
  17. package/dist/agents/core/session/utils/jsonl-reader.js.map +1 -1
  18. package/dist/agents/plugins/claude/claude.plugin.js +1 -1
  19. package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
  20. package/dist/agents/plugins/claude/plugin/hooks/hooks.json +0 -15
  21. package/dist/agents/plugins/claude/plugin/skills/codemie-analytics/SKILL.md +641 -0
  22. package/dist/agents/plugins/claude/plugin/skills/codemie-analytics/references/leaderboard-dashboard-report.md +225 -0
  23. package/dist/agents/plugins/claude/plugin/skills/codemie-analytics/references/people-spending-dashboard-report.md +746 -0
  24. package/dist/agents/plugins/claude/plugin/skills/codemie-analytics/references/people-spending-dashboard-template.html +3270 -0
  25. package/dist/agents/plugins/claude/plugin/skills/codemie-analytics/scripts/analytics-cli.js +893 -0
  26. package/dist/agents/plugins/claude/plugin/skills/codemie-analytics/scripts/inspect-schema.js +211 -0
  27. package/dist/agents/plugins/claude/plugin/skills/codemie-html-report/README.md +39 -0
  28. package/dist/agents/plugins/claude/plugin/skills/codemie-html-report/SKILL.md +117 -26
  29. package/dist/agents/plugins/claude/plugin/skills/codemie-html-report/scripts/inject-css.js +40 -0
  30. package/dist/agents/plugins/claude/plugin/skills/codemie-html-report/scripts/inject-data.js +68 -0
  31. package/dist/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/bundle.css +1 -0
  32. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/SKILL.md +240 -0
  33. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/assistants.md +256 -0
  34. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/categories.md +101 -0
  35. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/datasources.md +401 -0
  36. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/integrations.md +242 -0
  37. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/skills.md +191 -0
  38. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/users.md +38 -0
  39. package/dist/agents/plugins/claude/plugin/skills/codemie-sdk/examples/workflows.md +151 -0
  40. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
  41. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +2 -0
  42. package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
  43. package/dist/agents/plugins/codex/codex-message-types.d.ts +80 -0
  44. package/dist/agents/plugins/codex/codex-message-types.d.ts.map +1 -0
  45. package/dist/agents/plugins/codex/codex-message-types.js +36 -0
  46. package/dist/agents/plugins/codex/codex-message-types.js.map +1 -0
  47. package/dist/agents/plugins/codex/codex-models.d.ts +9 -0
  48. package/dist/agents/plugins/codex/codex-models.d.ts.map +1 -0
  49. package/dist/agents/plugins/codex/codex-models.js +227 -0
  50. package/dist/agents/plugins/codex/codex-models.js.map +1 -0
  51. package/dist/agents/plugins/codex/codex.incremental-sync.d.ts +39 -0
  52. package/dist/agents/plugins/codex/codex.incremental-sync.d.ts.map +1 -0
  53. package/dist/agents/plugins/codex/codex.incremental-sync.js +147 -0
  54. package/dist/agents/plugins/codex/codex.incremental-sync.js.map +1 -0
  55. package/dist/agents/plugins/codex/codex.paths.d.ts +29 -0
  56. package/dist/agents/plugins/codex/codex.paths.d.ts.map +1 -0
  57. package/dist/agents/plugins/codex/codex.paths.js +43 -0
  58. package/dist/agents/plugins/codex/codex.paths.js.map +1 -0
  59. package/dist/agents/plugins/codex/codex.plugin.d.ts +80 -0
  60. package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -0
  61. package/dist/agents/plugins/codex/codex.plugin.js +474 -0
  62. package/dist/agents/plugins/codex/codex.plugin.js.map +1 -0
  63. package/dist/agents/plugins/codex/codex.reconciliation.d.ts +43 -0
  64. package/dist/agents/plugins/codex/codex.reconciliation.d.ts.map +1 -0
  65. package/dist/agents/plugins/codex/codex.reconciliation.js +141 -0
  66. package/dist/agents/plugins/codex/codex.reconciliation.js.map +1 -0
  67. package/dist/agents/plugins/codex/codex.session.d.ts +58 -0
  68. package/dist/agents/plugins/codex/codex.session.d.ts.map +1 -0
  69. package/dist/agents/plugins/codex/codex.session.js +326 -0
  70. package/dist/agents/plugins/codex/codex.session.js.map +1 -0
  71. package/dist/agents/plugins/codex/codex.storage-utils.d.ts +15 -0
  72. package/dist/agents/plugins/codex/codex.storage-utils.d.ts.map +1 -0
  73. package/dist/agents/plugins/codex/codex.storage-utils.js +19 -0
  74. package/dist/agents/plugins/codex/codex.storage-utils.js.map +1 -0
  75. package/dist/agents/plugins/codex/index.d.ts +7 -0
  76. package/dist/agents/plugins/codex/index.d.ts.map +1 -0
  77. package/dist/agents/plugins/codex/index.js +9 -0
  78. package/dist/agents/plugins/codex/index.js.map +1 -0
  79. package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.d.ts +24 -0
  80. package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.d.ts.map +1 -0
  81. package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.js +613 -0
  82. package/dist/agents/plugins/codex/session/processors/codex.conversations-processor.js.map +1 -0
  83. package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.d.ts +21 -0
  84. package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.d.ts.map +1 -0
  85. package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.js +124 -0
  86. package/dist/agents/plugins/codex/session/processors/codex.metrics-processor.js.map +1 -0
  87. package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.d.ts.map +1 -1
  88. package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js +1 -0
  89. package/dist/agents/plugins/gemini/session/processors/gemini.conversations-processor.js.map +1 -1
  90. package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -1
  91. package/dist/agents/plugins/opencode/opencode.storage-utils.js +2 -29
  92. package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -1
  93. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -1
  94. package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -1
  95. package/dist/agents/registry.d.ts.map +1 -1
  96. package/dist/agents/registry.js +2 -0
  97. package/dist/agents/registry.js.map +1 -1
  98. package/dist/bin/codebase-memory-ui-daemon.d.ts +2 -0
  99. package/dist/bin/codebase-memory-ui-daemon.d.ts.map +1 -0
  100. package/dist/bin/codebase-memory-ui-daemon.js +141 -0
  101. package/dist/bin/codebase-memory-ui-daemon.js.map +1 -0
  102. package/dist/bin/proxy-daemon.js +4 -0
  103. package/dist/bin/proxy-daemon.js.map +1 -1
  104. package/dist/cli/commands/assistants/constants.js +2 -2
  105. package/dist/cli/commands/assistants/constants.js.map +1 -1
  106. package/dist/cli/commands/assistants/setup/configuration/constants.js +4 -4
  107. package/dist/cli/commands/assistants/setup/configuration/constants.js.map +1 -1
  108. package/dist/cli/commands/assistants/setup/configuration/ui.d.ts.map +1 -1
  109. package/dist/cli/commands/assistants/setup/configuration/ui.js +10 -13
  110. package/dist/cli/commands/assistants/setup/configuration/ui.js.map +1 -1
  111. package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.d.ts +4 -0
  112. package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.d.ts.map +1 -0
  113. package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.js +76 -0
  114. package/dist/cli/commands/assistants/setup/generators/codex-skill-generator.js.map +1 -0
  115. package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.d.ts +4 -0
  116. package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.d.ts.map +1 -0
  117. package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.js +68 -0
  118. package/dist/cli/commands/assistants/setup/generators/gemini-skill-generator.js.map +1 -0
  119. package/dist/cli/commands/assistants/setup/helpers.d.ts +3 -2
  120. package/dist/cli/commands/assistants/setup/helpers.d.ts.map +1 -1
  121. package/dist/cli/commands/assistants/setup/helpers.js +43 -8
  122. package/dist/cli/commands/assistants/setup/helpers.js.map +1 -1
  123. package/dist/cli/commands/assistants/setup/index.d.ts +3 -1
  124. package/dist/cli/commands/assistants/setup/index.d.ts.map +1 -1
  125. package/dist/cli/commands/assistants/setup/index.js +15 -12
  126. package/dist/cli/commands/assistants/setup/index.js.map +1 -1
  127. package/dist/cli/commands/assistants/setup/manualConfiguration/types.d.ts +2 -2
  128. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js +2 -2
  129. package/dist/cli/commands/assistants/setup/manualConfiguration/ui.js.map +1 -1
  130. package/dist/cli/commands/assistants/setup/selection/ui.d.ts.map +1 -1
  131. package/dist/cli/commands/assistants/setup/selection/ui.js +8 -13
  132. package/dist/cli/commands/assistants/setup/selection/ui.js.map +1 -1
  133. package/dist/cli/commands/assistants/setup/summary/index.d.ts.map +1 -1
  134. package/dist/cli/commands/assistants/setup/summary/index.js +14 -8
  135. package/dist/cli/commands/assistants/setup/summary/index.js.map +1 -1
  136. package/dist/cli/commands/codebase/daemon-manager.d.ts +24 -0
  137. package/dist/cli/commands/codebase/daemon-manager.d.ts.map +1 -0
  138. package/dist/cli/commands/codebase/daemon-manager.js +112 -0
  139. package/dist/cli/commands/codebase/daemon-manager.js.map +1 -0
  140. package/dist/cli/commands/codebase/index.d.ts +3 -0
  141. package/dist/cli/commands/codebase/index.d.ts.map +1 -0
  142. package/dist/cli/commands/codebase/index.js +130 -0
  143. package/dist/cli/commands/codebase/index.js.map +1 -0
  144. package/dist/cli/commands/hook.d.ts.map +1 -1
  145. package/dist/cli/commands/hook.js +15 -2
  146. package/dist/cli/commands/hook.js.map +1 -1
  147. package/dist/cli/commands/install.js +2 -2
  148. package/dist/cli/commands/install.js.map +1 -1
  149. package/dist/cli/commands/profile/display.d.ts.map +1 -1
  150. package/dist/cli/commands/profile/display.js +1 -0
  151. package/dist/cli/commands/profile/display.js.map +1 -1
  152. package/dist/cli/commands/profile/index.d.ts +14 -0
  153. package/dist/cli/commands/profile/index.d.ts.map +1 -1
  154. package/dist/cli/commands/profile/index.js +110 -27
  155. package/dist/cli/commands/profile/index.js.map +1 -1
  156. package/dist/cli/commands/proxy/connectors/desktop-managed-mcp-servers.json +1 -1
  157. package/dist/cli/commands/proxy/connectors/desktop.d.ts +4 -6
  158. package/dist/cli/commands/proxy/connectors/desktop.d.ts.map +1 -1
  159. package/dist/cli/commands/proxy/connectors/desktop.js +112 -25
  160. package/dist/cli/commands/proxy/connectors/desktop.js.map +1 -1
  161. package/dist/cli/commands/proxy/daemon-manager.d.ts +1 -0
  162. package/dist/cli/commands/proxy/daemon-manager.d.ts.map +1 -1
  163. package/dist/cli/commands/proxy/daemon-manager.js +2 -0
  164. package/dist/cli/commands/proxy/daemon-manager.js.map +1 -1
  165. package/dist/cli/commands/proxy/index.d.ts.map +1 -1
  166. package/dist/cli/commands/proxy/index.js +42 -0
  167. package/dist/cli/commands/proxy/index.js.map +1 -1
  168. package/dist/cli/commands/sdk/assistants.d.ts +3 -0
  169. package/dist/cli/commands/sdk/assistants.d.ts.map +1 -0
  170. package/dist/cli/commands/sdk/assistants.js +211 -0
  171. package/dist/cli/commands/sdk/assistants.js.map +1 -0
  172. package/dist/cli/commands/sdk/categories.d.ts +3 -0
  173. package/dist/cli/commands/sdk/categories.d.ts.map +1 -0
  174. package/dist/cli/commands/sdk/categories.js +186 -0
  175. package/dist/cli/commands/sdk/categories.js.map +1 -0
  176. package/dist/cli/commands/sdk/datasources.d.ts +3 -0
  177. package/dist/cli/commands/sdk/datasources.d.ts.map +1 -0
  178. package/dist/cli/commands/sdk/datasources.js +276 -0
  179. package/dist/cli/commands/sdk/datasources.js.map +1 -0
  180. package/dist/cli/commands/sdk/index.d.ts +3 -0
  181. package/dist/cli/commands/sdk/index.d.ts.map +1 -0
  182. package/dist/cli/commands/sdk/index.js +23 -0
  183. package/dist/cli/commands/sdk/index.js.map +1 -0
  184. package/dist/cli/commands/sdk/integrations.d.ts +3 -0
  185. package/dist/cli/commands/sdk/integrations.d.ts.map +1 -0
  186. package/dist/cli/commands/sdk/integrations.js +220 -0
  187. package/dist/cli/commands/sdk/integrations.js.map +1 -0
  188. package/dist/cli/commands/sdk/llm.d.ts +3 -0
  189. package/dist/cli/commands/sdk/llm.d.ts.map +1 -0
  190. package/dist/cli/commands/sdk/llm.js +48 -0
  191. package/dist/cli/commands/sdk/llm.js.map +1 -0
  192. package/dist/cli/commands/sdk/services/assistants.d.ts +13 -0
  193. package/dist/cli/commands/sdk/services/assistants.d.ts.map +1 -0
  194. package/dist/cli/commands/sdk/services/assistants.js +60 -0
  195. package/dist/cli/commands/sdk/services/assistants.js.map +1 -0
  196. package/dist/cli/commands/sdk/services/categories.d.ts +8 -0
  197. package/dist/cli/commands/sdk/services/categories.d.ts.map +1 -0
  198. package/dist/cli/commands/sdk/services/categories.js +19 -0
  199. package/dist/cli/commands/sdk/services/categories.js.map +1 -0
  200. package/dist/cli/commands/sdk/services/datasources.d.ts +33 -0
  201. package/dist/cli/commands/sdk/services/datasources.d.ts.map +1 -0
  202. package/dist/cli/commands/sdk/services/datasources.js +268 -0
  203. package/dist/cli/commands/sdk/services/datasources.js.map +1 -0
  204. package/dist/cli/commands/sdk/services/index.d.ts +6 -0
  205. package/dist/cli/commands/sdk/services/index.d.ts.map +1 -0
  206. package/dist/cli/commands/sdk/services/index.js +6 -0
  207. package/dist/cli/commands/sdk/services/index.js.map +1 -0
  208. package/dist/cli/commands/sdk/services/integrations.d.ts +27 -0
  209. package/dist/cli/commands/sdk/services/integrations.d.ts.map +1 -0
  210. package/dist/cli/commands/sdk/services/integrations.js +59 -0
  211. package/dist/cli/commands/sdk/services/integrations.js.map +1 -0
  212. package/dist/cli/commands/sdk/services/llm.d.ts +4 -0
  213. package/dist/cli/commands/sdk/services/llm.d.ts.map +1 -0
  214. package/dist/cli/commands/sdk/services/llm.js +7 -0
  215. package/dist/cli/commands/sdk/services/llm.js.map +1 -0
  216. package/dist/cli/commands/sdk/services/skills.d.ts +23 -0
  217. package/dist/cli/commands/sdk/services/skills.d.ts.map +1 -0
  218. package/dist/cli/commands/sdk/services/skills.js +69 -0
  219. package/dist/cli/commands/sdk/services/skills.js.map +1 -0
  220. package/dist/cli/commands/sdk/services/users.d.ts +4 -0
  221. package/dist/cli/commands/sdk/services/users.d.ts.map +1 -0
  222. package/dist/cli/commands/sdk/services/users.js +7 -0
  223. package/dist/cli/commands/sdk/services/users.js.map +1 -0
  224. package/dist/cli/commands/sdk/services/workflows.d.ts +7 -0
  225. package/dist/cli/commands/sdk/services/workflows.d.ts.map +1 -0
  226. package/dist/cli/commands/sdk/services/workflows.js +34 -0
  227. package/dist/cli/commands/sdk/services/workflows.js.map +1 -0
  228. package/dist/cli/commands/sdk/skills.d.ts +3 -0
  229. package/dist/cli/commands/sdk/skills.d.ts.map +1 -0
  230. package/dist/cli/commands/sdk/skills.js +492 -0
  231. package/dist/cli/commands/sdk/skills.js.map +1 -0
  232. package/dist/cli/commands/sdk/users.d.ts +3 -0
  233. package/dist/cli/commands/sdk/users.d.ts.map +1 -0
  234. package/dist/cli/commands/sdk/users.js +81 -0
  235. package/dist/cli/commands/sdk/users.js.map +1 -0
  236. package/dist/cli/commands/sdk/utils/cli-utils.d.ts +35 -0
  237. package/dist/cli/commands/sdk/utils/cli-utils.d.ts.map +1 -0
  238. package/dist/cli/commands/sdk/utils/cli-utils.js +110 -0
  239. package/dist/cli/commands/sdk/utils/cli-utils.js.map +1 -0
  240. package/dist/cli/commands/sdk/utils/datasource-types.d.ts +9 -0
  241. package/dist/cli/commands/sdk/utils/datasource-types.d.ts.map +1 -0
  242. package/dist/cli/commands/sdk/utils/datasource-types.js +61 -0
  243. package/dist/cli/commands/sdk/utils/datasource-types.js.map +1 -0
  244. package/dist/cli/commands/sdk/utils/file-utils.d.ts +8 -0
  245. package/dist/cli/commands/sdk/utils/file-utils.d.ts.map +1 -0
  246. package/dist/cli/commands/sdk/utils/file-utils.js +21 -0
  247. package/dist/cli/commands/sdk/utils/file-utils.js.map +1 -0
  248. package/dist/cli/commands/sdk/utils/render.d.ts +82 -0
  249. package/dist/cli/commands/sdk/utils/render.d.ts.map +1 -0
  250. package/dist/cli/commands/sdk/utils/render.js +149 -0
  251. package/dist/cli/commands/sdk/utils/render.js.map +1 -0
  252. package/dist/cli/commands/sdk/workflows.d.ts +3 -0
  253. package/dist/cli/commands/sdk/workflows.d.ts.map +1 -0
  254. package/dist/cli/commands/sdk/workflows.js +170 -0
  255. package/dist/cli/commands/sdk/workflows.js.map +1 -0
  256. package/dist/cli/commands/setup.js +1 -1
  257. package/dist/cli/commands/setup.js.map +1 -1
  258. package/dist/cli/commands/shared/agent-targets.d.ts +10 -0
  259. package/dist/cli/commands/shared/agent-targets.d.ts.map +1 -0
  260. package/dist/cli/commands/shared/agent-targets.js +220 -0
  261. package/dist/cli/commands/shared/agent-targets.js.map +1 -0
  262. package/dist/cli/commands/shared/prompts/storage-scope.d.ts.map +1 -1
  263. package/dist/cli/commands/shared/prompts/storage-scope.js +9 -2
  264. package/dist/cli/commands/shared/prompts/storage-scope.js.map +1 -1
  265. package/dist/cli/commands/shared/selection/ui.d.ts +22 -0
  266. package/dist/cli/commands/shared/selection/ui.d.ts.map +1 -1
  267. package/dist/cli/commands/shared/selection/ui.js +34 -0
  268. package/dist/cli/commands/shared/selection/ui.js.map +1 -1
  269. package/dist/cli/commands/skills/lib/skills-metrics.d.ts.map +1 -1
  270. package/dist/cli/commands/skills/lib/skills-metrics.js +47 -11
  271. package/dist/cli/commands/skills/lib/skills-metrics.js.map +1 -1
  272. package/dist/cli/commands/skills/setup/generators/codex-skill-generator.d.ts +4 -0
  273. package/dist/cli/commands/skills/setup/generators/codex-skill-generator.d.ts.map +1 -0
  274. package/dist/cli/commands/skills/setup/generators/codex-skill-generator.js +51 -0
  275. package/dist/cli/commands/skills/setup/generators/codex-skill-generator.js.map +1 -0
  276. package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.d.ts +4 -0
  277. package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.d.ts.map +1 -0
  278. package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.js +51 -0
  279. package/dist/cli/commands/skills/setup/generators/gemini-skill-generator.js.map +1 -0
  280. package/dist/cli/commands/skills/setup/helpers.d.ts +3 -2
  281. package/dist/cli/commands/skills/setup/helpers.d.ts.map +1 -1
  282. package/dist/cli/commands/skills/setup/helpers.js +31 -6
  283. package/dist/cli/commands/skills/setup/helpers.js.map +1 -1
  284. package/dist/cli/commands/skills/setup/index.d.ts +2 -1
  285. package/dist/cli/commands/skills/setup/index.d.ts.map +1 -1
  286. package/dist/cli/commands/skills/setup/index.js +14 -11
  287. package/dist/cli/commands/skills/setup/index.js.map +1 -1
  288. package/dist/cli/commands/skills/setup/selection/ui.d.ts.map +1 -1
  289. package/dist/cli/commands/skills/setup/selection/ui.js +8 -13
  290. package/dist/cli/commands/skills/setup/selection/ui.js.map +1 -1
  291. package/dist/cli/commands/test-metrics.js +3 -4
  292. package/dist/cli/commands/test-metrics.js.map +1 -1
  293. package/dist/cli/index.js +5 -0
  294. package/dist/cli/index.js.map +1 -1
  295. package/dist/env/types.d.ts +2 -0
  296. package/dist/env/types.d.ts.map +1 -1
  297. package/dist/env/types.js.map +1 -1
  298. package/dist/frameworks/plugins/bmad.plugin.d.ts +10 -1
  299. package/dist/frameworks/plugins/bmad.plugin.d.ts.map +1 -1
  300. package/dist/frameworks/plugins/bmad.plugin.js +108 -9
  301. package/dist/frameworks/plugins/bmad.plugin.js.map +1 -1
  302. package/dist/frameworks/plugins/codebase-memory.plugin.d.ts +18 -0
  303. package/dist/frameworks/plugins/codebase-memory.plugin.d.ts.map +1 -0
  304. package/dist/frameworks/plugins/codebase-memory.plugin.js +131 -0
  305. package/dist/frameworks/plugins/codebase-memory.plugin.js.map +1 -0
  306. package/dist/frameworks/plugins/index.d.ts +1 -0
  307. package/dist/frameworks/plugins/index.d.ts.map +1 -1
  308. package/dist/frameworks/plugins/index.js +3 -0
  309. package/dist/frameworks/plugins/index.js.map +1 -1
  310. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts +1 -1
  311. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +4 -4
  312. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
  313. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +20 -0
  314. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -0
  315. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +104 -0
  316. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -0
  317. package/dist/providers/plugins/sso/proxy/plugins/gateway-key.plugin.d.ts.map +1 -1
  318. package/dist/providers/plugins/sso/proxy/plugins/gateway-key.plugin.js +24 -3
  319. package/dist/providers/plugins/sso/proxy/plugins/gateway-key.plugin.js.map +1 -1
  320. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +5 -0
  321. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
  322. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +3 -1
  323. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  324. package/dist/providers/plugins/sso/proxy/plugins/index.js +5 -1
  325. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  326. package/dist/providers/plugins/sso/proxy/plugins/logging.plugin.js +10 -3
  327. package/dist/providers/plugins/sso/proxy/plugins/logging.plugin.js.map +1 -1
  328. package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.d.ts.map +1 -1
  329. package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.js +26 -8
  330. package/dist/providers/plugins/sso/proxy/plugins/sso.session-sync.plugin.js.map +1 -1
  331. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
  332. package/dist/providers/plugins/sso/proxy/sso.proxy.js +21 -4
  333. package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
  334. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  335. package/dist/providers/plugins/sso/session/SessionSyncer.js +5 -72
  336. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  337. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.d.ts +1 -1
  338. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.d.ts.map +1 -1
  339. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.js +95 -4
  340. package/dist/providers/plugins/sso/session/processors/conversations/apiClient.js.map +1 -1
  341. package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts +2 -2
  342. package/dist/providers/plugins/sso/session/processors/conversations/constants.d.ts.map +1 -1
  343. package/dist/providers/plugins/sso/session/processors/conversations/constants.js +2 -2
  344. package/dist/providers/plugins/sso/session/processors/conversations/constants.js.map +1 -1
  345. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.d.ts.map +1 -1
  346. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +85 -21
  347. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
  348. package/dist/providers/plugins/sso/session/processors/conversations/types.d.ts +10 -2
  349. package/dist/providers/plugins/sso/session/processors/conversations/types.d.ts.map +1 -1
  350. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts +1 -1
  351. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.d.ts.map +1 -1
  352. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js +80 -46
  353. package/dist/providers/plugins/sso/session/processors/metrics/metrics-aggregator.js.map +1 -1
  354. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts +1 -9
  355. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.d.ts.map +1 -1
  356. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js +94 -30
  357. package/dist/providers/plugins/sso/session/processors/metrics/metrics-api-client.js.map +1 -1
  358. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts +4 -6
  359. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts.map +1 -1
  360. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js +24 -25
  361. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js.map +1 -1
  362. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.d.ts.map +1 -1
  363. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js +140 -99
  364. package/dist/providers/plugins/sso/session/processors/metrics/metrics-sync-processor.js.map +1 -1
  365. package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts +11 -3
  366. package/dist/providers/plugins/sso/session/processors/metrics/metrics-types.d.ts.map +1 -1
  367. package/dist/providers/plugins/sso/sso.auth.d.ts.map +1 -1
  368. package/dist/providers/plugins/sso/sso.auth.js +22 -4
  369. package/dist/providers/plugins/sso/sso.auth.js.map +1 -1
  370. package/dist/providers/plugins/sso/sso.setup-steps.js +2 -2
  371. package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -1
  372. package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.d.ts.map +1 -1
  373. package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.js +4 -1
  374. package/dist/telemetry/clients/claude-desktop/claude-desktop.paths.js.map +1 -1
  375. package/dist/telemetry/runtime/DesktopTelemetryRuntime.d.ts.map +1 -1
  376. package/dist/telemetry/runtime/DesktopTelemetryRuntime.js +1 -3
  377. package/dist/telemetry/runtime/DesktopTelemetryRuntime.js.map +1 -1
  378. package/dist/utils/browser.d.ts +7 -0
  379. package/dist/utils/browser.d.ts.map +1 -0
  380. package/dist/utils/browser.js +10 -0
  381. package/dist/utils/browser.js.map +1 -0
  382. package/dist/utils/config.d.ts.map +1 -1
  383. package/dist/utils/config.js +7 -1
  384. package/dist/utils/config.js.map +1 -1
  385. package/dist/utils/paths.d.ts +8 -0
  386. package/dist/utils/paths.d.ts.map +1 -1
  387. package/dist/utils/paths.js +15 -0
  388. package/dist/utils/paths.js.map +1 -1
  389. package/package.json +2 -1
  390. package/scripts/compare-codex-conversations.mjs +894 -0
  391. package/scripts/validate-secrets.js +7 -3
  392. package/dist/agents/plugins/claude/plugin/claude-templates/README.md +0 -539
  393. package/dist/agents/plugins/claude/plugin/claude-templates/templates/CLAUDE.md.template +0 -252
  394. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/code-review-agent-template.md.template +0 -433
  395. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/refactor-cleaner-agent.md.template +0 -337
  396. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/solution-architect-agent.md.template +0 -197
  397. package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/unit-tester-agent.md.template +0 -258
  398. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/api/api-patterns.md.template +0 -179
  399. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/architecture.md.template +0 -197
  400. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/data/database-patterns.md.template +0 -248
  401. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/development/development-practices.md.template +0 -298
  402. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/integration/external-integrations.md.template +0 -160
  403. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/security/security-practices.md.template +0 -295
  404. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/code-quality.md.template +0 -186
  405. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/git-workflow.md.template +0 -177
  406. package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/testing/testing-patterns.md.template +0 -315
  407. package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +0 -522
  408. package/dist/agents/plugins/claude/plugin/commands/handoff.md +0 -56
  409. package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +0 -549
  410. package/dist/agents/plugins/claude/plugin/scripts/bash/rtk-baseline.sh +0 -39
  411. package/dist/agents/plugins/claude/plugin/scripts/bash/rtk-rewrite.sh +0 -101
  412. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/SKILL.md +0 -206
  413. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-agent.md +0 -45
  414. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-claude-md-snippet.md +0 -40
  415. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-command.md +0 -30
  416. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-hooks.json +0 -23
  417. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/bad-skill.md +0 -48
  418. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-agent.md +0 -145
  419. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-claude-md-snippet.md +0 -126
  420. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-command.md +0 -170
  421. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-hooks.json +0 -46
  422. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/good-skill.md +0 -144
  423. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/examples/sample-report.md +0 -223
  424. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/references/best-practices.md +0 -510
  425. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/references/component-checklists.md +0 -413
  426. package/dist/agents/plugins/claude/plugin/skills/claude-setup-audit/scripts/scan-repo.sh +0 -162
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * inspect-schema.js <data-dir>
4
+ *
5
+ * Reads all .json files in <data-dir> and prints a compact schema to stdout.
6
+ * Designed to give Claude enough structural information to write data extraction
7
+ * code without reading raw API responses into the conversation context.
8
+ *
9
+ * Output format (per file):
10
+ * - primitives: "number" | "boolean" | "string ~ 'sample'"
11
+ * - arrays: { _type: "array", _count: N, _item: <item-schema> }
12
+ * - objects: { key: <schema>, ... }
13
+ * - null fields: "null" or "<type> | null" when nullable across samples
14
+ *
15
+ * Usage:
16
+ * node inspect-schema.js /tmp/codemie-analytics-20260507/
17
+ */
18
+
19
+ import { readFileSync, writeFileSync, readdirSync } from 'fs';
20
+ import { join } from 'path';
21
+
22
+ const MAX_STRING_PREVIEW = 50;
23
+ const NULL_CHECK_SAMPLES = 5;
24
+ // For type-diversity detection: scan all items in small arrays, first N in large ones.
25
+ const TYPE_CHECK_SAMPLES = 20;
26
+
27
+ // Fields whose complete vocabulary is always emitted regardless of array context.
28
+ const ALWAYS_ENUMERATE = new Set([
29
+ 'type', 'format', 'classification', 'tier_name',
30
+ 'weekday', 'range', 'client_name', 'dimension_id',
31
+ ]);
32
+
33
+ // Values containing these chars are entity/path identifiers, not vocabulary — skip them.
34
+ const ENTITY_VALUE_RE = /[@/]/;
35
+
36
+ // UUID-shaped strings are entity IDs, not vocabulary.
37
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-/i;
38
+
39
+ /**
40
+ * Returns the set of fields in itemSchema that should be fully enumerated.
41
+ *
42
+ * Rules:
43
+ * - ALWAYS_ENUMERATE fields: always included.
44
+ * - 'id': only when the parent item has a 'label' key (metrics or columns context),
45
+ * ensuring we capture metric/column identifiers without enumerating entity IDs.
46
+ */
47
+ function getEnumerableFields(itemSchema) {
48
+ const keys = new Set();
49
+ for (const key of Object.keys(itemSchema)) {
50
+ if (ALWAYS_ENUMERATE.has(key)) keys.add(key);
51
+ }
52
+ if ('id' in itemSchema && 'label' in itemSchema) {
53
+ keys.add('id');
54
+ }
55
+ return keys;
56
+ }
57
+
58
+ /**
59
+ * Returns the bare type category of an already-inferred schema string.
60
+ * e.g. "string ~ 'foo'" → "string", "number" → "number", "null" → "null"
61
+ */
62
+ function typeCategory(schema) {
63
+ if (schema === 'null') return 'null';
64
+ if (schema === 'number' || schema === 'boolean') return schema;
65
+ if (typeof schema === 'string' && schema.startsWith('string')) return 'string';
66
+ if (schema && typeof schema === 'object' && schema._type === 'array') return 'array';
67
+ if (schema && typeof schema === 'object') return 'object';
68
+ return String(schema);
69
+ }
70
+
71
+ function infer(value) {
72
+ if (value === null || value === undefined) return 'null';
73
+
74
+ const t = typeof value;
75
+
76
+ if (t === 'boolean') return 'boolean';
77
+ if (t === 'number') return 'number';
78
+
79
+ if (t === 'string') {
80
+ const preview = value.length > MAX_STRING_PREVIEW
81
+ ? value.slice(0, MAX_STRING_PREVIEW) + '...'
82
+ : value;
83
+ return `string ~ '${preview}'`;
84
+ }
85
+
86
+ if (Array.isArray(value)) {
87
+ if (value.length === 0) return { _type: 'array', _count: 0, _item: 'unknown' };
88
+
89
+ const itemSchema = infer(value[0]);
90
+
91
+ // Scan multiple items to detect nullable fields AND type diversity.
92
+ // For small arrays scan everything; for large ones sample the first N.
93
+ if (
94
+ itemSchema !== null &&
95
+ typeof itemSchema === 'object' &&
96
+ !Array.isArray(itemSchema) &&
97
+ value.length > 1
98
+ ) {
99
+ const sampleSize = Math.min(
100
+ Math.max(NULL_CHECK_SAMPLES, TYPE_CHECK_SAMPLES),
101
+ value.length
102
+ );
103
+ const samples = value.slice(0, sampleSize);
104
+
105
+ for (const key of Object.keys(itemSchema)) {
106
+ if (typeof itemSchema[key] !== 'string') continue; // skip nested objects/arrays
107
+ if (itemSchema[key] === 'null') continue;
108
+
109
+ const baseCategory = typeCategory(itemSchema[key]);
110
+ const seenCategories = new Set([baseCategory]);
111
+
112
+ for (const sample of samples.slice(1)) {
113
+ const v = sample[key];
114
+ if (v === null || v === undefined) {
115
+ seenCategories.add('null');
116
+ } else {
117
+ seenCategories.add(typeCategory(infer(v)));
118
+ }
119
+ }
120
+
121
+ const nonNullTypes = [...seenCategories].filter(c => c !== 'null');
122
+ const hasNull = seenCategories.has('null') || itemSchema[key].includes('| null');
123
+
124
+ if (nonNullTypes.length > 1) {
125
+ // Multiple distinct types observed — drop string preview, show union
126
+ itemSchema[key] = nonNullTypes.join(' | ') + (hasNull ? ' | null' : '');
127
+ } else if (hasNull && !itemSchema[key].includes('| null')) {
128
+ itemSchema[key] += ' | null';
129
+ }
130
+ }
131
+
132
+ // Pass 2: enumerate vocabulary fields across ALL items
133
+ const enumerableFields = getEnumerableFields(itemSchema);
134
+ for (const key of enumerableFields) {
135
+ if (typeof itemSchema[key] !== 'string') continue;
136
+ if (!itemSchema[key].startsWith('string')) continue;
137
+
138
+ const uniqueVals = new Set();
139
+ for (const item of value) {
140
+ const v = item[key];
141
+ if (typeof v === 'string' && !UUID_RE.test(v) && !ENTITY_VALUE_RE.test(v)) {
142
+ uniqueVals.add(v);
143
+ }
144
+ }
145
+
146
+ // Always-enumerate fields emit even a single observed value; id requires ≥ 2.
147
+ const minUnique = ALWAYS_ENUMERATE.has(key) ? 1 : 2;
148
+ if (uniqueVals.size >= minUnique && uniqueVals.size <= 50) {
149
+ const sorted = [...uniqueVals].sort();
150
+ const preview = sorted.map(v => `'${v}'`).join(' | ');
151
+ const nullable = itemSchema[key].includes('| null');
152
+ itemSchema[key] = `string (enum) ~ ${preview}${nullable ? ' | null' : ''}`;
153
+ }
154
+ }
155
+ }
156
+
157
+ return { _type: 'array', _count: value.length, _item: itemSchema };
158
+ }
159
+
160
+ if (t === 'object') {
161
+ const schema = {};
162
+ for (const [k, v] of Object.entries(value)) {
163
+ schema[k] = infer(v);
164
+ }
165
+ return schema;
166
+ }
167
+
168
+ return t;
169
+ }
170
+
171
+ function processFile(filePath) {
172
+ let raw;
173
+ try {
174
+ raw = JSON.parse(readFileSync(filePath, 'utf8'));
175
+ } catch (e) {
176
+ return { _error: `Failed to parse: ${e.message}` };
177
+ }
178
+ return infer(raw);
179
+ }
180
+
181
+ const dataDir = process.argv[2];
182
+
183
+ if (!dataDir) {
184
+ console.error('Usage: node inspect-schema.js <data-dir>');
185
+ process.exit(1);
186
+ }
187
+
188
+ let files;
189
+ try {
190
+ files = readdirSync(dataDir).filter(f => f.endsWith('.json') && !f.endsWith('.schema.json')).sort();
191
+ } catch (e) {
192
+ console.error(`Cannot read directory: ${dataDir}\n${e.message}`);
193
+ process.exit(1);
194
+ }
195
+
196
+ if (files.length === 0) {
197
+ console.error(`No .json files found in: ${dataDir}`);
198
+ process.exit(1);
199
+ }
200
+
201
+ const written = [];
202
+ for (const file of files) {
203
+ const schema = processFile(join(dataDir, file));
204
+ const schemaFile = file.replace(/\.json$/, '.schema.json');
205
+ const schemaPath = join(dataDir, schemaFile);
206
+ writeFileSync(schemaPath, JSON.stringify(schema, null, 2));
207
+ written.push(` ✓ ${schemaFile}`);
208
+ }
209
+
210
+ console.log(`Schemas written to: ${dataDir}`);
211
+ console.log(written.join('\n'));
@@ -0,0 +1,39 @@
1
+ # CodeMie HTML Report — Style Guide
2
+
3
+ ## CSS Bundle
4
+
5
+ `css/bundle.css` is a pre-built, minified concatenation of all 8 design-system CSS files.
6
+ It is committed to the repo so report generation requires no build step at runtime.
7
+
8
+ **Do not edit `bundle.css` directly.** Edit the individual source files instead, then rebuild.
9
+
10
+ ### Source files (order matters)
11
+
12
+ | File | What it covers |
13
+ |------|---------------|
14
+ | `css/tokens.css` | CSS custom properties — colors, spacing, radii, shadows, gradients |
15
+ | `css/base.css` | Reset, body, scrollbar, code blocks, links, focus ring |
16
+ | `css/typography.css` | Headings h1–h6, text size/weight/color utilities |
17
+ | `css/buttons.css` | All button variants and sizes |
18
+ | `css/forms.css` | input, textarea, select, checkbox, radio, switch |
19
+ | `css/components.css` | card, badge, alert, avatar, stat-card, chip, empty-state, etc. |
20
+ | `css/layout.css` | table, tabs, pagination, modal, nav-sidebar, app-shell |
21
+ | `css/utilities.css` | flex, grid, gap, padding, margin, width, overflow, border |
22
+
23
+ ### Rebuilding bundle.css
24
+
25
+ Run this command from the repo root whenever any source CSS file changes:
26
+
27
+ ```bash
28
+ npx clean-css-cli -o src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/bundle.css \
29
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/tokens.css \
30
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/base.css \
31
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/typography.css \
32
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/buttons.css \
33
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/forms.css \
34
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/components.css \
35
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/layout.css \
36
+ src/agents/plugins/claude/plugin/skills/codemie-html-report/style-guide/css/utilities.css
37
+ ```
38
+
39
+ Commit the updated `bundle.css` alongside the source CSS change.
@@ -17,32 +17,49 @@ description: >
17
17
 
18
18
  You are building a standalone HTML page that visually matches the CodeMie (EPAM AI/Run) product UI. The design system is a dark-first, professional theme with Inter font, subtle borders, and semantic color tokens. Every page you produce should feel like a native screen of the CodeMie platform.
19
19
 
20
- ## Step 1 — Read the CSS files
20
+ ## Step 1 — CSS placeholder
21
21
 
22
- Read **all 8 CSS files** from `${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/style-guide/css/` you will inline them all:
22
+ **Do NOT read any CSS files. Do NOT inline any CSS yourself.**
23
23
 
24
- | File | What it covers |
25
- |------|---------------|
26
- | `tokens.css` | All CSS custom properties (colors, spacing, radii, shadows, gradients) |
27
- | `base.css` | Reset, body, scrollbar, code blocks, links, focus ring |
28
- | `typography.css` | Headings h1-h6, text size/weight/color utilities |
29
- | `buttons.css` | btn-primary, btn-secondary, btn-base, btn-delete, btn-tertiary, btn-magical, sizes |
30
- | `forms.css` | input, textarea, select, checkbox, radio, switch |
31
- | `components.css` | card, badge, tag, alert, avatar, spinner, progress, tooltip, stat-card, chip, empty-state |
32
- | `layout.css` | table, tabs, pagination, modal, nav-sidebar, app-shell |
33
- | `utilities.css` | flex, grid, gap, padding, margin, width, overflow, position, border, shadow |
24
+ In the `<style>` block write exactly this one token as the only content:
34
25
 
35
- All files are located at: `${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/style-guide/css/<filename>`
26
+ ```css
27
+ /* __CODEMIE_CSS__ */
28
+ ```
36
29
 
37
- ## Step 2Page skeleton (fully self-contained)
30
+ A post-processing script will replace this token with the full design system CSS after you write the file. All component classes are documented in Steps 3 and 4 use them freely without reading the source files.
31
+
32
+ ## Step 1.5 — Data placeholders (analytics pipeline only — skip for standalone use)
38
33
 
39
- **CRITICAL: Every HTML file you produce must be a single self-contained file.** Do NOT use `<link>` tags pointing to external `.css` files. Instead, inline the entire CodeMie design system directly inside a `<style>` block.
34
+ > **Backwards compatibility:** This step applies **only** when this skill is invoked
35
+ > from the **codemie-analytics** skill as part of its report pipeline. If you are
36
+ > generating a standalone HTML page directly for a user request, **skip this step
37
+ > entirely** and embed any data inline as regular JS variables.
40
38
 
41
- Workflow:
42
- 1. Read all 8 CSS files from `${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/style-guide/css/`.
43
- 2. Concatenate their contents in order: tokens base → typography → buttons → forms → components → layout → utilities.
44
- 3. Paste the full concatenated CSS into the `<style>` tag in `<head>`.
45
- 4. Keep the `@import url('https://fonts.googleapis.com/...')` line from `tokens.css` at the very top of the `<style>` block (Google Fonts CDN is acceptable as an external dependency).
39
+ When invoked from **codemie-analytics**, all JS data arrays must use
40
+ `/*__DATA:name__*/` placeholders instead of inline values. The analytics skill's
41
+ `inject-data.js` step replaces these after the HTML file is written.
42
+
43
+ ```html
44
+ <script>
45
+ /* Data is injected by inject-data.js after this file is written — do NOT hardcode arrays */
46
+ const LEADERBOARD = /*__DATA:leaderboard-top__*/;
47
+ const SUMMARIES = /*__DATA:summaries__*/;
48
+ const LLM_DATA = /*__DATA:llms-usage__*/;
49
+ </script>
50
+ ```
51
+
52
+ Rules for analytics-pipeline placeholders:
53
+ - **The placeholder name must exactly match the JSON filename without the `.json` extension.**
54
+ `/*__DATA:leaderboard-top__*/` is only replaced when `leaderboard-top.json` exists.
55
+ Wrong name → the placeholder is silently skipped by `inject-data.js`.
56
+ - Every JS variable populated from an API response must use a placeholder.
57
+ - Hardcoded lookup tables (tier colours, dimension labels, etc.) are fine as regular JS.
58
+ - **Never mix placeholders with inline data** in the same variable declaration.
59
+
60
+ ## Step 2 — Page skeleton (fully self-contained)
61
+
62
+ **CRITICAL: Every HTML file you produce must be a single self-contained file.** Do NOT use `<link>` tags. Write the `/* __CODEMIE_CSS__ */` placeholder in the `<style>` block — the inject-css.js script will inline the full design system CSS after you write the file.
46
63
 
47
64
  ```html
48
65
  <!DOCTYPE html>
@@ -52,12 +69,7 @@ Workflow:
52
69
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
53
70
  <title>PAGE TITLE</title>
54
71
  <style>
55
- /* === CodeMie Design System — inlined for portability === */
56
- @import url('https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500&display=swap');
57
-
58
- /* PASTE FULL CONTENTS OF: tokens.css, base.css, typography.css,
59
- buttons.css, forms.css, components.css, layout.css, utilities.css */
60
-
72
+ /* __CODEMIE_CSS__ */
61
73
  /* === Page-specific styles (use CSS variables, not hex colors) === */
62
74
  </style>
63
75
  </head>
@@ -271,3 +283,82 @@ body.p-6 > .container
271
283
  ```
272
284
 
273
285
  This pattern matches the analytics dashboard layout in the live CodeMie product and works for most reporting use cases.
286
+
287
+ ## Final Step — Inject CSS
288
+
289
+ After writing the HTML file, run this command to replace the placeholder with the full
290
+ design system bundle and make the report self-contained:
291
+
292
+ ```bash
293
+ node ${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/scripts/inject-css.js <path-to-the-html-file-you-just-wrote>
294
+ ```
295
+
296
+ For example:
297
+ ```bash
298
+ node ${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/scripts/inject-css.js reports/leaderboard-2026-Q1.html
299
+ ```
300
+
301
+ Expected output: `✓ CSS injected into reports/leaderboard-2026-Q1.html`
302
+
303
+ ## Final Step — Inject Data (analytics pipeline only — skip for standalone use)
304
+
305
+ > This step applies **only** when invoked from the **codemie-analytics** skill. Standalone
306
+ > HTML generation embeds data inline and must skip this step.
307
+
308
+ After the HTML file is written, run `inject-data.js` to replace every `/*__DATA:name__*/`
309
+ placeholder with the matching JSON file from the temp directory:
310
+
311
+ ```bash
312
+ node ${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/scripts/inject-data.js \
313
+ <path-to-html> <temp-dir>
314
+ ```
315
+
316
+ For example:
317
+ ```bash
318
+ node ${CLAUDE_PLUGIN_ROOT}/skills/codemie-html-report/scripts/inject-data.js \
319
+ reports/2026-05-07-leaderboard/leaderboard.html \
320
+ reports/2026-05-07-leaderboard/temp/
321
+ ```
322
+
323
+ **Placeholder names must exactly match the JSON filenames** (without `.json`):
324
+ - `/*__DATA:leaderboard-top__*/` is replaced from `leaderboard-top.json`
325
+ - `/*__DATA:summaries__*/` is replaced from `summaries.json`
326
+
327
+ A wrong name means the placeholder is silently skipped. If no placeholders are matched at
328
+ all, the script exits with an error.
329
+
330
+ Expected output:
331
+ ```
332
+ ✓ injected leaderboard-top
333
+ ✓ injected summaries
334
+ ✓ 2 data block(s) injected into reports/2026-05-07-leaderboard/leaderboard.html
335
+ ```
336
+
337
+ **Do not run inject-data.js before the HTML file exists.**
338
+ Run inject-css.js after inject-data.js.
339
+
340
+ ## Final Step — Temp file cleanup (analytics pipeline only — skip for standalone use)
341
+
342
+ > **Backwards compatibility:** This step applies **only** when this skill is invoked
343
+ > from the **codemie-analytics** skill. Standalone HTML generation has no temp
344
+ > directory and must skip this step.
345
+
346
+ After the CSS is injected and the report is complete, **always ask the user**:
347
+
348
+ > The report is ready at `<path>`. The `temp/` directory (`<OUT>`) contains the raw
349
+ > API response files used to build it (~N files). Would you like to delete it?
350
+
351
+ If the user says **yes**, delete the temp directory:
352
+
353
+ ```bash
354
+ rm -rf "<OUT>"
355
+ # e.g. rm -rf "reports/2026-05-07-executive-spending/temp"
356
+ ```
357
+
358
+ Confirm deletion:
359
+ ```
360
+ ✓ Temp files deleted → reports/2026-05-07-executive-spending/temp
361
+ ```
362
+
363
+ If the user says **no** (or does not respond), leave the directory intact and note its
364
+ location so they can inspect or re-use the raw data later.
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
3
+ import { join, dirname, resolve } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+
8
+ const htmlPath = process.argv[2];
9
+
10
+ if (!htmlPath) {
11
+ console.error('Usage: node inject-css.js <path-to-html-file>');
12
+ console.error('Example: node inject-css.js reports/leaderboard-2026-Q1.html');
13
+ process.exit(1);
14
+ }
15
+
16
+ const resolvedHtml = resolve(htmlPath);
17
+ const bundlePath = join(__dirname, '..', 'style-guide', 'css', 'bundle.css');
18
+
19
+ if (!existsSync(resolvedHtml)) {
20
+ console.error(`Error: HTML file not found: ${resolvedHtml}`);
21
+ process.exit(1);
22
+ }
23
+
24
+ if (!existsSync(bundlePath)) {
25
+ console.error(`Error: bundle.css not found at ${bundlePath}`);
26
+ console.error('Rebuild it — see style-guide/README.md for the command.');
27
+ process.exit(1);
28
+ }
29
+
30
+ const html = readFileSync(resolvedHtml, 'utf8');
31
+
32
+ if (!html.includes('/* __CODEMIE_CSS__ */')) {
33
+ console.error(`Error: placeholder "/* __CODEMIE_CSS__ */" not found in ${resolvedHtml}`);
34
+ console.error('The HTML file must contain: <style>/* __CODEMIE_CSS__ */</style>');
35
+ process.exit(1);
36
+ }
37
+
38
+ const css = readFileSync(bundlePath, 'utf8');
39
+ writeFileSync(resolvedHtml, html.replace('/* __CODEMIE_CSS__ */', css), 'utf8');
40
+ console.log(`✓ CSS injected into ${resolvedHtml}`);
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'fs';
3
+ import { join, resolve, basename, extname } from 'path';
4
+
5
+ const [htmlPath, ...sources] = process.argv.slice(2);
6
+
7
+ if (!htmlPath || sources.length === 0) {
8
+ console.error('Usage: node inject-data.js <path-to-html-file> <json-file-or-dir> [...]');
9
+ console.error('Example: node inject-data.js reports/report.html reports/temp/');
10
+ process.exit(1);
11
+ }
12
+
13
+ const resolvedHtml = resolve(htmlPath);
14
+
15
+ if (!existsSync(resolvedHtml)) {
16
+ console.error(`Error: HTML file not found: ${resolvedHtml}`);
17
+ process.exit(1);
18
+ }
19
+
20
+ // Collect all JSON files from files and/or directories
21
+ const jsonFiles = [];
22
+ for (const src of sources) {
23
+ const resolved = resolve(src);
24
+ if (!existsSync(resolved)) {
25
+ console.error(`Error: source not found: ${resolved}`);
26
+ process.exit(1);
27
+ }
28
+ if (statSync(resolved).isDirectory()) {
29
+ for (const entry of readdirSync(resolved)) {
30
+ if (extname(entry) === '.json' && !entry.endsWith('.schema.json')) jsonFiles.push(join(resolved, entry));
31
+ }
32
+ } else {
33
+ if (extname(resolved) !== '.json') {
34
+ console.error(`Error: not a JSON file: ${resolved}`);
35
+ process.exit(1);
36
+ }
37
+ jsonFiles.push(resolved);
38
+ }
39
+ }
40
+
41
+ if (jsonFiles.length === 0) {
42
+ console.error('Error: no JSON files found in the provided sources');
43
+ process.exit(1);
44
+ }
45
+
46
+ let html = readFileSync(resolvedHtml, 'utf8');
47
+
48
+ let injected = 0;
49
+ for (const jsonFile of jsonFiles) {
50
+ const name = basename(jsonFile, '.json');
51
+ const placeholder = `/*__DATA:${name}__*/`;
52
+ if (!html.includes(placeholder)) {
53
+ console.warn(` warn: no placeholder for "${name}" — skipping`);
54
+ continue;
55
+ }
56
+ const data = readFileSync(jsonFile, 'utf8').trim();
57
+ html = html.replaceAll(placeholder, data);
58
+ console.log(` ✓ injected ${name}`);
59
+ injected++;
60
+ }
61
+
62
+ if (injected === 0) {
63
+ console.error('Error: no placeholders were matched — HTML unchanged');
64
+ process.exit(1);
65
+ }
66
+
67
+ writeFileSync(resolvedHtml, html, 'utf8');
68
+ console.log(`✓ ${injected} data block(s) injected into ${resolvedHtml}`);
@@ -0,0 +1 @@
1
+ @import url(https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:wght@400;500&display=swap);:root{--font-sans:'Inter','Geist',-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif;--font-mono:'JetBrains Mono','GeistMono','Fira Code','Courier New',monospace;--text-xs-1:0.625rem;--text-xs:0.75rem;--text-sm-1:0.813rem;--text-sm:0.875rem;--text-base:1rem;--text-h1:2rem;--text-h2:1.5rem;--text-h3:1rem;--text-h4:0.875rem;--text-h5:0.75rem;--lh-h1:2rem;--lh-h2:1.5rem;--lh-h3:1.3125rem;--lh-h4:1.125rem;--lh-h5:1rem;--radius-sm:4px;--radius-md:6px;--radius-lg:8px;--radius-xl:12px;--radius-2xl:16px;--radius-full:9999px;--space-0-5:0.125rem;--space-1:0.25rem;--space-1-5:0.375rem;--space-2:0.5rem;--space-2-5:0.625rem;--space-3:0.75rem;--space-4:1rem;--space-5:1.25rem;--space-6:1.5rem;--space-8:2rem;--shadow-sm:0 1px 2px rgba(0, 0, 0, 0.4);--shadow-md:0 4px 6px -1px rgba(0, 0, 0, 0.5),0 2px 4px -2px rgba(0, 0, 0, 0.3);--shadow-lg:0 10px 15px -3px rgba(0, 0, 0, 0.6),0 4px 6px -4px rgba(0, 0, 0, 0.4);--shadow-sidebar:-1px 0 0 0 rgba(255, 255, 255, 0.1);--transition-fast:120ms ease;--transition-base:200ms ease;--transition-slow:300ms ease;--navbar-width:72px;--navbar-width-expanded:196px;--sidebar-width:308px;--layout-header-height:56px;--card-height:158px;--z-dropdown:30;--z-sticky:40;--z-modal:50;--z-toast:60}:root,:root.dark{--color-bg-page:#1A1A1A;--color-bg-sidebar:#151515;--color-bg-card:#151515;--color-bg-nav:#000000;--color-bg-elevated:#2E2E2E;--color-bg-secondary:#212224;--color-bg-tertiary:#2E3033;--color-bg-quaternary:#333436;--color-bg-hover:#212224;--color-bg-hover-strong:#333436;--color-bg-input:#1A1A1A;--color-bg-input-prefix:#333436;--color-bg-btn-primary:#20222E;--color-bg-btn-primary-h:#262941;--color-bg-pagination-active:#212224;--color-text-primary:#FFFFFF;--color-text-secondary:#F2F0EF;--color-text-tertiary:#CCCCCC;--color-text-muted:#BBBBBB;--color-text-placeholder:#CCCCCC;--color-text-link:#F2F0EF;--color-text-link-hover:#F2F0EF;--color-text-inverse:#FFFFFF;--color-text-heading:#BBBBBB;--color-text-nav:#CCCCCC;--color-border-primary:#333436;--color-border-secondary:#47484A;--color-border-structural:#333436;--color-border-subtle:#4C4C4C;--color-border-accent:#FFFFFF;--color-border-focus:#FFFFFF;--color-border-error:#F9303C;--color-border-panel:#333436;--color-border-btn-secondary:#333436;--color-border-btn-secondary-h:transparent;--color-icon-primary:#FFFFFF;--color-icon-secondary:#CCCCCC;--color-icon-tertiary:#999999;--color-icon-error:#F9303C;--color-success:#259F4C;--color-success-bg:#1B271F;--color-success-border:#259F4C;--color-success-text:#259F4C;--color-error:#F9303C;--color-error-bg:#262121;--color-error-border:#FE3B4C;--color-error-text:#FE3B4C;--color-warning:#F5A534;--color-warning-bg:#492B00;--color-warning-border:#663B00;--color-warning-text:#F5A534;--color-info:#2297F6;--color-info-bg:#002442;--color-info-border:#003A69;--color-info-text:#2297F6;--color-purple:#C084FC;--color-purple-bg:#2D1B3D;--color-purple-border:#2D1B3D;--color-purple-text:#F3E8FF;--color-cyan:#06B6D4;--color-cyan-bg:#003942;--color-cyan-border:#005866;--status-not-started-text:#A0A0A0;--status-not-started-bg:#333333;--status-not-started-border:#4C4C4C;--status-in-progress-text:#2297F6;--status-in-progress-bg:#002442;--status-in-progress-border:#003A69;--status-pending-text:#06B6D4;--status-pending-bg:#003942;--status-pending-border:#005866;--status-success-text:#259F4C;--status-success-bg:#1B271F;--status-success-border:#259F4C;--status-error-text:#FE3B4C;--status-error-bg:#262121;--status-error-border:#FE3B4C;--status-warning-text:#F5A534;--status-warning-bg:#492B00;--status-warning-border:#663B00;--status-advanced-text:#C084FC;--status-advanced-bg:#2D1B3D;--status-advanced-border:#2D1B3D;--gradient-primary-btn:linear-gradient(90deg, #672D92, #547CCC);--gradient-brand:linear-gradient(152deg, #0078C2, #0047FF, #8453D2);--gradient-magical:linear-gradient(90deg, #672D92, #5677C8);--gradient-purple-radial:radial-gradient(271.77% 163.1% at 50% -10.71%, #200E32 0%, #9E00FF 75.14%, #EC56FF 100%);--gradient-switch-off:linear-gradient(to right, #BBB, #666);--gradient-switch-on:linear-gradient(to right, #672C92, #547CCC);--blue-25:#F1F8FF;--blue-50:#D5E7FC;--blue-100:#B2D7FF;--blue-300:#2297F6;--blue-400:#007AFF;--blue-500:#4E32FF;--blue-550:#0C4DAF;--blue-600:#003A69;--blue-800:#002442}.light{--color-bg-page:#F9F9F9;--color-bg-sidebar:#FBFBFB;--color-bg-card:#FFFFFF;--color-bg-nav:#FBFBFB;--color-bg-elevated:#FFFFFF;--color-bg-secondary:#FFFFFF;--color-bg-tertiary:#FBFBFB;--color-bg-quaternary:#B2D7FF;--color-bg-hover:#D5E7FC;--color-bg-hover-strong:#D5E7FC;--color-bg-input:#FFFFFF;--color-bg-input-prefix:#EEEEEE;--color-bg-btn-primary:#D5E7FC;--color-bg-btn-primary-h:#B2D7FF;--color-bg-pagination-active:#D5E7FC;--color-text-primary:#333333;--color-text-secondary:#333333;--color-text-tertiary:#333333;--color-text-muted:#666666;--color-text-placeholder:#999999;--color-text-link:#007AFF;--color-text-link-hover:#0C4DAF;--color-text-inverse:#FFFFFF;--color-text-heading:#007AFF;--color-text-nav:#FFFFFF;--color-border-primary:#CCCCCC;--color-border-secondary:#BBBBBB;--color-border-structural:#E5E5E5;--color-border-subtle:#999999;--color-border-accent:#007AFF;--color-border-focus:#000000;--color-border-error:#F9303C;--color-border-panel:#E5E5E5;--color-border-btn-secondary:transparent;--color-border-btn-secondary-h:#007AFF;--color-icon-primary:#666666;--color-icon-secondary:#333333;--color-icon-tertiary:#707070;--color-icon-error:#F9303C;--color-success:#259F4C;--color-success-bg:#E6F7E6;--color-success-border:#259F4C;--color-success-text:#259F4C;--color-error:#F9303C;--color-error-bg:#F0E2E3;--color-error-border:#FE3B4C;--color-error-text:#FE3B4C;--color-warning:#F5A534;--color-warning-bg:#FAF2E7;--color-warning-border:#F5A534;--color-warning-text:#F5A534;--color-info:#2297F6;--color-info-bg:#D5E7FC;--color-info-border:#2297F6;--color-info-text:#2297F6;--color-purple:#8B5CF6;--color-purple-bg:#F3E8FF;--color-purple-border:#F3E8FF;--color-purple-text:#C084FC;--color-cyan:#06B6D4;--color-cyan-bg:#DFFAFF;--color-cyan-border:#005866;--status-not-started-text:#A0A0A0;--status-not-started-bg:#EEEEEE;--status-not-started-border:#999999;--status-in-progress-text:#2297F6;--status-in-progress-bg:#D5E7FC;--status-in-progress-border:#2297F6;--status-pending-text:#06B6D4;--status-pending-bg:#DFFAFF;--status-pending-border:#06B6D4;--status-success-text:#259F4C;--status-success-bg:#E6F7E6;--status-success-border:#259F4C;--status-error-text:#FE3B4C;--status-error-bg:#F0E2E3;--status-error-border:#FE3B4C;--status-warning-text:#F5A534;--status-warning-bg:#FAF2E7;--status-warning-border:#F5A534;--status-advanced-text:#8B5CF6;--status-advanced-bg:#F3E8FF;--status-advanced-border:#C084FC;--gradient-primary-btn:linear-gradient(90deg, #3676f7, #cc22f2);--gradient-magical:linear-gradient(90deg, #3676f7, #cc22f2);--gradient-switch-off:linear-gradient(to right, #fff, #fff);--gradient-switch-on:linear-gradient(to right, #007AFF, #007AFF);--shadow-sm:0 1px 2px rgba(0, 0, 0, 0.06);--shadow-md:0 4px 6px -1px rgba(0, 0, 0, 0.08),0 2px 4px -2px rgba(0, 0, 0, 0.06);--shadow-lg:0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -4px rgba(0, 0, 0, 0.08)}*,::after,::before{box-sizing:border-box;margin:0;padding:0}html{font-size:16px;-webkit-text-size-adjust:100%;scroll-behavior:smooth}body{font-family:var(--font-sans);font-size:var(--text-sm);line-height:1.5;color:var(--color-text-primary);background-color:var(--color-bg-page);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a{color:var(--color-text-link);text-decoration:none;transition:color var(--transition-fast)}a:hover{color:var(--color-text-link-hover);text-decoration:underline}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--color-border-subtle);border-radius:var(--radius-full)}::-webkit-scrollbar-thumb:hover{background:var(--color-border-secondary)}::selection{background:rgba(34,151,246,.3);color:var(--color-text-primary)}:focus-visible{outline:2px solid var(--color-border-focus);outline-offset:2px;border-radius:var(--radius-sm)}img,svg,video{display:block;max-width:100%}ol,ul{list-style:none}code,kbd,pre,samp{font-family:var(--font-mono)}code{font-size:.875em;background:var(--color-bg-quaternary);color:var(--color-text-secondary);padding:.1em .4em;border-radius:var(--radius-sm);border:1px solid var(--color-border-primary)}pre{background:var(--color-bg-quaternary);border:1px solid var(--color-border-primary);border-radius:var(--radius-lg);padding:var(--space-4);overflow-x:auto;font-size:var(--text-xs);line-height:1.6;color:var(--color-text-secondary)}pre code{background:0 0;border:none;padding:0;font-size:inherit}.divider,hr{border:none;border-top:1px solid var(--color-border-structural);margin:var(--space-4) 0}.container{width:100%;max-width:1200px;margin:0 auto;padding:0 var(--space-4)}.section{padding:var(--space-8) 0}.icon-xs{width:12px;height:12px;flex-shrink:0}.icon-sm{width:16px;height:16px;flex-shrink:0}.icon-md{width:18px;height:18px;flex-shrink:0}.icon-lg{width:20px;height:20px;flex-shrink:0}.icon-xl{width:24px;height:24px;flex-shrink:0}.icon-2xl{width:32px;height:32px;flex-shrink:0}.h1,h1{font-size:var(--text-h1);line-height:var(--lh-h1);font-weight:700;color:var(--color-text-primary);letter-spacing:-.02em}.h2,h2{font-size:var(--text-h2);line-height:var(--lh-h2);font-weight:600;color:var(--color-text-primary)}.h3,h3{font-size:var(--text-h3);line-height:var(--lh-h3);font-weight:600;color:var(--color-text-primary)}.h4,h4{font-size:var(--text-h4);line-height:var(--lh-h4);font-weight:600;color:var(--color-text-primary)}.h5,h5{font-size:var(--text-h5);line-height:var(--lh-h5);font-weight:600;color:var(--color-text-primary)}.h6,h6{font-size:var(--text-xs);line-height:1.4;font-weight:600;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em}.section-label{font-size:var(--text-xs);font-weight:600;color:var(--color-text-heading);text-transform:uppercase;letter-spacing:.05em;margin-bottom:var(--space-2)}.text-2xl{font-size:1.5rem}.text-xl{font-size:1.25rem}.text-lg{font-size:1.125rem}.text-base{font-size:var(--text-base)}.text-sm{font-size:var(--text-sm)}.text-sm-1{font-size:var(--text-sm-1)}.text-xs{font-size:var(--text-xs)}.text-xs-1{font-size:var(--text-xs-1)}.font-normal{font-weight:400}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-primary{color:var(--color-text-primary)}.text-secondary{color:var(--color-text-secondary)}.text-tertiary{color:var(--color-text-tertiary)}.text-muted{color:var(--color-text-muted)}.text-link{color:var(--color-text-link)}.text-inverse{color:var(--color-text-inverse)}.text-success{color:var(--color-success-text)}.text-error{color:var(--color-error-text)}.text-warning{color:var(--color-warning-text)}.text-info{color:var(--color-info-text)}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.lowercase{text-transform:lowercase}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.line-clamp-2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.line-clamp-3{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.nowrap{white-space:nowrap}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}p{color:var(--color-text-secondary);font-size:var(--text-sm);line-height:1.6}p+p{margin-top:var(--space-3)}.caption{font-size:var(--text-xs);color:var(--color-text-muted);line-height:1.4}.mono{font-family:var(--font-mono);font-size:.9em}.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-1-5);font-family:var(--font-sans);font-weight:600;white-space:nowrap;border-radius:var(--radius-lg);border:1px solid transparent;cursor:pointer;transition:background-color var(--transition-base),border-color var(--transition-base),color var(--transition-base),opacity var(--transition-base);text-decoration:none;user-select:none;outline:0;position:relative;overflow:hidden;-webkit-font-smoothing:antialiased}.btn:focus-visible{outline:2px solid var(--color-border-focus);outline-offset:2px}.btn:disabled,.btn[aria-disabled=true]{cursor:not-allowed;opacity:.5;pointer-events:none}.btn-sm{height:24px;padding:0 var(--space-1-5);gap:var(--space-1);font-size:var(--text-xs);line-height:20px}.btn-md{height:28px;padding:0 var(--space-2);gap:var(--space-1-5);font-size:var(--text-xs);line-height:24px}.btn-lg{height:44px;padding:0 var(--space-4);gap:var(--space-2-5);font-size:var(--text-sm);line-height:28px}.btn-primary{background-color:var(--color-bg-btn-primary);color:var(--color-text-secondary);border:1px solid transparent;background-image:linear-gradient(var(--color-bg-btn-primary),var(--color-bg-btn-primary)),var(--gradient-primary-btn);background-origin:border-box;background-clip:padding-box,border-box}.btn-primary:hover:not(:disabled){background-image:linear-gradient(var(--color-bg-btn-primary-h),var(--color-bg-btn-primary-h)),var(--gradient-primary-btn)}.btn-secondary{background-color:var(--color-bg-secondary);color:var(--color-text-secondary);border-color:var(--color-border-btn-secondary)}.btn-secondary:hover:not(:disabled){background-color:var(--color-bg-hover-strong);border-color:var(--color-border-btn-secondary-h)}.btn-base{background-color:var(--color-bg-secondary);color:var(--color-text-primary);border-color:var(--color-border-structural)}.btn-base:hover:not(:disabled){background-color:var(--color-border-structural)}.btn-action{background-color:var(--color-bg-btn-primary);color:var(--color-text-secondary);border-color:var(--color-bg-input-prefix)}.btn-action:hover:not(:disabled){border-color:var(--color-border-btn-secondary-h);background-color:var(--color-bg-btn-primary-h)}.btn-delete{background-color:rgba(254,59,76,.1);color:var(--color-error-text);border-color:var(--color-error-border)}.btn-delete:hover:not(:disabled){background-color:rgba(254,59,76,.15);border-color:var(--color-error)}.btn-ghost,.btn-tertiary{background-color:transparent;color:var(--color-text-primary);border-color:transparent}.btn-ghost:hover:not(:disabled),.btn-tertiary:hover:not(:disabled){background-color:var(--color-border-structural)}.btn-magical{background:var(--gradient-magical);color:var(--color-text-inverse);border-color:var(--color-border-structural)}.btn-magical:hover:not(:disabled){filter:brightness(1.1)}.btn-link{background:0 0;border-color:transparent;color:var(--color-text-link);padding-left:0;padding-right:0;font-weight:500;height:auto}.btn-link:hover:not(:disabled){text-decoration:underline}.btn-icon{padding:0;aspect-ratio:1}.btn-icon.btn-sm{width:24px}.btn-icon.btn-md{width:28px}.btn-icon.btn-lg{width:44px}.btn-full{width:100%}.btn-loading{cursor:wait;pointer-events:none}.btn-loading::after{content:'';position:absolute;inset:0;background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.12) 50%,transparent 100%);background-size:200% 100%;animation:btn-shimmer 1.5s infinite linear}@keyframes btn-shimmer{from{background-position:-200% 0}to{background-position:200% 0}}.btn-group{display:inline-flex;gap:0}.btn-group .btn{border-radius:0}.btn-group .btn:first-child{border-radius:var(--radius-lg) 0 0 var(--radius-lg)}.btn-group .btn:last-child{border-radius:0 var(--radius-lg) var(--radius-lg) 0}.btn-group .btn:not(:first-child){margin-left:-1px}.form-group{display:flex;flex-direction:column;gap:var(--space-1)}.form-label{display:flex;align-items:center;gap:var(--space-0-5);font-size:var(--text-xs);font-weight:500;color:var(--color-text-muted)}.form-label .required{color:var(--color-error);margin-left:1px}.input-wrapper{display:flex;align-items:stretch;min-height:32px;max-height:32px;border:1px solid var(--color-border-primary);border-radius:var(--radius-lg);background-color:var(--color-bg-input);transition:border-color var(--transition-base),box-shadow var(--transition-base);overflow:hidden}.input-wrapper:hover:not(.input-disabled){border-color:var(--color-border-secondary)}.input-wrapper:focus-within:not(.input-disabled){border-color:var(--color-border-secondary)}.input-wrapper.input-error{border-color:var(--color-border-error)}.input-wrapper.input-disabled{opacity:.6;cursor:not-allowed}.form-input{flex:1;background:0 0;border:none;outline:0;font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-primary);padding:0 var(--space-2);min-width:0}.form-input::placeholder{color:var(--color-text-placeholder)}.form-input:disabled{cursor:not-allowed}.input,input.input{display:block;width:100%;height:32px;padding:0 var(--space-2);background-color:var(--color-bg-input);border:1px solid var(--color-border-primary);border-radius:var(--radius-lg);font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-primary);outline:0;transition:border-color var(--transition-base)}.input::placeholder,input.input::placeholder{color:var(--color-text-placeholder)}.input:hover,input.input:hover{border-color:var(--color-border-secondary)}.input:focus,input.input:focus{border-color:var(--color-border-secondary)}.input.input-error,input.input.input-error{border-color:var(--color-border-error)}.input:disabled,input.input:disabled{opacity:.6;cursor:not-allowed}.input-lg{height:40px;font-size:var(--text-base);padding:0 var(--space-3)}.input-prefix,.input-suffix{display:flex;align-items:center;padding:0 var(--space-2);font-size:var(--text-xs);color:var(--color-text-tertiary);background-color:var(--color-bg-input-prefix);white-space:nowrap;flex-shrink:0;border-right:1px solid var(--color-border-subtle)}.input-suffix{border-right:none;border-left:1px solid var(--color-border-subtle)}.input-adornment{display:flex;align-items:center;padding:0 var(--space-2);color:var(--color-icon-tertiary);flex-shrink:0}.textarea,textarea.textarea{display:block;width:100%;min-height:80px;max-height:384px;padding:var(--space-2-5) var(--space-3);background-color:var(--color-bg-input);border:1px solid var(--color-border-primary);border-radius:var(--radius-lg);font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-primary);outline:0;resize:vertical;line-height:1.5;transition:border-color var(--transition-base)}.textarea::placeholder,textarea.textarea::placeholder{color:var(--color-text-placeholder)}.textarea:hover,textarea.textarea:hover{border-color:var(--color-border-secondary)}.textarea:focus,textarea.textarea:focus{border-color:var(--color-border-secondary)}.textarea.textarea-error,textarea.textarea.textarea-error{border-color:var(--color-border-error)}.textarea:disabled,textarea.textarea:disabled{background-color:var(--color-bg-secondary);color:var(--color-text-tertiary);cursor:not-allowed;opacity:.7}.select-trigger{display:flex;align-items:center;justify-content:space-between;height:32px;padding:0 var(--space-2);background-color:var(--color-bg-input);border:1px solid var(--color-border-primary);border-radius:var(--radius-lg);font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-primary);cursor:pointer;user-select:none;transition:border-color var(--transition-base);gap:var(--space-2)}.select-trigger:hover{border-color:var(--color-border-secondary)}.select-trigger.select-open{border-color:var(--color-border-secondary)}.select-trigger .select-arrow{color:var(--color-icon-tertiary);flex-shrink:0;transition:transform var(--transition-base)}.select-trigger.select-open .select-arrow{transform:rotate(180deg)}select.select{display:block;width:100%;height:32px;padding:0 var(--space-2);background-color:var(--color-bg-input);border:1px solid var(--color-border-primary);border-radius:var(--radius-lg);font-family:var(--font-sans);font-size:var(--text-sm);color:var(--color-text-primary);outline:0;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;padding-right:28px}select.select:hover{border-color:var(--color-border-secondary)}select.select:focus{border-color:var(--color-border-secondary)}.select-panel{position:absolute;z-index:var(--z-dropdown);min-width:160px;max-width:256px;margin-top:var(--space-2);padding:var(--space-1-5);background-color:var(--color-bg-elevated);border:1px solid var(--color-border-panel);border-radius:var(--radius-lg);box-shadow:var(--shadow-md);max-height:240px;overflow-y:auto}.select-option{display:block;padding:var(--space-1-5) var(--space-2-5);font-size:var(--text-sm);color:var(--color-text-primary);border-radius:var(--radius-md);cursor:pointer;transition:background-color var(--transition-fast);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.select-option:hover{background-color:var(--color-bg-hover-strong)}.select-option.selected{background-color:var(--color-bg-hover);font-weight:500}.checkbox-wrapper{display:inline-flex;align-items:center;gap:var(--space-2);cursor:pointer;user-select:none}.checkbox-wrapper input[type=checkbox]{position:absolute;opacity:0;width:0;height:0}.checkbox-box{display:flex;align-items:center;justify-content:center;width:20px;height:20px;flex-shrink:0;border-radius:var(--radius-md);border:2px solid var(--color-border-primary);background-color:var(--color-bg-elevated);transition:border-color var(--transition-fast),background-color var(--transition-fast)}.checkbox-wrapper:hover .checkbox-box{border-color:var(--color-border-secondary)}.checkbox-wrapper input[type=checkbox]:checked+.checkbox-box{border-color:var(--color-text-primary);background-color:var(--color-text-primary)}.checkbox-check{display:none;width:12px;height:12px;color:var(--color-bg-page)}.checkbox-wrapper input[type=checkbox]:checked+.checkbox-box .checkbox-check{display:block}.checkbox-label{font-size:var(--text-sm);color:var(--color-text-primary)}.checkbox-wrapper.disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.radio-wrapper{display:inline-flex;align-items:center;gap:var(--space-2);cursor:pointer;user-select:none}.radio-wrapper input[type=radio]{position:absolute;opacity:0;width:0;height:0}.radio-dot{display:flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0;border-radius:var(--radius-full);border:2px solid var(--color-border-primary);background-color:var(--color-bg-elevated);transition:border-color var(--transition-fast),background-color var(--transition-fast)}.radio-dot::after{content:'';width:8px;height:8px;border-radius:var(--radius-full);background-color:var(--color-bg-page);opacity:0;transition:opacity var(--transition-fast)}.radio-wrapper:hover .radio-dot{border-color:var(--color-border-secondary)}.radio-wrapper input[type=radio]:checked+.radio-dot{border-color:var(--color-text-primary);background-color:var(--color-text-primary)}.radio-wrapper input[type=radio]:checked+.radio-dot::after{opacity:1}.radio-label{font-size:var(--text-sm);color:var(--color-text-primary)}.switch-wrapper{display:inline-flex;align-items:center;gap:var(--space-2);cursor:pointer;user-select:none}.switch-wrapper input[type=checkbox]{position:absolute;opacity:0;width:0;height:0}.switch-track{position:relative;width:32px;height:16px;border-radius:var(--radius-full);background:var(--gradient-switch-off);border:1px solid var(--color-border-primary);transition:background var(--transition-base),border-color var(--transition-base);flex-shrink:0}.switch-wrapper input[type=checkbox]:checked+.switch-track{background:var(--gradient-switch-on);border-color:var(--color-border-accent)}.switch-knob{position:absolute;top:1px;left:2px;width:12px;height:12px;border-radius:var(--radius-full);background-color:#ccc;transition:transform var(--transition-base),background-color var(--transition-base);pointer-events:none}.switch-wrapper input[type=checkbox]:checked~.switch-track .switch-knob{transform:translateX(16px);background-color:#fff}.switch-track.switch-on .switch-knob{transform:translateX(16px);background-color:#fff}.switch-label{font-size:var(--text-xs);color:var(--color-text-muted);transition:color var(--transition-fast)}.switch-wrapper:hover .switch-label{color:var(--color-border-accent)}.form-error{font-size:var(--text-sm);color:var(--color-error-text);display:flex;align-items:center;gap:var(--space-1);margin-top:var(--space-0-5)}.form-helper{font-size:var(--text-xs);color:var(--color-text-muted);margin-top:var(--space-0-5)}.search-input-wrapper{position:relative;display:flex;align-items:center}.search-input-wrapper .search-icon{position:absolute;left:var(--space-2);color:var(--color-icon-tertiary);pointer-events:none}.search-input-wrapper input{padding-left:28px}.card{display:flex;flex-direction:column;background-color:var(--color-bg-card);border:1px solid var(--color-border-structural);border-radius:var(--radius-xl);overflow:hidden;transition:border-color var(--transition-base),box-shadow var(--transition-base)}.card:hover{border-color:var(--color-border-secondary)}.card-fixed{height:var(--card-height)}.card-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-4);border-bottom:1px solid var(--color-border-structural)}.card-body{flex:1;padding:var(--space-4);overflow:hidden}.card-footer{padding:var(--space-3) var(--space-4);border-top:1px solid var(--color-border-structural);display:flex;align-items:center;gap:var(--space-2)}.card-title{font-size:var(--text-base);font-weight:600;color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.card-subtitle{font-size:var(--text-xs);color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card-description{font-size:var(--text-xs);color:var(--color-text-tertiary);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.panel{background-color:var(--color-bg-secondary);border:1px solid var(--color-border-panel);border-radius:var(--radius-lg);overflow:hidden}.panel-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--color-border-structural);background-color:var(--color-bg-tertiary)}.panel-body{padding:var(--space-4)}.badge{display:inline-flex;align-items:center;gap:var(--space-1-5);padding:0 var(--space-2);height:17px;line-height:17px;border-radius:var(--radius-full);border:1px solid;font-size:var(--text-xs-1);font-weight:700;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;user-select:none;flex-shrink:0}.badge-dot{width:7px;height:7px;border-radius:var(--radius-full);flex-shrink:0;display:inline-block}.badge-not-started{background-color:var(--status-not-started-bg);color:var(--status-not-started-text);border-color:var(--status-not-started-border)}.badge-not-started .badge-dot{background-color:var(--status-not-started-text)}.badge-in-progress{background-color:var(--status-in-progress-bg);color:var(--status-in-progress-text);border-color:var(--status-in-progress-border)}.badge-in-progress .badge-dot{background-color:var(--status-in-progress-text);animation:badge-pulse 2s cubic-bezier(.4,0,.6,1) infinite}.badge-pending{background-color:var(--status-pending-bg);color:var(--status-pending-text);border-color:var(--status-pending-border)}.badge-pending .badge-dot{background-color:var(--status-pending-text)}.badge-success{background-color:var(--status-success-bg);color:var(--status-success-text);border-color:var(--status-success-border)}.badge-success .badge-dot{background-color:var(--status-success-text)}.badge-error{background-color:var(--status-error-bg);color:var(--status-error-text);border-color:var(--status-error-border)}.badge-error .badge-dot{background-color:var(--status-error-text)}.badge-warning{background-color:var(--status-warning-bg);color:var(--status-warning-text);border-color:var(--status-warning-border)}.badge-warning .badge-dot{background-color:var(--status-warning-text)}.badge-advanced{background-color:var(--status-advanced-bg);color:var(--status-advanced-text);border-color:var(--status-advanced-border)}.badge-advanced .badge-dot{background-color:var(--status-advanced-text)}@keyframes badge-pulse{0%,100%{opacity:1}50%{opacity:.4}}.tag{display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--space-2);border-radius:var(--radius-lg);border:1px solid var(--color-border-secondary);background-color:var(--color-bg-secondary);font-size:var(--text-xs);font-weight:600;color:var(--color-text-tertiary);white-space:nowrap;user-select:none}.tag-sm{padding:1px var(--space-1-5);font-size:var(--text-xs-1);border-radius:var(--radius-md)}.tag-blue{background-color:var(--color-info-bg);border-color:var(--color-info-border);color:var(--color-info-text)}.tag-green{background-color:var(--color-success-bg);border-color:var(--color-success-border);color:var(--color-success-text)}.tag-red{background-color:var(--color-error-bg);border-color:var(--color-error-border);color:var(--color-error-text)}.tag-yellow{background-color:var(--color-warning-bg);border-color:var(--color-warning-border);color:var(--color-warning-text)}.tag-purple{background-color:var(--color-purple-bg);border-color:var(--color-purple-border);color:var(--color-purple-text)}.alert{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);border:1px solid;font-size:var(--text-xs);line-height:1.5}.alert-icon{flex-shrink:0;margin-top:1px}.alert-info{background-color:var(--color-info-bg);border-color:var(--color-info-border);color:var(--color-info-text)}.alert-success{background-color:var(--color-success-bg);border-color:var(--color-success-border);color:var(--color-success-text)}.alert-warning{background-color:var(--color-warning-bg);border-color:var(--color-warning-border);color:var(--color-warning-text)}.alert-error{background-color:var(--color-error-bg);border-color:var(--color-error-border);color:var(--color-error-text)}.avatar{display:flex;align-items:center;justify-content:center;border-radius:var(--radius-full);border:1px solid var(--color-border-secondary);background-color:var(--color-bg-elevated);overflow:hidden;flex-shrink:0;user-select:none;font-weight:600;color:#fff;font-size:var(--text-xs)}.avatar img{width:100%;height:100%;object-fit:cover;border-radius:var(--radius-full)}.avatar-xs{width:20px;height:20px;font-size:8px;border-width:1px}.avatar-sm{width:24px;height:24px;font-size:9px;border-width:1px}.avatar-md{width:32px;height:32px;font-size:var(--text-xs)}.avatar-chat{width:40px;height:40px;font-size:var(--text-sm)}.avatar-lg{width:72px;height:72px;font-size:var(--text-h3);border-width:2px}.avatar-xl{width:96px;height:96px;font-size:var(--text-h2);border-width:2px}.avatar-modal{width:176px;height:176px;font-size:var(--text-h1);border-width:2px}.avatar-color-0{background-color:#aa47bc}.avatar-color-1{background-color:#7a1fa2}.avatar-color-2{background-color:#6b8592}.avatar-color-3{background-color:#465a65}.avatar-color-4{background-color:#ec407a}.avatar-color-5{background-color:#c2175b}.avatar-color-6{background-color:#5c6bc0}.avatar-color-7{background-color:#0288d1}.avatar-color-8{background-color:#00579c}.avatar-color-9{background-color:#0098a6}.avatar-color-10{background-color:#00887a}.avatar-color-11{background-color:#004c3f}.avatar-color-12{background-color:#689f39}.avatar-color-13{background-color:#33691e}.avatar-color-14{background-color:#8c6e63}.avatar-color-15{background-color:#5d4038}.avatar-color-16{background-color:#7e57c2}.avatar-color-17{background-color:#512da7}.avatar-color-18{background-color:#ef6c00}.avatar-color-19{background-color:#f5511e}.avatar-color-20{background-color:#aa3410}.avatar-group{display:flex;align-items:center}.avatar-group .avatar{margin-left:-8px}.avatar-group .avatar:first-child{margin-left:0}.spinner{display:inline-block;border-radius:var(--radius-full);border-style:solid;border-color:var(--color-border-secondary);border-top-color:var(--color-text-primary);animation:spinner-spin .8s linear infinite;flex-shrink:0}.spinner-xs{width:12px;height:12px;border-width:1.5px}.spinner-sm{width:16px;height:16px;border-width:2px}.spinner-md{width:24px;height:24px;border-width:2px}.spinner-lg{width:32px;height:32px;border-width:3px}.spinner-xl{width:48px;height:48px;border-width:3px}.spinner-page{display:flex;justify-content:center;align-items:center;min-height:200px}@keyframes spinner-spin{to{transform:rotate(360deg)}}.progress-track{position:relative;overflow:hidden;background-color:var(--color-bg-tertiary);border-radius:68px;border:1px solid var(--color-border-secondary);width:85px;height:14px}.progress-fill{height:100%;background:var(--gradient-primary-btn);border-radius:68px;transition:width .2s ease-out}.progress-label{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-size:9px;line-height:10px;font-weight:600;color:var(--color-text-primary);white-space:nowrap}.progress-bar{width:100%;height:4px;background-color:var(--color-bg-tertiary);border-radius:var(--radius-full);overflow:hidden}.progress-bar .progress-fill{height:4px;border-radius:var(--radius-full)}.tooltip-wrapper{position:relative;display:inline-flex}.tooltip{position:absolute;z-index:var(--z-toast);bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);background-color:var(--color-bg-elevated);color:var(--color-text-primary);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-xs);line-height:1;white-space:nowrap;box-shadow:var(--shadow-md);pointer-events:none;opacity:0;transition:opacity var(--transition-fast)}.tooltip-wrapper:hover .tooltip{opacity:1}.tooltip-right{bottom:auto;top:50%;left:calc(100% + 8px);transform:translateY(-50%)}.tooltip-bottom{bottom:auto;top:calc(100% + 8px)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-8) var(--space-4);text-align:center;gap:var(--space-3)}.empty-state-icon{color:var(--color-icon-tertiary);margin-bottom:var(--space-1)}.empty-state-title{font-size:var(--text-h4);font-weight:600;color:var(--color-text-primary)}.empty-state-description{font-size:var(--text-sm);color:var(--color-text-muted);max-width:320px}.chip{display:inline-flex;align-items:center;gap:var(--space-1);padding:2px var(--space-1-5);border-radius:var(--radius-full);background-color:var(--color-bg-quaternary);border:1px solid var(--color-border-primary);font-size:var(--text-xs);color:var(--color-text-secondary)}.chip-close{display:flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:var(--radius-full);background:0 0;border:none;color:var(--color-icon-tertiary);cursor:pointer;padding:0;transition:color var(--transition-fast),background-color var(--transition-fast)}.chip-close:hover{color:var(--color-text-primary);background-color:var(--color-bg-hover)}.stat-card{display:flex;flex-direction:column;gap:var(--space-1);padding:var(--space-3) var(--space-4);background-color:var(--color-bg-card);border:1px solid var(--color-border-structural);border-radius:var(--radius-xl);min-width:0}.stat-card-label{font-size:var(--text-xs-1);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.stat-card-value{font-size:var(--text-h2);font-weight:700;line-height:1.2;color:var(--color-text-primary)}.stat-card-desc{font-size:var(--text-xs);color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.stat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:var(--space-3)}.dl-grid{display:grid;grid-template-columns:max-content 1fr;gap:var(--space-2) var(--space-4);font-size:var(--text-sm)}.dl-grid dt{color:var(--color-text-muted);font-weight:500;white-space:nowrap}.dl-grid dd{color:var(--color-text-primary)}.table-wrapper{width:100%;overflow-x:auto}.table,table.table{width:100%;border-collapse:separate;border-spacing:0;font-size:var(--text-xs);line-height:1.3}.table thead tr th{text-align:left;padding:var(--space-2-5) var(--space-4);font-weight:600;color:var(--color-text-primary);background-color:var(--color-bg-quaternary);border-top:1px solid var(--color-border-structural);border-bottom:1px solid var(--color-border-structural);white-space:nowrap;position:sticky;top:0;z-index:1}.table thead tr th:first-child{border-left:1px solid var(--color-border-structural);border-radius:var(--radius-lg) 0 0 0}.table thead tr th:last-child{border-right:1px solid var(--color-border-structural);border-radius:0 var(--radius-lg) 0 0}.table tbody tr td{padding:var(--space-3) var(--space-4);color:var(--color-text-secondary);border-bottom:1px solid var(--color-border-structural);vertical-align:middle}.table tbody tr:hover td{background-color:var(--color-bg-hover)}.table tbody tr:last-child td{border-bottom:none}.th-sortable{cursor:pointer;user-select:none;gap:var(--space-1)}.th-sortable:hover{color:var(--color-text-link)}.sort-icon{display:inline-flex;flex-direction:column;gap:1px;color:var(--color-icon-tertiary);flex-shrink:0}.th-sortable.sort-asc .sort-icon,.th-sortable.sort-desc .sort-icon{color:var(--color-text-primary)}.td-number{text-align:right;font-variant-numeric:tabular-nums}.tabs{display:flex;flex-direction:column}.tabs-list{display:flex;align-items:stretch;border-bottom:1px solid var(--color-border-panel);flex-shrink:0}.tab-item{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-2) var(--space-2);padding-bottom:var(--space-4);font-size:var(--text-sm);color:var(--color-text-primary);cursor:pointer;border-bottom:2px solid transparent;transition:border-color var(--transition-base),color var(--transition-base);text-decoration:none;white-space:nowrap;user-select:none;background:0 0;border-top:none;border-left:none;border-right:none;font-family:var(--font-sans)}.tab-item:hover{border-bottom-color:var(--color-text-tertiary)}.tab-item.active,.tab-item[aria-selected=true]{border-bottom-color:var(--color-text-primary);font-weight:600;cursor:default}.tabs-sm .tab-item{font-size:var(--text-xs);padding:var(--space-2-5);padding-bottom:var(--space-2-5)}.tabs-panel{flex:1;padding-top:var(--space-4)}.pagination{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);padding:var(--space-3) 0;border-top:1px solid var(--color-border-structural)}.pagination-info{color:var(--color-text-muted);font-size:var(--text-h5);margin-right:auto}.page-btn{display:flex;align-items:center;justify-content:center;height:32px;min-width:32px;padding:0 var(--space-2);background-color:var(--color-bg-secondary);border:1px solid var(--color-border-structural);border-radius:var(--radius-lg);color:var(--color-text-link);font-size:var(--text-h5);cursor:pointer;transition:border-color var(--transition-fast),background-color var(--transition-fast);user-select:none;text-decoration:none;font-family:var(--font-sans);font-weight:400}.page-btn:hover:not(.disabled){border-color:var(--color-border-accent)}.page-btn.active{border-color:var(--color-border-accent);background-color:var(--color-bg-pagination-active);font-weight:600}.page-btn.disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.modal-overlay{position:fixed;inset:0;background-color:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:var(--z-modal);padding:var(--space-4)}.modal{display:flex;flex-direction:column;background-color:var(--color-bg-elevated);border:1px solid var(--color-border-panel);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);max-height:95vh;width:100%;overflow:hidden}.modal-sm{max-width:400px}.modal-md{max-width:512px}.modal-lg{max-width:720px}.modal-xl{max-width:1024px}.modal-full{max-width:90vw}.modal-header{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--color-border-structural);flex-shrink:0}.modal-title{font-size:var(--text-base);font-weight:600;color:var(--color-text-primary)}.modal-close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-lg);border:none;background:0 0;color:var(--color-icon-tertiary);cursor:pointer;transition:color var(--transition-fast),background-color var(--transition-fast);flex-shrink:0}.modal-close:hover{color:var(--color-text-primary);background-color:var(--color-bg-quaternary)}.modal-body{flex:1;padding:var(--space-4);overflow-y:auto}.modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-3);padding:var(--space-4);border-top:1px solid var(--color-border-structural);flex-shrink:0;background-color:var(--color-bg-elevated);border-radius:0 0 var(--radius-lg) var(--radius-lg)}.nav-sidebar{display:flex;flex-direction:column;gap:var(--space-0-5);padding:var(--space-2)}.nav-item{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);font-size:var(--text-sm);color:var(--color-text-nav);cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast);text-decoration:none;user-select:none;white-space:nowrap;overflow:hidden}.nav-item:hover{background-color:var(--color-bg-hover);color:var(--color-text-primary)}.nav-item.active{background-color:var(--color-bg-secondary);color:var(--color-text-primary);font-weight:500}.nav-item .nav-icon{flex-shrink:0;color:var(--color-icon-tertiary);transition:color var(--transition-fast)}.nav-item.active .nav-icon,.nav-item:hover .nav-icon{color:var(--color-icon-primary)}.nav-group-label{padding:var(--space-2) var(--space-3) var(--space-1);font-size:var(--text-xs);font-weight:600;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em}.app-shell{display:flex;min-height:100vh}.app-navbar{width:var(--navbar-width);min-height:100vh;background-color:var(--color-bg-nav);display:flex;flex-direction:column;align-items:center;padding:var(--space-3) 0;flex-shrink:0;border-right:1px solid var(--color-border-structural)}.app-sidebar{width:var(--sidebar-width);min-height:100vh;background-color:var(--color-bg-sidebar);display:flex;flex-direction:column;border-right:1px solid var(--color-border-structural);flex-shrink:0}.app-content{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden}.app-header{height:var(--layout-header-height);display:flex;align-items:center;padding:0 var(--space-4);border-bottom:1px solid var(--color-border-structural);background-color:var(--color-bg-page);flex-shrink:0;gap:var(--space-4)}.app-main{flex:1;padding:var(--space-4);overflow-y:auto}.hidden{display:none!important}.block{display:block}.inline{display:inline}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.flex-nowrap{flex-wrap:nowrap}.flex-1{flex:1}.flex-auto{flex:auto}.flex-none{flex:none}.flex-shrink-0{flex-shrink:0}.grow{flex-grow:1}.items-start{align-items:flex-start}.items-center{align-items:center}.items-end{align-items:flex-end}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-between{justify-content:space-between}.grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-auto-fill-sm{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}.grid-auto-fill-md{grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.grid-auto-fill-lg{grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}.gap-1{gap:var(--space-1)}.gap-2{gap:var(--space-2)}.gap-3{gap:var(--space-3)}.gap-4{gap:var(--space-4)}.gap-5{gap:var(--space-5)}.gap-6{gap:var(--space-6)}.gap-8{gap:var(--space-8)}.gap-x-2{column-gap:var(--space-2)}.gap-x-3{column-gap:var(--space-3)}.gap-x-4{column-gap:var(--space-4)}.gap-y-2{row-gap:var(--space-2)}.gap-y-3{row-gap:var(--space-3)}.gap-y-4{row-gap:var(--space-4)}.p-1{padding:var(--space-1)}.p-2{padding:var(--space-2)}.p-3{padding:var(--space-3)}.p-4{padding:var(--space-4)}.p-6{padding:var(--space-6)}.p-8{padding:var(--space-8)}.px-2{padding-left:var(--space-2);padding-right:var(--space-2)}.px-3{padding-left:var(--space-3);padding-right:var(--space-3)}.px-4{padding-left:var(--space-4);padding-right:var(--space-4)}.py-1{padding-top:var(--space-1);padding-bottom:var(--space-1)}.py-2{padding-top:var(--space-2);padding-bottom:var(--space-2)}.py-3{padding-top:var(--space-3);padding-bottom:var(--space-3)}.py-4{padding-top:var(--space-4);padding-bottom:var(--space-4)}.pt-2{padding-top:var(--space-2)}.pt-4{padding-top:var(--space-4)}.pt-8{padding-top:var(--space-8)}.pb-2{padding-bottom:var(--space-2)}.pb-4{padding-bottom:var(--space-4)}.m-auto{margin:auto}.mx-auto{margin-left:auto;margin-right:auto}.ml-auto{margin-left:auto}.mr-auto{margin-right:auto}.mt-1{margin-top:var(--space-1)}.mt-2{margin-top:var(--space-2)}.mt-3{margin-top:var(--space-3)}.mt-4{margin-top:var(--space-4)}.mt-6{margin-top:var(--space-6)}.mt-8{margin-top:var(--space-8)}.mb-1{margin-bottom:var(--space-1)}.mb-2{margin-bottom:var(--space-2)}.mb-3{margin-bottom:var(--space-3)}.mb-4{margin-bottom:var(--space-4)}.mb-6{margin-bottom:var(--space-6)}.w-full{width:100%}.w-auto{width:auto}.h-full{height:100%}.min-h-screen{min-height:100vh}.min-w-0{min-width:0}.max-w-sm{max-width:384px}.max-w-md{max-width:512px}.max-w-lg{max-width:720px}.max-w-xl{max-width:960px}.max-w-full{max-width:100%}.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-visible{overflow:visible}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.sticky{position:sticky}.inset-0{inset:0}.top-0{top:0}.bottom-0{bottom:0}.left-0{left:0}.right-0{right:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:var(--z-dropdown)}.z-50{z-index:var(--z-modal)}.z-60{z-index:var(--z-toast)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-md{border-radius:var(--radius-md)}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:var(--radius-full)}.bg-page{background-color:var(--color-bg-page)}.bg-card{background-color:var(--color-bg-card)}.bg-elevated{background-color:var(--color-bg-elevated)}.bg-secondary{background-color:var(--color-bg-secondary)}.bg-tertiary{background-color:var(--color-bg-tertiary)}.bg-success{background-color:var(--color-success-bg)}.bg-error{background-color:var(--color-error-bg)}.bg-warning{background-color:var(--color-warning-bg)}.bg-info{background-color:var(--color-info-bg)}.bg-brand{background:var(--gradient-brand)}.bg-magical{background:var(--gradient-magical)}.bg-purple-radial{background:var(--gradient-purple-radial)}.border{border:1px solid var(--color-border-structural)}.border-top{border-top:1px solid var(--color-border-structural)}.border-bottom{border-bottom:1px solid var(--color-border-structural)}.border-left{border-left:1px solid var(--color-border-structural)}.border-right{border-right:1px solid var(--color-border-structural)}.border-none{border:none}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-wait{cursor:wait}.pointer-none{pointer-events:none}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-100{opacity:1}.select-none{user-select:none}.select-text{user-select:text}.shadow-sm{box-shadow:var(--shadow-sm)}.shadow-md{box-shadow:var(--shadow-md)}.shadow-lg{box-shadow:var(--shadow-lg)}.transition{transition:all var(--transition-base)}.transition-colors{transition:color var(--transition-base),background-color var(--transition-base),border-color var(--transition-base)}