@kosdev-code/kos-codegen-core 3.0.18 → 3.0.20
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/index.js +293 -222
- package/index.js.map +1 -1
- package/index.mjs +293 -222
- package/index.mjs.map +1 -1
- package/lib/generators/add-future-to-model/normalize-options.d.ts.map +1 -1
- package/lib/generators/add-future-to-model/service-transformer.d.ts +1 -3
- package/lib/generators/add-future-to-model/service-transformer.d.ts.map +1 -1
- package/lib/generators/augment/model-services.d.ts +11 -0
- package/lib/generators/augment/model-services.d.ts.map +1 -0
- package/lib/generators/augment/ts-toolkit.d.ts +35 -0
- package/lib/generators/augment/ts-toolkit.d.ts.map +1 -1
- package/lib/generators/generate-container-model.d.ts +0 -1
- package/lib/generators/generate-container-model.d.ts.map +1 -1
- package/lib/generators/generate-init.d.ts.map +1 -1
- package/lib/generators/generate-model.d.ts +0 -1
- package/lib/generators/generate-model.d.ts.map +1 -1
- package/lib/generators/member-mutators/add-service-request.d.ts +9 -2
- package/lib/generators/member-mutators/add-service-request.d.ts.map +1 -1
- package/package.json +2 -2
- package/templates/kos-container-model/model/index.ts.template +0 -2
- package/templates/kos-model/model/index.ts__template__ +0 -3
- package/templates/kos-container-model/services/__modelNameDashCase__-services.ts.template +0 -22
- package/templates/kos-container-model/services/index.ts.template +0 -1
- package/templates/kos-model/services/__nameDashCase__-services.ts.template +0 -58
- package/templates/kos-model/services/index.ts.template +0 -1
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../packages/kos-codegen-core/src/lib/codegen-filesystem.ts","../../../packages/kos-codegen-core/src/lib/logger.ts","../../../packages/kos-codegen-core/src/lib/generate-files.ts","../../../packages/kos-codegen-core/src/lib/project-discovery.ts","../../../packages/kos-codegen-core/src/lib/json-utils.ts","../../../packages/kos-codegen-core/src/lib/format-files.ts","../../../packages/kos-codegen-core/src/lib/name-utils.ts","../../../packages/kos-codegen-core/src/lib/normalize-values.ts","../../../packages/kos-codegen-core/src/lib/kos-config.ts","../../../packages/kos-codegen-core/src/lib/template-resolver.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-splash-project.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-init.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-polyglot-workspace.ts","../../../packages/kos-codegen-core/src/lib/generators/kab-targets.ts","../../../packages/kos-codegen-core/src/lib/generators/ci-sync.ts","../../../packages/kos-codegen-core/src/lib/generators/java-workspace.ts","../../../packages/kos-codegen-core/src/lib/generators/normalize-options.ts","../../../packages/kos-codegen-core/src/lib/generators/augment/ts-toolkit.ts","../../../packages/kos-codegen-core/src/lib/generators/service-catalog.ts","../../../packages/kos-codegen-core/src/lib/generators/release-version-script.ts","../../../packages/kos-codegen-core/src/lib/generators/barrel-utils.ts","../../../packages/kos-codegen-core/src/lib/generators/update-model-index.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-hook.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-context.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-container-model.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-companion-model.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-model.ts","../../../packages/kos-codegen-core/src/lib/generators/augment/resolve-model-file.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/normalize-options.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/model-transformer.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/service-transformer.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/registration-transformer.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/generate-add-future-to-model.ts","../../../packages/kos-codegen-core/src/lib/generators/add-container-support/generate-add-container-support.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-model-effect.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-dependency.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-child.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-topic-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-config-property.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-property.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-computed.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-service-request.ts","../../../packages/kos-codegen-core/src/lib/generators/validate/validate-model.ts","../../../packages/kos-codegen-core/src/lib/generators/describe/describe-model.ts","../../../packages/kos-codegen-core/src/lib/generators/types/lookup-sdk-type.ts","../../../packages/kos-codegen-core/src/lib/generators/component/types.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/base.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/control-pour-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/cui-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/custom-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/default-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/nav-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/setting-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/setup-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/trouble-action-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/utility-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/factory.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/file-generator.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/kos-config-builder.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/localization.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/validation.ts","../../../packages/kos-codegen-core/src/lib/generators/component/generate-component.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * Abstraction over a filesystem for code generation.\n *\n * Mirrors the subset of the Nx Tree API that generators actually use,\n * enabling the same generator logic to run against the real filesystem\n * (CLI, VS Code extension) or an in-memory tree (Nx adapter).\n */\nexport interface CodegenFileSystem {\n /** Workspace root directory (absolute path). */\n readonly root: string;\n\n /** Read a file relative to the workspace root. Returns null if not found. */\n read(filePath: string): string | null;\n\n /** Write a file relative to the workspace root. Creates parent dirs as needed. */\n write(filePath: string, content: string): void;\n\n /** Check whether a file exists relative to the workspace root. */\n exists(filePath: string): boolean;\n\n /** Delete a file relative to the workspace root. No-op if not found. */\n delete(filePath: string): void;\n\n /** List all files under a directory (relative to root), returned as root-relative paths. */\n listFiles(dirPath: string): string[];\n}\n\n/**\n * CodegenFileSystem wrapper that records absolute paths of every file written.\n * Wrap any CodegenFileSystem to collect written paths for post-generation steps\n * such as formatting.\n *\n * @example\n * const fs = new TrackingFileSystem(new DirectFileSystem(cwd));\n * generateModel({ codegenFs: fs, ... });\n * await formatFiles(fs.root, fs.writtenPaths);\n */\nexport class TrackingFileSystem implements CodegenFileSystem {\n private readonly inner: CodegenFileSystem;\n private readonly _writtenPaths: string[] = [];\n\n constructor(inner: CodegenFileSystem) {\n this.inner = inner;\n }\n\n get root(): string {\n return this.inner.root;\n }\n\n get writtenPaths(): string[] {\n return [...this._writtenPaths];\n }\n\n read(filePath: string): string | null {\n return this.inner.read(filePath);\n }\n\n write(filePath: string, content: string): void {\n this.inner.write(filePath, content);\n this._writtenPaths.push(\n path.isAbsolute(filePath)\n ? filePath\n : path.join(this.inner.root, filePath)\n );\n }\n\n exists(filePath: string): boolean {\n return this.inner.exists(filePath);\n }\n\n delete(filePath: string): void {\n this.inner.delete(filePath);\n }\n\n listFiles(dirPath: string): string[] {\n return this.inner.listFiles(dirPath);\n }\n}\n\n/**\n * CodegenFileSystem backed by the real Node.js filesystem.\n * All paths passed to interface methods are relative to the workspace root.\n */\nexport class DirectFileSystem implements CodegenFileSystem {\n readonly root: string;\n\n constructor(workspaceRoot: string) {\n this.root = path.resolve(workspaceRoot);\n }\n\n read(filePath: string): string | null {\n const abs = this.resolve(filePath);\n try {\n return fs.readFileSync(abs, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n write(filePath: string, content: string): void {\n const abs = this.resolve(filePath);\n fs.mkdirSync(path.dirname(abs), { recursive: true });\n fs.writeFileSync(abs, content, \"utf-8\");\n }\n\n exists(filePath: string): boolean {\n return fs.existsSync(this.resolve(filePath));\n }\n\n delete(filePath: string): void {\n const abs = this.resolve(filePath);\n try {\n fs.unlinkSync(abs);\n } catch {\n // no-op if file doesn't exist\n }\n }\n\n listFiles(dirPath: string): string[] {\n const abs = this.resolve(dirPath);\n if (!fs.existsSync(abs)) {\n return [];\n }\n return this.walkDir(abs).map((file) => path.relative(this.root, file));\n }\n\n private resolve(filePath: string): string {\n if (path.isAbsolute(filePath)) {\n return filePath;\n }\n return path.join(this.root, filePath);\n }\n\n private walkDir(dir: string): string[] {\n const results: string[] = [];\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...this.walkDir(full));\n } else {\n results.push(full);\n }\n }\n return results;\n }\n}\n","/**\n * Settable logger interface for kos-codegen-core.\n *\n * Consumers (CLI, VS Code extension, Nx adapter) set their own logger\n * via setCodegenLogger(). Defaults to silent no-op.\n */\nexport interface CodegenLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst noopLogger: CodegenLogger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\nlet activeLogger: CodegenLogger = noopLogger;\n\nexport function setCodegenLogger(logger: CodegenLogger): void {\n activeLogger = logger;\n}\n\nexport function getCodegenLogger(): CodegenLogger {\n return activeLogger;\n}\n","/**\n * EJS-based file generation — replaces @nx/devkit generateFiles().\n *\n * Walks a source template directory, processes each file through EJS,\n * interpolates __var__ tokens in filenames, strips .template suffixes,\n * and writes results via a CodegenFileSystem.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as ejs from \"ejs\";\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\nimport { getCodegenLogger } from \"./logger\";\n\n/**\n * Generate files from a template directory into a destination path.\n *\n * Behavior matches @nx/devkit generateFiles():\n * - Walks `srcFolder` recursively\n * - For each file, replaces `__propName__` in the filename using `substitutions`\n * - Strips `.template` suffix from filenames\n * - Processes file contents through EJS with `substitutions` as data\n * - Writes the result to `destFolder` (relative to fs.root) via the CodegenFileSystem\n *\n * @param codegenFs - Target filesystem abstraction\n * @param srcFolder - Absolute path to the template directory\n * @param destFolder - Destination path relative to the filesystem root\n * @param substitutions - Key-value pairs for EJS and filename interpolation\n */\nexport function generateFilesFromTemplates(\n codegenFs: CodegenFileSystem,\n srcFolder: string,\n destFolder: string,\n substitutions: Record<string, any>\n): void {\n const logger = getCodegenLogger();\n const templateFiles = walkTemplateDir(srcFolder);\n\n for (const templateFile of templateFiles) {\n const relPath = path.relative(srcFolder, templateFile);\n\n // Interpolate __var__ tokens in the path segments\n let destRelPath = interpolateFilename(relPath, substitutions);\n\n // Strip .template suffix\n if (destRelPath.endsWith(\".template\")) {\n destRelPath = destRelPath.slice(0, -\".template\".length);\n }\n\n const destPath = path.join(destFolder, destRelPath);\n\n // Templates are read from the real filesystem (package assets),\n // while outputs are written through CodegenFileSystem.\n const rawContent = fs.readFileSync(templateFile, \"utf-8\");\n const rendered = ejs.render(rawContent, substitutions, {\n filename: templateFile, // for EJS error messages and includes\n });\n\n logger.debug(`Generating ${destPath}`);\n codegenFs.write(destPath, rendered);\n }\n}\n\n/**\n * Replace `__propName__` tokens in a file path with values from substitutions.\n * E.g., `__nameDashCase__-model.ts` with `{ nameDashCase: \"my-widget\" }` becomes\n * `my-widget-model.ts`.\n */\nfunction interpolateFilename(\n filePath: string,\n substitutions: Record<string, any>\n): string {\n return filePath.replace(/__([^_]+)__/g, (match, key: string) => {\n if (key in substitutions) {\n return String(substitutions[key]);\n }\n return match; // leave unmatched tokens as-is\n });\n}\n\nfunction walkTemplateDir(dir: string): string[] {\n const results: string[] = [];\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...walkTemplateDir(full));\n } else {\n results.push(full);\n }\n }\n return results;\n}\n","/**\n * Nx-free project discovery — scans for project.json files in the workspace.\n *\n * Replaces @nx/devkit readProjectConfiguration, getProjects, readNxJson.\n * Based on the pattern in kos-model-extension/src/utils/workspace-scanner.ts.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport fg from \"fast-glob\";\nimport { getCodegenLogger } from \"./logger\";\n\nexport interface ProjectConfiguration {\n name: string;\n root: string;\n sourceRoot: string;\n projectType?: \"library\" | \"application\";\n targets?: Record<string, unknown>;\n tags?: string[];\n}\n\n/**\n * Discover all projects in the workspace by scanning for project.json files.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @returns Map of project name to ProjectConfiguration\n */\nexport function discoverProjects(\n workspaceRoot: string\n): Map<string, ProjectConfiguration> {\n const logger = getCodegenLogger();\n const projects = new Map<string, ProjectConfiguration>();\n\n const projectJsonPaths = fg.sync(\"**/project.json\", {\n cwd: workspaceRoot,\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/.git/**\"],\n absolute: false,\n });\n\n for (const relPath of projectJsonPaths) {\n const absPath = path.join(workspaceRoot, relPath);\n try {\n const raw = fs.readFileSync(absPath, \"utf-8\");\n const json = JSON.parse(raw);\n const projectRoot = path.dirname(relPath);\n const name = json.name ?? path.basename(projectRoot);\n\n const config: ProjectConfiguration = {\n name,\n root: projectRoot,\n sourceRoot: json.sourceRoot ?? path.join(projectRoot, \"src\"),\n projectType: json.projectType,\n targets: json.targets,\n tags: json.tags,\n };\n\n projects.set(name, config);\n logger.debug(`Discovered project: ${name} at ${projectRoot}`);\n } catch (err) {\n logger.warn(`Failed to parse ${absPath}: ${err}`);\n }\n }\n\n logger.info(`Discovered ${projects.size} projects`);\n return projects;\n}\n\n/**\n * Find a single project by name.\n *\n * Note: This rescans the workspace on every call. If you need to look up\n * multiple projects, call discoverProjects() once and query the returned Map.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @param projectName - The project name to look up\n * @param projects - Optional pre-computed project map (avoids rescan)\n * @returns ProjectConfiguration or undefined if not found\n */\nexport function findProjectByName(\n workspaceRoot: string,\n projectName: string,\n projects?: Map<string, ProjectConfiguration>\n): ProjectConfiguration | undefined {\n const map = projects ?? discoverProjects(workspaceRoot);\n return map.get(projectName);\n}\n\n/**\n * Find the project that contains a given file path.\n * Walks up from the file path looking for the nearest project.json.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @param filePath - Absolute path to a file within the workspace\n * @returns ProjectConfiguration or undefined if not within any project\n */\nexport function findProjectForPath(\n workspaceRoot: string,\n filePath: string\n): ProjectConfiguration | undefined {\n const resolved = path.resolve(workspaceRoot);\n let dir = path.dirname(path.resolve(filePath));\n\n while (dir.startsWith(resolved) && dir !== resolved) {\n const projectJsonPath = path.join(dir, \"project.json\");\n if (fs.existsSync(projectJsonPath)) {\n try {\n const raw = fs.readFileSync(projectJsonPath, \"utf-8\");\n const json = JSON.parse(raw);\n const projectRoot = path.relative(resolved, dir);\n const name = json.name ?? path.basename(dir);\n\n return {\n name,\n root: projectRoot,\n sourceRoot: json.sourceRoot ?? path.join(projectRoot, \"src\"),\n projectType: json.projectType,\n targets: json.targets,\n tags: json.tags,\n };\n } catch {\n return undefined;\n }\n }\n dir = path.dirname(dir);\n }\n\n return undefined;\n}\n\n/**\n * Read the workspace-level nx.json configuration.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @returns Parsed nx.json contents, or empty object if not found\n */\nexport function readNxJson(workspaceRoot: string): Record<string, unknown> {\n const nxJsonPath = path.join(workspaceRoot, \"nx.json\");\n try {\n const raw = fs.readFileSync(nxJsonPath, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n","/**\n * JSON read/write/update utilities operating on a CodegenFileSystem.\n *\n * Replaces @nx/devkit readJson, writeJson, updateJson.\n */\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\n\n/**\n * Read and parse a JSON file from the filesystem.\n *\n * @param codegenFs - Filesystem abstraction\n * @param filePath - Path relative to workspace root\n * @returns Parsed JSON object\n * @throws If the file does not exist or contains invalid JSON\n */\nexport function readJson<T = Record<string, unknown>>(\n codegenFs: CodegenFileSystem,\n filePath: string\n): T {\n const content = codegenFs.read(filePath);\n if (content === null) {\n throw new Error(`File not found: ${filePath}`);\n }\n return JSON.parse(content) as T;\n}\n\n/**\n * Serialize and write a JSON object to the filesystem.\n *\n * @param codegenFs - Filesystem abstraction\n * @param filePath - Path relative to workspace root\n * @param value - Object to serialize\n */\nexport function writeJson<T = Record<string, unknown>>(\n codegenFs: CodegenFileSystem,\n filePath: string,\n value: T\n): void {\n codegenFs.write(filePath, JSON.stringify(value, null, 2) + \"\\n\");\n}\n\n/**\n * Read a JSON file, apply a transformation, and write it back.\n *\n * @param codegenFs - Filesystem abstraction\n * @param filePath - Path relative to workspace root\n * @param updater - Function that receives the parsed object and returns the updated object\n */\nexport function updateJson<T = Record<string, unknown>>(\n codegenFs: CodegenFileSystem,\n filePath: string,\n updater: (json: T) => T\n): void {\n const current = readJson<T>(codegenFs, filePath);\n const updated = updater(current);\n writeJson(codegenFs, filePath, updated);\n}\n","/**\n * Format files using Prettier — replaces @nx/devkit formatFiles().\n *\n * Resolves the Prettier config from the workspace root and formats\n * all files tracked by a CodegenFileSystem that match supported extensions.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport prettier from \"prettier\";\nimport { getCodegenLogger } from \"./logger\";\n\nconst FORMATTABLE_EXTENSIONS = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".css\",\n \".scss\",\n \".md\",\n \".yaml\",\n \".yml\",\n \".html\",\n]);\n\n/**\n * Format files at the given paths using Prettier.\n *\n * @param workspaceRoot - Absolute path to the workspace root (for Prettier config resolution)\n * @param filePaths - Absolute paths of files to format\n */\nexport async function formatFiles(\n workspaceRoot: string,\n filePaths: string[]\n): Promise<void> {\n const logger = getCodegenLogger();\n\n for (const filePath of filePaths) {\n const ext = path.extname(filePath);\n if (!FORMATTABLE_EXTENSIONS.has(ext)) {\n continue;\n }\n\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const options = await prettier.resolveConfig(filePath, {\n editorconfig: true,\n });\n const formatted = await prettier.format(content, {\n ...options,\n filepath: filePath,\n });\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n logger.debug(`Formatted ${path.relative(workspaceRoot, filePath)}`);\n } catch (err) {\n logger.warn(`Failed to format ${filePath}: ${err}`);\n }\n }\n}\n","/**\n * String case-conversion utilities.\n *\n * Pure functions with no external dependencies.\n * Ported from kos-nx-plugin/src/utils/name-utils.ts (minus the logger calls).\n */\n\nexport function dashCase(input: string): string {\n return input\n .replace(/\\s+/g, \"-\")\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n}\n\nexport function camelCase(input: string): string {\n if (input.length === 0) return \"\";\n const words = input.split(/-|\\s+/);\n if (words.length > 0 && words[0].length > 0) {\n words[0] = words[0].charAt(0).toLowerCase() + words[0].slice(1);\n }\n for (let i = 1; i < words.length; i++) {\n words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);\n }\n return words.join(\"\");\n}\n\nexport function pascalCase(input: string): string {\n if (input.length === 0) return \"\";\n const cc = camelCase(input);\n return cc[0].toUpperCase() + cc.slice(1);\n}\n\nexport function properCase(input: string): string {\n const words = input\n .toLowerCase()\n .replaceAll(\"-\", \" \")\n .split(\" \")\n .filter(Boolean);\n for (let i = 0; i < words.length; i++) {\n words[i] = words[i][0].toUpperCase() + words[i].slice(1);\n }\n return words.join(\"\");\n}\n\n/**\n * Convert to CONSTANT_CASE. Expects space-separated or dash-separated input.\n * camelCase input is not split (e.g. \"myWidget\" becomes \"MYWIDGET\").\n */\nexport function constantCase(input: string): string {\n if (input.length === 0) return \"\";\n return input\n .toUpperCase()\n .split(/[\\s-]+/)\n .filter(Boolean)\n .join(\"_\");\n}\n","/**\n * Option normalization — generates all case variants for every string property.\n *\n * Given `{ name: \"my-widget\" }`, produces:\n * ```\n * {\n * name: \"my-widget\",\n * nameCamelCase: \"myWidget\",\n * namePascalCase: \"MyWidget\",\n * nameDashCase: \"my-widget\",\n * nameProperCase: \"MyWidget\",\n * nameConstantCase: \"MY_WIDGET\",\n * nameLowerCase: \"my-widget\",\n * }\n * ```\n *\n * Ported from kos-nx-plugin/src/utils/normalize-value.ts.\n */\nimport {\n camelCase,\n constantCase,\n dashCase,\n pascalCase,\n properCase,\n} from \"./name-utils\";\n\ntype NormalizedFunctions =\n | \"CamelCase\"\n | \"ConstantCase\"\n | \"DashCase\"\n | \"PascalCase\"\n | \"ProperCase\"\n | \"LowerCase\";\n\ntype NormalizedValue<Type extends Record<string, string>> = {\n [k in Type as `${Extract<keyof Type, string>}${NormalizedFunctions}`]: string;\n};\n\ntype Normalized<T extends string> = {\n [k in T as `${T}${NormalizedFunctions}`]: string;\n};\n\nconst normalizeValue = <T extends string>(\n optionsName: T,\n value: string\n): Normalized<T> & { [k in T]: string } =>\n ({\n [`${camelCase(optionsName)}CamelCase`]: camelCase(value),\n [`${camelCase(optionsName)}ConstantCase`]: constantCase(value),\n [`${camelCase(optionsName)}DashCase`]: dashCase(value),\n [`${camelCase(optionsName)}PascalCase`]: pascalCase(value),\n [`${camelCase(optionsName)}ProperCase`]: properCase(value),\n [`${camelCase(optionsName)}LowerCase`]: value.toLowerCase(),\n [`${optionsName}`]: value,\n } as Normalized<T> & { [k in T]: string });\n\nexport const normalizeAllValues = <T extends Record<string, any>>(\n options: T\n): NormalizedValue<T> & T => {\n let normalizedValues = {} as NormalizedValue<T> & T;\n for (const key in options) {\n if (Object.prototype.hasOwnProperty.call(options, key)) {\n const element = options[key];\n const newOptions =\n typeof element !== \"string\" || element === \"\"\n ? { [key]: element }\n : normalizeValue(key, element);\n\n normalizedValues = {\n ...normalizedValues,\n ...newOptions,\n };\n }\n }\n return normalizedValues;\n};\n","/**\n * KOS project and model configuration utilities.\n *\n * Reads and writes .kos.json files through CodegenFileSystem.\n * Ported from kos-nx-plugin/src/utils/project-utils.ts.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\nimport {\n findProjectByName,\n findProjectForPath,\n type ProjectConfiguration,\n} from \"./project-discovery\";\nimport { updateJson } from \"./json-utils\";\nimport { dashCase } from \"./name-utils\";\nimport { getCodegenLogger } from \"./logger\";\n\nexport interface KosModelConfiguration {\n name: string;\n type: string;\n singleton: boolean;\n container?: boolean;\n /**\n * Exported registration bean symbol (e.g. \"Board\") — the agent-facing handle.\n * Imported from the SDK root; `factory.type` is the modelType to depend on, and\n * models are auto-registered so consumers never instantiate it. Written\n * automatically by the generator (it names the bean). Links to the full shape\n * at `kos://types/{factory}`.\n */\n factory?: string;\n /**\n * One-line, human-curated purpose. The only genuinely authored field — set via\n * an optional prompt/slot at generation, never inferred.\n */\n purpose?: string;\n /**\n * `.kos.json` keys of the container/managing models that hold this model —\n * consume it THROUGH them (depend on the container, navigate), not by id. Set\n * only when generation establishes containment; never inferred.\n */\n managedBy?: string[];\n}\n\nexport interface KosProjectConfiguration {\n name: string;\n type: string;\n version: string;\n models: Record<string, KosModelConfiguration>;\n generator?: {\n internal?: boolean;\n defaults?: {\n model?: { folder?: string };\n component?: { folder?: string };\n };\n };\n}\n\nexport function getCurrentDirectoryName(cwd: string): string | undefined {\n return cwd.split(\"/\").pop();\n}\n\n/**\n * Find the project that contains the given working directory.\n */\nexport function getProject(\n codegenFs: CodegenFileSystem,\n cwd: string\n): ProjectConfiguration | undefined {\n return findProjectForPath(codegenFs.root, cwd);\n}\n\n/**\n * Read .kos.json for a project, creating a default if it doesn't exist.\n */\nexport function getKosProjectConfiguration(\n codegenFs: CodegenFileSystem,\n projectName: string,\n projects?: Map<string, ProjectConfiguration>\n): KosProjectConfiguration | undefined {\n const project = findProjectByName(codegenFs.root, projectName, projects);\n if (!project) return undefined;\n\n const configPath = path.join(project.root, \".kos.json\");\n if (!codegenFs.exists(configPath)) {\n const defaultConfig: KosProjectConfiguration = {\n name: `${dashCase(projectName)}-model`,\n type: \"kos.model\",\n version: \"0.1.0\",\n models: {},\n generator: { defaults: { model: { folder: \"\" } } },\n };\n codegenFs.write(configPath, JSON.stringify(defaultConfig, null, 2));\n }\n\n const content = codegenFs.read(configPath);\n return content ? JSON.parse(content) : undefined;\n}\n\n/**\n * Find the `.kos.json` model key for a model name. Keys are normally the model\n * name itself; fall back to matching the derived `<name>-model` type id so a\n * differently-cased name still resolves.\n */\nfunction findModelKey(\n models: Record<string, any>,\n name: string\n): string | undefined {\n if (models[name]) return name;\n const typeId = `${dashCase(name)}-model`;\n return Object.keys(models).find((k) => models[k]?.type === typeId);\n}\n\n/**\n * Record that an existing model gained in-place container support\n * (`@kosContainerAware`) in `.kos.json`: flag it `container: true`, and — when it\n * holds a concrete model type rather than the generic `IKosDataModel` — record\n * that child as `managedBy` this container so it is consumed THROUGH it.\n *\n * Containment is only recorded from this explicit generation step; nothing is\n * inferred. No-ops if the project or its `.kos.json` can't be found.\n */\nexport function recordContainerSupportInKosConfig(params: {\n codegenFs: CodegenFileSystem;\n projectName: string;\n modelName: string;\n childType?: string;\n projects?: Map<string, ProjectConfiguration>;\n}): void {\n const project = findProjectByName(\n params.codegenFs.root,\n params.projectName,\n params.projects\n );\n if (!project) return;\n const configPath = path.join(project.root, \".kos.json\");\n if (!params.codegenFs.exists(configPath)) return;\n\n updateJson(params.codegenFs, configPath, (json: any) => {\n const models: Record<string, any> = json.models ?? {};\n const selfKey = findModelKey(models, params.modelName);\n if (!selfKey) return json;\n\n models[selfKey] = { ...models[selfKey], container: true };\n\n const childType = params.childType?.trim();\n if (\n childType &&\n childType !== \"IKosDataModel\" &&\n /Model$/.test(childType)\n ) {\n const childTypeId = dashCase(childType);\n const childKey = Object.keys(models).find(\n (k) => models[k]?.type === childTypeId\n );\n if (childKey && childKey !== selfKey) {\n const managedBy = [\n ...new Set([...(models[childKey].managedBy ?? []), selfKey]),\n ];\n models[childKey] = { ...models[childKey], managedBy };\n }\n }\n\n json.models = models;\n return json;\n });\n}\n\n/**\n * Read a specific model's configuration from .kos.json.\n */\nexport function getKosModelConfiguration(\n codegenFs: CodegenFileSystem,\n projectName: string,\n modelName: string,\n projects?: Map<string, ProjectConfiguration>\n): KosModelConfiguration | undefined {\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectName,\n projects\n );\n return kosConfig?.models?.[modelName];\n}\n\n/**\n * Read a specific property from a model's configuration.\n */\nexport function getKosModelConfigProp(params: {\n codegenFs: CodegenFileSystem;\n project: string;\n modelName: string;\n prop: string;\n projects?: Map<string, ProjectConfiguration>;\n}): any {\n const config = getKosModelConfiguration(\n params.codegenFs,\n params.project,\n params.modelName,\n params.projects\n );\n return config ? (config as any)[params.prop] : undefined;\n}\n\n/**\n * Add a model entry to a project's .kos.json.\n */\nexport function addKosModelConfiguration(params: {\n codegenFs: CodegenFileSystem;\n projectName: string;\n projectRoot: string;\n modelName: string;\n singleton: boolean;\n container?: boolean;\n /** Exported registration bean symbol (the generator knows it). */\n factory?: string;\n}): void {\n const logger = getCodegenLogger();\n const kosConfigPath = path.join(params.projectRoot, \".kos.json\");\n\n if (!params.codegenFs.exists(kosConfigPath)) {\n logger.info(`Creating .kos.json in ${params.projectRoot}`);\n const defaultConfig = {\n name: params.projectName,\n type: \"kos.model\",\n version: \"0.1.0\",\n models: {},\n generator: { defaults: { model: { folder: \"\" } } },\n };\n params.codegenFs.write(\n kosConfigPath,\n JSON.stringify(defaultConfig, null, 2) + \"\\n\"\n );\n }\n\n updateJson(params.codegenFs, kosConfigPath, (json: any) => {\n const existing = json.models?.[params.modelName] ?? {};\n json.models = {\n ...json.models,\n [params.modelName]: {\n // Preserve any curated fields (purpose/managedBy) on re-generation.\n ...existing,\n name: params.modelName,\n type: `${params.modelName}-model`,\n singleton: !!params.singleton,\n container: !!params.container,\n ...(params.factory ? { factory: params.factory } : {}),\n },\n };\n return json;\n });\n}\n","import * as path from \"path\";\nimport * as fs from \"fs\";\n\n/**\n * Finds the root directory containing the templates/ directory.\n *\n * Resolution order:\n * 1. KOS_TEMPLATE_BASE_DIR env var — set by kos-ui-cli when running as a\n * bundled ESM package (where __dirname is unavailable).\n * 2. Walk up from __dirname looking for this package's package.json — works\n * in CJS context (tsc-compiled output or direct Node.js require).\n */\nfunction findPackageRoot(): string {\n if (process.env.KOS_TEMPLATE_BASE_DIR) {\n return process.env.KOS_TEMPLATE_BASE_DIR;\n }\n\n // CJS context: walk up from __dirname to find our package.json\n let dir = __dirname;\n while (dir !== path.dirname(dir)) {\n const pkgPath = path.join(dir, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n if (pkg.name === \"@kosdev-code/kos-codegen-core\") {\n return dir;\n }\n } catch {\n // Not valid JSON, keep looking\n }\n }\n dir = path.dirname(dir);\n }\n // Fallback: assume source layout (src/lib/ -> package root)\n return path.resolve(__dirname, \"..\", \"..\");\n}\n\n/**\n * Resolves the absolute path to a generator's template directory.\n * Templates are stored in the `templates/` directory at the package root.\n *\n * @param generatorName - The generator name matching a subdirectory under templates/\n * @returns Absolute path to the template directory for the given generator\n */\nexport function getTemplateDir(generatorName: string): string {\n return path.join(findPackageRoot(), \"templates\", generatorName);\n}\n","/**\n * Core generator: Splash project.\n *\n * Creates a splash screen project structure and associated tooling scripts.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { normalizeAllValues } from \"../normalize-values\";\n\nexport interface SplashProjectOptions {\n name: string;\n}\n\n/**\n * Generate a splash project with its associated tooling.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory containing\n * `project/` and `tools/` subdirectories\n * @param options - Generator options\n */\nexport function generateSplashProject(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: SplashProjectOptions\n): void {\n const normalized = normalizeAllValues(options);\n\n const projectRoot = `splash/${normalized.nameDashCase}`;\n const toolsRoot = path.join(\"tools\", \"scripts\");\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"project\"),\n projectRoot,\n normalized\n );\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"tools\"),\n toolsRoot,\n normalized\n );\n}\n","/**\n * Core generator: KOS Init.\n *\n * Updates nx.json with default KOS generator configuration for the workspace.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { readJson, writeJson } from \"../json-utils\";\nimport { getCodegenLogger } from \"../logger\";\n\nexport interface KosInitOptions {\n appProject: string;\n modelProject: string;\n registrationProject?: string;\n}\n\n/**\n * Initialize KOS generator defaults in nx.json.\n *\n * Sets default project references for kos-model, kos-component,\n * kos-context, and kos-hook generators.\n *\n * @param codegenFs - Target filesystem\n * @param options - Generator options\n */\nexport function generateInit(\n codegenFs: CodegenFileSystem,\n options: KosInitOptions\n): void {\n const logger = getCodegenLogger();\n const { appProject, modelProject, registrationProject } = options;\n\n let nxConfig: Record<string, any>;\n try {\n nxConfig = readJson(codegenFs, \"nx.json\");\n } catch {\n logger.error(\"Unable to find nx.json\");\n return;\n }\n\n logger.info(\"Updating nx.json\");\n\n const defaultProjectConfig = {\n appProject,\n modelProject,\n registrationProject,\n modelDirectory: \"lib\",\n appDirectory: \"app\",\n components: true,\n dataServices: true,\n internal: false,\n singleton: false,\n unitTests: true,\n };\n\n const generatorsConfig = nxConfig.generators || {};\n const kosConfig = generatorsConfig[\"@kosdev-code/kos-nx-plugin\"] || {};\n\n const updateConfig = (configName: string) => {\n const config = kosConfig[configName] || { ...defaultProjectConfig };\n config.appProject = appProject;\n config.modelProject = modelProject;\n config.registrationProject = registrationProject;\n kosConfig[configName] = config;\n };\n\n [\"kos-model\", \"kos-component\", \"kos-context\", \"kos-hook\"].forEach(\n updateConfig\n );\n\n nxConfig.generators = {\n ...generatorsConfig,\n \"@kosdev-code/kos-nx-plugin\": kosConfig,\n };\n\n writeJson(codegenFs, \"nx.json\", nxConfig);\n}\n","/**\n * Core generator: polyglot workspace repo root.\n *\n * Scaffolds the repo-level layer of a java + ui KOS application repository\n * (the tccc-rack-app pattern): build/ orchestration scripts, GitHub Actions\n * workflows, and kos_build_handler manifests. The ui/ interior is produced by\n * the Nx preset (create-nx-workspace) and java/ modules by the KOS Maven\n * archetypes — this generator only contributes the layer neither of them owns.\n *\n * Framework-agnostic — operates through CodegenFileSystem; the repo root is\n * deliberately NOT an Nx workspace.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { normalizeAllValues } from \"../normalize-values\";\n\nexport interface PolyglotWorkspaceOptions {\n /** Workspace/repo name (also determines the UI app name `<name>-ui`). */\n name: string;\n /**\n * The repo-root layer is IDENTICAL for every type — same scripts,\n * workflows, and manifests, all runtime-tolerant of a missing half — so a\n * repo can grow the other half later without restructuring. The type only\n * seeds the manifests: \"polyglot\"/\"ui\" (default) pre-register the UI app\n * artifact; \"java\" starts with empty artifact lists (ci:sync/java:add\n * fill them in).\n */\n type?: \"polyglot\" | \"ui\" | \"java\";\n /**\n * `default_keyset` for the kos_build_handler manifests. Org-specific;\n * changeable in .github/build-*.json afterward. Default: \"prod.kos\".\n */\n keyset?: string;\n /**\n * Node version build/nodew.sh pins and auto-provisions when the machine\n * has none. Defaults to the Node running this generator — grounded in a\n * version known to work with the scaffolded workspace.\n */\n nodeVersion?: string;\n /**\n * JDK major build/jdkw.sh pins. Default 21 (compiles the archetypes'\n * release-17 target; also what java discovery prefers).\n */\n jdkMajor?: string;\n /** Maven version build/jdkw.sh provisions when mvn is absent. */\n mavenVersion?: string;\n}\n\nexport interface PolyglotWorkspaceResult {\n /**\n * Root-relative paths the caller must mark executable (CodegenFileSystem\n * has no chmod; CI invokes these directly as ./build/<script>).\n */\n executablePaths: string[];\n}\n\nconst BUILD_SCRIPTS = [\n \"build/build-ui.sh\",\n \"build/build-java.sh\",\n \"build/build-release.sh\",\n \"build/release_version_prebuild.sh\",\n \"build/docker-build.sh\",\n];\n\nexport function generatePolyglotWorkspace(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: PolyglotWorkspaceOptions\n): PolyglotWorkspaceResult {\n const hasUi = (options.type ?? \"polyglot\") !== \"java\";\n const normalized = normalizeAllValues({ name: options.name });\n const vars = {\n ...normalized,\n hasUi,\n keyset: options.keyset || \"prod.kos\",\n appUiName: `${normalized.nameDashCase}-ui`,\n nodeVersion: options.nodeVersion || process.version.replace(/^v/, \"\"),\n jdkMajor: options.jdkMajor || \"21\",\n mavenVersion: options.mavenVersion || \"3.9.9\",\n };\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"root\"),\n \".\",\n vars\n );\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"build\"),\n \"build\",\n vars\n );\n // Template dir is named \"github\" (npm packs dot-directories unreliably);\n // emitted as .github.\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"github\"),\n \".github\",\n vars\n );\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"java\"),\n \"java\",\n vars\n );\n\n return { executablePaths: [...BUILD_SCRIPTS] };\n}\n","/**\n * Shared KOS artifact-target bundle.\n *\n * Every project that packages a KAB gets the same target family:\n * kab — kabtool build + list (dependsOn zip)\n * zip — archiver (dependsOn build, sbom [+ descriptor])\n * descriptor — descriptor.mjs (optional; apps/plugins/content/i18n)\n * version — stamps the release version into the project's `.kos.json`\n * sbom — SPDX SBOM (pruned lockfile), packaged inside the KAB\n *\n * ARTIFACT LAYOUT: the KAB and ui.zip land in `{projectRoot}/target/` — a peer\n * of the project's `src/`, the same place the Maven half of a polyglot repo\n * drops its KABs (`java/<module>/target/*.kab`). A project's artifacts sit\n * beside the sources that produced them rather than in a workspace-wide\n * `dist/archives/` tree.\n *\n * `descriptor` and `sbom` write to the project's BUILD output dir\n * (`dist/{projectRoot}`) instead, because archiver zips that directory\n * wholesale: both have to end up INSIDE ui.zip — and therefore inside the KAB\n * — rather than beside it. An SBOM that shipped next to the KAB would not\n * travel with the distribution, which is the entire reason it is generated.\n * That is also why `zip` (not `kab`) is what depends on `sbom`: by the time\n * kabtool runs, the zip it packages is already sealed.\n *\n * Paths are written as Nx `{projectRoot}` tokens so `nx move` needs no\n * rewrite. Nx does NOT interpolate arbitrary target options, so the scripts\n * that read these (kabtool.mjs, archiver.js, descriptor.mjs, splashtool.mjs)\n * and the sbom executor expand the token themselves against the project's\n * root — see `resolveTargetPath` in each script.\n *\n * The `version` target is KOS *artifact* versioning: it rewrites the\n * `version` field of the project's `.kos.json` (which kabtool/descriptor bake\n * into the KAB) and never touches `package.json`. Tag-based release pipelines\n * drive it via:\n * nx run-many --target=version --args=--ver=$KOSBUILD_VERSION\n *\n * kab and version are deliberately produced by ONE helper so no generator can\n * emit a KAB-packaging project that is not release-versionable.\n */\n\n/** Directory, under each project root, that holds the project's KAB artifacts. */\nexport const KAB_OUTPUT_DIR = \"target\";\n\n/**\n * Archive directory for every KAB-producing project — `{projectRoot}/target/`.\n *\n * Deliberately a token rather than a resolved path: a project that moves keeps\n * working without anyone rewriting its project.json. Consumers expand it with\n * `resolveKabPath` (or its per-script equivalent) before touching the disk.\n */\nexport const KAB_OUTPUT_PATH = `{projectRoot}/${KAB_OUTPUT_DIR}/`;\n\n/**\n * Expand the Nx path tokens KOS artifact targets use in their options.\n *\n * Nx interpolates `{projectRoot}`/`{workspaceRoot}` in a target's `outputs`,\n * never in arbitrary `options`, and the KAB scripts read those options straight\n * off the cached project graph — so expansion is on us. The result stays\n * workspace-root-relative (the cwd Nx runs commands from) unless the token was\n * `{workspaceRoot}`.\n */\nexport function resolveKabPath(value: string, projectRoot: string): string {\n const root = projectRoot.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n return value\n .replace(/\\{projectRoot\\}/g, root)\n .replace(/\\{workspaceRoot\\}\\/?/g, \"\");\n}\n\nexport interface KabTargetsOptions {\n /** Project name as Nx knows it (argument to kabtool/archiver/descriptor). */\n name: string;\n /**\n * Emit a `descriptor` target (and make `zip` depend on it). Its\n * descriptor.json is written into the build output dir so the zip contains\n * it. Omit for projects without a descriptor (themes).\n */\n descriptor?: boolean;\n /** Build target `zip` depends on. Default: \"build\" (plugins: \"build:production\"). */\n buildTarget?: string;\n}\n\nexport interface KabTargetDefinition {\n command?: string;\n executor?: string;\n outputs?: string[];\n cache?: boolean;\n inputs?: string[];\n options?: Record<string, unknown>;\n dependsOn?: string[];\n}\n\nexport const UPDATE_RELEASE_VERSION_SCRIPT_PATH =\n \"tools/scripts/update-release-version.mjs\";\n\nexport function buildKabTargets(\n options: KabTargetsOptions\n): Record<string, KabTargetDefinition> {\n const { name, descriptor = false, buildTarget = \"build\" } = options;\n const outputPath = KAB_OUTPUT_PATH;\n // Everything that must ride INSIDE ui.zip is written here, because archiver\n // zips the build output dir wholesale.\n const zipPayloadDir = \"dist/{projectRoot}\";\n\n const targets: Record<string, KabTargetDefinition> = {\n kab: {\n command: `node tools/scripts/kabtool.mjs build ${name} && node tools/scripts/kabtool.mjs list ${name} `,\n options: {\n outputPath,\n zipName: \"ui.zip\",\n kabName: `${name}.kab`,\n },\n dependsOn: [\"zip\"],\n },\n zip: {\n command: `node tools/scripts/archiver.js ${name}`,\n options: {\n outputPath,\n zipName: \"ui.zip\",\n },\n // `sbom` is a zip dependency, not a kab one: kabtool packages an\n // already-sealed ui.zip, so anything ordered after `zip` misses it.\n dependsOn: descriptor\n ? [buildTarget, \"descriptor\", \"sbom\"]\n : [buildTarget, \"sbom\"],\n },\n };\n\n if (descriptor) {\n targets.descriptor = {\n command: `node tools/scripts/descriptor.mjs ${name}`,\n options: {\n outputPath: zipPayloadDir,\n fileName: \"descriptor.json\",\n },\n dependsOn: [\"build\"],\n };\n }\n\n targets.version = {\n command: `node ${UPDATE_RELEASE_VERSION_SCRIPT_PATH} ${name} {args.ver}`,\n options: {},\n dependsOn: [],\n };\n\n // The SBOM ships inside the KAB so it travels with the distribution.\n targets.sbom = buildSbomTarget({ outputPath: zipPayloadDir });\n\n return targets;\n}\n\nexport interface SbomTargetOptions {\n /**\n * Directory the SBOM lands in. `dist/{projectRoot}` — the build output dir\n * archiver zips — so the SBOM ships inside the KAB.\n */\n outputPath: string;\n}\n\n/**\n * SBOM target for any artifact-producing project. Standalone so migrations\n * can retrofit it onto existing projects without rebuilding the kab bundle.\n *\n * Whatever consumes this must order it BEFORE `zip`; an SBOM written after the\n * zip is sealed never reaches the KAB.\n */\nexport function buildSbomTarget({\n outputPath,\n}: SbomTargetOptions): KabTargetDefinition {\n const dir = outputPath.replace(/\\/+$/, \"\");\n // `outputs` is one of the few places Nx expands tokens itself, so a\n // tokenized dir goes in as-is; a plain path still needs the root prefix.\n const outputDir = dir.startsWith(\"{\") ? dir : `{workspaceRoot}/${dir}`;\n return {\n executor: \"@kosdev-code/kos-nx-plugin:sbom\",\n outputs: [\n `${outputDir}/sbom.spdx.json`,\n `${outputDir}/sbom.cyclonedx.json`,\n ],\n cache: true,\n inputs: [\"production\", \"^production\", \"{workspaceRoot}/package-lock.json\"],\n options: { outputPath: dir, softFail: true },\n };\n}\n","/**\n * ci:sync — reconcile the kos_build_handler manifests of a polyglot\n * workspace with the artifacts the repo actually produces.\n *\n * MERGE-PRESERVE semantics (the design contract):\n * - Existing artifact entries whose file is still produced are kept\n * VERBATIM — ids and custom fields (layer, artifactstore, …) are the\n * user's, and manifest ids are often hand-chosen (tccc-rack-app's\n * \"tccc-rack-splash-endcap\" for the `splash` project).\n * - Newly discovered artifacts are appended with generated entries.\n * - Entries whose artifact is no longer discovered are reported as stale\n * and kept, unless prune is set.\n * - Nothing outside the artifacts arrays is ever touched, and a manifest\n * is only rewritten when its artifact set actually changed.\n * Consequence: running ci:sync on an already-correct repo is a no-op, and\n * hand-running a Maven archetype + ci:sync converges to the same manifests\n * as `kosui java:add`.\n *\n * Discovery:\n * - ui: project.json files under the KOS layout dirs (never a bare walk of\n * ui/ — listFiles has no node_modules exclusion). A `kab` target's own\n * outputPath/kabName options give the artifact path; projects with a\n * `splash` target produce layer KABs; ui/external/*.kab files are\n * prebuilt artifacts.\n * - java: modules listed in the java/pom.xml aggregator whose pom uses the\n * kos-kab-maven-plugin (same java/pom.xml contract as build-java.sh).\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { KAB_OUTPUT_DIR, resolveKabPath } from \"./kab-targets\";\n\nexport interface DiscoveredArtifact {\n id: string;\n filename: string;\n layer?: number;\n}\n\nexport interface CiSyncOptions {\n /** Remove stale entries instead of keeping and reporting them. */\n prune?: boolean;\n}\n\nexport interface CiSyncManifestResult {\n added: string[];\n stale: string[];\n pruned: string[];\n}\n\nexport interface CiSyncResult {\n manifests: Record<string, CiSyncManifestResult>;\n discovered: { ui: DiscoveredArtifact[]; java: DiscoveredArtifact[] };\n}\n\nconst UI_PROJECT_DIRS = [\n \"apps\",\n \"libs\",\n \"plugins\",\n \"splash\",\n \"themes\",\n \"content\",\n \"translations\",\n];\n\nfunction joinArtifactPath(outputPath: string, fileName: string): string {\n return `${outputPath.replace(/\\/+$/, \"\")}/${fileName}`;\n}\n\nexport function discoverUiArtifacts(\n codegenFs: CodegenFileSystem\n): DiscoveredArtifact[] {\n const artifacts: DiscoveredArtifact[] = [];\n\n for (const dir of UI_PROJECT_DIRS) {\n for (const file of codegenFs.listFiles(`ui/${dir}`)) {\n if (!file.endsWith(\"project.json\")) continue;\n const raw = codegenFs.read(file);\n if (raw === null) continue;\n let project: any;\n try {\n project = JSON.parse(raw);\n } catch {\n continue;\n }\n const name = project.name;\n if (!name) continue;\n\n // Artifact paths are {projectRoot}-tokenized so projects can move; the\n // build handler needs a literal path, and the project.json's own\n // location is the project root (Nx allows no other).\n const projectRoot = file.slice(\"ui/\".length, file.lastIndexOf(\"/\"));\n const resolve = (value: string) => resolveKabPath(value, projectRoot);\n\n const kabOptions = project.targets?.kab?.options;\n if (kabOptions?.outputPath && kabOptions?.kabName) {\n artifacts.push({\n id: name,\n filename: `ui/${joinArtifactPath(\n resolve(kabOptions.outputPath),\n kabOptions.kabName\n )}`,\n });\n } else if (project.targets?.splash) {\n // splashtool writes the layer KAB into its target's outputPath; fall\n // back to the standard <projectRoot>/target/ when it is unset.\n const splashOutput = project.targets.splash.options?.outputPath as\n | string\n | undefined;\n artifacts.push({\n id: name,\n filename: `ui/${joinArtifactPath(\n resolve(splashOutput ?? `{projectRoot}/${KAB_OUTPUT_DIR}`),\n `${name}.kab`\n )}`,\n layer: 1,\n });\n }\n }\n }\n\n for (const file of codegenFs.listFiles(\"ui/external\")) {\n if (!file.endsWith(\".kab\")) continue;\n const base = file.slice(file.lastIndexOf(\"/\") + 1, -\".kab\".length);\n artifacts.push({ id: base, filename: file });\n }\n\n return artifacts;\n}\n\nexport function discoverJavaArtifacts(\n codegenFs: CodegenFileSystem\n): DiscoveredArtifact[] {\n const aggregator = codegenFs.read(\"java/pom.xml\");\n if (aggregator === null) return [];\n\n const artifacts: DiscoveredArtifact[] = [];\n for (const match of aggregator.matchAll(/<module>([^<]+)<\\/module>/g)) {\n const moduleDir = match[1];\n const pom = codegenFs.read(`java/${moduleDir}/pom.xml`);\n if (pom === null || !pom.includes(\"kos-kab-maven-plugin\")) continue;\n // The project's own artifactId is the first one outside any <parent>.\n const withoutParent = pom.replace(/<parent>[\\s\\S]*?<\\/parent>/, \"\");\n const artifactId = withoutParent.match(\n /<artifactId>([^<]+)<\\/artifactId>/\n )?.[1];\n if (!artifactId) continue;\n artifacts.push({\n id: moduleDir,\n // eslint-disable-next-line no-template-curly-in-string\n filename: `java/${moduleDir}/target/${artifactId}-\\${KOS_STD_VERSION_REGEX}.kab`,\n });\n }\n return artifacts;\n}\n\nfunction syncManifest(\n codegenFs: CodegenFileSystem,\n manifestPath: string,\n discovered: DiscoveredArtifact[],\n prune: boolean\n): CiSyncManifestResult | null {\n const raw = codegenFs.read(manifestPath);\n if (raw === null) return null;\n const manifest = JSON.parse(raw);\n const existing: any[] = manifest.artifacts ?? [];\n\n const byFilename = new Map(discovered.map((d) => [d.filename, d]));\n const kept: any[] = [];\n const stale: string[] = [];\n const pruned: string[] = [];\n\n for (const entry of existing) {\n if (byFilename.has(entry.filename)) {\n kept.push(entry);\n byFilename.delete(entry.filename);\n } else if (prune) {\n pruned.push(entry.id ?? entry.filename);\n } else {\n kept.push(entry);\n stale.push(entry.id ?? entry.filename);\n }\n }\n\n const added: string[] = [];\n for (const artifact of byFilename.values()) {\n kept.push({\n id: artifact.id,\n filename: artifact.filename,\n artifactstore: \"kos-cdn\",\n marketplace: 1,\n ...(artifact.layer !== undefined ? { layer: artifact.layer } : {}),\n });\n added.push(artifact.id);\n }\n\n if (added.length > 0 || pruned.length > 0) {\n manifest.artifacts = kept;\n codegenFs.write(manifestPath, JSON.stringify(manifest, null, 2) + \"\\n\");\n }\n\n return { added, stale, pruned };\n}\n\nexport function syncCiManifests(\n codegenFs: CodegenFileSystem,\n options: CiSyncOptions = {}\n): CiSyncResult {\n const prune = options.prune ?? false;\n const ui = discoverUiArtifacts(codegenFs);\n const java = discoverJavaArtifacts(codegenFs);\n\n const manifests: Record<string, CiSyncManifestResult> = {};\n const plan: Array<[string, DiscoveredArtifact[]]> = [\n [\".github/build-ui.json\", ui],\n [\".github/build-java.json\", java],\n [\".github/build-release.json\", [...ui, ...java]],\n ];\n for (const [manifestPath, discovered] of plan) {\n const result = syncManifest(codegenFs, manifestPath, discovered, prune);\n if (result) {\n manifests[manifestPath] = result;\n }\n }\n\n return { manifests, discovered: { ui, java } };\n}\n","/**\n * Helpers for the java/ half of a polyglot workspace (see\n * generate-polyglot-workspace.ts).\n *\n * The Java modules themselves come from the KOS Maven archetypes\n * (com.kos.archetypes — local-install via github.com/kosdev-code/\n * kos-maven-archetypes); these helpers contribute only the glue the\n * archetypes don't own:\n * - the java/pom.xml aggregator (archetype modules are standalone — no\n * parent link — so an aggregator is needed for `mvn` at java/ and for\n * build-java.sh's java/pom.xml check)\n * - repairs to the generated pom (the archetype references\n * ${kos-kab-maven-plugin.version} without defining it, and depends on\n * api-info which the kos-bom does not manage)\n * - registration of the module's KAB in the kos_build_handler manifests\n *\n * Version numbers are always passed in by the caller (derived from the KOS\n * Maven repo's maven-metadata.xml at run time) — nothing hardcoded here.\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\n\nexport interface EnsureJavaAggregatorOptions {\n groupId: string;\n /** Aggregator artifactId (typically the workspace name). */\n artifactId: string;\n moduleName: string;\n}\n\nexport function ensureJavaAggregatorPom(\n codegenFs: CodegenFileSystem,\n options: EnsureJavaAggregatorOptions\n): void {\n const pomPath = \"java/pom.xml\";\n const existing = codegenFs.read(pomPath);\n if (existing === null) {\n codegenFs.write(\n pomPath,\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n <modelVersion>4.0.0</modelVersion>\n <groupId>${options.groupId}</groupId>\n <artifactId>${options.artifactId}</artifactId>\n <version>0.0.0-SNAPSHOT</version>\n <packaging>pom</packaging>\n <modules>\n <module>${options.moduleName}</module>\n </modules>\n</project>\n`\n );\n return;\n }\n if (existing.includes(`<module>${options.moduleName}</module>`)) {\n return;\n }\n codegenFs.write(\n pomPath,\n existing.replace(\n \"</modules>\",\n ` <module>${options.moduleName}</module>\\n </modules>`\n )\n );\n}\n\nexport interface FinalizeArchetypeModuleOptions {\n moduleName: string;\n /** kos-bom version to pin (replaces the template's 0.0.0-SNAPSHOT). */\n kosVersion?: string;\n /** Fills the template's undefined ${kos-kab-maven-plugin.version}. */\n kabPluginVersion?: string;\n /** Explicit version for the api-info dep the kos-bom doesn't manage. */\n apiInfoVersion?: string;\n}\n\n/**\n * Repair a freshly archetype-generated module for use inside a polyglot\n * workspace. Returns human-readable notes about anything it could NOT fix\n * (missing versions the caller failed to derive) so the CLI can warn.\n */\nexport function finalizeArchetypeModule(\n codegenFs: CodegenFileSystem,\n options: FinalizeArchetypeModuleOptions\n): string[] {\n const { moduleName, kosVersion, kabPluginVersion, apiInfoVersion } = options;\n const notes: string[] = [];\n const pomPath = `java/${moduleName}/pom.xml`;\n let pom = codegenFs.read(pomPath);\n if (pom === null) {\n throw new Error(`Generated module pom not found: ${pomPath}`);\n }\n\n if (pom.includes(\"<kos.version>0.0.0-SNAPSHOT</kos.version>\")) {\n if (kosVersion) {\n pom = pom.replace(\n \"<kos.version>0.0.0-SNAPSHOT</kos.version>\",\n `<kos.version>${kosVersion}</kos.version>`\n );\n } else {\n notes.push(\n \"kos.version is 0.0.0-SNAPSHOT — set it to a released kos-bom version before building\"\n );\n }\n }\n\n if (\n pom.includes(\"${kos-kab-maven-plugin.version}\") &&\n !pom.includes(\"<kos-kab-maven-plugin.version>\")\n ) {\n if (kabPluginVersion) {\n pom = pom.replace(\n /(<kos\\.version>[^<]*<\\/kos\\.version>)/,\n `$1\\n <kos-kab-maven-plugin.version>${kabPluginVersion}</kos-kab-maven-plugin.version>`\n );\n } else {\n notes.push(\n \"the ${kos-kab-maven-plugin.version} property is referenced but undefined — add it before building\"\n );\n }\n }\n\n const unversionedApiInfo = /<artifactId>api-info<\\/artifactId>(\\s*)<\\/dependency>/;\n if (unversionedApiInfo.test(pom)) {\n if (apiInfoVersion) {\n pom = pom.replace(\n unversionedApiInfo,\n `<artifactId>api-info</artifactId>$1 <version>${apiInfoVersion}</version>$1</dependency>`\n );\n } else {\n notes.push(\n \"api-info has no version and is not managed by the kos-bom — add one before building\"\n );\n }\n }\n\n codegenFs.write(pomPath, pom);\n\n // Standalone-repo extras the archetype ships that are redundant inside a\n // polyglot workspace (the repo root owns CI):\n const githubDir = `java/${moduleName}/github`;\n if (codegenFs.exists(githubDir)) {\n for (const file of codegenFs.listFiles(githubDir)) {\n codegenFs.delete(file);\n }\n }\n const gitignore = codegenFs.read(`java/${moduleName}/gitignore`);\n if (gitignore !== null) {\n codegenFs.write(`java/${moduleName}/.gitignore`, gitignore);\n codegenFs.delete(`java/${moduleName}/gitignore`);\n }\n\n return notes;\n}\n\nexport interface AddJavaArtifactOptions {\n moduleName: string;\n}\n\n/**\n * Register the module's KAB in build-java.json and build-release.json.\n * Only the artifacts arrays are touched — keyset/build_cmd/etc. are the\n * user's (same contract as ci:sync).\n */\nexport function addJavaArtifactToManifests(\n codegenFs: CodegenFileSystem,\n options: AddJavaArtifactOptions\n): void {\n const { moduleName } = options;\n for (const manifestPath of [\n \".github/build-java.json\",\n \".github/build-release.json\",\n ]) {\n const raw = codegenFs.read(manifestPath);\n if (raw === null) {\n continue;\n }\n const manifest = JSON.parse(raw);\n manifest.artifacts = manifest.artifacts ?? [];\n if (\n manifest.artifacts.some(\n (artifact: { id?: string }) => artifact.id === moduleName\n )\n ) {\n continue;\n }\n manifest.artifacts.push({\n id: moduleName,\n // eslint-disable-next-line no-template-curly-in-string\n filename: `java/${moduleName}/target/${moduleName}-\\${KOS_STD_VERSION_REGEX}.kab`,\n artifactstore: \"kos-cdn\",\n marketplace: 1,\n });\n codegenFs.write(manifestPath, JSON.stringify(manifest, null, 2) + \"\\n\");\n }\n}\n","/**\n * Normalize generator options — resolves project references and generates\n * all case variants for template substitution.\n *\n * Ported from kos-nx-plugin/src/generators/kos-model/lib/normalize-options.ts.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { readJson } from \"../json-utils\";\nimport { normalizeAllValues } from \"../normalize-values\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../project-discovery\";\n\nexport interface KosBaseGeneratorOptions {\n name: string;\n modelProject: string;\n registrationProject?: string;\n skipRegistration?: boolean;\n modelDirectory: string;\n companion?: boolean;\n companionModel?: string;\n companionModelProject?: string;\n companionPattern?: \"composition\" | \"decorator\";\n futureAware?: \"none\" | \"minimal\" | \"complete\";\n}\n\nexport type NormalizedOptions<T extends KosBaseGeneratorOptions> = T & {\n nameDashCase: string;\n nameProperCase: string;\n nameCamelCase: string;\n namePascalCase: string;\n nameConstantCase: string;\n nameLowerCase: string;\n companionModelDashCase: string;\n companionModelProperCase: string;\n companionModelCamelCase: string;\n companionModelPascalCase: string;\n companionModelConstantCase: string;\n companionModelLowerCase: string;\n registrationProject: string;\n importPath: string;\n template: string;\n [key: string]: any;\n};\n\n/**\n * Normalize generator options by resolving the model project and generating\n * all name variants for template substitution.\n *\n * @param codegenFs - Filesystem abstraction\n * @param options - Raw generator options\n * @param projects - Optional pre-computed project map\n */\nexport function normalizeOptions<T extends KosBaseGeneratorOptions>(\n codegenFs: CodegenFileSystem,\n options: T,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedOptions<T> {\n const toNormalize: Record<string, string> = {\n name: options.name,\n };\n\n if ((options as any).modelName) {\n toNormalize.modelName = (options as any).modelName;\n }\n\n if (options.companionModel) {\n toNormalize.companionModel = options.companionModel;\n }\n\n const normalizedValues = normalizeAllValues(toNormalize);\n const modelProject = options.modelProject;\n const registrationProject = options.registrationProject || \"\";\n const useModelProject = modelProject !== \"__NONE__\";\n\n let importPath = \"\";\n if (useModelProject) {\n const modelProjectConfig = findProjectByName(\n codegenFs.root,\n modelProject,\n projects\n );\n if (modelProjectConfig) {\n const pkgJsonPath = path.join(modelProjectConfig.root, \"package.json\");\n try {\n const pkgJson = readJson<{ name: string }>(codegenFs, pkgJsonPath);\n importPath = pkgJson.name || \"\";\n } catch {\n importPath = \"\";\n }\n }\n }\n\n // Provide safe defaults for optional boolean fields that templates reference\n // directly. Without explicit values, EJS throws ReferenceError for variables\n // that are simply absent from the options object (undefined keys are omitted\n // by the spread, which is different from being present-but-false).\n const booleanDefaults: Partial<KosBaseGeneratorOptions> = {\n companion: false,\n skipRegistration: false,\n futureAware: \"none\",\n };\n\n return {\n ...booleanDefaults,\n ...options,\n ...normalizedValues,\n modelProject,\n importPath,\n registrationProject,\n template: \"\",\n } as NormalizedOptions<T>;\n}\n","/**\n * Shared model-augmentation toolkit (ts-morph / AST based).\n *\n * Primitives for the capability mutators (add-container-support, add-future, …)\n * that augment an EXISTING model with coordinated, multi-site edits — decorators,\n * declaration-merging interfaces, imports, methods — without the fragility of\n * regex string replacement.\n *\n * Bridged through CodegenFileSystem so the same dry-run overlay + formatFiles\n * pipeline used by the scaffolders applies unchanged: read content → in-memory\n * ts-morph SourceFile → mutate → getFullText() → write.\n *\n * ts-morph is confined to kos-codegen-core (build-time tooling) and must not leak\n * into any runtime SDK package.\n */\nimport {\n Project,\n IndentationText,\n QuoteKind,\n Scope,\n VariableDeclarationKind,\n type SourceFile,\n type ClassDeclaration,\n} from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\n\n/**\n * Read a file via the filesystem abstraction, apply an AST mutation, write it back.\n * The mutation operates on an in-memory ts-morph SourceFile — no disk access here,\n * so the caller's CodegenFileSystem (real or dry-run overlay) owns all I/O.\n */\nexport function transformSourceFile(\n codegenFs: CodegenFileSystem,\n filePath: string,\n mutate: (sf: SourceFile) => void\n): void {\n const content = codegenFs.read(filePath);\n if (content === null) {\n throw new Error(`File not found: ${filePath}`);\n }\n const project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Double,\n },\n });\n const sourceFile = project.createSourceFile(filePath, content, {\n overwrite: true,\n });\n mutate(sourceFile);\n codegenFs.write(filePath, sourceFile.getFullText());\n}\n\n/**\n * Read a file via the filesystem abstraction and inspect it as a ts-morph\n * SourceFile, writing nothing back. The read-only counterpart of\n * `transformSourceFile`, for discovery over generated declarations.\n */\nexport function readSourceFile<T>(\n codegenFs: CodegenFileSystem,\n filePath: string,\n inspect: (sf: SourceFile) => T\n): T {\n const content = codegenFs.read(filePath);\n if (content === null) {\n throw new Error(`File not found: ${filePath}`);\n }\n const project = new Project({ useInMemoryFileSystem: true });\n return inspect(\n project.createSourceFile(filePath, content, { overwrite: true })\n );\n}\n\n/** A named import to ensure on a module: the symbol and whether it is type-only. */\nexport interface NamedImportSpec {\n name: string;\n isTypeOnly?: boolean;\n}\n\n/**\n * Ensure the given named imports exist on an import from `moduleSpecifier`.\n * Idempotent: existing names are left untouched; the import declaration is created\n * if absent. Resolves to the same module the model already imports `kosModel` from\n * when `moduleSpecifier` matches, so internal vs. published paths are respected.\n */\nexport function ensureNamedImport(\n sourceFile: SourceFile,\n moduleSpecifier: string,\n names: NamedImportSpec[]\n): void {\n const decls = sourceFile\n .getImportDeclarations()\n .filter((d) => d.getModuleSpecifierValue() === moduleSpecifier);\n\n // Dedup across ALL imports from this module (a file may have both a value\n // import and a separate `import type { … }` from the same specifier).\n const existing = new Set<string>();\n for (const d of decls) {\n for (const n of d.getNamedImports()) existing.add(n.getName());\n }\n\n // Always target a VALUE import declaration — adding a runtime symbol to an\n // `import type { … }` block would strip it at compile time. Type-only names go\n // in with an inline `type` modifier (the `import { kosX, type KosX }` idiom).\n let target = decls.find((d) => !d.isTypeOnly());\n if (!target) {\n target = sourceFile.addImportDeclaration({ moduleSpecifier });\n }\n\n for (const { name, isTypeOnly } of names) {\n if (existing.has(name)) continue;\n target.addNamedImport({ name, isTypeOnly: !!isTypeOnly });\n existing.add(name);\n }\n}\n\n/**\n * Resolve the module specifier the model imports `kosModel` from, so augmentation\n * imports land on the same line/source (internal `../../../core/core/decorators`\n * vs. published `@kosdev-code/kos-ui-sdk`). Falls back to the published package.\n */\nexport function resolveSdkModuleSpecifier(sourceFile: SourceFile): string {\n const decl = sourceFile\n .getImportDeclarations()\n .find((d) => d.getNamedImports().some((n) => n.getName() === \"kosModel\"));\n return decl?.getModuleSpecifierValue() ?? \"@kosdev-code/kos-ui-sdk\";\n}\n\n/**\n * Find the primary model class. Prefers `preferName`, then a class whose name ends\n * in `ModelImpl`, then the first exported class, then the first class.\n */\nexport function getModelClass(\n sourceFile: SourceFile,\n preferName?: string\n): ClassDeclaration {\n const classes = sourceFile.getClasses();\n const byName = preferName\n ? classes.find((c) => c.getName() === preferName)\n : undefined;\n if (byName) return byName;\n const impl = classes.find((c) => /ModelImpl$/.test(c.getName() ?? \"\"));\n if (impl) return impl;\n const exported = classes.find((c) => c.isExported());\n if (exported) return exported;\n if (classes.length > 0) return classes[0];\n throw new Error(\"No class declaration found in model file.\");\n}\n\n/**\n * Add a class decorator idempotently (matched by decorator name). Supports type\n * arguments (`@name<T>(args)`) which ts-morph's structured API can't express, by\n * writing the call expression as decorator text. Inserts directly after `@kosModel`\n * when present (matching KOS convention), otherwise nearest the class.\n */\nexport function addClassDecorator(\n cls: ClassDeclaration,\n name: string,\n opts?: { typeArgs?: string[]; argsText?: string }\n): void {\n if (cls.getDecorator(name)) return;\n const typeArgs = opts?.typeArgs?.length\n ? `<${opts.typeArgs.join(\", \")}>`\n : \"\";\n const args = opts?.argsText ?? \"\";\n\n const decorators = cls.getDecorators();\n const kosModelIdx = decorators.findIndex((d) => d.getName() === \"kosModel\");\n const insertIdx = kosModelIdx >= 0 ? kosModelIdx + 1 : decorators.length;\n cls.insertDecorator(insertIdx, {\n name: `${name}${typeArgs}`,\n arguments: args ? [args] : [],\n });\n}\n\n/**\n * Ensure a declaration-merging interface `export interface <name> extends <expr>`.\n * If the interface already exists (e.g. merged for another capability), adds the\n * extends expression to it; otherwise creates an empty exported interface with the\n * `no-empty-interface` lint suppression. Idempotent by base type name.\n */\nexport function ensureDeclarationMerge(\n sourceFile: SourceFile,\n interfaceName: string,\n extendsExpr: string,\n typeParameters: string[] = []\n): void {\n const baseType = extendsExpr.split(\"<\")[0].trim();\n let iface = sourceFile.getInterface(interfaceName);\n if (iface) {\n const already = iface\n .getExtends()\n .some((e) => e.getText().split(\"<\")[0].trim() === baseType);\n if (!already) iface.addExtends(extendsExpr);\n return;\n }\n // A merged interface must carry the SAME type parameters as the class it merges\n // with, or TS errors (\"all declarations must have identical type parameters\").\n iface = sourceFile.addInterface({\n name: interfaceName,\n isExported: true,\n typeParameters,\n extends: [extendsExpr],\n });\n // Prepend the empty-interface lint suppression line.\n sourceFile.insertText(\n iface.getStart(),\n \"// eslint-disable-next-line @typescript-eslint/no-empty-interface\\n\"\n );\n}\n\n/**\n * Ensure a file-level eslint-disable block comment for `rule` at the top of file.\n * Call LAST in a mutation — it uses raw text insertion and invalidates node refs.\n */\nexport function ensureFileEslintDisable(\n sourceFile: SourceFile,\n rule: string\n): void {\n if (sourceFile.getFullText().includes(rule)) return;\n sourceFile.insertText(0, `/* eslint-disable ${rule} */\\n`);\n}\n\n/**\n * Add a module-level `const` after the import block, idempotently. Returns true\n * if added. Used for endpoint descriptors, which must sit outside the class so\n * `typeof NAME` can be referenced from a parameter type.\n */\nexport function ensureModuleConst(\n sourceFile: SourceFile,\n spec: { name: string; initializer: string }\n): boolean {\n if (sourceFile.getVariableDeclaration(spec.name)) return false;\n const imports = sourceFile.getImportDeclarations();\n const index =\n imports.length > 0 ? imports[imports.length - 1].getChildIndex() + 1 : 0;\n sourceFile.insertVariableStatement(index, {\n declarationKind: VariableDeclarationKind.Const,\n declarations: [{ name: spec.name, initializer: spec.initializer }],\n });\n return true;\n}\n\n/** A decorated method to add to a model class. */\nexport interface DecoratedMethodSpec {\n name: string;\n decoratorName: string;\n decoratorArgsText?: string;\n parameters?: { name: string; type?: string; optional?: boolean }[];\n returnType?: string;\n isAsync?: boolean;\n statements?: string;\n}\n\n/**\n * Add a decorated method to a class idempotently (skips if a method of that name\n * already exists). Returns true if added.\n */\nexport function addDecoratedMethod(\n cls: ClassDeclaration,\n spec: DecoratedMethodSpec\n): boolean {\n if (cls.getMethod(spec.name)) return false;\n cls.addMethod({\n name: spec.name,\n isAsync: spec.isAsync,\n returnType: spec.returnType,\n parameters: spec.parameters?.map((p) => {\n return { name: p.name, type: p.type, hasQuestionToken: p.optional };\n }),\n statements: spec.statements,\n decorators: [\n {\n name: spec.decoratorName,\n arguments: spec.decoratorArgsText ? [spec.decoratorArgsText] : [],\n },\n ],\n });\n return true;\n}\n\n/** A plain (undecorated) property to add to a model class. */\nexport interface PlainPropertySpec {\n name: string;\n type?: string;\n /** Initializer expression text, e.g. `\"\"`, `0`, `false`. */\n initializer?: string;\n scope?: \"private\" | \"protected\" | \"public\";\n readonly?: boolean;\n /** Definite-assignment `!` (compiles under strictPropertyInitialization). */\n hasExclamation?: boolean;\n}\n\n/**\n * Member index for a new property: right after the last existing property, so\n * properties (basic fields, dependencies, config properties) stay grouped at the\n * TOP of the class — before the constructor and methods. Index 0 if none yet.\n */\nfunction propertyInsertIndex(cls: ClassDeclaration): number {\n const props = cls.getProperties();\n if (props.length === 0) return 0;\n return props[props.length - 1].getChildIndex() + 1;\n}\n\n/**\n * Add a plain class property (no decorator) idempotently. Returns true if added.\n * Used for basic model state fields (`prop1: string`) — distinct from the\n * decorator-backed config/dependency/etc. properties. Inserted at the top.\n */\nexport function addPlainProperty(\n cls: ClassDeclaration,\n spec: PlainPropertySpec\n): boolean {\n if (cls.getProperty(spec.name)) return false;\n cls.insertProperty(propertyInsertIndex(cls), {\n name: spec.name,\n type: spec.type,\n initializer: spec.initializer,\n isReadonly: !!spec.readonly,\n scope: spec.scope ? SCOPE_MAP[spec.scope] : undefined,\n hasExclamationToken: spec.initializer ? false : !!spec.hasExclamation,\n });\n return true;\n}\n\n/** A decorated property to add to a model class. */\nexport interface DecoratedPropertySpec {\n name: string;\n decoratorName: string;\n decoratorArgsText?: string;\n type?: string;\n scope?: \"private\" | \"protected\" | \"public\";\n hasExclamation?: boolean;\n /** Initializer expression text, e.g. `new KosModelContainer<X>()` or `[]`. */\n initializer?: string;\n /**\n * Emit the decorator WITHOUT call parens — a DIRECT (non-factory) decorator like\n * `@kosChild`. Default false (factory form `@name()` / `@name(args)`).\n */\n bare?: boolean;\n}\n\nconst SCOPE_MAP = {\n private: Scope.Private,\n protected: Scope.Protected,\n public: Scope.Public,\n} as const;\n\n/**\n * Add a decorated property to a class idempotently (skips if a property of that\n * name already exists). Returns true if added.\n */\nexport function addDecoratedProperty(\n cls: ClassDeclaration,\n spec: DecoratedPropertySpec\n): boolean {\n if (cls.getProperty(spec.name)) return false;\n cls.insertProperty(propertyInsertIndex(cls), {\n name: spec.name,\n type: spec.type,\n initializer: spec.initializer,\n scope: spec.scope ? SCOPE_MAP[spec.scope] : undefined,\n hasExclamationToken: spec.initializer ? false : !!spec.hasExclamation,\n decorators: [\n spec.bare && !spec.decoratorArgsText\n ? { name: spec.decoratorName } // no `arguments` key → bare `@name`, no parens\n : {\n name: spec.decoratorName,\n arguments: spec.decoratorArgsText ? [spec.decoratorArgsText] : [],\n },\n ],\n });\n return true;\n}\n\n/** A computed getter to add to a model class. */\nexport interface GetterSpec {\n name: string;\n returnType?: string;\n /** Body statements; default a TODO stub returning undefined. */\n statements?: string;\n}\n\n/**\n * Add a computed getter (`get name(): T { ... }`) idempotently — a derived,\n * read-only member. Returns true if added. Placed after the constructor (or after\n * the properties if there is none), ahead of regular methods.\n */\nexport function addGetter(cls: ClassDeclaration, spec: GetterSpec): boolean {\n if (cls.getGetAccessor(spec.name)) return false;\n const ctor = cls.getConstructors()[0];\n const index = ctor ? ctor.getChildIndex() + 1 : propertyInsertIndex(cls);\n cls.insertGetAccessor(index, {\n name: spec.name,\n returnType: spec.returnType,\n statements:\n spec.statements ?? \"// TODO: derive and return the computed value\",\n });\n return true;\n}\n","/**\n * Enumerate the service operations a project already has types for.\n *\n * NOT a substitute for the device. A connected device's live OpenAPI is the\n * source of truth about what endpoints exist, what they mean, and whether one\n * is debug-only — discover there first (kos-device: `search_services` →\n * `describe_endpoint` → `resolve_service_request`). This reads the types\n * `api:generate` already wrote into the project, which is a SNAPSHOT of that\n * truth: correct for the app/version it was generated from, silent about\n * anything added since, and empty until api:generate has run.\n *\n * It exists for the offline case — no device reachable, or a human picking from\n * a list rather than typing a path from memory.\n *\n * Everything here comes out of `openapi.d.ts`, which openapi-typescript emits in\n * a shape precise enough to read structurally: a method that exists is\n * `post: { … }` while an absent one is `post?: never`, the OpenAPI `summary`\n * survives as the method's JSDoc, and path parameters keep their names.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { readSourceFile } from \"./augment/ts-toolkit\";\n\n/** HTTP methods a response type can be derived for (lowercase, as spec'd). */\nconst CATALOG_METHODS = [\"get\", \"put\", \"post\", \"delete\", \"patch\"] as const;\nexport type CatalogMethod = (typeof CATALOG_METHODS)[number];\n\nexport interface ServiceOperation {\n /** OpenAPI path, e.g. `/api/board/{id}`. */\n path: string;\n method: CatalogMethod;\n /** The spec's `summary`, when it had one. */\n summary?: string;\n /** Names of the `{…}` placeholders the path declares, in order. */\n pathParams: string[];\n}\n\nexport interface ServiceCatalogEntry {\n /** App segment of the services dir, e.g. `dispense`. */\n app: string;\n /** Version segment, e.g. `daily` or `1.9.x`. */\n version: string;\n /** Root-relative path of the generated service module (with extension). */\n serviceModulePath: string;\n operations: ServiceOperation[];\n}\n\nconst SERVICE_MODULE_RE = /\\/utils\\/services\\/([^/]+)\\/([^/]+)\\/service\\.ts$/;\n\nexport interface ServiceCatalogQuery {\n /** Project whose generated types to read. */\n modelProject: string;\n /** Limit to one app segment (e.g. `dispense`). */\n app?: string;\n /** Limit to one version segment (e.g. `daily`). */\n version?: string;\n}\n\n/**\n * List every generated service module in a project and the operations it types.\n * Returns an empty array when the project has no generated types — the caller\n * should tell the user to run `api:generate`, not treat it as \"no endpoints\".\n */\nexport function listServiceCatalog(\n codegenFs: CodegenFileSystem,\n query: ServiceCatalogQuery,\n projects?: Map<string, ProjectConfiguration>\n): ServiceCatalogEntry[] {\n const project = findProjectByName(\n codegenFs.root,\n query.modelProject,\n projects\n );\n if (!project) {\n throw new Error(`Project not found: ${query.modelProject}`);\n }\n const sourceRoot = project.sourceRoot || path.join(project.root, \"src\");\n\n const entries: ServiceCatalogEntry[] = [];\n for (const file of codegenFs.listFiles(sourceRoot)) {\n const posix = file.split(path.sep).join(\"/\");\n const match = SERVICE_MODULE_RE.exec(posix);\n if (!match) continue;\n const [, app, version] = match;\n if (query.app && app !== query.app) continue;\n if (query.version && version !== query.version) continue;\n\n const openapiPath = posix.replace(/service\\.ts$/, \"openapi.d.ts\");\n if (!codegenFs.exists(openapiPath)) continue;\n\n entries.push({\n app,\n version,\n serviceModulePath: posix,\n operations: readOperations(codegenFs, openapiPath),\n });\n }\n return entries.sort(\n (a, b) => a.app.localeCompare(b.app) || a.version.localeCompare(b.version)\n );\n}\n\n/** Parse one `openapi.d.ts` into its operations. */\nfunction readOperations(\n codegenFs: CodegenFileSystem,\n openapiPath: string\n): ServiceOperation[] {\n return readSourceFile(codegenFs, openapiPath, (sf) => {\n const paths = sf.getInterface(\"paths\");\n if (!paths) return [];\n\n const operations: ServiceOperation[] = [];\n for (const pathProp of paths.getProperties()) {\n const servicePath = unquote(pathProp.getName());\n const literal = pathProp.getTypeNode();\n // Each path maps to a type literal of per-method members; anything else\n // is a shape this parser does not claim to understand.\n if (!literal || !(\"getProperties\" in literal)) continue;\n\n for (const methodProp of (literal as any).getProperties()) {\n const method = methodProp.getName();\n if (!isCatalogMethod(method)) continue;\n const typeText: string = methodProp.getTypeNode()?.getText() ?? \"\";\n // `post?: never` is the spec saying this path has no POST.\n if (methodProp.hasQuestionToken() && typeText === \"never\") continue;\n\n operations.push({\n path: servicePath,\n method,\n summary: readSummary(methodProp),\n pathParams: [...servicePath.matchAll(/\\{([^}]+)\\}/g)].map(\n (m) => m[1]\n ),\n });\n }\n }\n return operations;\n });\n}\n\nfunction isCatalogMethod(value: string): value is CatalogMethod {\n return (CATALOG_METHODS as readonly string[]).includes(value);\n}\n\n/** The OpenAPI `summary`, which openapi-typescript emits as leading JSDoc. */\nfunction readSummary(methodProp: {\n getLeadingCommentRanges: () => { getText: () => string }[];\n}): string | undefined {\n const text = methodProp\n .getLeadingCommentRanges()\n .map((c) => c.getText())\n .join(\" \")\n .replace(/^\\/\\*+/, \"\")\n .replace(/\\*+\\/$/, \"\")\n .replace(/^\\s*\\*\\s?/gm, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n return text || undefined;\n}\n\nfunction unquote(name: string): string {\n return name.replace(/^[\"']|[\"']$/g, \"\");\n}\n","/**\n * Source of tools/scripts/update-release-version.mjs — the implementation of\n * the `version` target emitted by buildKabTargets (see kab-targets.ts).\n *\n * Kept as a constant (not a .template file) so the preset generator and the\n * add-version-targets migration emit byte-identical scripts and cannot drift.\n * The script has no template variables: the project name arrives via argv.\n */\nexport const UPDATE_RELEASE_VERSION_SCRIPT = `import devkit from \"@nx/devkit\";\nimport { resolve } from \"path\";\nimport { readFileSync, writeFileSync } from \"fs\";\nimport prettier from \"prettier\";\n\n// KOS artifact versioning: stamps the project's .kos.json \"version\" field\n// (which kabtool bakes into the KAB). Never touches package.json.\n// Driven by tag-based releases:\n// nx run-many --target=version --args=--ver=$KOSBUILD_VERSION\n\nconst { readCachedProjectGraph } = devkit;\nconst [, , name, versionArg] = process.argv;\n\n// \"{args.ver}\" arrives literally when the target runs without --args=--ver=<v>;\n// treat that (or a missing arg) as \"report current version, change nothing\".\nconst version =\n versionArg && !versionArg.startsWith(\"{args\") ? versionArg : undefined;\n\nif (!name) {\n console.error(\"usage: update-release-version.mjs <project> <version>\");\n process.exit(1);\n}\n\nconst graph = readCachedProjectGraph();\nconst project = graph.nodes[name];\nif (!project) {\n console.error(\"Unknown project: \" + name);\n process.exit(1);\n}\n\nconst kosJsonPath = resolve(process.cwd(), project.data.root, \".kos.json\");\nlet kosJson;\ntry {\n kosJson = JSON.parse(readFileSync(kosJsonPath, \"utf8\"));\n} catch {\n console.error(\"Missing or invalid .kos.json: \" + kosJsonPath);\n process.exit(1);\n}\n\nif (!version) {\n console.log(name + \": \" + kosJson.version + \" (no --ver given; unchanged)\");\n process.exit(0);\n}\n\nconst prettierOptions = await prettier.resolveConfig(kosJsonPath);\nconst output = await prettier.format(\n JSON.stringify({ ...kosJson, version }, null, 2),\n { ...prettierOptions, parser: \"json\" }\n);\nwriteFileSync(kosJsonPath, output);\nconsole.log(name + \": version -> \" + version);\n`;\n","/**\n * Barrel export manipulation utilities.\n *\n * Appends `export * from './path'` lines to index.ts files,\n * handling deduplication.\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\n\n/**\n * Append a barrel re-export to an index.ts file, creating it if necessary.\n * Skips the append if the export already exists.\n *\n * @param codegenFs - Filesystem abstraction\n * @param indexPath - Path to the index.ts file (relative to root)\n * @param exportPath - The module path to export (e.g. './my-hook')\n */\nexport function appendBarrelExport(\n codegenFs: CodegenFileSystem,\n indexPath: string,\n exportPath: string\n): void {\n const exportLine = `export * from '${exportPath}'`;\n const content = codegenFs.read(indexPath) ?? \"\";\n const lines = content.split(\"\\n\");\n\n if (lines.some((line) => line.includes(exportLine))) {\n return; // already present\n }\n\n lines.push(exportLine);\n codegenFs.write(indexPath, lines.join(\"\\n\"));\n}\n","/**\n * TypeScript AST-based index.ts updater.\n *\n * Adds `export * from './path'` declarations to a barrel file using\n * the TypeScript compiler API for proper AST manipulation.\n *\n * Ported from kos-nx-plugin/src/generators/kos-model/lib/utils/ts-visitor.ts.\n */\nimport * as ts from \"typescript\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { getCodegenLogger } from \"../logger\";\n\n/**\n * Add an export-all declaration to an index.ts file using TS AST.\n *\n * @param codegenFs - Filesystem abstraction\n * @param indexPath - Path to the index.ts file (relative to root)\n * @param modelPath - Relative path to export (e.g. 'models/my-model')\n */\nexport function updateModelIndex(\n codegenFs: CodegenFileSystem,\n indexPath: string,\n modelPath: string\n): void {\n const logger = getCodegenLogger();\n\n if (!indexPath) return;\n\n const content = codegenFs.read(indexPath);\n if (content === null) {\n logger.warn(`Index file not found: ${indexPath}`);\n return;\n }\n\n logger.info(`Updating ${indexPath} — adding export for ${modelPath}`);\n\n const sourceFile = ts.createSourceFile(\n indexPath,\n content,\n ts.ScriptTarget.Latest,\n true\n );\n\n // Idempotent: the model and container passes both target the same directory,\n // and generators may be re-run — never append a duplicate export.\n const alreadyExported = sourceFile.statements.some(\n (st) =>\n ts.isExportDeclaration(st) &&\n st.moduleSpecifier !== undefined &&\n ts.isStringLiteral(st.moduleSpecifier) &&\n st.moduleSpecifier.text === `./${modelPath}`\n );\n if (alreadyExported) {\n logger.info(`Export for ${modelPath} already present in ${indexPath}`);\n return;\n }\n\n const exportDeclaration = ts.factory.createExportDeclaration(\n undefined,\n false,\n undefined,\n ts.factory.createStringLiteral(`./${modelPath}`)\n );\n\n const updatedSourceFile = ts.factory.updateSourceFile(sourceFile, [\n ...sourceFile.statements,\n exportDeclaration,\n ]);\n\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n const newContents = printer.printFile(updatedSourceFile);\n\n codegenFs.write(indexPath, newContents);\n}\n","/**\n * Core generator: KOS Hook.\n *\n * Generates a hook file set inside an app project and updates the barrel export.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport {\n getCurrentDirectoryName,\n getKosModelConfiguration,\n getKosProjectConfiguration,\n getProject,\n} from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { appendBarrelExport } from \"./barrel-utils\";\n\nexport interface HookOptions extends KosBaseGeneratorOptions {\n appProject: string;\n appDirectory: string;\n singleton?: boolean;\n internal?: boolean;\n}\n\n/**\n * Generate a KOS hook.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory\n * @param options - Generator options (mutated to fill in defaults)\n * @param cwd - Current working directory for project resolution\n * @param projects - Optional pre-computed project map\n */\nexport function generateHook(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: HookOptions,\n cwd: string,\n projects?: Map<string, ProjectConfiguration>\n): void {\n if (!options.appProject) {\n throw new Error(\"No app project specified\");\n }\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n const modelName = options.name || getCurrentDirectoryName(cwd);\n if (!modelName) {\n throw new Error(\n \"No model name found. Please specify a model name with --name.\"\n );\n }\n\n const kosModelConfig = getKosModelConfiguration(\n codegenFs,\n modelProjectName,\n modelName,\n projects\n );\n options.singleton = kosModelConfig ? !!kosModelConfig.singleton : false;\n options.name = modelName;\n options.modelProject = modelProjectName;\n\n const normalized = normalizeOptions(codegenFs, options, projects);\n const appProject = findProjectByName(\n codegenFs.root,\n normalized.appProject,\n projects\n );\n if (!appProject) {\n throw new Error(`App project '${normalized.appProject}' not found`);\n }\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n appProject.name,\n projects\n );\n const componentLocation =\n kosConfig?.generator?.defaults?.component?.folder || \"\";\n options.appDirectory = options.appDirectory || componentLocation;\n\n const projectRoot = appProject.sourceRoot;\n if (projectRoot) {\n generateFilesFromTemplates(\n codegenFs,\n templateDir,\n path.join(\n projectRoot,\n options.appDirectory,\n \"hooks\",\n normalized.nameDashCase\n ),\n normalized\n );\n\n appendBarrelExport(\n codegenFs,\n path.join(projectRoot, options.appDirectory, \"hooks\", \"index.ts\"),\n `./${normalized.nameDashCase}`\n );\n }\n}\n","/**\n * Core generator: KOS Context.\n *\n * Generates a context file set inside an app project and updates the barrel export.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport {\n getCurrentDirectoryName,\n getKosModelConfigProp,\n getProject,\n} from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { appendBarrelExport } from \"./barrel-utils\";\n\nexport interface ContextOptions extends KosBaseGeneratorOptions {\n appProject: string;\n appDirectory: string;\n singleton?: boolean;\n internal?: boolean;\n}\n\n/**\n * Generate a KOS context.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory\n * @param options - Generator options (mutated to fill in defaults)\n * @param cwd - Current working directory for project resolution\n * @param projects - Optional pre-computed project map\n */\nexport function generateContext(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: ContextOptions,\n cwd: string,\n projects?: Map<string, ProjectConfiguration>\n): void {\n if (!options.appProject) {\n throw new Error(\"No app project specified\");\n }\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n const modelName = options.name || getCurrentDirectoryName(cwd);\n if (!modelName) {\n throw new Error(\n \"No model name found. Please specify a model name with --name.\"\n );\n }\n\n const singletonProp = getKosModelConfigProp({\n codegenFs,\n project: modelProjectName,\n modelName,\n prop: \"singleton\",\n projects,\n });\n options.singleton = !!singletonProp;\n options.name = modelName;\n options.modelProject = modelProjectName;\n\n const normalized = normalizeOptions(codegenFs, options, projects);\n const appProject = findProjectByName(\n codegenFs.root,\n normalized.appProject,\n projects\n );\n if (!appProject) {\n throw new Error(`App project '${normalized.appProject}' not found`);\n }\n\n const projectRoot = appProject.sourceRoot;\n if (projectRoot) {\n const dir =\n appProject.projectType === \"application\" || options.internal\n ? options.appDirectory\n : options.appDirectory ?? \"lib\";\n\n generateFilesFromTemplates(\n codegenFs,\n templateDir,\n path.join(projectRoot, dir, \"contexts\", normalized.nameDashCase),\n normalized\n );\n\n appendBarrelExport(\n codegenFs,\n path.join(projectRoot, dir, \"contexts\", \"index.ts\"),\n `./${normalized.nameDashCase}`\n );\n }\n}\n","/**\n * Core generator: KOS Container Model.\n *\n * Generates a container model within an existing model project.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { getCodegenLogger } from \"../logger\";\nimport {\n addKosModelConfiguration,\n getCurrentDirectoryName,\n getKosProjectConfiguration,\n getProject,\n} from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { updateModelIndex } from \"./update-model-index\";\n\nexport interface ContainerModelOptions extends KosBaseGeneratorOptions {\n modelName?: string;\n singleton?: boolean;\n dataServices?: boolean;\n autoRegister?: boolean;\n}\n\n/**\n * Generate a container model.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory (containing model/ and services/ subdirs)\n * @param options - Generator options (mutated to fill in defaults)\n * @param cwd - Current working directory for project resolution\n * @param projects - Optional pre-computed project map\n */\nexport function generateContainerModel(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: ContainerModelOptions,\n cwd: string,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n const modelName = options.modelName || getCurrentDirectoryName(cwd);\n if (!modelName) {\n throw new Error(\n \"No model name found. Please specify a model name with --name.\"\n );\n }\n\n options.modelName = modelName;\n options.name = `${modelName}-container`;\n\n const normalized = normalizeOptions(codegenFs, options, projects);\n const projectConfig = findProjectByName(\n codegenFs.root,\n normalized.modelProject,\n projects\n );\n if (!projectConfig) {\n throw new Error(`Model project '${normalized.modelProject}' not found`);\n }\n\n addKosModelConfiguration({\n codegenFs,\n modelName: normalized.nameDashCase,\n projectName: projectConfig.name,\n projectRoot: projectConfig.root,\n singleton: !!options.singleton,\n container: true,\n // The container's exported registration bean (`export const <ProperCase>`).\n factory: normalized.nameProperCase,\n });\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectConfig.name,\n projects\n );\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const internal = !!kosConfig?.generator?.internal;\n options.modelDirectory = options.modelDirectory || modelLocation;\n\n const projectRoot = projectConfig.sourceRoot;\n if (projectRoot) {\n logger.info(\n `Generating container model ${normalized.nameDashCase} in ${projectRoot}`\n );\n\n const modelNameDashCase =\n (normalized as any).modelNameDashCase || normalized.nameDashCase;\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"model\"),\n path.join(projectRoot, options.modelDirectory || \"\", modelNameDashCase),\n { ...normalized, internal }\n );\n\n if (options.dataServices) {\n logger.info(`Generating data services for ${modelNameDashCase}`);\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"services\"),\n path.join(\n projectRoot,\n options.modelDirectory,\n modelNameDashCase,\n \"services\"\n ),\n { ...normalized, internal }\n );\n }\n\n const modelIndex = path.join(projectRoot, \"index.ts\");\n const modelPath = normalized.modelDirectory\n ? `${normalized.modelDirectory}/${modelNameDashCase}`\n : modelNameDashCase;\n updateModelIndex(codegenFs, modelIndex, modelPath);\n }\n}\n","/**\n * Core generator: KOS Companion Model.\n *\n * Generates companion model files into a child project with references\n * to the parent model's package.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { readJson } from \"../json-utils\";\nimport { normalizeAllValues } from \"../normalize-values\";\nimport { getCodegenLogger } from \"../logger\";\nimport { getKosProjectConfiguration } from \"../kos-config\";\n\nexport interface CompanionModelOptions {\n companionModelName: string;\n companionModelProject: string;\n modelName: string;\n modelProject: string;\n companionPattern?: \"composition\" | \"decorator\";\n}\n\n/**\n * Generate a companion model.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory\n * @param options - Generator options\n * @param projects - Optional pre-computed project map\n */\nexport function generateCompanionModel(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: CompanionModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n\n const normalized = normalizeAllValues({\n companionModelName: options.companionModelName,\n modelName: options.modelName,\n });\n\n const companionChildKosConfig = getKosProjectConfiguration(\n codegenFs,\n options.companionModelProject,\n projects\n );\n\n const parentProject = findProjectByName(\n codegenFs.root,\n options.modelProject,\n projects\n );\n const childProject = findProjectByName(\n codegenFs.root,\n options.companionModelProject,\n projects\n );\n\n const projectRoot = childProject?.sourceRoot;\n if (!projectRoot) {\n logger.warn(`Companion child project source root not found`);\n return;\n }\n\n let importPath = \"\";\n if (parentProject) {\n const pkgJsonPath = path.join(parentProject.root, \"package.json\");\n try {\n const pkgJson = readJson<{ name: string }>(codegenFs, pkgJsonPath);\n importPath = pkgJson.name || \"\";\n } catch {\n importPath = \"\";\n }\n }\n\n const modelLocation =\n companionChildKosConfig?.generator?.defaults?.model?.folder || \"\";\n const filePath = path.join(\n projectRoot,\n modelLocation,\n normalized.companionModelNameDashCase\n );\n\n logger.info(`Generating companion model in ${filePath}`);\n generateFilesFromTemplates(codegenFs, templateDir, filePath, {\n ...options,\n ...normalized,\n importPath,\n });\n}\n","/**\n * Core generator: KOS Model.\n *\n * Generates a model within a model project, optionally with container\n * and companion sub-generators.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { updateJson } from \"../json-utils\";\nimport { getCodegenLogger } from \"../logger\";\nimport { getKosProjectConfiguration, getProject } from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { updateModelIndex } from \"./update-model-index\";\nimport {\n generateContainerModel,\n type ContainerModelOptions,\n} from \"./generate-container-model\";\nimport {\n generateCompanionModel,\n type CompanionModelOptions,\n} from \"./generate-companion-model\";\n\nexport interface ModelOptions extends KosBaseGeneratorOptions {\n singleton?: boolean;\n isContainerSingleton?: boolean;\n unitTests?: boolean;\n dataServices?: boolean;\n container?: boolean;\n parentAware?: boolean;\n autoRegister?: boolean;\n /** One-line, human-curated purpose for the model catalog (optional). */\n purpose?: string;\n}\n\nexport interface GenerateModelParams {\n codegenFs: CodegenFileSystem;\n modelTemplateDir: string;\n containerTemplateDir?: string;\n companionTemplateDir?: string;\n options: ModelOptions;\n cwd: string;\n projects?: Map<string, ProjectConfiguration>;\n}\n\n/**\n * Generate a KOS model with optional container and companion.\n */\nexport function generateModel(params: GenerateModelParams): void {\n const {\n codegenFs,\n modelTemplateDir,\n containerTemplateDir,\n companionTemplateDir,\n options,\n cwd,\n projects,\n } = params;\n const logger = getCodegenLogger();\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n options.modelProject = modelProjectName;\n const normalized = normalizeOptions(codegenFs, options, projects);\n const projectConfig = findProjectByName(\n codegenFs.root,\n normalized.modelProject,\n projects\n );\n if (!projectConfig) {\n throw new Error(`Model project '${normalized.modelProject}' not found`);\n }\n\n const projectRoot = projectConfig.sourceRoot;\n if (!projectRoot) return;\n\n const kosConfigPath = path.join(projectConfig.root, \".kos.json\");\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectConfig.name,\n projects\n );\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const internal = !!kosConfig?.generator?.internal;\n options.modelDirectory = options.modelDirectory || modelLocation;\n\n logger.info(`Generating model ${normalized.nameDashCase} in ${projectRoot}`);\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(modelTemplateDir, \"model\"),\n path.join(projectRoot, options.modelDirectory, normalized.nameDashCase),\n { ...normalized, internal }\n );\n\n if (normalized.dataServices) {\n generateFilesFromTemplates(\n codegenFs,\n path.join(modelTemplateDir, \"services\"),\n path.join(\n projectRoot,\n options.modelDirectory,\n normalized.nameDashCase,\n \"services\"\n ),\n { ...normalized, internal }\n );\n }\n\n const modelIndex = path.join(projectRoot, \"index.ts\");\n const modelPath = options.modelDirectory\n ? `${options.modelDirectory}/${normalized.nameDashCase}`\n : normalized.nameDashCase;\n updateModelIndex(codegenFs, modelIndex, modelPath);\n\n // The generator names the exported registration bean (`export const <ProperCase>`),\n // so it knows the catalog `factory` exactly — no inference. When a container is\n // also generated, this model is held by it: record that as `managedBy` so a\n // consumer depends on the container and navigates, rather than taking the model\n // by id. `purpose` is the only authored field (optional slot).\n const containerKey = normalized.container\n ? `${normalized.nameDashCase}-container`\n : undefined;\n updateJson(codegenFs, kosConfigPath, (json: any) => {\n const existing = json.models?.[normalized.name] ?? {};\n const managedBy = containerKey\n ? [...new Set([...(existing.managedBy ?? []), containerKey])]\n : existing.managedBy;\n json.models = {\n ...json.models,\n [normalized.name]: {\n ...existing,\n name: normalized.name,\n type: `${normalized.nameDashCase}-model`,\n singleton: !!normalized.singleton,\n factory: normalized.nameProperCase,\n ...(normalized.purpose ? { purpose: normalized.purpose } : {}),\n ...(managedBy?.length ? { managedBy } : {}),\n },\n };\n return json;\n });\n\n if (normalized.container && containerTemplateDir) {\n logger.info(`Generating container for ${normalized.name}`);\n generateContainerModel(\n codegenFs,\n containerTemplateDir,\n {\n ...options,\n name: `${normalized.name}-container`,\n modelName: normalized.name,\n singleton: normalized.isContainerSingleton,\n dataServices: normalized.dataServices,\n } as ContainerModelOptions,\n cwd,\n projects\n );\n }\n\n if (\n normalized.companion &&\n normalized.companionModel &&\n normalized.companionModelProject &&\n companionTemplateDir\n ) {\n generateCompanionModel(\n codegenFs,\n companionTemplateDir,\n {\n companionModelName: normalized.name,\n companionModelProject: normalized.modelProject,\n modelName: normalized.companionModel,\n modelProject: normalized.companionModelProject,\n companionPattern: normalized.companionPattern,\n } as CompanionModelOptions,\n projects\n );\n }\n}\n","/**\n * Shared model-file resolution for capability mutators. Locates the `-model.ts`\n * file for a model in a project. The conventional `<folder>/<name>/<name>-model.ts`\n * location is tried first; when absent, the project's model folder is searched for\n * the file by name — models are routinely co-located (a container in its item\n * model's directory) or grouped in shared directories, and the file NAME is the\n * stable invariant, not the directory.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport { normalizeAllValues } from \"../../normalize-values\";\n\nexport interface ModelFileQuery {\n modelName: string;\n modelProject: string;\n /** Explicit model file path (relative to root), overriding resolution. */\n modelPath?: string;\n}\n\nexport function resolveModelFilePath(\n codegenFs: CodegenFileSystem,\n query: ModelFileQuery,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string; internal: boolean; sourceRoot?: string } {\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n query.modelProject,\n projects\n );\n const internal = !!kosConfig?.generator?.internal;\n\n const project = findProjectByName(\n codegenFs.root,\n query.modelProject,\n projects\n );\n const sourceRoot = project\n ? project.sourceRoot || path.join(project.root, \"src\")\n : undefined;\n\n if (query.modelPath) {\n return { modelFilePath: query.modelPath, internal, sourceRoot };\n }\n\n if (!project) {\n throw new Error(\n `Project not found: ${query.modelProject}. Ensure a project.json exists.`\n );\n }\n const { modelNameDashCase } = normalizeAllValues({\n modelName: query.modelName,\n });\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const modelFilePath = path.join(\n sourceRoot as string,\n modelLocation,\n modelNameDashCase,\n `${modelNameDashCase}-model.ts`\n );\n if (codegenFs.exists(modelFilePath)) {\n return { modelFilePath, internal, sourceRoot };\n }\n\n const discovered = findModelFileByName(\n codegenFs,\n path.join(sourceRoot as string, modelLocation),\n modelNameDashCase\n );\n if (discovered) {\n return { modelFilePath: discovered, internal, sourceRoot };\n }\n return { modelFilePath, internal, sourceRoot };\n}\n\n/**\n * Search a directory tree for `<name>-model.ts`. Returns the single match, null\n * when there is none (callers keep the conventional path so their not-found\n * error names the expected location), and throws on ambiguity — a wrong guess\n * would silently mutate the wrong model.\n */\nfunction findModelFileByName(\n codegenFs: CodegenFileSystem,\n searchRoot: string,\n modelNameDashCase: string\n): string | null {\n const fileName = `${modelNameDashCase}-model.ts`;\n const candidates = codegenFs\n .listFiles(searchRoot)\n .filter((f) => path.basename(f) === fileName)\n .sort();\n if (candidates.length === 0) return null;\n if (candidates.length > 1) {\n throw new Error(\n `Model name '${modelNameDashCase}' is ambiguous — multiple files match ${fileName}:\\n` +\n candidates.map((c) => ` - ${c}`).join(\"\\n\") +\n `\\nPass modelPath to pick one.`\n );\n }\n return candidates[0];\n}\n","/**\n * Option normalization for the add-future-to-model generator.\n *\n * Resolves project configuration, computes name case variants,\n * and determines file paths for model, services, and registration files.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport { normalizeAllValues } from \"../../normalize-values\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport type {\n AddFutureToModelOptions,\n NormalizedAddFutureToModelOptions,\n} from \"./types\";\n\nexport function normalizeAddFutureOptions(\n codegenFs: CodegenFileSystem,\n options: AddFutureToModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedAddFutureToModelOptions {\n const projectConfiguration = findProjectByName(\n codegenFs.root,\n options.modelProject,\n projects\n );\n\n if (!projectConfiguration) {\n throw new Error(\n `Project not found: ${options.modelProject}. Ensure a project.json exists for this project.`\n );\n }\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n options.modelProject,\n projects\n );\n const internal = !!kosConfig?.generator?.internal;\n\n // Normalize name variations\n const normalizedValues = normalizeAllValues({\n modelName: options.modelName,\n });\n\n const nameDashCase = normalizedValues.modelNameDashCase;\n const nameProperCase = normalizedValues.modelNameProperCase;\n const nameCamelCase = normalizedValues.modelNameCamelCase;\n const namePascalCase = normalizedValues.modelNamePascalCase;\n const nameConstantCase = normalizedValues.modelNameConstantCase;\n const nameLowerCase = normalizedValues.modelNameLowerCase;\n\n const projectRoot = projectConfiguration.root;\n const sourceRoot =\n projectConfiguration.sourceRoot || path.join(projectRoot, \"src\");\n\n // Determine model file path — shared resolution covers co-located containers\n // and shared-dir models, not just the conventional `<folder>/<name>/` layout.\n const { modelFilePath } = resolveModelFilePath(\n codegenFs,\n { modelName: options.modelName, modelProject: options.modelProject },\n projects\n );\n const modelDirectory = path.dirname(modelFilePath);\n\n // Determine services file path\n const servicesDirectory = path.join(modelDirectory, \"services\");\n const servicesFilePath = codegenFs.exists(servicesDirectory)\n ? path.join(servicesDirectory, `${nameDashCase}-services.ts`)\n : undefined;\n\n // Determine registration file path\n const registrationFilePath = path.join(\n modelDirectory,\n `${nameDashCase}-registration.ts`\n );\n\n return {\n ...options,\n nameDashCase,\n nameProperCase,\n nameCamelCase,\n namePascalCase,\n nameConstantCase,\n nameLowerCase,\n projectRoot,\n sourceRoot,\n modelFilePath,\n servicesFilePath,\n registrationFilePath: codegenFs.exists(registrationFilePath)\n ? registrationFilePath\n : undefined,\n internal,\n };\n}\n","/**\n * Transformer that updates existing models to use the @kosFutureAware\n * decorator pattern with TypeScript interface merging for type safety.\n *\n * AST-based (ts-morph via the augment toolkit): every edit anchors on a real\n * node — class, decorator list, import declaration, type alias — so a model\n * with existing decorated methods round-trips intact. The earlier regex\n * string-splice version doubled the class declaration and unbalanced braces\n * on any non-trivial model (G-111).\n */\nimport type { SourceFile, ClassDeclaration } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addClassDecorator,\n ensureDeclarationMerge,\n ensureFileEslintDisable,\n} from \"../augment/ts-toolkit\";\n\n// Symbols from the legacy (pre-decorator) future pattern, scrubbed on sight.\nconst LEGACY_IMPORTS = new Set([\n \"setupCompleteFutureSupport\",\n \"setupMinimalFutureSupport\",\n \"FutureAwareContainer\",\n \"FutureHandlerContainer\",\n \"FutureStateAccessor\",\n \"FutureUpdateHandler\",\n]);\nconst LEGACY_IMPLEMENTS = new Set([\n \"FutureUpdateHandler\",\n \"FutureHandlerContainer\",\n \"FutureStateAccessor\",\n]);\n\nexport class ModelFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n private get progressType(): string {\n const { nameProperCase, updateServices } = this.options;\n return updateServices\n ? `${nameProperCase}OperationProgress`\n : \"Record<string, unknown>\";\n }\n\n transform(): void {\n const { modelFilePath } = this.options;\n\n if (!this.codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n transformSourceFile(this.codegenFs, modelFilePath, (sf) => {\n this.removeLegacyImports(sf);\n this.addImports(sf);\n\n const cls = getModelClass(sf, `${this.options.nameProperCase}ModelImpl`);\n this.removeLegacyClassMembers(cls);\n this.addDecorator(cls);\n this.addFutureMethod(cls);\n if (this.options.futureType === \"complete\") {\n this.addOnFutureUpdateMethod(cls);\n }\n\n this.updatePublicType(sf);\n\n // Raw-text insertions LAST — they invalidate node references.\n ensureDeclarationMerge(\n sf,\n `${this.options.nameProperCase}ModelImpl`,\n `${\n this.options.futureType === \"complete\"\n ? \"KosFutureAwareFull\"\n : \"KosFutureAwareMinimal\"\n }<${this.progressType}>`\n );\n ensureFileEslintDisable(\n sf,\n \"@typescript-eslint/no-unsafe-declaration-merging\"\n );\n });\n }\n\n private removeLegacyImports(sf: SourceFile): void {\n for (const decl of sf.getImportDeclarations()) {\n for (const named of decl.getNamedImports()) {\n if (LEGACY_IMPORTS.has(named.getName())) named.remove();\n }\n if (\n decl.getNamedImports().length === 0 &&\n !decl.getDefaultImport() &&\n !decl.getNamespaceImport()\n ) {\n decl.remove();\n }\n }\n }\n\n private addImports(sf: SourceFile): void {\n const { internal, futureType, updateServices, nameProperCase } =\n this.options;\n const isComplete = futureType === \"complete\";\n const sdkSpec = resolveSdkModuleSpecifier(sf);\n\n ensureNamedImport(sf, sdkSpec, [\n { name: \"kosFuture\" },\n { name: \"kosFutureAware\" },\n {\n name: isComplete ? \"KosFutureAwareFull\" : \"KosFutureAwareMinimal\",\n isTypeOnly: true,\n },\n ]);\n\n const typeSpec = internal\n ? \"../../../models/types/future-interfaces\"\n : sdkSpec;\n ensureNamedImport(sf, typeSpec, [\n { name: \"ExternalFutureInterface\", isTypeOnly: true },\n ...(isComplete ? [{ name: \"IFutureModel\", isTypeOnly: true }] : []),\n ]);\n\n if (updateServices) {\n ensureNamedImport(sf, \"./services\", [\n { name: `${nameProperCase}OperationProgress`, isTypeOnly: true },\n ]);\n }\n }\n\n private removeLegacyClassMembers(cls: ClassDeclaration): void {\n for (const ctor of cls.getConstructors()) {\n for (const stmt of ctor.getStatements()) {\n if (\n /setup(Complete|Minimal)FutureSupport\\s*\\(\\s*this\\s*\\)/.test(\n stmt.getText()\n )\n ) {\n stmt.remove();\n }\n }\n }\n\n const futureHandler = cls.getProperty(\"futureHandler\");\n if (\n futureHandler?.getTypeNode()?.getText().includes(\"FutureAwareContainer\")\n ) {\n futureHandler.remove();\n }\n const future = cls.getProperty(\"future\");\n if (future?.getTypeNode()?.getText().includes(\"IFutureModel\")) {\n future.remove();\n }\n\n const impls = cls.getImplements();\n for (let i = impls.length - 1; i >= 0; i--) {\n const base = impls[i].getText().split(\"<\")[0].trim();\n if (LEGACY_IMPLEMENTS.has(base)) cls.removeImplements(i);\n }\n }\n\n private addDecorator(cls: ClassDeclaration): void {\n const argsText =\n this.options.futureType === \"complete\" ? \"\" : `{ mode: \"minimal\" }`;\n addClassDecorator(cls, \"kosFutureAware\", { argsText });\n }\n\n private updatePublicType(sf: SourceFile): void {\n const { nameProperCase } = this.options;\n const alias = sf.getTypeAlias(`${nameProperCase}Model`);\n if (!alias) return;\n const text = alias.getTypeNode()?.getText() ?? \"\";\n if (\n !text.includes(`PublicModelInterface<${nameProperCase}ModelImpl>`) ||\n text.includes(\"ExternalFutureInterface\")\n ) {\n return;\n }\n alias.setType(\n `PublicModelInterface<${nameProperCase}ModelImpl> & ExternalFutureInterface<${this.progressType}>`\n );\n }\n\n private addFutureMethod(cls: ClassDeclaration): void {\n const { nameProperCase } = this.options;\n // A model that already has any @kosFuture method needs no placeholder.\n const hasFutureMethod = cls\n .getMethods()\n .some((m) => m.getDecorator(\"kosFuture\"));\n if (hasFutureMethod || cls.getMethod(\"performLongRunningOperation\")) return;\n\n cls.addMethod({\n name: \"performLongRunningOperation\",\n isAsync: true,\n returnType: \"Promise<void>\",\n decorators: [{ name: \"kosFuture\", arguments: [] }],\n docs: [\n {\n description:\n \"Placeholder method for Future operations\\nReplace this with your actual long-running operation\",\n },\n ],\n statements: [\n \"// TODO: Implement your long-running operation here\",\n \"// This method should use a service that returns a Future for progress tracking\",\n \"\",\n \"this.logger.debug(`Starting long-running operation for ${this.id}`);\",\n \"\",\n \"// Example implementation pattern using services:\",\n `// import { perform${nameProperCase}Operation } from './services';`,\n \"//\",\n `// const future = await perform${nameProperCase}Operation();`,\n \"// return this.futureHandler.setFuture(future);\",\n \"\",\n \"// Placeholder that doesn't actually do anything\",\n \"await new Promise((resolve) => setTimeout(resolve, 1000));\",\n \"\",\n \"this.logger.debug(`Completed long-running operation for ${this.id}`);\",\n ],\n });\n }\n\n private addOnFutureUpdateMethod(cls: ClassDeclaration): void {\n if (cls.getMethod(\"onFutureUpdate\")) return;\n\n cls.addMethod({\n name: \"onFutureUpdate\",\n hasQuestionToken: true,\n returnType: \"void\",\n parameters: [\n { name: \"update\", type: `IFutureModel<${this.progressType}>` },\n ],\n docs: [\n {\n description:\n \"Optional: Custom Future update handling\\nCalled whenever the Future state changes (progress, status, completion, etc.)\",\n },\n ],\n statements: [\n \"// Add custom Future update logic here\",\n \"// Examples:\",\n \"// - Log progress milestones\",\n \"// - Update derived state based on progress\",\n \"// - Handle specific error conditions\",\n \"// - Trigger notifications at certain thresholds\",\n \"\",\n \"this.logger.debug(`Future update for ${this.id}:`, {\",\n \" progress: update.progress,\",\n \" status: update.status,\",\n \" endState: update.endState,\",\n \" clientData: update.clientData,\",\n \"});\",\n ],\n });\n }\n}\n","/**\n * Transformer that updates or creates service files with Future operation support.\n *\n * Adds FutureResponse imports, a placeholder future service function,\n * and progress/result type definitions.\n *\n * Ported from kos-nx-plugin to use CodegenFileSystem instead of Nx Tree.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\n\nexport class ServiceFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const { servicesFilePath } = this.options;\n\n if (!servicesFilePath || !this.codegenFs.exists(servicesFilePath)) {\n // Create services file if it doesn't exist\n this.createServicesFile();\n return;\n }\n\n let content = this.codegenFs.read(servicesFilePath)!;\n\n content = this.addFutureImports(content);\n content = this.addFutureService(content);\n content = this.addProgressTypes(content);\n\n this.codegenFs.write(servicesFilePath, content);\n }\n\n private createServicesFile(): void {\n const { servicesFilePath, nameProperCase, nameDashCase, nameLowerCase } =\n this.options;\n\n if (!servicesFilePath) {\n return;\n }\n\n const content = `import {\n KosLog,\n type ClientResponse,\n type DeepRequired,\n type ElementType,\n type ServiceResponse,\n type FutureResponse\n} from '@kosdev-code/kos-ui-sdk';\n\nimport API, { type KosApi, type ApiPath } from '../../../utils/service';\n\nconst log = KosLog.createLogger({name: \"${nameDashCase}-service\", group: \"Services\"});\n\nconst SERVICE_PATH: ApiPath = \"ENTER_SERVICE_PATH\"\nexport type ${nameProperCase}ClientResponse = ClientResponse<\n KosApi,\n typeof SERVICE_PATH,\n 'get'\n>;\nexport type ${nameProperCase}Response = DeepRequired<${nameProperCase}ClientResponse>;\n\n/**\n * @category Service\n * Retrieves the initial ${nameLowerCase} data.\n */\nexport const get${nameProperCase} = async (): Promise<ServiceResponse<${nameProperCase}Response>> => {\n log.debug('sending GET for ${nameLowerCase}');\n return await API.get(SERVICE_PATH);\n};\n\n/**\n * @category Service - Future Operation\n * Placeholder for a long-running operation that returns a Future for progress tracking\n *\n * Replace this with your actual long-running service operation\n */\nexport const perform${nameProperCase}Operation = async (): Promise<FutureResponse> => {\n // TODO: Implement your long-running service operation here\n // This should return a Future that can be tracked for progress\n\n log.debug('starting long-running ${nameLowerCase} operation');\n\n // Example pattern:\n // return API.post(OPERATION_SERVICE_PATH, {\n // // operation parameters\n // });\n\n // Placeholder - replace with actual implementation\n throw new Error('perform${nameProperCase}Operation not yet implemented');\n};\n\n// Additional Future-aware service types (add as needed)\nexport type ${nameProperCase}OperationProgress = {\n // Define your progress data structure here\n stage: string;\n percentComplete: number;\n currentItem?: string;\n totalItems?: number;\n};\n\nexport type ${nameProperCase}OperationResult = {\n // Define your operation result structure here\n success: boolean;\n message?: string;\n data?: any;\n};\n`;\n\n this.codegenFs.write(servicesFilePath, content);\n }\n\n private addFutureImports(content: string): string {\n // Check if FutureResponse is already imported\n if (content.includes(\"FutureResponse\")) {\n return content;\n }\n\n // Add FutureResponse to existing import\n const importRegex =\n /import {\\s*([^}]*)\\s*} from '@kosdev-code\\/kos-ui-sdk';/;\n const importMatch = content.match(importRegex);\n\n if (importMatch) {\n const existingImports = importMatch[1];\n if (existingImports.includes(\"FutureResponse\")) {\n return content; // Already imported\n }\n\n // Clean up existing imports and add FutureResponse\n const cleanedImports = existingImports.trim().replace(/,\\s*$/, \"\"); // Remove trailing comma\n const newImports = cleanedImports\n ? `${cleanedImports},\\n type FutureResponse`\n : `type FutureResponse`;\n\n const newImportStatement = `import {\\n ${newImports}\\n} from '@kosdev-code/kos-ui-sdk';`;\n return content.replace(importMatch[0], newImportStatement);\n }\n\n return content;\n }\n\n private addFutureService(content: string): string {\n const { nameProperCase, nameLowerCase } = this.options;\n\n // Check if Future service already exists\n if (content.includes(`perform${nameProperCase}Operation`)) {\n return content;\n }\n\n const futureService = `\n/**\n * @category Service - Future Operation\n * Placeholder for a long-running operation that returns a Future for progress tracking\n *\n * Replace this with your actual long-running service operation\n */\nexport const perform${nameProperCase}Operation = async (): Promise<FutureResponse> => {\n // TODO: Implement your long-running service operation here\n // This should return a Future that can be tracked for progress\n\n log.debug('starting long-running ${nameLowerCase} operation');\n\n // Example pattern:\n // return API.post(OPERATION_SERVICE_PATH, {\n // // operation parameters\n // });\n\n // Placeholder - replace with actual implementation\n throw new Error('perform${nameProperCase}Operation not yet implemented');\n};`;\n\n // Add at the end of the file\n return content + \"\\n\" + futureService;\n }\n\n private addProgressTypes(content: string): string {\n const { nameProperCase } = this.options;\n\n // Check if progress types already exist\n if (content.includes(`${nameProperCase}OperationProgress`)) {\n return content;\n }\n\n const progressTypes = `\n// Additional Future-aware service types (add as needed)\nexport type ${nameProperCase}OperationProgress = {\n // Define your progress data structure here\n stage: string;\n percentComplete: number;\n currentItem?: string;\n totalItems?: number;\n};\n\nexport type ${nameProperCase}OperationResult = {\n // Define your operation result structure here\n success: boolean;\n message?: string;\n data?: any;\n};`;\n\n // Add at the end of the file\n return content + \"\\n\" + progressTypes;\n }\n}\n","/**\n * Transformer that updates registration files to support Future-enabled models.\n *\n * Adds type casts and documentation for Future capabilities.\n *\n * Ported from kos-nx-plugin to use CodegenFileSystem instead of Nx Tree.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport { getCodegenLogger } from \"../../logger\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\n\nexport class RegistrationFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const logger = getCodegenLogger();\n const { registrationFilePath } = this.options;\n\n if (!registrationFilePath || !this.codegenFs.exists(registrationFilePath)) {\n logger.warn(\"Registration file not found, skipping registration updates\");\n return;\n }\n\n const original = this.codegenFs.read(registrationFilePath)!;\n\n let content = original;\n content = this.addTypeCast(content);\n content = this.updateDocumentation(content);\n\n // Only legacy registration patterns produce edits — writing unchanged\n // content makes dry-run predict a modification that never happens.\n if (content === original) {\n logger.info(\n \"Registration file has no legacy future patterns — leaving it untouched\"\n );\n return;\n }\n this.codegenFs.write(registrationFilePath, content);\n }\n\n private addTypeCast(content: string): string {\n const { nameProperCase } = this.options;\n\n // Find the registration factory instantiation and add type cast\n const factoryRegex = new RegExp(`class: ${nameProperCase}ModelImpl,`);\n\n const replacement = `class: ${nameProperCase}ModelImpl as any, // Type cast needed for Future intersection`;\n\n return content.replace(factoryRegex, replacement);\n }\n\n private updateDocumentation(content: string): string {\n const { nameProperCase, futureType } = this.options;\n\n // Add Future support documentation after the main description\n const descriptionRegex = new RegExp(\n `(\\\\* The registration bean includes convenience methods for creating and working with ${nameProperCase}Model instances\\\\.)`\n );\n\n const futureDocumentation = `$1\n *\n * ## Future Support\n * This model includes ${futureType} Future support for tracking long-running operations with:\n * - Progress tracking (0-1) with reactive updates\n * - Status messages during operation\n * - Cancellation support with bi-directional AbortController integration\n * - Reactive integration for UI updates${\n futureType === \"complete\"\n ? \"\\n * - Internal access to Future state for custom logic and computed properties\"\n : \"\"\n }`;\n\n if (content.match(descriptionRegex)) {\n content = content.replace(descriptionRegex, futureDocumentation);\n }\n\n // Add Future usage examples to factory documentation\n const factoryExampleRegex = /(\\*\\s+\\}\\);?\\s*\\*\\s+```)/;\n\n const futureExample = `$1\n *\n * // Example: Accessing Future state (when a Future is active)\n * const isRunning = model.futureIsRunning;\n * const progress = model.futureProgress; // 0-1\n * const status = model.futureStatus; // Current status message\n * \\`\\`\\``;\n\n if (content.match(factoryExampleRegex)) {\n content = content.replace(factoryExampleRegex, futureExample);\n }\n\n // Add Future capabilities to predicate examples\n const predicateExampleRegex =\n /(\\*\\s+model\\.updateAvailability\\(false\\);?\\s*\\*\\s+\\})/;\n\n const predicateFutureExample = `$1\n *\n * // Future capabilities are also available\n * const isRunning = model.futureIsRunning;\n * const progress = model.futureProgress;\n * }`;\n\n if (content.match(predicateExampleRegex)) {\n content = content.replace(predicateExampleRegex, predicateFutureExample);\n }\n\n return content;\n }\n}\n","/**\n * Framework-agnostic core logic for the add-future-to-model generator.\n *\n * Adds Future (long-running operation) support to an existing KOS model\n * by transforming model, service, and registration files. Works through\n * the CodegenFileSystem abstraction so it can run in any environment\n * (CLI, VS Code, Nx).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { normalizeAddFutureOptions } from \"./normalize-options\";\nimport { ModelFileTransformer } from \"./model-transformer\";\nimport { ServiceFileTransformer } from \"./service-transformer\";\nimport { RegistrationFileTransformer } from \"./registration-transformer\";\nimport type { AddFutureToModelOptions } from \"./types\";\n\nexport function addFutureToModel(\n codegenFs: CodegenFileSystem,\n options: AddFutureToModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n const normalized = normalizeAddFutureOptions(codegenFs, options, projects);\n\n logger.info(\n `Adding ${normalized.futureType} Future support to model: ${normalized.modelName}`\n );\n\n // Validate that model file exists\n if (!codegenFs.exists(normalized.modelFilePath)) {\n throw new Error(`Model file not found: ${normalized.modelFilePath}`);\n }\n\n if (options.dryRun) {\n logger.info(\"DRY RUN - No files will be modified\");\n logger.info(`Would modify model file: ${normalized.modelFilePath}`);\n if (normalized.servicesFilePath) {\n logger.info(\n `Would modify/create services file: ${normalized.servicesFilePath}`\n );\n }\n if (normalized.registrationFilePath) {\n logger.info(\n `Would update registration file (only if legacy patterns are present): ${normalized.registrationFilePath}`\n );\n }\n return;\n }\n\n try {\n // Transform model file\n logger.info(`Transforming model file: ${normalized.modelFilePath}`);\n const modelTransformer = new ModelFileTransformer(codegenFs, normalized);\n modelTransformer.transform();\n\n // Transform or create services file\n if (normalized.updateServices) {\n logger.info(\n `Transforming services file: ${\n normalized.servicesFilePath || \"creating new\"\n }`\n );\n const serviceTransformer = new ServiceFileTransformer(\n codegenFs,\n normalized\n );\n serviceTransformer.transform();\n }\n\n // Transform registration file\n if (normalized.registrationFilePath) {\n logger.info(\n `Transforming registration file: ${normalized.registrationFilePath}`\n );\n const registrationTransformer = new RegistrationFileTransformer(\n codegenFs,\n normalized\n );\n registrationTransformer.transform();\n }\n\n logger.info(\n `Successfully added ${normalized.futureType} Future support to ${normalized.modelName}`\n );\n logger.info(\"\");\n logger.info(\"Next steps:\");\n logger.info(\n \"1. Review the generated @kosFuture method and implement your actual operation\"\n );\n logger.info(\n \"2. Update the service method to return a proper FutureResponse\"\n );\n logger.info(\"3. Define your specific progress and result types\");\n if (normalized.futureType === \"complete\") {\n logger.info(\n \"4. Customize the onFutureUpdate method for your specific needs\"\n );\n }\n } catch (error) {\n logger.error(`Failed to add Future support: ${error}`);\n throw error;\n }\n}\n","/**\n * Capability mutator: add container support to an EXISTING model.\n *\n * Applies the `@kosContainerAware` capability (decorator + declaration-merging\n * interface + imports) to a model in place, so a model can manage a collection of\n * children directly — replacing the older pattern that forced a separate container\n * model plus an extra model-manager layer.\n *\n * AST-based via the shared ts-morph toolkit (no regex); routes all I/O through\n * CodegenFileSystem so dry-run + formatFiles apply unchanged.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { recordContainerSupportInKosConfig } from \"../../kos-config\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addClassDecorator,\n ensureDeclarationMerge,\n ensureFileEslintDisable,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddContainerSupportOptions {\n modelName: string;\n modelProject: string;\n /** TS type the container holds. Default `IKosDataModel`. */\n childType?: string;\n /** Container property name on the instance. Default `container`. */\n containerProperty?: string;\n /** Optional `containerOptions.sortKey`. */\n sortKey?: string;\n /** Explicit model file path (relative to root), overriding resolution. */\n modelPath?: string;\n}\n\nfunction buildDecoratorArgs(options: AddContainerSupportOptions): string {\n const top: string[] = [];\n if (options.containerProperty) {\n top.push(`containerProperty: ${JSON.stringify(options.containerProperty)}`);\n }\n if (options.sortKey) {\n top.push(\n `containerOptions: { sortKey: ${JSON.stringify(options.sortKey)} }`\n );\n }\n return top.length ? `{ ${top.join(\", \")} }` : \"\";\n}\n\n/**\n * Add `@kosContainerAware` support to an existing model file.\n */\nexport function addContainerSupportToModel(\n codegenFs: CodegenFileSystem,\n options: AddContainerSupportOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const childType = options.childType?.trim() || \"IKosDataModel\";\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n logger.info(\n `Adding container support (<${childType}>) to model: ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [\n { name: \"kosContainerAware\" },\n { name: \"KosContainerAware\", isTypeOnly: true },\n ]);\n // Default child type comes from the SDK; ensure it's imported.\n if (childType === \"IKosDataModel\") {\n ensureNamedImport(sf, sdk, [{ name: \"IKosDataModel\", isTypeOnly: true }]);\n }\n\n const cls = getModelClass(sf);\n const className = cls.getName();\n if (!className) throw new Error(\"Model class has no name.\");\n // Capture the class's type parameters so the merged interface matches.\n const typeParams = cls.getTypeParameters().map((tp) => tp.getText());\n\n addClassDecorator(cls, \"kosContainerAware\", {\n typeArgs: [childType],\n argsText: buildDecoratorArgs(options),\n });\n\n ensureDeclarationMerge(\n sf,\n className,\n `KosContainerAware<${childType}>`,\n typeParams\n );\n ensureFileEslintDisable(\n sf,\n \"@typescript-eslint/no-unsafe-declaration-merging\"\n );\n });\n\n // The model now manages children directly — reflect that containment in the\n // catalog (`container: true`, and `managedBy` on a concrete held model).\n recordContainerSupportInKosConfig({\n codegenFs,\n projectName: options.modelProject,\n modelName: options.modelName,\n childType,\n projects,\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosModelEffect` reaction method to an existing model.\n * Generates an idiomatic skeleton (dependencies arrow + async handler) for the\n * developer/agent to fill in. AST-based via the shared toolkit.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedMethod,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddModelEffectOptions {\n modelName: string;\n modelProject: string;\n /** Effect handler method name, e.g. `handleSelectionChange`. */\n methodName: string;\n modelPath?: string;\n}\n\nexport function addModelEffectToModel(\n codegenFs: CodegenFileSystem,\n options: AddModelEffectOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosModelEffect \"${options.methodName}\" to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [{ name: \"kosModelEffect\" }]);\n const cls = getModelClass(sf);\n const modelType = (cls.getName() ?? \"\").replace(/Impl$/, \"\");\n addDecoratedMethod(cls, {\n name: options.methodName,\n decoratorName: \"kosModelEffect\",\n decoratorArgsText: `{ dependencies: (model: ${modelType}) => [] }`,\n isAsync: true,\n returnType: \"Promise<void>\",\n statements: \"// TODO: react to the tracked dependencies\",\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosDependency` property (cross-model reference) to an\n * existing model. The dependency's TS type and `modelType` ref are caller-supplied.\n *\n * When `dependencyPackage` is given (the SDK that owns the dependency — exactly what\n * `describe_sdk_model` surfaces from the catalog), this also adds the import for the\n * registration bean (the `X` in `X.type`) and the model interface type from that\n * package, so wiring an SDK model is a single call. Without it, importing those\n * symbols stays the caller's responsibility (the mutator can't guess their origin).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedProperty,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddDependencyOptions {\n modelName: string;\n modelProject: string;\n /** Property name to hold the dependency, e.g. `application`. */\n propertyName: string;\n /** TS type of the dependency, e.g. `ApplicationModel`. */\n dependencyType: string;\n /** Runtime model-type ref, e.g. `Application.type` or a string literal. */\n modelTypeRef: string;\n /** Optional dependency id. */\n id?: string;\n /**\n * The SDK package that owns the dependency (e.g. `@kosdev-code/kos-ui-sdk`). When\n * set, the registration bean and the model interface type are imported from it.\n */\n dependencyPackage?: string;\n modelPath?: string;\n}\n\n// Framework generics that come from the KOS SDK, not the dependency's own package —\n// never import these from `dependencyPackage`.\nconst FRAMEWORK_TYPES = new Set([\"IKosDataModel\", \"IKosIdentifiable\"]);\n\nexport function addDependencyToModel(\n codegenFs: CodegenFileSystem,\n options: AddDependencyOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosDependency \"${options.propertyName}\" to ${options.modelName}`\n );\n\n const argsParts = [`modelType: ${options.modelTypeRef}`];\n if (options.id) argsParts.push(`id: ${JSON.stringify(options.id)}`);\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [{ name: \"kosDependency\" }]);\n\n // Import the dependency's own symbols from the SDK root barrel (NOT a subpath —\n // every model/bean/type is re-exported from the package root).\n if (options.dependencyPackage) {\n const named: { name: string; isTypeOnly?: boolean }[] = [];\n // Registration bean: the `X` in `X.type` (skip string-literal refs).\n const bean = options.modelTypeRef.match(\n /^([A-Za-z_$][\\w$]*)\\.type$/\n )?.[1];\n if (bean) named.push({ name: bean });\n // Model interface type, unless it's a framework generic from the SDK.\n const depType = options.dependencyType?.trim();\n if (\n depType &&\n /^[A-Za-z_$][\\w$]*$/.test(depType) &&\n !FRAMEWORK_TYPES.has(depType)\n ) {\n named.push({ name: depType, isTypeOnly: true });\n }\n if (named.length) ensureNamedImport(sf, options.dependencyPackage, named);\n }\n\n const cls = getModelClass(sf);\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosDependency\",\n decoratorArgsText: `{ ${argsParts.join(\", \")} }`,\n type: options.dependencyType,\n scope: \"private\",\n hasExclamation: true,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosChild` property (owned sub-model enrollment) to an\n * existing model. Enrolls the child(ren) into the parent's model graph, lifecycle\n * cascade, and context scope-chain (a key the parent sets on its context bean resolves\n * down the whole subtree — see kos://guide/model-context). Three shapes:\n * single → `@kosChild private {prop}!: {Child};`\n * container → `@kosChild private {prop} = new KosModelContainer<{Child}>();`\n * array → `@kosChild private {prop}: {Child}[] = [];`\n *\n * When `childPackage` is given (the SDK/package that owns the child model — exactly\n * what `describe_sdk_model` surfaces), the child type is imported from it; without it,\n * importing the child type stays the caller's responsibility (the mutator can't guess\n * its origin). `KosModelContainer` (container shape) always imports from the SDK.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedProperty,\n} from \"../augment/ts-toolkit\";\n\nexport type ChildShape = \"single\" | \"container\" | \"array\";\n\nexport interface AddChildOptions {\n modelName: string;\n modelProject: string;\n /** Property name that holds the child(ren), e.g. `pages`, `pump`, `sensors`. */\n propertyName: string;\n /** Child model TS type, e.g. `PageModel`. */\n childType: string;\n /** How the child(ren) are held. Default `single`. */\n shape?: ChildShape;\n /** Package that owns the child model; when set, its type is imported from the root. */\n childPackage?: string;\n modelPath?: string;\n}\n\n// Framework generics that come from the KOS SDK, not the child's own package — never\n// import these from `childPackage`.\nconst FRAMEWORK_TYPES = new Set([\"IKosDataModel\", \"IKosIdentifiable\"]);\n\nexport function addChildToModel(\n codegenFs: CodegenFileSystem,\n options: AddChildOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const shape: ChildShape = options.shape ?? \"single\";\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosChild \"${options.propertyName}\" (${shape}) to ${options.modelName}`\n );\n\n const childType = options.childType?.trim();\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n const sdkImports: { name: string; isTypeOnly?: boolean }[] = [\n { name: \"kosChild\" },\n ];\n // The container shape uses KosModelContainer as a VALUE (`new …`) — import it.\n if (shape === \"container\") sdkImports.push({ name: \"KosModelContainer\" });\n ensureNamedImport(sf, sdk, sdkImports);\n\n // Import the child model type from its owning package when known. In every shape\n // the child type appears only in TYPE position (annotation or generic arg), so a\n // type-only import is correct.\n if (\n options.childPackage &&\n childType &&\n /^[A-Za-z_$][\\w$]*$/.test(childType) &&\n !FRAMEWORK_TYPES.has(childType)\n ) {\n ensureNamedImport(sf, options.childPackage, [\n { name: childType, isTypeOnly: true },\n ]);\n }\n\n const cls = getModelClass(sf);\n if (shape === \"container\") {\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosChild\",\n bare: true,\n initializer: `new KosModelContainer<${childType}>()`,\n scope: \"private\",\n });\n } else if (shape === \"array\") {\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosChild\",\n bare: true,\n type: `${childType}[]`,\n initializer: \"[]\",\n scope: \"private\",\n });\n } else {\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosChild\",\n bare: true,\n type: childType,\n scope: \"private\",\n hasExclamation: true,\n });\n }\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosTopicHandler` subscription method to an existing\n * model. Generates an idiomatic INIT/websocket handler skeleton. The `topic` and\n * event type are caller-supplied (the caller ensures the topic constant is defined).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedMethod,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddTopicHandlerOptions {\n modelName: string;\n modelProject: string;\n /** Handler method name, e.g. `handleBoardLinked`. */\n handlerName: string;\n /** Topic expression — a constant ref (e.g. `TOPIC_BOARD_LINKED`) or string literal. */\n topic: string;\n /** Event payload TS type for the handler parameter. Default `unknown`. */\n eventType?: string;\n /** Subscribe over websocket. Default true. */\n websocket?: boolean;\n modelPath?: string;\n}\n\nexport function addTopicHandlerToModel(\n codegenFs: CodegenFileSystem,\n options: AddTopicHandlerOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosTopicHandler \"${options.handlerName}\" to ${options.modelName}`\n );\n\n const websocket = options.websocket ?? true;\n const eventType = options.eventType || \"unknown\";\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [\n { name: \"kosTopicHandler\" },\n { name: \"DependencyLifecycle\" },\n ]);\n const cls = getModelClass(sf);\n addDecoratedMethod(cls, {\n name: options.handlerName,\n decoratorName: \"kosTopicHandler\",\n decoratorArgsText: `{ lifecycle: DependencyLifecycle.INIT, topic: ${options.topic}, websocket: ${websocket} }`,\n parameters: [{ name: \"event\", type: eventType }],\n statements: \"// TODO: handle the topic event\",\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosConfigProperty` reactive config-bound property to an\n * existing model. The `path` (config path ref/literal) and `attribute` are caller\n * supplied; the value is exposed as `KosConfigProperty<T>`.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedProperty,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddConfigPropertyOptions {\n modelName: string;\n modelProject: string;\n /** Property name to hold the config value, e.g. `remoteTrayEnabled`. */\n propertyName: string;\n /** Config path expression — a constant ref (e.g. `PROP_CONFIG_PATH`) or string literal. */\n path: string;\n /** Config attribute name, e.g. `enabled` or `settings.volWithoutIceMl`. */\n attribute: string;\n /** Value TS type inside `KosConfigProperty<…>`. Default `unknown`. */\n valueType?: string;\n modelPath?: string;\n}\n\nexport function addConfigPropertyToModel(\n codegenFs: CodegenFileSystem,\n options: AddConfigPropertyOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosConfigProperty \"${options.propertyName}\" to ${options.modelName}`\n );\n\n const valueType = options.valueType || \"unknown\";\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [\n { name: \"kosConfigProperty\" },\n { name: \"KosConfigProperty\", isTypeOnly: true },\n ]);\n const cls = getModelClass(sf);\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosConfigProperty\",\n decoratorArgsText: `{ path: ${options.path}, attribute: ${JSON.stringify(\n options.attribute\n )} }`,\n type: `KosConfigProperty<${valueType}>`,\n hasExclamation: true,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a basic (plain) typed property to an existing model —\n * just a TypeScript field like `prop1: string`. This is local model state, NOT a\n * device-config-bound reactive value (that's `addConfigPropertyToModel`) nor a\n * cross-model reference (`addDependencyToModel`). Use for simple state the model\n * holds and sets itself.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n getModelClass,\n addPlainProperty,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddPropertyOptions {\n modelName: string;\n modelProject: string;\n /** Property name, e.g. `prop1`. */\n propertyName: string;\n /** TS type of the field, e.g. `string`, `number`, `boolean`. Default `string`. */\n type?: string;\n /** Optional initializer expression (e.g. `\"\"`, `0`, `false`). */\n initializer?: string;\n /** Mark the field `readonly`. */\n readonly?: boolean;\n modelPath?: string;\n}\n\n/** Sensible default initializer per primitive so the field compiles under strict mode. */\nfunction defaultInitializer(type: string): string | undefined {\n switch (type) {\n case \"string\":\n return '\"\"';\n case \"number\":\n return \"0\";\n case \"boolean\":\n return \"false\";\n default:\n return undefined; // non-primitive → definite-assignment `!`\n }\n}\n\nexport function addPropertyToModel(\n codegenFs: CodegenFileSystem,\n options: AddPropertyOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n const type = options.type || \"string\";\n // Caller initializer wins; else a primitive default; else definite-assignment.\n const initializer =\n options.initializer !== undefined\n ? options.initializer\n : defaultInitializer(type);\n\n logger.info(\n `Adding property \"${options.propertyName}: ${type}\" to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const cls = getModelClass(sf);\n addPlainProperty(cls, {\n name: options.propertyName,\n type,\n initializer,\n readonly: options.readonly,\n hasExclamation: initializer === undefined,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a COMPUTED member to a model — a read-only getter\n * (`get name(): T { ... }`) that derives its value from other model state. Distinct\n * from a stored field (`addPropertyToModel`): a computed member holds no state, it\n * recomputes on access.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n getModelClass,\n addGetter,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddComputedOptions {\n modelName: string;\n modelProject: string;\n /** Getter name, e.g. `displayName`. */\n name: string;\n /** Return TS type, e.g. `string`. Default inferred (omitted). */\n returnType?: string;\n /** Body statements; default a TODO stub. */\n body?: string;\n modelPath?: string;\n}\n\nexport function addComputedToModel(\n codegenFs: CodegenFileSystem,\n options: AddComputedOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding computed getter \"${options.name}\" to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const cls = getModelClass(sf);\n addGetter(cls, {\n name: options.name,\n returnType: options.returnType,\n statements: options.body,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosServiceRequest` method to an existing model.\n *\n * Uses the TYPED decorator generated by `api:generate` (imported from the project's\n * `…/utils/services/<app>/<version>/service.ts`), so `path` is validated against the\n * OpenAPI-derived `openapi.d.ts` at compile time. Purely mechanical: device query,\n * path discovery, and live-spec validation are a separate discovery orchestration.\n *\n * Emits ONE OF TWO SHAPES, because @kosServiceRequest has two, and they are not\n * interchangeable:\n *\n * lifecycle — the framework performs the request during the phase and calls the\n * method back error-first as `(error, data)`. No execution context exists.\n * method — the method performs the request when called, through the `$ctx`\n * the decorator injects as the last parameter.\n *\n * The decorator itself decides by the presence of `lifecycle` (it only wraps the\n * handler to inject `$ctx` when `lifecycle` is absent), so this mutator derives\n * the mode the same way rather than defaulting to one of them.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedMethod,\n addClassDecorator,\n ensureDeclarationMerge,\n ensureFileEslintDisable,\n ensureModuleConst,\n} from \"../augment/ts-toolkit\";\n\nexport type ServiceRequestMode = \"lifecycle\" | \"method\";\n\nexport interface AddServiceRequestOptions {\n modelName: string;\n modelProject: string;\n /** Handler method name, e.g. `onDataLoaded`. */\n methodName: string;\n /** OpenAPI path string, validated by the generated types, e.g. `/api/board/{id}`. */\n servicePath: string;\n /** HTTP method. Default `get`. */\n method?: string;\n /**\n * Which form to emit. Defaults to `lifecycle` when `lifecycle` is supplied and\n * `method` otherwise — the same rule @kosServiceRequest applies at runtime.\n */\n mode?: ServiceRequestMode;\n /**\n * DependencyLifecycle member name (LOAD, INIT, …). Only meaningful in\n * `lifecycle` mode; defaults to `LOAD` there.\n */\n lifecycle?: string;\n /** Import specifier for the generated typed service module (relative to the model\n * file). If omitted, auto-resolved when the project has exactly one. */\n serviceModule?: string;\n /**\n * Root-relative path of the service module, as `listServiceCatalog` reports\n * it. Converted to an import specifier here, so a caller that picked an\n * operation from the catalog does not have to compute one — and does not trip\n * the \"multiple service modules\" error when a project types several versions.\n */\n serviceModulePath?: string;\n modelPath?: string;\n}\n\nconst SERVICE_MODULE_RE = /\\/utils\\/services\\/.*\\/service\\.ts$/;\n\n/** Find generated service modules under the project source root (root-relative paths). */\nfunction findServiceModules(\n codegenFs: CodegenFileSystem,\n sourceRoot: string\n): string[] {\n return codegenFs\n .listFiles(sourceRoot)\n .filter((f) => SERVICE_MODULE_RE.test(f.split(path.sep).join(\"/\")));\n}\n\n/** Build a relative import specifier (posix, no extension) from one file to another. */\nfunction toImportSpecifier(fromFile: string, toFileNoExt: string): string {\n let rel = path\n .relative(path.dirname(fromFile), toFileNoExt)\n .split(path.sep)\n .join(\"/\");\n if (!rel.startsWith(\".\")) rel = `./${rel}`;\n return rel;\n}\n\nexport function addServiceRequestToModel(\n codegenFs: CodegenFileSystem,\n options: AddServiceRequestOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string; serviceModule: string; mode: ServiceRequestMode } {\n const logger = getCodegenLogger();\n const { modelFilePath, sourceRoot } = resolveModelFilePath(\n codegenFs,\n options,\n projects\n );\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n // Resolve the typed-decorator import specifier.\n let serviceImport = options.serviceModule;\n if (!serviceImport && options.serviceModulePath) {\n serviceImport = toImportSpecifier(\n modelFilePath,\n options.serviceModulePath.replace(/\\.ts$/, \"\")\n );\n }\n if (!serviceImport) {\n if (!sourceRoot) {\n throw new Error(\n \"Cannot auto-resolve the service module without a project source root. Pass serviceModule.\"\n );\n }\n const modules = findServiceModules(codegenFs, sourceRoot);\n if (modules.length === 0) {\n throw new Error(\n \"No generated service module found. Run `kosui api:generate` for this project first.\"\n );\n }\n const specifiers = modules.map((m) =>\n toImportSpecifier(modelFilePath, m.replace(/\\.ts$/, \"\"))\n );\n if (modules.length > 1) {\n throw new Error(\n `Multiple service modules found — pass serviceModule (one of): ${specifiers.join(\n \", \"\n )}`\n );\n }\n serviceImport = specifiers[0];\n }\n\n const method = options.method || \"get\";\n const mode: ServiceRequestMode =\n options.mode ?? (options.lifecycle ? \"lifecycle\" : \"method\");\n const lifecycle = options.lifecycle || \"LOAD\";\n logger.info(\n `Adding ${mode}-driven @kosServiceRequest \"${options.methodName}\" (${method} ${options.servicePath}) to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n // EVERY file-level write below (eslint pragma, imports, the const, the\n // merged interface) re-writes the file text, which makes ts-morph forget\n // nodes captured before it. So all of them happen first, and the class is\n // looked up only once nothing else will move underneath it.\n const endpointConst = endpointConstName(options.methodName);\n const className = getModelClass(sf).getName();\n if (!className) throw new Error(\"Model class has no name.\");\n const typeParams = getModelClass(sf)\n .getTypeParameters()\n .map((tp) => tp.getText());\n\n // BOTH forms hang off one endpoint descriptor. The path is written once and\n // every derived type reads it back through `typeof`, so a path can never\n // drift between the decorator and the signature.\n ensureNamedImport(sf, serviceImport as string, [\n { name: \"endpoint\" },\n { name: \"serviceRequest\" },\n ]);\n ensureModuleConst(sf, {\n name: endpointConst,\n initializer: `endpoint(${JSON.stringify(\n options.servicePath\n )}, ${JSON.stringify(method)})`,\n });\n\n if (mode === \"lifecycle\") {\n ensureNamedImport(sf, serviceImport as string, [\n { name: \"EndpointResponse\", isTypeOnly: true },\n ]);\n ensureNamedImport(sf, resolveSdkModuleSpecifier(sf), [\n { name: \"DependencyLifecycle\" },\n ]);\n addDecoratedMethod(getModelClass(sf), {\n name: options.methodName,\n decoratorName: \"serviceRequest\",\n decoratorArgsText: `${endpointConst}, { lifecycle: DependencyLifecycle.${lifecycle} }`,\n // The manager invokes phase handlers error-first, passing (null, data)\n // on success. The `error` half is only ever reached because\n // `serviceRequest` supplies an errorHandler — the bare decorator\n // defaults to `throw`, which fails the phase instead of calling back.\n parameters: [\n { name: \"error\", type: \"string | null\" },\n {\n name: \"data\",\n type: `EndpointResponse<typeof ${endpointConst}>`,\n },\n ],\n returnType: \"void\",\n statements: \"// TODO: apply `data` to the model\",\n });\n return;\n }\n\n ensureNamedImport(sf, serviceImport as string, [\n { name: \"EndpointCtx\", isTypeOnly: true },\n ]);\n ensureNamedImport(sf, resolveSdkModuleSpecifier(sf), [\n { name: \"executeServiceRequest\" },\n { name: \"kosLoggerAware\" },\n { name: \"KosLoggerAware\", isTypeOnly: true },\n ]);\n\n // executeServiceRequest reports failures through the model's logger, so the\n // model has to be logger-aware for the emitted call to compile at all.\n ensureFileEslintDisable(\n sf,\n \"@typescript-eslint/no-unsafe-declaration-merging\"\n );\n ensureDeclarationMerge(sf, className, \"KosLoggerAware\", typeParams);\n addClassDecorator(getModelClass(sf), \"kosLoggerAware\", { argsText: \"\" });\n\n addDecoratedMethod(getModelClass(sf), {\n name: options.methodName,\n decoratorName: \"serviceRequest\",\n decoratorArgsText: endpointConst,\n // Optional: the framework appends the context, callers never pass it.\n parameters: [\n {\n name: \"$ctx\",\n type: `EndpointCtx<typeof ${endpointConst}>`,\n optional: true,\n },\n ],\n isAsync: true,\n returnType: \"Promise<void>\",\n statements: [\n \"const data = await executeServiceRequest(this, $ctx);\",\n \"if (!data) return;\",\n \"// TODO: apply `data` to the model\",\n ].join(\"\\n\"),\n });\n });\n\n return { modelFilePath, serviceModule: serviceImport as string, mode };\n}\n\n/** `refreshBoard` → `ENDPOINT_REFRESH_BOARD`. */\nfunction endpointConstName(methodName: string): string {\n const snake = methodName\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[^A-Za-z0-9]+/g, \"_\")\n .toUpperCase();\n return `ENDPOINT_${snake}`;\n}\n","/**\n * Read-only static validation of a KOS model against best-practice guardrails.\n * AST-based (ts-morph), high-signal / low-false-positive — a few reliable checks\n * beat many noisy ones. Mirrors the AGENTS.md guardrails + anti-patterns guide.\n */\nimport { Project } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\n\nexport interface ValidateModelOptions {\n modelName: string;\n modelProject: string;\n modelPath?: string;\n}\n\nexport interface ValidationFinding {\n level: \"error\" | \"warning\";\n rule: string;\n message: string;\n}\n\nexport interface ValidationResult {\n modelFilePath: string;\n ok: boolean; // no errors (warnings allowed)\n findings: ValidationFinding[];\n}\n\n/** Extract a `*Model`-named element type from a raw collection type, else null. */\nfunction modelElementType(typeText: string): string | null {\n let m: RegExpMatchArray | null;\n if ((m = typeText.match(/^([A-Za-z_]\\w*Model)\\s*\\[\\]$/))) return m[1];\n if ((m = typeText.match(/^Array<\\s*([A-Za-z_]\\w*Model)\\s*>$/))) return m[1];\n if ((m = typeText.match(/^(?:Map|Set)<[^>]*?\\b([A-Za-z_]\\w*Model)\\b[^>]*>$/)))\n return m[1];\n return null;\n}\n\nexport function validateModel(\n codegenFs: CodegenFileSystem,\n options: ValidateModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): ValidationResult {\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n const content = codegenFs.read(modelFilePath);\n if (content === null) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = project.createSourceFile(modelFilePath, content, {\n overwrite: true,\n });\n const findings: ValidationFinding[] = [];\n\n // 1. Must be a KOS model.\n const hasKosModel = sf.getClasses().some((c) => c.getDecorator(\"kosModel\"));\n if (!hasKosModel) {\n findings.push({\n level: \"error\",\n rule: \"missing-kosModel\",\n message: \"No @kosModel decorator found — this is not a KOS model.\",\n });\n }\n\n const imports = sf.getImportDeclarations();\n\n // 2. No direct MobX — reactivity is internal to KOS.\n const mobxImport = imports.find((d) =>\n /^mobx(-react-lite)?$/.test(d.getModuleSpecifierValue())\n );\n if (mobxImport) {\n findings.push({\n level: \"error\",\n rule: \"mobx-import\",\n message:\n \"Imports mobx directly. Reactivity is internal to KOS — remove the mobx import and use KOS reactivity / container models.\",\n });\n }\n\n // 3. Service requests should use the typed decorator from the api:generate'd\n // service module, not the untyped one from the SDK barrel.\n const barrelServiceRequest = imports.find(\n (d) =>\n d.getModuleSpecifierValue() === \"@kosdev-code/kos-ui-sdk\" &&\n d.getNamedImports().some((n) => n.getName() === \"kosServiceRequest\")\n );\n if (barrelServiceRequest) {\n findings.push({\n level: \"warning\",\n rule: \"untyped-service-request\",\n message:\n \"kosServiceRequest imported from the SDK barrel. Use the typed decorator from the api:generate'd service module so paths are validated against the OpenAPI types.\",\n });\n }\n\n // 4. Model collections should be KOS containers + enrolled as children.\n for (const cls of sf.getClasses()) {\n for (const prop of cls.getProperties()) {\n const name = prop.getName();\n const typeText = (prop.getTypeNode()?.getText() ?? \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n const initText = prop.getInitializer()?.getText() ?? \"\";\n const hasChild = !!prop.getDecorator(\"kosChild\");\n\n const isModelContainer =\n /\\bI?KosModelContainer\\s*</.test(typeText) ||\n /new\\s+KosModelContainer\\b/.test(initText);\n\n if (isModelContainer && !hasChild) {\n findings.push({\n level: \"warning\",\n rule: \"container-missing-kosChild\",\n message: `Property '${name}' is a model container but is not marked @kosChild — add @kosChild so its models join the model graph and lifecycle.`,\n });\n continue;\n }\n\n const elem = modelElementType(typeText);\n if (elem && !isModelContainer) {\n findings.push({\n level: \"warning\",\n rule: \"raw-model-collection\",\n message: `Property '${name}' is a raw ${typeText} of models — prefer a KosModelContainer<${elem}> (indexing, sorting, lifecycle, delta handling) marked @kosChild.`,\n });\n }\n }\n }\n\n const hasError = findings.some((f) => f.level === \"error\");\n return { modelFilePath, ok: !hasError, findings };\n}\n","/**\n * Read-only structural report of a KOS model. AST-based (ts-morph): surfaces the\n * model's type id, the @kos* decorators it carries, the capabilities already wired\n * (child collections, dependencies, topic handlers, config properties, service\n * requests, effects, futures), and whether it is itself a companion. Lets an agent\n * see what a model already has before deciding which mutator to apply — the\n * discovery counterpart to validate_model.\n */\nimport { Project, type ClassDeclaration } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\n\nexport interface DescribeModelOptions {\n modelName: string;\n modelProject: string;\n modelPath?: string;\n}\n\n/** A decorated member (method or property) and the bare argument text of its decorator. */\nexport interface DescribedMember {\n name: string;\n /** First decorator argument as written, trimmed (e.g. the topic or config path). */\n arg?: string;\n /** Property/return type as written, when present. */\n type?: string;\n}\n\nexport interface ModelDescription {\n modelFilePath: string;\n /** Value of the MODEL_TYPE constant, if declared. */\n modelType?: string;\n /** The impl class name (e.g. BoardModelImpl). */\n className?: string;\n /** Class-level @kos* decorators in source order (e.g. kosModel, kosLoggerAware). */\n classDecorators: string[];\n singleton: boolean;\n /** True when the class carries @kosCompanion — it augments a parent model. */\n isCompanion: boolean;\n /** @kosChild collection/child properties. */\n children: DescribedMember[];\n /** @kosDependency cross-model references. */\n dependencies: DescribedMember[];\n /** @kosTopicHandler subscription methods. */\n topicHandlers: DescribedMember[];\n /** @kosConfigProperty reactive config-bound properties. */\n configProperties: DescribedMember[];\n /** @kosServiceRequest backend-call methods. */\n serviceRequests: DescribedMember[];\n /** @kosModelEffect reaction methods. */\n effects: DescribedMember[];\n /** @kosFuture long-running-operation methods. */\n futures: DescribedMember[];\n}\n\n/** First decorator argument as written, whitespace-collapsed to one line, if any. */\nfunction firstDecoratorArg(decoratorText: string): string | undefined {\n const open = decoratorText.indexOf(\"(\");\n if (open === -1) return undefined;\n const inner = decoratorText\n .slice(open + 1, decoratorText.lastIndexOf(\")\"))\n .replace(/\\s+/g, \" \")\n .trim();\n return inner || undefined;\n}\n\nfunction collectDecorated(\n cls: ClassDeclaration,\n decoratorName: string\n): DescribedMember[] {\n const members: DescribedMember[] = [];\n const visit = (\n name: string,\n decoratorTextOf: () => string | undefined,\n typeText?: string\n ) => {\n const text = decoratorTextOf();\n if (text === undefined) return;\n members.push({\n name,\n arg: firstDecoratorArg(text),\n type: typeText || undefined,\n });\n };\n for (const m of cls.getMethods()) {\n const dec = m.getDecorator(decoratorName);\n if (dec) {\n visit(m.getName(), () => dec.getText(), m.getReturnTypeNode()?.getText());\n }\n }\n for (const p of cls.getProperties()) {\n const dec = p.getDecorator(decoratorName);\n if (dec) {\n visit(p.getName(), () => dec.getText(), p.getTypeNode()?.getText());\n }\n }\n return members;\n}\n\nexport function describeModel(\n codegenFs: CodegenFileSystem,\n options: DescribeModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): ModelDescription {\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n const content = codegenFs.read(modelFilePath);\n if (content === null) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = project.createSourceFile(modelFilePath, content, {\n overwrite: true,\n });\n\n // MODEL_TYPE = \"...\" (the runtime model-type id).\n let modelType: string | undefined;\n const modelTypeDecl = sf.getVariableDeclaration(\"MODEL_TYPE\");\n if (modelTypeDecl) {\n const init = modelTypeDecl.getInitializer()?.getText();\n if (init) modelType = init.replace(/^[\"'`]|[\"'`]$/g, \"\");\n }\n\n // The model impl class is the one carrying @kosModel.\n const cls =\n sf.getClasses().find((c) => c.getDecorator(\"kosModel\")) ??\n sf.getClasses().find((c) => c.isExported()) ??\n sf.getClasses()[0];\n\n if (!cls) {\n return {\n modelFilePath,\n modelType,\n classDecorators: [],\n singleton: false,\n isCompanion: false,\n children: [],\n dependencies: [],\n topicHandlers: [],\n configProperties: [],\n serviceRequests: [],\n effects: [],\n futures: [],\n };\n }\n\n const classDecorators = cls.getDecorators().map((d) => d.getName());\n const kosModelArg = cls.getDecorator(\"kosModel\")\n ? firstDecoratorArg(cls.getDecorator(\"kosModel\")!.getText())\n : undefined;\n const singleton = /\\bsingleton\\s*:\\s*true\\b/.test(kosModelArg ?? \"\");\n\n return {\n modelFilePath,\n modelType,\n className: cls.getName(),\n classDecorators,\n singleton,\n isCompanion: classDecorators.includes(\"kosCompanion\"),\n children: collectDecorated(cls, \"kosChild\"),\n dependencies: collectDecorated(cls, \"kosDependency\"),\n topicHandlers: collectDecorated(cls, \"kosTopicHandler\"),\n configProperties: collectDecorated(cls, \"kosConfigProperty\"),\n serviceRequests: collectDecorated(cls, \"kosServiceRequest\"),\n effects: collectDecorated(cls, \"kosModelEffect\"),\n futures: collectDecorated(cls, \"kosFuture\"),\n };\n}\n","/**\n * Resolve an exported SDK symbol to its signature, so an agent (especially a\n * consumer building models) never hallucinates a type's shape. AST-based\n * (ts-morph); confined here in codegen-core, never a runtime SDK dep.\n *\n * Graceful resolution, in priority order:\n * 1. Monorepo SOURCE — the SDK project's `src/index.ts` (source of truth).\n * 2. Installed DECLARATIONS — `node_modules/<pkg>` `exports[\".\"].*.types` /\n * `types` entry (a consumer workspace only has this built `.d.ts`).\n * 3. Neither present → a clear \"not resolvable\" result (no throw).\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Project, Node, type ExportedDeclarations } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\n\nconst DEFAULT_SDK_PACKAGE = \"@kosdev-code/kos-ui-sdk\";\nconst MAX_SIGNATURE_CHARS = 2000;\n\nexport interface LookupSdkTypeOptions {\n symbol: string;\n /** SDK package name. Default @kosdev-code/kos-ui-sdk. */\n sdkPackage?: string;\n /** Explicit entry file (absolute or workspace-relative), overriding resolution. */\n entryFile?: string;\n}\n\nexport interface SdkSymbolDeclaration {\n kind: string;\n /** Declaring file, workspace-relative when under root. */\n file: string;\n /** Signature text (bodies stripped, length-capped). */\n signature: string;\n}\n\nexport interface SdkTypeLookupResult {\n symbol: string;\n resolved: boolean;\n /** Which surface answered: the SDK source tree or the installed declarations. */\n mode?: \"source\" | \"declarations\";\n entryFile?: string;\n declarations: SdkSymbolDeclaration[];\n /** Set when not resolved (or partially) — explains what was tried. */\n message?: string;\n triedEntries: string[];\n}\n\n/** Read a package's TS-declaration entry from its package.json exports/types. */\nfunction declarationEntryFromPackageJson(pkgDir: string): string | undefined {\n const pkgJsonPath = path.join(pkgDir, \"package.json\");\n if (!fs.existsSync(pkgJsonPath)) return undefined;\n let pkg: any;\n try {\n pkg = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf-8\"));\n } catch {\n return undefined;\n }\n const candidates: Array<string | undefined> = [\n pkg.exports?.[\".\"]?.import?.types,\n pkg.exports?.[\".\"]?.require?.types,\n pkg.exports?.[\".\"]?.types,\n pkg.types,\n pkg.typings,\n ];\n for (const rel of candidates) {\n if (typeof rel === \"string\") {\n const abs = path.join(pkgDir, rel);\n if (fs.existsSync(abs)) return abs;\n }\n }\n return undefined;\n}\n\n/** Build the ordered list of candidate entry files (absolute paths). */\nfunction resolveCandidateEntries(\n codegenFs: CodegenFileSystem,\n options: LookupSdkTypeOptions,\n projects?: Map<string, ProjectConfiguration>\n): Array<{ file: string; mode: \"source\" | \"declarations\" }> {\n const root = codegenFs.root;\n const sdkPackage = options.sdkPackage || DEFAULT_SDK_PACKAGE;\n const out: Array<{ file: string; mode: \"source\" | \"declarations\" }> = [];\n\n if (options.entryFile) {\n const abs = path.isAbsolute(options.entryFile)\n ? options.entryFile\n : path.join(root, options.entryFile);\n out.push({\n file: abs,\n mode: abs.endsWith(\".d.ts\") ? \"declarations\" : \"source\",\n });\n }\n\n // 1. Monorepo source — the SDK project's src/index.ts.\n const sdkProject = findProjectByName(root, sdkPackage, projects);\n const sourceRoot = sdkProject\n ? sdkProject.sourceRoot || path.join(sdkProject.root, \"src\")\n : undefined;\n for (const srcDir of [\n sourceRoot && path.join(root, sourceRoot),\n path.join(root, \"packages\", \"kos-ui-sdk\", \"src\"),\n ]) {\n if (!srcDir) continue;\n const entry = path.join(srcDir, \"index.ts\");\n if (fs.existsSync(entry) && !out.some((c) => c.file === entry)) {\n out.push({ file: entry, mode: \"source\" });\n }\n }\n\n // 2. Installed declarations — node_modules/<pkg> types entry.\n const dts = declarationEntryFromPackageJson(\n path.join(root, \"node_modules\", ...sdkPackage.split(\"/\"))\n );\n if (dts && !out.some((c) => c.file === dts)) {\n out.push({ file: dts, mode: \"declarations\" });\n }\n\n return out;\n}\n\n/**\n * Render an object-like type as a member list via the type checker. KOS model\n * interfaces are utility-wrapped aliases — e.g. `type KosTimeModel =\n * PublicModelInterface<KosTimeModelImpl>` — so the verbatim declaration text is\n * just the unevaluated alias and carries NO members. Resolving the type expands\n * the projection (public members, private/@internal already stripped by\n * `PublicModelInterface<T>`) into the real surface: `timezone`,\n * `updateSystemTimezone(...)`, etc. Returns undefined for non-object types\n * (unions, primitives, generics with unresolved params) so the caller falls back\n * to the literal text, which is clearer for those.\n */\nfunction renderTypeMembers(\n decl: ExportedDeclarations & { getType: () => import(\"ts-morph\").Type }\n): string | undefined {\n const props = decl.getType().getProperties();\n if (props.length === 0) return undefined;\n const lines: string[] = [];\n for (const p of props) {\n const at = p.getDeclarations()[0] ?? decl;\n let pt: string;\n try {\n pt = p.getTypeAtLocation(at).getText(at);\n } catch {\n pt = \"unknown\";\n }\n lines.push(` ${p.getName()}: ${pt};`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Strip method/function bodies and length-cap a declaration's text. */\nfunction signatureText(decl: ExportedDeclarations): string {\n let text: string;\n if (Node.isTypeAliasDeclaration(decl) || Node.isInterfaceDeclaration(decl)) {\n // Resolve to members so utility-wrapped model interfaces yield their real\n // shape in ONE lookup (no jump from the bean to the model alias to the impl).\n const members = renderTypeMembers(decl);\n if (members) {\n const name = decl.getName();\n const tps = decl.getTypeParameters().map((t) => t.getText());\n const head = tps.length ? `${name}<${tps.join(\", \")}>` : name;\n const kw = Node.isInterfaceDeclaration(decl) ? \"interface\" : \"type\";\n const open = Node.isInterfaceDeclaration(decl) ? \" {\" : \" = {\";\n text = `${kw} ${head}${open}\\n${members}\\n}`;\n } else {\n text = decl.getText();\n }\n } else if (Node.isEnumDeclaration(decl)) {\n text = decl.getText();\n } else if (Node.isVariableDeclaration(decl)) {\n // Avoid dumping a large initializer — show the inferred type instead.\n const name = decl.getName();\n const typeText = decl.getType().getText(decl);\n text = `const ${name}: ${typeText}`;\n } else if (Node.isFunctionDeclaration(decl)) {\n if (decl.getBody()) decl.removeBody();\n text = decl.getText();\n } else if (Node.isClassDeclaration(decl)) {\n // Show the PUBLIC surface — drop private/protected members so the useful\n // public API fits the cap, and strip method/constructor bodies.\n const isHidden = (member: { getScope?: () => string }): boolean =>\n typeof member.getScope === \"function\" && member.getScope() !== \"public\";\n for (const p of decl.getProperties()) if (isHidden(p)) p.remove();\n for (const a of [...decl.getGetAccessors(), ...decl.getSetAccessors()]) {\n if (isHidden(a)) a.remove();\n }\n for (const m of decl.getMethods()) {\n if (isHidden(m)) {\n m.remove();\n continue;\n }\n if (m.getBody()) m.removeBody();\n }\n for (const c of decl.getConstructors()) {\n if (c.getBody()) c.removeBody();\n }\n text = decl.getText();\n } else {\n text = decl.getText();\n }\n text = text.replace(/\\s+$/, \"\");\n if (text.length > MAX_SIGNATURE_CHARS) {\n text = text.slice(0, MAX_SIGNATURE_CHARS) + \"\\n/* … truncated */\";\n }\n return text;\n}\n\nexport function lookupSdkType(\n codegenFs: CodegenFileSystem,\n options: LookupSdkTypeOptions,\n projects?: Map<string, ProjectConfiguration>\n): SdkTypeLookupResult {\n const symbol = options.symbol;\n const candidates = resolveCandidateEntries(codegenFs, options, projects);\n const triedEntries = candidates.map((c) =>\n path.relative(codegenFs.root, c.file)\n );\n\n if (candidates.length === 0) {\n return {\n symbol,\n resolved: false,\n declarations: [],\n triedEntries,\n message:\n \"No SDK entry found — neither the SDK source (packages/kos-ui-sdk/src/index.ts) nor an installed declaration file (node_modules/@kosdev-code/kos-ui-sdk) is present. Build or install the SDK, or pass entryFile.\",\n };\n }\n\n const project = new Project({\n skipAddingFilesFromTsConfig: true,\n compilerOptions: { allowJs: false, skipLibCheck: true },\n });\n\n for (const candidate of candidates) {\n let sf;\n try {\n sf = project.addSourceFileAtPath(candidate.file);\n } catch {\n continue;\n }\n let exported: ReadonlyMap<string, ExportedDeclarations[]>;\n try {\n exported = sf.getExportedDeclarations();\n } catch {\n continue;\n }\n const decls = exported.get(symbol);\n if (!decls || decls.length === 0) continue;\n\n return {\n symbol,\n resolved: true,\n mode: candidate.mode,\n entryFile: path.relative(codegenFs.root, candidate.file),\n triedEntries,\n declarations: decls.map((d) => {\n return {\n kind: d.getKindName(),\n file: path.relative(codegenFs.root, d.getSourceFile().getFilePath()),\n signature: signatureText(d),\n };\n }),\n };\n }\n\n return {\n symbol,\n resolved: false,\n declarations: [],\n triedEntries,\n message: `Symbol '${symbol}' is not an export of the SDK entry (${triedEntries.join(\n \", \"\n )}). Check the name, or it may be internal / not part of the public surface.`,\n };\n}\n","/**\n * Type definitions for KOS Component Generator\n */\n\n// Plugin type constants\nexport const PLUGIN_TYPES = {\n CUI: \"cui\",\n UTILITY: \"utility\",\n TROUBLE_ACTION: \"troubleAction\",\n SETUP: \"setup\",\n SETTING: \"setting\",\n NAV: \"nav\",\n CONTROL_POUR: \"controlPour\",\n CUSTOM: \"custom\",\n} as const;\n\nexport type PluginType = (typeof PLUGIN_TYPES)[keyof typeof PLUGIN_TYPES];\n\n// Contribution type mapping\nexport const CONTRIBUTION_TYPE_MAP: Record<string, string> = {\n [PLUGIN_TYPES.SETUP]: \"setup\",\n [PLUGIN_TYPES.CUI]: \"cui\",\n [PLUGIN_TYPES.UTILITY]: \"utility\",\n [PLUGIN_TYPES.SETTING]: \"setting\",\n [PLUGIN_TYPES.NAV]: \"nav\",\n [PLUGIN_TYPES.TROUBLE_ACTION]: \"trouble-action\",\n [PLUGIN_TYPES.CONTROL_POUR]: \"control-pour\",\n [PLUGIN_TYPES.CUSTOM]: \"custom\",\n};\n\n// Plugin types that require localization\nexport const LOCALIZED_PLUGIN_TYPES: ReadonlySet<string> = new Set([\n PLUGIN_TYPES.CUI,\n PLUGIN_TYPES.UTILITY,\n PLUGIN_TYPES.SETUP,\n PLUGIN_TYPES.SETTING,\n PLUGIN_TYPES.NAV,\n PLUGIN_TYPES.CONTROL_POUR,\n PLUGIN_TYPES.TROUBLE_ACTION,\n PLUGIN_TYPES.CUSTOM,\n]);\n\n// Configuration interfaces\nexport interface ExperienceConfig {\n id: string;\n component: string;\n location: string;\n}\n\nexport interface PluginContribution {\n id: string;\n title: string;\n namespace: string;\n experienceId?: string;\n [key: string]: any; // Allow plugin-specific properties\n}\n\nexport interface PluginConfiguration {\n contributions: Record<string, PluginContribution[]>;\n experiences: Record<string, ExperienceConfig>;\n views?: Record<string, any[]>;\n}\n\nexport interface NormalizedComponentOptions {\n name: string;\n nameDashCase: string;\n nameCamelCase: string;\n namePascalCase: string;\n nameLowerCase: string;\n appProject: string;\n group?: string;\n pluginType?: string;\n type: string;\n appDirectory: string;\n useEmotionCss?: boolean;\n contributionKey?: string; // User-specified contribution key for custom plugins\n}\n\n// Component generator input options\nexport interface ComponentOptions {\n name: string;\n type: \"components\" | \"features\";\n useEmotionCss: boolean;\n appProject: string;\n appDirectory: string;\n modelDirectory: string;\n group?: string;\n pluginType?: string;\n contributionKey?: string;\n registrationProject?: string;\n skipRegistration?: boolean;\n companion?: boolean;\n companionModel?: string;\n companionModelProject?: string;\n companionPattern?: \"composition\" | \"decorator\";\n}\n\n// JSON path constants for .kos.json structure\nexport const KOS_JSON_PATHS = {\n PLUGIN_ROOT: \"kosdev.ddk.ncui.plugin\",\n CONTRIBUTES: \"kosdev.ddk.ncui.plugin.contributes\",\n EXPERIENCES: \"kosdev.ddk.ncui.plugin.contributes.experiences\",\n VIEWS: \"kosdev.ddk.ncui.plugin.contributes.views\",\n TAB_VIEW: \"ddk.ncui.settings.tabView\",\n} as const;\n","import {\n ExperienceConfig,\n NormalizedComponentOptions,\n PluginConfiguration,\n} from \"../types\";\n\n/**\n * Base interface for plugin-specific handlers\n */\nexport interface PluginHandler {\n /**\n * Creates the plugin-specific configuration\n */\n createConfiguration(options: NormalizedComponentOptions): PluginConfiguration;\n\n /**\n * Returns the contribution key for this plugin type\n */\n getContributionKey(): string;\n\n /**\n * Checks if this plugin type requires localization\n */\n requiresLocalization(): boolean;\n\n /**\n * Gets the template source path for this plugin type\n */\n getTemplatePath(): string;\n}\n\n/**\n * Base implementation with common functionality\n */\nexport abstract class BasePluginHandler implements PluginHandler {\n protected abstract pluginType: string;\n protected abstract contributionKey: string;\n protected abstract requiresI18n: boolean;\n\n abstract createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration;\n\n getContributionKey(): string {\n return this.contributionKey;\n }\n\n requiresLocalization(): boolean {\n return this.requiresI18n;\n }\n\n getTemplatePath(): string {\n return this.contributionKey;\n }\n\n /**\n * Helper to create experience configuration\n */\n protected createExperience(\n options: NormalizedComponentOptions,\n experienceId: string\n ): ExperienceConfig {\n const compPath = this.getComponentPath(options);\n\n return {\n id: experienceId,\n component: options.namePascalCase,\n location: `./src/${compPath}`,\n };\n }\n\n /**\n * Helper to get component path\n */\n protected getComponentPath(options: NormalizedComponentOptions): string {\n return `${options.appDirectory}/${this.contributionKey}/${options.nameDashCase}/${options.nameDashCase}.tsx`;\n }\n\n /**\n * Helper to create config prefix\n */\n protected getConfigPrefix(options: NormalizedComponentOptions): string {\n return `${options.appProject}.${options.nameCamelCase}`;\n }\n}\n","import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class ControlPourPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CONTROL_POUR;\n protected contributionKey = \"control-pour\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.controlPour.experience`;\n\n const contribution = {\n id: `${configPrefix}.controlPour`,\n title: `${configPrefix}.controlPour.title`,\n namespace: options.appProject,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n controlPour: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class CuiPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CUI;\n protected contributionKey = \"cui\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.cui.experience`;\n\n const contribution = {\n id: configPrefix,\n title: `${configPrefix}.cui.title`,\n namespace: options.appProject,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n cui: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class CustomPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CUSTOM;\n protected contributionKey = \"custom\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.${\n options.contributionKey || \"custom\"\n }.experience`;\n\n // Get the user-specified contribution key or default to 'custom'\n const userContributionKey = options.contributionKey || \"custom\";\n\n const contribution = {\n id: configPrefix,\n title: `${configPrefix}.${userContributionKey}.title`,\n namespace: options.appProject,\n experienceId,\n // TODO: Add additional fields as required by the plugin-explorer specification\n // Refer to the plugin-explorer documentation for your specific contribution type\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n [userContributionKey]: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n\n override getTemplatePath(): string {\n // Use the generic 'custom' template path\n return this.contributionKey || \"custom\";\n }\n\n protected override getComponentPath(\n options: NormalizedComponentOptions\n ): string {\n // Use the user-specified contribution key for the path if available\n const pathKey = options.contributionKey || \"custom\";\n return `${options.appDirectory}/${pathKey}/${options.nameDashCase}/${options.nameDashCase}.tsx`;\n }\n}\n","import { NormalizedComponentOptions, PluginConfiguration } from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\n/**\n * Default handler for non-plugin components\n */\nexport class DefaultComponentHandler extends BasePluginHandler {\n protected pluginType = \"component\";\n protected contributionKey = \"components\";\n protected requiresI18n = false;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const compPath = this.getComponentPath(options);\n\n const viewConfig = {\n id: `${options.appProject}.${options.nameCamelCase}`,\n title: \"ddk.ncui.config.title\",\n namespace: options.appProject,\n component: options.namePascalCase,\n location: `./src/${compPath}`,\n };\n\n return {\n contributions: {},\n experiences: {},\n views: {\n [this.getTabViewKey()]: [viewConfig],\n },\n };\n }\n\n private getTabViewKey(): string {\n return \"ddk.ncui.settings.tabView\";\n }\n\n override getTemplatePath(): string {\n return \"files\"; // Default template path\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class NavPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.NAV;\n protected contributionKey = \"nav\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.nav.experience`;\n\n const contribution = {\n id: `${configPrefix}.nav`,\n title: `${configPrefix}.nav.title`,\n namespace: options.appProject,\n navDescriptor: options.nameLowerCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n navViews: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class SettingPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.SETTING;\n protected contributionKey = \"setting\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.settings.experience`;\n\n const contribution = {\n id: `${configPrefix}.setting`,\n title: `${configPrefix}.setting.title`,\n namespace: options.appProject,\n settingsGroup: options.group || \"general\",\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n settings: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class SetupPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.SETUP;\n protected contributionKey = \"setup\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.setup.experience`;\n\n const contribution = {\n id: `${configPrefix}.setup`,\n title: `${configPrefix}.setup.title`,\n namespace: options.appProject,\n setupDescriptor: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n setupStep: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class TroubleActionPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.TROUBLE_ACTION;\n protected contributionKey = \"trouble-action\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.troubleAction.experience`;\n\n const contribution = {\n id: `${configPrefix}.troubleAction`,\n title: `${configPrefix}.troubleAction.title`,\n namespace: options.appProject,\n troubleType: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n troubleActions: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class UtilityPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.UTILITY;\n protected contributionKey = \"utility\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.util.experience`;\n\n const contribution = {\n id: `${configPrefix}.util`,\n title: `${configPrefix}.utility.title`,\n namespace: options.appProject,\n utilDescriptor: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n utilities: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import { PLUGIN_TYPES } from \"../types\";\nimport { PluginHandler } from \"./base\";\nimport { ControlPourPluginHandler } from \"./control-pour-handler\";\nimport { CuiPluginHandler } from \"./cui-handler\";\nimport { CustomPluginHandler } from \"./custom-handler\";\nimport { DefaultComponentHandler } from \"./default-handler\";\nimport { NavPluginHandler } from \"./nav-handler\";\nimport { SettingPluginHandler } from \"./setting-handler\";\nimport { SetupPluginHandler } from \"./setup-handler\";\nimport { TroubleActionPluginHandler } from \"./trouble-action-handler\";\nimport { UtilityPluginHandler } from \"./utility-handler\";\n\n/**\n * Factory for creating plugin-specific handlers\n */\nexport class PluginHandlerFactory {\n private static handlers: Map<string, new () => PluginHandler> = new Map<\n string,\n new () => PluginHandler\n >([\n [PLUGIN_TYPES.CUI, CuiPluginHandler],\n [PLUGIN_TYPES.UTILITY, UtilityPluginHandler],\n [PLUGIN_TYPES.SETTING, SettingPluginHandler],\n [PLUGIN_TYPES.SETUP, SetupPluginHandler],\n [PLUGIN_TYPES.NAV, NavPluginHandler],\n [PLUGIN_TYPES.CONTROL_POUR, ControlPourPluginHandler],\n [PLUGIN_TYPES.TROUBLE_ACTION, TroubleActionPluginHandler],\n [PLUGIN_TYPES.CUSTOM, CustomPluginHandler],\n ]);\n\n static createHandler(pluginType?: string): PluginHandler {\n if (!pluginType) {\n return new DefaultComponentHandler();\n }\n\n const HandlerClass = this.handlers.get(pluginType);\n\n if (!HandlerClass) {\n console.warn(\n `No handler found for plugin type: ${pluginType}. Using default handler.`\n );\n return new DefaultComponentHandler();\n }\n\n return new HandlerClass();\n }\n\n static isValidPluginType(type: string): boolean {\n return this.handlers.has(type);\n }\n}\n","import * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport { generateFilesFromTemplates } from \"../../../generate-files\";\nimport { NormalizedComponentOptions } from \"../types\";\n\n/**\n * Generates component files from templates.\n *\n * @param codegenFs - Filesystem abstraction\n * @param templateBaseDir - Absolute path to the base template directory\n * @param templateSubPath - Sub-path from handler (e.g., \"cui\", \"files\")\n * @param targetPath - Destination path relative to workspace root\n * @param options - Normalized component options for template substitution\n */\nexport function generateComponentFiles(\n codegenFs: CodegenFileSystem,\n templateBaseDir: string,\n templateSubPath: string,\n targetPath: string,\n options: NormalizedComponentOptions\n): void {\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateBaseDir, templateSubPath),\n targetPath,\n options\n );\n\n // Handle CSS file deletion if needed\n if (options.useEmotionCss) {\n deleteCssFile(codegenFs, targetPath, options);\n }\n}\n\n/**\n * Deletes the CSS file when using Emotion CSS\n */\nfunction deleteCssFile(\n codegenFs: CodegenFileSystem,\n targetPath: string,\n options: NormalizedComponentOptions\n): void {\n const cssPath = path.join(targetPath, `${options.nameDashCase}.css`);\n\n if (codegenFs.exists(cssPath)) {\n codegenFs.delete(cssPath);\n }\n}\n","import type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport { updateJson } from \"../../../json-utils\";\nimport { PluginConfiguration } from \"../types\";\n\n/**\n * Builder for constructing and updating .kos.json configuration\n */\nexport class KosConfigBuilder {\n private contributions: Record<string, any[]> = {};\n private experiences: Record<string, any> = {};\n private views: Record<string, any[]> = {};\n\n /**\n * Adds plugin configuration to the builder\n */\n addPluginConfiguration(config: PluginConfiguration): this {\n // Merge contributions\n Object.entries(config.contributions).forEach(([key, value]) => {\n this.contributions[key] = [...(this.contributions[key] || []), ...value];\n });\n\n // Merge experiences\n Object.assign(this.experiences, config.experiences);\n\n // Merge views\n if (config.views) {\n Object.entries(config.views).forEach(([key, value]) => {\n this.views[key] = [...(this.views[key] || []), ...value];\n });\n }\n\n return this;\n }\n\n /**\n * Applies the built configuration to the .kos.json file\n */\n applyToFile(codegenFs: CodegenFileSystem, kosConfigPath: string): void {\n updateJson(codegenFs, kosConfigPath, (json: any) => {\n // Initialize the deep structure if it doesn't exist\n const structure = this.initializeStructure(json);\n\n // Merge contributions\n Object.entries(this.contributions).forEach(([key, value]) => {\n structure.contributes[key] = [\n ...(structure.contributes[key] || []),\n ...value,\n ];\n });\n\n // Merge experiences\n structure.contributes.experiences = {\n ...structure.contributes.experiences,\n ...this.experiences,\n };\n\n // Merge views\n if (Object.keys(this.views).length > 0) {\n structure.contributes.views = structure.contributes.views || {};\n\n Object.entries(this.views).forEach(([key, value]) => {\n structure.contributes.views[key] = [\n ...(structure.contributes.views[key] || []),\n ...value,\n ];\n });\n }\n\n return json;\n });\n }\n\n /**\n * Initializes the deep JSON structure\n */\n private initializeStructure(json: any): any {\n json.kos ??= {};\n json.kos.ui ??= {};\n json.kos.ui.plugin ??= {};\n json.kos.ui.plugin.contributes ??= {};\n\n return json.kos.ui.plugin;\n }\n\n /**\n * Creates a new builder instance\n */\n static create(): KosConfigBuilder {\n return new KosConfigBuilder();\n }\n}\n","import * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport { updateJson } from \"../../../json-utils\";\nimport { NormalizedComponentOptions } from \"../types\";\n\n/**\n * Updates localization files for plugin components\n */\nexport function updateLocalization(\n codegenFs: CodegenFileSystem,\n projectRoot: string,\n options: NormalizedComponentOptions,\n pluginType: string\n): void {\n const localePath = path.join(\n projectRoot,\n \"assets\",\n \"locales\",\n \"en\",\n `${options.appProject}.json`\n );\n\n if (!codegenFs.exists(localePath)) {\n console.warn(`Locale file not found: ${localePath}`);\n return;\n }\n\n updateJson(codegenFs, localePath, (json: any) => {\n // Ensure nested structure exists\n json[options.appProject] = json[options.appProject] || {};\n json[options.appProject][options.nameCamelCase] =\n json[options.appProject][options.nameCamelCase] || {};\n\n // Add localization entry\n json[options.appProject][options.nameCamelCase][pluginType] = {\n ...json[options.appProject][options.nameCamelCase][pluginType],\n title: options.nameCamelCase,\n };\n\n return json;\n });\n}\n","import type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../../project-discovery\";\nimport { PluginHandlerFactory } from \"../plugin-handlers/factory\";\nimport type { ComponentOptions } from \"../types\";\n\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Validates generator options\n */\nexport function validateOptions(\n codegenFs: CodegenFileSystem,\n options: ComponentOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n // Validate required fields\n if (!options.name) {\n throw new ValidationError(\"Component name is required\");\n }\n\n if (!options.appProject) {\n throw new ValidationError(\"App project is required\");\n }\n\n // Validate project exists\n const project = findProjectByName(\n codegenFs.root,\n options.appProject,\n projects\n );\n if (!project) {\n throw new ValidationError(\n `Project \"${options.appProject}\" not found in workspace`\n );\n }\n\n // Validate plugin type if provided\n if (\n options.pluginType &&\n !PluginHandlerFactory.isValidPluginType(options.pluginType)\n ) {\n console.warn(\n `Unknown plugin type \"${options.pluginType}\". ` +\n `Component will be generated with default configuration.`\n );\n }\n\n // Validate group is provided for setting type\n if (options.pluginType === \"setting\" && !options.group) {\n throw new ValidationError(\n \"Settings group is required for setting plugin type\"\n );\n }\n}\n\n/**\n * Validates file paths\n */\nexport function validateFilePath(\n codegenFs: CodegenFileSystem,\n filePath: string\n): boolean {\n return codegenFs.exists(filePath);\n}\n\n/**\n * Safe JSON update with error handling\n */\nexport function safeJsonUpdate<T = any>(\n operation: () => T,\n fallback: T,\n errorMessage?: string\n): T {\n try {\n return operation();\n } catch (error) {\n if (errorMessage) {\n console.error(errorMessage, error);\n }\n return fallback;\n }\n}\n","/**\n * Core component generator — framework-agnostic.\n *\n * Replaces the Nx-coupled logic from kos-nx-plugin kos-component generator.\n * Uses CodegenFileSystem instead of @nx/devkit Tree.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { findProjectByName } from \"../../project-discovery\";\nimport { normalizeOptions } from \"../normalize-options\";\nimport { PluginHandlerFactory } from \"./plugin-handlers/factory\";\nimport {\n ComponentOptions,\n CONTRIBUTION_TYPE_MAP,\n NormalizedComponentOptions,\n} from \"./types\";\nimport { generateComponentFiles } from \"./utils/file-generator\";\nimport { KosConfigBuilder } from \"./utils/kos-config-builder\";\nimport { updateLocalization } from \"./utils/localization\";\nimport { validateOptions } from \"./utils/validation\";\n\nexport type { ComponentOptions } from \"./types\";\n\n/**\n * Generate a KOS component using the framework-agnostic CodegenFileSystem.\n *\n * @param codegenFs - Filesystem abstraction (NxTreeAdapter or DirectFileSystem)\n * @param templateDir - Absolute path to the template base directory\n * @param options - Component generator options\n * @param projects - Optional pre-computed project map (avoids rescan)\n */\nexport function generateComponent(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: ComponentOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n // Step 1: Validate options\n validateOptions(codegenFs, options, projects);\n\n // Step 2: Normalize options\n const normalized = prepareOptions(codegenFs, options, projects);\n\n // Step 3: Get project configuration\n const projectConfig = findProjectByName(\n codegenFs.root,\n normalized.appProject,\n projects\n );\n\n if (!projectConfig) {\n throw new Error(\n `Project \"${normalized.appProject}\" not found in workspace`\n );\n }\n\n const projectRoot = projectConfig.sourceRoot;\n\n if (!projectRoot) {\n throw new Error(\n `No source root found for project ${normalized.appProject}`\n );\n }\n\n // Step 4: Generate component files\n generateFiles(codegenFs, templateDir, projectRoot, normalized);\n\n // Step 5: Update plugin configuration if needed\n if (options.pluginType) {\n updatePluginConfiguration(codegenFs, projectConfig, normalized);\n }\n}\n\n/**\n * Prepares and normalizes options\n */\nfunction prepareOptions(\n codegenFs: CodegenFileSystem,\n options: ComponentOptions,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedComponentOptions {\n const normalized = normalizeOptions(\n codegenFs,\n {\n ...options,\n modelProject: \"__NONE__\",\n },\n projects\n ) as unknown as NormalizedComponentOptions;\n\n // Get KOS configuration for component location\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n options.appProject,\n projects\n );\n\n const componentLocation =\n (kosConfig?.generator?.defaults as any)?.component?.folder || \"\";\n\n // Set component directory and type\n normalized.appDirectory = options.appDirectory || componentLocation;\n normalized.type =\n CONTRIBUTION_TYPE_MAP[options.pluginType || \"\"] || options.type;\n\n // Pass through contributionKey for custom plugin types\n if (options.contributionKey) {\n normalized.contributionKey = options.contributionKey;\n }\n\n return normalized;\n}\n\n/**\n * Generates component files from templates\n */\nfunction generateFiles(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n projectRoot: string,\n options: NormalizedComponentOptions\n): void {\n // Get appropriate handler\n const handler = PluginHandlerFactory.createHandler(options.pluginType);\n const templatePath = handler.getTemplatePath();\n\n // Determine target path\n const targetPath = path.join(\n projectRoot,\n options.appDirectory,\n options.type,\n options.nameDashCase\n );\n\n // Generate files\n generateComponentFiles(\n codegenFs,\n templateDir,\n templatePath,\n targetPath,\n options\n );\n}\n\n/**\n * Updates plugin configuration in .kos.json\n */\nfunction updatePluginConfiguration(\n codegenFs: CodegenFileSystem,\n projectConfig: ProjectConfiguration,\n options: NormalizedComponentOptions\n): void {\n const kosConfigPath = path.join(projectConfig.root, \".kos.json\");\n\n if (!codegenFs.exists(kosConfigPath)) {\n console.warn(`No .kos.json found at ${kosConfigPath}`);\n return;\n }\n\n // Get handler and create configuration\n const handler = PluginHandlerFactory.createHandler(options.pluginType);\n const pluginConfig = handler.createConfiguration(options);\n\n // Update .kos.json using builder\n const builder = KosConfigBuilder.create();\n builder.addPluginConfiguration(pluginConfig);\n builder.applyToFile(codegenFs, kosConfigPath);\n\n // Update localization if needed\n if (handler.requiresLocalization() && projectConfig.sourceRoot) {\n updateLocalization(\n codegenFs,\n projectConfig.sourceRoot,\n options,\n handler.getContributionKey()\n );\n }\n}\n"],"names":["path","fs","ejs","Project","IndentationText","QuoteKind","VariableDeclarationKind","Scope","SERVICE_MODULE_RE","ts","FRAMEWORK_TYPES","Node"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../packages/kos-codegen-core/src/lib/codegen-filesystem.ts","../../../packages/kos-codegen-core/src/lib/logger.ts","../../../packages/kos-codegen-core/src/lib/generate-files.ts","../../../packages/kos-codegen-core/src/lib/project-discovery.ts","../../../packages/kos-codegen-core/src/lib/json-utils.ts","../../../packages/kos-codegen-core/src/lib/format-files.ts","../../../packages/kos-codegen-core/src/lib/name-utils.ts","../../../packages/kos-codegen-core/src/lib/normalize-values.ts","../../../packages/kos-codegen-core/src/lib/kos-config.ts","../../../packages/kos-codegen-core/src/lib/template-resolver.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-splash-project.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-init.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-polyglot-workspace.ts","../../../packages/kos-codegen-core/src/lib/generators/kab-targets.ts","../../../packages/kos-codegen-core/src/lib/generators/ci-sync.ts","../../../packages/kos-codegen-core/src/lib/generators/java-workspace.ts","../../../packages/kos-codegen-core/src/lib/generators/normalize-options.ts","../../../packages/kos-codegen-core/src/lib/generators/augment/ts-toolkit.ts","../../../packages/kos-codegen-core/src/lib/generators/service-catalog.ts","../../../packages/kos-codegen-core/src/lib/generators/release-version-script.ts","../../../packages/kos-codegen-core/src/lib/generators/barrel-utils.ts","../../../packages/kos-codegen-core/src/lib/generators/update-model-index.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-hook.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-context.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-container-model.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-companion-model.ts","../../../packages/kos-codegen-core/src/lib/generators/generate-model.ts","../../../packages/kos-codegen-core/src/lib/generators/augment/resolve-model-file.ts","../../../packages/kos-codegen-core/src/lib/generators/augment/model-services.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/normalize-options.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/model-transformer.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/service-transformer.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/registration-transformer.ts","../../../packages/kos-codegen-core/src/lib/generators/add-future-to-model/generate-add-future-to-model.ts","../../../packages/kos-codegen-core/src/lib/generators/add-container-support/generate-add-container-support.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-model-effect.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-dependency.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-child.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-topic-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-config-property.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-property.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-computed.ts","../../../packages/kos-codegen-core/src/lib/generators/member-mutators/add-service-request.ts","../../../packages/kos-codegen-core/src/lib/generators/validate/validate-model.ts","../../../packages/kos-codegen-core/src/lib/generators/describe/describe-model.ts","../../../packages/kos-codegen-core/src/lib/generators/types/lookup-sdk-type.ts","../../../packages/kos-codegen-core/src/lib/generators/component/types.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/base.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/control-pour-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/cui-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/custom-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/default-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/nav-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/setting-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/setup-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/trouble-action-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/utility-handler.ts","../../../packages/kos-codegen-core/src/lib/generators/component/plugin-handlers/factory.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/file-generator.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/kos-config-builder.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/localization.ts","../../../packages/kos-codegen-core/src/lib/generators/component/utils/validation.ts","../../../packages/kos-codegen-core/src/lib/generators/component/generate-component.ts"],"sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * Abstraction over a filesystem for code generation.\n *\n * Mirrors the subset of the Nx Tree API that generators actually use,\n * enabling the same generator logic to run against the real filesystem\n * (CLI, VS Code extension) or an in-memory tree (Nx adapter).\n */\nexport interface CodegenFileSystem {\n /** Workspace root directory (absolute path). */\n readonly root: string;\n\n /** Read a file relative to the workspace root. Returns null if not found. */\n read(filePath: string): string | null;\n\n /** Write a file relative to the workspace root. Creates parent dirs as needed. */\n write(filePath: string, content: string): void;\n\n /** Check whether a file exists relative to the workspace root. */\n exists(filePath: string): boolean;\n\n /** Delete a file relative to the workspace root. No-op if not found. */\n delete(filePath: string): void;\n\n /** List all files under a directory (relative to root), returned as root-relative paths. */\n listFiles(dirPath: string): string[];\n}\n\n/**\n * CodegenFileSystem wrapper that records absolute paths of every file written.\n * Wrap any CodegenFileSystem to collect written paths for post-generation steps\n * such as formatting.\n *\n * @example\n * const fs = new TrackingFileSystem(new DirectFileSystem(cwd));\n * generateModel({ codegenFs: fs, ... });\n * await formatFiles(fs.root, fs.writtenPaths);\n */\nexport class TrackingFileSystem implements CodegenFileSystem {\n private readonly inner: CodegenFileSystem;\n private readonly _writtenPaths: string[] = [];\n\n constructor(inner: CodegenFileSystem) {\n this.inner = inner;\n }\n\n get root(): string {\n return this.inner.root;\n }\n\n get writtenPaths(): string[] {\n return [...this._writtenPaths];\n }\n\n read(filePath: string): string | null {\n return this.inner.read(filePath);\n }\n\n write(filePath: string, content: string): void {\n this.inner.write(filePath, content);\n this._writtenPaths.push(\n path.isAbsolute(filePath)\n ? filePath\n : path.join(this.inner.root, filePath)\n );\n }\n\n exists(filePath: string): boolean {\n return this.inner.exists(filePath);\n }\n\n delete(filePath: string): void {\n this.inner.delete(filePath);\n }\n\n listFiles(dirPath: string): string[] {\n return this.inner.listFiles(dirPath);\n }\n}\n\n/**\n * CodegenFileSystem backed by the real Node.js filesystem.\n * All paths passed to interface methods are relative to the workspace root.\n */\nexport class DirectFileSystem implements CodegenFileSystem {\n readonly root: string;\n\n constructor(workspaceRoot: string) {\n this.root = path.resolve(workspaceRoot);\n }\n\n read(filePath: string): string | null {\n const abs = this.resolve(filePath);\n try {\n return fs.readFileSync(abs, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n write(filePath: string, content: string): void {\n const abs = this.resolve(filePath);\n fs.mkdirSync(path.dirname(abs), { recursive: true });\n fs.writeFileSync(abs, content, \"utf-8\");\n }\n\n exists(filePath: string): boolean {\n return fs.existsSync(this.resolve(filePath));\n }\n\n delete(filePath: string): void {\n const abs = this.resolve(filePath);\n try {\n fs.unlinkSync(abs);\n } catch {\n // no-op if file doesn't exist\n }\n }\n\n listFiles(dirPath: string): string[] {\n const abs = this.resolve(dirPath);\n if (!fs.existsSync(abs)) {\n return [];\n }\n return this.walkDir(abs).map((file) => path.relative(this.root, file));\n }\n\n private resolve(filePath: string): string {\n if (path.isAbsolute(filePath)) {\n return filePath;\n }\n return path.join(this.root, filePath);\n }\n\n private walkDir(dir: string): string[] {\n const results: string[] = [];\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...this.walkDir(full));\n } else {\n results.push(full);\n }\n }\n return results;\n }\n}\n","/**\n * Settable logger interface for kos-codegen-core.\n *\n * Consumers (CLI, VS Code extension, Nx adapter) set their own logger\n * via setCodegenLogger(). Defaults to silent no-op.\n */\nexport interface CodegenLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst noopLogger: CodegenLogger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n};\n\nlet activeLogger: CodegenLogger = noopLogger;\n\nexport function setCodegenLogger(logger: CodegenLogger): void {\n activeLogger = logger;\n}\n\nexport function getCodegenLogger(): CodegenLogger {\n return activeLogger;\n}\n","/**\n * EJS-based file generation — replaces @nx/devkit generateFiles().\n *\n * Walks a source template directory, processes each file through EJS,\n * interpolates __var__ tokens in filenames, strips .template suffixes,\n * and writes results via a CodegenFileSystem.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as ejs from \"ejs\";\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\nimport { getCodegenLogger } from \"./logger\";\n\n/**\n * Generate files from a template directory into a destination path.\n *\n * Behavior matches @nx/devkit generateFiles():\n * - Walks `srcFolder` recursively\n * - For each file, replaces `__propName__` in the filename using `substitutions`\n * - Strips `.template` suffix from filenames\n * - Processes file contents through EJS with `substitutions` as data\n * - Writes the result to `destFolder` (relative to fs.root) via the CodegenFileSystem\n *\n * @param codegenFs - Target filesystem abstraction\n * @param srcFolder - Absolute path to the template directory\n * @param destFolder - Destination path relative to the filesystem root\n * @param substitutions - Key-value pairs for EJS and filename interpolation\n */\nexport function generateFilesFromTemplates(\n codegenFs: CodegenFileSystem,\n srcFolder: string,\n destFolder: string,\n substitutions: Record<string, any>\n): void {\n const logger = getCodegenLogger();\n const templateFiles = walkTemplateDir(srcFolder);\n\n for (const templateFile of templateFiles) {\n const relPath = path.relative(srcFolder, templateFile);\n\n // Interpolate __var__ tokens in the path segments\n let destRelPath = interpolateFilename(relPath, substitutions);\n\n // Strip .template suffix\n if (destRelPath.endsWith(\".template\")) {\n destRelPath = destRelPath.slice(0, -\".template\".length);\n }\n\n const destPath = path.join(destFolder, destRelPath);\n\n // Templates are read from the real filesystem (package assets),\n // while outputs are written through CodegenFileSystem.\n const rawContent = fs.readFileSync(templateFile, \"utf-8\");\n const rendered = ejs.render(rawContent, substitutions, {\n filename: templateFile, // for EJS error messages and includes\n });\n\n logger.debug(`Generating ${destPath}`);\n codegenFs.write(destPath, rendered);\n }\n}\n\n/**\n * Replace `__propName__` tokens in a file path with values from substitutions.\n * E.g., `__nameDashCase__-model.ts` with `{ nameDashCase: \"my-widget\" }` becomes\n * `my-widget-model.ts`.\n */\nfunction interpolateFilename(\n filePath: string,\n substitutions: Record<string, any>\n): string {\n return filePath.replace(/__([^_]+)__/g, (match, key: string) => {\n if (key in substitutions) {\n return String(substitutions[key]);\n }\n return match; // leave unmatched tokens as-is\n });\n}\n\nfunction walkTemplateDir(dir: string): string[] {\n const results: string[] = [];\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...walkTemplateDir(full));\n } else {\n results.push(full);\n }\n }\n return results;\n}\n","/**\n * Nx-free project discovery — scans for project.json files in the workspace.\n *\n * Replaces @nx/devkit readProjectConfiguration, getProjects, readNxJson.\n * Based on the pattern in kos-model-extension/src/utils/workspace-scanner.ts.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport fg from \"fast-glob\";\nimport { getCodegenLogger } from \"./logger\";\n\nexport interface ProjectConfiguration {\n name: string;\n root: string;\n sourceRoot: string;\n projectType?: \"library\" | \"application\";\n targets?: Record<string, unknown>;\n tags?: string[];\n}\n\n/**\n * Discover all projects in the workspace by scanning for project.json files.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @returns Map of project name to ProjectConfiguration\n */\nexport function discoverProjects(\n workspaceRoot: string\n): Map<string, ProjectConfiguration> {\n const logger = getCodegenLogger();\n const projects = new Map<string, ProjectConfiguration>();\n\n const projectJsonPaths = fg.sync(\"**/project.json\", {\n cwd: workspaceRoot,\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/.git/**\"],\n absolute: false,\n });\n\n for (const relPath of projectJsonPaths) {\n const absPath = path.join(workspaceRoot, relPath);\n try {\n const raw = fs.readFileSync(absPath, \"utf-8\");\n const json = JSON.parse(raw);\n const projectRoot = path.dirname(relPath);\n const name = json.name ?? path.basename(projectRoot);\n\n const config: ProjectConfiguration = {\n name,\n root: projectRoot,\n sourceRoot: json.sourceRoot ?? path.join(projectRoot, \"src\"),\n projectType: json.projectType,\n targets: json.targets,\n tags: json.tags,\n };\n\n projects.set(name, config);\n logger.debug(`Discovered project: ${name} at ${projectRoot}`);\n } catch (err) {\n logger.warn(`Failed to parse ${absPath}: ${err}`);\n }\n }\n\n logger.info(`Discovered ${projects.size} projects`);\n return projects;\n}\n\n/**\n * Find a single project by name.\n *\n * Note: This rescans the workspace on every call. If you need to look up\n * multiple projects, call discoverProjects() once and query the returned Map.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @param projectName - The project name to look up\n * @param projects - Optional pre-computed project map (avoids rescan)\n * @returns ProjectConfiguration or undefined if not found\n */\nexport function findProjectByName(\n workspaceRoot: string,\n projectName: string,\n projects?: Map<string, ProjectConfiguration>\n): ProjectConfiguration | undefined {\n const map = projects ?? discoverProjects(workspaceRoot);\n return map.get(projectName);\n}\n\n/**\n * Find the project that contains a given file path.\n * Walks up from the file path looking for the nearest project.json.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @param filePath - Absolute path to a file within the workspace\n * @returns ProjectConfiguration or undefined if not within any project\n */\nexport function findProjectForPath(\n workspaceRoot: string,\n filePath: string\n): ProjectConfiguration | undefined {\n const resolved = path.resolve(workspaceRoot);\n let dir = path.dirname(path.resolve(filePath));\n\n while (dir.startsWith(resolved) && dir !== resolved) {\n const projectJsonPath = path.join(dir, \"project.json\");\n if (fs.existsSync(projectJsonPath)) {\n try {\n const raw = fs.readFileSync(projectJsonPath, \"utf-8\");\n const json = JSON.parse(raw);\n const projectRoot = path.relative(resolved, dir);\n const name = json.name ?? path.basename(dir);\n\n return {\n name,\n root: projectRoot,\n sourceRoot: json.sourceRoot ?? path.join(projectRoot, \"src\"),\n projectType: json.projectType,\n targets: json.targets,\n tags: json.tags,\n };\n } catch {\n return undefined;\n }\n }\n dir = path.dirname(dir);\n }\n\n return undefined;\n}\n\n/**\n * Read the workspace-level nx.json configuration.\n *\n * @param workspaceRoot - Absolute path to the workspace root\n * @returns Parsed nx.json contents, or empty object if not found\n */\nexport function readNxJson(workspaceRoot: string): Record<string, unknown> {\n const nxJsonPath = path.join(workspaceRoot, \"nx.json\");\n try {\n const raw = fs.readFileSync(nxJsonPath, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return {};\n }\n}\n","/**\n * JSON read/write/update utilities operating on a CodegenFileSystem.\n *\n * Replaces @nx/devkit readJson, writeJson, updateJson.\n */\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\n\n/**\n * Read and parse a JSON file from the filesystem.\n *\n * @param codegenFs - Filesystem abstraction\n * @param filePath - Path relative to workspace root\n * @returns Parsed JSON object\n * @throws If the file does not exist or contains invalid JSON\n */\nexport function readJson<T = Record<string, unknown>>(\n codegenFs: CodegenFileSystem,\n filePath: string\n): T {\n const content = codegenFs.read(filePath);\n if (content === null) {\n throw new Error(`File not found: ${filePath}`);\n }\n return JSON.parse(content) as T;\n}\n\n/**\n * Serialize and write a JSON object to the filesystem.\n *\n * @param codegenFs - Filesystem abstraction\n * @param filePath - Path relative to workspace root\n * @param value - Object to serialize\n */\nexport function writeJson<T = Record<string, unknown>>(\n codegenFs: CodegenFileSystem,\n filePath: string,\n value: T\n): void {\n codegenFs.write(filePath, JSON.stringify(value, null, 2) + \"\\n\");\n}\n\n/**\n * Read a JSON file, apply a transformation, and write it back.\n *\n * @param codegenFs - Filesystem abstraction\n * @param filePath - Path relative to workspace root\n * @param updater - Function that receives the parsed object and returns the updated object\n */\nexport function updateJson<T = Record<string, unknown>>(\n codegenFs: CodegenFileSystem,\n filePath: string,\n updater: (json: T) => T\n): void {\n const current = readJson<T>(codegenFs, filePath);\n const updated = updater(current);\n writeJson(codegenFs, filePath, updated);\n}\n","/**\n * Format files using Prettier — replaces @nx/devkit formatFiles().\n *\n * Resolves the Prettier config from the workspace root and formats\n * all files tracked by a CodegenFileSystem that match supported extensions.\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport prettier from \"prettier\";\nimport { getCodegenLogger } from \"./logger\";\n\nconst FORMATTABLE_EXTENSIONS = new Set([\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".css\",\n \".scss\",\n \".md\",\n \".yaml\",\n \".yml\",\n \".html\",\n]);\n\n/**\n * Format files at the given paths using Prettier.\n *\n * @param workspaceRoot - Absolute path to the workspace root (for Prettier config resolution)\n * @param filePaths - Absolute paths of files to format\n */\nexport async function formatFiles(\n workspaceRoot: string,\n filePaths: string[]\n): Promise<void> {\n const logger = getCodegenLogger();\n\n for (const filePath of filePaths) {\n const ext = path.extname(filePath);\n if (!FORMATTABLE_EXTENSIONS.has(ext)) {\n continue;\n }\n\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const options = await prettier.resolveConfig(filePath, {\n editorconfig: true,\n });\n const formatted = await prettier.format(content, {\n ...options,\n filepath: filePath,\n });\n fs.writeFileSync(filePath, formatted, \"utf-8\");\n logger.debug(`Formatted ${path.relative(workspaceRoot, filePath)}`);\n } catch (err) {\n logger.warn(`Failed to format ${filePath}: ${err}`);\n }\n }\n}\n","/**\n * String case-conversion utilities.\n *\n * Pure functions with no external dependencies.\n * Ported from kos-nx-plugin/src/utils/name-utils.ts (minus the logger calls).\n */\n\nexport function dashCase(input: string): string {\n return input\n .replace(/\\s+/g, \"-\")\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n}\n\nexport function camelCase(input: string): string {\n if (input.length === 0) return \"\";\n const words = input.split(/-|\\s+/);\n if (words.length > 0 && words[0].length > 0) {\n words[0] = words[0].charAt(0).toLowerCase() + words[0].slice(1);\n }\n for (let i = 1; i < words.length; i++) {\n words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);\n }\n return words.join(\"\");\n}\n\nexport function pascalCase(input: string): string {\n if (input.length === 0) return \"\";\n const cc = camelCase(input);\n return cc[0].toUpperCase() + cc.slice(1);\n}\n\nexport function properCase(input: string): string {\n const words = input\n .toLowerCase()\n .replaceAll(\"-\", \" \")\n .split(\" \")\n .filter(Boolean);\n for (let i = 0; i < words.length; i++) {\n words[i] = words[i][0].toUpperCase() + words[i].slice(1);\n }\n return words.join(\"\");\n}\n\n/**\n * Convert to CONSTANT_CASE. Expects space-separated or dash-separated input.\n * camelCase input is not split (e.g. \"myWidget\" becomes \"MYWIDGET\").\n */\nexport function constantCase(input: string): string {\n if (input.length === 0) return \"\";\n return input\n .toUpperCase()\n .split(/[\\s-]+/)\n .filter(Boolean)\n .join(\"_\");\n}\n","/**\n * Option normalization — generates all case variants for every string property.\n *\n * Given `{ name: \"my-widget\" }`, produces:\n * ```\n * {\n * name: \"my-widget\",\n * nameCamelCase: \"myWidget\",\n * namePascalCase: \"MyWidget\",\n * nameDashCase: \"my-widget\",\n * nameProperCase: \"MyWidget\",\n * nameConstantCase: \"MY_WIDGET\",\n * nameLowerCase: \"my-widget\",\n * }\n * ```\n *\n * Ported from kos-nx-plugin/src/utils/normalize-value.ts.\n */\nimport {\n camelCase,\n constantCase,\n dashCase,\n pascalCase,\n properCase,\n} from \"./name-utils\";\n\ntype NormalizedFunctions =\n | \"CamelCase\"\n | \"ConstantCase\"\n | \"DashCase\"\n | \"PascalCase\"\n | \"ProperCase\"\n | \"LowerCase\";\n\ntype NormalizedValue<Type extends Record<string, string>> = {\n [k in Type as `${Extract<keyof Type, string>}${NormalizedFunctions}`]: string;\n};\n\ntype Normalized<T extends string> = {\n [k in T as `${T}${NormalizedFunctions}`]: string;\n};\n\nconst normalizeValue = <T extends string>(\n optionsName: T,\n value: string\n): Normalized<T> & { [k in T]: string } =>\n ({\n [`${camelCase(optionsName)}CamelCase`]: camelCase(value),\n [`${camelCase(optionsName)}ConstantCase`]: constantCase(value),\n [`${camelCase(optionsName)}DashCase`]: dashCase(value),\n [`${camelCase(optionsName)}PascalCase`]: pascalCase(value),\n [`${camelCase(optionsName)}ProperCase`]: properCase(value),\n [`${camelCase(optionsName)}LowerCase`]: value.toLowerCase(),\n [`${optionsName}`]: value,\n } as Normalized<T> & { [k in T]: string });\n\nexport const normalizeAllValues = <T extends Record<string, any>>(\n options: T\n): NormalizedValue<T> & T => {\n let normalizedValues = {} as NormalizedValue<T> & T;\n for (const key in options) {\n if (Object.prototype.hasOwnProperty.call(options, key)) {\n const element = options[key];\n const newOptions =\n typeof element !== \"string\" || element === \"\"\n ? { [key]: element }\n : normalizeValue(key, element);\n\n normalizedValues = {\n ...normalizedValues,\n ...newOptions,\n };\n }\n }\n return normalizedValues;\n};\n","/**\n * KOS project and model configuration utilities.\n *\n * Reads and writes .kos.json files through CodegenFileSystem.\n * Ported from kos-nx-plugin/src/utils/project-utils.ts.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"./codegen-filesystem\";\nimport {\n findProjectByName,\n findProjectForPath,\n type ProjectConfiguration,\n} from \"./project-discovery\";\nimport { updateJson } from \"./json-utils\";\nimport { dashCase } from \"./name-utils\";\nimport { getCodegenLogger } from \"./logger\";\n\nexport interface KosModelConfiguration {\n name: string;\n type: string;\n singleton: boolean;\n container?: boolean;\n /**\n * Exported registration bean symbol (e.g. \"Board\") — the agent-facing handle.\n * Imported from the SDK root; `factory.type` is the modelType to depend on, and\n * models are auto-registered so consumers never instantiate it. Written\n * automatically by the generator (it names the bean). Links to the full shape\n * at `kos://types/{factory}`.\n */\n factory?: string;\n /**\n * One-line, human-curated purpose. The only genuinely authored field — set via\n * an optional prompt/slot at generation, never inferred.\n */\n purpose?: string;\n /**\n * `.kos.json` keys of the container/managing models that hold this model —\n * consume it THROUGH them (depend on the container, navigate), not by id. Set\n * only when generation establishes containment; never inferred.\n */\n managedBy?: string[];\n}\n\nexport interface KosProjectConfiguration {\n name: string;\n type: string;\n version: string;\n models: Record<string, KosModelConfiguration>;\n generator?: {\n internal?: boolean;\n defaults?: {\n model?: { folder?: string };\n component?: { folder?: string };\n };\n };\n}\n\nexport function getCurrentDirectoryName(cwd: string): string | undefined {\n return cwd.split(\"/\").pop();\n}\n\n/**\n * Find the project that contains the given working directory.\n */\nexport function getProject(\n codegenFs: CodegenFileSystem,\n cwd: string\n): ProjectConfiguration | undefined {\n return findProjectForPath(codegenFs.root, cwd);\n}\n\n/**\n * Read .kos.json for a project, creating a default if it doesn't exist.\n */\nexport function getKosProjectConfiguration(\n codegenFs: CodegenFileSystem,\n projectName: string,\n projects?: Map<string, ProjectConfiguration>\n): KosProjectConfiguration | undefined {\n const project = findProjectByName(codegenFs.root, projectName, projects);\n if (!project) return undefined;\n\n const configPath = path.join(project.root, \".kos.json\");\n if (!codegenFs.exists(configPath)) {\n const defaultConfig: KosProjectConfiguration = {\n name: `${dashCase(projectName)}-model`,\n type: \"kos.model\",\n version: \"0.1.0\",\n models: {},\n generator: { defaults: { model: { folder: \"\" } } },\n };\n codegenFs.write(configPath, JSON.stringify(defaultConfig, null, 2));\n }\n\n const content = codegenFs.read(configPath);\n return content ? JSON.parse(content) : undefined;\n}\n\n/**\n * Find the `.kos.json` model key for a model name. Keys are normally the model\n * name itself; fall back to matching the derived `<name>-model` type id so a\n * differently-cased name still resolves.\n */\nfunction findModelKey(\n models: Record<string, any>,\n name: string\n): string | undefined {\n if (models[name]) return name;\n const typeId = `${dashCase(name)}-model`;\n return Object.keys(models).find((k) => models[k]?.type === typeId);\n}\n\n/**\n * Record that an existing model gained in-place container support\n * (`@kosContainerAware`) in `.kos.json`: flag it `container: true`, and — when it\n * holds a concrete model type rather than the generic `IKosDataModel` — record\n * that child as `managedBy` this container so it is consumed THROUGH it.\n *\n * Containment is only recorded from this explicit generation step; nothing is\n * inferred. No-ops if the project or its `.kos.json` can't be found.\n */\nexport function recordContainerSupportInKosConfig(params: {\n codegenFs: CodegenFileSystem;\n projectName: string;\n modelName: string;\n childType?: string;\n projects?: Map<string, ProjectConfiguration>;\n}): void {\n const project = findProjectByName(\n params.codegenFs.root,\n params.projectName,\n params.projects\n );\n if (!project) return;\n const configPath = path.join(project.root, \".kos.json\");\n if (!params.codegenFs.exists(configPath)) return;\n\n updateJson(params.codegenFs, configPath, (json: any) => {\n const models: Record<string, any> = json.models ?? {};\n const selfKey = findModelKey(models, params.modelName);\n if (!selfKey) return json;\n\n models[selfKey] = { ...models[selfKey], container: true };\n\n const childType = params.childType?.trim();\n if (\n childType &&\n childType !== \"IKosDataModel\" &&\n /Model$/.test(childType)\n ) {\n const childTypeId = dashCase(childType);\n const childKey = Object.keys(models).find(\n (k) => models[k]?.type === childTypeId\n );\n if (childKey && childKey !== selfKey) {\n const managedBy = [\n ...new Set([...(models[childKey].managedBy ?? []), selfKey]),\n ];\n models[childKey] = { ...models[childKey], managedBy };\n }\n }\n\n json.models = models;\n return json;\n });\n}\n\n/**\n * Read a specific model's configuration from .kos.json.\n */\nexport function getKosModelConfiguration(\n codegenFs: CodegenFileSystem,\n projectName: string,\n modelName: string,\n projects?: Map<string, ProjectConfiguration>\n): KosModelConfiguration | undefined {\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectName,\n projects\n );\n return kosConfig?.models?.[modelName];\n}\n\n/**\n * Read a specific property from a model's configuration.\n */\nexport function getKosModelConfigProp(params: {\n codegenFs: CodegenFileSystem;\n project: string;\n modelName: string;\n prop: string;\n projects?: Map<string, ProjectConfiguration>;\n}): any {\n const config = getKosModelConfiguration(\n params.codegenFs,\n params.project,\n params.modelName,\n params.projects\n );\n return config ? (config as any)[params.prop] : undefined;\n}\n\n/**\n * Add a model entry to a project's .kos.json.\n */\nexport function addKosModelConfiguration(params: {\n codegenFs: CodegenFileSystem;\n projectName: string;\n projectRoot: string;\n modelName: string;\n singleton: boolean;\n container?: boolean;\n /** Exported registration bean symbol (the generator knows it). */\n factory?: string;\n}): void {\n const logger = getCodegenLogger();\n const kosConfigPath = path.join(params.projectRoot, \".kos.json\");\n\n if (!params.codegenFs.exists(kosConfigPath)) {\n logger.info(`Creating .kos.json in ${params.projectRoot}`);\n const defaultConfig = {\n name: params.projectName,\n type: \"kos.model\",\n version: \"0.1.0\",\n models: {},\n generator: { defaults: { model: { folder: \"\" } } },\n };\n params.codegenFs.write(\n kosConfigPath,\n JSON.stringify(defaultConfig, null, 2) + \"\\n\"\n );\n }\n\n updateJson(params.codegenFs, kosConfigPath, (json: any) => {\n const existing = json.models?.[params.modelName] ?? {};\n json.models = {\n ...json.models,\n [params.modelName]: {\n // Preserve any curated fields (purpose/managedBy) on re-generation.\n ...existing,\n name: params.modelName,\n type: `${params.modelName}-model`,\n singleton: !!params.singleton,\n container: !!params.container,\n ...(params.factory ? { factory: params.factory } : {}),\n },\n };\n return json;\n });\n}\n","import * as path from \"path\";\nimport * as fs from \"fs\";\n\n/**\n * Finds the root directory containing the templates/ directory.\n *\n * Resolution order:\n * 1. KOS_TEMPLATE_BASE_DIR env var — set by kos-ui-cli when running as a\n * bundled ESM package (where __dirname is unavailable).\n * 2. Walk up from __dirname looking for this package's package.json — works\n * in CJS context (tsc-compiled output or direct Node.js require).\n */\nfunction findPackageRoot(): string {\n if (process.env.KOS_TEMPLATE_BASE_DIR) {\n return process.env.KOS_TEMPLATE_BASE_DIR;\n }\n\n // CJS context: walk up from __dirname to find our package.json\n let dir = __dirname;\n while (dir !== path.dirname(dir)) {\n const pkgPath = path.join(dir, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n if (pkg.name === \"@kosdev-code/kos-codegen-core\") {\n return dir;\n }\n } catch {\n // Not valid JSON, keep looking\n }\n }\n dir = path.dirname(dir);\n }\n // Fallback: assume source layout (src/lib/ -> package root)\n return path.resolve(__dirname, \"..\", \"..\");\n}\n\n/**\n * Resolves the absolute path to a generator's template directory.\n * Templates are stored in the `templates/` directory at the package root.\n *\n * @param generatorName - The generator name matching a subdirectory under templates/\n * @returns Absolute path to the template directory for the given generator\n */\nexport function getTemplateDir(generatorName: string): string {\n return path.join(findPackageRoot(), \"templates\", generatorName);\n}\n","/**\n * Core generator: Splash project.\n *\n * Creates a splash screen project structure and associated tooling scripts.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { normalizeAllValues } from \"../normalize-values\";\n\nexport interface SplashProjectOptions {\n name: string;\n}\n\n/**\n * Generate a splash project with its associated tooling.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory containing\n * `project/` and `tools/` subdirectories\n * @param options - Generator options\n */\nexport function generateSplashProject(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: SplashProjectOptions\n): void {\n const normalized = normalizeAllValues(options);\n\n const projectRoot = `splash/${normalized.nameDashCase}`;\n const toolsRoot = path.join(\"tools\", \"scripts\");\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"project\"),\n projectRoot,\n normalized\n );\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"tools\"),\n toolsRoot,\n normalized\n );\n}\n","/**\n * Core generator: KOS Init.\n *\n * Updates nx.json with default KOS generator configuration for the workspace.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { readJson, writeJson } from \"../json-utils\";\nimport { getCodegenLogger } from \"../logger\";\n\nexport interface KosInitOptions {\n appProject: string;\n modelProject: string;\n registrationProject?: string;\n}\n\n/**\n * Initialize KOS generator defaults in nx.json.\n *\n * Sets default project references for kos-model, kos-component,\n * kos-context, and kos-hook generators.\n *\n * @param codegenFs - Target filesystem\n * @param options - Generator options\n */\nexport function generateInit(\n codegenFs: CodegenFileSystem,\n options: KosInitOptions\n): void {\n const logger = getCodegenLogger();\n const { appProject, modelProject, registrationProject } = options;\n\n let nxConfig: Record<string, any>;\n try {\n nxConfig = readJson(codegenFs, \"nx.json\");\n } catch {\n logger.error(\"Unable to find nx.json\");\n return;\n }\n\n logger.info(\"Updating nx.json\");\n\n const defaultProjectConfig = {\n appProject,\n modelProject,\n registrationProject,\n modelDirectory: \"lib\",\n appDirectory: \"app\",\n components: true,\n internal: false,\n singleton: false,\n unitTests: true,\n };\n\n const generatorsConfig = nxConfig.generators || {};\n const kosConfig = generatorsConfig[\"@kosdev-code/kos-nx-plugin\"] || {};\n\n const updateConfig = (configName: string) => {\n const config = kosConfig[configName] || { ...defaultProjectConfig };\n config.appProject = appProject;\n config.modelProject = modelProject;\n config.registrationProject = registrationProject;\n kosConfig[configName] = config;\n };\n\n [\"kos-model\", \"kos-component\", \"kos-context\", \"kos-hook\"].forEach(\n updateConfig\n );\n\n nxConfig.generators = {\n ...generatorsConfig,\n \"@kosdev-code/kos-nx-plugin\": kosConfig,\n };\n\n writeJson(codegenFs, \"nx.json\", nxConfig);\n}\n","/**\n * Core generator: polyglot workspace repo root.\n *\n * Scaffolds the repo-level layer of a java + ui KOS application repository\n * (the tccc-rack-app pattern): build/ orchestration scripts, GitHub Actions\n * workflows, and kos_build_handler manifests. The ui/ interior is produced by\n * the Nx preset (create-nx-workspace) and java/ modules by the KOS Maven\n * archetypes — this generator only contributes the layer neither of them owns.\n *\n * Framework-agnostic — operates through CodegenFileSystem; the repo root is\n * deliberately NOT an Nx workspace.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { normalizeAllValues } from \"../normalize-values\";\n\nexport interface PolyglotWorkspaceOptions {\n /** Workspace/repo name (also determines the UI app name `<name>-ui`). */\n name: string;\n /**\n * The repo-root layer is IDENTICAL for every type — same scripts,\n * workflows, and manifests, all runtime-tolerant of a missing half — so a\n * repo can grow the other half later without restructuring. The type only\n * seeds the manifests: \"polyglot\"/\"ui\" (default) pre-register the UI app\n * artifact; \"java\" starts with empty artifact lists (ci:sync/java:add\n * fill them in).\n */\n type?: \"polyglot\" | \"ui\" | \"java\";\n /**\n * `default_keyset` for the kos_build_handler manifests. Org-specific;\n * changeable in .github/build-*.json afterward. Default: \"prod.kos\".\n */\n keyset?: string;\n /**\n * Node version build/nodew.sh pins and auto-provisions when the machine\n * has none. Defaults to the Node running this generator — grounded in a\n * version known to work with the scaffolded workspace.\n */\n nodeVersion?: string;\n /**\n * JDK major build/jdkw.sh pins. Default 21 (compiles the archetypes'\n * release-17 target; also what java discovery prefers).\n */\n jdkMajor?: string;\n /** Maven version build/jdkw.sh provisions when mvn is absent. */\n mavenVersion?: string;\n}\n\nexport interface PolyglotWorkspaceResult {\n /**\n * Root-relative paths the caller must mark executable (CodegenFileSystem\n * has no chmod; CI invokes these directly as ./build/<script>).\n */\n executablePaths: string[];\n}\n\nconst BUILD_SCRIPTS = [\n \"build/build-ui.sh\",\n \"build/build-java.sh\",\n \"build/build-release.sh\",\n \"build/release_version_prebuild.sh\",\n \"build/docker-build.sh\",\n];\n\nexport function generatePolyglotWorkspace(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: PolyglotWorkspaceOptions\n): PolyglotWorkspaceResult {\n const hasUi = (options.type ?? \"polyglot\") !== \"java\";\n const normalized = normalizeAllValues({ name: options.name });\n const vars = {\n ...normalized,\n hasUi,\n keyset: options.keyset || \"prod.kos\",\n appUiName: `${normalized.nameDashCase}-ui`,\n nodeVersion: options.nodeVersion || process.version.replace(/^v/, \"\"),\n jdkMajor: options.jdkMajor || \"21\",\n mavenVersion: options.mavenVersion || \"3.9.9\",\n };\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"root\"),\n \".\",\n vars\n );\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"build\"),\n \"build\",\n vars\n );\n // Template dir is named \"github\" (npm packs dot-directories unreliably);\n // emitted as .github.\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"github\"),\n \".github\",\n vars\n );\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"java\"),\n \"java\",\n vars\n );\n\n return { executablePaths: [...BUILD_SCRIPTS] };\n}\n","/**\n * Shared KOS artifact-target bundle.\n *\n * Every project that packages a KAB gets the same target family:\n * kab — kabtool build + list (dependsOn zip)\n * zip — archiver (dependsOn build, sbom [+ descriptor])\n * descriptor — descriptor.mjs (optional; apps/plugins/content/i18n)\n * version — stamps the release version into the project's `.kos.json`\n * sbom — SPDX SBOM (pruned lockfile), packaged inside the KAB\n *\n * ARTIFACT LAYOUT: the KAB and ui.zip land in `{projectRoot}/target/` — a peer\n * of the project's `src/`, the same place the Maven half of a polyglot repo\n * drops its KABs (`java/<module>/target/*.kab`). A project's artifacts sit\n * beside the sources that produced them rather than in a workspace-wide\n * `dist/archives/` tree.\n *\n * `descriptor` and `sbom` write to the project's BUILD output dir\n * (`dist/{projectRoot}`) instead, because archiver zips that directory\n * wholesale: both have to end up INSIDE ui.zip — and therefore inside the KAB\n * — rather than beside it. An SBOM that shipped next to the KAB would not\n * travel with the distribution, which is the entire reason it is generated.\n * That is also why `zip` (not `kab`) is what depends on `sbom`: by the time\n * kabtool runs, the zip it packages is already sealed.\n *\n * Paths are written as Nx `{projectRoot}` tokens so `nx move` needs no\n * rewrite. Nx does NOT interpolate arbitrary target options, so the scripts\n * that read these (kabtool.mjs, archiver.js, descriptor.mjs, splashtool.mjs)\n * and the sbom executor expand the token themselves against the project's\n * root — see `resolveTargetPath` in each script.\n *\n * The `version` target is KOS *artifact* versioning: it rewrites the\n * `version` field of the project's `.kos.json` (which kabtool/descriptor bake\n * into the KAB) and never touches `package.json`. Tag-based release pipelines\n * drive it via:\n * nx run-many --target=version --args=--ver=$KOSBUILD_VERSION\n *\n * kab and version are deliberately produced by ONE helper so no generator can\n * emit a KAB-packaging project that is not release-versionable.\n */\n\n/** Directory, under each project root, that holds the project's KAB artifacts. */\nexport const KAB_OUTPUT_DIR = \"target\";\n\n/**\n * Archive directory for every KAB-producing project — `{projectRoot}/target/`.\n *\n * Deliberately a token rather than a resolved path: a project that moves keeps\n * working without anyone rewriting its project.json. Consumers expand it with\n * `resolveKabPath` (or its per-script equivalent) before touching the disk.\n */\nexport const KAB_OUTPUT_PATH = `{projectRoot}/${KAB_OUTPUT_DIR}/`;\n\n/**\n * Expand the Nx path tokens KOS artifact targets use in their options.\n *\n * Nx interpolates `{projectRoot}`/`{workspaceRoot}` in a target's `outputs`,\n * never in arbitrary `options`, and the KAB scripts read those options straight\n * off the cached project graph — so expansion is on us. The result stays\n * workspace-root-relative (the cwd Nx runs commands from) unless the token was\n * `{workspaceRoot}`.\n */\nexport function resolveKabPath(value: string, projectRoot: string): string {\n const root = projectRoot.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n return value\n .replace(/\\{projectRoot\\}/g, root)\n .replace(/\\{workspaceRoot\\}\\/?/g, \"\");\n}\n\nexport interface KabTargetsOptions {\n /** Project name as Nx knows it (argument to kabtool/archiver/descriptor). */\n name: string;\n /**\n * Emit a `descriptor` target (and make `zip` depend on it). Its\n * descriptor.json is written into the build output dir so the zip contains\n * it. Omit for projects without a descriptor (themes).\n */\n descriptor?: boolean;\n /** Build target `zip` depends on. Default: \"build\" (plugins: \"build:production\"). */\n buildTarget?: string;\n}\n\nexport interface KabTargetDefinition {\n command?: string;\n executor?: string;\n outputs?: string[];\n cache?: boolean;\n inputs?: string[];\n options?: Record<string, unknown>;\n dependsOn?: string[];\n}\n\nexport const UPDATE_RELEASE_VERSION_SCRIPT_PATH =\n \"tools/scripts/update-release-version.mjs\";\n\nexport function buildKabTargets(\n options: KabTargetsOptions\n): Record<string, KabTargetDefinition> {\n const { name, descriptor = false, buildTarget = \"build\" } = options;\n const outputPath = KAB_OUTPUT_PATH;\n // Everything that must ride INSIDE ui.zip is written here, because archiver\n // zips the build output dir wholesale.\n const zipPayloadDir = \"dist/{projectRoot}\";\n\n const targets: Record<string, KabTargetDefinition> = {\n kab: {\n command: `node tools/scripts/kabtool.mjs build ${name} && node tools/scripts/kabtool.mjs list ${name} `,\n options: {\n outputPath,\n zipName: \"ui.zip\",\n kabName: `${name}.kab`,\n },\n dependsOn: [\"zip\"],\n },\n zip: {\n command: `node tools/scripts/archiver.js ${name}`,\n options: {\n outputPath,\n zipName: \"ui.zip\",\n },\n // `sbom` is a zip dependency, not a kab one: kabtool packages an\n // already-sealed ui.zip, so anything ordered after `zip` misses it.\n dependsOn: descriptor\n ? [buildTarget, \"descriptor\", \"sbom\"]\n : [buildTarget, \"sbom\"],\n },\n };\n\n if (descriptor) {\n targets.descriptor = {\n command: `node tools/scripts/descriptor.mjs ${name}`,\n options: {\n outputPath: zipPayloadDir,\n fileName: \"descriptor.json\",\n },\n dependsOn: [\"build\"],\n };\n }\n\n targets.version = {\n command: `node ${UPDATE_RELEASE_VERSION_SCRIPT_PATH} ${name} {args.ver}`,\n options: {},\n dependsOn: [],\n };\n\n // The SBOM ships inside the KAB so it travels with the distribution.\n targets.sbom = buildSbomTarget({ outputPath: zipPayloadDir });\n\n return targets;\n}\n\nexport interface SbomTargetOptions {\n /**\n * Directory the SBOM lands in. `dist/{projectRoot}` — the build output dir\n * archiver zips — so the SBOM ships inside the KAB.\n */\n outputPath: string;\n}\n\n/**\n * SBOM target for any artifact-producing project. Standalone so migrations\n * can retrofit it onto existing projects without rebuilding the kab bundle.\n *\n * Whatever consumes this must order it BEFORE `zip`; an SBOM written after the\n * zip is sealed never reaches the KAB.\n */\nexport function buildSbomTarget({\n outputPath,\n}: SbomTargetOptions): KabTargetDefinition {\n const dir = outputPath.replace(/\\/+$/, \"\");\n // `outputs` is one of the few places Nx expands tokens itself, so a\n // tokenized dir goes in as-is; a plain path still needs the root prefix.\n const outputDir = dir.startsWith(\"{\") ? dir : `{workspaceRoot}/${dir}`;\n return {\n executor: \"@kosdev-code/kos-nx-plugin:sbom\",\n outputs: [\n `${outputDir}/sbom.spdx.json`,\n `${outputDir}/sbom.cyclonedx.json`,\n ],\n cache: true,\n inputs: [\"production\", \"^production\", \"{workspaceRoot}/package-lock.json\"],\n options: { outputPath: dir, softFail: true },\n };\n}\n","/**\n * ci:sync — reconcile the kos_build_handler manifests of a polyglot\n * workspace with the artifacts the repo actually produces.\n *\n * MERGE-PRESERVE semantics (the design contract):\n * - Existing artifact entries whose file is still produced are kept\n * VERBATIM — ids and custom fields (layer, artifactstore, …) are the\n * user's, and manifest ids are often hand-chosen (tccc-rack-app's\n * \"tccc-rack-splash-endcap\" for the `splash` project).\n * - Newly discovered artifacts are appended with generated entries.\n * - Entries whose artifact is no longer discovered are reported as stale\n * and kept, unless prune is set.\n * - Nothing outside the artifacts arrays is ever touched, and a manifest\n * is only rewritten when its artifact set actually changed.\n * Consequence: running ci:sync on an already-correct repo is a no-op, and\n * hand-running a Maven archetype + ci:sync converges to the same manifests\n * as `kosui java:add`.\n *\n * Discovery:\n * - ui: project.json files under the KOS layout dirs (never a bare walk of\n * ui/ — listFiles has no node_modules exclusion). A `kab` target's own\n * outputPath/kabName options give the artifact path; projects with a\n * `splash` target produce layer KABs; ui/external/*.kab files are\n * prebuilt artifacts.\n * - java: modules listed in the java/pom.xml aggregator whose pom uses the\n * kos-kab-maven-plugin (same java/pom.xml contract as build-java.sh).\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { KAB_OUTPUT_DIR, resolveKabPath } from \"./kab-targets\";\n\nexport interface DiscoveredArtifact {\n id: string;\n filename: string;\n layer?: number;\n}\n\nexport interface CiSyncOptions {\n /** Remove stale entries instead of keeping and reporting them. */\n prune?: boolean;\n}\n\nexport interface CiSyncManifestResult {\n added: string[];\n stale: string[];\n pruned: string[];\n}\n\nexport interface CiSyncResult {\n manifests: Record<string, CiSyncManifestResult>;\n discovered: { ui: DiscoveredArtifact[]; java: DiscoveredArtifact[] };\n}\n\nconst UI_PROJECT_DIRS = [\n \"apps\",\n \"libs\",\n \"plugins\",\n \"splash\",\n \"themes\",\n \"content\",\n \"translations\",\n];\n\nfunction joinArtifactPath(outputPath: string, fileName: string): string {\n return `${outputPath.replace(/\\/+$/, \"\")}/${fileName}`;\n}\n\nexport function discoverUiArtifacts(\n codegenFs: CodegenFileSystem\n): DiscoveredArtifact[] {\n const artifacts: DiscoveredArtifact[] = [];\n\n for (const dir of UI_PROJECT_DIRS) {\n for (const file of codegenFs.listFiles(`ui/${dir}`)) {\n if (!file.endsWith(\"project.json\")) continue;\n const raw = codegenFs.read(file);\n if (raw === null) continue;\n let project: any;\n try {\n project = JSON.parse(raw);\n } catch {\n continue;\n }\n const name = project.name;\n if (!name) continue;\n\n // Artifact paths are {projectRoot}-tokenized so projects can move; the\n // build handler needs a literal path, and the project.json's own\n // location is the project root (Nx allows no other).\n const projectRoot = file.slice(\"ui/\".length, file.lastIndexOf(\"/\"));\n const resolve = (value: string) => resolveKabPath(value, projectRoot);\n\n const kabOptions = project.targets?.kab?.options;\n if (kabOptions?.outputPath && kabOptions?.kabName) {\n artifacts.push({\n id: name,\n filename: `ui/${joinArtifactPath(\n resolve(kabOptions.outputPath),\n kabOptions.kabName\n )}`,\n });\n } else if (project.targets?.splash) {\n // splashtool writes the layer KAB into its target's outputPath; fall\n // back to the standard <projectRoot>/target/ when it is unset.\n const splashOutput = project.targets.splash.options?.outputPath as\n | string\n | undefined;\n artifacts.push({\n id: name,\n filename: `ui/${joinArtifactPath(\n resolve(splashOutput ?? `{projectRoot}/${KAB_OUTPUT_DIR}`),\n `${name}.kab`\n )}`,\n layer: 1,\n });\n }\n }\n }\n\n for (const file of codegenFs.listFiles(\"ui/external\")) {\n if (!file.endsWith(\".kab\")) continue;\n const base = file.slice(file.lastIndexOf(\"/\") + 1, -\".kab\".length);\n artifacts.push({ id: base, filename: file });\n }\n\n return artifacts;\n}\n\nexport function discoverJavaArtifacts(\n codegenFs: CodegenFileSystem\n): DiscoveredArtifact[] {\n const aggregator = codegenFs.read(\"java/pom.xml\");\n if (aggregator === null) return [];\n\n const artifacts: DiscoveredArtifact[] = [];\n for (const match of aggregator.matchAll(/<module>([^<]+)<\\/module>/g)) {\n const moduleDir = match[1];\n const pom = codegenFs.read(`java/${moduleDir}/pom.xml`);\n if (pom === null || !pom.includes(\"kos-kab-maven-plugin\")) continue;\n // The project's own artifactId is the first one outside any <parent>.\n const withoutParent = pom.replace(/<parent>[\\s\\S]*?<\\/parent>/, \"\");\n const artifactId = withoutParent.match(\n /<artifactId>([^<]+)<\\/artifactId>/\n )?.[1];\n if (!artifactId) continue;\n artifacts.push({\n id: moduleDir,\n // eslint-disable-next-line no-template-curly-in-string\n filename: `java/${moduleDir}/target/${artifactId}-\\${KOS_STD_VERSION_REGEX}.kab`,\n });\n }\n return artifacts;\n}\n\nfunction syncManifest(\n codegenFs: CodegenFileSystem,\n manifestPath: string,\n discovered: DiscoveredArtifact[],\n prune: boolean\n): CiSyncManifestResult | null {\n const raw = codegenFs.read(manifestPath);\n if (raw === null) return null;\n const manifest = JSON.parse(raw);\n const existing: any[] = manifest.artifacts ?? [];\n\n const byFilename = new Map(discovered.map((d) => [d.filename, d]));\n const kept: any[] = [];\n const stale: string[] = [];\n const pruned: string[] = [];\n\n for (const entry of existing) {\n if (byFilename.has(entry.filename)) {\n kept.push(entry);\n byFilename.delete(entry.filename);\n } else if (prune) {\n pruned.push(entry.id ?? entry.filename);\n } else {\n kept.push(entry);\n stale.push(entry.id ?? entry.filename);\n }\n }\n\n const added: string[] = [];\n for (const artifact of byFilename.values()) {\n kept.push({\n id: artifact.id,\n filename: artifact.filename,\n artifactstore: \"kos-cdn\",\n marketplace: 1,\n ...(artifact.layer !== undefined ? { layer: artifact.layer } : {}),\n });\n added.push(artifact.id);\n }\n\n if (added.length > 0 || pruned.length > 0) {\n manifest.artifacts = kept;\n codegenFs.write(manifestPath, JSON.stringify(manifest, null, 2) + \"\\n\");\n }\n\n return { added, stale, pruned };\n}\n\nexport function syncCiManifests(\n codegenFs: CodegenFileSystem,\n options: CiSyncOptions = {}\n): CiSyncResult {\n const prune = options.prune ?? false;\n const ui = discoverUiArtifacts(codegenFs);\n const java = discoverJavaArtifacts(codegenFs);\n\n const manifests: Record<string, CiSyncManifestResult> = {};\n const plan: Array<[string, DiscoveredArtifact[]]> = [\n [\".github/build-ui.json\", ui],\n [\".github/build-java.json\", java],\n [\".github/build-release.json\", [...ui, ...java]],\n ];\n for (const [manifestPath, discovered] of plan) {\n const result = syncManifest(codegenFs, manifestPath, discovered, prune);\n if (result) {\n manifests[manifestPath] = result;\n }\n }\n\n return { manifests, discovered: { ui, java } };\n}\n","/**\n * Helpers for the java/ half of a polyglot workspace (see\n * generate-polyglot-workspace.ts).\n *\n * The Java modules themselves come from the KOS Maven archetypes\n * (com.kos.archetypes — local-install via github.com/kosdev-code/\n * kos-maven-archetypes); these helpers contribute only the glue the\n * archetypes don't own:\n * - the java/pom.xml aggregator (archetype modules are standalone — no\n * parent link — so an aggregator is needed for `mvn` at java/ and for\n * build-java.sh's java/pom.xml check)\n * - repairs to the generated pom (the archetype references\n * ${kos-kab-maven-plugin.version} without defining it, and depends on\n * api-info which the kos-bom does not manage)\n * - registration of the module's KAB in the kos_build_handler manifests\n *\n * Version numbers are always passed in by the caller (derived from the KOS\n * Maven repo's maven-metadata.xml at run time) — nothing hardcoded here.\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\n\nexport interface EnsureJavaAggregatorOptions {\n groupId: string;\n /** Aggregator artifactId (typically the workspace name). */\n artifactId: string;\n moduleName: string;\n}\n\nexport function ensureJavaAggregatorPom(\n codegenFs: CodegenFileSystem,\n options: EnsureJavaAggregatorOptions\n): void {\n const pomPath = \"java/pom.xml\";\n const existing = codegenFs.read(pomPath);\n if (existing === null) {\n codegenFs.write(\n pomPath,\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\">\n <modelVersion>4.0.0</modelVersion>\n <groupId>${options.groupId}</groupId>\n <artifactId>${options.artifactId}</artifactId>\n <version>0.0.0-SNAPSHOT</version>\n <packaging>pom</packaging>\n <modules>\n <module>${options.moduleName}</module>\n </modules>\n</project>\n`\n );\n return;\n }\n if (existing.includes(`<module>${options.moduleName}</module>`)) {\n return;\n }\n codegenFs.write(\n pomPath,\n existing.replace(\n \"</modules>\",\n ` <module>${options.moduleName}</module>\\n </modules>`\n )\n );\n}\n\nexport interface FinalizeArchetypeModuleOptions {\n moduleName: string;\n /** kos-bom version to pin (replaces the template's 0.0.0-SNAPSHOT). */\n kosVersion?: string;\n /** Fills the template's undefined ${kos-kab-maven-plugin.version}. */\n kabPluginVersion?: string;\n /** Explicit version for the api-info dep the kos-bom doesn't manage. */\n apiInfoVersion?: string;\n}\n\n/**\n * Repair a freshly archetype-generated module for use inside a polyglot\n * workspace. Returns human-readable notes about anything it could NOT fix\n * (missing versions the caller failed to derive) so the CLI can warn.\n */\nexport function finalizeArchetypeModule(\n codegenFs: CodegenFileSystem,\n options: FinalizeArchetypeModuleOptions\n): string[] {\n const { moduleName, kosVersion, kabPluginVersion, apiInfoVersion } = options;\n const notes: string[] = [];\n const pomPath = `java/${moduleName}/pom.xml`;\n let pom = codegenFs.read(pomPath);\n if (pom === null) {\n throw new Error(`Generated module pom not found: ${pomPath}`);\n }\n\n if (pom.includes(\"<kos.version>0.0.0-SNAPSHOT</kos.version>\")) {\n if (kosVersion) {\n pom = pom.replace(\n \"<kos.version>0.0.0-SNAPSHOT</kos.version>\",\n `<kos.version>${kosVersion}</kos.version>`\n );\n } else {\n notes.push(\n \"kos.version is 0.0.0-SNAPSHOT — set it to a released kos-bom version before building\"\n );\n }\n }\n\n if (\n pom.includes(\"${kos-kab-maven-plugin.version}\") &&\n !pom.includes(\"<kos-kab-maven-plugin.version>\")\n ) {\n if (kabPluginVersion) {\n pom = pom.replace(\n /(<kos\\.version>[^<]*<\\/kos\\.version>)/,\n `$1\\n <kos-kab-maven-plugin.version>${kabPluginVersion}</kos-kab-maven-plugin.version>`\n );\n } else {\n notes.push(\n \"the ${kos-kab-maven-plugin.version} property is referenced but undefined — add it before building\"\n );\n }\n }\n\n const unversionedApiInfo = /<artifactId>api-info<\\/artifactId>(\\s*)<\\/dependency>/;\n if (unversionedApiInfo.test(pom)) {\n if (apiInfoVersion) {\n pom = pom.replace(\n unversionedApiInfo,\n `<artifactId>api-info</artifactId>$1 <version>${apiInfoVersion}</version>$1</dependency>`\n );\n } else {\n notes.push(\n \"api-info has no version and is not managed by the kos-bom — add one before building\"\n );\n }\n }\n\n codegenFs.write(pomPath, pom);\n\n // Standalone-repo extras the archetype ships that are redundant inside a\n // polyglot workspace (the repo root owns CI):\n const githubDir = `java/${moduleName}/github`;\n if (codegenFs.exists(githubDir)) {\n for (const file of codegenFs.listFiles(githubDir)) {\n codegenFs.delete(file);\n }\n }\n const gitignore = codegenFs.read(`java/${moduleName}/gitignore`);\n if (gitignore !== null) {\n codegenFs.write(`java/${moduleName}/.gitignore`, gitignore);\n codegenFs.delete(`java/${moduleName}/gitignore`);\n }\n\n return notes;\n}\n\nexport interface AddJavaArtifactOptions {\n moduleName: string;\n}\n\n/**\n * Register the module's KAB in build-java.json and build-release.json.\n * Only the artifacts arrays are touched — keyset/build_cmd/etc. are the\n * user's (same contract as ci:sync).\n */\nexport function addJavaArtifactToManifests(\n codegenFs: CodegenFileSystem,\n options: AddJavaArtifactOptions\n): void {\n const { moduleName } = options;\n for (const manifestPath of [\n \".github/build-java.json\",\n \".github/build-release.json\",\n ]) {\n const raw = codegenFs.read(manifestPath);\n if (raw === null) {\n continue;\n }\n const manifest = JSON.parse(raw);\n manifest.artifacts = manifest.artifacts ?? [];\n if (\n manifest.artifacts.some(\n (artifact: { id?: string }) => artifact.id === moduleName\n )\n ) {\n continue;\n }\n manifest.artifacts.push({\n id: moduleName,\n // eslint-disable-next-line no-template-curly-in-string\n filename: `java/${moduleName}/target/${moduleName}-\\${KOS_STD_VERSION_REGEX}.kab`,\n artifactstore: \"kos-cdn\",\n marketplace: 1,\n });\n codegenFs.write(manifestPath, JSON.stringify(manifest, null, 2) + \"\\n\");\n }\n}\n","/**\n * Normalize generator options — resolves project references and generates\n * all case variants for template substitution.\n *\n * Ported from kos-nx-plugin/src/generators/kos-model/lib/normalize-options.ts.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { readJson } from \"../json-utils\";\nimport { normalizeAllValues } from \"../normalize-values\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../project-discovery\";\n\nexport interface KosBaseGeneratorOptions {\n name: string;\n modelProject: string;\n registrationProject?: string;\n skipRegistration?: boolean;\n modelDirectory: string;\n companion?: boolean;\n companionModel?: string;\n companionModelProject?: string;\n companionPattern?: \"composition\" | \"decorator\";\n futureAware?: \"none\" | \"minimal\" | \"complete\";\n}\n\nexport type NormalizedOptions<T extends KosBaseGeneratorOptions> = T & {\n nameDashCase: string;\n nameProperCase: string;\n nameCamelCase: string;\n namePascalCase: string;\n nameConstantCase: string;\n nameLowerCase: string;\n companionModelDashCase: string;\n companionModelProperCase: string;\n companionModelCamelCase: string;\n companionModelPascalCase: string;\n companionModelConstantCase: string;\n companionModelLowerCase: string;\n registrationProject: string;\n importPath: string;\n template: string;\n [key: string]: any;\n};\n\n/**\n * Normalize generator options by resolving the model project and generating\n * all name variants for template substitution.\n *\n * @param codegenFs - Filesystem abstraction\n * @param options - Raw generator options\n * @param projects - Optional pre-computed project map\n */\nexport function normalizeOptions<T extends KosBaseGeneratorOptions>(\n codegenFs: CodegenFileSystem,\n options: T,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedOptions<T> {\n const toNormalize: Record<string, string> = {\n name: options.name,\n };\n\n if ((options as any).modelName) {\n toNormalize.modelName = (options as any).modelName;\n }\n\n if (options.companionModel) {\n toNormalize.companionModel = options.companionModel;\n }\n\n const normalizedValues = normalizeAllValues(toNormalize);\n const modelProject = options.modelProject;\n const registrationProject = options.registrationProject || \"\";\n const useModelProject = modelProject !== \"__NONE__\";\n\n let importPath = \"\";\n if (useModelProject) {\n const modelProjectConfig = findProjectByName(\n codegenFs.root,\n modelProject,\n projects\n );\n if (modelProjectConfig) {\n const pkgJsonPath = path.join(modelProjectConfig.root, \"package.json\");\n try {\n const pkgJson = readJson<{ name: string }>(codegenFs, pkgJsonPath);\n importPath = pkgJson.name || \"\";\n } catch {\n importPath = \"\";\n }\n }\n }\n\n // Provide safe defaults for optional boolean fields that templates reference\n // directly. Without explicit values, EJS throws ReferenceError for variables\n // that are simply absent from the options object (undefined keys are omitted\n // by the spread, which is different from being present-but-false).\n const booleanDefaults: Partial<KosBaseGeneratorOptions> = {\n companion: false,\n skipRegistration: false,\n futureAware: \"none\",\n };\n\n return {\n ...booleanDefaults,\n ...options,\n ...normalizedValues,\n modelProject,\n importPath,\n registrationProject,\n template: \"\",\n } as NormalizedOptions<T>;\n}\n","/**\n * Shared model-augmentation toolkit (ts-morph / AST based).\n *\n * Primitives for the capability mutators (add-container-support, add-future, …)\n * that augment an EXISTING model with coordinated, multi-site edits — decorators,\n * declaration-merging interfaces, imports, methods — without the fragility of\n * regex string replacement.\n *\n * Bridged through CodegenFileSystem so the same dry-run overlay + formatFiles\n * pipeline used by the scaffolders applies unchanged: read content → in-memory\n * ts-morph SourceFile → mutate → getFullText() → write.\n *\n * ts-morph is confined to kos-codegen-core (build-time tooling) and must not leak\n * into any runtime SDK package.\n */\nimport {\n Node,\n Project,\n IndentationText,\n QuoteKind,\n Scope,\n VariableDeclarationKind,\n type ObjectLiteralExpression,\n type SourceFile,\n type ClassDeclaration,\n} from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\n\n/**\n * Read a file via the filesystem abstraction, apply an AST mutation, write it back.\n * The mutation operates on an in-memory ts-morph SourceFile — no disk access here,\n * so the caller's CodegenFileSystem (real or dry-run overlay) owns all I/O.\n */\nexport function transformSourceFile(\n codegenFs: CodegenFileSystem,\n filePath: string,\n mutate: (sf: SourceFile) => void\n): void {\n const content = codegenFs.read(filePath);\n if (content === null) {\n throw new Error(`File not found: ${filePath}`);\n }\n const project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: {\n indentationText: IndentationText.TwoSpaces,\n quoteKind: QuoteKind.Double,\n },\n });\n const sourceFile = project.createSourceFile(filePath, content, {\n overwrite: true,\n });\n mutate(sourceFile);\n codegenFs.write(filePath, sourceFile.getFullText());\n}\n\n/**\n * Read a file via the filesystem abstraction and inspect it as a ts-morph\n * SourceFile, writing nothing back. The read-only counterpart of\n * `transformSourceFile`, for discovery over generated declarations.\n */\nexport function readSourceFile<T>(\n codegenFs: CodegenFileSystem,\n filePath: string,\n inspect: (sf: SourceFile) => T\n): T {\n const content = codegenFs.read(filePath);\n if (content === null) {\n throw new Error(`File not found: ${filePath}`);\n }\n const project = new Project({ useInMemoryFileSystem: true });\n return inspect(\n project.createSourceFile(filePath, content, { overwrite: true })\n );\n}\n\n/** A named import to ensure on a module: the symbol and whether it is type-only. */\nexport interface NamedImportSpec {\n name: string;\n isTypeOnly?: boolean;\n}\n\n/**\n * Ensure the given named imports exist on an import from `moduleSpecifier`.\n * Idempotent: existing names are left untouched; the import declaration is created\n * if absent. Resolves to the same module the model already imports `kosModel` from\n * when `moduleSpecifier` matches, so internal vs. published paths are respected.\n */\nexport function ensureNamedImport(\n sourceFile: SourceFile,\n moduleSpecifier: string,\n names: NamedImportSpec[]\n): void {\n const decls = sourceFile\n .getImportDeclarations()\n .filter((d) => d.getModuleSpecifierValue() === moduleSpecifier);\n\n // Dedup across ALL imports from this module (a file may have both a value\n // import and a separate `import type { … }` from the same specifier).\n const existing = new Set<string>();\n for (const d of decls) {\n for (const n of d.getNamedImports()) existing.add(n.getName());\n }\n\n // Always target a VALUE import declaration — adding a runtime symbol to an\n // `import type { … }` block would strip it at compile time. Type-only names go\n // in with an inline `type` modifier (the `import { kosX, type KosX }` idiom).\n let target = decls.find((d) => !d.isTypeOnly());\n if (!target) {\n target = sourceFile.addImportDeclaration({ moduleSpecifier });\n }\n\n for (const { name, isTypeOnly } of names) {\n if (existing.has(name)) continue;\n target.addNamedImport({ name, isTypeOnly: !!isTypeOnly });\n existing.add(name);\n }\n}\n\n/**\n * Resolve the module specifier the model imports `kosModel` from, so augmentation\n * imports land on the same line/source (internal `../../../core/core/decorators`\n * vs. published `@kosdev-code/kos-ui-sdk`). Falls back to the published package.\n */\nexport function resolveSdkModuleSpecifier(sourceFile: SourceFile): string {\n const decl = sourceFile\n .getImportDeclarations()\n .find((d) => d.getNamedImports().some((n) => n.getName() === \"kosModel\"));\n return decl?.getModuleSpecifierValue() ?? \"@kosdev-code/kos-ui-sdk\";\n}\n\n/**\n * Find the primary model class. Prefers `preferName`, then a class whose name ends\n * in `ModelImpl`, then the first exported class, then the first class.\n */\nexport function getModelClass(\n sourceFile: SourceFile,\n preferName?: string\n): ClassDeclaration {\n const classes = sourceFile.getClasses();\n const byName = preferName\n ? classes.find((c) => c.getName() === preferName)\n : undefined;\n if (byName) return byName;\n const impl = classes.find((c) => /ModelImpl$/.test(c.getName() ?? \"\"));\n if (impl) return impl;\n const exported = classes.find((c) => c.isExported());\n if (exported) return exported;\n if (classes.length > 0) return classes[0];\n throw new Error(\"No class declaration found in model file.\");\n}\n\n/**\n * Add a class decorator idempotently (matched by decorator name). Supports type\n * arguments (`@name<T>(args)`) which ts-morph's structured API can't express, by\n * writing the call expression as decorator text. Inserts directly after `@kosModel`\n * when present (matching KOS convention), otherwise nearest the class.\n */\nexport function addClassDecorator(\n cls: ClassDeclaration,\n name: string,\n opts?: { typeArgs?: string[]; argsText?: string }\n): void {\n if (cls.getDecorator(name)) return;\n const typeArgs = opts?.typeArgs?.length\n ? `<${opts.typeArgs.join(\", \")}>`\n : \"\";\n const args = opts?.argsText ?? \"\";\n\n const decorators = cls.getDecorators();\n const kosModelIdx = decorators.findIndex((d) => d.getName() === \"kosModel\");\n const insertIdx = kosModelIdx >= 0 ? kosModelIdx + 1 : decorators.length;\n cls.insertDecorator(insertIdx, {\n name: `${name}${typeArgs}`,\n arguments: args ? [args] : [],\n });\n}\n\n/**\n * Ensure a declaration-merging interface `export interface <name> extends <expr>`.\n * If the interface already exists (e.g. merged for another capability), adds the\n * extends expression to it; otherwise creates an empty exported interface with the\n * `no-empty-interface` lint suppression. Idempotent by base type name.\n */\nexport function ensureDeclarationMerge(\n sourceFile: SourceFile,\n interfaceName: string,\n extendsExpr: string,\n typeParameters: string[] = []\n): void {\n const baseType = extendsExpr.split(\"<\")[0].trim();\n let iface = sourceFile.getInterface(interfaceName);\n if (iface) {\n const already = iface\n .getExtends()\n .some((e) => e.getText().split(\"<\")[0].trim() === baseType);\n if (!already) iface.addExtends(extendsExpr);\n return;\n }\n // A merged interface must carry the SAME type parameters as the class it merges\n // with, or TS errors (\"all declarations must have identical type parameters\").\n iface = sourceFile.addInterface({\n name: interfaceName,\n isExported: true,\n typeParameters,\n extends: [extendsExpr],\n });\n // Prepend the empty-interface lint suppression line.\n sourceFile.insertText(\n iface.getStart(),\n \"// eslint-disable-next-line @typescript-eslint/no-empty-interface\\n\"\n );\n}\n\n/**\n * Ensure a file-level eslint-disable block comment for `rule` at the top of file.\n * Call LAST in a mutation — it uses raw text insertion and invalidates node refs.\n */\nexport function ensureFileEslintDisable(\n sourceFile: SourceFile,\n rule: string\n): void {\n if (sourceFile.getFullText().includes(rule)) return;\n sourceFile.insertText(0, `/* eslint-disable ${rule} */\\n`);\n}\n\n/**\n * Add a module-level `const` after the import block, idempotently. Returns true\n * if added. Used for endpoint descriptors, which must sit outside the class so\n * `typeof NAME` can be referenced from a parameter type.\n */\nexport function ensureModuleConst(\n sourceFile: SourceFile,\n spec: { name: string; initializer: string }\n): boolean {\n if (sourceFile.getVariableDeclaration(spec.name)) return false;\n const imports = sourceFile.getImportDeclarations();\n const index =\n imports.length > 0 ? imports[imports.length - 1].getChildIndex() + 1 : 0;\n sourceFile.insertVariableStatement(index, {\n declarationKind: VariableDeclarationKind.Const,\n declarations: [{ name: spec.name, initializer: spec.initializer }],\n });\n return true;\n}\n\n/** Index just past the last import, where module-level declarations belong. */\nfunction afterImports(sourceFile: SourceFile): number {\n const imports = sourceFile.getImportDeclarations();\n return imports.length > 0\n ? imports[imports.length - 1].getChildIndex() + 1\n : 0;\n}\n\n/** Strip the quotes ts-morph keeps on a quoted property name. */\nfunction unquote(name: string): string {\n return name.replace(/^[\"']|[\"']$/g, \"\");\n}\n\n/** The object literal an `export const X = { … } as const` declares, or null. */\nfunction getConstCatalogLiteral(\n sourceFile: SourceFile,\n name: string\n): ObjectLiteralExpression | null {\n const declaration = sourceFile.getVariableDeclaration(name);\n if (!declaration) return null;\n let initializer = declaration.getInitializer();\n if (Node.isAsExpression(initializer)) {\n initializer = initializer.getExpression();\n }\n if (!initializer || !Node.isObjectLiteralExpression(initializer)) {\n throw new Error(\n `\"${name}\" exists in ${sourceFile.getBaseName()} but is not an object literal.`\n );\n }\n return initializer;\n}\n\n/**\n * Ensure an exported `as const` catalog holds an entry with this initializer,\n * and report the key that holds it.\n *\n * An entry whose initializer already matches is REUSED rather than duplicated,\n * so one descriptor is declared once however many members reference it.\n * Equivalence is delegated to `equals` because equivalent initializers are not\n * always identical text — quote style and spacing vary by who wrote the file.\n */\nexport function ensureConstCatalogEntry(\n sourceFile: SourceFile,\n spec: {\n catalogName: string;\n key: string;\n initializer: string;\n equals?: (existing: string, candidate: string) => boolean;\n }\n): { key: string; created: boolean } {\n const matches =\n spec.equals ??\n ((existing: string, candidate: string) => existing === candidate);\n\n let literal = getConstCatalogLiteral(sourceFile, spec.catalogName);\n if (!literal) {\n // Created empty and filled through the structured API, so the first entry\n // is indented by ts-morph exactly like every later one.\n sourceFile.insertVariableStatement(afterImports(sourceFile), {\n isExported: true,\n declarationKind: VariableDeclarationKind.Const,\n declarations: [{ name: spec.catalogName, initializer: \"{} as const\" }],\n });\n literal = getConstCatalogLiteral(sourceFile, spec.catalogName);\n if (!literal) {\n throw new Error(`Failed to create catalog \"${spec.catalogName}\".`);\n }\n literal.addPropertyAssignment({\n name: spec.key,\n initializer: spec.initializer,\n });\n return { key: spec.key, created: true };\n }\n\n for (const property of literal\n .getProperties()\n .filter(Node.isPropertyAssignment)) {\n const existingKey = unquote(property.getName());\n const existingInitializer = property.getInitializerOrThrow().getText();\n if (matches(existingInitializer, spec.initializer)) {\n return { key: existingKey, created: false };\n }\n if (existingKey === spec.key) {\n throw new Error(\n `\"${spec.catalogName}.${spec.key}\" already exists with a different value ` +\n `(${existingInitializer}). Use a different methodName, or reconcile the catalog by hand.`\n );\n }\n }\n\n literal.addPropertyAssignment({\n name: spec.key,\n initializer: spec.initializer,\n });\n return { key: spec.key, created: true };\n}\n\n/** Add an exported type alias unless one of that name already exists. */\nexport function ensureExportedTypeAlias(\n sourceFile: SourceFile,\n spec: { name: string; type: string }\n): boolean {\n if (sourceFile.getTypeAlias(spec.name)) return false;\n sourceFile.addTypeAlias({\n name: spec.name,\n type: spec.type,\n isExported: true,\n });\n return true;\n}\n\n/**\n * Add an exported identity mapper `raw -> data` unless one of that name exists.\n * Emitted as an identity so it compiles untouched; narrowing the data type is\n * what makes it a real boundary.\n */\nexport function ensureExportedMapper(\n sourceFile: SourceFile,\n spec: { name: string; rawType: string; dataType: string }\n): boolean {\n if (sourceFile.getVariableDeclaration(spec.name)) return false;\n sourceFile.addVariableStatement({\n isExported: true,\n declarationKind: VariableDeclarationKind.Const,\n declarations: [\n {\n name: spec.name,\n initializer: `(raw: ${spec.rawType}): ${spec.dataType} => raw`,\n },\n ],\n });\n return true;\n}\n\n/** Add `export * from \"<moduleSpecifier>\"` unless the barrel already has it. */\nexport function ensureBarrelExport(\n sourceFile: SourceFile,\n moduleSpecifier: string\n): boolean {\n const present = sourceFile\n .getExportDeclarations()\n .some((d) => d.getModuleSpecifierValue() === moduleSpecifier);\n if (present) return false;\n sourceFile.addExportDeclaration({ moduleSpecifier });\n return true;\n}\n\n/** A decorated method to add to a model class. */\nexport interface DecoratedMethodSpec {\n name: string;\n decoratorName: string;\n decoratorArgsText?: string;\n parameters?: { name: string; type?: string; optional?: boolean }[];\n returnType?: string;\n isAsync?: boolean;\n statements?: string;\n}\n\n/**\n * Add a decorated method to a class idempotently (skips if a method of that name\n * already exists). Returns true if added.\n */\nexport function addDecoratedMethod(\n cls: ClassDeclaration,\n spec: DecoratedMethodSpec\n): boolean {\n if (cls.getMethod(spec.name)) return false;\n cls.addMethod({\n name: spec.name,\n isAsync: spec.isAsync,\n returnType: spec.returnType,\n parameters: spec.parameters?.map((p) => {\n return { name: p.name, type: p.type, hasQuestionToken: p.optional };\n }),\n statements: spec.statements,\n decorators: [\n {\n name: spec.decoratorName,\n arguments: spec.decoratorArgsText ? [spec.decoratorArgsText] : [],\n },\n ],\n });\n return true;\n}\n\n/** A plain (undecorated) property to add to a model class. */\nexport interface PlainPropertySpec {\n name: string;\n type?: string;\n /** Initializer expression text, e.g. `\"\"`, `0`, `false`. */\n initializer?: string;\n scope?: \"private\" | \"protected\" | \"public\";\n readonly?: boolean;\n /** Definite-assignment `!` (compiles under strictPropertyInitialization). */\n hasExclamation?: boolean;\n}\n\n/**\n * Member index for a new property: right after the last existing property, so\n * properties (basic fields, dependencies, config properties) stay grouped at the\n * TOP of the class — before the constructor and methods. Index 0 if none yet.\n */\nfunction propertyInsertIndex(cls: ClassDeclaration): number {\n const props = cls.getProperties();\n if (props.length === 0) return 0;\n return props[props.length - 1].getChildIndex() + 1;\n}\n\n/**\n * Add a plain class property (no decorator) idempotently. Returns true if added.\n * Used for basic model state fields (`prop1: string`) — distinct from the\n * decorator-backed config/dependency/etc. properties. Inserted at the top.\n */\nexport function addPlainProperty(\n cls: ClassDeclaration,\n spec: PlainPropertySpec\n): boolean {\n if (cls.getProperty(spec.name)) return false;\n cls.insertProperty(propertyInsertIndex(cls), {\n name: spec.name,\n type: spec.type,\n initializer: spec.initializer,\n isReadonly: !!spec.readonly,\n scope: spec.scope ? SCOPE_MAP[spec.scope] : undefined,\n hasExclamationToken: spec.initializer ? false : !!spec.hasExclamation,\n });\n return true;\n}\n\n/** A decorated property to add to a model class. */\nexport interface DecoratedPropertySpec {\n name: string;\n decoratorName: string;\n decoratorArgsText?: string;\n type?: string;\n scope?: \"private\" | \"protected\" | \"public\";\n hasExclamation?: boolean;\n /** Initializer expression text, e.g. `new KosModelContainer<X>()` or `[]`. */\n initializer?: string;\n /**\n * Emit the decorator WITHOUT call parens — a DIRECT (non-factory) decorator like\n * `@kosChild`. Default false (factory form `@name()` / `@name(args)`).\n */\n bare?: boolean;\n}\n\nconst SCOPE_MAP = {\n private: Scope.Private,\n protected: Scope.Protected,\n public: Scope.Public,\n} as const;\n\n/**\n * Add a decorated property to a class idempotently (skips if a property of that\n * name already exists). Returns true if added.\n */\nexport function addDecoratedProperty(\n cls: ClassDeclaration,\n spec: DecoratedPropertySpec\n): boolean {\n if (cls.getProperty(spec.name)) return false;\n cls.insertProperty(propertyInsertIndex(cls), {\n name: spec.name,\n type: spec.type,\n initializer: spec.initializer,\n scope: spec.scope ? SCOPE_MAP[spec.scope] : undefined,\n hasExclamationToken: spec.initializer ? false : !!spec.hasExclamation,\n decorators: [\n spec.bare && !spec.decoratorArgsText\n ? { name: spec.decoratorName } // no `arguments` key → bare `@name`, no parens\n : {\n name: spec.decoratorName,\n arguments: spec.decoratorArgsText ? [spec.decoratorArgsText] : [],\n },\n ],\n });\n return true;\n}\n\n/** A computed getter to add to a model class. */\nexport interface GetterSpec {\n name: string;\n returnType?: string;\n /** Body statements; default a TODO stub returning undefined. */\n statements?: string;\n}\n\n/**\n * Add a computed getter (`get name(): T { ... }`) idempotently — a derived,\n * read-only member. Returns true if added. Placed after the constructor (or after\n * the properties if there is none), ahead of regular methods.\n */\nexport function addGetter(cls: ClassDeclaration, spec: GetterSpec): boolean {\n if (cls.getGetAccessor(spec.name)) return false;\n const ctor = cls.getConstructors()[0];\n const index = ctor ? ctor.getChildIndex() + 1 : propertyInsertIndex(cls);\n cls.insertGetAccessor(index, {\n name: spec.name,\n returnType: spec.returnType,\n statements:\n spec.statements ?? \"// TODO: derive and return the computed value\",\n });\n return true;\n}\n","/**\n * Enumerate the service operations a project already has types for.\n *\n * NOT a substitute for the device. A connected device's live OpenAPI is the\n * source of truth about what endpoints exist, what they mean, and whether one\n * is debug-only — discover there first (kos-device: `search_services` →\n * `describe_endpoint` → `resolve_service_request`). This reads the types\n * `api:generate` already wrote into the project, which is a SNAPSHOT of that\n * truth: correct for the app/version it was generated from, silent about\n * anything added since, and empty until api:generate has run.\n *\n * It exists for the offline case — no device reachable, or a human picking from\n * a list rather than typing a path from memory.\n *\n * Everything here comes out of `openapi.d.ts`, which openapi-typescript emits in\n * a shape precise enough to read structurally: a method that exists is\n * `post: { … }` while an absent one is `post?: never`, the OpenAPI `summary`\n * survives as the method's JSDoc, and path parameters keep their names.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { readSourceFile } from \"./augment/ts-toolkit\";\n\n/** HTTP methods a response type can be derived for (lowercase, as spec'd). */\nconst CATALOG_METHODS = [\"get\", \"put\", \"post\", \"delete\", \"patch\"] as const;\nexport type CatalogMethod = (typeof CATALOG_METHODS)[number];\n\nexport interface ServiceOperation {\n /** OpenAPI path, e.g. `/api/board/{id}`. */\n path: string;\n method: CatalogMethod;\n /** The spec's `summary`, when it had one. */\n summary?: string;\n /** Names of the `{…}` placeholders the path declares, in order. */\n pathParams: string[];\n}\n\nexport interface ServiceCatalogEntry {\n /** App segment of the services dir, e.g. `dispense`. */\n app: string;\n /** Version segment, e.g. `daily` or `1.9.x`. */\n version: string;\n /** Root-relative path of the generated service module (with extension). */\n serviceModulePath: string;\n operations: ServiceOperation[];\n}\n\nconst SERVICE_MODULE_RE = /\\/utils\\/services\\/([^/]+)\\/([^/]+)\\/service\\.ts$/;\n\nexport interface ServiceCatalogQuery {\n /** Project whose generated types to read. */\n modelProject: string;\n /** Limit to one app segment (e.g. `dispense`). */\n app?: string;\n /** Limit to one version segment (e.g. `daily`). */\n version?: string;\n}\n\n/**\n * List every generated service module in a project and the operations it types.\n * Returns an empty array when the project has no generated types — the caller\n * should tell the user to run `api:generate`, not treat it as \"no endpoints\".\n */\nexport function listServiceCatalog(\n codegenFs: CodegenFileSystem,\n query: ServiceCatalogQuery,\n projects?: Map<string, ProjectConfiguration>\n): ServiceCatalogEntry[] {\n const project = findProjectByName(\n codegenFs.root,\n query.modelProject,\n projects\n );\n if (!project) {\n throw new Error(`Project not found: ${query.modelProject}`);\n }\n const sourceRoot = project.sourceRoot || path.join(project.root, \"src\");\n\n const entries: ServiceCatalogEntry[] = [];\n for (const file of codegenFs.listFiles(sourceRoot)) {\n const posix = file.split(path.sep).join(\"/\");\n const match = SERVICE_MODULE_RE.exec(posix);\n if (!match) continue;\n const [, app, version] = match;\n if (query.app && app !== query.app) continue;\n if (query.version && version !== query.version) continue;\n\n const openapiPath = posix.replace(/service\\.ts$/, \"openapi.d.ts\");\n if (!codegenFs.exists(openapiPath)) continue;\n\n entries.push({\n app,\n version,\n serviceModulePath: posix,\n operations: readOperations(codegenFs, openapiPath),\n });\n }\n return entries.sort(\n (a, b) => a.app.localeCompare(b.app) || a.version.localeCompare(b.version)\n );\n}\n\n/** Parse one `openapi.d.ts` into its operations. */\nfunction readOperations(\n codegenFs: CodegenFileSystem,\n openapiPath: string\n): ServiceOperation[] {\n return readSourceFile(codegenFs, openapiPath, (sf) => {\n const paths = sf.getInterface(\"paths\");\n if (!paths) return [];\n\n const operations: ServiceOperation[] = [];\n for (const pathProp of paths.getProperties()) {\n const servicePath = unquote(pathProp.getName());\n const literal = pathProp.getTypeNode();\n // Each path maps to a type literal of per-method members; anything else\n // is a shape this parser does not claim to understand.\n if (!literal || !(\"getProperties\" in literal)) continue;\n\n for (const methodProp of (literal as any).getProperties()) {\n const method = methodProp.getName();\n if (!isCatalogMethod(method)) continue;\n const typeText: string = methodProp.getTypeNode()?.getText() ?? \"\";\n // `post?: never` is the spec saying this path has no POST.\n if (methodProp.hasQuestionToken() && typeText === \"never\") continue;\n\n operations.push({\n path: servicePath,\n method,\n summary: readSummary(methodProp),\n pathParams: [...servicePath.matchAll(/\\{([^}]+)\\}/g)].map(\n (m) => m[1]\n ),\n });\n }\n }\n return operations;\n });\n}\n\nfunction isCatalogMethod(value: string): value is CatalogMethod {\n return (CATALOG_METHODS as readonly string[]).includes(value);\n}\n\n/** The OpenAPI `summary`, which openapi-typescript emits as leading JSDoc. */\nfunction readSummary(methodProp: {\n getLeadingCommentRanges: () => { getText: () => string }[];\n}): string | undefined {\n const text = methodProp\n .getLeadingCommentRanges()\n .map((c) => c.getText())\n .join(\" \")\n .replace(/^\\/\\*+/, \"\")\n .replace(/\\*+\\/$/, \"\")\n .replace(/^\\s*\\*\\s?/gm, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n return text || undefined;\n}\n\nfunction unquote(name: string): string {\n return name.replace(/^[\"']|[\"']$/g, \"\");\n}\n","/**\n * Source of tools/scripts/update-release-version.mjs — the implementation of\n * the `version` target emitted by buildKabTargets (see kab-targets.ts).\n *\n * Kept as a constant (not a .template file) so the preset generator and the\n * add-version-targets migration emit byte-identical scripts and cannot drift.\n * The script has no template variables: the project name arrives via argv.\n */\nexport const UPDATE_RELEASE_VERSION_SCRIPT = `import devkit from \"@nx/devkit\";\nimport { resolve } from \"path\";\nimport { readFileSync, writeFileSync } from \"fs\";\nimport prettier from \"prettier\";\n\n// KOS artifact versioning: stamps the project's .kos.json \"version\" field\n// (which kabtool bakes into the KAB). Never touches package.json.\n// Driven by tag-based releases:\n// nx run-many --target=version --args=--ver=$KOSBUILD_VERSION\n\nconst { readCachedProjectGraph } = devkit;\nconst [, , name, versionArg] = process.argv;\n\n// \"{args.ver}\" arrives literally when the target runs without --args=--ver=<v>;\n// treat that (or a missing arg) as \"report current version, change nothing\".\nconst version =\n versionArg && !versionArg.startsWith(\"{args\") ? versionArg : undefined;\n\nif (!name) {\n console.error(\"usage: update-release-version.mjs <project> <version>\");\n process.exit(1);\n}\n\nconst graph = readCachedProjectGraph();\nconst project = graph.nodes[name];\nif (!project) {\n console.error(\"Unknown project: \" + name);\n process.exit(1);\n}\n\nconst kosJsonPath = resolve(process.cwd(), project.data.root, \".kos.json\");\nlet kosJson;\ntry {\n kosJson = JSON.parse(readFileSync(kosJsonPath, \"utf8\"));\n} catch {\n console.error(\"Missing or invalid .kos.json: \" + kosJsonPath);\n process.exit(1);\n}\n\nif (!version) {\n console.log(name + \": \" + kosJson.version + \" (no --ver given; unchanged)\");\n process.exit(0);\n}\n\nconst prettierOptions = await prettier.resolveConfig(kosJsonPath);\nconst output = await prettier.format(\n JSON.stringify({ ...kosJson, version }, null, 2),\n { ...prettierOptions, parser: \"json\" }\n);\nwriteFileSync(kosJsonPath, output);\nconsole.log(name + \": version -> \" + version);\n`;\n","/**\n * Barrel export manipulation utilities.\n *\n * Appends `export * from './path'` lines to index.ts files,\n * handling deduplication.\n */\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\n\n/**\n * Append a barrel re-export to an index.ts file, creating it if necessary.\n * Skips the append if the export already exists.\n *\n * @param codegenFs - Filesystem abstraction\n * @param indexPath - Path to the index.ts file (relative to root)\n * @param exportPath - The module path to export (e.g. './my-hook')\n */\nexport function appendBarrelExport(\n codegenFs: CodegenFileSystem,\n indexPath: string,\n exportPath: string\n): void {\n const exportLine = `export * from '${exportPath}'`;\n const content = codegenFs.read(indexPath) ?? \"\";\n const lines = content.split(\"\\n\");\n\n if (lines.some((line) => line.includes(exportLine))) {\n return; // already present\n }\n\n lines.push(exportLine);\n codegenFs.write(indexPath, lines.join(\"\\n\"));\n}\n","/**\n * TypeScript AST-based index.ts updater.\n *\n * Adds `export * from './path'` declarations to a barrel file using\n * the TypeScript compiler API for proper AST manipulation.\n *\n * Ported from kos-nx-plugin/src/generators/kos-model/lib/utils/ts-visitor.ts.\n */\nimport * as ts from \"typescript\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport { getCodegenLogger } from \"../logger\";\n\n/**\n * Add an export-all declaration to an index.ts file using TS AST.\n *\n * @param codegenFs - Filesystem abstraction\n * @param indexPath - Path to the index.ts file (relative to root)\n * @param modelPath - Relative path to export (e.g. 'models/my-model')\n */\nexport function updateModelIndex(\n codegenFs: CodegenFileSystem,\n indexPath: string,\n modelPath: string\n): void {\n const logger = getCodegenLogger();\n\n if (!indexPath) return;\n\n const content = codegenFs.read(indexPath);\n if (content === null) {\n logger.warn(`Index file not found: ${indexPath}`);\n return;\n }\n\n logger.info(`Updating ${indexPath} — adding export for ${modelPath}`);\n\n const sourceFile = ts.createSourceFile(\n indexPath,\n content,\n ts.ScriptTarget.Latest,\n true\n );\n\n // Idempotent: the model and container passes both target the same directory,\n // and generators may be re-run — never append a duplicate export.\n const alreadyExported = sourceFile.statements.some(\n (st) =>\n ts.isExportDeclaration(st) &&\n st.moduleSpecifier !== undefined &&\n ts.isStringLiteral(st.moduleSpecifier) &&\n st.moduleSpecifier.text === `./${modelPath}`\n );\n if (alreadyExported) {\n logger.info(`Export for ${modelPath} already present in ${indexPath}`);\n return;\n }\n\n const exportDeclaration = ts.factory.createExportDeclaration(\n undefined,\n false,\n undefined,\n ts.factory.createStringLiteral(`./${modelPath}`)\n );\n\n const updatedSourceFile = ts.factory.updateSourceFile(sourceFile, [\n ...sourceFile.statements,\n exportDeclaration,\n ]);\n\n const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });\n const newContents = printer.printFile(updatedSourceFile);\n\n codegenFs.write(indexPath, newContents);\n}\n","/**\n * Core generator: KOS Hook.\n *\n * Generates a hook file set inside an app project and updates the barrel export.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport {\n getCurrentDirectoryName,\n getKosModelConfiguration,\n getKosProjectConfiguration,\n getProject,\n} from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { appendBarrelExport } from \"./barrel-utils\";\n\nexport interface HookOptions extends KosBaseGeneratorOptions {\n appProject: string;\n appDirectory: string;\n singleton?: boolean;\n internal?: boolean;\n}\n\n/**\n * Generate a KOS hook.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory\n * @param options - Generator options (mutated to fill in defaults)\n * @param cwd - Current working directory for project resolution\n * @param projects - Optional pre-computed project map\n */\nexport function generateHook(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: HookOptions,\n cwd: string,\n projects?: Map<string, ProjectConfiguration>\n): void {\n if (!options.appProject) {\n throw new Error(\"No app project specified\");\n }\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n const modelName = options.name || getCurrentDirectoryName(cwd);\n if (!modelName) {\n throw new Error(\n \"No model name found. Please specify a model name with --name.\"\n );\n }\n\n const kosModelConfig = getKosModelConfiguration(\n codegenFs,\n modelProjectName,\n modelName,\n projects\n );\n options.singleton = kosModelConfig ? !!kosModelConfig.singleton : false;\n options.name = modelName;\n options.modelProject = modelProjectName;\n\n const normalized = normalizeOptions(codegenFs, options, projects);\n const appProject = findProjectByName(\n codegenFs.root,\n normalized.appProject,\n projects\n );\n if (!appProject) {\n throw new Error(`App project '${normalized.appProject}' not found`);\n }\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n appProject.name,\n projects\n );\n const componentLocation =\n kosConfig?.generator?.defaults?.component?.folder || \"\";\n options.appDirectory = options.appDirectory || componentLocation;\n\n const projectRoot = appProject.sourceRoot;\n if (projectRoot) {\n generateFilesFromTemplates(\n codegenFs,\n templateDir,\n path.join(\n projectRoot,\n options.appDirectory,\n \"hooks\",\n normalized.nameDashCase\n ),\n normalized\n );\n\n appendBarrelExport(\n codegenFs,\n path.join(projectRoot, options.appDirectory, \"hooks\", \"index.ts\"),\n `./${normalized.nameDashCase}`\n );\n }\n}\n","/**\n * Core generator: KOS Context.\n *\n * Generates a context file set inside an app project and updates the barrel export.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport {\n getCurrentDirectoryName,\n getKosModelConfigProp,\n getProject,\n} from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { appendBarrelExport } from \"./barrel-utils\";\n\nexport interface ContextOptions extends KosBaseGeneratorOptions {\n appProject: string;\n appDirectory: string;\n singleton?: boolean;\n internal?: boolean;\n}\n\n/**\n * Generate a KOS context.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory\n * @param options - Generator options (mutated to fill in defaults)\n * @param cwd - Current working directory for project resolution\n * @param projects - Optional pre-computed project map\n */\nexport function generateContext(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: ContextOptions,\n cwd: string,\n projects?: Map<string, ProjectConfiguration>\n): void {\n if (!options.appProject) {\n throw new Error(\"No app project specified\");\n }\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n const modelName = options.name || getCurrentDirectoryName(cwd);\n if (!modelName) {\n throw new Error(\n \"No model name found. Please specify a model name with --name.\"\n );\n }\n\n const singletonProp = getKosModelConfigProp({\n codegenFs,\n project: modelProjectName,\n modelName,\n prop: \"singleton\",\n projects,\n });\n options.singleton = !!singletonProp;\n options.name = modelName;\n options.modelProject = modelProjectName;\n\n const normalized = normalizeOptions(codegenFs, options, projects);\n const appProject = findProjectByName(\n codegenFs.root,\n normalized.appProject,\n projects\n );\n if (!appProject) {\n throw new Error(`App project '${normalized.appProject}' not found`);\n }\n\n const projectRoot = appProject.sourceRoot;\n if (projectRoot) {\n const dir =\n appProject.projectType === \"application\" || options.internal\n ? options.appDirectory\n : options.appDirectory ?? \"lib\";\n\n generateFilesFromTemplates(\n codegenFs,\n templateDir,\n path.join(projectRoot, dir, \"contexts\", normalized.nameDashCase),\n normalized\n );\n\n appendBarrelExport(\n codegenFs,\n path.join(projectRoot, dir, \"contexts\", \"index.ts\"),\n `./${normalized.nameDashCase}`\n );\n }\n}\n","/**\n * Core generator: KOS Container Model.\n *\n * Generates a container model within an existing model project.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { getCodegenLogger } from \"../logger\";\nimport {\n addKosModelConfiguration,\n getCurrentDirectoryName,\n getKosProjectConfiguration,\n getProject,\n} from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { updateModelIndex } from \"./update-model-index\";\n\nexport interface ContainerModelOptions extends KosBaseGeneratorOptions {\n modelName?: string;\n singleton?: boolean;\n autoRegister?: boolean;\n}\n\n/**\n * Generate a container model.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory (containing model/ and services/ subdirs)\n * @param options - Generator options (mutated to fill in defaults)\n * @param cwd - Current working directory for project resolution\n * @param projects - Optional pre-computed project map\n */\nexport function generateContainerModel(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: ContainerModelOptions,\n cwd: string,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n const modelName = options.modelName || getCurrentDirectoryName(cwd);\n if (!modelName) {\n throw new Error(\n \"No model name found. Please specify a model name with --name.\"\n );\n }\n\n options.modelName = modelName;\n options.name = `${modelName}-container`;\n\n const normalized = normalizeOptions(codegenFs, options, projects);\n const projectConfig = findProjectByName(\n codegenFs.root,\n normalized.modelProject,\n projects\n );\n if (!projectConfig) {\n throw new Error(`Model project '${normalized.modelProject}' not found`);\n }\n\n addKosModelConfiguration({\n codegenFs,\n modelName: normalized.nameDashCase,\n projectName: projectConfig.name,\n projectRoot: projectConfig.root,\n singleton: !!options.singleton,\n container: true,\n // The container's exported registration bean (`export const <ProperCase>`).\n factory: normalized.nameProperCase,\n });\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectConfig.name,\n projects\n );\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const internal = !!kosConfig?.generator?.internal;\n options.modelDirectory = options.modelDirectory || modelLocation;\n\n const projectRoot = projectConfig.sourceRoot;\n if (projectRoot) {\n logger.info(\n `Generating container model ${normalized.nameDashCase} in ${projectRoot}`\n );\n\n const modelNameDashCase =\n (normalized as any).modelNameDashCase || normalized.nameDashCase;\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateDir, \"model\"),\n path.join(projectRoot, options.modelDirectory || \"\", modelNameDashCase),\n { ...normalized, internal }\n );\n\n const modelIndex = path.join(projectRoot, \"index.ts\");\n const modelPath = normalized.modelDirectory\n ? `${normalized.modelDirectory}/${modelNameDashCase}`\n : modelNameDashCase;\n updateModelIndex(codegenFs, modelIndex, modelPath);\n }\n}\n","/**\n * Core generator: KOS Companion Model.\n *\n * Generates companion model files into a child project with references\n * to the parent model's package.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { readJson } from \"../json-utils\";\nimport { normalizeAllValues } from \"../normalize-values\";\nimport { getCodegenLogger } from \"../logger\";\nimport { getKosProjectConfiguration } from \"../kos-config\";\n\nexport interface CompanionModelOptions {\n companionModelName: string;\n companionModelProject: string;\n modelName: string;\n modelProject: string;\n companionPattern?: \"composition\" | \"decorator\";\n}\n\n/**\n * Generate a companion model.\n *\n * @param codegenFs - Target filesystem\n * @param templateDir - Absolute path to the template directory\n * @param options - Generator options\n * @param projects - Optional pre-computed project map\n */\nexport function generateCompanionModel(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: CompanionModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n\n const normalized = normalizeAllValues({\n companionModelName: options.companionModelName,\n modelName: options.modelName,\n });\n\n const companionChildKosConfig = getKosProjectConfiguration(\n codegenFs,\n options.companionModelProject,\n projects\n );\n\n const parentProject = findProjectByName(\n codegenFs.root,\n options.modelProject,\n projects\n );\n const childProject = findProjectByName(\n codegenFs.root,\n options.companionModelProject,\n projects\n );\n\n const projectRoot = childProject?.sourceRoot;\n if (!projectRoot) {\n logger.warn(`Companion child project source root not found`);\n return;\n }\n\n let importPath = \"\";\n if (parentProject) {\n const pkgJsonPath = path.join(parentProject.root, \"package.json\");\n try {\n const pkgJson = readJson<{ name: string }>(codegenFs, pkgJsonPath);\n importPath = pkgJson.name || \"\";\n } catch {\n importPath = \"\";\n }\n }\n\n const modelLocation =\n companionChildKosConfig?.generator?.defaults?.model?.folder || \"\";\n const filePath = path.join(\n projectRoot,\n modelLocation,\n normalized.companionModelNameDashCase\n );\n\n logger.info(`Generating companion model in ${filePath}`);\n generateFilesFromTemplates(codegenFs, templateDir, filePath, {\n ...options,\n ...normalized,\n importPath,\n });\n}\n","/**\n * Core generator: KOS Model.\n *\n * Generates a model within a model project, optionally with container\n * and companion sub-generators.\n * Framework-agnostic — operates through CodegenFileSystem.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../project-discovery\";\nimport { findProjectByName } from \"../project-discovery\";\nimport { generateFilesFromTemplates } from \"../generate-files\";\nimport { updateJson } from \"../json-utils\";\nimport { getCodegenLogger } from \"../logger\";\nimport { getKosProjectConfiguration, getProject } from \"../kos-config\";\nimport {\n normalizeOptions,\n type KosBaseGeneratorOptions,\n} from \"./normalize-options\";\nimport { updateModelIndex } from \"./update-model-index\";\nimport {\n generateContainerModel,\n type ContainerModelOptions,\n} from \"./generate-container-model\";\nimport {\n generateCompanionModel,\n type CompanionModelOptions,\n} from \"./generate-companion-model\";\n\nexport interface ModelOptions extends KosBaseGeneratorOptions {\n singleton?: boolean;\n isContainerSingleton?: boolean;\n unitTests?: boolean;\n container?: boolean;\n parentAware?: boolean;\n autoRegister?: boolean;\n /** One-line, human-curated purpose for the model catalog (optional). */\n purpose?: string;\n}\n\nexport interface GenerateModelParams {\n codegenFs: CodegenFileSystem;\n modelTemplateDir: string;\n containerTemplateDir?: string;\n companionTemplateDir?: string;\n options: ModelOptions;\n cwd: string;\n projects?: Map<string, ProjectConfiguration>;\n}\n\n/**\n * Generate a KOS model with optional container and companion.\n */\nexport function generateModel(params: GenerateModelParams): void {\n const {\n codegenFs,\n modelTemplateDir,\n containerTemplateDir,\n companionTemplateDir,\n options,\n cwd,\n projects,\n } = params;\n const logger = getCodegenLogger();\n\n const currentProject = getProject(codegenFs, cwd);\n const modelProjectName = options.modelProject || currentProject?.name;\n if (!modelProjectName) {\n throw new Error(\n \"No model project found. Please specify a model project with --modelProject.\"\n );\n }\n\n options.modelProject = modelProjectName;\n const normalized = normalizeOptions(codegenFs, options, projects);\n const projectConfig = findProjectByName(\n codegenFs.root,\n normalized.modelProject,\n projects\n );\n if (!projectConfig) {\n throw new Error(`Model project '${normalized.modelProject}' not found`);\n }\n\n const projectRoot = projectConfig.sourceRoot;\n if (!projectRoot) return;\n\n const kosConfigPath = path.join(projectConfig.root, \".kos.json\");\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n projectConfig.name,\n projects\n );\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const internal = !!kosConfig?.generator?.internal;\n options.modelDirectory = options.modelDirectory || modelLocation;\n\n logger.info(`Generating model ${normalized.nameDashCase} in ${projectRoot}`);\n\n generateFilesFromTemplates(\n codegenFs,\n path.join(modelTemplateDir, \"model\"),\n path.join(projectRoot, options.modelDirectory, normalized.nameDashCase),\n { ...normalized, internal }\n );\n\n const modelIndex = path.join(projectRoot, \"index.ts\");\n const modelPath = options.modelDirectory\n ? `${options.modelDirectory}/${normalized.nameDashCase}`\n : normalized.nameDashCase;\n updateModelIndex(codegenFs, modelIndex, modelPath);\n\n // The generator names the exported registration bean (`export const <ProperCase>`),\n // so it knows the catalog `factory` exactly — no inference. When a container is\n // also generated, this model is held by it: record that as `managedBy` so a\n // consumer depends on the container and navigates, rather than taking the model\n // by id. `purpose` is the only authored field (optional slot).\n const containerKey = normalized.container\n ? `${normalized.nameDashCase}-container`\n : undefined;\n updateJson(codegenFs, kosConfigPath, (json: any) => {\n const existing = json.models?.[normalized.name] ?? {};\n const managedBy = containerKey\n ? [...new Set([...(existing.managedBy ?? []), containerKey])]\n : existing.managedBy;\n json.models = {\n ...json.models,\n [normalized.name]: {\n ...existing,\n name: normalized.name,\n type: `${normalized.nameDashCase}-model`,\n singleton: !!normalized.singleton,\n factory: normalized.nameProperCase,\n ...(normalized.purpose ? { purpose: normalized.purpose } : {}),\n ...(managedBy?.length ? { managedBy } : {}),\n },\n };\n return json;\n });\n\n if (normalized.container && containerTemplateDir) {\n logger.info(`Generating container for ${normalized.name}`);\n generateContainerModel(\n codegenFs,\n containerTemplateDir,\n {\n ...options,\n name: `${normalized.name}-container`,\n modelName: normalized.name,\n singleton: normalized.isContainerSingleton,\n } as ContainerModelOptions,\n cwd,\n projects\n );\n }\n\n if (\n normalized.companion &&\n normalized.companionModel &&\n normalized.companionModelProject &&\n companionTemplateDir\n ) {\n generateCompanionModel(\n codegenFs,\n companionTemplateDir,\n {\n companionModelName: normalized.name,\n companionModelProject: normalized.modelProject,\n modelName: normalized.companionModel,\n modelProject: normalized.companionModelProject,\n companionPattern: normalized.companionPattern,\n } as CompanionModelOptions,\n projects\n );\n }\n}\n","/**\n * Shared model-file resolution for capability mutators. Locates the `-model.ts`\n * file for a model in a project. The conventional `<folder>/<name>/<name>-model.ts`\n * location is tried first; when absent, the project's model folder is searched for\n * the file by name — models are routinely co-located (a container in its item\n * model's directory) or grouped in shared directories, and the file NAME is the\n * stable invariant, not the directory.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport { normalizeAllValues } from \"../../normalize-values\";\n\nexport interface ModelFileQuery {\n modelName: string;\n modelProject: string;\n /** Explicit model file path (relative to root), overriding resolution. */\n modelPath?: string;\n}\n\nexport function resolveModelFilePath(\n codegenFs: CodegenFileSystem,\n query: ModelFileQuery,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string; internal: boolean; sourceRoot?: string } {\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n query.modelProject,\n projects\n );\n const internal = !!kosConfig?.generator?.internal;\n\n const project = findProjectByName(\n codegenFs.root,\n query.modelProject,\n projects\n );\n const sourceRoot = project\n ? project.sourceRoot || path.join(project.root, \"src\")\n : undefined;\n\n if (query.modelPath) {\n return { modelFilePath: query.modelPath, internal, sourceRoot };\n }\n\n if (!project) {\n throw new Error(\n `Project not found: ${query.modelProject}. Ensure a project.json exists.`\n );\n }\n const { modelNameDashCase } = normalizeAllValues({\n modelName: query.modelName,\n });\n const modelLocation = kosConfig?.generator?.defaults?.model?.folder || \"\";\n const modelFilePath = path.join(\n sourceRoot as string,\n modelLocation,\n modelNameDashCase,\n `${modelNameDashCase}-model.ts`\n );\n if (codegenFs.exists(modelFilePath)) {\n return { modelFilePath, internal, sourceRoot };\n }\n\n const discovered = findModelFileByName(\n codegenFs,\n path.join(sourceRoot as string, modelLocation),\n modelNameDashCase\n );\n if (discovered) {\n return { modelFilePath: discovered, internal, sourceRoot };\n }\n return { modelFilePath, internal, sourceRoot };\n}\n\n/**\n * Search a directory tree for `<name>-model.ts`. Returns the single match, null\n * when there is none (callers keep the conventional path so their not-found\n * error names the expected location), and throws on ambiguity — a wrong guess\n * would silently mutate the wrong model.\n */\nfunction findModelFileByName(\n codegenFs: CodegenFileSystem,\n searchRoot: string,\n modelNameDashCase: string\n): string | null {\n const fileName = `${modelNameDashCase}-model.ts`;\n const candidates = codegenFs\n .listFiles(searchRoot)\n .filter((f) => path.basename(f) === fileName)\n .sort();\n if (candidates.length === 0) return null;\n if (candidates.length > 1) {\n throw new Error(\n `Model name '${modelNameDashCase}' is ambiguous — multiple files match ${fileName}:\\n` +\n candidates.map((c) => ` - ${c}`).join(\"\\n\") +\n `\\nPass modelPath to pick one.`\n );\n }\n return candidates[0];\n}\n","/**\n * The model's own `services/` module — where a model's data-transfer concerns\n * live: the endpoints it calls, the types derived from them, and standalone\n * service functions for callers outside a model context.\n *\n * Created on demand, at the point a capability actually has something to put in\n * it. Scaffolding it up front only produced a placeholder that had to be\n * replaced before the project could compile.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport { transformSourceFile, ensureBarrelExport } from \"./ts-toolkit\";\n\n/** `board-model.ts` → `board`; falls back to the requested model name. */\nexport function modelBaseName(\n modelFilePath: string,\n modelName: string\n): string {\n const base = path.basename(modelFilePath);\n const match = base.match(/^(.*)-model\\.ts$/);\n return match ? match[1] : modelName;\n}\n\n/** Where a model's services module lives, whether or not it exists yet. */\nexport function servicesFilePathFor(\n modelFilePath: string,\n modelBase: string\n): string {\n return path.join(\n path.dirname(modelFilePath),\n \"services\",\n `${modelBase}-services.ts`\n );\n}\n\nfunction header(modelBase: string): string {\n return `/**\n * Service layer for the ${modelBase} model: the endpoints it calls and the\n * types derived from them. Standalone service functions for callers outside a\n * model context belong here too.\n */\n`;\n}\n\n/**\n * Ensure the model's services module and its barrel exist, and return the\n * module's path. Existing files are left alone — callers add to them.\n */\nexport function ensureServicesModule(\n codegenFs: CodegenFileSystem,\n modelFilePath: string,\n modelBase: string\n): string {\n const servicesFilePath = servicesFilePathFor(modelFilePath, modelBase);\n if (!codegenFs.exists(servicesFilePath)) {\n codegenFs.write(servicesFilePath, header(modelBase));\n }\n\n const barrelPath = path.join(path.dirname(servicesFilePath), \"index.ts\");\n if (!codegenFs.exists(barrelPath)) {\n codegenFs.write(barrelPath, \"\");\n }\n transformSourceFile(codegenFs, barrelPath, (sf) => {\n ensureBarrelExport(sf, `./${modelBase}-services`);\n });\n\n return servicesFilePath;\n}\n","/**\n * Option normalization for the add-future-to-model generator.\n *\n * Resolves project configuration, computes name case variants,\n * and determines file paths for model, services, and registration files.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport { normalizeAllValues } from \"../../normalize-values\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport { servicesFilePathFor } from \"../augment/model-services\";\nimport type {\n AddFutureToModelOptions,\n NormalizedAddFutureToModelOptions,\n} from \"./types\";\n\nexport function normalizeAddFutureOptions(\n codegenFs: CodegenFileSystem,\n options: AddFutureToModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedAddFutureToModelOptions {\n const projectConfiguration = findProjectByName(\n codegenFs.root,\n options.modelProject,\n projects\n );\n\n if (!projectConfiguration) {\n throw new Error(\n `Project not found: ${options.modelProject}. Ensure a project.json exists for this project.`\n );\n }\n\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n options.modelProject,\n projects\n );\n const internal = !!kosConfig?.generator?.internal;\n\n // Normalize name variations\n const normalizedValues = normalizeAllValues({\n modelName: options.modelName,\n });\n\n const nameDashCase = normalizedValues.modelNameDashCase;\n const nameProperCase = normalizedValues.modelNameProperCase;\n const nameCamelCase = normalizedValues.modelNameCamelCase;\n const namePascalCase = normalizedValues.modelNamePascalCase;\n const nameConstantCase = normalizedValues.modelNameConstantCase;\n const nameLowerCase = normalizedValues.modelNameLowerCase;\n\n const projectRoot = projectConfiguration.root;\n const sourceRoot =\n projectConfiguration.sourceRoot || path.join(projectRoot, \"src\");\n\n // Determine model file path — shared resolution covers co-located containers\n // and shared-dir models, not just the conventional `<folder>/<name>/` layout.\n const { modelFilePath } = resolveModelFilePath(\n codegenFs,\n { modelName: options.modelName, modelProject: options.modelProject },\n projects\n );\n const modelDirectory = path.dirname(modelFilePath);\n\n // The services module is created on demand by the capability that needs it,\n // so this path is where it belongs, not proof that it already exists.\n const servicesFilePath = servicesFilePathFor(modelFilePath, nameDashCase);\n\n // Determine registration file path\n const registrationFilePath = path.join(\n modelDirectory,\n `${nameDashCase}-registration.ts`\n );\n\n return {\n ...options,\n nameDashCase,\n nameProperCase,\n nameCamelCase,\n namePascalCase,\n nameConstantCase,\n nameLowerCase,\n projectRoot,\n sourceRoot,\n modelFilePath,\n servicesFilePath,\n registrationFilePath: codegenFs.exists(registrationFilePath)\n ? registrationFilePath\n : undefined,\n internal,\n };\n}\n","/**\n * Transformer that updates existing models to use the @kosFutureAware\n * decorator pattern with TypeScript interface merging for type safety.\n *\n * AST-based (ts-morph via the augment toolkit): every edit anchors on a real\n * node — class, decorator list, import declaration, type alias — so a model\n * with existing decorated methods round-trips intact. The earlier regex\n * string-splice version doubled the class declaration and unbalanced braces\n * on any non-trivial model (G-111).\n */\nimport type { SourceFile, ClassDeclaration } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addClassDecorator,\n ensureDeclarationMerge,\n ensureFileEslintDisable,\n} from \"../augment/ts-toolkit\";\n\n// Symbols from the legacy (pre-decorator) future pattern, scrubbed on sight.\nconst LEGACY_IMPORTS = new Set([\n \"setupCompleteFutureSupport\",\n \"setupMinimalFutureSupport\",\n \"FutureAwareContainer\",\n \"FutureHandlerContainer\",\n \"FutureStateAccessor\",\n \"FutureUpdateHandler\",\n]);\nconst LEGACY_IMPLEMENTS = new Set([\n \"FutureUpdateHandler\",\n \"FutureHandlerContainer\",\n \"FutureStateAccessor\",\n]);\n\nexport class ModelFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n private get progressType(): string {\n const { nameProperCase, updateServices } = this.options;\n return updateServices\n ? `${nameProperCase}OperationProgress`\n : \"Record<string, unknown>\";\n }\n\n transform(): void {\n const { modelFilePath } = this.options;\n\n if (!this.codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n transformSourceFile(this.codegenFs, modelFilePath, (sf) => {\n this.removeLegacyImports(sf);\n this.addImports(sf);\n\n const cls = getModelClass(sf, `${this.options.nameProperCase}ModelImpl`);\n this.removeLegacyClassMembers(cls);\n this.addDecorator(cls);\n this.addFutureMethod(cls);\n if (this.options.futureType === \"complete\") {\n this.addOnFutureUpdateMethod(cls);\n }\n\n this.updatePublicType(sf);\n\n // Raw-text insertions LAST — they invalidate node references.\n ensureDeclarationMerge(\n sf,\n `${this.options.nameProperCase}ModelImpl`,\n `${\n this.options.futureType === \"complete\"\n ? \"KosFutureAwareFull\"\n : \"KosFutureAwareMinimal\"\n }<${this.progressType}>`\n );\n ensureFileEslintDisable(\n sf,\n \"@typescript-eslint/no-unsafe-declaration-merging\"\n );\n });\n }\n\n private removeLegacyImports(sf: SourceFile): void {\n for (const decl of sf.getImportDeclarations()) {\n for (const named of decl.getNamedImports()) {\n if (LEGACY_IMPORTS.has(named.getName())) named.remove();\n }\n if (\n decl.getNamedImports().length === 0 &&\n !decl.getDefaultImport() &&\n !decl.getNamespaceImport()\n ) {\n decl.remove();\n }\n }\n }\n\n private addImports(sf: SourceFile): void {\n const { internal, futureType, updateServices, nameProperCase } =\n this.options;\n const isComplete = futureType === \"complete\";\n const sdkSpec = resolveSdkModuleSpecifier(sf);\n\n ensureNamedImport(sf, sdkSpec, [\n { name: \"kosFuture\" },\n { name: \"kosFutureAware\" },\n {\n name: isComplete ? \"KosFutureAwareFull\" : \"KosFutureAwareMinimal\",\n isTypeOnly: true,\n },\n ]);\n\n const typeSpec = internal\n ? \"../../../models/types/future-interfaces\"\n : sdkSpec;\n ensureNamedImport(sf, typeSpec, [\n { name: \"ExternalFutureInterface\", isTypeOnly: true },\n ...(isComplete ? [{ name: \"IFutureModel\", isTypeOnly: true }] : []),\n ]);\n\n if (updateServices) {\n ensureNamedImport(sf, \"./services\", [\n { name: `${nameProperCase}OperationProgress`, isTypeOnly: true },\n ]);\n }\n }\n\n private removeLegacyClassMembers(cls: ClassDeclaration): void {\n for (const ctor of cls.getConstructors()) {\n for (const stmt of ctor.getStatements()) {\n if (\n /setup(Complete|Minimal)FutureSupport\\s*\\(\\s*this\\s*\\)/.test(\n stmt.getText()\n )\n ) {\n stmt.remove();\n }\n }\n }\n\n const futureHandler = cls.getProperty(\"futureHandler\");\n if (\n futureHandler?.getTypeNode()?.getText().includes(\"FutureAwareContainer\")\n ) {\n futureHandler.remove();\n }\n const future = cls.getProperty(\"future\");\n if (future?.getTypeNode()?.getText().includes(\"IFutureModel\")) {\n future.remove();\n }\n\n const impls = cls.getImplements();\n for (let i = impls.length - 1; i >= 0; i--) {\n const base = impls[i].getText().split(\"<\")[0].trim();\n if (LEGACY_IMPLEMENTS.has(base)) cls.removeImplements(i);\n }\n }\n\n private addDecorator(cls: ClassDeclaration): void {\n const argsText =\n this.options.futureType === \"complete\" ? \"\" : `{ mode: \"minimal\" }`;\n addClassDecorator(cls, \"kosFutureAware\", { argsText });\n }\n\n private updatePublicType(sf: SourceFile): void {\n const { nameProperCase } = this.options;\n const alias = sf.getTypeAlias(`${nameProperCase}Model`);\n if (!alias) return;\n const text = alias.getTypeNode()?.getText() ?? \"\";\n if (\n !text.includes(`PublicModelInterface<${nameProperCase}ModelImpl>`) ||\n text.includes(\"ExternalFutureInterface\")\n ) {\n return;\n }\n alias.setType(\n `PublicModelInterface<${nameProperCase}ModelImpl> & ExternalFutureInterface<${this.progressType}>`\n );\n }\n\n private addFutureMethod(cls: ClassDeclaration): void {\n const { nameProperCase } = this.options;\n // A model that already has any @kosFuture method needs no placeholder.\n const hasFutureMethod = cls\n .getMethods()\n .some((m) => m.getDecorator(\"kosFuture\"));\n if (hasFutureMethod || cls.getMethod(\"performLongRunningOperation\")) return;\n\n cls.addMethod({\n name: \"performLongRunningOperation\",\n isAsync: true,\n returnType: \"Promise<void>\",\n decorators: [{ name: \"kosFuture\", arguments: [] }],\n docs: [\n {\n description:\n \"Placeholder method for Future operations\\nReplace this with your actual long-running operation\",\n },\n ],\n statements: [\n \"// TODO: Implement your long-running operation here\",\n \"// This method should use a service that returns a Future for progress tracking\",\n \"\",\n \"this.logger.debug(`Starting long-running operation for ${this.id}`);\",\n \"\",\n \"// Example implementation pattern using services:\",\n `// import { perform${nameProperCase}Operation } from './services';`,\n \"//\",\n `// const future = await perform${nameProperCase}Operation();`,\n \"// return this.futureHandler.setFuture(future);\",\n \"\",\n \"// Placeholder that doesn't actually do anything\",\n \"await new Promise((resolve) => setTimeout(resolve, 1000));\",\n \"\",\n \"this.logger.debug(`Completed long-running operation for ${this.id}`);\",\n ],\n });\n }\n\n private addOnFutureUpdateMethod(cls: ClassDeclaration): void {\n if (cls.getMethod(\"onFutureUpdate\")) return;\n\n cls.addMethod({\n name: \"onFutureUpdate\",\n hasQuestionToken: true,\n returnType: \"void\",\n parameters: [\n { name: \"update\", type: `IFutureModel<${this.progressType}>` },\n ],\n docs: [\n {\n description:\n \"Optional: Custom Future update handling\\nCalled whenever the Future state changes (progress, status, completion, etc.)\",\n },\n ],\n statements: [\n \"// Add custom Future update logic here\",\n \"// Examples:\",\n \"// - Log progress milestones\",\n \"// - Update derived state based on progress\",\n \"// - Handle specific error conditions\",\n \"// - Trigger notifications at certain thresholds\",\n \"\",\n \"this.logger.debug(`Future update for ${this.id}:`, {\",\n \" progress: update.progress,\",\n \" status: update.status,\",\n \" endState: update.endState,\",\n \" clientData: update.clientData,\",\n \"});\",\n ],\n });\n }\n}\n","/**\n * Adds Future-operation scaffolding to the model's services module: a\n * placeholder long-running operation and the progress/result types that go with\n * it, created on demand when the model has no services module yet.\n *\n * Every piece it needs — the SDK import, the logger, the function, the types —\n * is ensured independently, because the module it edits may have been created\n * by any capability (or by hand) and carries no guaranteed shape.\n */\nimport { VariableDeclarationKind, type SourceFile } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n ensureModuleConst,\n ensureExportedTypeAlias,\n} from \"../augment/ts-toolkit\";\nimport { ensureServicesModule } from \"../augment/model-services\";\n\nconst SDK_MODULE = \"@kosdev-code/kos-ui-sdk\";\n\nexport class ServiceFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const { modelFilePath, nameDashCase } = this.options;\n if (!modelFilePath) return;\n\n const servicesFilePath = ensureServicesModule(\n this.codegenFs,\n modelFilePath,\n nameDashCase\n );\n\n transformSourceFile(this.codegenFs, servicesFilePath, (sf) => {\n ensureNamedImport(sf, SDK_MODULE, [\n { name: \"KosLog\" },\n { name: \"FutureResponse\", isTypeOnly: true },\n ]);\n // The emitted operation logs through `log`; a services module written by\n // another capability has no logger of its own.\n ensureModuleConst(sf, {\n name: \"log\",\n initializer: `KosLog.createLogger({ name: \"${nameDashCase}-service\", group: \"Services\" })`,\n });\n this.addFutureOperation(sf);\n this.addProgressTypes(sf);\n });\n }\n\n private addFutureOperation(sf: SourceFile): void {\n const { nameProperCase, nameLowerCase } = this.options;\n const name = `perform${nameProperCase}Operation`;\n if (sf.getVariableDeclaration(name)) return;\n\n sf.addVariableStatement({\n isExported: true,\n declarationKind: VariableDeclarationKind.Const,\n declarations: [\n {\n name,\n initializer: `async (): Promise<FutureResponse> => {\n log.debug(\"starting long-running ${nameLowerCase} operation\");\n throw new Error(\"${name} not yet implemented\");\n}`,\n },\n ],\n docs: [\n {\n description: `@category Service - Future Operation\\nA long-running operation returning a Future for progress tracking. Replace the body with the real service call.`,\n },\n ],\n });\n }\n\n private addProgressTypes(sf: SourceFile): void {\n const { nameProperCase } = this.options;\n ensureExportedTypeAlias(sf, {\n name: `${nameProperCase}OperationProgress`,\n type: `{\n stage: string;\n percentComplete: number;\n currentItem?: string;\n totalItems?: number;\n}`,\n });\n ensureExportedTypeAlias(sf, {\n name: `${nameProperCase}OperationResult`,\n type: `{\n success: boolean;\n message?: string;\n data?: unknown;\n}`,\n });\n }\n}\n","/**\n * Transformer that updates registration files to support Future-enabled models.\n *\n * Adds type casts and documentation for Future capabilities.\n *\n * Ported from kos-nx-plugin to use CodegenFileSystem instead of Nx Tree.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport { getCodegenLogger } from \"../../logger\";\nimport type { NormalizedAddFutureToModelOptions } from \"./types\";\n\nexport class RegistrationFileTransformer {\n constructor(\n private codegenFs: CodegenFileSystem,\n private options: NormalizedAddFutureToModelOptions\n ) {}\n\n transform(): void {\n const logger = getCodegenLogger();\n const { registrationFilePath } = this.options;\n\n if (!registrationFilePath || !this.codegenFs.exists(registrationFilePath)) {\n logger.warn(\"Registration file not found, skipping registration updates\");\n return;\n }\n\n const original = this.codegenFs.read(registrationFilePath)!;\n\n let content = original;\n content = this.addTypeCast(content);\n content = this.updateDocumentation(content);\n\n // Only legacy registration patterns produce edits — writing unchanged\n // content makes dry-run predict a modification that never happens.\n if (content === original) {\n logger.info(\n \"Registration file has no legacy future patterns — leaving it untouched\"\n );\n return;\n }\n this.codegenFs.write(registrationFilePath, content);\n }\n\n private addTypeCast(content: string): string {\n const { nameProperCase } = this.options;\n\n // Find the registration factory instantiation and add type cast\n const factoryRegex = new RegExp(`class: ${nameProperCase}ModelImpl,`);\n\n const replacement = `class: ${nameProperCase}ModelImpl as any, // Type cast needed for Future intersection`;\n\n return content.replace(factoryRegex, replacement);\n }\n\n private updateDocumentation(content: string): string {\n const { nameProperCase, futureType } = this.options;\n\n // Add Future support documentation after the main description\n const descriptionRegex = new RegExp(\n `(\\\\* The registration bean includes convenience methods for creating and working with ${nameProperCase}Model instances\\\\.)`\n );\n\n const futureDocumentation = `$1\n *\n * ## Future Support\n * This model includes ${futureType} Future support for tracking long-running operations with:\n * - Progress tracking (0-1) with reactive updates\n * - Status messages during operation\n * - Cancellation support with bi-directional AbortController integration\n * - Reactive integration for UI updates${\n futureType === \"complete\"\n ? \"\\n * - Internal access to Future state for custom logic and computed properties\"\n : \"\"\n }`;\n\n if (content.match(descriptionRegex)) {\n content = content.replace(descriptionRegex, futureDocumentation);\n }\n\n // Add Future usage examples to factory documentation\n const factoryExampleRegex = /(\\*\\s+\\}\\);?\\s*\\*\\s+```)/;\n\n const futureExample = `$1\n *\n * // Example: Accessing Future state (when a Future is active)\n * const isRunning = model.futureIsRunning;\n * const progress = model.futureProgress; // 0-1\n * const status = model.futureStatus; // Current status message\n * \\`\\`\\``;\n\n if (content.match(factoryExampleRegex)) {\n content = content.replace(factoryExampleRegex, futureExample);\n }\n\n // Add Future capabilities to predicate examples\n const predicateExampleRegex =\n /(\\*\\s+model\\.updateAvailability\\(false\\);?\\s*\\*\\s+\\})/;\n\n const predicateFutureExample = `$1\n *\n * // Future capabilities are also available\n * const isRunning = model.futureIsRunning;\n * const progress = model.futureProgress;\n * }`;\n\n if (content.match(predicateExampleRegex)) {\n content = content.replace(predicateExampleRegex, predicateFutureExample);\n }\n\n return content;\n }\n}\n","/**\n * Framework-agnostic core logic for the add-future-to-model generator.\n *\n * Adds Future (long-running operation) support to an existing KOS model\n * by transforming model, service, and registration files. Works through\n * the CodegenFileSystem abstraction so it can run in any environment\n * (CLI, VS Code, Nx).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { normalizeAddFutureOptions } from \"./normalize-options\";\nimport { ModelFileTransformer } from \"./model-transformer\";\nimport { ServiceFileTransformer } from \"./service-transformer\";\nimport { RegistrationFileTransformer } from \"./registration-transformer\";\nimport type { AddFutureToModelOptions } from \"./types\";\n\nexport function addFutureToModel(\n codegenFs: CodegenFileSystem,\n options: AddFutureToModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n const logger = getCodegenLogger();\n const normalized = normalizeAddFutureOptions(codegenFs, options, projects);\n\n logger.info(\n `Adding ${normalized.futureType} Future support to model: ${normalized.modelName}`\n );\n\n // Validate that model file exists\n if (!codegenFs.exists(normalized.modelFilePath)) {\n throw new Error(`Model file not found: ${normalized.modelFilePath}`);\n }\n\n if (options.dryRun) {\n logger.info(\"DRY RUN - No files will be modified\");\n logger.info(`Would modify model file: ${normalized.modelFilePath}`);\n if (normalized.servicesFilePath) {\n logger.info(\n `Would modify/create services file: ${normalized.servicesFilePath}`\n );\n }\n if (normalized.registrationFilePath) {\n logger.info(\n `Would update registration file (only if legacy patterns are present): ${normalized.registrationFilePath}`\n );\n }\n return;\n }\n\n try {\n // Transform model file\n logger.info(`Transforming model file: ${normalized.modelFilePath}`);\n const modelTransformer = new ModelFileTransformer(codegenFs, normalized);\n modelTransformer.transform();\n\n // Transform or create services file\n if (normalized.updateServices) {\n logger.info(\n `Transforming services file: ${\n normalized.servicesFilePath || \"creating new\"\n }`\n );\n const serviceTransformer = new ServiceFileTransformer(\n codegenFs,\n normalized\n );\n serviceTransformer.transform();\n }\n\n // Transform registration file\n if (normalized.registrationFilePath) {\n logger.info(\n `Transforming registration file: ${normalized.registrationFilePath}`\n );\n const registrationTransformer = new RegistrationFileTransformer(\n codegenFs,\n normalized\n );\n registrationTransformer.transform();\n }\n\n logger.info(\n `Successfully added ${normalized.futureType} Future support to ${normalized.modelName}`\n );\n logger.info(\"\");\n logger.info(\"Next steps:\");\n logger.info(\n \"1. Review the generated @kosFuture method and implement your actual operation\"\n );\n logger.info(\n \"2. Update the service method to return a proper FutureResponse\"\n );\n logger.info(\"3. Define your specific progress and result types\");\n if (normalized.futureType === \"complete\") {\n logger.info(\n \"4. Customize the onFutureUpdate method for your specific needs\"\n );\n }\n } catch (error) {\n logger.error(`Failed to add Future support: ${error}`);\n throw error;\n }\n}\n","/**\n * Capability mutator: add container support to an EXISTING model.\n *\n * Applies the `@kosContainerAware` capability (decorator + declaration-merging\n * interface + imports) to a model in place, so a model can manage a collection of\n * children directly — replacing the older pattern that forced a separate container\n * model plus an extra model-manager layer.\n *\n * AST-based via the shared ts-morph toolkit (no regex); routes all I/O through\n * CodegenFileSystem so dry-run + formatFiles apply unchanged.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { recordContainerSupportInKosConfig } from \"../../kos-config\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addClassDecorator,\n ensureDeclarationMerge,\n ensureFileEslintDisable,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddContainerSupportOptions {\n modelName: string;\n modelProject: string;\n /** TS type the container holds. Default `IKosDataModel`. */\n childType?: string;\n /** Container property name on the instance. Default `container`. */\n containerProperty?: string;\n /** Optional `containerOptions.sortKey`. */\n sortKey?: string;\n /** Explicit model file path (relative to root), overriding resolution. */\n modelPath?: string;\n}\n\nfunction buildDecoratorArgs(options: AddContainerSupportOptions): string {\n const top: string[] = [];\n if (options.containerProperty) {\n top.push(`containerProperty: ${JSON.stringify(options.containerProperty)}`);\n }\n if (options.sortKey) {\n top.push(\n `containerOptions: { sortKey: ${JSON.stringify(options.sortKey)} }`\n );\n }\n return top.length ? `{ ${top.join(\", \")} }` : \"\";\n}\n\n/**\n * Add `@kosContainerAware` support to an existing model file.\n */\nexport function addContainerSupportToModel(\n codegenFs: CodegenFileSystem,\n options: AddContainerSupportOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const childType = options.childType?.trim() || \"IKosDataModel\";\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n logger.info(\n `Adding container support (<${childType}>) to model: ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [\n { name: \"kosContainerAware\" },\n { name: \"KosContainerAware\", isTypeOnly: true },\n ]);\n // Default child type comes from the SDK; ensure it's imported.\n if (childType === \"IKosDataModel\") {\n ensureNamedImport(sf, sdk, [{ name: \"IKosDataModel\", isTypeOnly: true }]);\n }\n\n const cls = getModelClass(sf);\n const className = cls.getName();\n if (!className) throw new Error(\"Model class has no name.\");\n // Capture the class's type parameters so the merged interface matches.\n const typeParams = cls.getTypeParameters().map((tp) => tp.getText());\n\n addClassDecorator(cls, \"kosContainerAware\", {\n typeArgs: [childType],\n argsText: buildDecoratorArgs(options),\n });\n\n ensureDeclarationMerge(\n sf,\n className,\n `KosContainerAware<${childType}>`,\n typeParams\n );\n ensureFileEslintDisable(\n sf,\n \"@typescript-eslint/no-unsafe-declaration-merging\"\n );\n });\n\n // The model now manages children directly — reflect that containment in the\n // catalog (`container: true`, and `managedBy` on a concrete held model).\n recordContainerSupportInKosConfig({\n codegenFs,\n projectName: options.modelProject,\n modelName: options.modelName,\n childType,\n projects,\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosModelEffect` reaction method to an existing model.\n * Generates an idiomatic skeleton (dependencies arrow + async handler) for the\n * developer/agent to fill in. AST-based via the shared toolkit.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedMethod,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddModelEffectOptions {\n modelName: string;\n modelProject: string;\n /** Effect handler method name, e.g. `handleSelectionChange`. */\n methodName: string;\n modelPath?: string;\n}\n\nexport function addModelEffectToModel(\n codegenFs: CodegenFileSystem,\n options: AddModelEffectOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosModelEffect \"${options.methodName}\" to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [{ name: \"kosModelEffect\" }]);\n const cls = getModelClass(sf);\n const modelType = (cls.getName() ?? \"\").replace(/Impl$/, \"\");\n addDecoratedMethod(cls, {\n name: options.methodName,\n decoratorName: \"kosModelEffect\",\n decoratorArgsText: `{ dependencies: (model: ${modelType}) => [] }`,\n isAsync: true,\n returnType: \"Promise<void>\",\n statements: \"// TODO: react to the tracked dependencies\",\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosDependency` property (cross-model reference) to an\n * existing model. The dependency's TS type and `modelType` ref are caller-supplied.\n *\n * When `dependencyPackage` is given (the SDK that owns the dependency — exactly what\n * `describe_sdk_model` surfaces from the catalog), this also adds the import for the\n * registration bean (the `X` in `X.type`) and the model interface type from that\n * package, so wiring an SDK model is a single call. Without it, importing those\n * symbols stays the caller's responsibility (the mutator can't guess their origin).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedProperty,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddDependencyOptions {\n modelName: string;\n modelProject: string;\n /** Property name to hold the dependency, e.g. `application`. */\n propertyName: string;\n /** TS type of the dependency, e.g. `ApplicationModel`. */\n dependencyType: string;\n /** Runtime model-type ref, e.g. `Application.type` or a string literal. */\n modelTypeRef: string;\n /** Optional dependency id. */\n id?: string;\n /**\n * The SDK package that owns the dependency (e.g. `@kosdev-code/kos-ui-sdk`). When\n * set, the registration bean and the model interface type are imported from it.\n */\n dependencyPackage?: string;\n modelPath?: string;\n}\n\n// Framework generics that come from the KOS SDK, not the dependency's own package —\n// never import these from `dependencyPackage`.\nconst FRAMEWORK_TYPES = new Set([\"IKosDataModel\", \"IKosIdentifiable\"]);\n\nexport function addDependencyToModel(\n codegenFs: CodegenFileSystem,\n options: AddDependencyOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosDependency \"${options.propertyName}\" to ${options.modelName}`\n );\n\n const argsParts = [`modelType: ${options.modelTypeRef}`];\n if (options.id) argsParts.push(`id: ${JSON.stringify(options.id)}`);\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [{ name: \"kosDependency\" }]);\n\n // Import the dependency's own symbols from the SDK root barrel (NOT a subpath —\n // every model/bean/type is re-exported from the package root).\n if (options.dependencyPackage) {\n const named: { name: string; isTypeOnly?: boolean }[] = [];\n // Registration bean: the `X` in `X.type` (skip string-literal refs).\n const bean = options.modelTypeRef.match(\n /^([A-Za-z_$][\\w$]*)\\.type$/\n )?.[1];\n if (bean) named.push({ name: bean });\n // Model interface type, unless it's a framework generic from the SDK.\n const depType = options.dependencyType?.trim();\n if (\n depType &&\n /^[A-Za-z_$][\\w$]*$/.test(depType) &&\n !FRAMEWORK_TYPES.has(depType)\n ) {\n named.push({ name: depType, isTypeOnly: true });\n }\n if (named.length) ensureNamedImport(sf, options.dependencyPackage, named);\n }\n\n const cls = getModelClass(sf);\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosDependency\",\n decoratorArgsText: `{ ${argsParts.join(\", \")} }`,\n type: options.dependencyType,\n scope: \"private\",\n hasExclamation: true,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosChild` property (owned sub-model enrollment) to an\n * existing model. Enrolls the child(ren) into the parent's model graph, lifecycle\n * cascade, and context scope-chain (a key the parent sets on its context bean resolves\n * down the whole subtree — see kos://guide/model-context). Three shapes:\n * single → `@kosChild private {prop}!: {Child};`\n * container → `@kosChild private {prop} = new KosModelContainer<{Child}>();`\n * array → `@kosChild private {prop}: {Child}[] = [];`\n *\n * When `childPackage` is given (the SDK/package that owns the child model — exactly\n * what `describe_sdk_model` surfaces), the child type is imported from it; without it,\n * importing the child type stays the caller's responsibility (the mutator can't guess\n * its origin). `KosModelContainer` (container shape) always imports from the SDK.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedProperty,\n} from \"../augment/ts-toolkit\";\n\nexport type ChildShape = \"single\" | \"container\" | \"array\";\n\nexport interface AddChildOptions {\n modelName: string;\n modelProject: string;\n /** Property name that holds the child(ren), e.g. `pages`, `pump`, `sensors`. */\n propertyName: string;\n /** Child model TS type, e.g. `PageModel`. */\n childType: string;\n /** How the child(ren) are held. Default `single`. */\n shape?: ChildShape;\n /** Package that owns the child model; when set, its type is imported from the root. */\n childPackage?: string;\n modelPath?: string;\n}\n\n// Framework generics that come from the KOS SDK, not the child's own package — never\n// import these from `childPackage`.\nconst FRAMEWORK_TYPES = new Set([\"IKosDataModel\", \"IKosIdentifiable\"]);\n\nexport function addChildToModel(\n codegenFs: CodegenFileSystem,\n options: AddChildOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const shape: ChildShape = options.shape ?? \"single\";\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosChild \"${options.propertyName}\" (${shape}) to ${options.modelName}`\n );\n\n const childType = options.childType?.trim();\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n const sdkImports: { name: string; isTypeOnly?: boolean }[] = [\n { name: \"kosChild\" },\n ];\n // The container shape uses KosModelContainer as a VALUE (`new …`) — import it.\n if (shape === \"container\") sdkImports.push({ name: \"KosModelContainer\" });\n ensureNamedImport(sf, sdk, sdkImports);\n\n // Import the child model type from its owning package when known. In every shape\n // the child type appears only in TYPE position (annotation or generic arg), so a\n // type-only import is correct.\n if (\n options.childPackage &&\n childType &&\n /^[A-Za-z_$][\\w$]*$/.test(childType) &&\n !FRAMEWORK_TYPES.has(childType)\n ) {\n ensureNamedImport(sf, options.childPackage, [\n { name: childType, isTypeOnly: true },\n ]);\n }\n\n const cls = getModelClass(sf);\n if (shape === \"container\") {\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosChild\",\n bare: true,\n initializer: `new KosModelContainer<${childType}>()`,\n scope: \"private\",\n });\n } else if (shape === \"array\") {\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosChild\",\n bare: true,\n type: `${childType}[]`,\n initializer: \"[]\",\n scope: \"private\",\n });\n } else {\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosChild\",\n bare: true,\n type: childType,\n scope: \"private\",\n hasExclamation: true,\n });\n }\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosTopicHandler` subscription method to an existing\n * model. Generates an idiomatic INIT/websocket handler skeleton. The `topic` and\n * event type are caller-supplied (the caller ensures the topic constant is defined).\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedMethod,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddTopicHandlerOptions {\n modelName: string;\n modelProject: string;\n /** Handler method name, e.g. `handleBoardLinked`. */\n handlerName: string;\n /** Topic expression — a constant ref (e.g. `TOPIC_BOARD_LINKED`) or string literal. */\n topic: string;\n /** Event payload TS type for the handler parameter. Default `unknown`. */\n eventType?: string;\n /** Subscribe over websocket. Default true. */\n websocket?: boolean;\n modelPath?: string;\n}\n\nexport function addTopicHandlerToModel(\n codegenFs: CodegenFileSystem,\n options: AddTopicHandlerOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosTopicHandler \"${options.handlerName}\" to ${options.modelName}`\n );\n\n const websocket = options.websocket ?? true;\n const eventType = options.eventType || \"unknown\";\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [\n { name: \"kosTopicHandler\" },\n { name: \"DependencyLifecycle\" },\n ]);\n const cls = getModelClass(sf);\n addDecoratedMethod(cls, {\n name: options.handlerName,\n decoratorName: \"kosTopicHandler\",\n decoratorArgsText: `{ lifecycle: DependencyLifecycle.INIT, topic: ${options.topic}, websocket: ${websocket} }`,\n parameters: [{ name: \"event\", type: eventType }],\n statements: \"// TODO: handle the topic event\",\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosConfigProperty` reactive config-bound property to an\n * existing model. The `path` (config path ref/literal) and `attribute` are caller\n * supplied; the value is exposed as `KosConfigProperty<T>`.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedProperty,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddConfigPropertyOptions {\n modelName: string;\n modelProject: string;\n /** Property name to hold the config value, e.g. `remoteTrayEnabled`. */\n propertyName: string;\n /** Config path expression — a constant ref (e.g. `PROP_CONFIG_PATH`) or string literal. */\n path: string;\n /** Config attribute name, e.g. `enabled` or `settings.volWithoutIceMl`. */\n attribute: string;\n /** Value TS type inside `KosConfigProperty<…>`. Default `unknown`. */\n valueType?: string;\n modelPath?: string;\n}\n\nexport function addConfigPropertyToModel(\n codegenFs: CodegenFileSystem,\n options: AddConfigPropertyOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding @kosConfigProperty \"${options.propertyName}\" to ${options.modelName}`\n );\n\n const valueType = options.valueType || \"unknown\";\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const sdk = resolveSdkModuleSpecifier(sf);\n ensureNamedImport(sf, sdk, [\n { name: \"kosConfigProperty\" },\n { name: \"KosConfigProperty\", isTypeOnly: true },\n ]);\n const cls = getModelClass(sf);\n addDecoratedProperty(cls, {\n name: options.propertyName,\n decoratorName: \"kosConfigProperty\",\n decoratorArgsText: `{ path: ${options.path}, attribute: ${JSON.stringify(\n options.attribute\n )} }`,\n type: `KosConfigProperty<${valueType}>`,\n hasExclamation: true,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a basic (plain) typed property to an existing model —\n * just a TypeScript field like `prop1: string`. This is local model state, NOT a\n * device-config-bound reactive value (that's `addConfigPropertyToModel`) nor a\n * cross-model reference (`addDependencyToModel`). Use for simple state the model\n * holds and sets itself.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n getModelClass,\n addPlainProperty,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddPropertyOptions {\n modelName: string;\n modelProject: string;\n /** Property name, e.g. `prop1`. */\n propertyName: string;\n /** TS type of the field, e.g. `string`, `number`, `boolean`. Default `string`. */\n type?: string;\n /** Optional initializer expression (e.g. `\"\"`, `0`, `false`). */\n initializer?: string;\n /** Mark the field `readonly`. */\n readonly?: boolean;\n modelPath?: string;\n}\n\n/** Sensible default initializer per primitive so the field compiles under strict mode. */\nfunction defaultInitializer(type: string): string | undefined {\n switch (type) {\n case \"string\":\n return '\"\"';\n case \"number\":\n return \"0\";\n case \"boolean\":\n return \"false\";\n default:\n return undefined; // non-primitive → definite-assignment `!`\n }\n}\n\nexport function addPropertyToModel(\n codegenFs: CodegenFileSystem,\n options: AddPropertyOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n const type = options.type || \"string\";\n // Caller initializer wins; else a primitive default; else definite-assignment.\n const initializer =\n options.initializer !== undefined\n ? options.initializer\n : defaultInitializer(type);\n\n logger.info(\n `Adding property \"${options.propertyName}: ${type}\" to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const cls = getModelClass(sf);\n addPlainProperty(cls, {\n name: options.propertyName,\n type,\n initializer,\n readonly: options.readonly,\n hasExclamation: initializer === undefined,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a COMPUTED member to a model — a read-only getter\n * (`get name(): T { ... }`) that derives its value from other model state. Distinct\n * from a stored field (`addPropertyToModel`): a computed member holds no state, it\n * recomputes on access.\n */\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n transformSourceFile,\n getModelClass,\n addGetter,\n} from \"../augment/ts-toolkit\";\n\nexport interface AddComputedOptions {\n modelName: string;\n modelProject: string;\n /** Getter name, e.g. `displayName`. */\n name: string;\n /** Return TS type, e.g. `string`. Default inferred (omitted). */\n returnType?: string;\n /** Body statements; default a TODO stub. */\n body?: string;\n modelPath?: string;\n}\n\nexport function addComputedToModel(\n codegenFs: CodegenFileSystem,\n options: AddComputedOptions,\n projects?: Map<string, ProjectConfiguration>\n): { modelFilePath: string } {\n const logger = getCodegenLogger();\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n logger.info(\n `Adding computed getter \"${options.name}\" to ${options.modelName}`\n );\n\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n const cls = getModelClass(sf);\n addGetter(cls, {\n name: options.name,\n returnType: options.returnType,\n statements: options.body,\n });\n });\n\n return { modelFilePath };\n}\n","/**\n * Capability mutator: add a `@kosServiceRequest` method to an existing model.\n *\n * Uses the TYPED decorator generated by `api:generate` (imported from the project's\n * `…/utils/services/<app>/<version>/service.ts`), so `path` is validated against the\n * OpenAPI-derived `openapi.d.ts` at compile time. Purely mechanical: device query,\n * path discovery, and live-spec validation are a separate discovery orchestration.\n *\n * WHERE THE DESCRIPTOR LIVES: the endpoint catalog and the types derived from it\n * belong to the model's own `services/` module, alongside the standalone service\n * functions that serve callers outside a model context. The model file only\n * IMPORTS from there — it declares no paths of its own, so data-transfer concerns\n * stay in one place and one path is described once however many methods use it.\n * The catalog is keyed by handler name but matched by (path, method): a second\n * method on an endpoint already in the catalog reuses that entry.\n *\n * Emits ONE OF TWO SHAPES, because @kosServiceRequest has two, and they are not\n * interchangeable:\n *\n * lifecycle — the framework performs the request during the phase and calls the\n * method back error-first as `(error, data)`. No execution context exists.\n * method — the method performs the request when called, through the `$ctx`\n * the decorator injects as the last parameter.\n *\n * The decorator itself decides by the presence of `lifecycle` (it only wraps the\n * handler to inject `$ctx` when `lifecycle` is absent), so this mutator derives\n * the mode the same way rather than defaulting to one of them.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { getCodegenLogger } from \"../../logger\";\nimport { pascalCase } from \"../../name-utils\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\nimport {\n ensureServicesModule,\n modelBaseName,\n servicesFilePathFor,\n} from \"../augment/model-services\";\nimport {\n transformSourceFile,\n readSourceFile,\n ensureNamedImport,\n resolveSdkModuleSpecifier,\n getModelClass,\n addDecoratedMethod,\n addClassDecorator,\n ensureDeclarationMerge,\n ensureFileEslintDisable,\n ensureConstCatalogEntry,\n ensureExportedTypeAlias,\n ensureExportedMapper,\n} from \"../augment/ts-toolkit\";\n\nexport type ServiceRequestMode = \"lifecycle\" | \"method\";\n\nexport interface AddServiceRequestOptions {\n modelName: string;\n modelProject: string;\n /** Handler method name, e.g. `onDataLoaded`. */\n methodName: string;\n /** OpenAPI path string, validated by the generated types, e.g. `/api/board/{id}`. */\n servicePath: string;\n /** HTTP method. Default `get`. */\n method?: string;\n /**\n * Which form to emit. Defaults to `lifecycle` when `lifecycle` is supplied and\n * `method` otherwise — the same rule @kosServiceRequest applies at runtime.\n */\n mode?: ServiceRequestMode;\n /**\n * DependencyLifecycle member name (LOAD, INIT, …). Only meaningful in\n * `lifecycle` mode; defaults to `LOAD` there.\n */\n lifecycle?: string;\n /** Import specifier for the generated typed service module (relative to the model\n * file). If omitted, auto-resolved when the project has exactly one. */\n serviceModule?: string;\n /**\n * Root-relative path of the service module, as `listServiceCatalog` reports\n * it. Converted to an import specifier here, so a caller that picked an\n * operation from the catalog does not have to compute one — and does not trip\n * the \"multiple service modules\" error when a project types several versions.\n */\n serviceModulePath?: string;\n modelPath?: string;\n}\n\nexport interface AddServiceRequestResult {\n modelFilePath: string;\n /** The model's services module the descriptor was written to. */\n servicesFilePath: string;\n serviceModule: string;\n mode: ServiceRequestMode;\n /** Catalog entry the method points at — reused when the endpoint was known. */\n endpointKey: string;\n /** False when an existing catalog entry for this (path, method) was reused. */\n endpointCreated: boolean;\n}\n\nconst SERVICE_MODULE_RE = /\\/utils\\/services\\/.*\\/service\\.ts$/;\n\n/** Find generated service modules under the project source root (root-relative paths). */\nfunction findServiceModules(\n codegenFs: CodegenFileSystem,\n sourceRoot: string\n): string[] {\n return codegenFs\n .listFiles(sourceRoot)\n .filter((f) => SERVICE_MODULE_RE.test(f.split(path.sep).join(\"/\")));\n}\n\n/** Build a relative import specifier (posix, no extension) from one file to another. */\nfunction toImportSpecifier(fromFile: string, toFileNoExt: string): string {\n let rel = path\n .relative(path.dirname(fromFile), toFileNoExt)\n .split(path.sep)\n .join(\"/\");\n if (!rel.startsWith(\".\")) rel = `./${rel}`;\n return rel;\n}\n\n/** Resolve a specifier stated relative to one file into a root-relative path. */\nfunction fromImportSpecifier(fromFile: string, specifier: string): string {\n return path.join(path.dirname(fromFile), specifier);\n}\n\n/**\n * The emitted method passes a transformed type to `EndpointCtx` and to\n * `serviceRequest`, which only the current `api:generate` output declares. A\n * module generated before that would accept the code and then fail to compile,\n * so refuse up front rather than write something that cannot build.\n *\n * A module that does not declare `EndpointCtx` at all is left alone — that is a\n * shape this check does not claim to understand.\n */\nfunction assertServiceModuleAcceptsTransform(\n codegenFs: CodegenFileSystem,\n serviceModuleFile: string,\n modelProject: string\n): void {\n const file = `${serviceModuleFile}.ts`;\n if (!codegenFs.exists(file)) return;\n\n const typeParams = readSourceFile(codegenFs, file, (sf) => {\n const alias = sf.getTypeAlias(\"EndpointCtx\");\n return alias ? alias.getTypeParameters().length : null;\n });\n if (typeParams === null || typeParams >= 2) return;\n\n throw new Error(\n `${file} predates the transform-aware service layer (EndpointCtx takes ${typeParams} type parameter). ` +\n `Run \\`kosui api:generate --project ${modelProject} --helpers-only\\` to refresh the helper layer ` +\n `in place (no spec fetch, openapi.d.ts untouched), then add the service request.`\n );\n}\n\n/**\n * The two `endpoint(...)` initializers describe the same endpoint when their\n * path and method arguments match. Compared as parsed literals rather than as\n * text so quote style and spacing in a hand-edited catalog do not defeat reuse.\n */\nfunction sameEndpoint(existing: string, candidate: string): boolean {\n const args = (text: string) => {\n const match = text.match(\n /^endpoint\\s*\\(\\s*(['\"])(.*?)\\1\\s*,\\s*(['\"])(.*?)\\3\\s*,?\\s*\\)$/\n );\n return match ? [match[2], match[4].toLowerCase()] : null;\n };\n const a = args(existing.trim());\n const b = args(candidate.trim());\n return !!a && !!b && a[0] === b[0] && a[1] === b[1];\n}\n\nexport function addServiceRequestToModel(\n codegenFs: CodegenFileSystem,\n options: AddServiceRequestOptions,\n projects?: Map<string, ProjectConfiguration>\n): AddServiceRequestResult {\n const logger = getCodegenLogger();\n const { modelFilePath, sourceRoot } = resolveModelFilePath(\n codegenFs,\n options,\n projects\n );\n if (!codegenFs.exists(modelFilePath)) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n // Resolve the generated service module as a ROOT-RELATIVE path first: the\n // model and the services module sit at different depths, so each needs its own\n // specifier and neither can be derived from the other's.\n let serviceModuleFile: string | undefined;\n if (options.serviceModulePath) {\n serviceModuleFile = options.serviceModulePath.replace(/\\.ts$/, \"\");\n } else if (options.serviceModule) {\n serviceModuleFile = fromImportSpecifier(\n modelFilePath,\n options.serviceModule\n );\n } else {\n if (!sourceRoot) {\n throw new Error(\n \"Cannot auto-resolve the service module without a project source root. Pass serviceModule.\"\n );\n }\n const modules = findServiceModules(codegenFs, sourceRoot);\n if (modules.length === 0) {\n throw new Error(\n \"No generated service module found. Run `kosui api:generate` for this project first.\"\n );\n }\n if (modules.length > 1) {\n const specifiers = modules.map((m) =>\n toImportSpecifier(modelFilePath, m.replace(/\\.ts$/, \"\"))\n );\n throw new Error(\n `Multiple service modules found — pass serviceModule (one of): ${specifiers.join(\n \", \"\n )}`\n );\n }\n serviceModuleFile = modules[0].replace(/\\.ts$/, \"\");\n }\n\n assertServiceModuleAcceptsTransform(\n codegenFs,\n serviceModuleFile,\n options.modelProject\n );\n\n const modelBase = modelBaseName(modelFilePath, options.modelName);\n const servicesFilePath = servicesFilePathFor(modelFilePath, modelBase);\n\n const serviceImportFromModel = toImportSpecifier(\n modelFilePath,\n serviceModuleFile\n );\n const serviceImportFromServices = toImportSpecifier(\n servicesFilePath,\n serviceModuleFile\n );\n\n const method = (options.method || \"get\").toLowerCase();\n const mode: ServiceRequestMode =\n options.mode ?? (options.lifecycle ? \"lifecycle\" : \"method\");\n const lifecycle = options.lifecycle || \"LOAD\";\n const catalogName = `${pascalCase(modelBase)}Endpoints`;\n\n logger.info(\n `Adding ${mode}-driven @kosServiceRequest \"${options.methodName}\" (${method} ${options.servicePath}) to ${options.modelName}`\n );\n\n // ---- the model's services module: the endpoint and the types from it ----\n ensureServicesModule(codegenFs, modelFilePath, modelBase);\n\n let endpointKey = options.methodName;\n let endpointCreated = true;\n // Everything the endpoint implies — its normalized shape, the mapper that\n // normalizes it, and the context type carrying that shape — belongs to the\n // ENDPOINT, not to whichever method happens to call it. Normalization is a\n // property of the service response, so a second method on the same endpoint\n // shares all three rather than declaring a parallel set that could drift.\n // These are keyed off the resolved catalog entry, so they are filled in once\n // it is known.\n let dataAlias = \"\";\n let mapperName = \"\";\n let ctxAlias = \"\";\n\n transformSourceFile(codegenFs, servicesFilePath, (sf) => {\n ensureNamedImport(sf, serviceImportFromServices, [{ name: \"endpoint\" }]);\n\n const entry = ensureConstCatalogEntry(sf, {\n catalogName,\n key: options.methodName,\n initializer: `endpoint(${JSON.stringify(\n options.servicePath\n )}, ${JSON.stringify(method)})`,\n equals: sameEndpoint,\n });\n endpointKey = entry.key;\n endpointCreated = entry.created;\n dataAlias = `${pascalCase(endpointKey)}Data`;\n mapperName = `to${pascalCase(endpointKey)}Data`;\n ctxAlias = `${pascalCase(endpointKey)}Ctx`;\n\n // Everything below reads the path back through `typeof`, so no type can\n // drift from the descriptor even though each is declared separately.\n const rawType = `EndpointResponse<typeof ${catalogName}.${endpointKey}>`;\n ensureNamedImport(sf, serviceImportFromServices, [\n { name: \"EndpointResponse\", isTypeOnly: true },\n ]);\n\n // The mapper is where the response stops being the wire shape and starts\n // being the model's. It is emitted as an identity so the project compiles\n // untouched; narrowing the data type is what turns it into a real boundary,\n // and the compiler then walks the author through filling it in.\n ensureExportedTypeAlias(sf, { name: dataAlias, type: rawType });\n ensureExportedMapper(sf, {\n name: mapperName,\n rawType,\n dataType: dataAlias,\n });\n\n if (mode === \"method\") {\n ensureNamedImport(sf, serviceImportFromServices, [\n { name: \"EndpointCtx\", isTypeOnly: true },\n ]);\n ensureExportedTypeAlias(sf, {\n name: ctxAlias,\n type: `EndpointCtx<typeof ${catalogName}.${endpointKey}, ${dataAlias}>`,\n });\n }\n });\n\n // ---- the model: imports and the decorated method, nothing declared ----\n transformSourceFile(codegenFs, modelFilePath, (sf) => {\n // EVERY file-level write below (eslint pragma, imports, the merged\n // interface) re-writes the file text, which makes ts-morph forget nodes\n // captured before it. So all of them happen first, and the class is looked\n // up only once nothing else will move underneath it.\n const className = getModelClass(sf).getName();\n if (!className) throw new Error(\"Model class has no name.\");\n const typeParams = getModelClass(sf)\n .getTypeParameters()\n .map((tp) => tp.getText());\n\n ensureNamedImport(sf, serviceImportFromModel, [{ name: \"serviceRequest\" }]);\n\n if (mode === \"lifecycle\") {\n ensureNamedImport(sf, \"./services\", [\n { name: catalogName },\n { name: mapperName },\n { name: dataAlias, isTypeOnly: true },\n ]);\n ensureNamedImport(sf, resolveSdkModuleSpecifier(sf), [\n { name: \"DependencyLifecycle\" },\n ]);\n addDecoratedMethod(getModelClass(sf), {\n name: options.methodName,\n decoratorName: \"serviceRequest\",\n decoratorArgsText: `${catalogName}.${endpointKey}, { lifecycle: DependencyLifecycle.${lifecycle}, transform: ${mapperName} }`,\n // The manager invokes phase handlers error-first, passing (null, data)\n // on success. The `error` half is only ever reached because\n // `serviceRequest` supplies an errorHandler — the bare decorator\n // defaults to `throw`, which fails the phase instead of calling back.\n parameters: [\n { name: \"error\", type: \"string | null\" },\n { name: \"data\", type: dataAlias },\n ],\n returnType: \"void\",\n statements: \"// TODO: apply `data` to the model\",\n });\n return;\n }\n\n ensureNamedImport(sf, \"./services\", [\n { name: catalogName },\n { name: mapperName },\n { name: ctxAlias, isTypeOnly: true },\n ]);\n ensureNamedImport(sf, resolveSdkModuleSpecifier(sf), [\n { name: \"executeServiceRequest\" },\n { name: \"kosLoggerAware\" },\n { name: \"KosLoggerAware\", isTypeOnly: true },\n ]);\n\n // executeServiceRequest reports failures through the model's logger, so the\n // model has to be logger-aware for the emitted call to compile at all.\n ensureFileEslintDisable(\n sf,\n \"@typescript-eslint/no-unsafe-declaration-merging\"\n );\n ensureDeclarationMerge(sf, className, \"KosLoggerAware\", typeParams);\n addClassDecorator(getModelClass(sf), \"kosLoggerAware\", { argsText: \"\" });\n\n addDecoratedMethod(getModelClass(sf), {\n name: options.methodName,\n decoratorName: \"serviceRequest\",\n decoratorArgsText: `${catalogName}.${endpointKey}, { transform: ${mapperName} }`,\n // Optional: the framework appends the context, callers never pass it.\n parameters: [{ name: \"$ctx\", type: ctxAlias, optional: true }],\n isAsync: true,\n returnType: \"Promise<void>\",\n statements: [\n \"const data = await executeServiceRequest(this, $ctx);\",\n \"if (!data) return;\",\n \"// TODO: apply `data` to the model\",\n ].join(\"\\n\"),\n });\n });\n\n return {\n modelFilePath,\n servicesFilePath,\n serviceModule: serviceImportFromModel,\n mode,\n endpointKey,\n endpointCreated,\n };\n}\n","/**\n * Read-only static validation of a KOS model against best-practice guardrails.\n * AST-based (ts-morph), high-signal / low-false-positive — a few reliable checks\n * beat many noisy ones. Mirrors the AGENTS.md guardrails + anti-patterns guide.\n */\nimport { Project } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\n\nexport interface ValidateModelOptions {\n modelName: string;\n modelProject: string;\n modelPath?: string;\n}\n\nexport interface ValidationFinding {\n level: \"error\" | \"warning\";\n rule: string;\n message: string;\n}\n\nexport interface ValidationResult {\n modelFilePath: string;\n ok: boolean; // no errors (warnings allowed)\n findings: ValidationFinding[];\n}\n\n/** Extract a `*Model`-named element type from a raw collection type, else null. */\nfunction modelElementType(typeText: string): string | null {\n let m: RegExpMatchArray | null;\n if ((m = typeText.match(/^([A-Za-z_]\\w*Model)\\s*\\[\\]$/))) return m[1];\n if ((m = typeText.match(/^Array<\\s*([A-Za-z_]\\w*Model)\\s*>$/))) return m[1];\n if ((m = typeText.match(/^(?:Map|Set)<[^>]*?\\b([A-Za-z_]\\w*Model)\\b[^>]*>$/)))\n return m[1];\n return null;\n}\n\nexport function validateModel(\n codegenFs: CodegenFileSystem,\n options: ValidateModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): ValidationResult {\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n const content = codegenFs.read(modelFilePath);\n if (content === null) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = project.createSourceFile(modelFilePath, content, {\n overwrite: true,\n });\n const findings: ValidationFinding[] = [];\n\n // 1. Must be a KOS model.\n const hasKosModel = sf.getClasses().some((c) => c.getDecorator(\"kosModel\"));\n if (!hasKosModel) {\n findings.push({\n level: \"error\",\n rule: \"missing-kosModel\",\n message: \"No @kosModel decorator found — this is not a KOS model.\",\n });\n }\n\n const imports = sf.getImportDeclarations();\n\n // 2. No direct MobX — reactivity is internal to KOS.\n const mobxImport = imports.find((d) =>\n /^mobx(-react-lite)?$/.test(d.getModuleSpecifierValue())\n );\n if (mobxImport) {\n findings.push({\n level: \"error\",\n rule: \"mobx-import\",\n message:\n \"Imports mobx directly. Reactivity is internal to KOS — remove the mobx import and use KOS reactivity / container models.\",\n });\n }\n\n // 3. Service requests should use the typed decorator from the api:generate'd\n // service module, not the untyped one from the SDK barrel.\n const barrelServiceRequest = imports.find(\n (d) =>\n d.getModuleSpecifierValue() === \"@kosdev-code/kos-ui-sdk\" &&\n d.getNamedImports().some((n) => n.getName() === \"kosServiceRequest\")\n );\n if (barrelServiceRequest) {\n findings.push({\n level: \"warning\",\n rule: \"untyped-service-request\",\n message:\n \"kosServiceRequest imported from the SDK barrel. Use the typed decorator from the api:generate'd service module so paths are validated against the OpenAPI types.\",\n });\n }\n\n // 4. Model collections should be KOS containers + enrolled as children.\n for (const cls of sf.getClasses()) {\n for (const prop of cls.getProperties()) {\n const name = prop.getName();\n const typeText = (prop.getTypeNode()?.getText() ?? \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n const initText = prop.getInitializer()?.getText() ?? \"\";\n const hasChild = !!prop.getDecorator(\"kosChild\");\n\n const isModelContainer =\n /\\bI?KosModelContainer\\s*</.test(typeText) ||\n /new\\s+KosModelContainer\\b/.test(initText);\n\n if (isModelContainer && !hasChild) {\n findings.push({\n level: \"warning\",\n rule: \"container-missing-kosChild\",\n message: `Property '${name}' is a model container but is not marked @kosChild — add @kosChild so its models join the model graph and lifecycle.`,\n });\n continue;\n }\n\n const elem = modelElementType(typeText);\n if (elem && !isModelContainer) {\n findings.push({\n level: \"warning\",\n rule: \"raw-model-collection\",\n message: `Property '${name}' is a raw ${typeText} of models — prefer a KosModelContainer<${elem}> (indexing, sorting, lifecycle, delta handling) marked @kosChild.`,\n });\n }\n }\n }\n\n const hasError = findings.some((f) => f.level === \"error\");\n return { modelFilePath, ok: !hasError, findings };\n}\n","/**\n * Read-only structural report of a KOS model. AST-based (ts-morph): surfaces the\n * model's type id, the @kos* decorators it carries, the capabilities already wired\n * (child collections, dependencies, topic handlers, config properties, service\n * requests, effects, futures), and whether it is itself a companion. Lets an agent\n * see what a model already has before deciding which mutator to apply — the\n * discovery counterpart to validate_model.\n */\nimport { Project, type ClassDeclaration } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { resolveModelFilePath } from \"../augment/resolve-model-file\";\n\nexport interface DescribeModelOptions {\n modelName: string;\n modelProject: string;\n modelPath?: string;\n}\n\n/** A decorated member (method or property) and the bare argument text of its decorator. */\nexport interface DescribedMember {\n name: string;\n /** First decorator argument as written, trimmed (e.g. the topic or config path). */\n arg?: string;\n /** Property/return type as written, when present. */\n type?: string;\n}\n\nexport interface ModelDescription {\n modelFilePath: string;\n /** Value of the MODEL_TYPE constant, if declared. */\n modelType?: string;\n /** The impl class name (e.g. BoardModelImpl). */\n className?: string;\n /** Class-level @kos* decorators in source order (e.g. kosModel, kosLoggerAware). */\n classDecorators: string[];\n singleton: boolean;\n /** True when the class carries @kosCompanion — it augments a parent model. */\n isCompanion: boolean;\n /** @kosChild collection/child properties. */\n children: DescribedMember[];\n /** @kosDependency cross-model references. */\n dependencies: DescribedMember[];\n /** @kosTopicHandler subscription methods. */\n topicHandlers: DescribedMember[];\n /** @kosConfigProperty reactive config-bound properties. */\n configProperties: DescribedMember[];\n /** @kosServiceRequest backend-call methods. */\n serviceRequests: DescribedMember[];\n /** @kosModelEffect reaction methods. */\n effects: DescribedMember[];\n /** @kosFuture long-running-operation methods. */\n futures: DescribedMember[];\n}\n\n/** First decorator argument as written, whitespace-collapsed to one line, if any. */\nfunction firstDecoratorArg(decoratorText: string): string | undefined {\n const open = decoratorText.indexOf(\"(\");\n if (open === -1) return undefined;\n const inner = decoratorText\n .slice(open + 1, decoratorText.lastIndexOf(\")\"))\n .replace(/\\s+/g, \" \")\n .trim();\n return inner || undefined;\n}\n\nfunction collectDecorated(\n cls: ClassDeclaration,\n decoratorName: string\n): DescribedMember[] {\n const members: DescribedMember[] = [];\n const visit = (\n name: string,\n decoratorTextOf: () => string | undefined,\n typeText?: string\n ) => {\n const text = decoratorTextOf();\n if (text === undefined) return;\n members.push({\n name,\n arg: firstDecoratorArg(text),\n type: typeText || undefined,\n });\n };\n for (const m of cls.getMethods()) {\n const dec = m.getDecorator(decoratorName);\n if (dec) {\n visit(m.getName(), () => dec.getText(), m.getReturnTypeNode()?.getText());\n }\n }\n for (const p of cls.getProperties()) {\n const dec = p.getDecorator(decoratorName);\n if (dec) {\n visit(p.getName(), () => dec.getText(), p.getTypeNode()?.getText());\n }\n }\n return members;\n}\n\nexport function describeModel(\n codegenFs: CodegenFileSystem,\n options: DescribeModelOptions,\n projects?: Map<string, ProjectConfiguration>\n): ModelDescription {\n const { modelFilePath } = resolveModelFilePath(codegenFs, options, projects);\n const content = codegenFs.read(modelFilePath);\n if (content === null) {\n throw new Error(`Model file not found: ${modelFilePath}`);\n }\n\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = project.createSourceFile(modelFilePath, content, {\n overwrite: true,\n });\n\n // MODEL_TYPE = \"...\" (the runtime model-type id).\n let modelType: string | undefined;\n const modelTypeDecl = sf.getVariableDeclaration(\"MODEL_TYPE\");\n if (modelTypeDecl) {\n const init = modelTypeDecl.getInitializer()?.getText();\n if (init) modelType = init.replace(/^[\"'`]|[\"'`]$/g, \"\");\n }\n\n // The model impl class is the one carrying @kosModel.\n const cls =\n sf.getClasses().find((c) => c.getDecorator(\"kosModel\")) ??\n sf.getClasses().find((c) => c.isExported()) ??\n sf.getClasses()[0];\n\n if (!cls) {\n return {\n modelFilePath,\n modelType,\n classDecorators: [],\n singleton: false,\n isCompanion: false,\n children: [],\n dependencies: [],\n topicHandlers: [],\n configProperties: [],\n serviceRequests: [],\n effects: [],\n futures: [],\n };\n }\n\n const classDecorators = cls.getDecorators().map((d) => d.getName());\n const kosModelArg = cls.getDecorator(\"kosModel\")\n ? firstDecoratorArg(cls.getDecorator(\"kosModel\")!.getText())\n : undefined;\n const singleton = /\\bsingleton\\s*:\\s*true\\b/.test(kosModelArg ?? \"\");\n\n return {\n modelFilePath,\n modelType,\n className: cls.getName(),\n classDecorators,\n singleton,\n isCompanion: classDecorators.includes(\"kosCompanion\"),\n children: collectDecorated(cls, \"kosChild\"),\n dependencies: collectDecorated(cls, \"kosDependency\"),\n topicHandlers: collectDecorated(cls, \"kosTopicHandler\"),\n configProperties: collectDecorated(cls, \"kosConfigProperty\"),\n serviceRequests: collectDecorated(cls, \"kosServiceRequest\"),\n effects: collectDecorated(cls, \"kosModelEffect\"),\n futures: collectDecorated(cls, \"kosFuture\"),\n };\n}\n","/**\n * Resolve an exported SDK symbol to its signature, so an agent (especially a\n * consumer building models) never hallucinates a type's shape. AST-based\n * (ts-morph); confined here in codegen-core, never a runtime SDK dep.\n *\n * Graceful resolution, in priority order:\n * 1. Monorepo SOURCE — the SDK project's `src/index.ts` (source of truth).\n * 2. Installed DECLARATIONS — `node_modules/<pkg>` `exports[\".\"].*.types` /\n * `types` entry (a consumer workspace only has this built `.d.ts`).\n * 3. Neither present → a clear \"not resolvable\" result (no throw).\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Project, Node, type ExportedDeclarations } from \"ts-morph\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../project-discovery\";\n\nconst DEFAULT_SDK_PACKAGE = \"@kosdev-code/kos-ui-sdk\";\nconst MAX_SIGNATURE_CHARS = 2000;\n\nexport interface LookupSdkTypeOptions {\n symbol: string;\n /** SDK package name. Default @kosdev-code/kos-ui-sdk. */\n sdkPackage?: string;\n /** Explicit entry file (absolute or workspace-relative), overriding resolution. */\n entryFile?: string;\n}\n\nexport interface SdkSymbolDeclaration {\n kind: string;\n /** Declaring file, workspace-relative when under root. */\n file: string;\n /** Signature text (bodies stripped, length-capped). */\n signature: string;\n}\n\nexport interface SdkTypeLookupResult {\n symbol: string;\n resolved: boolean;\n /** Which surface answered: the SDK source tree or the installed declarations. */\n mode?: \"source\" | \"declarations\";\n entryFile?: string;\n declarations: SdkSymbolDeclaration[];\n /** Set when not resolved (or partially) — explains what was tried. */\n message?: string;\n triedEntries: string[];\n}\n\n/** Read a package's TS-declaration entry from its package.json exports/types. */\nfunction declarationEntryFromPackageJson(pkgDir: string): string | undefined {\n const pkgJsonPath = path.join(pkgDir, \"package.json\");\n if (!fs.existsSync(pkgJsonPath)) return undefined;\n let pkg: any;\n try {\n pkg = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf-8\"));\n } catch {\n return undefined;\n }\n const candidates: Array<string | undefined> = [\n pkg.exports?.[\".\"]?.import?.types,\n pkg.exports?.[\".\"]?.require?.types,\n pkg.exports?.[\".\"]?.types,\n pkg.types,\n pkg.typings,\n ];\n for (const rel of candidates) {\n if (typeof rel === \"string\") {\n const abs = path.join(pkgDir, rel);\n if (fs.existsSync(abs)) return abs;\n }\n }\n return undefined;\n}\n\n/** Build the ordered list of candidate entry files (absolute paths). */\nfunction resolveCandidateEntries(\n codegenFs: CodegenFileSystem,\n options: LookupSdkTypeOptions,\n projects?: Map<string, ProjectConfiguration>\n): Array<{ file: string; mode: \"source\" | \"declarations\" }> {\n const root = codegenFs.root;\n const sdkPackage = options.sdkPackage || DEFAULT_SDK_PACKAGE;\n const out: Array<{ file: string; mode: \"source\" | \"declarations\" }> = [];\n\n if (options.entryFile) {\n const abs = path.isAbsolute(options.entryFile)\n ? options.entryFile\n : path.join(root, options.entryFile);\n out.push({\n file: abs,\n mode: abs.endsWith(\".d.ts\") ? \"declarations\" : \"source\",\n });\n }\n\n // 1. Monorepo source — the SDK project's src/index.ts.\n const sdkProject = findProjectByName(root, sdkPackage, projects);\n const sourceRoot = sdkProject\n ? sdkProject.sourceRoot || path.join(sdkProject.root, \"src\")\n : undefined;\n for (const srcDir of [\n sourceRoot && path.join(root, sourceRoot),\n path.join(root, \"packages\", \"kos-ui-sdk\", \"src\"),\n ]) {\n if (!srcDir) continue;\n const entry = path.join(srcDir, \"index.ts\");\n if (fs.existsSync(entry) && !out.some((c) => c.file === entry)) {\n out.push({ file: entry, mode: \"source\" });\n }\n }\n\n // 2. Installed declarations — node_modules/<pkg> types entry.\n const dts = declarationEntryFromPackageJson(\n path.join(root, \"node_modules\", ...sdkPackage.split(\"/\"))\n );\n if (dts && !out.some((c) => c.file === dts)) {\n out.push({ file: dts, mode: \"declarations\" });\n }\n\n return out;\n}\n\n/**\n * Render an object-like type as a member list via the type checker. KOS model\n * interfaces are utility-wrapped aliases — e.g. `type KosTimeModel =\n * PublicModelInterface<KosTimeModelImpl>` — so the verbatim declaration text is\n * just the unevaluated alias and carries NO members. Resolving the type expands\n * the projection (public members, private/@internal already stripped by\n * `PublicModelInterface<T>`) into the real surface: `timezone`,\n * `updateSystemTimezone(...)`, etc. Returns undefined for non-object types\n * (unions, primitives, generics with unresolved params) so the caller falls back\n * to the literal text, which is clearer for those.\n */\nfunction renderTypeMembers(\n decl: ExportedDeclarations & { getType: () => import(\"ts-morph\").Type }\n): string | undefined {\n const props = decl.getType().getProperties();\n if (props.length === 0) return undefined;\n const lines: string[] = [];\n for (const p of props) {\n const at = p.getDeclarations()[0] ?? decl;\n let pt: string;\n try {\n pt = p.getTypeAtLocation(at).getText(at);\n } catch {\n pt = \"unknown\";\n }\n lines.push(` ${p.getName()}: ${pt};`);\n }\n return lines.join(\"\\n\");\n}\n\n/** Strip method/function bodies and length-cap a declaration's text. */\nfunction signatureText(decl: ExportedDeclarations): string {\n let text: string;\n if (Node.isTypeAliasDeclaration(decl) || Node.isInterfaceDeclaration(decl)) {\n // Resolve to members so utility-wrapped model interfaces yield their real\n // shape in ONE lookup (no jump from the bean to the model alias to the impl).\n const members = renderTypeMembers(decl);\n if (members) {\n const name = decl.getName();\n const tps = decl.getTypeParameters().map((t) => t.getText());\n const head = tps.length ? `${name}<${tps.join(\", \")}>` : name;\n const kw = Node.isInterfaceDeclaration(decl) ? \"interface\" : \"type\";\n const open = Node.isInterfaceDeclaration(decl) ? \" {\" : \" = {\";\n text = `${kw} ${head}${open}\\n${members}\\n}`;\n } else {\n text = decl.getText();\n }\n } else if (Node.isEnumDeclaration(decl)) {\n text = decl.getText();\n } else if (Node.isVariableDeclaration(decl)) {\n // Avoid dumping a large initializer — show the inferred type instead.\n const name = decl.getName();\n const typeText = decl.getType().getText(decl);\n text = `const ${name}: ${typeText}`;\n } else if (Node.isFunctionDeclaration(decl)) {\n if (decl.getBody()) decl.removeBody();\n text = decl.getText();\n } else if (Node.isClassDeclaration(decl)) {\n // Show the PUBLIC surface — drop private/protected members so the useful\n // public API fits the cap, and strip method/constructor bodies.\n const isHidden = (member: { getScope?: () => string }): boolean =>\n typeof member.getScope === \"function\" && member.getScope() !== \"public\";\n for (const p of decl.getProperties()) if (isHidden(p)) p.remove();\n for (const a of [...decl.getGetAccessors(), ...decl.getSetAccessors()]) {\n if (isHidden(a)) a.remove();\n }\n for (const m of decl.getMethods()) {\n if (isHidden(m)) {\n m.remove();\n continue;\n }\n if (m.getBody()) m.removeBody();\n }\n for (const c of decl.getConstructors()) {\n if (c.getBody()) c.removeBody();\n }\n text = decl.getText();\n } else {\n text = decl.getText();\n }\n text = text.replace(/\\s+$/, \"\");\n if (text.length > MAX_SIGNATURE_CHARS) {\n text = text.slice(0, MAX_SIGNATURE_CHARS) + \"\\n/* … truncated */\";\n }\n return text;\n}\n\nexport function lookupSdkType(\n codegenFs: CodegenFileSystem,\n options: LookupSdkTypeOptions,\n projects?: Map<string, ProjectConfiguration>\n): SdkTypeLookupResult {\n const symbol = options.symbol;\n const candidates = resolveCandidateEntries(codegenFs, options, projects);\n const triedEntries = candidates.map((c) =>\n path.relative(codegenFs.root, c.file)\n );\n\n if (candidates.length === 0) {\n return {\n symbol,\n resolved: false,\n declarations: [],\n triedEntries,\n message:\n \"No SDK entry found — neither the SDK source (packages/kos-ui-sdk/src/index.ts) nor an installed declaration file (node_modules/@kosdev-code/kos-ui-sdk) is present. Build or install the SDK, or pass entryFile.\",\n };\n }\n\n const project = new Project({\n skipAddingFilesFromTsConfig: true,\n compilerOptions: { allowJs: false, skipLibCheck: true },\n });\n\n for (const candidate of candidates) {\n let sf;\n try {\n sf = project.addSourceFileAtPath(candidate.file);\n } catch {\n continue;\n }\n let exported: ReadonlyMap<string, ExportedDeclarations[]>;\n try {\n exported = sf.getExportedDeclarations();\n } catch {\n continue;\n }\n const decls = exported.get(symbol);\n if (!decls || decls.length === 0) continue;\n\n return {\n symbol,\n resolved: true,\n mode: candidate.mode,\n entryFile: path.relative(codegenFs.root, candidate.file),\n triedEntries,\n declarations: decls.map((d) => {\n return {\n kind: d.getKindName(),\n file: path.relative(codegenFs.root, d.getSourceFile().getFilePath()),\n signature: signatureText(d),\n };\n }),\n };\n }\n\n return {\n symbol,\n resolved: false,\n declarations: [],\n triedEntries,\n message: `Symbol '${symbol}' is not an export of the SDK entry (${triedEntries.join(\n \", \"\n )}). Check the name, or it may be internal / not part of the public surface.`,\n };\n}\n","/**\n * Type definitions for KOS Component Generator\n */\n\n// Plugin type constants\nexport const PLUGIN_TYPES = {\n CUI: \"cui\",\n UTILITY: \"utility\",\n TROUBLE_ACTION: \"troubleAction\",\n SETUP: \"setup\",\n SETTING: \"setting\",\n NAV: \"nav\",\n CONTROL_POUR: \"controlPour\",\n CUSTOM: \"custom\",\n} as const;\n\nexport type PluginType = (typeof PLUGIN_TYPES)[keyof typeof PLUGIN_TYPES];\n\n// Contribution type mapping\nexport const CONTRIBUTION_TYPE_MAP: Record<string, string> = {\n [PLUGIN_TYPES.SETUP]: \"setup\",\n [PLUGIN_TYPES.CUI]: \"cui\",\n [PLUGIN_TYPES.UTILITY]: \"utility\",\n [PLUGIN_TYPES.SETTING]: \"setting\",\n [PLUGIN_TYPES.NAV]: \"nav\",\n [PLUGIN_TYPES.TROUBLE_ACTION]: \"trouble-action\",\n [PLUGIN_TYPES.CONTROL_POUR]: \"control-pour\",\n [PLUGIN_TYPES.CUSTOM]: \"custom\",\n};\n\n// Plugin types that require localization\nexport const LOCALIZED_PLUGIN_TYPES: ReadonlySet<string> = new Set([\n PLUGIN_TYPES.CUI,\n PLUGIN_TYPES.UTILITY,\n PLUGIN_TYPES.SETUP,\n PLUGIN_TYPES.SETTING,\n PLUGIN_TYPES.NAV,\n PLUGIN_TYPES.CONTROL_POUR,\n PLUGIN_TYPES.TROUBLE_ACTION,\n PLUGIN_TYPES.CUSTOM,\n]);\n\n// Configuration interfaces\nexport interface ExperienceConfig {\n id: string;\n component: string;\n location: string;\n}\n\nexport interface PluginContribution {\n id: string;\n title: string;\n namespace: string;\n experienceId?: string;\n [key: string]: any; // Allow plugin-specific properties\n}\n\nexport interface PluginConfiguration {\n contributions: Record<string, PluginContribution[]>;\n experiences: Record<string, ExperienceConfig>;\n views?: Record<string, any[]>;\n}\n\nexport interface NormalizedComponentOptions {\n name: string;\n nameDashCase: string;\n nameCamelCase: string;\n namePascalCase: string;\n nameLowerCase: string;\n appProject: string;\n group?: string;\n pluginType?: string;\n type: string;\n appDirectory: string;\n useEmotionCss?: boolean;\n contributionKey?: string; // User-specified contribution key for custom plugins\n}\n\n// Component generator input options\nexport interface ComponentOptions {\n name: string;\n type: \"components\" | \"features\";\n useEmotionCss: boolean;\n appProject: string;\n appDirectory: string;\n modelDirectory: string;\n group?: string;\n pluginType?: string;\n contributionKey?: string;\n registrationProject?: string;\n skipRegistration?: boolean;\n companion?: boolean;\n companionModel?: string;\n companionModelProject?: string;\n companionPattern?: \"composition\" | \"decorator\";\n}\n\n// JSON path constants for .kos.json structure\nexport const KOS_JSON_PATHS = {\n PLUGIN_ROOT: \"kosdev.ddk.ncui.plugin\",\n CONTRIBUTES: \"kosdev.ddk.ncui.plugin.contributes\",\n EXPERIENCES: \"kosdev.ddk.ncui.plugin.contributes.experiences\",\n VIEWS: \"kosdev.ddk.ncui.plugin.contributes.views\",\n TAB_VIEW: \"ddk.ncui.settings.tabView\",\n} as const;\n","import {\n ExperienceConfig,\n NormalizedComponentOptions,\n PluginConfiguration,\n} from \"../types\";\n\n/**\n * Base interface for plugin-specific handlers\n */\nexport interface PluginHandler {\n /**\n * Creates the plugin-specific configuration\n */\n createConfiguration(options: NormalizedComponentOptions): PluginConfiguration;\n\n /**\n * Returns the contribution key for this plugin type\n */\n getContributionKey(): string;\n\n /**\n * Checks if this plugin type requires localization\n */\n requiresLocalization(): boolean;\n\n /**\n * Gets the template source path for this plugin type\n */\n getTemplatePath(): string;\n}\n\n/**\n * Base implementation with common functionality\n */\nexport abstract class BasePluginHandler implements PluginHandler {\n protected abstract pluginType: string;\n protected abstract contributionKey: string;\n protected abstract requiresI18n: boolean;\n\n abstract createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration;\n\n getContributionKey(): string {\n return this.contributionKey;\n }\n\n requiresLocalization(): boolean {\n return this.requiresI18n;\n }\n\n getTemplatePath(): string {\n return this.contributionKey;\n }\n\n /**\n * Helper to create experience configuration\n */\n protected createExperience(\n options: NormalizedComponentOptions,\n experienceId: string\n ): ExperienceConfig {\n const compPath = this.getComponentPath(options);\n\n return {\n id: experienceId,\n component: options.namePascalCase,\n location: `./src/${compPath}`,\n };\n }\n\n /**\n * Helper to get component path\n */\n protected getComponentPath(options: NormalizedComponentOptions): string {\n return `${options.appDirectory}/${this.contributionKey}/${options.nameDashCase}/${options.nameDashCase}.tsx`;\n }\n\n /**\n * Helper to create config prefix\n */\n protected getConfigPrefix(options: NormalizedComponentOptions): string {\n return `${options.appProject}.${options.nameCamelCase}`;\n }\n}\n","import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class ControlPourPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CONTROL_POUR;\n protected contributionKey = \"control-pour\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.controlPour.experience`;\n\n const contribution = {\n id: `${configPrefix}.controlPour`,\n title: `${configPrefix}.controlPour.title`,\n namespace: options.appProject,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n controlPour: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class CuiPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CUI;\n protected contributionKey = \"cui\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.cui.experience`;\n\n const contribution = {\n id: configPrefix,\n title: `${configPrefix}.cui.title`,\n namespace: options.appProject,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n cui: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PLUGIN_TYPES,\n PluginConfiguration,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class CustomPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.CUSTOM;\n protected contributionKey = \"custom\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.${\n options.contributionKey || \"custom\"\n }.experience`;\n\n // Get the user-specified contribution key or default to 'custom'\n const userContributionKey = options.contributionKey || \"custom\";\n\n const contribution = {\n id: configPrefix,\n title: `${configPrefix}.${userContributionKey}.title`,\n namespace: options.appProject,\n experienceId,\n // TODO: Add additional fields as required by the plugin-explorer specification\n // Refer to the plugin-explorer documentation for your specific contribution type\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n [userContributionKey]: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n\n override getTemplatePath(): string {\n // Use the generic 'custom' template path\n return this.contributionKey || \"custom\";\n }\n\n protected override getComponentPath(\n options: NormalizedComponentOptions\n ): string {\n // Use the user-specified contribution key for the path if available\n const pathKey = options.contributionKey || \"custom\";\n return `${options.appDirectory}/${pathKey}/${options.nameDashCase}/${options.nameDashCase}.tsx`;\n }\n}\n","import { NormalizedComponentOptions, PluginConfiguration } from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\n/**\n * Default handler for non-plugin components\n */\nexport class DefaultComponentHandler extends BasePluginHandler {\n protected pluginType = \"component\";\n protected contributionKey = \"components\";\n protected requiresI18n = false;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const compPath = this.getComponentPath(options);\n\n const viewConfig = {\n id: `${options.appProject}.${options.nameCamelCase}`,\n title: \"ddk.ncui.config.title\",\n namespace: options.appProject,\n component: options.namePascalCase,\n location: `./src/${compPath}`,\n };\n\n return {\n contributions: {},\n experiences: {},\n views: {\n [this.getTabViewKey()]: [viewConfig],\n },\n };\n }\n\n private getTabViewKey(): string {\n return \"ddk.ncui.settings.tabView\";\n }\n\n override getTemplatePath(): string {\n return \"files\"; // Default template path\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class NavPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.NAV;\n protected contributionKey = \"nav\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.nav.experience`;\n\n const contribution = {\n id: `${configPrefix}.nav`,\n title: `${configPrefix}.nav.title`,\n namespace: options.appProject,\n navDescriptor: options.nameLowerCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n navViews: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class SettingPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.SETTING;\n protected contributionKey = \"setting\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.settings.experience`;\n\n const contribution = {\n id: `${configPrefix}.setting`,\n title: `${configPrefix}.setting.title`,\n namespace: options.appProject,\n settingsGroup: options.group || \"general\",\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n settings: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class SetupPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.SETUP;\n protected contributionKey = \"setup\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.setup.experience`;\n\n const contribution = {\n id: `${configPrefix}.setup`,\n title: `${configPrefix}.setup.title`,\n namespace: options.appProject,\n setupDescriptor: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n setupStep: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class TroubleActionPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.TROUBLE_ACTION;\n protected contributionKey = \"trouble-action\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.troubleAction.experience`;\n\n const contribution = {\n id: `${configPrefix}.troubleAction`,\n title: `${configPrefix}.troubleAction.title`,\n namespace: options.appProject,\n troubleType: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n troubleActions: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import {\n NormalizedComponentOptions,\n PluginConfiguration,\n PLUGIN_TYPES,\n} from \"../types\";\nimport { BasePluginHandler } from \"./base\";\n\nexport class UtilityPluginHandler extends BasePluginHandler {\n protected pluginType = PLUGIN_TYPES.UTILITY;\n protected contributionKey = \"utility\";\n protected requiresI18n = true;\n\n createConfiguration(\n options: NormalizedComponentOptions\n ): PluginConfiguration {\n const configPrefix = this.getConfigPrefix(options);\n const experienceId = `${configPrefix}.util.experience`;\n\n const contribution = {\n id: `${configPrefix}.util`,\n title: `${configPrefix}.utility.title`,\n namespace: options.appProject,\n utilDescriptor: options.nameCamelCase,\n experienceId,\n };\n\n const experience = this.createExperience(options, experienceId);\n\n return {\n contributions: {\n utilities: [contribution],\n },\n experiences: {\n [experienceId]: experience,\n },\n };\n }\n}\n","import { PLUGIN_TYPES } from \"../types\";\nimport { PluginHandler } from \"./base\";\nimport { ControlPourPluginHandler } from \"./control-pour-handler\";\nimport { CuiPluginHandler } from \"./cui-handler\";\nimport { CustomPluginHandler } from \"./custom-handler\";\nimport { DefaultComponentHandler } from \"./default-handler\";\nimport { NavPluginHandler } from \"./nav-handler\";\nimport { SettingPluginHandler } from \"./setting-handler\";\nimport { SetupPluginHandler } from \"./setup-handler\";\nimport { TroubleActionPluginHandler } from \"./trouble-action-handler\";\nimport { UtilityPluginHandler } from \"./utility-handler\";\n\n/**\n * Factory for creating plugin-specific handlers\n */\nexport class PluginHandlerFactory {\n private static handlers: Map<string, new () => PluginHandler> = new Map<\n string,\n new () => PluginHandler\n >([\n [PLUGIN_TYPES.CUI, CuiPluginHandler],\n [PLUGIN_TYPES.UTILITY, UtilityPluginHandler],\n [PLUGIN_TYPES.SETTING, SettingPluginHandler],\n [PLUGIN_TYPES.SETUP, SetupPluginHandler],\n [PLUGIN_TYPES.NAV, NavPluginHandler],\n [PLUGIN_TYPES.CONTROL_POUR, ControlPourPluginHandler],\n [PLUGIN_TYPES.TROUBLE_ACTION, TroubleActionPluginHandler],\n [PLUGIN_TYPES.CUSTOM, CustomPluginHandler],\n ]);\n\n static createHandler(pluginType?: string): PluginHandler {\n if (!pluginType) {\n return new DefaultComponentHandler();\n }\n\n const HandlerClass = this.handlers.get(pluginType);\n\n if (!HandlerClass) {\n console.warn(\n `No handler found for plugin type: ${pluginType}. Using default handler.`\n );\n return new DefaultComponentHandler();\n }\n\n return new HandlerClass();\n }\n\n static isValidPluginType(type: string): boolean {\n return this.handlers.has(type);\n }\n}\n","import * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport { generateFilesFromTemplates } from \"../../../generate-files\";\nimport { NormalizedComponentOptions } from \"../types\";\n\n/**\n * Generates component files from templates.\n *\n * @param codegenFs - Filesystem abstraction\n * @param templateBaseDir - Absolute path to the base template directory\n * @param templateSubPath - Sub-path from handler (e.g., \"cui\", \"files\")\n * @param targetPath - Destination path relative to workspace root\n * @param options - Normalized component options for template substitution\n */\nexport function generateComponentFiles(\n codegenFs: CodegenFileSystem,\n templateBaseDir: string,\n templateSubPath: string,\n targetPath: string,\n options: NormalizedComponentOptions\n): void {\n generateFilesFromTemplates(\n codegenFs,\n path.join(templateBaseDir, templateSubPath),\n targetPath,\n options\n );\n\n // Handle CSS file deletion if needed\n if (options.useEmotionCss) {\n deleteCssFile(codegenFs, targetPath, options);\n }\n}\n\n/**\n * Deletes the CSS file when using Emotion CSS\n */\nfunction deleteCssFile(\n codegenFs: CodegenFileSystem,\n targetPath: string,\n options: NormalizedComponentOptions\n): void {\n const cssPath = path.join(targetPath, `${options.nameDashCase}.css`);\n\n if (codegenFs.exists(cssPath)) {\n codegenFs.delete(cssPath);\n }\n}\n","import type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport { updateJson } from \"../../../json-utils\";\nimport { PluginConfiguration } from \"../types\";\n\n/**\n * Builder for constructing and updating .kos.json configuration\n */\nexport class KosConfigBuilder {\n private contributions: Record<string, any[]> = {};\n private experiences: Record<string, any> = {};\n private views: Record<string, any[]> = {};\n\n /**\n * Adds plugin configuration to the builder\n */\n addPluginConfiguration(config: PluginConfiguration): this {\n // Merge contributions\n Object.entries(config.contributions).forEach(([key, value]) => {\n this.contributions[key] = [...(this.contributions[key] || []), ...value];\n });\n\n // Merge experiences\n Object.assign(this.experiences, config.experiences);\n\n // Merge views\n if (config.views) {\n Object.entries(config.views).forEach(([key, value]) => {\n this.views[key] = [...(this.views[key] || []), ...value];\n });\n }\n\n return this;\n }\n\n /**\n * Applies the built configuration to the .kos.json file\n */\n applyToFile(codegenFs: CodegenFileSystem, kosConfigPath: string): void {\n updateJson(codegenFs, kosConfigPath, (json: any) => {\n // Initialize the deep structure if it doesn't exist\n const structure = this.initializeStructure(json);\n\n // Merge contributions\n Object.entries(this.contributions).forEach(([key, value]) => {\n structure.contributes[key] = [\n ...(structure.contributes[key] || []),\n ...value,\n ];\n });\n\n // Merge experiences\n structure.contributes.experiences = {\n ...structure.contributes.experiences,\n ...this.experiences,\n };\n\n // Merge views\n if (Object.keys(this.views).length > 0) {\n structure.contributes.views = structure.contributes.views || {};\n\n Object.entries(this.views).forEach(([key, value]) => {\n structure.contributes.views[key] = [\n ...(structure.contributes.views[key] || []),\n ...value,\n ];\n });\n }\n\n return json;\n });\n }\n\n /**\n * Initializes the deep JSON structure\n */\n private initializeStructure(json: any): any {\n json.kos ??= {};\n json.kos.ui ??= {};\n json.kos.ui.plugin ??= {};\n json.kos.ui.plugin.contributes ??= {};\n\n return json.kos.ui.plugin;\n }\n\n /**\n * Creates a new builder instance\n */\n static create(): KosConfigBuilder {\n return new KosConfigBuilder();\n }\n}\n","import * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport { updateJson } from \"../../../json-utils\";\nimport { NormalizedComponentOptions } from \"../types\";\n\n/**\n * Updates localization files for plugin components\n */\nexport function updateLocalization(\n codegenFs: CodegenFileSystem,\n projectRoot: string,\n options: NormalizedComponentOptions,\n pluginType: string\n): void {\n const localePath = path.join(\n projectRoot,\n \"assets\",\n \"locales\",\n \"en\",\n `${options.appProject}.json`\n );\n\n if (!codegenFs.exists(localePath)) {\n console.warn(`Locale file not found: ${localePath}`);\n return;\n }\n\n updateJson(codegenFs, localePath, (json: any) => {\n // Ensure nested structure exists\n json[options.appProject] = json[options.appProject] || {};\n json[options.appProject][options.nameCamelCase] =\n json[options.appProject][options.nameCamelCase] || {};\n\n // Add localization entry\n json[options.appProject][options.nameCamelCase][pluginType] = {\n ...json[options.appProject][options.nameCamelCase][pluginType],\n title: options.nameCamelCase,\n };\n\n return json;\n });\n}\n","import type { CodegenFileSystem } from \"../../../codegen-filesystem\";\nimport {\n findProjectByName,\n type ProjectConfiguration,\n} from \"../../../project-discovery\";\nimport { PluginHandlerFactory } from \"../plugin-handlers/factory\";\nimport type { ComponentOptions } from \"../types\";\n\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Validates generator options\n */\nexport function validateOptions(\n codegenFs: CodegenFileSystem,\n options: ComponentOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n // Validate required fields\n if (!options.name) {\n throw new ValidationError(\"Component name is required\");\n }\n\n if (!options.appProject) {\n throw new ValidationError(\"App project is required\");\n }\n\n // Validate project exists\n const project = findProjectByName(\n codegenFs.root,\n options.appProject,\n projects\n );\n if (!project) {\n throw new ValidationError(\n `Project \"${options.appProject}\" not found in workspace`\n );\n }\n\n // Validate plugin type if provided\n if (\n options.pluginType &&\n !PluginHandlerFactory.isValidPluginType(options.pluginType)\n ) {\n console.warn(\n `Unknown plugin type \"${options.pluginType}\". ` +\n `Component will be generated with default configuration.`\n );\n }\n\n // Validate group is provided for setting type\n if (options.pluginType === \"setting\" && !options.group) {\n throw new ValidationError(\n \"Settings group is required for setting plugin type\"\n );\n }\n}\n\n/**\n * Validates file paths\n */\nexport function validateFilePath(\n codegenFs: CodegenFileSystem,\n filePath: string\n): boolean {\n return codegenFs.exists(filePath);\n}\n\n/**\n * Safe JSON update with error handling\n */\nexport function safeJsonUpdate<T = any>(\n operation: () => T,\n fallback: T,\n errorMessage?: string\n): T {\n try {\n return operation();\n } catch (error) {\n if (errorMessage) {\n console.error(errorMessage, error);\n }\n return fallback;\n }\n}\n","/**\n * Core component generator — framework-agnostic.\n *\n * Replaces the Nx-coupled logic from kos-nx-plugin kos-component generator.\n * Uses CodegenFileSystem instead of @nx/devkit Tree.\n */\nimport * as path from \"path\";\nimport type { CodegenFileSystem } from \"../../codegen-filesystem\";\nimport { getKosProjectConfiguration } from \"../../kos-config\";\nimport type { ProjectConfiguration } from \"../../project-discovery\";\nimport { findProjectByName } from \"../../project-discovery\";\nimport { normalizeOptions } from \"../normalize-options\";\nimport { PluginHandlerFactory } from \"./plugin-handlers/factory\";\nimport {\n ComponentOptions,\n CONTRIBUTION_TYPE_MAP,\n NormalizedComponentOptions,\n} from \"./types\";\nimport { generateComponentFiles } from \"./utils/file-generator\";\nimport { KosConfigBuilder } from \"./utils/kos-config-builder\";\nimport { updateLocalization } from \"./utils/localization\";\nimport { validateOptions } from \"./utils/validation\";\n\nexport type { ComponentOptions } from \"./types\";\n\n/**\n * Generate a KOS component using the framework-agnostic CodegenFileSystem.\n *\n * @param codegenFs - Filesystem abstraction (NxTreeAdapter or DirectFileSystem)\n * @param templateDir - Absolute path to the template base directory\n * @param options - Component generator options\n * @param projects - Optional pre-computed project map (avoids rescan)\n */\nexport function generateComponent(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n options: ComponentOptions,\n projects?: Map<string, ProjectConfiguration>\n): void {\n // Step 1: Validate options\n validateOptions(codegenFs, options, projects);\n\n // Step 2: Normalize options\n const normalized = prepareOptions(codegenFs, options, projects);\n\n // Step 3: Get project configuration\n const projectConfig = findProjectByName(\n codegenFs.root,\n normalized.appProject,\n projects\n );\n\n if (!projectConfig) {\n throw new Error(\n `Project \"${normalized.appProject}\" not found in workspace`\n );\n }\n\n const projectRoot = projectConfig.sourceRoot;\n\n if (!projectRoot) {\n throw new Error(\n `No source root found for project ${normalized.appProject}`\n );\n }\n\n // Step 4: Generate component files\n generateFiles(codegenFs, templateDir, projectRoot, normalized);\n\n // Step 5: Update plugin configuration if needed\n if (options.pluginType) {\n updatePluginConfiguration(codegenFs, projectConfig, normalized);\n }\n}\n\n/**\n * Prepares and normalizes options\n */\nfunction prepareOptions(\n codegenFs: CodegenFileSystem,\n options: ComponentOptions,\n projects?: Map<string, ProjectConfiguration>\n): NormalizedComponentOptions {\n const normalized = normalizeOptions(\n codegenFs,\n {\n ...options,\n modelProject: \"__NONE__\",\n },\n projects\n ) as unknown as NormalizedComponentOptions;\n\n // Get KOS configuration for component location\n const kosConfig = getKosProjectConfiguration(\n codegenFs,\n options.appProject,\n projects\n );\n\n const componentLocation =\n (kosConfig?.generator?.defaults as any)?.component?.folder || \"\";\n\n // Set component directory and type\n normalized.appDirectory = options.appDirectory || componentLocation;\n normalized.type =\n CONTRIBUTION_TYPE_MAP[options.pluginType || \"\"] || options.type;\n\n // Pass through contributionKey for custom plugin types\n if (options.contributionKey) {\n normalized.contributionKey = options.contributionKey;\n }\n\n return normalized;\n}\n\n/**\n * Generates component files from templates\n */\nfunction generateFiles(\n codegenFs: CodegenFileSystem,\n templateDir: string,\n projectRoot: string,\n options: NormalizedComponentOptions\n): void {\n // Get appropriate handler\n const handler = PluginHandlerFactory.createHandler(options.pluginType);\n const templatePath = handler.getTemplatePath();\n\n // Determine target path\n const targetPath = path.join(\n projectRoot,\n options.appDirectory,\n options.type,\n options.nameDashCase\n );\n\n // Generate files\n generateComponentFiles(\n codegenFs,\n templateDir,\n templatePath,\n targetPath,\n options\n );\n}\n\n/**\n * Updates plugin configuration in .kos.json\n */\nfunction updatePluginConfiguration(\n codegenFs: CodegenFileSystem,\n projectConfig: ProjectConfiguration,\n options: NormalizedComponentOptions\n): void {\n const kosConfigPath = path.join(projectConfig.root, \".kos.json\");\n\n if (!codegenFs.exists(kosConfigPath)) {\n console.warn(`No .kos.json found at ${kosConfigPath}`);\n return;\n }\n\n // Get handler and create configuration\n const handler = PluginHandlerFactory.createHandler(options.pluginType);\n const pluginConfig = handler.createConfiguration(options);\n\n // Update .kos.json using builder\n const builder = KosConfigBuilder.create();\n builder.addPluginConfiguration(pluginConfig);\n builder.applyToFile(codegenFs, kosConfigPath);\n\n // Update localization if needed\n if (handler.requiresLocalization() && projectConfig.sourceRoot) {\n updateLocalization(\n codegenFs,\n projectConfig.sourceRoot,\n options,\n handler.getContributionKey()\n );\n }\n}\n"],"names":["path","fs","ejs","Project","IndentationText","QuoteKind","VariableDeclarationKind","unquote","Node","Scope","SERVICE_MODULE_RE","ts","FRAMEWORK_TYPES"],"mappings":"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"}
|