fix: resolve merge-induced type errors and lint issues
- Deduplicate SkillEntry/SkillSnapshot imports in workspace.ts - Add missing skillFilter/applySkillsPromptLimits in workspace skills - Add sessionEventLog/sessionSubscriptions to runtime state return type - Add allowRealIpFallback to GatewayConfig type - Fix agent.subscribe/unsubscribe validation to use AJV pattern - Add missing imports (RuntimeEnv, inheritOptionFromParent, etc.) - Fix spread type in run-main.exit.test.ts - Type chat.ts appendMessage call correctly - Rename synology-chat workspace ref from openclaw to ironclaw - Regenerate pnpm-lock.yaml for merged dependencies Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6594de6186
commit
45f86187ed
@ -5,7 +5,7 @@
|
||||
"description": "Synology Chat channel plugin for OpenClaw",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"openclaw": "workspace:*"
|
||||
"ironclaw": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
|
||||
570
pnpm-lock.yaml
generated
570
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -9,10 +9,9 @@
|
||||
*/
|
||||
|
||||
import type { ThinkLevel } from "../../auto-reply/thinking.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import type { RunEmbeddedPiAgentParams } from "../pi-embedded-runner/run/params.js";
|
||||
import type { EmbeddedPiRunResult, EmbeddedPiAgentMeta } from "../pi-embedded-runner/types.js";
|
||||
import type { AiSdkConfig, ResolvedModel } from "./types.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import {
|
||||
resolveSkillsPromptForRun,
|
||||
applySkillEnvOverrides,
|
||||
@ -22,6 +21,7 @@ import {
|
||||
import { streamWithPiAgentEvents, type EventAdapterInput } from "./event-adapter.js";
|
||||
import { resolveModel, getDefaultConfig, validateConfig } from "./provider.js";
|
||||
import { createAiSdkTools, type ToolExecutionContext, type ConvertedAiSdkTool } from "./tools.js";
|
||||
import type { AiSdkConfig, ResolvedModel } from "./types.js";
|
||||
|
||||
/**
|
||||
* Configuration for the AI SDK agent runner.
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||
import type { ThinkLevel } from "../../auto-reply/thinking.js";
|
||||
import { resolveCliName } from "../../cli/cli-name.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { CliBackendConfig } from "../../config/types.js";
|
||||
import type { EmbeddedContextFile } from "../pi-embedded-helpers.js";
|
||||
import { resolveCliName } from "../../cli/cli-name.js";
|
||||
import { buildTtsSystemPromptHint } from "../../tts/tts.js";
|
||||
import { isRecord } from "../../utils.js";
|
||||
import { buildModelAliasLines } from "../model-alias-lines.js";
|
||||
import { resolveDefaultModelForAgent } from "../model-selection.js";
|
||||
import type { EmbeddedContextFile } from "../pi-embedded-helpers.js";
|
||||
import { detectRuntimeShell } from "../shell-utils.js";
|
||||
import { buildSystemPromptParams } from "../system-prompt-params.js";
|
||||
import { buildAgentSystemPrompt } from "../system-prompt.js";
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||
import { streamSimple } from "@mariozechner/pi-ai";
|
||||
@ -7,9 +9,6 @@ import {
|
||||
SessionManager,
|
||||
SettingsManager,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import type { EmbeddedRunAttemptParams, EmbeddedRunAttemptResult } from "./types.js";
|
||||
import { resolveHeartbeatPrompt } from "../../../auto-reply/heartbeat.js";
|
||||
import { resolveChannelCapabilities } from "../../../config/channel-capabilities.js";
|
||||
import { getMachineDisplayName } from "../../../infra/machine-name.js";
|
||||
@ -110,6 +109,7 @@ import {
|
||||
shouldFlagCompactionTimeout,
|
||||
} from "./compaction-timeout.js";
|
||||
import { detectAndLoadPromptImages } from "./images.js";
|
||||
import type { EmbeddedRunAttemptParams, EmbeddedRunAttemptResult } from "./types.js";
|
||||
|
||||
export function injectHistoryImagesIntoMessages(
|
||||
messages: AgentMessage[],
|
||||
|
||||
@ -3,10 +3,10 @@ import type { AgentSession } from "@mariozechner/pi-coding-agent";
|
||||
import type { MemoryCitationsMode } from "../../config/types.memory.js";
|
||||
import type { ResolvedTimeFormat } from "../date-time.js";
|
||||
import type { EmbeddedContextFile } from "../pi-embedded-helpers.js";
|
||||
import type { EmbeddedSandboxInfo } from "./types.js";
|
||||
import type { ReasoningLevel, ThinkLevel } from "./utils.js";
|
||||
import { buildAgentSystemPrompt, type PromptMode } from "../system-prompt.js";
|
||||
import { buildToolSummaryMap } from "../tool-summaries.js";
|
||||
import type { EmbeddedSandboxInfo } from "./types.js";
|
||||
import type { ReasoningLevel, ThinkLevel } from "./utils.js";
|
||||
|
||||
export function buildEmbeddedSystemPrompt(params: {
|
||||
workspaceDir: string;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { AgentEvent, AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import type { EmbeddedPiSubscribeContext } from "./pi-embedded-subscribe.handlers.types.js";
|
||||
import { parseReplyDirectives } from "../auto-reply/reply/reply-directives.js";
|
||||
import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
@ -8,6 +7,7 @@ import {
|
||||
isMessagingToolDuplicateNormalized,
|
||||
normalizeTextForComparison,
|
||||
} from "./pi-embedded-helpers.js";
|
||||
import type { EmbeddedPiSubscribeContext } from "./pi-embedded-subscribe.handlers.types.js";
|
||||
import { appendRawStream } from "./pi-embedded-subscribe.raw-stream.js";
|
||||
import {
|
||||
extractAssistantText,
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import type { InlineCodeState } from "../markdown/code-spans.js";
|
||||
import type {
|
||||
EmbeddedPiSubscribeContext,
|
||||
EmbeddedPiSubscribeState,
|
||||
} from "./pi-embedded-subscribe.handlers.types.js";
|
||||
import type { SubscribeEmbeddedPiSessionParams } from "./pi-embedded-subscribe.types.js";
|
||||
import { parseReplyDirectives } from "../auto-reply/reply/reply-directives.js";
|
||||
import { createStreamingDirectiveAccumulator } from "../auto-reply/reply/streaming-directives.js";
|
||||
import { formatToolAggregate } from "../auto-reply/tool-meta.js";
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import type { InlineCodeState } from "../markdown/code-spans.js";
|
||||
import { buildCodeSpanIndex, createInlineCodeState } from "../markdown/code-spans.js";
|
||||
import { EmbeddedBlockChunker } from "./pi-embedded-block-chunker.js";
|
||||
import {
|
||||
@ -17,7 +12,12 @@ import {
|
||||
normalizeTextForComparison,
|
||||
} from "./pi-embedded-helpers.js";
|
||||
import { createEmbeddedPiSessionEventHandler } from "./pi-embedded-subscribe.handlers.js";
|
||||
import type {
|
||||
EmbeddedPiSubscribeContext,
|
||||
EmbeddedPiSubscribeState,
|
||||
} from "./pi-embedded-subscribe.handlers.types.js";
|
||||
import { filterToolResultMediaUrls } from "./pi-embedded-subscribe.tools.js";
|
||||
import type { SubscribeEmbeddedPiSessionParams } from "./pi-embedded-subscribe.types.js";
|
||||
import { formatReasoningMessage, stripDowngradedToolCallText } from "./pi-embedded-utils.js";
|
||||
import { hasNonzeroUsage, normalizeUsage, type UsageLike } from "./usage.js";
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { OpenClawConfig, SkillConfig } from "../../config/config.js";
|
||||
import type { SkillEligibilityContext, SkillEntry } from "./types.js";
|
||||
import {
|
||||
evaluateRuntimeRequires,
|
||||
hasBinary,
|
||||
@ -8,6 +7,7 @@ import {
|
||||
resolveRuntimePlatform,
|
||||
} from "../../shared/config-eval.js";
|
||||
import { resolveSkillKey } from "./frontmatter.js";
|
||||
import type { SkillEligibilityContext, SkillEntry } from "./types.js";
|
||||
|
||||
const DEFAULT_CONFIG_VALUES: Record<string, boolean> = {
|
||||
"browser.enabled": true,
|
||||
|
||||
@ -1,11 +1,4 @@
|
||||
import type { Skill } from "@mariozechner/pi-coding-agent";
|
||||
import type {
|
||||
OpenClawSkillMetadata,
|
||||
ParsedSkillFrontmatter,
|
||||
SkillEntry,
|
||||
SkillInstallSpec,
|
||||
SkillInvocationPolicy,
|
||||
} from "./types.js";
|
||||
import { parseFrontmatterBlock } from "../../markdown/frontmatter.js";
|
||||
import {
|
||||
getFrontmatterString,
|
||||
@ -17,6 +10,13 @@ import {
|
||||
resolveOpenClawManifestOs,
|
||||
resolveOpenClawManifestRequires,
|
||||
} from "../../shared/frontmatter.js";
|
||||
import type {
|
||||
OpenClawSkillMetadata,
|
||||
ParsedSkillFrontmatter,
|
||||
SkillEntry,
|
||||
SkillInstallSpec,
|
||||
SkillInvocationPolicy,
|
||||
} from "./types.js";
|
||||
|
||||
export function parseFrontmatter(content: string): ParsedSkillFrontmatter {
|
||||
return parseFrontmatterBlock(content);
|
||||
|
||||
@ -82,7 +82,8 @@ describe("ensureSkillsWatcher", () => {
|
||||
mod.ensureSkillsWatcher({ workspaceDir: "/tmp/workspace-bundled-test" });
|
||||
|
||||
expect(watchMock).toHaveBeenCalledTimes(1);
|
||||
const watchedPaths = watchMock.mock.calls[0]?.[0] as string[];
|
||||
const watchedPaths =
|
||||
(watchMock.mock.calls as unknown as Array<[string[], { ignored?: unknown }]>)[0]?.[0] ?? [];
|
||||
|
||||
// Should include workspace skills and bundled skills (as SKILL.md globs)
|
||||
expect(watchedPaths.some((p) => p.startsWith("/tmp/workspace-bundled-test/skills"))).toBe(true);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import chokidar, { type FSWatcher } from "chokidar";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import chokidar, { type FSWatcher } from "chokidar";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
|
||||
|
||||
@ -1,27 +1,12 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import {
|
||||
formatSkillsForPrompt,
|
||||
loadSkillsFromDir,
|
||||
type Skill,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type {
|
||||
InjectedSkillContent,
|
||||
ParsedSkillFrontmatter,
|
||||
SkillEligibilityContext,
|
||||
SkillCommandSpec,
|
||||
SkillEntry,
|
||||
SkillSnapshot,
|
||||
} from "./types.js";
|
||||
import type {
|
||||
ParsedSkillFrontmatter,
|
||||
SkillEligibilityContext,
|
||||
SkillCommandSpec,
|
||||
SkillEntry,
|
||||
SkillSnapshot,
|
||||
} from "./types.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
|
||||
import { resolveSandboxPath } from "../sandbox-paths.js";
|
||||
@ -35,6 +20,14 @@ import {
|
||||
} from "./frontmatter.js";
|
||||
import { resolvePluginSkillDirs } from "./plugin-skills.js";
|
||||
import { serializeByKey } from "./serialize.js";
|
||||
import type {
|
||||
InjectedSkillContent,
|
||||
ParsedSkillFrontmatter,
|
||||
SkillEligibilityContext,
|
||||
SkillCommandSpec,
|
||||
SkillEntry,
|
||||
SkillSnapshot,
|
||||
} from "./types.js";
|
||||
|
||||
const fsp = fs.promises;
|
||||
const skillsLogger = createSubsystemLogger("skills");
|
||||
@ -430,6 +423,44 @@ function readSkillContent(filePath: string): string | undefined {
|
||||
}
|
||||
}
|
||||
|
||||
function applySkillsPromptLimits(params: { skills: Skill[]; config?: OpenClawConfig }): {
|
||||
skillsForPrompt: Skill[];
|
||||
truncated: boolean;
|
||||
truncatedReason: "count" | "chars" | null;
|
||||
} {
|
||||
const limits = resolveSkillsLimits(params.config);
|
||||
const total = params.skills.length;
|
||||
const byCount = params.skills.slice(0, Math.max(0, limits.maxSkillsInPrompt));
|
||||
|
||||
let skillsForPrompt = byCount;
|
||||
let truncated = total > byCount.length;
|
||||
let truncatedReason: "count" | "chars" | null = truncated ? "count" : null;
|
||||
|
||||
const fits = (skills: Skill[]): boolean => {
|
||||
const block = formatSkillsForPrompt(skills);
|
||||
return block.length <= limits.maxSkillsPromptChars;
|
||||
};
|
||||
|
||||
if (!fits(skillsForPrompt)) {
|
||||
// Binary search the largest prefix that fits in the char budget.
|
||||
let lo = 0;
|
||||
let hi = skillsForPrompt.length;
|
||||
while (lo < hi) {
|
||||
const mid = Math.ceil((lo + hi) / 2);
|
||||
if (fits(skillsForPrompt.slice(0, mid))) {
|
||||
lo = mid;
|
||||
} else {
|
||||
hi = mid - 1;
|
||||
}
|
||||
}
|
||||
skillsForPrompt = skillsForPrompt.slice(0, lo);
|
||||
truncated = true;
|
||||
truncatedReason = "chars";
|
||||
}
|
||||
|
||||
return { skillsForPrompt, truncated, truncatedReason };
|
||||
}
|
||||
|
||||
export function buildWorkspaceSkillSnapshot(
|
||||
workspaceDir: string,
|
||||
opts?: {
|
||||
@ -468,8 +499,21 @@ export function buildWorkspaceSkillSnapshot(
|
||||
(entry) => entry.invocation?.disableModelInvocation !== true,
|
||||
);
|
||||
const resolvedSkills = promptEntries.map((entry) => entry.skill);
|
||||
const { skillsForPrompt, truncated } = applySkillsPromptLimits({
|
||||
skills: resolvedSkills,
|
||||
config: opts?.config,
|
||||
});
|
||||
const truncationNote = truncated
|
||||
? `⚠️ Skills truncated: included ${skillsForPrompt.length} of ${resolvedSkills.length}. Run \`openclaw skills check\` to audit.`
|
||||
: "";
|
||||
const remoteNote = opts?.eligibility?.remote?.note?.trim();
|
||||
const prompt = [remoteNote, formatSkillsForPrompt(resolvedSkills)].filter(Boolean).join("\n");
|
||||
const prompt = [
|
||||
remoteNote,
|
||||
truncationNote,
|
||||
formatSkillsForPrompt(compactSkillPaths(skillsForPrompt)),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
|
||||
// Read full content of injected skills, substituting workspace path placeholders.
|
||||
// We replace both the tilde form and the expanded default path to handle
|
||||
@ -497,6 +541,7 @@ export function buildWorkspaceSkillSnapshot(
|
||||
}
|
||||
}
|
||||
|
||||
const skillFilter = normalizeSkillFilter(opts?.skillFilter);
|
||||
return {
|
||||
prompt,
|
||||
skills: eligible.map((entry) => ({
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { createHmac, createHash } from "node:crypto";
|
||||
import type { ReasoningLevel, ThinkLevel } from "../auto-reply/thinking.js";
|
||||
import type { MemoryCitationsMode } from "../config/types.memory.js";
|
||||
import type { ResolvedTimeFormat } from "./date-time.js";
|
||||
import type { EmbeddedContextFile } from "./pi-embedded-helpers.js";
|
||||
import { SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
||||
import { DEFAULT_CLI_NAME } from "../cli/cli-name.js";
|
||||
import type { MemoryCitationsMode } from "../config/types.memory.js";
|
||||
import { listDeliverableMessageChannels } from "../utils/message-channel.js";
|
||||
import type { ResolvedTimeFormat } from "./date-time.js";
|
||||
import type { EmbeddedContextFile } from "./pi-embedded-helpers.js";
|
||||
import { sanitizeForPromptLiteral } from "./sanitize-for-prompt.js";
|
||||
|
||||
/**
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
import crypto from "node:crypto";
|
||||
import type { ExecToolDefaults } from "../../agents/bash-tools.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { MsgContext, TemplateContext } from "../templating.js";
|
||||
import type { GetReplyOptions, ReplyPayload } from "../types.js";
|
||||
import type { buildCommandContext } from "./commands.js";
|
||||
import type { InlineDirectives } from "./directive-handling.js";
|
||||
import type { createModelSelectionState } from "./model-selection.js";
|
||||
import type { TypingController } from "./typing.js";
|
||||
import { resolveSessionAuthProfileOverride } from "../../agents/auth-profiles/session-override.js";
|
||||
import type { ExecToolDefaults } from "../../agents/bash-tools.js";
|
||||
import { resolveModelAuthLabel } from "../../agents/model-auth-label.js";
|
||||
import {
|
||||
abortEmbeddedPiRun,
|
||||
@ -15,6 +8,7 @@ import {
|
||||
isEmbeddedPiRunStreaming,
|
||||
resolveEmbeddedSessionLane,
|
||||
} from "../../agents/pi-embedded.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import {
|
||||
resolveGroupSessionKey,
|
||||
resolveSessionFilePath,
|
||||
@ -29,6 +23,7 @@ import { INTERNAL_MESSAGE_CHANNEL } from "../../utils/message-channel.js";
|
||||
import { isReasoningTagProvider } from "../../utils/provider-utils.js";
|
||||
import { hasControlCommand } from "../command-detection.js";
|
||||
import { buildInboundMediaNote } from "../media-note.js";
|
||||
import type { MsgContext, TemplateContext } from "../templating.js";
|
||||
import {
|
||||
type ElevatedLevel,
|
||||
formatXHighModelHint,
|
||||
@ -39,15 +34,20 @@ import {
|
||||
type VerboseLevel,
|
||||
} from "../thinking.js";
|
||||
import { SILENT_REPLY_TOKEN } from "../tokens.js";
|
||||
import type { GetReplyOptions, ReplyPayload } from "../types.js";
|
||||
import { runReplyAgent } from "./agent-runner.js";
|
||||
import { applySessionHints } from "./body.js";
|
||||
import type { buildCommandContext } from "./commands.js";
|
||||
import type { InlineDirectives } from "./directive-handling.js";
|
||||
import { buildGroupChatContext, buildGroupIntro } from "./groups.js";
|
||||
import { buildInboundMetaSystemPrompt, buildInboundUserContextPrefix } from "./inbound-meta.js";
|
||||
import type { createModelSelectionState } from "./model-selection.js";
|
||||
import { resolveQueueSettings } from "./queue.js";
|
||||
import { routeReply } from "./route-reply.js";
|
||||
import { BARE_SESSION_RESET_PROMPT } from "./session-reset-prompt.js";
|
||||
import { ensureSkillSnapshot, prependSystemEvents } from "./session-updates.js";
|
||||
import { resolveTypingMode } from "./typing-mode.js";
|
||||
import type { TypingController } from "./typing.js";
|
||||
import { appendUntrustedContext } from "./untrusted-context.js";
|
||||
|
||||
type AgentDefaults = NonNullable<OpenClawConfig["agents"]>["defaults"];
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import type { DaemonInstallOptions } from "./types.js";
|
||||
import { buildGatewayInstallPlan } from "../../commands/daemon-install-helpers.js";
|
||||
import {
|
||||
DEFAULT_GATEWAY_DAEMON_RUNTIME,
|
||||
@ -24,6 +23,7 @@ import {
|
||||
installDaemonServiceAndEmit,
|
||||
} from "./response.js";
|
||||
import { parsePort } from "./shared.js";
|
||||
import type { DaemonInstallOptions } from "./types.js";
|
||||
|
||||
export async function runDaemonInstall(opts: DaemonInstallOptions) {
|
||||
const json = Boolean(opts.json);
|
||||
|
||||
@ -16,11 +16,8 @@ vi.mock("../infra/dotenv.js", () => ({
|
||||
}));
|
||||
|
||||
vi.mock("../infra/env.js", async (importOriginal) => {
|
||||
const actual = await importOriginal();
|
||||
return {
|
||||
...actual,
|
||||
normalizeEnv: normalizeEnvMock,
|
||||
};
|
||||
const actual = await importOriginal<typeof import("../infra/env.js")>();
|
||||
return Object.assign({}, actual, { normalizeEnv: normalizeEnvMock });
|
||||
});
|
||||
|
||||
vi.mock("../infra/path-env.js", () => ({
|
||||
|
||||
@ -3,6 +3,7 @@ import { defaultRuntime } from "../runtime.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { theme } from "../terminal/theme.js";
|
||||
import { replaceCliName, resolveCliName } from "./cli-name.js";
|
||||
import { inheritOptionFromParent } from "./command-options.js";
|
||||
import { formatHelpExamples } from "./help-format.js";
|
||||
import { updateStatusCommand } from "./update-cli/status.js";
|
||||
import { updateCommand } from "./update-cli/update-command.js";
|
||||
|
||||
@ -67,6 +67,7 @@ vi.mock("../gateway/client.js", () => {
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import * as configModule from "../config/config.js";
|
||||
import { callGateway } from "../gateway/call.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { agentCliCommand, emitNdjsonLine } from "./agent-via-gateway.js";
|
||||
import { agentCommand } from "./agent.js";
|
||||
|
||||
@ -252,7 +253,7 @@ describe("agentCliCommand", () => {
|
||||
const store = path.join(dir, "sessions.json");
|
||||
mockConfig(store);
|
||||
|
||||
vi.mocked(agentCommand).mockResolvedValueOnce(undefined);
|
||||
mockLocalAgentReply();
|
||||
|
||||
try {
|
||||
await agentCliCommand({ message: "hi", to: "+1555", local: true, streamJson: true }, runtime);
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { listAgentIds } from "../agents/agent-scope.js";
|
||||
import { DEFAULT_CHAT_CHANNEL } from "../channels/registry.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import { withProgress } from "../cli/progress.js";
|
||||
import { loadConfig, resolveConfigPath, resolveStateDir } from "../config/config.js";
|
||||
import {
|
||||
@ -15,6 +14,7 @@ import { PROTOCOL_VERSION } from "../gateway/protocol/index.js";
|
||||
import { loadOrCreateDeviceIdentity } from "../infra/device-identity.js";
|
||||
import { loadGatewayTlsRuntime } from "../infra/tls/gateway.js";
|
||||
import { normalizeAgentId } from "../routing/session-key.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import {
|
||||
GATEWAY_CLIENT_MODES,
|
||||
GATEWAY_CLIENT_NAMES,
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import path from "node:path";
|
||||
import type { AgentCommandOpts } from "./agent/types.js";
|
||||
import {
|
||||
listAgentIds,
|
||||
resolveAgentDir,
|
||||
@ -68,6 +67,7 @@ import { deliverAgentCommandResult } from "./agent/delivery.js";
|
||||
import { resolveAgentRunContext } from "./agent/run-context.js";
|
||||
import { updateSessionStoreAfterAgentRun } from "./agent/session-store.js";
|
||||
import { resolveSession } from "./agent/session.js";
|
||||
import type { AgentCommandOpts } from "./agent/types.js";
|
||||
|
||||
type PersistSessionEntryParams = {
|
||||
sessionStore: Record<string, SessionEntry>;
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type {
|
||||
ChannelsWizardMode,
|
||||
ConfigureWizardParams,
|
||||
WizardSection,
|
||||
} from "./configure.shared.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { readConfigFileSnapshot, resolveGatewayPort, writeConfigFile } from "../config/config.js";
|
||||
import { logConfigUpdated } from "../config/logging.js";
|
||||
import { ensureWebAppBuilt } from "../gateway/server-web-app.js";
|
||||
import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { note } from "../terminal/note.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
@ -19,6 +14,11 @@ import { removeChannelConfigWizard } from "./configure.channels.js";
|
||||
import { maybeInstallDaemon } from "./configure.daemon.js";
|
||||
import { promptAuthConfig } from "./configure.gateway-auth.js";
|
||||
import { promptGatewayConfig } from "./configure.gateway.js";
|
||||
import type {
|
||||
ChannelsWizardMode,
|
||||
ConfigureWizardParams,
|
||||
WizardSection,
|
||||
} from "./configure.shared.js";
|
||||
import {
|
||||
CONFIGURE_SECTION_OPTIONS,
|
||||
confirm,
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import type { OpenClawConfig } from "../../../config/config.js";
|
||||
import type { OnboardOptions } from "../../onboard-types.js";
|
||||
import { resolveGatewayService } from "../../../daemon/service.js";
|
||||
import { isSystemdUserServiceAvailable } from "../../../daemon/systemd.js";
|
||||
import { ensureWebAppBuilt } from "../../../gateway/server-web-app.js";
|
||||
import { ensureControlUiAssetsBuilt } from "../../../infra/control-ui-assets.js";
|
||||
import type { RuntimeEnv } from "../../../runtime.js";
|
||||
import { buildGatewayInstallPlan, gatewayInstallErrorHint } from "../../daemon-install-helpers.js";
|
||||
import { DEFAULT_GATEWAY_DAEMON_RUNTIME, isGatewayDaemonRuntime } from "../../daemon-runtime.js";
|
||||
import type { OnboardOptions } from "../../onboard-types.js";
|
||||
import { ensureSystemdUserLingerNonInteractive } from "../../systemd-linger.js";
|
||||
|
||||
export async function installGatewayDaemonNonInteractive(params: {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { OpenClawConfig } from "../../../config/config.js";
|
||||
import type { RuntimeEnv } from "../../../runtime.js";
|
||||
import type { OnboardOptions } from "../../onboard-types.js";
|
||||
import { randomToken } from "../../onboard-helpers.js";
|
||||
import type { OnboardOptions } from "../../onboard-types.js";
|
||||
|
||||
export function applyNonInteractiveGatewayConfig(params: {
|
||||
nextConfig: OpenClawConfig;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { Skill } from "@mariozechner/pi-coding-agent";
|
||||
import crypto from "node:crypto";
|
||||
import type { Skill } from "@mariozechner/pi-coding-agent";
|
||||
import type { ChatType } from "../../channels/chat-type.js";
|
||||
import type { ChannelId } from "../../channels/plugins/types.js";
|
||||
import type { DeliveryContext } from "../../utils/delivery-context.js";
|
||||
|
||||
@ -323,6 +323,11 @@ export type GatewayConfig = {
|
||||
* to determine the client IP for local pairing and HTTP checks.
|
||||
*/
|
||||
trustedProxies?: string[];
|
||||
/**
|
||||
* When true, fall back to X-Real-IP header if X-Forwarded-For is absent.
|
||||
* Only applies when trustedProxies is configured.
|
||||
*/
|
||||
allowRealIpFallback?: boolean;
|
||||
/** Ironclaw Next.js web app served alongside the gateway. */
|
||||
webApp?: GatewayWebAppConfig;
|
||||
/** Tool access restrictions for HTTP /tools/invoke endpoint. */
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import type { Server as HttpServer } from "node:http";
|
||||
import type { WebSocketServer } from "ws";
|
||||
import type { CanvasHostHandler, CanvasHostServer } from "../canvas-host/server.js";
|
||||
import { type ChannelId, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import { stopGmailWatcher } from "../hooks/gmail-watcher.js";
|
||||
import type { HeartbeatRunner } from "../infra/heartbeat-runner.js";
|
||||
import type { PluginServicesHandle } from "../plugins/services.js";
|
||||
import type { WebAppHandle } from "./server-web-app.js";
|
||||
import { type ChannelId, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import { stopGmailWatcher } from "../hooks/gmail-watcher.js";
|
||||
|
||||
export function createGatewayCloseHandler(params: {
|
||||
bonjourStop: (() => Promise<void>) | null;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import type { GatewayRequestHandlerOptions, GatewayRequestHandlers } from "./types.js";
|
||||
import { listAgentIds } from "../../agents/agent-scope.js";
|
||||
import { BARE_SESSION_RESET_PROMPT } from "../../auto-reply/reply/session-reset-prompt.js";
|
||||
import { agentCommand } from "../../commands/agent.js";
|
||||
@ -52,6 +51,7 @@ import { waitForAgentJob } from "./agent-job.js";
|
||||
import { injectTimestamp, timestampOptsFromConfig } from "./agent-timestamp.js";
|
||||
import { normalizeRpcAttachmentsToChatAttachments } from "./attachment-normalize.js";
|
||||
import { sessionsHandlers } from "./sessions.js";
|
||||
import type { GatewayRequestHandlerOptions, GatewayRequestHandlers } from "./types.js";
|
||||
|
||||
const RESET_COMMAND_RE = /^\/(new|reset)(?:\s+([\s\S]*))?$/i;
|
||||
|
||||
@ -694,19 +694,21 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
},
|
||||
|
||||
"agent.subscribe": ({ params, client, respond, context }) => {
|
||||
const validated = validateAgentSubscribeParams(params);
|
||||
if (!validated.ok) {
|
||||
if (!validateAgentSubscribeParams(params)) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_PARAMS, formatValidationErrors(validated.errors)),
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
`invalid agent.subscribe params: ${formatValidationErrors(validateAgentSubscribeParams.errors)}`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const p = validated.value;
|
||||
const p = params;
|
||||
const connId = client?.connId;
|
||||
if (!connId) {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_PARAMS, "no connection id"));
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "no connection id"));
|
||||
return;
|
||||
}
|
||||
context.registerSessionSubscription(p.sessionKey, connId);
|
||||
@ -718,21 +720,23 @@ export const agentHandlers: GatewayRequestHandlers = {
|
||||
},
|
||||
|
||||
"agent.unsubscribe": ({ params, client, respond, context }) => {
|
||||
const validated = validateAgentUnsubscribeParams(params);
|
||||
if (!validated.ok) {
|
||||
if (!validateAgentUnsubscribeParams(params)) {
|
||||
respond(
|
||||
false,
|
||||
undefined,
|
||||
errorShape(ErrorCodes.INVALID_PARAMS, formatValidationErrors(validated.errors)),
|
||||
errorShape(
|
||||
ErrorCodes.INVALID_REQUEST,
|
||||
`invalid agent.unsubscribe params: ${formatValidationErrors(validateAgentUnsubscribeParams.errors)}`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
const connId = client?.connId;
|
||||
if (!connId) {
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_PARAMS, "no connection id"));
|
||||
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "no connection id"));
|
||||
return;
|
||||
}
|
||||
context.unregisterSessionSubscription(validated.value.sessionKey, connId);
|
||||
context.unregisterSessionSubscription(params.sessionKey, connId);
|
||||
respond(true, {});
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import { CURRENT_SESSION_VERSION, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import type { GatewayRequestContext, GatewayRequestHandlers } from "./types.js";
|
||||
import { CURRENT_SESSION_VERSION, SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { resolveSessionAgentId } from "../../agents/agent-scope.js";
|
||||
import { resolveThinkingDefault } from "../../agents/model-selection.js";
|
||||
import { resolveAgentTimeoutMs } from "../../agents/timeout.js";
|
||||
import { dispatchInboundMessage } from "../../auto-reply/dispatch.js";
|
||||
import { createReplyDispatcher } from "../../auto-reply/reply/reply-dispatcher.js";
|
||||
import type { MsgContext } from "../../auto-reply/templating.js";
|
||||
import { createReplyPrefixOptions } from "../../channels/reply-prefix.js";
|
||||
import { resolveSessionFilePath } from "../../config/sessions.js";
|
||||
import { resolveSendPolicy } from "../../sessions/send-policy.js";
|
||||
@ -43,6 +42,7 @@ import {
|
||||
import { formatForLog } from "../ws-log.js";
|
||||
import { injectTimestamp, timestampOptsFromConfig } from "./agent-timestamp.js";
|
||||
import { normalizeRpcAttachmentsToChatAttachments } from "./attachment-normalize.js";
|
||||
import type { GatewayRequestContext, GatewayRequestHandlers } from "./types.js";
|
||||
|
||||
type TranscriptAppendResult = {
|
||||
ok: boolean;
|
||||
@ -417,7 +417,7 @@ function appendAssistantTranscriptMessage(params: {
|
||||
// IMPORTANT: Use SessionManager so the entry is attached to the current leaf via parentId.
|
||||
// Raw jsonl appends break the parent chain and can hide compaction summaries from context.
|
||||
const sessionManager = SessionManager.open(transcriptPath);
|
||||
const messageId = sessionManager.appendMessage(messageBody);
|
||||
const messageId = sessionManager.appendMessage(messageBody as unknown as AppendMessageArg);
|
||||
return { ok: true, messageId, message: messageBody };
|
||||
} catch (err) {
|
||||
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
||||
@ -478,7 +478,7 @@ function appendUserTranscriptMessage(params: {
|
||||
// IMPORTANT: Use SessionManager so the entry is attached to the current leaf via parentId.
|
||||
// Raw jsonl appends break the parent chain and can hide compaction summaries from context.
|
||||
const sessionManager = SessionManager.open(transcriptPath);
|
||||
const messageId = sessionManager.appendMessage(messageBody);
|
||||
const messageId = sessionManager.appendMessage(messageBody as unknown as AppendMessageArg);
|
||||
return { ok: true, messageId, message: messageBody };
|
||||
} catch (err) {
|
||||
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { Server as HttpServer } from "node:http";
|
||||
import { WebSocketServer } from "ws";
|
||||
import { CANVAS_HOST_PATH } from "../canvas-host/a2ui.js";
|
||||
import { type CanvasHostHandler, createCanvasHostHandler } from "../canvas-host/server.js";
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import type { PluginRegistry } from "../plugins/registry.js";
|
||||
@ -9,11 +11,6 @@ import type { ResolvedGatewayAuth } from "./auth.js";
|
||||
import type { ChatAbortControllerEntry } from "./chat-abort.js";
|
||||
import type { ControlUiRootState } from "./control-ui.js";
|
||||
import type { HooksConfigResolved } from "./hooks.js";
|
||||
import type { DedupeEntry } from "./server-shared.js";
|
||||
import type { GatewayTlsRuntime } from "./server/tls.js";
|
||||
import type { GatewayWsClient } from "./server/ws-types.js";
|
||||
import { CANVAS_HOST_PATH } from "../canvas-host/a2ui.js";
|
||||
import { type CanvasHostHandler, createCanvasHostHandler } from "../canvas-host/server.js";
|
||||
import { resolveGatewayListenHosts } from "./net.js";
|
||||
import {
|
||||
createGatewayBroadcaster,
|
||||
@ -22,6 +19,8 @@ import {
|
||||
} from "./server-broadcast.js";
|
||||
import {
|
||||
type ChatRunEntry,
|
||||
type SessionEventLog,
|
||||
type SessionSubscriptionRegistry,
|
||||
createChatRunState,
|
||||
createToolEventRecipientRegistry,
|
||||
createSessionEventLog,
|
||||
@ -29,9 +28,12 @@ import {
|
||||
} from "./server-chat.js";
|
||||
import { MAX_PAYLOAD_BYTES } from "./server-constants.js";
|
||||
import { attachGatewayUpgradeHandler, createGatewayHttpServer } from "./server-http.js";
|
||||
import type { DedupeEntry } from "./server-shared.js";
|
||||
import { createGatewayHooksRequestHandler } from "./server/hooks.js";
|
||||
import { listenGatewayHttpServer } from "./server/http-listen.js";
|
||||
import { createGatewayPluginRequestHandler } from "./server/plugins-http.js";
|
||||
import type { GatewayTlsRuntime } from "./server/tls.js";
|
||||
import type { GatewayWsClient } from "./server/ws-types.js";
|
||||
|
||||
export async function createGatewayRuntimeState(params: {
|
||||
cfg: import("../config/config.js").OpenClawConfig;
|
||||
@ -79,6 +81,8 @@ export async function createGatewayRuntimeState(params: {
|
||||
) => ChatRunEntry | undefined;
|
||||
chatAbortControllers: Map<string, ChatAbortControllerEntry>;
|
||||
toolEventRecipients: ReturnType<typeof createToolEventRecipientRegistry>;
|
||||
sessionEventLog: SessionEventLog;
|
||||
sessionSubscriptions: SessionSubscriptionRegistry;
|
||||
}> {
|
||||
let canvasHost: CanvasHostHandler | null = null;
|
||||
if (params.canvasHostEnabled) {
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { loadConfig } from "../config/config.js";
|
||||
import type { loadOpenClawPlugins } from "../plugins/loader.js";
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
|
||||
import { loadModelCatalog } from "../agents/model-catalog.js";
|
||||
import {
|
||||
@ -10,6 +7,8 @@ import {
|
||||
} from "../agents/model-selection.js";
|
||||
import { resolveAgentSessionDirs } from "../agents/session-dirs.js";
|
||||
import { cleanStaleLockFiles } from "../agents/session-write-lock.js";
|
||||
import type { CliDeps } from "../cli/deps.js";
|
||||
import type { loadConfig } from "../config/config.js";
|
||||
import { resolveStateDir } from "../config/paths.js";
|
||||
import { startGmailWatcherWithLogs } from "../hooks/gmail-watcher-lifecycle.js";
|
||||
import {
|
||||
@ -19,6 +18,7 @@ import {
|
||||
} from "../hooks/internal-hooks.js";
|
||||
import { loadInternalHooks } from "../hooks/loader.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import type { loadOpenClawPlugins } from "../plugins/loader.js";
|
||||
import { type PluginServicesHandle, startPluginServices } from "../plugins/services.js";
|
||||
import { startBrowserControlServerIfEnabled } from "./server-browser.js";
|
||||
import {
|
||||
|
||||
@ -42,7 +42,7 @@ describe("server-web-app", () => {
|
||||
it("returns true when standalone server.js exists", async () => {
|
||||
const { hasStandaloneBuild, resolveStandaloneServerJs } = await import("./server-web-app.js");
|
||||
const webAppDir = "/pkg/apps/web";
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
return String(p) === resolveStandaloneServerJs(webAppDir);
|
||||
});
|
||||
expect(hasStandaloneBuild(webAppDir)).toBe(true);
|
||||
@ -60,7 +60,7 @@ describe("server-web-app", () => {
|
||||
describe("hasLegacyNextBuild", () => {
|
||||
it("returns true when .next/BUILD_ID exists", async () => {
|
||||
const { hasLegacyNextBuild } = await import("./server-web-app.js");
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
return String(p).endsWith(path.join(".next", "BUILD_ID"));
|
||||
});
|
||||
expect(hasLegacyNextBuild("/pkg/apps/web")).toBe(true);
|
||||
@ -78,7 +78,7 @@ describe("server-web-app", () => {
|
||||
describe("isInWorkspace", () => {
|
||||
it("returns true when pnpm-workspace.yaml exists at root", async () => {
|
||||
const { isInWorkspace } = await import("./server-web-app.js");
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
return String(p).endsWith("pnpm-workspace.yaml");
|
||||
});
|
||||
expect(isInWorkspace("/proj/apps/web")).toBe(true);
|
||||
@ -132,7 +132,7 @@ describe("server-web-app", () => {
|
||||
|
||||
it("returns ok when standalone build exists", async () => {
|
||||
const { ensureWebAppBuilt } = await import("./server-web-app.js");
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -148,7 +148,7 @@ describe("server-web-app", () => {
|
||||
|
||||
it("returns ok when legacy .next/BUILD_ID exists (dev workspace)", async () => {
|
||||
const { ensureWebAppBuilt } = await import("./server-web-app.js");
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -164,7 +164,7 @@ describe("server-web-app", () => {
|
||||
|
||||
it("returns error for global install when no build found", async () => {
|
||||
const { ensureWebAppBuilt } = await import("./server-web-app.js");
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
// Only the package.json exists — no build, no workspace.
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
@ -266,7 +266,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled } = await import("./server-web-app.js");
|
||||
mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -304,7 +304,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled } = await import("./server-web-app.js");
|
||||
mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -337,7 +337,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled } = await import("./server-web-app.js");
|
||||
mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
// Only package.json exists — no builds, no workspace.
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
@ -359,7 +359,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled, DEFAULT_WEB_APP_PORT } = await import("./server-web-app.js");
|
||||
mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -383,7 +383,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled } = await import("./server-web-app.js");
|
||||
const child = mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -415,7 +415,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled } = await import("./server-web-app.js");
|
||||
const child = mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -450,7 +450,7 @@ describe("server-web-app", () => {
|
||||
|
||||
// resolveWebAppDir() needs to find a valid directory before reaching
|
||||
// the port check, so mock existsSync for the package.json check.
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
@ -491,7 +491,7 @@ describe("server-web-app", () => {
|
||||
const { startWebAppIfEnabled } = await import("./server-web-app.js");
|
||||
mockChildProcess();
|
||||
|
||||
existsSyncSpy.mockImplementation((p) => {
|
||||
existsSyncSpy.mockImplementation((p: unknown) => {
|
||||
const s = String(p);
|
||||
if (s.endsWith(path.join("apps", "web", "package.json"))) {
|
||||
return true;
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
import path from "node:path";
|
||||
import type { CanvasHostServer } from "../canvas-host/server.js";
|
||||
import type { PluginServicesHandle } from "../plugins/services.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { ControlUiRootState } from "./control-ui.js";
|
||||
import type { startBrowserControlServerIfEnabled } from "./server-browser.js";
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { getActiveEmbeddedRunCount } from "../agents/pi-embedded-runner/runs.js";
|
||||
import { registerSkillsChangeListener } from "../agents/skills/refresh.js";
|
||||
import { initSubagentRegistry } from "../agents/subagent-registry.js";
|
||||
import { getTotalPendingReplies } from "../auto-reply/reply/dispatcher-registry.js";
|
||||
import type { CanvasHostServer } from "../canvas-host/server.js";
|
||||
import { type ChannelId, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import { createDefaultDeps } from "../cli/deps.js";
|
||||
@ -46,17 +42,21 @@ import { startDiagnosticHeartbeat, stopDiagnosticHeartbeat } from "../logging/di
|
||||
import { createSubsystemLogger, runtimeForLogger } from "../logging/subsystem.js";
|
||||
import { getGlobalHookRunner, runGlobalGatewayStopSafely } from "../plugins/hook-runner-global.js";
|
||||
import { createEmptyPluginRegistry } from "../plugins/registry.js";
|
||||
import type { PluginServicesHandle } from "../plugins/services.js";
|
||||
import { getTotalQueueSize } from "../process/command-queue.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { runOnboardingWizard } from "../wizard/onboarding.js";
|
||||
import { createAuthRateLimiter, type AuthRateLimiter } from "./auth-rate-limit.js";
|
||||
import { startChannelHealthMonitor } from "./channel-health-monitor.js";
|
||||
import { startGatewayConfigReloader } from "./config-reload.js";
|
||||
import type { ControlUiRootState } from "./control-ui.js";
|
||||
import {
|
||||
GATEWAY_EVENT_UPDATE_AVAILABLE,
|
||||
type GatewayUpdateAvailableEventPayload,
|
||||
} from "./events.js";
|
||||
import { ExecApprovalManager } from "./exec-approval-manager.js";
|
||||
import { NodeRegistry } from "./node-registry.js";
|
||||
import type { startBrowserControlServerIfEnabled } from "./server-browser.js";
|
||||
import { createChannelManager } from "./server-channels.js";
|
||||
import { createAgentEventHandler } from "./server-chat.js";
|
||||
import { createGatewayCloseHandler } from "./server-close.js";
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
resolveDefaultAgentId,
|
||||
resolveAgentWorkspaceDir,
|
||||
@ -14,6 +13,7 @@ import {
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js";
|
||||
import { resolveConfiguredModelRef } from "../agents/model-selection.js";
|
||||
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
|
||||
const log = createSubsystemLogger("llm-slug-generator");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { PortListener, PortListenerKind, PortUsage } from "./ports-types.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { PortListener, PortListenerKind, PortUsage } from "./ports-types.js";
|
||||
|
||||
export function classifyPortListener(listener: PortListener, port: number): PortListenerKind {
|
||||
const raw = `${listener.commandLine ?? ""} ${listener.command ?? ""}`.trim().toLowerCase();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import type { Llama, LlamaEmbeddingContext, LlamaModel } from "node-llama-cpp";
|
||||
import fsSync from "node:fs";
|
||||
import type { Llama, LlamaEmbeddingContext, LlamaModel } from "node-llama-cpp";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { formatErrorMessage } from "../infra/errors.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ExecFn } from "./windows-acl.js";
|
||||
import { resolveSandboxConfigForAgent } from "../agents/sandbox.js";
|
||||
import { execDockerRaw } from "../agents/sandbox/docker.js";
|
||||
import { resolveBrowserConfig, resolveProfile } from "../browser/config.js";
|
||||
import { resolveBrowserControlAuth } from "../browser/control-auth.js";
|
||||
import { listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveConfigPath, resolveStateDir } from "../config/paths.js";
|
||||
import { resolveGatewayAuth } from "../gateway/auth.js";
|
||||
import { buildGatewayConnectionDetails } from "../gateway/call.js";
|
||||
@ -40,6 +39,7 @@ import {
|
||||
inspectPathPermissions,
|
||||
} from "./audit-fs.js";
|
||||
import { DEFAULT_GATEWAY_HTTP_TOOL_DENY } from "./dangerous-tools.js";
|
||||
import type { ExecFn } from "./windows-acl.js";
|
||||
|
||||
export type SecurityAuditSeverity = "info" | "warn" | "critical";
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { Chat, Message } from "@grammyjs/types";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { Chat, Message } from "@grammyjs/types";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { escapeRegExp, formatEnvelopeTimestamp } from "../../test/helpers/envelope-timestamp.js";
|
||||
import { withEnvAsync } from "../test-utils/env.js";
|
||||
|
||||
@ -13,10 +13,12 @@ import {
|
||||
enqueueSystemEventSpy,
|
||||
getLoadConfigMock,
|
||||
getReadChannelAllowFromStoreMock,
|
||||
getUpsertChannelPairingRequestMock,
|
||||
getOnHandler,
|
||||
listSkillCommandsForAgents,
|
||||
onSpy,
|
||||
replySpy,
|
||||
sendChatActionSpy,
|
||||
sendMessageSpy,
|
||||
setMyCommandsSpy,
|
||||
wasSentByBot,
|
||||
@ -25,6 +27,7 @@ import { createTelegramBot } from "./bot.js";
|
||||
|
||||
const loadConfig = getLoadConfigMock();
|
||||
const readChannelAllowFromStore = getReadChannelAllowFromStoreMock();
|
||||
const upsertChannelPairingRequest = getUpsertChannelPairingRequestMock();
|
||||
|
||||
function resolveSkillCommands(config: Parameters<typeof listNativeCommandSpecsForConfig>[0]) {
|
||||
void config;
|
||||
@ -280,7 +283,6 @@ describe("createTelegramBot", () => {
|
||||
|
||||
try {
|
||||
onSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
||||
replySpy.mockReset();
|
||||
|
||||
createTelegramBot({ token: "tok" });
|
||||
@ -321,7 +323,6 @@ describe("createTelegramBot", () => {
|
||||
it("requests pairing by default for unknown DM senders", async () => {
|
||||
onSpy.mockReset();
|
||||
sendMessageSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
||||
replySpy.mockReset();
|
||||
|
||||
loadConfig.mockReturnValue({
|
||||
@ -361,7 +362,6 @@ describe("createTelegramBot", () => {
|
||||
it("does not resend pairing code when a request is already pending", async () => {
|
||||
onSpy.mockReset();
|
||||
sendMessageSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
||||
replySpy.mockReset();
|
||||
|
||||
loadConfig.mockReturnValue({
|
||||
@ -414,7 +414,6 @@ describe("createTelegramBot", () => {
|
||||
|
||||
it("accepts group messages when mentionPatterns match (without @botUsername)", async () => {
|
||||
onSpy.mockReset();
|
||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
||||
replySpy.mockReset();
|
||||
|
||||
loadConfig.mockReturnValue({
|
||||
|
||||
@ -8,13 +8,6 @@ import {
|
||||
Text,
|
||||
TUI,
|
||||
} from "@mariozechner/pi-tui";
|
||||
import type {
|
||||
AgentSummary,
|
||||
SessionInfo,
|
||||
SessionScope,
|
||||
TuiOptions,
|
||||
TuiStateAccess,
|
||||
} from "./tui-types.js";
|
||||
import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import {
|
||||
@ -34,6 +27,13 @@ import { formatTokens } from "./tui-formatters.js";
|
||||
import { createLocalShellRunner } from "./tui-local-shell.js";
|
||||
import { createOverlayHandlers } from "./tui-overlays.js";
|
||||
import { createSessionActions } from "./tui-session-actions.js";
|
||||
import type {
|
||||
AgentSummary,
|
||||
SessionInfo,
|
||||
SessionScope,
|
||||
TuiOptions,
|
||||
TuiStateAccess,
|
||||
} from "./tui-types.js";
|
||||
import { buildWaitingStatusMessage, defaultWaitingPhrases } from "./tui-waiting.js";
|
||||
|
||||
export { resolveFinalAssistantText } from "./tui-formatters.js";
|
||||
|
||||
@ -1,8 +1,3 @@
|
||||
import type { OnboardOptions } from "../commands/onboard-types.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { GatewayWizardSettings, WizardFlow } from "./onboarding.types.js";
|
||||
import type { WizardPrompter } from "./prompts.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import {
|
||||
buildGatewayInstallPlan,
|
||||
@ -22,6 +17,8 @@ import {
|
||||
waitForGatewayReachable,
|
||||
resolveControlUiLinks,
|
||||
} from "../commands/onboard-helpers.js";
|
||||
import type { OnboardOptions } from "../commands/onboard-types.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveGatewayService } from "../daemon/service.js";
|
||||
import { isSystemdUserServiceAvailable } from "../daemon/systemd.js";
|
||||
import {
|
||||
@ -30,7 +27,10 @@ import {
|
||||
probeForWebApp,
|
||||
} from "../gateway/server-web-app.js";
|
||||
import { ensureControlUiAssetsBuilt } from "../infra/control-ui-assets.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { setupOnboardingShellCompletion } from "./onboarding.completion.js";
|
||||
import type { GatewayWizardSettings, WizardFlow } from "./onboarding.types.js";
|
||||
import type { WizardPrompter } from "./prompts.js";
|
||||
|
||||
type FinalizeOnboardingOptions = {
|
||||
flow: WizardFlow;
|
||||
|
||||
@ -1,24 +1,24 @@
|
||||
import type { GatewayAuthChoice } from "../commands/onboard-types.js";
|
||||
import type { GatewayBindMode, GatewayTailscaleMode, OpenClawConfig } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type {
|
||||
GatewayWizardSettings,
|
||||
QuickstartGatewayDefaults,
|
||||
WizardFlow,
|
||||
} from "./onboarding.types.js";
|
||||
import type { WizardPrompter } from "./prompts.js";
|
||||
import {
|
||||
normalizeGatewayTokenInput,
|
||||
randomToken,
|
||||
validateGatewayPasswordInput,
|
||||
} from "../commands/onboard-helpers.js";
|
||||
import type { GatewayAuthChoice } from "../commands/onboard-types.js";
|
||||
import type { GatewayBindMode, GatewayTailscaleMode, OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
TAILSCALE_DOCS_LINES,
|
||||
TAILSCALE_EXPOSURE_OPTIONS,
|
||||
TAILSCALE_MISSING_BIN_NOTE_LINES,
|
||||
} from "../gateway/gateway-config-prompts.shared.js";
|
||||
import { findTailscaleBinary } from "../infra/tailscale.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { validateIPv4AddressInput } from "../shared/net/ipv4.js";
|
||||
import type {
|
||||
GatewayWizardSettings,
|
||||
QuickstartGatewayDefaults,
|
||||
WizardFlow,
|
||||
} from "./onboarding.types.js";
|
||||
import type { WizardPrompter } from "./prompts.js";
|
||||
|
||||
// These commands are "high risk" (privacy writes/recording) and should be
|
||||
// explicitly armed by the user when they want to use them.
|
||||
|
||||
@ -2,10 +2,10 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { WizardPrompter, WizardSelectParams } from "./prompts.js";
|
||||
import { DEFAULT_BOOTSTRAP_FILENAME } from "../agents/workspace.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { runOnboardingWizard } from "./onboarding.js";
|
||||
import type { WizardPrompter, WizardSelectParams } from "./prompts.js";
|
||||
|
||||
const ensureAuthProfileStore = vi.hoisted(() => vi.fn(() => ({ profiles: {} })));
|
||||
const promptAuthChoiceGrouped = vi.hoisted(() => vi.fn(async () => "skip"));
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import type {
|
||||
GatewayAuthChoice,
|
||||
OnboardMode,
|
||||
@ -5,17 +6,16 @@ import type {
|
||||
ResetScope,
|
||||
} from "../commands/onboard-types.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { QuickstartGatewayDefaults, WizardFlow } from "./onboarding.types.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
import {
|
||||
DEFAULT_GATEWAY_PORT,
|
||||
readConfigFileSnapshot,
|
||||
resolveGatewayPort,
|
||||
writeConfigFile,
|
||||
} from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
import type { QuickstartGatewayDefaults, WizardFlow } from "./onboarding.types.js";
|
||||
import { WizardCancelledError, type WizardPrompter } from "./prompts.js";
|
||||
|
||||
async function requireRiskAcknowledgement(params: {
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import type { OpenClawApp } from "./app.ts";
|
||||
import type { GatewayHelloOk } from "./gateway.ts";
|
||||
import type { ChatAttachment, ChatQueueItem } from "./ui-types.ts";
|
||||
import { parseAgentSessionKey } from "../../../src/sessions/session-key-utils.js";
|
||||
import { scheduleChatScroll } from "./app-scroll.ts";
|
||||
import { setLastActiveSessionKey } from "./app-settings.ts";
|
||||
import { resetToolStream } from "./app-tool-stream.ts";
|
||||
import type { OpenClawApp } from "./app.ts";
|
||||
import { abortChatRun, loadChatHistory, sendChatMessage } from "./controllers/chat.ts";
|
||||
import { loadSessions } from "./controllers/sessions.ts";
|
||||
import type { GatewayHelloOk } from "./gateway.ts";
|
||||
import { normalizeBasePath } from "./navigation.ts";
|
||||
import type { ChatAttachment, ChatQueueItem } from "./ui-types.ts";
|
||||
import { generateUUID } from "./uuid.ts";
|
||||
|
||||
export type ChatHost = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user