negotium 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/README.md +26 -2
- package/dist/canonical-mcp-bridge.js +14 -0
- package/dist/canonical-mcp-bridge.js.map +9 -0
- package/dist/chunk-10ct8814.js +429 -0
- package/dist/chunk-10ct8814.js.map +11 -0
- package/dist/chunk-18fzftjf.js +214 -0
- package/dist/chunk-18fzftjf.js.map +10 -0
- package/dist/chunk-1k7t7bnx.js +97 -0
- package/dist/chunk-1k7t7bnx.js.map +10 -0
- package/dist/chunk-1msje2zf.js +23 -0
- package/dist/chunk-1msje2zf.js.map +10 -0
- package/dist/chunk-2dgkah1z.js +706 -0
- package/dist/chunk-2dgkah1z.js.map +14 -0
- package/dist/chunk-3t4dtm26.js +61 -0
- package/dist/chunk-3t4dtm26.js.map +10 -0
- package/dist/chunk-3vn2vnj1.js +51 -0
- package/dist/chunk-3vn2vnj1.js.map +10 -0
- package/dist/chunk-6hknphtc.js +2054 -0
- package/dist/chunk-6hknphtc.js.map +29 -0
- package/dist/chunk-6tfzpcvk.js +2149 -0
- package/dist/chunk-6tfzpcvk.js.map +15 -0
- package/dist/chunk-8g0c4as0.js +23 -0
- package/dist/chunk-8g0c4as0.js.map +10 -0
- package/dist/chunk-9spx3h9n.js +279 -0
- package/dist/chunk-9spx3h9n.js.map +10 -0
- package/dist/chunk-c500xe9z.js +33 -0
- package/dist/chunk-c500xe9z.js.map +10 -0
- package/dist/chunk-e9b2xpff.js +147 -0
- package/dist/chunk-e9b2xpff.js.map +10 -0
- package/dist/chunk-edb07sjp.js +567 -0
- package/dist/chunk-edb07sjp.js.map +14 -0
- package/dist/chunk-eexqsee7.js +368 -0
- package/dist/chunk-eexqsee7.js.map +11 -0
- package/dist/chunk-efyxk97v.js +500 -0
- package/dist/chunk-efyxk97v.js.map +13 -0
- package/dist/chunk-epqxwkvh.js +3534 -0
- package/dist/chunk-epqxwkvh.js.map +20 -0
- package/dist/chunk-f1pzh3xh.js +115 -0
- package/dist/chunk-f1pzh3xh.js.map +10 -0
- package/dist/chunk-f5xgprg1.js +59 -0
- package/dist/chunk-f5xgprg1.js.map +10 -0
- package/dist/chunk-f97qybwk.js +584 -0
- package/dist/chunk-f97qybwk.js.map +11 -0
- package/dist/chunk-fvc7ncxd.js +252 -0
- package/dist/chunk-fvc7ncxd.js.map +10 -0
- package/dist/chunk-g7pvfj5e.js +574 -0
- package/dist/chunk-g7pvfj5e.js.map +14 -0
- package/dist/chunk-h8vmb9gf.js +315 -0
- package/dist/chunk-h8vmb9gf.js.map +10 -0
- package/dist/chunk-hgw7n8cm.js +43 -0
- package/dist/chunk-hgw7n8cm.js.map +10 -0
- package/dist/chunk-hsq7j9jk.js +126 -0
- package/dist/chunk-hsq7j9jk.js.map +10 -0
- package/dist/chunk-hwy3n31w.js +21 -0
- package/dist/chunk-hwy3n31w.js.map +9 -0
- package/dist/chunk-j0kjscb7.js +53 -0
- package/dist/chunk-j0kjscb7.js.map +10 -0
- package/dist/chunk-jzz91jwh.js +70 -0
- package/dist/chunk-jzz91jwh.js.map +10 -0
- package/dist/chunk-k9z47mab.js +247 -0
- package/dist/chunk-k9z47mab.js.map +12 -0
- package/dist/chunk-kbm35t7w.js +1331 -0
- package/dist/chunk-kbm35t7w.js.map +16 -0
- package/dist/chunk-m4veth0c.js +1649 -0
- package/dist/chunk-m4veth0c.js.map +17 -0
- package/dist/chunk-mhty3nna.js +150 -0
- package/dist/chunk-mhty3nna.js.map +11 -0
- package/dist/chunk-mmgh670x.js +248 -0
- package/dist/chunk-mmgh670x.js.map +11 -0
- package/dist/chunk-n0kk5xbq.js +2358 -0
- package/dist/chunk-n0kk5xbq.js.map +26 -0
- package/dist/chunk-nmv41qx9.js +2847 -0
- package/dist/chunk-nmv41qx9.js.map +23 -0
- package/dist/chunk-nqdp52aj.js +113 -0
- package/dist/chunk-nqdp52aj.js.map +12 -0
- package/dist/chunk-ns2m25dz.js +139 -0
- package/dist/chunk-ns2m25dz.js.map +10 -0
- package/dist/chunk-pkdmypdd.js +147 -0
- package/dist/chunk-pkdmypdd.js.map +11 -0
- package/dist/chunk-rmyfmrrr.js +1634 -0
- package/dist/chunk-rmyfmrrr.js.map +15 -0
- package/dist/chunk-sa874j5c.js +9 -0
- package/dist/chunk-sa874j5c.js.map +10 -0
- package/dist/chunk-sgsz2fpq.js +289 -0
- package/dist/chunk-sgsz2fpq.js.map +10 -0
- package/dist/chunk-sn51wnf1.js +3020 -0
- package/dist/chunk-sn51wnf1.js.map +32 -0
- package/dist/chunk-sqhr1a7e.js +587 -0
- package/dist/chunk-sqhr1a7e.js.map +11 -0
- package/dist/chunk-tmj5r2zv.js +2933 -0
- package/dist/chunk-tmj5r2zv.js.map +20 -0
- package/dist/chunk-vefj3880.js +56 -0
- package/dist/chunk-vefj3880.js.map +10 -0
- package/dist/chunk-vp2db42d.js +121 -0
- package/dist/chunk-vp2db42d.js.map +10 -0
- package/dist/chunk-wry79q55.js +108 -0
- package/dist/chunk-wry79q55.js.map +10 -0
- package/dist/chunk-x1arr7ze.js +63 -0
- package/dist/chunk-x1arr7ze.js.map +10 -0
- package/dist/chunk-z2xy5n2q.js +103 -0
- package/dist/chunk-z2xy5n2q.js.map +10 -0
- package/dist/hosted-agent.js +53 -0
- package/dist/hosted-agent.js.map +10 -0
- package/dist/main.js +132 -20
- package/dist/main.js.map +4 -4
- package/dist/runtime/scripts/faster-whisper-wrapper.py +87 -0
- package/dist/runtime/scripts/mcp-patchright-http.mjs +349 -0
- package/dist/runtime/src/agents/api-topic-agent-switch.ts +178 -0
- package/dist/runtime/src/agents/archiver.ts +396 -0
- package/dist/runtime/src/agents/auth-check.ts +64 -0
- package/dist/runtime/src/agents/claude-provider.ts +737 -0
- package/dist/runtime/src/agents/claude-registry.ts +115 -0
- package/dist/runtime/src/agents/codex-native-multi-agent.ts +177 -0
- package/dist/runtime/src/agents/codex-provider.ts +785 -0
- package/dist/runtime/src/agents/codex-registry.ts +115 -0
- package/dist/runtime/src/agents/codex-tree-kill.ts +365 -0
- package/dist/runtime/src/agents/contracts.ts +69 -0
- package/dist/runtime/src/agents/deep-map.ts +13 -0
- package/dist/runtime/src/agents/execution-host.ts +91 -0
- package/dist/runtime/src/agents/fixtures/claude-attachments.jsonl +2 -0
- package/dist/runtime/src/agents/fixtures/codex-shell.jsonl +5 -0
- package/dist/runtime/src/agents/fork.ts +65 -0
- package/dist/runtime/src/agents/hosted-agent.ts +49 -0
- package/dist/runtime/src/agents/idle-archiver.ts +128 -0
- package/dist/runtime/src/agents/index.ts +205 -0
- package/dist/runtime/src/agents/maestro-provider.ts +206 -0
- package/dist/runtime/src/agents/maestro-registry.ts +31 -0
- package/dist/runtime/src/agents/mcp-tools/ask-user.ts +280 -0
- package/dist/runtime/src/agents/mcp-tools/common.ts +21 -0
- package/dist/runtime/src/agents/mcp-tools/self-config.ts +220 -0
- package/dist/runtime/src/agents/mcp-tools/spawn-subagent.ts +525 -0
- package/dist/runtime/src/agents/mcp-tools/visuals.ts +88 -0
- package/dist/runtime/src/agents/model-catalog.ts +151 -0
- package/dist/runtime/src/agents/registry.ts +24 -0
- package/dist/runtime/src/agents/rollout/claude.ts +331 -0
- package/dist/runtime/src/agents/rollout/codex.ts +569 -0
- package/dist/runtime/src/agents/rollout/shared.ts +205 -0
- package/dist/runtime/src/agents/self-config-core.ts +415 -0
- package/dist/runtime/src/agents/task-events.ts +44 -0
- package/dist/runtime/src/agents/tool-format.ts +352 -0
- package/dist/runtime/src/agents/topic-agent-switch.ts +193 -0
- package/dist/runtime/src/agents/topic-cleanup.ts +231 -0
- package/dist/runtime/src/agents/vault-tool-policy.ts +33 -0
- package/dist/runtime/src/application/execute-external-user-turn.ts +23 -0
- package/dist/runtime/src/application/submit-user-message.ts +50 -0
- package/dist/runtime/src/application/switch-topic-effort.ts +48 -0
- package/dist/runtime/src/application/switch-topic-model.ts +79 -0
- package/dist/runtime/src/application/topic-service.ts +139 -0
- package/dist/runtime/src/application/vault-command.ts +170 -0
- package/dist/runtime/src/bus.ts +319 -0
- package/dist/runtime/src/index.ts +333 -0
- package/dist/runtime/src/mcp/agent-health-server.ts +309 -0
- package/dist/runtime/src/mcp/background-bash-server.ts +346 -0
- package/dist/runtime/src/mcp/canonical-bridge-config.ts +84 -0
- package/dist/runtime/src/mcp/canonical-proxy-server.ts +171 -0
- package/dist/runtime/src/mcp/dm-ipc.ts +60 -0
- package/dist/runtime/src/mcp/mcp-helpers.ts +40 -0
- package/dist/runtime/src/mcp/paddleocr-server.ts +105 -0
- package/dist/runtime/src/mcp/peer-bridge.ts +114 -0
- package/dist/runtime/src/mcp/runtime-spec.ts +137 -0
- package/dist/runtime/src/mcp/session-comm/bridge-ipc-config.ts +27 -0
- package/dist/runtime/src/mcp/session-comm/peer-forward.ts +165 -0
- package/dist/runtime/src/mcp/session-comm/runtime.ts +115 -0
- package/dist/runtime/src/mcp/session-comm/server.ts +649 -0
- package/dist/runtime/src/mcp/session-comm/topic-config.ts +131 -0
- package/dist/runtime/src/mcp/session-comm/topics.ts +229 -0
- package/dist/runtime/src/mcp/stdio-protect.ts +84 -0
- package/dist/runtime/src/mcp/system-health-server.ts +130 -0
- package/dist/runtime/src/mcp/task-server.ts +173 -0
- package/dist/runtime/src/mcp/token-stats-server.ts +98 -0
- package/dist/runtime/src/mcp/vault-http.ts +219 -0
- package/dist/runtime/src/mcp/vault-run.ts +153 -0
- package/dist/runtime/src/mcp/vault-server.ts +104 -0
- package/dist/runtime/src/mcp/wiki-server.ts +755 -0
- package/dist/runtime/src/media/file-events.ts +33 -0
- package/dist/runtime/src/media/text-extractor.ts +312 -0
- package/dist/runtime/src/media/video.ts +92 -0
- package/dist/runtime/src/outbox/file-ops.ts +210 -0
- package/dist/runtime/src/outbox/index.ts +8 -0
- package/dist/runtime/src/outbox/utils.ts +51 -0
- package/dist/runtime/src/platform/background-bash/manager.ts +279 -0
- package/dist/runtime/src/platform/config.ts +371 -0
- package/dist/runtime/src/platform/constants.ts +18 -0
- package/dist/runtime/src/platform/debug-users.ts +14 -0
- package/dist/runtime/src/platform/delay.ts +1 -0
- package/dist/runtime/src/platform/error.ts +9 -0
- package/dist/runtime/src/platform/file-utils.ts +16 -0
- package/dist/runtime/src/platform/jsonl.ts +202 -0
- package/dist/runtime/src/platform/lifecycle.ts +174 -0
- package/dist/runtime/src/platform/logger.ts +31 -0
- package/dist/runtime/src/platform/maestro-bootstrap-env.ts +3 -0
- package/dist/runtime/src/platform/mcp-config.ts +878 -0
- package/dist/runtime/src/platform/modules.ts +145 -0
- package/dist/runtime/src/platform/node-plugins.ts +46 -0
- package/dist/runtime/src/platform/playwright/manager.ts +1233 -0
- package/dist/runtime/src/prompts/agents/wiki-archiver.md +261 -0
- package/dist/runtime/src/prompts/builders.ts +368 -0
- package/dist/runtime/src/prompts/sessions/channel-system.md +48 -0
- package/dist/runtime/src/prompts/sessions/manager-system.md +37 -0
- package/dist/runtime/src/prompts/sessions/topic-system.md +47 -0
- package/dist/runtime/src/prompts/sessions/visual-design.md +86 -0
- package/dist/runtime/src/query/active-rooms.ts +534 -0
- package/dist/runtime/src/query/control.ts +313 -0
- package/dist/runtime/src/query/index.ts +24 -0
- package/dist/runtime/src/query/session-inbox-cleanup.ts +44 -0
- package/dist/runtime/src/query/session-inbox-path.ts +42 -0
- package/dist/runtime/src/query/state.ts +94 -0
- package/dist/runtime/src/query/types.ts +83 -0
- package/dist/runtime/src/runtime/ask-callbacks.ts +153 -0
- package/dist/runtime/src/runtime/attachments.ts +151 -0
- package/dist/runtime/src/runtime/background-sessions.ts +83 -0
- package/dist/runtime/src/runtime/channel-context.ts +107 -0
- package/dist/runtime/src/runtime/errors.ts +69 -0
- package/dist/runtime/src/runtime/event-heartbeat.ts +77 -0
- package/dist/runtime/src/runtime/file-hooks.ts +81 -0
- package/dist/runtime/src/runtime/footer.ts +23 -0
- package/dist/runtime/src/runtime/inbox.ts +946 -0
- package/dist/runtime/src/runtime/tasks.ts +56 -0
- package/dist/runtime/src/runtime/topic-config.ts +29 -0
- package/dist/runtime/src/runtime/turn-runner.ts +2298 -0
- package/dist/runtime/src/runtime/usage-alert.ts +84 -0
- package/dist/runtime/src/runtime/visual-html.ts +109 -0
- package/dist/runtime/src/runtime/visual-store.ts +430 -0
- package/dist/runtime/src/runtime/visuals.ts +171 -0
- package/dist/runtime/src/security/sanitize.ts +27 -0
- package/dist/runtime/src/security/sensitive-path.ts +34 -0
- package/dist/runtime/src/storage/activity-log.ts +152 -0
- package/dist/runtime/src/storage/api-messages.ts +617 -0
- package/dist/runtime/src/storage/api-topic-brief.ts +127 -0
- package/dist/runtime/src/storage/api-topic-config.ts +192 -0
- package/dist/runtime/src/storage/api-topics.ts +844 -0
- package/dist/runtime/src/storage/app-settings.ts +44 -0
- package/dist/runtime/src/storage/browser-profiles.ts +133 -0
- package/dist/runtime/src/storage/conversations.ts +268 -0
- package/dist/runtime/src/storage/forum/agent-settings.ts +20 -0
- package/dist/runtime/src/storage/forum/index.ts +4 -0
- package/dist/runtime/src/storage/forum/repository.ts +283 -0
- package/dist/runtime/src/storage/forum/schema.ts +300 -0
- package/dist/runtime/src/storage/forum-db.ts +23 -0
- package/dist/runtime/src/storage/runtime-events.ts +130 -0
- package/dist/runtime/src/storage/runtime-leases.ts +189 -0
- package/dist/runtime/src/storage/runtime-process-leases.ts +216 -0
- package/dist/runtime/src/storage/runtime-topic-state.ts +148 -0
- package/dist/runtime/src/storage/runtime-turn-requests.ts +301 -0
- package/dist/runtime/src/storage/self-schedules.ts +298 -0
- package/dist/runtime/src/storage/session-asks.ts +347 -0
- package/dist/runtime/src/storage/sqlite.ts +129 -0
- package/dist/runtime/src/storage/tasks.ts +179 -0
- package/dist/runtime/src/storage/token-stats.ts +144 -0
- package/dist/runtime/src/storage/topic-archive-state.ts +59 -0
- package/dist/runtime/src/storage/topic-archive.ts +74 -0
- package/dist/runtime/src/storage/topic-settings.ts +67 -0
- package/dist/runtime/src/storage/topic-transcript.ts +98 -0
- package/dist/runtime/src/storage/vault-crypto.ts +65 -0
- package/dist/runtime/src/storage/vault.ts +225 -0
- package/dist/runtime/src/storage/wiki-summary-names.ts +33 -0
- package/dist/runtime/src/storage/wiki.ts +85 -0
- package/dist/runtime/src/topics/create.ts +123 -0
- package/dist/runtime/src/topics/derive.ts +398 -0
- package/dist/runtime/src/topics/lifecycle.ts +311 -0
- package/dist/runtime/src/topics/links.ts +7 -0
- package/dist/runtime/src/topics/personal-general.ts +65 -0
- package/dist/runtime/src/topics/session.ts +381 -0
- package/dist/runtime/src/types/api.ts +497 -0
- package/dist/runtime/src/types.ts +257 -0
- package/dist/runtime/src/version.ts +1 -0
- package/dist/runtime/tsconfig.json +13 -0
- package/package.json +28 -3
- package/dist/main.d.ts +0 -3
- package/dist/main.d.ts.map +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional node modules.
|
|
3
|
+
*
|
|
4
|
+
* The runtime kernel does not discover or import modules. A host explicitly
|
|
5
|
+
* passes the modules it wants when it boots a node, which keeps disabled
|
|
6
|
+
* features at zero runtime cost: no import, timer, listener, table migration,
|
|
7
|
+
* or hot-path dispatch.
|
|
8
|
+
*
|
|
9
|
+
* Module startup is deliberately synchronous. A module may start background
|
|
10
|
+
* async work, but it must return its cleanup handle immediately so a partially
|
|
11
|
+
* started node can always unwind deterministically.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { RuntimeBus } from "#bus";
|
|
15
|
+
import { logger } from "#platform/logger";
|
|
16
|
+
import { acquireRuntimeProcessLease } from "#storage/runtime-process-leases";
|
|
17
|
+
|
|
18
|
+
export interface NegotiumNodeModuleContext {
|
|
19
|
+
port: number;
|
|
20
|
+
stateDir: string;
|
|
21
|
+
dataDir: string;
|
|
22
|
+
runDir: string;
|
|
23
|
+
workspaceDir: string;
|
|
24
|
+
bus: RuntimeBus;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface NegotiumNodeModuleHandle {
|
|
28
|
+
stop?: () => Promise<void> | void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface NegotiumNodeModule {
|
|
32
|
+
/** Stable capability name, e.g. `cron` or `otium-peer`. */
|
|
33
|
+
name: string;
|
|
34
|
+
/** Run this module in at most one process sharing the same state database. */
|
|
35
|
+
singleton?: boolean | string;
|
|
36
|
+
/** Stable wire-facing capabilities advertised by hosts such as Otium. */
|
|
37
|
+
capabilities?: readonly string[];
|
|
38
|
+
// biome-ignore lint/suspicious/noConfusingVoidType: modules without cleanup intentionally return nothing.
|
|
39
|
+
start(context: NegotiumNodeModuleContext): NegotiumNodeModuleHandle | void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface StartedNegotiumNodeModules {
|
|
43
|
+
names: readonly string[];
|
|
44
|
+
capabilities: readonly string[];
|
|
45
|
+
stop: () => Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Start an explicit module set and return one reverse-order cleanup handle. */
|
|
49
|
+
export function startNegotiumNodeModules(
|
|
50
|
+
modules: readonly NegotiumNodeModule[],
|
|
51
|
+
context: NegotiumNodeModuleContext,
|
|
52
|
+
): StartedNegotiumNodeModules {
|
|
53
|
+
const seen = new Set<string>();
|
|
54
|
+
const seenCapabilities = new Set<string>();
|
|
55
|
+
const capabilities: string[] = [];
|
|
56
|
+
const started: Array<{ name: string; handle: NegotiumNodeModuleHandle }> = [];
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
for (const module of modules) {
|
|
60
|
+
const name = module.name.trim();
|
|
61
|
+
if (!name) throw new Error("negotium module name must not be empty");
|
|
62
|
+
if (seen.has(name)) throw new Error(`duplicate negotium module: ${name}`);
|
|
63
|
+
seen.add(name);
|
|
64
|
+
const moduleCapabilities: string[] = [];
|
|
65
|
+
for (const rawCapability of module.capabilities ?? []) {
|
|
66
|
+
const capability = rawCapability.trim();
|
|
67
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/.test(capability)) {
|
|
68
|
+
throw new Error(`invalid negotium module capability: ${rawCapability}`);
|
|
69
|
+
}
|
|
70
|
+
if (seenCapabilities.has(capability) || moduleCapabilities.includes(capability)) {
|
|
71
|
+
throw new Error(`duplicate negotium module capability: ${capability}`);
|
|
72
|
+
}
|
|
73
|
+
moduleCapabilities.push(capability);
|
|
74
|
+
}
|
|
75
|
+
const singletonRole =
|
|
76
|
+
typeof module.singleton === "string"
|
|
77
|
+
? module.singleton.trim()
|
|
78
|
+
: module.singleton
|
|
79
|
+
? `module:${name}`
|
|
80
|
+
: null;
|
|
81
|
+
let moduleHandle: NegotiumNodeModuleHandle | undefined;
|
|
82
|
+
let moduleStopped = false;
|
|
83
|
+
const stopModule = async (): Promise<void> => {
|
|
84
|
+
if (moduleStopped) return;
|
|
85
|
+
moduleStopped = true;
|
|
86
|
+
await moduleHandle?.stop?.();
|
|
87
|
+
};
|
|
88
|
+
const singletonLease = singletonRole
|
|
89
|
+
? acquireRuntimeProcessLease(singletonRole, {
|
|
90
|
+
onLost: () => {
|
|
91
|
+
logger.error(
|
|
92
|
+
{ module: name, role: singletonRole },
|
|
93
|
+
"node module singleton lease lost; stopping module",
|
|
94
|
+
);
|
|
95
|
+
void stopModule().catch((error) =>
|
|
96
|
+
logger.error({ error, module: name }, "node module stop after lease loss failed"),
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
: null;
|
|
101
|
+
if (singletonRole && !singletonLease) {
|
|
102
|
+
logger.info({ module: name, role: singletonRole }, "node module owned by another process");
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
moduleHandle = module.start(context) ?? {};
|
|
107
|
+
const handle: NegotiumNodeModuleHandle = singletonLease
|
|
108
|
+
? {
|
|
109
|
+
async stop() {
|
|
110
|
+
try {
|
|
111
|
+
await stopModule();
|
|
112
|
+
} finally {
|
|
113
|
+
singletonLease.stop();
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
: moduleHandle;
|
|
118
|
+
for (const capability of moduleCapabilities) {
|
|
119
|
+
seenCapabilities.add(capability);
|
|
120
|
+
capabilities.push(capability);
|
|
121
|
+
}
|
|
122
|
+
started.push({ name, handle });
|
|
123
|
+
} catch (error) {
|
|
124
|
+
singletonLease?.stop();
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
// Startup is synchronous, so cleanup can be scheduled without delaying the
|
|
130
|
+
// original error. Every shipped module returns an idempotent stop handle.
|
|
131
|
+
for (const entry of started.reverse()) void entry.handle.stop?.();
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let stopped = false;
|
|
136
|
+
return {
|
|
137
|
+
names: started.map((entry) => entry.name),
|
|
138
|
+
capabilities,
|
|
139
|
+
async stop() {
|
|
140
|
+
if (stopped) return;
|
|
141
|
+
stopped = true;
|
|
142
|
+
for (const entry of [...started].reverse()) await entry.handle.stop?.();
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node request-handler plugins.
|
|
3
|
+
*
|
|
4
|
+
* The node's HTTP surface is a chain: plugins → negotium MCP → /health.
|
|
5
|
+
* External integrations (an otium workspace worker, a future peer protocol,
|
|
6
|
+
* custom webhooks) register a handler here BEFORE the host calls startNode;
|
|
7
|
+
* the host mounts every registered handler in registration order. A handler
|
|
8
|
+
* returns `null` to pass the request down the chain.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately tiny: no lifecycle here — plugins own their startup and
|
|
11
|
+
* register cleanup via `onShutdown` like every other subsystem.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type NodeRequestHandler = (req: Request) => Promise<Response | null> | Response | null;
|
|
15
|
+
|
|
16
|
+
interface NodePlugin {
|
|
17
|
+
name: string;
|
|
18
|
+
handler: NodeRequestHandler;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const plugins: NodePlugin[] = [];
|
|
22
|
+
|
|
23
|
+
/** Register a request handler ahead of the built-in MCP routes. Idempotent by name (last wins). */
|
|
24
|
+
export function registerNodeRequestHandler(name: string, handler: NodeRequestHandler): void {
|
|
25
|
+
const existing = plugins.findIndex((p) => p.name === name);
|
|
26
|
+
if (existing >= 0) plugins.splice(existing, 1);
|
|
27
|
+
plugins.push({ name, handler });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function unregisterNodeRequestHandler(name: string): void {
|
|
31
|
+
const existing = plugins.findIndex((p) => p.name === name);
|
|
32
|
+
if (existing >= 0) plugins.splice(existing, 1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Run the plugin chain. Returns the first non-null response, else null. */
|
|
36
|
+
export async function runNodeRequestHandlers(req: Request): Promise<Response | null> {
|
|
37
|
+
for (const plugin of plugins) {
|
|
38
|
+
const res = await plugin.handler(req);
|
|
39
|
+
if (res) return res;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function nodeRequestHandlerNames(): string[] {
|
|
45
|
+
return plugins.map((p) => p.name);
|
|
46
|
+
}
|