@agentistics/mcp 2.203.1 → 2.204.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.
- package/dist/agentistics-mcp.js +97 -4
- package/package.json +1 -1
package/dist/agentistics-mcp.js
CHANGED
|
@@ -23,6 +23,43 @@ function liveDeliveryQuery(a) {
|
|
|
23
23
|
return q.toString() ? `?${q}` : "";
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// delivery-calendar-args.ts
|
|
27
|
+
var CALENDAR_STAGES = ["queue", "blocked", "running", "qa", "adjust", "leader", "merge", "ci", "published"];
|
|
28
|
+
var CALENDAR_PRIORITIES = ["urgent", "high", "medium", "low"];
|
|
29
|
+
function list(v, allowed) {
|
|
30
|
+
const items = (Array.isArray(v) ? v : typeof v === "string" ? v.split(",") : []).filter((x) => typeof x === "string").map((x) => x.trim()).filter(Boolean);
|
|
31
|
+
return (allowed ? items.filter((x) => allowed.includes(x)) : items).join(",");
|
|
32
|
+
}
|
|
33
|
+
function deliveryCalendarQuery(a) {
|
|
34
|
+
const q = new URLSearchParams;
|
|
35
|
+
const task = typeof a?.task === "string" ? a.task.trim() : "";
|
|
36
|
+
if (task)
|
|
37
|
+
q.set("task", task);
|
|
38
|
+
const subtask = typeof a?.subtask === "string" ? a.subtask.trim() : "";
|
|
39
|
+
if (subtask)
|
|
40
|
+
q.set("subtask", subtask);
|
|
41
|
+
for (const [key, value] of [
|
|
42
|
+
["version", list(a?.version)],
|
|
43
|
+
["stage", list(a?.stage, CALENDAR_STAGES)],
|
|
44
|
+
["harness", list(a?.harness)],
|
|
45
|
+
["priority", list(a?.priority, CALENDAR_PRIORITIES)]
|
|
46
|
+
])
|
|
47
|
+
if (value)
|
|
48
|
+
q.set(key, value);
|
|
49
|
+
for (const key of ["from", "to"]) {
|
|
50
|
+
const v = a?.[key];
|
|
51
|
+
if (typeof v === "string" && v.trim())
|
|
52
|
+
q.set(key, v.trim());
|
|
53
|
+
}
|
|
54
|
+
if (a?.all === true)
|
|
55
|
+
q.set("all", "1");
|
|
56
|
+
if (a?.confirmedOnly === true)
|
|
57
|
+
q.set("confirmed", "1");
|
|
58
|
+
if (a?.format === "ics")
|
|
59
|
+
q.set("format", "ics");
|
|
60
|
+
return q.toString() ? `?${q}` : "";
|
|
61
|
+
}
|
|
62
|
+
|
|
26
63
|
// ../core/src/local-models.ts
|
|
27
64
|
var LOCAL_RUNTIME_PREFIXES = [
|
|
28
65
|
"ollama",
|
|
@@ -967,6 +1004,7 @@ var AGENT_TOOL_POLICY = {
|
|
|
967
1004
|
agentistics_task_claim: { ...TASKS, risk: "W", routes: ["POST /api/tasks/:ref/claim"], reason: "a lease that expires on its own and can be released" },
|
|
968
1005
|
agentistics_task_activity: { ...TASKS, risk: "R", routes: ["GET /api/tasks/activity"], reason: "reads the board activity log" },
|
|
969
1006
|
agentistics_live_delivery: { ...TASKS, risk: "R", routes: ["GET /api/tasks/live"], reason: "reads the live delivery line and the leaders band; changes nothing" },
|
|
1007
|
+
agentistics_delivery_calendar: { ...TASKS, risk: "R", routes: ["GET /api/deliveries/calendar"], reason: "reads the delivery calendar (dates, versions, ETAs); changes nothing" },
|
|
970
1008
|
agentistics_task_edit: { ...TASKS, risk: "W", routes: ["POST /api/tasks/:ref"], reason: "edits task fields; reversible by another edit" },
|
|
971
1009
|
agentistics_task_session: {
|
|
972
1010
|
...TASKS,
|
|
@@ -1008,7 +1046,7 @@ var AGENT_TOOL_POLICY = {
|
|
|
1008
1046
|
agentistics_task_phase: {
|
|
1009
1047
|
...TASKS,
|
|
1010
1048
|
risk: "W",
|
|
1011
|
-
routes: ["GET /api/deliveries", "GET /api/deliveries/:subtask", "POST /api/deliveries/:subtask", "POST /api/deliveries/release", "POST /api/deliveries/reconcile"],
|
|
1049
|
+
routes: ["GET /api/deliveries", "GET /api/deliveries/:subtask", "POST /api/deliveries/:subtask", "POST /api/deliveries/release", "POST /api/deliveries/reconcile", "POST /api/deliveries/antigas"],
|
|
1012
1050
|
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"
|
|
1013
1051
|
},
|
|
1014
1052
|
agentistics_task_stage: {
|
|
@@ -1224,6 +1262,10 @@ var GO_WINDOW_MS = {
|
|
|
1224
1262
|
function isFlowRunId(id) {
|
|
1225
1263
|
return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(id);
|
|
1226
1264
|
}
|
|
1265
|
+
// ../core/src/deliveryCalendar.ts
|
|
1266
|
+
var BRT_OFFSET_MS = -3 * 3600000;
|
|
1267
|
+
var RECENT_ACTIVITY_MS = 24 * 3600000;
|
|
1268
|
+
var BLIP_MS = 15 * 60000;
|
|
1227
1269
|
// ../core/src/vaultPassword.ts
|
|
1228
1270
|
var VAULT_PASSWORD_RULES = ["length", "upper", "special", "digit"];
|
|
1229
1271
|
var VAULT_PASSWORD_MIN_LENGTH = 9;
|
|
@@ -2153,6 +2195,12 @@ var CATALOG = [
|
|
|
2153
2195
|
{ id: "sessions.highlights", label: "Highlights", category: "sessions", defaultW: 12, defaultH: 6, minW: 6, minH: 3, description: "Record-breaking sessions" },
|
|
2154
2196
|
{ id: "sessions.recent", label: "Recent sessions", category: "sessions", defaultW: 12, defaultH: 7, minW: 6, minH: 4, description: "List of most recent sessions" }
|
|
2155
2197
|
];
|
|
2198
|
+
async function apiGetText(path) {
|
|
2199
|
+
const res = await fetch(`${API}${path}`);
|
|
2200
|
+
if (!res.ok)
|
|
2201
|
+
throw new Error(`agentistics API ${path} → HTTP ${res.status}`);
|
|
2202
|
+
return res.text();
|
|
2203
|
+
}
|
|
2156
2204
|
async function apiGet(path) {
|
|
2157
2205
|
const res = await fetch(`${API}${path}`);
|
|
2158
2206
|
if (!res.ok)
|
|
@@ -2486,7 +2534,7 @@ var TOOLS = [
|
|
|
2486
2534
|
type: "object",
|
|
2487
2535
|
properties: {
|
|
2488
2536
|
task: { type: "string", description: "A task id or part of its title." },
|
|
2489
|
-
stage: { type: "string", enum: ["queue", "running", "qa", "adjust", "leader", "merge", "published"] },
|
|
2537
|
+
stage: { type: "string", enum: ["queue", "blocked", "running", "qa", "adjust", "leader", "merge", "ci", "completed", "published"] },
|
|
2490
2538
|
stalledOnly: { type: "boolean", description: "Only deliveries that need a person, lost an agent or are blocked." },
|
|
2491
2539
|
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." },
|
|
2492
2540
|
period: { type: "string", enum: ["24h", "7d", "30d", "all"], description: "How far back Publicado reaches. Default 24h." },
|
|
@@ -2551,13 +2599,38 @@ var TOOLS = [
|
|
|
2551
2599
|
description: "Delete a task and its comments, subtasks, files and links. The SESSIONS filed under it are kept — deleting a board entry never deletes work.",
|
|
2552
2600
|
inputSchema: { type: "object", properties: { ref: { type: "string" } }, required: ["ref"] }
|
|
2553
2601
|
},
|
|
2602
|
+
{
|
|
2603
|
+
name: "agentistics_delivery_calendar",
|
|
2604
|
+
description: "BETA. The DELIVERY CALENDAR — when each piece of work started, when it is expected to ship, which release version it rides and when a version really went out; the same source and rules as the \"Calendário de entregas\" screen (`agentop flow calendario` prints the same). Returns `pieces` (task, subtask, stage, `version`, harness/model, priority, `startedAtMs`, `stageEta` and `publishEta` — `kind: none` means there is NO estimate: say so, never invent a time — `publishedAtMs`, `dueDate`, `confirmed`, `late`), `versions` (each with `state` published|planned, `atMs` = the real publication or the LATEST piece estimate, `basis` published|estimate|partial|none, the pieces and the count per stage) and `marks` (an account's usage window renewing, a task's due day). Times are epoch ms; day arguments are BRT days (America/Sao_Paulo). By default only pieces of tasks being worked on now; pass `all` for the history too. Filters: `task` (id or part of the title), `subtask`, `version` (one or a list), `stage`, `harness`, `priority`, `from`/`to` (yyyy-MM-dd or an ISO instant — keeps what touches the period), `confirmedOnly` (published or a medium/high-confidence estimate). `format: \"ics\"` returns the filtered view as an .ics file instead of JSON.",
|
|
2605
|
+
inputSchema: {
|
|
2606
|
+
type: "object",
|
|
2607
|
+
properties: {
|
|
2608
|
+
task: { type: "string", description: "A task id or part of its title." },
|
|
2609
|
+
subtask: { type: "string", description: "A subtask id." },
|
|
2610
|
+
version: { anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }], description: "A release version (2.202.0) or a list." },
|
|
2611
|
+
stage: { anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }], description: "queue, blocked, running, qa, adjust, leader, merge, ci, published — one or a list." },
|
|
2612
|
+
harness: { anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }] },
|
|
2613
|
+
priority: { anyOf: [{ type: "string" }, { type: "array", items: { type: "string" } }], description: "urgent, high, medium, low." },
|
|
2614
|
+
from: { type: "string", description: "Start of the period: yyyy-MM-dd (BRT) or an ISO instant." },
|
|
2615
|
+
to: { type: "string", description: "End of the period (inclusive)." },
|
|
2616
|
+
all: { type: "boolean", description: "Include pieces of tasks not being worked on now (history)." },
|
|
2617
|
+
confirmedOnly: { type: "boolean", description: "Only published pieces or those with a medium/high-confidence estimate." },
|
|
2618
|
+
format: { type: "string", enum: ["json", "ics"] }
|
|
2619
|
+
},
|
|
2620
|
+
required: []
|
|
2621
|
+
}
|
|
2622
|
+
},
|
|
2554
2623
|
{
|
|
2555
2624
|
name: "agentistics_task_phase",
|
|
2556
2625
|
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.",
|
|
2557
2626
|
inputSchema: {
|
|
2558
2627
|
type: "object",
|
|
2559
2628
|
properties: {
|
|
2560
|
-
action: { type: "string", enum: ["get", "phase", "gate", "block", "unblock", "dequeue", "tick", "step", "configure", "approve", "stage-run", "merge", "release", "reconcile"] },
|
|
2629
|
+
action: { type: "string", enum: ["get", "phase", "gate", "block", "unblock", "dequeue", "tick", "step", "configure", "approve", "stage-run", "merge", "release", "reconcile", "antigas"] },
|
|
2630
|
+
antigasAction: { type: "string", enum: ["publish", "archive", "conclude"], description: "antigas: 'conclude' (the screen's one click) completes the pieces with a session and archives the ones without; add `preview` to read the counts without changing anything. 'publish' marks the old record-less pieces published (optional `version`), 'archive' abandons them with an optional `reason`. Targets: `subtaskIds`, or `all` = every piece the reconcile classifies as antiga. Never deletes; a leader or the owner" },
|
|
2631
|
+
preview: { type: "boolean", description: "antigas conclude: only count what the click would do (concluded vs archived); changes nothing" },
|
|
2632
|
+
all: { type: "boolean", description: 'antigas: act on every old piece in the group "Antigas sem registro" (answers from the board at once; a piece the last reconcile proved is left out)' },
|
|
2633
|
+
expect: { type: "number", description: "antigas: the size of the group you saw; a different size refuses (409 count_changed) and nothing changes" },
|
|
2561
2634
|
apply: { type: "boolean", description: "reconcile: write the moves (a leader of the task, or the owner). Absent/false = dry run: the report only" },
|
|
2562
2635
|
subtaskId: { type: "string" },
|
|
2563
2636
|
version: { type: "string", description: "release: the version the pieces shipped in, x.y.z" },
|
|
@@ -2573,7 +2646,7 @@ var TOOLS = [
|
|
|
2573
2646
|
phase: { type: "string", description: "approve: the phase whose human gate is answered" },
|
|
2574
2647
|
decision: { type: "string", enum: ["approve", "reject"] },
|
|
2575
2648
|
note: { type: "string" },
|
|
2576
|
-
reason: { type: "string", description: "dequeue: required free-text audit reason (leader only); block: dependencia | pedido_de_bloqueio | limite | maquina | externo | fora_das_autorizacoes" },
|
|
2649
|
+
reason: { type: "string", description: "dequeue: required free-text audit reason (leader only); block: dependencia | pedido_de_bloqueio | limite | maquina | externo | fora_das_autorizacoes; antigas archive: why (kept in the comment)" },
|
|
2577
2650
|
text: { type: "string" },
|
|
2578
2651
|
step: { type: "number" },
|
|
2579
2652
|
patch: { type: "object" }
|
|
@@ -3202,6 +3275,13 @@ async function callTool(req) {
|
|
|
3202
3275
|
const body = await apiSend("DELETE", `/api/tasks/${encodeURIComponent(ref)}`);
|
|
3203
3276
|
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
3204
3277
|
}
|
|
3278
|
+
case "agentistics_delivery_calendar": {
|
|
3279
|
+
const q = deliveryCalendarQuery(args);
|
|
3280
|
+
if (args?.format === "ics")
|
|
3281
|
+
return { content: [{ type: "text", text: await apiGetText(`/api/deliveries/calendar${q}`) }] };
|
|
3282
|
+
const body = await apiGet(`/api/deliveries/calendar${q}`);
|
|
3283
|
+
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
3284
|
+
}
|
|
3205
3285
|
case "agentistics_task_phase": {
|
|
3206
3286
|
const a = args ?? {};
|
|
3207
3287
|
const action = typeof a.action === "string" ? a.action : "get";
|
|
@@ -3223,6 +3303,19 @@ async function callTool(req) {
|
|
|
3223
3303
|
const body = await apiSend("POST", "/api/deliveries/reconcile", { apply: a.apply === true, session: sessionProof(process.env) });
|
|
3224
3304
|
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
3225
3305
|
}
|
|
3306
|
+
if (action === "antigas") {
|
|
3307
|
+
const body = await apiSend("POST", "/api/deliveries/antigas", {
|
|
3308
|
+
action: a.antigasAction,
|
|
3309
|
+
ids: a.subtaskIds,
|
|
3310
|
+
all: a.all === true,
|
|
3311
|
+
preview: a.preview === true,
|
|
3312
|
+
expect: a.expect,
|
|
3313
|
+
version: a.version,
|
|
3314
|
+
reason: a.reason,
|
|
3315
|
+
session: sessionProof(process.env)
|
|
3316
|
+
});
|
|
3317
|
+
return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
|
|
3318
|
+
}
|
|
3226
3319
|
if (action !== "tick" && (typeof a.subtaskId !== "string" || !a.subtaskId))
|
|
3227
3320
|
throw new Error("subtaskId is required");
|
|
3228
3321
|
const { subtaskId: _s, action: _a, ...rest } = a;
|
package/package.json
CHANGED