@hualinge/relay-mcp-server 0.1.3
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 +21 -0
- package/README.md +11 -0
- package/dist/collab.d.ts +8 -0
- package/dist/collab.d.ts.map +1 -0
- package/dist/collab.js +47 -0
- package/dist/collab.js.map +1 -0
- package/dist/dare.d.ts +4 -0
- package/dist/dare.d.ts.map +1 -0
- package/dist/dare.js +46 -0
- package/dist/dare.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/memory.d.ts +8 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +47 -0
- package/dist/memory.js.map +1 -0
- package/dist/server-toolsets.d.ts +13 -0
- package/dist/server-toolsets.d.ts.map +1 -0
- package/dist/server-toolsets.js +119 -0
- package/dist/server-toolsets.js.map +1 -0
- package/dist/tools/callback-memory-tools.d.ts +46 -0
- package/dist/tools/callback-memory-tools.d.ts.map +1 -0
- package/dist/tools/callback-memory-tools.js +59 -0
- package/dist/tools/callback-memory-tools.js.map +1 -0
- package/dist/tools/callback-outbox.d.ts +15 -0
- package/dist/tools/callback-outbox.d.ts.map +1 -0
- package/dist/tools/callback-outbox.js +162 -0
- package/dist/tools/callback-outbox.js.map +1 -0
- package/dist/tools/callback-retry.d.ts +14 -0
- package/dist/tools/callback-retry.d.ts.map +1 -0
- package/dist/tools/callback-retry.js +58 -0
- package/dist/tools/callback-retry.js.map +1 -0
- package/dist/tools/callback-tools.d.ts +444 -0
- package/dist/tools/callback-tools.d.ts.map +1 -0
- package/dist/tools/callback-tools.js +771 -0
- package/dist/tools/callback-tools.js.map +1 -0
- package/dist/tools/evidence-tools.d.ts +36 -0
- package/dist/tools/evidence-tools.d.ts.map +1 -0
- package/dist/tools/evidence-tools.js +87 -0
- package/dist/tools/evidence-tools.js.map +1 -0
- package/dist/tools/file-tools.d.ts +78 -0
- package/dist/tools/file-tools.d.ts.map +1 -0
- package/dist/tools/file-tools.js +178 -0
- package/dist/tools/file-tools.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +18 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/limb-tools.d.ts +113 -0
- package/dist/tools/limb-tools.d.ts.map +1 -0
- package/dist/tools/limb-tools.js +120 -0
- package/dist/tools/limb-tools.js.map +1 -0
- package/dist/tools/reflect-tools.d.ts +23 -0
- package/dist/tools/reflect-tools.d.ts.map +1 -0
- package/dist/tools/reflect-tools.js +52 -0
- package/dist/tools/reflect-tools.js.map +1 -0
- package/dist/tools/rich-block-rules-tool.d.ts +17 -0
- package/dist/tools/rich-block-rules-tool.d.ts.map +1 -0
- package/dist/tools/rich-block-rules-tool.js +36 -0
- package/dist/tools/rich-block-rules-tool.js.map +1 -0
- package/dist/tools/schedule-tools.d.ts +134 -0
- package/dist/tools/schedule-tools.d.ts.map +1 -0
- package/dist/tools/schedule-tools.js +397 -0
- package/dist/tools/schedule-tools.js.map +1 -0
- package/dist/tools/session-chain-tools.d.ts +99 -0
- package/dist/tools/session-chain-tools.d.ts.map +1 -0
- package/dist/tools/session-chain-tools.js +288 -0
- package/dist/tools/session-chain-tools.js.map +1 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/path-utils.d.ts +6 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +63 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/dist/utils/path-validator.d.ts +45 -0
- package/dist/utils/path-validator.d.ts.map +1 -0
- package/dist/utils/path-validator.js +126 -0
- package/dist/utils/path-validator.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* *
|
|
3
|
+
* * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Callback outbox persistence for at-least-once delivery
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from 'node:crypto';
|
|
10
|
+
import { existsSync } from 'node:fs';
|
|
11
|
+
import { mkdir, readdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { getRetryDelaysMs, postJsonWithRetry } from './callback-retry.js';
|
|
15
|
+
const DEFAULT_OUTBOX_MAX_FLUSH_BATCH = 20;
|
|
16
|
+
const DEFAULT_OUTBOX_MAX_ATTEMPTS = 10;
|
|
17
|
+
const OUTBOX_FILE_SUFFIX = '.json';
|
|
18
|
+
function parseIntEnv(raw) {
|
|
19
|
+
if (!raw)
|
|
20
|
+
return null;
|
|
21
|
+
const parsed = Number.parseInt(raw.trim(), 10);
|
|
22
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
23
|
+
}
|
|
24
|
+
function isOutboxEnabled() {
|
|
25
|
+
const raw = (process.env['OFFICE_CLAW_CALLBACK_OUTBOX_ENABLED'] ?? 'true').toLowerCase();
|
|
26
|
+
return raw !== '0' && raw !== 'false' && raw !== 'off';
|
|
27
|
+
}
|
|
28
|
+
function getOutboxDir() {
|
|
29
|
+
const fromEnv = process.env['OFFICE_CLAW_CALLBACK_OUTBOX_DIR'];
|
|
30
|
+
if (fromEnv && fromEnv.trim().length > 0)
|
|
31
|
+
return fromEnv;
|
|
32
|
+
return join(homedir(), '.office-claw', 'callback-outbox');
|
|
33
|
+
}
|
|
34
|
+
function getOutboxMaxFlushBatch() {
|
|
35
|
+
const parsed = parseIntEnv(process.env['OFFICE_CLAW_CALLBACK_OUTBOX_MAX_FLUSH_BATCH']);
|
|
36
|
+
if (parsed === null || parsed < 0)
|
|
37
|
+
return DEFAULT_OUTBOX_MAX_FLUSH_BATCH;
|
|
38
|
+
return parsed;
|
|
39
|
+
}
|
|
40
|
+
function getOutboxMaxAttempts() {
|
|
41
|
+
const parsed = parseIntEnv(process.env['OFFICE_CLAW_CALLBACK_OUTBOX_MAX_ATTEMPTS']);
|
|
42
|
+
if (parsed === null || parsed < 0)
|
|
43
|
+
return DEFAULT_OUTBOX_MAX_ATTEMPTS;
|
|
44
|
+
return parsed;
|
|
45
|
+
}
|
|
46
|
+
function parseOutboxEntry(raw) {
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
if (typeof parsed.id !== 'string' ||
|
|
50
|
+
typeof parsed.queuedAt !== 'number' ||
|
|
51
|
+
typeof parsed.apiUrl !== 'string' ||
|
|
52
|
+
typeof parsed.path !== 'string' ||
|
|
53
|
+
typeof parsed.attempts !== 'number' ||
|
|
54
|
+
typeof parsed.lastError !== 'string' ||
|
|
55
|
+
typeof parsed.body !== 'object' ||
|
|
56
|
+
parsed.body === null) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return parsed;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function enqueueOutbox(entry) {
|
|
66
|
+
try {
|
|
67
|
+
const dir = getOutboxDir();
|
|
68
|
+
await mkdir(dir, { recursive: true });
|
|
69
|
+
const file = join(dir, `${entry.queuedAt}-${entry.id}${OUTBOX_FILE_SUFFIX}`);
|
|
70
|
+
await writeFile(file, JSON.stringify(entry), 'utf8');
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function flushOutbox() {
|
|
78
|
+
if (!isOutboxEnabled())
|
|
79
|
+
return;
|
|
80
|
+
const dir = getOutboxDir();
|
|
81
|
+
if (!existsSync(dir))
|
|
82
|
+
return;
|
|
83
|
+
const retryDelaysMs = getRetryDelaysMs();
|
|
84
|
+
const maxFlushBatch = getOutboxMaxFlushBatch();
|
|
85
|
+
const maxAttempts = getOutboxMaxAttempts();
|
|
86
|
+
const files = (await readdir(dir))
|
|
87
|
+
.filter((name) => name.endsWith(OUTBOX_FILE_SUFFIX) && !name.endsWith('.processing'))
|
|
88
|
+
.sort()
|
|
89
|
+
.slice(0, maxFlushBatch);
|
|
90
|
+
for (const name of files) {
|
|
91
|
+
const originalPath = join(dir, name);
|
|
92
|
+
const processingPath = `${originalPath}.processing`;
|
|
93
|
+
try {
|
|
94
|
+
await rename(originalPath, processingPath);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const raw = await readFile(processingPath, 'utf8');
|
|
101
|
+
const entry = parseOutboxEntry(raw);
|
|
102
|
+
if (!entry || entry.attempts >= maxAttempts) {
|
|
103
|
+
await unlink(processingPath);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const replay = await postJsonWithRetry(`${entry.apiUrl}${entry.path}`, JSON.stringify(entry.body), retryDelaysMs);
|
|
107
|
+
if (replay.ok) {
|
|
108
|
+
await unlink(processingPath);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (!replay.failure.retryable || entry.attempts + 1 >= maxAttempts) {
|
|
112
|
+
await unlink(processingPath);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const updated = {
|
|
116
|
+
...entry,
|
|
117
|
+
attempts: entry.attempts + 1,
|
|
118
|
+
lastError: replay.failure.error,
|
|
119
|
+
};
|
|
120
|
+
await writeFile(processingPath, JSON.stringify(updated), 'utf8');
|
|
121
|
+
await rename(processingPath, originalPath);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
try {
|
|
125
|
+
await rename(processingPath, originalPath);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Keep best-effort semantics.
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export async function sendCallbackRequest(request, options) {
|
|
134
|
+
const enableOutbox = options?.enableOutbox === true && isOutboxEnabled();
|
|
135
|
+
if (enableOutbox)
|
|
136
|
+
await flushOutbox();
|
|
137
|
+
const retryDelaysMs = getRetryDelaysMs();
|
|
138
|
+
const payload = JSON.stringify(request.body);
|
|
139
|
+
const result = await postJsonWithRetry(`${request.apiUrl}${request.path}`, payload, retryDelaysMs);
|
|
140
|
+
if (result.ok)
|
|
141
|
+
return { ok: true, data: result.data };
|
|
142
|
+
if (enableOutbox && result.failure.retryable) {
|
|
143
|
+
const queuedAt = Date.now();
|
|
144
|
+
const queued = await enqueueOutbox({
|
|
145
|
+
id: randomUUID(),
|
|
146
|
+
queuedAt,
|
|
147
|
+
apiUrl: request.apiUrl,
|
|
148
|
+
path: request.path,
|
|
149
|
+
body: request.body,
|
|
150
|
+
attempts: 0,
|
|
151
|
+
lastError: result.failure.error,
|
|
152
|
+
});
|
|
153
|
+
if (queued) {
|
|
154
|
+
return {
|
|
155
|
+
ok: true,
|
|
156
|
+
data: { status: 'queued_for_retry', queuedAt },
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return { ok: false, error: result.failure.error };
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=callback-outbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback-outbox.js","sourceRoot":"","sources":["../../src/tools/callback-outbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface CallbackPostFailure {
|
|
2
|
+
error: string;
|
|
3
|
+
retryable: boolean;
|
|
4
|
+
}
|
|
5
|
+
export type CallbackPostResult = {
|
|
6
|
+
ok: true;
|
|
7
|
+
data: unknown;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
failure: CallbackPostFailure;
|
|
11
|
+
};
|
|
12
|
+
export declare function getRetryDelaysMs(): number[];
|
|
13
|
+
export declare function postJsonWithRetry(url: string, payload: string, retryDelaysMs: number[]): Promise<CallbackPostResult>;
|
|
14
|
+
//# sourceMappingURL=callback-retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback-retry.d.ts","sourceRoot":"","sources":["../../src/tools/callback-retry.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE3G,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAQ3C;AAUD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAmC7B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* *
|
|
3
|
+
* * Copyright (C) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Callback HTTP retry helpers
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_RETRY_DELAYS_MS = [1000, 2000, 4000];
|
|
10
|
+
export function getRetryDelaysMs() {
|
|
11
|
+
const raw = process.env['OFFICE_CLAW_CALLBACK_RETRY_DELAYS_MS'];
|
|
12
|
+
if (!raw)
|
|
13
|
+
return DEFAULT_RETRY_DELAYS_MS;
|
|
14
|
+
const parsed = raw
|
|
15
|
+
.split(',')
|
|
16
|
+
.map((value) => Number.parseInt(value.trim(), 10))
|
|
17
|
+
.filter((value) => Number.isFinite(value) && value >= 0);
|
|
18
|
+
return parsed.length > 0 ? parsed : DEFAULT_RETRY_DELAYS_MS;
|
|
19
|
+
}
|
|
20
|
+
function shouldRetryStatus(status) {
|
|
21
|
+
return status === 408 || status === 429 || status >= 500;
|
|
22
|
+
}
|
|
23
|
+
function sleep(ms) {
|
|
24
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
25
|
+
}
|
|
26
|
+
export async function postJsonWithRetry(url, payload, retryDelaysMs) {
|
|
27
|
+
let lastError = 'Callback failed';
|
|
28
|
+
let retryable = true;
|
|
29
|
+
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt += 1) {
|
|
30
|
+
try {
|
|
31
|
+
const response = await fetch(url, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: { 'Content-Type': 'application/json' },
|
|
34
|
+
body: payload,
|
|
35
|
+
});
|
|
36
|
+
if (response.ok) {
|
|
37
|
+
return { ok: true, data: await response.json() };
|
|
38
|
+
}
|
|
39
|
+
const text = await response.text();
|
|
40
|
+
lastError = `Callback failed (${response.status}): ${text}`;
|
|
41
|
+
retryable = shouldRetryStatus(response.status);
|
|
42
|
+
if (!retryable || attempt >= retryDelaysMs.length) {
|
|
43
|
+
return { ok: false, failure: { error: lastError, retryable } };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
48
|
+
lastError = `Callback request failed: ${message}`;
|
|
49
|
+
retryable = true;
|
|
50
|
+
if (attempt >= retryDelaysMs.length) {
|
|
51
|
+
return { ok: false, failure: { error: lastError, retryable } };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
await sleep(retryDelaysMs[attempt]);
|
|
55
|
+
}
|
|
56
|
+
return { ok: false, failure: { error: lastError, retryable } };
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=callback-retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback-retry.js","sourceRoot":"","sources":["../../src/tools/callback-retry.ts"],"names":[],"mappings":"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"}
|