@noclaf/cli 0.5.6 → 0.7.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 (78) hide show
  1. package/README.md +18 -1
  2. package/dist/adapters/supabase/calendar-gateway.js +48 -0
  3. package/dist/adapters/supabase/calendar-gateway.js.map +1 -0
  4. package/dist/adapters/supabase/calendar-write-gateway.js +35 -0
  5. package/dist/adapters/supabase/calendar-write-gateway.js.map +1 -0
  6. package/dist/adapters/supabase/gateway.js +8 -0
  7. package/dist/adapters/supabase/gateway.js.map +1 -1
  8. package/dist/adapters/supabase/release-gateway.js +61 -0
  9. package/dist/adapters/supabase/release-gateway.js.map +1 -0
  10. package/dist/adapters/supabase/sprint-gateway.js +59 -0
  11. package/dist/adapters/supabase/sprint-gateway.js.map +1 -0
  12. package/dist/adapters/supabase/task-gateway.js +41 -36
  13. package/dist/adapters/supabase/task-gateway.js.map +1 -1
  14. package/dist/core/types.js +4 -6
  15. package/dist/core/types.js.map +1 -1
  16. package/dist/lib/calendar-logic.js +59 -0
  17. package/dist/lib/calendar-logic.js.map +1 -0
  18. package/dist/lib/calendar-write-logic.js +6 -0
  19. package/dist/lib/calendar-write-logic.js.map +1 -0
  20. package/dist/lib/dates.js +21 -0
  21. package/dist/lib/dates.js.map +1 -0
  22. package/dist/lib/pg-error.js +53 -0
  23. package/dist/lib/pg-error.js.map +1 -0
  24. package/dist/lib/release-logic.js +10 -0
  25. package/dist/lib/release-logic.js.map +1 -0
  26. package/dist/lib/sprint-deadline.js +28 -0
  27. package/dist/lib/sprint-deadline.js.map +1 -0
  28. package/dist/lib/sprint-logic.js +31 -0
  29. package/dist/lib/sprint-logic.js.map +1 -0
  30. package/dist/lib/tool-result.js +4 -1
  31. package/dist/lib/tool-result.js.map +1 -1
  32. package/dist/tools/activate-sprint.js +44 -0
  33. package/dist/tools/activate-sprint.js.map +1 -0
  34. package/dist/tools/add-holiday.js +41 -0
  35. package/dist/tools/add-holiday.js.map +1 -0
  36. package/dist/tools/add-home-office.js +31 -0
  37. package/dist/tools/add-home-office.js.map +1 -0
  38. package/dist/tools/add-vacation.js +39 -0
  39. package/dist/tools/add-vacation.js.map +1 -0
  40. package/dist/tools/create-release.js +46 -0
  41. package/dist/tools/create-release.js.map +1 -0
  42. package/dist/tools/create-sprint.js +66 -0
  43. package/dist/tools/create-sprint.js.map +1 -0
  44. package/dist/tools/create-task.js +52 -7
  45. package/dist/tools/create-task.js.map +1 -1
  46. package/dist/tools/end-sprint.js +37 -0
  47. package/dist/tools/end-sprint.js.map +1 -0
  48. package/dist/tools/finalize-release.js +45 -0
  49. package/dist/tools/finalize-release.js.map +1 -0
  50. package/dist/tools/get-calendar.js +40 -0
  51. package/dist/tools/get-calendar.js.map +1 -0
  52. package/dist/tools/get-sprint.js +38 -0
  53. package/dist/tools/get-sprint.js.map +1 -0
  54. package/dist/tools/get-task.js +1 -0
  55. package/dist/tools/get-task.js.map +1 -1
  56. package/dist/tools/index.js +34 -0
  57. package/dist/tools/index.js.map +1 -1
  58. package/dist/tools/list-releases.js +32 -0
  59. package/dist/tools/list-releases.js.map +1 -0
  60. package/dist/tools/list-sprints.js +30 -0
  61. package/dist/tools/list-sprints.js.map +1 -0
  62. package/dist/tools/list-tasks.js +18 -16
  63. package/dist/tools/list-tasks.js.map +1 -1
  64. package/dist/tools/remove-holiday.js +31 -0
  65. package/dist/tools/remove-holiday.js.map +1 -0
  66. package/dist/tools/remove-home-office.js +32 -0
  67. package/dist/tools/remove-home-office.js.map +1 -0
  68. package/dist/tools/remove-vacation.js +31 -0
  69. package/dist/tools/remove-vacation.js.map +1 -0
  70. package/dist/tools/sprint-common.js +13 -0
  71. package/dist/tools/sprint-common.js.map +1 -0
  72. package/dist/tools/update-release.js +58 -0
  73. package/dist/tools/update-release.js.map +1 -0
  74. package/dist/tools/update-sprint.js +56 -0
  75. package/dist/tools/update-sprint.js.map +1 -0
  76. package/dist/tools/update-task.js +61 -17
  77. package/dist/tools/update-task.js.map +1 -1
  78. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import { FINISHED_STATUSES } from '../core/types.js';
2
+ const pad = (n) => String(n).padStart(2, '0');
3
+ const iso = (d) => `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())}`;
4
+ /** Datas YYYY-MM-DD de `from` a `to`, inclusive. */
5
+ export function eachDay(from, to) {
6
+ const out = [];
7
+ for (let d = new Date(`${from}T00:00:00Z`); iso(d) <= to; d.setUTCDate(d.getUTCDate() + 1))
8
+ out.push(iso(d));
9
+ return out;
10
+ }
11
+ const isLeap = (y) => (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0;
12
+ /** Ocorrência anual (mês/dia de `origin`) em `date`; 29/02 cai em 28/02 em ano não bissexto. Devolve anos desde a origem. */
13
+ export function yearsOn(origin, date) {
14
+ if (!origin)
15
+ return null;
16
+ const [oy, om, od] = origin.split('-').map(Number);
17
+ const [y, m, d] = date.split('-').map(Number);
18
+ const day = om === 2 && od === 29 && !isLeap(y) ? 28 : od;
19
+ return om === m && day === d ? y - oy : null;
20
+ }
21
+ /** Monta os dias com eventos (só dias não vazios), agrupados por data. */
22
+ export function buildCalendar(from, to, s) {
23
+ const byDay = new Map();
24
+ const add = (date, ev) => {
25
+ if (date < from || date > to)
26
+ return;
27
+ const list = byDay.get(date);
28
+ if (list)
29
+ list.push(ev);
30
+ else
31
+ byDay.set(date, [ev]);
32
+ };
33
+ for (const h of s.holidays)
34
+ add(h.date, { kind: 'holiday', id: h.id, name: h.name, type: h.type, scope: h.scope });
35
+ for (const t of s.deadlines) {
36
+ if (FINISHED_STATUSES.includes(t.status))
37
+ continue;
38
+ add(t.end_date, { kind: 'deadline', key: t.key, title: t.title, status: t.status, project: t.project });
39
+ }
40
+ for (const v of s.vacations) {
41
+ for (const d of eachDay(v.start_date, v.end_date))
42
+ add(d, { kind: 'vacation', id: v.id, person: v.person, notes: v.notes });
43
+ }
44
+ for (const h of s.homeOffice)
45
+ add(h.date, { kind: 'home_office', person: h.person });
46
+ for (const r of s.releases)
47
+ add(r.target_date, { kind: 'release', name: r.name, status: r.status });
48
+ for (const d of eachDay(from, to)) {
49
+ for (const p of s.people) {
50
+ if (yearsOn(p.birth_date, d) !== null)
51
+ add(d, { kind: 'birthday', person: p.name });
52
+ const y = yearsOn(p.company_anniversary_date, d);
53
+ if (y !== null && y > 0)
54
+ add(d, { kind: 'work_anniversary', person: p.name, years: y });
55
+ }
56
+ }
57
+ return [...byDay.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([date, events]) => ({ date, events }));
58
+ }
59
+ //# sourceMappingURL=calendar-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-logic.js","sourceRoot":"","sources":["../../src/lib/calendar-logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAA8D,MAAM,kBAAkB,CAAC;AAEjH,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACtD,MAAM,GAAG,GAAG,CAAC,CAAO,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC;AAEpG,oDAAoD;AACpD,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,EAAU;IAC9C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7G,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;AAE9E,6HAA6H;AAC7H,MAAM,UAAU,OAAO,CAAC,MAAqB,EAAE,IAAY;IACzD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,OAAO,EAAE,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,EAAU,EAAE,CAAkB;IACxE,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjD,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAiB,EAAE,EAAE;QAC9C,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE;YAAE,OAAO;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;YACnB,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ;QAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IACnH,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAC5B,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,SAAS;QACnD,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1G,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9H,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU;QAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACrF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ;QAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACpG,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACzB,IAAI,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,KAAK,IAAI;gBAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACpF,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAe,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC9H,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Regras puras da escrita no calendário. */
2
+ /** DELETE negado por RLS afeta 0 linhas sem erro: 0 vira mensagem amigável; null se ok. */
3
+ export function deleteFailure(rows, what) {
4
+ return rows && rows.length > 0 ? null : `${what} não encontrado ou sem permissão.`;
5
+ }
6
+ //# sourceMappingURL=calendar-write-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendar-write-logic.js","sourceRoot":"","sources":["../../src/lib/calendar-write-logic.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAE7C,2FAA2F;AAC3F,MAAM,UAAU,aAAa,CAAC,IAAsB,EAAE,IAAY;IAChE,OAAO,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,mCAAmC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { z } from 'zod';
2
+ /** Hoje em YYYY-MM-DD, fuso local. */
3
+ export function todayStr(now = new Date()) {
4
+ const p = (n) => String(n).padStart(2, '0');
5
+ return `${now.getFullYear()}-${p(now.getMonth() + 1)}-${p(now.getDate())}`;
6
+ }
7
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
8
+ /** YYYY-MM-DD real (rejeita 2026-02-31 por round-trip). */
9
+ export function isIsoDate(s) {
10
+ if (!DATE_RE.test(s))
11
+ return false;
12
+ const d = new Date(`${s}T00:00:00Z`);
13
+ return !Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s;
14
+ }
15
+ /** Schema zod de data ISO válida, compartilhado pelas tools. */
16
+ export const isoDate = z.string().refine(isIsoDate, 'use uma data real no formato YYYY-MM-DD');
17
+ /** Erro se início > fim (ISO, comparação lexicográfica); null se ok ou se faltar um lado. */
18
+ export function dateRangeError(start, end) {
19
+ return start && end && start > end ? `Intervalo inválido: início (${start}) deve ser <= fim (${end}).` : null;
20
+ }
21
+ //# sourceMappingURL=dates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dates.js","sourceRoot":"","sources":["../../src/lib/dates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sCAAsC;AACtC,MAAM,UAAU,QAAQ,CAAC,MAAY,IAAI,IAAI,EAAE;IAC7C,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAEtC,2DAA2D;AAC3D,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AAC1E,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,yCAAyC,CAAC,CAAC;AAE/F,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,KAAqB,EAAE,GAAmB;IACvE,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,+BAA+B,KAAK,sBAAsB,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAChH,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Tradução de erro de constraint do Postgres em mensagem acionável.
3
+ *
4
+ * Quando uma invariante do banco barra a escrita, o driver devolve o nome
5
+ * interno da constraint (`violates check constraint "tasks_sprint_requires_end_date"`),
6
+ * que não diz ao cliente MCP o que fazer. A tradução aqui é por *classe* de
7
+ * constraint — nada de caso especial por nome, senão vira um `if` por invariante
8
+ * do banco.
9
+ */
10
+ /** `tasks_sprint_requires_end_date` (tabela `tasks`) → `sprint requires end date`. Pura. */
11
+ function humanizeConstraint(name, table) {
12
+ const withoutTable = table && name.startsWith(`${table}_`) ? name.slice(table.length + 1) : name;
13
+ return withoutTable.replace(/_(check|key|fkey|excl)$/, '').replace(/_/g, ' ').trim();
14
+ }
15
+ const RULES = [
16
+ {
17
+ re: /(?:new row for relation|insert or update on table) "([^"]+)" violates check constraint "([^"]+)"/i,
18
+ text: (m) => `os dados enviados quebram a regra "${humanizeConstraint(m[2], m[1])}" da tabela ${m[1]} — ` +
19
+ 'preencha/ajuste os campos que a regra cita e repita',
20
+ },
21
+ {
22
+ re: /duplicate key value violates unique constraint "([^"]+)"/i,
23
+ text: (m) => `já existe um registro com esses valores (regra "${humanizeConstraint(m[1])}") — ` +
24
+ 'use o registro existente ou mude o valor duplicado',
25
+ },
26
+ {
27
+ re: /(?:insert or update on table|update or delete on table) "([^"]+)" violates foreign key constraint "([^"]+)"/i,
28
+ text: (m) => `referência inválida em ${m[1]} (regra "${humanizeConstraint(m[2], m[1])}") — ` +
29
+ 'o registro apontado não existe ou ainda tem dependentes',
30
+ },
31
+ {
32
+ re: /null value in column "([^"]+)" of relation "([^"]+)" violates not-null constraint/i,
33
+ text: (m) => `o campo obrigatório "${m[1]}" de ${m[2]} veio vazio — preencha antes de repetir`,
34
+ },
35
+ {
36
+ re: /new row violates row-level security policy(?: for table "[^"]+")?/i,
37
+ text: () => 'sem permissão pra essa ação (seu papel não permite escrever aqui)',
38
+ },
39
+ ];
40
+ /**
41
+ * Reescreve o trecho cru do Postgres dentro da mensagem, preservando o resto
42
+ * (o prefixo que a gateway pôs: "Erro ao criar tarefa: ..."). Mensagem sem
43
+ * erro de constraint passa intacta. Pura.
44
+ */
45
+ export function humanizePgError(message) {
46
+ for (const rule of RULES) {
47
+ const m = message.match(rule.re);
48
+ if (m)
49
+ return message.replace(rule.re, () => rule.text(m));
50
+ }
51
+ return message;
52
+ }
53
+ //# sourceMappingURL=pg-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-error.js","sourceRoot":"","sources":["../../src/lib/pg-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,4FAA4F;AAC5F,SAAS,kBAAkB,CAAC,IAAY,EAAE,KAAc;IACtD,MAAM,YAAY,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjG,OAAO,YAAY,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACvF,CAAC;AAED,MAAM,KAAK,GAA4D;IACrE;QACE,EAAE,EAAE,mGAAmG;QACvG,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CACV,sCAAsC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK;YAC5F,qDAAqD;KACxD;IACD;QACE,EAAE,EAAE,2DAA2D;QAC/D,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CACV,mDAAmD,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;YAClF,oDAAoD;KACvD;IACD;QACE,EAAE,EAAE,8GAA8G;QAClH,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CACV,0BAA0B,CAAC,CAAC,CAAC,CAAC,YAAY,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;YAC/E,yDAAyD;KAC5D;IACD;QACE,EAAE,EAAE,oFAAoF;QACxF,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,yCAAyC;KAC/F;IACD;QACE,EAAE,EAAE,oEAAoE;QACxE,IAAI,EAAE,GAAG,EAAE,CAAC,mEAAmE;KAChF;CACF,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ /** Status aceitos no update; `delivered` só via finalize. */
3
+ export const UPDATABLE_RELEASE_STATUS = z.enum(['planning', 'in_progress', 'cancelled']);
4
+ /** Garante que a release é do projeto; erro acionável senão. */
5
+ export async function assertReleaseInProject(gw, projectId, releaseId) {
6
+ if (!(await gw.findRelease(projectId, releaseId))) {
7
+ throw new Error('Release não encontrada neste projeto. Use list_releases pra ver os ids válidos.');
8
+ }
9
+ }
10
+ //# sourceMappingURL=release-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-logic.js","sourceRoot":"","sources":["../../src/lib/release-logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;AAEzF,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,EAAuC,EAAE,SAAiB,EAAE,SAAiB;IACxH,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,iFAAiF,CAAC,CAAC;IACrG,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Prazo de tarefa que entra em sprint.
3
+ *
4
+ * O banco do NOS tem a invariante `sprint_id NOT NULL ⇒ end_date NOT NULL`
5
+ * (CHECK `tasks_sprint_requires_end_date`, spec 0021 do NOS): tarefa em sprint é
6
+ * compromisso, e compromisso tem prazo. Backlog segue livre de prazo.
7
+ *
8
+ * Os outros caminhos de escrita do produto (`create_client_task`,
9
+ * `move_task_to_project`) já aplicam hoje + 5 dias quando ninguém informou data
10
+ * — "tarefa que não nasce é pior que tarefa sem prazo". Aqui é o mesmo default,
11
+ * pro agente não morrer na constraint.
12
+ */
13
+ /** Dias de prazo aplicados quando a tarefa entra em sprint sem `end_date`. */
14
+ export const SPRINT_DEADLINE_FALLBACK_DAYS = 5;
15
+ /**
16
+ * `end_date` final de uma tarefa: o informado, ou — só quando ela fica em sprint
17
+ * sem data — hoje + `SPRINT_DEADLINE_FALLBACK_DAYS` em `YYYY-MM-DD`. Pura
18
+ * (`today` injetável); a data é lida no fuso local, como o usuário enxerga "hoje".
19
+ */
20
+ export function resolveTaskDeadline(sprintId, endDate, today = new Date()) {
21
+ if (sprintId === null || endDate)
22
+ return endDate ?? null;
23
+ const d = new Date(today);
24
+ d.setDate(d.getDate() + SPRINT_DEADLINE_FALLBACK_DAYS);
25
+ const pad = (n) => String(n).padStart(2, '0');
26
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
27
+ }
28
+ //# sourceMappingURL=sprint-deadline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprint-deadline.js","sourceRoot":"","sources":["../../src/lib/sprint-deadline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAE/C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAAuB,EACvB,OAAkC,EAClC,QAAc,IAAI,IAAI,EAAE;IAExB,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO;QAAE,OAAO,OAAO,IAAI,IAAI,CAAC;IACzD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,6BAA6B,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { FINISHED_STATUSES } from '../core/types.js';
2
+ /** Plano de encerramento: quem volta pro backlog e quem fica. Pura. */
3
+ export function planSprintEnd(tasks) {
4
+ const toBacklog = [];
5
+ const kept = [];
6
+ for (const t of tasks)
7
+ (FINISHED_STATUSES.includes(t.status) ? kept : toBacklog).push(t.id);
8
+ return { toBacklog, kept };
9
+ }
10
+ /** Contagem por status + vencidas (end_date < hoje, fora de done/production). Pura. */
11
+ export function summarizeSprintTasks(tasks, today) {
12
+ const by_status = {};
13
+ for (const t of tasks)
14
+ by_status[t.status] = (by_status[t.status] ?? 0) + 1;
15
+ const overdue = tasks
16
+ .filter((t) => t.end_date && t.end_date < today && !FINISHED_STATUSES.includes(t.status))
17
+ .map(({ key, title, end_date }) => ({ key, title, end_date }));
18
+ return { total: tasks.length, by_status, overdue };
19
+ }
20
+ /** Encerra a sprint: tasks primeiro, sprint depois. Já encerrada = no-op (preserva end_date). */
21
+ export async function closeSprint(gw, sprint, today) {
22
+ if (sprint.status === 'encerrada') {
23
+ return { sprint, already_closed: true, returned_to_backlog: 0, kept_done: 0 };
24
+ }
25
+ const tasks = await gw.listSprintTasks(sprint.id);
26
+ const { toBacklog, kept } = planSprintEnd(tasks);
27
+ await gw.returnTasksToBacklog(toBacklog);
28
+ const updated = await gw.updateSprint(sprint.id, { status: 'encerrada', end_date: today });
29
+ return { sprint: updated, already_closed: false, returned_to_backlog: toBacklog.length, kept_done: kept.length };
30
+ }
31
+ //# sourceMappingURL=sprint-logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sprint-logic.js","sourceRoot":"","sources":["../../src/lib/sprint-logic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAsC,MAAM,kBAAkB,CAAC;AAEzF,uEAAuE;AACvE,MAAM,UAAU,aAAa,CAAC,KAAsB;IAClD,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5F,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,oBAAoB,CAAC,KAAsB,EAAE,KAAa;IACxE,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,KAAK;SAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,KAAK,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;SACxF,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACrD,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,EAAiB,EAAE,MAAiB,EAAE,KAAa;IACnF,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClD,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3F,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,mBAAmB,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AACnH,CAAC"}
@@ -1,11 +1,14 @@
1
+ import { humanizePgError } from './pg-error.js';
1
2
  export function jsonResult(data) {
2
3
  return {
3
4
  content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
4
5
  };
5
6
  }
7
+ /** Erro de tool. Passa pelo tradutor de constraint do Postgres: nome interno de
8
+ * invariante do banco nunca chega ao cliente MCP, venha de onde vier. */
6
9
  export function errorResult(message) {
7
10
  return {
8
- content: [{ type: 'text', text: message }],
11
+ content: [{ type: 'text', text: humanizePgError(message) }],
9
12
  isError: true,
10
13
  };
11
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-result.js","sourceRoot":"","sources":["../../src/lib/tool-result.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAC1C,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"tool-result.js","sourceRoot":"","sources":["../../src/lib/tool-result.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED;yEACyE;AACzE,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ import { jsonResult, errorResult } from '../lib/tool-result.js';
3
+ import { resolveProjectConfig, isErrorResult } from '../lib/require-config.js';
4
+ import { closeSprint } from '../lib/sprint-logic.js';
5
+ import { todayStr } from '../lib/dates.js';
6
+ import { brand } from '../brand.js';
7
+ import { projectIdProp } from './sprint-common.js';
8
+ const ArgsSchema = z.object({ sprint_id: z.uuid(), project_id: z.uuid().optional() }).strict();
9
+ export const definition = {
10
+ name: `${brand.toolPrefix}activate_sprint`,
11
+ description: 'Reativa uma sprint: encerra qualquer outra ativa do projeto (tasks não concluídas voltam pro backlog) ' +
12
+ 'e reabre a escolhida com status "ativa", start_date = hoje e end_date = null (como a UI).',
13
+ inputSchema: {
14
+ type: 'object',
15
+ properties: { sprint_id: { type: 'string', format: 'uuid' }, project_id: projectIdProp },
16
+ required: ['sprint_id'],
17
+ additionalProperties: false,
18
+ },
19
+ };
20
+ export async function handler(args, ctx) {
21
+ const parsed = ArgsSchema.safeParse(args);
22
+ if (!parsed.success)
23
+ return errorResult(`Argumento inválido: ${parsed.error.message}`);
24
+ const cfg = resolveProjectConfig(ctx, parsed.data.project_id);
25
+ if (isErrorResult(cfg))
26
+ return cfg;
27
+ try {
28
+ const gw = ctx.gateway;
29
+ const target = await gw.findSprint(cfg.project_id, parsed.data.sprint_id);
30
+ if (!target)
31
+ return errorResult('Sprint não encontrada neste projeto.');
32
+ if (target.status === 'ativa')
33
+ return jsonResult({ ok: true, sprint: target, already_active: true });
34
+ const today = todayStr();
35
+ const active = await gw.findSprint(cfg.project_id, 'active');
36
+ const closed = active && active.id !== target.id ? await closeSprint(gw, active, today) : undefined;
37
+ const sprint = await gw.updateSprint(target.id, { status: 'ativa', start_date: today, end_date: null });
38
+ return jsonResult({ ok: true, sprint, ...(closed && { closed_previous: closed }) });
39
+ }
40
+ catch (err) {
41
+ return errorResult(err.message);
42
+ }
43
+ }
44
+ //# sourceMappingURL=activate-sprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activate-sprint.js","sourceRoot":"","sources":["../../src/tools/activate-sprint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { z } from 'zod';
2
+ import { jsonResult, errorResult } from '../lib/tool-result.js';
3
+ import { brand } from '../brand.js';
4
+ import { isoDate } from '../lib/dates.js';
5
+ const ArgsSchema = z
6
+ .object({
7
+ date: isoDate,
8
+ name: z.string().trim().min(1),
9
+ type: z.enum(['full', 'half']).default('full'),
10
+ scope: z.enum(['national', 'state', 'municipal']).default('national'),
11
+ })
12
+ .strict();
13
+ export const definition = {
14
+ name: `${brand.toolPrefix}add_holiday`,
15
+ description: 'Cria feriado no calendário do time (só admin/gerente).',
16
+ inputSchema: {
17
+ type: 'object',
18
+ properties: {
19
+ date: { type: 'string', description: 'Data (YYYY-MM-DD).' },
20
+ name: { type: 'string', description: 'Nome do feriado.' },
21
+ type: { type: 'string', enum: ['full', 'half'], description: 'Padrão full.' },
22
+ scope: { type: 'string', enum: ['national', 'state', 'municipal'], description: 'Padrão national.' },
23
+ },
24
+ required: ['date', 'name'],
25
+ additionalProperties: false,
26
+ },
27
+ };
28
+ export async function handler(args, ctx) {
29
+ const parsed = ArgsSchema.safeParse(args ?? {});
30
+ if (!parsed.success)
31
+ return errorResult(`Argumento inválido: ${parsed.error.message}`);
32
+ const a = parsed.data;
33
+ try {
34
+ const h = await ctx.gateway.addHoliday(a);
35
+ return jsonResult({ holiday_id: h.id, ...a });
36
+ }
37
+ catch (err) {
38
+ return errorResult(err.message);
39
+ }
40
+ }
41
+ //# sourceMappingURL=add-holiday.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-holiday.js","sourceRoot":"","sources":["../../src/tools/add-holiday.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,CAAC;IACN,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAC9C,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;CACtE,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,UAAU,aAAa;IACtC,WAAW,EAAE,wDAAwD;IACrE,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;YAC3D,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE;YACzD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE;YAC7E,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE;SACrG;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;QAC1B,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAa,EAAE,GAAgB;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,WAAW,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ import { jsonResult, errorResult } from '../lib/tool-result.js';
3
+ import { brand } from '../brand.js';
4
+ import { isoDate } from '../lib/dates.js';
5
+ const ArgsSchema = z.object({ date: isoDate }).strict();
6
+ export const definition = {
7
+ name: `${brand.toolPrefix}add_home_office`,
8
+ description: 'Marca home office do PRÓPRIO usuário num dia (o banco pode recusar por limite mensal).',
9
+ inputSchema: {
10
+ type: 'object',
11
+ properties: {
12
+ date: { type: 'string', description: 'Data (YYYY-MM-DD).' },
13
+ },
14
+ required: ['date'],
15
+ additionalProperties: false,
16
+ },
17
+ };
18
+ export async function handler(args, ctx) {
19
+ const parsed = ArgsSchema.safeParse(args ?? {});
20
+ if (!parsed.success)
21
+ return errorResult(`Argumento inválido: ${parsed.error.message}`);
22
+ const a = parsed.data;
23
+ try {
24
+ const h = await ctx.gateway.addHomeOffice(ctx.user.id, a.date);
25
+ return jsonResult({ home_office_id: h.id, date: a.date });
26
+ }
27
+ catch (err) {
28
+ return errorResult(err.message);
29
+ }
30
+ }
31
+ //# sourceMappingURL=add-home-office.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-home-office.js","sourceRoot":"","sources":["../../src/tools/add-home-office.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAExD,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,UAAU,iBAAiB;IAC1C,WAAW,EAAE,wFAAwF;IACrG,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;SAC5D;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAa,EAAE,GAAgB;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,OAAO,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,WAAW,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { z } from 'zod';
2
+ import { jsonResult, errorResult } from '../lib/tool-result.js';
3
+ import { brand } from '../brand.js';
4
+ import { isoDate, dateRangeError } from '../lib/dates.js';
5
+ const ArgsSchema = z
6
+ .object({ user_id: z.uuid(), start_date: isoDate, end_date: isoDate, notes: z.string().optional() })
7
+ .strict();
8
+ export const definition = {
9
+ name: `${brand.toolPrefix}add_vacation`,
10
+ description: 'Registra férias de um usuário no calendário do time (só admin/gerente).',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ user_id: { type: 'string', format: 'uuid', description: 'ID do usuário.' },
15
+ start_date: { type: 'string', description: 'Início (YYYY-MM-DD).' },
16
+ end_date: { type: 'string', description: 'Fim (YYYY-MM-DD), >= start_date.' },
17
+ notes: { type: 'string', description: 'Observações.' },
18
+ },
19
+ required: ['user_id', 'start_date', 'end_date'],
20
+ additionalProperties: false,
21
+ },
22
+ };
23
+ export async function handler(args, ctx) {
24
+ const parsed = ArgsSchema.safeParse(args ?? {});
25
+ if (!parsed.success)
26
+ return errorResult(`Argumento inválido: ${parsed.error.message}`);
27
+ const a = parsed.data;
28
+ const bad = dateRangeError(a.start_date, a.end_date);
29
+ if (bad)
30
+ return errorResult(bad);
31
+ try {
32
+ const v = await ctx.gateway.addVacation({ ...a, notes: a.notes ?? null, created_by: ctx.user.id });
33
+ return jsonResult({ vacation_id: v.id, ...a });
34
+ }
35
+ catch (err) {
36
+ return errorResult(err.message);
37
+ }
38
+ }
39
+ //# sourceMappingURL=add-vacation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-vacation.js","sourceRoot":"","sources":["../../src/tools/add-vacation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;KACnG,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,UAAU,cAAc;IACvC,WAAW,EAAE,yEAAyE;IACtF,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE;YAC1E,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;YACnE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;YAC7E,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;SACvD;QACD,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC;QAC/C,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAa,EAAE,GAAgB;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;IACtB,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,GAAG;QAAE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACnG,OAAO,UAAU,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,WAAW,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import { jsonResult, errorResult } from '../lib/tool-result.js';
3
+ import { resolveProjectConfig, isErrorResult } from '../lib/require-config.js';
4
+ import { isoDate } from '../lib/dates.js';
5
+ import { brand } from '../brand.js';
6
+ import { projectIdProp } from './sprint-common.js';
7
+ const ArgsSchema = z
8
+ .object({
9
+ name: z.string().trim().min(1).max(100),
10
+ target_date: isoDate,
11
+ description: z.string().optional(),
12
+ project_id: z.uuid().optional(),
13
+ })
14
+ .strict();
15
+ export const definition = {
16
+ name: `${brand.toolPrefix}create_release`,
17
+ description: 'Cria uma release (status planning) no projeto. target_date é obrigatória (YYYY-MM-DD).',
18
+ inputSchema: {
19
+ type: 'object',
20
+ properties: {
21
+ name: { type: 'string' },
22
+ target_date: { type: 'string', description: 'YYYY-MM-DD.' },
23
+ description: { type: 'string' },
24
+ project_id: projectIdProp,
25
+ },
26
+ required: ['name', 'target_date'],
27
+ additionalProperties: false,
28
+ },
29
+ };
30
+ export async function handler(args, ctx) {
31
+ const parsed = ArgsSchema.safeParse(args);
32
+ if (!parsed.success)
33
+ return errorResult(`Argumento inválido: ${parsed.error.message}`);
34
+ const cfg = resolveProjectConfig(ctx, parsed.data.project_id);
35
+ if (isErrorResult(cfg))
36
+ return cfg;
37
+ const { project_id: _p, ...rest } = parsed.data;
38
+ try {
39
+ const release = await ctx.gateway.createRelease({ ...rest, project_id: cfg.project_id, created_by: ctx.user.id });
40
+ return jsonResult({ ok: true, release });
41
+ }
42
+ catch (err) {
43
+ return errorResult(err.message);
44
+ }
45
+ }
46
+ //# sourceMappingURL=create-release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-release.js","sourceRoot":"","sources":["../../src/tools/create-release.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACvC,WAAW,EAAE,OAAO;IACpB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,UAAU,gBAAgB;IACzC,WAAW,EAAE,wFAAwF;IACrG,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE;YAC3D,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,UAAU,EAAE,aAAa;SAC1B;QACD,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;QACjC,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAa,EAAE,GAAgB;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvF,MAAM,GAAG,GAAG,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC9D,IAAI,aAAa,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACnC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAClH,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,WAAW,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import { jsonResult, errorResult } from '../lib/tool-result.js';
3
+ import { resolveProjectConfig, isErrorResult } from '../lib/require-config.js';
4
+ import { closeSprint } from '../lib/sprint-logic.js';
5
+ import { todayStr, isoDate, dateRangeError } from '../lib/dates.js';
6
+ import { brand } from '../brand.js';
7
+ import { projectIdProp } from './sprint-common.js';
8
+ const ArgsSchema = z
9
+ .object({
10
+ name: z.string().trim().min(1).max(100),
11
+ start_date: isoDate.optional(),
12
+ end_date: isoDate.optional(),
13
+ replace_active: z.boolean().optional(),
14
+ project_id: z.uuid().optional(),
15
+ })
16
+ .strict();
17
+ export const definition = {
18
+ name: `${brand.toolPrefix}create_sprint`,
19
+ description: 'Cria uma sprint já ATIVA. Se o projeto já tem sprint ativa, falha dizendo qual — ' +
20
+ 'passe replace_active=true pra encerrá-la (tasks não concluídas voltam pro backlog) e criar a nova.',
21
+ inputSchema: {
22
+ type: 'object',
23
+ properties: {
24
+ name: { type: 'string' },
25
+ start_date: { type: 'string', description: 'YYYY-MM-DD. Default: hoje.' },
26
+ end_date: { type: 'string', description: 'YYYY-MM-DD.' },
27
+ replace_active: { type: 'boolean', description: 'Encerra a sprint ativa atual antes de criar. Default false.' },
28
+ project_id: projectIdProp,
29
+ },
30
+ required: ['name'],
31
+ additionalProperties: false,
32
+ },
33
+ };
34
+ export async function handler(args, ctx) {
35
+ const parsed = ArgsSchema.safeParse(args);
36
+ if (!parsed.success)
37
+ return errorResult(`Argumento inválido: ${parsed.error.message}`);
38
+ const { name, replace_active } = parsed.data;
39
+ const today = todayStr();
40
+ const start = parsed.data.start_date ?? today;
41
+ const end = parsed.data.end_date ?? null;
42
+ const bad = dateRangeError(start, end);
43
+ if (bad)
44
+ return errorResult(bad);
45
+ const cfg = resolveProjectConfig(ctx, parsed.data.project_id);
46
+ if (isErrorResult(cfg))
47
+ return cfg;
48
+ try {
49
+ const gw = ctx.gateway;
50
+ const active = await gw.findSprint(cfg.project_id, 'active');
51
+ let closed;
52
+ if (active) {
53
+ if (!replace_active) {
54
+ return errorResult(`Já existe sprint ativa: "${active.name}" (${active.id}). Use replace_active=true pra encerrá-la ` +
55
+ `e criar a nova, ou ${brand.toolPrefix}end_sprint antes.`);
56
+ }
57
+ closed = await closeSprint(gw, active, today);
58
+ }
59
+ const sprint = await gw.createSprint(cfg.project_id, name, start, end);
60
+ return jsonResult({ ok: true, sprint, ...(closed && { closed_previous: closed }) });
61
+ }
62
+ catch (err) {
63
+ return errorResult(err.message);
64
+ }
65
+ }
66
+ //# sourceMappingURL=create-sprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-sprint.js","sourceRoot":"","sources":["../../src/tools/create-sprint.ts"],"names":[],"mappings":"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"}