teamix-evo 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Teamix Evo Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,196 @@
1
+ # teamix-evo (CLI)
2
+
3
+ > Teamix Evo 命令行入口 — 管理设计体系资源的安装、更新和查询。
4
+
5
+ ## 定位
6
+
7
+ CLI 是 Teamix Evo 的**执行层**,用户通过 `npx teamix-evo` 或全局安装后使用。核心职责:
8
+
9
+ - 从 npm 包加载 variant manifest 和模板数据
10
+ - 使用 Handlebars 渲染模板为目标文件
11
+ - 根据 updateStrategy(frozen / regenerable / managed)决定文件更新方式
12
+ - 维护 `.teamix-evo/` 下的配置和状态文件
13
+
14
+ ## 目录结构
15
+
16
+ ```
17
+ packages/cli/
18
+ ├── src/
19
+ │ ├── index.ts # 入口:Commander 注册
20
+ │ ├── commands/
21
+ │ │ ├── design/
22
+ │ │ │ ├── index.ts # design 命令组
23
+ │ │ │ ├── init.ts # design init [variant]
24
+ │ │ │ ├── update.ts # design update
25
+ │ │ │ └── list.ts # design list
26
+ │ │ ├── skills/
27
+ │ │ │ ├── index.ts # skills 命令组
28
+ │ │ │ ├── add.ts # skills add [name...]
29
+ │ │ │ ├── list.ts # skills list
30
+ │ │ │ ├── update.ts # skills update
31
+ │ │ │ └── uninstall.ts # skills uninstall
32
+ │ │ └── ui/
33
+ │ │ ├── index.ts # ui 命令组
34
+ │ │ ├── init.ts # ui init
35
+ │ │ ├── add.ts # ui add <id...>
36
+ │ │ └── list.ts # ui list
37
+ │ ├── core/
38
+ │ │ ├── installer.ts # 资源安装引擎
39
+ │ │ ├── updater.ts # 资源更新引擎(三策略处理)
40
+ │ │ ├── registry-client.ts # 从 npm 包解析 variant
41
+ │ │ └── state.ts # .teamix-evo/ 状态读写
42
+ │ ├── ide/
43
+ │ │ ├── IdeAdapter.ts # IDE 适配接口
44
+ │ │ ├── QoderAdapter.ts # Qoder 适配实现
45
+ │ │ └── index.ts # IDE 检测入口
46
+ │ ├── utils/
47
+ │ │ ├── fs.ts # 原子写入、备份、文件操作
48
+ │ │ ├── hash.ts # SHA-256 哈希
49
+ │ │ ├── logger.ts # 分级彩色日志
50
+ │ │ ├── path.ts # 路径解析、目录遍历
51
+ │ │ └── template.ts # Handlebars 渲染(带缓存)
52
+ │ └── __tests__/ # 单元测试
53
+ ├── tsup.config.ts # 构建配置(单文件 ESM + shebang)
54
+ ├── tsconfig.json
55
+ └── package.json
56
+ ```
57
+
58
+ ## 研发流程
59
+
60
+ ### 1. 环境准备
61
+
62
+ ```bash
63
+ # 在仓库根目录
64
+ pnpm install
65
+
66
+ # 需要先构建依赖包
67
+ pnpm --filter @teamix-evo/registry build
68
+ ```
69
+
70
+ ### 2. 开发
71
+
72
+ ```bash
73
+ # 监听模式构建
74
+ pnpm --filter teamix-evo dev
75
+ ```
76
+
77
+ 构建产物为单文件 `dist/index.js`(ESM,带 `#!/usr/bin/env node` banner)。
78
+
79
+ ### 3. 新增命令
80
+
81
+ 1. 在 `src/commands/<group>/` 下新建命令文件
82
+ 2. 使用 Commander 的 `Command` 类定义命令
83
+ 3. 在对应 group 的 `index.ts` 中注册(`addCommand`)
84
+ 4. 如果是新的命令组,在 `src/index.ts` 中注册
85
+
86
+ 示例模式:
87
+
88
+ ```typescript
89
+ import { Command } from 'commander';
90
+ import { detectIde } from '../../ide/index.js';
91
+ import { logger } from '../../utils/logger.js';
92
+
93
+ export const myCommand = new Command('my-cmd')
94
+ .description('命令描述')
95
+ .action(async () => {
96
+ try {
97
+ const ide = detectIde();
98
+ const projectRoot = ide.getProjectRoot();
99
+ // ... 业务逻辑
100
+ logger.success('完成');
101
+ } catch (err) {
102
+ logger.error(`Failed: ${(err as Error).message}`);
103
+ process.exitCode = 1;
104
+ }
105
+ });
106
+ ```
107
+
108
+ ### 4. 修改核心引擎
109
+
110
+ - `core/installer.ts` — 资源首次安装逻辑
111
+ - `core/updater.ts` — 资源更新逻辑(处理三种策略 + managed regions)
112
+ - `core/registry-client.ts` — 从 node_modules 解析 variant 包路径
113
+ - `core/state.ts` — `.teamix-evo/config.json` 和 `manifest.json` 的读写
114
+
115
+ ### 5. IDE 适配
116
+
117
+ 当前 MVP 仅支持 Qoder。扩展新 IDE:
118
+
119
+ 1. 在 `src/ide/` 下新建 `XxxAdapter.ts`,实现 `IdeAdapter` 接口
120
+ 2. 在 `src/ide/index.ts` 的 `detectIde()` 中添加检测逻辑
121
+
122
+ ### 6. 测试
123
+
124
+ ```bash
125
+ # 运行全部测试
126
+ pnpm --filter teamix-evo test
127
+
128
+ # 监听模式
129
+ pnpm --filter teamix-evo test:watch
130
+ ```
131
+
132
+ 测试文件位于 `src/__tests__/`,覆盖:
133
+
134
+ - `installer.test.ts` — 资源安装(plain / template / recursive)
135
+ - `updater.test.ts` — 三种策略更新逻辑
136
+ - `state.test.ts` — 配置文件读写
137
+ - `template.test.ts` — Handlebars 渲染
138
+
139
+ ### 7. 类型检查 & 构建
140
+
141
+ ```bash
142
+ pnpm --filter teamix-evo typecheck
143
+ pnpm --filter teamix-evo build
144
+ ```
145
+
146
+ ### 8. 本地调试
147
+
148
+ ```bash
149
+ # 构建后在任意目录执行
150
+ node /path/to/packages/cli/dist/index.js design init opentrek
151
+
152
+ # 或通过 pnpm 链接
153
+ cd packages/cli && pnpm link --global
154
+ teamix-evo design init opentrek
155
+ ```
156
+
157
+ 开启调试日志:
158
+
159
+ ```bash
160
+ TEAMIX_DEBUG=1 teamix-evo design init opentrek
161
+ ```
162
+
163
+ ## 命令参考
164
+
165
+ | 命令 | 说明 |
166
+ | ---------------------------------- | ------------------------------- |
167
+ | `teamix-evo design init [variant]` | 初始化设计体系(默认 opentrek) |
168
+ | `teamix-evo design update` | 更新已安装的设计资源 |
169
+ | `teamix-evo design list` | 查看已安装信息 |
170
+ | `teamix-evo skills add [name...]` | 装入 skills(全量/增量) |
171
+ | `teamix-evo skills list` | 列出所有 skill 的安装状态 |
172
+ | `teamix-evo skills update` | 升级已安装 skills |
173
+ | `teamix-evo skills uninstall` | 卸载 skills |
174
+ | `teamix-evo ui init` | 初始化 ui 组件环境 |
175
+ | `teamix-evo ui add <id...>` | 安装指定 ui 组件源码 |
176
+ | `teamix-evo ui list` | 列出可用/已安装 ui 组件 |
177
+
178
+ 选项:
179
+
180
+ - `--tailwind <v3|v4>` — 指定 Tailwind CSS 版本(默认 v3)
181
+
182
+ ## 关键约定
183
+
184
+ - 使用 `process.exitCode = 1` 而非 `process.exit(1)`,确保异步操作完成
185
+ - 文件写入使用 `writeFileSafe`(tmp + rename 原子写入)
186
+ - 更新前自动备份到 `.teamix-evo/.backups/`
187
+ - 版本号从 `package.json` 动态读取,不硬编码
188
+
189
+ ## 依赖关系
190
+
191
+ ```
192
+ 本包 → @teamix-evo/registry(协议层)
193
+ 本包 → @teamix-evo/design(设计资源,运行时解析)
194
+ 本包 → @teamix-evo/skills(技能资源,运行时解析)
195
+ 本包 → @teamix-evo/ui(UI 资源,manifest + 源码)
196
+ ```
@@ -0,0 +1,364 @@
1
+ import { TailwindVersion, InstalledResource, SkillIde, SkillScope, UiAliases, UiEntry, VariantManifest, SkillsPackageManifest, UiPackageManifest, InstalledManifest, ProjectConfig } from '@teamix-evo/registry';
2
+ export { InstalledManifest, InstalledResource, ProjectConfig, SkillIde, SkillScope, TailwindVersion, UiAliases } from '@teamix-evo/registry';
3
+
4
+ interface RunDesignInitOptions {
5
+ /** Absolute project root directory. */
6
+ projectRoot: string;
7
+ /** Design variant id, e.g. "opentrek". */
8
+ variant: string;
9
+ /** Tailwind major version of the consuming project. */
10
+ tailwind: TailwindVersion;
11
+ /** IDE identifier written into config.json (e.g. "qoder", "claude"). */
12
+ ide: string;
13
+ /** Override the design package name (defaults to "@teamix-evo/design"). */
14
+ packageName?: string;
15
+ }
16
+ type RunDesignInitResult = {
17
+ status: 'installed';
18
+ packageName: string;
19
+ variant: string;
20
+ version: string;
21
+ tailwind: TailwindVersion;
22
+ count: number;
23
+ resources: InstalledResource[];
24
+ } | {
25
+ status: 'already-initialized';
26
+ existingVariant: string;
27
+ };
28
+ /**
29
+ * Programmatic equivalent of `teamix-evo design init <variant>`.
30
+ *
31
+ * Side effects:
32
+ * - Creates `<projectRoot>/.teamix-evo/`
33
+ * - Writes `config.json` and `manifest.json`
34
+ * - Installs design resources from the variant manifest into the project
35
+ *
36
+ * No interactive prompts, no `process.exit`. Throws on hard failure.
37
+ */
38
+ declare function runDesignInit(options: RunDesignInitOptions): Promise<RunDesignInitResult>;
39
+
40
+ interface RunSkillsAddOptions {
41
+ /** Absolute project root directory. */
42
+ projectRoot: string;
43
+ /**
44
+ * Target IDEs to inject skills into. Optional in incremental mode (i.e. when
45
+ * `names` is provided) — falls back to the previously installed config.
46
+ * Required for the bulk path.
47
+ */
48
+ ides?: readonly SkillIde[];
49
+ /**
50
+ * Install scope. Optional in incremental mode (falls back to existing
51
+ * config). Required for the bulk path.
52
+ */
53
+ scope?: SkillScope;
54
+ /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to "qoder"). */
55
+ ide?: string;
56
+ /** Override the skills package name (defaults to "@teamix-evo/skills"). */
57
+ packageName?: string;
58
+ /**
59
+ * Optional skill ids to add. When omitted, all skills declared in the
60
+ * manifest are installed (bulk mode). When provided, only the listed skills
61
+ * are added (incremental mode); skills that are already installed are
62
+ * silently skipped and reported via `skippedSkillIds`.
63
+ */
64
+ names?: readonly string[];
65
+ }
66
+ type RunSkillsAddResult = {
67
+ status: 'installed';
68
+ packageName: string;
69
+ version: string;
70
+ ides: SkillIde[];
71
+ scope: SkillScope;
72
+ /** Number of skills that were freshly added in this call. */
73
+ skillCount: number;
74
+ /** Number of files written by `installSkills` for the freshly added skills. */
75
+ fileCount: number;
76
+ /** InstalledResource records for the freshly added skills only. */
77
+ resources: InstalledResource[];
78
+ /** Skill ids that were freshly added in this call. */
79
+ addedSkillIds: string[];
80
+ /** Skill ids that were requested but already installed; skipped. */
81
+ skippedSkillIds: string[];
82
+ } | {
83
+ /** Returned only from bulk mode when a skills package is already installed. */
84
+ status: 'already-added';
85
+ };
86
+ /**
87
+ * Programmatic equivalent of `teamix-evo skills add`.
88
+ *
89
+ * - Bulk mode (`names` omitted): install every skill in the manifest. Re-run
90
+ * on a project that already has `packages.skills` returns `'already-added'`.
91
+ * - Incremental mode (`names` provided): install only the listed skills. Skills
92
+ * already present are skipped (use `skills update` to refresh). `ides`/`scope`
93
+ * may be omitted — they fall back to the previously installed config.
94
+ */
95
+ declare function runSkillsAdd(options: RunSkillsAddOptions): Promise<RunSkillsAddResult>;
96
+
97
+ declare const DEFAULT_UI_ALIASES: UiAliases;
98
+ declare const DEFAULT_UI_ICON_LIBRARY = "lucide";
99
+ interface RunUiInitOptions {
100
+ /** Absolute project root directory. */
101
+ projectRoot: string;
102
+ /** Component aliases. Falls back to {@link DEFAULT_UI_ALIASES}. */
103
+ aliases?: Partial<UiAliases>;
104
+ /** Declared icon library (does not trigger code rewrite). Defaults to "lucide". */
105
+ iconLibrary?: string;
106
+ /** Whether the project uses TSX (true) or JSX (false). Defaults to true. */
107
+ tsx?: boolean;
108
+ /** Whether the project emits React Server Components markers. Defaults to false. */
109
+ rsc?: boolean;
110
+ /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to "qoder"). */
111
+ ide?: string;
112
+ }
113
+ type RunUiInitResult = {
114
+ status: 'installed';
115
+ aliases: UiAliases;
116
+ iconLibrary: string;
117
+ tsx: boolean;
118
+ rsc: boolean;
119
+ } | {
120
+ status: 'already-initialized';
121
+ };
122
+ /**
123
+ * Programmatic equivalent of `teamix-evo ui init`.
124
+ *
125
+ * Writes `packages.ui` into `.teamix-evo/config.json` only — no resource files
126
+ * are touched. Use {@link runUiAdd} afterwards to install component sources.
127
+ */
128
+ declare function runUiInit(options: RunUiInitOptions): Promise<RunUiInitResult>;
129
+
130
+ interface RunUiAddOptions {
131
+ /** Absolute project root directory. */
132
+ projectRoot: string;
133
+ /** Entry ids to install (registry dependencies are resolved transitively). */
134
+ ids: string[];
135
+ /** When true, overwrite frozen entries that already exist on disk. */
136
+ overwrite?: boolean;
137
+ /** Override the ui package name (defaults to "@teamix-evo/ui"). */
138
+ packageName?: string;
139
+ }
140
+ interface RunUiAddResult {
141
+ packageName: string;
142
+ /** Registered ids in install order (deps + requested). */
143
+ orderedIds: string[];
144
+ /** Number of files written. */
145
+ written: number;
146
+ /** Number of files skipped due to frozen + exists. */
147
+ skipped: number;
148
+ /** Meta files dropped under .teamix-evo/design/components/. */
149
+ metaFiles: string[];
150
+ /** Aggregate npm dependencies of the installed entries. */
151
+ npmDependencies: Record<string, string>;
152
+ /** Per-file install records merged into the installed manifest. */
153
+ resources: InstalledResource[];
154
+ }
155
+ /**
156
+ * Programmatic equivalent of `teamix-evo ui add <ids...>`.
157
+ *
158
+ * Requires `packages.ui` to already exist in `.teamix-evo/config.json`
159
+ * (i.e. {@link runUiInit} was called earlier).
160
+ */
161
+ declare function runUiAdd(options: RunUiAddOptions): Promise<RunUiAddResult>;
162
+
163
+ interface RunUiListOptions {
164
+ /** Absolute project root directory. */
165
+ projectRoot: string;
166
+ /** When true, only return entries that are already installed. */
167
+ installedOnly?: boolean;
168
+ /** Override the ui package name (defaults to "@teamix-evo/ui"). */
169
+ packageName?: string;
170
+ }
171
+ interface UiEntryListItem {
172
+ id: string;
173
+ type: UiEntry['type'];
174
+ description: string;
175
+ installed: boolean;
176
+ }
177
+ interface RunUiListResult {
178
+ packageName: string;
179
+ /** Total number of entries declared by the package manifest. */
180
+ total: number;
181
+ /** Number of installed entries (based on the project's installed manifest). */
182
+ installedCount: number;
183
+ /** Filtered + decorated entries. */
184
+ entries: UiEntryListItem[];
185
+ }
186
+ /**
187
+ * Programmatic equivalent of `teamix-evo ui list`.
188
+ *
189
+ * Returns structured data; the CLI command formats it for terminal output.
190
+ */
191
+ declare function runUiList(options: RunUiListOptions): Promise<RunUiListResult>;
192
+
193
+ interface InstallOptions {
194
+ /** Project root directory */
195
+ projectRoot: string;
196
+ /** The variant manifest */
197
+ manifest: VariantManifest;
198
+ /** Template data for Handlebars rendering */
199
+ data: Record<string, unknown>;
200
+ /** Absolute path to the variant directory (where source files live) */
201
+ variantDir: string;
202
+ /** Absolute path to the package root (for resolving _template/ sources) */
203
+ packageRoot: string;
204
+ }
205
+ interface InstallResult {
206
+ /** Successfully installed resource records */
207
+ resources: InstalledResource[];
208
+ /** Number of resources installed */
209
+ count: number;
210
+ }
211
+ /**
212
+ * Install resources from a variant manifest into the project.
213
+ */
214
+ declare function installResources(options: InstallOptions): Promise<InstallResult>;
215
+
216
+ interface SkillInstallOptions {
217
+ /** Project root directory */
218
+ projectRoot: string;
219
+ /** Skills package manifest */
220
+ manifest: SkillsPackageManifest;
221
+ /** Template data */
222
+ data: Record<string, unknown>;
223
+ /** Absolute skills package root */
224
+ packageRoot: string;
225
+ /** IDE kinds to install for (intersection with skill.ides is computed) */
226
+ ides: readonly SkillIde[];
227
+ /** Install scope */
228
+ scope: SkillScope;
229
+ /** Optional: limit to specific skill ids */
230
+ onlyIds?: string[];
231
+ }
232
+ interface SkillInstallResult {
233
+ resources: InstalledResource[];
234
+ count: number;
235
+ }
236
+ /**
237
+ * Install (or reinstall) all skills declared in the manifest, fanning out to the
238
+ * intersection of requested IDEs and each skill's declared `ides`.
239
+ */
240
+ declare function installSkills(options: SkillInstallOptions): Promise<SkillInstallResult>;
241
+ interface SkillUpdateOptions extends SkillInstallOptions {
242
+ /** Existing installed records for the skills package */
243
+ installed: InstalledResource[];
244
+ }
245
+ interface SkillUpdateResult {
246
+ resources: InstalledResource[];
247
+ summary: {
248
+ overwritten: number;
249
+ managed: number;
250
+ skipped: number;
251
+ created: number;
252
+ };
253
+ }
254
+ /**
255
+ * Update skills according to their updateStrategy.
256
+ */
257
+ declare function updateSkills(options: SkillUpdateOptions): Promise<SkillUpdateResult>;
258
+ /**
259
+ * Remove all installed skill files. Returns the absolute paths removed.
260
+ */
261
+ declare function removeSkillFiles(records: InstalledResource[]): Promise<string[]>;
262
+
263
+ interface UiInstallOptions {
264
+ /** Project root directory */
265
+ projectRoot: string;
266
+ /** UI package manifest */
267
+ manifest: UiPackageManifest;
268
+ /** Absolute ui package root (used to resolve entry source paths) */
269
+ packageRoot: string;
270
+ /** Aliases configured in `packages.ui.aliases` */
271
+ aliases: UiAliases;
272
+ /** Entry ids the user explicitly requested to add */
273
+ requested: string[];
274
+ /** When true, skip writing entries whose target file already exists (frozen-on-add). */
275
+ skipExisting?: boolean;
276
+ }
277
+ interface UiInstallResult {
278
+ /** Ordered list of entry ids that were processed (deps + requested) */
279
+ orderedIds: string[];
280
+ /** Per-file install records (for InstalledManifest) */
281
+ resources: InstalledResource[];
282
+ /** Aggregate npm dependencies across the installed entries */
283
+ npmDependencies: Record<string, string>;
284
+ /** Number of files written */
285
+ written: number;
286
+ /** Number of files skipped because they already exist (frozen) */
287
+ skipped: number;
288
+ /** Meta files dropped under .teamix-evo/design/components/ */
289
+ metaFiles: string[];
290
+ }
291
+ /**
292
+ * Install the requested ui entries (transitively resolving registryDependencies).
293
+ * For frozen entries that already exist on disk, the write is skipped — shadcn-style.
294
+ */
295
+ declare function installUiEntries(options: UiInstallOptions): Promise<UiInstallResult>;
296
+ /**
297
+ * Remove all installed ui resource files and prune empty parent directories.
298
+ */
299
+ declare function removeUiFiles(records: InstalledResource[]): Promise<string[]>;
300
+
301
+ /**
302
+ * Load the variant manifest and _data.json for template rendering.
303
+ *
304
+ * @param packageName - e.g. "@teamix-evo/design"
305
+ * @param variant - e.g. "opentrek"
306
+ * @returns manifest and data for template rendering
307
+ */
308
+ declare function loadVariantData(packageName: string, variant: string): Promise<{
309
+ manifest: VariantManifest;
310
+ data: Record<string, unknown>;
311
+ variantDir: string;
312
+ packageRoot: string;
313
+ }>;
314
+
315
+ /**
316
+ * Load the skills package manifest and optional shared `_data.json`.
317
+ *
318
+ * @param packageName - e.g. "@teamix-evo/skills"
319
+ */
320
+ declare function loadSkillsData(packageName: string): Promise<{
321
+ manifest: SkillsPackageManifest;
322
+ data: Record<string, unknown>;
323
+ packageRoot: string;
324
+ }>;
325
+
326
+ /**
327
+ * Load the ui package manifest and optional shared `_data.json`.
328
+ *
329
+ * @param packageName - e.g. "@teamix-evo/ui"
330
+ */
331
+ declare function loadUiData(packageName: string): Promise<{
332
+ manifest: UiPackageManifest;
333
+ data: Record<string, unknown>;
334
+ packageRoot: string;
335
+ }>;
336
+
337
+ /**
338
+ * Get the .teamix-evo directory path for a project.
339
+ */
340
+ declare function getTeamixDir(projectRoot: string): string;
341
+ /**
342
+ * Ensure the .teamix-evo directory exists.
343
+ */
344
+ declare function ensureTeamixDir(projectRoot: string): Promise<string>;
345
+ /**
346
+ * Read the project config from .teamix-evo/config.json.
347
+ * Returns null if the file does not exist.
348
+ */
349
+ declare function readProjectConfig(projectRoot: string): Promise<ProjectConfig | null>;
350
+ /**
351
+ * Write the project config to .teamix-evo/config.json.
352
+ */
353
+ declare function writeProjectConfig(projectRoot: string, config: ProjectConfig): Promise<void>;
354
+ /**
355
+ * Read the installed manifest from .teamix-evo/manifest.json.
356
+ * Returns null if the file does not exist.
357
+ */
358
+ declare function readInstalledManifest(projectRoot: string): Promise<InstalledManifest | null>;
359
+ /**
360
+ * Write the installed manifest to .teamix-evo/manifest.json.
361
+ */
362
+ declare function writeInstalledManifest(projectRoot: string, manifest: InstalledManifest): Promise<void>;
363
+
364
+ export { DEFAULT_UI_ALIASES, DEFAULT_UI_ICON_LIBRARY, type InstallOptions, type InstallResult, type RunDesignInitOptions, type RunDesignInitResult, type RunSkillsAddOptions, type RunSkillsAddResult, type RunUiAddOptions, type RunUiAddResult, type RunUiInitOptions, type RunUiInitResult, type RunUiListOptions, type RunUiListResult, type SkillInstallOptions, type SkillInstallResult, type SkillUpdateOptions, type SkillUpdateResult, type UiEntryListItem, type UiInstallOptions, type UiInstallResult, ensureTeamixDir, getTeamixDir, installResources, installSkills, installUiEntries, loadSkillsData, loadUiData, loadVariantData, readInstalledManifest, readProjectConfig, removeSkillFiles, removeUiFiles, runDesignInit, runSkillsAdd, runUiAdd, runUiInit, runUiList, updateSkills, writeInstalledManifest, writeProjectConfig };