conectese 0.1.14

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 (260) hide show
  1. package/README.md +265 -0
  2. package/_conectese/.conectese-version +1 -0
  3. package/_conectese/config/playwright.config.json +11 -0
  4. package/_conectese/core/architect.agent.yaml +110 -0
  5. package/_conectese/core/best-practices/_catalog.yaml +116 -0
  6. package/_conectese/core/best-practices/blog-post.md +132 -0
  7. package/_conectese/core/best-practices/blog-seo.md +127 -0
  8. package/_conectese/core/best-practices/copywriting.md +426 -0
  9. package/_conectese/core/best-practices/data-analysis.md +401 -0
  10. package/_conectese/core/best-practices/email-newsletter.md +118 -0
  11. package/_conectese/core/best-practices/email-sales.md +110 -0
  12. package/_conectese/core/best-practices/image-design.md +348 -0
  13. package/_conectese/core/best-practices/instagram-feed.md +235 -0
  14. package/_conectese/core/best-practices/instagram-reels.md +112 -0
  15. package/_conectese/core/best-practices/instagram-stories.md +107 -0
  16. package/_conectese/core/best-practices/linkedin-article.md +116 -0
  17. package/_conectese/core/best-practices/linkedin-post.md +121 -0
  18. package/_conectese/core/best-practices/researching.md +349 -0
  19. package/_conectese/core/best-practices/review.md +269 -0
  20. package/_conectese/core/best-practices/social-networks-publishing.md +294 -0
  21. package/_conectese/core/best-practices/strategist.md +344 -0
  22. package/_conectese/core/best-practices/technical-writing.md +365 -0
  23. package/_conectese/core/best-practices/twitter-post.md +105 -0
  24. package/_conectese/core/best-practices/twitter-thread.md +122 -0
  25. package/_conectese/core/best-practices/whatsapp-broadcast.md +107 -0
  26. package/_conectese/core/best-practices/youtube-script.md +122 -0
  27. package/_conectese/core/best-practices/youtube-shorts.md +112 -0
  28. package/_conectese/core/prompts/build.prompt.md +547 -0
  29. package/_conectese/core/prompts/design.prompt.md +469 -0
  30. package/_conectese/core/prompts/discovery.prompt.md +269 -0
  31. package/_conectese/core/prompts/sherlock-instagram.md +123 -0
  32. package/_conectese/core/prompts/sherlock-linkedin.md +73 -0
  33. package/_conectese/core/prompts/sherlock-shared.md +684 -0
  34. package/_conectese/core/prompts/sherlock-twitter.md +78 -0
  35. package/_conectese/core/prompts/sherlock-youtube.md +85 -0
  36. package/_conectese/core/runner.pipeline.md +535 -0
  37. package/_conectese/core/skills.engine.md +381 -0
  38. package/agents/data-extractor/AGENT.md +13 -0
  39. package/agents/direito-adaneiro/AGENT.md +18 -0
  40. package/agents/direito-administrativo/AGENT.md +18 -0
  41. package/agents/direito-aeroporta-rio/AGENT.md +18 -0
  42. package/agents/direito-agra-rio/AGENT.md +18 -0
  43. package/agents/direito-ambiental/AGENT.md +18 -0
  44. package/agents/direito-banca-rio/AGENT.md +18 -0
  45. package/agents/direito-civil/AGENT.md +18 -0
  46. package/agents/direito-constitcional/AGENT.md +18 -0
  47. package/agents/direito-da-crianc-a-e-do-adolescente-eca/AGENT.md +18 -0
  48. package/agents/direito-da-propriedade-intelectal/AGENT.md +18 -0
  49. package/agents/direito-de-ami-lia/AGENT.md +18 -0
  50. package/agents/direito-de-tra-nsito/AGENT.md +18 -0
  51. package/agents/direito-desportivo/AGENT.md +18 -0
  52. package/agents/direito-digital/AGENT.md +18 -0
  53. package/agents/direito-do-consmidor/AGENT.md +18 -0
  54. package/agents/direito-do-trabalho/AGENT.md +18 -0
  55. package/agents/direito-econo-mico/AGENT.md +18 -0
  56. package/agents/direito-eleitoral/AGENT.md +18 -0
  57. package/agents/direito-empresarial/AGENT.md +18 -0
  58. package/agents/direito-imobilia-rio/AGENT.md +18 -0
  59. package/agents/direito-inanceiro/AGENT.md +18 -0
  60. package/agents/direito-internacional/AGENT.md +18 -0
  61. package/agents/direito-mari-timo/AGENT.md +18 -0
  62. package/agents/direito-me-dico-e-da-sa-de/AGENT.md +18 -0
  63. package/agents/direito-militar/AGENT.md +18 -0
  64. package/agents/direito-ndia-rio/AGENT.md +18 -0
  65. package/agents/direito-notarial-e-registral/AGENT.md +18 -0
  66. package/agents/direito-penal/AGENT.md +18 -0
  67. package/agents/direito-previdencia-rio/AGENT.md +18 -0
  68. package/agents/direito-processal-civil/AGENT.md +18 -0
  69. package/agents/direito-processal-do-trabalho/AGENT.md +18 -0
  70. package/agents/direito-processal-militar/AGENT.md +18 -0
  71. package/agents/direito-processal-penal/AGENT.md +18 -0
  72. package/agents/direito-rbani-stico/AGENT.md +18 -0
  73. package/agents/direito-secrita-rio/AGENT.md +18 -0
  74. package/agents/direito-sindical/AGENT.md +18 -0
  75. package/agents/direito-societa-rio/AGENT.md +18 -0
  76. package/agents/direito-tribta-rio/AGENT.md +18 -0
  77. package/agents/direitos-hmanos/AGENT.md +18 -0
  78. package/agents/legal-analyst/AGENT.md +16 -0
  79. package/agents/legal-synthesizer/AGENT.md +13 -0
  80. package/agents/lgpd-anonymizer/AGENT.md +14 -0
  81. package/agents/lgpd-restorer/AGENT.md +14 -0
  82. package/agents/task-router/AGENT.md +13 -0
  83. package/bin/conectese.js +73 -0
  84. package/dashboard/index.html +12 -0
  85. package/dashboard/package-lock.json +1971 -0
  86. package/dashboard/package.json +28 -0
  87. package/dashboard/public/assets/avatars/Female1_1wave.png +0 -0
  88. package/dashboard/public/assets/avatars/Female1_2wave.png +0 -0
  89. package/dashboard/public/assets/avatars/Female1_blink.png +0 -0
  90. package/dashboard/public/assets/avatars/Female1_talk.png +0 -0
  91. package/dashboard/public/assets/avatars/Female2_1wave.png +0 -0
  92. package/dashboard/public/assets/avatars/Female2_2wave.png +0 -0
  93. package/dashboard/public/assets/avatars/Female2_blink.png +0 -0
  94. package/dashboard/public/assets/avatars/Female2_talk.png +0 -0
  95. package/dashboard/public/assets/avatars/Female3_blink.png +0 -0
  96. package/dashboard/public/assets/avatars/Female3_talk.png +0 -0
  97. package/dashboard/public/assets/avatars/Female3_wave.png +0 -0
  98. package/dashboard/public/assets/avatars/Female4_blink.png +0 -0
  99. package/dashboard/public/assets/avatars/Female4_talk.png +0 -0
  100. package/dashboard/public/assets/avatars/Female4_wave.png +0 -0
  101. package/dashboard/public/assets/avatars/Female5_blink.png +0 -0
  102. package/dashboard/public/assets/avatars/Female5_talk.png +0 -0
  103. package/dashboard/public/assets/avatars/Female5_wave.png +0 -0
  104. package/dashboard/public/assets/avatars/Female6_blink.png +0 -0
  105. package/dashboard/public/assets/avatars/Female6_talk.png +0 -0
  106. package/dashboard/public/assets/avatars/Female6_wave.png +0 -0
  107. package/dashboard/public/assets/avatars/Male1_1wave.png +0 -0
  108. package/dashboard/public/assets/avatars/Male1_2wave.png +0 -0
  109. package/dashboard/public/assets/avatars/Male1_blink.png +0 -0
  110. package/dashboard/public/assets/avatars/Male1_talk.png +0 -0
  111. package/dashboard/public/assets/avatars/Male2_1wave.png +0 -0
  112. package/dashboard/public/assets/avatars/Male2_2wave.png +0 -0
  113. package/dashboard/public/assets/avatars/Male2_blink.png +0 -0
  114. package/dashboard/public/assets/avatars/Male2_talk.png +0 -0
  115. package/dashboard/public/assets/avatars/Male3_blink.png +0 -0
  116. package/dashboard/public/assets/avatars/Male3_talk.png +0 -0
  117. package/dashboard/public/assets/avatars/Male3_wave.png +0 -0
  118. package/dashboard/public/assets/avatars/Male4_blink.png +0 -0
  119. package/dashboard/public/assets/avatars/Male4_talk.png +0 -0
  120. package/dashboard/public/assets/avatars/Male4_wave.png +0 -0
  121. package/dashboard/public/assets/desks/desktop_set_black_down.png +0 -0
  122. package/dashboard/public/assets/desks/desktop_set_black_down_coding-1.png +0 -0
  123. package/dashboard/public/assets/desks/desktop_set_black_down_coding.png +0 -0
  124. package/dashboard/public/assets/desks/desktop_set_black_up.png +0 -0
  125. package/dashboard/public/assets/desks/desktop_set_white_down.png +0 -0
  126. package/dashboard/public/assets/desks/desktop_set_white_down_coding-1.png +0 -0
  127. package/dashboard/public/assets/desks/desktop_set_white_down_coding.png +0 -0
  128. package/dashboard/public/assets/desks/desktop_set_white_up.png +0 -0
  129. package/dashboard/public/assets/furniture/armchair_tan.png +0 -0
  130. package/dashboard/public/assets/furniture/armchair_tan_down.png +0 -0
  131. package/dashboard/public/assets/furniture/backpack_blue.png +0 -0
  132. package/dashboard/public/assets/furniture/backpack_red.png +0 -0
  133. package/dashboard/public/assets/furniture/blinds.png +0 -0
  134. package/dashboard/public/assets/furniture/blinds_large_closed_white.png +0 -0
  135. package/dashboard/public/assets/furniture/bookshelf.png +0 -0
  136. package/dashboard/public/assets/furniture/bookshelf_purple_tall.png +0 -0
  137. package/dashboard/public/assets/furniture/bulletin_board.png +0 -0
  138. package/dashboard/public/assets/furniture/clock.png +0 -0
  139. package/dashboard/public/assets/furniture/coffee_mug.png +0 -0
  140. package/dashboard/public/assets/furniture/coffee_mug_blue.png +0 -0
  141. package/dashboard/public/assets/furniture/coffee_table.png +0 -0
  142. package/dashboard/public/assets/furniture/coffeepot_right.png +0 -0
  143. package/dashboard/public/assets/furniture/coffeetable_black_horizontal.png +0 -0
  144. package/dashboard/public/assets/furniture/couch.png +0 -0
  145. package/dashboard/public/assets/furniture/couch_tan_down.png +0 -0
  146. package/dashboard/public/assets/furniture/cushion_blue.png +0 -0
  147. package/dashboard/public/assets/furniture/cushion_tan.png +0 -0
  148. package/dashboard/public/assets/furniture/desk_wood.png +0 -0
  149. package/dashboard/public/assets/furniture/fancy_rug.png +0 -0
  150. package/dashboard/public/assets/furniture/fancy_rug_wide.png +0 -0
  151. package/dashboard/public/assets/furniture/flowers1.png +0 -0
  152. package/dashboard/public/assets/furniture/flowers2.png +0 -0
  153. package/dashboard/public/assets/furniture/lamp_tan.png +0 -0
  154. package/dashboard/public/assets/furniture/lantern.png +0 -0
  155. package/dashboard/public/assets/furniture/monstera.png +0 -0
  156. package/dashboard/public/assets/furniture/monstera_small.png +0 -0
  157. package/dashboard/public/assets/furniture/picture_frame.png +0 -0
  158. package/dashboard/public/assets/furniture/plant1.png +0 -0
  159. package/dashboard/public/assets/furniture/plant2.png +0 -0
  160. package/dashboard/public/assets/furniture/plant3.png +0 -0
  161. package/dashboard/public/assets/furniture/plant_poof.png +0 -0
  162. package/dashboard/public/assets/furniture/plant_spindly.png +0 -0
  163. package/dashboard/public/assets/furniture/poster_blue.png +0 -0
  164. package/dashboard/public/assets/furniture/rug.png +0 -0
  165. package/dashboard/public/assets/furniture/succulent_blue.png +0 -0
  166. package/dashboard/public/assets/furniture/succulent_green.png +0 -0
  167. package/dashboard/public/assets/furniture/treasurechest_closed_gold.png +0 -0
  168. package/dashboard/public/assets/furniture/water_cooler_better.png +0 -0
  169. package/dashboard/public/assets/furniture/whiteboard.png +0 -0
  170. package/dashboard/public/assets/furniture/whiteboard_stand_graph.png +0 -0
  171. package/dashboard/public/assets/furniture/window_blinds_open.png +0 -0
  172. package/dashboard/src/App.tsx +46 -0
  173. package/dashboard/src/components/SquadCard.tsx +47 -0
  174. package/dashboard/src/components/SquadSelector.tsx +61 -0
  175. package/dashboard/src/components/StatusBadge.tsx +32 -0
  176. package/dashboard/src/components/StatusBar.tsx +97 -0
  177. package/dashboard/src/hooks/useSquadSocket.ts +135 -0
  178. package/dashboard/src/lib/formatTime.ts +16 -0
  179. package/dashboard/src/lib/normalizeState.ts +25 -0
  180. package/dashboard/src/main.tsx +10 -0
  181. package/dashboard/src/office/AgentSprite.ts +241 -0
  182. package/dashboard/src/office/OfficeScene.ts +153 -0
  183. package/dashboard/src/office/PhaserGame.tsx +80 -0
  184. package/dashboard/src/office/RoomBuilder.ts +190 -0
  185. package/dashboard/src/office/assetKeys.ts +150 -0
  186. package/dashboard/src/office/palette.ts +32 -0
  187. package/dashboard/src/plugin/squadWatcher.ts +233 -0
  188. package/dashboard/src/store/useSquadStore.ts +56 -0
  189. package/dashboard/src/styles/globals.css +36 -0
  190. package/dashboard/src/types/state.ts +63 -0
  191. package/dashboard/src/vite-env.d.ts +1 -0
  192. package/dashboard/test-results/.last-run.json +4 -0
  193. package/dashboard/tsconfig.json +24 -0
  194. package/dashboard/tsconfig.tsbuildinfo +1 -0
  195. package/dashboard/vite.config.ts +13 -0
  196. package/package.json +53 -0
  197. package/skills/README.md +63 -0
  198. package/skills/apify/SKILL.md +55 -0
  199. package/skills/blotato/SKILL.md +63 -0
  200. package/skills/canva/SKILL.md +60 -0
  201. package/skills/conectese-agent-creator/SKILL.md +192 -0
  202. package/skills/conectese-skill-creator/SKILL.md +407 -0
  203. package/skills/conectese-skill-creator/agents/analyzer.md +274 -0
  204. package/skills/conectese-skill-creator/agents/comparator.md +202 -0
  205. package/skills/conectese-skill-creator/agents/grader.md +223 -0
  206. package/skills/conectese-skill-creator/assets/eval_review.html +146 -0
  207. package/skills/conectese-skill-creator/eval-viewer/generate_review.py +471 -0
  208. package/skills/conectese-skill-creator/eval-viewer/viewer.html +1325 -0
  209. package/skills/conectese-skill-creator/references/schemas.md +430 -0
  210. package/skills/conectese-skill-creator/references/skill-format.md +235 -0
  211. package/skills/conectese-skill-creator/scripts/__init__.py +0 -0
  212. package/skills/conectese-skill-creator/scripts/aggregate_benchmark.py +401 -0
  213. package/skills/conectese-skill-creator/scripts/quick_validate.py +103 -0
  214. package/skills/conectese-skill-creator/scripts/run_eval.py +310 -0
  215. package/skills/conectese-skill-creator/scripts/utils.py +47 -0
  216. package/skills/image-ai-generator/SKILL.md +124 -0
  217. package/skills/image-ai-generator/scripts/generate.py +175 -0
  218. package/skills/image-creator/SKILL.md +155 -0
  219. package/skills/image-fetcher/SKILL.md +91 -0
  220. package/skills/instagram-publisher/SKILL.md +119 -0
  221. package/skills/instagram-publisher/scripts/publish.js +165 -0
  222. package/skills/resend/SKILL.md +80 -0
  223. package/skills/template-designer/SKILL.md +201 -0
  224. package/skills/template-designer/base-templates/model-a.html +27 -0
  225. package/skills/template-designer/base-templates/model-b.html +31 -0
  226. package/skills/template-designer/base-templates/model-c.html +42 -0
  227. package/src/agents-cli.js +158 -0
  228. package/src/agents.js +134 -0
  229. package/src/i18n.js +48 -0
  230. package/src/init.js +341 -0
  231. package/src/locales/en.json +73 -0
  232. package/src/locales/es.json +72 -0
  233. package/src/locales/pt-BR.json +72 -0
  234. package/src/logger.js +38 -0
  235. package/src/prompt.js +46 -0
  236. package/src/readme/README.md +119 -0
  237. package/src/runs.js +90 -0
  238. package/src/skills-cli.js +157 -0
  239. package/src/skills.js +146 -0
  240. package/src/update.js +169 -0
  241. package/templates/_conectese/.conectese-version +1 -0
  242. package/templates/_conectese/_investigations/.gitkeep +0 -0
  243. package/templates/ide-templates/antigravity/.agent/rules/conectese.md +55 -0
  244. package/templates/ide-templates/antigravity/.agent/workflows/conectese.md +102 -0
  245. package/templates/ide-templates/claude-code/.claude/skills/conectese/SKILL.md +182 -0
  246. package/templates/ide-templates/claude-code/.mcp.json +8 -0
  247. package/templates/ide-templates/claude-code/CLAUDE.md +43 -0
  248. package/templates/ide-templates/codex/.agents/skills/conectese/SKILL.md +6 -0
  249. package/templates/ide-templates/codex/AGENTS.md +105 -0
  250. package/templates/ide-templates/cursor/.cursor/commands/conectese.md +9 -0
  251. package/templates/ide-templates/cursor/.cursor/mcp.json +8 -0
  252. package/templates/ide-templates/cursor/.cursor/rules/conectese.mdc +48 -0
  253. package/templates/ide-templates/cursor/.cursorignore +3 -0
  254. package/templates/ide-templates/opencode/.opencode/commands/conectese.md +9 -0
  255. package/templates/ide-templates/opencode/AGENTS.md +105 -0
  256. package/templates/ide-templates/vscode-copilot/.github/prompts/conectese.prompt.md +201 -0
  257. package/templates/ide-templates/vscode-copilot/.vscode/mcp.json +8 -0
  258. package/templates/ide-templates/vscode-copilot/.vscode/settings.json +3 -0
  259. package/templates/package.json +8 -0
  260. package/templates/squads/.gitkeep +0 -0
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "conectese-dashboard",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc -b && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "dependencies": {
12
+ "phaser": "^3.90.0",
13
+ "react": "^19.1.0",
14
+ "react-dom": "^19.1.0",
15
+ "yaml": "^2.7.1",
16
+ "zustand": "^5.0.3"
17
+ },
18
+ "devDependencies": {
19
+ "@types/react": "^19.1.2",
20
+ "@types/react-dom": "^19.1.2",
21
+ "@types/ws": "^8.18.1",
22
+ "@vitejs/plugin-react": "^4.5.2",
23
+ "chokidar": "^4.0.3",
24
+ "typescript": "^5.8.3",
25
+ "vite": "^6.3.5",
26
+ "ws": "^8.18.1"
27
+ }
28
+ }
@@ -0,0 +1,46 @@
1
+ import { useSquadSocket } from "@/hooks/useSquadSocket";
2
+ import { SquadSelector } from "@/components/SquadSelector";
3
+ import { PhaserGame } from "@/office/PhaserGame";
4
+ import { StatusBar } from "@/components/StatusBar";
5
+
6
+ export function App() {
7
+ useSquadSocket();
8
+
9
+ return (
10
+ <div
11
+ style={{
12
+ display: "flex",
13
+ flexDirection: "column",
14
+ height: "100%",
15
+ width: "100%",
16
+ }}
17
+ >
18
+ {/* Header */}
19
+ <header
20
+ style={{
21
+ display: "flex",
22
+ alignItems: "center",
23
+ padding: "0 16px",
24
+ height: 40,
25
+ minHeight: 40,
26
+ borderBottom: "1px solid var(--border)",
27
+ background: "var(--bg-sidebar)",
28
+ fontSize: 13,
29
+ fontWeight: 600,
30
+ letterSpacing: 0.5,
31
+ }}
32
+ >
33
+ conectese Dashboard
34
+ </header>
35
+
36
+ {/* Main content */}
37
+ <div style={{ display: "flex", flex: 1, overflow: "hidden" }}>
38
+ <SquadSelector />
39
+ <PhaserGame />
40
+ </div>
41
+
42
+ {/* Footer */}
43
+ <StatusBar />
44
+ </div>
45
+ );
46
+ }
@@ -0,0 +1,47 @@
1
+ import type { SquadInfo, SquadState } from "@/types/state";
2
+ import { StatusBadge } from "./StatusBadge";
3
+
4
+ interface SquadCardProps {
5
+ squad: SquadInfo;
6
+ state: SquadState | undefined;
7
+ isSelected: boolean;
8
+ onSelect: () => void;
9
+ }
10
+
11
+ export function SquadCard({ squad, state, isSelected, onSelect }: SquadCardProps) {
12
+ const isActive = !!state;
13
+ const status = state?.status ?? "inactive";
14
+
15
+ return (
16
+ <button
17
+ onClick={onSelect}
18
+ style={{
19
+ display: "flex",
20
+ alignItems: "center",
21
+ gap: 8,
22
+ width: "100%",
23
+ padding: "10px 12px",
24
+ border: "none",
25
+ borderLeft: isSelected ? "3px solid var(--accent-cyan)" : "3px solid transparent",
26
+ background: isSelected ? "var(--bg-secondary)" : "transparent",
27
+ color: isActive ? "var(--text-primary)" : "var(--text-secondary)",
28
+ cursor: "pointer",
29
+ textAlign: "left",
30
+ fontSize: 13,
31
+ fontFamily: "inherit",
32
+ transition: "all 0.15s ease",
33
+ }}
34
+ >
35
+ <StatusBadge status={status} />
36
+ <span style={{ marginRight: 4 }}>{squad.icon}</span>
37
+ <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
38
+ {squad.name}
39
+ </span>
40
+ {state?.step && (
41
+ <span style={{ fontSize: 11, color: "var(--text-secondary)" }}>
42
+ {state.step.current}/{state.step.total}
43
+ </span>
44
+ )}
45
+ </button>
46
+ );
47
+ }
@@ -0,0 +1,61 @@
1
+ import { useSquadStore } from "@/store/useSquadStore";
2
+ import { SquadCard } from "./SquadCard";
3
+
4
+ export function SquadSelector() {
5
+ const squads = useSquadStore((s) => s.squads);
6
+ const activeStates = useSquadStore((s) => s.activeStates);
7
+ const selectedSquad = useSquadStore((s) => s.selectedSquad);
8
+ const selectSquad = useSquadStore((s) => s.selectSquad);
9
+
10
+ // Sort: active squads first, then alphabetical
11
+ const squadList = Array.from(squads.values()).sort((a, b) => {
12
+ const aActive = activeStates.has(a.code) ? 0 : 1;
13
+ const bActive = activeStates.has(b.code) ? 0 : 1;
14
+ if (aActive !== bActive) return aActive - bActive;
15
+ return a.name.localeCompare(b.name);
16
+ });
17
+
18
+ return (
19
+ <aside
20
+ style={{
21
+ width: 240,
22
+ minWidth: 240,
23
+ height: "100%",
24
+ background: "var(--bg-sidebar)",
25
+ borderRight: "1px solid var(--border)",
26
+ display: "flex",
27
+ flexDirection: "column",
28
+ overflow: "hidden",
29
+ }}
30
+ >
31
+ <div
32
+ style={{
33
+ padding: "16px 12px 8px",
34
+ fontSize: 11,
35
+ fontWeight: 600,
36
+ textTransform: "uppercase",
37
+ letterSpacing: 1,
38
+ color: "var(--text-secondary)",
39
+ }}
40
+ >
41
+ Squads
42
+ </div>
43
+ <div style={{ flex: 1, overflowY: "auto" }}>
44
+ {squadList.length === 0 && (
45
+ <div style={{ padding: "16px 12px", color: "var(--text-secondary)", fontSize: 12 }}>
46
+ No squads found
47
+ </div>
48
+ )}
49
+ {squadList.map((squad) => (
50
+ <SquadCard
51
+ key={squad.code}
52
+ squad={squad}
53
+ state={activeStates.get(squad.code)}
54
+ isSelected={selectedSquad === squad.code}
55
+ onSelect={() => selectSquad(squad.code)}
56
+ />
57
+ ))}
58
+ </div>
59
+ </aside>
60
+ );
61
+ }
@@ -0,0 +1,32 @@
1
+ import type { SquadStatus } from "@/types/state";
2
+
3
+ const STATUS_COLORS: Record<SquadStatus | "inactive", string> = {
4
+ idle: "#888",
5
+ running: "var(--accent-cyan)",
6
+ completed: "var(--accent-green)",
7
+ checkpoint: "var(--accent-amber)",
8
+ inactive: "#444",
9
+ };
10
+
11
+ interface StatusBadgeProps {
12
+ status: SquadStatus | "inactive";
13
+ }
14
+
15
+ export function StatusBadge({ status }: StatusBadgeProps) {
16
+ const color = STATUS_COLORS[status];
17
+ const isPulsing = status === "running" || status === "checkpoint";
18
+
19
+ return (
20
+ <span
21
+ style={{
22
+ display: "inline-block",
23
+ width: 8,
24
+ height: 8,
25
+ borderRadius: "50%",
26
+ backgroundColor: color,
27
+ boxShadow: isPulsing ? `0 0 6px ${color}` : "none",
28
+ animation: isPulsing ? "pulse 1.5s ease-in-out infinite" : "none",
29
+ }}
30
+ />
31
+ );
32
+ }
@@ -0,0 +1,97 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useSquadStore } from "@/store/useSquadStore";
3
+ import { formatElapsed } from "@/lib/formatTime";
4
+
5
+ export function StatusBar() {
6
+ const selectedSquad = useSquadStore((s) => s.selectedSquad);
7
+ const state = useSquadStore((s) =>
8
+ s.selectedSquad ? s.activeStates.get(s.selectedSquad) : undefined
9
+ );
10
+ const isConnected = useSquadStore((s) => s.isConnected);
11
+
12
+ // Elapsed timer
13
+ const [elapsed, setElapsed] = useState(0);
14
+
15
+ useEffect(() => {
16
+ if (!state?.startedAt) {
17
+ setElapsed(0);
18
+ return;
19
+ }
20
+
21
+ const startTime = new Date(state.startedAt).getTime();
22
+ const tick = () => setElapsed(Date.now() - startTime);
23
+ tick();
24
+ const interval = setInterval(tick, 1000);
25
+ return () => clearInterval(interval);
26
+ }, [state?.startedAt]);
27
+
28
+ if (!selectedSquad || !state) {
29
+ return (
30
+ <footer style={footerStyle}>
31
+ <span style={{ color: "var(--text-secondary)" }}>
32
+ Select an active squad to monitor
33
+ </span>
34
+ <ConnectionDot connected={isConnected} />
35
+ </footer>
36
+ );
37
+ }
38
+
39
+ return (
40
+ <footer style={footerStyle}>
41
+ <div style={{ display: "flex", alignItems: "center", gap: 16, flex: 1, minWidth: 0 }}>
42
+ <span>
43
+ Step {state.step.current}/{state.step.total}
44
+ {state.step.label ? ` — ${state.step.label}` : ""}
45
+ </span>
46
+ {state.startedAt && (
47
+ <span style={{ color: "var(--text-secondary)" }}>
48
+ {formatElapsed(elapsed)}
49
+ </span>
50
+ )}
51
+ {state.handoff && (
52
+ <span
53
+ style={{
54
+ flex: 1,
55
+ overflow: "hidden",
56
+ textOverflow: "ellipsis",
57
+ whiteSpace: "nowrap",
58
+ color: "var(--text-secondary)",
59
+ fontSize: 12,
60
+ }}
61
+ title={`${state.handoff.from} → ${state.handoff.to}: ${state.handoff.message}`}
62
+ >
63
+ {state.handoff.from} → {state.handoff.to}: {state.handoff.message}
64
+ </span>
65
+ )}
66
+ </div>
67
+ <ConnectionDot connected={isConnected} />
68
+ </footer>
69
+ );
70
+ }
71
+
72
+ function ConnectionDot({ connected }: { connected: boolean }) {
73
+ return (
74
+ <span
75
+ title={connected ? "Connected" : "Disconnected"}
76
+ style={{
77
+ width: 8,
78
+ height: 8,
79
+ borderRadius: "50%",
80
+ backgroundColor: connected ? "var(--accent-green)" : "var(--accent-red)",
81
+ flexShrink: 0,
82
+ }}
83
+ />
84
+ );
85
+ }
86
+
87
+ const footerStyle: React.CSSProperties = {
88
+ display: "flex",
89
+ alignItems: "center",
90
+ justifyContent: "space-between",
91
+ padding: "8px 16px",
92
+ borderTop: "1px solid var(--border)",
93
+ background: "var(--bg-sidebar)",
94
+ fontSize: 13,
95
+ height: 40,
96
+ minHeight: 40,
97
+ };