@uoyo/mvtt 2.0.0-beta.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.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/dist/build/assembler.d.ts +6 -0
  4. package/dist/build/assembler.d.ts.map +1 -0
  5. package/dist/build/assembler.js +32 -0
  6. package/dist/build/assembler.js.map +1 -0
  7. package/dist/build/section-loader.d.ts +4 -0
  8. package/dist/build/section-loader.d.ts.map +1 -0
  9. package/dist/build/section-loader.js +55 -0
  10. package/dist/build/section-loader.js.map +1 -0
  11. package/dist/build/validator.d.ts +6 -0
  12. package/dist/build/validator.d.ts.map +1 -0
  13. package/dist/build/validator.js +77 -0
  14. package/dist/build/validator.js.map +1 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +49 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/commands/build.d.ts +5 -0
  20. package/dist/commands/build.d.ts.map +1 -0
  21. package/dist/commands/build.js +46 -0
  22. package/dist/commands/build.js.map +1 -0
  23. package/dist/commands/doctor.d.ts +2 -0
  24. package/dist/commands/doctor.d.ts.map +1 -0
  25. package/dist/commands/doctor.js +79 -0
  26. package/dist/commands/doctor.js.map +1 -0
  27. package/dist/commands/install.d.ts +5 -0
  28. package/dist/commands/install.d.ts.map +1 -0
  29. package/dist/commands/install.js +63 -0
  30. package/dist/commands/install.js.map +1 -0
  31. package/dist/commands/shared.d.ts +2 -0
  32. package/dist/commands/shared.d.ts.map +1 -0
  33. package/dist/commands/shared.js +2 -0
  34. package/dist/commands/shared.js.map +1 -0
  35. package/dist/commands/uninstall.d.ts +2 -0
  36. package/dist/commands/uninstall.d.ts.map +1 -0
  37. package/dist/commands/uninstall.js +56 -0
  38. package/dist/commands/uninstall.js.map +1 -0
  39. package/dist/commands/update.d.ts +5 -0
  40. package/dist/commands/update.d.ts.map +1 -0
  41. package/dist/commands/update.js +59 -0
  42. package/dist/commands/update.js.map +1 -0
  43. package/dist/fs/hash.d.ts +3 -0
  44. package/dist/fs/hash.d.ts.map +1 -0
  45. package/dist/fs/hash.js +10 -0
  46. package/dist/fs/hash.js.map +1 -0
  47. package/dist/fs/install-manifest.d.ts +16 -0
  48. package/dist/fs/install-manifest.d.ts.map +1 -0
  49. package/dist/fs/install-manifest.js +29 -0
  50. package/dist/fs/install-manifest.js.map +1 -0
  51. package/dist/fs/materialize.d.ts +14 -0
  52. package/dist/fs/materialize.d.ts.map +1 -0
  53. package/dist/fs/materialize.js +116 -0
  54. package/dist/fs/materialize.js.map +1 -0
  55. package/dist/fs/protection.d.ts +15 -0
  56. package/dist/fs/protection.d.ts.map +1 -0
  57. package/dist/fs/protection.js +16 -0
  58. package/dist/fs/protection.js.map +1 -0
  59. package/dist/index.d.ts +3 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +17 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/types/manifest.d.ts +21 -0
  64. package/dist/types/manifest.d.ts.map +1 -0
  65. package/dist/types/manifest.js +2 -0
  66. package/dist/types/manifest.js.map +1 -0
  67. package/dist/types/registry.d.ts +25 -0
  68. package/dist/types/registry.d.ts.map +1 -0
  69. package/dist/types/registry.js +2 -0
  70. package/dist/types/registry.js.map +1 -0
  71. package/dist/util/color.d.ts +9 -0
  72. package/dist/util/color.d.ts.map +1 -0
  73. package/dist/util/color.js +13 -0
  74. package/dist/util/color.js.map +1 -0
  75. package/dist/util/package.d.ts +3 -0
  76. package/dist/util/package.d.ts.map +1 -0
  77. package/dist/util/package.js +13 -0
  78. package/dist/util/package.js.map +1 -0
  79. package/install-manifest.yaml +27 -0
  80. package/package.json +57 -0
  81. package/registry.yaml +209 -0
  82. package/sources/defaults/config.yaml +30 -0
  83. package/sources/defaults/project-context.yaml +26 -0
  84. package/sources/defaults/session.yaml +23 -0
  85. package/sources/knowledge/core/manifest.yaml +47 -0
  86. package/sources/knowledge/core/review-principles.md +51 -0
  87. package/sources/knowledge/patterns/clean-architecture/manifest.yaml +66 -0
  88. package/sources/knowledge/patterns/clean-architecture/review-checklist.md +230 -0
  89. package/sources/knowledge/patterns/ddd/manifest.yaml +83 -0
  90. package/sources/knowledge/patterns/ddd/review-checklist.md +226 -0
  91. package/sources/knowledge/patterns/ddd/tactical-patterns.md +12 -0
  92. package/sources/knowledge/patterns/frontend-react/manifest.yaml +44 -0
  93. package/sources/knowledge/patterns/frontend-react/review-checklist.md +78 -0
  94. package/sources/knowledge/patterns/manifest.yaml +113 -0
  95. package/sources/sections/activation-load-config.md +5 -0
  96. package/sources/sections/activation-load-context.md +11 -0
  97. package/sources/sections/activation-preflight.md +4 -0
  98. package/sources/sections/footer-next-steps.md +9 -0
  99. package/sources/sections/role-header.md +13 -0
  100. package/sources/skills/mvt-add-context/business.md +47 -0
  101. package/sources/skills/mvt-add-context/manifest.yaml +83 -0
  102. package/sources/skills/mvt-analyze/business.md +33 -0
  103. package/sources/skills/mvt-analyze/manifest.yaml +89 -0
  104. package/sources/skills/mvt-analyze-code/business.md +35 -0
  105. package/sources/skills/mvt-analyze-code/manifest.yaml +88 -0
  106. package/sources/skills/mvt-check-context/business.md +42 -0
  107. package/sources/skills/mvt-check-context/manifest.yaml +74 -0
  108. package/sources/skills/mvt-cleanup/business.md +31 -0
  109. package/sources/skills/mvt-cleanup/manifest.yaml +93 -0
  110. package/sources/skills/mvt-config/business.md +26 -0
  111. package/sources/skills/mvt-config/manifest.yaml +108 -0
  112. package/sources/skills/mvt-create-skill/business.md +111 -0
  113. package/sources/skills/mvt-create-skill/manifest.yaml +79 -0
  114. package/sources/skills/mvt-design/business.md +34 -0
  115. package/sources/skills/mvt-design/manifest.yaml +105 -0
  116. package/sources/skills/mvt-fix/business.md +28 -0
  117. package/sources/skills/mvt-fix/manifest.yaml +86 -0
  118. package/sources/skills/mvt-help/business.md +70 -0
  119. package/sources/skills/mvt-help/manifest.yaml +61 -0
  120. package/sources/skills/mvt-implement/business.md +32 -0
  121. package/sources/skills/mvt-implement/manifest.yaml +96 -0
  122. package/sources/skills/mvt-init/business.md +49 -0
  123. package/sources/skills/mvt-init/manifest.yaml +93 -0
  124. package/sources/skills/mvt-refactor/business.md +33 -0
  125. package/sources/skills/mvt-refactor/manifest.yaml +101 -0
  126. package/sources/skills/mvt-review/business.md +49 -0
  127. package/sources/skills/mvt-review/manifest.yaml +106 -0
  128. package/sources/skills/mvt-status/business.md +24 -0
  129. package/sources/skills/mvt-status/manifest.yaml +74 -0
  130. package/sources/skills/mvt-sync-context/business.md +25 -0
  131. package/sources/skills/mvt-sync-context/manifest.yaml +84 -0
  132. package/sources/skills/mvt-template/business.md +49 -0
  133. package/sources/skills/mvt-template/manifest.yaml +71 -0
  134. package/sources/skills/mvt-test/business.md +36 -0
  135. package/sources/skills/mvt-test/manifest.yaml +111 -0
  136. package/sources/templates/analyze-code-output/body.md +44 -0
  137. package/sources/templates/analyze-code-output/manifest.yaml +11 -0
  138. package/sources/templates/analyze-output/body.md +38 -0
  139. package/sources/templates/analyze-output/manifest.yaml +11 -0
  140. package/sources/templates/cleanup-output/body.md +9 -0
  141. package/sources/templates/cleanup-output/manifest.yaml +11 -0
  142. package/sources/templates/config-output/body.md +11 -0
  143. package/sources/templates/config-output/manifest.yaml +11 -0
  144. package/sources/templates/context-check-output/body.md +32 -0
  145. package/sources/templates/context-check-output/manifest.yaml +11 -0
  146. package/sources/templates/design-output/body.md +50 -0
  147. package/sources/templates/design-output/manifest.yaml +11 -0
  148. package/sources/templates/fix-output/body.md +30 -0
  149. package/sources/templates/fix-output/manifest.yaml +11 -0
  150. package/sources/templates/implement-output/body.md +32 -0
  151. package/sources/templates/implement-output/manifest.yaml +11 -0
  152. package/sources/templates/init-output/body.md +34 -0
  153. package/sources/templates/init-output/manifest.yaml +11 -0
  154. package/sources/templates/refactor-output/body.md +32 -0
  155. package/sources/templates/refactor-output/manifest.yaml +11 -0
  156. package/sources/templates/review-output/body.md +45 -0
  157. package/sources/templates/review-output/manifest.yaml +11 -0
  158. package/sources/templates/status-output/body.md +36 -0
  159. package/sources/templates/status-output/manifest.yaml +11 -0
  160. package/sources/templates/sync-context-output/body.md +16 -0
  161. package/sources/templates/sync-context-output/manifest.yaml +11 -0
  162. package/sources/templates/test-output/body.md +31 -0
  163. package/sources/templates/test-output/manifest.yaml +11 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xiangjie
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,209 @@
1
+ # My-Virtual-TechTeam (MVTT)
2
+
3
+ A virtual IT team made up of AI agents. Built for [Claude Code](https://claude.ai/claude-code), MVTT turns your IDE into a coordinated squad of Analyst, Architect, Developer, Reviewer, and Tester — each with a clear role, a shared workspace, and enforceable team conventions.
4
+
5
+ ## Why MVTT
6
+
7
+ - **One-command install** — `npx @uoyo/mvtt install` drops a full skill suite into any project
8
+ - **Claude Code native** — 18 skills auto-discovered from `.claude/skills/`
9
+ - **Bilingual output** — choose `en-US` or `zh-CN` at install time; every skill honors the setting
10
+ - **Shared workspace** — `.ai-agents/` centralizes session state, domain knowledge, config, and output templates
11
+ - **Safe lifecycle** — `install` / `update` / `uninstall` / `doctor` with manifest-based file ownership, so user data is never overwritten
12
+ - **Extensible** — `/mvt-create-skill` lets your team grow its own skills for project-specific workflows
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npx @uoyo/mvtt install
18
+ ```
19
+
20
+ The installer is interactive:
21
+
22
+ ```
23
+ ? Select language / 选择语言
24
+ ❯ English (en-US)
25
+ 中文 (zh-CN)
26
+ ```
27
+
28
+ Optional flags:
29
+
30
+ ```bash
31
+ npx @uoyo/mvtt install --pattern ddd # Preset architecture pattern (ddd | clean-architecture | frontend-react)
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ 1. Run `npx @uoyo/mvtt install` in your project root
37
+ 2. Open the project in Claude Code
38
+ 3. Run `/mvt-init` to initialize the workspace
39
+ 4. Run `/mvt-help` to see all available skills
40
+ 5. Follow the guided workflow through your development phases
41
+
42
+ ## CLI Commands
43
+
44
+ | Command | Purpose |
45
+ |---|---|
46
+ | `npx @uoyo/mvtt install` | First-time install; interactive language selection |
47
+ | `npx @uoyo/mvtt install --pattern <name>` | Install with a preset architecture pattern |
48
+ | `npx @uoyo/mvtt update` | Upgrade to the latest version (user data preserved) |
49
+ | `npx @uoyo/mvtt update --check` | Show version diff without modifying anything |
50
+ | `npx @uoyo/mvtt doctor` | Check installation health and detect manual edits |
51
+ | `npx @uoyo/mvtt uninstall` | Interactive confirmation, then remove generated files (user data preserved) |
52
+ | `npx @uoyo/mvtt --help` | Full CLI help |
53
+ | `npx @uoyo/mvtt --version` | Print version |
54
+
55
+ ## Skills (18 total)
56
+
57
+ ### Workflow Skills (Sequential Phases)
58
+
59
+ | Skill | Description |
60
+ |-------|-------------|
61
+ | `/mvt-analyze` | Analyze requirements and extract domain concepts |
62
+ | `/mvt-analyze-code` | Reverse-analyze existing code to generate context |
63
+ | `/mvt-design` | Create architecture design based on requirements |
64
+ | `/mvt-implement` | Implement features based on architecture design |
65
+ | `/mvt-review` | Code review for quality and standards compliance |
66
+ | `/mvt-test` | Generate tests to validate implementations |
67
+
68
+ ### Shortcut Skills (Anytime)
69
+
70
+ | Skill | Description |
71
+ |-------|-------------|
72
+ | `/mvt-fix` | Diagnose and fix bugs or issues |
73
+ | `/mvt-refactor` | Refactor code while preserving behavior |
74
+
75
+ ### Project Management Skills
76
+
77
+ | Skill | Description |
78
+ |-------|-------------|
79
+ | `/mvt-init` | Initialize or refresh project setup |
80
+ | `/mvt-status` | Show current project and workflow status |
81
+ | `/mvt-config` | Manage framework configuration |
82
+ | `/mvt-sync-context` | Synchronize context with code changes |
83
+ | `/mvt-cleanup` | Clean up workspace artifacts |
84
+
85
+ ### Utility Skills
86
+
87
+ | Skill | Description |
88
+ |-------|-------------|
89
+ | `/mvt-help` | Show available skills and workflow guidance |
90
+ | `/mvt-create-skill` | Create custom MVTT skills |
91
+ | `/mvt-add-context` | Add or update project context interactively |
92
+ | `/mvt-check-context` | Analyze context token load and optimization |
93
+ | `/mvt-template` | View and customize output templates |
94
+
95
+ ## Standard Workflow
96
+
97
+ ```
98
+ /mvt-analyze → /mvt-design → /mvt-implement → /mvt-review → /mvt-test
99
+ Analyst Architect Developer Reviewer Tester
100
+ ```
101
+
102
+ The Conductor (the underlying orchestration logic) keeps session state in `.ai-agents/workspace/session.yaml` so any skill can pick up where the previous one left off.
103
+
104
+ ## Configuration
105
+
106
+ All preferences live in `.ai-agents/config.yaml`:
107
+
108
+ ```yaml
109
+ version: "2.0"
110
+
111
+ preferences:
112
+ language: en-US # en-US | zh-CN — chosen during install, changeable anytime
113
+ output:
114
+ no_emojis: true # Disable emojis in skill output
115
+ data_format: yaml # yaml | json
116
+
117
+ pattern:
118
+ active: "" # Detected via /mvt-init or set via --pattern on install
119
+ selection:
120
+ auto_detect: true
121
+ confirm_with_user: true
122
+ ```
123
+
124
+ Every skill reads this file on activation and enforces the settings through the shared Activation Protocol.
125
+
126
+ ## Architecture Patterns
127
+
128
+ MVTT ships with first-class knowledge for three patterns (`.ai-agents/knowledge/patterns/`):
129
+
130
+ - **`ddd`** — Domain-Driven Design (bounded contexts, aggregates, domain events)
131
+ - **`clean-architecture`** — Layered boundaries, dependency inversion
132
+ - **`frontend-react`** — React-specific structural conventions
133
+
134
+ Each pattern contributes its own review checklist and design guidance that `/mvt-design`, `/mvt-review`, and `/mvt-refactor` automatically consume.
135
+
136
+ ## Runtime Layout
137
+
138
+ After `install`, your project has:
139
+
140
+ ```
141
+ .claude/skills/mvt-*/SKILL.md # GENERATED (18 skills, Claude Code entry points)
142
+
143
+ .ai-agents/
144
+ ├── config.yaml # CREATE_ONCE (user-editable)
145
+ ├── registry.yaml # GENERATED (skill metadata)
146
+ ├── .mvtt-manifest.json # GENERATED (install metadata, hashes)
147
+ ├── workspace/
148
+ │ ├── session.yaml # CREATE_ONCE
149
+ │ ├── project-context.yaml # CREATE_ONCE
150
+ │ └── artifacts/ # USER DATA (skill outputs)
151
+ ├── skills/_templates/
152
+ │ ├── *-output.md # GENERATED (14 templates)
153
+ │ └── custom/ # USER DATA (your overrides)
154
+ └── knowledge/
155
+ ├── core/ # GENERATED (framework-wide principles)
156
+ ├── patterns/ # GENERATED (ddd, clean-architecture, frontend-react)
157
+ ├── principle/ # USER DATA (team conventions)
158
+ └── project/ # USER DATA (domain-specific knowledge)
159
+ ```
160
+
161
+ File classification:
162
+
163
+ - **GENERATED** — owned by the CLI; overwritten on every `update`
164
+ - **CREATE_ONCE** — created only on first install; never overwritten
165
+ - **USER DATA** — CLI never touches these paths
166
+
167
+ `doctor` hashes every GENERATED file against the manifest, so manual edits are detected immediately.
168
+
169
+ ## Activation Protocol (Runtime)
170
+
171
+ Every skill shares a 4-step activation sequence, inlined into each `SKILL.md` at build time:
172
+
173
+ 1. **Load Context** — `session.yaml` + `project-context.yaml` + skill-specific extended context
174
+ 2. **Load Config & Apply Preferences** — read `config.yaml`, enforce language and output style
175
+ 3. **Pre-flight Checks** — validate prerequisites (workspace initialized, required artifacts exist, etc.)
176
+ 4. **Execute** — run skill-specific logic
177
+
178
+ DRY at source (one shared section per step), flat at runtime (each `SKILL.md` is self-contained — no cross-file reads when Claude Code loads a skill).
179
+
180
+ ## Extending MVTT
181
+
182
+ Beyond the 18 built-in skills, run `/mvt-create-skill` to scaffold a project-specific skill interactively. Custom skills live under `.ai-agents/skills/` and can override or complement any default behavior (e.g. a `/mvt-test-gherkin` variant that emits Gherkin feature files in your team's house style).
183
+
184
+ ## Development (Contributing to MVTT Itself)
185
+
186
+ Requirements: Node.js ≥ 18.
187
+
188
+ ```bash
189
+ npm install
190
+ npm run build # Compile TypeScript
191
+ npm test # Run test suite (66 tests)
192
+ npm test -- --coverage # With coverage report
193
+
194
+ # Rebuild skills / templates from sources into any output directory
195
+ node dist/index.js build --out .test-output
196
+ ```
197
+
198
+ Source layout:
199
+
200
+ - `src/` — CLI TypeScript source (commander-based; uses `prompts` for interactive selection)
201
+ - `sources/skills/<name>/manifest.yaml + business.md` — Skill source files
202
+ - `sources/templates/<name>/manifest.yaml + body.md` — Template source files
203
+ - `sources/sections/*.md` — Shared activation protocol sections (mustache-style blocks)
204
+ - `registry.yaml` — Single source of truth for skill metadata
205
+ - `install-manifest.yaml` — File classification (generated / create_once / user_data)
206
+
207
+ ## License
208
+
209
+ MIT
@@ -0,0 +1,6 @@
1
+ export interface AssembleOptions {
2
+ sourcesDir: string;
3
+ timestamp?: string;
4
+ }
5
+ export declare function assembleFromManifest(manifestPath: string, options: AssembleOptions): string;
6
+ //# sourceMappingURL=assembler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembler.d.ts","sourceRoot":"","sources":["../../src/build/assembler.ts"],"names":[],"mappings":"AAmBA,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,GACvB,MAAM,CAiBR"}
@@ -0,0 +1,32 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { loadSection } from "./section-loader.js";
5
+ function buildFrontmatter(fm) {
6
+ const lines = ["---"];
7
+ for (const [key, value] of Object.entries(fm)) {
8
+ if (value.includes("\n") || value.includes("'")) {
9
+ lines.push(`${key}: "${value.replace(/"/g, '\\"')}"`);
10
+ }
11
+ else {
12
+ lines.push(`${key}: '${value}'`);
13
+ }
14
+ }
15
+ lines.push("---");
16
+ return lines.join("\n");
17
+ }
18
+ export function assembleFromManifest(manifestPath, options) {
19
+ const raw = readFileSync(manifestPath, "utf-8");
20
+ const manifest = parseYaml(raw);
21
+ const skillDir = path.dirname(manifestPath);
22
+ const parts = [];
23
+ parts.push(buildFrontmatter(manifest.frontmatter));
24
+ parts.push("");
25
+ for (const section of manifest.sections) {
26
+ const content = loadSection(section, skillDir, options.sourcesDir);
27
+ parts.push(content.trimEnd());
28
+ parts.push("");
29
+ }
30
+ return parts.join("\n");
31
+ }
32
+ //# sourceMappingURL=assembler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assembler.js","sourceRoot":"","sources":["../../src/build/assembler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,SAAS,gBAAgB,CAAC,EAA0B;IAClD,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC;IACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAOD,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,OAAwB;IAExB,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAa,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;IACnD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Section } from "../types/manifest.js";
2
+ export declare function applyParams(template: string, params: Record<string, unknown>): string;
3
+ export declare function loadSection(section: Section, skillDir: string, sourcesDir: string): string;
4
+ //# sourceMappingURL=section-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-loader.d.ts","sourceRoot":"","sources":["../../src/build/section-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAuCpD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAIR;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAiBR"}
@@ -0,0 +1,55 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ const BLOCK_PATTERN = /\{\{#(\w+)\}\}([\s\S]*?)\{\{\/\1\}\}\n?/g;
4
+ const VAR_PATTERN = /\{\{(\w+|\.)?\}\}/g;
5
+ function replaceVars(template, vars) {
6
+ return template.replace(VAR_PATTERN, (_match, key) => {
7
+ if (key === ".")
8
+ return String(vars["."] ?? "");
9
+ const val = vars[key];
10
+ if (val === undefined || val === null)
11
+ return "";
12
+ return String(val);
13
+ });
14
+ }
15
+ function expandBlocks(template, params) {
16
+ return template.replace(BLOCK_PATTERN, (_match, key, rawBody) => {
17
+ const val = params[key];
18
+ if (val === undefined || val === null || val === false)
19
+ return "";
20
+ const body = rawBody.replace(/^\n/, "");
21
+ if (Array.isArray(val)) {
22
+ return val
23
+ .map((item) => {
24
+ if (typeof item === "object" && item !== null) {
25
+ return replaceVars(body, item).trimEnd();
26
+ }
27
+ return replaceVars(body, { ".": item }).trimEnd();
28
+ })
29
+ .join("\n");
30
+ }
31
+ return replaceVars(body, params);
32
+ });
33
+ }
34
+ export function applyParams(template, params) {
35
+ let result = expandBlocks(template, params);
36
+ result = replaceVars(result, params);
37
+ return result;
38
+ }
39
+ export function loadSection(section, skillDir, sourcesDir) {
40
+ switch (section.type) {
41
+ case "inline":
42
+ return section.content;
43
+ case "file": {
44
+ const filePath = path.resolve(skillDir, section.source);
45
+ return readFileSync(filePath, "utf-8");
46
+ }
47
+ case "shared":
48
+ case "template": {
49
+ const filePath = path.resolve(sourcesDir, section.source);
50
+ const content = readFileSync(filePath, "utf-8");
51
+ return applyParams(content, section.params ?? {});
52
+ }
53
+ }
54
+ }
55
+ //# sourceMappingURL=section-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-loader.js","sourceRoot":"","sources":["../../src/build/section-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface ValidationError {
2
+ file: string;
3
+ message: string;
4
+ }
5
+ export declare function validateManifest(manifestPath: string, sourcesDir: string): ValidationError[];
6
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/build/validator.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AA6CD,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,eAAe,EAAE,CAqDnB"}
@@ -0,0 +1,77 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ function validateSectionRef(section, skillDir, sourcesDir) {
5
+ if (section.type === "file") {
6
+ const p = path.resolve(skillDir, section.source);
7
+ if (!existsSync(p))
8
+ return `File not found: ${section.source} (resolved: ${p})`;
9
+ }
10
+ if (section.type === "shared" || section.type === "template") {
11
+ const p = path.resolve(sourcesDir, section.source);
12
+ if (!existsSync(p))
13
+ return `Shared section not found: ${section.source} (resolved: ${p})`;
14
+ }
15
+ return null;
16
+ }
17
+ function checkParamCompleteness(sectionSource, sourcesDir, params) {
18
+ const errors = [];
19
+ const filePath = path.resolve(sourcesDir, sectionSource);
20
+ if (!existsSync(filePath))
21
+ return errors;
22
+ const content = readFileSync(filePath, "utf-8");
23
+ const stripped = content.replace(/\{\{#(\w+)\}\}[\s\S]*?\{\{\/\1\}\}/g, "");
24
+ const topLevelVars = stripped.match(/\{\{(\w+)\}\}/g) ?? [];
25
+ const requiredParams = new Set(topLevelVars.map((v) => v.slice(2, -2)));
26
+ for (const varName of requiredParams) {
27
+ if (varName === ".")
28
+ continue;
29
+ if (!params || !(varName in params)) {
30
+ errors.push(`Missing param "${varName}" for section "${sectionSource}"`);
31
+ }
32
+ }
33
+ return errors;
34
+ }
35
+ export function validateManifest(manifestPath, sourcesDir) {
36
+ const errors = [];
37
+ if (!existsSync(manifestPath)) {
38
+ errors.push({ file: manifestPath, message: "Manifest file not found" });
39
+ return errors;
40
+ }
41
+ let manifest;
42
+ try {
43
+ const raw = readFileSync(manifestPath, "utf-8");
44
+ manifest = parseYaml(raw);
45
+ }
46
+ catch (e) {
47
+ errors.push({ file: manifestPath, message: `Invalid YAML: ${e}` });
48
+ return errors;
49
+ }
50
+ if (!manifest.name) {
51
+ errors.push({ file: manifestPath, message: 'Missing required field "name"' });
52
+ }
53
+ if (!manifest.output) {
54
+ errors.push({ file: manifestPath, message: 'Missing required field "output"' });
55
+ }
56
+ if (!manifest.sections || !Array.isArray(manifest.sections)) {
57
+ errors.push({ file: manifestPath, message: 'Missing or invalid "sections" array' });
58
+ return errors;
59
+ }
60
+ const skillDir = path.dirname(manifestPath);
61
+ for (let i = 0; i < manifest.sections.length; i++) {
62
+ const section = manifest.sections[i];
63
+ const refErr = validateSectionRef(section, skillDir, sourcesDir);
64
+ if (refErr) {
65
+ errors.push({ file: manifestPath, message: `sections[${i}]: ${refErr}` });
66
+ }
67
+ if ((section.type === "shared" || section.type === "template") &&
68
+ section.params) {
69
+ const paramErrors = checkParamCompleteness(section.source, sourcesDir, section.params);
70
+ for (const pe of paramErrors) {
71
+ errors.push({ file: manifestPath, message: `sections[${i}]: ${pe}` });
72
+ }
73
+ }
74
+ }
75
+ return errors;
76
+ }
77
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/build/validator.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function run(argv: string[]): Promise<void>;
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CvD"}
package/dist/cli.js ADDED
@@ -0,0 +1,49 @@
1
+ import { Command } from "commander";
2
+ import { buildCommand } from "./commands/build.js";
3
+ import { installCommand } from "./commands/install.js";
4
+ import { updateCommand } from "./commands/update.js";
5
+ import { doctorCommand } from "./commands/doctor.js";
6
+ import { uninstallCommand } from "./commands/uninstall.js";
7
+ import { getVersion } from "./commands/shared.js";
8
+ export async function run(argv) {
9
+ const program = new Command();
10
+ program
11
+ .name("mvtt")
12
+ .description("My Virtual Tech Team CLI")
13
+ .version(getVersion(), "-v, --version");
14
+ program
15
+ .command("install")
16
+ .description("Install MVTT into current project")
17
+ .option("--pattern <name>", "Set architecture pattern (ddd, clean-architecture, etc.)")
18
+ .action(async (opts) => {
19
+ await installCommand(opts);
20
+ });
21
+ program
22
+ .command("update")
23
+ .description("Update MVTT to latest version")
24
+ .option("--check", "Only report version diff, do not modify")
25
+ .action((opts) => {
26
+ updateCommand(opts);
27
+ });
28
+ program
29
+ .command("doctor")
30
+ .description("Check installation health")
31
+ .action(() => {
32
+ doctorCommand();
33
+ });
34
+ program
35
+ .command("uninstall")
36
+ .description("Remove MVTT generated files")
37
+ .action(async () => {
38
+ await uninstallCommand();
39
+ });
40
+ program
41
+ .command("build")
42
+ .description("Build skills and templates from sources (dev)")
43
+ .option("--out <dir>", "Output directory (default: cwd)")
44
+ .action((opts) => {
45
+ buildCommand(opts);
46
+ });
47
+ await program.parseAsync(argv, { from: "user" });
48
+ }
49
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc;IACtC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,0BAA0B,CAAC;SACvC,OAAO,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;IAE1C,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,kBAAkB,EAAE,0DAA0D,CAAC;SACtF,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,SAAS,EAAE,yCAAyC,CAAC;SAC5D,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,aAAa,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,2BAA2B,CAAC;SACxC,MAAM,CAAC,GAAG,EAAE;QACX,aAAa,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,gBAAgB,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,aAAa,EAAE,iCAAiC,CAAC;SACxD,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,YAAY,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface BuildOptions {
2
+ out?: string;
3
+ }
4
+ export declare function buildCommand(options?: BuildOptions): void;
5
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,IAAI,CA4C7D"}
@@ -0,0 +1,46 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { assembleFromManifest } from "../build/assembler.js";
5
+ import { validateManifest } from "../build/validator.js";
6
+ export function buildCommand(options = {}) {
7
+ const projectRoot = process.cwd();
8
+ const sourcesDir = path.resolve(projectRoot, "sources");
9
+ const outputRoot = options.out ? path.resolve(options.out) : projectRoot;
10
+ const timestamp = new Date().toISOString();
11
+ let totalFiles = 0;
12
+ let totalErrors = 0;
13
+ for (const kind of ["skills", "templates"]) {
14
+ const baseDir = path.resolve(sourcesDir, kind);
15
+ if (!existsSync(baseDir))
16
+ continue;
17
+ for (const entry of readdirSync(baseDir)) {
18
+ const manifestPath = path.join(baseDir, entry, "manifest.yaml");
19
+ if (!existsSync(manifestPath))
20
+ continue;
21
+ const errors = validateManifest(manifestPath, sourcesDir);
22
+ if (errors.length > 0) {
23
+ for (const err of errors) {
24
+ console.error(`[ERROR] ${err.file}: ${err.message}`);
25
+ }
26
+ totalErrors += errors.length;
27
+ continue;
28
+ }
29
+ const raw = readFileSync(manifestPath, "utf-8");
30
+ const manifest = parseYaml(raw);
31
+ const content = assembleFromManifest(manifestPath, {
32
+ sourcesDir,
33
+ timestamp,
34
+ });
35
+ const outPath = path.resolve(outputRoot, manifest.output);
36
+ mkdirSync(path.dirname(outPath), { recursive: true });
37
+ writeFileSync(outPath, content, "utf-8");
38
+ console.log(`[OK] ${manifest.output}`);
39
+ totalFiles++;
40
+ }
41
+ }
42
+ console.log(`\nBuild complete: ${totalFiles} files generated, ${totalErrors} errors.`);
43
+ if (totalErrors > 0)
44
+ process.exit(1);
45
+ }
46
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC1F,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAMzD,MAAM,UAAU,YAAY,CAAC,UAAwB,EAAE;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IAEzE,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAU,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QAEnC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;gBAAE,SAAS;YAExC,MAAM,MAAM,GAAG,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YAC1D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvD,CAAC;gBACD,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;gBAC7B,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAa,SAAS,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,oBAAoB,CAAC,YAAY,EAAE;gBACjD,UAAU;gBACV,SAAS;aACV,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1D,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAEzC,OAAO,CAAC,GAAG,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACvC,UAAU,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,UAAU,qBAAqB,WAAW,UAAU,CAAC,CAAC;IACvF,IAAI,WAAW,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function doctorCommand(): void;
2
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAOA,wBAAgB,aAAa,IAAI,IAAI,CAgEpC"}