@node-in-layers/core-knowledge-mcp 1.12.8 → 1.13.0

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.
@@ -59,7 +59,7 @@
59
59
  "id": "21229efb-9d95-48b1-8ce7-0922837c9919",
60
60
  "name": "features.ts — Features Layer",
61
61
  "description": "This file defines the features layer for the domain. Features integrate services and implement business logic. They are always implemented as a closure factory and should never connect to external resources directly.\n",
62
- "content": "```\n### 1.3. `features.ts` — Features Layer\n\n**Description:**\nThis file defines the features layer for the domain. Features integrate services and implement business logic. They are always implemented as a closure factory and should never connect to external resources directly.\n\n> **Key Standards/AI Callouts:**\n>\n> - Always use the context logger for all logging; pass `crossLayerProps` for traceability.\n> - Use `error` for critical failures, `debug` for internal feature logic.\n> - Features should only call services, never connect to external resources directly.\n> - Return pure data structures—never mutate context or state.\n\n```typescript\nimport { randomUUID } from 'node:crypto'\nimport {\n Config,\n CrossLayerProps,\n FeaturesContext,\n} from '@node-in-layers/core/index.js'\nimport {\n CodingServicesLayer,\n CodingFeaturesLayer,\n CodingFeatures,\n CodingKnowledgeLibraries,\n} from './types.js'\n\nexport const create = (\n // NOTE: We are going to use the coding services object, so we need to add the layer here to the context which is specific to features.\n context: FeaturesContext<Config, CodingServicesLayer>\n): CodingFeatures => {\n const _availableLibraries = [CodingKnowledgeLibraries.nodeInLayers]\n\n const listAvailableCodeKnowledgeBases = async (\n crossLayerProps?: CrossLayerProps\n ) => {\n return Promise.resolve(_availableLibraries)\n }\n\n // AI: All of these inputs are automatically logged when this function is executed.\n const getCodeLibraryKnowledgeBase = async (\n codingLibrary: CodingKnowledgeLibraries,\n tags?: readonly string[],\n crossLayerProps?: CrossLayerProps\n ) => {\n const log = context.log.getInnerLogger(\n 'getCodeLibraryKnowledgeBase',\n crossLayerProps\n )\n if (_availableLibraries.includes(codingLibrary) === false) {\n // AI: If you have an error that ends execution, use error.\n log.error(`Coding library ${codingLibrary} not found`)\n throw new Error(`Coding library ${codingLibrary} not found`)\n }\n\n // AI: Inside of features, use debug for logging.\n // AI: Btw this log message is not needed. Its just for show.\n log.debug('Reading code library', { codingLibrary })\n // AI: ALWAYS pass the crossLayerProps to other features/services or any other layer call.\n const content = await context.services.coding.readCodeDescriptionFile(\n codingLibrary,\n crossLayerProps\n )\n return [\n {\n id: randomUUID(),\n library: codingLibrary,\n title: `Code Library: ${codingLibrary} details`,\n details: content,\n tags: ['typescript', 'nodejs', codingLibrary, 'how-to', 'examples'],\n lastModified: new Date(),\n createdAt: new Date(),\n },\n ]\n }\n\n return {\n listAvailableCodeKnowledgeBases,\n getCodeLibraryKnowledgeBase,\n }\n}\n```\n\n```\n",
62
+ "content": "```\n### 1.3. `features.ts` — Features Layer\n\n**Description:**\nThis file defines the features layer for the domain. Features integrate services and implement business logic. They are always implemented as a closure factory and should never connect to external resources directly.\n\n> **Key Standards/AI Callouts:**\n>\n> - Always use the context logger for all logging; pass `crossLayerProps` for traceability.\n> - Use `error` for critical failures, `debug` for internal feature logic.\n> - Features should only call services, never connect to external resources directly.\n> - Return pure data structures—never mutate context or state.\n\n```typescript\nimport { randomUUID } from 'node:crypto'\nimport {\n Config,\n CrossLayerProps,\n FeaturesContext,\n} from '@node-in-layers/core'\nimport {\n CodingServicesLayer,\n CodingFeaturesLayer,\n CodingFeatures,\n CodingKnowledgeLibraries,\n} from './types.js'\n\nexport const create = (\n // NOTE: We are going to use the coding services object, so we need to add the layer here to the context which is specific to features.\n context: FeaturesContext<Config, CodingServicesLayer>\n): CodingFeatures => {\n const _availableLibraries = [CodingKnowledgeLibraries.nodeInLayers]\n\n const listAvailableCodeKnowledgeBases = async (\n crossLayerProps?: CrossLayerProps\n ) => {\n return Promise.resolve(_availableLibraries)\n }\n\n // AI: All of these inputs are automatically logged when this function is executed.\n const getCodeLibraryKnowledgeBase = async (\n codingLibrary: CodingKnowledgeLibraries,\n tags?: readonly string[],\n crossLayerProps?: CrossLayerProps\n ) => {\n const log = context.log.getInnerLogger(\n 'getCodeLibraryKnowledgeBase',\n crossLayerProps\n )\n if (_availableLibraries.includes(codingLibrary) === false) {\n // AI: If you have an error that ends execution, use error.\n log.error(`Coding library ${codingLibrary} not found`)\n throw new Error(`Coding library ${codingLibrary} not found`)\n }\n\n // AI: Inside of features, use debug for logging.\n // AI: Btw this log message is not needed. Its just for show.\n log.debug('Reading code library', { codingLibrary })\n // AI: ALWAYS pass the crossLayerProps to other features/services or any other layer call.\n const content = await context.services.coding.readCodeDescriptionFile(\n codingLibrary,\n crossLayerProps\n )\n return [\n {\n id: randomUUID(),\n library: codingLibrary,\n title: `Code Library: ${codingLibrary} details`,\n details: content,\n tags: ['typescript', 'nodejs', codingLibrary, 'how-to', 'examples'],\n lastModified: new Date(),\n createdAt: new Date(),\n },\n ]\n }\n\n return {\n listAvailableCodeKnowledgeBases,\n getCodeLibraryKnowledgeBase,\n }\n}\n```\n\n```\n",
63
63
  "tags": [
64
64
  "features",
65
65
  "typescript",
@@ -97,7 +97,7 @@
97
97
  "id": "9707d819-ac03-4f82-87a7-0750d95a1530",
98
98
  "name": "Minimal Real-World config.base.mts Example",
99
99
  "description": "This entry provides a real, production-ready minimal configuration example for Node In Layers systems. Use this as your starting point for any Node In Layers system. It demonstrates how to organize domains, layers, logging, databases, and environment-safe configuration.\n",
100
- "content": "\n### 2.1. Minimal (Real-World) `config.base.mts` Example\n\nThis is a real, production-ready minimal config. Use this as your starting point for any Node In Layers system.\n\n```typescript\n// AI:\nimport { CoreNamespace, LogFormat } from '@node-in-layers/core/index.js'\n// AI: We should only use this if we are dealing with a backend system.\nimport { DataNamespace } from '@node-in-layers/data/index.js'\n// AI: We should only use RestApi if we have an express server.\nimport { RestApiNamespace } from '@node-in-layers/rest-api/index.js'\n\nimport { createCustomLogger } from '@deep-helix/backend-sdk'\nimport { SystemConfig } from './src/types'\nimport { LogLevelNames } from '@node-in-layers/core'\nimport { SimpleServerConfig } from '@l4t/mcp-ai'\n\nconst core = {\n // AI: The domains are loaded here in order from top to bottom.\n apps: await Promise.all([\n // AI: Only need if we use data.\n import(`@node-in-layers/data/index.js`),\n import(`@node-in-layers/rest-api/express/index.js`),\n // AI: We created some helpful logging functionalities.\n import(`@deep-helix/backend-sdk/dist/logging/index.js`),\n // AI: This is just an example app\n import(`./dist/coding/index.js`),\n import(`./dist/mcp-server/index.js`),\n // AI: This is just an example app for an api express server.\n import(`./dist/api/index.js`),\n ]),\n // AI: The layers are loaded from left to right, except when its an array. That is a composite layer.\n layerOrder: ['services', 'features', ['entries', 'express']],\n logging: {\n logLevel: LogLevelNames.trace,\n logFormat: LogFormat.json,\n customLogger: createCustomLogger(),\n },\n // AI: This sets the default model factory for database backends..\n modelFactory: '@node-in-layers/data',\n // AI: This should probably always be true. It automatically creates CRUD operations for all models.\n modelCruds: true,\n // AI: This is an example of creating multi-database systems, where for this situation the logging app uses a different database than the main app, note \"logDatabase\"\n customModelFactory: {\n // AI: Domain\n ['logging']: {\n // AI: The model's name: ['namespace', 'databaseNameListedBelow']\n LogMessages: ['@node-in-layers/data', 'logDatabase'],\n },\n },\n}\n\n// AI: This is for @node-in-layers/data.\nconst data = {\n databases: {\n default: {\n datastoreType: 'memory', // AI: mongo, postgres, etc.\n },\n // AI: Multi-database configuration\n logDatabase: {\n datastoreType: 'memory',\n },\n },\n}\n\nconst logging = {\n colorized: false,\n databaseLogging: false,\n consoleLogging: true,\n}\n\nconst express = {\n port: 3000,\n urlPrefix: '/api/v1/',\n logging: {\n requestLogLevel: LogLevelNames.info,\n responseLogLevel: LogLevelNames.info,\n },\n jsonBodySizeLimitInMb: 10,\n encodedBodySizeLimitInMb: 10,\n}\n\nconst mcpServer: Omit<SimpleServerConfig, 'tools'> = {\n name: 'my-mcp-server',\n version: '1.0.0',\n server: {\n connection: {\n type: 'cli',\n },\n },\n}\n\n// AI: Actually create the config as a default exported function\nexport default (): SystemConfig => ({\n // AI: Override this.\n environment: 'base',\n // AI: The name of our system.\n systemName: 'praxis-sphere/backend',\n [CoreNamespace.root]: core,\n [DataNamespace.root]: data,\n [RestApiNamespace.express]: express,\n logging,\n mcpServer,\n})\n```\n\n**AI CALLOUT:** Real systems require detailed config for logging, databases, APIs, and more. Use this as your reference for production-grade systems. Always keep config organized, DRY, and environment-safe.\n",
100
+ "content": "\n### 2.1. Minimal (Real-World) `config.base.mts` Example\n\nThis is a real, production-ready minimal config. Use this as your starting point for any Node In Layers system.\n\n```typescript\n// AI:\nimport { CoreNamespace, LogFormat } from '@node-in-layers/core'\n// AI: We should only use this if we are dealing with a backend system.\nimport { DataNamespace } from '@node-in-layers/data/index.js'\n// AI: We should only use RestApi if we have an express server.\nimport { RestApiNamespace } from '@node-in-layers/rest-api/index.js'\n\nimport { createCustomLogger } from '@deep-helix/backend-sdk'\nimport { SystemConfig } from './src/types'\nimport { LogLevelNames } from '@node-in-layers/core'\nimport { SimpleServerConfig } from '@l4t/mcp-ai'\n\nconst core = {\n // AI: The domains are loaded here in order from top to bottom.\n apps: await Promise.all([\n // AI: Only need if we use data.\n import(`@node-in-layers/data/index.js`),\n import(`@node-in-layers/rest-api/express/index.js`),\n // AI: We created some helpful logging functionalities.\n import(`@deep-helix/backend-sdk/dist/logging/index.js`),\n // AI: This is just an example app\n import(`./dist/coding/index.js`),\n import(`./dist/mcp-server/index.js`),\n // AI: This is just an example app for an api express server.\n import(`./dist/api/index.js`),\n ]),\n // AI: The layers are loaded from left to right, except when its an array. That is a composite layer.\n layerOrder: ['services', 'features', ['entries', 'express']],\n logging: {\n logLevel: LogLevelNames.trace,\n logFormat: LogFormat.json,\n customLogger: createCustomLogger(),\n },\n // AI: This sets the default model factory for database backends..\n modelFactory: '@node-in-layers/data',\n // AI: This should probably always be true. It automatically creates CRUD operations for all models.\n modelCruds: true,\n // AI: This is an example of creating multi-database systems, where for this situation the logging app uses a different database than the main app, note \"logDatabase\"\n customModelFactory: {\n // AI: Domain\n ['logging']: {\n // AI: The model's name: ['namespace', 'databaseNameListedBelow']\n LogMessages: ['@node-in-layers/data', 'logDatabase'],\n },\n },\n}\n\n// AI: This is for @node-in-layers/data.\nconst data = {\n databases: {\n default: {\n datastoreType: 'memory', // AI: mongo, postgres, etc.\n },\n // AI: Multi-database configuration\n logDatabase: {\n datastoreType: 'memory',\n },\n },\n}\n\nconst logging = {\n colorized: false,\n databaseLogging: false,\n consoleLogging: true,\n}\n\nconst express = {\n port: 3000,\n urlPrefix: '/api/v1/',\n logging: {\n requestLogLevel: LogLevelNames.info,\n responseLogLevel: LogLevelNames.info,\n },\n jsonBodySizeLimitInMb: 10,\n encodedBodySizeLimitInMb: 10,\n}\n\nconst mcpServer: Omit<SimpleServerConfig, 'tools'> = {\n name: 'my-mcp-server',\n version: '1.0.0',\n server: {\n connection: {\n type: 'cli',\n },\n },\n}\n\n// AI: Actually create the config as a default exported function\nexport default (): SystemConfig => ({\n // AI: Override this.\n environment: 'base',\n // AI: The name of our system.\n systemName: 'praxis-sphere/backend',\n [CoreNamespace.root]: core,\n [DataNamespace.root]: data,\n [RestApiNamespace.express]: express,\n logging,\n mcpServer,\n})\n```\n\n**AI CALLOUT:** Real systems require detailed config for logging, databases, APIs, and more. Use this as your reference for production-grade systems. Always keep config organized, DRY, and environment-safe.\n",
101
101
  "tags": [
102
102
  "config",
103
103
  "base",
@@ -119,8 +119,8 @@
119
119
  {
120
120
  "id": "e1c6daad-2e78-48ab-a98a-adc8318cd293",
121
121
  "name": "Using loadSystem with Real Config",
122
- "description": "This entry explains how to bootstrap a Node In Layers system using the `loadSystem` function and a real config. Always call the config as a function (e.g., `config()`). Never manually wire up layers or context. `loadSystem` ensures everything is loaded in the correct order, with full traceability and logging.\n",
123
- "content": "### 3.1. Using `loadSystem` with Real Config\n\nTo bootstrap your Node In Layers system, use the `loadSystem` function from `@node-in-layers/core`. This will automatically load all domains, services, features, and configure logging and context, using the real config structure above.\n\n```typescript\n// src/main.ts\nimport config from '../config.base.mts'\nimport { loadSystem } from '@node-in-layers/core'\n\nconst system = await loadSystem({ config: config() })\n```\n\n> **AI CALLOUT:** Always call the config as a function (e.g., `config()`). Never manually wire up layers or context. `loadSystem` ensures everything is loaded in the correct order, with full traceability and logging.\n",
122
+ "description": "Advanced usage: shows how to bootstrap a Node In Layers system using the `loadSystem` function with an explicit config object. This is only needed when you want to override the automatic config loading (e.g., tests, multiple environments at once, frontends). The normal approach is to pass only `environment` and let the framework load `config.<env>.mjs` for you.\n",
123
+ "content": "### 3.1. Using `loadSystem` with an Explicit Config (Advanced)\n\nMost of the time you should call `loadSystem` with **only** an `environment`, and let Node In Layers load your config files (e.g., `config.base.mjs`, `config.dev.mjs`) automatically.\n\nFor advanced scenarios—such as running two environments side by side, custom unit tests, or special frontend tooling—you can pass an explicit config object:\n\n```typescript\n// src/main.ts\nimport * as config from '../config.base.mjs'\nimport { loadSystem } from '@node-in-layers/core'\n\nconst system = await loadSystem({\n environment: 'prod',\n config: config.default(),\n})\n```\n\n> **AI CALLOUT:** Only pass a `config` object when you deliberately need to override automatic config loading (tests, multi-env, frontend, etc.). The normal approach is simply `await loadSystem({ environment: 'dev' })`.\n",
124
124
  "tags": [
125
125
  "system",
126
126
  "bootstrap",
@@ -144,7 +144,7 @@
144
144
  "id": "c366c193-223e-4a0e-9a72-6f4c4f1b9f94",
145
145
  "name": "Minimal CLI Entry Example",
146
146
  "description": "This entry provides a minimal, real-world example of a CLI entry file for Node In Layers systems. Entries are the only place you should handle CLI args, environment, or direct user interaction. Keep them thin—just grab args, call a feature, and log output. Never put business logic in entries. They should only handle input/output and call features. This keeps your system testable and maintainable. Always use `console.info` for meaningful outputs, and use the logger for internal details.\n",
147
- "content": "### Entry/Bin Minimal CLI Entry Example\n\nEntries are the only place you should handle CLI args, environment, or direct user interaction. Keep them thin—just grab args, call a feature, and log output. Here is a real example:\n\n```typescript\n// bin/coding.ts\n#!/usr/bin/env tsx\nimport { loadSystem } from '@node-in-layers/core'\nimport config from '../config.base.mts'\n\nconst main = async () => {\n const system = await loadSystem({ config: config() })\n // Example: Call a feature and print the result\n const result = await system.features.coding.getCodeLibraryKnowledgeBase('node-in-layers')\n console.info(JSON.stringify(result, null, 2))\n}\n\nmain()\n```\n\n> **AI CALLOUT:** Never put business logic in entries. They should only handle input/output and call features. This keeps your system testable and maintainable. Always use `console.info` for meaningful outputs, and use the logger for internal details.\n",
147
+ "content": "### Entry/Bin Minimal CLI Entry Example\n\nEntries are the only place you should handle CLI args, environment, or direct user interaction. Keep them thin—just grab args, call a feature, and log output. Here is a real example using the normal `environment`-only pattern:\n\n```typescript\n// bin/coding.ts\n#!/usr/bin/env tsx\nimport { loadSystem } from '@node-in-layers/core'\n\nconst main = async () => {\n const system = await loadSystem({\n environment: 'dev',\n })\n // Example: Call a feature and print the result\n const result = await system.features.coding.getCodeLibraryKnowledgeBase('node-in-layers')\n console.info(JSON.stringify(result, null, 2))\n}\n\nmain()\n```\n\n> **AI CALLOUT:** Never put business logic in entries. They should only handle input/output and call features. This keeps your system testable and maintainable. Always use `console.info` for meaningful outputs, and use the logger for internal details.\n",
148
148
  "tags": [
149
149
  "entries",
150
150
  "cli",
@@ -163,6 +163,31 @@
163
163
  "best-practices"
164
164
  ]
165
165
  },
166
+ {
167
+ "id": "otel-setup-config-base",
168
+ "name": "How to Enable OpenTelemetry in a Node In Layers System",
169
+ "description": "Step-by-step instructions for wiring OpenTelemetry into a Node In Layers system using only configuration. You bring the OTel SDK/exporters; Node In Layers forwards logs, spans, and metrics based on config. This is a concise version of the README's OpenTelemetry section.\n",
170
+ "content": "### Enabling OpenTelemetry via `config.base.mts`\n\nNode In Layers can forward logs, spans, and metrics to OpenTelemetry without you touching your domain code. You bring the OTel SDK and exporters; the framework forwards data based on `logging.otel` and `LogFormat.otel`.\n\n1. **Install OTel APIs (in your app)**\n\n```bash\nnpm install @opentelemetry/api @opentelemetry/api-logs\n```\n\nYou can use any OTel SDK/setup (NodeSDK, manual providers, auto-instrumentation, etc.) as long as global providers are registered.\n\n2. **Configure core logging with OTel enabled**\n\n```typescript\n// config.base.mts\nimport { CoreNamespace, LogFormat, LogLevelNames } from '@node-in-layers/core'\n\nexport default () => ({\n systemName: 'your-system-name',\n environment: 'base',\n [CoreNamespace.root]: {\n logging: {\n logLevel: LogLevelNames.info,\n // Send logs both to console (JSON) and to OpenTelemetry\n logFormat: [LogFormat.json, LogFormat.otel],\n // Optional: cap extra data size; large objects are truncated by default\n maxLogSizeInCharacters: 50_000,\n // Configure OpenTelemetry integration\n otel: {\n serviceName: 'your-system-name',\n version: '1.0.0',\n // Enable OTel logs (used by LogFormat.otel)\n logs: { enabled: true },\n // Optional: spans for wrapped layer functions\n trace: { enabled: true },\n // Optional: metrics for wrapped layer functions\n metrics: { enabled: true },\n },\n },\n layerOrder: ['services', 'features', 'entries'],\n apps: [], // your apps here\n },\n})\n```\n\n3. **Use `loadSystem` as normal (environment-only)**\n\n```typescript\nimport { loadSystem } from '@node-in-layers/core'\n\nconst system = await loadSystem({\n environment: 'prod',\n})\n```\n\nAs long as global OTel providers are registered in your process, Node In Layers will:\n\n- Forward framework logs to the OTel Logs API when `LogFormat.otel` is configured.\n- Emit spans and metrics for wrapped layer functions when `logging.otel.trace`/`logging.otel.metrics` are enabled.\n",
171
+ "tags": [
172
+ "config",
173
+ "otel",
174
+ "logging",
175
+ "best-practices"
176
+ ]
177
+ },
178
+ {
179
+ "id": "otel-optional-services-usage",
180
+ "name": "Optional OpenTelemetry Services in @node-in-layers/core",
181
+ "description": "Overview of the optional OpenTelemetry services made available by @node-in-layers/core (trace, metrics, logs, and runWithTraceAndMetrics), plus examples of calling them from a services or features layer using the correct context.services[CoreNamespace.otel] syntax.\n",
182
+ "content": "### Optional OpenTelemetry Services (Trace, Metrics, Logs)\n\nWhen `logging.otel` is configured, Node In Layers exposes an optional OTel services domain at `CoreNamespace.otel` (`'@node-in-layers/core/otel'`). You can use this from services or features for advanced tracing/metrics/logs in addition to the automatic wrapping the framework does.\n\n```typescript\nimport { CoreNamespace, FeaturesContext, Config } from '@node-in-layers/core'\n\nexport const create = (context: FeaturesContext<Config, any, any>) => {\n const runImportantStep = async () => {\n const otel = context.services[CoreNamespace.otel]\n\n // --- Traces ---\n const span = otel.trace.startSpan('important-step', {\n attributes: { component: 'my-domain', feature: 'runImportantStep' },\n })\n\n try {\n // Do your work here\n const activeSpan = otel.trace.getActiveSpan()\n if (activeSpan) {\n activeSpan.setAttribute('hasActiveSpan', true)\n }\n } finally {\n span.end()\n }\n }\n\n return { runImportantStep }\n}\n```\n\nYou can also use metrics helpers for custom timers and counters:\n\n```typescript\nimport { CoreNamespace, ServicesContext, Config } from '@node-in-layers/core'\n\nexport const create = (context: ServicesContext<Config>) => {\n const recordBackgroundJobDuration = (durationMs: number) => {\n const otel = context.services[CoreNamespace.otel]\n otel.metrics.recordDuration('background.job.duration', durationMs, {\n component: 'jobs',\n jobType: 'my-job',\n })\n otel.metrics.incrementCounter('background.job.completed', 1, {\n component: 'jobs',\n jobType: 'my-job',\n })\n }\n\n const requestHistogram = context.services[CoreNamespace.otel].metrics.createHistogram(\n 'http.request.duration',\n { unit: 'ms' },\n )\n\n const countRequests = context.services[CoreNamespace.otel].metrics.createCounter(\n 'http.request.count',\n )\n\n const trackHttpRequest = (durationMs: number, path: string) => {\n requestHistogram.record(durationMs, { path })\n countRequests.add(1, { path })\n }\n\n const emitStructuredLog = () => {\n const otel = context.services[CoreNamespace.otel]\n otel.logs.emit({\n body: 'Important business event',\n attributes: { component: 'my-domain', event: 'business-event' },\n })\n }\n\n const logLargePayloadExample = async () => {\n const log = context.log.getInnerLogger('logLargePayloadExample')\n const bigPayload = { /* huge object here */ }\n\n // This will be truncated according to maxLogSizeInCharacters\n await log.info('Large payload (truncated)', { bigPayload })\n\n // If you really want to log a giant object that would normally be truncated, do this:\n await log.info('Large payload (full)', { bigPayload }, { ignoreSizeLimit: true })\n }\n\n return {\n recordBackgroundJobDuration,\n trackHttpRequest,\n emitStructuredLog,\n logLargePayloadExample,\n }\n}\n```\n\n> **AI CALLOUT:** OpenTelemetry integration is entirely optional and driven by config. If `logging.otel` is not set, `CoreNamespace.otel` services will effectively no-op. Use these helpers when you need explicit spans/metrics/logs in addition to the framework's automatic wrapping.\n",
183
+ "tags": [
184
+ "otel",
185
+ "services",
186
+ "logging",
187
+ "metrics",
188
+ "tracing"
189
+ ]
190
+ },
166
191
  {
167
192
  "id": "15b68d0d-9f62-420c-97a4-c7a1ca4c1b7b",
168
193
  "name": "Deep Dives and AI Callouts",
@@ -178,8 +203,8 @@
178
203
  {
179
204
  "id": "9e2cd198-cf32-45d3-8bb9-b9773cf4e452",
180
205
  "name": "All Exported Types in @node-in-layers/core",
181
- "description": "All types exported from @node-in-layers/core, grouped by purpose. Minimal comments, full TypeScript code for reference.\n",
182
- "content": "```typescript\n// --- Config and Core ---\ntype Config = Readonly<{\n systemName: string\n environment: string\n [CoreNamespace.root]: CoreConfig\n}>\ntype CoreConfig = Readonly<{\n logging: {\n logLevel: LogLevelNames\n logFormat: LogFormat | readonly LogFormat[]\n tcpLoggingOptions?: Readonly<{\n url: string\n headers?: Record<string, string | object>\n }>\n customLogger?: RootLogger\n getFunctionWrapLogLevel?: (\n layerName: string,\n functionName?: string\n ) => LogLevelNames\n ignoreLayerFunctions?: Record<\n string,\n Record<string, Record<string, boolean> | boolean>\n >\n }\n layerOrder: readonly LayerDescription[]\n apps: readonly App[]\n modelFactory?: string\n modelCruds?: boolean\n customModelFactory?: NamespaceToFactory\n}>\nenum CoreNamespace {\n root = '@node-in-layers/core',\n globals = '@node-in-layers/core/globals',\n layers = '@node-in-layers/core/layers',\n models = '@node-in-layers/core/models',\n}\ntype App = Readonly<{\n name: string\n services?: AppLayer<Config, any>\n features?: AppLayer<Config, any>\n globals?: GlobalsLayer<Config, any>\n models?: Record<string, ModelConstructor>\n}>\ntype AppLayer<\n TConfig extends Config = Config,\n TContext extends object = object,\n> = Readonly<{\n create: (context: LayerContext<TConfig, TContext>) => MaybePromise<TLayer>\n}>\ntype LayerContext<\n TConfig extends Config = Config,\n TContext extends object = object,\n> = CommonContext<TConfig> & TContext & { log: LayerLogger }\ntype CommonContext<TConfig extends Config = Config> = Readonly<{\n config: TConfig\n rootLogger: RootLogger\n constants: {\n environment: string\n workingDirectory: string\n runtimeId: string\n }\n}>\n\n// --- Logging ---\nenum LogLevel {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n SILENT = 5,\n}\nenum LogLevelNames {\n trace = 'trace',\n debug = 'debug',\n info = 'info',\n warn = 'warn',\n error = 'error',\n silent = 'silent',\n}\nenum LogFormat {\n json = 'json',\n custom = 'custom',\n simple = 'simple',\n tcp = 'tcp',\n full = 'full',\n}\ntype Logger = Readonly<{\n trace: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject\n ) => MaybePromise<void>\n debug: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject\n ) => MaybePromise<void>\n info: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject\n ) => MaybePromise<void>\n warn: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject\n ) => MaybePromise<void>\n error: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject\n ) => MaybePromise<void>\n applyData: (data: Record<string, JsonAble>) => Logger\n getIdLogger: (name: string, logIdorKey: LogId | string, id?: string) => Logger\n getSubLogger: (name: string) => Logger\n getIds: () => readonly LogId[]\n}>\ntype LayerLogger = Logger &\n Readonly<{\n _logWrap: <T, A extends Array<any>>(\n functionName: string,\n func: LogWrapAsync<T, A> | LogWrapSync<T, A>\n ) => (...a: A) => Promise<T> | T\n _logWrapAsync: <T, A extends Array<any>>(\n functionName: string,\n func: LogWrapAsync<T, A>\n ) => (...a: A) => Promise<T>\n _logWrapSync: <T, A extends Array<any>>(\n functionName: string,\n func: LogWrapSync<T, A>\n ) => (...a: A) => T\n getFunctionLogger: (\n name: string,\n crossLayerProps?: CrossLayerProps\n ) => FunctionLogger\n getInnerLogger: (\n functionName: string,\n crossLayerProps?: CrossLayerProps\n ) => FunctionLogger\n }>\ntype AppLogger = Logger &\n Readonly<{\n getLayerLogger: (\n layerName: CommonLayerName | string,\n crossLayerProps?: CrossLayerProps\n ) => LayerLogger\n }>\ntype RootLogger<TConfig extends Config = Config> = Readonly<{\n getLogger: (\n context: CommonContext<TConfig>,\n props?: { ids?: readonly LogId[]; data?: Record<string, any> }\n ) => HighLevelLogger\n}>\ntype HighLevelLogger = Logger & Readonly<{ getAppLogger: GetAppLogger }>\ntype GetAppLogger = (appName: string) => AppLogger\ntype LogId = Readonly<Record<string, string>>\ntype LogMessage<T extends Record<string, JsonAble> = Record<string, JsonAble>> =\n Readonly<{\n id: string\n logger: string\n environment: string\n ids?: readonly LogId[]\n logLevel: LogLevelNames\n datetime: Date\n message: string\n }> &\n Partial<ErrorObject> &\n T\ntype LogFunction = (logMessage: LogMessage) => void | Promise<void>\ntype LogMethod<TConfig extends Config = Config> = (\n context: CommonContext<TConfig>\n) => LogFunction\nenum CommonLayerName {\n models = 'models',\n services = 'services',\n features = 'features',\n entries = 'entries',\n}\n\n// --- Layers and Cross-Layer ---\ntype CrossLayerProps<T extends object = object> = Readonly<{\n logging?: { ids?: readonly LogId[] }\n}> &\n T\ntype LayerFunction<T extends (...args: any[]) => any> = T extends (\n ...args: infer Args\n) => infer ReturnType\n ? (...args: [...Args, crossLayerProps?: CrossLayerProps]) => ReturnType\n : never\ntype TypedFunction<T, A extends Array<any>> = (...args: A) => T\ntype TypedFunctionAsync<T, A extends Array<any>> = (...args: A) => Promise<T>\ntype LogWrapSync<T, A extends Array<any>> = (\n functionLogger: FunctionLogger,\n ...args: A\n) => T\ntype LogWrapAsync<T, A extends Array<any>> = (\n functionLogger: FunctionLogger,\n ...args: A\n) => Promise<T>\ntype FunctionLogger = Logger\ntype GlobalsLayer<\n TConfig extends Config = Config,\n TGlobals extends object = object,\n> = Readonly<{ create: (context: CommonContext<TConfig>) => Promise<TGlobals> }>\ntype ServicesContext<\n TConfig extends Config = Config,\n TServices extends object = object,\n TContext extends object = object,\n> = LayerContext<\n TConfig,\n {\n models: Record<\n string,\n {\n getModels: <TModelType extends ModelType<any>>() => Record<\n string,\n TModelType\n >\n }\n >\n services: TServices\n } & TContext\n>\ntype ServicesLayerFactory<\n TConfig extends Config = Config,\n TServices extends object = object,\n TContext extends object = object,\n TLayer extends object = object,\n> = Readonly<{\n create: (context: ServicesContext<TConfig, TServices, TContext>) => TLayer\n}>\ntype FeaturesContext<\n TConfig extends Config = Config,\n TServices extends object = object,\n TFeatures extends object = object,\n TGlobals extends object = object,\n> = LayerContext<\n TConfig,\n { services: TServices; features: TFeatures } & TGlobals\n>\ntype FeaturesLayerFactory<\n TConfig extends Config = Config,\n TContext extends object = object,\n TServices extends object = object,\n TFeatures extends object = object,\n TLayer extends object = object,\n> = Readonly<{\n create: (\n context: FeaturesContext<TConfig, TServices, TFeatures, TContext>\n ) => TLayer\n}>\ntype System<\n TConfig extends Config = Config,\n TServices extends object = object,\n TFeatures extends object = object,\n> = CommonContext<TConfig> & { services: TServices; features: TFeatures }\n\n// --- Models and CRUD ---\ntype ModelConstructor = Readonly<{\n create: <\n T extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n modelProps: ModelProps\n ) => ModelType<T, TModelExtensions, TModelInstanceExtensions>\n}>\ntype ModelProps<\n TModelOverrides extends object = object,\n TModelInstanceOverrides extends object = object,\n> = Readonly<{\n Model: ModelFactory<TModelOverrides, TModelOverrides>\n fetcher: ModelInstanceFetcher<TModelOverrides, TModelInstanceOverrides>\n getModel: <T extends DataDescription>(\n namespace: string,\n modelName: string\n ) => () => ModelType<T, TModelOverrides, TModelInstanceOverrides>\n}>\ntype PartialModelProps<\n TModelOverrides extends object = object,\n TModelInstanceOverrides extends object = object,\n> = Readonly<{\n Model: ModelFactory<TModelOverrides, TModelOverrides>\n fetcher: ModelInstanceFetcher<TModelOverrides, TModelInstanceOverrides>\n}>\ntype GetModelPropsFunc = (\n context: ServicesContext,\n ...args: any[]\n) => PartialModelProps\ntype GenericLayer = Record<string, any>\ntype LayerServices = Readonly<{\n getModelProps: (context: ServicesContext) => ModelProps\n loadLayer: (\n app: App,\n layer: string,\n existingLayers: LayerContext\n ) => MaybePromise<GenericLayer | undefined>\n}>\ntype LayerServicesLayer = {\n log: LayerLogger\n services: { [CoreNamespace.layers]: LayerServices }\n}\ntype LayerDescription = string | readonly string[]\ntype ModelToModelFactoryNamespace = Record<string, string | [string, any[]]>\ntype NamespaceToFactory = Record<string, ModelToModelFactoryNamespace>\n\n// --- Error and Utility ---\ntype ErrorObject = Readonly<{\n error: Readonly<{\n code: string\n message: string\n details?: string\n data?: Record<string, JsonAble>\n trace?: string\n cause?: ErrorObject\n }>\n}>\ntype MaybePromise<T> = Promise<T> | T\n\n// --- Model CRUDs (from models/types.ts) ---\ntype ModelCrudsFunctions<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n getModel: () => OrmModel<TData, TModelExtensions, TModelInstanceExtensions>\n create: CreateFunction<TData>\n retrieve: RetrieveFunction<TData>\n update: UpdateFunction<TData>\n delete: DeleteFunction\n search: SearchFunction<TData>\n}>\ntype ModelServices = Readonly<{\n createModelCruds: <TData extends DataDescription>(\n model: OrmModel<TData>,\n options?: CrudsOptions<TData>\n ) => ModelCrudsFunctions<TData>\n}>\ntype CreateFunction<TData extends DataDescription> = <\n IgnoreProperties extends string = '',\n>(\n data: Omit<TData, IgnoreProperties> | ToObjectResult<TData>\n) => Promise<OrmModelInstance<TData>>\ntype RetrieveFunction<TData extends DataDescription> = (\n primaryKey: PrimaryKeyType\n) => Promise<OrmModelInstance<TData> | undefined>\ntype UpdateFunction<TData extends DataDescription> = (\n primaryKey: PrimaryKeyType,\n data: TData | ToObjectResult<TData>\n) => Promise<OrmModelInstance<TData>>\ntype DeleteFunction = (primaryKey: PrimaryKeyType) => Promise<void>\ntype SearchFunction<TData extends DataDescription> = (\n ormSearch: OrmSearch\n) => Promise<OrmSearchResult<TData>>\ntype CrudsOverrides<TData extends DataDescription> = Partial<\n Omit<ModelCrudsFunctions<TData>, 'getModel'>\n>\ntype CrudsOptions<TData extends DataDescription> = Readonly<{\n overrides?: CrudsOverrides<TData>\n}>\ntype ModelCrudsServicesContext<\n TModels extends Record<string, ModelCrudsFunctions<any>>,\n TConfig extends Config = Config,\n TServices extends object = object,\n TContext extends object = object,\n> = ServicesContext<TConfig, TServices & { cruds: TModels }, TContext>\n```\n",
206
+ "description": "Key types exported from @node-in-layers/core, grouped by purpose. This is a curated subset focused on config, logging (including OpenTelemetry), layers, and model CRUDs.\n",
207
+ "content": "```typescript\n// --- Config and Core ---\nexport type Config = Readonly<{\n systemName: string\n environment: string\n [CoreNamespace.root]: CoreConfig\n}>\n\nexport type OtelExporterConfig = Readonly<{\n endpoint?: string\n headers?: Record<string, string>\n}>\n\nexport type OtelSignalConfig = Readonly<{\n enabled?: boolean\n exporter?: OtelExporterConfig\n}>\n\nexport type OtelConfig = Readonly<{\n serviceName?: string\n version?: string\n trace?: OtelSignalConfig\n logs?: OtelSignalConfig\n metrics?: OtelSignalConfig\n exporter?: OtelExporterConfig\n}>\n\nexport type CoreConfig = Readonly<{\n logging: {\n logLevel: LogLevelNames\n logFormat: XOR<LogFormat, readonly LogFormat[]>\n maxLogSizeInCharacters?: number\n tcpLoggingOptions?: Readonly<{\n url: string\n headers?: Record<string, string | object>\n }>\n customLogger?: RootLogger\n getFunctionWrapLogLevel?: (\n layerName: string,\n functionName?: string\n ) => LogLevelNames\n ignoreLayerFunctions?: Record<\n string,\n boolean | Record<string, Record<string, boolean> | boolean>\n >\n otel?: OtelConfig\n }\n layerOrder: readonly LayerDescription[]\n apps: readonly App[]\n modelFactory?: string\n modelCruds?: boolean\n customModelFactory?: NamespaceToFactory\n}>\n\nexport enum CoreNamespace {\n root = '@node-in-layers/core',\n globals = '@node-in-layers/core/globals',\n layers = '@node-in-layers/core/layers',\n models = '@node-in-layers/core/models',\n otel = '@node-in-layers/core/otel',\n}\n\nexport type App = Readonly<{\n name: string\n description?: string\n services?: AppLayer<Config, any>\n features?: AppLayer<Config, any>\n globals?: GlobalsLayer<Config, any>\n models?: Record<string, ModelConstructor>\n}>\n\nexport type AppLayer<\n TConfig extends Config = Config,\n TContext extends object = object,\n TLayer extends object = object,\n> = Readonly<{\n create: (context: LayerContext<TConfig, TContext>) => MaybePromise<TLayer>\n}>\n\nexport type LayerContext<\n TConfig extends Config = Config,\n TContext extends object = object,\n> = CommonContext<TConfig> &\n TContext & {\n log: LayerLogger\n }\n\nexport type CommonContext<TConfig extends Config = Config> = Readonly<{\n config: TConfig\n rootLogger: RootLogger\n constants: {\n environment: string\n workingDirectory: string\n runtimeId: string\n }\n}>\n\n// --- Logging ---\nexport enum LogLevel {\n TRACE = 0,\n DEBUG = 1,\n INFO = 2,\n WARN = 3,\n ERROR = 4,\n SILENT = 5,\n}\n\nexport enum LogLevelNames {\n trace = 'trace',\n debug = 'debug',\n info = 'info',\n warn = 'warn',\n error = 'error',\n silent = 'silent',\n}\n\nexport enum LogFormat {\n json = 'json',\n custom = 'custom',\n simple = 'simple',\n tcp = 'tcp',\n otel = 'otel',\n full = 'full',\n}\n\nexport type LogInstanceOptions = Readonly<{\n ignoreSizeLimit?: boolean\n}>\n\nexport type Logger = Readonly<{\n trace: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject,\n options?: LogInstanceOptions\n ) => MaybePromise<void>\n debug: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject,\n options?: LogInstanceOptions\n ) => MaybePromise<void>\n info: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject,\n options?: LogInstanceOptions\n ) => MaybePromise<void>\n warn: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject,\n options?: LogInstanceOptions\n ) => MaybePromise<void>\n error: (\n message: string,\n dataOrError?: Record<string, JsonAble | object> | ErrorObject,\n options?: LogInstanceOptions\n ) => MaybePromise<void>\n applyData: (data: Record<string, JsonAble>) => Logger\n getIdLogger: (name: string, logIdOrKey: LogId | string, id?: string) => Logger\n getSubLogger: (name: string) => Logger\n getIds: () => readonly LogId[]\n}>\n\nexport type LayerLogger = Logger &\n Readonly<{\n _logWrap: <T, A extends Array<any>>(\n functionName: string,\n func: LogWrapAsync<T, A> | LogWrapSync<T, A>\n ) => (...a: A) => Promise<T> | T\n _logWrapAsync: <T, A extends Array<any>>(\n functionName: string,\n func: LogWrapAsync<T, A>\n ) => (...a: A) => Promise<T>\n _logWrapSync: <T, A extends Array<any>>(\n functionName: string,\n func: LogWrapSync<T, A>\n ) => (...a: A) => T\n getFunctionLogger: (\n name: string,\n crossLayerProps?: CrossLayerProps\n ) => FunctionLogger\n getInnerLogger: (\n functionName: string,\n crossLayerProps?: CrossLayerProps\n ) => FunctionLogger\n }>\n\nexport type AppLogger = Logger &\n Readonly<{\n getLayerLogger: (\n layerName: CommonLayerName | string,\n crossLayerProps?: CrossLayerProps\n ) => LayerLogger\n }>\n\nexport type RootLogger<TConfig extends Config = Config> = Readonly<{\n getLogger: (\n context: CommonContext<TConfig>,\n props?: { ids?: readonly LogId[]; data?: Record<string, any> }\n ) => HighLevelLogger\n}>\n\nexport type LogId = Readonly<Record<string, string>>\n\nexport type LogMessage<\n T extends Record<string, JsonAble> = Record<string, JsonAble>,\n> = Readonly<{\n id: string\n logger: string\n environment: string\n ids?: readonly LogId[]\n logLevel: LogLevelNames\n datetime: Date\n message: string\n}> &\n Partial<ErrorObject> &\n T\n\nexport type LogFunction = (logMessage: LogMessage) => void | Promise<void>\n\nexport type LogMethod<TConfig extends Config = Config> = (\n context: CommonContext<TConfig>\n) => LogFunction\n\nexport enum CommonLayerName {\n models = 'models',\n services = 'services',\n features = 'features',\n entries = 'entries',\n}\n\n// --- Layers, Cross-Layer, and NIL Functions ---\nexport type CrossLayerProps<T extends object = object> = Readonly<{\n logging?: {\n ids?: readonly LogId[]\n }\n}> &\n T\n\nexport type LayerFunction<T extends (...args: any[]) => any> = T extends (\n ...args: infer Args\n) => infer ReturnType\n ? (...args: [...Args, crossLayerProps?: CrossLayerProps]) => ReturnType\n : never\n\nexport type ErrorObject = Readonly<{\n error: Readonly<{\n code: string\n message: string\n details?: string\n data?: Record<string, JsonAble>\n trace?: string\n cause?: ErrorObject\n }>\n}>\n\nexport type Response<R> = XOR<R, ErrorObject>\nexport type TrueMaybePromise<T> = XOR<Promise<T>, T>\n\nexport type NilFunctionReturn<TOutput> = [TOutput] extends [void]\n ? TrueMaybePromise<void>\n : TrueMaybePromise<Response<TOutput>>\n\nexport type NilFunction<\n TProps extends JsonObj,\n TOutput extends XOR<JsonObj, void>,\n> = (\n props: TProps,\n crossLayerProps?: CrossLayerProps\n) => NilFunctionReturn<TOutput>\n\nexport type NilAnnotatedFunction<\n TProps extends JsonObj,\n TOutput extends XOR<JsonObj, void>,\n> = NilFunction<TProps, TOutput> &\n Readonly<{\n functionName: string\n domain: string\n schema: z.ZodFunction<\n z.ZodTuple<[\n ZodType<TProps>,\n ZodType<CrossLayerProps | undefined>,\n ]>,\n ZodType<NilFunctionReturn<TOutput>>\n >\n }>\n\n// --- Models and CRUD (high level) ---\nexport type ModelConstructor = Readonly<{\n create: <\n T extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n modelProps: ModelProps\n ) => ModelType<T, TModelExtensions, TModelInstanceExtensions>\n}>\n\nexport type ModelProps<\n TConfig extends Config = Config,\n TModelOverrides extends object = object,\n TModelInstanceOverrides extends object = object,\n> = Readonly<{\n context: CommonContext<TConfig>\n Model: ModelFactory<TModelOverrides, TModelOverrides>\n fetcher: ModelInstanceFetcher<TModelOverrides, TModelInstanceOverrides>\n getModel: <T extends DataDescription>(\n namespace: string,\n modelName: string\n ) => () => ModelType<T, TModelOverrides, TModelInstanceOverrides>\n}>\n\nexport type ModelCrudsFunctions<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n getModel: () => OrmModel<TData, TModelExtensions, TModelInstanceExtensions>\n create: CreateFunction<TData>\n retrieve: RetrieveFunction<TData>\n update: UpdateFunction<TData>\n delete: DeleteFunction\n search: SearchFunction<TData>\n bulkInsert: BulkInsertFunction<TData>\n bulkDelete: BulkDeleteFunction\n}>\n\nexport type CreateFunction<TData extends DataDescription> = <\n IgnoreProperties extends string = '',\n>(\n data: Omit<TData, IgnoreProperties> | ToObjectResult<TData>\n) => Promise<OrmModelInstance<TData>>\n\nexport type RetrieveFunction<TData extends DataDescription> = (\n primaryKey: PrimaryKeyType\n) => Promise<OrmModelInstance<TData> | undefined>\n\nexport type UpdateFunction<TData extends DataDescription> = (\n primaryKey: PrimaryKeyType,\n data: TData | ToObjectResult<TData>\n) => Promise<OrmModelInstance<TData>>\n\nexport type DeleteFunction = (primaryKey: PrimaryKeyType) => Promise<void>\n\nexport type SearchFunction<TData extends DataDescription> = (\n ormSearch: OrmSearch\n) => Promise<OrmSearchResult<TData>>\n\nexport type BulkInsertFunction<TData extends DataDescription> = (\n data: readonly TData[]\n) => Promise<void>\n\nexport type BulkDeleteFunction = (\n primaryKeys: readonly PrimaryKeyType[]\n) => Promise<void>\n```\n",
183
208
  "tags": [
184
209
  "types",
185
210
  "architecture",
@@ -192,7 +217,7 @@
192
217
  "id": "9f70590a-3ed8-445a-a483-e2c04a93a642",
193
218
  "name": "API Surface of @node-in-layers/core",
194
219
  "description": "All functions and objects exported from @node-in-layers/core. Each export shows its name, input/output types, and a minimal code snippet. Implementation details are omitted.\n",
195
- "content": "```typescript\n// From index.ts\nexport { loadSystem } from './entries.js'\nexport * from './types.js'\nexport * from './models/types.js'\nexport * from './globals/logging.js'\n\n// --- Main Function ---\n// entries.ts\nasync function loadSystem<TConfig extends Config = Config>(args: {\n environment: string\n config?: TConfig\n}): Promise<any>\n\n// --- Logging (globals/logging.ts) ---\nfunction standardLogger<TConfig extends Config = Config>(): RootLogger<TConfig>\nfunction compositeLogger<TConfig extends Config = Config>(\n logMethods: readonly LogMethod<TConfig>[]\n): RootLogger<TConfig>\nfunction consoleLogSimple(logMessage: LogMessage): void\nfunction consoleLogJson(logMessage: LogMessage): void\nfunction consoleLogFull(logMessage: LogMessage): void\nfunction logTcp(\n context: CommonContext\n): (logMessage: LogMessage) => Promise<any>\n\n// --- Types and Model CRUDs (see types entry for full list) ---\n// All types from types.ts and models/types.ts are exported\n```\n",
220
+ "content": "```typescript\n// From index.ts\nexport { loadSystem } from './entries.js'\nexport * from './types.js'\nexport * from './libs.js'\nexport * from './utils.js'\nexport * from './models/types.js'\nexport * from './globals/logging.js'\nexport * from './globals/libs.js'\n\n// --- Main Function ---\n// entries.ts\nasync function loadSystem<TConfig extends Config = Config>(args: {\n environment: string\n config?: TConfig\n}): Promise<any>\n\n// --- Logging (globals/logging.ts) ---\nfunction standardLogger<TConfig extends Config = Config>(): RootLogger<TConfig>\nfunction compositeLogger<TConfig extends Config = Config>(\n logMethods: readonly LogMethod<TConfig>[]\n): RootLogger<TConfig>\nfunction consoleLogSimple(logMessage: LogMessage): void\nfunction consoleLogJson(logMessage: LogMessage): void\nfunction consoleLogFull(logMessage: LogMessage): void\nfunction logTcp(\n context: CommonContext\n): (logMessage: LogMessage) => Promise<any>\n\n// --- Types and Model CRUDs (see types entry for curated list) ---\n// Key types from types.ts and models/types.ts are exported\n```\n",
196
221
  "tags": [
197
222
  "api-surface",
198
223
  "architecture",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-in-layers/core-knowledge-mcp",
3
- "version": "1.12.8",
3
+ "version": "1.13.0",
4
4
  "description": "A developer MCP server for working with systems using node-in-layers core.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "argparse": "^2.0.1",
18
18
  "es-main": "^1.4.0",
19
- "@node-in-layers/core": "1.12.8",
19
+ "@node-in-layers/core": "1.13.0",
20
20
  "@node-in-layers/mcp-server": "^2.2.6",
21
21
  "lodash": "^4.17.21",
22
22
  "zod": "^4.1.12"