{"version":3,"file":"server.mjs","names":["routes","apiRoute","resourceConfig","resourceDoompiAuthorConfig"],"sources":["../../src/constants/settings.ts","../../src/types/apiRoutes.ts","../../src/services/settings/index.ts","../../src/services/settingsApi/index.ts","../../src/extensions/(backend)/api/settings/route.server.ts","../../src/services/configResources/index.ts","../../src/extensions/workspaces/sessions/(backend)/resource/config.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-config.server.ts","../../generated/server.ts"],"sourcesContent":["export const KEY_SEPARATOR = '.';\n\n/** The repeatable query parameter naming which keys a read is about. */\nexport const KEY_QUERY_PARAM = 'key';\n\nexport const SELECTION_KEYS = {\n  majorMode: ['selection', 'majorMode'],\n  domains: ['selection', 'domains'],\n  profile: ['selection', 'profile'],\n} as const;\n","import { apiResponse, defineApiRoutes } from '@agimon-ai/doompi-core/web';\n\nimport { KEY_QUERY_PARAM } from '../constants/settings';\nimport type { RepositorySettingsView, SettingsConfigView, SettingsImagesView, SettingsRepository } from './settings';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/settings/`, so the mount is stated once, by the\n * folder that creates it. `settings` is the host's own API: it answers at\n * `/api/settings` and `/api/workspaces/<id>/settings`, beside `/plugins` rather\n * than under it, and the client knows that from the base path alone.\n *\n * This is the one file the mount's dispatcher and, once the client crosses the\n * package boundary, the cockpit both read, so a path cannot move on one side\n * alone.\n */\nexport default defineApiRoutes({\n  /** The mount itself: the selected keys and the hash of each file they came from. */\n  config: {\n    method: 'GET',\n    path: '/',\n    /** Repeatable. The page also sends `repoRoot`, which the mount ignores: it serves one repository. */\n    query: [KEY_QUERY_PARAM],\n    response: apiResponse<SettingsConfigView>(),\n  },\n  value: {\n    method: 'PUT',\n    path: '/value',\n    response: apiResponse<SettingsConfigView>(),\n  },\n  repositories: {\n    method: 'GET',\n    path: '/repositories',\n    response: apiResponse<{ repositories: readonly SettingsRepository[] }>(),\n  },\n  /** The workspace this mount was bound to; a global mount has none and answers 404. */\n  repository: {\n    method: 'GET',\n    path: '/repository',\n    response: apiResponse<RepositorySettingsView>(),\n  },\n  selection: {\n    method: 'PUT',\n    path: '/repository/selection',\n    response: apiResponse<RepositorySettingsView>(),\n  },\n  /** Pi's own image limits, served by the global mount only. */\n  images: {\n    method: 'GET',\n    path: '/images',\n    response: apiResponse<SettingsImagesView>(),\n  },\n  /** The same path as `images`; the method is the whole of the difference. */\n  saveImages: {\n    method: 'PUT',\n    path: '/images',\n    response: apiResponse<SettingsImagesView>(),\n  },\n});\n","import type { DoomApiContext } from '@agimon-ai/doompi-core/packageApi';\n\nimport { KEY_SEPARATOR, SELECTION_KEYS } from '../../constants/settings';\nimport type {\n  RepositoryCatalogOption,\n  RepositorySelectionChanges,\n  RepositorySelectionWriteRequest,\n  RepositorySettingsView,\n  SettingsConfigView,\n  SettingsRepository,\n  SettingsScope,\n  SettingsValueView,\n  SettingsBatchWriteRequest,\n} from '../../types/settings';\nimport { globalDoomConfigPath, loadDoomConfigLayers, repositoryDoomConfigPath } from '../config';\nimport { configScopeOf } from '../configPolicy';\nimport { defaultDomainsForMajorMode, loadDomains } from '../domains';\nimport { loadMajorModesConfig } from '../majorModes';\nimport { loadProfiles } from '../profiles';\n\ntype SelectionKey = keyof typeof SELECTION_KEYS;\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function describe(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}\n\n/** The display form of a config value; a record has no single-line form, so it has none. */\nexport function displayValue(value: unknown): string | undefined {\n  if (typeof value === 'string') return value;\n  if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n  if (Array.isArray(value)) return value.map((entry) => displayValue(entry) ?? '').join(', ');\n  return undefined;\n}\n\nexport function pathFor(scope: SettingsScope, repoRoot: string, homeDirectory: string | undefined): string {\n  return scope === 'repository' ? repositoryDoomConfigPath(repoRoot) : globalDoomConfigPath(homeDirectory);\n}\n\nexport function parseWrite(body: unknown): SettingsBatchWriteRequest | undefined {\n  if (!isRecord(body)) return undefined;\n  const { repoRoot, scope, expectedHash } = body;\n  if (typeof repoRoot !== 'string' || (scope !== 'global' && scope !== 'repository')) return undefined;\n  if (scope === 'repository' && repoRoot === '') return undefined;\n  if (typeof expectedHash !== 'string') return undefined;\n  const edits = body.edits === undefined ? [{ keyPath: body.keyPath, value: body.value }] : body.edits;\n  if (!Array.isArray(edits) || edits.length === 0 || edits.length > 100) return undefined;\n  const validated: Array<SettingsBatchWriteRequest['edits'][number]> = [];\n  for (const edit of edits) {\n    if (!isRecord(edit)) return undefined;\n    const { keyPath, value } = edit;\n    if (!Array.isArray(keyPath) || keyPath.length === 0 || keyPath.some((part) => typeof part !== 'string'))\n      return undefined;\n    if (value !== null && typeof value !== 'string' && (typeof value !== 'number' || !Number.isFinite(value)))\n      return undefined;\n    validated.push({ keyPath: keyPath as string[], value });\n  }\n  return { repoRoot, scope, expectedHash, edits: validated };\n}\n\nexport function configuredSelectionValue<T>(\n  layers: ReturnType<typeof loadDoomConfigLayers>,\n  key: SelectionKey,\n  effective: T | undefined,\n): { effective?: T; repository?: T; origin: 'global' | 'repository' | 'default' } {\n  const origin = layers.originOf(SELECTION_KEYS[key]);\n  return {\n    ...(effective === undefined ? {} : { effective }),\n    ...(origin === 'repository' && effective !== undefined ? { repository: effective } : {}),\n    origin,\n  };\n}\n\nexport function repositorySettingsView(\n  repository: SettingsRepository,\n  homeDirectory: string | undefined,\n): RepositorySettingsView {\n  const repoRoot = repository.path;\n  const layers = loadDoomConfigLayers(repoRoot, homeDirectory);\n  const modes = loadMajorModesConfig(repoRoot, homeDirectory);\n  const domains = loadDomains(repoRoot, homeDirectory);\n  const profiles = loadProfiles(repoRoot, homeDirectory);\n  const configured = layers.effective.selection;\n  const effectiveMajorMode = configured?.majorMode ?? modes.defaultMajorMode;\n  const effectiveDomains =\n    configured?.domains ?? defaultDomainsForMajorMode(effectiveMajorMode, {}, domains.defaultDomains);\n  const majorModes: RepositoryCatalogOption[] = Object.entries(modes.majorMode)\n    .map(([name, definition]) => ({ name, description: definition.description, layers: definition.layers }))\n    .sort((left, right) => left.name.localeCompare(right.name));\n  const domainOptions: RepositoryCatalogOption[] = [\n    ...Object.entries(domains.domains).map(([name, definition]) => ({\n      name,\n      ...(definition.description ? { description: definition.description } : {}),\n    })),\n    ...Object.entries(domains.aliases).map(([name, expandsTo]) => ({\n      name,\n      description: `Alias for ${expandsTo.join(', ') || 'no domains'}.`,\n      expandsTo,\n    })),\n  ].sort((left, right) => left.name.localeCompare(right.name));\n\n  return {\n    repository,\n    hash: layers.repositoryFile.hash,\n    catalogs: {\n      majorModes,\n      domains: domainOptions,\n      profiles: profiles.map((profile) => ({ name: profile.name })),\n    },\n    selection: {\n      majorMode: configuredSelectionValue(layers, 'majorMode', effectiveMajorMode),\n      domains: configuredSelectionValue(layers, 'domains', effectiveDomains),\n      profile: configuredSelectionValue(layers, 'profile', configured?.profile),\n    },\n  };\n}\n\nexport function parseSelectionChanges(value: unknown): RepositorySelectionChanges | undefined {\n  if (!isRecord(value)) return undefined;\n  const keys = Object.keys(value);\n  if (keys.length === 0 || keys.some((key) => !Object.hasOwn(SELECTION_KEYS, key))) return undefined;\n  const changes: RepositorySelectionChanges = {};\n  if (Object.hasOwn(value, 'majorMode')) {\n    if (value.majorMode !== null && (typeof value.majorMode !== 'string' || value.majorMode.trim() === ''))\n      return undefined;\n    changes.majorMode = value.majorMode === null ? null : value.majorMode.trim();\n  }\n  if (Object.hasOwn(value, 'domains')) {\n    if (\n      value.domains !== null &&\n      (!Array.isArray(value.domains) || value.domains.some((name) => typeof name !== 'string' || name.trim() === ''))\n    ) {\n      return undefined;\n    }\n    changes.domains =\n      value.domains === null ? null : [...new Set((value.domains as string[]).map((name) => name.trim()))];\n  }\n  if (Object.hasOwn(value, 'profile')) {\n    if (value.profile !== null && (typeof value.profile !== 'string' || value.profile.trim() === '')) return undefined;\n    changes.profile = value.profile === null ? null : value.profile.trim();\n  }\n  return changes;\n}\n\nexport function parseSelectionWrite(value: unknown): RepositorySelectionWriteRequest | undefined {\n  if (!isRecord(value) || typeof value.repositoryId !== 'string' || typeof value.expectedHash !== 'string')\n    return undefined;\n  const changes = parseSelectionChanges(value.changes);\n  return changes === undefined\n    ? undefined\n    : { repositoryId: value.repositoryId, expectedHash: value.expectedHash, changes };\n}\n\nexport function validateSelectionChanges(\n  view: RepositorySettingsView,\n  changes: RepositorySelectionChanges,\n): string | undefined {\n  if (changes.majorMode !== undefined && changes.majorMode !== null) {\n    if (!view.catalogs.majorModes.some((mode) => mode.name === changes.majorMode)) {\n      return `Unknown major mode '${changes.majorMode}'.`;\n    }\n  }\n  if (changes.domains !== undefined && changes.domains !== null) {\n    const known = new Set(view.catalogs.domains.map((domain) => domain.name));\n    const unknown = changes.domains.find((domain) => !known.has(domain));\n    if (unknown !== undefined) return `Unknown domain '${unknown}'.`;\n  }\n  if (changes.profile !== undefined && changes.profile !== null) {\n    if (!view.catalogs.profiles.some((profile) => profile.name === changes.profile)) {\n      return `Unknown profile '${changes.profile}'.`;\n    }\n  }\n  return undefined;\n}\n\nexport function selectionEdits(changes: RepositorySelectionChanges) {\n  return (Object.entries(changes) as Array<[SelectionKey, string | readonly string[] | null]>).map(([key, value]) => ({\n    keyPath: SELECTION_KEYS[key],\n    ...(value === null ? {} : { value }),\n  }));\n}\n\nexport function configView(context: DoomApiContext, keys: readonly string[]): SettingsConfigView {\n  const root = context.scope === 'workspace' ? context.workspaceRoot : undefined;\n  const layers = loadDoomConfigLayers(root, context.homeDirectory);\n  const values: Record<string, SettingsValueView> = {};\n  for (const key of keys) {\n    const keyPath = key.split(KEY_SEPARATOR);\n    const value = displayValue(layers.valueAt(keyPath));\n    values[key] = {\n      ...(value === undefined ? {} : { value }),\n      origin: layers.originOf(keyPath),\n      scope: configScopeOf(keyPath),\n    };\n  }\n  return {\n    repoRoot: root ?? '',\n    values,\n    hashes: { global: layers.globalFile.hash, repository: layers.repositoryFile.hash },\n  };\n}\n","import type { DoomApi } from '@agimon-ai/doompi-core/packageApi';\n\nimport { KEY_QUERY_PARAM, KEY_SEPARATOR } from '../../constants/settings';\nimport routes from '../../types/apiRoutes';\nimport type { SettingsRepository } from '../../types/settings';\nimport { repositoryDoomConfigPath } from '../config';\nimport { configScopeOf } from '../configPolicy';\nimport { writeDoomConfigValues } from '../configWriter';\nimport { DEFAULT_IMAGE_MAX_DIMENSION, MIN_IMAGE_MAX_DIMENSION } from '../imageSettings';\nimport { loadPiImageSettings, savePiImageSettings } from '../piConfig';\nimport {\n  configView,\n  describe,\n  isRecord,\n  parseSelectionWrite,\n  parseWrite,\n  pathFor,\n  repositorySettingsView,\n  selectionEdits,\n  validateSelectionChanges,\n} from '../settings';\n\n/** One declared route, as much of it as a comparison needs. */\ntype RouteSpec = { readonly method: string; readonly path: string };\n\n/** Config handlers are bound to their mount. Request paths cannot choose a different repository. */\nexport const settingsApi: DoomApi = {\n  basePath: 'settings',\n  start(context) {\n    if (context.scope === 'session') throw new Error('Configuration settings require a global or workspace mount.');\n    const { homeDirectory } = context;\n    const repository = (): SettingsRepository | undefined =>\n      context.scope === 'workspace' && context.workspaceId && context.workspaceRoot\n        ? {\n            id: context.workspaceId,\n            name: context.workspaceRoot.split('/').at(-1) ?? context.workspaceId,\n            path: context.workspaceRoot,\n            active: context.repositories?.().find((entry) => entry.id === context.workspaceId)?.active ?? false,\n          }\n        : undefined;\n    const imageView = () => ({\n      ...loadPiImageSettings(homeDirectory),\n      minDimension: MIN_IMAGE_MAX_DIMENSION,\n      maxAllowedDimension: DEFAULT_IMAGE_MAX_DIMENSION,\n    });\n    let writes: Promise<unknown> = Promise.resolve();\n    let closed = false;\n    const dispatch = async (request: Request): Promise<Response> => {\n      if (closed) return Response.json({ error: 'Configuration mount is closed.' }, { status: 503 });\n      const url = new URL(request.url);\n      /**\n       * Whether this request addresses one declared route.\n       *\n       * The table owns both halves of the comparison, so the path this mount\n       * answers and the path the client asks for cannot drift apart: there is\n       * one spelling of each, in `src/types/apiRoutes`.\n       */\n      const addresses = (route: RouteSpec): boolean => url.pathname === route.path && request.method === route.method;\n      const currentRepository = repository();\n      if (addresses(routes.config)) return Response.json(configView(context, url.searchParams.getAll(KEY_QUERY_PARAM)));\n      if (addresses(routes.repositories)) return Response.json({ repositories: context.repositories?.() ?? [] });\n      if (addresses(routes.repository)) {\n        return currentRepository\n          ? Response.json(repositorySettingsView(currentRepository, homeDirectory))\n          : Response.json({ error: 'Choose a workspace.' }, { status: 404 });\n      }\n      // One path, two methods, so the branch is on the path the pair share.\n      if (url.pathname === routes.images.path && context.scope === 'global') {\n        if (request.method === routes.images.method) return Response.json(imageView());\n        if (request.method === routes.saveImages.method) {\n          const body: unknown = await request.json();\n          if (\n            !isRecord(body) ||\n            (body.autoResize !== undefined && typeof body.autoResize !== 'boolean') ||\n            (body.maxDimension !== undefined &&\n              (typeof body.maxDimension !== 'number' || !Number.isFinite(body.maxDimension)))\n          )\n            return Response.json({ error: 'Invalid image settings.' }, { status: 400 });\n          savePiImageSettings(\n            {\n              ...(typeof body.autoResize === 'boolean' ? { autoResize: body.autoResize } : {}),\n              ...(typeof body.maxDimension === 'number' ? { maxDimension: body.maxDimension } : {}),\n            },\n            homeDirectory,\n          );\n          context.configurationChanged?.();\n          return Response.json(imageView());\n        }\n      }\n      if (addresses(routes.selection)) {\n        const body = parseSelectionWrite(await request.json());\n        if (!body)\n          return Response.json({ error: 'A selection write needs typed changes and a file hash.' }, { status: 400 });\n        if (!currentRepository || body.repositoryId !== currentRepository.id)\n          return Response.json({ error: 'Workspace not found in this mount.' }, { status: 404 });\n        const before = repositorySettingsView(currentRepository, homeDirectory);\n        if (before.hash !== body.expectedHash)\n          return Response.json(\n            { error: 'The repository config changed since it was read.', hash: before.hash },\n            { status: 409 },\n          );\n        const invalid = validateSelectionChanges(before, body.changes);\n        if (invalid) return Response.json({ error: invalid }, { status: 422 });\n        await writeDoomConfigValues(repositoryDoomConfigPath(currentRepository.path), selectionEdits(body.changes), {\n          scope: 'repository',\n        });\n        context.configurationChanged?.();\n        return Response.json(repositorySettingsView(currentRepository, homeDirectory));\n      }\n      if (addresses(routes.value)) {\n        const body = parseWrite(await request.json());\n        if (!body)\n          return Response.json({ error: 'A save requires a scope, key, value and file hash.' }, { status: 400 });\n        const scope = context.scope === 'global' ? 'global' : 'repository';\n        if (body.scope !== scope || (scope === 'repository' && body.repoRoot !== currentRepository?.path))\n          return Response.json({ error: 'The write targets a different mount.' }, { status: 403 });\n        if (\n          body.edits.some((edit) => {\n            const allowed = configScopeOf(edit.keyPath);\n            return allowed !== 'both' && allowed !== scope;\n          })\n        )\n          return Response.json({ error: 'This key cannot be set at this scope.' }, { status: 409 });\n        const before = configView(context, []);\n        if (before.hashes[scope] !== body.expectedHash)\n          return Response.json(\n            { error: 'The config changed since it was read.', hash: before.hashes[scope] },\n            { status: 409 },\n          );\n        const target = pathFor(scope, currentRepository?.path ?? '', homeDirectory);\n        await writeDoomConfigValues(\n          target,\n          body.edits.map(({ keyPath, value }) => ({ keyPath, ...(value === null ? {} : { value }) })),\n          { scope },\n        );\n        context.configurationChanged?.();\n        return Response.json(\n          configView(\n            context,\n            body.edits.map((edit) => edit.keyPath.join(KEY_SEPARATOR)),\n          ),\n        );\n      }\n      return Response.json({ error: 'Configuration route not found.' }, { status: 404 });\n    };\n    const guarded = async (request: Request): Promise<Response> => {\n      try {\n        return await dispatch(request);\n      } catch (error) {\n        return Response.json({ error: describe(error) }, { status: error instanceof SyntaxError ? 400 : 422 });\n      }\n    };\n    return {\n      fetch(request) {\n        if (request.method === 'GET' || request.method === 'HEAD') return guarded(request);\n        const result = writes.then(() => guarded(request));\n        writes = result.catch(() => undefined);\n        return result;\n      },\n      close() {\n        closed = true;\n      },\n    };\n  },\n};\n","import { defineRoutedContribution } from '@agimon-ai/doompi-core/extensionFile';\nimport type { DoomServerPluginContext } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { settingsApi } from '../../../../services/settingsApi';\n\nexport default defineRoutedContribution(\n  ({ host }: DoomServerPluginContext) => (host.scope === 'session' ? undefined : settingsApi),\n  { cardinality: 'optional' },\n);\n","export function selectionMetadata(execution: {\n  readonly selection: {\n    readonly profile?: string;\n    readonly domains: readonly string[];\n    readonly majorMode: string;\n    readonly activeLayers: readonly string[];\n  };\n}): string {\n  return JSON.stringify({\n    profile: execution.selection.profile ?? null,\n    domains: execution.selection.domains,\n    majorMode: execution.selection.majorMode,\n    activeLayers: execution.selection.activeLayers,\n  });\n}\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\n\nimport { selectionMetadata } from '../../../../../services/configResources';\nexport default defineResource({ name: 'doompi/config', kind: 'context' as const, read: selectionMetadata });\n","import { defineResource } from '@agimon-ai/doompi-core/extensionFile';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/doompi-core/serverFacet';\n\nimport { CONFIG_HELP_SKILL } from '../../../../../constants/config';\n\nexport default defineResource({\n  ...CONFIG_HELP_SKILL,\n  when: { state: { 'minor-mode': 'help' }, attribution: { kind: 'minor' as const, mode: 'help' } },\n  kind: 'skill' as const,\n  path: packageResourcePath(import.meta.url, 'src/prompts/doompi-author-config/SKILL.md'),\n  read: () => readPackageResource(import.meta.url, 'src/prompts/doompi-author-config/SKILL.md'),\n});\n","// Generated by @agimon-ai/doompi-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/doompi-core/serverFacet';\n\nimport apiRoute from '../src/extensions/(backend)/api/settings/route.server';\nimport resourceConfig from '../src/extensions/workspaces/sessions/(backend)/resource/config.server';\nimport resourceDoompiAuthorConfig from '../src/extensions/workspaces/sessions/(backend)/resource/doompi-author-config.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n  typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\n/* v8 ignore next -- generated normalization branch */\nconst defined = <T>(values: readonly (T | undefined)[]): T[] =>\n  values.filter((value): value is T => value !== undefined);\n\nexport const facet = defineServerPlugin({\n  name: '@agimon-ai/doompi-config',\n  global: (context) => ({\n    get api(): DoomServerSessionPlugin['api'] { return defined([at(apiRoute, context)]); },\n  }),\n  workspace: (context) => ({\n    get api(): DoomServerSessionPlugin['api'] { return defined([at(apiRoute, context)]); },\n  }),\n  session: (context) => ({\n    get api(): DoomServerSessionPlugin['api'] { return defined([at(apiRoute, context)]); },\n    get resources(): DoomServerSessionPlugin['resources'] { return [at(resourceConfig, context), at(resourceDoompiAuthorConfig, context)]; },\n  }),\n});\n\nexport default facet;\n"],"mappings":"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"}