feat: mac node exec policy + remote skills hot reload
This commit is contained in:
@@ -3,6 +3,7 @@ import type { CanvasHostHandler, CanvasHostServer } from "../canvas-host/server.
|
||||
import { startCanvasHost } from "../canvas-host/server.js";
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { HealthSummary } from "../commands/health.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { deriveDefaultBridgePort, deriveDefaultCanvasHostPort } from "../config/port-defaults.js";
|
||||
import type { NodeBridgeServer } from "../infra/bridge/server.js";
|
||||
import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
|
||||
@@ -33,15 +34,7 @@ export type GatewayBridgeRuntime = {
|
||||
};
|
||||
|
||||
export async function startGatewayBridgeRuntime(params: {
|
||||
cfg: {
|
||||
bridge?: {
|
||||
enabled?: boolean;
|
||||
port?: number;
|
||||
bind?: "loopback" | "lan" | "auto" | "custom";
|
||||
};
|
||||
canvasHost?: { port?: number; root?: string; liveReload?: boolean };
|
||||
discovery?: { wideArea?: { enabled?: boolean } };
|
||||
};
|
||||
cfg: ClawdbotConfig;
|
||||
port: number;
|
||||
canvasHostEnabled: boolean;
|
||||
canvasHost: CanvasHostHandler | null;
|
||||
@@ -200,6 +193,7 @@ export async function startGatewayBridgeRuntime(params: {
|
||||
: undefined;
|
||||
|
||||
const bridgeRuntime = await startGatewayNodeBridge({
|
||||
cfg: params.cfg,
|
||||
bridgeEnabled,
|
||||
bridgePort,
|
||||
bridgeHost,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { installSkill } from "../../agents/skills-install.js";
|
||||
import { buildWorkspaceSkillStatus } from "../../agents/skills-status.js";
|
||||
import type { ClawdbotConfig } from "../../config/config.js";
|
||||
import { loadConfig, writeConfigFile } from "../../config/config.js";
|
||||
import { getRemoteSkillEligibility } from "../../infra/skills-remote.js";
|
||||
import {
|
||||
ErrorCodes,
|
||||
errorShape,
|
||||
@@ -30,6 +31,7 @@ export const skillsHandlers: GatewayRequestHandlers = {
|
||||
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
|
||||
const report = buildWorkspaceSkillStatus(workspaceDir, {
|
||||
config: cfg,
|
||||
eligibility: { remote: getRemoteSkillEligibility() },
|
||||
});
|
||||
respond(true, report, undefined);
|
||||
},
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { NodeBridgeServer } from "../infra/bridge/server.js";
|
||||
import { startNodeBridgeServer } from "../infra/bridge/server.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { bumpSkillsSnapshotVersion } from "../agents/skills/refresh.js";
|
||||
import { recordRemoteNodeInfo, refreshRemoteNodeBins } from "../infra/skills-remote.js";
|
||||
import { listSystemPresence, upsertPresence } from "../infra/system-presence.js";
|
||||
import { loadVoiceWakeConfig } from "../infra/voicewake.js";
|
||||
import { isLoopbackAddress } from "./net.js";
|
||||
@@ -16,6 +19,7 @@ export type GatewayNodeBridgeRuntime = {
|
||||
};
|
||||
|
||||
export async function startGatewayNodeBridge(params: {
|
||||
cfg: ClawdbotConfig;
|
||||
bridgeEnabled: boolean;
|
||||
bridgePort: number;
|
||||
bridgeHost: string | null;
|
||||
@@ -114,6 +118,21 @@ export async function startGatewayNodeBridge(params: {
|
||||
onAuthenticated: async (node) => {
|
||||
beaconNodePresence(node, "node-connected");
|
||||
startNodePresenceTimer(node);
|
||||
recordRemoteNodeInfo({
|
||||
nodeId: node.nodeId,
|
||||
displayName: node.displayName,
|
||||
platform: node.platform,
|
||||
deviceFamily: node.deviceFamily,
|
||||
commands: node.commands,
|
||||
});
|
||||
bumpSkillsSnapshotVersion({ reason: "remote-node" });
|
||||
await refreshRemoteNodeBins({
|
||||
nodeId: node.nodeId,
|
||||
platform: node.platform,
|
||||
deviceFamily: node.deviceFamily,
|
||||
commands: node.commands,
|
||||
cfg: params.cfg,
|
||||
});
|
||||
|
||||
try {
|
||||
const cfg = await loadVoiceWakeConfig();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { initSubagentRegistry } from "../agents/subagent-registry.js";
|
||||
import { registerSkillsChangeListener } from "../agents/skills/refresh.js";
|
||||
import type { CanvasHostServer } from "../canvas-host/server.js";
|
||||
import { type ChannelId, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import { createDefaultDeps } from "../cli/deps.js";
|
||||
@@ -16,6 +17,11 @@ import { onHeartbeatEvent } from "../infra/heartbeat-events.js";
|
||||
import { startHeartbeatRunner } from "../infra/heartbeat-runner.js";
|
||||
import { getMachineDisplayName } from "../infra/machine-name.js";
|
||||
import { ensureClawdbotCliOnPath } from "../infra/path-env.js";
|
||||
import {
|
||||
primeRemoteSkillsCache,
|
||||
refreshRemoteBinsForConnectedNodes,
|
||||
setSkillsRemoteBridge,
|
||||
} from "../infra/skills-remote.js";
|
||||
import { autoMigrateLegacyState } from "../infra/state-migrations.js";
|
||||
import { createSubsystemLogger, runtimeForLogger } from "../logging.js";
|
||||
import type { PluginServicesHandle } from "../plugins/services.js";
|
||||
@@ -288,6 +294,13 @@ export async function startGatewayServer(
|
||||
const bridgeSendToAllSubscribed = bridgeRuntime.bridgeSendToAllSubscribed;
|
||||
const broadcastVoiceWakeChanged = bridgeRuntime.broadcastVoiceWakeChanged;
|
||||
|
||||
setSkillsRemoteBridge(bridge);
|
||||
void primeRemoteSkillsCache();
|
||||
registerSkillsChangeListener(() => {
|
||||
const latest = loadConfig();
|
||||
void refreshRemoteBinsForConnectedNodes(latest);
|
||||
});
|
||||
|
||||
const { tickInterval, healthInterval, dedupeCleanup } = startGatewayMaintenanceTimers({
|
||||
broadcast,
|
||||
bridgeSendToAllSubscribed,
|
||||
|
||||
Reference in New Issue
Block a user