@taiga-ai/mcp-server 0.25.0-dev.467 → 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
|
@@ -4892,7 +4892,7 @@ function registerMaintenanceTools(server, client) {
|
|
|
4892
4892
|
}));
|
|
4893
4893
|
server.registerTool("taiga_get_policy_standing", {
|
|
4894
4894
|
title: "Get a product's policy standing",
|
|
4895
|
-
description: "How a product stands against the organization's published policies: summary counts, when the documents were assessed, and each violated control with its violations (critical and high only, citing the policy sentence and the contradicting passage) and the work on each. state: breached (open scanner findings map to it, by findingsByTier; routine-only is not urgent) or diverged (the documents contradict it). live: false means the violation's initiative ended without fixing it: it needs a person or a new fix. An unlisted control is not \"passing\" (summary.controlsWithNothingRecorded counts them). full: true adds evidence and resolved ones. Fix with taiga_fix_policy_violation.",
|
|
4895
|
+
description: "How a product stands against the organization's published policies: summary counts, when the documents were assessed, and each violated control with its violations (critical and high only, citing the policy sentence and the contradicting passage) and the work on each. state: breached (open scanner findings map to it, by findingsByTier; routine-only is not urgent) or diverged (the documents contradict it). live: false means the violation's initiative ended without fixing it: it needs a person or a new fix. raisedFor: false means the link is the backlog planner's: it said an initiative a person asked it for would close the violation, which may be a dedicated fix or broader work; true means a fix was raised for it (taiga_fix_policy_violation or the sweep). An unlisted control is not \"passing\" (summary.controlsWithNothingRecorded counts them). full: true adds evidence and resolved ones. Fix with taiga_fix_policy_violation.",
|
|
4896
4896
|
inputSchema: z.object({
|
|
4897
4897
|
productId,
|
|
4898
4898
|
full: z.boolean().optional().describe("Carry each violation's evidence and policy excerpt, cut to about 1,500 characters each, and up to 20 resolved violations (default false)"),
|
|
@@ -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
|
|
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
|
@@ -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 = {
|
package/src/tools/inbox.ts
CHANGED
|
@@ -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.
|
|
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(),
|
package/src/tools/maintenance.ts
CHANGED
|
@@ -311,6 +311,9 @@ export function registerMaintenanceTools(server: McpServer, client: TaigaClient)
|
|
|
311
311
|
'sentence and the contradicting passage) and the work on each. state: breached (open scanner findings ' +
|
|
312
312
|
'map to it, by findingsByTier; routine-only is not urgent) or diverged (the documents contradict it). ' +
|
|
313
313
|
"live: false means the violation's initiative ended without fixing it: it needs a person or a new fix. " +
|
|
314
|
+
"raisedFor: false means the link is the backlog planner's: it said an initiative a person asked it for " +
|
|
315
|
+
'would close the violation, which may be a dedicated fix or broader work; true means a fix was raised ' +
|
|
316
|
+
'for it (taiga_fix_policy_violation or the sweep). ' +
|
|
314
317
|
'An unlisted control is not "passing" (summary.controlsWithNothingRecorded counts them). full: true adds ' +
|
|
315
318
|
'evidence and resolved ones. Fix with taiga_fix_policy_violation.',
|
|
316
319
|
inputSchema: z.object({
|
|
Binary file
|
|
Binary file
|