@milcho0604/velog-mcp 0.4.0 → 0.4.2

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/me.js CHANGED
@@ -8,11 +8,14 @@
8
8
  */
9
9
  import { QUERY_CURRENT_USER } from "./graphql.js";
10
10
  const cache = new WeakMap();
11
- export async function fetchCurrentUser(client) {
11
+ export async function fetchCurrentUser(client, signal) {
12
+ // ★ 캐시 적중도 취소를 존중한다. 여기서 빼면 '취소했는데 어떤 호출은 그냥
13
+ // 진행되는' 비일관이 생긴다 — 취소 규약은 경로마다 달라지면 안 된다.
14
+ signal?.throwIfAborted();
12
15
  const cached = cache.get(client);
13
16
  if (cached)
14
17
  return cached;
15
- const data = await client.request(QUERY_CURRENT_USER);
18
+ const data = await client.request(QUERY_CURRENT_USER, {}, { signal });
16
19
  if (!data.currentUser) {
17
20
  throw new Error('현재 로그인한 계정을 확인할 수 없습니다. 토큰이 만료됐거나 잘못됐습니다. ' +
18
21
  '(access_token 1시간 / refresh_token 30일)');
@@ -21,8 +24,8 @@ export async function fetchCurrentUser(client) {
21
24
  return data.currentUser;
22
25
  }
23
26
  /** username 을 생략한 도구들이 쓴다. */
24
- export async function resolveMyUsername(client) {
25
- const me = await fetchCurrentUser(client);
27
+ export async function resolveMyUsername(client, signal) {
28
+ const me = await fetchCurrentUser(client, signal);
26
29
  if (!me.username) {
27
30
  throw new Error('계정에 username 이 없습니다. 도구 인자로 username 을 직접 지정하세요.');
28
31
  }
package/dist/me.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"me.js","sourceRoot":"","sources":["../src/me.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AASlD,MAAM,KAAK,GAAG,IAAI,OAAO,EAA4B,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAmB;IACzD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAChC,kBAAkB,CAClB,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACd,4CAA4C;YAC3C,wCAAwC,CACzC,CAAC;IACH,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,WAAW,CAAC;AACzB,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAmB;IAC1D,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACd,kDAAkD,CAClD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC,QAAQ,CAAC;AACpB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC/C,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"me.js","sourceRoot":"","sources":["../src/me.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AASlD,MAAM,KAAK,GAAG,IAAI,OAAO,EAA4B,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,MAAmB,EACnB,MAAoB;IAEpB,6CAA6C;IAC7C,4CAA4C;IAC5C,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAChC,kBAAkB,EAClB,EAAE,EACF,EAAE,MAAM,EAAE,CACV,CAAC;IACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACd,4CAA4C;YAC3C,wCAAwC,CACzC,CAAC;IACH,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,WAAW,CAAC;AACzB,CAAC;AAED,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,MAAmB,EACnB,MAAoB;IAEpB,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACd,kDAAkD,CAClD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC,QAAQ,CAAC;AACpB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC/C,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC"}
@@ -15,6 +15,7 @@ import { mkdtemp, readdir, rm, stat, writeFile } from 'node:fs/promises';
15
15
  import { tmpdir } from 'node:os';
16
16
  import { join } from 'node:path';
17
17
  import { pathToFileURL } from 'node:url';
18
+ import { makeSerializer } from "../serial.js";
18
19
  import { dumpDom, screenshot } from "./chrome.js";
19
20
  import { MAX_AREA, MAX_DIM, buildDiagramHtml, parseAudit, } from "./page.js";
20
21
  import { buildCoverHtml } from "./cover.js";
@@ -26,16 +27,13 @@ import { buildCoverHtml } from "./cover.js";
26
27
  * 모델이 그림 다섯 장을 한 번에 요청하면 크롬 45개·6GB 가 된다.
27
28
  * 사용자 기기에서 도는 물건이 그러면 안 된다 — 다른 작업까지 같이 죽는다.
28
29
  *
29
- * 그림 한 장은 4초면 끝나므로 줄 세워도 체감 손해가 거의 없다.
30
- * 얻는 것(메모리 상한이 1GB 고정된다) 훨씬 크다.
30
+ * 그림 한 장은 4초면 끝나므로 줄 세워도 체감 손해가 거의 없다
31
+ * (실측 2026-08-07: 3.9초/장 60초에 15장). 얻는 것이 훨씬 크다.
32
+ *
33
+ * ★ 구현은 src/serial.ts 로 옮겼다. 업로드도 같은 이유로 줄이 필요해졌는데,
34
+ * 같은 코드를 두 벌 두면 한쪽만 고치게 된다.
31
35
  */
32
- let renderQueue = Promise.resolve();
33
- function serialize(task) {
34
- // 앞 작업이 실패해도 줄은 계속 이어져야 한다.
35
- const next = renderQueue.then(task, task);
36
- renderQueue = next.then(() => undefined, () => undefined);
37
- return next;
38
- }
36
+ const serialize = makeSerializer();
39
37
  const RENDER_PREFIX = 'velog-mcp-render-';
40
38
  const PROFILE_PREFIX = 'velog-mcp-chrome-';
41
39
  const KEEP_MS = 24 * 60 * 60 * 1000;
@@ -70,8 +68,16 @@ async function render(args, parse) {
70
68
  // 프로필만 finally 에서 지운다. 렌더 결과(dir)는 남겨야 하므로 밖에 둘 이유가 없다.
71
69
  let profileA = '';
72
70
  let profileB = '';
71
+ // ★ 결과 디렉터리는 **성공했을 때만** 남긴다. 예전엔 실패해도 남겨서,
72
+ // 감사 파싱이나 스크린샷이 반복 실패하면 HTML 과 쓰다 만 PNG 가 든 폴더가
73
+ // 매번 하나씩 쌓였다. 청소(sweepOld)는 다음 렌더가 돌 때만, 그것도 24시간이
74
+ // 지난 것만 거둬가므로 다시 안 그리면 영영 남는다.
75
+ // 실패한 산출물은 사용자가 열어볼 이유도 없다 — 경로를 돌려주지 못하니까.
76
+ let resultDir = '';
77
+ let succeeded = false;
73
78
  try {
74
79
  const dir = await mkdtemp(join(tmpdir(), RENDER_PREFIX));
80
+ resultDir = dir;
75
81
  // 크롬 두 번에 **서로 다른 프로필**을 준다. 산출물이 나오면 SIGKILL 하고 실제
76
82
  // 종료를 기다리지 않으므로, 같은 프로필을 재사용하면 앞선 크롬이 잠금을 놓기
77
83
  // 전에 다음 크롬이 같은 폴더를 열게 된다.
@@ -100,6 +106,7 @@ async function render(args, parse) {
100
106
  throw new Error('크롬이 PNG 를 만들지 못했습니다. 화면 크기가 비정상이거나(0 이하) ' +
101
107
  '크롬 실행이 중간에 끊겼을 수 있습니다.');
102
108
  }
109
+ succeeded = true;
103
110
  return {
104
111
  pngPath,
105
112
  htmlPath,
@@ -111,12 +118,15 @@ async function render(args, parse) {
111
118
  };
112
119
  }
113
120
  finally {
114
- // 크롬 프로필은 임시 산출물이라 항상 지운다. 렌더 결과(dir)는 남긴다 —
115
- // 사용자가 HTML 을 열어 손보거나 PNG 를 다시 쓸 수 있어야 한다.
121
+ // 크롬 프로필은 임시 산출물이라 항상 지운다. 렌더 결과(dir)는 **성공했을
122
+ // 때만** 남긴다 — 사용자가 HTML 을 열어 손보거나 PNG 를 다시 쓸 수 있어야 한다.
116
123
  for (const profile of [profileA, profileB]) {
117
124
  if (profile)
118
125
  await rm(profile, { recursive: true, force: true }).catch(() => { });
119
126
  }
127
+ if (!succeeded && resultDir) {
128
+ await rm(resultDir, { recursive: true, force: true }).catch(() => { });
129
+ }
120
130
  }
121
131
  }
122
132
  export function renderDiagram(spec, scale = 2) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * 줄 세우기.
3
+ *
4
+ * MCP 클라이언트는 도구를 **병렬로** 부른다. 이 저장소에는 그게 문제가 되는
5
+ * 자리가 두 종류 있다.
6
+ *
7
+ * ① 자원을 통째로 먹는 작업 — 렌더는 이미 이 방식으로 크롬 메모리를 1GB 에
8
+ * 묶어뒀다(render/index.ts 주석). 업로드도 같은 성격이다: 파일당 10MB 를
9
+ * 최대 60초간 들고 있는데 동시성 상한이 없으면 그대로 곱해진다.
10
+ *
11
+ * ② **읽고-합쳐-쓰는** 작업 — `velog_update_post` 는 기존 글을 읽어 생략 필드를
12
+ * 채운 뒤 전체를 교체한다. 벨로그에는 버전도 ETag 도 없다. 같은 글에
13
+ * '제목=A' 와 '본문=B' 가 동시에 오면 둘 다 옛 값을 읽고, 나중에 쓴 쪽이
14
+ * 앞선 변경을 지운다. 그런데 **둘 다 성공을 보고한다** — 사후 검증도 각자
15
+ * 자기가 보낸 값과 맞춰보므로 통과한다. 사용자는 제목이 사라진 걸 모른다.
16
+ *
17
+ * ②는 같은 대상(글 id·프로필)끼리만 줄을 세우면 되므로 키를 받는다.
18
+ * 다른 글끼리는 그대로 병렬로 돈다.
19
+ *
20
+ * ⚠️ 이건 **한 프로세스 안**에서만 유효하다. 사용자가 벨로그 웹에서 동시에
21
+ * 고치는 것은 막을 수 없다 — 그건 벨로그가 버전을 주지 않는 한 방법이 없다.
22
+ * rate limiter 와 같은 한계이고, 같은 이유로 여기에 적어둔다.
23
+ */
24
+ type Task<T> = () => Promise<T>;
25
+ /** 앞 작업이 끝나야 다음이 시작한다. 앞이 실패해도 줄은 이어진다. */
26
+ export declare function makeSerializer(): <T>(task: Task<T>) => Promise<T>;
27
+ /**
28
+ * 키가 같은 작업끼리만 줄을 세운다.
29
+ *
30
+ * ★ 다 쓴 키는 지운다. 안 지우면 글을 고칠 때마다 항목이 하나씩 쌓여
31
+ * 오래 켜둔 서버에서 계속 자란다. 대기자 수를 세다가 0 이 되면 버린다.
32
+ */
33
+ export interface KeyedSerializer {
34
+ <T>(key: string, task: Task<T>): Promise<T>;
35
+ /**
36
+ * 지금 살아 있는 줄 수. **테스트 전용.**
37
+ * 정리가 되는지 밖에서 볼 방법이 없으면 그 테스트는 거짓 초록이 된다 —
38
+ * 실제로 `lanes.delete()` 를 지워도 통과하는 테스트를 썼다가 코덱스에 잡혔다.
39
+ */
40
+ laneCount(): number;
41
+ }
42
+ export declare function makeKeyedSerializer(): KeyedSerializer;
43
+ /**
44
+ * ★★ 쓰기 줄은 **저장소 전체에 하나뿐이어야 한다.**
45
+ *
46
+ * 처음엔 모듈마다 `makeKeyedSerializer()` 를 따로 만들었다. 그러면 키가 같아도
47
+ * 줄이 다르다 — `velog_update_draft` 와 `velog_publish_draft` 를 같은 글에 동시에
48
+ * 부르면 서로를 못 본다. 코덱스 교차검증에서 실제로 재현됐다: 같은 글의 사전
49
+ * 조회가 겹쳤고(2), 발행 mutation 뒤에 초안 수정이 덮어써 최종 상태가 다시
50
+ * 초안이 됐다. 도구 이름이 달라도 **대상이 같으면 같은 줄**이어야 한다.
51
+ *
52
+ * 키 규약: 글은 `post:<id>`, 새 글은 `post:new`, 프로필은 `profile`.
53
+ */
54
+ export declare const serializeWrite: KeyedSerializer;
55
+ /** 테스트에서만 쓴다 — 줄이 실제로 비워지는지 본다. */
56
+ export declare const __testing: {
57
+ makeKeyedSerializer: typeof makeKeyedSerializer;
58
+ makeSerializer: typeof makeSerializer;
59
+ };
60
+ export {};
package/dist/serial.js ADDED
@@ -0,0 +1,68 @@
1
+ /**
2
+ * 줄 세우기.
3
+ *
4
+ * MCP 클라이언트는 도구를 **병렬로** 부른다. 이 저장소에는 그게 문제가 되는
5
+ * 자리가 두 종류 있다.
6
+ *
7
+ * ① 자원을 통째로 먹는 작업 — 렌더는 이미 이 방식으로 크롬 메모리를 1GB 에
8
+ * 묶어뒀다(render/index.ts 주석). 업로드도 같은 성격이다: 파일당 10MB 를
9
+ * 최대 60초간 들고 있는데 동시성 상한이 없으면 그대로 곱해진다.
10
+ *
11
+ * ② **읽고-합쳐-쓰는** 작업 — `velog_update_post` 는 기존 글을 읽어 생략 필드를
12
+ * 채운 뒤 전체를 교체한다. 벨로그에는 버전도 ETag 도 없다. 같은 글에
13
+ * '제목=A' 와 '본문=B' 가 동시에 오면 둘 다 옛 값을 읽고, 나중에 쓴 쪽이
14
+ * 앞선 변경을 지운다. 그런데 **둘 다 성공을 보고한다** — 사후 검증도 각자
15
+ * 자기가 보낸 값과 맞춰보므로 통과한다. 사용자는 제목이 사라진 걸 모른다.
16
+ *
17
+ * ②는 같은 대상(글 id·프로필)끼리만 줄을 세우면 되므로 키를 받는다.
18
+ * 다른 글끼리는 그대로 병렬로 돈다.
19
+ *
20
+ * ⚠️ 이건 **한 프로세스 안**에서만 유효하다. 사용자가 벨로그 웹에서 동시에
21
+ * 고치는 것은 막을 수 없다 — 그건 벨로그가 버전을 주지 않는 한 방법이 없다.
22
+ * rate limiter 와 같은 한계이고, 같은 이유로 여기에 적어둔다.
23
+ */
24
+ /** 앞 작업이 끝나야 다음이 시작한다. 앞이 실패해도 줄은 이어진다. */
25
+ export function makeSerializer() {
26
+ let queue = Promise.resolve();
27
+ return (task) => {
28
+ // 성공·실패 둘 다에 task 를 걸어 앞 작업의 실패가 줄을 끊지 않게 한다.
29
+ const next = queue.then(task, task);
30
+ queue = next.then(() => undefined, () => undefined);
31
+ return next;
32
+ };
33
+ }
34
+ export function makeKeyedSerializer() {
35
+ const lanes = new Map();
36
+ const serialize = (key, task) => {
37
+ const lane = lanes.get(key) ?? { tail: Promise.resolve(), waiting: 0 };
38
+ lanes.set(key, lane);
39
+ lane.waiting++;
40
+ const next = lane.tail.then(task, task);
41
+ lane.tail = next.then(() => undefined, () => undefined);
42
+ // ★ 정리는 `next` 가 아니라 `lane.tail` 에 건다. next 는 호출자에게 그대로
43
+ // 돌려주므로, 여기에 .then 을 걸면 호출자가 잡지 않은 거절이 하나 더 생긴다.
44
+ void lane.tail.then(() => {
45
+ lane.waiting--;
46
+ if (lane.waiting === 0 && lanes.get(key) === lane)
47
+ lanes.delete(key);
48
+ });
49
+ return next;
50
+ };
51
+ serialize.laneCount = () => lanes.size;
52
+ return serialize;
53
+ }
54
+ /**
55
+ * ★★ 쓰기 줄은 **저장소 전체에 하나뿐이어야 한다.**
56
+ *
57
+ * 처음엔 모듈마다 `makeKeyedSerializer()` 를 따로 만들었다. 그러면 키가 같아도
58
+ * 줄이 다르다 — `velog_update_draft` 와 `velog_publish_draft` 를 같은 글에 동시에
59
+ * 부르면 서로를 못 본다. 코덱스 교차검증에서 실제로 재현됐다: 같은 글의 사전
60
+ * 조회가 겹쳤고(2), 발행 mutation 뒤에 초안 수정이 덮어써 최종 상태가 다시
61
+ * 초안이 됐다. 도구 이름이 달라도 **대상이 같으면 같은 줄**이어야 한다.
62
+ *
63
+ * 키 규약: 글은 `post:<id>`, 새 글은 `post:new`, 프로필은 `profile`.
64
+ */
65
+ export const serializeWrite = makeKeyedSerializer();
66
+ /** 테스트에서만 쓴다 — 줄이 실제로 비워지는지 본다. */
67
+ export const __testing = { makeKeyedSerializer, makeSerializer };
68
+ //# sourceMappingURL=serial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serial.js","sourceRoot":"","sources":["../src/serial.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,2CAA2C;AAC3C,MAAM,UAAU,cAAc;IAC7B,IAAI,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;IAChD,OAAO,CAAI,IAAa,EAAc,EAAE;QACvC,8CAA8C;QAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpC,KAAK,GAAG,IAAI,CAAC,IAAI,CAChB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC;AAkBD,MAAM,UAAU,mBAAmB;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuD,CAAC;IAE7E,MAAM,SAAS,GAAG,CAAI,GAAW,EAAE,IAAa,EAAc,EAAE;QAC/D,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACvE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,OAAO,EAAE,CAAC;QAEf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;QACF,wDAAwD;QACxD,mDAAmD;QACnD,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACxB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;gBAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;IACF,SAAS,CAAC,SAAS,GAAG,GAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;IAC/C,OAAO,SAAS,CAAC;AAClB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,EAAE,CAAC;AAEpD,mCAAmC;AACnC,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,mBAAmB,EAAE,cAAc,EAAE,CAAC"}
@@ -15,6 +15,7 @@ import { toUrlSlug, isSafeImageUrl } from "../slug.js";
15
15
  import { resolveMyUsername } from "../me.js";
16
16
  import { assertOwned, assertOwnsSeries } from "../ownership.js";
17
17
  import { READ_ONLY } from "./posts.js";
18
+ import { serializeWrite } from "../serial.js";
18
19
  /**
19
20
  * ★ 발행 차단 지점. 이 값은 파라미터가 아니라 상수다.
20
21
  * true = 임시저장(남에게 보이지 않음), false = 발행(되돌릴 수 없음).
@@ -83,7 +84,9 @@ export function registerDraftTools(server, client) {
83
84
  },
84
85
  // 되돌릴 수 있는 쓰기다 — 비공개 초안이므로 파괴적이지 않다.
85
86
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false },
86
- }, async ({ title, body, tags, url_slug, thumbnail, series_id }) => {
87
+ }, async ({ title, body, tags, url_slug, thumbnail, series_id }, extra) =>
88
+ // ★ 같은 대상에 대한 쓰기는 줄을 세운다 — 이유는 src/serial.ts
89
+ serializeWrite('post:new', async () => {
87
90
  client.requireAuth('velog_create_draft');
88
91
  if (series_id)
89
92
  await assertOwnsSeries(client, series_id, 'velog_create_draft');
@@ -102,7 +105,7 @@ export function registerDraftTools(server, client) {
102
105
  if (series_id)
103
106
  input['series_id'] = series_id;
104
107
  // mutate 는 재시도하지 않는다 — 응답 유실 시 초안이 중복 생성된다.
105
- const data = await client.mutate(MUTATION_WRITE_POST, { input });
108
+ const data = await client.mutate(MUTATION_WRITE_POST, { input }, { signal: extra.signal });
106
109
  assertStayedDraft(data.writePost);
107
110
  // ★ 벨로그는 임시저장 생성 시 series_id 를 조용히 버린다:
108
111
  // // apps/server/src/services/PostApiService/index.mts
@@ -115,7 +118,7 @@ export function registerDraftTools(server, client) {
115
118
  ' 한 번 호출하면 그때 실제로 붙습니다.'
116
119
  : '';
117
120
  return textResult(draftResult(data.writePost, '저장') + seriesNote);
118
- });
121
+ }));
119
122
  server.registerTool('velog_update_draft', {
120
123
  title: '벨로그 초안 수정',
121
124
  description: '기존 초안을 **통째로 교체**한다. 부분 수정이 아니다. ' +
@@ -139,7 +142,9 @@ export function registerDraftTools(server, client) {
139
142
  // ★ destructive 가 맞다. 생략 필드가 보존되지 않고 초기화된다 —
140
143
  // MCP 명세상 destructiveHint:false 는 '추가만 한다'는 뜻이라 거짓이 된다.
141
144
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true },
142
- }, async ({ id, title, body, tags, url_slug, thumbnail, series_id }) => {
145
+ }, async ({ id, title, body, tags, url_slug, thumbnail, series_id }, extra) =>
146
+ // ★ 같은 대상에 대한 쓰기는 줄을 세운다 — 이유는 src/serial.ts
147
+ serializeWrite(`post:${id}`, async () => {
143
148
  client.requireAuth('velog_update_draft');
144
149
  // ★ 두 가지를 확인한 뒤에야 수정한다.
145
150
  // ① 내 글인가 — 벨로그 서버가 edit 에서 소유권을 안 본다(ownership.ts)
@@ -172,9 +177,7 @@ export function registerDraftTools(server, client) {
172
177
  input['thumbnail'] = thumbnail;
173
178
  if (series_id)
174
179
  input['series_id'] = series_id;
175
- const data = await client.mutate(MUTATION_EDIT_POST, {
176
- input,
177
- });
180
+ const data = await client.mutate(MUTATION_EDIT_POST, { input }, { signal: extra.signal });
178
181
  // ★ editPost 의 응답으로는 사후 상태를 알 수 없다. 공식 구현이
179
182
  // `return { ...post, url_slug: data.url_slug }` 로 **갱신 전에 읽은**
180
183
  // post 를 돌려주고 url_slug 만 덮기 때문이다
@@ -196,7 +199,7 @@ export function registerDraftTools(server, client) {
196
199
  // 그걸로 문구를 만들면 제목을 바꿔도 옛 제목이 표시된다.
197
200
  // 이미 재조회했으므로 그 결과를 얹는다.
198
201
  return textResult(draftResult({ ...data.editPost, title: after.post.title ?? data.editPost.title ?? null }, '수정'));
199
- });
202
+ }));
200
203
  server.registerTool('velog_list_drafts', {
201
204
  title: '내 초안 목록',
202
205
  description: '내 임시저장 글 목록. 초안을 이어 쓰거나 수정하기 전에 id 를 여기서 확인한다.',
@@ -1 +1 @@
1
- {"version":3,"file":"drafts.js","sourceRoot":"","sources":["../../src/tools/drafts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"drafts.js","sourceRoot":"","sources":["../../src/tools/drafts.ts"],"names":[],"mappings":"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"}
@@ -15,6 +15,31 @@ import { slugify } from "../slug.js";
15
15
  import { fetchAllPosts } from "./stats.js";
16
16
  import { READ_ONLY } from "./posts.js";
17
17
  import { resolveMyUsername } from "../me.js";
18
+ /** 벨로그 커넥션 풀(limit 5)을 배려하는 요청 간격. */
19
+ const GAP_MS = 250;
20
+ /**
21
+ * 한 호출에 쓸 수 있는 시간.
22
+ *
23
+ * ★ 왜 필요한가 — MCP SDK 의 클라이언트측 기본 요청 타임아웃은 60초다
24
+ * (shared/protocol.js: DEFAULT_REQUEST_TIMEOUT_MSEC = 60000).
25
+ * 그런데 이 도구는 글 한 편마다 상세를 따로 받는다. 실측(2026-08-07, 벨로그
26
+ * 공개 글 3편): 본문 왕복 평균 1,313ms. 간격 250ms 를 더하면 편당 약 1.5초다.
27
+ * **기본값 limit=50 이면 약 78초** — 60초를 넘는다. 즉 기본 인자로 부르면
28
+ * 클라이언트가 먼저 포기했고, 그런데도 루프는 계속 돌며 파일을 썼다.
29
+ * 화면에는 '실패'가 뜨는데 디스크에는 파일이 생기는 상태였다.
30
+ *
31
+ * 그래서 60초 안쪽에서 **우리가 먼저 멈추고 무엇을 했는지 보고한다.**
32
+ * 파일 이름이 글 순서로 정해지므로 같은 out_dir 로 다시 부르면 그대로 이어진다.
33
+ */
34
+ const TIME_BUDGET_MS = 50_000;
35
+ /**
36
+ * 한 편을 더 시작하기 전에 남겨둬야 할 여유.
37
+ *
38
+ * 데드라인 직전에 루프로 들어가면 간격 250ms 에 상세 요청 한 번이 통째로 붙는다.
39
+ * 실측 왕복이 1.3초대이므로 3초면 정상 한 편은 넉넉히 들어가고, 안 들어갈 만하면
40
+ * 아예 시작하지 않아 예산을 지킨다.
41
+ */
42
+ const PER_POST_RESERVE_MS = 3_000;
18
43
  /** YAML 문자열 값. 따옴표·백슬래시를 이스케이프해 프론트매터가 깨지지 않게 한다. */
19
44
  function yamlString(value) {
20
45
  return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
@@ -80,28 +105,48 @@ export function registerExportTools(server, client) {
80
105
  // 벨로그 쪽 상태는 안 바뀌지만 로컬 파일은 '덮어쓴다'. MCP 명세상
81
106
  // destructiveHint:false 는 '추가만 한다'는 뜻이라 거짓이 된다.
82
107
  annotations: { ...READ_ONLY, readOnlyHint: false, destructiveHint: true },
83
- }, async ({ username, out_dir, limit }) => {
84
- const target = username ?? (await resolveMyUsername(client));
108
+ }, async ({ username, out_dir, limit }, extra) => {
109
+ // 예산 시계는 **핸들러가 시작하자마자** 켠다. 예전엔 목록 조회가 끝난
110
+ // 뒤에 켰는데, 그 앞의 계정 조회·목록 4페이지가 이미 몇 초를 먹는다.
111
+ // '한 호출에 쓸 수 있는 시간'을 재는데 그 앞을 빼면 예산이 아니다.
112
+ const deadline = Date.now() + TIME_BUDGET_MS;
113
+ const target = username ?? (await resolveMyUsername(client, extra.signal));
85
114
  const dir = resolve(out_dir);
86
115
  await mkdir(dir, { recursive: true });
87
116
  const maxPages = Math.ceil(limit / 50);
88
- const { posts } = await fetchAllPosts(client, target, maxPages);
117
+ const { posts } = await fetchAllPosts(client, target, maxPages, extra.signal);
89
118
  const targets = posts.slice(0, limit);
90
119
  if (targets.length === 0)
91
120
  return textResult(`@${target} 의 공개 글이 없습니다.`);
92
121
  const written = [];
93
122
  const failed = [];
123
+ /** 다 못 돈 이유. 없으면 끝까지 돈 것이다. */
124
+ let stoppedBy = null;
94
125
  for (const [index, summary] of targets.entries()) {
126
+ // ★ 클라이언트가 취소했으면 즉시 멈춘다. 여기서 안 보면 사용자는 이미
127
+ // 포기했는데 파일은 계속 쌓인다 — 화면과 디스크가 어긋난다.
128
+ if (extra.signal.aborted) {
129
+ stoppedBy = '취소';
130
+ break;
131
+ }
132
+ // ★ 시간 예산. 이유는 TIME_BUDGET_MS 주석 참고.
133
+ // ★ 남은 시간이 '한 편 분량'도 안 되면 시작하지 않는다. 데드라인
134
+ // 직전에 들어가면 간격 250ms + 상세 요청(최대 재시도 예산)이
135
+ // 그대로 붙어 예산을 훌쩍 넘긴다.
136
+ if (Date.now() + PER_POST_RESERVE_MS >= deadline) {
137
+ stoppedBy = '시간';
138
+ break;
139
+ }
95
140
  // 벨로그 커넥션 풀(limit 5)을 배려한다. 몰아치면 상대가 먼저 죽는다.
96
141
  if (index > 0)
97
- await new Promise((r) => setTimeout(r, 250));
142
+ await new Promise((r) => setTimeout(r, GAP_MS));
98
143
  try {
99
144
  // 목록에는 body 가 없으므로 한 편씩 상세를 받는다.
100
145
  const data = await client.request(QUERY_POST,
101
146
  // url_slug 가 없으면 id 로 조회한다.
102
147
  summary.url_slug
103
148
  ? { input: { username: target, url_slug: summary.url_slug } }
104
- : { input: { id: summary.id } });
149
+ : { input: { id: summary.id } }, { signal: extra.signal });
105
150
  if (!data.post) {
106
151
  failed.push(`${summary.title} (본문 조회 실패)`);
107
152
  continue;
@@ -111,16 +156,32 @@ export function registerExportTools(server, client) {
111
156
  written.push(name);
112
157
  }
113
158
  catch (error) {
159
+ if (extra.signal.aborted) {
160
+ stoppedBy = '취소';
161
+ break;
162
+ }
114
163
  const reason = error instanceof Error ? error.message : String(error);
115
164
  failed.push(`${summary.title} — ${reason}`);
116
165
  }
117
166
  }
167
+ const done = written.length + failed.length;
118
168
  const lines = [
119
169
  `✅ ${written.length}편을 저장했습니다.`,
120
170
  '',
121
171
  `- 위치: ${dir}`,
122
172
  `- 형식: YAML 프론트매터 + 마크다운 본문`,
123
173
  ];
174
+ if (stoppedBy !== null) {
175
+ const left = targets.length - done;
176
+ lines.push('', stoppedBy === '취소'
177
+ ? `⏹️ 요청이 취소되어 ${done}/${targets.length}편에서 멈췄습니다.`
178
+ : `⏱️ ${TIME_BUDGET_MS / 1000}초 예산에 도달해 ${done}/${targets.length}편에서 멈췄습니다.`, done === 0
179
+ ? '준비 조회(계정·글 목록)만으로 예산을 다 썼습니다. 벨로그가 느린 ' +
180
+ '상태일 수 있으니 잠시 뒤 다시 시도하세요 — limit 을 줄여도 소용없습니다.'
181
+ : `남은 ${left}편은 저장되지 않았습니다. **같은 out_dir 로 다시 부르면** ` +
182
+ '이미 받은 파일을 덮어쓰며 이어집니다(파일 이름이 글 순서로 정해집니다). ' +
183
+ '한 번에 끝내려면 limit 을 줄여 나눠 부르세요.');
184
+ }
124
185
  if (failed.length > 0) {
125
186
  lines.push('', `⚠️ ${failed.length}편 실패:`, ...failed.slice(0, 10).map((f) => ` - ${f}`));
126
187
  if (failed.length > 10)
@@ -1 +1 @@
1
- {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/tools/export.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,qDAAqD;AACrD,SAAS,UAAU,CAAC,KAAa;IAChC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAqB,EAAE,QAAgB;IACjE,mDAAmD;IACnD,kCAAkC;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG;QACb,KAAK;QACL,UAAU,UAAU,CAAC,KAAK,CAAC,EAAE;QAC7B,SAAS,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE;QACpD,SAAS,UAAU,CAAC,IAAI,CAAC,EAAE;QAC3B,QAAQ,UAAU,CAAC,qBAAqB,QAAQ,IAAI,IAAI,EAAE,CAAC,EAAE;KAC7D,CAAC;IACF,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,WAAW,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,EAAE,UAAU,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,IAAI,IAAI,CAAC,UAAU;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjD,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5C,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAEtB,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC;AACpD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAa;IACvD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9C,OAAO,GAAG,MAAM,IAAI,IAAI,IAAI,UAAU,KAAK,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,MAAmB;IACzE,MAAM,CAAC,YAAY,CAClB,oBAAoB,EACpB;QACC,KAAK,EAAE,WAAW;QAClB,WAAW,EACV,6CAA6C;YAC7C,6BAA6B;YAC7B,iDAAiD;YACjD,kCAAkC;QACnC,WAAW,EAAE;YACZ,QAAQ,EAAE,CAAC;iBACT,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,yBAAyB,CAAC;YACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAC3D,KAAK,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,EAAE;iBACL,GAAG,CAAC,CAAC,CAAC;iBACN,GAAG,CAAC,GAAG,CAAC;iBACR,OAAO,CAAC,EAAE,CAAC;iBACX,QAAQ,CAAC,YAAY,CAAC;SACxB;QACD,0CAA0C;QAC1C,gDAAgD;QAChD,WAAW,EAAE,EAAE,GAAG,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE;KACzE,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QACtC,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACvC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC,IAAI,MAAM,gBAAgB,CAAC,CAAC;QAExE,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAClD,6CAA6C;YAC7C,IAAI,KAAK,GAAG,CAAC;gBAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC;gBACJ,iCAAiC;gBACjC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAChC,UAAU;gBACV,4BAA4B;gBAC5B,OAAO,CAAC,QAAQ;oBACf,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE;oBAC7D,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,CAChC,CAAC;gBACF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBAChB,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,aAAa,CAAC,CAAC;oBAC3C,SAAS;gBACV,CAAC;gBACD,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACrE,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;gBACxE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACtE,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;YAC7C,CAAC;QACF,CAAC;QAED,MAAM,KAAK,GAAG;YACb,KAAK,OAAO,CAAC,MAAM,YAAY;YAC/B,EAAE;YACF,SAAS,GAAG,EAAE;YACd,4BAA4B;SAC5B,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CACT,EAAE,EACF,MAAM,MAAM,CAAC,MAAM,OAAO,EAC1B,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAC7C,CAAC;YACF,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC,CACD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/tools/export.ts"],"names":[],"mappings":"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"}