@mclawnet/mcp-server 0.1.7 → 0.1.9
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/inbox-touch-relay.d.ts +23 -0
- package/dist/inbox-touch-relay.d.ts.map +1 -0
- package/dist/inbox-touch-relay.js +41 -0
- package/dist/inbox-touch-relay.js.map +1 -0
- package/dist/server.js +107 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/inbox.d.ts +165 -2
- package/dist/tools/inbox.d.ts.map +1 -1
- package/dist/tools/inbox.js +256 -2
- package/dist/tools/inbox.js.map +1 -1
- package/dist/tools/index.d.ts +146 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/swarm.d.ts +66 -0
- package/dist/tools/swarm.d.ts.map +1 -0
- package/dist/tools/swarm.js +142 -0
- package/dist/tools/swarm.js.map +1 -0
- package/dist/tools/task.d.ts.map +1 -1
- package/dist/tools/task.js +11 -2
- package/dist/tools/task.js.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-process "wake the agent" shim.
|
|
3
|
+
*
|
|
4
|
+
* The MCP server lives in a stdio subprocess spawned by the LLM backend
|
|
5
|
+
* (claude / codex CLI); the agent process owns the real InboxRelay and runs an
|
|
6
|
+
* InboxWatcher (fs.watch on the inbox dir, 50ms debounce) that calls
|
|
7
|
+
* InboxRelay.deliver() whenever anything in the inbox dir changes.
|
|
8
|
+
*
|
|
9
|
+
* When this process needs to wake the agent — e.g. a `wakeup_after` timer
|
|
10
|
+
* fires, or a `watch_path` trigger just wrote a new inbox message — we can't
|
|
11
|
+
* call InboxRelay directly (different process). Instead we touch the
|
|
12
|
+
* recipient's inbox file's mtime so the agent's InboxWatcher picks it up and
|
|
13
|
+
* runs its normal deliver pass.
|
|
14
|
+
*
|
|
15
|
+
* `home` matches the value passed to InboxStore (CLAWNET_HOME or os.homedir());
|
|
16
|
+
* filenames live at `<projectRoot>/swarms/<swarmId>/inboxes/<instanceId>.json`.
|
|
17
|
+
*/
|
|
18
|
+
export declare class InboxTouchRelay {
|
|
19
|
+
private home;
|
|
20
|
+
constructor(home: string);
|
|
21
|
+
deliver(workDir: string, swarmId: string, instanceId: string): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=inbox-touch-relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox-touch-relay.d.ts","sourceRoot":"","sources":["../src/inbox-touch-relay.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,MAAM;IAEhC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;CAiBpE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { utimesSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { projectRoot } from "@mclawnet/task";
|
|
4
|
+
import { createLogger } from "@mclawnet/logger";
|
|
5
|
+
const log = createLogger({ module: "mcp-server/inbox-touch-relay" });
|
|
6
|
+
/**
|
|
7
|
+
* Cross-process "wake the agent" shim.
|
|
8
|
+
*
|
|
9
|
+
* The MCP server lives in a stdio subprocess spawned by the LLM backend
|
|
10
|
+
* (claude / codex CLI); the agent process owns the real InboxRelay and runs an
|
|
11
|
+
* InboxWatcher (fs.watch on the inbox dir, 50ms debounce) that calls
|
|
12
|
+
* InboxRelay.deliver() whenever anything in the inbox dir changes.
|
|
13
|
+
*
|
|
14
|
+
* When this process needs to wake the agent — e.g. a `wakeup_after` timer
|
|
15
|
+
* fires, or a `watch_path` trigger just wrote a new inbox message — we can't
|
|
16
|
+
* call InboxRelay directly (different process). Instead we touch the
|
|
17
|
+
* recipient's inbox file's mtime so the agent's InboxWatcher picks it up and
|
|
18
|
+
* runs its normal deliver pass.
|
|
19
|
+
*
|
|
20
|
+
* `home` matches the value passed to InboxStore (CLAWNET_HOME or os.homedir());
|
|
21
|
+
* filenames live at `<projectRoot>/swarms/<swarmId>/inboxes/<instanceId>.json`.
|
|
22
|
+
*/
|
|
23
|
+
export class InboxTouchRelay {
|
|
24
|
+
home;
|
|
25
|
+
constructor(home) {
|
|
26
|
+
this.home = home;
|
|
27
|
+
}
|
|
28
|
+
deliver(workDir, swarmId, instanceId) {
|
|
29
|
+
try {
|
|
30
|
+
const fp = join(projectRoot(workDir, this.home), "swarms", swarmId, "inboxes", `${instanceId}.json`);
|
|
31
|
+
const now = new Date();
|
|
32
|
+
utimesSync(fp, now, now);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
// File may not exist yet (no messages ever appended) or perms problem.
|
|
36
|
+
// Best-effort: the agent will catch up on the next message_send / scan.
|
|
37
|
+
log.debug({ err, swarmId, instanceId }, "inbox touch failed (best-effort)");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=inbox-touch-relay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox-touch-relay.js","sourceRoot":"","sources":["../src/inbox-touch-relay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC,CAAC;AAErE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAEpC,OAAO,CAAC,OAAe,EAAE,OAAe,EAAE,UAAkB;QAC1D,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAI,CACb,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,EAC/B,QAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,UAAU,OAAO,CACrB,CAAC;YACF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,uEAAuE;YACvE,wEAAwE;YACxE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,kCAAkC,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;CACF"}
|
package/dist/server.js
CHANGED
|
@@ -14,7 +14,9 @@ import { join } from "node:path";
|
|
|
14
14
|
import { createLogger } from "@mclawnet/logger";
|
|
15
15
|
import { createEmbeddingProviders, EmbeddingService, initDatabase, MemoryStore, } from "@mclawnet/memory";
|
|
16
16
|
import { SkillStore, EvolutionPipeline } from "@mclawnet/skill-manager";
|
|
17
|
+
import { WakeupScheduler, WatchManager } from "@mclawnet/swarm";
|
|
17
18
|
import { getAllToolDefinitions, routeToolCall } from "./tools/index.js";
|
|
19
|
+
import { InboxTouchRelay } from "./inbox-touch-relay.js";
|
|
18
20
|
const log = createLogger({ module: "mcp-server" });
|
|
19
21
|
// Two distinct roots:
|
|
20
22
|
// homeDir — user home (no `.clawnet` suffix). TaskStore/InboxStore append
|
|
@@ -39,7 +41,89 @@ const context = {
|
|
|
39
41
|
task: { rootDir: homeDir },
|
|
40
42
|
inbox: { rootDir: homeDir },
|
|
41
43
|
planReview: { rootDir: homeDir },
|
|
44
|
+
swarm: { rootDir: homeDir },
|
|
42
45
|
};
|
|
46
|
+
// === Self-wakeup wiring (M5 Task 7) ===
|
|
47
|
+
//
|
|
48
|
+
// The MCP server lives in a stdio subprocess (one per LLM session) while the
|
|
49
|
+
// agent — which owns the real InboxRelay and runs an InboxWatcher on the
|
|
50
|
+
// inbox dir — lives in a sibling process. Same-process injection is therefore
|
|
51
|
+
// impossible. The fix:
|
|
52
|
+
// 1. Construct WakeupScheduler + WatchManager inside this process.
|
|
53
|
+
// 2. Wire them into the inbox tool context.
|
|
54
|
+
// 3. When a timer/watch fires, the cross-process touch-relay updates the
|
|
55
|
+
// recipient's inbox file mtime; the agent's InboxWatcher catches the fs
|
|
56
|
+
// event (50ms debounce) and runs its normal InboxRelay.deliver pass,
|
|
57
|
+
// which picks up the newly-deliverable message (notBefore <= now).
|
|
58
|
+
//
|
|
59
|
+
// The scheduler / watchManager from @mclawnet/swarm only know (swarmId,
|
|
60
|
+
// instanceId); the touch-relay also needs workDir to resolve the inbox file
|
|
61
|
+
// path. We keep a small in-process registry mapping (s,i)→workDir, populated
|
|
62
|
+
// at register time by the wrapper. It can grow indefinitely for distinct
|
|
63
|
+
// (s,i) keys but is bounded by the MCP server's process lifetime (single LLM
|
|
64
|
+
// session) — acceptable for v1.
|
|
65
|
+
const touchRelay = new InboxTouchRelay(homeDir);
|
|
66
|
+
const workdirRegistry = new Map();
|
|
67
|
+
const registryKey = (s, i) => `${s}::${i}`;
|
|
68
|
+
const wakeupScheduler = new WakeupScheduler({
|
|
69
|
+
deliver: (swarmId, instanceId) => {
|
|
70
|
+
const key = registryKey(swarmId, instanceId);
|
|
71
|
+
const workDir = workdirRegistry.get(key);
|
|
72
|
+
if (!workDir) {
|
|
73
|
+
// Should not happen — wakeup_after always populates the registry before
|
|
74
|
+
// register. Log so a future eviction policy can be debugged.
|
|
75
|
+
log.warn({ swarmId, instanceId }, "wakeup deliver: no workDir in registry");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
touchRelay.deliver(workDir, swarmId, instanceId);
|
|
79
|
+
// Wakeup is single-fire — drop the registry entry to bound growth.
|
|
80
|
+
// (Re-registration by a new wakeup_after call will re-populate.)
|
|
81
|
+
workdirRegistry.delete(key);
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
const watchManager = new WatchManager();
|
|
85
|
+
context.inbox.scheduler = {
|
|
86
|
+
register: (swarmId, instanceId, notBefore, workDir) => {
|
|
87
|
+
workdirRegistry.set(registryKey(swarmId, instanceId), workDir);
|
|
88
|
+
wakeupScheduler.register(swarmId, instanceId, notBefore);
|
|
89
|
+
},
|
|
90
|
+
countForInstance: (s, i) => wakeupScheduler.countForInstance(s, i),
|
|
91
|
+
};
|
|
92
|
+
context.inbox.watchManager = {
|
|
93
|
+
register: (reg) => {
|
|
94
|
+
workdirRegistry.set(registryKey(reg.swarmId, reg.instanceId), reg.projectRoot);
|
|
95
|
+
watchManager.register(reg);
|
|
96
|
+
},
|
|
97
|
+
countForInstance: (s, i) => watchManager.countForInstance(s, i),
|
|
98
|
+
unregister: (s, i, w) => {
|
|
99
|
+
watchManager.unregister(s, i, w);
|
|
100
|
+
// I3: when the last watch for (s,i) is dropped, prune the registry
|
|
101
|
+
// entry too — long-lived sessions with many distinct (s,i) pairs
|
|
102
|
+
// otherwise grow monotonically. Wakeups re-set the entry on demand;
|
|
103
|
+
// we don't need to worry about racing with an in-flight wakeup
|
|
104
|
+
// because the registry entry is single-fire (wakeup deliver also
|
|
105
|
+
// deletes it on fire).
|
|
106
|
+
if (watchManager.countForInstance(s, i) === 0) {
|
|
107
|
+
workdirRegistry.delete(registryKey(s, i));
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
unwatchByInstance: (s, i) => {
|
|
111
|
+
watchManager.unwatchByInstance(s, i);
|
|
112
|
+
workdirRegistry.delete(registryKey(s, i));
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
context.inbox.relay = {
|
|
116
|
+
deliver: (swarmId, instanceId) => {
|
|
117
|
+
const workDir = workdirRegistry.get(registryKey(swarmId, instanceId));
|
|
118
|
+
if (workDir)
|
|
119
|
+
touchRelay.deliver(workDir, swarmId, instanceId);
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
// Restart safety: timers don't survive process exit. We intentionally do NOT
|
|
123
|
+
// call WakeupScheduler.restoreFromInbox here — mcp-server lifetime equals the
|
|
124
|
+
// LLM session, so restoring across sessions would pile up stale timers. The
|
|
125
|
+
// agent-process restart story is a separate concern (it owns InboxRelay and
|
|
126
|
+
// can re-scan inboxes on its own startup).
|
|
43
127
|
const server = new Server({ name: "clawnet-mcp", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
44
128
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
45
129
|
tools: getAllToolDefinitions(),
|
|
@@ -53,6 +137,18 @@ await server.connect(transport);
|
|
|
53
137
|
log.info("ClawNet MCP server connected via stdio");
|
|
54
138
|
function cleanup() {
|
|
55
139
|
log.info("ClawNet MCP server shutting down");
|
|
140
|
+
try {
|
|
141
|
+
wakeupScheduler.dispose();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// ignore
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
watchManager.dispose();
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// ignore
|
|
151
|
+
}
|
|
56
152
|
try {
|
|
57
153
|
db.close();
|
|
58
154
|
}
|
|
@@ -60,6 +156,17 @@ function cleanup() {
|
|
|
60
156
|
// ignore
|
|
61
157
|
}
|
|
62
158
|
}
|
|
159
|
+
// `process.on("exit")` runs cleanup at natural exit too. SIGINT/SIGTERM
|
|
160
|
+
// handlers below call cleanup and then exit; the "exit" handler is a no-op
|
|
161
|
+
// the second time around (dispose / db.close are idempotent enough).
|
|
162
|
+
//
|
|
163
|
+
// We do NOT try to drain in-flight `routeToolCall` work before exiting —
|
|
164
|
+
// MCP protocol over stdio has no graceful-close handshake exposed via the
|
|
165
|
+
// SDK at the time of writing, and a stuck handler would block shutdown
|
|
166
|
+
// indefinitely. The trade-off: a tool call interrupted at the wrong instant
|
|
167
|
+
// may leave a partially-written inbox file. InboxStore uses proper-lockfile +
|
|
168
|
+
// integer-replace writes, so the file stays valid JSON; the worst case is
|
|
169
|
+
// a missing message that the caller will need to retry.
|
|
63
170
|
process.on("exit", cleanup);
|
|
64
171
|
process.on("SIGINT", () => {
|
|
65
172
|
cleanup();
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,uEAAuE;AACvE,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,wEAAwE;AACxE,6DAA6D;AAC7D,OAAO,gBAAgB,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EACL,wBAAwB,EACxB,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAoB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/inbox.d.ts
CHANGED
|
@@ -16,9 +16,54 @@ export interface InboxToolContext {
|
|
|
16
16
|
* agent is woken immediately. Failures are swallowed (best-effort).
|
|
17
17
|
*/
|
|
18
18
|
relay?: InboxRelayLike;
|
|
19
|
+
/**
|
|
20
|
+
* Optional wakeup scheduler. When present, `wakeup_after` registers a timer
|
|
21
|
+
* after writing the deferred inbox message so it fires in-process when the
|
|
22
|
+
* notBefore time arrives. Without this, the message still lands on disk and
|
|
23
|
+
* will be picked up on the next inbox scan / restart restore.
|
|
24
|
+
*/
|
|
25
|
+
scheduler?: {
|
|
26
|
+
/**
|
|
27
|
+
* `workDir` is required by the MCP server's wrapper, which keeps a
|
|
28
|
+
* (swarmId,instanceId)→workDir registry so the cross-process touch-relay
|
|
29
|
+
* can resolve the inbox file path when the timer fires. The underlying
|
|
30
|
+
* @mclawnet/swarm WakeupScheduler still takes only 3 args; the extra
|
|
31
|
+
* parameter is consumed by the wrapper before delegating.
|
|
32
|
+
*/
|
|
33
|
+
register(swarmId: string, instanceId: string, notBefore: number, workDir: string): void;
|
|
34
|
+
/** I4 caps: per-instance active timer count, used to reject before write. */
|
|
35
|
+
countForInstance?(swarmId: string, instanceId: string): number;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Optional fs-watch manager. When present, `watch_path` registers a watch
|
|
39
|
+
* whose `onTrigger` writes an inbox message and (best-effort) wakes the
|
|
40
|
+
* recipient via `relay.deliver`. Without it, `watch_path` returns isError.
|
|
41
|
+
*/
|
|
42
|
+
watchManager?: {
|
|
43
|
+
register(reg: WatchRegistrationLike): void;
|
|
44
|
+
unregister(swarmId: string, instanceId: string, watchId: string): void;
|
|
45
|
+
unwatchByInstance(swarmId: string, instanceId: string): void;
|
|
46
|
+
/** I4 caps: per-instance active watch count, used to reject before register. */
|
|
47
|
+
countForInstance?(swarmId: string, instanceId: string): number;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Minimal structural shape for a WatchManager registration. Kept local (not
|
|
52
|
+
* imported from @mclawnet/swarm) to keep the contextual coupling loose — the
|
|
53
|
+
* router wires in the real type at start time.
|
|
54
|
+
*/
|
|
55
|
+
export interface WatchRegistrationLike {
|
|
56
|
+
swarmId: string;
|
|
57
|
+
instanceId: string;
|
|
58
|
+
watchId: string;
|
|
59
|
+
projectRoot: string;
|
|
60
|
+
includeGlobs: string[];
|
|
61
|
+
ignoreGlobs: string[];
|
|
62
|
+
debounceMs: number;
|
|
63
|
+
onTrigger: (matchedPath: string) => void | Promise<void>;
|
|
19
64
|
}
|
|
20
65
|
export declare const INBOX_TOOL_NAMES: Set<string>;
|
|
21
|
-
export declare function getInboxToolDefinitions(): {
|
|
66
|
+
export declare function getInboxToolDefinitions(): ({
|
|
22
67
|
name: string;
|
|
23
68
|
description: string;
|
|
24
69
|
inputSchema: {
|
|
@@ -60,10 +105,128 @@ export declare function getInboxToolDefinitions(): {
|
|
|
60
105
|
type: string[];
|
|
61
106
|
description: string;
|
|
62
107
|
};
|
|
108
|
+
instanceId?: undefined;
|
|
109
|
+
seconds?: undefined;
|
|
110
|
+
payload?: undefined;
|
|
111
|
+
includeGlobs?: undefined;
|
|
112
|
+
ignoreGlobs?: undefined;
|
|
113
|
+
debounceMs?: undefined;
|
|
114
|
+
watchId?: undefined;
|
|
115
|
+
};
|
|
116
|
+
required: string[];
|
|
117
|
+
};
|
|
118
|
+
} | {
|
|
119
|
+
name: string;
|
|
120
|
+
description: string;
|
|
121
|
+
inputSchema: {
|
|
122
|
+
type: "object";
|
|
123
|
+
properties: {
|
|
124
|
+
workDir: {
|
|
125
|
+
type: string;
|
|
126
|
+
description: string;
|
|
127
|
+
};
|
|
128
|
+
swarmId: {
|
|
129
|
+
type: string;
|
|
130
|
+
description: string;
|
|
131
|
+
};
|
|
132
|
+
instanceId: {
|
|
133
|
+
type: string;
|
|
134
|
+
description: string;
|
|
135
|
+
};
|
|
136
|
+
seconds: {
|
|
137
|
+
type: string;
|
|
138
|
+
exclusiveMinimum: number;
|
|
139
|
+
maximum: number;
|
|
140
|
+
description: string;
|
|
141
|
+
};
|
|
142
|
+
payload: {
|
|
143
|
+
type: string;
|
|
144
|
+
description: string;
|
|
145
|
+
};
|
|
146
|
+
type: {
|
|
147
|
+
type: string;
|
|
148
|
+
description: string;
|
|
149
|
+
};
|
|
150
|
+
from: {
|
|
151
|
+
type: string;
|
|
152
|
+
description: string;
|
|
153
|
+
};
|
|
154
|
+
to?: undefined;
|
|
155
|
+
data?: undefined;
|
|
156
|
+
taskId?: undefined;
|
|
157
|
+
expectedStatus?: undefined;
|
|
158
|
+
expectedOwner?: undefined;
|
|
159
|
+
includeGlobs?: undefined;
|
|
160
|
+
ignoreGlobs?: undefined;
|
|
161
|
+
debounceMs?: undefined;
|
|
162
|
+
watchId?: undefined;
|
|
163
|
+
};
|
|
164
|
+
required: string[];
|
|
165
|
+
};
|
|
166
|
+
} | {
|
|
167
|
+
name: string;
|
|
168
|
+
description: string;
|
|
169
|
+
inputSchema: {
|
|
170
|
+
type: "object";
|
|
171
|
+
properties: {
|
|
172
|
+
workDir: {
|
|
173
|
+
type: string;
|
|
174
|
+
description: string;
|
|
175
|
+
};
|
|
176
|
+
swarmId: {
|
|
177
|
+
type: string;
|
|
178
|
+
description?: undefined;
|
|
179
|
+
};
|
|
180
|
+
instanceId: {
|
|
181
|
+
type: string;
|
|
182
|
+
description: string;
|
|
183
|
+
};
|
|
184
|
+
includeGlobs: {
|
|
185
|
+
type: string;
|
|
186
|
+
items: {
|
|
187
|
+
type: string;
|
|
188
|
+
};
|
|
189
|
+
minItems: number;
|
|
190
|
+
description: string;
|
|
191
|
+
};
|
|
192
|
+
payload: {
|
|
193
|
+
type: string;
|
|
194
|
+
description: string;
|
|
195
|
+
};
|
|
196
|
+
ignoreGlobs: {
|
|
197
|
+
type: string;
|
|
198
|
+
items: {
|
|
199
|
+
type: string;
|
|
200
|
+
};
|
|
201
|
+
description: string;
|
|
202
|
+
};
|
|
203
|
+
debounceMs: {
|
|
204
|
+
type: string;
|
|
205
|
+
minimum: number;
|
|
206
|
+
description: string;
|
|
207
|
+
};
|
|
208
|
+
type: {
|
|
209
|
+
type: string;
|
|
210
|
+
description: string;
|
|
211
|
+
};
|
|
212
|
+
from: {
|
|
213
|
+
type: string;
|
|
214
|
+
description: string;
|
|
215
|
+
};
|
|
216
|
+
watchId: {
|
|
217
|
+
type: string;
|
|
218
|
+
description: string;
|
|
219
|
+
};
|
|
220
|
+
to?: undefined;
|
|
221
|
+
data?: undefined;
|
|
222
|
+
taskId?: undefined;
|
|
223
|
+
expectedStatus?: undefined;
|
|
224
|
+
expectedOwner?: undefined;
|
|
225
|
+
seconds?: undefined;
|
|
63
226
|
};
|
|
64
227
|
required: string[];
|
|
65
228
|
};
|
|
66
|
-
}[];
|
|
229
|
+
})[];
|
|
67
230
|
export declare function handleInboxToolCall(name: string, args: Record<string, unknown>, context: InboxToolContext): Promise<{
|
|
68
231
|
content: Array<{
|
|
69
232
|
type: "text";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/tools/inbox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/tools/inbox.ts"],"names":[],"mappings":"AAiCA,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;;;;;OAKG;IACH,SAAS,CAAC,EAAE;QACV;;;;;;WAMG;QACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACxF,6EAA6E;QAC7E,gBAAgB,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;KAChE,CAAC;IACF;;;;OAIG;IACH,YAAY,CAAC,EAAE;QACb,QAAQ,CAAC,GAAG,EAAE,qBAAqB,GAAG,IAAI,CAAC;QAC3C,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvE,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7D,gFAAgF;QAChF,gBAAgB,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;KAChE,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED,eAAO,MAAM,gBAAgB,aAA0D,CAAC;AAcxF,wBAAgB,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkFtC;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAmChF"}
|