Extract agent setup tooling seam
This commit is contained in:
parent
6bb7d4ddf7
commit
d5c907016f
10 changed files with 219 additions and 165 deletions
|
|
@ -67,6 +67,7 @@ const behaviorTests = [
|
|||
".test-dist/tests/integrations-view-state.test.js",
|
||||
".test-dist/tests/familiars-view-state.test.js",
|
||||
".test-dist/tests/agent-setup-actions.test.js",
|
||||
".test-dist/tests/agent-setup-actions-tooling.test.js",
|
||||
".test-dist/tests/agent-setup-command-runner.test.js",
|
||||
".test-dist/tests/agent-setup-command-context.test.js",
|
||||
".test-dist/tests/agent-setup-support.test.js",
|
||||
|
|
|
|||
157
apps/desktop/src/agent-setup-actions-tooling.ts
Normal file
157
apps/desktop/src/agent-setup-actions-tooling.ts
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
import { app } from "electron";
|
||||
import type { ClaudeCommandSpec, FamiliarOSCommandMode } from "@familiaros/claude";
|
||||
|
||||
import {
|
||||
buildCursorSetupSnapshot,
|
||||
buildOpenCodeSetupSnapshot,
|
||||
installCursorGlobalConfig,
|
||||
installOpenCodeGlobalConfig,
|
||||
removeCursorGlobalConfig,
|
||||
removeOpenCodeGlobalConfig,
|
||||
replaceCursorGlobalConfig,
|
||||
type CursorSetupPreview,
|
||||
type CursorSetupStatus,
|
||||
type OpenCodeSetupPreview,
|
||||
type OpenCodeSetupStatus,
|
||||
} from "./agent-setup-editor-tools.js";
|
||||
import { buildFamiliarOSMcpServerPreview } from "./agent-setup-support.js";
|
||||
import {
|
||||
getAgentSetupCliEntryPath,
|
||||
getCliPackageVersion,
|
||||
getMcpPackageVersion,
|
||||
getOpenCodePackageVersion,
|
||||
getPreferredNodeCommand,
|
||||
getPreferredOpenCodeCommand,
|
||||
} from "./agent-setup-command-context.js";
|
||||
import type { AgentSetupCommandResult } from "./agent-setup-command-runner.js";
|
||||
import type { AgentSetupActionResult, FamiliarOSMcpServerHealth } from "./agent-setup.js";
|
||||
|
||||
type CommandResult = AgentSetupCommandResult;
|
||||
|
||||
export async function getOpenCodeSetup(
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
selectedPetId: string | undefined,
|
||||
runCommandFn: (spec: ClaudeCommandSpec) => Promise<CommandResult>,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<{ readonly status: OpenCodeSetupStatus; readonly preview: OpenCodeSetupPreview }> {
|
||||
const detected = await runCommandFn({ command: getPreferredOpenCodeCommand(), args: ["--version"] });
|
||||
return buildOpenCodeSetupSnapshot({
|
||||
env: process.env,
|
||||
homeDir: app.getPath("home"),
|
||||
processPlatform: process.platform,
|
||||
selectedPetId,
|
||||
commandMode,
|
||||
cliVersion: getCliPackageVersion(),
|
||||
pluginVersion: getOpenCodePackageVersion(),
|
||||
cliEntryPath: commandMode === "published" ? undefined : getAgentSetupCliEntryPath(commandMode),
|
||||
detectedOk: detected.ok,
|
||||
preferredOpenCodeCommand: getPreferredOpenCodeCommand(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCursorSetup(
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
selectedPetId: string | undefined,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<{ readonly status: CursorSetupStatus; readonly preview: CursorSetupPreview }> {
|
||||
void commandMode;
|
||||
return buildCursorSetupSnapshot({
|
||||
homeDir: app.getPath("home"),
|
||||
selectedPetId,
|
||||
mcpVersion: getMcpPackageVersion(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function runAgentSetupMcpServerHealthCheck(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
runCommandFn: (spec: ClaudeCommandSpec) => Promise<CommandResult>,
|
||||
): Promise<FamiliarOSMcpServerHealth> {
|
||||
const preview = buildFamiliarOSMcpServerPreview(selectedPetId, commandMode);
|
||||
const result = await runCommandFn({ command: preview.command, args: [...preview.args, "--version"] });
|
||||
if (result.ok) {
|
||||
return { ok: true, output: result.stdout.trim() || "MCP server responded." };
|
||||
}
|
||||
const errorMessage = result.error || result.stderr.trim() || `Command exited with code ${result.exitCode ?? "unknown"}.`;
|
||||
return { ok: false, output: "", error: errorMessage };
|
||||
}
|
||||
|
||||
export async function installOpenCodeGlobal(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
helpers: {
|
||||
readonly runCommand: (spec: ClaudeCommandSpec) => Promise<CommandResult>;
|
||||
readonly summarizeCommandResult: (result: CommandResult) => string;
|
||||
readonly formatUserPath: (path: string | undefined) => string | undefined;
|
||||
},
|
||||
): Promise<AgentSetupActionResult> {
|
||||
if (commandMode === "bundled") {
|
||||
const node = await helpers.runCommand({ command: getPreferredNodeCommand(), args: ["--version"] });
|
||||
if (!node.ok) {
|
||||
return {
|
||||
ok: false,
|
||||
action: "opencode-install",
|
||||
message: `Node.js is required for packaged FamiliarOS commands. Open OpenCode configuration, set the Node.js command path, then try again. ${helpers.summarizeCommandResult(node)}`,
|
||||
changed: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
return installOpenCodeGlobalConfig({
|
||||
env: process.env,
|
||||
homeDir: app.getPath("home"),
|
||||
processPlatform: process.platform,
|
||||
selectedPetId,
|
||||
commandMode,
|
||||
cliVersion: getCliPackageVersion(),
|
||||
pluginVersion: getOpenCodePackageVersion(),
|
||||
cliEntryPath: commandMode === "published" ? undefined : getAgentSetupCliEntryPath(commandMode),
|
||||
formatUserPath: helpers.formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeOpenCodeGlobal(): Promise<AgentSetupActionResult> {
|
||||
return removeOpenCodeGlobalConfig({
|
||||
env: process.env,
|
||||
homeDir: app.getPath("home"),
|
||||
processPlatform: process.platform,
|
||||
});
|
||||
}
|
||||
|
||||
export async function installCursorGlobal(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
void commandMode;
|
||||
return installCursorGlobalConfig({
|
||||
homeDir: app.getPath("home"),
|
||||
selectedPetId,
|
||||
mcpVersion: getMcpPackageVersion(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function replaceCursorGlobal(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
void commandMode;
|
||||
return replaceCursorGlobalConfig({
|
||||
homeDir: app.getPath("home"),
|
||||
selectedPetId,
|
||||
mcpVersion: getMcpPackageVersion(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function removeCursorGlobal(
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
return removeCursorGlobalConfig({
|
||||
homeDir: app.getPath("home"),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
|
@ -9,20 +9,18 @@ import {
|
|||
} from "@familiaros/claude";
|
||||
|
||||
import {
|
||||
buildCursorSetupSnapshot,
|
||||
buildOpenCodeSetupSnapshot,
|
||||
installCursorGlobalConfig,
|
||||
installOpenCodeGlobalConfig,
|
||||
removeCursorGlobalConfig,
|
||||
removeOpenCodeGlobalConfig,
|
||||
replaceCursorGlobalConfig,
|
||||
type CursorSetupPreview,
|
||||
type CursorSetupStatus,
|
||||
type OpenCodeSetupPreview,
|
||||
type OpenCodeSetupStatus,
|
||||
} from "./agent-setup-editor-tools.js";
|
||||
installCursorGlobal,
|
||||
installOpenCodeGlobal,
|
||||
removeCursorGlobal,
|
||||
removeOpenCodeGlobal,
|
||||
replaceCursorGlobal,
|
||||
} from "./agent-setup-actions-tooling.js";
|
||||
export {
|
||||
getCursorSetup,
|
||||
getOpenCodeSetup,
|
||||
runAgentSetupMcpServerHealthCheck,
|
||||
} from "./agent-setup-actions-tooling.js";
|
||||
import {
|
||||
buildFamiliarOSMcpServerPreview,
|
||||
createHookJournalCommand,
|
||||
safeInstallClaudeMemory,
|
||||
safeUninstallClaudeMemory,
|
||||
|
|
@ -32,12 +30,7 @@ import {
|
|||
type JournalAction,
|
||||
} from "./agent-setup-support.js";
|
||||
import {
|
||||
getAgentSetupCliEntryPath,
|
||||
getCliPackageVersion,
|
||||
getMcpPackageVersion,
|
||||
getPreferredClaudeCommand,
|
||||
getOpenCodePackageVersion,
|
||||
getPreferredOpenCodeCommand,
|
||||
getPreferredNodeCommand,
|
||||
} from "./agent-setup-command-context.js";
|
||||
import type { AgentSetupCommandResult } from "./agent-setup-command-runner.js";
|
||||
|
|
@ -45,7 +38,6 @@ import type {
|
|||
AgentSetupAction,
|
||||
AgentSetupActionResult,
|
||||
ClaudeCodeStatus,
|
||||
FamiliarOSMcpServerHealth,
|
||||
} from "./agent-setup.js";
|
||||
|
||||
type CommandResult = AgentSetupCommandResult;
|
||||
|
|
@ -89,56 +81,6 @@ export async function executeAgentSetupResolvedAction(
|
|||
return runClaudeMcpAction(action, previewResult.preview, helpers);
|
||||
}
|
||||
|
||||
export async function getOpenCodeSetup(
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
selectedPetId: string | undefined,
|
||||
runCommandFn: (spec: ClaudeCommandSpec) => Promise<CommandResult>,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<{ readonly status: OpenCodeSetupStatus; readonly preview: OpenCodeSetupPreview }> {
|
||||
const detected = await runCommandFn({ command: getPreferredOpenCodeCommand(), args: ["--version"] });
|
||||
return buildOpenCodeSetupSnapshot({
|
||||
env: process.env,
|
||||
homeDir: app.getPath("home"),
|
||||
processPlatform: process.platform,
|
||||
selectedPetId,
|
||||
commandMode,
|
||||
cliVersion: getCliPackageVersion(),
|
||||
pluginVersion: getOpenCodePackageVersion(),
|
||||
cliEntryPath: commandMode === "published" ? undefined : getAgentSetupCliEntryPath(commandMode),
|
||||
detectedOk: detected.ok,
|
||||
preferredOpenCodeCommand: getPreferredOpenCodeCommand(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCursorSetup(
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
selectedPetId: string | undefined,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<{ readonly status: CursorSetupStatus; readonly preview: CursorSetupPreview }> {
|
||||
void commandMode;
|
||||
return buildCursorSetupSnapshot({
|
||||
homeDir: app.getPath("home"),
|
||||
selectedPetId,
|
||||
mcpVersion: getMcpPackageVersion(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
export async function runAgentSetupMcpServerHealthCheck(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
runCommandFn: (spec: ClaudeCommandSpec) => Promise<CommandResult>,
|
||||
): Promise<FamiliarOSMcpServerHealth> {
|
||||
const preview = buildFamiliarOSMcpServerPreview(selectedPetId, commandMode);
|
||||
const result = await runCommandFn({ command: preview.command, args: [...preview.args, "--version"] });
|
||||
if (result.ok) {
|
||||
return { ok: true, output: result.stdout.trim() || "MCP server responded." };
|
||||
}
|
||||
const errorMessage = result.error || result.stderr.trim() || `Command exited with code ${result.exitCode ?? "unknown"}.`;
|
||||
return { ok: false, output: "", error: errorMessage };
|
||||
}
|
||||
|
||||
async function runImmediateAction(
|
||||
action: AgentSetupAction,
|
||||
helpers: AgentSetupActionHelpers,
|
||||
|
|
@ -315,80 +257,6 @@ function runConfigureClaudeMcpAction(
|
|||
return runAdd(preview, previousStatus, "configure", helpers);
|
||||
}
|
||||
|
||||
async function installOpenCodeGlobal(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
helpers: Pick<AgentSetupActionHelpers, "runCommand" | "summarizeCommandResult" | "formatUserPath">,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
if (commandMode === "bundled") {
|
||||
const node = await helpers.runCommand({ command: getPreferredNodeCommand(), args: ["--version"] });
|
||||
if (!node.ok) {
|
||||
return {
|
||||
ok: false,
|
||||
action: "opencode-install",
|
||||
message: `Node.js is required for packaged FamiliarOS commands. Open OpenCode configuration, set the Node.js command path, then try again. ${helpers.summarizeCommandResult(node)}`,
|
||||
changed: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
return installOpenCodeGlobalConfig({
|
||||
env: process.env,
|
||||
homeDir: app.getPath("home"),
|
||||
processPlatform: process.platform,
|
||||
selectedPetId,
|
||||
commandMode,
|
||||
cliVersion: getCliPackageVersion(),
|
||||
pluginVersion: getOpenCodePackageVersion(),
|
||||
cliEntryPath: commandMode === "published" ? undefined : getAgentSetupCliEntryPath(commandMode),
|
||||
formatUserPath: helpers.formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
async function removeOpenCodeGlobal(): Promise<AgentSetupActionResult> {
|
||||
return removeOpenCodeGlobalConfig({
|
||||
env: process.env,
|
||||
homeDir: app.getPath("home"),
|
||||
processPlatform: process.platform,
|
||||
});
|
||||
}
|
||||
|
||||
async function installCursorGlobal(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
void commandMode;
|
||||
return installCursorGlobalConfig({
|
||||
homeDir: app.getPath("home"),
|
||||
selectedPetId,
|
||||
mcpVersion: getMcpPackageVersion(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
async function replaceCursorGlobal(
|
||||
selectedPetId: string | undefined,
|
||||
commandMode: FamiliarOSCommandMode,
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
void commandMode;
|
||||
return replaceCursorGlobalConfig({
|
||||
homeDir: app.getPath("home"),
|
||||
selectedPetId,
|
||||
mcpVersion: getMcpPackageVersion(),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
async function removeCursorGlobal(
|
||||
formatUserPath: (path: string | undefined) => string | undefined,
|
||||
): Promise<AgentSetupActionResult> {
|
||||
return removeCursorGlobalConfig({
|
||||
homeDir: app.getPath("home"),
|
||||
formatUserPath,
|
||||
});
|
||||
}
|
||||
|
||||
async function runAdd(
|
||||
preview: ClaudeMcpPreview,
|
||||
previousStatus: string,
|
||||
|
|
|
|||
|
|
@ -159,6 +159,7 @@ const appStateFamiliarRecordsSource = readFileSync(join(appDir, "src", "app-stat
|
|||
const appStateStorageSource = readFileSync(join(appDir, "src", "app-state-storage.ts"), "utf8");
|
||||
const agentSetupSource = readFileSync(join(appDir, "src", "agent-setup.ts"), "utf8");
|
||||
const agentSetupActionsSource = readFileSync(join(appDir, "src", "agent-setup-actions.ts"), "utf8");
|
||||
const agentSetupActionsToolingSource = readFileSync(join(appDir, "src", "agent-setup-actions-tooling.ts"), "utf8");
|
||||
const agentSetupCommandRunnerSource = readFileSync(join(appDir, "src", "agent-setup-command-runner.ts"), "utf8");
|
||||
const agentSetupCommandContextSource = readFileSync(join(appDir, "src", "agent-setup-command-context.ts"), "utf8");
|
||||
const agentSetupEditorToolsSource = readFileSync(join(appDir, "src", "agent-setup-editor-tools.ts"), "utf8");
|
||||
|
|
@ -413,9 +414,10 @@ assert.match(agentSetupCommandRunnerSource, /export async function runAgentSetup
|
|||
assert.match(agentSetupCommandRunnerSource, /export function createAgentSetupCommandEnv/, "agent-setup command-runner seam must export PATH environment shaping.");
|
||||
assert.match(agentSetupCommandRunnerSource, /export function summarizeAgentSetupCommandResult/, "agent-setup command-runner seam must export command result summarization.");
|
||||
assert.match(agentSetupActionsSource, /export async function executeAgentSetupResolvedAction/, "agent-setup action seam must export action execution.");
|
||||
assert.match(agentSetupActionsSource, /export async function getOpenCodeSetup/, "agent-setup action seam must export OpenCode setup loading.");
|
||||
assert.match(agentSetupActionsSource, /export async function getCursorSetup/, "agent-setup action seam must export Cursor setup loading.");
|
||||
assert.match(agentSetupActionsSource, /export async function runAgentSetupMcpServerHealthCheck/, "agent-setup action seam must export MCP server health checks.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-actions-tooling(?:\.js)?"/, "agent-setup action seam must import the extracted tooling seam.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function getOpenCodeSetup/, "agent-setup tooling seam must export OpenCode setup loading.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function getCursorSetup/, "agent-setup tooling seam must export Cursor setup loading.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function runAgentSetupMcpServerHealthCheck/, "agent-setup tooling seam must export MCP server health checks.");
|
||||
assert.match(pluginServiceDefaultPetSource, /export async function buildDefaultPetPluginCommands/, "plugin-service default-pet helper must export default familiar command shaping.");
|
||||
assert.match(pluginServiceSupportSource, /from "\.\/plugin-service-actions(?:\.js)?"/, "plugin-service support barrel must re-export the service action seam.");
|
||||
assert.match(pluginServiceActionsSource, /export async function buildPluginCatalogSnapshot/, "plugin-service action seam must export catalog snapshot shaping.");
|
||||
|
|
@ -595,10 +597,10 @@ assert.match(enCatalogSource, /OpenCode/, "Control Center integrations must incl
|
|||
assert.match(enCatalogSource, /Cursor/, "Control Center integrations must include Cursor.");
|
||||
assert.match(enCatalogSource, /Pi/, "Control Center integrations must include Pi.");
|
||||
assert.match(agentSetupSource, /from "\.\/agent-setup-command-context\.js"/, "Agent setup must import the extracted command context helper seam.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-editor-tools\.js"/, "Agent setup action seam must import the extracted editor setup helper seam.");
|
||||
assert.match(agentSetupActionsToolingSource, /from "\.\/agent-setup-editor-tools\.js"/, "Agent setup tooling seam must import the extracted editor setup helper seam.");
|
||||
assert.match(agentSetupSource, /agent-setup-support\.js/, "Agent setup must import and re-export the extracted support helper seam.");
|
||||
assert.match(agentSetupActionsSource, /getCliPackageVersion/, "Agent setup action seam must compose package version metadata through the command context helper.");
|
||||
assert.match(agentSetupActionsSource, /buildOpenCodeSetupSnapshot/, "Agent setup action seam must delegate OpenCode previews through the editor setup helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /getCliPackageVersion/, "Agent setup tooling seam must compose package version metadata through the command context helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /buildOpenCodeSetupSnapshot/, "Agent setup tooling seam must delegate OpenCode previews through the editor setup helper.");
|
||||
assert.match(agentSetupActionsSource, /writeActionJournal/, "Agent setup action seam must delegate journal writes through the support helper.");
|
||||
assert.match(petWindowRenderSource, /from "\.\/familiar-window-render-bubbles(?:\.js)?"/, "familiar-window-render must compose the extracted bubble helper seam.");
|
||||
assert.match(petWindowRenderBubblesSource, /export function createBubbleMarkup/, "familiar-window render bubble seam must export the shared bubble markup builder.");
|
||||
|
|
|
|||
|
|
@ -67,8 +67,7 @@ windows.ts (IPC handlers)
|
|||
├── detectClaudeCodeStatus() (claude --version, claude mcp list)
|
||||
├── agent-setup-actions.ts
|
||||
│ ├── runAgentSetupResolvedAction() (configure/replace/remove, install-memory, hook actions)
|
||||
│ ├── getOpenCodeSetup() / getCursorSetup() (editor setup snapshots)
|
||||
│ └── runAgentSetupMcpServerHealthCheck() (FamiliarOS MCP server health)
|
||||
│ └── agent-setup-actions-tooling.ts (OpenCode/Cursor setup snapshots, global config actions, and FamiliarOS MCP server health)
|
||||
├── agent-setup-command-context.ts
|
||||
│ ├── persisted command path preferences
|
||||
│ └── CLI/package version resolution for agent setup
|
||||
|
|
@ -199,7 +198,8 @@ plugin-service-local-support.ts → plugin-local-loader.ts validates selected fo
|
|||
- `control-center-ipc-plugin.ts`: Plugin snapshot/config/catalog/platform IPC routes for the Control Center
|
||||
- `control-center-ipc-pets.ts`: Familiar/catalog/Codex import and default familiar IPC routes for the Control Center
|
||||
- `control-center-ipc-agent.ts`: Agent setup, toolkit, and FamiliarOS MCP preview/test IPC routes for the Control Center
|
||||
- `agent-setup-actions.ts`: Extracted action execution, OpenCode/Cursor setup loading, hook handling, Claude MCP add/remove orchestration, and FamiliarOS MCP health checks
|
||||
- `agent-setup-actions.ts`: Extracted action execution shell for hook handling plus Claude MCP add/remove orchestration
|
||||
- `agent-setup-actions-tooling.ts`: Extracted OpenCode/Cursor setup loading, global config actions, and FamiliarOS MCP server health checks
|
||||
- `agent-setup-support.ts`: Extracted MCP preview, Claude memory safety wrappers, and bounded action journal helpers for agent setup
|
||||
- `assets.ts`: Tray icon loading with generated fallback
|
||||
- `display.ts`: Screen geometry helpers, familiar window positioning
|
||||
|
|
@ -288,7 +288,8 @@ plugin-service-local-support.ts → plugin-local-loader.ts validates selected fo
|
|||
|
||||
**Agent Integration**:
|
||||
- `agent-setup.ts`: Claude detection, snapshot assembly, selected-pet validation, command wrappers, and public agent-setup API entry points
|
||||
- `agent-setup-actions.ts`: Extracted action execution, editor setup loading, Claude MCP add/remove orchestration, and FamiliarOS MCP server health checks
|
||||
- `agent-setup-actions.ts`: Extracted action execution shell plus Claude MCP add/remove orchestration
|
||||
- `agent-setup-actions-tooling.ts`: Extracted editor setup loading, global config actions, and FamiliarOS MCP server health checks
|
||||
- `agent-setup-command-context.ts`: Agent setup command path persistence, preferred command resolution, and workspace package metadata helpers
|
||||
- `agent-setup-command-runner.ts`: Extracted agent-setup command execution, PATH shaping, Claude command candidate selection, and sanitized command result summarization
|
||||
- `agent-setup-editor-tools.ts`: OpenCode/Cursor global setup status, previews, and config write helpers
|
||||
|
|
|
|||
18
apps/desktop/tests/agent-setup-actions-tooling.test.ts
Normal file
18
apps/desktop/tests/agent-setup-actions-tooling.test.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const agentSetupActionsSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions.ts"), "utf8");
|
||||
const agentSetupActionsToolingSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions-tooling.ts"), "utf8");
|
||||
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-actions-tooling(?:\.js)?"/, "Agent setup action shell must import the extracted tooling seam.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function installOpenCodeGlobal/, "Agent setup tooling seam must export OpenCode global config installation.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function removeOpenCodeGlobal/, "Agent setup tooling seam must export OpenCode global config removal.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function installCursorGlobal/, "Agent setup tooling seam must export Cursor global config installation.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function replaceCursorGlobal/, "Agent setup tooling seam must export Cursor global config replacement.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function removeCursorGlobal/, "Agent setup tooling seam must export Cursor global config removal.");
|
||||
assert.match(agentSetupActionsToolingSource, /buildFamiliarOSMcpServerPreview/, "Agent setup tooling seam must own FamiliarOS MCP server health preview shaping.");
|
||||
|
||||
console.error("Agent setup tooling seam validation passed.");
|
||||
|
|
@ -6,12 +6,14 @@ import { fileURLToPath } from "node:url";
|
|||
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const agentSetupSource = readFileSync(resolve(desktopRoot, "src/agent-setup.ts"), "utf8");
|
||||
const agentSetupActionsSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions.ts"), "utf8");
|
||||
const agentSetupActionsToolingSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions-tooling.ts"), "utf8");
|
||||
|
||||
assert.match(agentSetupSource, /from "\.\/agent-setup-actions\.js"/, "Agent setup must import the extracted action seam.");
|
||||
assert.match(agentSetupActionsSource, /export async function executeAgentSetupResolvedAction/, "Agent setup action seam must export the action executor.");
|
||||
assert.match(agentSetupActionsSource, /export async function getOpenCodeSetup/, "Agent setup action seam must export OpenCode setup loading.");
|
||||
assert.match(agentSetupActionsSource, /export async function getCursorSetup/, "Agent setup action seam must export Cursor setup loading.");
|
||||
assert.match(agentSetupActionsSource, /export async function runAgentSetupMcpServerHealthCheck/, "Agent setup action seam must export MCP server health checks.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-actions-tooling(?:\.js)?"/, "Agent setup action seam must compose the extracted tooling seam.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function getOpenCodeSetup/, "Agent setup tooling seam must export OpenCode setup loading.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function getCursorSetup/, "Agent setup tooling seam must export Cursor setup loading.");
|
||||
assert.match(agentSetupActionsToolingSource, /export async function runAgentSetupMcpServerHealthCheck/, "Agent setup tooling seam must export MCP server health checks.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-support\.js"/, "Agent setup action seam must compose the extracted support helper seam.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-command-context\.js"/, "Agent setup action seam must compose the extracted command context seam.");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,14 +6,16 @@ import { fileURLToPath } from "node:url";
|
|||
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const agentSetupSource = readFileSync(resolve(desktopRoot, "src/agent-setup.ts"), "utf8");
|
||||
const agentSetupActionsSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions.ts"), "utf8");
|
||||
const agentSetupActionsToolingSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions-tooling.ts"), "utf8");
|
||||
const agentSetupCommandContextSource = readFileSync(resolve(desktopRoot, "src/agent-setup-command-context.ts"), "utf8");
|
||||
|
||||
assert.match(agentSetupSource, /from "\.\/agent-setup-command-context\.js"/, "Agent setup must import the extracted command context helper module.");
|
||||
assert.match(agentSetupSource, /updateStoredAgentSetupCommandPaths/, "Agent setup must delegate command path persistence through the extracted command context helper.");
|
||||
assert.match(agentSetupSource, /getPreferredNodeCommand/, "Agent setup must resolve preferred command paths through the extracted command context helper.");
|
||||
assert.match(agentSetupActionsSource, /getCliPackageVersion/, "Agent setup action seam must resolve package version metadata through the extracted command context helper.");
|
||||
assert.match(agentSetupActionsSource, /getAgentSetupCliEntryPath/, "Agent setup action seam must resolve packaged CLI entry metadata through the extracted command context helper.");
|
||||
assert.match(agentSetupActionsSource, /getPreferredOpenCodeCommand/, "Agent setup action seam must resolve preferred OpenCode command paths through the extracted command context helper.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-actions-tooling(?:\.js)?"/, "Agent setup action shell must compose the extracted tooling seam.");
|
||||
assert.match(agentSetupActionsToolingSource, /getCliPackageVersion/, "Agent setup tooling seam must resolve package version metadata through the extracted command context helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /getAgentSetupCliEntryPath/, "Agent setup tooling seam must resolve packaged CLI entry metadata through the extracted command context helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /getPreferredOpenCodeCommand/, "Agent setup tooling seam must resolve preferred OpenCode command paths through the extracted command context helper.");
|
||||
|
||||
assert.match(agentSetupCommandContextSource, /export function getStoredAgentSetupCommandPaths/, "Agent setup command context helper must own stored command path reads.");
|
||||
assert.match(agentSetupCommandContextSource, /export function updateStoredAgentSetupCommandPaths/, "Agent setup command context helper must own command path validation and writes.");
|
||||
|
|
|
|||
|
|
@ -6,14 +6,16 @@ import { fileURLToPath } from "node:url";
|
|||
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const agentSetupSource = readFileSync(resolve(desktopRoot, "src/agent-setup.ts"), "utf8");
|
||||
const agentSetupActionsSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions.ts"), "utf8");
|
||||
const agentSetupActionsToolingSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions-tooling.ts"), "utf8");
|
||||
const agentSetupEditorToolsSource = readFileSync(resolve(desktopRoot, "src/agent-setup-editor-tools.ts"), "utf8");
|
||||
|
||||
assert.match(agentSetupSource, /from "\.\/agent-setup-actions\.js"/, "Agent setup must import the extracted action seam.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-editor-tools\.js"/, "Agent setup action seam must import the extracted editor setup helper module.");
|
||||
assert.match(agentSetupActionsSource, /buildOpenCodeSetupSnapshot/, "Agent setup action seam must delegate OpenCode status/preview building through the extracted helper.");
|
||||
assert.match(agentSetupActionsSource, /buildCursorSetupSnapshot/, "Agent setup action seam must delegate Cursor status/preview building through the extracted helper.");
|
||||
assert.match(agentSetupActionsSource, /installOpenCodeGlobalConfig/, "Agent setup action seam must delegate OpenCode config writes through the extracted helper.");
|
||||
assert.match(agentSetupActionsSource, /replaceCursorGlobalConfig/, "Agent setup action seam must delegate Cursor replace writes through the extracted helper.");
|
||||
assert.match(agentSetupActionsSource, /from "\.\/agent-setup-actions-tooling(?:\.js)?"/, "Agent setup action shell must compose the extracted tooling seam.");
|
||||
assert.match(agentSetupActionsToolingSource, /from "\.\/agent-setup-editor-tools\.js"/, "Agent setup tooling seam must import the extracted editor setup helper module.");
|
||||
assert.match(agentSetupActionsToolingSource, /buildOpenCodeSetupSnapshot/, "Agent setup tooling seam must delegate OpenCode status/preview building through the extracted helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /buildCursorSetupSnapshot/, "Agent setup tooling seam must delegate Cursor status/preview building through the extracted helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /installOpenCodeGlobalConfig/, "Agent setup tooling seam must delegate OpenCode config writes through the extracted helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /replaceCursorGlobalConfig/, "Agent setup tooling seam must delegate Cursor replace writes through the extracted helper.");
|
||||
|
||||
assert.match(agentSetupEditorToolsSource, /export function buildOpenCodeSetupSnapshot/, "Agent setup editor helper must own the OpenCode preview/status seam.");
|
||||
assert.match(agentSetupEditorToolsSource, /export function buildCursorSetupSnapshot/, "Agent setup editor helper must own the Cursor preview/status seam.");
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ import { fileURLToPath } from "node:url";
|
|||
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const agentSetupSource = readFileSync(resolve(desktopRoot, "src/agent-setup.ts"), "utf8");
|
||||
const agentSetupActionsSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions.ts"), "utf8");
|
||||
const agentSetupActionsToolingSource = readFileSync(resolve(desktopRoot, "src/agent-setup-actions-tooling.ts"), "utf8");
|
||||
const agentSetupSupportSource = readFileSync(resolve(desktopRoot, "src/agent-setup-support.ts"), "utf8");
|
||||
|
||||
assert.match(agentSetupSource, /from "\.\/agent-setup-support\.js"/, "Agent setup must import the extracted support helper seam.");
|
||||
assert.match(agentSetupActionsSource, /safeInstallClaudeMemory\(app\.getPath\("home"\)\)/, "Agent setup action seam must delegate Claude memory installs through the extracted support helper.");
|
||||
assert.match(agentSetupActionsSource, /writeActionJournal\(\{\s*entry:/, "Agent setup action seam must delegate action journaling through the extracted support helper.");
|
||||
assert.match(agentSetupActionsSource, /buildFamiliarOSMcpServerPreview/, "Agent setup action seam must delegate MCP server preview shaping through the extracted support helper.");
|
||||
assert.match(agentSetupActionsToolingSource, /buildFamiliarOSMcpServerPreview/, "Agent setup tooling seam must delegate MCP server preview shaping through the extracted support helper.");
|
||||
|
||||
assert.match(agentSetupSupportSource, /export function buildFamiliarOSMcpServerPreview/, "Agent setup support helper must own FamiliarOS MCP preview shaping.");
|
||||
assert.match(agentSetupSupportSource, /export function safeInstallClaudeMemory/, "Agent setup support helper must own Claude memory install safety wrappers.");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue