@hilbras/omninode 2.0.0-alpha.14 → 2.0.0-alpha.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.
- package/README.md +16 -2
- package/dist/cli/index.js +658 -251
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +65 -4
- package/dist/index.js +202 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1502,6 +1502,10 @@ declare const projectConfigSchema: z.ZodObject<{
|
|
|
1502
1502
|
} | undefined;
|
|
1503
1503
|
}>;
|
|
1504
1504
|
declare const appConfigSchema: z.ZodObject<{
|
|
1505
|
+
/** Active profile; overlays live under `profiles` (§16). */
|
|
1506
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
1507
|
+
/** Named partial overlays, e.g. development/production/testing. */
|
|
1508
|
+
profiles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1505
1509
|
project: z.ZodObject<{
|
|
1506
1510
|
name: z.ZodString;
|
|
1507
1511
|
providers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -1924,6 +1928,8 @@ declare const appConfigSchema: z.ZodObject<{
|
|
|
1924
1928
|
required?: boolean | undefined;
|
|
1925
1929
|
} | undefined;
|
|
1926
1930
|
};
|
|
1931
|
+
profile?: string | undefined;
|
|
1932
|
+
profiles?: Record<string, unknown> | undefined;
|
|
1927
1933
|
logging?: {
|
|
1928
1934
|
level: "info" | "error" | "debug" | "warn";
|
|
1929
1935
|
format?: "text" | "json" | undefined;
|
|
@@ -1997,6 +2003,8 @@ declare const appConfigSchema: z.ZodObject<{
|
|
|
1997
2003
|
required?: boolean | undefined;
|
|
1998
2004
|
} | undefined;
|
|
1999
2005
|
};
|
|
2006
|
+
profile?: string | undefined;
|
|
2007
|
+
profiles?: Record<string, unknown> | undefined;
|
|
2000
2008
|
logging?: {
|
|
2001
2009
|
level: "info" | "error" | "debug" | "warn";
|
|
2002
2010
|
format?: "text" | "json" | undefined;
|
|
@@ -2055,11 +2063,13 @@ interface AppConfig {
|
|
|
2055
2063
|
};
|
|
2056
2064
|
}
|
|
2057
2065
|
interface LoadConfigOptions {
|
|
2058
|
-
/** Explicit path; otherwise
|
|
2066
|
+
/** Explicit path (CLI --config); otherwise the project file is discovered. */
|
|
2059
2067
|
path?: string;
|
|
2060
2068
|
directory?: string;
|
|
2061
|
-
/** Environment used for ${VAR} expansion; defaults to process.env. */
|
|
2069
|
+
/** Environment used for ${VAR} expansion and OMNINODE_* overrides; defaults to process.env. */
|
|
2062
2070
|
env?: Record<string, string | undefined>;
|
|
2071
|
+
/** Profile override (CLI --profile), above environment and file selection. */
|
|
2072
|
+
profile?: string;
|
|
2063
2073
|
}
|
|
2064
2074
|
declare function findConfigFile(directory?: string): string | undefined;
|
|
2065
2075
|
/**
|
|
@@ -2068,7 +2078,58 @@ declare function findConfigFile(directory?: string): string | undefined;
|
|
|
2068
2078
|
* authentication.
|
|
2069
2079
|
*/
|
|
2070
2080
|
declare function expandEnvRefs(text: string, env: Record<string, string | undefined>, source?: string): string;
|
|
2081
|
+
interface LoadConfigResult {
|
|
2082
|
+
config: AppConfig;
|
|
2083
|
+
sources: ConfigSources;
|
|
2084
|
+
}
|
|
2085
|
+
/**
|
|
2086
|
+
* Composes configuration from every source with the documented precedence
|
|
2087
|
+
* (roadmap §16): CLI → environment → project file → user file → profile
|
|
2088
|
+
* overlay → defaults.
|
|
2089
|
+
*/
|
|
2090
|
+
declare function loadConfigDetailed(options?: LoadConfigOptions): LoadConfigResult;
|
|
2091
|
+
/** Backwards-compatible wrapper: the composed configuration. */
|
|
2071
2092
|
declare function loadConfig(options?: LoadConfigOptions): AppConfig;
|
|
2093
|
+
/**
|
|
2094
|
+
* Actionable configuration diagnostics (roadmap §16) — the kind of message a
|
|
2095
|
+
* user can act on, rather than a generic schema failure.
|
|
2096
|
+
*/
|
|
2097
|
+
declare function configDiagnostics(config: AppConfig): string[];
|
|
2098
|
+
|
|
2099
|
+
/** Loose input shape: composition happens before strict validation. */
|
|
2100
|
+
type AppConfigInput = Record<string, unknown>;
|
|
2101
|
+
declare const KNOWN_PROFILES: readonly ["default", "development", "production", "testing"];
|
|
2102
|
+
type ProfileName = (typeof KNOWN_PROFILES)[number];
|
|
2103
|
+
interface ConfigSources {
|
|
2104
|
+
/** Project-level configuration file, if any. */
|
|
2105
|
+
projectFile?: string;
|
|
2106
|
+
/** User-level configuration file, if any. */
|
|
2107
|
+
userFile?: string;
|
|
2108
|
+
/** Active profile. */
|
|
2109
|
+
profile: string;
|
|
2110
|
+
/** Environment variables that overrode configuration. */
|
|
2111
|
+
envOverrides: string[];
|
|
2112
|
+
/** Values that came from built-in defaults. */
|
|
2113
|
+
defaults: string[];
|
|
2114
|
+
}
|
|
2115
|
+
/** Default user-level configuration locations, most portable first. */
|
|
2116
|
+
declare function userConfigPath(env?: Record<string, string | undefined>): string;
|
|
2117
|
+
/** Picks the profile: CLI (applied by the loader) > environment > file > default. */
|
|
2118
|
+
declare function resolveProfile(input: {
|
|
2119
|
+
profile?: unknown;
|
|
2120
|
+
}, env: Record<string, string | undefined>): string;
|
|
2121
|
+
/** Deep-merges configuration overlays (objects merge, scalars/arrays replace). */
|
|
2122
|
+
declare function mergeConfig<T>(base: T, overlay: unknown): T;
|
|
2123
|
+
/** Environment overrides applied above every file source. */
|
|
2124
|
+
declare function applyEnvOverrides(input: AppConfigInput, env: Record<string, string | undefined>): {
|
|
2125
|
+
config: AppConfigInput;
|
|
2126
|
+
applied: string[];
|
|
2127
|
+
};
|
|
2128
|
+
/** Built-in defaults, applied last. */
|
|
2129
|
+
declare function applyDefaults(input: AppConfigInput): {
|
|
2130
|
+
config: AppConfigInput;
|
|
2131
|
+
applied: string[];
|
|
2132
|
+
};
|
|
2072
2133
|
|
|
2073
2134
|
/** Template written by `omninode init` (§22, §23). */
|
|
2074
2135
|
declare function defaultProjectConfigYaml(projectName?: string): string;
|
|
@@ -3151,6 +3212,6 @@ declare function migrateProjectStores(directory?: string, options?: {
|
|
|
3151
3212
|
checkOnly?: boolean;
|
|
3152
3213
|
}): Promise<MigrationReport[]>;
|
|
3153
3214
|
|
|
3154
|
-
declare const OMNINODE_VERSION = "2.0.0-alpha.
|
|
3215
|
+
declare const OMNINODE_VERSION = "2.0.0-alpha.16";
|
|
3155
3216
|
|
|
3156
|
-
export { AgentAdapterRegistry, type AgentConfig, type AgentConfigYaml, type AgentDescriptor, AgentError, type AgentInfo, type AgentInputMode, type AgentIntegrationType, AgentRegistry, type AgentStatus, type AgentTaskInput, type AgentTaskOutput, type AgentToNodeMessage, type AggregateOptions, type AggregatedFinding, type AggregatedRecommendation, type AppConfig, type AppConfigYaml, type ArtifactKind, type ArtifactPayload, type AskedQuestion, type AuditAction, type AuditEvent, type AuditSink, type AuditSink as AuditStore, type ChatFn, type ChatMessage, type ChatRequest, type ChatResponse, type ChatRole, type ChatStreamChunk, type ChatUsage, type CollectionDiagnostics, type CombinedMeta, type CombinedReport, type CombinedReportFilter, type Confidence, ConfigError, type ConflictPosition, ConsoleLogSink, type CreateTaskInput, type CwdValidation, DEFAULT_MAX_OUTPUT_BYTES, type DecodeResult, type DefaultChatOptions, type DiscoveryResult, type DocumentState, type Durability, type EnvPolicy, type EnvelopeMeta, type Evidence, type EvidenceInput, type EvidenceKind, type ExecutionRecord, type ExtractionMeta, FileAuditLog, FilePipelineRunStore, FilePlanStore, FileReportStore, FileTaskStore, type Finding, type FindingOrigin, type FindingSeverity, type FindingSource, type HelloResult, HeuristicPlanner, type HttpRequestOptions, type HttpResponse, type IAgent, type IAgentAdapter, type IChatProvider, type IMemoryProvider, type IPipelineExecutor, type IPlanner, type IProvider, type JsonDocument, JsonFileStore, type JsonFileStoreOptions, type LoadConfigOptions, LocalMemoryProvider, type LogFormat, type LogLevel, type LogSink, Logger, type LoggerOptions, MAX_CONTEXT_CHARS, MAX_MESSAGE_BYTES, MAX_REPORT_BYTES, type MemoryCategory, type MemoryContextQuery, type MemoryEntry, MemoryError, type MemoryProviderConfig, type MemoryProviderMetadata, type MemoryQuery, type MemoryScope, MemoryService, type MemoryServiceOptions, LocalMemoryProvider as MemoryStore, type MemoryTaskContext, type MessageEnvelope, type MigrationReport, type Modality, type ModelCapabilities, type ModelFilter, type ModelInfo, ModelPlanner, ModelRegistry, type ModelStatus, type NodeToAgentMessage, OMNINODE_VERSION, OPENAI_COMPATIBLE_TYPES, type OmniHilbrasConnectionResult, OmniHilbrasProvider, OmniNodeError, type OmniNodeErrorCode, type OmniNodeErrorOptions, OpenAICompatibleProvider, PROTOCOL_V2, type PipelineConfigYaml, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, PipelineError, type PipelineRun, type PipelineRunAttempt, type PipelineRunFilter, type PipelineRunOptions, type PipelineRunStatus, type PipelineRunStore, type PipelineStep, type PipelineStepCondition, type PipelineStepConfigYaml, type PipelineStepKind, type PipelineStepRun, type PipelineRunStore as PipelineStore, type Plan, type PlanFilter, type PlanJsonResult, type PlanRequest, type PlanStep, type PlanStore, type PlanValidationIssue, type PlanValidationResult, type PlannerConfigYaml, PlannerError, ProcessAgent, ProcessAgentAdapter, type Project, type ProjectConfigYaml, ProjectStores, type ProtocolAgentToNodeType, ProtocolDecoder, type ProtocolEnvelope, ProtocolError, type ProtocolMessageType, type ProtocolNodeToAgentType, ProtocolSession, type ProtocolViolation, type ProtocolViolationCode, type ProviderAuthentication, type ProviderCapability, type ProviderConfig, type ProviderConfigYaml, ProviderError, type ProviderErrorKind, type ProviderHealth, type ProviderStatus, type ProviderType, type QuestionPayload, type QuestionResponder, type RememberaConfig, RememberaMemoryProvider, type Report, type ReportArtifact, type ReportConflict, type ReportFilter, type ReportPayload, ReportService, type ReportStore, type ReportValidationIssue, type ReportValidationResult, type RoleConfigYaml, type RoleDefinition, RoleRegistry, type RunPipelineOptions, SCHEMA_VERSION, STORE_FILES, SUPPORTED_PROTOCOL_VERSIONS, type SecretFinding, type SessionIds, TERMINAL_TASK_STATUSES, type Task, type TaskContext, TaskEngine, type TaskEngineOptions, TaskError, type TaskPayload, type TaskResult, type TaskStatus, type TaskStore, type TaskStoreFilter, type WritableLike, agentConfigSchema, aggregateReports, appConfigSchema, authHeaders, buildAgentRegistry, buildChildEnv, buildHello, buildHelloAck, buildPipelineEngine, buildPlanner, buildPlannerContext, buildRoleRegistry, composeTaskText, configureLogger, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, decodeMessage, decodeStream, defaultMetadata, defaultProjectConfigYaml, defaultSearch, describeExit, describeSecretFindings, detectConflicts, encodeMessage, envelope, expandEnvRefs, extractMessage, extractReportFromText, findConfigFile, inspectDocument, isNetworkError, isOmniNodeError, isRetryable, isSupportedProtocol, isTimeoutError, keywords, killTree, kindFromStatus, loadConfig, logger, migrateProjectStores, newMessageId, normalizeEvidence, normalizeFinding, parseHello, parsePlanJson, parseRetryAfter, pipelineConfigSchema, pipelineStepConfigSchema, planJsonSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, providerHttpError, providerTransportError, readDocument, registryKey, requestJson, requireCompletion, resolveApiKey, resolveEnvPolicy, roleConfigSchema, sanitizeChunk, scanForInlineSecrets, similar, validateEnvelope, validatePlan, validateReport, validateWorkingDirectory, writeFileAtomic };
|
|
3217
|
+
export { AgentAdapterRegistry, type AgentConfig, type AgentConfigYaml, type AgentDescriptor, AgentError, type AgentInfo, type AgentInputMode, type AgentIntegrationType, AgentRegistry, type AgentStatus, type AgentTaskInput, type AgentTaskOutput, type AgentToNodeMessage, type AggregateOptions, type AggregatedFinding, type AggregatedRecommendation, type AppConfig, type AppConfigInput, type AppConfigYaml, type ArtifactKind, type ArtifactPayload, type AskedQuestion, type AuditAction, type AuditEvent, type AuditSink, type AuditSink as AuditStore, type ChatFn, type ChatMessage, type ChatRequest, type ChatResponse, type ChatRole, type ChatStreamChunk, type ChatUsage, type CollectionDiagnostics, type CombinedMeta, type CombinedReport, type CombinedReportFilter, type Confidence, ConfigError, type ConfigSources, type ConflictPosition, ConsoleLogSink, type CreateTaskInput, type CwdValidation, DEFAULT_MAX_OUTPUT_BYTES, type DecodeResult, type DefaultChatOptions, type DiscoveryResult, type DocumentState, type Durability, type EnvPolicy, type EnvelopeMeta, type Evidence, type EvidenceInput, type EvidenceKind, type ExecutionRecord, type ExtractionMeta, FileAuditLog, FilePipelineRunStore, FilePlanStore, FileReportStore, FileTaskStore, type Finding, type FindingOrigin, type FindingSeverity, type FindingSource, type HelloResult, HeuristicPlanner, type HttpRequestOptions, type HttpResponse, type IAgent, type IAgentAdapter, type IChatProvider, type IMemoryProvider, type IPipelineExecutor, type IPlanner, type IProvider, type JsonDocument, JsonFileStore, type JsonFileStoreOptions, KNOWN_PROFILES, type LoadConfigOptions, type LoadConfigResult, LocalMemoryProvider, type LogFormat, type LogLevel, type LogSink, Logger, type LoggerOptions, MAX_CONTEXT_CHARS, MAX_MESSAGE_BYTES, MAX_REPORT_BYTES, type MemoryCategory, type MemoryContextQuery, type MemoryEntry, MemoryError, type MemoryProviderConfig, type MemoryProviderMetadata, type MemoryQuery, type MemoryScope, MemoryService, type MemoryServiceOptions, LocalMemoryProvider as MemoryStore, type MemoryTaskContext, type MessageEnvelope, type MigrationReport, type Modality, type ModelCapabilities, type ModelFilter, type ModelInfo, ModelPlanner, ModelRegistry, type ModelStatus, type NodeToAgentMessage, OMNINODE_VERSION, OPENAI_COMPATIBLE_TYPES, type OmniHilbrasConnectionResult, OmniHilbrasProvider, OmniNodeError, type OmniNodeErrorCode, type OmniNodeErrorOptions, OpenAICompatibleProvider, PROTOCOL_V2, type PipelineConfigYaml, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, PipelineError, type PipelineRun, type PipelineRunAttempt, type PipelineRunFilter, type PipelineRunOptions, type PipelineRunStatus, type PipelineRunStore, type PipelineStep, type PipelineStepCondition, type PipelineStepConfigYaml, type PipelineStepKind, type PipelineStepRun, type PipelineRunStore as PipelineStore, type Plan, type PlanFilter, type PlanJsonResult, type PlanRequest, type PlanStep, type PlanStore, type PlanValidationIssue, type PlanValidationResult, type PlannerConfigYaml, PlannerError, ProcessAgent, ProcessAgentAdapter, type ProfileName, type Project, type ProjectConfigYaml, ProjectStores, type ProtocolAgentToNodeType, ProtocolDecoder, type ProtocolEnvelope, ProtocolError, type ProtocolMessageType, type ProtocolNodeToAgentType, ProtocolSession, type ProtocolViolation, type ProtocolViolationCode, type ProviderAuthentication, type ProviderCapability, type ProviderConfig, type ProviderConfigYaml, ProviderError, type ProviderErrorKind, type ProviderHealth, type ProviderStatus, type ProviderType, type QuestionPayload, type QuestionResponder, type RememberaConfig, RememberaMemoryProvider, type Report, type ReportArtifact, type ReportConflict, type ReportFilter, type ReportPayload, ReportService, type ReportStore, type ReportValidationIssue, type ReportValidationResult, type RoleConfigYaml, type RoleDefinition, RoleRegistry, type RunPipelineOptions, SCHEMA_VERSION, STORE_FILES, SUPPORTED_PROTOCOL_VERSIONS, type SecretFinding, type SessionIds, TERMINAL_TASK_STATUSES, type Task, type TaskContext, TaskEngine, type TaskEngineOptions, TaskError, type TaskPayload, type TaskResult, type TaskStatus, type TaskStore, type TaskStoreFilter, type WritableLike, agentConfigSchema, aggregateReports, appConfigSchema, applyDefaults, applyEnvOverrides, authHeaders, buildAgentRegistry, buildChildEnv, buildHello, buildHelloAck, buildPipelineEngine, buildPlanner, buildPlannerContext, buildRoleRegistry, composeTaskText, configDiagnostics, configureLogger, createAgent, createDefaultChatFn, createMemoryProvider, createProvider, createTaskEngine, decodeMessage, decodeStream, defaultMetadata, defaultProjectConfigYaml, defaultSearch, describeExit, describeSecretFindings, detectConflicts, encodeMessage, envelope, expandEnvRefs, extractMessage, extractReportFromText, findConfigFile, inspectDocument, isNetworkError, isOmniNodeError, isRetryable, isSupportedProtocol, isTimeoutError, keywords, killTree, kindFromStatus, loadConfig, loadConfigDetailed, logger, mergeConfig, migrateProjectStores, newMessageId, normalizeEvidence, normalizeFinding, parseHello, parsePlanJson, parseRetryAfter, pipelineConfigSchema, pipelineStepConfigSchema, planJsonSchema, plannerConfigSchema, projectConfigSchema, providerConfigSchema, providerHttpError, providerTransportError, readDocument, registryKey, requestJson, requireCompletion, resolveApiKey, resolveEnvPolicy, resolveProfile, roleConfigSchema, sanitizeChunk, scanForInlineSecrets, similar, userConfigPath, validateEnvelope, validatePlan, validateReport, validateWorkingDirectory, writeFileAtomic };
|
package/dist/index.js
CHANGED
|
@@ -210,6 +210,10 @@ var projectConfigSchema = z.object({
|
|
|
210
210
|
}).strict().optional()
|
|
211
211
|
}).strict();
|
|
212
212
|
var appConfigSchema = z.object({
|
|
213
|
+
/** Active profile; overlays live under `profiles` (§16). */
|
|
214
|
+
profile: z.string().min(1).optional(),
|
|
215
|
+
/** Named partial overlays, e.g. development/production/testing. */
|
|
216
|
+
profiles: z.record(z.unknown()).optional(),
|
|
213
217
|
project: projectConfigSchema,
|
|
214
218
|
logging: z.object({
|
|
215
219
|
level: z.enum(["debug", "info", "warn", "error"]),
|
|
@@ -250,6 +254,86 @@ ${lines}
|
|
|
250
254
|
OmniNode never stores credentials in configuration. Replace each value with an environment-variable reference, e.g. api_key_env_var: MY_API_KEY.`;
|
|
251
255
|
}
|
|
252
256
|
|
|
257
|
+
// src/config/profiles.ts
|
|
258
|
+
import { homedir } from "os";
|
|
259
|
+
import path from "path";
|
|
260
|
+
var KNOWN_PROFILES = ["default", "development", "production", "testing"];
|
|
261
|
+
function userConfigPath(env = process.env) {
|
|
262
|
+
if (env.OMNINODE_USER_CONFIG) return env.OMNINODE_USER_CONFIG;
|
|
263
|
+
const home = env.HOME ?? homedir();
|
|
264
|
+
return path.join(home, ".omninode", "config.yaml");
|
|
265
|
+
}
|
|
266
|
+
function resolveProfile(input, env) {
|
|
267
|
+
if (env.OMNINODE_PROFILE) return env.OMNINODE_PROFILE;
|
|
268
|
+
if (typeof input.profile === "string" && input.profile.length > 0) return input.profile;
|
|
269
|
+
return "default";
|
|
270
|
+
}
|
|
271
|
+
function mergeConfig(base, overlay) {
|
|
272
|
+
if (!isPlainObject(base) || !isPlainObject(overlay)) {
|
|
273
|
+
return overlay === void 0 ? base : overlay;
|
|
274
|
+
}
|
|
275
|
+
const result = { ...base };
|
|
276
|
+
for (const [key, value] of Object.entries(overlay)) {
|
|
277
|
+
const existing = result[key];
|
|
278
|
+
if (Array.isArray(value)) {
|
|
279
|
+
result[key] = value;
|
|
280
|
+
} else if (isPlainObject(value) && isPlainObject(existing)) {
|
|
281
|
+
result[key] = mergeConfig(existing, value);
|
|
282
|
+
} else {
|
|
283
|
+
result[key] = value;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return result;
|
|
287
|
+
}
|
|
288
|
+
function isPlainObject(value) {
|
|
289
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
290
|
+
}
|
|
291
|
+
function asObject(value) {
|
|
292
|
+
return isPlainObject(value) ? value : {};
|
|
293
|
+
}
|
|
294
|
+
function applyEnvOverrides(input, env) {
|
|
295
|
+
const applied = [];
|
|
296
|
+
const config = mergeConfig(input, {});
|
|
297
|
+
if (env.OMNINODE_LOG_LEVEL) {
|
|
298
|
+
config.logging = { ...asObject(config.logging), level: env.OMNINODE_LOG_LEVEL };
|
|
299
|
+
applied.push("OMNINODE_LOG_LEVEL");
|
|
300
|
+
}
|
|
301
|
+
if (env.OMNINODE_LOG_FORMAT) {
|
|
302
|
+
config.logging = { ...asObject(config.logging), format: env.OMNINODE_LOG_FORMAT };
|
|
303
|
+
applied.push("OMNINODE_LOG_FORMAT");
|
|
304
|
+
}
|
|
305
|
+
const memoryProvider = env.OMNINODE_MEMORY_PROVIDER;
|
|
306
|
+
const memoryRequired = env.OMNINODE_MEMORY_REQUIRED;
|
|
307
|
+
if (memoryProvider || memoryRequired) {
|
|
308
|
+
const project = asObject(config.project);
|
|
309
|
+
config.project = {
|
|
310
|
+
...project,
|
|
311
|
+
memory: {
|
|
312
|
+
...asObject(project.memory ?? { provider: "local" }),
|
|
313
|
+
...memoryProvider ? { provider: memoryProvider } : {},
|
|
314
|
+
...memoryRequired ? { required: memoryRequired !== "false" } : {}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
if (memoryProvider) applied.push("OMNINODE_MEMORY_PROVIDER");
|
|
318
|
+
if (memoryRequired) applied.push("OMNINODE_MEMORY_REQUIRED");
|
|
319
|
+
}
|
|
320
|
+
return { config, applied };
|
|
321
|
+
}
|
|
322
|
+
function applyDefaults(input) {
|
|
323
|
+
const applied = [];
|
|
324
|
+
const config = mergeConfig(input, {});
|
|
325
|
+
const logging = asObject(config.logging);
|
|
326
|
+
if (logging.level === void 0) {
|
|
327
|
+
config.logging = { ...logging, level: "info" };
|
|
328
|
+
applied.push("logging.level");
|
|
329
|
+
}
|
|
330
|
+
if (logging.format === void 0) {
|
|
331
|
+
config.logging = { ...asObject(config.logging), format: "text" };
|
|
332
|
+
applied.push("logging.format");
|
|
333
|
+
}
|
|
334
|
+
return { config, applied };
|
|
335
|
+
}
|
|
336
|
+
|
|
253
337
|
// src/config/loader.ts
|
|
254
338
|
import { existsSync, readFileSync } from "fs";
|
|
255
339
|
import { parse as parseYaml } from "yaml";
|
|
@@ -276,38 +360,111 @@ function expandEnvRefs(text, env, source = "config") {
|
|
|
276
360
|
}
|
|
277
361
|
);
|
|
278
362
|
}
|
|
279
|
-
function
|
|
363
|
+
function loadConfigDetailed(options = {}) {
|
|
280
364
|
const env = options.env ?? process.env;
|
|
281
|
-
const
|
|
282
|
-
|
|
365
|
+
const explicitPath = options.path;
|
|
366
|
+
let input = {};
|
|
367
|
+
let projectFile;
|
|
368
|
+
let userFile;
|
|
369
|
+
if (!explicitPath) {
|
|
370
|
+
const candidate = userConfigPath(env);
|
|
371
|
+
if (existsSync(candidate)) {
|
|
372
|
+
input = mergeConfig(input, readConfigDocument(candidate, env));
|
|
373
|
+
userFile = candidate;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const resolvedProject = explicitPath ?? (options.directory ? findConfigFile(options.directory) : findConfigFile());
|
|
377
|
+
if (resolvedProject) {
|
|
378
|
+
input = mergeConfig(input, readConfigDocument(resolvedProject, env));
|
|
379
|
+
projectFile = resolvedProject;
|
|
380
|
+
}
|
|
381
|
+
if (!projectFile && !userFile) {
|
|
283
382
|
throw new ConfigError(
|
|
284
383
|
"CONFIG_NOT_FOUND",
|
|
285
384
|
"No omninode.yaml found. Run `omninode init` to create one, or pass an explicit path."
|
|
286
385
|
);
|
|
287
386
|
}
|
|
288
|
-
const
|
|
387
|
+
const profile = options.profile ?? resolveProfile(input, env);
|
|
388
|
+
const overlay = input.profiles?.[profile];
|
|
389
|
+
if (overlay !== void 0) {
|
|
390
|
+
const { profiles: _drop, ...base } = input;
|
|
391
|
+
input = mergeConfig(base, overlay);
|
|
392
|
+
} else if (profile !== "default" && profile !== "") {
|
|
393
|
+
throw new ConfigError(
|
|
394
|
+
"CONFIG_INVALID",
|
|
395
|
+
`Profile "${profile}" is not defined in this configuration (known: ${Object.keys(input.profiles ?? {}).join(", ") || "none"}).`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
const withEnv = applyEnvOverrides(input, env);
|
|
399
|
+
const withDefaults = applyDefaults(withEnv.config);
|
|
400
|
+
const parsed = appConfigSchema.safeParse(withDefaults.config);
|
|
401
|
+
if (!parsed.success) {
|
|
402
|
+
const issues = parsed.error.issues.map((issue) => {
|
|
403
|
+
const location = issue.path.join(".") || "(root)";
|
|
404
|
+
return `${location}: ${issue.message}`;
|
|
405
|
+
});
|
|
406
|
+
throw new ConfigError(
|
|
407
|
+
"CONFIG_INVALID",
|
|
408
|
+
`Invalid configuration:
|
|
409
|
+
${issues.join("\n ")}`,
|
|
410
|
+
{ details: { issues } }
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
config: toAppConfig(parsed.data),
|
|
415
|
+
sources: {
|
|
416
|
+
...projectFile !== void 0 ? { projectFile } : {},
|
|
417
|
+
...userFile !== void 0 ? { userFile } : {},
|
|
418
|
+
profile,
|
|
419
|
+
envOverrides: withEnv.applied,
|
|
420
|
+
defaults: withDefaults.applied
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
function readConfigDocument(path2, optionsEnv) {
|
|
425
|
+
const raw = readFileSync(path2, "utf8");
|
|
289
426
|
const secretFindings = scanForInlineSecrets(raw);
|
|
290
427
|
if (secretFindings.length > 0) {
|
|
291
|
-
throw new ConfigError("CONFIG_INVALID", describeSecretFindings(
|
|
428
|
+
throw new ConfigError("CONFIG_INVALID", describeSecretFindings(path2, secretFindings));
|
|
292
429
|
}
|
|
293
|
-
const expanded = expandEnvRefs(raw,
|
|
294
|
-
let data;
|
|
430
|
+
const expanded = expandEnvRefs(raw, optionsEnv, path2);
|
|
295
431
|
try {
|
|
296
|
-
|
|
432
|
+
return parseYaml(expanded);
|
|
297
433
|
} catch (error) {
|
|
298
|
-
throw new ConfigError("CONFIG_INVALID", `Failed to parse ${
|
|
434
|
+
throw new ConfigError("CONFIG_INVALID", `Failed to parse ${path2}.`, { cause: error });
|
|
299
435
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
436
|
+
}
|
|
437
|
+
function loadConfig(options = {}) {
|
|
438
|
+
return loadConfigDetailed(options).config;
|
|
439
|
+
}
|
|
440
|
+
function configDiagnostics(config) {
|
|
441
|
+
const notes = [];
|
|
442
|
+
for (const provider of config.project.providers) {
|
|
443
|
+
if (!provider.apiKeyEnvVar && provider.baseUrl.startsWith("https://")) {
|
|
444
|
+
notes.push(
|
|
445
|
+
`Provider "${provider.name}": API key reference is missing \u2014 add api_key_env_var: <ENV_VAR> unless this endpoint is intentionally keyless.`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
for (const agent of config.project.agents) {
|
|
450
|
+
if (!agent.command && agent.integration !== "custom") {
|
|
451
|
+
notes.push(`Agent "${agent.name}": no command configured \u2014 the process adapter needs one.`);
|
|
452
|
+
}
|
|
453
|
+
if (agent.allowExternalCwd) {
|
|
454
|
+
notes.push(`Agent "${agent.name}": may run outside the project root (allow_external_cwd).`);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
for (const pipeline of config.project.pipelines) {
|
|
458
|
+
const ids = new Set(pipeline.steps.map((s) => s.id));
|
|
459
|
+
for (const step of pipeline.steps) {
|
|
460
|
+
for (const dep of step.dependsOn ?? []) {
|
|
461
|
+
if (!ids.has(dep)) {
|
|
462
|
+
notes.push(`Pipeline "${pipeline.id}": step "${step.id}" depends on unknown step "${dep}".`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
309
466
|
}
|
|
310
|
-
return
|
|
467
|
+
return notes;
|
|
311
468
|
}
|
|
312
469
|
function toAppConfig(yaml) {
|
|
313
470
|
return {
|
|
@@ -1942,15 +2099,15 @@ async function writeFileAtomic(target, contents, durability = "rename") {
|
|
|
1942
2099
|
}
|
|
1943
2100
|
}
|
|
1944
2101
|
}
|
|
1945
|
-
async function inspectDocument(
|
|
2102
|
+
async function inspectDocument(path2) {
|
|
1946
2103
|
let raw;
|
|
1947
2104
|
try {
|
|
1948
|
-
await stat(
|
|
2105
|
+
await stat(path2);
|
|
1949
2106
|
} catch {
|
|
1950
2107
|
return { status: "missing" };
|
|
1951
2108
|
}
|
|
1952
2109
|
try {
|
|
1953
|
-
raw = await readFile(
|
|
2110
|
+
raw = await readFile(path2, "utf8");
|
|
1954
2111
|
} catch (error) {
|
|
1955
2112
|
return { status: "corrupt", detail: `unreadable: ${error instanceof Error ? error.message : String(error)}` };
|
|
1956
2113
|
}
|
|
@@ -1970,21 +2127,21 @@ async function inspectDocument(path) {
|
|
|
1970
2127
|
if (version < SCHEMA_VERSION) return { status: "v1-legacy" };
|
|
1971
2128
|
return { status: "current", schemaVersion: version, count: doc.items.length };
|
|
1972
2129
|
}
|
|
1973
|
-
async function readDocument(
|
|
1974
|
-
const state = await inspectDocument(
|
|
2130
|
+
async function readDocument(path2, onCorrupt, quarantine = true) {
|
|
2131
|
+
const state = await inspectDocument(path2);
|
|
1975
2132
|
if (state.status === "missing" || state.status === "empty") return [];
|
|
1976
2133
|
if (state.status === "future") {
|
|
1977
2134
|
const error = new Error(
|
|
1978
|
-
`${
|
|
2135
|
+
`${path2} was written by a newer OmniNode (schema v${state.schemaVersion} > v${SCHEMA_VERSION})`
|
|
1979
2136
|
);
|
|
1980
|
-
onCorrupt?.(
|
|
2137
|
+
onCorrupt?.(path2, error);
|
|
1981
2138
|
return [];
|
|
1982
2139
|
}
|
|
1983
2140
|
let raw;
|
|
1984
2141
|
try {
|
|
1985
|
-
raw = await readFile(
|
|
2142
|
+
raw = await readFile(path2, "utf8");
|
|
1986
2143
|
} catch (error) {
|
|
1987
|
-
onCorrupt?.(
|
|
2144
|
+
onCorrupt?.(path2, error);
|
|
1988
2145
|
return [];
|
|
1989
2146
|
}
|
|
1990
2147
|
try {
|
|
@@ -1993,16 +2150,16 @@ async function readDocument(path, onCorrupt, quarantine = true) {
|
|
|
1993
2150
|
return parsed.items ?? [];
|
|
1994
2151
|
} catch (error) {
|
|
1995
2152
|
if (quarantine) {
|
|
1996
|
-
const quarantinePath = `${
|
|
2153
|
+
const quarantinePath = `${path2}.corrupt-${Date.now()}`;
|
|
1997
2154
|
try {
|
|
1998
|
-
await rename(
|
|
2155
|
+
await rename(path2, quarantinePath);
|
|
1999
2156
|
logger.child({ component: "persistence" }).warn(
|
|
2000
|
-
`Quarantined unreadable store file ${
|
|
2157
|
+
`Quarantined unreadable store file ${path2} \u2192 ${quarantinePath}`
|
|
2001
2158
|
);
|
|
2002
2159
|
} catch {
|
|
2003
2160
|
}
|
|
2004
2161
|
}
|
|
2005
|
-
onCorrupt?.(
|
|
2162
|
+
onCorrupt?.(path2, error);
|
|
2006
2163
|
return [];
|
|
2007
2164
|
}
|
|
2008
2165
|
}
|
|
@@ -4208,8 +4365,8 @@ var STORE_FILES = [
|
|
|
4208
4365
|
async function migrateProjectStores(directory = `${process.cwd()}/.omninode`, options = {}) {
|
|
4209
4366
|
const reports = [];
|
|
4210
4367
|
for (const file of STORE_FILES) {
|
|
4211
|
-
const
|
|
4212
|
-
const state = await inspectDocument(
|
|
4368
|
+
const path2 = `${directory}/${file}`;
|
|
4369
|
+
const state = await inspectDocument(path2);
|
|
4213
4370
|
if (state.status === "missing") {
|
|
4214
4371
|
reports.push({ file, state: state.status, migrated: false });
|
|
4215
4372
|
continue;
|
|
@@ -4231,9 +4388,9 @@ async function migrateProjectStores(directory = `${process.cwd()}/.omninode`, op
|
|
|
4231
4388
|
reports.push({ file, state: state.status, migrated: false, note: state.detail });
|
|
4232
4389
|
continue;
|
|
4233
4390
|
}
|
|
4234
|
-
const items = await readDocument(
|
|
4391
|
+
const items = await readDocument(path2, void 0, false);
|
|
4235
4392
|
if (!options.checkOnly) {
|
|
4236
|
-
await writeFileAtomic(
|
|
4393
|
+
await writeFileAtomic(path2, `${JSON.stringify({ schemaVersion: SCHEMA_VERSION, items }, null, 2)}
|
|
4237
4394
|
`);
|
|
4238
4395
|
}
|
|
4239
4396
|
const beforeCount = items.length;
|
|
@@ -4250,7 +4407,7 @@ async function migrateProjectStores(directory = `${process.cwd()}/.omninode`, op
|
|
|
4250
4407
|
}
|
|
4251
4408
|
|
|
4252
4409
|
// src/version.ts
|
|
4253
|
-
var OMNINODE_VERSION = "2.0.0-alpha.
|
|
4410
|
+
var OMNINODE_VERSION = "2.0.0-alpha.16";
|
|
4254
4411
|
export {
|
|
4255
4412
|
AgentAdapterRegistry,
|
|
4256
4413
|
AgentError,
|
|
@@ -4265,6 +4422,7 @@ export {
|
|
|
4265
4422
|
FileTaskStore,
|
|
4266
4423
|
HeuristicPlanner,
|
|
4267
4424
|
JsonFileStore,
|
|
4425
|
+
KNOWN_PROFILES,
|
|
4268
4426
|
LocalMemoryProvider,
|
|
4269
4427
|
Logger,
|
|
4270
4428
|
MAX_CONTEXT_CHARS,
|
|
@@ -4302,6 +4460,8 @@ export {
|
|
|
4302
4460
|
agentConfigSchema,
|
|
4303
4461
|
aggregateReports,
|
|
4304
4462
|
appConfigSchema,
|
|
4463
|
+
applyDefaults,
|
|
4464
|
+
applyEnvOverrides,
|
|
4305
4465
|
authHeaders,
|
|
4306
4466
|
buildAgentRegistry,
|
|
4307
4467
|
buildChildEnv,
|
|
@@ -4312,6 +4472,7 @@ export {
|
|
|
4312
4472
|
buildPlannerContext,
|
|
4313
4473
|
buildRoleRegistry,
|
|
4314
4474
|
composeTaskText,
|
|
4475
|
+
configDiagnostics,
|
|
4315
4476
|
configureLogger,
|
|
4316
4477
|
createAgent,
|
|
4317
4478
|
createDefaultChatFn,
|
|
@@ -4342,7 +4503,9 @@ export {
|
|
|
4342
4503
|
killTree,
|
|
4343
4504
|
kindFromStatus,
|
|
4344
4505
|
loadConfig,
|
|
4506
|
+
loadConfigDetailed,
|
|
4345
4507
|
logger,
|
|
4508
|
+
mergeConfig,
|
|
4346
4509
|
migrateProjectStores,
|
|
4347
4510
|
newMessageId,
|
|
4348
4511
|
normalizeEvidence,
|
|
@@ -4364,10 +4527,12 @@ export {
|
|
|
4364
4527
|
requireCompletion,
|
|
4365
4528
|
resolveApiKey,
|
|
4366
4529
|
resolveEnvPolicy,
|
|
4530
|
+
resolveProfile,
|
|
4367
4531
|
roleConfigSchema,
|
|
4368
4532
|
sanitizeChunk,
|
|
4369
4533
|
scanForInlineSecrets,
|
|
4370
4534
|
similar,
|
|
4535
|
+
userConfigPath,
|
|
4371
4536
|
validateEnvelope,
|
|
4372
4537
|
validatePlan,
|
|
4373
4538
|
validateReport,
|