teamix-evo 0.1.0 → 0.3.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,222 @@
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/ # design init <variant> / list / list-variants
22
+ │ │ │ │ # / update(stub) / uninstall
23
+ │ │ ├── skills/ # source-mirror 模型见 ADR 0013
24
+ │ │ │ │ # add / list / update / sync / doctor / uninstall
25
+ │ │ └── ui/ # init / add / list
26
+ │ ├── core/ # 业务编排层(programmatic API,subpath 导出)
27
+ │ │ ├── design-init.ts # walk-and-merge 装机
28
+ │ │ ├── design-pack-classify.ts # 路径分类(W1.4 tokens 提层)
29
+ │ │ ├── installer.ts # UI 资源安装引擎
30
+ │ │ ├── updater.ts # 三策略更新引擎(frozen/regenerable/managed)
31
+ │ │ ├── ui-{add,init,list,client,installer}.ts
32
+ │ │ ├── skills-{add,client,installer,sync,doctor}.ts
33
+ │ │ ├── registry-client.ts # 从 npm 包解析 variant
34
+ │ │ └── state.ts # .teamix-evo/ 状态读写
35
+ │ ├── ide/
36
+ │ │ ├── IdeAdapter.ts # IDE 适配接口
37
+ │ │ ├── QoderAdapter.ts # Qoder 适配
38
+ │ │ ├── ClaudeAdapter.ts # Claude Code 适配
39
+ │ │ └── index.ts # detectIde / ALL_IDE_KINDS
40
+ │ ├── utils/
41
+ │ │ ├── fs.ts # 原子写入、备份
42
+ │ │ ├── hash.ts # SHA-256
43
+ │ │ ├── logger.ts # 分级彩色日志
44
+ │ │ ├── path.ts # 路径解析、目录遍历
45
+ │ │ ├── template.ts # Handlebars 渲染(带缓存)
46
+ │ │ ├── transform-imports.ts # 假路径 @/ → 用户 alias
47
+ │ │ └── global-root.ts # ~/.teamix-evo-global 解析(scope=global 用)
48
+ │ └── __tests__/ # 10 份单测,见下方测试章节
49
+ ├── tsup.config.ts # 构建配置(双入口:bin + core subpath)
50
+ ├── tsconfig.json
51
+ └── package.json
52
+ ```
53
+
54
+ ## 研发流程
55
+
56
+ ### 1. 环境准备
57
+
58
+ ```bash
59
+ # 在仓库根目录
60
+ pnpm install
61
+
62
+ # 需要先构建依赖包
63
+ pnpm --filter @teamix-evo/registry build
64
+ ```
65
+
66
+ ### 2. 开发
67
+
68
+ ```bash
69
+ # 监听模式构建
70
+ pnpm --filter teamix-evo dev
71
+ ```
72
+
73
+ 构建产物双入口(见 `tsup.config.ts`):
74
+
75
+ - `dist/index.js` — CLI bin(ESM,带 `#!/usr/bin/env node` banner,对应 `package.json#bin`)
76
+ - `dist/core/index.{js,d.ts}` — programmatic API(ESM + 类型,对应 `teamix-evo/core` subpath 导出,不带 banner)
77
+
78
+ ### 3. 新增命令
79
+
80
+ 1. 在 `src/commands/<group>/` 下新建命令文件
81
+ 2. 使用 Commander 的 `Command` 类定义命令
82
+ 3. 在对应 group 的 `index.ts` 中注册(`addCommand`)
83
+ 4. 如果是新的命令组,在 `src/index.ts` 中注册
84
+
85
+ 示例模式:
86
+
87
+ ```typescript
88
+ import { Command } from 'commander';
89
+ import { detectIde } from '../../ide/index.js';
90
+ import { logger } from '../../utils/logger.js';
91
+
92
+ export const myCommand = new Command('my-cmd')
93
+ .description('命令描述')
94
+ .action(async () => {
95
+ try {
96
+ const ide = detectIde();
97
+ const projectRoot = ide.getProjectRoot();
98
+ // ... 业务逻辑
99
+ logger.success('完成');
100
+ } catch (err) {
101
+ logger.error(`Failed: ${(err as Error).message}`);
102
+ process.exitCode = 1;
103
+ }
104
+ });
105
+ ```
106
+
107
+ ### 4. 修改核心引擎
108
+
109
+ - `core/installer.ts` — 资源首次安装逻辑
110
+ - `core/updater.ts` — 资源更新逻辑(处理三种策略 + managed regions)
111
+ - `core/registry-client.ts` — 从 node_modules 解析 variant 包路径
112
+ - `core/state.ts` — `.teamix-evo/config.json` 和 `manifest.json` 的读写
113
+
114
+ ### 5. IDE 适配
115
+
116
+ 当前支持 Qoder 与 Claude Code(`QoderAdapter` / `ClaudeAdapter`),`detectIde()` 自动判断。扩展新 IDE:
117
+
118
+ 1. 在 `src/ide/` 下新建 `XxxAdapter.ts`,实现 `IdeAdapter` 接口
119
+ 2. 在 `src/ide/index.ts` 的 `detectIde()` 中添加检测逻辑
120
+ 3. 在 `ALL_IDE_KINDS` 与 `SkillIde` 类型中加上新 IDE 名
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
+ - `core-api.test.ts` — programmatic core API(runDesignInit / runSkillsAdd / runUiAdd)
135
+ - `design-init-skills-link.test.ts` — design init ↔ skills auto-install 联动
136
+ - `installer.test.ts` — UI 资源安装(frozen / regenerable)
137
+ - `ui-installer.test.ts` — UI 装机引擎(依赖图 / alias 转换)
138
+ - `skills-installer.test.ts` — skills 装机(source-mirror)
139
+ - `skills-sync-doctor.test.ts` — source ↔ mirror 漂移检测
140
+ - `updater.test.ts` — 三策略更新逻辑(ADR 0003)
141
+ - `state.test.ts` — `.teamix-evo/` 状态读写
142
+ - `template.test.ts` — Handlebars 渲染
143
+ - `transform-imports.test.ts` — 假路径(@/)→ 用户 alias 转换
144
+
145
+ ### 7. 类型检查 & 构建
146
+
147
+ ```bash
148
+ pnpm --filter teamix-evo typecheck
149
+ pnpm --filter teamix-evo build
150
+ ```
151
+
152
+ ### 8. 本地调试
153
+
154
+ ```bash
155
+ # 构建后在任意目录执行
156
+ node /path/to/packages/cli/dist/index.js design init opentrek
157
+
158
+ # 或通过 pnpm 链接
159
+ cd packages/cli && pnpm link --global
160
+ teamix-evo design init opentrek
161
+ ```
162
+
163
+ 开启调试日志:
164
+
165
+ ```bash
166
+ TEAMIX_DEBUG=1 teamix-evo design init opentrek
167
+ ```
168
+
169
+ ## 命令参考
170
+
171
+ | 命令 | 说明 |
172
+ | --------------------------------------------------- | ------------------------------------------------- |
173
+ | `teamix-evo design init <variant>` | 初始化设计体系(variant 必填) |
174
+ | `teamix-evo design list-variants` | 列出可用 variant |
175
+ | `teamix-evo design list` | 查看已装机的 variant |
176
+ | `teamix-evo design update` | 更新已装资源(stub,v0.7 见 ADR 0019) |
177
+ | `teamix-evo design uninstall` | 卸载已装 design |
178
+ | `teamix-evo skills add [name...]` | 装 skills(写源 + 镜像 IDE);不传 = 全装 |
179
+ | `teamix-evo skills list` | 列出所有 skill 的安装状态 |
180
+ | `teamix-evo skills update` | 升级 skills(保留 managed 改动) |
181
+ | `teamix-evo skills sync [name...]` | 源 → IDE 镜像(漂移恢复用) |
182
+ | `teamix-evo skills doctor` | 检测源/镜像漂移(ADR 0013) |
183
+ | `teamix-evo skills uninstall` | 卸载 skills(源 + 镜像 + lock) |
184
+ | `teamix-evo ui init` | 初始化 ui 配置(aliases / iconLibrary / tsx / rsc) |
185
+ | `teamix-evo ui add <id...>` | 安装指定 ui 组件源码 |
186
+ | `teamix-evo ui list [--installed]` | 列出可用/已安装 ui 组件 |
187
+ | `teamix-evo biz-ui list-variants` | 列出 biz-ui 包内提供的业务变体 |
188
+ | `teamix-evo biz-ui add <id...> --variant <name>` | 安装变体感知业务组件(`--variant` 必填) |
189
+ | `teamix-evo templates list-variants` | 列出 templates 包内提供的页面模板变体 |
190
+ | `teamix-evo templates add <id...> --variant <name>` | 安装变体感知页面模板(`--variant` 必填) |
191
+
192
+ > 占位组件 → 真组件的升级流程**不是** CLI 子命令,由
193
+ > [`teamix-evo-ui-upgrade`](../../packages/skills/skills/teamix-evo-ui-upgrade/SKILL.md)
194
+ > skill 在 IDE 内驱动,底层仍调用 `teamix-evo ui add`。
195
+
196
+ ### 全局装 skill(`--scope global`)
197
+
198
+ `skills add` 支持 `--scope global` 装到 IDE 全局(`~/.qoder/skills/` + `~/.claude/skills/`)。当 cwd 不是 Teamix Evo 项目时,工具会自动把元数据写到 `~/.teamix-evo-global/`,不污染当前目录。
199
+
200
+ ```bash
201
+ # Onboarding 推荐:全局装 manage skill
202
+ npx teamix-evo@latest skills add teamix-evo-manage --scope global --ide claude,qoder -y
203
+
204
+ # 后续维护(update / uninstall 等)需 cd 到全局元数据根
205
+ cd ~/.teamix-evo-global && npx teamix-evo skills update
206
+ ```
207
+
208
+ ## 关键约定
209
+
210
+ - 使用 `process.exitCode = 1` 而非 `process.exit(1)`,确保异步操作完成
211
+ - 文件写入使用 `writeFileSafe`(tmp + rename 原子写入)
212
+ - 更新前自动备份到 `.teamix-evo/.backups/`
213
+ - 版本号从 `package.json` 动态读取,不硬编码
214
+
215
+ ## 依赖关系
216
+
217
+ ```
218
+ 本包 → @teamix-evo/registry(协议层)
219
+ 本包 → @teamix-evo/design(设计资源,运行时解析)
220
+ 本包 → @teamix-evo/skills(技能资源,运行时解析)
221
+ 本包 → @teamix-evo/ui(UI 资源,manifest + 源码)
222
+ ```
@@ -0,0 +1,442 @@
1
+ import { InstalledResource, SkillIde, SkillScope, UiAliases, UiEntry, VariantManifest, SkillsPackageManifest, SkillEntry, 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"`, `"uni-manager"`). */
8
+ variant: string;
9
+ /** IDE identifier written into config.json (e.g. `"qoder"`, `"claude"`). */
10
+ ide: string;
11
+ /** Override the design package name (defaults to `"@teamix-evo/design"`). */
12
+ packageName?: string;
13
+ /**
14
+ * Override resolution of the design package root. When provided, skips
15
+ * `require.resolve("<packageName>/package.json")`. Useful for tests that
16
+ * want to point at a fixture tree, and for embedding inside `create`
17
+ * where the package may not yet be installed in the consumer.
18
+ */
19
+ packageRoot?: string;
20
+ }
21
+ /**
22
+ * Outcome of the post-init skill auto-install step. `attempted` lists the skill
23
+ * ids we tried to install (baseline + variant overlay); `addedSkillIds` is what
24
+ * was actually installed (the rest were already present); `missing` lists skill
25
+ * ids that aren't in the manifest (warned, not fatal).
26
+ */
27
+ interface SkillsAutoInstallResult {
28
+ attempted: string[];
29
+ addedSkillIds: string[];
30
+ skippedSkillIds: string[];
31
+ missing: string[];
32
+ }
33
+ type RunDesignInitResult = {
34
+ status: 'installed';
35
+ packageName: string;
36
+ variant: string;
37
+ version: string;
38
+ count: number;
39
+ resources: InstalledResource[];
40
+ /** Per ADR 0010 §4 diagnostics. */
41
+ merge: {
42
+ overrides: string[];
43
+ variantAdds: string[];
44
+ defaultPassThrough: string[];
45
+ };
46
+ /** Result of the auto-install of baseline + variant design-rules skills. */
47
+ skills?: SkillsAutoInstallResult;
48
+ } | {
49
+ status: 'already-initialized';
50
+ existingVariant: string;
51
+ };
52
+ /**
53
+ * Programmatic equivalent of `teamix-evo design init <variant>`.
54
+ *
55
+ * Side effects:
56
+ * - Creates `<projectRoot>/.teamix-evo/`
57
+ * - Walks `default/` + `variants/<variant>/`, classifies each file by path
58
+ * convention, writes to consumer (skipping `frozen` files that already exist)
59
+ * - Writes `pack.lock.json`, `config.json`, `manifest.json` (installed)
60
+ *
61
+ * No interactive prompts, no `process.exit`. Throws on hard failure (P8).
62
+ */
63
+ declare function runDesignInit(options: RunDesignInitOptions): Promise<RunDesignInitResult>;
64
+
65
+ interface RunSkillsAddOptions {
66
+ /** Absolute project root directory. */
67
+ projectRoot: string;
68
+ /**
69
+ * Target IDEs to inject skills into. Optional in incremental mode (i.e. when
70
+ * `names` is provided) — falls back to the previously installed config.
71
+ * Required for the bulk path.
72
+ */
73
+ ides?: readonly SkillIde[];
74
+ /**
75
+ * Install scope. Optional in incremental mode (falls back to existing
76
+ * config). Required for the bulk path.
77
+ */
78
+ scope?: SkillScope;
79
+ /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to "qoder"). */
80
+ ide?: string;
81
+ /** Override the skills package name (defaults to "@teamix-evo/skills"). */
82
+ packageName?: string;
83
+ /**
84
+ * Optional skill ids to add. When omitted, all skills declared in the
85
+ * manifest are installed (bulk mode). When provided, only the listed skills
86
+ * are added (incremental mode); skills that are already installed are
87
+ * silently skipped and reported via `skippedSkillIds`.
88
+ */
89
+ names?: readonly string[];
90
+ }
91
+ type RunSkillsAddResult = {
92
+ status: 'installed';
93
+ packageName: string;
94
+ version: string;
95
+ ides: SkillIde[];
96
+ scope: SkillScope;
97
+ /** Number of skills that were freshly added in this call. */
98
+ skillCount: number;
99
+ /** Number of files written by `installSkills` for the freshly added skills. */
100
+ fileCount: number;
101
+ /** InstalledResource records for the freshly added skills only. */
102
+ resources: InstalledResource[];
103
+ /** Skill ids that were freshly added in this call. */
104
+ addedSkillIds: string[];
105
+ /** Skill ids that were requested but already installed; skipped. */
106
+ skippedSkillIds: string[];
107
+ } | {
108
+ /** Returned only from bulk mode when a skills package is already installed. */
109
+ status: 'already-added';
110
+ };
111
+ /**
112
+ * Programmatic equivalent of `teamix-evo skills add`.
113
+ *
114
+ * - Bulk mode (`names` omitted): install every skill in the manifest. Re-run
115
+ * on a project that already has `packages.skills` returns `'already-added'`.
116
+ * - Incremental mode (`names` provided): install only the listed skills. Skills
117
+ * already present are skipped (use `skills update` to refresh). `ides`/`scope`
118
+ * may be omitted — they fall back to the previously installed config.
119
+ */
120
+ declare function runSkillsAdd(options: RunSkillsAddOptions): Promise<RunSkillsAddResult>;
121
+
122
+ declare const DEFAULT_UI_ALIASES: UiAliases;
123
+ declare const DEFAULT_UI_ICON_LIBRARY = "lucide";
124
+ interface RunUiInitOptions {
125
+ /** Absolute project root directory. */
126
+ projectRoot: string;
127
+ /** Component aliases. Falls back to {@link DEFAULT_UI_ALIASES}. */
128
+ aliases?: Partial<UiAliases>;
129
+ /** Declared icon library (does not trigger code rewrite). Defaults to "lucide". */
130
+ iconLibrary?: string;
131
+ /** Whether the project uses TSX (true) or JSX (false). Defaults to true. */
132
+ tsx?: boolean;
133
+ /** Whether the project emits React Server Components markers. Defaults to false. */
134
+ rsc?: boolean;
135
+ /** IDE identifier written into config.ide when bootstrapping a fresh config (defaults to "qoder"). */
136
+ ide?: string;
137
+ }
138
+ type RunUiInitResult = {
139
+ status: 'installed';
140
+ aliases: UiAliases;
141
+ iconLibrary: string;
142
+ tsx: boolean;
143
+ rsc: boolean;
144
+ } | {
145
+ status: 'already-initialized';
146
+ };
147
+ /**
148
+ * Programmatic equivalent of `teamix-evo ui init`.
149
+ *
150
+ * Writes `packages.ui` into `.teamix-evo/config.json` only — no resource files
151
+ * are touched. Use {@link runUiAdd} afterwards to install component sources.
152
+ */
153
+ declare function runUiInit(options: RunUiInitOptions): Promise<RunUiInitResult>;
154
+
155
+ interface RunUiAddOptions {
156
+ /** Absolute project root directory. */
157
+ projectRoot: string;
158
+ /** Entry ids to install (registry dependencies are resolved transitively). */
159
+ ids: string[];
160
+ /** When true, overwrite frozen entries that already exist on disk. */
161
+ overwrite?: boolean;
162
+ /** Override the ui package name (defaults to "@teamix-evo/ui"). */
163
+ packageName?: string;
164
+ }
165
+ interface RunUiAddResult {
166
+ packageName: string;
167
+ /** Registered ids in install order (deps + requested). */
168
+ orderedIds: string[];
169
+ /** Number of files written. */
170
+ written: number;
171
+ /** Number of files skipped due to frozen + exists. */
172
+ skipped: number;
173
+ /** Meta files dropped under .teamix-evo/design/components/. */
174
+ metaFiles: string[];
175
+ /** Aggregate npm dependencies of the installed entries. */
176
+ npmDependencies: Record<string, string>;
177
+ /** Per-file install records merged into the installed manifest. */
178
+ resources: InstalledResource[];
179
+ }
180
+ /**
181
+ * Programmatic equivalent of `teamix-evo ui add <ids...>`.
182
+ *
183
+ * Requires `packages.ui` to already exist in `.teamix-evo/config.json`
184
+ * (i.e. {@link runUiInit} was called earlier).
185
+ */
186
+ declare function runUiAdd(options: RunUiAddOptions): Promise<RunUiAddResult>;
187
+
188
+ interface RunUiListOptions {
189
+ /** Absolute project root directory. */
190
+ projectRoot: string;
191
+ /** When true, only return entries that are already installed. */
192
+ installedOnly?: boolean;
193
+ /** Override the ui package name (defaults to "@teamix-evo/ui"). */
194
+ packageName?: string;
195
+ }
196
+ interface UiEntryListItem {
197
+ id: string;
198
+ type: UiEntry['type'];
199
+ description: string;
200
+ installed: boolean;
201
+ }
202
+ interface RunUiListResult {
203
+ packageName: string;
204
+ /** Total number of entries declared by the package manifest. */
205
+ total: number;
206
+ /** Number of installed entries (based on the project's installed manifest). */
207
+ installedCount: number;
208
+ /** Filtered + decorated entries. */
209
+ entries: UiEntryListItem[];
210
+ }
211
+ /**
212
+ * Programmatic equivalent of `teamix-evo ui list`.
213
+ *
214
+ * Returns structured data; the CLI command formats it for terminal output.
215
+ */
216
+ declare function runUiList(options: RunUiListOptions): Promise<RunUiListResult>;
217
+
218
+ interface InstallOptions {
219
+ /** Project root directory */
220
+ projectRoot: string;
221
+ /** The variant manifest */
222
+ manifest: VariantManifest;
223
+ /** Template data for Handlebars rendering */
224
+ data: Record<string, unknown>;
225
+ /** Absolute path to the variant directory (where source files live) */
226
+ variantDir: string;
227
+ /** Absolute path to the package root (for resolving _template/ sources) */
228
+ packageRoot: string;
229
+ }
230
+ interface InstallResult {
231
+ /** Successfully installed resource records */
232
+ resources: InstalledResource[];
233
+ /** Number of resources installed */
234
+ count: number;
235
+ }
236
+ /**
237
+ * Install resources from a variant manifest into the project.
238
+ */
239
+ declare function installResources(options: InstallOptions): Promise<InstallResult>;
240
+
241
+ /**
242
+ * Source-mirror skills installer (per ADR 0013).
243
+ *
244
+ * Two-stage flow:
245
+ * 1. **writeSkillSources** — render upstream `<packageRoot>/<skill.source>` and
246
+ * write to `<projectRoot>/.teamix-evo/skills/<id>/` (the consumer-side
247
+ * source of truth, regenerable, in git).
248
+ * 2. **syncSkillsToIdes** — pure byte-for-byte copy from source dir to each
249
+ * requested IDE mirror path (`.qoder/skills/<id>/`, `.claude/skills/<id>/`).
250
+ * Mirrors are 100% derived; not subject to managed-region preservation.
251
+ *
252
+ * `installSkills` orchestrates both. `updateSkills` re-renders the source with
253
+ * managed-region preservation against the existing source (NOT the mirrors),
254
+ * then re-syncs.
255
+ */
256
+ interface SkillInstallOptions {
257
+ /** Project root directory */
258
+ projectRoot: string;
259
+ /** Skills package manifest */
260
+ manifest: SkillsPackageManifest;
261
+ /** Template data */
262
+ data: Record<string, unknown>;
263
+ /** Absolute skills package root */
264
+ packageRoot: string;
265
+ /** IDE kinds to install for (intersection with skill.ides is computed) */
266
+ ides: readonly SkillIde[];
267
+ /** Install scope */
268
+ scope: SkillScope;
269
+ /** Optional: limit to specific skill ids */
270
+ onlyIds?: string[];
271
+ }
272
+ interface SkillInstallResult {
273
+ resources: InstalledResource[];
274
+ count: number;
275
+ }
276
+ /**
277
+ * Install (or reinstall) all skills declared in the manifest using the
278
+ * source-mirror flow. Returns InstalledResource records for both source files
279
+ * and IDE mirror files.
280
+ */
281
+ declare function installSkills(options: SkillInstallOptions): Promise<SkillInstallResult>;
282
+ interface SkillUpdateOptions extends SkillInstallOptions {
283
+ /**
284
+ * Optional: existing installed records (legacy parameter kept for callers that
285
+ * still pass it). The refactored updater consults the file-system source under
286
+ * `.teamix-evo/skills/<id>/` for managed-region preservation, so this is
287
+ * unused by the new flow. Callers should stop passing it.
288
+ */
289
+ installed?: InstalledResource[];
290
+ }
291
+ interface SkillUpdateResult {
292
+ resources: InstalledResource[];
293
+ summary: {
294
+ overwritten: number;
295
+ managed: number;
296
+ skipped: number;
297
+ created: number;
298
+ };
299
+ }
300
+ /**
301
+ * Update skills with managed-region preservation applied at the SOURCE layer
302
+ * (not the mirrors). After source is rewritten, mirrors are re-synced cleanly.
303
+ */
304
+ declare function updateSkills(options: SkillUpdateOptions): Promise<SkillUpdateResult>;
305
+ /**
306
+ * Sync existing skill sources to the requested IDE mirror paths.
307
+ *
308
+ * Used by:
309
+ * - `skills add` (immediate mirror after source write — handled by installSkills)
310
+ * - `skills sync` (re-mirror after the user adds an IDE or moves machines)
311
+ * - `skills update` (re-mirror after source is rewritten)
312
+ *
313
+ * `onlyIds` lets the caller limit which skills are synced.
314
+ */
315
+ interface SkillSyncOptions {
316
+ projectRoot: string;
317
+ /** Skills present in the source dir to mirror (caller derives from lock). */
318
+ skills: ReadonlyArray<{
319
+ id: string;
320
+ name: string;
321
+ updateStrategy: SkillEntry['updateStrategy'];
322
+ }>;
323
+ ides: readonly SkillIde[];
324
+ scope: SkillScope;
325
+ onlyIds?: string[];
326
+ }
327
+ interface SkillSyncResult {
328
+ resources: InstalledResource[];
329
+ count: number;
330
+ }
331
+ /**
332
+ * Mirror existing source dirs (`.teamix-evo/skills/<id>/`) to the given IDE
333
+ * paths. Pure byte-for-byte copy — no rendering, no merge.
334
+ */
335
+ declare function syncSkillsToIdes(options: SkillSyncOptions): Promise<SkillSyncResult>;
336
+ /**
337
+ * Remove all installed skill files. Returns the absolute paths removed.
338
+ */
339
+ declare function removeSkillFiles(records: InstalledResource[]): Promise<string[]>;
340
+
341
+ interface UiInstallOptions {
342
+ /** Project root directory */
343
+ projectRoot: string;
344
+ /** UI package manifest */
345
+ manifest: UiPackageManifest;
346
+ /** Absolute ui package root (used to resolve entry source paths) */
347
+ packageRoot: string;
348
+ /** Aliases configured in `packages.ui.aliases` */
349
+ aliases: UiAliases;
350
+ /** Entry ids the user explicitly requested to add */
351
+ requested: string[];
352
+ /** When true, skip writing entries whose target file already exists (frozen-on-add). */
353
+ skipExisting?: boolean;
354
+ }
355
+ interface UiInstallResult {
356
+ /** Ordered list of entry ids that were processed (deps + requested) */
357
+ orderedIds: string[];
358
+ /** Per-file install records (for InstalledManifest) */
359
+ resources: InstalledResource[];
360
+ /** Aggregate npm dependencies across the installed entries */
361
+ npmDependencies: Record<string, string>;
362
+ /** Number of files written */
363
+ written: number;
364
+ /** Number of files skipped because they already exist (frozen) */
365
+ skipped: number;
366
+ /** Meta files dropped under .teamix-evo/design/components/ */
367
+ metaFiles: string[];
368
+ }
369
+ /**
370
+ * Install the requested ui entries (transitively resolving registryDependencies).
371
+ * For frozen entries that already exist on disk, the write is skipped — shadcn-style.
372
+ */
373
+ declare function installUiEntries(options: UiInstallOptions): Promise<UiInstallResult>;
374
+ /**
375
+ * Remove all installed ui resource files and prune empty parent directories.
376
+ */
377
+ declare function removeUiFiles(records: InstalledResource[]): Promise<string[]>;
378
+
379
+ /**
380
+ * Load the variant manifest and _data.json for template rendering.
381
+ *
382
+ * @param packageName - e.g. "@teamix-evo/design"
383
+ * @param variant - e.g. "opentrek"
384
+ * @returns manifest and data for template rendering
385
+ */
386
+ declare function loadVariantData(packageName: string, variant: string): Promise<{
387
+ manifest: VariantManifest;
388
+ data: Record<string, unknown>;
389
+ variantDir: string;
390
+ packageRoot: string;
391
+ }>;
392
+
393
+ /**
394
+ * Load the skills package manifest and optional shared `_data.json`.
395
+ *
396
+ * @param packageName - e.g. "@teamix-evo/skills"
397
+ */
398
+ declare function loadSkillsData(packageName: string): Promise<{
399
+ manifest: SkillsPackageManifest;
400
+ data: Record<string, unknown>;
401
+ packageRoot: string;
402
+ }>;
403
+
404
+ /**
405
+ * Load the ui package manifest and optional shared `_data.json`.
406
+ *
407
+ * @param packageName - e.g. "@teamix-evo/ui"
408
+ */
409
+ declare function loadUiData(packageName: string): Promise<{
410
+ manifest: UiPackageManifest;
411
+ data: Record<string, unknown>;
412
+ packageRoot: string;
413
+ }>;
414
+
415
+ /**
416
+ * Get the .teamix-evo directory path for a project.
417
+ */
418
+ declare function getTeamixDir(projectRoot: string): string;
419
+ /**
420
+ * Ensure the .teamix-evo directory exists.
421
+ */
422
+ declare function ensureTeamixDir(projectRoot: string): Promise<string>;
423
+ /**
424
+ * Read the project config from .teamix-evo/config.json.
425
+ * Returns null if the file does not exist.
426
+ */
427
+ declare function readProjectConfig(projectRoot: string): Promise<ProjectConfig | null>;
428
+ /**
429
+ * Write the project config to .teamix-evo/config.json.
430
+ */
431
+ declare function writeProjectConfig(projectRoot: string, config: ProjectConfig): Promise<void>;
432
+ /**
433
+ * Read the installed manifest from .teamix-evo/manifest.json.
434
+ * Returns null if the file does not exist.
435
+ */
436
+ declare function readInstalledManifest(projectRoot: string): Promise<InstalledManifest | null>;
437
+ /**
438
+ * Write the installed manifest to .teamix-evo/manifest.json.
439
+ */
440
+ declare function writeInstalledManifest(projectRoot: string, manifest: InstalledManifest): Promise<void>;
441
+
442
+ 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 SkillSyncOptions, type SkillSyncResult, 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, syncSkillsToIdes, updateSkills, writeInstalledManifest, writeProjectConfig };