@taiga-ai/mcp-server 0.25.0-dev.468 → 0.25.0-dev.469

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/index.js CHANGED
@@ -5227,7 +5227,8 @@ const SETUP_TASK_FIELDS = [
5227
5227
  "providerActionUrl",
5228
5228
  "inboxItemId",
5229
5229
  "inboxItemStatus",
5230
- "createdAt"
5230
+ "createdAt",
5231
+ "stale"
5231
5232
  ];
5232
5233
  /** The API's count across every page, on the first page; nothing from an API that does not send one. */
5233
5234
  function totalOf(result) {
@@ -5267,7 +5268,10 @@ function sameKeyOnce(rows) {
5267
5268
  const { alsoFiledAs: _also, ...was } = kept;
5268
5269
  for (const field of Object.keys(kept)) delete kept[field];
5269
5270
  Object.assign(kept, row, { alsoFiledAs: [...also, record(was)] });
5270
- } else kept["alsoFiledAs"] = [...also, record(row)];
5271
+ } else {
5272
+ kept["alsoFiledAs"] = [...also, record(row)];
5273
+ if (isOpen(row) && row["stale"] === void 0) delete kept["stale"];
5274
+ }
5271
5275
  }
5272
5276
  return out;
5273
5277
  }
@@ -5342,7 +5346,7 @@ function registerInboxTools(server, client) {
5342
5346
  }));
5343
5347
  server.registerTool("taiga_list_setup_tasks", {
5344
5348
  title: "List setup tasks",
5345
- description: "List what a person must set up for a product (secrets, variables, accounts), with exactly what and where: key (the name to create; Taiga never stores values), the provider page, and phase: prereq (the deploy fails without it), wiring (generated values back to providers) or followup (can wait until after launch). Runs do not wait for them. One product or all, oldest first; includeDone: true adds done and dismissed. A variable filed twice lists the others under alsoFiledAs; totalCount counts records, and a page that folded some says recordsOnPage. Unlike taiga_list_action_required, which lists the same work as items to resolve.",
5349
+ description: "List what a person must set up for a product (secrets, variables, accounts), with exactly what and where: key (the name to create; Taiga never stores values), the provider page, and phase: prereq (the deploy fails without it), wiring (generated values back to providers) or followup (can wait until after launch). Runs do not wait for them. One product or all, oldest first; includeDone: true adds done and dismissed. A variable filed twice lists the others under alsoFiledAs; totalCount counts records, and a page that folded some says recordsOnPage. stale on an open task says no document derived from the code since it was raised mentions its key: it may not apply any more, so check before asking anyone to set it. Unlike taiga_list_action_required, which lists the same work as items to resolve.",
5346
5350
  inputSchema: z.object({
5347
5351
  productId: productId.optional(),
5348
5352
  includeDone: z.boolean().optional().describe("Also the tasks already done or dismissed (default false)"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taiga-ai/mcp-server",
3
- "version": "0.25.0-dev.468",
3
+ "version": "0.25.0-dev.469",
4
4
  "description": "MCP server for Taiga -- gives AI assistants access to documents and products",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -6856,6 +6856,52 @@ describe('what the second agent review found (PRO-2778, PRO-2780)', () => {
6856
6856
  expect(sentUrl(fetchSpy, '/v1/inbox').searchParams.has('withTotal')).toBe(false);
6857
6857
  });
6858
6858
 
6859
+ it("passes on a setup task's stale note (PRO-2819)", async () => {
6860
+ const stale = "None of the current code's documents, derived since this task was raised, mention JWT_SECRET.";
6861
+ const { client } = await bootMcpPair({
6862
+ capabilities: ALL_CAPABILITIES,
6863
+ routes: {
6864
+ 'GET /v1/setup-tasks': {
6865
+ data: [
6866
+ {
6867
+ id: ENV_ID,
6868
+ productId: ENV_ID,
6869
+ key: 'JWT_SECRET',
6870
+ inboxItemStatus: 'open',
6871
+ title: 'Set JWT_SECRET',
6872
+ stale,
6873
+ },
6874
+ ],
6875
+ nextCursor: null,
6876
+ },
6877
+ },
6878
+ });
6879
+
6880
+ const tasks = parseToolResult(await client.callTool({ name: 'taiga_list_setup_tasks', arguments: {} }));
6881
+ expect(tasks.data[0].stale).toBe(stale);
6882
+ });
6883
+
6884
+ it('drops the stale note from a folded variable when one open record of it is live (PRO-2819)', async () => {
6885
+ const stale = "None of the current code's documents, derived since this task was raised, mention JWT_SECRET.";
6886
+ const record = { productId: ENV_ID, key: 'JWT_SECRET', inboxItemStatus: 'open' };
6887
+ const { client } = await bootMcpPair({
6888
+ capabilities: ALL_CAPABILITIES,
6889
+ routes: {
6890
+ 'GET /v1/setup-tasks': {
6891
+ data: [
6892
+ { ...record, id: 'old', category: 'secret', title: 'Set JWT_SECRET', stale },
6893
+ { ...record, id: 'new', category: 'env_var', title: 'Set JWT_SECRET' },
6894
+ ],
6895
+ nextCursor: null,
6896
+ },
6897
+ },
6898
+ });
6899
+
6900
+ const tasks = parseToolResult(await client.callTool({ name: 'taiga_list_setup_tasks', arguments: {} }));
6901
+ expect(tasks.data).toHaveLength(1);
6902
+ expect(tasks.data[0].stale).toBeUndefined();
6903
+ });
6904
+
6859
6905
  it('carries who cancelled a failed plan and when, and leaves the item as it was when the history is refused', async () => {
6860
6906
  const failed = { id: ITEM_ID, title: 'Login', planningStatus: 'failed', planFailureCause: 'cancelled' };
6861
6907
  const history = {
@@ -306,6 +306,7 @@ const SETUP_TASK_FIELDS = [
306
306
  'inboxItemId',
307
307
  'inboxItemStatus',
308
308
  'createdAt',
309
+ 'stale',
309
310
  ] as const;
310
311
 
311
312
  /** The API's count across every page, on the first page; nothing from an API that does not send one. */
@@ -350,6 +351,9 @@ export function sameKeyOnce(rows: Row[]): Row[] {
350
351
  Object.assign(kept, row, { alsoFiledAs: [...also, record(was)] });
351
352
  } else {
352
353
  kept['alsoFiledAs'] = [...also, record(row)];
354
+ // Stale only while every open record is (PRO-2819): one raised after the code's documents were derived
355
+ // is a live ask, whichever record leads.
356
+ if (isOpen(row) && row['stale'] === undefined) delete kept['stale'];
353
357
  }
354
358
  }
355
359
  return out;
@@ -471,7 +475,9 @@ export function registerInboxTools(server: McpServer, client: TaigaClient) {
471
475
  'deploy fails without it), wiring (generated values back to providers) or followup (can wait until after ' +
472
476
  'launch). Runs do not wait for them. One product or all, oldest first; includeDone: true adds done and ' +
473
477
  'dismissed. A variable filed twice lists the others under alsoFiledAs; totalCount counts records, and a ' +
474
- 'page that folded some says recordsOnPage. Unlike ' +
478
+ 'page that folded some says recordsOnPage. stale on an open task says no document derived from the code ' +
479
+ 'since it was raised mentions its key: it may not apply any more, so check before asking anyone to set ' +
480
+ 'it. Unlike ' +
475
481
  'taiga_list_action_required, which lists the same work as items to resolve.',
476
482
  inputSchema: z.object({
477
483
  productId: productId.optional(),