@ankimcp/anki-mcp-server 0.8.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.
- package/LICENSE +7 -0
- package/README.md +756 -0
- package/bin/ankimcp.js +12 -0
- package/dist/anki-config.service.d.ts +10 -0
- package/dist/anki-config.service.js +42 -0
- package/dist/anki-config.service.js.map +1 -0
- package/dist/app.module.d.ts +5 -0
- package/dist/app.module.js +84 -0
- package/dist/app.module.js.map +1 -0
- package/dist/bootstrap.d.ts +3 -0
- package/dist/bootstrap.js +39 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +114 -0
- package/dist/cli.js.map +1 -0
- package/dist/http/guards/origin-validation.guard.d.ts +7 -0
- package/dist/http/guards/origin-validation.guard.js +52 -0
- package/dist/http/guards/origin-validation.guard.js.map +1 -0
- package/dist/main-http.d.ts +1 -0
- package/dist/main-http.js +42 -0
- package/dist/main-http.js.map +1 -0
- package/dist/main-stdio.d.ts +1 -0
- package/dist/main-stdio.js +20 -0
- package/dist/main-stdio.js.map +1 -0
- package/dist/mcp/clients/__mocks__/anki-connect.client.d.ts +6 -0
- package/dist/mcp/clients/__mocks__/anki-connect.client.js +18 -0
- package/dist/mcp/clients/__mocks__/anki-connect.client.js.map +1 -0
- package/dist/mcp/clients/anki-connect.client.d.ts +15 -0
- package/dist/mcp/clients/anki-connect.client.js +145 -0
- package/dist/mcp/clients/anki-connect.client.js.map +1 -0
- package/dist/mcp/config/anki-config.interface.d.ts +7 -0
- package/dist/mcp/config/anki-config.interface.js +5 -0
- package/dist/mcp/config/anki-config.interface.js.map +1 -0
- package/dist/mcp/primitives/essential/index.d.ts +32 -0
- package/dist/mcp/primitives/essential/index.js +130 -0
- package/dist/mcp/primitives/essential/index.js.map +1 -0
- package/dist/mcp/primitives/essential/prompts/review-session.prompt.d.ts +12 -0
- package/dist/mcp/primitives/essential/prompts/review-session.prompt.js +113 -0
- package/dist/mcp/primitives/essential/prompts/review-session.prompt.js.map +1 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/content.md +195 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.d.ts +12 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js +89 -0
- package/dist/mcp/primitives/essential/prompts/twenty-rules.prompt/index.js.map +1 -0
- package/dist/mcp/primitives/essential/resources/system-info.resource.d.ts +21 -0
- package/dist/mcp/primitives/essential/resources/system-info.resource.js +115 -0
- package/dist/mcp/primitives/essential/resources/system-info.resource.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/add-note.tool.d.ts +93 -0
- package/dist/mcp/primitives/essential/tools/add-note.tool.js +185 -0
- package/dist/mcp/primitives/essential/tools/add-note.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/create-deck.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/create-deck.tool.js +121 -0
- package/dist/mcp/primitives/essential/tools/create-deck.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/create-model.tool.d.ts +88 -0
- package/dist/mcp/primitives/essential/tools/create-model.tool.js +144 -0
- package/dist/mcp/primitives/essential/tools/create-model.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/delete-notes.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/delete-notes.tool.js +120 -0
- package/dist/mcp/primitives/essential/tools/delete-notes.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/find-notes.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/find-notes.tool.js +106 -0
- package/dist/mcp/primitives/essential/tools/find-notes.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/get-due-cards.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js +108 -0
- package/dist/mcp/primitives/essential/tools/get-due-cards.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/list-decks.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/list-decks.tool.js +117 -0
- package/dist/mcp/primitives/essential/tools/list-decks.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.d.ts +10 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js +18 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/deleteMediaFile.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.d.ts +12 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js +22 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/getMediaFilesNames.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.d.ts +12 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js +29 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/retrieveMediaFile.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.d.ts +15 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js +41 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/actions/storeMediaFile.action.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/index.d.ts +5 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/index.js +6 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/index.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.d.ts +89 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js +141 -0
- package/dist/mcp/primitives/essential/tools/mediaActions/mediaActions.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.js +119 -0
- package/dist/mcp/primitives/essential/tools/model-field-names.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-names.tool.d.ts +81 -0
- package/dist/mcp/primitives/essential/tools/model-names.tool.js +80 -0
- package/dist/mcp/primitives/essential/tools/model-names.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/model-styling.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/model-styling.tool.js +93 -0
- package/dist/mcp/primitives/essential/tools/model-styling.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/notes-info.tool.d.ts +83 -0
- package/dist/mcp/primitives/essential/tools/notes-info.tool.js +111 -0
- package/dist/mcp/primitives/essential/tools/notes-info.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/present-card.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/present-card.tool.js +100 -0
- package/dist/mcp/primitives/essential/tools/present-card.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/rate-card.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/rate-card.tool.js +101 -0
- package/dist/mcp/primitives/essential/tools/rate-card.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/sync.tool.d.ts +81 -0
- package/dist/mcp/primitives/essential/tools/sync.tool.js +61 -0
- package/dist/mcp/primitives/essential/tools/sync.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/update-model-styling.tool.d.ts +84 -0
- package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js +119 -0
- package/dist/mcp/primitives/essential/tools/update-model-styling.tool.js.map +1 -0
- package/dist/mcp/primitives/essential/tools/update-note-fields.tool.d.ts +96 -0
- package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js +154 -0
- package/dist/mcp/primitives/essential/tools/update-note-fields.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/index.d.ts +23 -0
- package/dist/mcp/primitives/gui/index.js +94 -0
- package/dist/mcp/primitives/gui/index.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.d.ts +88 -0
- package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js +111 -0
- package/dist/mcp/primitives/gui/tools/gui-add-cards.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-browse.tool.d.ts +87 -0
- package/dist/mcp/primitives/gui/tools/gui-browse.tool.js +99 -0
- package/dist/mcp/primitives/gui/tools/gui-browse.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-current-card.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js +76 -0
- package/dist/mcp/primitives/gui/tools/gui-current-card.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js +64 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-browser.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.d.ts +83 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js +88 -0
- package/dist/mcp/primitives/gui/tools/gui-deck-overview.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.d.ts +83 -0
- package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js +80 -0
- package/dist/mcp/primitives/gui/tools/gui-edit-note.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-select-card.tool.d.ts +83 -0
- package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js +90 -0
- package/dist/mcp/primitives/gui/tools/gui-select-card.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js +83 -0
- package/dist/mcp/primitives/gui/tools/gui-selected-notes.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js +74 -0
- package/dist/mcp/primitives/gui/tools/gui-show-answer.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-show-question.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js +74 -0
- package/dist/mcp/primitives/gui/tools/gui-show-question.tool.js.map +1 -0
- package/dist/mcp/primitives/gui/tools/gui-undo.tool.d.ts +81 -0
- package/dist/mcp/primitives/gui/tools/gui-undo.tool.js +74 -0
- package/dist/mcp/primitives/gui/tools/gui-undo.tool.js.map +1 -0
- package/dist/mcp/types/anki.types.d.ts +180 -0
- package/dist/mcp/types/anki.types.js +18 -0
- package/dist/mcp/types/anki.types.js.map +1 -0
- package/dist/mcp/utils/anki.utils.d.ts +19 -0
- package/dist/mcp/utils/anki.utils.js +157 -0
- package/dist/mcp/utils/anki.utils.js.map +1 -0
- package/dist/mcp/utils/markdown.utils.d.ts +4 -0
- package/dist/mcp/utils/markdown.utils.js +60 -0
- package/dist/mcp/utils/markdown.utils.js.map +1 -0
- package/dist/mcp/utils/mcpb-workarounds.d.ts +1 -0
- package/dist/mcp/utils/mcpb-workarounds.js +13 -0
- package/dist/mcp/utils/mcpb-workarounds.js.map +1 -0
- package/dist/services/ngrok.service.d.ts +15 -0
- package/dist/services/ngrok.service.js +120 -0
- package/dist/services/ngrok.service.js.map +1 -0
- package/dist/test-fixtures/mock-data.d.ts +126 -0
- package/dist/test-fixtures/mock-data.js +112 -0
- package/dist/test-fixtures/mock-data.js.map +1 -0
- package/dist/test-fixtures/test-helpers.d.ts +12 -0
- package/dist/test-fixtures/test-helpers.js +24 -0
- package/dist/test-fixtures/test-helpers.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +168 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
export declare enum CardType {
|
|
2
|
+
New = 0,
|
|
3
|
+
Learning = 1,
|
|
4
|
+
Review = 2,
|
|
5
|
+
Relearning = 3
|
|
6
|
+
}
|
|
7
|
+
export interface AnkiCard {
|
|
8
|
+
cardId: number;
|
|
9
|
+
fields: Record<string, {
|
|
10
|
+
value: string;
|
|
11
|
+
order: number;
|
|
12
|
+
}>;
|
|
13
|
+
fieldOrder: number;
|
|
14
|
+
question: string;
|
|
15
|
+
answer: string;
|
|
16
|
+
modelName: string;
|
|
17
|
+
ord: number;
|
|
18
|
+
deckName: string;
|
|
19
|
+
css: string;
|
|
20
|
+
factor?: number;
|
|
21
|
+
interval?: number;
|
|
22
|
+
note: number;
|
|
23
|
+
type: number;
|
|
24
|
+
queue: number;
|
|
25
|
+
due?: number;
|
|
26
|
+
reps?: number;
|
|
27
|
+
lapses?: number;
|
|
28
|
+
left?: number;
|
|
29
|
+
mod?: number;
|
|
30
|
+
flags?: number;
|
|
31
|
+
tags?: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface SimplifiedCard {
|
|
34
|
+
cardId: number;
|
|
35
|
+
front: string;
|
|
36
|
+
back: string;
|
|
37
|
+
deckName: string;
|
|
38
|
+
modelName: string;
|
|
39
|
+
due: number;
|
|
40
|
+
interval: number;
|
|
41
|
+
factor: number;
|
|
42
|
+
}
|
|
43
|
+
export interface CardPresentation {
|
|
44
|
+
cardId: number;
|
|
45
|
+
front: string;
|
|
46
|
+
back?: string;
|
|
47
|
+
deckName: string;
|
|
48
|
+
modelName: string;
|
|
49
|
+
tags: string[];
|
|
50
|
+
currentInterval: number;
|
|
51
|
+
easeFactor: number;
|
|
52
|
+
reviews: number;
|
|
53
|
+
lapses: number;
|
|
54
|
+
cardType: string;
|
|
55
|
+
noteId: number;
|
|
56
|
+
}
|
|
57
|
+
export interface DeckInfo {
|
|
58
|
+
name: string;
|
|
59
|
+
stats?: DeckStats;
|
|
60
|
+
}
|
|
61
|
+
export interface DeckStats {
|
|
62
|
+
deck_id: number;
|
|
63
|
+
name: string;
|
|
64
|
+
new_count: number;
|
|
65
|
+
learn_count: number;
|
|
66
|
+
review_count: number;
|
|
67
|
+
total_new: number;
|
|
68
|
+
total_cards: number;
|
|
69
|
+
}
|
|
70
|
+
export declare enum CardRating {
|
|
71
|
+
Again = 1,
|
|
72
|
+
Hard = 2,
|
|
73
|
+
Good = 3,
|
|
74
|
+
Easy = 4
|
|
75
|
+
}
|
|
76
|
+
export interface AnkiConnectRequest {
|
|
77
|
+
action: string;
|
|
78
|
+
version: number;
|
|
79
|
+
params?: Record<string, any>;
|
|
80
|
+
key?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface AnkiConnectResponse<T = any> {
|
|
83
|
+
result: T;
|
|
84
|
+
error: string | null;
|
|
85
|
+
}
|
|
86
|
+
export interface NoteOptions {
|
|
87
|
+
allowDuplicate?: boolean;
|
|
88
|
+
duplicateScope?: "deck" | "collection";
|
|
89
|
+
duplicateScopeOptions?: {
|
|
90
|
+
deckName?: string;
|
|
91
|
+
checkChildren?: boolean;
|
|
92
|
+
checkAllModels?: boolean;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export interface AddNoteParams {
|
|
96
|
+
deckName: string;
|
|
97
|
+
modelName: string;
|
|
98
|
+
fields: Record<string, string>;
|
|
99
|
+
tags?: string[];
|
|
100
|
+
options?: NoteOptions;
|
|
101
|
+
}
|
|
102
|
+
export interface Model {
|
|
103
|
+
name: string;
|
|
104
|
+
id: number;
|
|
105
|
+
css: string;
|
|
106
|
+
fields: string[];
|
|
107
|
+
}
|
|
108
|
+
export interface NoteInfo {
|
|
109
|
+
noteId: number;
|
|
110
|
+
modelName: string;
|
|
111
|
+
tags: string[];
|
|
112
|
+
fields: Record<string, {
|
|
113
|
+
value: string;
|
|
114
|
+
order: number;
|
|
115
|
+
}>;
|
|
116
|
+
cards: number[];
|
|
117
|
+
mod: number;
|
|
118
|
+
}
|
|
119
|
+
export interface UpdateNoteFieldsParams {
|
|
120
|
+
note: {
|
|
121
|
+
id: number;
|
|
122
|
+
fields: Record<string, string>;
|
|
123
|
+
audio?: Array<{
|
|
124
|
+
url: string;
|
|
125
|
+
filename: string;
|
|
126
|
+
fields: string[];
|
|
127
|
+
}>;
|
|
128
|
+
picture?: Array<{
|
|
129
|
+
url: string;
|
|
130
|
+
filename: string;
|
|
131
|
+
fields: string[];
|
|
132
|
+
}>;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export interface CardTemplate {
|
|
136
|
+
Name: string;
|
|
137
|
+
Front: string;
|
|
138
|
+
Back: string;
|
|
139
|
+
}
|
|
140
|
+
export interface CreateModelParams {
|
|
141
|
+
modelName: string;
|
|
142
|
+
inOrderFields: string[];
|
|
143
|
+
cardTemplates: CardTemplate[];
|
|
144
|
+
css?: string;
|
|
145
|
+
isCloze?: boolean;
|
|
146
|
+
}
|
|
147
|
+
export interface UpdateModelStylingParams {
|
|
148
|
+
model: {
|
|
149
|
+
name: string;
|
|
150
|
+
css: string;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export interface GuiCurrentCardInfo {
|
|
154
|
+
answer: string;
|
|
155
|
+
question: string;
|
|
156
|
+
deckName: string;
|
|
157
|
+
modelName: string;
|
|
158
|
+
cardId: number;
|
|
159
|
+
buttons: number[];
|
|
160
|
+
nextReviews: string[];
|
|
161
|
+
fields?: Record<string, {
|
|
162
|
+
value: string;
|
|
163
|
+
order: number;
|
|
164
|
+
}>;
|
|
165
|
+
}
|
|
166
|
+
export interface GuiBrowseParams {
|
|
167
|
+
query: string;
|
|
168
|
+
reorderCards?: {
|
|
169
|
+
order: "ascending" | "descending";
|
|
170
|
+
columnId: string;
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export interface GuiAddCardsParams {
|
|
174
|
+
note: {
|
|
175
|
+
deckName: string;
|
|
176
|
+
modelName: string;
|
|
177
|
+
fields: Record<string, string>;
|
|
178
|
+
tags?: string[];
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CardRating = exports.CardType = void 0;
|
|
4
|
+
var CardType;
|
|
5
|
+
(function (CardType) {
|
|
6
|
+
CardType[CardType["New"] = 0] = "New";
|
|
7
|
+
CardType[CardType["Learning"] = 1] = "Learning";
|
|
8
|
+
CardType[CardType["Review"] = 2] = "Review";
|
|
9
|
+
CardType[CardType["Relearning"] = 3] = "Relearning";
|
|
10
|
+
})(CardType || (exports.CardType = CardType = {}));
|
|
11
|
+
var CardRating;
|
|
12
|
+
(function (CardRating) {
|
|
13
|
+
CardRating[CardRating["Again"] = 1] = "Again";
|
|
14
|
+
CardRating[CardRating["Hard"] = 2] = "Hard";
|
|
15
|
+
CardRating[CardRating["Good"] = 3] = "Good";
|
|
16
|
+
CardRating[CardRating["Easy"] = 4] = "Easy";
|
|
17
|
+
})(CardRating || (exports.CardRating = CardRating = {}));
|
|
18
|
+
//# sourceMappingURL=anki.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anki.types.js","sourceRoot":"","sources":["../../../src/mcp/types/anki.types.ts"],"names":[],"mappings":";;;AAOA,IAAY,QAKX;AALD,WAAY,QAAQ;IAClB,qCAAO,CAAA;IACP,+CAAY,CAAA;IACZ,2CAAU,CAAA;IACV,mDAAc,CAAA;AAChB,CAAC,EALW,QAAQ,wBAAR,QAAQ,QAKnB;AAqFD,IAAY,UAKX;AALD,WAAY,UAAU;IACpB,6CAAS,CAAA;IACT,2CAAQ,CAAA;IACR,2CAAQ,CAAA;IACR,2CAAQ,CAAA;AACV,CAAC,EALW,UAAU,0BAAV,UAAU,QAKrB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { AnkiCard } from "../types/anki.types";
|
|
3
|
+
export declare function cleanHtml(html: string): string;
|
|
4
|
+
export declare function extractCardContent(fields: AnkiCard["fields"]): {
|
|
5
|
+
front: string;
|
|
6
|
+
back: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function getCardType(type: number): string;
|
|
9
|
+
export declare function getNoteType(modelName: string): string;
|
|
10
|
+
export declare function getRatingDescription(rating: number): string;
|
|
11
|
+
export declare function createSuccessResponse(data: any): CallToolResult;
|
|
12
|
+
export declare function createErrorResponse(error: unknown, context?: Record<string, any>): CallToolResult;
|
|
13
|
+
export declare function formatInterval(days: number): string;
|
|
14
|
+
export declare function parseDeckStats(stats: any): {
|
|
15
|
+
new_count: number;
|
|
16
|
+
learn_count: number;
|
|
17
|
+
review_count: number;
|
|
18
|
+
total_cards: number;
|
|
19
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cleanHtml = cleanHtml;
|
|
4
|
+
exports.extractCardContent = extractCardContent;
|
|
5
|
+
exports.getCardType = getCardType;
|
|
6
|
+
exports.getNoteType = getNoteType;
|
|
7
|
+
exports.getRatingDescription = getRatingDescription;
|
|
8
|
+
exports.createSuccessResponse = createSuccessResponse;
|
|
9
|
+
exports.createErrorResponse = createErrorResponse;
|
|
10
|
+
exports.formatInterval = formatInterval;
|
|
11
|
+
exports.parseDeckStats = parseDeckStats;
|
|
12
|
+
const anki_types_1 = require("../types/anki.types");
|
|
13
|
+
const anki_connect_client_1 = require("../clients/anki-connect.client");
|
|
14
|
+
function cleanHtml(html) {
|
|
15
|
+
return html
|
|
16
|
+
.replace(/<[^>]*>/g, "")
|
|
17
|
+
.replace(/ /g, " ")
|
|
18
|
+
.replace(/&/g, "&")
|
|
19
|
+
.replace(/</g, "<")
|
|
20
|
+
.replace(/>/g, ">")
|
|
21
|
+
.replace(/"/g, '"')
|
|
22
|
+
.replace(/'/g, "'")
|
|
23
|
+
.replace(/\n\s*\n/g, "\n")
|
|
24
|
+
.trim();
|
|
25
|
+
}
|
|
26
|
+
function extractCardContent(fields) {
|
|
27
|
+
let front = "";
|
|
28
|
+
let back = "";
|
|
29
|
+
if (!fields) {
|
|
30
|
+
return { front, back };
|
|
31
|
+
}
|
|
32
|
+
const frontFieldNames = ["Front", "正面", "Question", "Text"];
|
|
33
|
+
const backFieldNames = ["Back", "背面", "Answer", "Extra", "Back Extra"];
|
|
34
|
+
for (const fieldName of frontFieldNames) {
|
|
35
|
+
if (fields[fieldName]) {
|
|
36
|
+
front = fields[fieldName].value;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
for (const fieldName of backFieldNames) {
|
|
41
|
+
if (fields[fieldName]) {
|
|
42
|
+
back = fields[fieldName].value;
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (!front && !back) {
|
|
47
|
+
const fieldEntries = Object.entries(fields).sort((a, b) => a[1].order - b[1].order);
|
|
48
|
+
if (fieldEntries.length > 0) {
|
|
49
|
+
front = fieldEntries[0][1].value;
|
|
50
|
+
}
|
|
51
|
+
if (fieldEntries.length > 1) {
|
|
52
|
+
back = fieldEntries[1][1].value;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
front: cleanHtml(front),
|
|
57
|
+
back: cleanHtml(back),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function getCardType(type) {
|
|
61
|
+
switch (type) {
|
|
62
|
+
case anki_types_1.CardType.New:
|
|
63
|
+
return "new";
|
|
64
|
+
case anki_types_1.CardType.Learning:
|
|
65
|
+
return "learning";
|
|
66
|
+
case anki_types_1.CardType.Review:
|
|
67
|
+
return "review";
|
|
68
|
+
case anki_types_1.CardType.Relearning:
|
|
69
|
+
return "relearning";
|
|
70
|
+
default:
|
|
71
|
+
return "unknown";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function getNoteType(modelName) {
|
|
75
|
+
const lowerName = modelName.toLowerCase();
|
|
76
|
+
if (lowerName.includes("basic")) {
|
|
77
|
+
if (lowerName.includes("reverse")) {
|
|
78
|
+
return "Basic (and reversed card)";
|
|
79
|
+
}
|
|
80
|
+
return "Basic";
|
|
81
|
+
}
|
|
82
|
+
if (lowerName.includes("cloze")) {
|
|
83
|
+
return "Cloze";
|
|
84
|
+
}
|
|
85
|
+
return "Custom";
|
|
86
|
+
}
|
|
87
|
+
function getRatingDescription(rating) {
|
|
88
|
+
switch (rating) {
|
|
89
|
+
case anki_types_1.CardRating.Again:
|
|
90
|
+
return "Again (failed to recall)";
|
|
91
|
+
case anki_types_1.CardRating.Hard:
|
|
92
|
+
return "Hard (recalled with difficulty)";
|
|
93
|
+
case anki_types_1.CardRating.Good:
|
|
94
|
+
return "Good (recalled with some effort)";
|
|
95
|
+
case anki_types_1.CardRating.Easy:
|
|
96
|
+
return "Easy (recalled instantly)";
|
|
97
|
+
default:
|
|
98
|
+
return "Unknown";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function createSuccessResponse(data) {
|
|
102
|
+
return {
|
|
103
|
+
content: [
|
|
104
|
+
{
|
|
105
|
+
type: "text",
|
|
106
|
+
text: JSON.stringify(data, null, 2),
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function createErrorResponse(error, context) {
|
|
112
|
+
const errorData = {
|
|
113
|
+
success: false,
|
|
114
|
+
error: error instanceof Error ? error.message : "Unknown error occurred",
|
|
115
|
+
};
|
|
116
|
+
if (error instanceof anki_connect_client_1.AnkiConnectError) {
|
|
117
|
+
if (error.action) {
|
|
118
|
+
errorData.action = error.action;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (context) {
|
|
122
|
+
Object.assign(errorData, context);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: "text",
|
|
128
|
+
text: JSON.stringify(errorData, null, 2),
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
isError: true,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function formatInterval(days) {
|
|
135
|
+
if (days < 1) {
|
|
136
|
+
const hours = Math.round(days * 24);
|
|
137
|
+
return `${hours} hour${hours !== 1 ? "s" : ""}`;
|
|
138
|
+
}
|
|
139
|
+
if (days < 30) {
|
|
140
|
+
return `${Math.round(days)} day${days !== 1 ? "s" : ""}`;
|
|
141
|
+
}
|
|
142
|
+
if (days < 365) {
|
|
143
|
+
const months = Math.round(days / 30);
|
|
144
|
+
return `${months} month${months !== 1 ? "s" : ""}`;
|
|
145
|
+
}
|
|
146
|
+
const years = Math.round((days / 365) * 10) / 10;
|
|
147
|
+
return `${years} year${years !== 1 ? "s" : ""}`;
|
|
148
|
+
}
|
|
149
|
+
function parseDeckStats(stats) {
|
|
150
|
+
return {
|
|
151
|
+
new_count: stats.new_count || 0,
|
|
152
|
+
learn_count: stats.lrn_count || 0,
|
|
153
|
+
review_count: stats.rev_count || 0,
|
|
154
|
+
total_cards: stats.total || 0,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=anki.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anki.utils.js","sourceRoot":"","sources":["../../../src/mcp/utils/anki.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseMarkdownSections = parseMarkdownSections;
|
|
7
|
+
const unified_1 = require("unified");
|
|
8
|
+
const remark_parse_1 = __importDefault(require("remark-parse"));
|
|
9
|
+
const unist_util_visit_1 = require("unist-util-visit");
|
|
10
|
+
function nodeToString(node) {
|
|
11
|
+
if (node.type === "text") {
|
|
12
|
+
return node.value;
|
|
13
|
+
}
|
|
14
|
+
if (node.type === "inlineCode") {
|
|
15
|
+
return `\`${node.value}\``;
|
|
16
|
+
}
|
|
17
|
+
if ("children" in node && Array.isArray(node.children)) {
|
|
18
|
+
return node.children
|
|
19
|
+
.map((child) => nodeToString(child))
|
|
20
|
+
.join("");
|
|
21
|
+
}
|
|
22
|
+
if ("value" in node && typeof node.value === "string") {
|
|
23
|
+
return node.value;
|
|
24
|
+
}
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
function extractHeadingText(node) {
|
|
28
|
+
if ("children" in node && Array.isArray(node.children)) {
|
|
29
|
+
return node.children
|
|
30
|
+
.map((child) => nodeToString(child))
|
|
31
|
+
.join("");
|
|
32
|
+
}
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
function parseMarkdownSections(markdown) {
|
|
36
|
+
const tree = (0, unified_1.unified)().use(remark_parse_1.default).parse(markdown);
|
|
37
|
+
const sections = {};
|
|
38
|
+
let currentHeading = null;
|
|
39
|
+
let currentContent = [];
|
|
40
|
+
(0, unist_util_visit_1.visit)(tree, (node) => {
|
|
41
|
+
if (node.type === "heading" && node.depth === 1) {
|
|
42
|
+
if (currentHeading) {
|
|
43
|
+
sections[currentHeading] = currentContent.join("\n").trim();
|
|
44
|
+
}
|
|
45
|
+
currentHeading = extractHeadingText(node);
|
|
46
|
+
currentContent = [];
|
|
47
|
+
}
|
|
48
|
+
else if (currentHeading) {
|
|
49
|
+
const content = nodeToString(node);
|
|
50
|
+
if (content.trim()) {
|
|
51
|
+
currentContent.push(content.trim());
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
if (currentHeading) {
|
|
56
|
+
sections[currentHeading] = currentContent.join("\n").trim();
|
|
57
|
+
}
|
|
58
|
+
return sections;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=markdown.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.utils.js","sourceRoot":"","sources":["../../../src/mcp/utils/markdown.utils.ts"],"names":[],"mappings":";;;;;AAsEA,sDAgCC;AAtGD,qCAAkC;AAClC,gEAAuC;AACvC,uDAAyC;AAezC,SAAS,YAAY,CAAC,IAAiB;IACrC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC/B,OAAO,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;IAC7B,CAAC;IACD,IAAI,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,QAAQ;aACjB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAoB,CAAC,CAAC;aAClD,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IACD,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAKD,SAAS,kBAAkB,CAAC,IAAiB;IAC3C,IAAI,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC,QAAQ;aACjB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAoB,CAAC,CAAC;aAClD,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAyBD,SAAgB,qBAAqB,CAAC,QAAgB;IACpD,MAAM,IAAI,GAAG,IAAA,iBAAO,GAAE,CAAC,GAAG,CAAC,sBAAW,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAS,CAAC;IAChE,MAAM,QAAQ,GAAqB,EAAE,CAAC;IAEtC,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,IAAI,cAAc,GAAa,EAAE,CAAC;IAElC,IAAA,wBAAK,EAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;QACnB,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YAEhD,IAAI,cAAc,EAAE,CAAC;gBACnB,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9D,CAAC;YAGD,cAAc,GAAG,kBAAkB,CAAC,IAAmB,CAAC,CAAC;YACzD,cAAc,GAAG,EAAE,CAAC;QACtB,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAE1B,MAAM,OAAO,GAAG,YAAY,CAAC,IAAmB,CAAC,CAAC;YAClD,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBACnB,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IAGH,IAAI,cAAc,EAAE,CAAC;QACnB,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sanitizeMcpbConfigValue(value: string | undefined): string | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizeMcpbConfigValue = sanitizeMcpbConfigValue;
|
|
4
|
+
function sanitizeMcpbConfigValue(value) {
|
|
5
|
+
if (!value || value.trim() === "") {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
if (value.startsWith("${") && value.endsWith("}")) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=mcpb-workarounds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcpb-workarounds.js","sourceRoot":"","sources":["../../../src/mcp/utils/mcpb-workarounds.ts"],"names":[],"mappings":";;AA0BA,0DAaC;AAbD,SAAgB,uBAAuB,CACrC,KAAyB;IAEzB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IAGD,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface NgrokTunnelInfo {
|
|
2
|
+
publicUrl: string;
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class NgrokService {
|
|
6
|
+
private process;
|
|
7
|
+
private cleanupHandlersRegistered;
|
|
8
|
+
start(port: number): Promise<NgrokTunnelInfo>;
|
|
9
|
+
private isNgrokInstalled;
|
|
10
|
+
private waitForNgrok;
|
|
11
|
+
private getTunnelUrl;
|
|
12
|
+
private registerCleanupHandlers;
|
|
13
|
+
private cleanup;
|
|
14
|
+
getWebInterfaceUrl(): string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NgrokService = void 0;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const http_1 = __importDefault(require("http"));
|
|
9
|
+
class NgrokService {
|
|
10
|
+
process = null;
|
|
11
|
+
cleanupHandlersRegistered = false;
|
|
12
|
+
async start(port) {
|
|
13
|
+
if (!(await this.isNgrokInstalled())) {
|
|
14
|
+
throw new Error("ngrok is not installed.\n" +
|
|
15
|
+
"Install it with: npm install -g ngrok\n" +
|
|
16
|
+
"Or download from: https://ngrok.com/download\n" +
|
|
17
|
+
"Then setup auth: ngrok config add-authtoken <your-token>");
|
|
18
|
+
}
|
|
19
|
+
this.process = (0, child_process_1.spawn)("ngrok", ["http", port.toString()], {
|
|
20
|
+
stdio: "pipe",
|
|
21
|
+
});
|
|
22
|
+
if (!this.cleanupHandlersRegistered) {
|
|
23
|
+
this.registerCleanupHandlers();
|
|
24
|
+
this.cleanupHandlersRegistered = true;
|
|
25
|
+
}
|
|
26
|
+
this.process.on("error", (err) => {
|
|
27
|
+
throw new Error(`Failed to start ngrok: ${err.message}`);
|
|
28
|
+
});
|
|
29
|
+
this.process.on("exit", (code, _signal) => {
|
|
30
|
+
if (code !== 0 && code !== null) {
|
|
31
|
+
console.error(`ngrok exited with code ${code}`);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
await this.waitForNgrok();
|
|
35
|
+
const publicUrl = await this.getTunnelUrl();
|
|
36
|
+
return {
|
|
37
|
+
publicUrl,
|
|
38
|
+
apiUrl: "http://localhost:4040",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async isNgrokInstalled() {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
const check = (0, child_process_1.spawn)("which", ["ngrok"]);
|
|
44
|
+
check.on("close", (code) => resolve(code === 0));
|
|
45
|
+
check.on("error", () => resolve(false));
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async waitForNgrok(maxAttempts = 20, delayMs = 500) {
|
|
49
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
51
|
+
try {
|
|
52
|
+
await this.getTunnelUrl();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
throw new Error("ngrok failed to start in time.\n" +
|
|
59
|
+
"Make sure you have configured your auth token:\n" +
|
|
60
|
+
"ngrok config add-authtoken <your-token>");
|
|
61
|
+
}
|
|
62
|
+
async getTunnelUrl() {
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
http_1.default
|
|
65
|
+
.get("http://localhost:4040/api/tunnels", (res) => {
|
|
66
|
+
let data = "";
|
|
67
|
+
res.on("data", (chunk) => (data += chunk));
|
|
68
|
+
res.on("end", () => {
|
|
69
|
+
try {
|
|
70
|
+
const response = JSON.parse(data);
|
|
71
|
+
const tunnel = response.tunnels?.find((t) => t.proto === "https");
|
|
72
|
+
const publicUrl = tunnel?.public_url;
|
|
73
|
+
if (publicUrl) {
|
|
74
|
+
resolve(publicUrl);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
reject(new Error("No HTTPS tunnel found in ngrok API response"));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
reject(new Error(`Failed to parse ngrok API response: ${err}`));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
})
|
|
85
|
+
.on("error", (err) => {
|
|
86
|
+
reject(new Error(`Failed to connect to ngrok API: ${err.message}`));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
registerCleanupHandlers() {
|
|
91
|
+
process.on("SIGINT", () => {
|
|
92
|
+
console.log("\n\n🛑 Shutting down ngrok tunnel...");
|
|
93
|
+
this.cleanup();
|
|
94
|
+
process.exit(0);
|
|
95
|
+
});
|
|
96
|
+
process.on("SIGTERM", () => {
|
|
97
|
+
this.cleanup();
|
|
98
|
+
process.exit(0);
|
|
99
|
+
});
|
|
100
|
+
process.on("exit", () => {
|
|
101
|
+
this.cleanup();
|
|
102
|
+
});
|
|
103
|
+
process.on("uncaughtException", (err) => {
|
|
104
|
+
console.error("Uncaught exception:", err);
|
|
105
|
+
this.cleanup();
|
|
106
|
+
process.exit(1);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
cleanup() {
|
|
110
|
+
if (this.process && !this.process.killed) {
|
|
111
|
+
this.process.kill("SIGTERM");
|
|
112
|
+
this.process = null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
getWebInterfaceUrl() {
|
|
116
|
+
return "http://localhost:4040";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.NgrokService = NgrokService;
|
|
120
|
+
//# sourceMappingURL=ngrok.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngrok.service.js","sourceRoot":"","sources":["../../src/services/ngrok.service.ts"],"names":[],"mappings":"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"}
|