@semiont/core 0.4.7 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { E as EnvironmentConfig } from '../config.types-D3ReOdqd.js';
1
+ import { E as EnvironmentConfig } from '../config.types-kPA59Jjb.js';
2
2
 
3
3
  /**
4
4
  * Represents a Semiont project rooted at a given directory.
@@ -19,12 +19,12 @@ import { E as EnvironmentConfig } from '../config.types-D3ReOdqd.js';
19
19
  * backendLogsDir — stateDir/backend/
20
20
  * backendAppLogFile — backendLogsDir/app.log
21
21
  * backendErrorLogFile — backendLogsDir/error.log
22
- * frontendLogsDir — stateDir/frontend/
23
- * frontendAppLogFile — frontendLogsDir/app.log
24
- * frontendErrorLogFile — frontendLogsDir/error.log
25
22
  * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)
26
23
  * backendPidFile — runtimeDir/backend.pid
27
- * frontendPidFile — runtimeDir/frontend.pid
24
+ *
25
+ * Note: frontend paths are NOT project-scoped. The frontend service is bundled
26
+ * with the CLI and uses fixed XDG paths keyed by "frontend", not project name.
27
+ * See apps/cli/src/platforms/posix/handlers/frontend-paths.ts.
28
28
  */
29
29
  declare class SemiontProject {
30
30
  readonly root: string;
@@ -42,12 +42,8 @@ declare class SemiontProject {
42
42
  readonly backendLogsDir: string;
43
43
  readonly backendAppLogFile: string;
44
44
  readonly backendErrorLogFile: string;
45
- readonly frontendLogsDir: string;
46
- readonly frontendAppLogFile: string;
47
- readonly frontendErrorLogFile: string;
48
45
  readonly runtimeDir: string;
49
46
  readonly backendPidFile: string;
50
- readonly frontendPidFile: string;
51
47
  constructor(projectRoot: string, name?: string);
52
48
  /**
53
49
  * Delete all ephemeral state for this project (stateDir + runtimeDir).
@@ -45,13 +45,15 @@ function requirePlatform(value, serviceName) {
45
45
  return value;
46
46
  }
47
47
  function loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env) {
48
- const projectConfigContent = reader.readIfExists(`${projectRoot}/.semiont/config`);
48
+ const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;
49
49
  let projectName = "semiont-project";
50
+ let projectVersion;
50
51
  let projectSite;
51
52
  let projectEnvSection = {};
52
53
  if (projectConfigContent) {
53
54
  const projectConfig = parse(projectConfigContent);
54
55
  projectName = projectConfig.project?.name ?? projectName;
56
+ projectVersion = projectConfig.project?.version;
55
57
  projectSite = projectConfig.site;
56
58
  projectEnvSection = projectConfig.environments?.[environment] ?? {};
57
59
  }
@@ -239,6 +241,7 @@ function loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env)
239
241
  environment,
240
242
  projectRoot,
241
243
  projectName,
244
+ projectVersion,
242
245
  ...Object.keys(actors).length > 0 ? { actors } : {},
243
246
  ...Object.keys(workers).length > 0 ? { workers } : {}
244
247
  }
@@ -270,13 +273,9 @@ var SemiontProject = class _SemiontProject {
270
273
  backendLogsDir;
271
274
  backendAppLogFile;
272
275
  backendErrorLogFile;
273
- frontendLogsDir;
274
- frontendAppLogFile;
275
- frontendErrorLogFile;
276
276
  // Ephemeral — runtime
277
277
  runtimeDir;
278
278
  backendPidFile;
279
- frontendPidFile;
280
279
  constructor(projectRoot, name) {
281
280
  this.root = projectRoot;
282
281
  if (name !== void 0) {
@@ -303,14 +302,10 @@ name = "${name}"
303
302
  this.backendLogsDir = path.join(this.stateDir, "backend");
304
303
  this.backendAppLogFile = path.join(this.backendLogsDir, "app.log");
305
304
  this.backendErrorLogFile = path.join(this.backendLogsDir, "error.log");
306
- this.frontendLogsDir = path.join(this.stateDir, "frontend");
307
- this.frontendAppLogFile = path.join(this.frontendLogsDir, "app.log");
308
- this.frontendErrorLogFile = path.join(this.frontendLogsDir, "error.log");
309
305
  const xdgRuntime = process.env.XDG_RUNTIME_DIR;
310
306
  const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? "/tmp";
311
307
  this.runtimeDir = path.join(runtimeBase, "semiont", this.name);
312
308
  this.backendPidFile = path.join(this.runtimeDir, "backend.pid");
313
- this.frontendPidFile = path.join(this.runtimeDir, "frontend.pid");
314
309
  }
315
310
  /**
316
311
  * Delete all ephemeral state for this project (stateDir + runtimeDir).
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/toml-loader.ts","../../src/project.ts","../../src/config/node-config-loader.ts"],"names":["parseToml","fs2","path2","os2"],"mappings":"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","file":"node-config-loader.js","sourcesContent":["/**\n * TOML Config Loader\n *\n * Reads ~/.semiontconfig (TOML) and .semiont/config (TOML) and produces\n * an EnvironmentConfig for the requested environment.\n *\n * File format: see TOML-XDG-CONFIG.md\n *\n * Loading sequence:\n * 1. Read .semiont/config → projectName, site, environments.<env>.* (project base)\n * 2. Read ~/.semiontconfig → defaults, environments.<env>.* (user overrides)\n * 3. Deep-merge: project base ← user overrides (user wins on conflicts)\n * Any environment name is valid (local, staging, production, custom, ...)\n * 4. Resolve ${VAR} references from process.env\n * 5. Apply inheritance: workers.<name> → workers.default → error\n * 6. Map to EnvironmentConfig shape\n */\n\nimport { parse as parseToml } from 'smol-toml';\nimport type { EnvironmentConfig, OllamaProviderConfig, AnthropicProviderConfig } from './config.types';\nimport type { PlatformType } from './config.types';\n\n/**\n * Deep merge two plain objects. Arrays and primitives in `override` replace those in `base`.\n * Nested objects are merged recursively. `override` takes precedence on conflicts.\n */\nfunction deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(override)) {\n const b = base[key];\n const o = override[key];\n if (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o) &&\n b !== undefined && b !== null && typeof b === 'object' && !Array.isArray(b)) {\n result[key] = deepMerge(b as Record<string, unknown>, o as Record<string, unknown>);\n } else if (o !== undefined) {\n result[key] = o;\n }\n }\n return result as T;\n}\n\nfunction resolveEnvVars(obj: unknown, env: Record<string, string | undefined>): unknown {\n if (typeof obj === 'string') {\n return obj.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEnvVars(item, env));\n }\n if (obj !== null && typeof obj === 'object') {\n const resolved: Record<string, unknown> = {};\n for (const key in obj as Record<string, unknown>) {\n resolved[key] = resolveEnvVars((obj as Record<string, unknown>)[key], env);\n }\n return resolved;\n }\n return obj;\n}\n\n// ── Inference config types (mirrored from packages/make-meaning/src/config.ts) ─\n// Kept here to avoid a circular dependency: core cannot import make-meaning.\n\nexport interface InferenceConfig {\n type: 'anthropic' | 'ollama';\n model: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport interface ActorInferenceConfig {\n gatherer?: InferenceConfig;\n matcher?: InferenceConfig;\n}\n\nexport interface WorkerInferenceConfig {\n default?: InferenceConfig;\n 'reference-annotation'?: InferenceConfig;\n 'highlight-annotation'?: InferenceConfig;\n 'assessment-annotation'?: InferenceConfig;\n 'comment-annotation'?: InferenceConfig;\n 'tag-annotation'?: InferenceConfig;\n 'generation'?: InferenceConfig;\n}\n\n// ── Types for ~/.semiontconfig ────────────────────────────────────────────────\n\ninterface SemiontConfigFile {\n user?: {\n name?: string;\n email?: string;\n };\n defaults?: {\n environment?: string;\n platform?: string;\n };\n environments?: Record<string, EnvironmentSection>;\n}\n\ninterface GraphSection {\n platform?: string;\n type?: string;\n name?: string;\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n [key: string]: unknown;\n}\n\ninterface InferenceFlatSection {\n // Flat (single-provider) format: type = \"anthropic\"|\"ollama\" at this level\n type?: 'anthropic' | 'ollama';\n platform?: string;\n model?: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n // Keyed (multi-provider) format: [inference.anthropic] / [inference.ollama]\n anthropic?: { platform?: string; apiKey?: string; endpoint?: string };\n ollama?: { platform?: string; baseURL?: string; port?: number };\n}\n\ninterface EnvironmentSection {\n backend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n frontendURL?: string;\n corsOrigin?: string;\n };\n frontend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n };\n proxy?: {\n platform?: string;\n port?: number;\n adminPort?: number;\n publicURL?: string;\n };\n site?: {\n domain?: string;\n siteName?: string;\n adminEmail?: string;\n oauthAllowedDomains?: string[];\n enableLocalAuth?: boolean;\n };\n database?: {\n platform?: string;\n image?: string;\n host?: string;\n port?: number;\n name?: string;\n user?: string;\n password?: string;\n };\n graph?: GraphSection;\n inference?: InferenceFlatSection;\n 'make-meaning'?: {\n graph?: Record<string, unknown>;\n actors?: {\n gatherer?: { inference?: InferenceConfig };\n matcher?: { inference?: InferenceConfig };\n };\n default?: { inference?: InferenceConfig };\n };\n workers?: Record<string, { inference?: InferenceConfig }>;\n actors?: Record<string, { inference?: InferenceConfig }>;\n logLevel?: 'error' | 'warn' | 'info' | 'http' | 'debug';\n}\n\n// ── File reader abstraction (same pattern as createConfigLoader) ──────────────\n\nexport type TomlFileReader = {\n readIfExists: (path: string) => string | null;\n};\n\nfunction requirePlatform(value: string | undefined, serviceName: string): PlatformType {\n if (!value) {\n throw new Error(`platform is required for service '${serviceName}' — add 'platform = \"posix\"|\"container\"|\"external\"' to its config section`);\n }\n return value as PlatformType;\n}\n\n// ── Main loader function ──────────────────────────────────────────────────────\n\n/**\n * Parse ~/.semiontconfig and .semiont/config and return EnvironmentConfig.\n *\n * @param projectRoot - Path to the project root (contains .semiont/config)\n * @param environment - Environment name (e.g. 'local', 'production')\n * @param globalConfigPath - Path to ~/.semiontconfig (caller resolves ~ expansion)\n * @param reader - File reader abstraction\n * @param env - Environment variables for ${VAR} resolution\n */\nexport function loadTomlConfig(\n projectRoot: string,\n environment: string,\n globalConfigPath: string,\n reader: TomlFileReader,\n env: Record<string, string | undefined>\n): EnvironmentConfig {\n // 1. Read project config from .semiont/config\n const projectConfigContent = reader.readIfExists(`${projectRoot}/.semiont/config`);\n let projectName = 'semiont-project';\n let projectSite: EnvironmentSection['site'] | undefined;\n let projectEnvSection: EnvironmentSection = {};\n if (projectConfigContent) {\n const projectConfig = parseToml(projectConfigContent) as {\n project?: { name?: string };\n site?: EnvironmentSection['site'];\n environments?: Record<string, EnvironmentSection>;\n };\n projectName = projectConfig.project?.name ?? projectName;\n projectSite = projectConfig.site;\n projectEnvSection = projectConfig.environments?.[environment] ?? {};\n }\n\n // 2. Read global config (optional — missing config yields empty environments)\n const globalContent = reader.readIfExists(globalConfigPath);\n const raw = globalContent ? (parseToml(globalContent) as SemiontConfigFile) : ({} as SemiontConfigFile);\n\n // 3. Deep-merge: project base + user overrides (user wins on conflicts)\n const userEnvSection: EnvironmentSection = raw.environments?.[environment] ?? {};\n const envSection: EnvironmentSection = deepMerge(\n projectEnvSection as Record<string, unknown>,\n userEnvSection as Record<string, unknown>\n ) as EnvironmentSection;\n\n // 4. Resolve ${VAR} references\n const resolved = resolveEnvVars(envSection, env) as EnvironmentSection;\n\n // 5. Build make-meaning actor/worker inference config with inheritance\n // The flat [inference] section provides defaults (apiKey, maxTokens, endpoint/baseURL).\n // Actor/worker sections only need to specify type and model; missing fields fall back\n // to the flat inference section.\n const flatInference = resolved.inference;\n const makeMeaningSection = resolved['make-meaning'];\n const workersSection = resolved.workers ?? {};\n const actorsSection = resolved.actors ?? {};\n const defaultWorkerInference = workersSection['default']?.inference;\n const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;\n\n function mergeWithFlatInference(specific: InferenceConfig): InferenceConfig {\n if (!flatInference) return specific;\n // For keyed sub-sections, inherit credentials from the matching provider sub-section.\n // For flat (legacy) format, flatInference.type is required to know which fields apply.\n const providerDefaults: Partial<InferenceConfig> = {};\n if (specific.type === 'anthropic') {\n const a = flatInference.anthropic;\n if (a) {\n providerDefaults.apiKey = a.apiKey;\n providerDefaults.endpoint = a.endpoint;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"anthropic\" or use [inference.anthropic] sub-section.`\n );\n }\n providerDefaults.apiKey = flatInference.apiKey;\n providerDefaults.endpoint = flatInference.endpoint;\n }\n } else if (specific.type === 'ollama') {\n const o = flatInference.ollama;\n if (o) {\n providerDefaults.baseURL = o.baseURL;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"ollama\" or use [inference.ollama] sub-section.`\n );\n }\n providerDefaults.baseURL = flatInference.baseURL;\n }\n }\n return {\n maxTokens: flatInference.maxTokens,\n ...providerDefaults,\n ...specific,\n };\n }\n\n function resolveActorInference(fromMakeMeaning?: InferenceConfig, fromActors?: InferenceConfig): InferenceConfig | undefined {\n const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;\n if (!base) return undefined;\n return mergeWithFlatInference(base);\n }\n\n const actors: ActorInferenceConfig = {};\n const gathererInference = resolveActorInference(\n makeMeaningSection?.actors?.gatherer?.inference,\n actorsSection['gatherer']?.inference\n );\n if (gathererInference) actors.gatherer = gathererInference;\n\n const matcherInference = resolveActorInference(\n makeMeaningSection?.actors?.matcher?.inference,\n actorsSection['matcher']?.inference\n );\n if (matcherInference) actors.matcher = matcherInference;\n\n const workers: WorkerInferenceConfig = {};\n const workerTypes = ['reference-annotation', 'highlight-annotation', 'assessment-annotation', 'comment-annotation', 'tag-annotation', 'generation'] as const;\n if (defaultWorkerInference) {\n workers.default = mergeWithFlatInference(defaultWorkerInference);\n }\n for (const wt of workerTypes) {\n const specific = workersSection[wt]?.inference;\n if (specific) {\n (workers as Record<string, InferenceConfig>)[wt] = mergeWithFlatInference(specific);\n }\n }\n\n // 6. Map to EnvironmentConfig\n const backend = resolved.backend;\n const site = resolved.site ?? projectSite;\n const inferenceSection = resolved.inference;\n\n // Build inference providers config.\n // Supports two formats:\n // Flat: [environments.local.inference] type = \"anthropic\"|\"ollama\" (single provider)\n // Keyed: [environments.local.inference.anthropic] / [environments.local.inference.ollama] (multi-provider)\n let inferenceProviders: EnvironmentConfig['inference'] | undefined;\n if (inferenceSection) {\n inferenceProviders = {};\n // Keyed sub-sections take priority\n if (inferenceSection.anthropic) {\n const a = inferenceSection.anthropic;\n inferenceProviders.anthropic = {\n platform: requirePlatform(a.platform, 'inference.anthropic'),\n endpoint: a.endpoint ?? 'https://api.anthropic.com',\n apiKey: a.apiKey ?? '',\n } as AnthropicProviderConfig;\n } else if (inferenceSection.type === 'anthropic') {\n inferenceProviders.anthropic = {\n platform: requirePlatform(inferenceSection.platform, 'inference'),\n endpoint: inferenceSection.endpoint ?? 'https://api.anthropic.com',\n apiKey: inferenceSection.apiKey ?? '',\n } as AnthropicProviderConfig;\n }\n if (inferenceSection.ollama) {\n const o = inferenceSection.ollama;\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(o.platform, 'inference.ollama') },\n baseURL: o.baseURL,\n port: o.baseURL ? undefined : (o.port ?? 11434),\n } as OllamaProviderConfig;\n } else if (inferenceSection.type === 'ollama') {\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(inferenceSection.platform, 'inference') },\n baseURL: inferenceSection.baseURL,\n port: inferenceSection.baseURL ? undefined : 11434,\n } as OllamaProviderConfig;\n }\n }\n\n // Build top-level workers/actors maps for EnvironmentConfig\n const topLevelWorkers: EnvironmentConfig['workers'] = {};\n for (const [name, w] of Object.entries(workersSection)) {\n if (w.inference) {\n topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };\n }\n }\n const topLevelActors: EnvironmentConfig['actors'] = {};\n for (const [name, a] of Object.entries(actorsSection)) {\n if (a.inference) {\n topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };\n }\n }\n // Also include make-meaning actors\n if (makeMeaningSection?.actors?.gatherer?.inference) {\n topLevelActors['gatherer'] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };\n }\n if (makeMeaningSection?.actors?.matcher?.inference) {\n topLevelActors['matcher'] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };\n }\n\n const frontend = resolved.frontend;\n const proxy = resolved.proxy;\n\n const config: EnvironmentConfig = {\n services: {\n backend: backend ? {\n platform: { type: requirePlatform(backend.platform, 'backend') },\n port: backend.port ?? 4000,\n publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4000}`,\n corsOrigin: backend.corsOrigin ?? backend.frontendURL ?? 'http://localhost:3000',\n } : undefined,\n frontend: frontend ? {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n } : undefined,\n proxy: proxy ? {\n platform: { type: requirePlatform(proxy.platform, 'proxy') },\n type: 'envoy',\n port: proxy.port ?? 8080,\n adminPort: proxy.adminPort ?? 9901,\n backendPort: backend?.port ?? 4000,\n frontendPort: frontend?.port ?? 3000,\n } : undefined,\n graph: resolved.graph ? {\n ...resolved.graph,\n platform: { type: requirePlatform(resolved.graph.platform as string | undefined, 'graph') },\n type: (resolved.graph.type ?? 'neo4j') as import('./config.types').GraphDatabaseType,\n } as EnvironmentConfig['services']['graph'] : (makeMeaningSection?.graph as EnvironmentConfig['services']['graph']),\n database: resolved.database ? {\n platform: { type: requirePlatform(resolved.database.platform, 'database') },\n type: 'postgres',\n image: resolved.database.image,\n host: resolved.database.host ?? 'localhost',\n port: resolved.database.port ?? 5432,\n name: resolved.database.name,\n user: resolved.database.user,\n password: resolved.database.password,\n } as EnvironmentConfig['services']['database'] : undefined,\n },\n ...(inferenceProviders ? { inference: inferenceProviders } : {}),\n ...(Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {}),\n ...(Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {}),\n site: site ? {\n domain: site.domain ?? 'localhost',\n siteName: site.siteName,\n adminEmail: site.adminEmail,\n oauthAllowedDomains: site.oauthAllowedDomains as [string, ...string[]] | undefined,\n } : undefined,\n logLevel: resolved.logLevel,\n _metadata: {\n environment,\n projectRoot,\n projectName,\n ...(Object.keys(actors).length > 0 ? { actors } : {}),\n ...(Object.keys(workers).length > 0 ? { workers } : {}),\n },\n };\n\n return config;\n}\n\n/**\n * Create a TOML config loader backed by a file reader.\n * Drop-in replacement for createConfigLoader that reads TOML instead of JSON.\n * The caller must resolve globalConfigPath (e.g. expand '~' using process.env.HOME).\n */\nexport function createTomlConfigLoader(\n reader: TomlFileReader,\n globalConfigPath: string,\n env: Record<string, string | undefined>\n) {\n return (projectRoot: string, environment: string): EnvironmentConfig => {\n return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);\n };\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Represents a Semiont project rooted at a given directory.\n *\n * Computes all paths — durable and ephemeral — once at construction time.\n * XDG environment variables are read here and nowhere else.\n *\n * Durable paths (inside the project root, committed or repo-local):\n * eventsDir — .semiont/events/ (system of record, committed)\n * representationsDir — representations/ (content store, committed)\n *\n * Ephemeral paths (outside the project root, never committed):\n * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)\n * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)\n * stateDir — $XDG_STATE_HOME/semiont/{name}/\n * projectionsDir — stateDir/projections/\n * jobsDir — stateDir/jobs/\n * backendLogsDir — stateDir/backend/\n * backendAppLogFile — backendLogsDir/app.log\n * backendErrorLogFile — backendLogsDir/error.log\n * frontendLogsDir — stateDir/frontend/\n * frontendAppLogFile — frontendLogsDir/app.log\n * frontendErrorLogFile — frontendLogsDir/error.log\n * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)\n * backendPidFile — runtimeDir/backend.pid\n * frontendPidFile — runtimeDir/frontend.pid\n */\nexport class SemiontProject {\n readonly root: string;\n readonly name: string;\n\n /** True if [git] sync = true in .semiont/config. When true, semiont stages\n * working-tree and event-log changes in the git index automatically. */\n readonly gitSync: boolean;\n\n // Durable\n readonly eventsDir: string;\n readonly representationsDir: string;\n\n // Ephemeral — config (generated config files for managed processes)\n readonly configDir: string;\n\n // Ephemeral — data (persistent user data managed by semiont)\n readonly dataHome: string;\n\n // Ephemeral — state\n readonly stateDir: string;\n readonly projectionsDir: string;\n readonly jobsDir: string;\n readonly backendLogsDir: string;\n readonly backendAppLogFile: string;\n readonly backendErrorLogFile: string;\n readonly frontendLogsDir: string;\n readonly frontendAppLogFile: string;\n readonly frontendErrorLogFile: string;\n\n // Ephemeral — runtime\n readonly runtimeDir: string;\n readonly backendPidFile: string;\n readonly frontendPidFile: string;\n\n constructor(projectRoot: string, name?: string) {\n this.root = projectRoot;\n if (name !== undefined) {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) {\n fs.mkdirSync(path.join(projectRoot, '.semiont'), { recursive: true });\n fs.writeFileSync(configPath, `[project]\\nname = \"${name}\"\\n`);\n }\n }\n this.name = SemiontProject.readName(projectRoot);\n this.gitSync = SemiontProject.readGitSync(projectRoot);\n\n this.eventsDir = path.join(projectRoot, '.semiont', 'events');\n this.representationsDir = path.join(projectRoot, 'representations');\n\n const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n this.configDir = path.join(xdgConfig, 'semiont', this.name);\n\n const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n this.dataHome = path.join(xdgData, 'semiont', this.name);\n\n const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n this.stateDir = path.join(xdgState, 'semiont', this.name);\n this.projectionsDir = path.join(this.stateDir, 'projections');\n this.jobsDir = path.join(this.stateDir, 'jobs');\n this.backendLogsDir = path.join(this.stateDir, 'backend');\n this.backendAppLogFile = path.join(this.backendLogsDir, 'app.log');\n this.backendErrorLogFile = path.join(this.backendLogsDir, 'error.log');\n this.frontendLogsDir = path.join(this.stateDir, 'frontend');\n this.frontendAppLogFile = path.join(this.frontendLogsDir, 'app.log');\n this.frontendErrorLogFile = path.join(this.frontendLogsDir, 'error.log');\n\n const xdgRuntime = process.env.XDG_RUNTIME_DIR;\n const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? '/tmp';\n this.runtimeDir = path.join(runtimeBase, 'semiont', this.name);\n this.backendPidFile = path.join(this.runtimeDir, 'backend.pid');\n this.frontendPidFile = path.join(this.runtimeDir, 'frontend.pid');\n }\n\n /**\n * Delete all ephemeral state for this project (stateDir + runtimeDir).\n * Does not touch eventsDir or dataDir.\n */\n async destroy(): Promise<void> {\n await Promise.all([\n fs.promises.rm(this.configDir, { recursive: true, force: true }),\n fs.promises.rm(this.stateDir, { recursive: true, force: true }),\n fs.promises.rm(this.runtimeDir, { recursive: true, force: true }),\n ]);\n }\n\n /**\n * Read [git] sync from .semiont/config.\n * Defaults to false if the section or key is absent.\n */\n private static readGitSync(projectRoot: string): boolean {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) return false;\n const content = fs.readFileSync(configPath, 'utf-8');\n let inGitSection = false;\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '[git]') { inGitSection = true; continue; }\n if (trimmed.startsWith('[')) { inGitSection = false; continue; }\n if (inGitSection && trimmed.startsWith('sync') && trimmed.includes('=')) {\n const value = trimmed.split('=')[1]?.trim();\n return value === 'true';\n }\n }\n return false;\n }\n\n /**\n * Read the project name from .semiont/config [project] name = \"...\"\n * Falls back to the directory basename if the config is absent or has no name.\n */\n private static readName(projectRoot: string): string {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('name') && trimmed.includes('=')) {\n const [, ...rest] = trimmed.split('=');\n return rest.join('=').trim().replace(/^\"(.*)\"$/, '$1');\n }\n }\n }\n return path.basename(projectRoot);\n }\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createTomlConfigLoader } from './toml-loader.js';\nimport type { EnvironmentConfig } from './config.types.js';\n\nexport { SemiontProject } from '../project.js';\n\nconst nodeTomlFileReader = {\n readIfExists: (filePath: string): string | null =>\n fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null,\n};\n\n/**\n * Load semiont environment config for a Node.js process.\n *\n * Reads ~/.semiontconfig (global) merged with .semiont/config (project-local),\n * then selects the given environment overlay.\n *\n * This is the canonical config loader for any Node.js process. SEMIONT_ENV\n * should be read once at the process entry point and passed as `environment`.\n */\nexport function loadEnvironmentConfig(\n projectRoot: string,\n environment: string\n): EnvironmentConfig {\n const globalConfigPath = path.join(os.homedir(), '.semiontconfig');\n return createTomlConfigLoader(\n nodeTomlFileReader,\n globalConfigPath,\n process.env\n )(projectRoot, environment);\n}\n"]}
1
+ {"version":3,"sources":["../../src/config/toml-loader.ts","../../src/project.ts","../../src/config/node-config-loader.ts"],"names":["parseToml","fs2","path2","os2"],"mappings":"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","file":"node-config-loader.js","sourcesContent":["/**\n * TOML Config Loader\n *\n * Reads ~/.semiontconfig (TOML) and .semiont/config (TOML) and produces\n * an EnvironmentConfig for the requested environment.\n *\n * File format: see TOML-XDG-CONFIG.md\n *\n * Loading sequence:\n * 1. Read .semiont/config → projectName, site, environments.<env>.* (project base)\n * 2. Read ~/.semiontconfig → defaults, environments.<env>.* (user overrides)\n * 3. Deep-merge: project base ← user overrides (user wins on conflicts)\n * Any environment name is valid (local, staging, production, custom, ...)\n * 4. Resolve ${VAR} references from process.env\n * 5. Apply inheritance: workers.<name> → workers.default → error\n * 6. Map to EnvironmentConfig shape\n */\n\nimport { parse as parseToml } from 'smol-toml';\nimport type { EnvironmentConfig, OllamaProviderConfig, AnthropicProviderConfig } from './config.types';\nimport type { PlatformType } from './config.types';\n\n/**\n * Deep merge two plain objects. Arrays and primitives in `override` replace those in `base`.\n * Nested objects are merged recursively. `override` takes precedence on conflicts.\n */\nfunction deepMerge<T extends Record<string, unknown>>(base: T, override: Partial<T>): T {\n const result = { ...base } as Record<string, unknown>;\n for (const key of Object.keys(override)) {\n const b = base[key];\n const o = override[key];\n if (o !== undefined && o !== null && typeof o === 'object' && !Array.isArray(o) &&\n b !== undefined && b !== null && typeof b === 'object' && !Array.isArray(b)) {\n result[key] = deepMerge(b as Record<string, unknown>, o as Record<string, unknown>);\n } else if (o !== undefined) {\n result[key] = o;\n }\n }\n return result as T;\n}\n\nfunction resolveEnvVars(obj: unknown, env: Record<string, string | undefined>): unknown {\n if (typeof obj === 'string') {\n return obj.replace(/\\$\\{([^}]+)\\}/g, (match, varName) => {\n if (env[varName] === undefined) {\n throw new Error(`Environment variable ${varName} is not set (referenced in config as ${match})`);\n }\n return env[varName] as string;\n });\n }\n if (Array.isArray(obj)) {\n return obj.map(item => resolveEnvVars(item, env));\n }\n if (obj !== null && typeof obj === 'object') {\n const resolved: Record<string, unknown> = {};\n for (const key in obj as Record<string, unknown>) {\n resolved[key] = resolveEnvVars((obj as Record<string, unknown>)[key], env);\n }\n return resolved;\n }\n return obj;\n}\n\n// ── Inference config types (mirrored from packages/make-meaning/src/config.ts) ─\n// Kept here to avoid a circular dependency: core cannot import make-meaning.\n\nexport interface InferenceConfig {\n type: 'anthropic' | 'ollama';\n model: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n}\n\nexport interface ActorInferenceConfig {\n gatherer?: InferenceConfig;\n matcher?: InferenceConfig;\n}\n\nexport interface WorkerInferenceConfig {\n default?: InferenceConfig;\n 'reference-annotation'?: InferenceConfig;\n 'highlight-annotation'?: InferenceConfig;\n 'assessment-annotation'?: InferenceConfig;\n 'comment-annotation'?: InferenceConfig;\n 'tag-annotation'?: InferenceConfig;\n 'generation'?: InferenceConfig;\n}\n\n// ── Types for ~/.semiontconfig ────────────────────────────────────────────────\n\ninterface SemiontConfigFile {\n user?: {\n name?: string;\n email?: string;\n };\n defaults?: {\n environment?: string;\n platform?: string;\n };\n environments?: Record<string, EnvironmentSection>;\n}\n\ninterface GraphSection {\n platform?: string;\n type?: string;\n name?: string;\n uri?: string;\n username?: string;\n password?: string;\n database?: string;\n [key: string]: unknown;\n}\n\ninterface InferenceFlatSection {\n // Flat (single-provider) format: type = \"anthropic\"|\"ollama\" at this level\n type?: 'anthropic' | 'ollama';\n platform?: string;\n model?: string;\n maxTokens?: number;\n apiKey?: string;\n endpoint?: string;\n baseURL?: string;\n // Keyed (multi-provider) format: [inference.anthropic] / [inference.ollama]\n anthropic?: { platform?: string; apiKey?: string; endpoint?: string };\n ollama?: { platform?: string; baseURL?: string; port?: number };\n}\n\ninterface EnvironmentSection {\n backend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n frontendURL?: string;\n corsOrigin?: string;\n };\n frontend?: {\n platform?: string;\n port?: number;\n publicURL?: string;\n };\n proxy?: {\n platform?: string;\n port?: number;\n adminPort?: number;\n publicURL?: string;\n };\n site?: {\n domain?: string;\n siteName?: string;\n adminEmail?: string;\n oauthAllowedDomains?: string[];\n enableLocalAuth?: boolean;\n };\n database?: {\n platform?: string;\n image?: string;\n host?: string;\n port?: number;\n name?: string;\n user?: string;\n password?: string;\n };\n graph?: GraphSection;\n inference?: InferenceFlatSection;\n 'make-meaning'?: {\n graph?: Record<string, unknown>;\n actors?: {\n gatherer?: { inference?: InferenceConfig };\n matcher?: { inference?: InferenceConfig };\n };\n default?: { inference?: InferenceConfig };\n };\n workers?: Record<string, { inference?: InferenceConfig }>;\n actors?: Record<string, { inference?: InferenceConfig }>;\n logLevel?: 'error' | 'warn' | 'info' | 'http' | 'debug';\n}\n\n// ── File reader abstraction (same pattern as createConfigLoader) ──────────────\n\nexport type TomlFileReader = {\n readIfExists: (path: string) => string | null;\n};\n\nfunction requirePlatform(value: string | undefined, serviceName: string): PlatformType {\n if (!value) {\n throw new Error(`platform is required for service '${serviceName}' — add 'platform = \"posix\"|\"container\"|\"external\"' to its config section`);\n }\n return value as PlatformType;\n}\n\n// ── Main loader function ──────────────────────────────────────────────────────\n\n/**\n * Parse ~/.semiontconfig and .semiont/config and return EnvironmentConfig.\n *\n * @param projectRoot - Path to the project root (contains .semiont/config)\n * @param environment - Environment name (e.g. 'local', 'production')\n * @param globalConfigPath - Path to ~/.semiontconfig (caller resolves ~ expansion)\n * @param reader - File reader abstraction\n * @param env - Environment variables for ${VAR} resolution\n */\nexport function loadTomlConfig(\n projectRoot: string | null,\n environment: string,\n globalConfigPath: string,\n reader: TomlFileReader,\n env: Record<string, string | undefined>\n): EnvironmentConfig {\n // 1. Read project config from .semiont/config (skipped when no project root)\n const projectConfigContent = projectRoot ? reader.readIfExists(`${projectRoot}/.semiont/config`) : null;\n let projectName = 'semiont-project';\n let projectVersion: string | undefined;\n let projectSite: EnvironmentSection['site'] | undefined;\n let projectEnvSection: EnvironmentSection = {};\n if (projectConfigContent) {\n const projectConfig = parseToml(projectConfigContent) as {\n project?: { name?: string; version?: string };\n site?: EnvironmentSection['site'];\n environments?: Record<string, EnvironmentSection>;\n };\n projectName = projectConfig.project?.name ?? projectName;\n projectVersion = projectConfig.project?.version;\n projectSite = projectConfig.site;\n projectEnvSection = projectConfig.environments?.[environment] ?? {};\n }\n\n // 2. Read global config (optional — missing config yields empty environments)\n const globalContent = reader.readIfExists(globalConfigPath);\n const raw = globalContent ? (parseToml(globalContent) as SemiontConfigFile) : ({} as SemiontConfigFile);\n\n // 3. Deep-merge: project base + user overrides (user wins on conflicts)\n const userEnvSection: EnvironmentSection = raw.environments?.[environment] ?? {};\n const envSection: EnvironmentSection = deepMerge(\n projectEnvSection as Record<string, unknown>,\n userEnvSection as Record<string, unknown>\n ) as EnvironmentSection;\n\n // 4. Resolve ${VAR} references\n const resolved = resolveEnvVars(envSection, env) as EnvironmentSection;\n\n // 5. Build make-meaning actor/worker inference config with inheritance\n // The flat [inference] section provides defaults (apiKey, maxTokens, endpoint/baseURL).\n // Actor/worker sections only need to specify type and model; missing fields fall back\n // to the flat inference section.\n const flatInference = resolved.inference;\n const makeMeaningSection = resolved['make-meaning'];\n const workersSection = resolved.workers ?? {};\n const actorsSection = resolved.actors ?? {};\n const defaultWorkerInference = workersSection['default']?.inference;\n const defaultMakeMeaningInference = makeMeaningSection?.default?.inference;\n\n function mergeWithFlatInference(specific: InferenceConfig): InferenceConfig {\n if (!flatInference) return specific;\n // For keyed sub-sections, inherit credentials from the matching provider sub-section.\n // For flat (legacy) format, flatInference.type is required to know which fields apply.\n const providerDefaults: Partial<InferenceConfig> = {};\n if (specific.type === 'anthropic') {\n const a = flatInference.anthropic;\n if (a) {\n providerDefaults.apiKey = a.apiKey;\n providerDefaults.endpoint = a.endpoint;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"anthropic\" or use [inference.anthropic] sub-section.`\n );\n }\n providerDefaults.apiKey = flatInference.apiKey;\n providerDefaults.endpoint = flatInference.endpoint;\n }\n } else if (specific.type === 'ollama') {\n const o = flatInference.ollama;\n if (o) {\n providerDefaults.baseURL = o.baseURL;\n } else {\n if (!flatInference.type) {\n throw new Error(\n `[environments.${environment}.inference] is missing 'type'. ` +\n `Add type = \"ollama\" or use [inference.ollama] sub-section.`\n );\n }\n providerDefaults.baseURL = flatInference.baseURL;\n }\n }\n return {\n maxTokens: flatInference.maxTokens,\n ...providerDefaults,\n ...specific,\n };\n }\n\n function resolveActorInference(fromMakeMeaning?: InferenceConfig, fromActors?: InferenceConfig): InferenceConfig | undefined {\n const base = fromMakeMeaning ?? fromActors ?? defaultMakeMeaningInference;\n if (!base) return undefined;\n return mergeWithFlatInference(base);\n }\n\n const actors: ActorInferenceConfig = {};\n const gathererInference = resolveActorInference(\n makeMeaningSection?.actors?.gatherer?.inference,\n actorsSection['gatherer']?.inference\n );\n if (gathererInference) actors.gatherer = gathererInference;\n\n const matcherInference = resolveActorInference(\n makeMeaningSection?.actors?.matcher?.inference,\n actorsSection['matcher']?.inference\n );\n if (matcherInference) actors.matcher = matcherInference;\n\n const workers: WorkerInferenceConfig = {};\n const workerTypes = ['reference-annotation', 'highlight-annotation', 'assessment-annotation', 'comment-annotation', 'tag-annotation', 'generation'] as const;\n if (defaultWorkerInference) {\n workers.default = mergeWithFlatInference(defaultWorkerInference);\n }\n for (const wt of workerTypes) {\n const specific = workersSection[wt]?.inference;\n if (specific) {\n (workers as Record<string, InferenceConfig>)[wt] = mergeWithFlatInference(specific);\n }\n }\n\n // 6. Map to EnvironmentConfig\n const backend = resolved.backend;\n const site = resolved.site ?? projectSite;\n const inferenceSection = resolved.inference;\n\n // Build inference providers config.\n // Supports two formats:\n // Flat: [environments.local.inference] type = \"anthropic\"|\"ollama\" (single provider)\n // Keyed: [environments.local.inference.anthropic] / [environments.local.inference.ollama] (multi-provider)\n let inferenceProviders: EnvironmentConfig['inference'] | undefined;\n if (inferenceSection) {\n inferenceProviders = {};\n // Keyed sub-sections take priority\n if (inferenceSection.anthropic) {\n const a = inferenceSection.anthropic;\n inferenceProviders.anthropic = {\n platform: requirePlatform(a.platform, 'inference.anthropic'),\n endpoint: a.endpoint ?? 'https://api.anthropic.com',\n apiKey: a.apiKey ?? '',\n } as AnthropicProviderConfig;\n } else if (inferenceSection.type === 'anthropic') {\n inferenceProviders.anthropic = {\n platform: requirePlatform(inferenceSection.platform, 'inference'),\n endpoint: inferenceSection.endpoint ?? 'https://api.anthropic.com',\n apiKey: inferenceSection.apiKey ?? '',\n } as AnthropicProviderConfig;\n }\n if (inferenceSection.ollama) {\n const o = inferenceSection.ollama;\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(o.platform, 'inference.ollama') },\n baseURL: o.baseURL,\n port: o.baseURL ? undefined : (o.port ?? 11434),\n } as OllamaProviderConfig;\n } else if (inferenceSection.type === 'ollama') {\n inferenceProviders.ollama = {\n platform: { type: requirePlatform(inferenceSection.platform, 'inference') },\n baseURL: inferenceSection.baseURL,\n port: inferenceSection.baseURL ? undefined : 11434,\n } as OllamaProviderConfig;\n }\n }\n\n // Build top-level workers/actors maps for EnvironmentConfig\n const topLevelWorkers: EnvironmentConfig['workers'] = {};\n for (const [name, w] of Object.entries(workersSection)) {\n if (w.inference) {\n topLevelWorkers[name] = { inference: { type: w.inference.type, model: w.inference.model } };\n }\n }\n const topLevelActors: EnvironmentConfig['actors'] = {};\n for (const [name, a] of Object.entries(actorsSection)) {\n if (a.inference) {\n topLevelActors[name] = { inference: { type: a.inference.type, model: a.inference.model } };\n }\n }\n // Also include make-meaning actors\n if (makeMeaningSection?.actors?.gatherer?.inference) {\n topLevelActors['gatherer'] = { inference: { type: makeMeaningSection.actors.gatherer.inference.type, model: makeMeaningSection.actors.gatherer.inference.model } };\n }\n if (makeMeaningSection?.actors?.matcher?.inference) {\n topLevelActors['matcher'] = { inference: { type: makeMeaningSection.actors.matcher.inference.type, model: makeMeaningSection.actors.matcher.inference.model } };\n }\n\n const frontend = resolved.frontend;\n const proxy = resolved.proxy;\n\n const config: EnvironmentConfig = {\n services: {\n backend: backend ? {\n platform: { type: requirePlatform(backend.platform, 'backend') },\n port: backend.port ?? 4000,\n publicURL: backend.publicURL ?? `http://localhost:${backend.port ?? 4000}`,\n corsOrigin: backend.corsOrigin ?? backend.frontendURL ?? 'http://localhost:3000',\n } : undefined,\n frontend: frontend ? {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n } : undefined,\n proxy: proxy ? {\n platform: { type: requirePlatform(proxy.platform, 'proxy') },\n type: 'envoy',\n port: proxy.port ?? 8080,\n adminPort: proxy.adminPort ?? 9901,\n backendPort: backend?.port ?? 4000,\n frontendPort: frontend?.port ?? 3000,\n } : undefined,\n graph: resolved.graph ? {\n ...resolved.graph,\n platform: { type: requirePlatform(resolved.graph.platform as string | undefined, 'graph') },\n type: (resolved.graph.type ?? 'neo4j') as import('./config.types').GraphDatabaseType,\n } as EnvironmentConfig['services']['graph'] : (makeMeaningSection?.graph as EnvironmentConfig['services']['graph']),\n database: resolved.database ? {\n platform: { type: requirePlatform(resolved.database.platform, 'database') },\n type: 'postgres',\n image: resolved.database.image,\n host: resolved.database.host ?? 'localhost',\n port: resolved.database.port ?? 5432,\n name: resolved.database.name,\n user: resolved.database.user,\n password: resolved.database.password,\n } as EnvironmentConfig['services']['database'] : undefined,\n },\n ...(inferenceProviders ? { inference: inferenceProviders } : {}),\n ...(Object.keys(topLevelWorkers).length > 0 ? { workers: topLevelWorkers } : {}),\n ...(Object.keys(topLevelActors).length > 0 ? { actors: topLevelActors } : {}),\n site: site ? {\n domain: site.domain ?? 'localhost',\n siteName: site.siteName,\n adminEmail: site.adminEmail,\n oauthAllowedDomains: site.oauthAllowedDomains as [string, ...string[]] | undefined,\n } : undefined,\n logLevel: resolved.logLevel,\n _metadata: {\n environment,\n projectRoot,\n projectName,\n projectVersion,\n ...(Object.keys(actors).length > 0 ? { actors } : {}),\n ...(Object.keys(workers).length > 0 ? { workers } : {}),\n },\n };\n\n return config;\n}\n\n/**\n * Create a TOML config loader backed by a file reader.\n * Drop-in replacement for createConfigLoader that reads TOML instead of JSON.\n * The caller must resolve globalConfigPath (e.g. expand '~' using process.env.HOME).\n */\nexport function createTomlConfigLoader(\n reader: TomlFileReader,\n globalConfigPath: string,\n env: Record<string, string | undefined>\n) {\n return (projectRoot: string | null, environment: string): EnvironmentConfig => {\n return loadTomlConfig(projectRoot, environment, globalConfigPath, reader, env);\n };\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\n\n/**\n * Represents a Semiont project rooted at a given directory.\n *\n * Computes all paths — durable and ephemeral — once at construction time.\n * XDG environment variables are read here and nowhere else.\n *\n * Durable paths (inside the project root, committed or repo-local):\n * eventsDir — .semiont/events/ (system of record, committed)\n * representationsDir — representations/ (content store, committed)\n *\n * Ephemeral paths (outside the project root, never committed):\n * configDir — $XDG_CONFIG_HOME/semiont/{name}/ (generated config for managed processes)\n * dataHome — $XDG_DATA_HOME/semiont/{name}/ (persistent user data, e.g. database files)\n * stateDir — $XDG_STATE_HOME/semiont/{name}/\n * projectionsDir — stateDir/projections/\n * jobsDir — stateDir/jobs/\n * backendLogsDir — stateDir/backend/\n * backendAppLogFile — backendLogsDir/app.log\n * backendErrorLogFile — backendLogsDir/error.log\n * runtimeDir — $XDG_RUNTIME_DIR/semiont/{name}/ (or $TMPDIR fallback)\n * backendPidFile — runtimeDir/backend.pid\n *\n * Note: frontend paths are NOT project-scoped. The frontend service is bundled\n * with the CLI and uses fixed XDG paths keyed by \"frontend\", not project name.\n * See apps/cli/src/platforms/posix/handlers/frontend-paths.ts.\n */\nexport class SemiontProject {\n readonly root: string;\n readonly name: string;\n\n /** True if [git] sync = true in .semiont/config. When true, semiont stages\n * working-tree and event-log changes in the git index automatically. */\n readonly gitSync: boolean;\n\n // Durable\n readonly eventsDir: string;\n readonly representationsDir: string;\n\n // Ephemeral — config (generated config files for managed processes)\n readonly configDir: string;\n\n // Ephemeral — data (persistent user data managed by semiont)\n readonly dataHome: string;\n\n // Ephemeral — state\n readonly stateDir: string;\n readonly projectionsDir: string;\n readonly jobsDir: string;\n readonly backendLogsDir: string;\n readonly backendAppLogFile: string;\n readonly backendErrorLogFile: string;\n\n // Ephemeral — runtime\n readonly runtimeDir: string;\n readonly backendPidFile: string;\n\n constructor(projectRoot: string, name?: string) {\n this.root = projectRoot;\n if (name !== undefined) {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) {\n fs.mkdirSync(path.join(projectRoot, '.semiont'), { recursive: true });\n fs.writeFileSync(configPath, `[project]\\nname = \"${name}\"\\n`);\n }\n }\n this.name = SemiontProject.readName(projectRoot);\n this.gitSync = SemiontProject.readGitSync(projectRoot);\n\n this.eventsDir = path.join(projectRoot, '.semiont', 'events');\n this.representationsDir = path.join(projectRoot, 'representations');\n\n const xdgConfig = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');\n this.configDir = path.join(xdgConfig, 'semiont', this.name);\n\n const xdgData = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n this.dataHome = path.join(xdgData, 'semiont', this.name);\n\n const xdgState = process.env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');\n this.stateDir = path.join(xdgState, 'semiont', this.name);\n this.projectionsDir = path.join(this.stateDir, 'projections');\n this.jobsDir = path.join(this.stateDir, 'jobs');\n this.backendLogsDir = path.join(this.stateDir, 'backend');\n this.backendAppLogFile = path.join(this.backendLogsDir, 'app.log');\n this.backendErrorLogFile = path.join(this.backendLogsDir, 'error.log');\n\n const xdgRuntime = process.env.XDG_RUNTIME_DIR;\n const runtimeBase = xdgRuntime ?? process.env.TMPDIR ?? '/tmp';\n this.runtimeDir = path.join(runtimeBase, 'semiont', this.name);\n this.backendPidFile = path.join(this.runtimeDir, 'backend.pid');\n }\n\n /**\n * Delete all ephemeral state for this project (stateDir + runtimeDir).\n * Does not touch eventsDir or dataDir.\n */\n async destroy(): Promise<void> {\n await Promise.all([\n fs.promises.rm(this.configDir, { recursive: true, force: true }),\n fs.promises.rm(this.stateDir, { recursive: true, force: true }),\n fs.promises.rm(this.runtimeDir, { recursive: true, force: true }),\n ]);\n }\n\n /**\n * Read [git] sync from .semiont/config.\n * Defaults to false if the section or key is absent.\n */\n private static readGitSync(projectRoot: string): boolean {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (!fs.existsSync(configPath)) return false;\n const content = fs.readFileSync(configPath, 'utf-8');\n let inGitSection = false;\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed === '[git]') { inGitSection = true; continue; }\n if (trimmed.startsWith('[')) { inGitSection = false; continue; }\n if (inGitSection && trimmed.startsWith('sync') && trimmed.includes('=')) {\n const value = trimmed.split('=')[1]?.trim();\n return value === 'true';\n }\n }\n return false;\n }\n\n /**\n * Read the project name from .semiont/config [project] name = \"...\"\n * Falls back to the directory basename if the config is absent or has no name.\n */\n private static readName(projectRoot: string): string {\n const configPath = path.join(projectRoot, '.semiont', 'config');\n if (fs.existsSync(configPath)) {\n const content = fs.readFileSync(configPath, 'utf-8');\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (trimmed.startsWith('name') && trimmed.includes('=')) {\n const [, ...rest] = trimmed.split('=');\n return rest.join('=').trim().replace(/^\"(.*)\"$/, '$1');\n }\n }\n }\n return path.basename(projectRoot);\n }\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createTomlConfigLoader } from './toml-loader.js';\nimport type { EnvironmentConfig } from './config.types.js';\n\nexport { SemiontProject } from '../project.js';\n\nconst nodeTomlFileReader = {\n readIfExists: (filePath: string): string | null =>\n fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : null,\n};\n\n/**\n * Load semiont environment config for a Node.js process.\n *\n * Reads ~/.semiontconfig (global) merged with .semiont/config (project-local),\n * then selects the given environment overlay.\n *\n * This is the canonical config loader for any Node.js process. SEMIONT_ENV\n * should be read once at the process entry point and passed as `environment`.\n */\nexport function loadEnvironmentConfig(\n projectRoot: string,\n environment: string\n): EnvironmentConfig {\n const globalConfigPath = path.join(os.homedir(), '.semiontconfig');\n return createTomlConfigLoader(\n nodeTomlFileReader,\n globalConfigPath,\n process.env\n )(projectRoot, environment);\n}\n"]}
@@ -230,7 +230,6 @@ interface FrontendServiceConfig {
230
230
  [k: string]: string;
231
231
  };
232
232
  publicURL?: string;
233
- backendURL?: string;
234
233
  allowedOrigins?: string[];
235
234
  }
236
235
  /**
@@ -490,7 +489,7 @@ interface EnvironmentConfig {
490
489
  _comment?: string;
491
490
  _metadata?: {
492
491
  environment: string;
493
- projectRoot: string;
492
+ projectRoot: string | null;
494
493
  [k: string]: unknown;
495
494
  };
496
495
  /**