conectese 0.1.15 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +2 -2
  2. package/agents/conectese_admin/AGENT.md +10 -5
  3. package/agents/data-extractor/AGENT.md +35 -3
  4. package/agents/direito-administrativo/AGENT.md +68 -22
  5. package/agents/direito-aduaneiro/AGENT.md +55 -0
  6. package/agents/direito-aeroportuario/AGENT.md +53 -0
  7. package/agents/direito-agrario/AGENT.md +73 -0
  8. package/agents/direito-ambiental/AGENT.md +61 -24
  9. package/agents/direito-bancario/AGENT.md +79 -0
  10. package/agents/direito-civil/AGENT.md +71 -20
  11. package/agents/direito-constitucional/AGENT.md +79 -0
  12. package/agents/direito-da-crianca-e-do-adolescente-eca/AGENT.md +69 -0
  13. package/agents/direito-da-propriedade-intelectual/AGENT.md +65 -0
  14. package/agents/direito-de-familia/AGENT.md +92 -0
  15. package/agents/direito-de-transito/AGENT.md +59 -0
  16. package/agents/direito-desportivo/AGENT.md +40 -27
  17. package/agents/direito-digital/AGENT.md +61 -24
  18. package/agents/direito-do-consumidor/AGENT.md +77 -0
  19. package/agents/direito-do-trabalho/AGENT.md +73 -20
  20. package/agents/direito-economico/AGENT.md +58 -0
  21. package/agents/direito-eleitoral/AGENT.md +56 -24
  22. package/agents/direito-empresarial/AGENT.md +62 -24
  23. package/agents/direito-financeiro/AGENT.md +63 -0
  24. package/agents/direito-imobiliario/AGENT.md +79 -0
  25. package/agents/direito-indigena/AGENT.md +72 -0
  26. package/agents/direito-internacional/AGENT.md +55 -24
  27. package/agents/direito-maritimo/AGENT.md +55 -0
  28. package/agents/direito-medico-e-da-saude/AGENT.md +69 -0
  29. package/agents/direito-militar/AGENT.md +54 -24
  30. package/agents/direito-notarial-e-registral/AGENT.md +47 -24
  31. package/agents/direito-penal/AGENT.md +74 -19
  32. package/agents/direito-previdenciario/AGENT.md +84 -0
  33. package/agents/direito-processal-civil/AGENT.md +72 -20
  34. package/agents/direito-processal-do-trabalho/AGENT.md +58 -24
  35. package/agents/direito-processal-militar/AGENT.md +38 -27
  36. package/agents/direito-processal-penal/AGENT.md +62 -24
  37. package/agents/direito-processual-civil/AGENT.md +94 -0
  38. package/agents/direito-processual-do-trabalho/AGENT.md +76 -0
  39. package/agents/direito-processual-militar/AGENT.md +53 -0
  40. package/agents/direito-processual-penal/AGENT.md +80 -0
  41. package/agents/direito-securitario/AGENT.md +75 -0
  42. package/agents/direito-sindical/AGENT.md +46 -24
  43. package/agents/direito-societario/AGENT.md +65 -0
  44. package/agents/direito-tributario/AGENT.md +98 -0
  45. package/agents/direito-urbanistico/AGENT.md +58 -0
  46. package/agents/direitos-humanos/AGENT.md +76 -0
  47. package/agents/legal-analyst/AGENT.md +1 -1
  48. package/agents/legal-designer/AGENT.md +8 -3
  49. package/agents/lgpd-anonymizer/AGENT.md +66 -4
  50. package/agents/lgpd-restorer/AGENT.md +38 -4
  51. package/agents/task-router/AGENT.md +47 -3
  52. package/bin/conectese.js +4 -4
  53. package/dashboard/src/App.tsx +6 -4
  54. package/dashboard/src/components/CheckpointModal.tsx +150 -0
  55. package/dashboard/src/components/StatusBadge.tsx +3 -3
  56. package/dashboard/src/components/StatusBar.tsx +7 -7
  57. package/dashboard/src/components/{SquadCard.tsx → TeamCard.tsx} +7 -7
  58. package/dashboard/src/components/{SquadSelector.tsx → TeamSelector.tsx} +18 -18
  59. package/dashboard/src/hooks/{useSquadSocket.ts → useTeamSocket.ts} +13 -13
  60. package/dashboard/src/lib/normalizeState.ts +3 -3
  61. package/dashboard/src/office/OfficeScene.ts +3 -3
  62. package/dashboard/src/office/PhaserGame.tsx +6 -6
  63. package/dashboard/src/plugin/{squadWatcher.ts → teamWatcher.ts} +83 -44
  64. package/dashboard/src/store/useTeamStore.ts +56 -0
  65. package/dashboard/src/types/state.ts +10 -9
  66. package/dashboard/tsconfig.tsbuildinfo +1 -1
  67. package/dashboard/vite.config.ts +2 -2
  68. package/package.json +12 -9
  69. package/skills/README.md +1 -1
  70. package/skills/conectese-agent-creator/SKILL.md +1 -1
  71. package/skills/conectese-design/SKILL.md +50 -0
  72. package/skills/conectese-skill-creator/SKILL.md +3 -3
  73. package/skills/conectese-skill-creator/references/skill-format.md +4 -4
  74. package/skills/document-analyzer/SKILL.md +40 -0
  75. package/skills/document-analyzer/scripts/parse-doc.js +113 -0
  76. package/skills/image-ai-generator/SKILL.md +5 -5
  77. package/skills/image-creator/SKILL.md +3 -3
  78. package/skills/image-fetcher/SKILL.md +5 -5
  79. package/skills/instagram-publisher/SKILL.md +2 -2
  80. package/skills/jurisprudencia-validator/SKILL.md +45 -0
  81. package/skills/jurisprudencia-validator/scripts/validate-urls.js +103 -0
  82. package/skills/legal-pricing/SKILL.md +33 -0
  83. package/skills/legal-pricing/scripts/pricing-engine.js +72 -0
  84. package/skills/resend/SKILL.md +2 -2
  85. package/skills/template-designer/SKILL.md +29 -29
  86. package/src/agents-cli.js +1 -1
  87. package/src/agents.js +1 -1
  88. package/src/init.js +2 -1
  89. package/src/locales/en.json +2 -2
  90. package/src/locales/es.json +2 -2
  91. package/src/locales/pt-BR.json +2 -2
  92. package/src/readme/README.md +26 -26
  93. package/src/runs.js +14 -14
  94. package/src/skills-cli.js +1 -1
  95. package/src/update.js +1 -1
  96. package/templates/_conectese/.conectese-version +1 -1
  97. package/templates/ide-templates/antigravity/.agent/rules/conectese.md +10 -10
  98. package/templates/ide-templates/antigravity/.agent/workflows/conectese.md +18 -18
  99. package/templates/ide-templates/claude-code/.claude/skills/conectese/SKILL.md +31 -31
  100. package/templates/ide-templates/claude-code/CLAUDE.md +10 -10
  101. package/templates/ide-templates/codex/.agents/skills/conectese/SKILL.md +1 -1
  102. package/templates/ide-templates/codex/AGENTS.md +18 -18
  103. package/templates/ide-templates/cursor/.cursor/commands/conectese.md +1 -1
  104. package/templates/ide-templates/opencode/.opencode/commands/conectese.md +1 -1
  105. package/templates/ide-templates/opencode/AGENTS.md +18 -18
  106. package/templates/ide-templates/vscode-copilot/.github/prompts/conectese.prompt.md +33 -33
  107. package/_conectese/.conectese-version +0 -1
  108. package/_conectese/_memory/company/modelo_contrato.md +0 -18
  109. package/_conectese/_memory/company/modelo_procuracao.md +0 -15
  110. package/_conectese/_memory/company/modelo_recibo.md +0 -13
  111. package/_conectese/config/playwright.config.json +0 -11
  112. package/_conectese/core/architect.agent.yaml +0 -110
  113. package/_conectese/core/best-practices/_catalog.yaml +0 -116
  114. package/_conectese/core/best-practices/blog-post.md +0 -132
  115. package/_conectese/core/best-practices/blog-seo.md +0 -127
  116. package/_conectese/core/best-practices/copywriting.md +0 -426
  117. package/_conectese/core/best-practices/data-analysis.md +0 -401
  118. package/_conectese/core/best-practices/email-newsletter.md +0 -118
  119. package/_conectese/core/best-practices/email-sales.md +0 -110
  120. package/_conectese/core/best-practices/image-design.md +0 -348
  121. package/_conectese/core/best-practices/instagram-feed.md +0 -235
  122. package/_conectese/core/best-practices/instagram-reels.md +0 -112
  123. package/_conectese/core/best-practices/instagram-stories.md +0 -107
  124. package/_conectese/core/best-practices/linkedin-article.md +0 -116
  125. package/_conectese/core/best-practices/linkedin-post.md +0 -121
  126. package/_conectese/core/best-practices/researching.md +0 -349
  127. package/_conectese/core/best-practices/review.md +0 -269
  128. package/_conectese/core/best-practices/social-networks-publishing.md +0 -294
  129. package/_conectese/core/best-practices/strategist.md +0 -344
  130. package/_conectese/core/best-practices/technical-writing.md +0 -365
  131. package/_conectese/core/best-practices/twitter-post.md +0 -105
  132. package/_conectese/core/best-practices/twitter-thread.md +0 -122
  133. package/_conectese/core/best-practices/whatsapp-broadcast.md +0 -107
  134. package/_conectese/core/best-practices/youtube-script.md +0 -122
  135. package/_conectese/core/best-practices/youtube-shorts.md +0 -112
  136. package/_conectese/core/prompts/build.prompt.md +0 -547
  137. package/_conectese/core/prompts/design.prompt.md +0 -469
  138. package/_conectese/core/prompts/discovery.prompt.md +0 -269
  139. package/_conectese/core/prompts/sherlock-instagram.md +0 -123
  140. package/_conectese/core/prompts/sherlock-linkedin.md +0 -73
  141. package/_conectese/core/prompts/sherlock-shared.md +0 -684
  142. package/_conectese/core/prompts/sherlock-twitter.md +0 -78
  143. package/_conectese/core/prompts/sherlock-youtube.md +0 -85
  144. package/_conectese/core/runner.pipeline.md +0 -535
  145. package/_conectese/core/skills.engine.md +0 -381
  146. package/agents/direito-adaneiro/AGENT.md +0 -42
  147. package/agents/direito-aeroporta-rio/AGENT.md +0 -42
  148. package/agents/direito-agra-rio/AGENT.md +0 -42
  149. package/agents/direito-banca-rio/AGENT.md +0 -42
  150. package/agents/direito-constitcional/AGENT.md +0 -42
  151. package/agents/direito-da-crianc-a-e-do-adolescente-eca/AGENT.md +0 -42
  152. package/agents/direito-da-propriedade-intelectal/AGENT.md +0 -42
  153. package/agents/direito-de-ami-lia/AGENT.md +0 -42
  154. package/agents/direito-de-tra-nsito/AGENT.md +0 -42
  155. package/agents/direito-do-consmidor/AGENT.md +0 -42
  156. package/agents/direito-econo-mico/AGENT.md +0 -42
  157. package/agents/direito-imobilia-rio/AGENT.md +0 -42
  158. package/agents/direito-inanceiro/AGENT.md +0 -42
  159. package/agents/direito-mari-timo/AGENT.md +0 -42
  160. package/agents/direito-me-dico-e-da-sa-de/AGENT.md +0 -42
  161. package/agents/direito-ndia-rio/AGENT.md +0 -42
  162. package/agents/direito-previdencia-rio/AGENT.md +0 -42
  163. package/agents/direito-rbani-stico/AGENT.md +0 -42
  164. package/agents/direito-secrita-rio/AGENT.md +0 -42
  165. package/agents/direito-societa-rio/AGENT.md +0 -42
  166. package/agents/direito-tribta-rio/AGENT.md +0 -42
  167. package/agents/direitos-hmanos/AGENT.md +0 -42
  168. package/dashboard/src/store/useSquadStore.ts +0 -56
@@ -7,40 +7,40 @@ import fsp from "node:fs/promises";
7
7
  import { watch as chokidarWatch } from "chokidar";
8
8
  import path from "node:path";
9
9
  import { parse as parseYaml } from "yaml";
10
- import type { SquadInfo, SquadState, WsMessage } from "../types/state";
10
+ import type { TeamInfo, TeamState, WsMessage } from "../types/state";
11
11
 
12
- function resolveSquadsDir(): string {
12
+ function resolveTeamsDir(): string {
13
13
  const candidates = [
14
- path.resolve(process.cwd(), "../squads"), // started from dashboard/
15
- path.resolve(process.cwd(), "squads"), // started from project root
14
+ path.resolve(process.cwd(), "../teams"), // started from dashboard/
15
+ path.resolve(process.cwd(), "teams"), // started from project root
16
16
  ];
17
17
  for (const c of candidates) {
18
18
  if (fs.existsSync(c)) return c;
19
19
  }
20
- return path.resolve(process.cwd(), "../squads"); // default (will be created on demand)
20
+ return path.resolve(process.cwd(), "../teams"); // default (will be created on demand)
21
21
  }
22
22
 
23
- async function discoverSquads(squadsDir: string): Promise<SquadInfo[]> {
23
+ async function discoverTeams(teamsDir: string): Promise<TeamInfo[]> {
24
24
  let entries;
25
25
  try {
26
- entries = await fsp.readdir(squadsDir, { withFileTypes: true });
26
+ entries = await fsp.readdir(teamsDir, { withFileTypes: true });
27
27
  } catch {
28
28
  return [];
29
29
  }
30
30
 
31
- const squads: SquadInfo[] = [];
31
+ const teams: TeamInfo[] = [];
32
32
 
33
33
  for (const entry of entries) {
34
34
  if (!entry.isDirectory()) continue;
35
35
  if (entry.name.startsWith(".") || entry.name.startsWith("_")) continue;
36
36
 
37
- const yamlPath = path.join(squadsDir, entry.name, "squad.yaml");
37
+ const yamlPath = path.join(teamsDir, entry.name, "team.yaml");
38
38
  try {
39
39
  const raw = await fsp.readFile(yamlPath, "utf-8");
40
40
  const parsed = parseYaml(raw);
41
- const s = parsed?.squad;
41
+ const s = parsed?.team;
42
42
  if (s) {
43
- squads.push({
43
+ teams.push({
44
44
  code: typeof s.code === "string" ? s.code : entry.name,
45
45
  name: typeof s.name === "string" ? s.name : entry.name,
46
46
  description: typeof s.description === "string" ? s.description : "",
@@ -50,10 +50,10 @@ async function discoverSquads(squadsDir: string): Promise<SquadInfo[]> {
50
50
  continue;
51
51
  }
52
52
  } catch {
53
- // No squad.yaml or invalid YAML — fall through to default
53
+ // No team.yaml or invalid YAML — fall through to default
54
54
  }
55
55
 
56
- squads.push({
56
+ teams.push({
57
57
  code: entry.name,
58
58
  name: entry.name,
59
59
  description: "",
@@ -62,10 +62,10 @@ async function discoverSquads(squadsDir: string): Promise<SquadInfo[]> {
62
62
  });
63
63
  }
64
64
 
65
- return squads;
65
+ return teams;
66
66
  }
67
67
 
68
- function isValidState(data: unknown): data is SquadState {
68
+ function isValidState(data: unknown): data is TeamState {
69
69
  if (!data || typeof data !== "object") return false;
70
70
  const d = data as Record<string, unknown>;
71
71
  return (
@@ -75,19 +75,19 @@ function isValidState(data: unknown): data is SquadState {
75
75
  );
76
76
  }
77
77
 
78
- async function readActiveStates(squadsDir: string): Promise<Record<string, SquadState>> {
79
- const states: Record<string, SquadState> = {};
78
+ async function readActiveStates(teamsDir: string): Promise<Record<string, TeamState>> {
79
+ const states: Record<string, TeamState> = {};
80
80
 
81
81
  let entries;
82
82
  try {
83
- entries = await fsp.readdir(squadsDir, { withFileTypes: true });
83
+ entries = await fsp.readdir(teamsDir, { withFileTypes: true });
84
84
  } catch {
85
85
  return states;
86
86
  }
87
87
 
88
88
  for (const entry of entries) {
89
89
  if (!entry.isDirectory()) continue;
90
- const statePath = path.join(squadsDir, entry.name, "state.json");
90
+ const statePath = path.join(teamsDir, entry.name, "state.json");
91
91
 
92
92
  try {
93
93
  const raw = await fsp.readFile(statePath, "utf-8");
@@ -103,11 +103,11 @@ async function readActiveStates(squadsDir: string): Promise<Record<string, Squad
103
103
  return states;
104
104
  }
105
105
 
106
- async function buildSnapshot(squadsDir: string): Promise<WsMessage> {
106
+ async function buildSnapshot(teamsDir: string): Promise<WsMessage> {
107
107
  return {
108
108
  type: "SNAPSHOT",
109
- squads: await discoverSquads(squadsDir),
110
- activeStates: await readActiveStates(squadsDir),
109
+ teams: await discoverTeams(teamsDir),
110
+ activeStates: await readActiveStates(teamsDir),
111
111
  };
112
112
  }
113
113
 
@@ -124,22 +124,22 @@ function broadcast(wss: WebSocketServer, msg: WsMessage) {
124
124
  }
125
125
  }
126
126
 
127
- export function squadWatcherPlugin(): Plugin {
127
+ export function teamWatcherPlugin(): Plugin {
128
128
  return {
129
- name: "squad-watcher",
129
+ name: "team-watcher",
130
130
  configureServer(server: ViteDevServer) {
131
131
  if (!server.httpServer) {
132
- server.config.logger.warn("[squad-watcher] no httpServer — skipping");
132
+ server.config.logger.warn("[team-watcher] no httpServer — skipping");
133
133
  return;
134
134
  }
135
135
 
136
- const squadsDir = resolveSquadsDir();
137
- server.config.logger.info(`[squad-watcher] squads dir: ${squadsDir}`);
136
+ const teamsDir = resolveTeamsDir();
137
+ server.config.logger.info(`[team-watcher] teams dir: ${teamsDir}`);
138
138
 
139
139
  // Create WebSocket server with noServer to avoid intercepting Vite's HMR
140
140
  const wss = new WebSocketServer({ noServer: true });
141
141
  (server.httpServer as Server).on("upgrade", (req: IncomingMessage, socket: Duplex, head: Buffer) => {
142
- if (req.url === "/__squads_ws") {
142
+ if (req.url === "/__teams_ws") {
143
143
  wss.handleUpgrade(req, socket, head, (ws) => {
144
144
  wss.emit("connection", ws, req);
145
145
  });
@@ -150,23 +150,23 @@ export function squadWatcherPlugin(): Plugin {
150
150
  // Send snapshot on new connection
151
151
  wss.on("connection", async (ws) => {
152
152
  try {
153
- const snap = await buildSnapshot(squadsDir);
153
+ const snap = await buildSnapshot(teamsDir);
154
154
  ws.send(JSON.stringify(snap));
155
155
  } catch {
156
156
  // Connection may have closed before snapshot was ready
157
157
  }
158
158
  });
159
159
 
160
- // Ensure squads directory exists
161
- fsp.mkdir(squadsDir, { recursive: true }).catch((err) => {
162
- server.config.logger.error(`[squad-watcher] failed to create squads dir: ${err.message}`);
160
+ // Ensure teams directory exists
161
+ fsp.mkdir(teamsDir, { recursive: true }).catch((err) => {
162
+ server.config.logger.error(`[team-watcher] failed to create teams dir: ${err.message}`);
163
163
  });
164
164
 
165
165
  // REST API fallback & File Upload
166
166
  server.middlewares.use(async (req, res, next) => {
167
167
  if (req.url === "/api/snapshot" && req.method === "GET") {
168
168
  try {
169
- const snapshot = await buildSnapshot(squadsDir);
169
+ const snapshot = await buildSnapshot(teamsDir);
170
170
  res.setHeader("Content-Type", "application/json");
171
171
  res.setHeader("Cache-Control", "no-cache");
172
172
  res.end(JSON.stringify(snapshot));
@@ -256,11 +256,50 @@ export function squadWatcherPlugin(): Plugin {
256
256
  return;
257
257
  }
258
258
 
259
+ if (req.url?.startsWith("/api/team/") && req.url?.endsWith("/checkpoint") && req.method === "POST") {
260
+ const parts = req.url.split("/");
261
+ const teamName = parts[3];
262
+ let body = "";
263
+ req.on("data", chunk => body += chunk.toString());
264
+ req.on("end", async () => {
265
+ try {
266
+ const payload = JSON.parse(body);
267
+ const checkpointFile = path.join(teamsDir, teamName, "checkpoint_response.json");
268
+ await fsp.writeFile(checkpointFile, JSON.stringify(payload, null, 2), "utf-8");
269
+
270
+ const stateFile = path.join(teamsDir, teamName, "state.json");
271
+ try {
272
+ const stateRaw = await fsp.readFile(stateFile, "utf-8");
273
+ const state = JSON.parse(stateRaw);
274
+ state.status = "running"; // Clear checkpoint status on UI
275
+ if (state.agents) {
276
+ state.agents.forEach((a: any) => {
277
+ if (a.status === "checkpoint") a.status = "working";
278
+ });
279
+ }
280
+ state.updatedAt = new Date().toISOString();
281
+ await fsp.writeFile(stateFile, JSON.stringify(state, null, 2), "utf-8");
282
+ } catch (e) {
283
+ // Ignore state.json update errors
284
+ }
285
+
286
+ res.setHeader("Content-Type", "application/json");
287
+ res.writeHead(200);
288
+ res.end(JSON.stringify({ success: true }));
289
+ } catch (err: any) {
290
+ res.setHeader("Content-Type", "application/json");
291
+ res.writeHead(400);
292
+ res.end(JSON.stringify({ success: false, error: err.message }));
293
+ }
294
+ });
295
+ return;
296
+ }
297
+
259
298
  return next();
260
299
  });
261
300
 
262
301
  // File watcher using chokidar — reliable cross-platform, handles partial writes
263
- const watcher = chokidarWatch(squadsDir, {
302
+ const watcher = chokidarWatch(teamsDir, {
264
303
  ignoreInitial: true,
265
304
  awaitWriteFinish: { stabilityThreshold: 300, pollInterval: 50 },
266
305
  ignored: [/(^|[/\\])\./, /node_modules/, /output[/\\]/],
@@ -268,38 +307,38 @@ export function squadWatcherPlugin(): Plugin {
268
307
  });
269
308
 
270
309
  function handleFileChange(filePath: string) {
271
- const relative = path.relative(squadsDir, filePath).replace(/\\/g, "/");
310
+ const relative = path.relative(teamsDir, filePath).replace(/\\/g, "/");
272
311
  const parts = relative.split("/");
273
312
  if (parts.length < 2) return;
274
313
 
275
- const squadName = parts[0];
314
+ const teamName = parts[0];
276
315
  const fileName = parts[1];
277
316
 
278
317
  if (fileName === "state.json") {
279
318
  fsp.readFile(filePath, "utf-8").then((raw) => {
280
319
  const parsed = JSON.parse(raw);
281
320
  if (!isValidState(parsed)) return;
282
- broadcast(wss, { type: "SQUAD_UPDATE", squad: squadName, state: parsed });
321
+ broadcast(wss, { type: "TEAM_UPDATE", team: teamName, state: parsed });
283
322
  }).catch(() => {
284
323
  // Invalid JSON — next change event will retry
285
324
  });
286
- } else if (fileName === "squad.yaml") {
287
- buildSnapshot(squadsDir).then((snap) => broadcast(wss, snap));
325
+ } else if (fileName === "team.yaml") {
326
+ buildSnapshot(teamsDir).then((snap) => broadcast(wss, snap));
288
327
  }
289
328
  }
290
329
 
291
330
  function handleFileRemoval(filePath: string) {
292
- const relative = path.relative(squadsDir, filePath).replace(/\\/g, "/");
331
+ const relative = path.relative(teamsDir, filePath).replace(/\\/g, "/");
293
332
  const parts = relative.split("/");
294
333
  if (parts.length < 2) return;
295
334
 
296
- const squadName = parts[0];
335
+ const teamName = parts[0];
297
336
  const fileName = parts[1];
298
337
 
299
338
  if (fileName === "state.json") {
300
- broadcast(wss, { type: "SQUAD_INACTIVE", squad: squadName });
301
- } else if (fileName === "squad.yaml") {
302
- buildSnapshot(squadsDir).then((snap) => broadcast(wss, snap));
339
+ broadcast(wss, { type: "TEAM_INACTIVE", team: teamName });
340
+ } else if (fileName === "team.yaml") {
341
+ buildSnapshot(teamsDir).then((snap) => broadcast(wss, snap));
303
342
  }
304
343
  }
305
344
 
@@ -0,0 +1,56 @@
1
+ import { create } from "zustand";
2
+ import type { TeamInfo, TeamState } from "@/types/state";
3
+
4
+ interface TeamStore {
5
+ // State
6
+ teams: Map<string, TeamInfo>;
7
+ activeStates: Map<string, TeamState>;
8
+ selectedTeam: string | null;
9
+ isConnected: boolean;
10
+
11
+ // Actions
12
+ selectTeam: (name: string | null) => void;
13
+ setConnected: (connected: boolean) => void;
14
+ setSnapshot: (teams: TeamInfo[], activeStates: Record<string, TeamState>) => void;
15
+ setTeamActive: (team: string, state: TeamState) => void;
16
+ updateTeamState: (team: string, state: TeamState) => void;
17
+ setTeamInactive: (team: string) => void;
18
+ }
19
+
20
+ export const useTeamStore = create<TeamStore>((set) => ({
21
+ teams: new Map(),
22
+ activeStates: new Map(),
23
+ selectedTeam: null,
24
+ isConnected: false,
25
+
26
+ selectTeam: (name) => set({ selectedTeam: name }),
27
+
28
+ setConnected: (connected) => set({ isConnected: connected }),
29
+
30
+ setSnapshot: (teams, activeStates) =>
31
+ set({
32
+ teams: new Map(teams.map((s) => [s.code, s])),
33
+ activeStates: new Map(Object.entries(activeStates)),
34
+ }),
35
+
36
+ setTeamActive: (team, state) =>
37
+ set((prev) => ({
38
+ activeStates: new Map(prev.activeStates).set(team, state),
39
+ })),
40
+
41
+ updateTeamState: (team, state) =>
42
+ set((prev) => ({
43
+ activeStates: new Map(prev.activeStates).set(team, state),
44
+ })),
45
+
46
+ setTeamInactive: (team) =>
47
+ set((prev) => {
48
+ const next = new Map(prev.activeStates);
49
+ next.delete(team);
50
+ return {
51
+ activeStates: next,
52
+ // Reset selection if the inactive team was selected
53
+ selectedTeam: prev.selectedTeam === team ? null : prev.selectedTeam,
54
+ };
55
+ }),
56
+ }));
@@ -25,17 +25,18 @@ export interface Handoff {
25
25
  to: string;
26
26
  message: string;
27
27
  completedAt: string;
28
+ missingData?: string[];
28
29
  }
29
30
 
30
- export type SquadStatus =
31
+ export type TeamStatus =
31
32
  | "idle"
32
33
  | "running"
33
34
  | "completed"
34
35
  | "checkpoint";
35
36
 
36
- export interface SquadState {
37
- squad: string;
38
- status: SquadStatus;
37
+ export interface TeamState {
38
+ team: string;
39
+ status: TeamStatus;
39
40
  step: {
40
41
  current: number;
41
42
  total: number;
@@ -47,8 +48,8 @@ export interface SquadState {
47
48
  updatedAt: string;
48
49
  }
49
50
 
50
- // Squad metadata from squad.yaml
51
- export interface SquadInfo {
51
+ // Team metadata from team.yaml
52
+ export interface TeamInfo {
52
53
  code: string;
53
54
  name: string;
54
55
  description: string;
@@ -58,6 +59,6 @@ export interface SquadInfo {
58
59
 
59
60
  // WebSocket messages
60
61
  export type WsMessage =
61
- | { type: "SNAPSHOT"; squads: SquadInfo[]; activeStates: Record<string, SquadState> }
62
- | { type: "SQUAD_UPDATE"; squad: string; state: SquadState }
63
- | { type: "SQUAD_INACTIVE"; squad: string };
62
+ | { type: "SNAPSHOT"; teams: TeamInfo[]; activeStates: Record<string, TeamState> }
63
+ | { type: "TEAM_UPDATE"; team: string; state: TeamState }
64
+ | { type: "TEAM_INACTIVE"; team: string };
@@ -1 +1 @@
1
- {"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/ingestionmodal.tsx","./src/components/squadcard.tsx","./src/components/squadselector.tsx","./src/components/statusbadge.tsx","./src/components/statusbar.tsx","./src/hooks/usesquadsocket.ts","./src/lib/formattime.ts","./src/lib/normalizestate.ts","./src/office/agentsprite.ts","./src/office/officescene.ts","./src/office/phasergame.tsx","./src/office/roombuilder.ts","./src/office/assetkeys.ts","./src/office/palette.ts","./src/plugin/squadwatcher.ts","./src/store/usesquadstore.ts","./src/types/state.ts"],"version":"5.9.3"}
1
+ {"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/components/ingestionmodal.tsx","./src/components/statusbadge.tsx","./src/components/statusbar.tsx","./src/components/teamcard.tsx","./src/components/teamselector.tsx","./src/hooks/useteamsocket.ts","./src/lib/formattime.ts","./src/lib/normalizestate.ts","./src/office/agentsprite.ts","./src/office/officescene.ts","./src/office/phasergame.tsx","./src/office/roombuilder.ts","./src/office/assetkeys.ts","./src/office/palette.ts","./src/plugin/teamwatcher.ts","./src/store/useteamstore.ts","./src/types/state.ts"],"version":"5.9.3"}
@@ -1,10 +1,10 @@
1
1
  import { defineConfig } from "vite";
2
2
  import react from "@vitejs/plugin-react";
3
3
  import path from "node:path";
4
- import { squadWatcherPlugin } from "./src/plugin/squadWatcher";
4
+ import { teamWatcherPlugin } from "./src/plugin/teamWatcher";
5
5
 
6
6
  export default defineConfig({
7
- plugins: [react(), squadWatcherPlugin()],
7
+ plugins: [react(), teamWatcherPlugin()],
8
8
  resolve: {
9
9
  alias: {
10
10
  "@": path.resolve(__dirname, "./src"),
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "conectese",
3
- "version": "0.1.15",
4
- "description": "Multi-agent orchestration framework — create AI squads that work together",
3
+ "version": "0.2.0",
4
+ "description": "Multi-agent orchestration framework — create AI teams that work together",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "conectese": "bin/conectese.js"
8
8
  },
9
9
  "scripts": {
10
- "test": "node --test tests/*.test.js",
10
+ "test": "node --test 'tests/**/*.test.js' 'tests/*.test.js'",
11
11
  "lint": "eslint src/ bin/ tests/",
12
12
  "setup-admin": "node bin/setup_admin.js",
13
13
  "version": "node -e \"require('fs').writeFileSync('templates/_conectese/.conectese-version', require('./package.json').version + '\\n')\" && git add templates/_conectese/.conectese-version"
@@ -17,16 +17,16 @@
17
17
  "ai-agents",
18
18
  "multi-agent",
19
19
  "orchestration",
20
- "squads"
20
+ "teams"
21
21
  ],
22
- "author": "Renato Asse (https://github.com/renatoasse)",
23
- "homepage": "https://github.com/renatoasse/conectese#readme",
22
+ "author": "Carlos Henrique (https://github.com/henriqueadm-ai)",
23
+ "homepage": "https://github.com/henriqueadm-ai/conectese#readme",
24
24
  "repository": {
25
25
  "type": "git",
26
- "url": "git+https://github.com/renatoasse/conectese.git"
26
+ "url": "git+https://github.com/henriqueadm-ai/conectese.git"
27
27
  },
28
28
  "bugs": {
29
- "url": "https://github.com/renatoasse/conectese/issues"
29
+ "url": "https://github.com/henriqueadm-ai/conectese/issues"
30
30
  },
31
31
  "license": "MIT",
32
32
  "engines": {
@@ -38,10 +38,10 @@
38
38
  "agents/",
39
39
  "skills/",
40
40
  "templates/",
41
- "_conectese/",
42
41
  "dashboard/"
43
42
  ],
44
43
  "dependencies": {
44
+ "@google/genai": "^1.48.0",
45
45
  "@inquirer/checkbox": "^5.1.0",
46
46
  "@inquirer/input": "^5.0.0",
47
47
  "@inquirer/select": "^5.1.0",
@@ -51,6 +51,9 @@
51
51
  "dotenv": "^17.4.0",
52
52
  "html-to-docx": "^1.8.0",
53
53
  "marked": "^17.0.5",
54
+ "pdf-parse": "^2.4.5"
55
+ },
56
+ "optionalDependencies": {
54
57
  "puppeteer": "^24.40.0",
55
58
  "puppeteer-extra": "^3.3.6",
56
59
  "puppeteer-extra-plugin-stealth": "^2.11.2"
package/skills/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Conectese Skill Catalog
2
2
 
3
- Browse available skills for your squads. Install any skill with:
3
+ Browse available skills for your teams. Install any skill with:
4
4
 
5
5
  ```bash
6
6
  npx conectese install <skill-name>
@@ -142,7 +142,7 @@ The Best-Practice Creator workflow (above) handles the initial `whenToUse` cross
142
142
 
143
143
  ### When updating a best-practice file's `whenToUse` scope
144
144
 
145
- This is the most impactful change — it affects how the Architect selects best practices during squad creation.
145
+ This is the most impactful change — it affects how the Architect selects best practices during team creation.
146
146
 
147
147
  1. Document the old scope and new scope
148
148
  2. Update the best-practice file's `whenToUse` field
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: conectese-design
3
+ description: >
4
+ Motor de design jurídico (Visual Law). Converte Markdown judicial em PDFs
5
+ e DOCXs estilizados com timbre do escritório, empregando CSS premium e
6
+ Puppeteer para renderização fiel. Inclui geração de contratos, procurações,
7
+ recibos e peças processuais formatadas.
8
+ type: mcp
9
+ version: "1.0.0"
10
+ mcp:
11
+ server_name: conectese-design
12
+ command: node
13
+ args: ["skills/conectese-design/index.cjs"]
14
+ transport: stdio
15
+ categories: [design, legal, pdf, visual-law]
16
+ ---
17
+
18
+ # Conectese Design (Visual Law Engine)
19
+
20
+ ## When to use
21
+
22
+ Use esta skill quando o pipeline precisar gerar documentos jurídicos em PDF ou DOCX com formatação profissional e timbre do escritório. Ela é o motor de saída visual da plataforma Conecte.se.
23
+
24
+ ## Instructions
25
+
26
+ ### Ferramentas disponíveis (MCP Tools)
27
+
28
+ - **`generate_visual_law_pdf`**: Recebe Markdown + ID do processo, gera PDF estilizado com timbre institucional.
29
+ - **`generate_visual_law_docx`**: Mesmo fluxo mas gera DOCX editável.
30
+ - **`generate_contract_pdf`**: Gera PDF de contrato preenchido a partir de modelo + dados do cliente.
31
+
32
+ ### Parâmetros obrigatórios
33
+
34
+ | Parâmetro | Descrição |
35
+ |-----------|-----------|
36
+ | `markdownContent` | O conteúdo Markdown da peça/documento |
37
+ | `processId` | ID do processo (ex: `P05_04_0001`) ou `ADMINISTRATIVO` para documentos fora de processos |
38
+ | `outputFormat` | `pdf` ou `docx` |
39
+
40
+ ### Comportamento de saída
41
+
42
+ - PDFs e DOCXs são salvos automaticamente em `PROCESSOS/{processId}/` ou `ADMINISTRATIVO/`.
43
+ - O timbre do escritório é carregado de `_conectese/_memory/company/dados.json`.
44
+ - CSS premium aplicado com fontes profissionais e espaçamento tipográfico adequado.
45
+
46
+ ### Best practices
47
+
48
+ - Sempre passe o `processId` correto para organização automática de arquivos.
49
+ - O Markdown de entrada deve usar as tags de anonimização `[PESSOA_1]` até o `lgpd-restorer` fazer a restauração final.
50
+ - Para documentos administrativos (contratos, procurações), use `ADMINISTRATIVO` como processId.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: conectese-skill-creator
3
- description: Create new Conectese skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill for their squads, update or optimize an existing skill, run evals to test a skill, or benchmark skill performance. Supports all Conectese skill types: MCP integrations, custom scripts, hybrid, and behavioral prompts.
3
+ description: Create new Conectese skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill for their teams, update or optimize an existing skill, run evals to test a skill, or benchmark skill performance. Supports all Conectese skill types: MCP integrations, custom scripts, hybrid, and behavioral prompts.
4
4
  ---
5
5
 
6
6
  # Conectese Skill Creator
@@ -47,7 +47,7 @@ It's OK to briefly explain terms if you're in doubt, and feel free to clarify te
47
47
  Start by understanding the user's intent. The current conversation might already contain a workflow the user wants to capture (e.g., they say "turn this into a skill"). If so, extract answers from the conversation history first — the tools used, the sequence of steps, corrections the user made, input/output formats observed. The user may need to fill the gaps, and should confirm before proceeding to the next step.
48
48
 
49
49
  1. What should this skill enable agents to do?
50
- 2. When should this skill be used? (what user phrases/contexts/squad scenarios)
50
+ 2. When should this skill be used? (what user phrases/contexts/team scenarios)
51
51
  3. What's the expected output format?
52
52
  4. Should we set up test cases to verify the skill works? Skills with objectively verifiable outputs (file transforms, data extraction, code generation, fixed workflow steps) benefit from test cases. Skills with subjective outputs (writing style, art) often don't need them. Suggest the appropriate default based on the skill type, but let the user decide.
53
53
 
@@ -190,7 +190,7 @@ For each test case, spawn two subagents in the same turn — one with the skill,
190
190
 
191
191
  **With-skill run:**
192
192
 
193
- The with-skill run simulates how a Conectese agent operates with this skill injected into its context. The skill's SKILL.md body gets appended to the agent's instructions, just like the pipeline runner does during actual squad execution.
193
+ The with-skill run simulates how a Conectese agent operates with this skill injected into its context. The skill's SKILL.md body gets appended to the agent's instructions, just like the pipeline runner does during actual team execution.
194
194
 
195
195
  ```
196
196
  Execute this task:
@@ -91,7 +91,7 @@ mcp:
91
91
 
92
92
  ## When to use
93
93
 
94
- Use this skill when the user or squad pipeline needs to create visual content — social media posts, presentations, flyers, or any graphic design task that benefits from Canva's template library.
94
+ Use this skill when the user or team pipeline needs to create visual content — social media posts, presentations, flyers, or any graphic design task that benefits from Canva's template library.
95
95
 
96
96
  ## Instructions
97
97
 
@@ -155,7 +155,7 @@ Use this skill when the pipeline needs to analyze tabular data from CSV files
155
155
  ```yaml
156
156
  ---
157
157
  name: professional-tone
158
- description: Write content in a professional corporate tone. Use when squad agents need to produce business communications, reports, or client-facing materials that require formal, polished language.
158
+ description: Write content in a professional corporate tone. Use when team agents need to produce business communications, reports, or client-facing materials that require formal, polished language.
159
159
  type: prompt
160
160
  version: 1.0.0
161
161
  categories:
@@ -198,7 +198,7 @@ When writing in professional tone:
198
198
  ```yaml
199
199
  ---
200
200
  name: social-publisher
201
- description: Draft social media content and publish via API. Use when squads need to create and post content to Instagram, Twitter/X, or LinkedIn with approval workflows.
201
+ description: Draft social media content and publish via API. Use when teams need to create and post content to Instagram, Twitter/X, or LinkedIn with approval workflows.
202
202
  type: hybrid
203
203
  version: 1.0.0
204
204
  categories:
@@ -227,7 +227,7 @@ Use this skill when the pipeline needs to both create and publish social media c
227
227
 
228
228
  ## Instructions
229
229
 
230
- 1. Draft the content using squad agent context (topic, tone, audience)
230
+ 1. Draft the content using team agent context (topic, tone, audience)
231
231
  2. Run the formatting script to prepare platform-specific versions
232
232
  3. Present drafts for user approval at the checkpoint
233
233
  4. After approval, use the MCP server to publish to the target platforms
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: document-analyzer
3
+ description: >
4
+ Motor analítico de documentos para extração e estruturação profunda de PDFs.
5
+ Lê arquivos não estruturados e aplica frameworks de extração semântica
6
+ (classificação de entidades, SLAs, Prazos, CNPJs, etc.).
7
+ version: "1.0.0"
8
+ type: "custom"
9
+ categories: [data, parsing, legal]
10
+ ---
11
+
12
+ # Document Analyzer
13
+
14
+ ## When to use
15
+
16
+ Use a ferramenta `document-analyzer` quando você ou outro Agente precisar inferir e extrair inteligência processável a partir de contratos, relatórios, peças processuais ou arquivos PDF enviados por usuários. Esta skill consolida extração óptica/vetorial (OCR/Parsing) com a sua própria capacidade nativa cognitiva para devolver formatos padronizados (JSON, Markdown) livres de ruído estrutural.
17
+
18
+ ## Instructions
19
+
20
+ Esta Skill invoca scripts locais do Node.js (via bash) juntamente com suas próprias heurísticas de extração semântica.
21
+
22
+ ### Key capabilities
23
+
24
+ - **Text Extraction (PDFs):** Extração bruta de texto de vetores locais usando algoritmos otimizados para evitar alucinações de formatação.
25
+ - **Data Extractor Pipeline:** Extração estruturada de dados densos (ex: Cláusulas de Quebra, Multas, Prazos Recusais, Qualificação de Partes) de forma determinística.
26
+ - **Noise Reduction:** Limpeza de cabeçalhos/rodapés mortos que gastam cota de tokens no prompt.
27
+
28
+ ### Best practices
29
+
30
+ - **Sempre Verifique o Retorno:** Ao ler um arquivo grande usando a ferramenta de extração, procure limitar a resposta fatiando-a, se for necessário analisar em múltiplos passos.
31
+ - **Saída Estruturada:** Se o usuário pedir os "termos chave", elabore um mapeamento estrito retornando num formato de blocos demarcados (`JSON` ou `lista md`).
32
+ - **Anonimização (LGPD):** Se você for rotear o resultado documentado para fora do ambiente de auditoria, Oculte CPFs e nomes sensíveis.
33
+
34
+ ## Available operations
35
+
36
+ Abaixo explicamos o wrapper integrado para consumo. Execute o script com sua sandbox local:
37
+
38
+ - `node skills/document-analyzer/scripts/parse-doc.js <caminho.pdf>`: Recebe um arquivo PDF e tenta extrair o texto via parsing nativo. Caso retorne texto vazio (indicando ser um arquivo digitalizado/imagem), **fará um fallback automático** para leitura via LLM (Gemini Vision) em background requerendo a chave de ambiente `GEMINI_API_KEY`.
39
+ - `node skills/document-analyzer/scripts/parse-doc.js <caminho.pdf> --vision`: Força imediatamente a leitura visual multimodal desabilitando a decodificação pura do arquivo local.
40
+ - `node skills/document-analyzer/scripts/parse-doc.js <caminho.pdf> --extract="Extraia apenas os valores e datas em formato JSON"`: Além de fazer OCR/Vision do documento, embute um system prompt customizado onde a extração será orientada de modo formidável a retornar dados pré-estruturados conforme seu pedido.