@freelancercom/phabricator-mcp 2.0.16 → 2.0.17
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/tools/maniphest.js +100 -9
- package/package.json +1 -1
package/dist/tools/maniphest.js
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { jsonCoerce } from './coerce.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve revision identifiers (e.g. "D223125", "PHID-DREV-xxx") to PHIDs.
|
|
5
|
+
* Accepts a mix of D-prefixed IDs and raw PHIDs.
|
|
6
|
+
*/
|
|
7
|
+
async function resolveRevisionPHIDs(client, ids) {
|
|
8
|
+
const phids = [];
|
|
9
|
+
const namesToLookup = [];
|
|
10
|
+
for (const id of ids) {
|
|
11
|
+
if (id.startsWith('PHID-')) {
|
|
12
|
+
phids.push(id);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
// Normalize to D-prefixed format if just a number
|
|
16
|
+
const name = /^\d+$/.test(id) ? `D${id}` : id;
|
|
17
|
+
namesToLookup.push(name);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (namesToLookup.length > 0) {
|
|
21
|
+
const lookupResult = await client.call('phid.lookup', { names: namesToLookup });
|
|
22
|
+
for (const name of namesToLookup) {
|
|
23
|
+
const entry = lookupResult[name];
|
|
24
|
+
if (entry) {
|
|
25
|
+
phids.push(entry.phid);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw new Error(`Could not resolve revision identifier: ${name}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return phids;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Link or unlink revisions to/from a task by calling differential.revision.edit
|
|
36
|
+
* with tasks.add / tasks.remove transactions.
|
|
37
|
+
*/
|
|
38
|
+
async function linkRevisionsToTask(client, taskIdentifier, revisionPHIDs, action) {
|
|
39
|
+
// Resolve the task identifier to a PHID if it's a T-prefixed ID
|
|
40
|
+
let taskPHID = taskIdentifier;
|
|
41
|
+
if (!taskIdentifier.startsWith('PHID-')) {
|
|
42
|
+
const lookupResult = await client.call('phid.lookup', { names: [taskIdentifier] });
|
|
43
|
+
const entry = lookupResult[taskIdentifier];
|
|
44
|
+
if (entry) {
|
|
45
|
+
taskPHID = entry.phid;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
throw new Error(`Could not resolve task identifier: ${taskIdentifier}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const results = [];
|
|
52
|
+
for (const revPHID of revisionPHIDs) {
|
|
53
|
+
const result = await client.call('differential.revision.edit', {
|
|
54
|
+
objectIdentifier: revPHID,
|
|
55
|
+
transactions: [{ type: `tasks.${action}`, value: [taskPHID] }],
|
|
56
|
+
});
|
|
57
|
+
results.push(result);
|
|
58
|
+
}
|
|
59
|
+
return results;
|
|
60
|
+
}
|
|
3
61
|
export function registerManiphestTools(server, client) {
|
|
4
62
|
// Search tasks
|
|
5
63
|
server.tool('phabricator_task_search', 'Search Maniphest tasks with optional filters', {
|
|
@@ -54,7 +112,8 @@ export function registerManiphestTools(server, client) {
|
|
|
54
112
|
subtype: z.string().optional().describe('Task subtype (e.g. "default", "incident")'),
|
|
55
113
|
parentPHIDs: z.array(z.string()).optional().describe('Parent task PHIDs'),
|
|
56
114
|
subtaskPHIDs: z.array(z.string()).optional().describe('Subtask PHIDs'),
|
|
57
|
-
commitPHIDs: z.array(z.string()).optional().describe('Commit PHIDs to associate'),
|
|
115
|
+
commitPHIDs: z.array(z.string()).optional().describe('Commit PHIDs to associate (for actual commits only, not revisions)'),
|
|
116
|
+
revisionIDs: z.array(z.string()).optional().describe('Differential revision IDs to link (e.g. ["D223125"] or ["PHID-DREV-xxx"]). Creates a bidirectional link between the revision and the task.'),
|
|
58
117
|
points: z.coerce.number().nullable().optional().describe('Story points value (if points are enabled on this instance)'),
|
|
59
118
|
space: z.string().optional().describe('Space PHID to place the task in (for multi-space installations)'),
|
|
60
119
|
comment: z.string().optional().describe('Initial comment on the task (supports Remarkup)'),
|
|
@@ -108,6 +167,18 @@ export function registerManiphestTools(server, client) {
|
|
|
108
167
|
}
|
|
109
168
|
}
|
|
110
169
|
const result = await client.call('maniphest.edit', { transactions });
|
|
170
|
+
// Link revisions to the newly created task via differential.revision.edit
|
|
171
|
+
if (params.revisionIDs !== undefined && params.revisionIDs.length > 0) {
|
|
172
|
+
const revPHIDs = await resolveRevisionPHIDs(client, params.revisionIDs);
|
|
173
|
+
const taskId = `T${result.object.id}`;
|
|
174
|
+
const linkResults = await linkRevisionsToTask(client, taskId, revPHIDs, 'add');
|
|
175
|
+
return {
|
|
176
|
+
content: [{
|
|
177
|
+
type: 'text',
|
|
178
|
+
text: JSON.stringify({ ...result, linkedRevisions: linkResults }, null, 2),
|
|
179
|
+
}],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
111
182
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
112
183
|
});
|
|
113
184
|
// Edit task
|
|
@@ -127,8 +198,10 @@ export function registerManiphestTools(server, client) {
|
|
|
127
198
|
removeParentPHIDs: z.array(z.string()).optional().describe('Parent task PHIDs to remove'),
|
|
128
199
|
addSubtaskPHIDs: z.array(z.string()).optional().describe('Subtask PHIDs to add'),
|
|
129
200
|
removeSubtaskPHIDs: z.array(z.string()).optional().describe('Subtask PHIDs to remove'),
|
|
130
|
-
addCommitPHIDs: z.array(z.string()).optional().describe('Commit PHIDs to associate'),
|
|
131
|
-
removeCommitPHIDs: z.array(z.string()).optional().describe('Commit PHIDs to disassociate'),
|
|
201
|
+
addCommitPHIDs: z.array(z.string()).optional().describe('Commit PHIDs to associate (for actual commits only, not revisions)'),
|
|
202
|
+
removeCommitPHIDs: z.array(z.string()).optional().describe('Commit PHIDs to disassociate (for actual commits only, not revisions)'),
|
|
203
|
+
addRevisionIDs: z.array(z.string()).optional().describe('Differential revision IDs to link (e.g. ["D223125"] or ["PHID-DREV-xxx"]). Creates a bidirectional link between the revision and the task.'),
|
|
204
|
+
removeRevisionIDs: z.array(z.string()).optional().describe('Differential revision IDs to unlink (e.g. ["D223125"] or ["PHID-DREV-xxx"]).'),
|
|
132
205
|
points: z.coerce.number().nullable().optional().describe('Story points value (null to clear)'),
|
|
133
206
|
columnPHID: z.string().optional().describe('Move to workboard column'),
|
|
134
207
|
space: z.string().optional().describe('Space PHID to move the task to (for multi-space installations)'),
|
|
@@ -201,14 +274,32 @@ export function registerManiphestTools(server, client) {
|
|
|
201
274
|
transactions.push({ type: key, value });
|
|
202
275
|
}
|
|
203
276
|
}
|
|
204
|
-
|
|
277
|
+
const hasRevisionChanges = (params.addRevisionIDs !== undefined && params.addRevisionIDs.length > 0) ||
|
|
278
|
+
(params.removeRevisionIDs !== undefined && params.removeRevisionIDs.length > 0);
|
|
279
|
+
if (transactions.length === 0 && !hasRevisionChanges) {
|
|
205
280
|
return { content: [{ type: 'text', text: 'No changes specified' }] };
|
|
206
281
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
282
|
+
let result = undefined;
|
|
283
|
+
if (transactions.length > 0) {
|
|
284
|
+
result = await client.call('maniphest.edit', {
|
|
285
|
+
objectIdentifier: params.objectIdentifier,
|
|
286
|
+
transactions,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
// Link/unlink revisions via differential.revision.edit
|
|
290
|
+
const revisionResults = {};
|
|
291
|
+
if (params.addRevisionIDs !== undefined && params.addRevisionIDs.length > 0) {
|
|
292
|
+
const revPHIDs = await resolveRevisionPHIDs(client, params.addRevisionIDs);
|
|
293
|
+
revisionResults.added = await linkRevisionsToTask(client, params.objectIdentifier, revPHIDs, 'add');
|
|
294
|
+
}
|
|
295
|
+
if (params.removeRevisionIDs !== undefined && params.removeRevisionIDs.length > 0) {
|
|
296
|
+
const revPHIDs = await resolveRevisionPHIDs(client, params.removeRevisionIDs);
|
|
297
|
+
revisionResults.removed = await linkRevisionsToTask(client, params.objectIdentifier, revPHIDs, 'remove');
|
|
298
|
+
}
|
|
299
|
+
const output = hasRevisionChanges
|
|
300
|
+
? { ...(result !== undefined ? { task: result } : {}), linkedRevisions: revisionResults }
|
|
301
|
+
: result;
|
|
302
|
+
return { content: [{ type: 'text', text: JSON.stringify(output, null, 2) }] };
|
|
212
303
|
});
|
|
213
304
|
// Add comment to task
|
|
214
305
|
server.tool('phabricator_task_add_comment', 'Add a comment to a Maniphest task', {
|
package/package.json
CHANGED