@agentistics/mcp 2.199.0 → 2.200.1

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.
@@ -1,5 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ // live-delivery-args.ts
4
+ var LIVE_STAGES = ["queue", "running", "qa", "adjust", "leader", "merge", "published"];
5
+ function liveDeliveryQuery(a) {
6
+ const q = new URLSearchParams;
7
+ const task = typeof a?.task === "string" ? a.task.trim() : "";
8
+ if (task)
9
+ q.set("task", task);
10
+ if (typeof a?.stage === "string" && LIVE_STAGES.includes(a.stage))
11
+ q.set("stage", a.stage);
12
+ if (a?.stalledOnly === true)
13
+ q.set("stalled", "1");
14
+ return q.toString() ? `?${q}` : "";
15
+ }
16
+
3
17
  // ../core/src/local-models.ts
4
18
  var LOCAL_RUNTIME_PREFIXES = [
5
19
  "ollama",
@@ -941,6 +955,7 @@ var AGENT_TOOL_POLICY = {
941
955
  agentistics_task_next: { ...TASKS, risk: "R", routes: ["GET /api/tasks/next"], reason: "asks what is ready; claims nothing" },
942
956
  agentistics_task_claim: { ...TASKS, risk: "W", routes: ["POST /api/tasks/:ref/claim"], reason: "a lease that expires on its own and can be released" },
943
957
  agentistics_task_activity: { ...TASKS, risk: "R", routes: ["GET /api/tasks/activity"], reason: "reads the board activity log" },
958
+ agentistics_live_delivery: { ...TASKS, risk: "R", routes: ["GET /api/tasks/live"], reason: "reads the live delivery line and the leaders band; changes nothing" },
944
959
  agentistics_task_edit: { ...TASKS, risk: "W", routes: ["POST /api/tasks/:ref"], reason: "edits task fields; reversible by another edit" },
945
960
  agentistics_task_session: {
946
961
  ...TASKS,
@@ -1001,7 +1016,7 @@ var AGENT_TOOL_POLICY = {
1001
1016
  ...GROUPS,
1002
1017
  risk: "W",
1003
1018
  routes: ["GET /api/away", "PUT /api/away", "PUT /api/away/session", "POST /api/away/notice"],
1004
- reason: "reads or switches away mode (what newly started sessions are told about the owner being out) and lets a leader raise a notice in the owner's bell; reversible by switching it off; the server accepts writes only from a verified LEADER session"
1019
+ reason: "reads or switches autonomous mode (what newly started sessions are told about the owner being out) and lets a leader raise a notice in the owner's bell; reversible by switching it off; the server accepts writes only from a verified LEADER session"
1005
1020
  },
1006
1021
  agentistics_session_switch_account: {
1007
1022
  ...GROUPS,
@@ -1627,6 +1642,7 @@ function planLimitsTool(args, body) {
1627
1642
  const routed = args?.kind ? routeRecommendation(budgets, args.kind, args.authorHarness) : undefined;
1628
1643
  const recommendation = routed?.accountLabel !== undefined ? { ...routed, accountLabel: plainLabel(routed.accountLabel) } : routed;
1629
1644
  const aggregates = harnessAggregate(budgets);
1645
+ const offBySchedule = (body.hiddenFromAgents ?? []).filter((b) => b?.agentUse && !b.agentUse.on).map((b) => ({ harness: b.harness, account: b.account, reason: b.agentUse.reason }));
1630
1646
  return {
1631
1647
  budgets,
1632
1648
  harnesses: body.harnesses ?? {},
@@ -1635,6 +1651,7 @@ function planLimitsTool(args, body) {
1635
1651
  freeSlotsByAccount: body.freeSlotsByAccount ?? Object.fromEntries(budgets.filter((b) => b.account).map((b) => [b.account, b.freeSlots ?? 0])),
1636
1652
  liveSessions: body.liveSessions ?? budgets.flatMap((b) => b.liveSessions ?? []).filter((s, i, all) => all.findIndex((x) => x.id === s.id) === i),
1637
1653
  ...body.pauseUntil !== undefined ? { pauseUntil: body.pauseUntil } : {},
1654
+ ...offBySchedule.length ? { offBySchedule } : {},
1638
1655
  ...recommendation ? { recommendation } : {},
1639
1656
  readAt: body.now ?? Date.now()
1640
1657
  };
@@ -2130,12 +2147,12 @@ var server = new Server({ name: "agentistics", version: "1.0.0" }, { capabilitie
2130
2147
  var TOOLS = [
2131
2148
  {
2132
2149
  name: "agentistics_tasks",
2133
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. List every task on the ALM board with its rollup (cost, rounds, sessions used, tokens) plus a board-wide overview: tasks in flight, delivered, average cost per task and per task, top models and harnesses. START HERE to see what work exists and what the other assistants are on.",
2150
+ description: "List every task on the ALM board with its rollup (cost, rounds, sessions used, tokens) plus a board-wide overview: tasks in flight, delivered, average cost per task and per task, top models and harnesses. START HERE to see what work exists and what the other assistants are on.",
2134
2151
  inputSchema: { type: "object", properties: {}, required: [] }
2135
2152
  },
2136
2153
  {
2137
2154
  name: "agentistics_task",
2138
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Open ONE task: its attempts (one per configuration tried), the sessions filed under it with their live state, its comments, subtasks, files, links and full metrics (models, harnesses, agent runs, tokens, delivery time). Comments come twice: `comments` (flat, oldest first, each with `subtaskId` when it was left on a subtask or group) and `commentThreads` — the same comments grouped by their OWN target (`target: {kind: 'task'|'group'|'subtask', id, title}`; the task first, empty targets omitted). `ref` is the task id or its exact title.",
2155
+ description: "Open ONE task: its attempts (one per configuration tried), the sessions filed under it with their live state, its comments, subtasks, files, links and full metrics (models, harnesses, agent runs, tokens, delivery time). Comments come twice: `comments` (flat, oldest first, each with `subtaskId` when it was left on a subtask or group) and `commentThreads` — the same comments grouped by their OWN target (`target: {kind: 'task'|'group'|'subtask', id, title}`; the task first, empty targets omitted). `ref` is the task id or its exact title.",
2139
2156
  inputSchema: {
2140
2157
  type: "object",
2141
2158
  properties: { ref: { type: "string", description: "Task id or exact title." } },
@@ -2144,7 +2161,7 @@ var TOOLS = [
2144
2161
  },
2145
2162
  {
2146
2163
  name: "agentistics_task_create",
2147
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. 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.",
2164
+ 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.",
2148
2165
  inputSchema: {
2149
2166
  type: "object",
2150
2167
  properties: { title: { type: "string" }, detail: { type: "string" } },
@@ -2153,7 +2170,7 @@ var TOOLS = [
2153
2170
  },
2154
2171
  {
2155
2172
  name: "agentistics_task_status",
2156
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Move a task to a status. The status VOCABULARY is an editable list now, not a fixed set — call agentistics_task_statuses first if you are unsure what this board currently has; a fresh board starts with exactly `todo`, `in_progress`, `blocked` and `done`. Only `done` stamps a task and closes rounds-to-delivery; `abandoned` (when the board has it) records that the work was given up on, which is a real outcome and not a failure to report — but it is NOT created by default, so use agentistics_task_status_edit to add it (or any other status) first if it is missing. **`blocked` REQUIRES a `reason` or a `blockedBy` list** and is refused (422) without one: it is the status that names a problem somebody has to go and solve, and a blocked card that does not say what it is waiting on cannot be unblocked by anyone but you. **`done` REQUIRES the task to have at least one session filed under it** and is refused (422, `done_needs_session`) without one. A `status` naming nothing this board currently has is refused (400, `unknown_status`). Pass `actor` (who you are) so the move is recorded against you in the activity log.",
2173
+ description: "Move a task to a status. The status VOCABULARY is an editable list now, not a fixed set — call agentistics_task_statuses first if you are unsure what this board currently has; a fresh board starts with exactly `todo`, `in_progress`, `blocked` and `done`. Only `done` stamps a task and closes rounds-to-delivery; `abandoned` (when the board has it) records that the work was given up on, which is a real outcome and not a failure to report — but it is NOT created by default, so use agentistics_task_status_edit to add it (or any other status) first if it is missing. **`blocked` REQUIRES a `reason` or a `blockedBy` list** and is refused (422) without one: it is the status that names a problem somebody has to go and solve, and a blocked card that does not say what it is waiting on cannot be unblocked by anyone but you. **`done` REQUIRES the task to have at least one session filed under it** and is refused (422, `done_needs_session`) without one. A `status` naming nothing this board currently has is refused (400, `unknown_status`). Pass `actor` (who you are) so the move is recorded against you in the activity log.",
2157
2174
  inputSchema: {
2158
2175
  type: "object",
2159
2176
  properties: {
@@ -2178,17 +2195,17 @@ var TOOLS = [
2178
2195
  },
2179
2196
  {
2180
2197
  name: "agentistics_task_statuses",
2181
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. List every status this board currently has (id, label, color, and whether it is protected — todo/in_progress/blocked/done can never be deleted or have their id changed, but their label and color can). Call this before agentistics_task_status if you are not sure a status you want to move a task to actually exists.",
2198
+ description: "List every status this board currently has (id, label, color, and whether it is protected — todo/in_progress/blocked/done can never be deleted or have their id changed, but their label and color can). Call this before agentistics_task_status if you are not sure a status you want to move a task to actually exists.",
2182
2199
  inputSchema: { type: "object", properties: {} }
2183
2200
  },
2184
2201
  {
2185
2202
  name: "agentistics_task_types",
2186
- description: "BETA — Agentask (the task board) is new and still changing. List the task TYPE vocabulary (id, label, color, order, usageCount). A type is a second classification beside the status (e.g. CORE); a task may carry one or none. Call this before setting `type` through agentistics_task_edit.",
2203
+ description: "List the task TYPE vocabulary (id, label, color, order, usageCount). A type is a second classification beside the status (e.g. CORE); a task may carry one or none. Call this before setting `type` through agentistics_task_edit.",
2187
2204
  inputSchema: { type: "object", properties: {} }
2188
2205
  },
2189
2206
  {
2190
2207
  name: "agentistics_task_type_edit",
2191
- description: "BETA — Agentask (the task board) is new and still changing. Add, rename/recolor, or delete a task type. Pass `label` (and optional `color`, a `#rrggbb` hex string) alone to CREATE a type — its id is derived from the label. Pass `id` with `label` and/or `color` to EDIT. Pass `id` with `remove: true` to DELETE: refused (422, `in_use`, with `usageCount`) while any task still carries it.",
2208
+ description: "Add, rename/recolor, or delete a task type. Pass `label` (and optional `color`, a `#rrggbb` hex string) alone to CREATE a type — its id is derived from the label. Pass `id` with `label` and/or `color` to EDIT. Pass `id` with `remove: true` to DELETE: refused (422, `in_use`, with `usageCount`) while any task still carries it.",
2192
2209
  inputSchema: {
2193
2210
  type: "object",
2194
2211
  properties: {
@@ -2202,7 +2219,7 @@ var TOOLS = [
2202
2219
  },
2203
2220
  {
2204
2221
  name: "agentistics_task_status_edit",
2205
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Add, rename/recolor, or delete a status. Pass `label` (and optional `color`, a `#rrggbb` hex string) alone to CREATE a new, non-protected status — its id is derived from the label and returned. Pass `id` with `label` and/or `color` to EDIT an existing status's label/color — works on a protected one too, only its id can never change. Pass `id` with `remove: true` to DELETE it: refused (422, `protected`) for todo/in_progress/blocked/done regardless of usage, and refused (422, `in_use`, with `usageCount`) for any other status still referenced by at least one task or subtask.",
2222
+ description: "Add, rename/recolor, or delete a status. Pass `label` (and optional `color`, a `#rrggbb` hex string) alone to CREATE a new, non-protected status — its id is derived from the label and returned. Pass `id` with `label` and/or `color` to EDIT an existing status's label/color — works on a protected one too, only its id can never change. Pass `id` with `remove: true` to DELETE it: refused (422, `protected`) for todo/in_progress/blocked/done regardless of usage, and refused (422, `in_use`, with `usageCount`) for any other status still referenced by at least one task or subtask.",
2206
2223
  inputSchema: {
2207
2224
  type: "object",
2208
2225
  properties: {
@@ -2215,7 +2232,7 @@ var TOOLS = [
2215
2232
  },
2216
2233
  {
2217
2234
  name: "agentistics_task_comment",
2218
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Leave a comment on a task — or on ONE of its subtasks or subtask GROUPS by passing `subtaskId` (a group's own id is allowed; omit it to comment on the task itself). `body` may be empty when `attachments` is given. Comments carry attachments as REFERENCES into the chat's own attachment store (`{name, path}`; agentistics_task returns them on each comment with a `url` that serves the file) — there is no second store. Use it to tell the person and the other assistants what you did, what you found, or what you are blocked on; comment where the work is (the subtask you are on) rather than on the whole task. An unknown, deleted or other task's `subtaskId` is REFUSED with a sentence (422, `no_such_subtask` / `wrong_delivery`) — never silently filed on the task. Threads read downward: a subtask's thread is its own comments, a group's thread is its own plus its members', the task's is everything. The activity log names the target. `author` is free text — say who you are (e.g. 'claude:3f5f'). THREADS: a thread is a topic on the task; post into one with `threadId`, or open one with `threadTitle` (sessions: handbacks and blocks only). A thread is a RECORD, not a chat: a comment there reaches nobody by itself, so never wait for an answer in a thread. When you post in a thread you join it; the person may explicitly SEND a message from it, which arrives in your own chat starting `[Agentask · … · sent by the owner]` — answer there, in your chat, which is where conversations live. If you need something from the person, ask in your own chat as always.",
2235
+ description: "Leave a comment on a task — or on ONE of its subtasks or subtask GROUPS by passing `subtaskId` (a group's own id is allowed; omit it to comment on the task itself). `body` may be empty when `attachments` is given. Comments carry attachments as REFERENCES into the chat's own attachment store (`{name, path}`; agentistics_task returns them on each comment with a `url` that serves the file) — there is no second store. Use it to tell the person and the other assistants what you did, what you found, or what you are blocked on; comment where the work is (the subtask you are on) rather than on the whole task. An unknown, deleted or other task's `subtaskId` is REFUSED with a sentence (422, `no_such_subtask` / `wrong_delivery`) — never silently filed on the task. Threads read downward: a subtask's thread is its own comments, a group's thread is its own plus its members', the task's is everything. The activity log names the target. `author` is free text — say who you are (e.g. 'claude:3f5f'). THREADS: a thread is a topic on the task; post into one with `threadId`, or open one with `threadTitle` (sessions: handbacks and blocks only). A thread is a RECORD, not a chat: a comment there reaches nobody by itself, so never wait for an answer in a thread. When you post in a thread you join it; the person may explicitly SEND a message from it, which arrives in your own chat starting `[Agentask · … · sent by the owner]` — answer there, in your chat, which is where conversations live. If you need something from the person, ask in your own chat as always.",
2219
2236
  inputSchema: {
2220
2237
  type: "object",
2221
2238
  properties: {
@@ -2255,7 +2272,7 @@ var TOOLS = [
2255
2272
  },
2256
2273
  {
2257
2274
  name: "agentistics_task_subtask",
2258
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Add a subtask, or change one. Pass `title` to add; pass `id` with `done`, `status`, `dueDate`, `startDate`, `blockedBy` or `parentGroupId` to edit one. `startedAt`/`deliveredAt` are system-stamped facts (when real work began / when this piece reached `done`) and are never set through this tool — they are read back on the subtask record. A subtask carries the same columns its parent does; its own cost, tokens, rounds and harness are rolled up from the sessions filed under it — the PARENT task's rollup is the sum of all its subtasks' sessions. A subtask CAN be blocked by another subtask of the SAME parent (pass `blockedBy` as the full list of sibling subtask ids that must be `done` first; a sibling outside this task, or the subtask itself, is dropped rather than accepted) — this is separate from agentistics_task_blocked_by, which blocks a whole TASK on other tasks. **`done` REQUIRES the subtask to have at least one session filed under it** and is refused (422, `done_needs_session`) without one — EXCEPT for a group MEMBER (`parentGroupId` set), which can never hold a session of its own (see below) and therefore reaches `done` through this same edit with no session required; a GROUP itself (`isGroup: true`) and an ordinary loose subtask both still need one. **The moment every one of a task's top-level subtasks (loose subtasks and groups — a group's own members never count separately) reaches `done`, the parent task auto-delivers too.** To put a session ON a subtask use agentistics_task_session with `subtaskId` — a subtask holds ANY NUMBER of sessions, so the link lives on the session, not in a field here. **SUBTASK GROUPS are a real hierarchy level, not a label**: pass `isGroup: true` with `title` to create a GROUP — a peer row that CAN hold a session, exactly like a loose subtask. Pass `id` (a subtask) with `parentGroupId` (a group's own subtask id, from the SAME parent task) to make it a MEMBER of that group — join with the group's id, leave with `parentGroupId: ''`. A refused reference (the id names no subtask, names one that is not `isGroup: true`, names a different task, or the subtask being patched is itself a group) is refused as `invalid_group` (422). **Joining a group is ALSO refused (422, `subtask_has_sessions`) when the subtask already has a session filed on it** — a member gets no rollup bucket of its own, so that session's cost would silently drop out of every visible breakdown while the task's own total kept counting it; detach the session first. **A MEMBER can never hold a session of its own** — filing on one is refused by agentistics_task_session with `subtask_in_group` (422); only the group itself accounts for a session, and a member's own status/dates/comments still exist and feed the group's progress percentage.",
2275
+ description: "Add a subtask, or change one. Pass `title` to add; pass `id` with `done`, `status`, `dueDate`, `startDate`, `blockedBy` or `parentGroupId` to edit one. `startedAt`/`deliveredAt` are system-stamped facts (when real work began / when this piece reached `done`) and are never set through this tool — they are read back on the subtask record. A subtask carries the same columns its parent does; its own cost, tokens, rounds and harness are rolled up from the sessions filed under it — the PARENT task's rollup is the sum of all its subtasks' sessions. A subtask CAN be blocked by another subtask of the SAME parent (pass `blockedBy` as the full list of sibling subtask ids that must be `done` first; a sibling outside this task, or the subtask itself, is dropped rather than accepted) — this is separate from agentistics_task_blocked_by, which blocks a whole TASK on other tasks. **`done` REQUIRES the subtask to have at least one session filed under it** and is refused (422, `done_needs_session`) without one — EXCEPT for a group MEMBER (`parentGroupId` set), which can never hold a session of its own (see below) and therefore reaches `done` through this same edit with no session required; a GROUP itself (`isGroup: true`) and an ordinary loose subtask both still need one. **The moment every one of a task's top-level subtasks (loose subtasks and groups — a group's own members never count separately) reaches `done`, the parent task auto-delivers too.** To put a session ON a subtask use agentistics_task_session with `subtaskId` — a subtask holds ANY NUMBER of sessions, so the link lives on the session, not in a field here. **SUBTASK GROUPS are a real hierarchy level, not a label**: pass `isGroup: true` with `title` to create a GROUP — a peer row that CAN hold a session, exactly like a loose subtask. Pass `id` (a subtask) with `parentGroupId` (a group's own subtask id, from the SAME parent task) to make it a MEMBER of that group — join with the group's id, leave with `parentGroupId: ''`. A refused reference (the id names no subtask, names one that is not `isGroup: true`, names a different task, or the subtask being patched is itself a group) is refused as `invalid_group` (422). **Joining a group is ALSO refused (422, `subtask_has_sessions`) when the subtask already has a session filed on it** — a member gets no rollup bucket of its own, so that session's cost would silently drop out of every visible breakdown while the task's own total kept counting it; detach the session first. **A MEMBER can never hold a session of its own** — filing on one is refused by agentistics_task_session with `subtask_in_group` (422); only the group itself accounts for a session, and a member's own status/dates/comments still exist and feed the group's progress percentage.",
2259
2276
  inputSchema: {
2260
2277
  type: "object",
2261
2278
  properties: {
@@ -2291,7 +2308,7 @@ var TOOLS = [
2291
2308
  },
2292
2309
  {
2293
2310
  name: "agentistics_task_link",
2294
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Attach a link to a task — a pull request, an issue, a document. Pass `url` (http/https only) with an optional `label` and `kind` ('pr', 'issue', …). Pass `remove` with a link id to detach one.",
2311
+ description: "Attach a link to a task — a pull request, an issue, a document. Pass `url` (http/https only) with an optional `label` and `kind` ('pr', 'issue', …). Pass `remove` with a link id to detach one.",
2295
2312
  inputSchema: {
2296
2313
  type: "object",
2297
2314
  properties: {
@@ -2306,7 +2323,7 @@ var TOOLS = [
2306
2323
  },
2307
2324
  {
2308
2325
  name: "agentistics_task_blocked_by",
2309
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Set which tasks must finish before this one can proceed. Pass the full list of blocker task ids (it replaces, it does not append). A task cannot block itself.",
2326
+ description: "Set which tasks must finish before this one can proceed. Pass the full list of blocker task ids (it replaces, it does not append). A task cannot block itself.",
2310
2327
  inputSchema: {
2311
2328
  type: "object",
2312
2329
  properties: { ref: { type: "string" }, blockedBy: { type: "array", items: { type: "string" } } },
@@ -2315,7 +2332,7 @@ var TOOLS = [
2315
2332
  },
2316
2333
  {
2317
2334
  name: "agentistics_task_next",
2318
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. THE ORCHESTRATION CALL: what you can pick up right now. Returns the tasks that are open, not blocked by unfinished work, and not in another agent's hands — most urgent first, numbered from 1. It also returns `withheld`, every task that is NOT available with the reason (closed / blocked / claimed / status), because an agent told 'nothing' learns nothing; and `progress`, which separates 'it is all done' from 'everything is in somebody's hands right now'. Pass `actor` (who you are) so a task you already hold comes back as available to you rather than as taken.",
2335
+ description: "THE ORCHESTRATION CALL: what you can pick up right now. Returns the tasks that are open, not blocked by unfinished work, and not in another agent's hands — most urgent first, numbered from 1. It also returns `withheld`, every task that is NOT available with the reason (closed / blocked / claimed / status), because an agent told 'nothing' learns nothing; and `progress`, which separates 'it is all done' from 'everything is in somebody's hands right now'. Pass `actor` (who you are) so a task you already hold comes back as available to you rather than as taken.",
2319
2336
  inputSchema: {
2320
2337
  type: "object",
2321
2338
  properties: {
@@ -2327,7 +2344,7 @@ var TOOLS = [
2327
2344
  },
2328
2345
  {
2329
2346
  name: "agentistics_task_claim",
2330
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. TAKE a task before working on it, so two agents cannot do the same one twice. This is a LEASE, not a lock: it expires (default 30 minutes) and the task returns to the board on its own, so an agent that dies does not hold work forever. Re-claiming as the same `by` REFRESHES the lease — do that while you are still working. Pass `release: true` to give it back when you finish or stop. A refusal names who holds it and until when; `takeover` is for a person overriding a live claim on purpose and an agent should not send it.",
2347
+ description: "TAKE a task before working on it, so two agents cannot do the same one twice. This is a LEASE, not a lock: it expires (default 30 minutes) and the task returns to the board on its own, so an agent that dies does not hold work forever. Re-claiming as the same `by` REFRESHES the lease — do that while you are still working. Pass `release: true` to give it back when you finish or stop. A refusal names who holds it and until when; `takeover` is for a person overriding a live claim on purpose and an agent should not send it.",
2331
2348
  inputSchema: {
2332
2349
  type: "object",
2333
2350
  properties: {
@@ -2345,16 +2362,29 @@ var TOOLS = [
2345
2362
  },
2346
2363
  {
2347
2364
  name: "agentistics_task_activity",
2348
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. What has been HAPPENING, newest first — status moves, claims, releases, priority changes, sessions filed. Pass `ref` for one task, or nothing for the whole board. On a board several agents drive this is how you find out what the others did without asking them.",
2365
+ description: "What has been HAPPENING, newest first — status moves, claims, releases, priority changes, sessions filed. Pass `ref` for one task, or nothing for the whole board. On a board several agents drive this is how you find out what the others did without asking them.",
2349
2366
  inputSchema: {
2350
2367
  type: "object",
2351
2368
  properties: { ref: { type: "string" }, limit: { type: "number" } },
2352
2369
  required: []
2353
2370
  }
2354
2371
  },
2372
+ {
2373
+ name: "agentistics_live_delivery",
2374
+ 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 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). Filters: `task` (id or part of the title), `stage`, `stalledOnly`.',
2375
+ inputSchema: {
2376
+ type: "object",
2377
+ properties: {
2378
+ task: { type: "string", description: "A task id or part of its title." },
2379
+ stage: { type: "string", enum: ["queue", "running", "qa", "adjust", "leader", "merge", "published"] },
2380
+ stalledOnly: { type: "boolean", description: "Only deliveries that need a person, lost an agent or are blocked." }
2381
+ },
2382
+ required: []
2383
+ }
2384
+ },
2355
2385
  {
2356
2386
  name: "agentistics_task_edit",
2357
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Set a task's fields: `title`, `detail`, `priority` (urgent | high | medium | low), `type` (an id from agentistics_task_types; empty string clears it), `dueDate` / `startDate` (yyyy-mm-dd), `labels`. An absent field is left alone; an EMPTY STRING clears it. `priority` defaults to `low`; a legacy `none` is stored as `low`. `startedAt`/`deliveredAt` are system-stamped facts and are never set through this tool. Pass `actor` so the change is recorded against you in the activity log.",
2387
+ description: "Set a task's fields: `title`, `detail`, `priority` (urgent | high | medium | low), `type` (an id from agentistics_task_types; empty string clears it), `dueDate` / `startDate` (yyyy-mm-dd), `labels`. An absent field is left alone; an EMPTY STRING clears it. `priority` defaults to `low`; a legacy `none` is stored as `low`. `startedAt`/`deliveredAt` are system-stamped facts and are never set through this tool. Pass `actor` so the change is recorded against you in the activity log.",
2358
2388
  inputSchema: {
2359
2389
  type: "object",
2360
2390
  properties: {
@@ -2373,7 +2403,7 @@ var TOOLS = [
2373
2403
  },
2374
2404
  {
2375
2405
  name: "agentistics_task_session",
2376
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. File a SESSION under a task, which is what makes the task measurable: its cost, tokens, rounds and harness all come from the sessions filed under it. Pass `subtaskId` to file it under one of the task's subtasks (the unit of WORK, for a task broken into steps) — this INCLUDES a subtask GROUP (see agentistics_task_subtask's `isGroup`), which holds a session exactly like any other subtask; omit `subtaskId` to file the session directly on the task itself (the unit of DELIVERY) — **only LEADER sessions may be filed on the task itself; a worker is refused (422, `leader_only`: only leader sessions are filed on the task itself; file this session on a subtask)**, so pass a `subtaskId` for workers. Both can be used on the same task — some sessions direct, some under subtasks — and each subtask's own rollup plus the directly-filed sessions' own rollup are both readable via agentistics_task's `subtaskRollups` (keyed by subtask id, with `id: null` for the direct ones), so the breakdown never disappears. **Filing on a subtask that is a MEMBER of a group (has a `parentGroupId`) is refused (422, `subtask_in_group`)** — a member can never hold a session, only the group itself can; file on the group's own id instead. Use agentistics_task to read the subtasks, or agentistics_task_subtask to create one, then pass `ref` + `sessionId` (a managed session id) + optionally `subtaskId`. Pass `detach` with a session id to unfile one. The task inherits the session's repository when it has none. **HISTORICAL conversations — pass `conversationId` INSTEAD of `sessionId`** to file a conversation that has NO live/registry row: typically a session that was killed and whose row agentop then purged, leaving its subtask `done` with 0 sessions and its cost missing from every rollup. The conversation must still be in the metrics store (its tokens/cost are what get counted); the link is kept on the board, never in the fleet, so nothing appears in the Sessions workspace and there is nothing to open — the row is marked `historical: true` in agentistics_task's `sessions`. Filing is a MOVE: one link per conversation, so filing it elsewhere replaces the old link and the answer reports `movedFrom: {taskId, subtaskId?}` (a plain `sessionId` filing reports `movedFrom` too when it displaced another filing). It counts everywhere a live session does (rollups, `subtaskRollups`, the board headline, `done_needs_session`, the group-join rule). Refusals: `no_such_conversation` (422 — the store has no record of that id; nothing to price, so nothing is filed), `conversation_in_fleet` (422 — a registry row already exists; the answer carries its `sessionId`, so call again with that as `sessionId`), plus the same target refusals as a session (`no_such_task`, `no_such_subtask`, `wrong_delivery`, `blocked`, `subtask_in_group`, `leader_only`). Optional `harness` disambiguates and `note` is kept on the link. To remove a historical link pass `detach` with the conversation id (or the row's `hist:<conversationId>` id).",
2406
+ description: "File a SESSION under a task, which is what makes the task measurable: its cost, tokens, rounds and harness all come from the sessions filed under it. Pass `subtaskId` to file it under one of the task's subtasks (the unit of WORK, for a task broken into steps) — this INCLUDES a subtask GROUP (see agentistics_task_subtask's `isGroup`), which holds a session exactly like any other subtask; omit `subtaskId` to file the session directly on the task itself (the unit of DELIVERY) — **only LEADER sessions may be filed on the task itself; a worker is refused (422, `leader_only`: only leader sessions are filed on the task itself; file this session on a subtask)**, so pass a `subtaskId` for workers. Both can be used on the same task — some sessions direct, some under subtasks — and each subtask's own rollup plus the directly-filed sessions' own rollup are both readable via agentistics_task's `subtaskRollups` (keyed by subtask id, with `id: null` for the direct ones), so the breakdown never disappears. **Filing on a subtask that is a MEMBER of a group (has a `parentGroupId`) is refused (422, `subtask_in_group`)** — a member can never hold a session, only the group itself can; file on the group's own id instead. Use agentistics_task to read the subtasks, or agentistics_task_subtask to create one, then pass `ref` + `sessionId` (a managed session id) + optionally `subtaskId`. Pass `detach` with a session id to unfile one. The task inherits the session's repository when it has none. **HISTORICAL conversations — pass `conversationId` INSTEAD of `sessionId`** to file a conversation that has NO live/registry row: typically a session that was killed and whose row agentop then purged, leaving its subtask `done` with 0 sessions and its cost missing from every rollup. The conversation must still be in the metrics store (its tokens/cost are what get counted); the link is kept on the board, never in the fleet, so nothing appears in the Sessions workspace and there is nothing to open — the row is marked `historical: true` in agentistics_task's `sessions`. Filing is a MOVE: one link per conversation, so filing it elsewhere replaces the old link and the answer reports `movedFrom: {taskId, subtaskId?}` (a plain `sessionId` filing reports `movedFrom` too when it displaced another filing). It counts everywhere a live session does (rollups, `subtaskRollups`, the board headline, `done_needs_session`, the group-join rule). Refusals: `no_such_conversation` (422 — the store has no record of that id; nothing to price, so nothing is filed), `conversation_in_fleet` (422 — a registry row already exists; the answer carries its `sessionId`, so call again with that as `sessionId`), plus the same target refusals as a session (`no_such_task`, `no_such_subtask`, `wrong_delivery`, `blocked`, `subtask_in_group`, `leader_only`). Optional `harness` disambiguates and `note` is kept on the link. To remove a historical link pass `detach` with the conversation id (or the row's `hist:<conversationId>` id).",
2377
2407
  inputSchema: {
2378
2408
  type: "object",
2379
2409
  properties: {
@@ -2405,7 +2435,7 @@ var TOOLS = [
2405
2435
  },
2406
2436
  {
2407
2437
  name: "agentistics_task_delete",
2408
- description: "BETA — Agentask (the task board) is new and still changing; its shapes may move between releases. Delete a task and its comments, subtasks, files and links. The SESSIONS filed under it are kept — deleting a board entry never deletes work.",
2438
+ 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.",
2409
2439
  inputSchema: { type: "object", properties: { ref: { type: "string" } }, required: ["ref"] }
2410
2440
  },
2411
2441
  {
@@ -2514,18 +2544,18 @@ var TOOLS = [
2514
2544
  },
2515
2545
  {
2516
2546
  name: "agentistics_session_away",
2517
- description: "Read or switch AWAY MODE, or send the owner a notice while away — the owner is out (asleep, travelling) and the fleet carries on without asking them. With no `on` it reports the state (`active`, `until`, what is pre-authorised). With `on: true` it switches it on: `until` is an ISO instant (omit = until the owner says they are back), `authorised` lists what the owner pre-approved (releases = publish releases the leader approved; workers = open worker sessions within the plan limits; merges = merge PRs the leader reviewed), `note` is free text. `on: false` switches it off. Every session started while it is active is told in its briefing. With `target` (a session's managed id or conversation id) `on` switches THAT session's own away mode instead — it alone is told the owner is out, even with the global switch off, and a running one is told the change; sessions it starts inherit it. Ceilings are per PROVIDER: `topCaps` maps a harness (claude, codex, gemini, copilot, antigravity, kimi, opencode) to how many workers may run on its top model tier at once. Only a LEADER session may switch it; use it when the owner tells you they are leaving or are back.",
2547
+ description: "Read or switch AUTONOMOUS MODE, or send the owner a notice while autonomous — the fleet works on its own, without asking permission or questions (the owner may be asleep or travelling). While it is on, every new session is born in the no-questions approval mode unless its caller names a mode. With no `on` it reports the state (`active`, `until`, what is pre-authorised). With `on: true` it switches it on: `until` is an ISO instant (omit = until the owner says they are back), `authorised` lists what the owner pre-approved (releases = publish releases the leader approved; workers = open worker sessions within the plan limits; merges = merge PRs the leader reviewed), `note` is free text. `on: false` switches it off. Every session started while it is active is told in its briefing. With `target` (a session's managed id or conversation id) `on` switches THAT session's own autonomous mode instead — it alone is told the owner is out, even with the global switch off, and a running one is told the change; sessions it starts inherit it. Ceilings are per PROVIDER: `topCaps` maps a harness (claude, codex, gemini, copilot, antigravity, kimi, opencode) to how many workers may run on its top model tier at once. Only a LEADER session may switch it; use it when the owner tells you they are leaving or are back.",
2518
2548
  inputSchema: {
2519
2549
  type: "object",
2520
2550
  properties: {
2521
- on: { type: "boolean", description: "true = owner away, false = owner back. Omit to read." },
2522
- until: { type: "string", description: "ISO instant the away period ends. Omit for 'until I'm back'." },
2551
+ on: { type: "boolean", description: "true = autonomous mode on, false = off. Omit to read." },
2552
+ until: { type: "string", description: "ISO instant the autonomous period ends. Omit for 'until I turn it off'." },
2523
2553
  authorised: { type: "array", items: { type: "string", enum: ["releases", "workers", "merges"] } },
2524
2554
  note: { type: "string", description: "Free text from the owner (max 500 chars)." },
2525
- maxWorkers: { type: "number", description: "Ceiling of worker sessions at once while away (default 6)." },
2555
+ maxWorkers: { type: "number", description: "Ceiling of worker sessions at once while autonomous (default 6)." },
2526
2556
  topCaps: { type: "object", additionalProperties: { type: "number" }, description: "Per provider (harness id → number): ceiling of workers on that provider's top model tier at once (Opus, top GPT tier, Gemini Pro, …). A provider with no entry gets 2." },
2527
- target: { type: "string", description: "A session's managed id or conversation id: switch only that session's own away mode (with `on`)." },
2528
- notice: { type: "string", description: "While away: a warning or decision that cannot wait, sent to the owner's bell/Nay as a notice (max 500 chars) instead of a question that blocks your turn. Leaders only; ignores the other fields." }
2557
+ target: { type: "string", description: "A session's managed id or conversation id: switch only that session's own autonomous mode (with `on`)." },
2558
+ notice: { type: "string", description: "While autonomous: a warning or decision that cannot wait, sent to the owner's bell/Nay as a notice (max 500 chars) instead of a question that blocks your turn. Leaders only; ignores the other fields." }
2529
2559
  },
2530
2560
  required: []
2531
2561
  }
@@ -2821,6 +2851,7 @@ async function callTool(req) {
2821
2851
  const a = args;
2822
2852
  const body = await apiSend("POST", "/api/flows/run", {
2823
2853
  name: a?.name,
2854
+ session: sessionProof(process.env),
2824
2855
  ...a?.inputs && typeof a.inputs === "object" ? { inputs: a.inputs } : {}
2825
2856
  });
2826
2857
  return text(body);
@@ -2941,6 +2972,10 @@ async function callTool(req) {
2941
2972
  const body = await apiGet(`/api/tasks/activity${q.toString() ? `?${q}` : ""}`);
2942
2973
  return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
2943
2974
  }
2975
+ case "agentistics_live_delivery": {
2976
+ const body = await apiGet(`/api/tasks/live${liveDeliveryQuery(args)}`);
2977
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
2978
+ }
2944
2979
  case "agentistics_task_edit": {
2945
2980
  const a = args;
2946
2981
  const ref = encodeURIComponent(String(a?.ref ?? ""));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentistics/mcp",
3
- "version": "2.199.0",
3
+ "version": "2.200.1",
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",