@semiont/core 0.4.15 → 0.4.16
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.
|
@@ -45,6 +45,11 @@ declare class SemiontProject {
|
|
|
45
45
|
readonly runtimeDir: string;
|
|
46
46
|
readonly backendPidFile: string;
|
|
47
47
|
constructor(projectRoot: string, name?: string);
|
|
48
|
+
/**
|
|
49
|
+
* Read the current git branch for the project root.
|
|
50
|
+
* Returns null if the project is not a git repo or git is not available.
|
|
51
|
+
*/
|
|
52
|
+
gitBranch(): string | null;
|
|
48
53
|
/**
|
|
49
54
|
* Delete all ephemeral state for this project (stateDir + runtimeDir).
|
|
50
55
|
* Does not touch eventsDir or dataDir.
|
|
@@ -2,6 +2,7 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as os from 'os';
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { parse } from 'smol-toml';
|
|
5
|
+
import { execFileSync } from 'child_process';
|
|
5
6
|
|
|
6
7
|
// src/config/node-config-loader.ts
|
|
7
8
|
function deepMerge(base, override) {
|
|
@@ -331,6 +332,21 @@ name = "${name}"
|
|
|
331
332
|
this.runtimeDir = path.join(runtimeBase, "semiont", this.name);
|
|
332
333
|
this.backendPidFile = path.join(this.runtimeDir, "backend.pid");
|
|
333
334
|
}
|
|
335
|
+
/**
|
|
336
|
+
* Read the current git branch for the project root.
|
|
337
|
+
* Returns null if the project is not a git repo or git is not available.
|
|
338
|
+
*/
|
|
339
|
+
gitBranch() {
|
|
340
|
+
try {
|
|
341
|
+
return execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
342
|
+
cwd: this.root,
|
|
343
|
+
encoding: "utf-8",
|
|
344
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
345
|
+
}).trim() || null;
|
|
346
|
+
} catch {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
334
350
|
/**
|
|
335
351
|
* Delete all ephemeral state for this project (stateDir + runtimeDir).
|
|
336
352
|
* Does not touch eventsDir or dataDir.
|
|
@@ -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 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 vectors?: {\n type?: 'qdrant' | 'memory';\n host?: string;\n port?: number;\n // Legacy: embedding nested under vectors (migrated to top-level)\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n };\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\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\n const services: EnvironmentConfig['services'] = {};\n\n if (backend) {\n services.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 };\n }\n\n if (frontend) {\n services.frontend = {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n };\n }\n\n if (resolved.graph) {\n services.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'];\n } else if (makeMeaningSection?.graph) {\n services.graph = makeMeaningSection.graph as EnvironmentConfig['services']['graph'];\n }\n\n if (resolved.database) {\n services.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'];\n }\n\n if (resolved.vectors) {\n services.vectors = {\n platform: { type: 'external' as PlatformType },\n type: (resolved.vectors.type ?? 'qdrant') as 'qdrant' | 'memory',\n host: resolved.vectors.host,\n port: resolved.vectors.port ?? 6333,\n } as EnvironmentConfig['services']['vectors'];\n }\n\n // Embedding: top-level takes precedence, fall back to legacy vectors.embedding\n const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;\n if (embeddingSource) {\n services.embedding = {\n platform: { type: 'external' as PlatformType },\n type: embeddingSource.type!,\n model: embeddingSource.model!,\n apiKey: embeddingSource.apiKey,\n baseURL: embeddingSource.baseURL,\n endpoint: embeddingSource.endpoint,\n chunking: (resolved.embedding?.chunking ?? resolved.vectors?.chunking) ? {\n chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,\n overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64,\n } : undefined,\n } as EnvironmentConfig['services']['embedding'];\n }\n\n const config: EnvironmentConfig = {\n services,\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"]}
|
|
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 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 vectors?: {\n type?: 'qdrant' | 'memory';\n host?: string;\n port?: number;\n // Legacy: embedding nested under vectors (migrated to top-level)\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n };\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\n embedding?: {\n type?: 'voyage' | 'ollama';\n model?: string;\n apiKey?: string;\n baseURL?: string;\n endpoint?: string;\n chunking?: {\n chunkSize?: number;\n overlap?: number;\n };\n };\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\n const services: EnvironmentConfig['services'] = {};\n\n if (backend) {\n services.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 };\n }\n\n if (frontend) {\n services.frontend = {\n platform: { type: requirePlatform(frontend.platform, 'frontend') },\n port: frontend.port ?? 3000,\n siteName: site?.siteName ?? 'Semiont',\n publicURL: frontend.publicURL,\n };\n }\n\n if (resolved.graph) {\n services.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'];\n } else if (makeMeaningSection?.graph) {\n services.graph = makeMeaningSection.graph as EnvironmentConfig['services']['graph'];\n }\n\n if (resolved.database) {\n services.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'];\n }\n\n if (resolved.vectors) {\n services.vectors = {\n platform: { type: 'external' as PlatformType },\n type: (resolved.vectors.type ?? 'qdrant') as 'qdrant' | 'memory',\n host: resolved.vectors.host,\n port: resolved.vectors.port ?? 6333,\n } as EnvironmentConfig['services']['vectors'];\n }\n\n // Embedding: top-level takes precedence, fall back to legacy vectors.embedding\n const embeddingSource = resolved.embedding ?? resolved.vectors?.embedding;\n if (embeddingSource) {\n services.embedding = {\n platform: { type: 'external' as PlatformType },\n type: embeddingSource.type!,\n model: embeddingSource.model!,\n apiKey: embeddingSource.apiKey,\n baseURL: embeddingSource.baseURL,\n endpoint: embeddingSource.endpoint,\n chunking: (resolved.embedding?.chunking ?? resolved.vectors?.chunking) ? {\n chunkSize: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.chunkSize ?? 512,\n overlap: (resolved.embedding?.chunking ?? resolved.vectors?.chunking)?.overlap ?? 64,\n } : undefined,\n } as EnvironmentConfig['services']['embedding'];\n }\n\n const config: EnvironmentConfig = {\n services,\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';\nimport { execFileSync } from 'child_process';\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 * Read the current git branch for the project root.\n * Returns null if the project is not a git repo or git is not available.\n */\n gitBranch(): string | null {\n try {\n return execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd: this.root,\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'ignore'],\n }).trim() || null;\n } catch {\n return null;\n }\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"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -4015,6 +4015,8 @@ interface components {
|
|
|
4015
4015
|
authenticatedAs?: string;
|
|
4016
4016
|
/** @description Name of the knowledge base project */
|
|
4017
4017
|
projectName?: string;
|
|
4018
|
+
/** @description Current git branch of the knowledge base repository */
|
|
4019
|
+
gitBranch?: string;
|
|
4018
4020
|
};
|
|
4019
4021
|
TextPositionSelector: {
|
|
4020
4022
|
/** @enum {string} */
|