@k-system/tickr-mcp 1.20.0 → 1.21.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.
@@ -0,0 +1,9 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ApiClient } from "../api-client.js";
3
+ /**
4
+ * Dynamic resource tickr://pending-tasks
5
+ * Vrací aktuální stav dev queue — počet čekajících tasků a detail dalšího v řadě.
6
+ * Aktualizuje se přes sendResourceListChanged() při DevTaskQueued eventu.
7
+ */
8
+ export declare function registerPendingTasksResource(server: McpServer, api: ApiClient): void;
9
+ //# sourceMappingURL=pending-tasks-resource.d.ts.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Dynamic resource tickr://pending-tasks
3
+ * Vrací aktuální stav dev queue — počet čekajících tasků a detail dalšího v řadě.
4
+ * Aktualizuje se přes sendResourceListChanged() při DevTaskQueued eventu.
5
+ */
6
+ export function registerPendingTasksResource(server, api) {
7
+ server.resource("pending-tasks", "tickr://pending-tasks", { description: "Current dev queue status — queued task count and next task preview" }, async (uri) => {
8
+ // Heartbeat vrací počet queued tasků bez side-effectu na assignment
9
+ const heartbeat = await api
10
+ .post("/api/dev-queue/heartbeat", {})
11
+ .catch(() => null);
12
+ const queuedTasks = heartbeat?.queuedTasks ?? 0;
13
+ const agentStatus = heartbeat?.agentStatus ?? "unknown";
14
+ let text = `## Dev Queue Status\n`;
15
+ text += `- **Agent Status:** ${agentStatus}\n`;
16
+ text += `- **Queued Tasks:** ${queuedTasks}\n`;
17
+ if (queuedTasks > 0) {
18
+ text += `\n⚠️ There are ${queuedTasks} task(s) waiting. Run \`poll_dev_queue\` to pick up the next one.\n`;
19
+ }
20
+ else {
21
+ text += `\n✅ Queue is empty — no pending tasks.\n`;
22
+ }
23
+ return {
24
+ contents: [
25
+ {
26
+ uri: uri.href,
27
+ mimeType: "text/markdown",
28
+ text,
29
+ },
30
+ ],
31
+ };
32
+ });
33
+ }
34
+ //# sourceMappingURL=pending-tasks-resource.js.map
package/dist/server.js CHANGED
@@ -90,6 +90,7 @@ import { registerLinkCommit } from "./tools/link-commit.js";
90
90
  // Resources
91
91
  import { registerTicketResource } from "./resources/ticket-resource.js";
92
92
  import { registerProjectResource } from "./resources/project-resource.js";
93
+ import { registerPendingTasksResource } from "./resources/pending-tasks-resource.js";
93
94
  // SignalR push notifications
94
95
  import { initSignalRClient, stopSignalRClient } from "./signalr-client.js";
95
96
  export async function startServer() {
@@ -97,7 +98,7 @@ export async function startServer() {
97
98
  const api = new ApiClient(config);
98
99
  const server = new McpServer({
99
100
  name: "tickr",
100
- version: "0.1.8",
101
+ version: "0.1.9",
101
102
  });
102
103
  // Debug logging wrapper (dedup odstraněn — nefunkční cross-process, řeší se na API straně: TKR-ADR-0043)
103
104
  {
@@ -212,14 +213,22 @@ export async function startServer() {
212
213
  // Registrace resources
213
214
  registerTicketResource(server, api);
214
215
  registerProjectResource(server, api);
216
+ registerPendingTasksResource(server, api);
215
217
  // Spuštění na stdio transportu
216
218
  const transport = new StdioServerTransport();
217
219
  await server.connect(transport);
218
220
  // SignalR push notifications — pripojeni na BoardHub pro real-time eventy
219
221
  // Neni kriticke — MCP server funguje i bez SignalR
220
222
  initSignalRClient(config, server, config.defaultProject).catch(() => { });
223
+ // Initial heartbeat — nastav agenta jako idle
224
+ api.post("/api/dev-queue/heartbeat", {}).catch(() => { });
225
+ // Periodicky heartbeat kazdych 60 sekund — udržuje agent status + snižuje latenci task discovery
226
+ const heartbeatInterval = setInterval(() => {
227
+ api.post("/api/dev-queue/heartbeat", {}).catch(() => { });
228
+ }, 60_000);
221
229
  // Cleanup pri ukonceni procesu
222
230
  const cleanup = async () => {
231
+ clearInterval(heartbeatInterval);
223
232
  await stopSignalRClient();
224
233
  process.exit(0);
225
234
  };
@@ -19,8 +19,13 @@ export async function initSignalRClient(config, server, projectSlug) {
19
19
  .withAutomaticReconnect([0, 2000, 5000, 10000, 30000])
20
20
  .configureLogging(LogLevel.None)
21
21
  .build();
22
- // Event handlery — notifikace do MCP session
22
+ // Event handlery — resource update + logging notifikace do MCP session
23
23
  connection.on("DevTaskQueued", () => {
24
+ // Aktualizuj tickr://pending-tasks resource — agent uvidí změnu při dalším tool callu
25
+ try {
26
+ server.sendResourceListChanged();
27
+ }
28
+ catch { }
24
29
  server
25
30
  .sendLoggingMessage({
26
31
  level: "notice",
@@ -30,6 +35,10 @@ export async function initSignalRClient(config, server, projectSlug) {
30
35
  .catch(() => { });
31
36
  });
32
37
  connection.on("DevTaskCompleted", () => {
38
+ try {
39
+ server.sendResourceListChanged();
40
+ }
41
+ catch { }
33
42
  server
34
43
  .sendLoggingMessage({
35
44
  level: "info",
@@ -39,6 +48,10 @@ export async function initSignalRClient(config, server, projectSlug) {
39
48
  .catch(() => { });
40
49
  });
41
50
  connection.on("TicketUpdated", () => {
51
+ try {
52
+ server.sendResourceListChanged();
53
+ }
54
+ catch { }
42
55
  server
43
56
  .sendLoggingMessage({
44
57
  level: "debug",
@@ -48,6 +61,10 @@ export async function initSignalRClient(config, server, projectSlug) {
48
61
  .catch(() => { });
49
62
  });
50
63
  connection.on("TicketCreated", () => {
64
+ try {
65
+ server.sendResourceListChanged();
66
+ }
67
+ catch { }
51
68
  server
52
69
  .sendLoggingMessage({
53
70
  level: "debug",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k-system/tickr-mcp",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "description": "MCP server for Tickr project management — 56 tools + setup CLI wizard",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",