@rockhopper-co/mcp-server 2.1.82-staging.65cfbf4 → 2.1.84-staging.bac34fe
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/CHANGELOG.md +10 -0
- package/dist/account-link-providers.d.ts +42 -0
- package/dist/account-link-providers.d.ts.map +1 -0
- package/dist/account-link-providers.js +47 -0
- package/dist/account-link-providers.js.map +1 -0
- package/dist/api-client.d.ts +16 -1
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +26 -1
- package/dist/api-client.js.map +1 -1
- package/dist/cell-history-unavailable.d.ts +7 -0
- package/dist/cell-history-unavailable.d.ts.map +1 -1
- package/dist/cell-history-unavailable.js +28 -0
- package/dist/cell-history-unavailable.js.map +1 -1
- package/dist/comment-location.d.ts +18 -0
- package/dist/comment-location.d.ts.map +1 -0
- package/dist/comment-location.js +29 -0
- package/dist/comment-location.js.map +1 -0
- package/dist/document-changes.d.ts +11 -1
- package/dist/document-changes.d.ts.map +1 -1
- package/dist/document-changes.js +1 -1
- package/dist/document-changes.js.map +1 -1
- package/dist/drive-search.d.ts +4 -3
- package/dist/drive-search.d.ts.map +1 -1
- package/dist/drive-search.js +7 -7
- package/dist/drive-search.js.map +1 -1
- package/dist/file-changes.d.ts +52 -0
- package/dist/file-changes.d.ts.map +1 -0
- package/dist/file-changes.js +82 -0
- package/dist/file-changes.js.map +1 -0
- package/dist/prompts/change-sections.d.ts +11 -0
- package/dist/prompts/change-sections.d.ts.map +1 -0
- package/dist/prompts/change-sections.js +47 -0
- package/dist/prompts/change-sections.js.map +1 -0
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +18 -34
- package/dist/prompts/index.js.map +1 -1
- package/dist/resources/changes.d.ts.map +1 -1
- package/dist/resources/changes.js +19 -10
- package/dist/resources/changes.js.map +1 -1
- package/dist/resources/orchestration-guide.md +1 -1
- package/dist/tools/{connect-microsoft.d.ts → account-link.d.ts} +9 -3
- package/dist/tools/account-link.d.ts.map +1 -0
- package/dist/tools/account-link.js +155 -0
- package/dist/tools/account-link.js.map +1 -0
- package/dist/tools/anchor-history-read.d.ts +25 -0
- package/dist/tools/anchor-history-read.d.ts.map +1 -0
- package/dist/tools/anchor-history-read.js +73 -0
- package/dist/tools/anchor-history-read.js.map +1 -0
- package/dist/tools/drive-search.contract.d.ts +7 -2
- package/dist/tools/drive-search.contract.d.ts.map +1 -1
- package/dist/tools/drive-search.contract.js +15 -7
- package/dist/tools/drive-search.contract.js.map +1 -1
- package/dist/tools/drive-search.d.ts.map +1 -1
- package/dist/tools/drive-search.js +16 -17
- package/dist/tools/drive-search.js.map +1 -1
- package/dist/tools/get-cell-history.d.ts +15 -0
- package/dist/tools/get-cell-history.d.ts.map +1 -1
- package/dist/tools/get-cell-history.js +67 -18
- package/dist/tools/get-cell-history.js.map +1 -1
- package/dist/tools/get-comments.d.ts.map +1 -1
- package/dist/tools/get-comments.js +2 -1
- package/dist/tools/get-comments.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list-unenrolled-files.d.ts.map +1 -1
- package/dist/tools/list-unenrolled-files.js +18 -178
- package/dist/tools/list-unenrolled-files.js.map +1 -1
- package/dist/tools/list-unenrolled-render.d.ts +4 -0
- package/dist/tools/list-unenrolled-render.d.ts.map +1 -0
- package/dist/tools/list-unenrolled-render.js +219 -0
- package/dist/tools/list-unenrolled-render.js.map +1 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +27 -57
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/write-comments.d.ts.map +1 -1
- package/dist/tools/write-comments.js +58 -2
- package/dist/tools/write-comments.js.map +1 -1
- package/dist/types.d.ts +79 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/zod-schemas.d.ts +57 -0
- package/dist/zod-schemas.d.ts.map +1 -1
- package/dist/zod-schemas.js +24 -1
- package/dist/zod-schemas.js.map +1 -1
- package/package.json +1 -1
- package/dist/tools/connect-microsoft.d.ts.map +0 -1
- package/dist/tools/connect-microsoft.js +0 -149
- package/dist/tools/connect-microsoft.js.map +0 -1
- package/dist/tools/document-changes-read.d.ts +0 -28
- package/dist/tools/document-changes-read.d.ts.map +0 -1
- package/dist/tools/document-changes-read.js +0 -34
- package/dist/tools/document-changes-read.js.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ApiClient } from './api-client.js';
|
|
2
|
+
import { type DocumentChangesUnavailableReason } from './document-changes.js';
|
|
3
|
+
import type { DocumentChangesResponse, EnrolledFile, PaginatedUnattributedResponse, UnattributedChange } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* ENG-6431 — THE change read, returned as DATA, for every surface that reports
|
|
6
|
+
* a file's changes since its last saved version.
|
|
7
|
+
*
|
|
8
|
+
* ENG-5397 wrote this dispatch inline in `get_unattributed_changes`, and the
|
|
9
|
+
* `…/changes` resource and the `summarize-file-changes` / `file-overview`
|
|
10
|
+
* prompts kept calling the spreadsheet-only lane for every file type — so a
|
|
11
|
+
* `.docx`, `.pptx`, Google Doc or Google Slides file read `totalCount: 0` there
|
|
12
|
+
* by construction. Every surface now calls this one function and does only its
|
|
13
|
+
* own formatting.
|
|
14
|
+
*
|
|
15
|
+
* EVERY EXIT IS REAL ROWS OR A NAMED REFUSAL. A withheld document window is
|
|
16
|
+
* `unavailable`, never a served empty one — the backend's DTO says a client
|
|
17
|
+
* MUST render the two differently. Not-ready states still THROW
|
|
18
|
+
* (`ChangeHistoryNotReadyError`), exactly as before.
|
|
19
|
+
*/
|
|
20
|
+
export type FileChangesRead = {
|
|
21
|
+
kind: 'spreadsheet';
|
|
22
|
+
file: EnrolledFile;
|
|
23
|
+
page: PaginatedUnattributedResponse;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'spreadsheet_sheet';
|
|
26
|
+
file: EnrolledFile;
|
|
27
|
+
sheetName: string;
|
|
28
|
+
changes: UnattributedChange[];
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'document';
|
|
31
|
+
file: EnrolledFile;
|
|
32
|
+
response: DocumentChangesResponse;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'unavailable';
|
|
35
|
+
file: EnrolledFile;
|
|
36
|
+
fileMsId: string;
|
|
37
|
+
reason: DocumentChangesUnavailableReason;
|
|
38
|
+
declineReason: string | null;
|
|
39
|
+
};
|
|
40
|
+
export declare function readFileChanges(api: ApiClient, fileMsId: string, opts?: {
|
|
41
|
+
sheetName?: string;
|
|
42
|
+
cursor?: string;
|
|
43
|
+
}): Promise<FileChangesRead>;
|
|
44
|
+
/**
|
|
45
|
+
* The refusal as the text every surface shows. A tool returns it as an
|
|
46
|
+
* `isError` result; a prompt embeds it; a resource, which has no `isError`
|
|
47
|
+
* channel, throws it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function fileChangesUnavailableText(read: Extract<FileChangesRead, {
|
|
50
|
+
kind: 'unavailable';
|
|
51
|
+
}>): string;
|
|
52
|
+
//# sourceMappingURL=file-changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-changes.d.ts","sourceRoot":"","sources":["../src/file-changes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAKjD,OAAO,EAGL,KAAK,gCAAgC,EACtC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,uBAAuB,EACvB,YAAY,EACZ,6BAA6B,EAC7B,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,6BAA6B,CAAA;CAAE,GAChF;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B,GACD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,uBAAuB,CAAA;CAAE,GAC3E;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,gCAAgC,CAAC;IACzC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,CAAC;AAEN,wBAAsB,eAAe,CACnC,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,eAAe,CAAC,CAsE1B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,GACtD,MAAM,CAOR"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { assertChangeHistoryComplete, assertEnrollmentComplete, } from './not-ready.js';
|
|
2
|
+
import { changeModelForFileType, documentChangesUnavailableToolResult, } from './document-changes.js';
|
|
3
|
+
import { assertSheetExists } from './sheet-catalogue.js';
|
|
4
|
+
export async function readFileChanges(api, fileMsId, opts = {}) {
|
|
5
|
+
const file = await api.getEnrolledFile(fileMsId);
|
|
6
|
+
const model = changeModelForFileType(file.fileType);
|
|
7
|
+
if (model === null) {
|
|
8
|
+
return {
|
|
9
|
+
kind: 'unavailable',
|
|
10
|
+
file,
|
|
11
|
+
fileMsId,
|
|
12
|
+
reason: 'unknown_file_type',
|
|
13
|
+
declineReason: null,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (model !== 'spreadsheet') {
|
|
17
|
+
// A worksheet filter over a file with no worksheets. Refusing beats
|
|
18
|
+
// quietly dropping it: the caller would otherwise be handed the WHOLE
|
|
19
|
+
// file's changes believing they were one sheet's.
|
|
20
|
+
if (opts.sheetName) {
|
|
21
|
+
return {
|
|
22
|
+
kind: 'unavailable',
|
|
23
|
+
file,
|
|
24
|
+
fileMsId,
|
|
25
|
+
reason: 'sheet_filter_not_applicable',
|
|
26
|
+
declineReason: null,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// ENG-2824 — a file whose first read has not landed has no versions, and
|
|
30
|
+
// an empty window over it is a premature absence.
|
|
31
|
+
assertEnrollmentComplete(fileMsId, await api.getFileVersions(fileMsId));
|
|
32
|
+
const response = await api.getDocumentChanges(fileMsId);
|
|
33
|
+
if (response.declineReason !== null) {
|
|
34
|
+
return {
|
|
35
|
+
kind: 'unavailable',
|
|
36
|
+
file,
|
|
37
|
+
fileMsId,
|
|
38
|
+
reason: 'window_withheld',
|
|
39
|
+
declineReason: response.declineReason,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return { kind: 'document', file, response };
|
|
43
|
+
}
|
|
44
|
+
// Plan 02 ruling 5 (STRICT): gate BOTH spreadsheet modes. The commit-diff
|
|
45
|
+
// fold retracts and rewrites the uncommitted window, so a pending fold means
|
|
46
|
+
// this list is mid-rewrite in either shape.
|
|
47
|
+
await assertChangeHistoryComplete(api, fileMsId);
|
|
48
|
+
if (opts.sheetName) {
|
|
49
|
+
const changes = await api.getUnattributedChangesBySheet(fileMsId, opts.sheetName);
|
|
50
|
+
// ENG-2824 / ENG-4347 — only an empty answer is ambiguous, so only it pays
|
|
51
|
+
// for the version read and then the sheet-existence check, in that order.
|
|
52
|
+
if (changes.length === 0) {
|
|
53
|
+
assertEnrollmentComplete(fileMsId, await api.getFileVersions(fileMsId));
|
|
54
|
+
await assertSheetExists(api, file, opts.sheetName);
|
|
55
|
+
}
|
|
56
|
+
return { kind: 'spreadsheet_sheet', file, sheetName: opts.sheetName, changes };
|
|
57
|
+
}
|
|
58
|
+
// ENG-4346 — `totalCount` is a FILE total only when no cursor is passed.
|
|
59
|
+
// Pass `cursor` through only when the caller supplied the key (the tool
|
|
60
|
+
// does, possibly as undefined); the resource and prompts never page.
|
|
61
|
+
const page = 'cursor' in opts
|
|
62
|
+
? await api.getUnattributedChangesPaginated(fileMsId, opts.cursor)
|
|
63
|
+
: await api.getUnattributedChangesPaginated(fileMsId);
|
|
64
|
+
if (page.changes.length === 0 && page.totalCount === 0) {
|
|
65
|
+
assertEnrollmentComplete(fileMsId, await api.getFileVersions(fileMsId));
|
|
66
|
+
}
|
|
67
|
+
return { kind: 'spreadsheet', file, page };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* The refusal as the text every surface shows. A tool returns it as an
|
|
71
|
+
* `isError` result; a prompt embeds it; a resource, which has no `isError`
|
|
72
|
+
* channel, throws it.
|
|
73
|
+
*/
|
|
74
|
+
export function fileChangesUnavailableText(read) {
|
|
75
|
+
return documentChangesUnavailableToolResult({
|
|
76
|
+
reason: read.reason,
|
|
77
|
+
fileMsId: read.fileMsId,
|
|
78
|
+
fileName: read.file.name,
|
|
79
|
+
declineReason: read.declineReason,
|
|
80
|
+
}).content[0].text;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=file-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-changes.js","sourceRoot":"","sources":["../src/file-changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FileChangesRead } from '../file-changes.js';
|
|
2
|
+
/**
|
|
3
|
+
* ENG-6431 — the prompts' own formatting of the shared change read. Documents
|
|
4
|
+
* reuse `formatDocumentChanges` (no second summariser); a refusal reuses the
|
|
5
|
+
* tool's refusal text, so a withheld window is NAMED and never rendered as 0.
|
|
6
|
+
*/
|
|
7
|
+
/** The `## Unattributed Changes …` section of `summarize-file-changes`. */
|
|
8
|
+
export declare function changeSummarySection(read: FileChangesRead): string;
|
|
9
|
+
/** The single-line change count of `file-overview`. */
|
|
10
|
+
export declare function changeCountLine(read: FileChangesRead): string;
|
|
11
|
+
//# sourceMappingURL=change-sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-sections.d.ts","sourceRoot":"","sources":["../../src/prompts/change-sections.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AAEH,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAwBlE;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAc7D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { formatDocumentChanges } from '../document-changes.js';
|
|
2
|
+
import { fileChangesUnavailableText, } from '../file-changes.js';
|
|
3
|
+
/**
|
|
4
|
+
* ENG-6431 — the prompts' own formatting of the shared change read. Documents
|
|
5
|
+
* reuse `formatDocumentChanges` (no second summariser); a refusal reuses the
|
|
6
|
+
* tool's refusal text, so a withheld window is NAMED and never rendered as 0.
|
|
7
|
+
*/
|
|
8
|
+
/** The `## Unattributed Changes …` section of `summarize-file-changes`. */
|
|
9
|
+
export function changeSummarySection(read) {
|
|
10
|
+
switch (read.kind) {
|
|
11
|
+
case 'unavailable':
|
|
12
|
+
return `## Unattributed Changes: unavailable\n${fileChangesUnavailableText(read)}`;
|
|
13
|
+
case 'document':
|
|
14
|
+
return `## Unattributed Changes\n${formatDocumentChanges(read.response, read.file.name)}`;
|
|
15
|
+
case 'spreadsheet_sheet':
|
|
16
|
+
case 'spreadsheet': {
|
|
17
|
+
// KI-097 / ENG-4346 — the prompt reads the UNSCOPED first page, so
|
|
18
|
+
// `totalCount` is a file total; the preview uses up to 20 rows of it.
|
|
19
|
+
const rows = read.kind === 'spreadsheet' ? read.page.changes : read.changes;
|
|
20
|
+
const total = read.kind === 'spreadsheet' ? read.page.totalCount : rows.length;
|
|
21
|
+
const body = rows.length
|
|
22
|
+
? rows
|
|
23
|
+
.slice(0, 20)
|
|
24
|
+
.map((c) => `- ${c.sheetName}!${c.cellAddress}: ${JSON.stringify(c.oldValue)} → ${JSON.stringify(c.newValue)}`)
|
|
25
|
+
.join('\n')
|
|
26
|
+
: 'None';
|
|
27
|
+
return `## Unattributed Changes (${total} total)\n${body}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** The single-line change count of `file-overview`. */
|
|
32
|
+
export function changeCountLine(read) {
|
|
33
|
+
switch (read.kind) {
|
|
34
|
+
case 'unavailable':
|
|
35
|
+
return `## Unattributed Changes: unavailable\n${fileChangesUnavailableText(read)}`;
|
|
36
|
+
case 'document':
|
|
37
|
+
// A truncated window is a LOWER bound, and says so.
|
|
38
|
+
return read.response.truncated
|
|
39
|
+
? `## Unattributed Changes: more than ${read.response.rows.length}`
|
|
40
|
+
: `## Unattributed Changes: ${read.response.rows.length}`;
|
|
41
|
+
case 'spreadsheet':
|
|
42
|
+
return `## Unattributed Changes: ${read.page.totalCount}`;
|
|
43
|
+
case 'spreadsheet_sheet':
|
|
44
|
+
return `## Unattributed Changes: ${read.changes.length}`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=change-sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-sections.js","sourceRoot":"","sources":["../../src/prompts/change-sections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EACL,0BAA0B,GAE3B,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AAEH,2EAA2E;AAC3E,MAAM,UAAU,oBAAoB,CAAC,IAAqB;IACxD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,aAAa;YAChB,OAAO,yCAAyC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;QACrF,KAAK,UAAU;YACb,OAAO,4BAA4B,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5F,KAAK,mBAAmB,CAAC;QACzB,KAAK,aAAa,CAAC,CAAC,CAAC;YACnB,mEAAmE;YACnE,sEAAsE;YACtE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;YAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM;gBACtB,CAAC,CAAC,IAAI;qBACD,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;qBACZ,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,KAAK,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CACrG;qBACA,IAAI,CAAC,IAAI,CAAC;gBACf,CAAC,CAAC,MAAM,CAAC;YACX,OAAO,4BAA4B,KAAK,YAAY,IAAI,EAAE,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,aAAa;YAChB,OAAO,yCAAyC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;QACrF,KAAK,UAAU;YACb,oDAAoD;YACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS;gBAC5B,CAAC,CAAC,sCAAsC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE;gBACnE,CAAC,CAAC,4BAA4B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC9D,KAAK,aAAa;YAChB,OAAO,4BAA4B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAC5D,KAAK,mBAAmB;YACtB,OAAO,4BAA4B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQlD,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAmNvE"}
|
package/dist/prompts/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { readFileChanges } from '../file-changes.js';
|
|
3
|
+
import { changeCountLine, changeSummarySection } from './change-sections.js';
|
|
3
4
|
import { renderMentions } from '../mentions.js';
|
|
5
|
+
import { commentLocation } from '../comment-location.js';
|
|
4
6
|
import { formatVersion } from '../version-format.js';
|
|
5
7
|
import { displayUserName } from '../user-display-name.js';
|
|
6
8
|
export function registerPrompts(server, api) {
|
|
@@ -12,30 +14,17 @@ export function registerPrompts(server, api) {
|
|
|
12
14
|
}),
|
|
13
15
|
}, async ({ fileMsId }) => {
|
|
14
16
|
// Plan 02 ruling 5 (STRICT) — a prompt is the highest-risk surface: its
|
|
15
|
-
// whole product is a model narrating these rows as fact.
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// uses `totalCount` for the full file count; the per-cell preview
|
|
23
|
-
// uses up to 20 rows from this first page (sufficient for a recap).
|
|
24
|
-
// ENG-4346 - `totalCount` counts rows remaining from the cursor
|
|
25
|
-
// onward, so it is a FILE total only on this unscoped read. Passing a
|
|
26
|
-
// cursor here would make the "total" label below false.
|
|
27
|
-
api.getUnattributedChangesPaginated(fileMsId),
|
|
28
|
-
]);
|
|
17
|
+
// whole product is a model narrating these rows as fact. The shared read
|
|
18
|
+
// refuses (throws) before anything is assembled; a prompt has no error
|
|
19
|
+
// channel but its own throw. ENG-6431 — it also routes a document to the
|
|
20
|
+
// document lane instead of the spreadsheet-only one that read 0.
|
|
21
|
+
const changes = await readFileChanges(api, fileMsId);
|
|
22
|
+
const file = changes.file;
|
|
23
|
+
const versions = await api.getFileVersions(fileMsId);
|
|
29
24
|
const recentVersions = versions.slice(0, 5);
|
|
30
25
|
const versionSummary = recentVersions
|
|
31
26
|
.map((v) => `- ${formatVersion(v)}: ${v.description || 'No description'} (${v.createdAt})`)
|
|
32
27
|
.join('\n');
|
|
33
|
-
const changeSummary = changesPage.changes.length
|
|
34
|
-
? changesPage.changes
|
|
35
|
-
.slice(0, 20)
|
|
36
|
-
.map((c) => `- ${c.sheetName}!${c.cellAddress}: ${JSON.stringify(c.oldValue)} → ${JSON.stringify(c.newValue)}`)
|
|
37
|
-
.join('\n')
|
|
38
|
-
: 'None';
|
|
39
28
|
return {
|
|
40
29
|
messages: [
|
|
41
30
|
{
|
|
@@ -44,7 +33,7 @@ export function registerPrompts(server, api) {
|
|
|
44
33
|
type: 'text',
|
|
45
34
|
text: `Summarize the recent activity on the file "${file.name}".\n\n` +
|
|
46
35
|
`## Recent Versions (last ${recentVersions.length} of ${versions.length})\n${versionSummary}\n\n` +
|
|
47
|
-
|
|
36
|
+
`${changeSummarySection(changes)}\n\n` +
|
|
48
37
|
`Provide a concise summary of what has changed recently, who made changes, and any notable patterns.`,
|
|
49
38
|
},
|
|
50
39
|
},
|
|
@@ -107,7 +96,7 @@ export function registerPrompts(server, api) {
|
|
|
107
96
|
? unresolved
|
|
108
97
|
.map((c) => {
|
|
109
98
|
const author = c.authorName || c.authorEmail || 'Unknown';
|
|
110
|
-
const cell = c
|
|
99
|
+
const cell = commentLocation(c);
|
|
111
100
|
const replyCount = c.replies?.length || 0;
|
|
112
101
|
return (`- **${author}**${cell}: "${renderMentions(c.message)}" (${c.createdAt})` +
|
|
113
102
|
(replyCount ? ` — ${replyCount} replies` : ''));
|
|
@@ -136,18 +125,13 @@ export function registerPrompts(server, api) {
|
|
|
136
125
|
}),
|
|
137
126
|
}, async ({ fileMsId }) => {
|
|
138
127
|
// Plan 02 ruling 5 (STRICT) — this prompt reports a change COUNT, which
|
|
139
|
-
// is the same factual claim in one number instead of many rows
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
128
|
+
// is the same factual claim in one number instead of many rows, so the
|
|
129
|
+
// shared read refuses first. ENG-6431 — and routes by file type.
|
|
130
|
+
const changes = await readFileChanges(api, fileMsId);
|
|
131
|
+
const file = changes.file;
|
|
132
|
+
const [versions, comments] = await Promise.all([
|
|
143
133
|
api.getFileVersions(fileMsId),
|
|
144
134
|
api.getFileComments(fileMsId),
|
|
145
|
-
// KI-097: switched to cursor-paginated route. The file-overview
|
|
146
|
-
// prompt only displays a total count, so we use `totalCount` from
|
|
147
|
-
// the first page — no need to fetch every row. ENG-4346 - that is
|
|
148
|
-
// sound only because no cursor is passed: `totalCount` counts rows
|
|
149
|
-
// remaining from the cursor onward, not rows in the file.
|
|
150
|
-
api.getUnattributedChangesPaginated(fileMsId),
|
|
151
135
|
]);
|
|
152
136
|
const latestVersion = versions[0];
|
|
153
137
|
let reviews = [];
|
|
@@ -178,7 +162,7 @@ export function registerPrompts(server, api) {
|
|
|
178
162
|
: 'No versions yet.\n') +
|
|
179
163
|
`\n## Comments: ${comments.length} total, ${unresolvedComments.length} unresolved\n` +
|
|
180
164
|
`## Reviews: ${reviews.length} total, ${pendingReviews.length} pending\n` +
|
|
181
|
-
|
|
165
|
+
`${changeCountLine(changes)}\n\n` +
|
|
182
166
|
`Provide a status report highlighting anything that needs attention.`,
|
|
183
167
|
},
|
|
184
168
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"changes.d.ts","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CAuDN"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ResourceTemplate } from '@modelcontextprotocol/server';
|
|
2
|
-
import {
|
|
2
|
+
import { fileChangesUnavailableText, readFileChanges } from '../file-changes.js';
|
|
3
3
|
export function registerChangeResources(server, api) {
|
|
4
4
|
// KI-078 (ENG-1381): template only, no per-file expansion into resources/list.
|
|
5
5
|
// Previously this enumerated only files with `hasUncommittedChanges === true` —
|
|
@@ -8,7 +8,9 @@ export function registerChangeResources(server, api) {
|
|
|
8
8
|
list: undefined,
|
|
9
9
|
}), {
|
|
10
10
|
title: 'Unattributed Changes',
|
|
11
|
-
description: '
|
|
11
|
+
description: 'Changes since the last saved version: cell changes for a workbook ' +
|
|
12
|
+
'(the paginated envelope), paragraph or shape changes for a document ' +
|
|
13
|
+
'or deck (the document-change window).',
|
|
12
14
|
mimeType: 'application/json',
|
|
13
15
|
}, async (uri, { fileMsId }) => {
|
|
14
16
|
// KI-097: switched to cursor-paginated route. Resource returns the
|
|
@@ -21,20 +23,27 @@ export function registerChangeResources(server, api) {
|
|
|
21
23
|
// so an incomplete window must THROW. The SDK renders that as a protocol
|
|
22
24
|
// error, which is the only shape here that cannot be mistaken for an
|
|
23
25
|
// empty change set.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
// ENG-2824 (enrolment) is enforced inside the shared read as well.
|
|
27
|
+
// ENG-6431 — the SAME dispatch `get_unattributed_changes` uses, so a
|
|
28
|
+
// document no longer reads the spreadsheet-only lane and serves
|
|
29
|
+
// `totalCount: 0`. A refusal (unknown type, withheld window) THROWS: a
|
|
30
|
+
// resource has no `isError` channel, and an empty body is the one shape
|
|
31
|
+
// that would be read as "nothing changed".
|
|
32
|
+
const read = await readFileChanges(api, fileMsId);
|
|
33
|
+
if (read.kind === 'unavailable') {
|
|
34
|
+
throw new Error(fileChangesUnavailableText(read));
|
|
31
35
|
}
|
|
36
|
+
const body = read.kind === 'document'
|
|
37
|
+
? read.response
|
|
38
|
+
: read.kind === 'spreadsheet'
|
|
39
|
+
? read.page
|
|
40
|
+
: read.changes;
|
|
32
41
|
return {
|
|
33
42
|
contents: [
|
|
34
43
|
{
|
|
35
44
|
uri: uri.href,
|
|
36
45
|
mimeType: 'application/json',
|
|
37
|
-
text: JSON.stringify(
|
|
46
|
+
text: JSON.stringify(body, null, 2),
|
|
38
47
|
},
|
|
39
48
|
],
|
|
40
49
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,
|
|
1
|
+
{"version":3,"file":"changes.js","sourceRoot":"","sources":["../../src/resources/changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEjF,MAAM,UAAU,uBAAuB,CACrC,MAAiB,EACjB,GAAc;IAEd,+EAA+E;IAC/E,gFAAgF;IAChF,+DAA+D;IAC/D,MAAM,CAAC,gBAAgB,CACrB,sBAAsB,EACtB,IAAI,gBAAgB,CAAC,uCAAuC,EAAE;QAC5D,IAAI,EAAE,SAAS;KAChB,CAAC,EACF;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,oEAAoE;YACpE,sEAAsE;YACtE,uCAAuC;QACzC,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC1B,mEAAmE;QACnE,uEAAuE;QACvE,8DAA8D;QAC9D,8DAA8D;QAC9D,iEAAiE;QACjE,gBAAgB;QAChB,wEAAwE;QACxE,yEAAyE;QACzE,qEAAqE;QACrE,oBAAoB;QACpB,mEAAmE;QACnE,qEAAqE;QACrE,gEAAgE;QAChE,uEAAuE;QACvE,wEAAwE;QACxE,2CAA2C;QAC3C,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,EAAE,QAAkB,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,IAAI,GACR,IAAI,CAAC,IAAI,KAAK,UAAU;YACtB,CAAC,CAAC,IAAI,CAAC,QAAQ;YACf,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa;gBAC3B,CAAC,CAAC,IAAI,CAAC,IAAI;gBACX,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QACrB,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;iBACpC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -197,7 +197,7 @@ If you need to know which cloud a file is in, inspect `fileType`, or read `provi
|
|
|
197
197
|
|
|
198
198
|
**Adding a file differs by cloud, and it is the one place it matters.** A Microsoft file can be added by link or by the `driveMsId` + `msId` pair `search_drive_files` returns. A Google file is added **by link only** — there is no id pair to pass. `search_drive_files` returns the link for a confirmed Google candidate; hand it to `enroll_file` as `url`.
|
|
199
199
|
|
|
200
|
-
`search_drive_files` takes a `provider` argument (`microsoft` or `google`). Each needs its own connected account. Ask the user which cloud their file is in rather than guessing: searching the wrong one returns an empty list that reads exactly like "no such file".
|
|
200
|
+
`search_drive_files` takes a `provider` argument (`microsoft` or `google`). Each needs its own connected account: `connect_microsoft` / `microsoft_link_status` / `disconnect_microsoft` for Microsoft, `connect_google` / `google_link_status` / `disconnect_google` for Google Drive. Ask the user which cloud their file is in rather than guessing: searching the wrong one returns an empty list that reads exactly like "no such file".
|
|
201
201
|
|
|
202
202
|
## 9. Error handling
|
|
203
203
|
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/server';
|
|
2
|
-
import type
|
|
2
|
+
import { type ApiClient } from '../api-client.js';
|
|
3
3
|
/**
|
|
4
|
+
* The account-link tools — `connect_<provider>`, `<provider>_link_status` and
|
|
5
|
+
* `disconnect_<provider>` — registered ONCE per row of
|
|
6
|
+
* `ACCOUNT_LINK_PROVIDERS` (ENG-6414 widened this from Microsoft alone to
|
|
7
|
+
* Microsoft and Google). Everything below is written about Microsoft, where it
|
|
8
|
+
* started; every word of it holds for Google too.
|
|
9
|
+
*
|
|
4
10
|
* `connect_microsoft` — the local half of SP07 §3.
|
|
5
11
|
*
|
|
6
12
|
* A REPAIR PATH, NOT A SETUP PATH, since ENG-2790. A user who signs in
|
|
@@ -28,5 +34,5 @@ import type { ApiClient } from '../api-client.js';
|
|
|
28
34
|
* server-side when it redeems the code. Two independent places refuse to take
|
|
29
35
|
* the caller's word for it.
|
|
30
36
|
*/
|
|
31
|
-
export declare function
|
|
32
|
-
//# sourceMappingURL=
|
|
37
|
+
export declare function registerAccountLinkTools(server: McpServer, api: ApiClient): void;
|
|
38
|
+
//# sourceMappingURL=account-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-link.d.ts","sourceRoot":"","sources":["../../src/tools/account-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,SAAS,GACb,IAAI,CAIN"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { RockhopperApiError } from '../api-client.js';
|
|
3
|
+
import { ACCOUNT_LINK_PROVIDERS, connectToolName, statusToolName, } from '../account-link-providers.js';
|
|
4
|
+
/**
|
|
5
|
+
* The account-link tools — `connect_<provider>`, `<provider>_link_status` and
|
|
6
|
+
* `disconnect_<provider>` — registered ONCE per row of
|
|
7
|
+
* `ACCOUNT_LINK_PROVIDERS` (ENG-6414 widened this from Microsoft alone to
|
|
8
|
+
* Microsoft and Google). Everything below is written about Microsoft, where it
|
|
9
|
+
* started; every word of it holds for Google too.
|
|
10
|
+
*
|
|
11
|
+
* `connect_microsoft` — the local half of SP07 §3.
|
|
12
|
+
*
|
|
13
|
+
* A REPAIR PATH, NOT A SETUP PATH, since ENG-2790. A user who signs in
|
|
14
|
+
* through `mcp.rockhopper.co` gets the delegated Graph grant in the same
|
|
15
|
+
* consent that signs them in, so this tool is no longer the way anyone
|
|
16
|
+
* normally arrives at a working link. It stays because the grant can end
|
|
17
|
+
* up missing for reasons sign-in cannot fix on its own — the user revoked
|
|
18
|
+
* it in Microsoft, the handover at sign-in failed, or the session is a
|
|
19
|
+
* local stdio one with a personal access token, which carries no Microsoft
|
|
20
|
+
* sign-in of its own and therefore still needs this.
|
|
21
|
+
*
|
|
22
|
+
* Deleting it would have left `disconnect_microsoft` as a one-way door.
|
|
23
|
+
*
|
|
24
|
+
* WHAT THIS TOOL DELIBERATELY CANNOT DO, and why the shape matters more than
|
|
25
|
+
* the feature. It takes NO authorize URL, no redirect URI, no client id and no
|
|
26
|
+
* scope list. It asks the backend to build the consent URL and relays what
|
|
27
|
+
* comes back.
|
|
28
|
+
*
|
|
29
|
+
* The reason is the threat this tool sits inside. An MCP tool's arguments are
|
|
30
|
+
* chosen by a language model, and that model reads content it did not author —
|
|
31
|
+
* file names, comments, review text. A tool that accepted a URL would let
|
|
32
|
+
* anything that model reads steer where a user's Microsoft consent is sent,
|
|
33
|
+
* and the user would see a real Microsoft consent screen the whole way. So the
|
|
34
|
+
* URL is not a parameter, and the callback re-pins the client id and redirect
|
|
35
|
+
* server-side when it redeems the code. Two independent places refuse to take
|
|
36
|
+
* the caller's word for it.
|
|
37
|
+
*/
|
|
38
|
+
export function registerAccountLinkTools(server, api) {
|
|
39
|
+
for (const provider of ACCOUNT_LINK_PROVIDERS) {
|
|
40
|
+
registerProviderLinkTools(server, api, provider);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const failure = (text) => ({
|
|
44
|
+
content: [{ type: 'text', text }],
|
|
45
|
+
isError: true,
|
|
46
|
+
});
|
|
47
|
+
const errorText = (error) => error instanceof Error ? error.message : String(error);
|
|
48
|
+
function registerProviderLinkTools(server, api, p) {
|
|
49
|
+
const connectName = connectToolName(p);
|
|
50
|
+
const statusName = statusToolName(p);
|
|
51
|
+
server.registerTool(connectName, {
|
|
52
|
+
title: `Connect ${p.label} Account`,
|
|
53
|
+
description: `Start connecting the user's ${p.label} account so Rockhopper can ` +
|
|
54
|
+
`${p.purpose} as them. Returns a ${p.label} sign-in link the USER must ` +
|
|
55
|
+
`open themselves. Call \`${statusName}\` afterwards to confirm they ` +
|
|
56
|
+
`finished. Use this when a file search reports that no ${p.label} ` +
|
|
57
|
+
'account is connected.',
|
|
58
|
+
inputSchema: z.object({}),
|
|
59
|
+
annotations: {
|
|
60
|
+
// Creates no Rockhopper data by itself — it hands back a link. The
|
|
61
|
+
// grant only exists once the USER completes the consent.
|
|
62
|
+
readOnlyHint: true,
|
|
63
|
+
// It sends the user to the provider.
|
|
64
|
+
openWorldHint: true,
|
|
65
|
+
},
|
|
66
|
+
}, async () => {
|
|
67
|
+
try {
|
|
68
|
+
const handoff = await p.begin(api);
|
|
69
|
+
return {
|
|
70
|
+
content: [
|
|
71
|
+
{
|
|
72
|
+
type: 'text',
|
|
73
|
+
text: `Open this link to connect your ${p.label} account:\n\n` +
|
|
74
|
+
`${handoff.authorizeUrl}\n\n` +
|
|
75
|
+
`The link expires at ${handoff.expiresAt}. ` +
|
|
76
|
+
(p.readOnlyConsent
|
|
77
|
+
? 'Rockhopper asks only to READ your files. '
|
|
78
|
+
: '') +
|
|
79
|
+
`After you approve, run \`${statusName}\` to confirm.`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
return failure(`Failed to start the ${p.label} connection: ${errorText(error)}`);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
server.registerTool(statusName, {
|
|
89
|
+
title: `${p.label} Connection Status`,
|
|
90
|
+
description: p.statusDescription,
|
|
91
|
+
inputSchema: z.object({}),
|
|
92
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
93
|
+
}, async () => {
|
|
94
|
+
try {
|
|
95
|
+
const status = await p.status(api);
|
|
96
|
+
return {
|
|
97
|
+
content: [
|
|
98
|
+
{
|
|
99
|
+
type: 'text',
|
|
100
|
+
text: status.linked
|
|
101
|
+
? `Connected${status.account ? ` as ${status.account}` : ''}.` +
|
|
102
|
+
(status.grantedScopes.length
|
|
103
|
+
? ` Granted: ${status.grantedScopes.join(', ')}.`
|
|
104
|
+
: '') +
|
|
105
|
+
(status.linkedAt ? ` Connected on ${status.linkedAt}.` : '')
|
|
106
|
+
: `No ${p.label} account is connected. Run \`${connectName}\` to connect one.`,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
return failure(`Failed to read the ${p.label} connection: ${errorText(error)}`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
server.registerTool(`disconnect_${p.key}`, {
|
|
116
|
+
title: `Disconnect ${p.label} Account`,
|
|
117
|
+
description: `Remove the stored ${p.label} connection, deleting the credential Rockhopper ` +
|
|
118
|
+
'holds for this user. Requires an interactive login; a personal access token ' +
|
|
119
|
+
'cannot sever a connection it did not create.',
|
|
120
|
+
inputSchema: z.object({}),
|
|
121
|
+
annotations: {
|
|
122
|
+
readOnlyHint: false,
|
|
123
|
+
destructiveHint: true,
|
|
124
|
+
idempotentHint: true,
|
|
125
|
+
openWorldHint: false,
|
|
126
|
+
},
|
|
127
|
+
}, async () => {
|
|
128
|
+
try {
|
|
129
|
+
const result = await p.unlink(api);
|
|
130
|
+
return {
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: 'text',
|
|
134
|
+
text: result.removed
|
|
135
|
+
? `${p.label} account disconnected. The stored credential has been deleted.`
|
|
136
|
+
: `No ${p.label} account was connected.`,
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
// The backend refuses a disconnect from a personal access token or API
|
|
143
|
+
// key with a 403 (`requireInteractiveAuth`). Said plainly, so the
|
|
144
|
+
// model does not relay a raw HTTP body or report a success.
|
|
145
|
+
if (error instanceof RockhopperApiError && error.status === 403) {
|
|
146
|
+
return failure(`Nothing was disconnected. Rockhopper removes a ${p.label} ` +
|
|
147
|
+
'connection only for someone signed in interactively, and this ' +
|
|
148
|
+
'session uses a personal access token. Ask the user to ' +
|
|
149
|
+
`disconnect ${p.label} from Rockhopper in their browser.`);
|
|
150
|
+
}
|
|
151
|
+
return failure(`Failed to disconnect: ${errorText(error)}`);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=account-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-link.js","sourceRoot":"","sources":["../../src/tools/account-link.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAkB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,cAAc,GAEf,MAAM,8BAA8B,CAAC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAiB,EACjB,GAAc;IAEd,KAAK,MAAM,QAAQ,IAAI,sBAAsB,EAAE,CAAC;QAC9C,yBAAyB,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC;IACjC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;IAC1C,OAAO,EAAE,IAAI;CACd,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE,CACnC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,SAAS,yBAAyB,CAChC,MAAiB,EACjB,GAAc,EACd,CAAsB;IAEtB,MAAM,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IAErC,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;QACE,KAAK,EAAE,WAAW,CAAC,CAAC,KAAK,UAAU;QACnC,WAAW,EACT,+BAA+B,CAAC,CAAC,KAAK,6BAA6B;YACnE,GAAG,CAAC,CAAC,OAAO,uBAAuB,CAAC,CAAC,KAAK,8BAA8B;YACxE,2BAA2B,UAAU,gCAAgC;YACrE,yDAAyD,CAAC,CAAC,KAAK,GAAG;YACnE,uBAAuB;QACzB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,WAAW,EAAE;YACX,mEAAmE;YACnE,yDAAyD;YACzD,YAAY,EAAE,IAAI;YAClB,qCAAqC;YACrC,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAEnC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EACF,kCAAkC,CAAC,CAAC,KAAK,eAAe;4BACxD,GAAG,OAAO,CAAC,YAAY,MAAM;4BAC7B,uBAAuB,OAAO,CAAC,SAAS,IAAI;4BAC5C,CAAC,CAAC,CAAC,eAAe;gCAChB,CAAC,CAAC,2CAA2C;gCAC7C,CAAC,CAAC,EAAE,CAAC;4BACP,4BAA4B,UAAU,gBAAgB;qBACzD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,OAAO,CACZ,uBAAuB,CAAC,CAAC,KAAK,gBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,CACjE,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,UAAU,EACV;QACE,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,oBAAoB;QACrC,WAAW,EAAE,CAAC,CAAC,iBAAiB;QAChC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;KAC1D,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEnC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM,CAAC,MAAM;4BACjB,CAAC,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG;gCAC5D,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM;oCAC1B,CAAC,CAAC,aAAa,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;oCACjD,CAAC,CAAC,EAAE,CAAC;gCACP,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC9D,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,gCAAgC,WAAW,oBAAoB;qBACjF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,OAAO,CACZ,sBAAsB,CAAC,CAAC,KAAK,gBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,CAChE,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,cAAc,CAAC,CAAC,GAAG,EAAE,EACrB;QACE,KAAK,EAAE,cAAc,CAAC,CAAC,KAAK,UAAU;QACtC,WAAW,EACT,qBAAqB,CAAC,CAAC,KAAK,kDAAkD;YAC9E,8EAA8E;YAC9E,8CAA8C;QAChD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEnC,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,MAAM,CAAC,OAAO;4BAClB,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,gEAAgE;4BAC5E,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,yBAAyB;qBAC3C;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uEAAuE;YACvE,kEAAkE;YAClE,4DAA4D;YAC5D,IAAI,KAAK,YAAY,kBAAkB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAChE,OAAO,OAAO,CACZ,kDAAkD,CAAC,CAAC,KAAK,GAAG;oBAC1D,gEAAgE;oBAChE,wDAAwD;oBACxD,cAAc,CAAC,CAAC,KAAK,oCAAoC,CAC5D,CAAC;YACJ,CAAC;YACD,OAAO,OAAO,CAAC,yBAAyB,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|