@agentistics/mcp 2.202.0 → 2.203.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.
@@ -3,6 +3,8 @@
3
3
  // live-delivery-args.ts
4
4
  var LIVE_STAGES = ["queue", "running", "qa", "adjust", "leader", "merge", "published"];
5
5
  var LIVE_SORTS = ["priority", "time-in-stage", "recent"];
6
+ var LIVE_TABS = ["active", "queue", "published", "all"];
7
+ var LIVE_PERIODS = ["24h", "7d", "30d", "all"];
6
8
  function liveDeliveryQuery(a) {
7
9
  const q = new URLSearchParams;
8
10
  const task = typeof a?.task === "string" ? a.task.trim() : "";
@@ -12,10 +14,10 @@ function liveDeliveryQuery(a) {
12
14
  q.set("stage", a.stage);
13
15
  if (a?.stalledOnly === true)
14
16
  q.set("stalled", "1");
15
- if (a?.onlyActive === false)
16
- q.set("onlyActive", "0");
17
- if (a?.showQueue === false)
18
- q.set("showQueue", "0");
17
+ if (typeof a?.tab === "string" && LIVE_TABS.includes(a.tab))
18
+ q.set("tab", a.tab);
19
+ if (typeof a?.period === "string" && LIVE_PERIODS.includes(a.period))
20
+ q.set("period", a.period);
19
21
  if (typeof a?.sort === "string" && LIVE_SORTS.includes(a.sort))
20
22
  q.set("sort", a.sort);
21
23
  return q.toString() ? `?${q}` : "";
@@ -780,6 +782,8 @@ var HARNESS_MODELS = {
780
782
  hermes: []
781
783
  };
782
784
  var SPAWN_SPECS_MODEL_IDS = Object.fromEntries(Object.entries(HARNESS_MODELS).map(([h, opts]) => [h, opts.map((o) => o.id)]));
785
+ // ../core/src/liveBoard.ts
786
+ var PERIOD_MS = { "24h": 24 * 3600000, "7d": 7 * 24 * 3600000, "30d": 30 * 24 * 3600000, all: Infinity };
783
787
  // ../core/src/taskThreads.ts
784
788
  var LIVE = new Set(["working", "waiting", "waiting-approval"]);
785
789
  // ../core/src/attachments.ts
@@ -1004,8 +1008,8 @@ var AGENT_TOOL_POLICY = {
1004
1008
  agentistics_task_phase: {
1005
1009
  ...TASKS,
1006
1010
  risk: "W",
1007
- routes: ["GET /api/deliveries", "GET /api/deliveries/:subtask", "POST /api/deliveries/:subtask", "POST /api/deliveries/release"],
1008
- reason: "reads or moves a delivery through the fixed phase table; release declares which pieces a release shipped (leader/owner only; the host still reads the green run and the tag); a skipped phase is refused (422 fase_pulada) and every gate is checked by the host from evidence, never from the caller"
1011
+ routes: ["GET /api/deliveries", "GET /api/deliveries/:subtask", "POST /api/deliveries/:subtask", "POST /api/deliveries/release", "POST /api/deliveries/reconcile"],
1012
+ reason: "reads or moves a delivery through the fixed phase table; release declares which pieces a release shipped (leader/owner only; the host still reads the green run and the tag); reconcile backfills merged/released pieces (dry run unless apply, leader/owner only); a skipped phase is refused (422 fase_pulada) and every gate is checked by the host from evidence, never from the caller"
1009
1013
  },
1010
1014
  agentistics_task_stage: {
1011
1015
  ...TASKS,
@@ -1135,7 +1139,7 @@ var roomOf = (b) => Math.max(b.fiveHourPct, b.weekPct);
1135
1139
  function pickAccount(candidates) {
1136
1140
  return candidates.map((b, i) => ({ b, i })).sort((x, y) => (x.b.daysToWeekReset > 0 ? x.b.weekResetsAt : Infinity) - (y.b.daysToWeekReset > 0 ? y.b.weekResetsAt : Infinity) || roomOf(x.b) - roomOf(y.b) || (y.b.updatedAt ?? 0) - (x.b.updatedAt ?? 0) || y.i - x.i)[0]?.b;
1137
1141
  }
1138
- function routeRecommendation(budgets, kind, authorHarness) {
1142
+ function routeRecommendation(budgets, kind, authorHarness, opts = {}) {
1139
1143
  const authorVendor = kind === "qa" && authorHarness ? HARNESS_VENDOR[authorHarness] : undefined;
1140
1144
  budgets = budgets.flatMap((b) => {
1141
1145
  if (!b.scopes?.length)
@@ -1145,9 +1149,15 @@ function routeRecommendation(budgets, kind, authorHarness) {
1145
1149
  return { ...row, ...sb, scope: scope.id, model: scope.models[0], scopeProviders: scope.providers };
1146
1150
  });
1147
1151
  });
1148
- const aggregates = new Map(harnessAggregate(budgets.filter((b) => b.plan !== "unregistered")).map((a) => [a.harness, a]));
1152
+ const aggregates = new Map(harnessAggregate(budgets.filter((b) => b.plan !== "unregistered" && !b.stale)).map((a) => [a.harness, a]));
1149
1153
  const eligibleHarness = (agg) => eligibleAccounts(agg.harness).length > 0 && agg.status !== "hold" && agg.harness !== (kind === "qa" ? authorHarness : undefined);
1150
- const eligibleAccounts = (h) => budgets.filter((b) => b.harness === h && b.spawnable !== false && b.plan !== "unregistered" && !b.yieldsTo && b.status !== "hold");
1154
+ const eligibleAccounts = (h) => budgets.filter((b) => b.harness === h && b.spawnable !== false && b.plan !== "unregistered" && !b.yieldsTo && b.status !== "hold" && !b.stale);
1155
+ const knownHarnesses = [...new Set([...opts.visibleHarnesses ?? [], ...budgets.map((b) => b.harness)])];
1156
+ const unknownList = knownHarnesses.flatMap((h) => {
1157
+ const rows = budgets.filter((b) => b.harness === h && b.plan !== "unregistered");
1158
+ return rows.some((b) => !b.stale) ? [] : [{ harness: h, why: rows.length ? "stale" : "no-reading" }];
1159
+ });
1160
+ const unknown = unknownList.length ? { unknown: unknownList } : {};
1151
1161
  const harnesses = [...aggregates.values()].filter(eligibleHarness);
1152
1162
  const ordered = [...harnesses].sort((a, b) => {
1153
1163
  const ap = a.paceStatus === "under" ? 0 : 1;
@@ -1162,14 +1172,19 @@ function routeRecommendation(budgets, kind, authorHarness) {
1162
1172
  const chosen = ordered.find((a) => preference.some(([h]) => h === a.harness));
1163
1173
  const pickAgg = chosen ?? ordered[0];
1164
1174
  const noRoute = () => {
1175
+ const base = { harness: null, alternatives: [], accountAlternatives: [], confidence: "none", ...unknown };
1165
1176
  if (budgets.length && budgets.every((b) => b.spawnable === false)) {
1166
- return { harness: null, reason: "No harness can start a new session.", alternatives: [], accountAlternatives: [], cadence: { parallel: 0, note: "Install or repair a harness before opening workers." } };
1177
+ return { ...base, reason: "No harness can start a new session.", cadence: { parallel: 0, note: "Install or repair a harness before opening workers." } };
1167
1178
  }
1168
1179
  if (budgets.length && budgets.every((b) => b.status === "hold")) {
1169
1180
  const earliest = Math.min(...budgets.map((b) => b.pauseUntil ?? b.weekResetsAt));
1170
- return { harness: null, reason: `all plans on hold until ${new Date(earliest).toISOString()}`, alternatives: [], accountAlternatives: [], cadence: { parallel: 0, note: "Wait for a plan to renew." } };
1181
+ return { ...base, reason: `all plans on hold until ${new Date(earliest).toISOString()}`, cadence: { parallel: 0, note: "Wait for a plan to renew." } };
1182
+ }
1183
+ const registered = budgets.filter((b) => b.plan !== "unregistered" && b.spawnable !== false && b.status !== "hold");
1184
+ if (registered.length && registered.every((b) => b.stale)) {
1185
+ return { ...base, reason: `No fresh plan_limits reading for ${kind}: ${[...new Set(registered.map((b) => b.harness))].join(", ")} ${registered.length === 1 ? "was" : "were"} last read more than ${PLAN_LIMITS_STALE_MS / 60000} minutes ago.`, cadence: { parallel: 0, note: "Read the plan windows again before opening workers; a stale meter is never trusted." } };
1171
1186
  }
1172
- return { harness: null, reason: `No eligible plan for ${kind}.`, alternatives: [], accountAlternatives: [], cadence: { parallel: 0, note: "Check plan registration, account availability, and author-harness exclusions." } };
1187
+ return { ...base, reason: `No eligible plan for ${kind}.`, cadence: { parallel: 0, note: "Check plan registration, account availability, and author-harness exclusions." } };
1173
1188
  };
1174
1189
  if (!pickAgg)
1175
1190
  return noRoute();
@@ -1192,7 +1207,9 @@ function routeRecommendation(budgets, kind, authorHarness) {
1192
1207
  reason: `${pick.harness} is the preferred eligible plan for ${kind}.${budgetText}${paceText}`,
1193
1208
  alternatives,
1194
1209
  accountAlternatives,
1195
- cadence: { parallel, note: pick.note ?? "Keep one worker running." }
1210
+ cadence: { parallel, note: pick.note ?? "Keep one worker running." },
1211
+ confidence: "fresh",
1212
+ ...unknown
1196
1213
  };
1197
1214
  }
1198
1215
  var NEW_PERIOD_MS = 5 * 60000;
@@ -1697,7 +1714,8 @@ function planLimitsTool(args, body) {
1697
1714
  const label = plainLabel(accountLabel);
1698
1715
  return label !== undefined ? { ...rest, accountLabel: label } : rest;
1699
1716
  });
1700
- const routed = args?.kind ? routeRecommendation(budgets, args.kind, args.authorHarness) : undefined;
1717
+ const visibleHarnesses = Object.entries(body.harnesses ?? {}).filter(([, v]) => v?.spawnable).map(([h]) => h);
1718
+ const routed = args?.kind ? routeRecommendation(budgets, args.kind, args.authorHarness, { visibleHarnesses }) : undefined;
1701
1719
  const recommendation = routed?.accountLabel !== undefined ? { ...routed, accountLabel: plainLabel(routed.accountLabel) } : routed;
1702
1720
  const aggregates = harnessAggregate(budgets);
1703
1721
  const offBySchedule = (body.hiddenFromAgents ?? []).filter((b) => b?.agentUse && !b.agentUse.on).map((b) => ({ harness: b.harness, account: b.account, reason: b.agentUse.reason }));
@@ -2247,10 +2265,15 @@ var TOOLS = [
2247
2265
  },
2248
2266
  {
2249
2267
  name: "agentistics_task_create",
2250
- description: "Create a task. A title is required; a description is optional. Creating a title that already exists returns the existing task rather than a duplicate, so this is safe to call before filing work under a name you are not sure exists.",
2268
+ description: "Create a task. A title is required; a description is optional. Set `priority` (urgent | high | medium | low — default low, and nobody chose a default) and `type` (an id from agentistics_task_types) when you know them: a board of defaults orders nothing. Creating a title that already exists returns the existing task rather than a duplicate (its priority and type are left alone — use agentistics_task_edit), so this is safe to call before filing work under a name you are not sure exists.",
2251
2269
  inputSchema: {
2252
2270
  type: "object",
2253
- properties: { title: { type: "string" }, detail: { type: "string" } },
2271
+ properties: {
2272
+ title: { type: "string" },
2273
+ detail: { type: "string" },
2274
+ priority: { type: "string", enum: ["urgent", "high", "medium", "low"], description: "Defaults to low. Decides the order of the queue and of the Live delivery line." },
2275
+ type: { type: "string", description: "A type id from agentistics_task_types (an unknown one is dropped)." }
2276
+ },
2254
2277
  required: ["title"]
2255
2278
  }
2256
2279
  },
@@ -2371,7 +2394,7 @@ var TOOLS = [
2371
2394
  },
2372
2395
  status: {
2373
2396
  type: "string",
2374
- enum: ["backlog", "todo", "in_progress", "blocked", "in_review", "done", "abandoned"]
2397
+ description: "A status id this board currently has — call agentistics_task_statuses for the live list (the vocabulary is editable, so it is NOT fixed here). The four every board starts with are todo | in_progress | blocked | done."
2375
2398
  },
2376
2399
  dueDate: { type: "string" },
2377
2400
  startDate: { type: "string" },
@@ -2457,15 +2480,15 @@ var TOOLS = [
2457
2480
  },
2458
2481
  {
2459
2482
  name: "agentistics_live_delivery",
2460
- description: 'What is being DELIVERED right now — the Live Delivery line, the same source as the screen. Use it to answer "what is running", "when does X ship" and "is anything stalled". Returns a `summary` (active deliveries, agents working, stalled, the next delivery with an estimate), the active `deliveries` with their stage (queue, running, qa, adjust, leader, merge, published), the agents on each (harness, model, account, live state), time in the stage and in total, the step inside the stage (`step`, with `stepSource` = `reported` or `signals` and `stepSignal` naming the observed fact — null `step` means nothing is observable, say so; the screen then draws no percent), the ETA with its source and confidence (`kind: none` means there is NO estimate — say so, never invent a time), the last action, and the `leaders` band (each leader\'s current action, its workers and what waits on a decision — leaders are never deliveries). Each delivery carries its Agentask `priority` (urgent | high | medium | low; a subtask inherits its task\'s). Filters: `task` (id or part of the title), `stage`, `stalledOnly`, and the screen\'s own switches — `onlyActive` (the stages after the queue; default true) and `showQueue` (the Na fila column; default true), pass false to turn one off — plus `sort` (how each stage lists its cards; default `priority`, highest first, ties by longest in the stage). Stage names on screen: queue = Na fila, running = Em desenvolvimento, qa = QA. `history` is the screen\'s Histórico column: pieces published more than 24 h ago (up to 30 days, newest first, same `task` filter, no live agents) — Publicado keeps a card for 24 h and then it moves there.',
2483
+ description: 'What is being DELIVERED right now — the Live Delivery line, the same source as the screen. Use it to answer "what is running", "when does X ship" and "is anything stalled". Returns a `summary` (active deliveries, agents working, stalled, the next delivery with an estimate), the active `deliveries` with their stage (queue, running, qa, adjust, leader, merge, published), the agents on each (harness, model, account, live state), time in the stage and in total, the step inside the stage (`step`, with `stepSource` = `reported` or `signals` and `stepSignal` naming the observed fact — null `step` means nothing is observable, say so; the screen then draws no percent), the ETA with its source and confidence (`kind: none` means there is NO estimate — say so, never invent a time), the last action, and the `leaders` band (each leader\'s current action, its workers and what waits on a decision — leaders are never deliveries). Each delivery carries its Agentask `priority` (urgent | high | medium | low; a subtask inherits its task\'s). Filters: `task` (id or part of the title), `stage`, `stalledOnly`, and the screen\'s own tabs — `tab`: `active` (Em andamento: only what has an agent working or waiting), `queue` (Na fila), `published` (Publicado) or `all` (Tudo: every piece in its real column, old legacy reviews marked `old`; the default here, while the screen opens on `active`) — and `period`, the Publicado period: `24h` (default), `7d`, `30d` or `all`. The answer\'s `view` carries `{tab, period, counts, defaulted, capped}`: `tab`/`period` are the EFFECTIVE values (a missing or invalid one falls back to `all` / `24h`, and `defaulted` names which did), `counts` is the count of EVERY tab under the same `task` filter and period, the very numbers the screen\'s tabs print, and `capped` (`{cap, omitted}`, else null) says the list was cut at 400 pieces per kind and that many older ones are NOT in the answer — then a count is not the total. Plus `sort` (how each stage lists its cards; default `priority`, highest first, ties by longest in the stage). Stage names on screen: queue = Na fila, running = Em desenvolvimento, qa = QA. There is no Histórico column any more: a piece published earlier is in `deliveries` whenever `period` covers it.',
2461
2484
  inputSchema: {
2462
2485
  type: "object",
2463
2486
  properties: {
2464
2487
  task: { type: "string", description: "A task id or part of its title." },
2465
2488
  stage: { type: "string", enum: ["queue", "running", "qa", "adjust", "leader", "merge", "published"] },
2466
2489
  stalledOnly: { type: "boolean", description: "Only deliveries that need a person, lost an agent or are blocked." },
2467
- onlyActive: { type: "boolean", description: `The screen's "apenas ativas": the cards of the stages after the queue. Default true; false hides them.` },
2468
- showQueue: { type: "boolean", description: `The screen's "exibir itens na fila": the cards of the Na fila column. Default true; false hides them.` },
2490
+ tab: { type: "string", enum: ["active", "queue", "published", "all"], description: "The screen's tab: active (Em andamento), queue (Na fila), published (Publicado) or all (Tudo). Default all." },
2491
+ period: { type: "string", enum: ["24h", "7d", "30d", "all"], description: "How far back Publicado reaches. Default 24h." },
2469
2492
  sort: { type: "string", enum: ["priority", "time-in-stage", "recent"], description: "Order within each stage. Default priority (highest first, ties by longest in the stage)." }
2470
2493
  },
2471
2494
  required: []
@@ -2529,11 +2552,12 @@ var TOOLS = [
2529
2552
  },
2530
2553
  {
2531
2554
  name: "agentistics_task_phase",
2532
- description: "`tick` also enables the mandatory owner-request/placement flows through the official engine switches and reads canonical pedidos; after 10 minutes without complete staging it wakes the current live task leader, including after a handoff or restart, and never asks the owner. " + "Queue actions: `dequeue` withdraws a queued piece with a required free-text `reason` (task leader or owner only), keeps the draft/history, and refuses dispatch until explicitly restaged; `tick` reconciles stale queued pieces against board review/done/abandoned and records a comment. Vacancy counts live backend processes; lost/exited/closed sessions reserve no slots. " + "FLUXO.ENTREGA-DSL — read or move a DELIVERY (one subtask) through its fixed phases: fila → executando → qa → (ajuste ⇄ qa) → revisao_lider → pr_merge → ci → publicado, plus bloqueado (from any phase, back to the stored origin only). Any transition outside that table is REFUSED (422 `fase_pulada`) with a sentence naming what is missing — executando → revisao_lider, ajuste → revisao_lider and every other skip included. The gates each edge needs are run BY THE SERVER from evidence (predispatch, vaga, salvo = sha on origin per ls-remote, qa-modelo = QA model ≠ author model from the registry and never Sonnet over Sonnet, cabeca = the pushed branch is still at the sha QA tested, delecoes = no file deleted outright by the PR, mergeado = gh says the PR is MERGED, the merge commit is on origin/main and the PR head is the sha QA approved — the merge sha is READ FROM THE PR, never from you, release = the batch's version tag exists AND the release.yml run that produced it is green, read in the repository the release recorded); salvo needs every check run on the pushed head to have concluded green (pending or absent refuse); you never pass proof. `action`: `get` (default; omit `subtaskId` to list every delivery) | `phase` (`to` + what that edge reads: `verdict` APROVADO/REPROVADO + `findings` from qa, `reviewedSha` = the sha QA approved for revisao_lider → pr_merge, `detail` for a request for change or a failure reason) | `gate` (`name`: run ONE gate and record its evidence) | `block` (`reason` one of dependencia, pedido_de_bloqueio, limite, maquina, externo, fora_das_autorizacoes; `text`) | `unblock` (`detail`; the leader of the task or the owner — an owner-decision block only the owner) | `step` (`step` 1..9: the step of the current phase, for the Live %. The Live already DERIVES the step from real signals — a session open, a file edit, a test run, a commit, the gates, the PR — so report only when you know better; the card shows the larger of the two and says which it is. Works for a legacy piece with no delivery record too: only the board's `step` event is written, nothing is adopted into the flow) | `configure` (the LEADER of the task or the owner only; `patch`: versionTarget, humanGates [phases needing the owner's approval — skipped and recorded as 'pulado: modo autônomo' while autonomous mode is on], leaderSessionId, pr, tag, allowDeletions {paths, reason}; the QA and author sessions are never settable — the host records them from the sessions it opened and the registry) | `approve` (`phase`, `decision` approve|reject, `note`: answers a human gate the owner was ASKED about; a session identity is deliberately not sent, the owner answers through this same door as the Live card button and `agentop flow approve`) | `stage-run` (predispatch + vaga gates, then start the staged session and move to executando) | `merge` (delecoes gate, squash-merge the PR, move to ci; a failure goes back to revisao_lider) | `release` (the LEADER of the task or the owner DECLARES what a release contains: `version` x.y.z, `mergeSha` = the commit on main carrying it (information only; 40 characters, or a short sha the server resolves), optional `repo` = owner/name (default agentistics/agentistics), `subtaskIds` = every piece in it; no `subtaskId`. Each piece gets its record (a legacy one is adopted), versionTarget/mergeSha/tag/repo, goes to ci and then to publicado as soon as the tag `v<version>` exists and the release.yml run that produced it is green — read by the server from the TAG, not from the sha — with the release's own publish time; a declared piece is never sent back to revisao_lider by the tick (a red tag run keeps it in ci and wakes the leader once); done/abandoned/blocked/unknown/other-task pieces refuse the whole batch, which is written in ONE store write; a second run changes nothing). In autonomous mode nothing here ever asks or waits for the owner.",
2555
+ description: "FLUXO.CICLO-COMPLETO — the minute `tick` also moves a piece in revisao_lider or pr_merge to ci BY ITSELF once its PR is merged (found from the piece's PR number, branch, the PR containing the sha QA approved, or its author worktree's branch; the merge gates `delecoes` + `mergeado` still run, and a refusal leaves the piece where it is with the reason), publishes ci pieces from the FIRST tag that contains the merge, and reminds the LIVE leader of the task (never the owner) of a piece waiting on them for 30 min, then every 2 h, at most 3 times. `get` with a `subtaskId` returns `tickReason`: why the tick has not moved it. `reconcile` (no `subtaskId`; `apply` true to write) is the one-shot BACKFILL: every piece in revisao_lider/pr_merge/ci matched to its merged PR and the first release tag containing it — a report of what moves and what cannot be proven, with the reason. " + "`tick` also enables the mandatory owner-request/placement flows through the official engine switches and reads canonical pedidos; after 10 minutes without complete staging it wakes the current live task leader, including after a handoff or restart, and never asks the owner. " + "Queue actions: `dequeue` withdraws a queued piece with a required free-text `reason` (task leader or owner only), keeps the draft/history, and refuses dispatch until explicitly restaged; `tick` reconciles stale queued pieces against board review/done/abandoned and records a comment. Vacancy counts live backend processes; lost/exited/closed sessions reserve no slots. " + "FLUXO.ENTREGA-DSL — read or move a DELIVERY (one subtask) through its fixed phases: fila → executando → qa → (ajuste ⇄ qa) → revisao_lider → pr_merge → ci → publicado, plus bloqueado (from any phase, back to the stored origin only). Any transition outside that table is REFUSED (422 `fase_pulada`) with a sentence naming what is missing — executando → revisao_lider, ajuste → revisao_lider and every other skip included. The gates each edge needs are run BY THE SERVER from evidence (predispatch, vaga, salvo = sha on origin per ls-remote, qa-modelo = QA model ≠ author model from the registry and never Sonnet over Sonnet, cabeca = the pushed branch is still at the sha QA tested, delecoes = no file deleted outright by the PR, mergeado = gh says the PR is MERGED, the merge commit is on origin/main and the PR head is the sha QA approved — the merge sha is READ FROM THE PR, never from you, release = the batch's version tag exists AND the release.yml run that produced it is green, read in the repository the release recorded); salvo needs every check run on the pushed head to have concluded green (pending or absent refuse); you never pass proof. `action`: `get` (default; omit `subtaskId` to list every delivery) | `phase` (`to` + what that edge reads: `verdict` APROVADO/REPROVADO + `findings` from qa, `reviewedSha` = the sha QA approved for revisao_lider → pr_merge, `detail` for a request for change or a failure reason) | `gate` (`name`: run ONE gate and record its evidence) | `block` (`reason` one of dependencia, pedido_de_bloqueio, limite, maquina, externo, fora_das_autorizacoes; `text`) | `unblock` (`detail`; the leader of the task or the owner — an owner-decision block only the owner) | `step` (`step` 1..9: the step of the current phase, for the Live %. The Live already DERIVES the step from real signals — a session open, a file edit, a test run, a commit, the gates, the PR — so report only when you know better; the card shows the larger of the two and says which it is. Works for a legacy piece with no delivery record too: only the board's `step` event is written, nothing is adopted into the flow) | `configure` (the LEADER of the task or the owner only; `patch`: versionTarget, humanGates [phases needing the owner's approval — skipped and recorded as 'pulado: modo autônomo' while autonomous mode is on], leaderSessionId, pr, tag, allowDeletions {paths, reason}; the QA and author sessions are never settable — the host records them from the sessions it opened and the registry) | `approve` (`phase`, `decision` approve|reject, `note`: answers a human gate the owner was ASKED about; a session identity is deliberately not sent, the owner answers through this same door as the Live card button and `agentop flow approve`) | `stage-run` (predispatch + vaga gates, then start the staged session and move to executando) | `merge` (delecoes gate, squash-merge the PR, move to ci; a failure goes back to revisao_lider) | `release` (the LEADER of the task or the owner DECLARES what a release contains: `version` x.y.z, `mergeSha` = the commit on main carrying it (information only; 40 characters, or a short sha the server resolves), optional `repo` = owner/name (default agentistics/agentistics), `subtaskIds` = every piece in it; no `subtaskId`. Each piece gets its record (a legacy one is adopted), versionTarget/mergeSha/tag/repo, goes to ci and then to publicado as soon as the tag `v<version>` exists and the release.yml run that produced it is green — read by the server from the TAG, not from the sha — with the release's own publish time; a declared piece is never sent back to revisao_lider by the tick (a red tag run keeps it in ci and wakes the leader once); done/abandoned/blocked/unknown/other-task pieces refuse the whole batch, which is written in ONE store write; a second run changes nothing). In autonomous mode nothing here ever asks or waits for the owner.",
2533
2556
  inputSchema: {
2534
2557
  type: "object",
2535
2558
  properties: {
2536
- action: { type: "string", enum: ["get", "phase", "gate", "block", "unblock", "dequeue", "tick", "step", "configure", "approve", "stage-run", "merge", "release"] },
2559
+ action: { type: "string", enum: ["get", "phase", "gate", "block", "unblock", "dequeue", "tick", "step", "configure", "approve", "stage-run", "merge", "release", "reconcile"] },
2560
+ apply: { type: "boolean", description: "reconcile: write the moves (a leader of the task, or the owner). Absent/false = dry run: the report only" },
2537
2561
  subtaskId: { type: "string" },
2538
2562
  version: { type: "string", description: "release: the version the pieces shipped in, x.y.z" },
2539
2563
  mergeSha: { type: "string", description: "release: the commit on main that carries the release (information only: stored on the record; a short sha is resolved to 40 characters or refused). The publication evidence is the version tag's own green release.yml run" },
@@ -2645,7 +2669,7 @@ var TOOLS = [
2645
2669
  to: { type: "string", description: "The target session reference." },
2646
2670
  kind: { type: "string", enum: ["handback", "block", "question"] },
2647
2671
  body: { type: "string", description: "The message." },
2648
- awaiting: { type: "string", description: "kind=handback only: what you stopped waiting for (marks the handback as intermediate; the worker is not closed). Omit on a final handback." }
2672
+ awaiting: { type: "string", description: `kind=handback only: what you stopped waiting for (marks the handback as intermediate: the worker is not closed, your subtask stays in_progress and the leader's check-in does not list it as delivered). A text that says it is part N of M ("parte 2 de 5", "2/5", "seguindo com…") with no awaiting is read the same way, and the reply tells you so. Omit on the FINAL handback.` }
2649
2673
  },
2650
2674
  required: ["to", "kind", "body"]
2651
2675
  }
@@ -3024,7 +3048,12 @@ async function callTool(req) {
3024
3048
  }
3025
3049
  case "agentistics_task_create": {
3026
3050
  const a = args;
3027
- const body = await apiSend("POST", "/api/tasks", { title: a?.title, detail: a?.detail });
3051
+ const body = await apiSend("POST", "/api/tasks", {
3052
+ title: a?.title,
3053
+ detail: a?.detail,
3054
+ ...typeof a?.priority === "string" ? { priority: a.priority } : {},
3055
+ ...typeof a?.type === "string" ? { type: a.type } : {}
3056
+ });
3028
3057
  return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
3029
3058
  }
3030
3059
  case "agentistics_task_status": {
@@ -3189,6 +3218,10 @@ async function callTool(req) {
3189
3218
  });
3190
3219
  return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
3191
3220
  }
3221
+ if (action === "reconcile") {
3222
+ const body = await apiSend("POST", "/api/deliveries/reconcile", { apply: a.apply === true, session: sessionProof(process.env) });
3223
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
3224
+ }
3192
3225
  if (action !== "tick" && (typeof a.subtaskId !== "string" || !a.subtaskId))
3193
3226
  throw new Error("subtaskId is required");
3194
3227
  const { subtaskId: _s, action: _a, ...rest } = a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentistics/mcp",
3
- "version": "2.202.0",
3
+ "version": "2.203.0",
4
4
  "description": "Agentistics MCP server — Claude Code analytics for Claude Desktop and Claude Code",
5
5
  "type": "module",
6
6
  "main": "./dist/agentistics-mcp.js",