@femtomc/mu-server 26.2.31 → 26.2.33

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 CHANGED
@@ -87,16 +87,17 @@ Bun.serve(server);
87
87
 
88
88
  ### With Web UI (Recommended)
89
89
 
90
- The easiest way to run the server with the web interface:
90
+ The easiest way to run the server with the bundled web interface (and default terminal meta-agent chat):
91
91
 
92
92
  ```bash
93
93
  # From any mu repository
94
- mu serve
95
-
96
- # Or with custom ports
97
- mu serve --port 8080 --api-port 3001
94
+ mu serve # API + web UI + terminal meta-agent session
95
+ mu serve --no-open # Skip browser auto-open (headless/SSH)
96
+ mu serve --port 8080 # Custom shared API/web UI port
98
97
  ```
99
98
 
99
+ Type `/exit` (or press Ctrl+C) to stop both the chat session and server.
100
+
100
101
  ### Standalone Server
101
102
 
102
103
  ```bash
@@ -1,4 +1,5 @@
1
1
  import { type Channel } from "@femtomc/mu-control-plane";
2
+ import { type MessagingMetaAgentBackend, MessagingMetaAgentRuntime } from "@femtomc/mu-agent";
2
3
  export declare const ENV_VARS: {
3
4
  readonly slack: {
4
5
  readonly signingSecret: "MU_SLACK_SIGNING_SECRET";
@@ -12,6 +13,17 @@ export declare const ENV_VARS: {
12
13
  readonly botUsername: "MU_TELEGRAM_BOT_USERNAME";
13
14
  readonly tenantId: "MU_TELEGRAM_TENANT_ID";
14
15
  };
16
+ readonly metaAgent: {
17
+ readonly enabled: "MU_META_AGENT_ENABLED";
18
+ readonly enabledChannels: "MU_META_AGENT_ENABLED_CHANNELS";
19
+ readonly runTriggersEnabled: "MU_META_AGENT_RUN_TRIGGERS_ENABLED";
20
+ readonly provider: "MU_META_AGENT_PROVIDER";
21
+ readonly model: "MU_META_AGENT_MODEL";
22
+ readonly thinking: "MU_META_AGENT_THINKING";
23
+ readonly systemPrompt: "MU_META_AGENT_SYSTEM_PROMPT";
24
+ readonly timeoutMs: "MU_META_AGENT_TIMEOUT_MS";
25
+ readonly piBinary: "MU_META_AGENT_PI_BINARY";
26
+ };
15
27
  };
16
28
  export type ActiveAdapter = {
17
29
  name: Channel;
@@ -36,8 +48,11 @@ type DetectedAdapter = {
36
48
  tenantId: string | null;
37
49
  };
38
50
  export declare function detectAdapters(env: Record<string, string | undefined>): DetectedAdapter[];
39
- export declare function bootstrapControlPlane(opts: {
51
+ export type BootstrapControlPlaneOpts = {
40
52
  repoRoot: string;
41
53
  env?: Record<string, string | undefined>;
42
- }): Promise<ControlPlaneHandle | null>;
54
+ metaAgentRuntime?: MessagingMetaAgentRuntime | null;
55
+ metaAgentBackend?: MessagingMetaAgentBackend;
56
+ };
57
+ export declare function bootstrapControlPlane(opts: BootstrapControlPlaneOpts): Promise<ControlPlaneHandle | null>;
43
58
  export {};
@@ -1,4 +1,5 @@
1
- import { ControlPlaneRuntime, ControlPlaneCommandPipeline, ControlPlaneOutbox, ControlPlaneOutboxDispatcher, SlackControlPlaneAdapter, DiscordControlPlaneAdapter, TelegramControlPlaneAdapter, getControlPlanePaths, } from "@femtomc/mu-control-plane";
1
+ import { ControlPlaneCommandPipeline, ControlPlaneOutbox, ControlPlaneOutboxDispatcher, ControlPlaneRuntime, DiscordControlPlaneAdapter, getControlPlanePaths, SlackControlPlaneAdapter, TelegramControlPlaneAdapter, } from "@femtomc/mu-control-plane";
2
+ import { ApprovedCommandBroker, CommandContextResolver, MessagingMetaAgentRuntime, PiMessagingMetaAgentBackend, } from "@femtomc/mu-agent";
2
3
  export const ENV_VARS = {
3
4
  slack: { signingSecret: "MU_SLACK_SIGNING_SECRET" },
4
5
  discord: { signingSecret: "MU_DISCORD_SIGNING_SECRET" },
@@ -8,6 +9,17 @@ export const ENV_VARS = {
8
9
  botUsername: "MU_TELEGRAM_BOT_USERNAME",
9
10
  tenantId: "MU_TELEGRAM_TENANT_ID",
10
11
  },
12
+ metaAgent: {
13
+ enabled: "MU_META_AGENT_ENABLED",
14
+ enabledChannels: "MU_META_AGENT_ENABLED_CHANNELS",
15
+ runTriggersEnabled: "MU_META_AGENT_RUN_TRIGGERS_ENABLED",
16
+ provider: "MU_META_AGENT_PROVIDER",
17
+ model: "MU_META_AGENT_MODEL",
18
+ thinking: "MU_META_AGENT_THINKING",
19
+ systemPrompt: "MU_META_AGENT_SYSTEM_PROMPT",
20
+ timeoutMs: "MU_META_AGENT_TIMEOUT_MS",
21
+ piBinary: "MU_META_AGENT_PI_BINARY",
22
+ },
11
23
  };
12
24
  const ROUTE_MAP = {
13
25
  slack: "/webhooks/slack",
@@ -36,6 +48,66 @@ export function detectAdapters(env) {
36
48
  }
37
49
  return adapters;
38
50
  }
51
+ function parseBooleanEnv(value, defaultValue) {
52
+ if (value == null) {
53
+ return defaultValue;
54
+ }
55
+ const normalized = value.trim().toLowerCase();
56
+ if (["1", "true", "yes", "on", "enabled"].includes(normalized)) {
57
+ return true;
58
+ }
59
+ if (["0", "false", "no", "off", "disabled"].includes(normalized)) {
60
+ return false;
61
+ }
62
+ return defaultValue;
63
+ }
64
+ function parsePositiveIntEnv(value) {
65
+ if (!value) {
66
+ return undefined;
67
+ }
68
+ const parsed = Number.parseInt(value, 10);
69
+ if (!Number.isFinite(parsed) || parsed <= 0) {
70
+ return undefined;
71
+ }
72
+ return parsed;
73
+ }
74
+ function parseCsvEnv(value) {
75
+ if (!value) {
76
+ return undefined;
77
+ }
78
+ const tokens = value
79
+ .split(",")
80
+ .map((token) => token.trim().toLowerCase())
81
+ .filter((token) => token.length > 0);
82
+ return tokens.length > 0 ? tokens : undefined;
83
+ }
84
+ function buildMessagingMetaAgentRuntime(opts) {
85
+ const enabled = parseBooleanEnv(opts.env[ENV_VARS.metaAgent.enabled], true);
86
+ if (!enabled) {
87
+ return null;
88
+ }
89
+ const runTriggersEnabled = parseBooleanEnv(opts.env[ENV_VARS.metaAgent.runTriggersEnabled], true);
90
+ const enabledChannels = parseCsvEnv(opts.env[ENV_VARS.metaAgent.enabledChannels]);
91
+ const timeoutMs = parsePositiveIntEnv(opts.env[ENV_VARS.metaAgent.timeoutMs]);
92
+ const backend = opts.backend ??
93
+ new PiMessagingMetaAgentBackend({
94
+ provider: opts.env[ENV_VARS.metaAgent.provider],
95
+ model: opts.env[ENV_VARS.metaAgent.model],
96
+ thinking: opts.env[ENV_VARS.metaAgent.thinking],
97
+ systemPrompt: opts.env[ENV_VARS.metaAgent.systemPrompt],
98
+ timeoutMs,
99
+ piBinary: opts.env[ENV_VARS.metaAgent.piBinary],
100
+ });
101
+ return new MessagingMetaAgentRuntime({
102
+ backend,
103
+ broker: new ApprovedCommandBroker({
104
+ runTriggersEnabled,
105
+ contextResolver: new CommandContextResolver({ allowedRepoRoots: [opts.repoRoot] }),
106
+ }),
107
+ enabled,
108
+ enabledChannels,
109
+ });
110
+ }
39
111
  export async function bootstrapControlPlane(opts) {
40
112
  const env = opts.env ?? process.env;
41
113
  const detected = detectAdapters(env);
@@ -45,7 +117,14 @@ export async function bootstrapControlPlane(opts) {
45
117
  const paths = getControlPlanePaths(opts.repoRoot);
46
118
  const runtime = new ControlPlaneRuntime({ repoRoot: opts.repoRoot });
47
119
  await runtime.start();
48
- const pipeline = new ControlPlaneCommandPipeline({ runtime });
120
+ const metaAgent = opts.metaAgentRuntime !== undefined
121
+ ? opts.metaAgentRuntime
122
+ : buildMessagingMetaAgentRuntime({
123
+ repoRoot: opts.repoRoot,
124
+ env,
125
+ backend: opts.metaAgentBackend,
126
+ });
127
+ const pipeline = new ControlPlaneCommandPipeline({ runtime, metaAgent });
49
128
  await pipeline.start();
50
129
  const outbox = new ControlPlaneOutbox(paths.outboxPath);
51
130
  await outbox.load();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@femtomc/mu-server",
3
- "version": "26.2.31",
3
+ "version": "26.2.33",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -23,9 +23,10 @@
23
23
  "start": "bun run dist/cli.js"
24
24
  },
25
25
  "dependencies": {
26
- "@femtomc/mu-core": "26.2.31",
27
- "@femtomc/mu-issue": "26.2.31",
28
- "@femtomc/mu-forum": "26.2.31",
29
- "@femtomc/mu-control-plane": "26.2.31"
26
+ "@femtomc/mu-agent": "26.2.33",
27
+ "@femtomc/mu-control-plane": "26.2.33",
28
+ "@femtomc/mu-core": "26.2.33",
29
+ "@femtomc/mu-forum": "26.2.33",
30
+ "@femtomc/mu-issue": "26.2.33"
30
31
  }
31
32
  }