Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/daemon/src/artifacts/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import path from 'node:path';

const MANIFEST_VERSION = 1;
const MAX_TITLE_LENGTH = 200;
const MAX_ENTRY_LENGTH = 260;
const MAX_SOURCE_SKILL_ID_LENGTH = 128;
const MAX_DESIGN_SYSTEM_ID_LENGTH = 128;
const MAX_SUPPORTING_FILE_LENGTH = 260;
Expand Down
8 changes: 0 additions & 8 deletions apps/daemon/src/artifacts/text-suppression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,6 @@ export function emitWithTextSuppressor(
return true;
}

function possibleDsmlArtifactOpenStart(text: string): number {
return possibleTagStart(text, isPossibleDsmlArtifactOpen);
}

function possibleTagStart(text: string, predicate: (tail: string) => boolean): number {
const min = Math.max(0, text.length - MAX_CANDIDATE_LENGTH);
let index = text.lastIndexOf('<');
Expand All @@ -170,10 +166,6 @@ function isPossibleDsmlArtifactOpen(text: string): boolean {
compact.startsWith(ARTIFACT_OPEN_CANONICAL);
}

function possibleArtifactCloseStart(text: string): number {
return possibleTagStart(text, isPossibleArtifactClose);
}

function isPossibleArtifactClose(text: string): boolean {
if (!text.startsWith('<') || text.includes('>')) return false;
const compact = text.toLowerCase().replace(/[<|/\s]/g, '');
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/byok-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export function isAIHubMixSpeechModel(value: unknown): value is string {
}
export const BYOK_AIHUBMIX_DEFAULT_SPEECH_MODEL = 'aihubmix-tts-1';

const AIHUBMIX_DEFAULT_TTS_MODEL = 'tts-1';
const AIHUBMIX_DEFAULT_TTS_VOICE = 'alloy';

// AIHubMix video knobs for the chat `generate_video` tool. The wire shape
Expand Down
2 changes: 1 addition & 1 deletion apps/daemon/src/connectors/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
type ConnectorToolSafety,
type ConnectorStatus,
} from './catalog.js';
import { composioConnectorProvider, getStaticComposioCatalogDefinitions, type ComposioAuthConfigPrepareResult, type ComposioConnectionStart } from './composio.js';
import { composioConnectorProvider, type ComposioAuthConfigPrepareResult, type ComposioConnectionStart } from './composio.js';

export interface ConnectorExecuteRequest {
connectorId: string;
Expand Down
2 changes: 1 addition & 1 deletion apps/daemon/src/critique/scoreboard.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CritiqueConfig, PanelEvent, PanelistRole, RoundDecision } from '@open-design/contracts/critique';
import type { CritiqueConfig, PanelistRole, RoundDecision } from '@open-design/contracts/critique';

/**
* Per-round scores indexed by panelist role. Absent roles are undefined.
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { migratePlugins } from './plugins/persistence.js';

type SqliteDb = Database.Database;
type DbRow = Record<string, any>;
type JsonObject = Record<string, unknown>;
type ChatSessionMode = 'design' | 'chat' | 'plan';

let dbInstance: SqliteDb | null = null;
Expand Down
13 changes: 0 additions & 13 deletions apps/daemon/src/design-systems/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2855,19 +2855,6 @@ function sanitizeRevisionId(raw: string | undefined): string | null {
return /^[a-zA-Z0-9-]+$/.test(value) ? value : null;
}

async function uniqueSlug(root: string, base: string): Promise<string> {
let candidate = base || 'design-system';
let index = 2;
for (;;) {
try {
await stat(path.join(root, candidate));
candidate = `${base}-${index++}`;
} catch {
return candidate;
}
}
}

async function reserveUniqueSlugDirectory(root: string, base: string): Promise<{ dirId: string; dir: string }> {
await mkdir(root, { recursive: true });
let candidate = base || 'design-system';
Expand Down
2 changes: 0 additions & 2 deletions apps/daemon/src/design-systems/token-contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ type RoleHint = {

const DEFAULT_BODY_FONT =
'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
const DEFAULT_MONO_FONT =
'ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Monaco, Consolas, monospace';

const DEFAULT_TOKEN_VALUES: TokenDefaults = {
'--bg': '#f8fafc',
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/import-export-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Express, Response } from 'express';
import { PROJECT_EXPORT_MANIFEST_SCHEMA, isExportFormat } from '@open-design/contracts';
import nodePath from 'node:path';
import os from 'node:os';
import { readFile, rm } from 'node:fs/promises';
import { isBlocked as isBlockedSystemDir } from './linked-dirs.js';
import type { RouteDeps } from './server-context.js';
import {
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/lint-artifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ export function lintArtifact(rawHtml: unknown): LintFinding[] {
// pedagogical examples ("paste a `<section class="slide">` here") that
// would otherwise fire false positives for the section / slide checks.
const html = rawHtml.replace(/<!--[\s\S]*?-->/g, '');
const lower = html.toLowerCase();

// ── P0-1: purple gradient backgrounds ─────────────────────────────
for (const hex of PURPLE_HEXES) {
Expand Down
48 changes: 0 additions & 48 deletions apps/daemon/src/live-artifacts/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@ const MAX_TITLE_LENGTH = 200;
const MAX_SLUG_LENGTH = 128;
const MAX_PATH_LENGTH = 260;
const MAX_SHORT_TEXT_LENGTH = 1_024;
const MAX_LONG_TEXT_LENGTH = 16 * 1024;
const MAX_PROVENANCE_SOURCES = 50;
const MAX_MAPPING_PATHS = 100;
const MAX_REFRESH_STEP_LENGTH = 128;
const MAX_REFRESH_ERROR_CODE_LENGTH = 128;
Expand Down Expand Up @@ -216,16 +214,6 @@ const REFRESH_PERMISSIONS = new Set<LiveArtifactSource['refreshPermission']>([
'manual_refresh_granted_for_read_only',
]);
const OUTPUT_TRANSFORMS = new Set<LiveArtifactOutputTransform>(['identity', 'compact_table', 'metric_summary']);
const PROVENANCE_GENERATORS = new Set<LiveArtifactProvenance['generatedBy']>([
'agent',
'refresh_runner',
]);
const PROVENANCE_SOURCE_TYPES = new Set<LiveArtifactProvenanceSource['type']>([
'connector',
'local_file',
'user_input',
'derived',
]);
const REFRESH_STEP_STATUSES = new Set<LiveArtifactRefreshStepStatus>([
'running',
'succeeded',
Expand Down Expand Up @@ -694,42 +682,6 @@ function validateRefreshErrorRecord(value: unknown, path: string, issues: LiveAr
return record;
}

function validateProvenance(value: unknown, path: string, issues: LiveArtifactValidationIssue[]): LiveArtifactProvenance | undefined {
if (!isPlainObject(value)) {
issues.push({ path, message: `${path} must be an object` });
return undefined;
}
const generatedAt = validateIsoDate(value.generatedAt, `${path}.generatedAt`, issues);
const generatedBy = validateEnum(value.generatedBy, PROVENANCE_GENERATORS, `${path}.generatedBy`, issues);
const notes = asOptionalString(value.notes, `${path}.notes`, issues, MAX_LONG_TEXT_LENGTH);
let sources: LiveArtifactProvenanceSource[] | undefined;
if (!Array.isArray(value.sources) || value.sources.length > MAX_PROVENANCE_SOURCES) {
issues.push({ path: `${path}.sources`, message: `${path}.sources must be a bounded array` });
} else {
sources = [];
value.sources.forEach((source, index) => {
const sourcePath = `${path}.sources.${index}`;
if (!isPlainObject(source)) {
issues.push({ path: sourcePath, message: `${sourcePath} must be an object` });
return;
}
const label = asString(source.label, `${sourcePath}.label`, issues, MAX_SHORT_TEXT_LENGTH);
const type = validateEnum(source.type, PROVENANCE_SOURCE_TYPES, `${sourcePath}.type`, issues);
const ref = asOptionalString(source.ref, `${sourcePath}.ref`, issues, MAX_PATH_LENGTH);
if (ref !== undefined) validateRelativePath(ref, `${sourcePath}.ref`, issues);
if (label !== undefined && type !== undefined) {
const provenanceSource: LiveArtifactProvenanceSource = { label, type };
if (ref !== undefined) provenanceSource.ref = ref;
sources?.push(provenanceSource);
}
});
}
if (generatedAt === undefined || generatedBy === undefined || sources === undefined) return undefined;
const provenance: LiveArtifactProvenance = { generatedAt, generatedBy, sources };
if (notes !== undefined) provenance.notes = notes;
return provenance;
}

function validateOptionalInteger(value: unknown, path: string, issues: LiveArtifactValidationIssue[], min: number, max: number): number | undefined {
if (value === undefined) return undefined;
if (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max) {
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/live-artifacts/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export const LIVE_ARTIFACT_SNAPSHOTS_DIR = 'snapshots' as const;
const SAFE_LIVE_ARTIFACT_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
const LIVE_ARTIFACT_ID_PREFIX = 'la';
const LIVE_ARTIFACT_ID_RANDOM_BYTES = 6;
const LIVE_ARTIFACT_ID_RANDOM_SUFFIX_LENGTH = LIVE_ARTIFACT_ID_RANDOM_BYTES * 2;
const MAX_LIVE_ARTIFACT_STORAGE_ID_LENGTH = 128;
const MAX_LIVE_ARTIFACT_SLUG_LENGTH = 128;
const FALLBACK_LIVE_ARTIFACT_SLUG = 'live-artifact';
Expand Down
11 changes: 5 additions & 6 deletions apps/daemon/src/mcp-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ import fs from 'node:fs';
import { SIDECAR_ENV } from '@open-design/sidecar-proto';
import { buildMcpInstallPayload, type McpInstallPayload } from './mcp-install-info.js';
import { installCodexMcp, probeCodexInstall, uninstallCodexMcp } from './codex-cli.js';
import { MCP_TEMPLATES, buildAcpMcpServers, buildClaudeMcpJson, isManagedProjectCwd, readMcpConfig, writeMcpConfig } from './mcp-config.js';
import { beginAuth, exchangeCodeForToken, refreshAccessToken } from './mcp-oauth.js';
import { clearToken, getToken, isTokenExpired, readAllTokens, setToken } from './mcp-tokens.js';
import { MCP_TEMPLATES, readMcpConfig, writeMcpConfig } from './mcp-config.js';
import { beginAuth, exchangeCodeForToken } from './mcp-oauth.js';
import { clearToken, getToken, setToken } from './mcp-tokens.js';
import type { RouteDeps } from './server-context.js';

export interface RegisterMcpRoutesDeps extends RouteDeps<'http' | 'paths' | 'mcp'> {}

export function registerMcpRoutes(app: Express, ctx: RegisterMcpRoutesDeps) {
const { isLocalSameOrigin, resolvedPortRef, sendApiError } = ctx.http;
const { OD_BIN, RUNTIME_DATA_DIR, PROJECTS_DIR } = ctx.paths;
const { pendingAuth, daemonUrlRef } = ctx.mcp;
const { OD_BIN, RUNTIME_DATA_DIR } = ctx.paths;
const { pendingAuth } = ctx.mcp;
const getResolvedPort = () => resolvedPortRef.current;
const getDaemonUrl = () => daemonUrlRef.current;
// Surfaces the absolute paths to the daemon's Node-compatible runtime and
// CLI entry so the Settings → MCP server panel can render snippets that work
// even when `od` isn't on the user's PATH (the common case for source clones
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ type JsonObject = Record<string, unknown>;
interface RunMcpOptions { daemonUrl: string | URL }
interface CatalogItem { id: string; name?: string; title?: string; description?: string; summary?: string }
interface SkillsPayload { skills?: CatalogItem[] }
interface PluginsPayload { plugins?: CatalogItem[] }
interface DesignSystemsPayload { designSystems?: CatalogItem[] }
interface ResourcePayload { skill?: { body?: string; content?: string }; designSystem?: { body?: string; content?: string }; body?: string; content?: string }
interface ProjectSummary { id: string; name: string; metadata?: JsonObject }
Expand Down
5 changes: 2 additions & 3 deletions apps/daemon/src/media/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@
// placeholder as the final result.

import { mkdir, mkdtemp, readdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
import { execFile as execFileCb, spawn } from 'node:child_process';
import { spawn } from 'node:child_process';
import os from 'node:os';
import path from 'node:path';
import { promisify } from 'node:util';

import { Agent as UndiciAgent } from 'undici';
import {
AUDIO_DURATIONS_SEC,
Expand Down Expand Up @@ -96,7 +96,6 @@ import {
classifyAIHubMixModel,
} from '../integrations/aihubmix.js';

const execFile = promisify(execFileCb);
const DEFAULT_OPENROUTER_VIDEO_POLL_INTERVAL_MS = 8000;
type ProviderConfig = { apiKey?: string; baseUrl?: string; model?: string };
type ProgressFn = (message: string) => void;
Expand Down
4 changes: 0 additions & 4 deletions apps/daemon/src/orbit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,6 @@ function summaryFile(dataDir: string): string {
return path.join(orbitDir(dataDir), SUMMARY_FILE);
}

async function readLastSummary(dataDir: string): Promise<OrbitActivitySummary | null> {
return (await readSummaryStore(dataDir)).lastRun;
}

function isOrbitRunSummary(value: unknown): value is OrbitActivitySummary {
if (!value || typeof value !== 'object') return false;
const obj = value as Partial<OrbitActivitySummary>;
Expand Down
2 changes: 0 additions & 2 deletions apps/daemon/src/plugins/apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import {
type InstalledPluginRecord,
type McpServerSpec,
type PluginAssetRef,
type PluginConnectorBinding,
type PluginConnectorRef,
type PluginManifest,
type PluginProjectMetadataPatch,
type TrustTier,
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/plugins/resolve-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import type Database from 'better-sqlite3';
import type {
AppliedPluginSnapshot,
ApplyResult,
InstalledPluginRecord,
PluginConnectorBinding,
} from '@open-design/contracts';
import {
Expand Down
1 change: 0 additions & 1 deletion apps/daemon/src/qa/cta-hierarchy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { type CheerioAPI, load } from 'cheerio';
// daemon's declared dependency boundary, so we derive a generic "node
// collection" type from the API surface we actually use.
type CheerioCollection = ReturnType<CheerioAPI>;
type CheerioNode = CheerioCollection extends ArrayLike<infer N> ? N : never;

export interface CtaHierarchyIssue {
/** Category of the finding; the UI may surface different copy per kind. */
Expand Down
3 changes: 1 addition & 2 deletions apps/daemon/src/routes/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
classifyAIHubMixModel,
} from '../integrations/aihubmix.js';
import { isSafeId as isSafeProjectId } from '../projects.js';
import { projectKindToTracking } from '@open-design/contracts/analytics';
import { proxyDispatcherRequestInit, validateUserProviderBaseUrl } from '../connectionTest.js';
import { resolveModelForServiceTier } from '../runtimes/models.js';
import { googleStreamGenerateContentUrl } from '../integrations/google-models.js';
Expand Down Expand Up @@ -59,7 +58,7 @@ const FEEDBACK_REASON_ALLOWLIST: ReadonlySet<string> = new Set([
export interface RegisterChatRoutesDeps extends RouteDeps<'db' | 'design' | 'http' | 'chat' | 'agents' | 'critique' | 'validation' | 'lifecycle' | 'paths' | 'telemetry' | 'appConfig'> {}

export function registerChatRoutes(app: Express, ctx: RegisterChatRoutesDeps) {
const { db, design } = ctx;
const { db } = ctx;
const { sendApiError, createSseResponse } = ctx.http;
const { readAppConfig } = ctx.appConfig;
const { testProviderConnection, testAgentConnection, getAgentDef, isKnownModel, isKnownServiceTier, sanitizeCustomModel, listProviderModels } = ctx.agents;
Expand Down
3 changes: 1 addition & 2 deletions apps/daemon/src/routes/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function resolveLegacyMediaRouteGrant(input: {

export function registerMediaRoutes(app: Express, ctx: RegisterMediaRoutesDeps) {
const { db, design } = ctx;
const { sendApiError, requireLocalDaemonRequest, isLocalSameOrigin, resolvedPortRef } = ctx.http;
const { sendApiError, isLocalSameOrigin, resolvedPortRef } = ctx.http;
const { PROJECT_ROOT, PROJECTS_DIR, RUNTIME_DATA_DIR } = ctx.paths;
const { authorizeToolRequest, optionalToolGrantFromRequest, requestProjectOverride } = ctx.auth;
const { randomUUID } = ctx.ids;
Expand All @@ -85,7 +85,6 @@ export function registerMediaRoutes(app: Express, ctx: RegisterMediaRoutesDeps)
const { orbitService } = ctx.orbit;
const { openBrowser, openNativeFolderDialog } = ctx.nativeDialogs;
const { getProject } = ctx.projectStore;
const { insertConversation, upsertMessage } = ctx.conversations;
const { searchResearch, ResearchError } = ctx.research;
const getResolvedPort = () => resolvedPortRef.current;

Expand Down
4 changes: 2 additions & 2 deletions apps/daemon/src/routes/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Express, NextFunction, Request, RequestHandler, Response } from 'express';
import type { Express, Request, RequestHandler, Response } from 'express';
import type {
InstalledPluginRecord,
PluginDuplicateProjectRequest,
Expand Down Expand Up @@ -278,7 +278,7 @@ export function registerPluginRoutes(app: Express, deps: RegisterPluginRoutesDep
}

export function registerProjectPluginRoutes(app: Express, deps: RegisterPluginRoutesDeps): void {
const { db, paths, plugins, helpers } = deps;
const { db, plugins, helpers } = deps;
app.post('/api/projects/:id/plugins/install-folder', async (req, res) => helpers.handleProjectInstallFolder(req, res));
app.post('/api/projects/:id/plugins/publish-github', async (req, res) => helpers.handleProjectPluginCli(req, res, 'publish-github'));
app.get('/api/projects/:id/plugin-candidates', (req, res) => { try { const project = helpers.getProject(db, req.params.id); if (!project) return helpers.sendApiError(res, 404, 'PROJECT_NOT_FOUND', 'project not found'); const includeDismissed = req.query.includeDismissed === 'true'; res.json({ candidates: plugins.listSkillPluginCandidates(db, req.params.id, includeDismissed) }); } catch (err: unknown) { res.status(400).json({ error: err instanceof Error ? err.message : String(err) }); } });
Expand Down
6 changes: 0 additions & 6 deletions apps/daemon/src/routes/static-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import type { DesignSystemTokenContractRebuildJobResponse } from '@open-design/c
import { detectAgents, detectAgentsStream } from '../agents.js';
import {
SkillImportError,
deleteUserSkill,
findSkillById,
importUserSkill,
listSkillFiles,
Expand All @@ -15,15 +14,12 @@ import {
} from '../skills.js';
import { listCodexPets, readCodexPetSpritesheet } from '../codex-pets.js';
import { syncCommunityPets } from '../community-pets-sync.js';
import { readDesignSystem } from '../design-systems/index.js';
import {
LocalDesignSystemImportError,
importLocalDesignSystemProject,
} from '../design-systems/import.js';
import { importGitHubDesignSystemProject } from '../design-systems/github-import.js';
import { importShadcnDesignSystemProject } from '../design-systems/shadcn-import.js';
import { renderDesignSystemPreview } from '../design-systems/preview.js';
import { renderDesignSystemShowcase } from '../design-systems/showcase.js';
import { listPromptTemplates, readPromptTemplate } from '../media/prompt-templates.js';
import { readAppConfig } from '../app-config.js';
import { installFromTarget, uninstallById } from '../library-install.js';
Expand Down Expand Up @@ -75,8 +71,6 @@ export function registerStaticResourceRoutes(app: Express, ctx: RegisterStaticRe
PROJECT_ROOT,
DESIGN_SYSTEMS_DIR,
USER_DESIGN_SYSTEMS_DIR,
DESIGN_TEMPLATES_DIR,
USER_DESIGN_TEMPLATES_DIR,
SKILLS_DIR,
USER_SKILLS_DIR,
PROMPT_TEMPLATES_DIR,
Expand Down
27 changes: 0 additions & 27 deletions apps/daemon/src/runtimes/defs/amr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -518,33 +518,6 @@ function isRetriableVelaModelsError(error: unknown): boolean {
].some((pattern) => message.includes(pattern));
}

async function fetchVelaModelsWithRetry(
resolvedBin: string,
env: NodeJS.ProcessEnv,
): Promise<RuntimeModelOption[]> {
let lastError: unknown = null;
for (let attempt = 0; attempt <= AMR_MODELS_RETRY_DELAYS_MS.length; attempt += 1) {
try {
const { stdout } = await execAgentFile(resolvedBin, ['models'], {
env,
timeout: AMR_MODELS_TIMEOUT_MS,
maxBuffer: 1024 * 1024,
});
return parseVelaModels(String(stdout));
} catch (error) {
lastError = error;
if (
attempt === AMR_MODELS_RETRY_DELAYS_MS.length ||
!isRetriableVelaModelsError(error)
) {
throw error;
}
await sleep(AMR_MODELS_RETRY_DELAYS_MS[attempt] ?? 0);
}
}
throw lastError instanceof Error ? lastError : new Error(velaModelsErrorMessage(lastError));
}

export async function fetchVelaPresetModels(
resolvedBin: string,
env: NodeJS.ProcessEnv,
Expand Down
Loading
Loading